aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorYevgeny Petrilin <yevgenyp@mellanox.co.il>2011-03-22 18:37:52 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-23 15:24:18 -0400
commit1fb9876e9bf895ea4127ff17180f1b2ab37771b6 (patch)
tree4d26408ec346531ee99e01c0c397c73e782cacef /drivers/net
parent0b7ca5a928e2271bbc225e9e1ac1f22e9fbee54f (diff)
mlx4_en: using new mlx4 interrupt scheme
Each RX ring will have its own interrupt vector, and TX rings will share one (we mostly use polling for TX completions). The vectors are assigned first time device is opened, and its name includes the interface name and ring number. Signed-off-by: Markuze Alex <markuze@mellanox.co.il> Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.co.il> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-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);