diff options
-rw-r--r-- | drivers/net/ethernet/intel/ice/ice_ethtool.c | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index 476bd1c83c87..1e71b70f0e52 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -3111,36 +3111,47 @@ static u32 ice_get_rxfh_indir_size(struct net_device *netdev) return np->vsi->rss_table_size; } -/** - * ice_get_rxfh - get the Rx flow hash indirection table - * @netdev: network interface device structure - * @indir: indirection table - * @key: hash key - * @hfunc: hash function - * - * Reads the indirection table directly from the hardware. - */ static int -ice_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc) +ice_get_rxfh_context(struct net_device *netdev, u32 *indir, + u8 *key, u8 *hfunc, u32 rss_context) { struct ice_netdev_priv *np = netdev_priv(netdev); struct ice_vsi *vsi = np->vsi; struct ice_pf *pf = vsi->back; - int err, i; + u16 qcount, offset; + int err, num_tc, i; u8 *lut; + if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { + netdev_warn(netdev, "RSS is not supported on this VSI!\n"); + return -EOPNOTSUPP; + } + + if (rss_context && !ice_is_adq_active(pf)) { + netdev_err(netdev, "RSS context cannot be non-zero when ADQ is not configured.\n"); + return -EINVAL; + } + + qcount = vsi->mqprio_qopt.qopt.count[rss_context]; + offset = vsi->mqprio_qopt.qopt.offset[rss_context]; + + if (rss_context && ice_is_adq_active(pf)) { + num_tc = vsi->mqprio_qopt.qopt.num_tc; + if (rss_context >= num_tc) { + netdev_err(netdev, "RSS context:%d > num_tc:%d\n", + rss_context, num_tc); + return -EINVAL; + } + /* Use channel VSI of given TC */ + vsi = vsi->tc_map_vsi[rss_context]; + } + if (hfunc) *hfunc = ETH_RSS_HASH_TOP; if (!indir) return 0; - if (!test_bit(ICE_FLAG_RSS_ENA, pf->flags)) { - /* RSS not supported return error here */ - netdev_warn(netdev, "RSS is not configured on this VSI!\n"); - return -EIO; - } - lut = kzalloc(vsi->rss_table_size, GFP_KERNEL); if (!lut) return -ENOMEM; @@ -3153,8 +3164,14 @@ ice_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc) if (err) goto out; + if (ice_is_adq_active(pf)) { + for (i = 0; i < vsi->rss_table_size; i++) + indir[i] = offset + lut[i] % qcount; + goto out; + } + for (i = 0; i < vsi->rss_table_size; i++) - indir[i] = (u32)(lut[i]); + indir[i] = lut[i]; out: kfree(lut); @@ -3162,6 +3179,21 @@ out: } /** + * ice_get_rxfh - get the Rx flow hash indirection table + * @netdev: network interface device structure + * @indir: indirection table + * @key: hash key + * @hfunc: hash function + * + * Reads the indirection table directly from the hardware. + */ +static int +ice_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key, u8 *hfunc) +{ + return ice_get_rxfh_context(netdev, indir, key, hfunc, 0); +} + +/** * ice_set_rxfh - set the Rx flow hash indirection table * @netdev: network interface device structure * @indir: indirection table @@ -4102,6 +4134,7 @@ static const struct ethtool_ops ice_ethtool_ops = { .set_pauseparam = ice_set_pauseparam, .get_rxfh_key_size = ice_get_rxfh_key_size, .get_rxfh_indir_size = ice_get_rxfh_indir_size, + .get_rxfh_context = ice_get_rxfh_context, .get_rxfh = ice_get_rxfh, .set_rxfh = ice_set_rxfh, .get_channels = ice_get_channels, |