IPQ5018: GLiNET B3000 info

Ok , i think I edited the dts in the build directory but never updated the dts in the src before pushing the code.

use this dts for now

/dts-v1/;

#include "ipq5018.dtsi"
#include "ipq5018-ess.dtsi"

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>

/ {
	model = "GL.iNet B3000, Inc. IPQ5018/AP-MP03.5-C1";
	compatible = "b3000", "glinet,gl-b3000", "qcom,ipq5018-ap-mp03.5-c1", "qcom,ipq5018-mp03.5", "qcom,ipq5018";
	
	interrupt-parent = <&intc>;
	
	aliases {
		serial0 = &blsp1_uart1;
		
		ethernet0 = &dp1;
		ethernet1 = &dp2;
		label-mac-device = &dp2;
		
		led-boot = &led_system_blue;
		led-failsafe = &led_status_white;
		led-running = &led_status_white;
		led-upgrade = &led_system_blue;
	};

	chosen {
		bootargs-append = " root=/dev/ubiblock0_1 swiotlb=1 coherent_pool=2M";
		stdout-path = "serial0:115200n8";
	};
	
	leds {
		compatible = "gpio-leds";
		pinctrl-0 = <&leds_pins>;
		pinctrl-names = "default";

		led_system_blue: led_system_blue {
			label = "led_system_blue";
			gpio = <&tlmm 24 0>;
			default-state = "on";
		};
		
		led_status_white: led_status_white {
			label = "led_status_white";
			gpio = <&tlmm 23 0>;
			default-state = "off";
		};
	};
	
	keys {
		compatible = "gpio-keys";
		pinctrl-0 = <&button_pins>;
		pinctrl-names = "default";

		button_reset {
			label = "reset";
			gpios = <&tlmm 27 GPIO_ACTIVE_LOW>;
			linux,input-type = <EV_KEY>;//<1>;
			linux,code = <KEY_RESTART>;
			debounce-interval = <60>;
		};
	};

	reserved-memory {
		tz_appps@4a400000 {
			no-map;
			reg = <0x0 0x4a400000 0x0 0x400000>;
		};
		
		q6_mem_regions: q6_mem_regions@4b000000 {
			no-map;
			reg = <0x0 0x4b000000 0x0 0x3000000>;
		};
	};
};

&switch {
	status = "okay";

	switch_mac_mode = <MAC_MODE_SGMII_CHANNEL0>;

	qcom,port_phyinfo {
		// MAC0 -> GE Phy -> QCA8337 Phy2
		port@0 {
			port_id = <1>;
			mdiobus = <&mdio0>;
			phy_address = <7>;
			phy_dac = <0x10 0x10>;
			// status = "disabled";
		};

		// MAC1 ---SGMII---> QCA8337 SerDes
		port@1 {
			port_id = <2>;
			forced-speed = <1000>;
			forced-duplex = <1>;
		};
	};
};

// MAC0 -> GE Phy
&dp1 {
	/*
	 * ===============================================================
	 *     _______________________         _______________________
	 *    |        IPQ5018        |       |        QCA8337        |
	 *    | +------+   +--------+ |       | +--------+   +------+ |
	 *    | | MAC0 |---| GE Phy |-+--UTP--+-|  Phy4  |---| MAC5 | |
	 *    | +------+   +--------+ |       | +--------+   +------+ |
	 *    | +------+   +--------+ |       | +--------+   +------+ |
	 *    | | MAC1 |---| Uniphy |-+-SGMII-+-| SerDes |---| MAC0 | |
	 *    | +------+   +--------+ |       | +--------+   +------+ |
	 *    |_______________________|       |_______________________|
	 *
	 * ===============================================================
	 *
	 * Current drivers don't support such topology. So dp1 and ge_phy
	 * are useless. But they can't be disabled due to qca-ssdk use
	 * ge_phy to detect IPQ5018 dummy switch.
	 */
	
	status = "okay";
};


// MAC1 ---SGMII---> QCA8337 SerDes
&dp2 {
	status = "okay";

	phy-mode = "sgmii";
	nvmem-cells = <&macaddr_dp2>;
	nvmem-cell-names = "mac-address";
	
	
	fixed-link {
		speed = <1000>;
		full-duplex;
	};
};

&mdio0 {
	status = "okay";
};

