aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRasesh Mody <rmody@brocade.com>2011-09-27 06:39:10 -0400
committerDavid S. Miller <davem@davemloft.net>2011-09-29 19:36:36 -0400
commit5bcf6ac036556fcb4f9b5637f61e1227b66416cc (patch)
tree2e3da237d33194f1daf359f3b94fb2cd4eca0e24
parentaafd5c2c3cba257888450796b916a7335ee21236 (diff)
bna: Add Callback to Fix RXQ Stop
Change details: - Add a callback in the BNA, which is called before sending FW command to stop RxQs. After this callback is called, driver should not post anymore Rx buffers to the RxQ. This addresses a small window where driver posts Rx buffers while FW is stopping/has stopped the RxQ. - Registering callback function, rx_stall_cbfn, during bna_rx_create. Invoking callback function, rx_stall_cbfn, before sending rx_cfg_clr command to FW - Bnad_cb_rx_stall implementation - set a flag in the Rxq to mark buffer posting disabled state. While posting buffers check for the above flag. Signed-off-by: Gurunatha Karaje <gkaraje@brocade.com> Signed-off-by: Rasesh Mody <rmody@brocade.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_tx_rx.c11
-rw-r--r--drivers/net/ethernet/brocade/bna/bna_types.h2
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c25
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.h1
4 files changed, 38 insertions, 1 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
index 066704efe34d..276fcb589f4b 100644
--- a/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
+++ b/drivers/net/ethernet/brocade/bna/bna_tx_rx.c
@@ -1335,6 +1335,12 @@ do { \
1335 } \ 1335 } \
1336} while (0) 1336} while (0)
1337 1337
1338#define call_rx_stall_cbfn(rx) \
1339do { \
1340 if ((rx)->rx_stall_cbfn) \
1341 (rx)->rx_stall_cbfn((rx)->bna->bnad, (rx)); \
1342} while (0)
1343
1338#define bfi_enet_datapath_q_init(bfi_q, bna_qpt) \ 1344#define bfi_enet_datapath_q_init(bfi_q, bna_qpt) \
1339do { \ 1345do { \
1340 struct bna_dma_addr cur_q_addr = \ 1346 struct bna_dma_addr cur_q_addr = \
@@ -1467,6 +1473,7 @@ bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
1467 case RX_E_FAIL: 1473 case RX_E_FAIL:
1468 bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait); 1474 bfa_fsm_set_state(rx, bna_rx_sm_cleanup_wait);
1469 bna_rxf_fail(&rx->rxf); 1475 bna_rxf_fail(&rx->rxf);
1476 call_rx_stall_cbfn(rx);
1470 rx->rx_cleanup_cbfn(rx->bna->bnad, rx); 1477 rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
1471 break; 1478 break;
1472 1479
@@ -1476,6 +1483,7 @@ bna_rx_sm_rxf_stop_wait(struct bna_rx *rx, enum bna_rx_event event)
1476 1483
1477 case RX_E_RXF_STOPPED: 1484 case RX_E_RXF_STOPPED:
1478 bfa_fsm_set_state(rx, bna_rx_sm_stop_wait); 1485 bfa_fsm_set_state(rx, bna_rx_sm_stop_wait);
1486 call_rx_stall_cbfn(rx);
1479 bna_rx_enet_stop(rx); 1487 bna_rx_enet_stop(rx);
1480 break; 1488 break;
1481 1489
@@ -1516,6 +1524,7 @@ bna_rx_sm_started(struct bna_rx *rx, enum bna_rx_event event)
1516 bfa_fsm_set_state(rx, bna_rx_sm_failed); 1524 bfa_fsm_set_state(rx, bna_rx_sm_failed);
1517 bna_ethport_cb_rx_stopped(&rx->bna->ethport); 1525 bna_ethport_cb_rx_stopped(&rx->bna->ethport);
1518 bna_rxf_fail(&rx->rxf); 1526 bna_rxf_fail(&rx->rxf);
1527 call_rx_stall_cbfn(rx);
1519 rx->rx_cleanup_cbfn(rx->bna->bnad, rx); 1528 rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
1520 break; 1529 break;
1521 1530
@@ -1536,6 +1545,7 @@ static void bna_rx_sm_rxf_start_wait(struct bna_rx *rx,
1536 case RX_E_FAIL: 1545 case RX_E_FAIL:
1537 bfa_fsm_set_state(rx, bna_rx_sm_failed); 1546 bfa_fsm_set_state(rx, bna_rx_sm_failed);
1538 bna_rxf_fail(&rx->rxf); 1547 bna_rxf_fail(&rx->rxf);
1548 call_rx_stall_cbfn(rx);
1539 rx->rx_cleanup_cbfn(rx->bna->bnad, rx); 1549 rx->rx_cleanup_cbfn(rx->bna->bnad, rx);
1540 break; 1550 break;
1541 1551
@@ -2369,6 +2379,7 @@ bna_rx_create(struct bna *bna, struct bnad *bnad,
2369 rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn; 2379 rx->rcb_destroy_cbfn = rx_cbfn->rcb_destroy_cbfn;
2370 rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn; 2380 rx->ccb_setup_cbfn = rx_cbfn->ccb_setup_cbfn;
2371 rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn; 2381 rx->ccb_destroy_cbfn = rx_cbfn->ccb_destroy_cbfn;
2382 rx->rx_stall_cbfn = rx_cbfn->rx_stall_cbfn;
2372 /* Following callbacks are mandatory */ 2383 /* Following callbacks are mandatory */
2373 rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn; 2384 rx->rx_cleanup_cbfn = rx_cbfn->rx_cleanup_cbfn;
2374 rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn; 2385 rx->rx_post_cbfn = rx_cbfn->rx_post_cbfn;
diff --git a/drivers/net/ethernet/brocade/bna/bna_types.h b/drivers/net/ethernet/brocade/bna/bna_types.h
index 242d7997ffb2..d090fbfb12fa 100644
--- a/drivers/net/ethernet/brocade/bna/bna_types.h
+++ b/drivers/net/ethernet/brocade/bna/bna_types.h
@@ -847,6 +847,7 @@ struct bna_rx {
847 void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *); 847 void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *);
848 void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *); 848 void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
849 void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *); 849 void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
850 void (*rx_stall_cbfn)(struct bnad *, struct bna_rx *);
850 void (*rx_cleanup_cbfn)(struct bnad *, struct bna_rx *); 851 void (*rx_cleanup_cbfn)(struct bnad *, struct bna_rx *);
851 void (*rx_post_cbfn)(struct bnad *, struct bna_rx *); 852 void (*rx_post_cbfn)(struct bnad *, struct bna_rx *);
852 853
@@ -864,6 +865,7 @@ struct bna_rx_event_cbfn {
864 void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *); 865 void (*rcb_destroy_cbfn)(struct bnad *, struct bna_rcb *);
865 void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *); 866 void (*ccb_setup_cbfn)(struct bnad *, struct bna_ccb *);
866 void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *); 867 void (*ccb_destroy_cbfn)(struct bnad *, struct bna_ccb *);
868 void (*rx_stall_cbfn)(struct bnad *, struct bna_rx *);
867 /* Mandatory */ 869 /* Mandatory */
868 void (*rx_cleanup_cbfn)(struct bnad *, struct bna_rx *); 870 void (*rx_cleanup_cbfn)(struct bnad *, struct bna_rx *);
869 void (*rx_post_cbfn)(struct bnad *, struct bna_rx *); 871 void (*rx_post_cbfn)(struct bnad *, struct bna_rx *);
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index d76d7cb0dd0e..2f4ced66612a 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -396,7 +396,7 @@ finishing:
396 unmap_q->producer_index = unmap_prod; 396 unmap_q->producer_index = unmap_prod;
397 rcb->producer_index = unmap_prod; 397 rcb->producer_index = unmap_prod;
398 smp_mb(); 398 smp_mb();
399 if (likely(test_bit(BNAD_RXQ_STARTED, &rcb->flags))) 399 if (likely(test_bit(BNAD_RXQ_POST_OK, &rcb->flags)))
400 bna_rxq_prod_indx_doorbell(rcb); 400 bna_rxq_prod_indx_doorbell(rcb);
401 } 401 }
402} 402}
@@ -956,6 +956,27 @@ bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx)
956} 956}
957 957
958static void 958static void
959bnad_cb_rx_stall(struct bnad *bnad, struct bna_rx *rx)
960{
961 struct bnad_rx_info *rx_info = (struct bnad_rx_info *)rx->priv;
962 struct bna_ccb *ccb;
963 struct bnad_rx_ctrl *rx_ctrl;
964 int i;
965
966 for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) {
967 rx_ctrl = &rx_info->rx_ctrl[i];
968 ccb = rx_ctrl->ccb;
969 if (!ccb)
970 continue;
971
972 clear_bit(BNAD_RXQ_POST_OK, &ccb->rcb[0]->flags);
973
974 if (ccb->rcb[1])
975 clear_bit(BNAD_RXQ_POST_OK, &ccb->rcb[1]->flags);
976 }
977}
978
979static void
959bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx) 980bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx)
960{ 981{
961 struct bnad_rx_info *rx_info = (struct bnad_rx_info *)rx->priv; 982 struct bnad_rx_info *rx_info = (struct bnad_rx_info *)rx->priv;
@@ -1009,6 +1030,7 @@ bnad_cb_rx_post(struct bnad *bnad, struct bna_rx *rx)
1009 bnad_free_all_rxbufs(bnad, rcb); 1030 bnad_free_all_rxbufs(bnad, rcb);
1010 1031
1011 set_bit(BNAD_RXQ_STARTED, &rcb->flags); 1032 set_bit(BNAD_RXQ_STARTED, &rcb->flags);
1033 set_bit(BNAD_RXQ_POST_OK, &rcb->flags);
1012 unmap_q = rcb->unmap_q; 1034 unmap_q = rcb->unmap_q;
1013 1035
1014 /* Now allocate & post buffers for this RCB */ 1036 /* Now allocate & post buffers for this RCB */
@@ -1898,6 +1920,7 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
1898 .rcb_destroy_cbfn = bnad_cb_rcb_destroy, 1920 .rcb_destroy_cbfn = bnad_cb_rcb_destroy,
1899 .ccb_setup_cbfn = bnad_cb_ccb_setup, 1921 .ccb_setup_cbfn = bnad_cb_ccb_setup,
1900 .ccb_destroy_cbfn = bnad_cb_ccb_destroy, 1922 .ccb_destroy_cbfn = bnad_cb_ccb_destroy,
1923 .rx_stall_cbfn = bnad_cb_rx_stall,
1901 .rx_cleanup_cbfn = bnad_cb_rx_cleanup, 1924 .rx_cleanup_cbfn = bnad_cb_rx_cleanup,
1902 .rx_post_cbfn = bnad_cb_rx_post, 1925 .rx_post_cbfn = bnad_cb_rx_post,
1903 }; 1926 };
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index 1c9328d564d2..50fb36aedd5d 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -103,6 +103,7 @@ struct bnad_rx_ctrl {
103/* Bit positions for rcb->flags */ 103/* Bit positions for rcb->flags */
104#define BNAD_RXQ_REFILL 0 104#define BNAD_RXQ_REFILL 0
105#define BNAD_RXQ_STARTED 1 105#define BNAD_RXQ_STARTED 1
106#define BNAD_RXQ_POST_OK 2
106 107
107/* Resource limits */ 108/* Resource limits */
108#define BNAD_NUM_TXQ (bnad->num_tx * bnad->num_txq_per_tx) 109#define BNAD_NUM_TXQ (bnad->num_tx * bnad->num_txq_per_tx)