aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRasesh Mody <rmody@brocade.com>2011-08-30 11:27:39 -0400
committerDavid S. Miller <davem@davemloft.net>2011-09-15 15:36:33 -0400
commit2be671442214402f890e367a19b5fc64cc13f878 (patch)
treef52dbb1500ee6d61623a0f3ee328319dd9aa5bba /drivers
parent0caa9aaec515268ec13b0939bfb7e32cf5a31a55 (diff)
bna: Interrupt Polling and NAPI Init Changes
Change details: - Remove unnecessary ccb check from bnad_poll_cq - Add bnad pointer to rx_ctrl structure, so that bnad can be accessed directly from rx_ctrl in the NAPI poll routines, even if ccb is NULL - Validate ccb before referencing to it in bnad_msix_rx and bnad_napi_poll_rx - Fix the order of NAPI init / uninit in Tx / Rx setup / teardown path: a. Kill bnad tx free tasklet ahead of call to bna_tx_destroy() b. Call NAPI disable only after call to Rx free_irq(). This makes sure Rx interrupt does not schedule a poll when NAPI is already disabled - NAPI poll runs before the h/w has completed configuration. This causes a crash. Delay enabling NAPI till after bna_rx_enable(). Split NAPI initialization into 2 steps, bnad_napi_init() & bnad_napi_enable(). 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')
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.c83
-rw-r--r--drivers/net/ethernet/brocade/bna/bnad.h1
2 files changed, 54 insertions, 30 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c
index 939abd45c0a4..630e818551a5 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.c
+++ b/drivers/net/ethernet/brocade/bna/bnad.c
@@ -535,16 +535,11 @@ next:
535 535
536 BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth); 536 BNA_QE_INDX_ADD(ccb->producer_index, wis, ccb->q_depth);
537 537
538 if (likely(ccb)) { 538 if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
539 if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags))) 539 bna_ib_ack(ccb->i_dbell, packets);
540 bna_ib_ack(ccb->i_dbell, packets); 540 bnad_refill_rxq(bnad, ccb->rcb[0]);
541 bnad_refill_rxq(bnad, ccb->rcb[0]); 541 if (ccb->rcb[1])
542 if (ccb->rcb[1]) 542 bnad_refill_rxq(bnad, ccb->rcb[1]);
543 bnad_refill_rxq(bnad, ccb->rcb[1]);
544 } else {
545 if (likely(test_bit(BNAD_RXQ_STARTED, &ccb->rcb[0]->flags)))
546 bna_ib_ack(ccb->i_dbell, 0);
547 }
548 543
549 clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags); 544 clear_bit(BNAD_FP_IN_RX_PATH, &rx_ctrl->flags);
550 545
@@ -590,9 +585,9 @@ static irqreturn_t
590bnad_msix_rx(int irq, void *data) 585bnad_msix_rx(int irq, void *data)
591{ 586{
592 struct bna_ccb *ccb = (struct bna_ccb *)data; 587 struct bna_ccb *ccb = (struct bna_ccb *)data;
593 struct bnad *bnad = ccb->bnad;
594 588
595 bnad_netif_rx_schedule_poll(bnad, ccb); 589 if (ccb)
590 bnad_netif_rx_schedule_poll(ccb->bnad, ccb);
596 591
597 return IRQ_HANDLED; 592 return IRQ_HANDLED;
598} 593}
@@ -1658,18 +1653,14 @@ bnad_napi_poll_rx(struct napi_struct *napi, int budget)
1658{ 1653{
1659 struct bnad_rx_ctrl *rx_ctrl = 1654 struct bnad_rx_ctrl *rx_ctrl =
1660 container_of(napi, struct bnad_rx_ctrl, napi); 1655 container_of(napi, struct bnad_rx_ctrl, napi);
1661 struct bna_ccb *ccb; 1656 struct bnad *bnad = rx_ctrl->bnad;
1662 struct bnad *bnad;
1663 int rcvd = 0; 1657 int rcvd = 0;
1664 1658
1665 ccb = rx_ctrl->ccb;
1666
1667 bnad = ccb->bnad;
1668 1659
1669 if (!netif_carrier_ok(bnad->netdev)) 1660 if (!netif_carrier_ok(bnad->netdev))
1670 goto poll_exit; 1661 goto poll_exit;
1671 1662
1672 rcvd = bnad_poll_cq(bnad, ccb, budget); 1663 rcvd = bnad_poll_cq(bnad, rx_ctrl->ccb, budget);
1673 if (rcvd == budget) 1664 if (rcvd == budget)
1674 return rcvd; 1665 return rcvd;
1675 1666
@@ -1678,12 +1669,15 @@ poll_exit:
1678 1669
1679 BNAD_UPDATE_CTR(bnad, netif_rx_complete); 1670 BNAD_UPDATE_CTR(bnad, netif_rx_complete);
1680 1671
1681 bnad_enable_rx_irq(bnad, ccb); 1672
1673 if (rx_ctrl->ccb)
1674 bnad_enable_rx_irq(bnad, rx_ctrl->ccb);
1682 return rcvd; 1675 return rcvd;
1683} 1676}
1684 1677
1678#define BNAD_NAPI_POLL_QUOTA 64
1685static void 1679static void
1686bnad_napi_enable(struct bnad *bnad, u32 rx_id) 1680bnad_napi_init(struct bnad *bnad, u32 rx_id)
1687{ 1681{
1688 struct bnad_rx_ctrl *rx_ctrl; 1682 struct bnad_rx_ctrl *rx_ctrl;
1689 int i; 1683 int i;
@@ -1691,9 +1685,20 @@ bnad_napi_enable(struct bnad *bnad, u32 rx_id)
1691 /* Initialize & enable NAPI */ 1685 /* Initialize & enable NAPI */
1692 for (i = 0; i < bnad->num_rxp_per_rx; i++) { 1686 for (i = 0; i < bnad->num_rxp_per_rx; i++) {
1693 rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i]; 1687 rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
1694
1695 netif_napi_add(bnad->netdev, &rx_ctrl->napi, 1688 netif_napi_add(bnad->netdev, &rx_ctrl->napi,
1696 bnad_napi_poll_rx, 64); 1689 bnad_napi_poll_rx, BNAD_NAPI_POLL_QUOTA);
1690 }
1691}
1692
1693static void
1694bnad_napi_enable(struct bnad *bnad, u32 rx_id)
1695{
1696 struct bnad_rx_ctrl *rx_ctrl;
1697 int i;
1698
1699 /* Initialize & enable NAPI */
1700 for (i = 0; i < bnad->num_rxp_per_rx; i++) {
1701 rx_ctrl = &bnad->rx_info[rx_id].rx_ctrl[i];
1697 1702
1698 napi_enable(&rx_ctrl->napi); 1703 napi_enable(&rx_ctrl->napi);
1699 } 1704 }
@@ -1732,6 +1737,9 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
1732 bnad_tx_msix_unregister(bnad, tx_info, 1737 bnad_tx_msix_unregister(bnad, tx_info,
1733 bnad->num_txq_per_tx); 1738 bnad->num_txq_per_tx);
1734 1739
1740 if (0 == tx_id)
1741 tasklet_kill(&bnad->tx_free_tasklet);
1742
1735 spin_lock_irqsave(&bnad->bna_lock, flags); 1743 spin_lock_irqsave(&bnad->bna_lock, flags);
1736 bna_tx_destroy(tx_info->tx); 1744 bna_tx_destroy(tx_info->tx);
1737 spin_unlock_irqrestore(&bnad->bna_lock, flags); 1745 spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -1739,9 +1747,6 @@ bnad_cleanup_tx(struct bnad *bnad, u32 tx_id)
1739 tx_info->tx = NULL; 1747 tx_info->tx = NULL;
1740 tx_info->tx_id = 0; 1748 tx_info->tx_id = 0;
1741 1749
1742 if (0 == tx_id)
1743 tasklet_kill(&bnad->tx_free_tasklet);
1744
1745 bnad_tx_res_free(bnad, res_info); 1750 bnad_tx_res_free(bnad, res_info);
1746} 1751}
1747 1752
@@ -1852,6 +1857,16 @@ bnad_init_rx_config(struct bnad *bnad, struct bna_rx_config *rx_config)
1852 rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED; 1857 rx_config->vlan_strip_status = BNA_STATUS_T_ENABLED;
1853} 1858}
1854 1859
1860static void
1861bnad_rx_ctrl_init(struct bnad *bnad, u32 rx_id)
1862{
1863 struct bnad_rx_info *rx_info = &bnad->rx_info[rx_id];
1864 int i;
1865
1866 for (i = 0; i < bnad->num_rxp_per_rx; i++)
1867 rx_info->rx_ctrl[i].bnad = bnad;
1868}
1869
1855/* Called with mutex_lock(&bnad->conf_mutex) held */ 1870/* Called with mutex_lock(&bnad->conf_mutex) held */
1856void 1871void
1857bnad_cleanup_rx(struct bnad *bnad, u32 rx_id) 1872bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
@@ -1875,8 +1890,6 @@ bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
1875 del_timer_sync(&bnad->dim_timer); 1890 del_timer_sync(&bnad->dim_timer);
1876 } 1891 }
1877 1892
1878 bnad_napi_disable(bnad, rx_id);
1879
1880 init_completion(&bnad->bnad_completions.rx_comp); 1893 init_completion(&bnad->bnad_completions.rx_comp);
1881 spin_lock_irqsave(&bnad->bna_lock, flags); 1894 spin_lock_irqsave(&bnad->bna_lock, flags);
1882 bna_rx_disable(rx_info->rx, BNA_HARD_CLEANUP, bnad_cb_rx_disabled); 1895 bna_rx_disable(rx_info->rx, BNA_HARD_CLEANUP, bnad_cb_rx_disabled);
@@ -1886,6 +1899,8 @@ bnad_cleanup_rx(struct bnad *bnad, u32 rx_id)
1886 if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX) 1899 if (rx_info->rx_ctrl[0].ccb->intr_type == BNA_INTR_T_MSIX)
1887 bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths); 1900 bnad_rx_msix_unregister(bnad, rx_info, rx_config->num_paths);
1888 1901
1902 bnad_napi_disable(bnad, rx_id);
1903
1889 spin_lock_irqsave(&bnad->bna_lock, flags); 1904 spin_lock_irqsave(&bnad->bna_lock, flags);
1890 bna_rx_destroy(rx_info->rx); 1905 bna_rx_destroy(rx_info->rx);
1891 spin_unlock_irqrestore(&bnad->bna_lock, flags); 1906 spin_unlock_irqrestore(&bnad->bna_lock, flags);
@@ -1939,6 +1954,8 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
1939 if (err) 1954 if (err)
1940 return err; 1955 return err;
1941 1956
1957 bnad_rx_ctrl_init(bnad, rx_id);
1958
1942 /* Ask BNA to create one Rx object, supplying required resources */ 1959 /* Ask BNA to create one Rx object, supplying required resources */
1943 spin_lock_irqsave(&bnad->bna_lock, flags); 1960 spin_lock_irqsave(&bnad->bna_lock, flags);
1944 rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info, 1961 rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info,
@@ -1948,6 +1965,12 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
1948 goto err_return; 1965 goto err_return;
1949 rx_info->rx = rx; 1966 rx_info->rx = rx;
1950 1967
1968 /*
1969 * Init NAPI, so that state is set to NAPI_STATE_SCHED,
1970 * so that IRQ handler cannot schedule NAPI at this point.
1971 */
1972 bnad_napi_init(bnad, rx_id);
1973
1951 /* Register ISR for the Rx object */ 1974 /* Register ISR for the Rx object */
1952 if (intr_info->intr_type == BNA_INTR_T_MSIX) { 1975 if (intr_info->intr_type == BNA_INTR_T_MSIX) {
1953 err = bnad_rx_msix_register(bnad, rx_info, rx_id, 1976 err = bnad_rx_msix_register(bnad, rx_info, rx_id,
@@ -1956,9 +1979,6 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
1956 goto err_return; 1979 goto err_return;
1957 } 1980 }
1958 1981
1959 /* Enable NAPI */
1960 bnad_napi_enable(bnad, rx_id);
1961
1962 spin_lock_irqsave(&bnad->bna_lock, flags); 1982 spin_lock_irqsave(&bnad->bna_lock, flags);
1963 if (0 == rx_id) { 1983 if (0 == rx_id) {
1964 /* Set up Dynamic Interrupt Moderation Vector */ 1984 /* Set up Dynamic Interrupt Moderation Vector */
@@ -1975,6 +1995,9 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id)
1975 bna_rx_enable(rx); 1995 bna_rx_enable(rx);
1976 spin_unlock_irqrestore(&bnad->bna_lock, flags); 1996 spin_unlock_irqrestore(&bnad->bna_lock, flags);
1977 1997
1998 /* Enable scheduling of NAPI */
1999 bnad_napi_enable(bnad, rx_id);
2000
1978 return 0; 2001 return 0;
1979 2002
1980err_return: 2003err_return:
diff --git a/drivers/net/ethernet/brocade/bna/bnad.h b/drivers/net/ethernet/brocade/bna/bnad.h
index 3c231390b17c..60c2e9d534a7 100644
--- a/drivers/net/ethernet/brocade/bna/bnad.h
+++ b/drivers/net/ethernet/brocade/bna/bnad.h
@@ -53,6 +53,7 @@
53 */ 53 */
54struct bnad_rx_ctrl { 54struct bnad_rx_ctrl {
55 struct bna_ccb *ccb; 55 struct bna_ccb *ccb;
56 struct bnad *bnad;
56 unsigned long flags; 57 unsigned long flags;
57 struct napi_struct napi; 58 struct napi_struct napi;
58}; 59};