// IPQ5018 GE Phy -> QCA8337 Phy1
&ge_phy {
	status = "okay";
};

&mdio1 {
	status = "okay";

	pinctrl-0 = <&mdio1_pins>;
	pinctrl-names = "default";
	reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;


	// QCA8337 Phy0 -> WAN
	qca8337_0: ethernet-phy@0 {
		reg = <0>;
	};

	// QCA8337 Phy1 -> LAN1
	qca8337_1: ethernet-phy@1 {
		reg = <1>;
	};


	// QCA8337 Phy3 -> LAN2
	qca8337_2: ethernet-phy@2 {
		reg = <2>;
	};


	// QCA8337 Phy2 -> IPQ5018 GE Phy
	qca8337_3: ethernet-phy@3 {
		reg = <3>;
	};
	
	// QCA8337 Phy4 -> LAN3
	qca8337_4: ethernet-phy@4 {
		reg = <4>;
	};

	// QCA8337 switch
	switch1: ethernet-switch@17 {
		compatible = "qca,qca8337";
		reg = <17>;
		#address-cells = <1>;
		#size-cells = <0>;

		//switch_cpu_bmp = <0x40>;  /* cpu port bitmap */
		//switch_lan_bmp = <0x0c>; /* lan port bitmap */
		//switch_wan_bmp = <0x02>;  /* wan port bitmap */

		ports {
			#address-cells = <1>;
			#size-cells = <0>;
			
			// QCA8337 Phy0 -> WAN
			port@1 {
				reg = <1>;
				label = "wan";
				phy-handle = <&qca8337_0>;
				port_id = <1>;
				phy_address = <0>;
			};
			
			// QCA8337 Phy1 -> LAN1
			port@2 {
				reg = <2>;
				label = "lan1";
				phy-handle = <&qca8337_1>;
				port_id = <2>;
				phy_address = <1>;
			};

			// QCA8337 Phy3 -> LAN2
			port@3 {
				reg = <3>;
				label = "lan2";
				phy-handle = <&qca8337_2>;
				port_id = <3>;
				phy_address = <2>;
				
			};

			// QCA8337 Phy2 -> IPQ5018 GE Phy
			port@4 {
				reg = <4>;
				label = "cpu1";
				phy-handle = <&qca8337_3>;
				port_id = <4>;
				phy_address = <3>;
				status = "disabled";
			};
			
			// N/A
			port@5 {
				reg = <5>;
				label = "lan3";
				phy-handle = <&qca8337_4>;
				status = "disabled";
			};
			
			port@6 {
				reg = <6>;
				label = "cpu";
				phy-mode = "sgmii";
				ethernet = <&dp2>;
				qca,sgmii-enable-pll;

				fixed-link {
					speed = <1000>;
					full-duplex;
				};
			};
		};
	};
};

&sleep_clk {
	clock-frequency = <32000>;
};

&xo_board_clk {
	clock-frequency = <24000000>;
};

&blsp1_uart1 {
	status = "okay";

	pinctrl-0 = <&blsp_uart0_pins>;
	pinctrl-names = "default";
};

&crypto {
	status = "okay";
};

&cryptobam {
	status = "okay";
};

&prng {
	status = "okay";
};

&qfprom {
	status = "okay";
};

&qpic_bam {
	status = "okay";
};

