Skip to content

Commit d21ce1d

Browse files
committed
HSD #15012366445: drivers: net: stmmac: Add support for HW-accelerated VLAN Stripping
This is to add HW-accelerated VLAN Stripping for XGMAC Signed-off-by: Boon Khai Ng <boon.khai.ng@intel.com>
1 parent b0ef580 commit d21ce1d

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@
431431
#define XGMAC_TDES2_VTIR GENMASK(15, 14)
432432
#define XGMAC_TDES2_VTIR_SHIFT 14
433433
#define XGMAC_TDES2_B1L GENMASK(13, 0)
434+
#define XGMAC_TDES2_VLAN_TAG_MASK GENMASK(15, 14)
434435
#define XGMAC_TDES3_OWN BIT(31)
435436
#define XGMAC_TDES3_CTXT BIT(30)
436437
#define XGMAC_TDES3_FD BIT(29)
@@ -462,6 +463,8 @@
462463
#define XGMAC_RDES3_RSV BIT(26)
463464
#define XGMAC_RDES3_L34T GENMASK(23, 20)
464465
#define XGMAC_RDES3_L34T_SHIFT 20
466+
#define XGMAC_RDES3_ET_LT GENMASK(19, 16)
467+
#define XGMAC_RDES3_ET_LT_SHIFT 16
465468
#define XGMAC_L34T_IP4TCP 0x1
466469
#define XGMAC_L34T_IP4UDP 0x2
467470
#define XGMAC_L34T_IP6TCP 0x9
@@ -471,4 +474,29 @@
471474
#define XGMAC_RDES3_TSD BIT(6)
472475
#define XGMAC_RDES3_TSA BIT(4)
473476

477+
/* RDES0 (write back format) */
478+
#define XGMAC_RDES0_VLAN_TAG_MASK GENMASK(15,0)
479+
480+
/* MAC VLAN Tag Control */
481+
#define XGMAC_VLAN_TAG_CTRL_OB BIT(0)
482+
#define XGMAC_VLAN_TAG_CTRL_CT BIT(1)
483+
#define XGMAC_VLAN_TAG_CTRL_OFS_MASK GENMASK(6, 2)
484+
#define XGMAC_VLAN_TAG_CTRL_OFS_SHIFT 2
485+
#define XGMAC_VLAN_TAG_CTRL_EVLS_MASK GENMASK(22, 21)
486+
#define XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT 21
487+
#define XGMAC_VLAN_TAG_CTRL_EVLRXS BIT(24)
488+
489+
#define XGMAC_VLAN_TAG_STRIP_NONE (0x0 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
490+
#define XGMAC_VLAN_TAG_STRIP_PASS (0x1 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
491+
#define XGMAC_VLAN_TAG_STRIP_FAIL (0x2 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
492+
#define XGMAC_VLAN_TAG_STRIP_ALL (0x3 << XGMAC_VLAN_TAG_CTRL_EVLS_SHIFT)
493+
494+
/* Error Type or L2 Type(ET/LT) Field Number */
495+
#define XGMAC_ET_LT_VLAN_STAG 8
496+
#define XGMAC_ET_LT_VLAN_CTAG 9
497+
#define XGMAC_ET_LT_DVLAN_CTAG_CTAG 10
498+
#define XGMAC_ET_LT_DVLAN_STAG_STAG 11
499+
#define XGMAC_ET_LT_DVLAN_CTAG_STAG 12
500+
#define XGMAC_ET_LT_DVLAN_STAG_CTAG 13
501+
474502
#endif /* __STMMAC_DWXGMAC2_H__ */

drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <linux/bitrev.h>
88
#include <linux/crc32.h>
99
#include <linux/iopoll.h>
10+
#include <linux/if_vlan.h>
1011
#include "stmmac.h"
1112
#include "stmmac_ptp.h"
1213
#include "dwxlgmac2.h"
@@ -1174,6 +1175,38 @@ static void dwxgmac2_sarc_configure(void __iomem *ioaddr, int val)
11741175
writel(value, ioaddr + XGMAC_TX_CONFIG);
11751176
}
11761177

