Skip to content

Commit

Permalink
net: ethtool: pass a pointer to parameters to get/set_rxfh ethtool ops
Browse files Browse the repository at this point in the history
The get/set_rxfh ethtool ops currently takes the rxfh (RSS) parameters
as direct function arguments. This will force us to change the API (and
all drivers' functions) every time some new parameters are added.

This is part 1/2 of the fix, as suggested in [1]:

- First simplify the code by always providing a pointer to all params
   (indir, key and func); the fact that some of them may be NULL seems
   like a weird historic thing or a premature optimization.
   It will simplify the drivers if all pointers are always present.

 - Then make the functions take a dev pointer, and a pointer to a
   single struct wrapping all arguments. The set_* should also take
   an extack.

Link: https://lore.kernel.org/netdev/20231121152906.2dd5f487@kernel.org/ [1]
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Suggested-by: Jacob Keller <jacob.e.keller@intel.com>
Signed-off-by: Ahmed Zaki <ahmed.zaki@intel.com>
Link: https://lore.kernel.org/r/20231213003321.605376-2-ahmed.zaki@intel.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Ahmed Zaki authored and Jakub Kicinski committed Dec 14, 2023
1 parent c3f687d commit fb6e30a
Show file tree
Hide file tree
Showing 48 changed files with 827 additions and 730 deletions.
28 changes: 14 additions & 14 deletions drivers/net/ethernet/amazon/ena/ena_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,15 +802,15 @@ static int ena_indirection_table_get(struct ena_adapter *adapter, u32 *indir)
return rc;
}

static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
u8 *hfunc)
static int ena_get_rxfh(struct net_device *netdev,
struct ethtool_rxfh_param *rxfh)
{
struct ena_adapter *adapter = netdev_priv(netdev);
enum ena_admin_hash_functions ena_func;
u8 func;
int rc;

rc = ena_indirection_table_get(adapter, indir);
rc = ena_indirection_table_get(adapter, rxfh->indir);
if (rc)
return rc;

Expand All @@ -825,7 +825,7 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
return rc;
}

rc = ena_com_get_hash_key(adapter->ena_dev, key);
rc = ena_com_get_hash_key(adapter->ena_dev, rxfh->key);
if (rc)
return rc;

Expand All @@ -842,27 +842,27 @@ static int ena_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
return -EOPNOTSUPP;
}

if (hfunc)
*hfunc = func;
rxfh->hfunc = func;

return 0;
}