&qpic_nand {
	pinctrl-0 = <&qpic_pins>;
	pinctrl-names = "default";
	status = "okay";

	partitions {
		status = "disabled";
	};

    nand@0 {
        compatible = "spi-nand";
		reg = <0>;
		#address-cells = <1>;
		#size-cells = <1>;

		nand-ecc-engine = <&qpic_nand>;

        nand-ecc-strength = <8>;
        nand-ecc-step-size = <512>;
        nand-bus-width = <8>;

        partitions {
            compatible = "fixed-partitions";
			#address-cells = <1>;
			#size-cells = <1>;

			partition@0 {
				label = "0:SBL1";
				reg = <0x00000000 0x80000>;
				read-only;
			};

            partition@80000 {
				label = "0:MIBIB";
				reg = <0x00080000 0x80000>;
				read-only;
			};

			partition@100000 {
				label = "0:BOOTCONFIG";
				reg = <0x00100000 0x40000>;
				read-only;
			};

            partition@140000 {
				label = "0:QSEE";
				reg = <0x00140000 0x100000>;
				read-only;
			};

            partition@240000 {
				label = "0:DEVCFG";
				reg = <0x00240000 0x40000>;
				read-only;
			};

            partition@280000 {
				label = "0:CDT";
				reg = <0x00280000 0x40000>;
				read-only;
			};

            partition@2c0000 {
				label = "0:APPSBLENV";
				reg = <0x002c0000 0x80000>;
			};

            partition@340000 {
				label = "0:APPSBL";
				reg = <0x00340000 0x140000>;
				read-only;
			};

			partition@480000 {
				label = "0:ART";
				reg = <0x00480000 0x100000>;
				read-only;
				
				nvmem-layout {
					compatible = "fixed-layout";
					#address-cells = <1>;
					#size-cells = <1>;

					macaddr_dp2: macaddr@0 {
						reg = <0x0 0x6>;
					};

				};
			};

            partition@580000 {
				label = "0:TRAINING";
				reg = <0x00580000 0x80000>;
				read-only;
			};

            partition@600000 {
				label = "CFG";
				reg = <0x00600000 0x200000>;
			};

            partition@800000 {
				label = "rootfs";
				reg = <0x00800000 0x7800000>;
			};
        };
    };
};

&tlmm {
	mdio1_pins: mdio-state {
		mdc-pins {
			pins = "gpio36";
			function = "mdc";
			drive-strength = <8>;
			bias-pull-up;
		};

		mdio-pins {
			pins = "gpio37";
			function = "mdio";
			drive-strength = <8>;
			bias-pull-up;
		};
	};
	
	leds_pins: leds_pins {
		led_system_blue {
			pins = "gpio24";
			function = "gpio";
			drive-strength = <8>;
			bias-pull-down;
		};
		
		led_status_white {
			pins = "gpio23";
			function = "gpio";
			drive-strength = <8>;
			bias-pull-down;
		};
	};

	button_pins: button_pins {
		button_reset {
			pins = "gpio27";
			function = "gpio";
			drive-strength = <8>;
			bias-pull-up;
		};
	};
	
	qpic_pins: qpic-state {
		clock-pins {
			pins = "gpio9";
			function = "qspi_clk";
			drive-strength = <8>;
			bias-disable;
		};

		cs-pins {
			pins = "gpio8";
			function = "qspi_cs";
			drive-strength = <8>;
			bias-disable;
		};

		data-pins {
			pins = "gpio4", "gpio5", "gpio6", "gpio7";
			function = "qspi_data";
			drive-strength = <8>;
			bias-disable;
		};
	};

	blsp_uart0_pins: blsp_uart0_pins {
		pins =
			"gpio20", // RX
			"gpio21"; // TX
		function = "blsp0_uart0";
		drive-strength = <8>;
		bias-disable;
	};
};

&tsens {
	status = "okay";
};

&pcie_x2phy {
	status = "disabled";
};

&pcie_x2 {
	status = "disabled";

	perst-gpios = <&tlmm 15 GPIO_ACTIVE_LOW>;
};

