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

Commit 892311f6 authored by Eyal Perry's avatar Eyal Perry Committed by David S. Miller
Browse files

ethtool: Support for configurable RSS hash function



This patch extends the set/get_rxfh ethtool-options for getting or
setting the RSS hash function.

It modifies drivers implementation of set/get_rxfh accordingly.

This change also delegates the responsibility of checking whether a
modification to a certain RX flow hash parameter is supported to the
driver implementation of set_rxfh.

User-kernel API is done through the new hfunc bitmask field in the
ethtool_rxfh struct. A bit set in the hfunc field is corresponding to an
index in the new string-set ETH_SS_RSS_HASH_FUNCS.

Got approval from most of the relevant driver maintainers that their
driver is using Toeplitz, and for the few that didn't answered, also
assumed it is Toeplitz.

Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Ariel Elior <ariel.elior@qlogic.com>
Cc: Prashant Sreedharan <prashant@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
Cc: Hariprasad S <hariprasad@chelsio.com>
Cc: Sathya Perla <sathya.perla@emulex.com>
Cc: Subbu Seetharaman <subbu.seetharaman@emulex.com>
Cc: Ajit Khaparde <ajit.khaparde@emulex.com>
Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Bruce Allan <bruce.w.allan@intel.com>
Cc: Carolyn Wyborny <carolyn.wyborny@intel.com>
Cc: Don Skidmore <donald.c.skidmore@intel.com>
Cc: Greg Rose <gregory.v.rose@intel.com>
Cc: Matthew Vick <matthew.vick@intel.com>
Cc: John Ronciak <john.ronciak@intel.com>
Cc: Mitch Williams <mitch.a.williams@intel.com>
Cc: Amir Vadai <amirv@mellanox.com>
Cc: Solarflare linux maintainers <linux-net-drivers@solarflare.com>
Cc: Shradha Shah <sshah@solarflare.com>
Cc: Shreyas Bhatewara <sbhatewara@vmware.com>
Cc: "VMware, Inc." <pv-drivers@vmware.com>
Cc: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: default avatarEyal Perry <eyalpe@mellanox.com>
Signed-off-by: default avatarAmir Vadai <amirv@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 18b5427a
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -511,7 +511,8 @@ static u32 xgbe_get_rxfh_indir_size(struct net_device *netdev)
	return ARRAY_SIZE(pdata->rss_table);
}

static int xgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
static int xgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
			 u8 *hfunc)
{
	struct xgbe_prv_data *pdata = netdev_priv(netdev);
	unsigned int i;
@@ -525,16 +526,22 @@ static int xgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key)
	if (key)
		memcpy(key, pdata->rss_key, sizeof(pdata->rss_key));

	if (hfunc)
		*hfunc = ETH_RSS_HASH_TOP;

	return 0;
}

static int xgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
			 const u8 *key)
			 const u8 *key, const u8 hfunc)
{
	struct xgbe_prv_data *pdata = netdev_priv(netdev);
	struct xgbe_hw_if *hw_if = &pdata->hw_if;
	unsigned int ret;

	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
		return -EOPNOTSUPP;

	if (indir) {
		ret = hw_if->set_rss_lookup_table(pdata, indir);
		if (ret)
+18 −2
Original line number Diff line number Diff line
@@ -3358,12 +3358,18 @@ static u32 bnx2x_get_rxfh_indir_size(struct net_device *dev)
	return T_ETH_INDIRECTION_TABLE_SIZE;
}

static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key)
static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
			  u8 *hfunc)
{
	struct bnx2x *bp = netdev_priv(dev);
	u8 ind_table[T_ETH_INDIRECTION_TABLE_SIZE] = {0};
	size_t i;

	if (hfunc)
		*hfunc = ETH_RSS_HASH_TOP;
	if (!indir)
		return 0;

	/* Get the current configuration of the RSS indirection table */
	bnx2x_get_rss_ind_table(&bp->rss_conf_obj, ind_table);

@@ -3383,11 +3389,21 @@ static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key)
}

