Skip to content

Commit 9cd451d

Browse files
LorenzoBianconiPaolo Abeni
authored andcommitted
net: airoha: Add loopback support for GDM2
Enable hw redirection for traffic received on GDM2 port to GDM{3,4}. This is required to apply Qdisc offloading (HTB or ETS) for traffic to and from GDM{3,4} port. Signed-off-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 00a7678 commit 9cd451d

File tree

4 files changed

+111
-8
lines changed

4 files changed

+111
-8
lines changed

drivers/net/ethernet/airoha/airoha_eth.c

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,14 +1588,81 @@ static int airoha_dev_set_macaddr(struct net_device *dev, void *p)
15881588
return 0;
15891589
}
15901590

1591+
static void airhoha_set_gdm2_loopback(struct airoha_gdm_port *port)
1592+
{
1593+
u32 pse_port = port->id == 3 ? FE_PSE_PORT_GDM3 : FE_PSE_PORT_GDM4;
1594+
struct airoha_eth *eth = port->qdma->eth;
1595+
u32 chan = port->id == 3 ? 4 : 0;
1596+
1597+
/* Forward the traffic to the proper GDM port */
1598+
airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(2), pse_port);
1599+
airoha_fe_clear(eth, REG_GDM_FWD_CFG(2), GDM_STRIP_CRC);
1600+
1601+
/* Enable GDM2 loopback */
1602+
airoha_fe_wr(eth, REG_GDM_TXCHN_EN(2), 0xffffffff);
1603+
airoha_fe_wr(eth, REG_GDM_RXCHN_EN(2), 0xffff);
1604+
airoha_fe_rmw(eth, REG_GDM_LPBK_CFG(2),
1605+
LPBK_CHAN_MASK | LPBK_MODE_MASK | LPBK_EN_MASK,
1606+
FIELD_PREP(LPBK_CHAN_MASK, chan) | LPBK_EN_MASK);
1607+
airoha_fe_rmw(eth, REG_GDM_LEN_CFG(2),
1608+
GDM_SHORT_LEN_MASK | GDM_LONG_LEN_MASK,
1609+
FIELD_PREP(GDM_SHORT_LEN_MASK, 60) |
1610+
FIELD_PREP(GDM_LONG_LEN_MASK, AIROHA_MAX_MTU));
1611+
1612+
/* Disable VIP and IFC for GDM2 */
1613+
airoha_fe_clear(eth, REG_FE_VIP_PORT_EN, BIT(2));
1614+
airoha_fe_clear(eth, REG_FE_IFC_PORT_EN, BIT(2));
1615+
1616+
if (port->id == 3) {
1617+
/* FIXME: handle XSI_PCE1_PORT */
1618+
airoha_fe_wr(eth, REG_PPE_DFT_CPORT0(0), 0x5500);
1619+
airoha_fe_rmw(eth, REG_FE_WAN_PORT,
1620+
WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
1621+
FIELD_PREP(WAN0_MASK, HSGMII_LAN_PCIE0_SRCPORT));
1622+
airoha_fe_rmw(eth,
1623+
REG_SP_DFT_CPORT(HSGMII_LAN_PCIE0_SRCPORT >> 3),
1624+
SP_CPORT_PCIE0_MASK,
1625+
FIELD_PREP(SP_CPORT_PCIE0_MASK,
1626+
FE_PSE_PORT_CDM2));
1627+
} else {
1628+
/* FIXME: handle XSI_USB_PORT */
1629+
airoha_fe_rmw(eth, REG_SRC_PORT_FC_MAP6,
1630+
FC_ID_OF_SRC_PORT24_MASK,
1631+
FIELD_PREP(FC_ID_OF_SRC_PORT24_MASK, 2));
1632+
airoha_fe_rmw(eth, REG_FE_WAN_PORT,
1633+
WAN1_EN_MASK | WAN1_MASK | WAN0_MASK,
1634+
FIELD_PREP(WAN0_MASK, HSGMII_LAN_ETH_SRCPORT));
1635+
airoha_fe_rmw(eth,
1636+
REG_SP_DFT_CPORT(HSGMII_LAN_ETH_SRCPORT >> 3),
1637+
SP_CPORT_ETH_MASK,
1638+
FIELD_PREP(SP_CPORT_ETH_MASK, FE_PSE_PORT_CDM2));
1639+
}
1640+
}
1641+
15911642
static int airoha_dev_init(struct net_device *dev)
15921643
{
15931644
struct airoha_gdm_port *port = netdev_priv(dev);
15941645
struct airoha_eth *eth = port->qdma->eth;
1646+
u32 pse_port;
15951647

15961648
airoha_set_macaddr(port, dev->dev_addr);
1597-
airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id),
1598-
FE_PSE_PORT_PPE1);
1649+
1650+
switch (port->id) {
1651+
case 3:
1652+
case 4:
1653+
/* If GDM2 is active we can't enable loopback */
1654+
if (!eth->ports[1])
1655+
airhoha_set_gdm2_loopback(port);
1656+
fallthrough;
1657+
case 2:
1658+
pse_port = FE_PSE_PORT_PPE2;
1659+
break;
1660+
default:
1661+
pse_port = FE_PSE_PORT_PPE1;
1662+
break;
1663+
}
1664+
1665+
airoha_set_gdm_port_fwd_cfg(eth, REG_GDM_FWD_CFG(port->id), pse_port);
15991666

16001667
return 0;
16011668
}