&q6v5_wcss {
	status = "okay";

	memory-region = <&q6_mem_regions>;
	firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt",
					"ath11k/IPQ5018/hw1.0/m3_fw.mdt",
					"ath11k/qcn6122/hw1.0/m3_fw.mdt";

	/*TODO: add support for v1 bootargs in mpd driver to control below settings*/
	/*qcom,bootargs_smem = <507>;		hard-coded in mpd driver  */
	/*boot-args = <						*/
			/*       type:	0x1  PCIE0	*/
			/*     length:	4			*/
			/*      PD id:	3			*/
			/* reset GPIO:	15			*/
			/*   reserved:	0 0>;		*/
			/* driver currently doesn't support passing bootargs */

	// IPQ5018
	q6_wcss_pd1: pd-1 {
		firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";

		resets =
			<&gcc GCC_WCSSAON_RESET>,
			<&gcc GCC_WCSS_BCR>,
			<&gcc GCC_CE_BCR>;
		reset-names =
			"wcss_aon_reset",
			"wcss_reset",
			"ce_reset";

		clocks =
			<&gcc GCC_WCSS_AHB_S_CLK>,
			<&gcc GCC_WCSS_ACMT_CLK>,
			<&gcc GCC_WCSS_AXI_M_CLK>;
		clock-names =
			"gcc_wcss_ahb_s_clk",
			"gcc_wcss_acmt_clk",
			"gcc_wcss_axi_m_clk";

		// qcom,halt-regs = <&tcsr_q6_block 0xa000 0xd000 0x0>;
		interrupts-extended =
			<&wcss_smp2p_in 8 0>,
			<&wcss_smp2p_in 9 0>,
			<&wcss_smp2p_in 12 0>,
			<&wcss_smp2p_in 11 0>;
		interrupt-names =
			"fatal",
			"ready",
			"spawn-ack",
			"stop-ack";

		qcom,smem-states =
			<&wcss_smp2p_out 8>,
			<&wcss_smp2p_out 9>,
			<&wcss_smp2p_out 10>;
		qcom,smem-state-names =
			"shutdown",
			"stop",
			"spawn";
		status = "okay";
	};

	// QCN6102 6G
	q6_wcss_pd2: pd-2 {
		firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";

		interrupts-extended =
			<&wcss_smp2p_in 16 0>,
			<&wcss_smp2p_in 17 0>,
			<&wcss_smp2p_in 20 0>,
			<&wcss_smp2p_in 19 0>;
		interrupt-names =
			"fatal",
			"ready",
			"spawn-ack",
			"stop-ack";

		qcom,smem-states =
			<&wcss_smp2p_out 16>,
			<&wcss_smp2p_out 17>,
			<&wcss_smp2p_out 18>;
		qcom,smem-state-names =
			"shutdown",
			"stop",
			"spawn";
		status = "disabled";
	};

	// QCN6102 5G
	q6_wcss_pd3: pd-3 {
		firmware-name = "ath11k/IPQ5018/hw1.0/q6_fw.mdt";

		interrupts-extended =
			<&wcss_smp2p_in 24 0>,
			<&wcss_smp2p_in 25 0>,
			<&wcss_smp2p_in 28 0>,
			<&wcss_smp2p_in 27 0>;
		interrupt-names =
			"fatal",
			"ready",
			"spawn-ack",
			"stop-ack";

		qcom,smem-states =
			<&wcss_smp2p_out 24>,
			<&wcss_smp2p_out 25>,
			<&wcss_smp2p_out 26>;
		qcom,smem-state-names =
			"shutdown",
			"stop",
			"spawn";
		status = "okay";
	};
};

&wifi0 {
	// IPQ5018
	qcom,rproc = <&q6_wcss_pd1>;
	qcom,userpd-subsys-name = "q6v5_wcss_userpd1";

	// Can be overridden by /etc/hotplug.d/firmware/10-ath11k-board_id
	//qcom,board_id = <0x23>;

	qcom,ath11k-calibration-variant = "GL-iNet-GL-B3000";
	qcom,ath11k-fw-memory-mode = <2>;
	qcom,bdf-addr = <0x4c400000>;

	status = "okay";
};

&wifi1 {
	// QCN6102 5G
	qcom,rproc = <&q6_wcss_pd3>;
	qcom,userpd-subsys-name = "q6v5_wcss_userpd3";

	// Can be overridden by /etc/hotplug.d/firmware/10-ath11k-board_id
	//qcom,board_id = <0x60>;

	qcom,ath11k-calibration-variant = "GL-iNet-GL-B3000";
	qcom,ath11k-fw-memory-mode = <2>;
	qcom,bdf-addr = <0x4d100000>;
	qcom,m3-dump-addr = <0x4df00000>;

	status = "okay";
};

I will push the updated dts to the repo when i get a change

Damn, I ran out of space on my VM :man_facepalming:

1 Like

yah I am pushing the limits on 1 tb. i have a few build systems and many projects on the drive, but mostly openwrt related stuff

Is there anything in the sources I can delete, without compromising the build process?
Any unrelated folders?
Like maybe other platforms?

Yay, so I disabled swap, delete swap file and was able to complete the build.
Shall I check images folder now for the resulting build?

images will be in

~/openwrt-pr/bin/targets/qualcommax/ipq50xx/

Hmm, the resulting files are fairly small.
They are ~13.5-14 MB.
I believe your images that I have currently flashed are quite a bit bigger?
I compiled just the basic stuff, the openwrt with default stuff and Luci and nothing else.
Did I miss some packages?

no, nothing mandatory anyway. I added luci-app-ttyd for console from luci, and I am doing some work on the luci acl (user manager) package, so it's included in my builds as well.

