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

net: stmmac: Implement RSS and enable it in XGMAC core



Implement the RSS functionality and add the corresponding callbacks in
XGMAC core.

Changes from v1:
	- Do not use magic constants (Jakub)
	- Use ethtool_rxfh_indir_default() (Jakub)

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

/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
@@ -381,6 +382,10 @@ struct dma_features {

#define JUMBO_LEN		9000

/* Receive Side Scaling */
#define STMMAC_RSS_HASH_KEY_SIZE	40
#define STMMAC_RSS_MAX_TABLE_SIZE	256

extern const struct stmmac_desc_ops enh_desc_ops;
extern const struct stmmac_desc_ops ndesc_ops;

+21 −1
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@
#define XGMAC_HWFEAT_RWKSEL		BIT(6)
#define XGMAC_HWFEAT_GMIISEL		BIT(1)
#define XGMAC_HW_FEATURE1		0x00000120
#define XGMAC_HWFEAT_RSSEN		BIT(20)
#define XGMAC_HWFEAT_TSOEN		BIT(18)
#define XGMAC_HWFEAT_ADDR64		GENMASK(15, 14)
#define XGMAC_HWFEAT_TXFIFOSIZE		GENMASK(10, 6)
@@ -109,6 +110,17 @@
#define XGMAC_DCS_SHIFT			16
#define XGMAC_ADDRx_LOW(x)		(0x00000304 + (x) * 0x8)
#define XGMAC_ARP_ADDR			0x00000c10
#define XGMAC_RSS_CTRL			0x00000c80
#define XGMAC_UDP4TE			BIT(3)
#define XGMAC_TCP4TE			BIT(2)
#define XGMAC_IP2TE			BIT(1)
#define XGMAC_RSSE			BIT(0)
#define XGMAC_RSS_ADDR			0x00000c88
#define XGMAC_RSSIA_SHIFT		8
#define XGMAC_ADDRT			BIT(2)
#define XGMAC_CT			BIT(1)
#define XGMAC_OB			BIT(0)
#define XGMAC_RSS_DATA			0x00000c8c
#define XGMAC_TIMESTAMP_STATUS		0x00000d20
#define XGMAC_TXTSC			BIT(15)
#define XGMAC_TXTIMESTAMP_NSEC		0x00000d30
@@ -125,8 +137,9 @@
#define XGMAC_MTL_INT_STATUS		0x00001020
#define XGMAC_MTL_RXQ_DMA_MAP0		0x00001030
#define XGMAC_MTL_RXQ_DMA_MAP1		0x00001034
#define XGMAC_QxMDMACH(x)		GENMASK((x) * 8 + 3, (x) * 8)
#define XGMAC_QxMDMACH(x)		GENMASK((x) * 8 + 7, (x) * 8)
#define XGMAC_QxMDMACH_SHIFT(x)		((x) * 8)
#define XGMAC_QDDMACH			BIT(7)
#define XGMAC_TC_PRTY_MAP0		0x00001040
#define XGMAC_TC_PRTY_MAP1		0x00001044
#define XGMAC_PSTC(x)			GENMASK((x) * 8 + 7, (x) * 8)
@@ -261,6 +274,13 @@
#define XGMAC_RDES3_IOC			BIT(30)
#define XGMAC_RDES3_LD			BIT(28)
#define XGMAC_RDES3_CDA			BIT(27)
#define XGMAC_RDES3_RSV			BIT(26)
#define XGMAC_RDES3_L34T		GENMASK(23, 20)
#define XGMAC_RDES3_L34T_SHIFT		20
#define XGMAC_L34T_IP4TCP		0x1
#define XGMAC_L34T_IP4UDP		0x2
#define XGMAC_L34T_IP6TCP		0x9
#define XGMAC_L34T_IP6UDP		0xA
#define XGMAC_RDES3_ES			BIT(15)
#define XGMAC_RDES3_PL			GENMASK(13, 0)
#define XGMAC_RDES3_TSD			BIT(6)
+52 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@

#include <linux/bitrev.h>
#include <linux/crc32.h>
#include <linux/iopoll.h>
#include "stmmac.h"
#include "dwxgmac2.h"

@@ -439,6 +440,56 @@ static void dwxgmac2_set_mac_loopback(void __iomem *ioaddr, bool enable)
	writel(value, ioaddr + XGMAC_RX_CONFIG);
}

