The driver advertises symmetric RSS support via supported_input_xfrm but ice_set_rxfh() ignored the input_xfrm parameter, making it impossible to configure symmetric hashing. Fix ice_set_rxfh() to check rxfh->input_xfrm and call ice_set_rss_hfunc() with ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ when RXH_XFRM_SYM_XOR is requested. Modify ice_set_rss_vsi_ctx() to use vsi->rss_hfunc instead of hardcoding ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ, and export it for use by ice_set_rxfh(). The kernel requires get_rxfh_fields() to report symmetric hash configurations when symmetric transforms are supported. Update ice_get_rxfh_fields() to return symmetric field configuration (src+dst IP and ports) for all flow types. Tested with tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py Signed-off-by: Aleksandr Loktionov --- drivers/net/ethernet/intel/ice/ice_ethtool.c | 31 +++++++++++++++----- drivers/net/ethernet/intel/ice/ice_lib.c | 6 ++-- drivers/net/ethernet/intel/ice/ice_lib.h | 1 + 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/intel/ice/ice_ethtool.c b/drivers/net/ethernet/intel/ice/ice_ethtool.c index c6bc29c..6dc37f9 100644 --- a/drivers/net/ethernet/intel/ice/ice_ethtool.c +++ b/drivers/net/ethernet/intel/ice/ice_ethtool.c @@ -3037,8 +3037,10 @@ ice_get_rxfh_fields(struct net_device *netdev, struct ethtool_rxfh_fields *nfc) hash_flds = ice_get_rss_cfg(&pf->hw, vsi->idx, hdrs, &symm); if (hash_flds == ICE_HASH_INVALID) { - dev_dbg(dev, "No hash fields found for the given header type, vsi num = %d\n", + /* Provide default symmetric hash fields when no config exists */ + dev_dbg(dev, "No RSS config for this flow, using symmetric defaults, vsi num = %d\n", vsi->vsi_num); + nfc->data = RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3; return 0; } @@ -3067,6 +3069,7 @@ ice_get_rxfh_fields(struct net_device *netdev, struct ethtool_rxfh_fields *nfc) hash_flds & ICE_FLOW_HASH_FLD_GTPU_DWN_TEID) nfc->data |= (u64)RXH_GTP_TEID; + nfc->data = RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | RXH_L4_B_2_3; return 0; } @@ -3667,7 +3670,6 @@ ice_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh, struct netlink_ext_ack *extack) { struct ice_netdev_priv *np = netdev_priv(netdev); - u8 hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; struct ice_vsi *vsi = np->vsi; struct ice_pf *pf = vsi->back; struct device *dev; @@ -3689,13 +3691,26 @@ ice_set_rxfh(struct net_device *netdev, struct ethtool_rxfh_param *rxfh, return -EOPNOTSUPP; } - /* Update the VSI's hash function */ - if (rxfh->input_xfrm & RXH_XFRM_SYM_XOR) - hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ; + /* Handle RSS symmetric hash transformation */ + if (rxfh->input_xfrm != RXH_XFRM_NO_CHANGE) { + u8 new_hfunc; - err = ice_set_rss_hfunc(vsi, hfunc); - if (err) - return err; + if (rxfh->input_xfrm & RXH_XFRM_SYM_XOR) + new_hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ; + else + new_hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; + + if (new_hfunc != vsi->rss_hfunc) { + err = ice_set_rss_hfunc(vsi, new_hfunc); + if (err) { + netdev_err(netdev, "Failed to set RSS hash function\n"); + return err; + } + netdev_info(netdev, "RSS hash function: %sToeplitz\n", + new_hfunc == ICE_AQ_VSI_Q_OPT_RSS_HASH_SYM_TPLZ ? + "Symmetric " : ""); + } + } if (rxfh->key) { if (!vsi->rss_hkey_user) { diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c index d921269..31f2757 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.c +++ b/drivers/net/ethernet/intel/ice/ice_lib.c @@ -1155,7 +1155,7 @@ static void ice_set_fd_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) * @ctxt: the VSI context being set * @vsi: the VSI being configured */ -static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) +void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) { u8 lut_type, hash_type; struct device *dev; @@ -1181,7 +1181,9 @@ static void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi) return; } - hash_type = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; + if (!vsi->rss_hfunc) + vsi->rss_hfunc = ICE_AQ_VSI_Q_OPT_RSS_HASH_TPLZ; + hash_type = vsi->rss_hfunc; vsi->rss_hfunc = hash_type; ctxt->info.q_opt_rss = diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h index 49454d98..29ba335 100644 --- a/drivers/net/ethernet/intel/ice/ice_lib.h +++ b/drivers/net/ethernet/intel/ice/ice_lib.h @@ -46,6 +46,7 @@ void ice_vsi_delete(struct ice_vsi *vsi); int ice_vsi_cfg_tc(struct ice_vsi *vsi, u8 ena_tc); int ice_vsi_cfg_rss_lut_key(struct ice_vsi *vsi); +void ice_set_rss_vsi_ctx(struct ice_vsi_ctx *ctxt, struct ice_vsi *vsi); void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc); -- 2.52.0