aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/mlx4/en_cq.c38
-rw-r--r--drivers/net/mlx4/en_ethtool.c2
-rw-r--r--drivers/net/mlx4/en_main.c20
-rw-r--r--drivers/net/mlx4/en_netdev.c18
-rw-r--r--drivers/net/mlx4/mlx4_en.h7
5 files changed, 62 insertions, 23 deletions
diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c
index 21786ad4455e..ec4b6d047fe0 100644
--- a/drivers/net/mlx4/en_cq.c
+++ b/drivers/net/mlx4/en_cq.c
@@ -51,13 +51,10 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv,
51 int err; 51 int err;
52 52
53 cq->size = entries; 53 cq->size = entries;
54 if (mode == RX) { 54 if (mode == RX)
55 cq->buf_size = cq->size * sizeof(struct mlx4_cqe); 55 cq->buf_size = cq->size * sizeof(struct mlx4_cqe);
56 cq->vector = ring % mdev->dev->caps.num_comp_vectors; 56 else
57 } else {
58 cq->buf_size = sizeof(struct mlx4_cqe); 57 cq->buf_size = sizeof(struct mlx4_cqe);
59 cq->vector = 0;
60 }
61 58
62 cq->ring = ring; 59 cq->ring = ring;
63 cq->is_tx = mode; 60 cq->is_tx = mode;
@@ -80,7 +77,8 @@ int mlx4_en_create_cq(struct mlx4_en_priv *priv,
80int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 77int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
81{ 78{
82 struct mlx4_en_dev *mdev = priv->mdev; 79 struct mlx4_en_dev *mdev = priv->mdev;
83 int err; 80 int err = 0;
81 char name[25];
84 82
85 cq->dev = mdev->pndev[priv->port]; 83 cq->dev = mdev->pndev[priv->port];
86 cq->mcq.set_ci_db = cq->wqres.db.db; 84 cq->mcq.set_ci_db = cq->wqres.db.db;
@@ -89,6 +87,29 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
89 *cq->mcq.arm_db = 0; 87 *cq->mcq.arm_db = 0;
90 memset(cq->buf, 0, cq->buf_size); 88 memset(cq->buf, 0, cq->buf_size);
91 89
90 if (cq->is_tx == RX) {
91 if (mdev->dev->caps.comp_pool) {
92 if (!cq->vector) {
93 sprintf(name , "%s-rx-%d", priv->dev->name, cq->ring);
94 if (mlx4_assign_eq(mdev->dev, name, &cq->vector)) {
95 cq->vector = (cq->ring + 1 + priv->port) %
96 mdev->dev->caps.num_comp_vectors;
97 mlx4_warn(mdev, "Failed Assigning an EQ to "
98 "%s_rx-%d ,Falling back to legacy EQ's\n",
99 priv->dev->name, cq->ring);
100 }
101 }
102 } else {
103 cq->vector = (cq->ring + 1 + priv->port) %
104 mdev->dev->caps.num_comp_vectors;
105 }
106 } else {
107 if (!cq->vector || !mdev->dev->caps.comp_pool) {
108 /*Fallback to legacy pool in case of error*/
109 cq->vector = 0;
110 }
111 }
112
92 if (!cq->is_tx) 113 if (!cq->is_tx)
93 cq->size = priv->rx_ring[cq->ring].actual_size; 114 cq->size = priv->rx_ring[cq->ring].actual_size;
94 115
@@ -112,12 +133,15 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
112 return 0; 133 return 0;
113} 134}
114 135
115void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 136void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
137 bool reserve_vectors)
116{ 138{
117 struct mlx4_en_dev *mdev = priv->mdev; 139 struct mlx4_en_dev *mdev = priv->mdev;
118 140
119 mlx4_en_unmap_buffer(&cq->wqres.buf); 141 mlx4_en_unmap_buffer(&cq->wqres.buf);
120 mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size); 142 mlx4_free_hwq_res(mdev->dev, &cq->wqres, cq->buf_size);
143 if (priv->mdev->dev->caps.comp_pool && cq->vector && !reserve_vectors)
144 mlx4_release_eq(priv->mdev->dev, cq->vector);
121 cq->buf_size = 0; 145 cq->buf_size = 0;
122 cq->buf = NULL; 146 cq->buf = NULL;
123} 147}
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
index 056152b3ff58..8cfe8586ed2d 100644
--- a/drivers/net/mlx4/en_ethtool.c
+++ b/drivers/net/mlx4/en_ethtool.c
@@ -388,7 +388,7 @@ static int mlx4_en_set_ringparam(struct net_device *dev,
388 mlx4_en_stop_port(dev); 388 mlx4_en_stop_port(dev);
389 } 389 }
390 390
391 mlx4_en_free_resources(priv); 391 mlx4_en_free_resources(priv, true);
392 392
393 priv->prof->tx_ring_size = tx_size; 393 priv->prof->tx_ring_size = tx_size;
394 priv->prof->rx_ring_size = rx_size; 394 priv->prof->rx_ring_size = rx_size;
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 1ff6ca6466ed..29aaa4303991 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -241,16 +241,18 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
241 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) 241 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH)
242 mdev->port_cnt++; 242 mdev->port_cnt++;
243 243
244 /* If we did not receive an explicit number of Rx rings, default to
245 * the number of completion vectors populated by the mlx4_core */
246 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) { 244 mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
247 mlx4_info(mdev, "Using %d tx rings for port:%d\n", 245 if (!dev->caps.comp_pool) {
248 mdev->profile.prof[i].tx_ring_num, i); 246 mdev->profile.prof[i].rx_ring_num =
249 mdev->profile.prof[i].rx_ring_num = min_t(int, 247 rounddown_pow_of_two(max_t(int, MIN_RX_RINGS,
250 roundup_pow_of_two(dev->caps.num_comp_vectors), 248 min_t(int,
251 MAX_RX_RINGS); 249 dev->caps.num_comp_vectors,
252 mlx4_info(mdev, "Defaulting to %d rx rings for port:%d\n", 250 MAX_RX_RINGS)));
253 mdev->profile.prof[i].rx_ring_num, i); 251 } else {
252 mdev->profile.prof[i].rx_ring_num = rounddown_pow_of_two(
253 min_t(int, dev->caps.comp_pool/
254 dev->caps.num_ports - 1 , MAX_MSIX_P_PORT - 1));
255 }
254 } 256 }
255 257
256 /* Create our own workqueue for reset/multicast tasks 258 /* Create our own workqueue for reset/multicast tasks
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 5727bf5ad452..f6ed315b4b89 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -557,6 +557,7 @@ int mlx4_en_start_port(struct net_device *dev)
557 int err = 0; 557 int err = 0;
558 int i; 558 int i;
559 int j; 559 int j;
560 char name[32];
560 561
561 if (priv->port_up) { 562 if (priv->port_up) {
562 en_dbg(DRV, priv, "start port called while port already up\n"); 563 en_dbg(DRV, priv, "start port called while port already up\n");
@@ -601,10 +602,19 @@ int mlx4_en_start_port(struct net_device *dev)
601 goto cq_err; 602 goto cq_err;
602 } 603 }
603 604
605 if (mdev->dev->caps.comp_pool && !priv->tx_vector) {
606 sprintf(name , "%s-tx", priv->dev->name);
607 if (mlx4_assign_eq(mdev->dev , name, &priv->tx_vector)) {
608 mlx4_warn(mdev, "Failed Assigning an EQ to "
609 "%s_tx ,Falling back to legacy "
610 "EQ's\n", priv->dev->name);
611 }
612 }
604 /* Configure tx cq's and rings */ 613 /* Configure tx cq's and rings */
605 for (i = 0; i < priv->tx_ring_num; i++) { 614 for (i = 0; i < priv->tx_ring_num; i++) {
606 /* Configure cq */ 615 /* Configure cq */
607 cq = &priv->tx_cq[i]; 616 cq = &priv->tx_cq[i];
617 cq->vector = priv->tx_vector;
608 err = mlx4_en_activate_cq(priv, cq); 618 err = mlx4_en_activate_cq(priv, cq);
609 if (err) { 619 if (err) {
610 en_err(priv, "Failed allocating Tx CQ\n"); 620 en_err(priv, "Failed allocating Tx CQ\n");
@@ -819,7 +829,7 @@ static int mlx4_en_close(struct net_device *dev)
819 return 0; 829 return 0;
820} 830}
821 831
822void mlx4_en_free_resources(struct mlx4_en_priv *priv) 832void mlx4_en_free_resources(struct mlx4_en_priv *priv, bool reserve_vectors)
823{ 833{
824 int i; 834 int i;
825 835
@@ -827,14 +837,14 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv)
827 if (priv->tx_ring[i].tx_info) 837 if (priv->tx_ring[i].tx_info)
828 mlx4_en_destroy_tx_ring(priv, &priv->tx_ring[i]); 838 mlx4_en_destroy_tx_ring(priv, &priv->tx_ring[i]);
829 if (priv->tx_cq[i].buf) 839 if (priv->tx_cq[i].buf)
830 mlx4_en_destroy_cq(priv, &priv->tx_cq[i]); 840 mlx4_en_destroy_cq(priv, &priv->tx_cq[i], reserve_vectors);
831 } 841 }
832 842
833 for (i = 0; i < priv->rx_ring_num; i++) { 843 for (i = 0; i < priv->rx_ring_num; i++) {
834 if (priv->rx_ring[i].rx_info) 844 if (priv->rx_ring[i].rx_info)
835 mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i]); 845 mlx4_en_destroy_rx_ring(priv, &priv->rx_ring[i]);
836 if (priv->rx_cq[i].buf) 846 if (priv->rx_cq[i].buf)
837 mlx4_en_destroy_cq(priv, &priv->rx_cq[i]); 847 mlx4_en_destroy_cq(priv, &priv->rx_cq[i], reserve_vectors);
838 } 848 }
839} 849}
840 850
@@ -896,7 +906,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
896 mdev->pndev[priv->port] = NULL; 906 mdev->pndev[priv->port] = NULL;
897 mutex_unlock(&mdev->state_lock); 907 mutex_unlock(&mdev->state_lock);
898 908
899 mlx4_en_free_resources(priv); 909 mlx4_en_free_resources(priv, false);
900 free_netdev(dev); 910 free_netdev(dev);
901} 911}
902 912
diff --git a/drivers/net/mlx4/mlx4_en.h b/drivers/net/mlx4/mlx4_en.h
index 5387c4e9f295..2db245fcd84b 100644
--- a/drivers/net/mlx4/mlx4_en.h
+++ b/drivers/net/mlx4/mlx4_en.h
@@ -62,6 +62,7 @@
62#define MLX4_EN_PAGE_SHIFT 12 62#define MLX4_EN_PAGE_SHIFT 12
63#define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT) 63#define MLX4_EN_PAGE_SIZE (1 << MLX4_EN_PAGE_SHIFT)
64#define MAX_RX_RINGS 16 64#define MAX_RX_RINGS 16
65#define MIN_RX_RINGS 4
65#define TXBB_SIZE 64 66#define TXBB_SIZE 64
66#define HEADROOM (2048 / TXBB_SIZE + 1) 67#define HEADROOM (2048 / TXBB_SIZE + 1)
67#define STAMP_STRIDE 64 68#define STAMP_STRIDE 64
@@ -462,6 +463,7 @@ struct mlx4_en_priv {
462 u16 log_rx_info; 463 u16 log_rx_info;
463 464
464 struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS]; 465 struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS];
466 int tx_vector;
465 struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS]; 467 struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS];
466 struct mlx4_en_cq tx_cq[MAX_TX_RINGS]; 468 struct mlx4_en_cq tx_cq[MAX_TX_RINGS];
467 struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; 469 struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
@@ -487,12 +489,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
487int mlx4_en_start_port(struct net_device *dev); 489int mlx4_en_start_port(struct net_device *dev);
488void mlx4_en_stop_port(struct net_device *dev); 490void mlx4_en_stop_port(struct net_device *dev);
489 491
490void mlx4_en_free_resources(struct mlx4_en_priv *priv); 492void mlx4_en_free_resources(struct mlx4_en_priv *priv, bool reserve_vectors);
491int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); 493int mlx4_en_alloc_resources(struct mlx4_en_priv *priv);
492 494
493int mlx4_en_create_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, 495int mlx4_en_create_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
494 int entries, int ring, enum cq_type mode); 496 int entries, int ring, enum cq_type mode);
495void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); 497void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
498 bool reserve_vectors);
496int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); 499int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
497void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); 500void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
498int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); 501int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);