Adding support for Cudy P4

Hello all,

I am trying to add OpenWrt support for Cudy P4. It is my first time adding support for a new device, and the qualcommax platform is fairly new. I have not used a device with this platform in the past, hence might need some help here.

Device page: https://www.cudy.com/products/p4-1-0
Datasheet: https://www.cudy.com/cdn/shop/files/P4_Datasheet.pdf
Downloads page: https://www.cudy.com/pages/download-center/p4-1-0 (firmware, documents, GPL)

As per the datasheet and device page, the hardware is:

  • CPU: Qualcomm IPQ5018 (2 x 1.0 GHz)
  • Flash: 128 MB
  • RAM: 512 MB DDR3
  • Wi-Fi (5 GHz): 802.11ax up to 2402 Mbps (2x2)
  • Wi-Fi (2.4 GHz): 802.11ax up to 574 Mbps (2x2)
  • Cellular modem (5G NR): Qualcomm X62

With a little digging into the GPL code and the OEM sysupgrade images, I could infer the following:

  • Stock firmware is based on OpenWrt 18.06.9
  • The firmware for P4 (profile DEVICE_R72) and P5 (profile DEVICE_R21) is based on a common codebase
  • The platform target is called ipq/ipq50xx (unlike qualcommax/ipq50xx in upstream)
  • The stock firmware has dropbear and telnetd but the init scripts are modified to not start the service unless bdinfo factory outputs 1
  • The cellular modem is possibly a Quectel RM520N as per comments in multiple places

I opened the case of the router, found the serial console pins with some trial and error and obtained access. From the OEM uboot-based bootloader, I was able to change the bootargs to insert init=/bin/sh and boot the firmware. From the booted shell, I looked at the output of ubinfo -a, created the device node for the rootfs_data ubi volume and mounted it. I copied the init scripts for dropbear and telnet into the overlay's upper dir and deleted the line that checked the output of bdinfo factory. Rebooting normally after this, the SSH and telnet services started as expected and I now have a root shell in the stock firmware.

Below is some useful information:

cat /proc/mtd
root@P4:/# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 00080000 00020000 "0:SBL1"
mtd1: 00080000 00020000 "0:MIBIB"
mtd2: 00040000 00020000 "0:BOOTCONFIG"
mtd3: 00040000 00020000 "0:BOOTCONFIG1"
mtd4: 00100000 00020000 "0:QSEE"
mtd5: 00040000 00020000 "0:DEVCFG"
mtd6: 00040000 00020000 "0:CDT"
mtd7: 00080000 00020000 "0:APPSBLENV"
mtd8: 00140000 00020000 "0:APPSBL"
mtd9: 00140000 00020000 "0:APPSBL_1"
mtd10: 00100000 00020000 "0:ART"
mtd11: 00080000 00020000 "0:TRAINING"
mtd12: 00040000 00020000 "bdinfo"
mtd13: 02400000 00020000 "rootfs_1"
mtd14: 02400000 00020000 "rootfs"
mtd15: 003816b0 0001f000 "kernel"
mtd16: 010d5000 0001f000 "ubi_rootfs"
mtd17: 00915000 0001f000 "rootfs_data"
ubinfo -a
root@P4:/# ubinfo -a
UBI version:                    1
Count of UBI devices:           1
UBI control device major/minor: 10:59
Present UBI devices:            ubi0

ubi0
Volumes count:                           3
Logical eraseblock size:                 126976 bytes, 124.0 KiB
Total amount of logical eraseblocks:     288 (36569088 bytes, 34.8 MiB)
Amount of available logical eraseblocks: 0 (0 bytes)
Maximum count of volumes                 128
Count of bad physical eraseblocks:       0
Count of reserved physical eraseblocks:  20
Current maximum erase counter value:     122
Minimum input/output unit size:          2048 bytes
Character device major/minor:            241:0
Present volumes:                         0, 1, 2

