diff options
| author | Lorenzo Bianconi <lorenzo@kernel.org> | 2025-10-17 11:06:20 +0200 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2025-10-21 13:07:05 +0200 |
| commit | 9d5b5219f672c80bed4d4e15f0068e648cdca43b (patch) | |
| tree | 5238129a0fc94985c4cb2eb85317045f9b733e54 | |
| parent | c71a7a861ef02aa2bebb18c2f3385aa3f19094e0 (diff) | |
net: airoha: Refactor src port configuration in airhoha_set_gdm2_loopback
AN7583 chipset relies on different definitions for source-port
identifier used for hw offloading. In order to support hw offloading
in AN7583 controller, refactor src port configuration in
airhoha_set_gdm2_loopback routine and introduce get_src_port_id
callback.
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20251017-an7583-eth-support-v3-11-f28319666667@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
| -rw-r--r-- | drivers/net/ethernet/airoha/airoha_eth.c | 82 | ||||
| -rw-r--r-- | drivers/net/ethernet/airoha/airoha_eth.h | 18 | ||||
| -rw-r--r-- | drivers/net/ethernet/airoha/airoha_regs.h | 6 |
3 files changed, 73 insertions, 33 deletions
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c index 4e338c126dd3..4671f906a68c 100644 --- a/drivers/net/ethernet/airoha/airoha_eth.c +++ b/drivers/net/ethernet/airoha/airoha_eth.c @@ -1682,13 +1682,17 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p) return 0; } -static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) +static int airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) { - u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4; + u32 val, pse_port, chan = port->id == AIROHA_GDM3_IDX ? 4 : 0; struct airoha_eth *eth = port->qdma->eth; - u32 chan = port->id == 3 ? 4 : 0; + /* XXX: handle XSI_USB_PORT and XSI_PCE1_PORT */ + u32 nbq = port->id == AIROHA_GDM3_IDX ? 4 : 0; + int src_port; /* Forward the traffic to the proper GDM port */ + pse_port = port->id == AIROHA_GDM3_IDX ? FE_PSE_PORT_GDM3 + : FE_PSE_PORT_GDM4; airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port); airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC); @@ -1709,29 +1713,25 @@ static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port) airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2)); airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2)); - if (port->id == 3) { - /* FIXME: handle XSI_PCE1_PORT */ - airoha_fe_rmw(eth, REG_FE_WAN_PORT, - WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, - FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT)); - airoha_fe_rmw(eth, - REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3), - SP_CPORT_PCIE0_MASK, - FIELD_PREP(SP_CPORT_PCIE0_MASK, - FE_PSE_PORT_CDM2)); - } else { - /* FIXME: handle XSI_USB_PORT */ + src_port = eth->soc->ops.get_src_port_id(port, nbq); + if (src_port < 0) + return src_port; + + airoha_fe_rmw(eth, REG_FE_WAN_PORT, + WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, + FIELD_PREP(WAN0_MASK, src_port)); + val = src_port & SP_CPORT_DFT_MASK; + airoha_fe_rmw(eth, + REG_SP_DFT_CPORT(src_port >> fls(SP_CPORT_DFT_MASK)), + SP_CPORT_MASK(val), + FE_PSE_PORT_CDM2 << __ffs(SP_CPORT_MASK(val))); + + if (port->id != AIROHA_GDM3_IDX) airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6, FC_ID_OF_SRC_PORT24_MASK, FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2)); - airoha_fe_rmw(eth, REG_FE_WAN_PORT, - WAN1_EN_MASK | WAN1_MASK | WAN0_MASK, - FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT)); - airoha_fe_rmw(eth, - REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3), - SP_CPORT_ETH_MASK, - FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2)); - } + + return 0; } static int airoha_dev_init(struct net_device *dev) @@ -1748,8 +1748,13 @@ static int airoha_dev_init(struct net_device *dev) case 3: case 4: /* If GDM2 is active we can't enable loopback */ - if (!eth->ports[1]) - airhoha_set_gdm2_loopback(port); + if (!eth->ports[1]) { + int err; + + err = airhoha_set_gdm2_loopback(port); + if (err) + return err; + } fallthrough; case 2: if (airoha_ppe_is_enabled(eth, 1)) { @@ -3069,11 +3074,38 @@ static const char * const en7581_xsi_rsts_names[] = { "xfp-mac", }; +static int airoha_en7581_get_src_port_id(struct airoha_gdm_port *port, int nbq) +{ + switch (port->id) { + case 3: + /* 7581 SoC supports PCIe serdes on GDM3 port */ + if (nbq == 4) + return HSGMII_LAN_7581_PCIE0_SRCPORT; + if (nbq == 5) + return HSGMII_LAN_7581_PCIE1_SRCPORT; + break; + case 4: + /* 7581 SoC supports eth and usb serdes on GDM4 port */ + if (!nbq) + return HSGMII_LAN_7581_ETH_SRCPORT; + if (nbq == 1) + return HSGMII_LAN_7581_USB_SRCPORT; + break; + default: + break; + } + + return -EINVAL; +} + static const struct airoha_eth_soc_data en7581_soc_data = { .version = 0x7581, .xsi_rsts_names = en7581_xsi_rsts_names, .num_xsi_rsts = ARRAY_SIZE(en7581_xsi_rsts_names), .num_ppe = 2, + .ops = { + .get_src_port_id = airoha_en7581_get_src_port_id, + }, }; static const struct of_device_id of_airoha_match[] = { diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h index df168d798699..e09579da8c78 100644 --- a/drivers/net/ethernet/airoha/airoha_eth.h +++ b/drivers/net/ethernet/airoha/airoha_eth.h @@ -67,10 +67,10 @@ enum { }; enum { - HSGMII_LAN_PCIE0_SRCPORT = 0x16, - HSGMII_LAN_PCIE1_SRCPORT, - HSGMII_LAN_ETH_SRCPORT, - HSGMII_LAN_USB_SRCPORT, + HSGMII_LAN_7581_PCIE0_SRCPORT = 0x16, + HSGMII_LAN_7581_PCIE1_SRCPORT, + HSGMII_LAN_7581_ETH_SRCPORT, + HSGMII_LAN_7581_USB_SRCPORT, }; enum { @@ -99,6 +99,13 @@ enum { CRSN_25 = 0x19, }; +enum airoha_gdm_index { + AIROHA_GDM1_IDX = 1, + AIROHA_GDM2_IDX = 2, + AIROHA_GDM3_IDX = 3, + AIROHA_GDM4_IDX = 4, +}; + enum { FE_PSE_PORT_CDM1, FE_PSE_PORT_GDM1, @@ -555,6 +562,9 @@ struct airoha_eth_soc_data { const char * const *xsi_rsts_names; int num_xsi_rsts; int num_ppe; + struct { + int (*get_src_port_id)(struct airoha_gdm_port *port, int nbq); + } ops; }; struct airoha_eth { diff --git a/drivers/net/ethernet/airoha/airoha_regs.h b/drivers/net/ethernet/airoha/airoha_regs.h index 69c5a143db8c..ebcce00d9bc6 100644 --- a/drivers/net/ethernet/airoha/airoha_regs.h +++ b/drivers/net/ethernet/airoha/airoha_regs.h @@ -383,10 +383,8 @@ #define REG_MC_VLAN_DATA 0x2108 #define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2)) -#define SP_CPORT_PCIE1_MASK GENMASK(31, 28) -#define SP_CPORT_PCIE0_MASK GENMASK(27, 24) -#define SP_CPORT_USB_MASK GENMASK(7, 4) -#define SP_CPORT_ETH_MASK GENMASK(7, 4) +#define SP_CPORT_DFT_MASK GENMASK(2, 0) +#define SP_CPORT_MASK(_n) GENMASK(3 + ((_n) << 2), ((_n) << 2)) #define REG_SRC_PORT_FC_MAP6 0x2298 #define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24) |