Adding OpenWrt support for Xiaomi AX3600 (Part 1)

Thanks. The firmware I created your tool, installed just fine :slight_smile:

Iv hit a bit of a block, i have tried to enable the pcie bus and related phys devices.

When enabling the qmp phys device alone everything works as expected

[    0.296010] qcom-qmp-phy 86000.phy: Registered Qcom-QMP phy

However when building the qcom pcie driver the kernel never logs after hand over from uboot (followed by a reset)

ipq807x_eth_init: done
Using eth0 device
TFTP from server 192.168.31.100; our IP address is 192.168.31.1
Filename 'openwrt-ipq807x-xiaomi_ax3600-initramfs-fit-uImage.itb'.
Load address: 0x44000000
Loading: *
Got TFTP_OACK: TFTP remote port: changes from 69 to 60590
#################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         #################################################################
         ############################################################
         4.9 MiB/s
done
Bytes transferred = 6593852 (649d3c hex)
ipq807x_eth_halt: done
IPQ807x# bootm
## Loading kernel from FIT Image at 44000000 ...
   Using 'config@1' configuration
   Trying 'kernel@1' kernel subimage
     Description:  ARM64 OpenWrt Linux-5.4.48
     Type:         Kernel Image
     Compression:  gzip compressed
     Data Start:   0x440000e8
     Data Size:    6580661 Bytes = 6.3 MiB
     Architecture: AArch64
     OS:           Linux
     Load Address: 0x41080000
     Entry Point:  0x41080000
     Hash algo:    crc32
     Hash value:   5a1989e1
     Hash algo:    sha1
     Hash value:   a2921e6d17ddccf5cb21393f9763cdab79d15661
   Verifying Hash Integrity ... crc32+ sha1+ OK
## Loading fdt from FIT Image at 44000000 ...
   Using 'config@1' configuration
   Trying 'fdt@1' fdt subimage
     Description:  ARM64 OpenWrt xiaomi_ax3600 device tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x44646be0
     Data Size:    11301 Bytes = 11 KiB
     Architecture: AArch64
     Hash algo:    crc32
     Hash value:   5733b418
     Hash algo:    sha1
     Hash value:   26959c5cd4f805b3c45b03b75e4fef5d92ef01bb
   Verifying Hash Integrity ... crc32+ sha1+ OK
   Booting using the fdt blob at 0x44646be0
   Uncompressing Kernel Image ... OK
   Loading Device Tree to 4a3fa000, end 4a3ffc24 ... OK
Using machid 0x8010010 from environment

Starting kernel ...

Jumping to AARCH64 kernel via monitor

Format: Log Type - Time(microsec) - Message - Optional Info
Log Type: B - Since Boot(Power On Reset),  D - Delta,  S - Statistic
S - QC_IMAGE_VERSION_STRING=BOOT.BF.3.3.1-00147
S - IMAGE_VARIANT_STRING=HAACANAZA
S - OEM_IMAGE_VERSION_STRING=CRM
S - Boot Config, 0x000002e5
B -       201 - PBL, Start

Not really sure how to debug this one as I do not get any logs about the failure.

Also worth saying this happens whenever enabling the qcom pcie driver, even if the pcie device(s) are disabled in DTS

I have also back ported this patch set with the same results : https://lkml.org/lkml/2020/7/5/77

Any ideas on how to proceed with this would be amazing.

Awesome... Thanks for your reply mate.

www.baidu.com
www.taobao.com
api.miwifi.com
broker.miwifi.com

Currently using it as an AP on original firmware.
My AdGuard Home log is totally inundated with the above connection attempts (blocked obviously).
Someone please jailbreak this thing!!

Was able to see the PCIE crash after switching on earlycon (logs below)

