diff options
author | David S. Miller <davem@davemloft.net> | 2019-09-11 11:21:34 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-09-11 11:21:34 +0300 |
commit | 6d47b4bca4616f0272743009614ca6adc0c9e85f (patch) | |
tree | 7d0066fd8f516bf140e562c84076412ce08db72f | |
parent | e7f13f44c77b68f8c4e6ea77984aa142613a50c9 (diff) | |
parent | c9b10043d0b8c57a75b61649e62f644962516efb (diff) | |
download | linux-6d47b4bca4616f0272743009614ca6adc0c9e85f.tar.xz |
Merge branch 'stmmac-next'
Jose Abreu says:
====================
net: stmmac: Improvements for -next
Misc patches for -next. It includes:
- Two fixes for features in -next only
- New features support for GMAC cores (which includes GMAC4 and GMAC5)
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 79 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 43 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 5 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 |
7 files changed, 162 insertions, 3 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h index 03301ffc0391..89a3420eba42 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h @@ -16,7 +16,10 @@ #define GMAC_CONFIG 0x00000000 #define GMAC_PACKET_FILTER 0x00000008 #define GMAC_HASH_TAB(x) (0x10 + (x) * 4) +#define GMAC_VLAN_TAG 0x00000050 +#define GMAC_VLAN_HASH_TABLE 0x00000058 #define GMAC_RX_FLOW_CTRL 0x00000090 +#define GMAC_VLAN_INCL 0x00000060 #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4) #define GMAC_TXQ_PRTY_MAP0 0x98 #define GMAC_TXQ_PRTY_MAP1 0x9C @@ -37,6 +40,7 @@ #define GMAC_HW_FEATURE3 0x00000128 #define GMAC_MDIO_ADDR 0x00000200 #define GMAC_MDIO_DATA 0x00000204 +#define GMAC_ARP_ADDR 0x00000210 #define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8) #define GMAC_ADDR_LOW(reg) (0x304 + reg * 8) @@ -62,9 +66,22 @@ #define GMAC_PACKET_FILTER_PM BIT(4) #define GMAC_PACKET_FILTER_PCF BIT(7) #define GMAC_PACKET_FILTER_HPF BIT(10) +#define GMAC_PACKET_FILTER_VTFE BIT(16) #define GMAC_MAX_PERFECT_ADDRESSES 128 +/* MAC VLAN */ +#define GMAC_VLAN_EDVLP BIT(26) +#define GMAC_VLAN_VTHM BIT(25) +#define GMAC_VLAN_DOVLTC BIT(20) +#define GMAC_VLAN_ESVL BIT(18) +#define GMAC_VLAN_ETV BIT(16) +#define GMAC_VLAN_VID GENMASK(15, 0) +#define GMAC_VLAN_VLTI BIT(20) +#define GMAC_VLAN_CSVL BIT(19) +#define GMAC_VLAN_VLC GENMASK(17, 16) +#define GMAC_VLAN_VLC_SHIFT 16 + /* MAC RX Queue Enable */ #define GMAC_RX_QUEUE_CLEAR(queue) ~(GENMASK(1, 0) << ((queue) * 2)) #define GMAC_RX_AV_QUEUE_ENABLE(queue) BIT((queue) * 2) @@ -149,6 +166,9 @@ enum power_event { #define GMAC_DEBUG_RPESTS BIT(0) /* MAC config */ +#define GMAC_CONFIG_ARPEN BIT(31) +#define GMAC_CONFIG_SARC GENMASK(30, 28) +#define GMAC_CONFIG_SARC_SHIFT 28 #define GMAC_CONFIG_IPC BIT(27) #define GMAC_CONFIG_2K BIT(22) #define GMAC_CONFIG_ACS BIT(20) @@ -164,11 +184,13 @@ enum power_event { #define GMAC_CONFIG_RE BIT(0) /* MAC HW features0 bitmap */ +#define GMAC_HW_FEAT_SAVLANINS BIT(27) #define GMAC_HW_FEAT_ADDMAC BIT(18) #define GMAC_HW_FEAT_RXCOESEL BIT(16) #define GMAC_HW_FEAT_TXCOSEL BIT(14) #define GMAC_HW_FEAT_EEESEL BIT(13) #define GMAC_HW_FEAT_TSSEL BIT(12) +#define GMAC_HW_FEAT_ARPOFFSEL BIT(9) #define GMAC_HW_FEAT_MMCSEL BIT(8) #define GMAC_HW_FEAT_MGKSEL BIT(7) #define GMAC_HW_FEAT_RWKSEL BIT(6) @@ -198,6 +220,7 @@ enum power_event { #define GMAC_HW_FEAT_FRPES GENMASK(14, 13) #define GMAC_HW_FEAT_FRPBS GENMASK(12, 11) #define GMAC_HW_FEAT_FRPSEL BIT(10) +#define GMAC_HW_FEAT_DVLAN BIT(5) /* MAC HW ADDR regs */ #define GMAC_HI_DCS GENMASK(18, 16) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 596311a80d1c..9b4b5f69fc02 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -731,6 +731,73 @@ static void dwmac4_set_mac_loopback(void __iomem *ioaddr, bool enable) writel(value, ioaddr + GMAC_CONFIG); } +static void dwmac4_update_vlan_hash(struct mac_device_info *hw, u32 hash, + bool is_double) +{ + void __iomem *ioaddr = hw->pcsr; + + writel(hash, ioaddr + GMAC_VLAN_HASH_TABLE); + + if (hash) { + u32 value = GMAC_VLAN_VTHM | GMAC_VLAN_ETV; + if (is_double) { + value |= GMAC_VLAN_EDVLP; + value |= GMAC_VLAN_ESVL; + value |= GMAC_VLAN_DOVLTC; + } + + writel(value, ioaddr + GMAC_VLAN_TAG); + } else { + u32 value = readl(ioaddr + GMAC_VLAN_TAG); + + value &= ~(GMAC_VLAN_VTHM | GMAC_VLAN_ETV); + value &= ~(GMAC_VLAN_EDVLP | GMAC_VLAN_ESVL); + value &= ~GMAC_VLAN_DOVLTC; + value &= ~GMAC_VLAN_VID; + + writel(value, ioaddr + GMAC_VLAN_TAG); + } +} + +static void dwmac4_sarc_configure(void __iomem *ioaddr, int val) +{ + u32 value = readl(ioaddr + GMAC_CONFIG); + + value &= ~GMAC_CONFIG_SARC; + value |= val << GMAC_CONFIG_SARC_SHIFT; + + writel(value, ioaddr + GMAC_CONFIG); +} + +static void dwmac4_enable_vlan(struct mac_device_info *hw, u32 type) +{ + void __iomem *ioaddr = hw->pcsr; + u32 value; + + value = readl(ioaddr + GMAC_VLAN_INCL); + value |= GMAC_VLAN_VLTI; + value |= GMAC_VLAN_CSVL; /* Only use SVLAN */ + value &= ~GMAC_VLAN_VLC; + value |= (type << GMAC_VLAN_VLC_SHIFT) & GMAC_VLAN_VLC; + writel(value, ioaddr + GMAC_VLAN_INCL); +} + +static void dwmac4_set_arp_offload(struct mac_device_info *hw, bool en, + u32 addr) +{ + void __iomem *ioaddr = hw->pcsr; + u32 value; + + writel(addr, ioaddr + GMAC_ARP_ADDR); + + value = readl(ioaddr + GMAC_CONFIG); + if (en) + value |= GMAC_CONFIG_ARPEN; + else + value &= ~GMAC_CONFIG_ARPEN; + writel(value, ioaddr + GMAC_CONFIG); +} + const struct stmmac_ops dwmac4_ops = { .core_init = dwmac4_core_init, .set_mac = stmmac_set_mac, @@ -761,6 +828,10 @@ const struct stmmac_ops dwmac4_ops = { .debug = dwmac4_debug, .set_filter = dwmac4_set_filter, .set_mac_loopback = dwmac4_set_mac_loopback, + .update_vlan_hash = dwmac4_update_vlan_hash, + .sarc_configure = dwmac4_sarc_configure, + .enable_vlan = dwmac4_enable_vlan, + .set_arp_offload = dwmac4_set_arp_offload, }; const struct stmmac_ops dwmac410_ops = { @@ -793,6 +864,10 @@ const struct stmmac_ops dwmac410_ops = { .debug = dwmac4_debug, .set_filter = dwmac4_set_filter, .set_mac_loopback = dwmac4_set_mac_loopback, + .update_vlan_hash = dwmac4_update_vlan_hash, + .sarc_configure = dwmac4_sarc_configure, + .enable_vlan = dwmac4_enable_vlan, + .set_arp_offload = dwmac4_set_arp_offload, }; const struct stmmac_ops dwmac510_ops = { @@ -830,6 +905,10 @@ const struct stmmac_ops dwmac510_ops = { .rxp_config = dwmac5_rxp_config, .flex_pps_config = dwmac5_flex_pps_config, .set_mac_loopback = dwmac4_set_mac_loopback, + .update_vlan_hash = dwmac4_update_vlan_hash, + .sarc_configure = dwmac4_sarc_configure, + .enable_vlan = dwmac4_enable_vlan, + .set_arp_offload = dwmac4_set_arp_offload, }; int dwmac4_setup(struct stmmac_priv *priv) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c index dbde23e7e169..15eb1abba91d 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c @@ -443,6 +443,13 @@ static void dwmac4_clear(struct dma_desc *p) p->des3 = 0; } +static void dwmac4_set_sarc(struct dma_desc *p, u32 sarc_type) +{ + sarc_type <<= TDES3_SA_INSERT_CTRL_SHIFT; + + p->des3 |= cpu_to_le32(sarc_type & TDES3_SA_INSERT_CTRL_MASK); +} + static int set_16kib_bfsize(int mtu) { int ret = 0; @@ -452,6 +459,39 @@ static int set_16kib_bfsize(int mtu) return ret; } +static void dwmac4_set_vlan_tag(struct dma_desc *p, u16 tag, u16 inner_tag, + u32 inner_type) +{ + p->des0 = 0; + p->des1 = 0; + p->des2 = 0; + p->des3 = 0; + + /* Inner VLAN */ + if (inner_type) { + u32 des = inner_tag << TDES2_IVT_SHIFT; + + des &= TDES2_IVT_MASK; + p->des2 = cpu_to_le32(des); + + des = inner_type << TDES3_IVTIR_SHIFT; + des &= TDES3_IVTIR_MASK; + p->des3 = cpu_to_le32(des | TDES3_IVLTV); + } + + /* Outer VLAN */ + p->des3 |= cpu_to_le32(tag & TDES3_VLAN_TAG); + p->des3 |= cpu_to_le32(TDES3_VLTV); + + p->des3 |= cpu_to_le32(TDES3_CONTEXT_TYPE); +} + +static void dwmac4_set_vlan(struct dma_desc *p, u32 type) +{ + type <<= TDES2_VLAN_TAG_SHIFT; + p->des2 |= cpu_to_le32(type & TDES2_VLAN_TAG_MASK); +} + const struct stmmac_desc_ops dwmac4_desc_ops = { .tx_status = dwmac4_wrback_get_tx_status, .rx_status = dwmac4_wrback_get_rx_status, @@ -476,6 +516,9 @@ const struct stmmac_desc_ops dwmac4_desc_ops = { .get_addr = dwmac4_get_addr, .set_addr = dwmac4_set_addr, .clear = dwmac4_clear, + .set_sarc = dwmac4_set_sarc, + .set_vlan_tag = dwmac4_set_vlan_tag, + .set_vlan = dwmac4_set_vlan, }; const struct stmmac_mode_ops dwmac4_ring_mode_ops = { diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h index f58191174287..0d7b3bbcd5a7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.h @@ -18,13 +18,21 @@ /* TDES2 (read format) */ #define TDES2_BUFFER1_SIZE_MASK GENMASK(13, 0) #define TDES2_VLAN_TAG_MASK GENMASK(15, 14) +#define TDES2_VLAN_TAG_SHIFT 14 #define TDES2_BUFFER2_SIZE_MASK GENMASK(29, 16) #define TDES2_BUFFER2_SIZE_MASK_SHIFT 16 +#define TDES3_IVTIR_MASK GENMASK(19, 18) +#define TDES3_IVTIR_SHIFT 18 +#define TDES3_IVLTV BIT(17) #define TDES2_TIMESTAMP_ENABLE BIT(30) +#define TDES2_IVT_MASK GENMASK(31, 16) +#define TDES2_IVT_SHIFT 16 #define TDES2_INTERRUPT_ON_COMPLETION BIT(31) /* TDES3 (read format) */ #define TDES3_PACKET_SIZE_MASK GENMASK(14, 0) +#define TDES3_VLAN_TAG GENMASK(15, 0) +#define TDES3_VLTV BIT(16) #define TDES3_CHECKSUM_INSERTION_MASK GENMASK(17, 16) #define TDES3_CHECKSUM_INSERTION_SHIFT 16 #define TDES3_TCP_PKT_PAYLOAD_MASK GENMASK(17, 0) @@ -32,6 +40,7 @@ #define TDES3_HDR_LEN_SHIFT 19 #define TDES3_SLOT_NUMBER_MASK GENMASK(22, 19) #define TDES3_SA_INSERT_CTRL_MASK GENMASK(25, 23) +#define TDES3_SA_INSERT_CTRL_SHIFT 23 #define TDES3_CRC_PAD_CTRL_MASK GENMASK(27, 26) /* TDES3 (write back format) */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c index 3ed5508586ef..68c157979b94 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c @@ -333,7 +333,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr, dma_cap->mbps_10_100 = (hw_cap & GMAC_HW_FEAT_MIISEL); dma_cap->mbps_1000 = (hw_cap & GMAC_HW_FEAT_GMIISEL) >> 1; dma_cap->half_duplex = (hw_cap & GMAC_HW_FEAT_HDSEL) >> 2; - dma_cap->hash_filter = (hw_cap & GMAC_HW_FEAT_VLHASH) >> 4; + dma_cap->vlhash = (hw_cap & GMAC_HW_FEAT_VLHASH) >> 4; dma_cap->multi_addr = (hw_cap & GMAC_HW_FEAT_ADDMAC) >> 18; dma_cap->pcs = (hw_cap & GMAC_HW_FEAT_PCSSEL) >> 3; dma_cap->sma_mdio = (hw_cap & GMAC_HW_FEAT_SMASEL) >> 5; @@ -348,6 +348,8 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr, /* TX and RX csum */ dma_cap->tx_coe = (hw_cap & GMAC_HW_FEAT_TXCOSEL) >> 14; dma_cap->rx_coe = (hw_cap & GMAC_HW_FEAT_RXCOESEL) >> 16; + dma_cap->vlins = (hw_cap & GMAC_HW_FEAT_SAVLANINS) >> 27; + dma_cap->arpoffsel = (hw_cap & GMAC_HW_FEAT_ARPOFFSEL) >> 9; /* MAC HW feature1 */ hw_cap = readl(ioaddr + GMAC_HW_FEATURE1); @@ -385,6 +387,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr, dma_cap->frpes = (hw_cap & GMAC_HW_FEAT_FRPES) >> 13; dma_cap->frpbs = (hw_cap & GMAC_HW_FEAT_FRPBS) >> 11; dma_cap->frpsel = (hw_cap & GMAC_HW_FEAT_FRPSEL) >> 10; + dma_cap->dvlan = (hw_cap & GMAC_HW_FEAT_DVLAN) >> 5; } /* Enable/disable TSO feature and set MSS */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c index 78ac659da279..d5173dd02a71 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c @@ -568,7 +568,7 @@ static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash, writel(value, ioaddr + XGMAC_PACKET_FILTER); - value |= XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV; + value = XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV; if (is_double) { value |= XGMAC_VLAN_EDVLP; value |= XGMAC_VLAN_ESVL; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 686b82068142..6e44013b20cc 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3418,7 +3418,9 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue) stmmac_refill_desc3(priv, rx_q, p); rx_q->rx_count_frames++; - rx_q->rx_count_frames %= priv->rx_coal_frames; + rx_q->rx_count_frames += priv->rx_coal_frames; + if (rx_q->rx_count_frames > priv->rx_coal_frames) + rx_q->rx_count_frames = 0; use_rx_wd = priv->use_riwt && rx_q->rx_count_frames; dma_wmb(); |