Volume ID:   0 (on ubi0)
Type:        static
Alignment:   1
Size:        50 LEBs (6348800 bytes, 6.0 MiB)
Data bytes:  3675824 bytes (3.5 MiB)
State:       OK
Name:        kernel
Character device major/minor: 241:1
-----------------------------------
Volume ID:   1 (on ubi0)
Type:        dynamic
Alignment:   1
Size:        139 LEBs (17649664 bytes, 16.8 MiB)
State:       OK
Name:        ubi_rootfs
Character device major/minor: 241:2
-----------------------------------
Volume ID:   2 (on ubi0)
Type:        dynamic
Alignment:   1
Size:        75 LEBs (9523200 bytes, 9.0 MiB)
State:       OK
Name:        rootfs_data
Character device major/minor: 241:3
logread | grep -A20 nand
root@P4:/# logread | grep -A20 nand
kern.info kernel: [    2.381287] QPIC controller support serial nand.
kern.info kernel: [    2.386564] nand: device found, Manufacturer ID: 0xc8, Chip ID: 0x11
kern.info kernel: [    2.391099] nand: GigaDevice F50D1G41LB(2M) SPI NAND 1G 1.8V
kern.info kernel: [    2.397463] nand: 128 MiB, SLC, erase size: 128 KiB, page size: 2048, OOB size: 64
kern.notice kernel: [    2.403946] 15 ofpart partitions found on MTD device qcom_nand.0
kern.notice kernel: [    2.410459] Creating 15 MTD partitions on "qcom_nand.0":
kern.notice kernel: [    2.416648] 0x000000000000-0x000000080000 : "0:SBL1"
kern.notice kernel: [    2.423377] 0x000000080000-0x000000100000 : "0:MIBIB"
kern.notice kernel: [    2.428195] 0x000000100000-0x000000140000 : "0:BOOTCONFIG"
kern.notice kernel: [    2.432979] 0x000000140000-0x000000180000 : "0:BOOTCONFIG1"
kern.notice kernel: [    2.438394] 0x000000180000-0x000000280000 : "0:QSEE"
kern.notice kernel: [    2.444429] 0x000000280000-0x0000002c0000 : "0:DEVCFG"
kern.notice kernel: [    2.448901] 0x0000002c0000-0x000000300000 : "0:CDT"
kern.notice kernel: [    2.453938] 0x000000300000-0x000000380000 : "0:APPSBLENV"
kern.notice kernel: [    2.458868] 0x000000380000-0x0000004c0000 : "0:APPSBL"
kern.notice kernel: [    2.465037] 0x0000004c0000-0x000000600000 : "0:APPSBL_1"
kern.notice kernel: [    2.470013] 0x000000600000-0x000000700000 : "0:ART"
kern.notice kernel: [    2.475367] 0x000000700000-0x000000780000 : "0:TRAINING"
kern.notice kernel: [    2.479542] 0x000000780000-0x0000007c0000 : "bdinfo"
kern.notice kernel: [    2.484965] 0x0000007c0000-0x000002bc0000 : "rootfs_1"
kern.notice kernel: [    2.515966] 0x000002bc0000-0x000004fc0000 : "rootfs"
kern.notice kernel: [    2.543245] mtd: device 14 (rootfs) set to be root filesystem
kern.alert kernel: [    2.543493] mtdsplit: no squashfs found in "rootfs"
lspci -vvv
00:00.0 PCI bridge: Qualcomm Device 1004 (prog-if 00 [Normal decode])
	Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx-
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Region 0: Memory at 80700000 (64-bit, non-prefetchable) [size=4K]
	Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
	I/O behind bridge: 00001000-00001fff [size=4K]
	Memory behind bridge: 80300000-804fffff [size=2M]
	Prefetchable memory behind bridge: 80500000-806fffff [size=2M]
	Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
	BridgeCtl: Parity+ SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
		PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
	Capabilities: [40] Power Management version 3
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
		Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [50] MSI: Enable- Count=1/32 Maskable+ 64bit+
		Address: 0000000000000000  Data: 0000
		Masking: 00000000  Pending: 00000000
	Capabilities: [70] Express (v2) Root Port (Slot+), MSI 00
		DevCap:	MaxPayload 128 bytes, PhantFunc 0
			ExtTag- RBE+
		DevCtl:	Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
			RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
			MaxPayload 128 bytes, MaxReadReq 256 bytes
		DevSta:	CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
		LnkCap:	Port #0, Speed 8GT/s, Width x1, ASPM not supported
			ClockPM- Surprise- LLActRep+ BwNot- ASPMOptComp+
		LnkCtl:	ASPM Disabled; RCB 128 bytes Disabled- CommClk-
			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
		LnkSta:	Speed 5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
		SltCap:	AttnBtn+ PwrCtrl+ MRL+ AttnInd+ PwrInd+ HotPlug+ Surprise+
			Slot #0, PowerLimit 25.000W; Interlock+ NoCompl-
		SltCtl:	Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
			Control: AttnInd Off, PwrInd Off, Power- Interlock-
		SltSta:	Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
			Changed: MRL- PresDet- LinkState-
		RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
		RootCap: CRSVisible-
		RootSta: PME ReqID 0000, PMEStatus- PMEPending-
		DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR+, OBFF Not Supported ARIFwd-
			 AtomicOpsCap: Routing- 32bit- 64bit- 128bitCAS-
		DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis+, LTR-, OBFF Disabled ARIFwd-
			 AtomicOpsCtl: ReqEn- EgressBlck-
		LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
			 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
			 Compliance De-emphasis: -6dB
		LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
			 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
	Capabilities: [100 v2] Advanced Error Reporting
		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UESvrt:	DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
		AERCap:	First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
			MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
		HeaderLog: 00000000 00000000 00000000 00000000
		RootCmd: CERptEn- NFERptEn- FERptEn-
		RootSta: CERcvd- MultCERcvd- UERcvd- MultUERcvd-
			 FirstFatal- NonFatalMsg- FatalMsg- IntMsg 0
		ErrorSrc: ERR_COR: 0000 ERR_FATAL/NONFATAL: 0000
	Capabilities: [148 v1] #19
	Capabilities: [168 v1] Transaction Processing Hints
		No steering table available
	Capabilities: [1fc v1] L1 PM Substates
		L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
			  PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
		L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
			   T_CommonMode=0us LTR1.2_Threshold=0ns
		L1SubCtl2: T_PwrOn=10us

