Commit dc07f5fd authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller

net: stmmac: Implement L3/L4 Filters in GMAC4+

GMAC4+ cores support Layer 3 and Layer 4 filtering. Add the
corresponding callbacks in these cores.
Signed-off-by: default avatarJose Abreu <joabreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1b2250a0
...@@ -43,6 +43,10 @@ ...@@ -43,6 +43,10 @@
#define GMAC_ARP_ADDR 0x00000210 #define GMAC_ARP_ADDR 0x00000210
#define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8) #define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8)
#define GMAC_ADDR_LOW(reg) (0x304 + reg * 8) #define GMAC_ADDR_LOW(reg) (0x304 + reg * 8)
#define GMAC_L3L4_CTRL(reg) (0x900 + (reg) * 0x30)
#define GMAC_L4_ADDR(reg) (0x904 + (reg) * 0x30)
#define GMAC_L3_ADDR0(reg) (0x910 + (reg) * 0x30)
#define GMAC_L3_ADDR1(reg) (0x914 + (reg) * 0x30)
/* RX Queues Routing */ /* RX Queues Routing */
#define GMAC_RXQCTRL_AVCPQ_MASK GENMASK(2, 0) #define GMAC_RXQCTRL_AVCPQ_MASK GENMASK(2, 0)
...@@ -67,6 +71,7 @@ ...@@ -67,6 +71,7 @@
#define GMAC_PACKET_FILTER_PCF BIT(7) #define GMAC_PACKET_FILTER_PCF BIT(7)
#define GMAC_PACKET_FILTER_HPF BIT(10) #define GMAC_PACKET_FILTER_HPF BIT(10)
#define GMAC_PACKET_FILTER_VTFE BIT(16) #define GMAC_PACKET_FILTER_VTFE BIT(16)
#define GMAC_PACKET_FILTER_IPFE BIT(20)
#define GMAC_MAX_PERFECT_ADDRESSES 128 #define GMAC_MAX_PERFECT_ADDRESSES 128
...@@ -202,6 +207,7 @@ enum power_event { ...@@ -202,6 +207,7 @@ enum power_event {
#define GMAC_HW_FEAT_MIISEL BIT(0) #define GMAC_HW_FEAT_MIISEL BIT(0)
/* MAC HW features1 bitmap */ /* MAC HW features1 bitmap */
#define GMAC_HW_FEAT_L3L4FNUM GENMASK(30, 27)
#define GMAC_HW_HASH_TB_SZ GENMASK(25, 24) #define GMAC_HW_HASH_TB_SZ GENMASK(25, 24)
#define GMAC_HW_FEAT_AVSEL BIT(20) #define GMAC_HW_FEAT_AVSEL BIT(20)
#define GMAC_HW_TSOEN BIT(18) #define GMAC_HW_TSOEN BIT(18)
...@@ -228,6 +234,21 @@ enum power_event { ...@@ -228,6 +234,21 @@ enum power_event {
#define GMAC_HI_DCS_SHIFT 16 #define GMAC_HI_DCS_SHIFT 16
#define GMAC_HI_REG_AE BIT(31) #define GMAC_HI_REG_AE BIT(31)
/* L3/L4 Filters regs */
#define GMAC_L4DPIM0 BIT(21)
#define GMAC_L4DPM0 BIT(20)
#define GMAC_L4SPIM0 BIT(19)
#define GMAC_L4SPM0 BIT(18)
#define GMAC_L4PEN0 BIT(16)
#define GMAC_L3DAIM0 BIT(5)
#define GMAC_L3DAM0 BIT(4)
#define GMAC_L3SAIM0 BIT(3)
#define GMAC_L3SAM0 BIT(2)
#define GMAC_L3PEN0 BIT(0)
#define GMAC_L4DP0 GENMASK(31, 16)
#define GMAC_L4DP0_SHIFT 16
#define GMAC_L4SP0 GENMASK(15, 0)
/* MTL registers */ /* MTL registers */
#define MTL_OPERATION_MODE 0x00000c00 #define MTL_OPERATION_MODE 0x00000c00
#define MTL_FRPE BIT(15) #define MTL_FRPE BIT(15)
......
...@@ -809,6 +809,106 @@ static void dwmac4_set_arp_offload(struct mac_device_info *hw, bool en, ...@@ -809,6 +809,106 @@ static void dwmac4_set_arp_offload(struct mac_device_info *hw, bool en,
writel(value, ioaddr + GMAC_CONFIG); writel(value, ioaddr + GMAC_CONFIG);
} }
static int dwmac4_config_l3_filter(struct mac_device_info *hw, u32 filter_no,
bool en, bool ipv6, bool sa, bool inv,
u32 match)
{
void __iomem *ioaddr = hw->pcsr;
u32 value;
value = readl(ioaddr + GMAC_PACKET_FILTER);
value |= GMAC_PACKET_FILTER_IPFE;
writel(value, ioaddr + GMAC_PACKET_FILTER);
value = readl(ioaddr + GMAC_L3L4_CTRL(filter_no));
/* For IPv6 not both SA/DA filters can be active */
if (ipv6) {
value |= GMAC_L3PEN0;
value &= ~(GMAC_L3SAM0 | GMAC_L3SAIM0);
value &= ~(GMAC_L3DAM0 | GMAC_L3DAIM0);
if (sa) {
value |= GMAC_L3SAM0;
if (inv)
value |= GMAC_L3SAIM0;
} else {
value |= GMAC_L3DAM0;
if (inv)
value |= GMAC_L3DAIM0;
}
} else {
value &= ~GMAC_L3PEN0;
if (sa) {
value |= GMAC_L3SAM0;
if (inv)
value |= GMAC_L3SAIM0;
} else {
value |= GMAC_L3DAM0;
if (inv)
value |= GMAC_L3DAIM0;
}
}
writel(value, ioaddr + GMAC_L3L4_CTRL(filter_no));
if (sa) {
writel(match, ioaddr + GMAC_L3_ADDR0(filter_no));
} else {
writel(match, ioaddr + GMAC_L3_ADDR1(filter_no));
}
if (!en)
writel(0, ioaddr + GMAC_L3L4_CTRL(filter_no));
return 0;
}
static int dwmac4_config_l4_filter(struct mac_device_info *hw, u32 filter_no,
bool en, bool udp, bool sa, bool inv,
u32 match)
{
void __iomem *ioaddr = hw->pcsr;
u32 value;
value = readl(ioaddr + GMAC_PACKET_FILTER);
value |= GMAC_PACKET_FILTER_IPFE;
writel(value, ioaddr + GMAC_PACKET_FILTER);
value = readl(ioaddr + GMAC_L3L4_CTRL(filter_no));
if (udp) {
value |= GMAC_L4PEN0;
} else {
value &= ~GMAC_L4PEN0;
}
value &= ~(GMAC_L4SPM0 | GMAC_L4SPIM0);
value &= ~(GMAC_L4DPM0 | GMAC_L4DPIM0);
if (sa) {
value |= GMAC_L4SPM0;
if (inv)
value |= GMAC_L4SPIM0;
} else {
value |= GMAC_L4DPM0;
if (inv)
value |= GMAC_L4DPIM0;
}
writel(value, ioaddr + GMAC_L3L4_CTRL(filter_no));
if (sa) {
value = match & GMAC_L4SP0;
} else {
value = (match << GMAC_L4DP0_SHIFT) & GMAC_L4DP0;
}
writel(value, ioaddr + GMAC_L4_ADDR(filter_no));
if (!en)
writel(0, ioaddr + GMAC_L3L4_CTRL(filter_no));
return 0;
}
const struct stmmac_ops dwmac4_ops = { const struct stmmac_ops dwmac4_ops = {
.core_init = dwmac4_core_init, .core_init = dwmac4_core_init,
.set_mac = stmmac_set_mac, .set_mac = stmmac_set_mac,
...@@ -843,6 +943,8 @@ const struct stmmac_ops dwmac4_ops = { ...@@ -843,6 +943,8 @@ const struct stmmac_ops dwmac4_ops = {
.sarc_configure = dwmac4_sarc_configure, .sarc_configure = dwmac4_sarc_configure,
.enable_vlan = dwmac4_enable_vlan, .enable_vlan = dwmac4_enable_vlan,
.set_arp_offload = dwmac4_set_arp_offload, .set_arp_offload = dwmac4_set_arp_offload,
.config_l3_filter = dwmac4_config_l3_filter,
.config_l4_filter = dwmac4_config_l4_filter,
}; };
const struct stmmac_ops dwmac410_ops = { const struct stmmac_ops dwmac410_ops = {
...@@ -879,6 +981,8 @@ const struct stmmac_ops dwmac410_ops = { ...@@ -879,6 +981,8 @@ const struct stmmac_ops dwmac410_ops = {
.sarc_configure = dwmac4_sarc_configure, .sarc_configure = dwmac4_sarc_configure,
.enable_vlan = dwmac4_enable_vlan, .enable_vlan = dwmac4_enable_vlan,
.set_arp_offload = dwmac4_set_arp_offload, .set_arp_offload = dwmac4_set_arp_offload,
.config_l3_filter = dwmac4_config_l3_filter,
.config_l4_filter = dwmac4_config_l4_filter,
}; };
const struct stmmac_ops dwmac510_ops = { const struct stmmac_ops dwmac510_ops = {
...@@ -920,6 +1024,8 @@ const struct stmmac_ops dwmac510_ops = { ...@@ -920,6 +1024,8 @@ const struct stmmac_ops dwmac510_ops = {
.sarc_configure = dwmac4_sarc_configure, .sarc_configure = dwmac4_sarc_configure,
.enable_vlan = dwmac4_enable_vlan, .enable_vlan = dwmac4_enable_vlan,
.set_arp_offload = dwmac4_set_arp_offload, .set_arp_offload = dwmac4_set_arp_offload,
.config_l3_filter = dwmac4_config_l3_filter,
.config_l4_filter = dwmac4_config_l4_filter,
}; };
int dwmac4_setup(struct stmmac_priv *priv) int dwmac4_setup(struct stmmac_priv *priv)
......
...@@ -364,6 +364,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr, ...@@ -364,6 +364,7 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
/* MAC HW feature1 */ /* MAC HW feature1 */
hw_cap = readl(ioaddr + GMAC_HW_FEATURE1); hw_cap = readl(ioaddr + GMAC_HW_FEATURE1);
dma_cap->l3l4fnum = (hw_cap & GMAC_HW_FEAT_L3L4FNUM) >> 27;
dma_cap->hash_tb_sz = (hw_cap & GMAC_HW_HASH_TB_SZ) >> 24; dma_cap->hash_tb_sz = (hw_cap & GMAC_HW_HASH_TB_SZ) >> 24;
dma_cap->av = (hw_cap & GMAC_HW_FEAT_AVSEL) >> 20; dma_cap->av = (hw_cap & GMAC_HW_FEAT_AVSEL) >> 20;
dma_cap->tsoen = (hw_cap & GMAC_HW_TSOEN) >> 18; dma_cap->tsoen = (hw_cap & GMAC_HW_TSOEN) >> 18;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment