Skip to content

Commit e94e3f3

Browse files
joabreudavem330
authored andcommitted
net: stmmac: Add support for VLAN Insertion Offload in GMAC4+
Adds support for TX VLAN Offload using descriptors based features available in GMAC4/5. Signed-off-by: Jose Abreu <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1d982e9 commit e94e3f3

File tree

5 files changed

+66
-0
lines changed

5 files changed

+66
-0
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define GMAC_VLAN_TAG 0x00000050
2020
#define GMAC_VLAN_HASH_TABLE 0x00000058
2121
#define GMAC_RX_FLOW_CTRL 0x00000090
22+
#define GMAC_VLAN_INCL 0x00000060
2223
#define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
2324
#define GMAC_TXQ_PRTY_MAP0 0x98
2425
#define GMAC_TXQ_PRTY_MAP1 0x9C
@@ -75,6 +76,10 @@
7576
#define GMAC_VLAN_ESVL BIT(18)
7677
#define GMAC_VLAN_ETV BIT(16)
7778
#define GMAC_VLAN_VID GENMASK(15, 0)
79+
#define GMAC_VLAN_VLTI BIT(20)
80+
#define GMAC_VLAN_CSVL BIT(19)
81+
#define GMAC_VLAN_VLC GENMASK(17, 16)
82+
#define GMAC_VLAN_VLC_SHIFT 16
7883

7984
/* MAC RX Queue Enable */
8085
#define GMAC_RX_QUEUE_CLEAR(queue) ~(GENMASK(1, 0) << ((queue) * 2))
@@ -212,6 +217,7 @@ enum power_event {
212217
#define GMAC_HW_FEAT_FRPES GENMASK(14, 13)
213218
#define GMAC_HW_FEAT_FRPBS GENMASK(12, 11)
214219
#define GMAC_HW_FEAT_FRPSEL BIT(10)
220+
#define GMAC_HW_FEAT_DVLAN BIT(5)
215221

216222
/* MAC HW ADDR regs */
217223
#define GMAC_HI_DCS GENMASK(18, 16)

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,19 @@ static void dwmac4_sarc_configure(void __iomem *ioaddr, int val)
769769
writel(value, ioaddr + GMAC_CONFIG);
770770
}
771771