01:00.0 Unassigned class [ff00]: Qualcomm Device 0308
	Subsystem: Qualcomm Device 0308
	Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr+ Stepping- SERR+ FastB2B- DisINTx+
	Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
	Latency: 0, Cache Line Size: 64 bytes
	Interrupt: pin ? routed to IRQ 89
	Region 0: Memory at 80300000 (64-bit, non-prefetchable) [size=4K]
	Region 2: Memory at 80301000 (64-bit, non-prefetchable) [size=4K]
	Capabilities: [40] Power Management version 3
		Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
		Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
	Capabilities: [50] MSI: Enable+ Count=4/32 Maskable+ 64bit+
		Address: 000000000b00b040  Data: 01e0
		Masking: ffffffff  Pending: 00000000
	Capabilities: [70] Express (v2) Endpoint, MSI 00
		DevCap:	MaxPayload 256 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
			ExtTag- AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 25.000W
		DevCtl:	Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
			RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
			MaxPayload 128 bytes, MaxReadReq 256 bytes
		DevSta:	CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
		LnkCap:	Port #0, Speed 16GT/s, Width x2, ASPM L0s L1, Exit Latency L0s <4us, L1 <64us
			ClockPM+ Surprise- LLActRep- BwNot- ASPMOptComp+
		LnkCtl:	ASPM Disabled; RCB 64 bytes Disabled- CommClk-
			ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
		LnkSta:	Speed 5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
		DevCap2: Completion Timeout: Range ABCD, TimeoutDis+, LTR+, OBFF Not Supported
			 AtomicOpsCap: 32bit- 64bit- 128bitCAS-
		DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
			 AtomicOpsCtl: ReqEn-
		LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
			 Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
			 Compliance De-emphasis: -6dB
		LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
			 EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
	Capabilities: [100 v2] Advanced Error Reporting
		UESta:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UEMsk:	DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
		UESvrt:	DLP+ SDES+ TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
		CESta:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
		CEMsk:	RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr+
		AERCap:	First Error Pointer: 00, ECRCGenCap+ ECRCGenEn- ECRCChkCap+ ECRCChkEn-
			MultHdrRecCap- MultHdrRecEn- TLPPfxPres- HdrLogCap-
		HeaderLog: 00000000 00000000 00000000 00000000
	Capabilities: [148 v1] #19
	Capabilities: [168 v1] #26
	Capabilities: [18c v1] #27
	Capabilities: [19c v1] Transaction Processing Hints
		No steering table available
	Capabilities: [228 v1] Latency Tolerance Reporting
		Max snoop latency: 0ns
		Max no snoop latency: 0ns
	Capabilities: [230 v1] L1 PM Substates
		L1SubCap: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ L1_PM_Substates+
			  PortCommonModeRestoreTime=70us PortTPowerOnTime=0us
		L1SubCtl1: PCI-PM_L1.2- PCI-PM_L1.1- ASPM_L1.2- ASPM_L1.1-
			   T_CommonMode=0us LTR1.2_Threshold=0ns
		L1SubCtl2: T_PwrOn=10us
	Capabilities: [240 v1] #25
	Kernel driver in use: mhi_q
lsusb -vvv
Bus 001 Device 002: ID 2c7c:0801
Bus 001 Device 001: ID 1d6b:0002
Bus 002 Device 001: ID 1d6b:0003

Now, how do I go about writing the DTS for this device without having to completely dismantle the device and actually looking at the components?
I did look at the commits for other ipq50xx devices and the DTS in the OEM GPL archive (located at openwrt/18.06/target/linux/ipq/ipq50xx/R72/qcom-ipq5018-mp03.3.dts) and they look very different, with the OEM one having lots of information.
How do I determine what is the minimum information I need to put in the DTS to get OpenWrt to boot and what would need to be added to get different components (ethernet switch, 2.4G WiFi, 5G WiFi, NR modem, NPU etc.) working?

1 Like

Any chance of you posting the dmesg?

This device should be easy to port to openwrt, not sure about the 5G modem though.
The output of dmesg would be useful as well as the fdt file located at /sys/firmware/

1 Like