aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEugenia Emantayev <eugenia@mellanox.com>2013-12-19 14:20:17 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-19 19:04:44 -0500
commit0276a330617a0cf380f09e5065299078d3d45886 (patch)
treeb2b2beef33e9136790157dbd566f191d37d5ed70
parente4b59a1cb6f8feb03f356b0abfd20451f05d7470 (diff)
net/mlx4_en: Add NAPI support for transmit side
Add NAPI for TX side, implement its support and provide NAPI callback. Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.com> Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_cq.c12
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/en_tx.c39
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4_en.h1
3 files changed, 41 insertions, 11 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
index 3a098cc4d349..70e95324a97d 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
@@ -161,12 +161,16 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
161 cq->mcq.comp = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq; 161 cq->mcq.comp = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
162 cq->mcq.event = mlx4_en_cq_event; 162 cq->mcq.event = mlx4_en_cq_event;
163 163
164 if (!cq->is_tx) { 164 if (cq->is_tx) {
165 netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_tx_cq,
166 NAPI_POLL_WEIGHT);
167 } else {
165 netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64); 168 netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
166 napi_hash_add(&cq->napi); 169 napi_hash_add(&cq->napi);
167 napi_enable(&cq->napi);
168 } 170 }
169 171
172 napi_enable(&cq->napi);
173
170 return 0; 174 return 0;
171} 175}
172 176
@@ -188,12 +192,12 @@ void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
188 192
189void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) 193void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
190{ 194{
195 napi_disable(&cq->napi);
191 if (!cq->is_tx) { 196 if (!cq->is_tx) {
192 napi_disable(&cq->napi);
193 napi_hash_del(&cq->napi); 197 napi_hash_del(&cq->napi);
194 synchronize_rcu(); 198 synchronize_rcu();
195 netif_napi_del(&cq->napi);
196 } 199 }
200 netif_napi_del(&cq->napi);
197 201
198 mlx4_cq_free(priv->mdev->dev, &cq->mcq); 202 mlx4_cq_free(priv->mdev->dev, &cq->mcq);
199} 203}
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
index 5e22d7d46b50..e3adcebfdfb8 100644
--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
@@ -324,7 +324,7 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
324 } 324 }
325 } 325 }
326 } 326 }
327 dev_kfree_skb_any(skb); 327 dev_kfree_skb(skb);
328 return tx_info->nr_txbb; 328 return tx_info->nr_txbb;
329} 329}
330 330
@@ -361,7 +361,9 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
361 return cnt; 361 return cnt;
362} 362}
363 363
364static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) 364static int mlx4_en_process_tx_cq(struct net_device *dev,
365 struct mlx4_en_cq *cq,
366 int budget)
365{ 367{
366 struct mlx4_en_priv *priv = netdev_priv(dev); 368 struct mlx4_en_priv *priv = netdev_priv(dev);
367 struct mlx4_cq *mcq = &cq->mcq; 369 struct mlx4_cq *mcq = &cq->mcq;
@@ -379,9 +381,10 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
379 u32 bytes = 0; 381 u32 bytes = 0;
380 int factor = priv->cqe_factor; 382 int factor = priv->cqe_factor;
381 u64 timestamp = 0; 383 u64 timestamp = 0;
384 int done = 0;
382 385
383 if (!priv->port_up) 386 if (!priv->port_up)
384 return; 387 return 0;
385 388
386 index = cons_index & size_mask; 389 index = cons_index & size_mask;
387 cqe = &buf[(index << factor) + factor]; 390 cqe = &buf[(index << factor) + factor];
@@ -390,7 +393,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
390 393
391 /* Process all completed CQEs */ 394 /* Process all completed CQEs */
392 while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK, 395 while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK,
393 cons_index & size)) { 396 cons_index & size) && (done < budget)) {
394 /* 397 /*
395 * make sure we read the CQE after we read the 398 * make sure we read the CQE after we read the
396 * ownership bit 399 * ownership bit
@@ -428,7 +431,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
428 txbbs_stamp = txbbs_skipped; 431 txbbs_stamp = txbbs_skipped;
429 packets++; 432 packets++;
430 bytes += ring->tx_info[ring_index].nr_bytes; 433 bytes += ring->tx_info[ring_index].nr_bytes;
431 } while (ring_index != new_index); 434 } while ((++done < budget) && (ring_index != new_index));
432 435
433 ++cons_index; 436 ++cons_index;
434 index = cons_index & size_mask; 437 index = cons_index & size_mask;
@@ -454,6 +457,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
454 netif_tx_wake_queue(ring->tx_queue); 457 netif_tx_wake_queue(ring->tx_queue);
455 priv->port_stats.wake_queue++; 458 priv->port_stats.wake_queue++;
456 } 459 }
460 return done;
457} 461}
458 462
459void mlx4_en_tx_irq(struct mlx4_cq *mcq) 463void mlx4_en_tx_irq(struct mlx4_cq *mcq)
@@ -461,10 +465,31 @@ void mlx4_en_tx_irq(struct mlx4_cq *mcq)
461 struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq); 465 struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq);
462 struct mlx4_en_priv *priv = netdev_priv(cq->dev); 466 struct mlx4_en_priv *priv = netdev_priv(cq->dev);
463 467
464 mlx4_en_process_tx_cq(cq->dev, cq); 468 if (priv->port_up)
465 mlx4_en_arm_cq(priv, cq); 469 napi_schedule(&cq->napi);
470 else
471 mlx4_en_arm_cq(priv, cq);
466} 472}
467 473
474/* TX CQ polling - called by NAPI */
475int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget)
476{
477 struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
478 struct net_device *dev = cq->dev;
479 struct mlx4_en_priv *priv = netdev_priv(dev);
480 int done;
481
482 done = mlx4_en_process_tx_cq(dev, cq, budget);
483
484 /* If we used up all the quota - we're probably not done yet... */
485 if (done < budget) {
486 /* Done for now */
487 napi_complete(napi);
488 mlx4_en_arm_cq(priv, cq);
489 return done;
490 }
491 return budget;
492}
468 493
469static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv, 494static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
470 struct mlx4_en_tx_ring *ring, 495 struct mlx4_en_tx_ring *ring,
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
index 202d8e5eb41f..123714cbd35f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h
@@ -744,6 +744,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev,
744 struct mlx4_en_cq *cq, 744 struct mlx4_en_cq *cq,
745 int budget); 745 int budget);
746int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget); 746int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
747int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget);
747void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, 748void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
748 int is_tx, int rss, int qpn, int cqn, int user_prio, 749 int is_tx, int rss, int qpn, int cqn, int user_prio,
749 struct mlx4_qp_context *context); 750 struct mlx4_qp_context *context);