Commit c1be0022 authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller
Browse files

net: stmmac: Add VLAN HASH filtering support in GMAC4+



Adds the support for VLAN HASH Filtering in GMAC4/5 cores.

Signed-off-by: default avatarJose Abreu <joabreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6fa9d691
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#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_QX_TX_FLOW_CTRL(x)		(0x70 + x * 4)
#define GMAC_TXQ_PRTY_MAP0		0x98
@@ -62,9 +64,18 @@
#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)

/* 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)
+31 −0
Original line number Diff line number Diff line
@@ -731,6 +731,34 @@ 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);
	}
}

const struct stmmac_ops dwmac4_ops = {
	.core_init = dwmac4_core_init,
	.set_mac = stmmac_set_mac,
@@ -761,6 +789,7 @@ 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,
};

const struct stmmac_ops dwmac410_ops = {
@@ -793,6 +822,7 @@ 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,
};

const struct stmmac_ops dwmac510_ops = {
@@ -830,6 +860,7 @@ 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,
};

int dwmac4_setup(struct stmmac_priv *priv)
+1 −1
Original line number Diff line number Diff line
@@ -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;