diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mlx4/en_cq.c | 38 | ||||
-rw-r--r-- | drivers/net/mlx4/en_ethtool.c | 2 | ||||
-rw-r--r-- | drivers/net/mlx4/en_main.c | 20 | ||||
-rw-r--r-- | drivers/net/mlx4/en_netdev.c | 18 | ||||
-rw-r--r-- | drivers/net/mlx4/mlx4_en.h | 7 |
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, | |||
80 | int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) | 77 | int 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 | ||
115 | void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) | 136 | void 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 | ||
822 | void mlx4_en_free_resources(struct mlx4_en_priv *priv) | 832 | void 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, | |||
487 | int mlx4_en_start_port(struct net_device *dev); | 489 | int mlx4_en_start_port(struct net_device *dev); |
488 | void mlx4_en_stop_port(struct net_device *dev); | 490 | void mlx4_en_stop_port(struct net_device *dev); |
489 | 491 | ||
490 | void mlx4_en_free_resources(struct mlx4_en_priv *priv); | 492 | void mlx4_en_free_resources(struct mlx4_en_priv *priv, bool reserve_vectors); |
491 | int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); | 493 | int mlx4_en_alloc_resources(struct mlx4_en_priv *priv); |
492 | 494 | ||
493 | int mlx4_en_create_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, | 495 | int 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); |
495 | void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); | 497 | void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq, |
498 | bool reserve_vectors); | ||
496 | int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); | 499 | int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); |
497 | void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); | 500 | void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); |
498 | int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); | 501 | int mlx4_en_set_cq_moder(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq); |