diff options
author | Eugenia Emantayev <eugenia@mellanox.com> | 2013-12-19 14:20:17 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-19 19:04:44 -0500 |
commit | 0276a330617a0cf380f09e5065299078d3d45886 (patch) | |
tree | b2b2beef33e9136790157dbd566f191d37d5ed70 | |
parent | e4b59a1cb6f8feb03f356b0abfd20451f05d7470 (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.c | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_tx.c | 39 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 |
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 | ||
189 | void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq) | 193 | void 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 | ||
364 | static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq) | 364 | static 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 | ||
459 | void mlx4_en_tx_irq(struct mlx4_cq *mcq) | 463 | void 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 */ | ||
475 | int 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 | ||
469 | static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv, | 494 | static 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); |
746 | int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget); | 746 | int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget); |
747 | int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget); | ||
747 | void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride, | 748 | void 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); |