FYI, US Amazon and gl.inet are currently selling these at $45.

https://www.amazon.com/gp/product/B0D7PTFZZM

1 Like

£41.90 from Amazon UK:
https://www.amazon.co.uk/GL-iNet-GL-B3000-Wall-Mountable-Dual-Band-WireGuard/dp/B0D7PTFZZM

1 Like

price have now dropped to $40.

I couldn't resist. I just grabbed 2 additional units, for less than the cost of the original unit :+1:

2 Likes

@Hostle
Do you have a sysupgrade .img available?
I've got one here but not got time to setup and build an image for it.

Is there a link to a link to a PR yet?

Images are on my repo. The .img file for flashing from stock glinet to openwrt is here -->

Just waiting on the initial ipq50xx and wifi support pr to be merged. Work is still being finalized on the ath11k driver i believe. In the meantime, I am picking away at the nss support.

@Hostle Thanks for your efforts!

Should that also work from the stock uboot webui? This seems to be true for all other GL-inet devices (and I have tried almost all at some time or another), or is there something I am missing?

no uboot webui recovery is not necessary. Just flash it from the glinet webui -->upgrade --> local upgrade

I have not tried to flash the openwrt .img file using uboot, I suspect it would fail the partition check as the wifi partition is not present,

Well it isn't just for recovery. IMO it is necessary. I would ultimately want to roll out numbers of them and the uboot webui is perfect for this. A low grade tech can start a reflash with the webui in a few seconds.
As I said, it works with the uboot webui and sysupgrade.img on all the gl-inet models I have had to work with so far.
Usually using a custom image generated by imagebuilder.
Examples:
MT6000
MT3000
MT1300
A1300
B1300
MT300N-V2
AR300M
plus more of the older models.

Can this be fixed?

1 Like

I think you miss understood. The uboot recovery (as it is named) is still functional. It can be used with the ginet stock .img file of your choice. It can also be used to recover from a bad flash or what have you. However, as I mentioned, it is not necessary to switch to openwrt from stock glinet firmware ...or vice versa for that matter. Simply flash the openwrt .img file i pointed you to, from the stock glinet firmware upgrade. Then in openwrt, sysuopgrade as needed. To switch back to glinet firmware, you have 2 options.

Option 1 flash the glinet .ubi file found in this thread, from luci firmware upgrade.

Option 2 use uboot recovery to flash stock .img file from vendor or otherwise

One could edit the flash script to skip the check for wifi partitioin very easy. But I will not, I don't like to mess with uboot until its the only option, the consequences are far more severe than a failed sysupgrade. The sources are on the repo, feel free to compile your own custom image with this mod if you prefer. Myself, I would not recommend it, until its the only method of recovery ...hence the name

No, not really, I have not miss understood. Yes it can be used for recovery, but its name is "Firmware Update", as can be seen from a screenshot taken from the B3000 I have here for testing:

It was flashed with a non-openwrt derived firmware using the uboot-webui and it can be flashed back to the original gl-inet firmware also using the uboot-webui.

An example of how it is used - Recently I needed to flash a batch of 30 MT3000s. On a workbench, doing 5 at a time, it took less than 10 minutes to do them all using a single laptop to kick them off.

Having to boot into oem firmware, do the firstboot setup, then transfer the image file takes about 5+ minutes each.

In addition, if you really do need recovery, are you saying you need to flash the ubi file using uboot-webui? I don't think it accepts ubi files does it?
I tried it just now and it booted back up unchanged. But If I flash the standard oem openwrt-b3000-4.5.19-0826-1724667664.img with uboot-webui it goes back to oem. Screenshot:

Your work is very much appreciated, but perhaps have you missed something?
Or is this a result of the way ipq5018 support has been developed?

1 Like

Actually its called uboot failsafe ... from the horses mouth.

And as i said, I have not tested the openwrt .img file with uboot failsafe. It may very well work. I don't see the need to use it, when i can switch back and forth from respective webui's (luci or glinet) firmware upgrades options, with all the safety features designed for this specific task. I use uboot only if necessary , as my safety net if you will. But if you ever have a uboot update interrupted or fail at the wrong spot and end up with a paper weight or jtag adventure at minimum, perhaps you'll appreciate the good old sysupgrade the way I do.

If you feel i missed something, the sources are here -->