static int bnx2x_set_rxfh(struct net_device *dev, const u32 *indir,
			  const u8 *key)
			  const u8 *key, const u8 hfunc)
{
	struct bnx2x *bp = netdev_priv(dev);
	size_t i;

	/* We require at least one supported parameter to be changed and no
	 * change in any of the unsupported parameters
	 */
	if (key ||
	    (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
		return -EOPNOTSUPP;

	if (!indir)
		return 0;

	for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) {
		/*
		 * The same as in bnx2x_get_rxfh: we can't use a memcpy()
+18 −2
Original line number Diff line number Diff line
@@ -12561,22 +12561,38 @@ static u32 tg3_get_rxfh_indir_size(struct net_device *dev)
	return size;
}

static int tg3_get_rxfh(struct net_device *dev, u32 *indir, u8 *key)
static int tg3_get_rxfh(struct net_device *dev, u32 *indir, u8 *key, u8 *hfunc)
{
	struct tg3 *tp = netdev_priv(dev);
	int i;

	if (hfunc)
		*hfunc = ETH_RSS_HASH_TOP;
	if (!indir)
		return 0;

	for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++)
		indir[i] = tp->rss_ind_tbl[i];

	return 0;
}

static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key)
static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key,
			const u8 hfunc)
{
	struct tg3 *tp = netdev_priv(dev);
	size_t i;

	/* We require at least one supported parameter to be changed and no
	 * change in any of the unsupported parameters
	 */
	if (key ||
	    (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
		return -EOPNOTSUPP;

	if (!indir)
		return 0;

	for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++)
		tp->rss_ind_tbl[i] = indir[i];

+16 −2
Original line number Diff line number Diff line
@@ -2923,21 +2923,35 @@ static u32 get_rss_table_size(struct net_device *dev)
	return pi->rss_size;
}

static int get_rss_table(struct net_device *dev, u32 *p, u8 *key)
static int get_rss_table(struct net_device *dev, u32 *p, u8 *key, u8 *hfunc)
{
	const struct port_info *pi = netdev_priv(dev);
	unsigned int n = pi->rss_size;

	if (hfunc)
		*hfunc = ETH_RSS_HASH_TOP;
	if (!p)
		return 0;
	while (n--)
		p[n] = pi->rss[n];
	return 0;
}

static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key)
static int set_rss_table(struct net_device *dev, const u32 *p, const u8 *key,
			 const u8 hfunc)
{
	unsigned int i;
	struct port_info *pi = netdev_priv(dev);

	/* We require at least one supported parameter to be changed and no
	 * change in any of the unsupported parameters
	 */
	if (key ||
	    (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP))
		return -EOPNOTSUPP;
	if (!p)
		return 0;

	for (i = 0; i < pi->rss_size; i++)
		pi->rss[i] = p[i];
	if (pi->adapter->flags & FULL_INIT_DONE)
+10 −2
Original line number Diff line number Diff line
@@ -1171,7 +1171,8 @@ static u32 be_get_rxfh_key_size(struct net_device *netdev)
	return RSS_HASH_KEY_LEN;
}

static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey)
static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey,
		       u8 *hfunc)
{
	struct be_adapter *adapter = netdev_priv(netdev);
	int i;
@@ -1185,16 +1186,23 @@ static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey)
	if (hkey)
		memcpy(hkey, rss->rss_hkey, RSS_HASH_KEY_LEN);

	if (hfunc)
		*hfunc = ETH_RSS_HASH_TOP;

	return 0;
}

static int be_set_rxfh(struct net_device *netdev, const u32 *indir,
		       const u8 *hkey)
		       const u8 *hkey, const u8 hfunc)
{
	int rc = 0, i, j;
	struct be_adapter *adapter = netdev_priv(netdev);
	u8 rsstable[RSS_INDIR_TABLE_LEN];

	/* We do not allow change in unsupported parameters */
	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
		return -EOPNOTSUPP;

	if (indir) {
		struct be_rx_obj *rxo;

Loading