static int dwxgmac2_rss_write_reg(void __iomem *ioaddr, bool is_key, int idx,
				  u32 val)
{
	u32 ctrl = 0;

	writel(val, ioaddr + XGMAC_RSS_DATA);
	ctrl |= idx << XGMAC_RSSIA_SHIFT;
	ctrl |= is_key ? XGMAC_ADDRT : 0x0;
	ctrl |= XGMAC_OB;
	writel(ctrl, ioaddr + XGMAC_RSS_ADDR);

	return readl_poll_timeout(ioaddr + XGMAC_RSS_ADDR, ctrl,
				  !(ctrl & XGMAC_OB), 100, 10000);
}

static int dwxgmac2_rss_configure(struct mac_device_info *hw,
				  struct stmmac_rss *cfg, u32 num_rxq)
{
	void __iomem *ioaddr = hw->pcsr;
	u32 *key = (u32 *)cfg->key;
	int i, ret;
	u32 value;

	value = readl(ioaddr + XGMAC_RSS_CTRL);
	if (!cfg->enable) {
		value &= ~XGMAC_RSSE;
		writel(value, ioaddr + XGMAC_RSS_CTRL);
		return 0;
	}

	for (i = 0; i < (sizeof(cfg->key) / sizeof(u32)); i++) {
		ret = dwxgmac2_rss_write_reg(ioaddr, true, i, *key++);
		if (ret)
			return ret;
	}

	for (i = 0; i < ARRAY_SIZE(cfg->table); i++) {
		ret = dwxgmac2_rss_write_reg(ioaddr, false, i, cfg->table[i]);
		if (ret)
			return ret;
	}

	for (i = 0; i < num_rxq; i++)
		dwxgmac2_map_mtl_to_dma(hw, i, XGMAC_QDDMACH);

	value |= XGMAC_UDP4TE | XGMAC_TCP4TE | XGMAC_IP2TE | XGMAC_RSSE;
	writel(value, ioaddr + XGMAC_RSS_CTRL);
	return 0;
}

const struct stmmac_ops dwxgmac210_ops = {
	.core_init = dwxgmac2_core_init,
	.set_mac = dwxgmac2_set_mac,
@@ -469,6 +520,7 @@ const struct stmmac_ops dwxgmac210_ops = {
	.debug = NULL,
	.set_filter = dwxgmac2_set_filter,
	.set_mac_loopback = dwxgmac2_set_mac_loopback,
	.rss_configure = dwxgmac2_rss_configure,
};

int dwxgmac2_setup(struct stmmac_priv *priv)
+29 −0
Original line number Diff line number Diff line
@@ -254,6 +254,34 @@ static void dwxgmac2_clear(struct dma_desc *p)
	p->des3 = 0;
}

static int dwxgmac2_get_rx_hash(struct dma_desc *p, u32 *hash,
				enum pkt_hash_types *type)
{
	unsigned int rdes3 = le32_to_cpu(p->des3);
	u32 ptype;

	if (rdes3 & XGMAC_RDES3_RSV) {
		ptype = (rdes3 & XGMAC_RDES3_L34T) >> XGMAC_RDES3_L34T_SHIFT;

		switch (ptype) {
		case XGMAC_L34T_IP4TCP:
		case XGMAC_L34T_IP4UDP:
		case XGMAC_L34T_IP6TCP:
		case XGMAC_L34T_IP6UDP:
			*type = PKT_HASH_TYPE_L4;
			break;
		default:
			*type = PKT_HASH_TYPE_L3;
			break;
		}

		*hash = le32_to_cpu(p->des1);
		return 0;
	}

	return -EINVAL;
}

const struct stmmac_desc_ops dwxgmac210_desc_ops = {
	.tx_status = dwxgmac2_get_tx_status,
	.rx_status = dwxgmac2_get_rx_status,
@@ -277,4 +305,5 @@ const struct stmmac_desc_ops dwxgmac210_desc_ops = {
	.get_addr = dwxgmac2_get_addr,
	.set_addr = dwxgmac2_set_addr,
	.clear = dwxgmac2_clear,
	.get_rx_hash = dwxgmac2_get_rx_hash,
};
+1 −0
Original line number Diff line number Diff line
@@ -363,6 +363,7 @@ static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,

	/* MAC HW feature 1 */
	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
	dma_cap->rssen = (hw_cap & XGMAC_HWFEAT_RSSEN) >> 20;
	dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18;

	dma_cap->addr64 = (hw_cap & XGMAC_HWFEAT_ADDR64) >> 14;
Loading