772+
static void dwmac4_enable_vlan(struct mac_device_info *hw, u32 type)
773+
{
774+
void __iomem *ioaddr = hw->pcsr;
775+
u32 value;
776+
777+
value = readl(ioaddr + GMAC_VLAN_INCL);
778+
value |= GMAC_VLAN_VLTI;
779+
value |= GMAC_VLAN_CSVL; /* Only use SVLAN */
780+
value &= ~GMAC_VLAN_VLC;
781+
value |= (type << GMAC_VLAN_VLC_SHIFT) & GMAC_VLAN_VLC;
782+
writel(value, ioaddr + GMAC_VLAN_INCL);
783+
}
784+
772785
const struct stmmac_ops dwmac4_ops = {
773786
.core_init = dwmac4_core_init,
774787
.set_mac = stmmac_set_mac,
@@ -801,6 +814,7 @@ const struct stmmac_ops dwmac4_ops = {
801814
.set_mac_loopback = dwmac4_set_mac_loopback,
802815
.update_vlan_hash = dwmac4_update_vlan_hash,
803816
.sarc_configure = dwmac4_sarc_configure,
817+
.enable_vlan = dwmac4_enable_vlan,
804818
};
805819

806820
const struct stmmac_ops dwmac410_ops = {
@@ -835,6 +849,7 @@ const struct stmmac_ops dwmac410_ops = {
835849
.set_mac_loopback = dwmac4_set_mac_loopback,
836850
.update_vlan_hash = dwmac4_update_vlan_hash,
837851
.sarc_configure = dwmac4_sarc_configure,
852+
.enable_vlan = dwmac4_enable_vlan,
838853
};
839854

840855
const struct stmmac_ops dwmac510_ops = {
@@ -874,6 +889,7 @@ const struct stmmac_ops dwmac510_ops = {
874889
.set_mac_loopback = dwmac4_set_mac_loopback,
875890
.update_vlan_hash = dwmac4_update_vlan_hash,
876891
.sarc_configure = dwmac4_sarc_configure,
892+
.enable_vlan = dwmac4_enable_vlan,
877893
};
878894

879895
int dwmac4_setup(struct stmmac_priv *priv)

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,39 @@ static int set_16kib_bfsize(int mtu)
459459
return ret;
460460
}
461461

462+
static void dwmac4_set_vlan_tag(struct dma_desc *p, u16 tag, u16 inner_tag,
463+
u32 inner_type)
464+
{
465+
p->des0 = 0;
466+
p->des1 = 0;
467+
p->des2 = 0;
468+
p->des3 = 0;
469+
470+
/* Inner VLAN */
471+
if (inner_type) {
472+
u32 des = inner_tag << TDES2_IVT_SHIFT;
473+
474+
des &= TDES2_IVT_MASK;
475+
p->des2 = cpu_to_le32(des);
476+
477+
des = inner_type << TDES3_IVTIR_SHIFT;
478+
des &= TDES3_IVTIR_MASK;
479+
p->des3 = cpu_to_le32(des | TDES3_IVLTV);
480+
}
481+
482+
/* Outer VLAN */
483+
p->des3 |= cpu_to_le32(tag & TDES3_VLAN_TAG);
484+
p->des3 |= cpu_to_le32(TDES3_VLTV);
485+
486+
p->des3 |= cpu_to_le32(TDES3_CONTEXT_TYPE);
487+
}
488+
489+
static void dwmac4_set_vlan(struct dma_desc *p, u32 type)
490+
{
491+
type <<= TDES2_VLAN_TAG_SHIFT;
492+
p->des2 |= cpu_to_le32(type & TDES2_VLAN_TAG_MASK);
493+
}
494+
462495
const struct stmmac_desc_ops dwmac4_desc_ops = {
463496
.tx_status = dwmac4_wrback_get_tx_status,
464497
.rx_status = dwmac4_wrback_get_rx_status,
@@ -484,6 +517,8 @@ const struct stmmac_desc_ops dwmac4_desc_ops = {
484517
.set_addr = dwmac4_set_addr,
485518
.clear = dwmac4_clear,
486519
.set_sarc = dwmac4_set_sarc,
520+
.set_vlan_tag = dwmac4_set_vlan_tag,
521+
.set_vlan = dwmac4_set_vlan,
487522
};
488523

489524
const struct stmmac_mode_ops dwmac4_ring_mode_ops = {

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,21 @@
1818
/* TDES2 (read format) */
1919
#define TDES2_BUFFER1_SIZE_MASK GENMASK(13, 0)
2020
#define TDES2_VLAN_TAG_MASK GENMASK(15, 14)
21+
#define TDES2_VLAN_TAG_SHIFT 14
2122
#define TDES2_BUFFER2_SIZE_MASK GENMASK(29, 16)
2223
#define TDES2_BUFFER2_SIZE_MASK_SHIFT 16
24+
#define TDES3_IVTIR_MASK GENMASK(19, 18)
25+
#define TDES3_IVTIR_SHIFT 18
26+
#define TDES3_IVLTV BIT(17)
2327
#define TDES2_TIMESTAMP_ENABLE BIT(30)
28+
#define TDES2_IVT_MASK GENMASK(31, 16)
29+
#define TDES2_IVT_SHIFT 16
2430
#define TDES2_INTERRUPT_ON_COMPLETION BIT(31)
2531

2632
/* TDES3 (read format) */
2733
#define TDES3_PACKET_SIZE_MASK GENMASK(14, 0)
34+
#define TDES3_VLAN_TAG GENMASK(15, 0)
35+
#define TDES3_VLTV BIT(16)
2836
#define TDES3_CHECKSUM_INSERTION_MASK GENMASK(17, 16)
2937
#define TDES3_CHECKSUM_INSERTION_SHIFT 16
3038
#define TDES3_TCP_PKT_PAYLOAD_MASK GENMASK(17, 0)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
386386
dma_cap->frpes = (hw_cap & GMAC_HW_FEAT_FRPES) >> 13;
387387
dma_cap->frpbs = (hw_cap & GMAC_HW_FEAT_FRPBS) >> 11;
388388
dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10;
389+
dma_cap->dvlan = (hw_cap & GMAC_HW_FEAT_DVLAN) >> 5;
389390
}
390391

391392
/* Enable/disable TSO feature and set MSS */

0 commit comments

Comments
 (0)