Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

net: stmmac: Implement VLAN Hash Filtering in XGMAC



Implement the VLAN Hash Filtering feature in XGMAC core.

Signed-off-by: default avatarJose Abreu <joabreu@synopsys.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1fbdad00
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -355,6 +355,7 @@ struct dma_features {
	unsigned int frpes;
	unsigned int addr64;
	unsigned int rssen;
	unsigned int vlhash;
};

/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
+10 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@
#define XGMAC_CORE_INIT_RX		0
#define XGMAC_PACKET_FILTER		0x00000008
#define XGMAC_FILTER_RA			BIT(31)
#define XGMAC_FILTER_VTFE		BIT(16)
#define XGMAC_FILTER_HPF		BIT(10)
#define XGMAC_FILTER_PCF		BIT(7)
#define XGMAC_FILTER_PM			BIT(4)
@@ -51,6 +52,14 @@
#define XGMAC_FILTER_PR			BIT(0)
#define XGMAC_HASH_TABLE(x)		(0x00000010 + (x) * 4)
#define XGMAC_MAX_HASH_TABLE		8
#define XGMAC_VLAN_TAG			0x00000050
#define XGMAC_VLAN_EDVLP		BIT(26)
#define XGMAC_VLAN_VTHM			BIT(25)
#define XGMAC_VLAN_DOVLTC		BIT(20)
#define XGMAC_VLAN_ESVL			BIT(18)
#define XGMAC_VLAN_ETV			BIT(16)
#define XGMAC_VLAN_VID			GENMASK(15, 0)
#define XGMAC_VLAN_HASH_TABLE		0x00000058
#define XGMAC_RXQ_CTRL0			0x000000a0
#define XGMAC_RXQEN(x)			GENMASK((x) * 2 + 1, (x) * 2)
#define XGMAC_RXQEN_SHIFT(x)		((x) * 2)
@@ -87,6 +96,7 @@
#define XGMAC_HWFEAT_MMCSEL		BIT(8)
#define XGMAC_HWFEAT_MGKSEL		BIT(7)
#define XGMAC_HWFEAT_RWKSEL		BIT(6)
#define XGMAC_HWFEAT_VLHASH		BIT(4)
#define XGMAC_HWFEAT_GMIISEL		BIT(1)
#define XGMAC_HW_FEATURE1		0x00000120
#define XGMAC_HWFEAT_RSSEN		BIT(20)
+41 −0
Original line number Diff line number Diff line
@@ -490,6 +490,46 @@ static int dwxgmac2_rss_configure(struct mac_device_info *hw,
	return 0;
}

static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash,
				      bool is_double)
{
	void __iomem *ioaddr = hw->pcsr;

	writel(hash, ioaddr + XGMAC_VLAN_HASH_TABLE);

	if (hash) {
		u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);

		value |= XGMAC_FILTER_VTFE;

		writel(value, ioaddr + XGMAC_PACKET_FILTER);

		value |= XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV;
		if (is_double) {
			value |= XGMAC_VLAN_EDVLP;
			value |= XGMAC_VLAN_ESVL;
			value |= XGMAC_VLAN_DOVLTC;
		}

		writel(value, ioaddr + XGMAC_VLAN_TAG);
	} else {
		u32 value = readl(ioaddr + XGMAC_PACKET_FILTER);

		value &= ~XGMAC_FILTER_VTFE;

		writel(value, ioaddr + XGMAC_PACKET_FILTER);

		value = readl(ioaddr + XGMAC_VLAN_TAG);

		value &= ~(XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV);
		value &= ~(XGMAC_VLAN_EDVLP | XGMAC_VLAN_ESVL);
		value &= ~XGMAC_VLAN_DOVLTC;
		value &= ~XGMAC_VLAN_VID;

		writel(value, ioaddr + XGMAC_VLAN_TAG);
	}
}

const struct stmmac_ops dwxgmac210_ops = {
	.core_init = dwxgmac2_core_init,
	.set_mac = dwxgmac2_set_mac,
@@ -521,6 +561,7 @@ const struct stmmac_ops dwxgmac210_ops = {
	.set_filter = dwxgmac2_set_filter,
	.set_mac_loopback = dwxgmac2_set_mac_loopback,
	.rss_configure = dwxgmac2_rss_configure,
	.update_vlan_hash = dwxgmac2_update_vlan_hash,
};

int dwxgmac2_setup(struct stmmac_priv *priv)
+1 −0
Original line number Diff line number Diff line
@@ -359,6 +359,7 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
	dma_cap->rmon = (hw_cap & XGMAC_HWFEAT_MMCSEL) >> 8;
	dma_cap->pmt_magic_frame = (hw_cap & XGMAC_HWFEAT_MGKSEL) >> 7;
	dma_cap->pmt_remote_wake_up = (hw_cap & XGMAC_HWFEAT_RWKSEL) >> 6;
	dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
	dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;

	/* MAC HW feature 1 */
+5 −0
Original line number Diff line number Diff line
@@ -336,6 +336,9 @@ struct stmmac_ops {
	/* RSS */
	int (*rss_configure)(struct mac_device_info *hw,
			     struct stmmac_rss *cfg, u32 num_rxq);
	/* VLAN */
	void (*update_vlan_hash)(struct mac_device_info *hw, u32 hash,
				 bool is_double);
};

#define stmmac_core_init(__priv, __args...) \
@@ -408,6 +411,8 @@ struct stmmac_ops {
	stmmac_do_void_callback(__priv, mac, set_mac_loopback, __args)
#define stmmac_rss_configure(__priv, __args...) \
	stmmac_do_callback(__priv, mac, rss_configure, __args)
#define stmmac_update_vlan_hash(__priv, __args...) \
	stmmac_do_void_callback(__priv, mac, update_vlan_hash, __args)

/* PTP and HW Timer helpers */
struct stmmac_hwtimestamp {
Loading