aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/benet/be_main.c
diff options
context:
space:
mode:
authorSathya Perla <sathyap@serverengines.com>2009-06-17 20:02:59 -0400
committerDavid S. Miller <davem@davemloft.net>2009-06-19 03:18:39 -0400
commit5fb379ee67a7ec55ff65b467b472f3d69b60ba16 (patch)
tree23d8c00fd535abb6f9d56e98ade838b8ed253e99 /drivers/net/benet/be_main.c
parente3453f6342110d60edb37be92c4a4f668ca8b0c4 (diff)
be2net: Add MCC queue mechanism for BE cmds
Currenlty all cmds use the blocking MCC mbox to post cmds. An mbox cmd is protected via a spin_lock(cmd_lock) and not spin_lock_bh() as it is undesirable to disable BHs while a blocking mbox cmd is in progress (and take long to finish.) This can lockup a cmd in progress in process context. Instead cmds that may be called in BH context must use the MCC queue to post cmds. The cmd completions are rcvd in a separate completion queue and the events are placed in the tx-event queue. Signed-off-by: Sathya Perla <sathyap@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet/be_main.c')
-rw-r--r--drivers/net/benet/be_main.c215
1 files changed, 145 insertions, 70 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 66bb56874d9b..a4ce80e776b6 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -60,26 +60,6 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
60 return 0; 60 return 0;
61} 61}
62 62
63static inline void *queue_head_node(struct be_queue_info *q)
64{
65 return q->dma_mem.va + q->head * q->entry_size;
66}
67
68static inline void *queue_tail_node(struct be_queue_info *q)
69{
70 return q->dma_mem.va + q->tail * q->entry_size;
71}
72
73static inline void queue_head_inc(struct be_queue_info *q)
74{
75 index_inc(&q->head, q->len);
76}
77
78static inline void queue_tail_inc(struct be_queue_info *q)
79{
80 index_inc(&q->tail, q->len);
81}
82
83static void be_intr_set(struct be_ctrl_info *ctrl, bool enable) 63static void be_intr_set(struct be_ctrl_info *ctrl, bool enable)
84{ 64{
85 u8 __iomem *addr = ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET; 65 u8 __iomem *addr = ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET;
@@ -127,7 +107,7 @@ static void be_eq_notify(struct be_ctrl_info *ctrl, u16 qid,
127 iowrite32(val, ctrl->db + DB_EQ_OFFSET); 107 iowrite32(val, ctrl->db + DB_EQ_OFFSET);
128} 108}
129 109
130static void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid, 110void be_cq_notify(struct be_ctrl_info *ctrl, u16 qid,
131 bool arm, u16 num_popped) 111 bool arm, u16 num_popped)
132{ 112{
133 u32 val = 0; 113 u32 val = 0;
@@ -960,10 +940,8 @@ static void be_post_rx_frags(struct be_adapter *adapter)
960 return; 940 return;
961} 941}
962 942
963static struct be_eth_tx_compl * 943static struct be_eth_tx_compl *be_tx_compl_get(struct be_queue_info *tx_cq)
964be_tx_compl_get(struct be_adapter *adapter)
965{ 944{
966 struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
967 struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq); 945 struct be_eth_tx_compl *txcp = queue_tail_node(tx_cq);
968 946
969 if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0) 947 if (txcp->dw[offsetof(struct amap_eth_tx_compl, valid) / 32] == 0)
@@ -1051,6 +1029,59 @@ static void be_tx_q_clean(struct be_adapter *adapter)
1051 } 1029 }
1052} 1030}
1053 1031
1032static void be_mcc_queues_destroy(struct be_adapter *adapter)
1033{
1034 struct be_queue_info *q;
1035 struct be_ctrl_info *ctrl = &adapter->ctrl;
1036
1037 q = &ctrl->mcc_obj.q;
1038 if (q->created)
1039 be_cmd_q_destroy(ctrl, q, QTYPE_MCCQ);
1040 be_queue_free(adapter, q);
1041
1042 q = &ctrl->mcc_obj.cq;
1043 if (q->created)
1044 be_cmd_q_destroy(ctrl, q, QTYPE_CQ);
1045 be_queue_free(adapter, q);
1046}
1047
1048/* Must be called only after TX qs are created as MCC shares TX EQ */
1049static int be_mcc_queues_create(struct be_adapter *adapter)
1050{
1051 struct be_queue_info *q, *cq;
1052 struct be_ctrl_info *ctrl = &adapter->ctrl;
1053
1054 /* Alloc MCC compl queue */
1055 cq = &ctrl->mcc_obj.cq;
1056 if (be_queue_alloc(adapter, cq, MCC_CQ_LEN,
1057 sizeof(struct be_mcc_cq_entry)))
1058 goto err;
1059
1060 /* Ask BE to create MCC compl queue; share TX's eq */
1061 if (be_cmd_cq_create(ctrl, cq, &adapter->tx_eq.q, false, true, 0))
1062 goto mcc_cq_free;
1063
1064 /* Alloc MCC queue */
1065 q = &ctrl->mcc_obj.q;
1066 if (be_queue_alloc(adapter, q, MCC_Q_LEN, sizeof(struct be_mcc_wrb)))
1067 goto mcc_cq_destroy;
1068
1069 /* Ask BE to create MCC queue */
1070 if (be_cmd_mccq_create(ctrl, q, cq))
1071 goto mcc_q_free;
1072
1073 return 0;
1074
1075mcc_q_free:
1076 be_queue_free(adapter, q);
1077mcc_cq_destroy:
1078 be_cmd_q_destroy(ctrl, cq, QTYPE_CQ);
1079mcc_cq_free:
1080 be_queue_free(adapter, cq);
1081err:
1082 return -1;
1083}
1084
1054static void be_tx_queues_destroy(struct be_adapter *adapter) 1085static void be_tx_queues_destroy(struct be_adapter *adapter)
1055{ 1086{
1056 struct be_queue_info *q; 1087 struct be_queue_info *q;
@@ -1263,7 +1294,7 @@ static irqreturn_t be_msix_rx(int irq, void *dev)
1263 return IRQ_HANDLED; 1294 return IRQ_HANDLED;
1264} 1295}
1265 1296
1266static irqreturn_t be_msix_tx(int irq, void *dev) 1297static irqreturn_t be_msix_tx_mcc(int irq, void *dev)
1267{ 1298{
1268 struct be_adapter *adapter = dev; 1299 struct be_adapter *adapter = dev;
1269 1300
@@ -1324,40 +1355,51 @@ int be_poll_rx(struct napi_struct *napi, int budget)
1324 return work_done; 1355 return work_done;
1325} 1356}
1326 1357
1327/* For TX we don't honour budget; consume everything */ 1358void be_process_tx(struct be_adapter *adapter)
1328int be_poll_tx(struct napi_struct *napi, int budget)
1329{ 1359{
1330 struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi); 1360 struct be_queue_info *txq = &adapter->tx_obj.q;
1331 struct be_adapter *adapter = 1361 struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
1332 container_of(tx_eq, struct be_adapter, tx_eq);
1333 struct be_tx_obj *tx_obj = &adapter->tx_obj;
1334 struct be_queue_info *tx_cq = &tx_obj->cq;
1335 struct be_queue_info *txq = &tx_obj->q;
1336 struct be_eth_tx_compl *txcp; 1362 struct be_eth_tx_compl *txcp;
1337 u32 num_cmpl = 0; 1363 u32 num_cmpl = 0;
1338 u16 end_idx; 1364 u16 end_idx;
1339 1365
1340 while ((txcp = be_tx_compl_get(adapter))) { 1366 while ((txcp = be_tx_compl_get(tx_cq))) {
1341 end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl, 1367 end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
1342 wrb_index, txcp); 1368 wrb_index, txcp);
1343 be_tx_compl_process(adapter, end_idx); 1369 be_tx_compl_process(adapter, end_idx);
1344 num_cmpl++; 1370 num_cmpl++;
1345 } 1371 }
1346 1372
1347 /* As Tx wrbs have been freed up, wake up netdev queue if 1373 if (num_cmpl) {
1348 * it was stopped due to lack of tx wrbs. 1374 be_cq_notify(&adapter->ctrl, tx_cq->id, true, num_cmpl);
1349 */ 1375
1350 if (netif_queue_stopped(adapter->netdev) && 1376 /* As Tx wrbs have been freed up, wake up netdev queue if
1377 * it was stopped due to lack of tx wrbs.
1378 */
1379 if (netif_queue_stopped(adapter->netdev) &&
1351 atomic_read(&txq->used) < txq->len / 2) { 1380 atomic_read(&txq->used) < txq->len / 2) {
1352 netif_wake_queue(adapter->netdev); 1381 netif_wake_queue(adapter->netdev);
1382 }
1383
1384 drvr_stats(adapter)->be_tx_events++;
1385 drvr_stats(adapter)->be_tx_compl += num_cmpl;
1353 } 1386 }
1387}
1388
1389/* As TX and MCC share the same EQ check for both TX and MCC completions.
1390 * For TX/MCC we don't honour budget; consume everything
1391 */
1392static int be_poll_tx_mcc(struct napi_struct *napi, int budget)
1393{
1394 struct be_eq_obj *tx_eq = container_of(napi, struct be_eq_obj, napi);
1395 struct be_adapter *adapter =
1396 container_of(tx_eq, struct be_adapter, tx_eq);
1354 1397
1355 napi_complete(napi); 1398 napi_complete(napi);
1356 1399
1357 be_cq_notify(&adapter->ctrl, tx_cq->id, true, num_cmpl); 1400 be_process_tx(adapter);
1358 1401
1359 drvr_stats(adapter)->be_tx_events++; 1402 be_process_mcc(&adapter->ctrl);
1360 drvr_stats(adapter)->be_tx_compl += num_cmpl;
1361 1403
1362 return 1; 1404 return 1;
1363} 1405}
@@ -1419,7 +1461,7 @@ static int be_msix_register(struct be_adapter *adapter)
1419 1461
1420 sprintf(tx_eq->desc, "%s-tx", netdev->name); 1462 sprintf(tx_eq->desc, "%s-tx", netdev->name);
1421 vec = be_msix_vec_get(adapter, tx_eq->q.id); 1463 vec = be_msix_vec_get(adapter, tx_eq->q.id);
1422 status = request_irq(vec, be_msix_tx, 0, tx_eq->desc, adapter); 1464 status = request_irq(vec, be_msix_tx_mcc, 0, tx_eq->desc, adapter);
1423 if (status) 1465 if (status)
1424 goto err; 1466 goto err;
1425 1467
@@ -1495,6 +1537,34 @@ static int be_open(struct net_device *netdev)
1495 struct be_ctrl_info *ctrl = &adapter->ctrl; 1537 struct be_ctrl_info *ctrl = &adapter->ctrl;
1496 struct be_eq_obj *rx_eq = &adapter->rx_eq; 1538 struct be_eq_obj *rx_eq = &adapter->rx_eq;
1497 struct be_eq_obj *tx_eq = &adapter->tx_eq; 1539 struct be_eq_obj *tx_eq = &adapter->tx_eq;
1540
1541 /* First time posting */
1542 be_post_rx_frags(adapter);
1543
1544 napi_enable(&rx_eq->napi);
1545 napi_enable(&tx_eq->napi);
1546
1547 be_irq_register(adapter);
1548
1549 be_intr_set(ctrl, true);
1550
1551 /* The evt queues are created in unarmed state; arm them */
1552 be_eq_notify(ctrl, rx_eq->q.id, true, false, 0);
1553 be_eq_notify(ctrl, tx_eq->q.id, true, false, 0);
1554
1555 /* Rx compl queue may be in unarmed state; rearm it */
1556 be_cq_notify(ctrl, adapter->rx_obj.cq.id, true, 0);
1557
1558 be_link_status_update(adapter);
1559
1560 schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
1561 return 0;
1562}
1563
1564static int be_setup(struct be_adapter *adapter)
1565{
1566 struct be_ctrl_info *ctrl = &adapter->ctrl;
1567 struct net_device *netdev = adapter->netdev;
1498 u32 if_flags; 1568 u32 if_flags;
1499 int status; 1569 int status;
1500 1570
@@ -1521,29 +1591,14 @@ static int be_open(struct net_device *netdev)
1521 if (status != 0) 1591 if (status != 0)
1522 goto tx_qs_destroy; 1592 goto tx_qs_destroy;
1523 1593
1524 /* First time posting */ 1594 status = be_mcc_queues_create(adapter);
1525 be_post_rx_frags(adapter); 1595 if (status != 0)
1526 1596 goto rx_qs_destroy;
1527 napi_enable(&rx_eq->napi);
1528 napi_enable(&tx_eq->napi);
1529
1530 be_irq_register(adapter);
1531
1532 be_intr_set(ctrl, true);
1533
1534 /* The evt queues are created in the unarmed state; arm them */
1535 be_eq_notify(ctrl, rx_eq->q.id, true, false, 0);
1536 be_eq_notify(ctrl, tx_eq->q.id, true, false, 0);
1537
1538 /* The compl queues are created in the unarmed state; arm them */
1539 be_cq_notify(ctrl, adapter->rx_obj.cq.id, true, 0);
1540 be_cq_notify(ctrl, adapter->tx_obj.cq.id, true, 0);
1541
1542 be_link_status_update(adapter);
1543 1597
1544 schedule_delayed_work(&adapter->work, msecs_to_jiffies(100));
1545 return 0; 1598 return 0;
1546 1599
1600rx_qs_destroy:
1601 be_rx_queues_destroy(adapter);
1547tx_qs_destroy: 1602tx_qs_destroy:
1548 be_tx_queues_destroy(adapter); 1603 be_tx_queues_destroy(adapter);
1549if_destroy: 1604if_destroy:
@@ -1552,6 +1607,19 @@ do_none:
1552 return status; 1607 return status;
1553} 1608}
1554 1609
1610static int be_clear(struct be_adapter *adapter)
1611{
1612 struct be_ctrl_info *ctrl = &adapter->ctrl;
1613
1614 be_rx_queues_destroy(adapter);
1615 be_tx_queues_destroy(adapter);
1616
1617 be_cmd_if_destroy(ctrl, adapter->if_handle);
1618
1619 be_mcc_queues_destroy(adapter);
1620 return 0;
1621}
1622
1555static int be_close(struct net_device *netdev) 1623static int be_close(struct net_device *netdev)
1556{ 1624{
1557 struct be_adapter *adapter = netdev_priv(netdev); 1625 struct be_adapter *adapter = netdev_priv(netdev);
@@ -1581,10 +1649,6 @@ static int be_close(struct net_device *netdev)
1581 napi_disable(&rx_eq->napi); 1649 napi_disable(&rx_eq->napi);
1582 napi_disable(&tx_eq->napi); 1650 napi_disable(&tx_eq->napi);
1583 1651
1584 be_rx_queues_destroy(adapter);
1585 be_tx_queues_destroy(adapter);
1586
1587 be_cmd_if_destroy(ctrl, adapter->if_handle);
1588 return 0; 1652 return 0;
1589} 1653}
1590 1654
@@ -1673,7 +1737,7 @@ static void be_netdev_init(struct net_device *netdev)
1673 1737
1674 netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx, 1738 netif_napi_add(netdev, &adapter->rx_eq.napi, be_poll_rx,
1675 BE_NAPI_WEIGHT); 1739 BE_NAPI_WEIGHT);
1676 netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx, 1740 netif_napi_add(netdev, &adapter->tx_eq.napi, be_poll_tx_mcc,
1677 BE_NAPI_WEIGHT); 1741 BE_NAPI_WEIGHT);
1678 1742
1679 netif_carrier_off(netdev); 1743 netif_carrier_off(netdev);
@@ -1755,7 +1819,9 @@ static int be_ctrl_init(struct be_adapter *adapter)
1755 mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); 1819 mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
1756 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); 1820 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
1757 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); 1821 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
1758 spin_lock_init(&ctrl->cmd_lock); 1822 spin_lock_init(&ctrl->mbox_lock);
1823 spin_lock_init(&ctrl->mcc_lock);
1824 spin_lock_init(&ctrl->mcc_cq_lock);
1759 1825
1760 val = ioread32(ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET); 1826 val = ioread32(ctrl->pcicfg + PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
1761 ctrl->pci_func = (val >> MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT) & 1827 ctrl->pci_func = (val >> MEMBAR_CTRL_INT_CTRL_PFUNC_SHIFT) &
@@ -1793,6 +1859,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
1793 1859
1794 unregister_netdev(adapter->netdev); 1860 unregister_netdev(adapter->netdev);
1795 1861
1862 be_clear(adapter);
1863
1796 be_stats_cleanup(adapter); 1864 be_stats_cleanup(adapter);
1797 1865
1798 be_ctrl_cleanup(adapter); 1866 be_ctrl_cleanup(adapter);
@@ -1890,13 +1958,18 @@ static int __devinit be_probe(struct pci_dev *pdev,
1890 be_netdev_init(netdev); 1958 be_netdev_init(netdev);
1891 SET_NETDEV_DEV(netdev, &adapter->pdev->dev); 1959 SET_NETDEV_DEV(netdev, &adapter->pdev->dev);
1892 1960
1961 status = be_setup(adapter);
1962 if (status)
1963 goto stats_clean;
1893 status = register_netdev(netdev); 1964 status = register_netdev(netdev);
1894 if (status != 0) 1965 if (status != 0)
1895 goto stats_clean; 1966 goto unsetup;
1896 1967
1897 dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num); 1968 dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
1898 return 0; 1969 return 0;
1899 1970
1971unsetup:
1972 be_clear(adapter);
1900stats_clean: 1973stats_clean:
1901 be_stats_cleanup(adapter); 1974 be_stats_cleanup(adapter);
1902ctrl_clean: 1975ctrl_clean:
@@ -1921,6 +1994,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
1921 if (netif_running(netdev)) { 1994 if (netif_running(netdev)) {
1922 rtnl_lock(); 1995 rtnl_lock();
1923 be_close(netdev); 1996 be_close(netdev);
1997 be_clear(adapter);
1924 rtnl_unlock(); 1998 rtnl_unlock();
1925 } 1999 }
1926 2000
@@ -1947,6 +2021,7 @@ static int be_resume(struct pci_dev *pdev)
1947 2021
1948 if (netif_running(netdev)) { 2022 if (netif_running(netdev)) {
1949 rtnl_lock(); 2023 rtnl_lock();
2024 be_setup(adapter);
1950 be_open(netdev); 2025 be_open(netdev);
1951 rtnl_unlock(); 2026 rtnl_unlock();
1952 } 2027 }