drivers/net/ethernet/airoha/airoha_eth.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,13 @@ enum {
6767
QDMA_INT_REG_MAX
6868
};
6969

70+
enum {
71+
HSGMII_LAN_PCIE0_SRCPORT = 0x16,
72+
HSGMII_LAN_PCIE1_SRCPORT,
73+
HSGMII_LAN_ETH_SRCPORT,
74+
HSGMII_LAN_USB_SRCPORT,
75+
};
76+
7077
enum {
7178
XSI_PCIE0_VIP_PORT_MASK = BIT(22),
7279
XSI_PCIE1_VIP_PORT_MASK = BIT(23),

drivers/net/ethernet/airoha/airoha_ppe.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,22 +216,22 @@ static int airoha_ppe_foe_entry_prepare(struct airoha_foe_entry *hwe,
216216
AIROHA_FOE_IB1_BIND_TTL;
217217
hwe->ib1 = val;
218218

219-
val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f);
219+
val = FIELD_PREP(AIROHA_FOE_IB2_PORT_AG, 0x1f) |
220+
AIROHA_FOE_IB2_PSE_QOS;
220221
if (dsa_port >= 0)
221222
val |= FIELD_PREP(AIROHA_FOE_IB2_NBQ, dsa_port);
222223

223224
if (dev) {
224225
struct airoha_gdm_port *port = netdev_priv(dev);
225226
u8 pse_port;
226227

227-
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
228+
if (dsa_port >= 0)
229+
pse_port = port->id == 4 ? FE_PSE_PORT_GDM4 : port->id;
230+
else
231+
pse_port = 2; /* uplink relies on GDM2 loopback */
228232
val |= FIELD_PREP(AIROHA_FOE_IB2_PSE_PORT, pse_port);
229233
}
230234

231-
/* FIXME: implement QoS support setting pse_port to 2 (loopback)
232-
* for uplink and setting qos bit in ib2
233-
*/
234-
235235
if (is_multicast_ether_addr(data->eth.h_dest))
236236
val |= AIROHA_FOE_IB2_MULTICAST;
237237

drivers/net/ethernet/airoha/airoha_regs.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@
3838
#define FE_RST_CORE_MASK BIT(0)
3939

4040
#define REG_FE_FOE_TS 0x0010
41+
42+
#define REG_FE_WAN_PORT 0x0024
43+
#define WAN1_EN_MASK BIT(16)
44+
#define WAN1_MASK GENMASK(12, 8)
45+
#define WAN0_MASK GENMASK(4, 0)
46+
4147
#define REG_FE_WAN_MAC_H 0x0030
4248
#define REG_FE_LAN_MAC_H 0x0040
4349

@@ -126,6 +132,7 @@
126132
#define GDM_IP4_CKSUM BIT(22)
127133
#define GDM_TCP_CKSUM BIT(21)
128134
#define GDM_UDP_CKSUM BIT(20)
135+
#define GDM_STRIP_CRC BIT(16)
129136
#define GDM_UCFQ_MASK GENMASK(15, 12)
130137
#define GDM_BCFQ_MASK GENMASK(11, 8)
131138
#define GDM_MCFQ_MASK GENMASK(7, 4)
@@ -139,6 +146,16 @@
139146
#define GDM_SHORT_LEN_MASK GENMASK(13, 0)
140147
#define GDM_LONG_LEN_MASK GENMASK(29, 16)
141148

149+
#define REG_GDM_LPBK_CFG(_n) (GDM_BASE(_n) + 0x1c)
150+
#define LPBK_GAP_MASK GENMASK(31, 24)
151+
#define LPBK_LEN_MASK GENMASK(23, 10)
152+
#define LPBK_CHAN_MASK GENMASK(8, 4)
153+
#define LPBK_MODE_MASK GENMASK(3, 1)
154+
#define LPBK_EN_MASK BIT(0)
155+
156+
#define REG_GDM_TXCHN_EN(_n) (GDM_BASE(_n) + 0x24)
157+
#define REG_GDM_RXCHN_EN(_n) (GDM_BASE(_n) + 0x28)
158+
142159
#define REG_FE_CPORT_CFG (GDM1_BASE + 0x40)
143160
#define FE_CPORT_PAD BIT(26)
144161
#define FE_CPORT_PORT_XFC_MASK BIT(25)
@@ -351,6 +368,18 @@
351368

352369
#define REG_MC_VLAN_DATA 0x2108
353370

371+
#define REG_SP_DFT_CPORT(_n) (0x20e0 + ((_n) << 2))
372+
#define SP_CPORT_PCIE1_MASK GENMASK(31, 28)
373+
#define SP_CPORT_PCIE0_MASK GENMASK(27, 24)
374+
#define SP_CPORT_USB_MASK GENMASK(7, 4)
375+
#define SP_CPORT_ETH_MASK GENMASK(7, 4)
376+
377+
#define REG_SRC_PORT_FC_MAP6 0x2298
378+
#define FC_ID_OF_SRC_PORT27_MASK GENMASK(28, 24)
379+
#define FC_ID_OF_SRC_PORT26_MASK GENMASK(20, 16)
380+
#define FC_ID_OF_SRC_PORT25_MASK GENMASK(12, 8)
381+
#define FC_ID_OF_SRC_PORT24_MASK GENMASK(4, 0)
382+
354383
#define REG_CDM5_RX_OQ1_DROP_CNT 0x29d4
355384

356385
/* QDMA */

0 commit comments

Comments
 (0)