@@ -451,6 +451,34 @@ int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
451451
452452 mutex_lock (& priv -> state_lock );
453453
454+ if (mlx5e_rx_res_get_current_hash (priv -> rx_res ).hfunc == ETH_RSS_HASH_XOR ) {
455+ unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8 ();
456+
457+ if (count > xor8_max_channels ) {
458+ err = - EINVAL ;
459+ netdev_err (priv -> netdev , "%s: Requested number of channels (%d) exceeds the maximum allowed by the XOR8 RSS hfunc (%d)\n" ,
460+ __func__ , count , xor8_max_channels );
461+ goto out ;
462+ }
463+ }
464+
465+ /* If RXFH is configured, changing the channels number is allowed only if
466+ * it does not require resizing the RSS table. This is because the previous
467+ * configuration may no longer be compatible with the new RSS table.
468+ */
469+ if (netif_is_rxfh_configured (priv -> netdev )) {
470+ int cur_rqt_size = mlx5e_rqt_size (priv -> mdev , cur_params -> num_channels );
471+ int new_rqt_size = mlx5e_rqt_size (priv -> mdev , count );
472+
473+ if (new_rqt_size != cur_rqt_size ) {
474+ err = - EINVAL ;
475+ netdev_err (priv -> netdev ,
476+ "%s: RXFH is configured, block changing channels number that affects RSS table size (new: %d, current: %d)\n" ,
477+ __func__ , new_rqt_size , cur_rqt_size );
478+ goto out ;
479+ }
480+ }
481+
454482 /* Don't allow changing the number of channels if HTB offload is active,
455483 * because the numeration of the QoS SQs will change, while per-queue
456484 * qdiscs are attached.
@@ -1281,17 +1309,30 @@ int mlx5e_set_rxfh(struct net_device *dev, struct ethtool_rxfh_param *rxfh,
12811309 struct mlx5e_priv * priv = netdev_priv (dev );
12821310 u32 * rss_context = & rxfh -> rss_context ;
12831311 u8 hfunc = rxfh -> hfunc ;
1312+ unsigned int count ;
12841313 int err ;
12851314
12861315 mutex_lock (& priv -> state_lock );
1316+
1317+ count = priv -> channels .params .num_channels ;
1318+
1319+ if (hfunc == ETH_RSS_HASH_XOR ) {
1320+ unsigned int xor8_max_channels = mlx5e_rqt_max_num_channels_allowed_for_xor8 ();
1321+
1322+ if (count > xor8_max_channels ) {
1323+ err = - EINVAL ;
1324+ netdev_err (priv -> netdev , "%s: Cannot set RSS hash function to XOR, current number of channels (%d) exceeds the maximum allowed for XOR8 RSS hfunc (%d)\n" ,
1325+ __func__ , count , xor8_max_channels );
1326+ goto unlock ;
1327+ }
1328+ }
1329+
12871330 if (* rss_context && rxfh -> rss_delete ) {
12881331 err = mlx5e_rx_res_rss_destroy (priv -> rx_res , * rss_context );
12891332 goto unlock ;
12901333 }
12911334
12921335 if (* rss_context == ETH_RXFH_CONTEXT_ALLOC ) {
1293- unsigned int count = priv -> channels .params .num_channels ;
1294-
12951336 err = mlx5e_rx_res_rss_init (priv -> rx_res , rss_context , count );
12961337 if (err )
12971338 goto unlock ;
0 commit comments