1
1

fixed compile errors
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled

This commit is contained in:
mooleshacat 2026-06-17 15:18:53 -04:00
parent 3bb2e28f43
commit 8dfae1f922
Signed by: mooleshacat
GPG Key ID: 6F42FE1A481818C2
2 changed files with 243 additions and 27 deletions

View File

@ -51,6 +51,8 @@
&gmac {
status = "okay";
phy-mode = "internal";
/* dual-GMAC: RRD port-id 5 = GMAC1 = QCA8337 switch */
qcom,gmac1-port = <5>;
fixed-link {
speed = <1000>;
full-duplex;
@ -167,7 +169,6 @@
label = "cpu";
ethernet = <&gmac>; /* side-by-side: ALSO points to EDMA, not to swport5 */
phy-mode = "rgmii";
tag-protocol = "none";
fixed-link {
speed = <1000>;
full-duplex;
@ -186,8 +187,8 @@
label = "lan5";
phy-mode = "internal";
phy-handle = <&qca8337_phy1>;
};
};
port@3 {
reg = <3>;
label = "lan6";
@ -308,10 +309,11 @@
/* start of &nand (Micron MT29F1G08ABADA NAND 128MB) */
&nand {
status = "okay"; /* was "disabled" in your WIP — enable it! */
status = "disabled"; /* DISABLED WHILE FIGURING OUT SWITCH CONFIG */
/delete-property/ pinctrl-0;
/delete-property/ pinctrl-names;
pinctrl-0 = <&nand_pins>;
pinctrl-names = "default";
/* REMOVED PINCTRL - NO CONFLICT PLS */
nand@0 {
reg = <0>;
@ -365,14 +367,14 @@
&tlmm {
nand_pins {
nand-state {
/* removed GPIO53, conflict resolved. */
pins = "gpio55", "gpio56", "gpio57", "gpio58",
"gpio59", "gpio60", "gpio62", "gpio63", "gpio64",
"gpio65", "gpio66", "gpio67", "gpio68", "gpio69";
function = "qpic";
};
};
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 */
usb_power_en: usb-power-en {
@ -382,20 +384,21 @@
line-name = "usb-power-enable";
};
mdio_pins: mdio_pinmux {
pinmux_1 {
pins = "gpio53";
function = "mdio";
};
pinmux_2 {
pins = "gpio52";
function = "mdc";
};
pinconf {
pins = "gpio52", "gpio53";
bias-pull-up;
};
};
mdio_pins: mdio_pinmux {
pinmux_1 {
pins = "gpio53";
function = "mdio";
};
pinmux_2 {
pins = "gpio52";
function = "mdc";
};
pinconf {
pins = "gpio52", "gpio53";
bias-pull-up;
};
};
/* pinmux / gpios */

View File

@ -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);