aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox
diff options
context:
space:
mode:
authorYevgeny Petrilin <yevgenyp@mellanox.co.il>2012-01-17 17:54:55 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-18 16:07:34 -0500
commit93d3e3678f23109363cd6f99f2944d2cda616b23 (patch)
treebb03e8801b25f03d3e658e9dc3108101f7e94fc1 /drivers/net/ethernet/mellanox
parentd00a9dd21bdf7908b70866794c8313ee8a5abd5c (diff)
mlx4_en: set number of rx rings used by RSS using ethtool
Value must be a power of 2 due to HW limitation. Driver supports only 'equal' mode in ethtool and can't be set by using weights. Signed-off-by: Amir Vadai <amirv@mellanox.co.il> Reviewed-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox')
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_ethtool.c93
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_main.c6
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_rx.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h2
4 files changed, 102 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
index 7dbc6a230779..53c66869aecd 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
@@ -479,6 +479,95 @@ static void mlx4_en_get_ringparam(struct net_device *dev,
479 param->tx_pending = priv->tx_ring[0].size; 479 param->tx_pending = priv->tx_ring[0].size;
480} 480}
481 481
482static u32 mlx4_en_get_rxfh_indir_size(struct net_device *dev)
483{
484 struct mlx4_en_priv *priv = netdev_priv(dev);
485
486 return priv->rx_ring_num;
487}
488
489static int mlx4_en_get_rxfh_indir(struct net_device *dev, u32 *ring_index)
490{
491 struct mlx4_en_priv *priv = netdev_priv(dev);
492 struct mlx4_en_rss_map *rss_map = &priv->rss_map;
493 int rss_rings;
494 size_t n = priv->rx_ring_num;
495 int err = 0;
496
497 rss_rings = priv->prof->rss_rings ?: priv->rx_ring_num;
498
499 while (n--) {
500 ring_index[n] = rss_map->qps[n % rss_rings].qpn -
501 rss_map->base_qpn;
502 }
503
504 return err;
505}
506
507static int mlx4_en_set_rxfh_indir(struct net_device *dev,
508 const u32 *ring_index)
509{
510 struct mlx4_en_priv *priv = netdev_priv(dev);
511 struct mlx4_en_dev *mdev = priv->mdev;
512 int port_up = 0;
513 int err = 0;
514 int i;
515 int rss_rings = 0;
516
517 /* Calculate RSS table size and make sure flows are spread evenly
518 * between rings
519 */
520 for (i = 0; i < priv->rx_ring_num; i++) {
521 if (i > 0 && !ring_index[i] && !rss_rings)
522 rss_rings = i;
523
524 if (ring_index[i] != (i % (rss_rings ?: priv->rx_ring_num)))
525 return -EINVAL;
526 }
527
528 if (!rss_rings)
529 rss_rings = priv->rx_ring_num;
530
531 /* RSS table size must be an order of 2 */
532 if (!is_power_of_2(rss_rings))
533 return -EINVAL;
534
535 mutex_lock(&mdev->state_lock);
536 if (priv->port_up) {
537 port_up = 1;
538 mlx4_en_stop_port(dev);
539 }
540
541 priv->prof->rss_rings = rss_rings;
542
543 if (port_up) {
544 err = mlx4_en_start_port(dev);
545 if (err)
546 en_err(priv, "Failed starting port\n");
547 }
548
549 mutex_unlock(&mdev->state_lock);
550 return err;
551}
552
553static int mlx4_en_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
554 u32 *rule_locs)
555{
556 struct mlx4_en_priv *priv = netdev_priv(dev);
557 int err = 0;
558
559 switch (cmd->cmd) {
560 case ETHTOOL_GRXRINGS:
561 cmd->data = priv->rx_ring_num;
562 break;
563 default:
564 err = -EOPNOTSUPP;
565 break;
566 }
567
568 return err;
569}
570
482const struct ethtool_ops mlx4_en_ethtool_ops = { 571const struct ethtool_ops mlx4_en_ethtool_ops = {
483 .get_drvinfo = mlx4_en_get_drvinfo, 572 .get_drvinfo = mlx4_en_get_drvinfo,
484 .get_settings = mlx4_en_get_settings, 573 .get_settings = mlx4_en_get_settings,
@@ -498,6 +587,10 @@ const struct ethtool_ops mlx4_en_ethtool_ops = {
498 .set_pauseparam = mlx4_en_set_pauseparam, 587 .set_pauseparam = mlx4_en_set_pauseparam,
499 .get_ringparam = mlx4_en_get_ringparam, 588 .get_ringparam = mlx4_en_get_ringparam,
500 .set_ringparam = mlx4_en_set_ringparam, 589 .set_ringparam = mlx4_en_set_ringparam,
590 .get_rxnfc = mlx4_en_get_rxnfc,
591 .get_rxfh_indir_size = mlx4_en_get_rxfh_indir_size,
592 .get_rxfh_indir = mlx4_en_get_rxfh_indir,
593 .set_rxfh_indir = mlx4_en_set_rxfh_indir,
501}; 594};
502 595
503 596
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_main.c b/drivers/net/ethernet/mellanox/mlx4/en_main.c
index a06096fcc0b8..2097a7d3c5b8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
@@ -62,10 +62,6 @@ static const char mlx4_en_version[] =
62 * Device scope module parameters 62 * Device scope module parameters
63 */ 63 */
64 64
65
66/* Enable RSS TCP traffic */
67MLX4_EN_PARM_INT(tcp_rss, 1,
68 "Enable RSS for incomming TCP traffic or disabled (0)");
69/* Enable RSS UDP traffic */ 65/* Enable RSS UDP traffic */
70MLX4_EN_PARM_INT(udp_rss, 1, 66MLX4_EN_PARM_INT(udp_rss, 1,
71 "Enable RSS for incomming UDP traffic or disabled (0)"); 67 "Enable RSS for incomming UDP traffic or disabled (0)");
@@ -104,7 +100,6 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
104 struct mlx4_en_profile *params = &mdev->profile; 100 struct mlx4_en_profile *params = &mdev->profile;
105 int i; 101 int i;
106 102
107 params->tcp_rss = tcp_rss;
108 params->udp_rss = udp_rss; 103 params->udp_rss = udp_rss;
109 if (params->udp_rss && !(mdev->dev->caps.flags 104 if (params->udp_rss && !(mdev->dev->caps.flags
110 & MLX4_DEV_CAP_FLAG_UDP_RSS)) { 105 & MLX4_DEV_CAP_FLAG_UDP_RSS)) {
@@ -120,6 +115,7 @@ static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
120 params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE; 115 params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
121 params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS + 116 params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
122 (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS; 117 (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS;
118 params->prof[i].rss_rings = 0;
123 } 119 }
124 120
125 return 0; 121 return 0;
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
index e8d6ad2dce0a..971d4b6b8dfe 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c
@@ -853,6 +853,7 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
853 struct mlx4_en_rss_map *rss_map = &priv->rss_map; 853 struct mlx4_en_rss_map *rss_map = &priv->rss_map;
854 struct mlx4_qp_context context; 854 struct mlx4_qp_context context;
855 struct mlx4_rss_context *rss_context; 855 struct mlx4_rss_context *rss_context;
856 int rss_rings;
856 void *ptr; 857 void *ptr;
857 u8 rss_mask = (MLX4_RSS_IPV4 | MLX4_RSS_TCP_IPV4 | MLX4_RSS_IPV6 | 858 u8 rss_mask = (MLX4_RSS_IPV4 | MLX4_RSS_TCP_IPV4 | MLX4_RSS_IPV6 |
858 MLX4_RSS_TCP_IPV6); 859 MLX4_RSS_TCP_IPV6);
@@ -893,10 +894,15 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
893 mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn, 894 mlx4_en_fill_qp_context(priv, 0, 0, 0, 1, priv->base_qpn,
894 priv->rx_ring[0].cqn, &context); 895 priv->rx_ring[0].cqn, &context);
895 896
897 if (!priv->prof->rss_rings || priv->prof->rss_rings > priv->rx_ring_num)
898 rss_rings = priv->rx_ring_num;
899 else
900 rss_rings = priv->prof->rss_rings;
901
896 ptr = ((void *) &context) + offsetof(struct mlx4_qp_context, pri_path) 902 ptr = ((void *) &context) + offsetof(struct mlx4_qp_context, pri_path)
897 + MLX4_RSS_OFFSET_IN_QPC_PRI_PATH; 903 + MLX4_RSS_OFFSET_IN_QPC_PRI_PATH;
898 rss_context = ptr; 904 rss_context = ptr;
899 rss_context->base_qpn = cpu_to_be32(ilog2(priv->rx_ring_num) << 24 | 905 rss_context->base_qpn = cpu_to_be32(ilog2(rss_rings) << 24 |
900 (rss_map->base_qpn)); 906 (rss_map->base_qpn));
901 rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn); 907 rss_context->default_qpn = cpu_to_be32(rss_map->base_qpn);
902 if (priv->mdev->profile.udp_rss) { 908 if (priv->mdev->profile.udp_rss) {
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index f2a8e65f5f88..f4d189a1290e 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -325,11 +325,11 @@ struct mlx4_en_port_profile {
325 u8 rx_ppp; 325 u8 rx_ppp;
326 u8 tx_pause; 326 u8 tx_pause;
327 u8 tx_ppp; 327 u8 tx_ppp;
328 int rss_rings;
328}; 329};
329 330
330struct mlx4_en_profile { 331struct mlx4_en_profile {
331 int rss_xor; 332 int rss_xor;
332 int tcp_rss;
333 int udp_rss; 333 int udp_rss;
334 u8 rss_mask; 334 u8 rss_mask;
335 u32 active_ports; 335 u32 active_ports;