[    0.526707] qcom-qmp-phy 86000.phy: Registered Qcom-QMP phy
[    0.526829] qcom-qmp-phy 8e000.phy: Registered Qcom-QMP phy
[    0.531702] qcom-pcie 20000000.pci: host bridge /soc/pci@20000000 ranges:
[    0.536681] qcom-pcie 20000000.pci:    IO 0x20200000..0x202fffff -> 0x20200000
[    0.543611] qcom-pcie 20000000.pci:   MEM 0x20300000..0x20ffffff -> 0x20300000
[    0.557375] Unable to handle kernel write to read-only memory at virtual address ffffffc01032d008
[    0.557905] Mem abort info:
[    0.566851]   ESR = 0x9600004e
[    0.569450]   EC = 0x25: DABT (current EL), IL = 32 bits
[    0.572578]   SET = 0, FnV = 0
[    0.578041]   EA = 0, S1PTW = 0
[    0.580904] Data abort info:
[    0.583943]   ISV = 0, ISS = 0x0000004e
[    0.587070]   CM = 0, WnR = 1
[    0.590621] swapper pgtable: 4k pages, 39-bit VAs, pgdp=0000000041929000
[    0.593762] [ffffffc01032d008] pgd=000000005ffff003, pud=000000005ffff003, pmd=0040000041200791
[    0.600538] Internal error: Oops: 9600004e [#1] PREEMPT SMP
[    0.608940] Modules linked in:
[    0.614496] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 5.4.48 #0
[    0.617620] Hardware name: AX3600 (DT)
[    0.623436] pstate: 60400005 (nZCv daif +PAN -UAO)
[    0.627263] pc : dw_pcie_write+0x44/0x78
[    0.632030] lr : dw_pcie_write_atu+0x50/0x78
[    0.636108] sp : ffffffc01002ba50
[    0.640359] x29: ffffffc01002ba50 x28: ffffffc0108b1eb0 
[    0.643576] x27: ffffff801fef9040 x26: 0000000000000000 
[    0.648957] x25: 0000000000000000 x24: 0000000000000000 
[    0.654251] x23: 0000000000000000 x22: 0000000020300000 
[    0.659546] x21: ffffff801eb43880 x20: 0000000020300000 
[    0.664842] x19: ffffff801eb43880 x18: 000000000000000e 
[    0.670137] x17: 0000000000000001 x16: 0000000000000019 
[    0.675433] x15: ffffffffffffffff x14: 0000000000000000 
[    0.680727] x13: 0000000000000000 x12: 0000000000000000 
[    0.686021] x11: 0000000000000003 x10: 0101010101010101 
[    0.691318] x9 : fffffffffffffffd x8 : 7f7f7f7f7f7f7f7f 
[    0.696612] x7 : 0000000000000008 x6 : ffffffc01032d000 
[    0.701908] x5 : 0000000000000000 x4 : 0000000020300000 
[    0.707203] x3 : 0000000000000003 x2 : 0000000020300000 
[    0.712498] x1 : 0000000000000004 x0 : ffffffc01032d008 
[    0.717794] Call trace:
[    0.723086]  dw_pcie_write+0x44/0x78
[    0.725258]  dw_pcie_prog_outbound_atu+0x180/0x240
[    0.729080]  dw_pcie_setup_rc+0x234/0x268
[    0.733680]  qcom_pcie_host_init+0x94/0x150
[    0.737758]  dw_pcie_host_init+0x238/0x5a8
[    0.741752]  qcom_pcie_probe+0x1dc/0x218
[    0.745920]  platform_drv_probe+0x50/0xa0
[    0.750001]  really_probe+0xd8/0x2f8
[    0.753905]  driver_probe_device+0x54/0xe8
[    0.757549]  device_driver_attach+0x6c/0x78
[    0.761455]  __driver_attach+0x54/0xd0
[    0.765536]  bus_for_each_dev+0x60/0x98
[    0.769355]  driver_attach+0x20/0x28
[    0.773088]  bus_add_driver+0x178/0x1d8
[    0.776906]  driver_register+0x60/0x110
[    0.780466]  __platform_driver_register+0x44/0x50
[    0.784290]  qcom_pcie_driver_init+0x18/0x20
[    0.789149]  do_one_initcall+0x74/0x1b0
[    0.793489]  kernel_init_freeable+0x190/0x224
[    0.797048]  kernel_init+0x10/0xfc
[    0.801560]  ret_from_fork+0x10/0x18
[    0.804867] Code: 52800001 2a0103e0 d65f03c0 d50332bf (b9000002) 
[    0.808601] ---[ end trace 4d0377d1902fd94e ]---
[    0.814583] Kernel panic - not syncing: Fatal exception
[    0.819274] SMP: stopping secondary CPUs
[    0.824219] Kernel Offset: disabled
[    0.828382] CPU features: 0x0002,20002004
[    0.831592] Memory Limit: none
[    0.835762] Rebooting in 5 seconds..

Any ideas would be amazing :smiley:

1 Like

My AX3600 just arrived.. ordered on April 23, by foot from China to Portugal certainly :D...

1 Like

Progress ! sort of, I have gotten through the above crash and now have the same PCI fault / error as the QSDK firmware.

Stock MiWiFi (Working PCI)

[    0.276346] PCI host bridge /soc/pci@20000000 ranges:
[    0.276374]    IO 0x20200000..0x202fffff -> 0x20200000
[    0.276388]   MEM 0x20300000..0x20ffffff -> 0x20300000
[    0.411911] qcom-pcie 20000000.pci: link up
[    0.412058] qcom-pcie 20000000.pci: PCI host bridge to bus 0000:00
[    0.412072] pci_bus 0000:00: root bus resource [bus 00-ff]
[    0.412085] pci_bus 0000:00: root bus resource [io  0x0000-0xfffff] (bus addr                                                  ess [0x20200000-0x202fffff])
[    0.412099] pci_bus 0000:00: root bus resource [mem 0x20300000-0x20ffffff]
[    0.414035] pci 0000:00:00.0: BAR 8: assigned [mem 0x20300000-0x205fffff]
[    0.414050] pci 0000:00:00.0: BAR 9: assigned [mem 0x20600000-0x207fffff 64bi                                                  t pref]
[    0.414062] pci 0000:00:00.0: BAR 0: assigned [mem 0x20800000-0x20800fff]
[    0.414075] pci 0000:00:00.0: BAR 7: assigned [io  0x1000-0x1fff]
[    0.414091] pci 0000:01:00.0: BAR 0: assigned [mem 0x20400000-0x205fffff 64bi                                                  t]
[    0.414186] pci 0000:01:00.0: BAR 6: assigned [mem 0x20300000-0x2030ffff pref                                                  ]
[    0.414197] pci 0000:00:00.0: PCI bridge to [bus 01]
[    0.414207] pci 0000:00:00.0:   bridge window [io  0x1000-0x1fff]
[    0.414219] pci 0000:00:00.0:   bridge window [mem 0x20300000-0x205fffff]
[    0.414230] pci 0000:00:00.0:   bridge window [mem 0x20600000-0x207fffff 64bi                                                  t pref]

QSDK (Broken PCI)

[    0.314714] PCI host bridge /soc/pci@20000000 ranges:
[    0.314740]    IO 0x20200000..0x2020ffff -> 0x20200000
[    0.314755]   MEM 0x20220000..0x2fffffff -> 0x20220000
[    1.465964] qcom-pcie 20000000.pci: phy link never came up
[    1.467522] qcom-pcie 20000000.pci: hostinit failed
[    1.467531] qcom-pcie 20000000.pci: cannot initialize host
[    1.467676] qcom-pcie: probe of 20000000.pci failed with error -110

Mainline (Broken PCI)

[    0.541027] qcom-pcie 20000000.pci: host bridge /soc/pci@20000000 ranges:
[    0.545672] qcom-pcie 20000000.pci: Parsing ranges property...
[    0.552627] qcom-pcie 20000000.pci:    IO 0x20200000..0x202fffff -> 0x20200000
[    0.558356] qcom-pcie 20000000.pci:   MEM 0x20220000..0x2fffffff -> 0x20220000
[    1.684552] qcom-pcie 20000000.pci: Phy link never came up
[    1.686140] qcom-pcie 20000000.pci: cannot initialize host
[    1.689131] qcom-pcie: probe of 20000000.pci failed with error -110

Getting more and more stuck with this :slight_smile:

@efsg any ideas why the PCI isnt working on the QSDK build ?

3 Likes

Can you explain what you have done between your first non working and your second non working (but equivalent to QSDK) try?
All i see is a different mem range!
Probably the first non working try is the right one as this mem range is also used in MiWiFi...?

Your first non working mem range.

QSDK and Mainline mem range.

MiWiFi mem range.

Sorry yes below is a full break down of how I got to this point.

1st I brought the qcom-pci and qcom-pys-qmp in from the qcom drivers-next trees found here (https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git/) and applied the patch set from https://lkml.org/lkml/2020/7/5/77

2nd on top of those patches also had to fix some of the new clocks to find parents by name to be in line with the rest of the ipq8074 clock drivers (see below) notice that the original patch had pcie0_rchng_clk_src define its number of parents as being 2 while only having one clock at parent_hws

struct freq_tbl ftbl_pcie_rchng_clk_src[] = {
	F(19200000, P_XO, 1, 0, 0),
	F(100000000, P_GPLL0, 8, 0, 0),
	{ }
};

struct clk_rcg2 pcie0_rchng_clk_src = {
	.cmd_rcgr = 0x75070,
	.freq_tbl = ftbl_pcie_rchng_clk_src,
	.hid_width = 5,
	.parent_map = gcc_xo_gpll0_map,
	.clkr.hw.init = &(struct clk_init_data){
		.name = "pcie0_rchng_clk_src",
		.parent_names = gcc_xo_gpll0,
		.num_parents = 2,
		.ops = &clk_rcg2_ops,
	},
};

static struct clk_branch gcc_pcie0_rchng_clk = {
	.halt_reg = 0x75070,
	.halt_bit = 31,
	.clkr = {
		.enable_reg = 0x75070,
		.enable_mask = BIT(1),
		.hw.init = &(struct clk_init_data){
			.name = "gcc_pcie0_rchng_clk",
			.parent_names = (const char *[]){
				"pcie0_rchng_clk_src"
			},
			.num_parents = 1,
			.flags = CLK_SET_RATE_PARENT,
			.ops = &clk_branch2_ops,
		},
	},
};

static struct clk_branch gcc_pcie0_axi_s_bridge_clk = {
	.halt_reg = 0x75048,
	.halt_bit = 31,
	.clkr = {
		.enable_reg = 0x75048,
		.enable_mask = BIT(0),
		.hw.init = &(struct clk_init_data){
			.name = "gcc_pcie0_axi_s_bridge_clk",
			.parent_names = (const char *[]){
				"pcie0_axi_clk_src"
			},
			.num_parents = 1,
			.flags = CLK_SET_RATE_PARENT,
			.ops = &clk_branch2_ops,
		},
	},
};

I have tried matching both mem ranges with no luck, im guessing that the QSDK is from an older build than what MiWiFi is. I would try bringing in the full pci and qys drivers from the latest QSDK tag but that seems like it would be very painful.

2 Likes

Added edma test code.
No switch, no packet send/recv yet.

https://github.com/gmzhuo/openwrt/tree/ax3600

1 Like

Pushed the (non working) PCIe changes to my github so others can have a look at it.

What would be useful is if someone running stock WiWiFi FW that has working PCIE could get the output of cat /sys/kernel/debug/gpio

The one from my current build is below for reference

gpiochip0: GPIOs 442-511, parent: platform/1000000.pinctrl, 1000000.pinctrl:
 gpio0   : in  low  func1 2mA pull down
 gpio1   : in  high func1 8mA no pull
 gpio2   : in  high func1 2mA pull down
 gpio3   : in  high func1 8mA no pull
 gpio4   : in  high func1 8mA no pull
 gpio5   : in  low  func1 8mA no pull
 gpio6   : in  low  func1 8mA no pull
 gpio7   : in  low  func1 8mA no pull
 gpio8   : in  low  func1 8mA no pull
 gpio9   : in  high func1 2mA pull down
 gpio10  : in  high func1 8mA no pull
 gpio11  : in  high func1 8mA no pull
 gpio12  : in  low  func1 8mA no pull
 gpio13  : in  low  func1 8mA no pull
 gpio14  : in  low  func1 8mA no pull
 gpio15  : in  low  func1 8mA no pull
 gpio16  : in  low  func1 8mA no pull
 gpio17  : in  high func1 8mA no pull
 gpio18  : in  low  func0 2mA pull down
 gpio19  : in  low  func0 2mA pull down
 gpio20  : in  low  func0 2mA pull down
 gpio21  : out low  func0 8mA pull down
 gpio22  : out low  func0 8mA pull down
 gpio23  : out low  func2 8mA no pull
 gpio24  : out low  func2 8mA no pull
 gpio25  : in  low  func0 2mA pull down
 gpio26  : in  low  func0 2mA pull down
 gpio27  : in  low  func0 2mA pull down
 gpio28  : in  high func0 2mA pull down
 gpio29  : in  low  func0 2mA pull down
 gpio30  : in  low  func0 2mA pull down
 gpio31  : in  low  func0 2mA pull down
 gpio32  : in  low  func0 2mA pull down
 gpio33  : in  low  func0 2mA pull down
 gpio34  : in  high func0 12mA pull up
 gpio35  : in  low  func0 2mA pull down
 gpio36  : in  high func0 2mA pull down
 gpio37  : out high func0 2mA pull up
 gpio38  : in  low  func3 2mA pull up
 gpio39  : in  high func3 2mA pull up
 gpio40  : in  high func2 2mA pull up
 gpio41  : in  high func2 2mA pull up
 gpio42  : out low  func0 8mA pull down
 gpio43  : out high func0 8mA pull down
 gpio44  : in  low  func1 2mA pull down
 gpio45  : in  high func1 2mA pull down
 gpio46  : in  high func1 8mA no pull
 gpio47  : in  low  func1 8mA no pull
 gpio48  : in  low  func1 8mA no pull
 gpio49  : in  high func1 8mA no pull
 gpio50  : in  low  func0 2mA pull down
 gpio51  : out low  func0 8mA pull down
 gpio52  : out low  func0 2mA pull down
 gpio53  : in  low  func0 2mA pull down
 gpio54  : in  low  func0 2mA pull down
 gpio55  : in  low  func0 2mA pull down
 gpio56  : in  low  func0 2mA pull down
 gpio57  : in  low  func0 2mA pull down
 gpio58  : in  low  func0 2mA pull down
 gpio59  : in  low  func0 2mA pull down
 gpio60  : in  low  func0 2mA pull down
 gpio61  : in  low  func0 2mA pull down
 gpio62  : in  low  func0 2mA pull down
 gpio63  : in  low  func0 2mA pull down
 gpio64  : in  low  func0 2mA pull down
 gpio65  : in  low  func0 2mA pull down
 gpio66  : in  low  func0 2mA pull down
 gpio67  : in  low  func0 2mA pull down
 gpio68  : in  high func1 2mA pull up
 gpio69  : in  high func1 2mA pull up
root@OpenWrt:/# 

root@XiaoQiang:/sys/firmware/devicetree/base/soc/mdio@90000# cat /sys/kernel/debug/gpio
GPIOs 0-69, platform/1000000.pinctrl, 1000000.pinctrl:
gpio0 : in 1 2mA pull down
gpio1 : in 1 8mA no pull
gpio2 : in 1 2mA pull down
gpio3 : in 1 8mA no pull
gpio4 : in 1 8mA no pull
gpio5 : in 1 8mA no pull
gpio6 : in 1 8mA no pull
gpio7 : in 1 8mA no pull
gpio8 : in 1 8mA no pull
gpio9 : in 1 2mA pull down
gpio10 : in 1 8mA no pull
gpio11 : in 1 8mA no pull
gpio12 : in 1 8mA no pull
gpio13 : in 1 8mA no pull
gpio14 : in 1 8mA no pull
gpio15 : in 1 8mA no pull
gpio16 : in 1 2mA pull down
gpio17 : in 1 8mA no pull
gpio18 : in 0 2mA pull down
gpio19 : in 0 2mA pull down
gpio20 : in 0 2mA pull down
gpio21 : out 0 8mA pull down
gpio22 : out 0 8mA pull down
gpio23 : out 2 8mA no pull
gpio24 : out 2 8mA no pull
gpio25 : in 0 2mA pull up
gpio26 : in 0 2mA pull down
gpio27 : in 0 2mA pull down
gpio28 : in 0 2mA pull down
gpio29 : in 0 2mA pull down
gpio30 : in 0 2mA pull down
gpio31 : in 0 2mA pull down
gpio32 : in 0 2mA pull down
gpio33 : in 0 2mA pull down
gpio34 : in 0 8mA pull up
gpio35 : in 0 2mA pull down
gpio36 : in 0 2mA pull down
gpio37 : out 0 2mA pull up
gpio38 : in 3 8mA no pull
gpio39 : in 3 8mA no pull
gpio40 : in 2 8mA no pull
gpio41 : in 2 8mA no pull
gpio42 : out 0 8mA pull down
gpio43 : out 0 8mA pull down
gpio44 : in 0 2mA pull up
gpio45 : in 1 2mA pull down
gpio46 : in 1 8mA no pull
gpio47 : in 1 8mA no pull
gpio48 : in 1 8mA no pull
gpio49 : in 1 8mA no pull
gpio50 : in 0 2mA pull down
gpio51 : out 0 8mA pull down
gpio52 : out 0 2mA pull down
gpio53 : in 0 2mA pull down
gpio54 : in 0 2mA pull down
gpio55 : in 0 2mA pull down
gpio56 : in 0 2mA pull down
gpio57 : in 0 2mA pull down
gpio58 : in 0 2mA pull down
gpio59 : in 0 2mA pull down
gpio60 : in 0 2mA pull down
gpio61 : in 0 2mA pull down
gpio62 : in 0 2mA pull down
gpio63 : in 0 2mA pull down
gpio64 : in 1 6mA pull down
gpio65 : in 1 6mA pull down
gpio66 : in 1 6mA pull down
gpio67 : in 0 2mA pull down
gpio68 : in 1 8mA pull up
gpio69 : in 1 8mA pull up

Thanks, shame there isnt anything that jumps out as wrong for the PCIE reset / wake GPIO's :frowning:

FYI Also tested the ranges from MIWiFi

[    0.531603] qcom-pcie 20000000.pci: host bridge /soc/pci@20000000 ranges:
[    0.536269] qcom-pcie 20000000.pci: Parsing ranges property...
[    0.543224] qcom-pcie 20000000.pci:    IO 0x20200000..0x202fffff -> 0x20200000
[    0.548953] qcom-pcie 20000000.pci:   MEM 0x20300000..0x20ffffff -> 0x20300000
[    1.672501] qcom-pcie 20000000.pci: Phy link never came up
[    1.674087] qcom-pcie 20000000.pci: cannot initialize host

Same thing

I'm confusing that there some "qca8075: ess-switch@c000000" in target/linux/ipq40xx/dts files.
Yes, I found that AVM FRITZ!Box 4040 use switch chip qca8075.
So where's the switch driver for qca8075? Is that use drivers/net/phy/ar40xx.c? or anything else?

Yes it looks to be using the ar40xx driver only.

You know the driver drivers/net/phy/ar40xx.c use local bus, I'm not sure there is a local bus between the SoC and the switch chip qca8075.

I don't think you should define GCC_PCIE0_AXI_S_BRIDGE_CLK as 132

In include/dt-bindings/clock/qcom,gcc-ipq8074.h

#define GCC_USB1_MASTER_CLK                     132
......
#define GCC_PCIE0_AXI_S_BRIDGE_CLK               132

Then in drivers/clk/qcom/gcc-ipq8074.c
[GCC_USB1_MASTER_CLK] = &gcc_usb1_master_clk.clkr,//GCC_USB1_MASTER_CLK = 132
......
[GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr,//GCC_USB1_MASTER_CLK = 132

I'm not sure which one will override the another one.

Good spot, I will try change it. But I don't think that's an issue, as there are no complaints about issues looking up clocks by name.

packet comming, but ping failed and can't capture data by tcpdump.

eth2 Link encap:Ethernet HWaddr 86:89:8E:F8:AF:C0
inet addr:192.168.2.130 Bcast:192.168.2.255 Mask:255.255.255.0
inet6 addr: fe80::8489:8eff:fef8:afc0/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:15004 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2226363 (2.1 MiB) TX bytes:0 (0.0 B)
Base address:0x1400