aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalesh AP <kalesh.purayil@avagotech.com>2015-08-05 03:27:49 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-07 14:53:05 -0400
commit99b44304f205a826501721d41928e87b0b9cf3b3 (patch)
tree9f95a93aa75e7e63aa375f6d1020fa8947c5331b
parentbcc84140a62c04f522eacceb793e6eef92965c84 (diff)
be2net: post buffers before destroying RXQs in Lancer
An RX stall issue was seen on Lancer adapters, when RXQs are destroyed while they are in an "out of buffer" state. This patch fixes this issue by posting 64 buffers to each RXQ before destroying them in the close path. This is done after ensuring that no more new packets are selected for transfer to the RXQs by disabling interface filters. Signed-off-by: Kalesh AP <kalesh.purayil@avagotech.com> Signed-off-by: Sathya Perla <sathya.perla@avagotech.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 7730f21b6071..14ae67a8949e 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2451,10 +2451,24 @@ static void be_eq_clean(struct be_eq_obj *eqo)
2451 be_eq_notify(eqo->adapter, eqo->q.id, false, true, num, 0); 2451 be_eq_notify(eqo->adapter, eqo->q.id, false, true, num, 0);
2452} 2452}
2453 2453
2454static void be_rx_cq_clean(struct be_rx_obj *rxo) 2454/* Free posted rx buffers that were not used */
2455static void be_rxq_clean(struct be_rx_obj *rxo)
2455{ 2456{
2456 struct be_rx_page_info *page_info;
2457 struct be_queue_info *rxq = &rxo->q; 2457 struct be_queue_info *rxq = &rxo->q;
2458 struct be_rx_page_info *page_info;
2459
2460 while (atomic_read(&rxq->used) > 0) {
2461 page_info = get_rx_page_info(rxo);
2462 put_page(page_info->page);
2463 memset(page_info, 0, sizeof(*page_info));
2464 }
2465 BUG_ON(atomic_read(&rxq->used));
2466 rxq->tail = 0;
2467 rxq->head = 0;
2468}
2469
2470static void be_rx_cq_clean(struct be_rx_obj *rxo)
2471{
2458 struct be_queue_info *rx_cq = &rxo->cq; 2472 struct be_queue_info *rx_cq = &rxo->cq;
2459 struct be_rx_compl_info *rxcp; 2473 struct be_rx_compl_info *rxcp;
2460 struct be_adapter *adapter = rxo->adapter; 2474 struct be_adapter *adapter = rxo->adapter;
@@ -2491,16 +2505,6 @@ static void be_rx_cq_clean(struct be_rx_obj *rxo)
2491 2505
2492 /* After cleanup, leave the CQ in unarmed state */ 2506 /* After cleanup, leave the CQ in unarmed state */
2493 be_cq_notify(adapter, rx_cq->id, false, 0); 2507 be_cq_notify(adapter, rx_cq->id, false, 0);
2494
2495 /* Then free posted rx buffers that were not used */
2496 while (atomic_read(&rxq->used) > 0) {
2497 page_info = get_rx_page_info(rxo);
2498 put_page(page_info->page);
2499 memset(page_info, 0, sizeof(*page_info));
2500 }
2501 BUG_ON(atomic_read(&rxq->used));
2502 rxq->tail = 0;
2503 rxq->head = 0;
2504} 2508}
2505 2509
2506static void be_tx_compl_clean(struct be_adapter *adapter) 2510static void be_tx_compl_clean(struct be_adapter *adapter)
@@ -3358,8 +3362,22 @@ static void be_rx_qs_destroy(struct be_adapter *adapter)
3358 for_all_rx_queues(adapter, rxo, i) { 3362 for_all_rx_queues(adapter, rxo, i) {
3359 q = &rxo->q; 3363 q = &rxo->q;
3360 if (q->created) { 3364 if (q->created) {
3365 /* If RXQs are destroyed while in an "out of buffer"
3366 * state, there is a possibility of an HW stall on
3367 * Lancer. So, post 64 buffers to each queue to relieve
3368 * the "out of buffer" condition.
3369 * Make sure there's space in the RXQ before posting.
3370 */
3371 if (lancer_chip(adapter)) {
3372 be_rx_cq_clean(rxo);
3373 if (atomic_read(&q->used) == 0)
3374 be_post_rx_frags(rxo, GFP_KERNEL,
3375 MAX_RX_POST);
3376 }
3377
3361 be_cmd_rxq_destroy(adapter, q); 3378 be_cmd_rxq_destroy(adapter, q);
3362 be_rx_cq_clean(rxo); 3379 be_rx_cq_clean(rxo);
3380 be_rxq_clean(rxo);
3363 } 3381 }
3364 be_queue_free(adapter, q); 3382 be_queue_free(adapter, q);
3365 } 3383 }