net: airoha: Introduce airoha_gdm_dev struct

EN7581 and AN7583 SoCs support connecting multiple external SerDes to GDM3
or GDM4 ports via a hw arbiter that manages the traffic in a TDM manner.
As a result multiple net_devices can connect to the same GDM{3,4} port
and there is a theoretical "1:n" relation between GDM port and
net_devices.
Introduce airoha_gdm_dev struct to collect net_device related info (e.g.
net_device and external phy pointer). Please note this is just a
preliminary patch and we are still supporting a single net_device for
each GDM port. Subsequent patches will add support for multiple net_devices
connected to the same GDM port.

Tested-by: Xuegang Lu <xuegang.lu@airoha.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20260527-airoha-eth-multi-serdes-preliminary-v1-1-ec6ed73ef7fc@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Lorenzo Bianconi
2026-06-02 13:24:25 -07:00
committed by Jakub Kicinski
parent 5996b5ab8b
commit ec6c391bcc
3 changed files with 206 additions and 136 deletions
File diff suppressed because it is too large Load Diff
+9 -4
View File
@@ -535,10 +535,15 @@ struct airoha_qdma {
struct airoha_queue q_rx[AIROHA_NUM_RX_RING]; struct airoha_queue q_rx[AIROHA_NUM_RX_RING];
}; };
struct airoha_gdm_dev {
struct airoha_gdm_port *port;
struct net_device *dev;
struct airoha_eth *eth;
};
struct airoha_gdm_port { struct airoha_gdm_port {
struct airoha_qdma *qdma; struct airoha_qdma *qdma;
struct airoha_eth *eth; struct airoha_gdm_dev *dev;
struct net_device *dev;
int id; int id;
int nbq; int nbq;
@@ -662,8 +667,8 @@ static inline bool airoha_is_7583(struct airoha_eth *eth)
} }
int airoha_get_fe_port(struct airoha_gdm_port *port); int airoha_get_fe_port(struct airoha_gdm_port *port);
bool airoha_is_valid_gdm_port(struct airoha_eth *eth, bool airoha_is_valid_gdm_dev(struct airoha_eth *eth,
struct airoha_gdm_port *port); struct airoha_gdm_dev *dev);
void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id, void airoha_ppe_set_cpu_port(struct airoha_gdm_port *port, u8 ppe_id,
u8 fport); u8 fport);
+10 -7
View File
@@ -298,12 +298,12 @@ static void airoha_ppe_foe_set_bridge_addrs(struct airoha_foe_bridge *br,
static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth, static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
struct airoha_foe_entry *hwe, struct airoha_foe_entry *hwe,
struct net_device *dev, int type, struct net_device *netdev, int type,
struct airoha_flow_data *data, struct airoha_flow_data *data,
int l4proto) int l4proto)
{ {
u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val; u32 qdata = FIELD_PREP(AIROHA_FOE_SHAPER_ID, 0x7f), ports_pad, val;
int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&dev); int wlan_etype = -EINVAL, dsa_port = airoha_get_dsa_port(&netdev);
struct airoha_foe_mac_info_common *l2; struct airoha_foe_mac_info_common *l2;
u8 smac_id = 0xf; u8 smac_id = 0xf;
@@ -319,10 +319,11 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
hwe->ib1 = val; hwe->ib1 = val;
val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f); val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f);
if (dev) { if (netdev) {
struct airoha_wdma_info info = {}; struct airoha_wdma_info info = {};
if (!airoha_ppe_get_wdma_info(dev, data->eth.h_dest, &info)) { if (!airoha_ppe_get_wdma_info(netdev, data->eth.h_dest,
&info)) {
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) | val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, info.idx) |
FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT,
FE_PSE_PORT_CDM4); FE_PSE_PORT_CDM4);
@@ -332,12 +333,14 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_eth *eth,
FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID, FIELD_PREP(AIROHA_FOE_MAC_WDMA_WCID,
info.wcid); info.wcid);
} else { } else {
struct airoha_gdm_port *port = netdev_priv(dev); struct airoha_gdm_dev *dev = netdev_priv(netdev);
struct airoha_gdm_port *port;
u8 pse_port, channel; u8 pse_port, channel;
if (!airoha_is_valid_gdm_port(eth, port)) if (!airoha_is_valid_gdm_dev(eth, dev))
return -EINVAL; return -EINVAL;
port = dev->port;
if (dsa_port >= 0 || eth->ports[1]) if (dsa_port >= 0 || eth->ports[1])
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 pse_port = port->id == 4 ? FE_PSE_PORT_GDM4
: port->id; : port->id;
@@ -1473,7 +1476,7 @@ void airoha_ppe_check_skb(struct airoha_ppe_dev *dev, struct sk_buff *skb,
void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port) void airoha_ppe_init_upd_mem(struct airoha_gdm_port *port)
{ {
struct airoha_eth *eth = port->qdma->eth; struct airoha_eth *eth = port->qdma->eth;
struct net_device *dev = port->dev; struct net_device *dev = port->dev->dev;
const u8 *addr = dev->dev_addr; const u8 *addr = dev->dev_addr;
u32 val; u32 val;