diff options
author | Rasesh Mody <rmody@brocade.com> | 2011-09-27 14:39:10 +0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-30 03:36:36 +0400 |
commit | 5bcf6ac036556fcb4f9b5637f61e1227b66416cc (patch) | |
tree | 2e3da237d33194f1daf359f3b94fb2cd4eca0e24 /drivers/net/ethernet/brocade/bna/bnad.c | |
parent | aafd5c2c3cba257888450796b916a7335ee21236 (diff) | |
download | linux-5bcf6ac036556fcb4f9b5637f61e1227b66416cc.tar.xz |
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>
Diffstat (limited to 'drivers/net/ethernet/brocade/bna/bnad.c')
-rw-r--r-- | drivers/net/ethernet/brocade/bna/bnad.c | 25 |
1 files changed, 24 insertions, 1 deletions
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: unmap_q->producer_index = unmap_prod; rcb->producer_index = unmap_prod; smp_mb(); - if (likely(test_bit(BNAD_RXQ_STARTED, &rcb->flags))) + if (likely(test_bit(BNAD_RXQ_POST_OK, &rcb->flags))) bna_rxq_prod_indx_doorbell(rcb); } } @@ -956,6 +956,27 @@ bnad_cb_tx_cleanup(struct bnad *bnad, struct bna_tx *tx) } static void +bnad_cb_rx_stall(struct bnad *bnad, struct bna_rx *rx) +{ + struct bnad_rx_info *rx_info = (struct bnad_rx_info *)rx->priv; + struct bna_ccb *ccb; + struct bnad_rx_ctrl *rx_ctrl; + int i; + + for (i = 0; i < BNAD_MAX_RXP_PER_RX; i++) { + rx_ctrl = &rx_info->rx_ctrl[i]; + ccb = rx_ctrl->ccb; + if (!ccb) + continue; + + clear_bit(BNAD_RXQ_POST_OK, &ccb->rcb[0]->flags); + + if (ccb->rcb[1]) + clear_bit(BNAD_RXQ_POST_OK, &ccb->rcb[1]->flags); + } +} + +static void bnad_cb_rx_cleanup(struct bnad *bnad, struct bna_rx *rx) { 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) bnad_free_all_rxbufs(bnad, rcb); set_bit(BNAD_RXQ_STARTED, &rcb->flags); + set_bit(BNAD_RXQ_POST_OK, &rcb->flags); unmap_q = rcb->unmap_q; /* Now allocate & post buffers for this RCB */ @@ -1898,6 +1920,7 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id) .rcb_destroy_cbfn = bnad_cb_rcb_destroy, .ccb_setup_cbfn = bnad_cb_ccb_setup, .ccb_destroy_cbfn = bnad_cb_ccb_destroy, + .rx_stall_cbfn = bnad_cb_rx_stall, .rx_cleanup_cbfn = bnad_cb_rx_cleanup, .rx_post_cbfn = bnad_cb_rx_post, }; |