1178+
static void dwxgmac2_rx_hw_vlan(struct net_device *dev,
1179+
struct mac_device_info *hw,
1180+
struct dma_desc *rx_desc, struct sk_buff *skb)
1181+
{
1182+
if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
1183+
hw->desc->get_rx_vlan_valid(rx_desc)){
1184+
u16 vid = (u16)hw->desc->get_rx_vlan_tci(rx_desc);
1185+
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vid);
1186+
}
1187+
}
1188+
1189+
static void dwxgmac2_set_hw_vlan_mode(void __iomem *ioaddr,
1190+
netdev_features_t features)
1191+
{
1192+
u32 val;
1193+
1194+
val = readl(ioaddr + XGMAC_VLAN_TAG);
1195+
val &= ~XGMAC_VLAN_TAG_CTRL_EVLS_MASK;
1196+
1197+
if (features & NETIF_F_HW_VLAN_CTAG_RX)
1198+
/* Always strip VLAN on Receive */
1199+
val |= XGMAC_VLAN_TAG_STRIP_ALL;
1200+
else
1201+
/* Do not strip VLAN on Receive */
1202+
val |= XGMAC_VLAN_TAG_STRIP_NONE;
1203+
1204+
/* Enable outer VLAN Tag in Rx DMA descriptro */
1205+
val |= XGMAC_VLAN_TAG_CTRL_EVLRXS;
1206+
1207+
writel(val, ioaddr + XGMAC_VLAN_TAG);
1208+
}
1209+
11771210
static void dwxgmac2_enable_vlan(struct mac_device_info *hw, u32 type)
11781211
{
11791212
void __iomem *ioaddr = hw->pcsr;
@@ -1498,6 +1531,8 @@ const struct stmmac_ops dwxgmac210_ops = {
14981531
.set_arp_offload = dwxgmac2_set_arp_offload,
14991532
.est_configure = dwxgmac3_est_configure,
15001533
.fpe_configure = dwxgmac3_fpe_configure,
1534+
.rx_hw_vlan = dwxgmac2_rx_hw_vlan,
1535+
.set_hw_vlan_mode = dwxgmac2_set_hw_vlan_mode,
15011536
};
15021537

15031538
static void dwxlgmac2_rx_queue_enable(struct mac_device_info *hw, u8 mode,
@@ -1559,6 +1594,8 @@ const struct stmmac_ops dwxlgmac2_ops = {
15591594
.set_arp_offload = dwxgmac2_set_arp_offload,
15601595
.est_configure = dwxgmac3_est_configure,
15611596
.fpe_configure = dwxgmac3_fpe_configure,
1597+
.rx_hw_vlan = dwxgmac2_rx_hw_vlan,
1598+
.set_hw_vlan_mode = dwxgmac2_set_hw_vlan_mode,
15621599
};
15631600

15641601
int dwxgmac2_setup(struct stmmac_priv *priv)

drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,19 @@ static int dwxgmac2_get_tx_ls(struct dma_desc *p)
6767
return (le32_to_cpu(p->des3) & XGMAC_RDES3_LD) > 0;
6868
}
6969

70+
static inline int dwxgmac2_wrback_get_rx_vlan_tci(struct dma_desc *p)
71+
{
72+
return (le32_to_cpu(p->des0) & XGMAC_RDES0_VLAN_TAG_MASK);
73+
}
74+
75+
static inline bool dwxgmac2_wrback_get_rx_vlan_valid(struct dma_desc *p)
76+
{
77+
return((((le32_to_cpu(p->des3) & XGMAC_RDES3_ET_LT) >>
78+
XGMAC_RDES3_ET_LT_SHIFT) >= XGMAC_ET_LT_VLAN_STAG) &&
79+
(((le32_to_cpu(p->des3) & XGMAC_RDES3_ET_LT) >>
80+
XGMAC_RDES3_ET_LT_SHIFT) <= XGMAC_ET_LT_DVLAN_STAG_CTAG));
81+
}
82+
7083
static int dwxgmac2_get_rx_frame_len(struct dma_desc *p, int rx_coe)
7184
{
7285
return (le32_to_cpu(p->des3) & XGMAC_RDES3_PL);
@@ -349,6 +362,8 @@ const struct stmmac_desc_ops dwxgmac210_desc_ops = {
349362
.set_tx_owner = dwxgmac2_set_tx_owner,
350363
.set_rx_owner = dwxgmac2_set_rx_owner,
351364
.get_tx_ls = dwxgmac2_get_tx_ls,
365+
.get_rx_vlan_tci = dwxgmac2_wrback_get_rx_vlan_tci,
366+
.get_rx_vlan_valid = dwxgmac2_wrback_get_rx_vlan_valid,
352367
.get_rx_frame_len = dwxgmac2_get_rx_frame_len,
353368
.enable_tx_timestamp = dwxgmac2_enable_tx_timestamp,
354369
.get_tx_timestamp_status = dwxgmac2_get_tx_timestamp_status,

0 commit comments

Comments
 (0)