aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/mlx4
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/mlx4')
-rw-r--r--drivers/net/mlx4/en_cq.c3
-rw-r--r--drivers/net/mlx4/en_netdev.c23
-rw-r--r--drivers/net/mlx4/en_rx.c71
3 files changed, 58 insertions, 39 deletions
diff --git a/drivers/net/mlx4/en_cq.c b/drivers/net/mlx4/en_cq.c
index a276125b709b..21786ad4455e 100644
--- a/drivers/net/mlx4/en_cq.c
+++ b/drivers/net/mlx4/en_cq.c
@@ -89,6 +89,9 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
89 *cq->mcq.arm_db = 0; 89 *cq->mcq.arm_db = 0;
90 memset(cq->buf, 0, cq->buf_size); 90 memset(cq->buf, 0, cq->buf_size);
91 91
92 if (!cq->is_tx)
93 cq->size = priv->rx_ring[cq->ring].actual_size;
94
92 err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt, &mdev->priv_uar, 95 err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt, &mdev->priv_uar,
93 cq->wqres.db.dma, &cq->mcq, cq->vector, cq->is_tx); 96 cq->wqres.db.dma, &cq->mcq, cq->vector, cq->is_tx);
94 if (err) 97 if (err)
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index be487fa8d9a7..0cd185a2e089 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -556,7 +556,6 @@ int mlx4_en_start_port(struct net_device *dev)
556 struct mlx4_en_dev *mdev = priv->mdev; 556 struct mlx4_en_dev *mdev = priv->mdev;
557 struct mlx4_en_cq *cq; 557 struct mlx4_en_cq *cq;
558 struct mlx4_en_tx_ring *tx_ring; 558 struct mlx4_en_tx_ring *tx_ring;
559 struct mlx4_en_rx_ring *rx_ring;
560 int rx_index = 0; 559 int rx_index = 0;
561 int tx_index = 0; 560 int tx_index = 0;
562 int err = 0; 561 int err = 0;
@@ -572,10 +571,15 @@ int mlx4_en_start_port(struct net_device *dev)
572 dev->mtu = min(dev->mtu, priv->max_mtu); 571 dev->mtu = min(dev->mtu, priv->max_mtu);
573 mlx4_en_calc_rx_buf(dev); 572 mlx4_en_calc_rx_buf(dev);
574 mlx4_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size); 573 mlx4_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
574
575 /* Configure rx cq's and rings */ 575 /* Configure rx cq's and rings */
576 err = mlx4_en_activate_rx_rings(priv);
577 if (err) {
578 mlx4_err(mdev, "Failed to activate RX rings\n");
579 return err;
580 }
576 for (i = 0; i < priv->rx_ring_num; i++) { 581 for (i = 0; i < priv->rx_ring_num; i++) {
577 cq = &priv->rx_cq[i]; 582 cq = &priv->rx_cq[i];
578 rx_ring = &priv->rx_ring[i];
579 583
580 err = mlx4_en_activate_cq(priv, cq); 584 err = mlx4_en_activate_cq(priv, cq);
581 if (err) { 585 if (err) {
@@ -591,20 +595,14 @@ int mlx4_en_start_port(struct net_device *dev)
591 goto cq_err; 595 goto cq_err;
592 } 596 }
593 mlx4_en_arm_cq(priv, cq); 597 mlx4_en_arm_cq(priv, cq);
594 598 priv->rx_ring[i].cqn = cq->mcq.cqn;
595 ++rx_index; 599 ++rx_index;
596 } 600 }
597 601
598 err = mlx4_en_activate_rx_rings(priv);
599 if (err) {
600 mlx4_err(mdev, "Failed to activate RX rings\n");
601 goto cq_err;
602 }
603
604 err = mlx4_en_config_rss_steer(priv); 602 err = mlx4_en_config_rss_steer(priv);
605 if (err) { 603 if (err) {
606 mlx4_err(mdev, "Failed configuring rss steering\n"); 604 mlx4_err(mdev, "Failed configuring rss steering\n");
607 goto rx_err; 605 goto cq_err;
608 } 606 }
609 607
610 /* Configure tx cq's and rings */ 608 /* Configure tx cq's and rings */
@@ -691,12 +689,11 @@ tx_err:
691 } 689 }
692 690
693 mlx4_en_release_rss_steer(priv); 691 mlx4_en_release_rss_steer(priv);
694rx_err:
695 for (i = 0; i < priv->rx_ring_num; i++)
696 mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
697cq_err: 692cq_err:
698 while (rx_index--) 693 while (rx_index--)
699 mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]); 694 mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
695 for (i = 0; i < priv->rx_ring_num; i++)
696 mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
700 697
701 return err; /* need to close devices */ 698 return err; /* need to close devices */
702} 699}
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index 9ee873e872b3..6bfab6e5ba1d 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -202,12 +202,35 @@ static inline void mlx4_en_update_rx_prod_db(struct mlx4_en_rx_ring *ring)
202 *ring->wqres.db.db = cpu_to_be32(ring->prod & 0xffff); 202 *ring->wqres.db.db = cpu_to_be32(ring->prod & 0xffff);
203} 203}
204 204
205static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv,
206 struct mlx4_en_rx_ring *ring,
207 int index)
208{
209 struct mlx4_en_dev *mdev = priv->mdev;
210 struct skb_frag_struct *skb_frags;
211 struct mlx4_en_rx_desc *rx_desc = ring->buf + (index << ring->log_stride);
212 dma_addr_t dma;
213 int nr;
214
215 skb_frags = ring->rx_info + (index << priv->log_rx_info);
216 for (nr = 0; nr < priv->num_frags; nr++) {
217 mlx4_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
218 dma = be64_to_cpu(rx_desc->data[nr].addr);
219
220 mlx4_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
221 pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
222 PCI_DMA_FROMDEVICE);
223 put_page(skb_frags[nr].page);
224 }
225}
226
205static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv) 227static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
206{ 228{
207 struct mlx4_en_dev *mdev = priv->mdev; 229 struct mlx4_en_dev *mdev = priv->mdev;
208 struct mlx4_en_rx_ring *ring; 230 struct mlx4_en_rx_ring *ring;
209 int ring_ind; 231 int ring_ind;
210 int buf_ind; 232 int buf_ind;
233 int new_size;
211 234
212 for (buf_ind = 0; buf_ind < priv->prof->rx_ring_size; buf_ind++) { 235 for (buf_ind = 0; buf_ind < priv->prof->rx_ring_size; buf_ind++) {
213 for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) { 236 for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
@@ -220,18 +243,30 @@ static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
220 "enough rx buffers\n"); 243 "enough rx buffers\n");
221 return -ENOMEM; 244 return -ENOMEM;
222 } else { 245 } else {
223 if (netif_msg_rx_err(priv)) 246 new_size = rounddown_pow_of_two(ring->actual_size);
224 mlx4_warn(mdev, 247 mlx4_warn(mdev, "Only %d buffers allocated "
225 "Only %d buffers allocated\n", 248 "reducing ring size to %d",
226 ring->actual_size); 249 ring->actual_size, new_size);
227 goto out; 250 goto reduce_rings;
228 } 251 }
229 } 252 }
230 ring->actual_size++; 253 ring->actual_size++;
231 ring->prod++; 254 ring->prod++;
232 } 255 }
233 } 256 }
234out: 257 return 0;
258
259reduce_rings:
260 for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
261 ring = &priv->rx_ring[ring_ind];
262 while (ring->actual_size > new_size) {
263 ring->actual_size--;
264 ring->prod--;
265 mlx4_en_free_rx_desc(priv, ring, ring->actual_size);
266 }
267 ring->size_mask = ring->actual_size - 1;
268 }
269
235 return 0; 270 return 0;
236} 271}
237 272
@@ -255,7 +290,7 @@ static int mlx4_en_fill_rx_buf(struct net_device *dev,
255 ++num; 290 ++num;
256 ++ring->prod; 291 ++ring->prod;
257 } 292 }
258 if ((u32) (ring->prod - ring->cons) == ring->size) 293 if ((u32) (ring->prod - ring->cons) == ring->actual_size)
259 ring->full = 1; 294 ring->full = 1;
260 295
261 return num; 296 return num;
@@ -264,33 +299,17 @@ static int mlx4_en_fill_rx_buf(struct net_device *dev,
264static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv, 299static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv,
265 struct mlx4_en_rx_ring *ring) 300 struct mlx4_en_rx_ring *ring)
266{ 301{
267 struct mlx4_en_dev *mdev = priv->mdev;
268 struct skb_frag_struct *skb_frags;
269 struct mlx4_en_rx_desc *rx_desc;
270 dma_addr_t dma;
271 int index; 302 int index;
272 int nr;
273 303
274 mlx4_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n", 304 mlx4_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n",
275 ring->cons, ring->prod); 305 ring->cons, ring->prod);
276 306
277 /* Unmap and free Rx buffers */ 307 /* Unmap and free Rx buffers */
278 BUG_ON((u32) (ring->prod - ring->cons) > ring->size); 308 BUG_ON((u32) (ring->prod - ring->cons) > ring->actual_size);
279 while (ring->cons != ring->prod) { 309 while (ring->cons != ring->prod) {
280 index = ring->cons & ring->size_mask; 310 index = ring->cons & ring->size_mask;
281 rx_desc = ring->buf + (index << ring->log_stride);
282 skb_frags = ring->rx_info + (index << priv->log_rx_info);
283 mlx4_dbg(DRV, priv, "Processing descriptor:%d\n", index); 311 mlx4_dbg(DRV, priv, "Processing descriptor:%d\n", index);
284 312 mlx4_en_free_rx_desc(priv, ring, index);
285 for (nr = 0; nr < priv->num_frags; nr++) {
286 mlx4_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
287 dma = be64_to_cpu(rx_desc->data[nr].addr);
288
289 mlx4_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
290 pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
291 PCI_DMA_FROMDEVICE);
292 put_page(skb_frags[nr].page);
293 }
294 ++ring->cons; 313 ++ring->cons;
295 } 314 }
296} 315}
@@ -454,7 +473,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
454 mlx4_en_update_rx_prod_db(ring); 473 mlx4_en_update_rx_prod_db(ring);
455 474
456 /* Configure SRQ representing the ring */ 475 /* Configure SRQ representing the ring */
457 ring->srq.max = ring->size; 476 ring->srq.max = ring->actual_size;
458 ring->srq.max_gs = max_gs; 477 ring->srq.max_gs = max_gs;
459 ring->srq.wqe_shift = ilog2(ring->stride); 478 ring->srq.wqe_shift = ilog2(ring->stride);
460 479