static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
const u8 *key, const u8 hfunc)
static int ena_set_rxfh(struct net_device *netdev,
struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct ena_adapter *adapter = netdev_priv(netdev);
struct ena_com_dev *ena_dev = adapter->ena_dev;
enum ena_admin_hash_functions func = 0;
int rc;

if (indir) {
rc = ena_indirection_table_set(adapter, indir);
if (rxfh->indir) {
rc = ena_indirection_table_set(adapter, rxfh->indir);
if (rc)
return rc;
}

switch (hfunc) {
switch (rxfh->hfunc) {
case ETH_RSS_HASH_NO_CHANGE:
func = ena_com_get_current_hash_function(ena_dev);
break;
Expand All @@ -874,12 +874,12 @@ static int ena_set_rxfh(struct net_device *netdev, const u32 *indir,
break;
default:
netif_err(adapter, drv, netdev, "Unsupported hfunc %d\n",
hfunc);
rxfh->hfunc);
return -EOPNOTSUPP;
}

if (key || func) {
rc = ena_com_fill_hash_function(ena_dev, func, key,
if (rxfh->key || func) {
rc = ena_com_fill_hash_function(ena_dev, func, rxfh->key,
ENA_HASH_KEY_SIZE,
0xFFFFFFFF);
if (unlikely(rc)) {
Expand Down
33 changes: 17 additions & 16 deletions drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,47 +527,48 @@ 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,
u8 *hfunc)
static int xgbe_get_rxfh(struct net_device *netdev,
struct ethtool_rxfh_param *rxfh)
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
unsigned int i;

if (indir) {
if (rxfh->indir) {
for (i = 0; i < ARRAY_SIZE(pdata->rss_table); i++)
indir[i] = XGMAC_GET_BITS(pdata->rss_table[i],
MAC_RSSDR, DMCH);
rxfh->indir[i] = XGMAC_GET_BITS(pdata->rss_table[i],
MAC_RSSDR, DMCH);
}

if (key)
memcpy(key, pdata->rss_key, sizeof(pdata->rss_key));
if (rxfh->key)
memcpy(rxfh->key, pdata->rss_key, sizeof(pdata->rss_key));

if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
rxfh->hfunc = ETH_RSS_HASH_TOP;

return 0;
}

static int xgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
const u8 *key, const u8 hfunc)
static int xgbe_set_rxfh(struct net_device *netdev,
struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
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) {
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
rxfh->hfunc != ETH_RSS_HASH_TOP) {
netdev_err(netdev, "unsupported hash function\n");
return -EOPNOTSUPP;
}

if (indir) {
ret = hw_if->set_rss_lookup_table(pdata, indir);
if (rxfh->indir) {
ret = hw_if->set_rss_lookup_table(pdata, rxfh->indir);
if (ret)
return ret;
}

if (key) {
ret = hw_if->set_rss_hash_key(pdata, key);
if (rxfh->key) {
ret = hw_if->set_rss_hash_key(pdata, rxfh->key);
if (ret)
return ret;
}
Expand Down
31 changes: 16 additions & 15 deletions drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,30 +447,30 @@ static u32 aq_ethtool_get_rss_key_size(struct net_device *ndev)
return sizeof(cfg->aq_rss.hash_secret_key);
}

static int aq_ethtool_get_rss(struct net_device *ndev, u32 *indir, u8 *key,
u8 *hfunc)
static int aq_ethtool_get_rss(struct net_device *ndev,
struct ethtool_rxfh_param *rxfh)
{
struct aq_nic_s *aq_nic = netdev_priv(ndev);
struct aq_nic_cfg_s *cfg;
unsigned int i = 0U;

cfg = aq_nic_get_cfg(aq_nic);

if (hfunc)
*hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
if (indir) {
rxfh->hfunc = ETH_RSS_HASH_TOP; /* Toeplitz */
if (rxfh->indir) {
for (i = 0; i < AQ_CFG_RSS_INDIRECTION_TABLE_MAX; i++)
indir[i] = cfg->aq_rss.indirection_table[i];
rxfh->indir[i] = cfg->aq_rss.indirection_table[i];
}
if (key)
memcpy(key, cfg->aq_rss.hash_secret_key,
if (rxfh->key)
memcpy(rxfh->key, cfg->aq_rss.hash_secret_key,
sizeof(cfg->aq_rss.hash_secret_key));

return 0;
}

static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
const u8 *key, const u8 hfunc)
static int aq_ethtool_set_rss(struct net_device *netdev,
struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct aq_nic_s *aq_nic = netdev_priv(netdev);
struct aq_nic_cfg_s *cfg;
Expand All @@ -482,16 +482,17 @@ static int aq_ethtool_set_rss(struct net_device *netdev, const u32 *indir,
rss_entries = cfg->aq_rss.indirection_table_size;

/* We do not allow change in unsupported parameters */
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
rxfh->hfunc != ETH_RSS_HASH_TOP)
return -EOPNOTSUPP;
/* Fill out the redirection table */
if (indir)
if (rxfh->indir)
for (i = 0; i < rss_entries; i++)
cfg->aq_rss.indirection_table[i] = indir[i];
cfg->aq_rss.indirection_table[i] = rxfh->indir[i];

/* Fill out the rss hash key */
if (key) {
memcpy(cfg->aq_rss.hash_secret_key, key,
if (rxfh->key) {
memcpy(cfg->aq_rss.hash_secret_key, rxfh->key,
sizeof(cfg->aq_rss.hash_secret_key));
err = aq_nic->aq_hw_ops->hw_rss_hash_set(aq_nic->aq_hw,
&cfg->aq_rss);
Expand Down
25 changes: 13 additions & 12 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -3486,16 +3486,15 @@ 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,
u8 *hfunc)
static int bnx2x_get_rxfh(struct net_device *dev,
struct ethtool_rxfh_param *rxfh)
{
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)
rxfh->hfunc = ETH_RSS_HASH_TOP;
if (!rxfh->indir)
return 0;

/* Get the current configuration of the RSS indirection table */
Expand All @@ -3511,25 +3510,27 @@ static int bnx2x_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
* queue.
*/
for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++)
indir[i] = ind_table[i] - bp->fp->cl_id;
rxfh->indir[i] = ind_table[i] - bp->fp->cl_id;

return 0;
}

static int bnx2x_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *key, const u8 hfunc)
static int bnx2x_set_rxfh(struct net_device *dev,
struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
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))
if (rxfh->key ||
(rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
rxfh->hfunc != ETH_RSS_HASH_TOP))
return -EOPNOTSUPP;

if (!indir)
if (!rxfh->indir)
return 0;

for (i = 0; i < T_ETH_INDIRECTION_TABLE_SIZE; i++) {
Expand All @@ -3542,7 +3543,7 @@ static int bnx2x_set_rxfh(struct net_device *dev, const u32 *indir,
* align the received table to the Client ID of the leading RSS
* queue
*/
bp->rss_conf_obj.ind_table[i] = indir[i] + bp->fp->cl_id;
bp->rss_conf_obj.ind_table[i] = rxfh->indir[i] + bp->fp->cl_id;
}

if (bp->state == BNX2X_STATE_OPEN)
Expand Down
28 changes: 14 additions & 14 deletions drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1333,49 +1333,49 @@ static u32 bnxt_get_rxfh_key_size(struct net_device *dev)
return HW_HASH_KEY_SIZE;
}

static int bnxt_get_rxfh(struct net_device *dev, u32 *indir, u8 *key,
u8 *hfunc)
static int bnxt_get_rxfh(struct net_device *dev,
struct ethtool_rxfh_param *rxfh)
{
struct bnxt *bp = netdev_priv(dev);
struct bnxt_vnic_info *vnic;
u32 i, tbl_size;

if (hfunc)
*hfunc = ETH_RSS_HASH_TOP;
rxfh->hfunc = ETH_RSS_HASH_TOP;

if (!bp->vnic_info)
return 0;

vnic = &bp->vnic_info[0];
if (indir && bp->rss_indir_tbl) {
if (rxfh->indir && bp->rss_indir_tbl) {
tbl_size = bnxt_get_rxfh_indir_size(dev);
for (i = 0; i < tbl_size; i++)
indir[i] = bp->rss_indir_tbl[i];
rxfh->indir[i] = bp->rss_indir_tbl[i];
}

if (key && vnic->rss_hash_key)
memcpy(key, vnic->rss_hash_key, HW_HASH_KEY_SIZE);
if (rxfh->key && vnic->rss_hash_key)
memcpy(rxfh->key, vnic->rss_hash_key, HW_HASH_KEY_SIZE);

return 0;
}

static int bnxt_set_rxfh(struct net_device *dev, const u32 *indir,
const u8 *key, const u8 hfunc)
static int bnxt_set_rxfh(struct net_device *dev,
struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
struct bnxt *bp = netdev_priv(dev);
int rc = 0;

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

if (key)
if (rxfh->key)
return -EOPNOTSUPP;

if (indir) {
if (rxfh->indir) {
u32 i, pad, tbl_size = bnxt_get_rxfh_indir_size(dev);

for (i = 0; i < tbl_size; i++)
bp->rss_indir_tbl[i] = indir[i];
bp->rss_indir_tbl[i] = rxfh->indir[i];
pad = bp->rss_indir_tbl_entries - tbl_size;
if (pad)
memset(&bp->rss_indir_tbl[i], 0, pad * sizeof(u16));
Expand Down
22 changes: 11 additions & 11 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -12745,40 +12745,40 @@ 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, u8 *hfunc)
static int tg3_get_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh)
{
struct tg3 *tp = netdev_priv(dev);
int i;

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

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

return 0;
}

static int tg3_set_rxfh(struct net_device *dev, const u32 *indir, const u8 *key,
const u8 hfunc)
static int tg3_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
struct netlink_ext_ack *extack)
{
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))
if (rxfh->key ||
(rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE &&
rxfh->hfunc != ETH_RSS_HASH_TOP))
return -EOPNOTSUPP;

if (!indir)
if (!rxfh->indir)
return 0;

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

if (!netif_running(dev) || !tg3_flag(tp, ENABLE_RSS))
return 0;
Expand Down
Loading

0 comments on commit fb6e30a

Please sign in to comment.