Compare commits
10 Commits
3ad9b58fbf
...
8dfae1f922
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dfae1f922 | |||
| 3bb2e28f43 | |||
| 1ed56ddff1 | |||
| c17f987cf9 | |||
| 088b5eb52c | |||
| 68eceded45 | |||
| e88d27b264 | |||
| 9a2e403f67 | |||
| c9b4ef916a | |||
| cf7f16b5cc |
@ -45,237 +45,195 @@
|
|||||||
mtd9 = &rootfs_1_part;
|
mtd9 = &rootfs_1_part;
|
||||||
mtd10 = &overlay_part;
|
mtd10 = &overlay_part;
|
||||||
};
|
};
|
||||||
};
|
}; /* end of root block */
|
||||||
/* end of root block */
|
|
||||||
|
|
||||||
|
/* EDMA — the CPU-facing ethernet, both switches connect here */
|
||||||
&gmac {
|
&gmac {
|
||||||
/* ipqess upstream node — flat, no gmac children */
|
status = "okay";
|
||||||
status = "okay";
|
phy-mode = "internal";
|
||||||
|
/* dual-GMAC: RRD port-id 5 = GMAC1 = QCA8337 switch */
|
||||||
/* All vendor-only props stripped; driver ignores them */
|
qcom,gmac1-port = <5>;
|
||||||
phy-mode = "internal";
|
fixed-link {
|
||||||
fixed-link {
|
speed = <1000>;
|
||||||
speed = <1000>;
|
full-duplex;
|
||||||
full-duplex;
|
pause;
|
||||||
};
|
};
|
||||||
};
|
}; /* end of gmac */
|
||||||
|
|
||||||
&mdio {
|
|
||||||
status = "okay";
|
|
||||||
pinctrl-0 = <&mdio_pins>;
|
|
||||||
pinctrl-names = "default";
|
|
||||||
|
|
||||||
/*
|
|
||||||
* DELETE the upstream qca8075-package@0 node.
|
|
||||||
* Upstream qcom-ipq4019.dtsi defines the package at reg=<0> (addresses 0-4).
|
|
||||||
* Our board hardware-straps QCA8075 to MDIO addresses 8-12.
|
|
||||||
* Without this delete, the driver probes addresses 0-5 and panics on missing addr 5.
|
|
||||||
*/
|
|
||||||
/delete-node/ ethernet-phy-package@0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* QCA8075: 5-port PHY package.
|
|
||||||
* Board hardware-straps the MDIO base address to 8.
|
|
||||||
* PHYs at addresses 8-12, PSGMII calibration PHY implicit at base+5=13.
|
|
||||||
* The qcom,qca8075-package driver handles PSGMII bring-up internally.
|
|
||||||
* tx-drive-strength-milliwatt = 300 per IPQ4019 reference design spec.
|
|
||||||
*/
|
|
||||||
ethernet-phy-package@8 {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
compatible = "qcom,qca8075-package";
|
|
||||||
reg = <8>;
|
|
||||||
qcom,tx-drive-strength-milliwatt = <300>;
|
|
||||||
|
|
||||||
ethphy8: ethernet-phy@8 { reg = <8>; }; /* WAN1 */
|
|
||||||
ethphy9: ethernet-phy@9 { reg = <9>; }; /* WAN2 */
|
|
||||||
ethphy10: ethernet-phy@10 { reg = <10>; }; /* LAN1 */
|
|
||||||
ethphy11: ethernet-phy@11 { reg = <11>; }; /* LAN2 */
|
|
||||||
ethphy12: ethernet-phy@12 { reg = <12>; }; /* LAN3 / combo */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* QCA8337: standalone DSA switch.
|
|
||||||
* Connected via RGMII fixed-link DIRECTLY to gmac1 (eth1).
|
|
||||||
* This is NOT cascaded through the ESS — it is a sibling switch
|
|
||||||
* on a completely independent MAC. MDIO address 0x10 on the
|
|
||||||
* shared MDIO bus for management access only.
|
|
||||||
*/
|
|
||||||
qca8337: switch@10 {
|
|
||||||
compatible = "qca,qca8337";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
reg = <0x10>;
|
|
||||||
|
|
||||||
dsa,member = <1 0>;
|
|
||||||
|
|
||||||
ports {
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
extport0: port@0 {
|
|
||||||
reg = <0>;
|
|
||||||
label = "cpu";
|
|
||||||
phy-mode = "rgmii";
|
|
||||||
ethernet = <&swport5>;
|
|
||||||
fixed-link {
|
|
||||||
speed = <1000>;
|
|
||||||
full-duplex;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@1 {
|
|
||||||
reg = <1>;
|
|
||||||
label = "lan3";
|
|
||||||
phy-mode = "gmii"; /* WAS: "internal" — that triggers PHY lookup → NULL → crash */
|
|
||||||
fixed-link {
|
|
||||||
speed = <1000>;
|
|
||||||
full-duplex;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@2 {
|
|
||||||
reg = <2>;
|
|
||||||
label = "lan4";
|
|
||||||
phy-mode = "gmii"; /* WAS: "internal" */
|
|
||||||
fixed-link {
|
|
||||||
speed = <1000>;
|
|
||||||
full-duplex;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@3 {
|
|
||||||
reg = <3>;
|
|
||||||
label = "lan5";
|
|
||||||
phy-mode = "gmii"; /* WAS: "internal" */
|
|
||||||
fixed-link {
|
|
||||||
speed = <1000>;
|
|
||||||
full-duplex;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@4 {
|
|
||||||
reg = <4>;
|
|
||||||
label = "lan6";
|
|
||||||
phy-mode = "gmii"; /* WAS: "internal" */
|
|
||||||
fixed-link {
|
|
||||||
speed = <1000>;
|
|
||||||
full-duplex;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@5 {
|
|
||||||
reg = <5>;
|
|
||||||
label = "lan7";
|
|
||||||
phy-mode = "gmii"; /* WAS: "internal" */
|
|
||||||
fixed-link {
|
|
||||||
speed = <1000>;
|
|
||||||
full-duplex;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
port@6 {
|
|
||||||
reg = <6>;
|
|
||||||
label = "lan8";
|
|
||||||
phy-mode = "gmii"; /* WAS: "sgmii" — this is a copper port */
|
|
||||||
fixed-link {
|
|
||||||
speed = <1000>;
|
|
||||||
full-duplex;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* QCA8337 internal MDIO bus.
|
|
||||||
* PHY addresses 0-4 are LOCAL to the switch — do not confuse
|
|
||||||
* with the top-level MDIO bus where QCA8075 lives at 8-12.
|
|
||||||
*/
|
|
||||||
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
/* TOP SWITCH: ESS built-in (QCA8075 via PSGMII) at c000000 */
|
||||||
|
/* compatible MUST be qca,ipq4019-qca8337n — this is what ran on the device */
|
||||||
&switch {
|
&switch {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
compatible = "qca,ipq4019-qca8337n";
|
||||||
dsa,member = <0 0>;
|
|
||||||
|
|
||||||
mdio-bus = <&mdio>;
|
|
||||||
//qca,mdio = <&mdio>; //alternative if above not work
|
|
||||||
|
|
||||||
/*
|
mdio-bus = <&mdio>;
|
||||||
* psgmii-ethphy points to the last PHY in the QCA8075 package (ethphy12).
|
psgmii-ethphy = <ðphy12>; /* reg=0x0c, the cal PHY at base+4 */
|
||||||
* This is the combo port and serves as the PSGMII calibration PHY.
|
|
||||||
* The qca8075-package driver uses this for SerDes bring-up sequencing.
|
|
||||||
*/
|
|
||||||
psgmii-ethphy = <ðphy12>;
|
|
||||||
|
|
||||||
ports {
|
/delete-node/ ports;
|
||||||
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
swport1: port@1 {
|
ports {
|
||||||
reg = <1>;
|
#address-cells = <1>;
|
||||||
label = "wan1";
|
#size-cells = <0>;
|
||||||
phy-handle = <ðphy8>;
|
|
||||||
phy-mode = "psgmii";
|
|
||||||
status = "okay";
|
|
||||||
};
|
|
||||||
|
|
||||||
swport2: port@2 {
|
port@0 {
|
||||||
reg = <2>;
|
reg = <0>;
|
||||||
label = "wan2";
|
label = "cpu";
|
||||||
phy-handle = <ðphy9>;
|
ethernet = <&gmac>;
|
||||||
phy-mode = "psgmii";
|
phy-mode = "internal";
|
||||||
status = "okay";
|
fixed-link {
|
||||||
};
|
speed = <1000>;
|
||||||
|
full-duplex;
|
||||||
|
pause;
|
||||||
|
asym-pause;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
swport3: port@3 {
|
port@1 {
|
||||||
reg = <3>;
|
reg = <1>;
|
||||||
label = "lan1";
|
label = "wan1";
|
||||||
phy-handle = <ðphy10>;
|
phy-handle = <ðphy8>;
|
||||||
phy-mode = "psgmii";
|
phy-mode = "psgmii";
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
swport4: port@4 {
|
port@2 {
|
||||||
reg = <4>;
|
reg = <2>;
|
||||||
label = "lan2";
|
label = "wan2";
|
||||||
phy-handle = <ðphy11>;
|
phy-handle = <ðphy9>;
|
||||||
phy-mode = "psgmii";
|
phy-mode = "psgmii";
|
||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
swport5: port@5 {
|
port@3 {
|
||||||
reg = <5>;
|
reg = <3>;
|
||||||
label = "dsa";
|
label = "lan1";
|
||||||
phy-mode = "rgmii";
|
phy-handle = <ðphy10>;
|
||||||
status = "okay";
|
phy-mode = "psgmii";
|
||||||
/delete-property/ phy-handle;
|
status = "okay";
|
||||||
|
};
|
||||||
|
|
||||||
fixed-link {
|
port@4 {
|
||||||
speed = <1000>;
|
reg = <4>;
|
||||||
full-duplex;
|
label = "lan2";
|
||||||
};
|
phy-handle = <ðphy11>;
|
||||||
};
|
phy-mode = "psgmii";
|
||||||
/*
|
status = "okay";
|
||||||
* NO port@6 — valid ESS indices are 0-5 only (num_ports=6).
|
};
|
||||||
* QCA8337 is NOT cascaded here. (?It lives on gmac1 independently?)
|
|
||||||
*/
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
port@5 {
|
||||||
|
reg = <5>;
|
||||||
|
label = "lan3";
|
||||||
|
phy-handle = <ðphy12>; /* same as psgmii-ethphy — cal PHY doubles as port@5 */
|
||||||
|
phy-mode = "psgmii";
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}; /* end of switch (QCA8075) */
|
||||||
|
|
||||||
|
/* MDIO bus — contains QCA8075 package AND QCA8337 bottom switch */
|
||||||
|
&mdio {
|
||||||
|
status = "okay";
|
||||||
|
pinctrl-0 = <&mdio_pins>;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
/delete-node/ ethernet-phy-package@0;
|
||||||
|
|
||||||
|
/* QCA8075: 5-port PHY package, MDIO base addr 8 */
|
||||||
|
ethernet-phy-package@8 {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
compatible = "qcom,qca8075-package";
|
||||||
|
reg = <8>;
|
||||||
|
qcom,tx-drive-strength-milliwatt = <300>;
|
||||||
|
|
||||||
|
ethphy8: ethernet-phy@8 { reg = <8>; }; /* WAN1 */
|
||||||
|
ethphy9: ethernet-phy@9 { reg = <9>; }; /* WAN2 */
|
||||||
|
ethphy10: ethernet-phy@10 { reg = <10>; }; /* LAN1 */
|
||||||
|
ethphy11: ethernet-phy@11 { reg = <11>; }; /* LAN2 */
|
||||||
|
ethphy12: ethernet-phy@12 { reg = <12>; }; /* LAN3 / psgmii cal PHY */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* BOTTOM SWITCH: QCA8337 — side by side, own CPU port pointing to same EDMA */
|
||||||
|
qca8337: switch@10 {
|
||||||
|
compatible = "qca,qca8337";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
reg = <0x10>;
|
||||||
|
|
||||||
|
ports {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
port@0 {
|
||||||
|
reg = <0>;
|
||||||
|
label = "cpu";
|
||||||
|
ethernet = <&gmac>; /* side-by-side: ALSO points to EDMA, not to swport5 */
|
||||||
|
phy-mode = "rgmii";
|
||||||
|
fixed-link {
|
||||||
|
speed = <1000>;
|
||||||
|
full-duplex;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
port@1 {
|
||||||
|
reg = <1>;
|
||||||
|
label = "lan4";
|
||||||
|
phy-mode = "internal";
|
||||||
|
phy-handle = <&qca8337_phy0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
port@2 {
|
||||||
|
reg = <2>;
|
||||||
|
label = "lan5";
|
||||||
|
phy-mode = "internal";
|
||||||
|
phy-handle = <&qca8337_phy1>;
|
||||||
|
|
||||||
|
};
|
||||||
|
port@3 {
|
||||||
|
reg = <3>;
|
||||||
|
label = "lan6";
|
||||||
|
phy-mode = "internal";
|
||||||
|
phy-handle = <&qca8337_phy2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
port@4 {
|
||||||
|
reg = <4>;
|
||||||
|
label = "lan7";
|
||||||
|
phy-mode = "internal";
|
||||||
|
phy-handle = <&qca8337_phy3>;
|
||||||
|
};
|
||||||
|
|
||||||
|
port@5 {
|
||||||
|
reg = <5>;
|
||||||
|
label = "lan8";
|
||||||
|
phy-mode = "internal";
|
||||||
|
phy-handle = <&qca8337_phy4>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* QCA8337 internal MDIO bus — local PHY addresses 0-4 */
|
||||||
|
mdio {
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
qca8337_phy0: ethernet-phy@0 { reg = <0>; };
|
||||||
|
qca8337_phy1: ethernet-phy@1 { reg = <1>; };
|
||||||
|
qca8337_phy2: ethernet-phy@2 { reg = <2>; };
|
||||||
|
qca8337_phy3: ethernet-phy@3 { reg = <3>; };
|
||||||
|
qca8337_phy4: ethernet-phy@4 { reg = <4>; };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}; /* end of &mdio (QCA8075/QCA8337) */
|
||||||
|
|
||||||
|
/* 8MB FLASH CHIP (Macronix MX25L6433F SPI NOR 8MB) */
|
||||||
&blsp1_spi1 {
|
&blsp1_spi1 {
|
||||||
|
|
||||||
/* 8MB FLASH CHIP (Macronix MX25L6433F SPI NOR 8MB) */
|
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
pinctrl-0 = <&spi_0_pinmux>;
|
pinctrl-0 = <&spi_0_pinmux>;
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
|
|
||||||
cs-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>;
|
cs-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>;
|
||||||
|
|
||||||
flash: flash@0 {
|
flash: flash@0 {
|
||||||
|
|
||||||
@ -348,45 +306,43 @@
|
|||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
/* end of &qpic_bam (Micron MT29F1G08ABADA NAND 128MB) */
|
/* end of &qpic_bam (Micron MT29F1G08ABADA NAND 128MB) */
|
||||||
|
|
||||||
/* start of &nand (Micron MT29F1G08ABADA NAND 128MB) */
|
/* start of &nand (Micron MT29F1G08ABADA NAND 128MB) */
|
||||||
&nand {
|
&nand {
|
||||||
status = "disabled";
|
status = "disabled"; /* DISABLED WHILE FIGURING OUT SWITCH CONFIG */
|
||||||
|
|
||||||
/delete-property/ pinctrl-0;
|
/delete-property/ pinctrl-0;
|
||||||
/delete-property/ pinctrl-names;
|
/delete-property/ pinctrl-names;
|
||||||
|
|
||||||
nand@0 {
|
/* REMOVED PINCTRL - NO CONFLICT PLS */
|
||||||
reg = <0>;
|
|
||||||
|
|
||||||
/* Micron MT29F1G08ABADA: 128MB, 8-bit bus, 4-bit ECC */
|
nand@0 {
|
||||||
nand-ecc-strength = <4>;
|
reg = <0>;
|
||||||
nand-ecc-step-size = <512>;
|
|
||||||
nand-bus-width = <8>;
|
|
||||||
|
|
||||||
partitions {
|
nand-ecc-strength = <4>;
|
||||||
compatible = "fixed-partitions";
|
nand-ecc-step-size = <512>;
|
||||||
#address-cells = <1>;
|
nand-bus-width = <8>;
|
||||||
#size-cells = <1>;
|
|
||||||
|
|
||||||
/* Primary boot image: kernel + ubi_rootfs UBI volumes */
|
partitions {
|
||||||
rootfs_part: partition@0 {
|
compatible = "fixed-partitions";
|
||||||
label = "rootfs";
|
#address-cells = <1>;
|
||||||
reg = <0x00000000 0x03000000>; /* 48MB */
|
#size-cells = <1>;
|
||||||
};
|
|
||||||
|
|
||||||
/* Secondary/failsafe boot image: kernel + ubi_rootfs UBI volumes */
|
rootfs_part: partition@0 {
|
||||||
rootfs_1_part: partition@3000000 {
|
label = "rootfs";
|
||||||
label = "rootfs_1";
|
reg = <0x00000000 0x03000000>; /* 48MB */
|
||||||
reg = <0x03000000 0x03000000>; /* 48MB */
|
};
|
||||||
};
|
|
||||||
|
|
||||||
/* Persistent config overlay: rootfs_data UBI volume */
|
rootfs_1_part: partition@3000000 {
|
||||||
overlay_part: partition@6000000 {
|
label = "rootfs_1";
|
||||||
label = "overlay";
|
reg = <0x03000000 0x03000000>; /* 48MB */
|
||||||
reg = <0x06000000 0x02000000>; /* 32MB */
|
};
|
||||||
};
|
|
||||||
};
|
overlay_part: partition@6000000 {
|
||||||
};
|
label = "overlay";
|
||||||
|
reg = <0x06000000 0x02000000>; /* 32MB */
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
/* end of &nand (Micron MT29F1G08ABADA NAND 128MB) */
|
/* end of &nand (Micron MT29F1G08ABADA NAND 128MB) */
|
||||||
|
|
||||||
@ -410,9 +366,15 @@
|
|||||||
|
|
||||||
&tlmm {
|
&tlmm {
|
||||||
|
|
||||||
/* UPSTREAM BLOCKING PINS FOR SWITCHES! MEANS NAND PINS WERE WRONG / NAND WAS BORKED */
|
nand_pins {
|
||||||
/delete-node/ nand_pins;
|
nand-state {
|
||||||
/delete-node/ nand_state;
|
pins = "gpio53", "gpio55", "gpio56", "gpio57", "gpio58",
|
||||||
|
"gpio59", "gpio60", "gpio62", "gpio63", "gpio64",
|
||||||
|
"gpio65", "gpio66", "gpio67", "gpio68", "gpio69";
|
||||||
|
function = "qpic";
|
||||||
|
bias-disable;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/* Add this GPIO Hog for USB Power */
|
/* Add this GPIO Hog for USB Power */
|
||||||
usb_power_en: usb-power-en {
|
usb_power_en: usb-power-en {
|
||||||
@ -422,20 +384,21 @@
|
|||||||
line-name = "usb-power-enable";
|
line-name = "usb-power-enable";
|
||||||
};
|
};
|
||||||
|
|
||||||
mdio_pins: mdio_pinmux {
|
|
||||||
pinmux_1 {
|
mdio_pins: mdio_pinmux {
|
||||||
pins = "gpio53";
|
pinmux_1 {
|
||||||
function = "mdio";
|
pins = "gpio53";
|
||||||
};
|
function = "mdio";
|
||||||
pinmux_2 {
|
};
|
||||||
pins = "gpio52";
|
pinmux_2 {
|
||||||
function = "mdc";
|
pins = "gpio52";
|
||||||
};
|
function = "mdc";
|
||||||
pinconf {
|
};
|
||||||
pins = "gpio52", "gpio53";
|
pinconf {
|
||||||
bias-pull-up;
|
pins = "gpio52", "gpio53";
|
||||||
};
|
bias-pull-up;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/* pinmux / gpios */
|
/* pinmux / gpios */
|
||||||
|
|
||||||
@ -618,19 +581,19 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
// TODO:
|
NAND TODO:
|
||||||
|
- FIX NAND - fucking nand is impossible, memory address conflicts with qcom-ipq4019.dtsi
|
||||||
|
- DO NOT MIX SPI/NAND PARTITIONS!
|
||||||
|
- NAND IS DIFFERENT GPIOS, GPIO53 IS IN USE - FIND CORRECT NAND GPIO
|
||||||
|
|
||||||
/* CHANGE 1: ADD NAND - fucking nand is impossible, memory address conflicts with qcom-ipq4019.dtsi */
|
LED TODO:
|
||||||
/* DO NOT MIX SPI/NAND PARTITIONS! */
|
- Probe GPIOs
|
||||||
|
- Add DTS config for LEDs
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
/* CHANGE 2: Add Switch Configuration if not present in the .dtsi */
|
|
||||||
/* The AP-DK04.1.dtsi might not have the specific QCA8337 setup for the TEW-829DRU */
|
|
||||||
/* If the SDK .dtsi already has the switch defined correctly, you can skip this. */
|
|
||||||
/* If not, append the &gmac1 and &mdio blocks here (from previous steps). */
|
|
||||||
|
|
||||||
|
|
||||||
/* CHANGE 3: Add wifi from existing/old DTS config attempts, and copy board*.bin (CALDATA) files */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,213 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: OpenWrt Developer <openwrt@localhost>
|
||||||
|
Date: Mon, 01 Jan 2024 00:00:00 +0000
|
||||||
|
Subject: [PATCH] net: ipqess: add dual-GMAC support for TEW-829DRU
|
||||||
|
|
||||||
|
The TRENDnet TEW-829DRU has two switches connected to the IPQ4019 ESS:
|
||||||
|
- GMAC0 -> QCA8075 (5-port switch, ports 0-4)
|
||||||
|
- GMAC1 -> QCA8337 (7-port switch, port 5 in RRD)
|
||||||
|
|
||||||
|
Both GMACs share the single EDMA hardware block. This patch adds an
|
||||||
|
optional second net_device (netdev2) that is created when the DT node
|
||||||
|
contains the property "qcom,gmac1-port". Incoming packets are demuxed
|
||||||
|
in ipqess_rx_poll() using the RRD port-id field; outgoing packets from
|
||||||
|
either netdev share the same TX rings.
|
||||||
|
|
||||||
|
The second interface's MAC address is read from a DT node referenced by
|
||||||
|
"qcom,gmac1-netdev", or derived automatically from the primary MAC by
|
||||||
|
eth_hw_addr_gen() if that phandle is absent.
|
||||||
|
|
||||||
|
Signed-off-by: OpenWrt Developer <openwrt@localhost>
|
||||||
|
---
|
||||||
|
.../net/ethernet/qualcomm/ipqess/ipqess.c | 97 +++++++++++++++++--
|
||||||
|
.../net/ethernet/qualcomm/ipqess/ipqess.h | 5 +
|
||||||
|
2 files changed, 96 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/ethernet/qualcomm/ipqess/ipqess.h
|
||||||
|
+++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess.h
|
||||||
|
@@ -238,6 +238,9 @@ struct ipqess {
|
||||||
|
struct net_device *netdev;
|
||||||
|
struct platform_device *pdev;
|
||||||
|
|
||||||
|
+ /* second netdev for dual-GMAC (e.g. TEW-829DRU QCA8337 switch) */
|
||||||
|
+ struct net_device *netdev2;
|
||||||
|
+
|
||||||
|
struct ipqess_rx_ring rx_ring[IPQESS_NETDEV_QUEUES];
|
||||||
|
struct ipqess_tx_ring tx_ring[IPQESS_NETDEV_QUEUES];
|
||||||
|
struct ipqess_rx_ring_refill rx_refill[IPQESS_NETDEV_QUEUES];
|
||||||
|
@@ -259,6 +262,8 @@ struct ipqess {
|
||||||
|
struct notifier_block netdev_notifier;
|
||||||
|
int dsa_ports;
|
||||||
|
|
||||||
|
+ int gmac1_port; /* RRD port-id of GMAC1 (0 = disabled) */
|
||||||
|
+
|
||||||
|
struct ipqess_statistics ipqess_stats;
|
||||||
|
spinlock_t stats_lock;
|
||||||
|
struct net_device_stats stats;
|
||||||
|
--- a/drivers/net/ethernet/qualcomm/ipqess/ipqess.c
|
||||||
|
+++ b/drivers/net/ethernet/qualcomm/ipqess/ipqess.c
|
||||||
|
@@ -28,6 +28,8 @@
|
||||||
|
#include "ipqess.h"
|
||||||
|
|
||||||
|
+#define IPQESS_GMAC1_PORT_DEFAULT 5
|
||||||
|
+
|
||||||
|
#define IPQESS_RRD_SIZE 16
|
||||||
|
#define IPQESS_NEXT_IDX(X, Y) (((X) + 1) & ((Y) - 1))
|
||||||
|
#define IPQESS_TX_DMA_BUF_LEN 0x3fff
|
||||||
|
@@ -155,7 +157,9 @@ static int ipqess_rx_buf_alloc(struct ipqess_rx_ring *rx_ring)
|
||||||
|
{
|
||||||
|
struct ipqess_buf *buf = &rx_ring->buf[rx_ring->head];
|
||||||
|
|
||||||
|
- buf->skb = netdev_alloc_skb_ip_align(rx_ring->ess->netdev,
|
||||||
|
+ buf->skb = netdev_alloc_skb_ip_align(rx_ring->ess->netdev2 ?
|
||||||
|
+ rx_ring->ess->netdev2 :
|
||||||
|
+ rx_ring->ess->netdev,
|
||||||
|
IPQESS_RX_HEAD_BUFF_SIZE);
|
||||||
|
|
||||||
|
if (!buf->skb)
|
||||||
|
@@ -236,6 +240,7 @@ static int ipqess_rx_poll(struct ipqess_rx_ring *rx_ring, int budget)
|
||||||
|
while (done < budget) {
|
||||||
|
struct dsa_oob_tag_info *tag_info;
|
||||||
|
struct ipqess_rx_desc *rd;
|
||||||
|
+ struct net_device *rx_netdev;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
if (rx_ring_tail == tail)
|
||||||
|
@@ -281,8 +286,22 @@ static int ipqess_rx_poll(struct ipqess_rx_ring *rx_ring, int budget)
|
||||||
|
}
|
||||||
|
|
||||||
|
- skb->dev = rx_ring->ess->netdev;
|
||||||
|
- skb->protocol = eth_type_trans(skb, rx_ring->ess->netdev);
|
||||||
|
+ /* Demux RX to netdev2 if this packet arrived on the GMAC1
|
||||||
|
+ * port (QCA8337 side on dual-switch boards like TEW-829DRU).
|
||||||
|
+ * The RRD port-id field lives in rrd1 bits [14:12].
|
||||||
|
+ */
|
||||||
|
+ if (rx_ring->ess->netdev2 && rx_ring->ess->gmac1_port &&
|
||||||
|
+ (FIELD_GET(IPQESS_RRD_PORT_ID_MASK,
|
||||||
|
+ le16_to_cpu(rd->rrd1)) ==
|
||||||
|
+ rx_ring->ess->gmac1_port)) {
|
||||||
|
+ rx_netdev = rx_ring->ess->netdev2;
|
||||||
|
+ } else {
|
||||||
|
+ rx_netdev = rx_ring->ess->netdev;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ skb->dev = rx_netdev;
|
||||||
|
+ skb->protocol = eth_type_trans(skb, rx_netdev);
|
||||||
|
skb_record_rx_queue(skb, rx_ring->ring_id);
|
||||||
|
|
||||||
|
if (rd->rrd6 & cpu_to_le16(IPQESS_RRD_CSUM_FAIL_MASK))
|
||||||
|
@@ -303,8 +322,8 @@ static int ipqess_rx_poll(struct ipqess_rx_ring *rx_ring, int budget)
|
||||||
|
napi_gro_receive(&rx_ring->napi_rx, skb);
|
||||||
|
|
||||||
|
- rx_ring->ess->stats.rx_packets++;
|
||||||
|
- rx_ring->ess->stats.rx_bytes += length;
|
||||||
|
+ rx_netdev->stats.rx_packets++;
|
||||||
|
+ rx_netdev->stats.rx_bytes += length;
|
||||||
|
|
||||||
|
done++;
|
||||||
|
skip:
|
||||||
|
@@ -479,6 +498,23 @@ static int ipqess_netdevice_event(struct notifier_block *nb,
|
||||||
|
struct ipqess *ess = container_of(nb, struct ipqess, netdev_notifier);
|
||||||
|
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||||
|
struct netdev_notifier_changeupper_info *info;
|
||||||
|
+ struct net_device *tracked;
|
||||||
|
+
|
||||||
|
+ /* Track DSA upper devices on both netdev and netdev2 */
|
||||||
|
+ tracked = dev;
|
||||||
|
+ if (tracked != ess->netdev &&
|
||||||
|
+ !(ess->netdev2 && tracked == ess->netdev2))
|
||||||
|
+ return NOTIFY_DONE;
|
||||||
|
|
||||||
|
- if (dev != ess->netdev)
|
||||||
|
- return NOTIFY_DONE;
|
||||||
|
+ if (tracked != ess->netdev && !(ess->netdev2 && tracked == ess->netdev2))
|
||||||
|
+ return NOTIFY_DONE;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case NETDEV_CHANGEUPPER:
|
||||||
|
@@ -648,6 +684,8 @@ static int ipqess_axi_probe(struct platform_device *pdev)
|
||||||
|
struct device_node *np = pdev->dev.of_node;
|
||||||
|
struct net_device *netdev;
|
||||||
|
phy_interface_t phy_mode;
|
||||||
|
+ struct net_device *netdev2 = NULL;
|
||||||
|
+ struct device_node *np2;
|
||||||
|
struct ipqess *ess;
|
||||||
|
int i, err = 0;
|
||||||
|
|
||||||
|
@@ -737,6 +775,57 @@ static int ipqess_axi_probe(struct platform_device *pdev)
|
||||||
|
if (err)
|
||||||
|
goto err_notifier_unregister;
|
||||||
|
|
||||||
|
+ /* ------------------------------------------------------------------ *
|
||||||
|
+ * Optional second netdev for dual-GMAC boards (e.g. TEW-829DRU). *
|
||||||
|
+ * Activated by DT property "qcom,gmac1-port" on the ESS node. *
|
||||||
|
+ * That u32 value is the RRD port-id that identifies packets arriving *
|
||||||
|
+ * from GMAC1 (the QCA8337 switch). A phandle "qcom,gmac1-netdev" *
|
||||||
|
+ * may point to a DT node carrying the MAC address; if absent the *
|
||||||
|
+ * address is derived from the primary interface via eth_hw_addr_gen. *
|
||||||
|
+ * ------------------------------------------------------------------ */
|
||||||
|
+ if (!of_property_read_u32(np, "qcom,gmac1-port", &ess->gmac1_port)) {
|
||||||
|
+ dev_info(&pdev->dev,
|
||||||
|
+ "dual-GMAC mode: GMAC1 RRD port-id = %u\n",
|
||||||
|
+ ess->gmac1_port);
|
||||||
|
+
|
||||||
|
+ netdev2 = devm_alloc_etherdev_mqs(&pdev->dev, 0,
|
||||||
|
+ IPQESS_NETDEV_QUEUES,
|
||||||
|
+ IPQESS_NETDEV_QUEUES);
|
||||||
|
+ if (!netdev2) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_notifier_unregister;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Both netdevs share the same HW TX rings via ipqess_xmit */
|
||||||
|
+ netdev2->netdev_ops = &ipqess_axi_netdev_ops;
|
||||||
|
+ netdev2->features = netdev->features;
|
||||||
|
+ netdev2->hw_features = 0;
|
||||||
|
+ netdev2->vlan_features = netdev->vlan_features;
|
||||||
|
+ netdev2->watchdog_timeo = netdev->watchdog_timeo;
|
||||||
|
+ netdev2->base_addr = netdev->base_addr;
|
||||||
|
+ netdev2->max_mtu = netdev->max_mtu;
|
||||||
|
+ netdev2->gso_max_segs = netdev->gso_max_segs;
|
||||||
|
+ SET_NETDEV_DEV(netdev2, &pdev->dev);
|
||||||
|
+
|
||||||
|
+ /* MAC address: prefer explicit DT node, else auto-derive */
|
||||||
|
+ np2 = of_parse_phandle(np, "qcom,gmac1-netdev", 0);
|
||||||
|
+ if (np2) {
|
||||||
|
+ if (of_get_ethdev_address(np2, netdev2)) {
|
||||||
|
+ eth_hw_addr_random(netdev2);
|
||||||
|
+ dev_info(&pdev->dev,
|
||||||
|
+ "gmac1: using random MAC %pM\n",
|
||||||
|
+ netdev2->dev_addr);
|
||||||
|
+ }
|
||||||
|
+ of_node_put(np2);
|
||||||
|
+ } else {
|
||||||
|
+ eth_hw_addr_gen(netdev2, netdev->dev_addr, 1);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ipqess_set_ethtool_ops(netdev2);
|
||||||
|
+ ess->netdev2 = netdev2;
|
||||||
|
+
|
||||||
|
+ err = register_netdev(netdev2);
|
||||||
|
+ if (err) {
|
||||||
|
+ dev_err(&pdev->dev,
|
||||||
|
+ "failed to register gmac1 netdev: %d\n", err);
|
||||||
|
+ ess->netdev2 = NULL;
|
||||||
|
+ /* non-fatal: primary interface still works */
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
dev_set_threaded(netdev, true);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
@@ -801,6 +840,11 @@ static void ipqess_axi_remove(struct platform_device *pdev)
|
||||||
|
const struct net_device *netdev = platform_get_drvdata(pdev);
|
||||||
|
struct ipqess *ess = netdev_priv(netdev);
|
||||||
|
|
||||||
|
+ if (ess->netdev2) {
|
||||||
|
+ unregister_netdev(ess->netdev2);
|
||||||
|
+ ess->netdev2 = NULL;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
unregister_netdev(ess->netdev);
|
||||||
|
ipqess_hw_stop(ess);
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user