aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajesh Borundia <rajesh.borundia@qlogic.com>2013-04-19 03:01:13 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-19 16:14:53 -0400
commitd1a1105efd901481b0dbba2ad07156a293a0dbe6 (patch)
treeaf160f484cf8663b233b1fb1100ea184fa73e85a
parent91b7282b613d4da65e8b4c87d521156cdc64c169 (diff)
qlcnic: Fix loopback test for SR-IOV PF.
o Do not disable mailbox interrupts while running loopback test through SR-IOV PF. Signed-off-by: Manish Chopra <manish.chopra@qlogic.com> Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h1
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c56
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c34
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c5
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c2
6 files changed, 78 insertions, 22 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 7dc7e02d00aa..fef2f4b8a22c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1868,6 +1868,7 @@ static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring)
1868 writel(0xfbff, adapter->tgt_mask_reg); 1868 writel(0xfbff, adapter->tgt_mask_reg);
1869} 1869}
1870 1870
1871extern const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops;
1871extern const struct ethtool_ops qlcnic_ethtool_ops; 1872extern const struct ethtool_ops qlcnic_ethtool_ops;
1872extern const struct ethtool_ops qlcnic_ethtool_failed_ops; 1873extern const struct ethtool_ops qlcnic_ethtool_failed_ops;
1873 1874
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 3a4b5723b94e..f1d06d2efd64 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -402,7 +402,8 @@ static void qlcnic_83xx_poll_process_aen(struct qlcnic_adapter *adapter)
402 402
403 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); 403 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
404 if (event & QLCNIC_MBX_ASYNC_EVENT) 404 if (event & QLCNIC_MBX_ASYNC_EVENT)
405 qlcnic_83xx_process_aen(adapter); 405 __qlcnic_83xx_process_aen(adapter);
406
406out: 407out:
407 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter); 408 qlcnic_83xx_enable_legacy_msix_mbx_intr(adapter);
408 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags); 409 spin_unlock_irqrestore(&adapter->ahw->mbx_lock, flags);
@@ -758,7 +759,7 @@ poll:
758 /* Get the FW response data */ 759 /* Get the FW response data */
759 fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); 760 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
760 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { 761 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
761 qlcnic_83xx_process_aen(adapter); 762 __qlcnic_83xx_process_aen(adapter);
762 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); 763 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
763 if (mbx_val) 764 if (mbx_val)
764 goto poll; 765 goto poll;
@@ -862,7 +863,7 @@ static void qlcnic_83xx_handle_idc_comp_aen(struct qlcnic_adapter *adapter,
862 return; 863 return;
863} 864}
864 865
865void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter) 866void __qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
866{ 867{
867 u32 event[QLC_83XX_MBX_AEN_CNT]; 868 u32 event[QLC_83XX_MBX_AEN_CNT];
868 int i; 869 int i;
@@ -907,6 +908,24 @@ void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
907 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER); 908 QLCWRX(ahw, QLCNIC_FW_MBX_CTRL, QLCNIC_CLR_OWNER);
908} 909}
909 910
911static void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter)
912{
913 struct qlcnic_hardware_context *ahw = adapter->ahw;
914 u32 resp, event;
915 unsigned long flags;
916
917 spin_lock_irqsave(&ahw->mbx_lock, flags);
918
919 resp = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
920 if (resp & QLCNIC_SET_OWNER) {
921 event = readl(QLCNIC_MBX_FW(ahw, 0));
922 if (event & QLCNIC_MBX_ASYNC_EVENT)
923 __qlcnic_83xx_process_aen(adapter);
924 }
925
926 spin_unlock_irqrestore(&ahw->mbx_lock, flags);
927}
928
910static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter) 929static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter)
911{ 930{
912 int index, i, err, sds_mbx_size; 931 int index, i, err, sds_mbx_size;
@@ -1274,7 +1293,8 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test)
1274 1293
1275 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1294 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1276 /* disable and free mailbox interrupt */ 1295 /* disable and free mailbox interrupt */
1277 qlcnic_83xx_free_mbx_intr(adapter); 1296 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1297 qlcnic_83xx_free_mbx_intr(adapter);
1278 adapter->ahw->loopback_state = 0; 1298 adapter->ahw->loopback_state = 0;
1279 adapter->ahw->hw_ops->setup_link_event(adapter, 1); 1299 adapter->ahw->hw_ops->setup_link_event(adapter, 1);
1280 } 1300 }
@@ -1302,12 +1322,14 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1302 qlcnic_detach(adapter); 1322 qlcnic_detach(adapter);
1303 1323
1304 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) { 1324 if (adapter->ahw->diag_test == QLCNIC_LOOPBACK_TEST) {
1305 err = qlcnic_83xx_setup_mbx_intr(adapter); 1325 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
1306 if (err) { 1326 err = qlcnic_83xx_setup_mbx_intr(adapter);
1307 dev_err(&adapter->pdev->dev, 1327 if (err) {
1308 "%s: failed to setup mbx interrupt\n", 1328 dev_err(&adapter->pdev->dev,
1309 __func__); 1329 "%s: failed to setup mbx interrupt\n",
1310 goto out; 1330 __func__);
1331 goto out;
1332 }
1311 } 1333 }
1312 } 1334 }
1313 adapter->ahw->diag_test = 0; 1335 adapter->ahw->diag_test = 0;
@@ -1556,7 +1578,9 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1556 /* Poll for link up event before running traffic */ 1578 /* Poll for link up event before running traffic */
1557 do { 1579 do {
1558 msleep(500); 1580 msleep(500);
1559 qlcnic_83xx_process_aen(adapter); 1581 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1582 qlcnic_83xx_process_aen(adapter);
1583
1560 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) { 1584 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1561 dev_info(&adapter->pdev->dev, 1585 dev_info(&adapter->pdev->dev,
1562 "Firmware didn't sent link up event to loopback request\n"); 1586 "Firmware didn't sent link up event to loopback request\n");
@@ -1610,7 +1634,9 @@ int qlcnic_83xx_set_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1610 /* Wait for Link and IDC Completion AEN */ 1634 /* Wait for Link and IDC Completion AEN */
1611 do { 1635 do {
1612 msleep(300); 1636 msleep(300);
1613 qlcnic_83xx_process_aen(adapter); 1637 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1638 qlcnic_83xx_process_aen(adapter);
1639
1614 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) { 1640 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1615 dev_err(&adapter->pdev->dev, 1641 dev_err(&adapter->pdev->dev,
1616 "FW did not generate IDC completion AEN\n"); 1642 "FW did not generate IDC completion AEN\n");
@@ -1650,7 +1676,9 @@ int qlcnic_83xx_clear_lb_mode(struct qlcnic_adapter *adapter, u8 mode)
1650 /* Wait for Link and IDC Completion AEN */ 1676 /* Wait for Link and IDC Completion AEN */
1651 do { 1677 do {
1652 msleep(300); 1678 msleep(300);
1653 qlcnic_83xx_process_aen(adapter); 1679 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
1680 qlcnic_83xx_process_aen(adapter);
1681
1654 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) { 1682 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) {
1655 dev_err(&adapter->pdev->dev, 1683 dev_err(&adapter->pdev->dev,
1656 "Firmware didn't sent IDC completion AEN\n"); 1684 "Firmware didn't sent IDC completion AEN\n");
@@ -1924,7 +1952,7 @@ irqreturn_t qlcnic_83xx_handle_aen(int irq, void *data)
1924 1952
1925 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0)); 1953 event = readl(QLCNIC_MBX_FW(adapter->ahw, 0));
1926 if (event & QLCNIC_MBX_ASYNC_EVENT) 1954 if (event & QLCNIC_MBX_ASYNC_EVENT)
1927 qlcnic_83xx_process_aen(adapter); 1955 __qlcnic_83xx_process_aen(adapter);
1928out: 1956out:
1929 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK); 1957 mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
1930 writel(0, adapter->ahw->pci_base0 + mask); 1958 writel(0, adapter->ahw->pci_base0 + mask);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 96f834445bff..73070bc25d76 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -558,7 +558,7 @@ void qlcnic_83xx_disable_intr(struct qlcnic_adapter *,
558 struct qlcnic_host_sds_ring *); 558 struct qlcnic_host_sds_ring *);
559void qlcnic_83xx_check_vf(struct qlcnic_adapter *, 559void qlcnic_83xx_check_vf(struct qlcnic_adapter *,
560 const struct pci_device_id *); 560 const struct pci_device_id *);
561void qlcnic_83xx_process_aen(struct qlcnic_adapter *); 561void __qlcnic_83xx_process_aen(struct qlcnic_adapter *);
562int qlcnic_83xx_get_port_config(struct qlcnic_adapter *); 562int qlcnic_83xx_get_port_config(struct qlcnic_adapter *);
563int qlcnic_83xx_set_port_config(struct qlcnic_adapter *); 563int qlcnic_83xx_set_port_config(struct qlcnic_adapter *);
564int qlcnic_enable_eswitch(struct qlcnic_adapter *, u8, u8); 564int qlcnic_enable_eswitch(struct qlcnic_adapter *, u8, u8);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index f4f279d5cba4..9f7aade4667c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -859,9 +859,11 @@ clear_diag_irq:
859 return ret; 859 return ret;
860} 860}
861 861
862#define QLCNIC_ILB_PKT_SIZE 64 862#define QLCNIC_ILB_PKT_SIZE 64
863#define QLCNIC_NUM_ILB_PKT 16 863#define QLCNIC_NUM_ILB_PKT 16
864#define QLCNIC_ILB_MAX_RCV_LOOP 10 864#define QLCNIC_ILB_MAX_RCV_LOOP 10
865#define QLCNIC_LB_PKT_POLL_DELAY_MSEC 1
866#define QLCNIC_LB_PKT_POLL_COUNT 20
865 867
866static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[]) 868static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[])
867{ 869{
@@ -898,9 +900,9 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)
898 loop = 0; 900 loop = 0;
899 901
900 do { 902 do {
901 msleep(1); 903 msleep(QLCNIC_LB_PKT_POLL_DELAY_MSEC);
902 qlcnic_process_rcv_ring_diag(sds_ring); 904 qlcnic_process_rcv_ring_diag(sds_ring);
903 if (loop++ > QLCNIC_ILB_MAX_RCV_LOOP) 905 if (loop++ > QLCNIC_LB_PKT_POLL_COUNT)
904 break; 906 break;
905 } while (!adapter->ahw->diag_cnt); 907 } while (!adapter->ahw->diag_cnt);
906 908
@@ -1539,3 +1541,25 @@ const struct ethtool_ops qlcnic_ethtool_ops = {
1539 .get_dump_data = qlcnic_get_dump_data, 1541 .get_dump_data = qlcnic_get_dump_data,
1540 .set_dump = qlcnic_set_dump, 1542 .set_dump = qlcnic_set_dump,
1541}; 1543};
1544
1545const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops = {
1546 .get_settings = qlcnic_get_settings,
1547 .get_drvinfo = qlcnic_get_drvinfo,
1548 .get_regs_len = qlcnic_get_regs_len,
1549 .get_regs = qlcnic_get_regs,
1550 .get_link = ethtool_op_get_link,
1551 .get_eeprom_len = qlcnic_get_eeprom_len,
1552 .get_eeprom = qlcnic_get_eeprom,
1553 .get_ringparam = qlcnic_get_ringparam,
1554 .set_ringparam = qlcnic_set_ringparam,
1555 .get_channels = qlcnic_get_channels,
1556 .get_pauseparam = qlcnic_get_pauseparam,
1557 .get_wol = qlcnic_get_wol,
1558 .get_strings = qlcnic_get_strings,
1559 .get_ethtool_stats = qlcnic_get_ethtool_stats,
1560 .get_sset_count = qlcnic_get_sset_count,
1561 .get_coalesce = qlcnic_get_intr_coalesce,
1562 .set_coalesce = qlcnic_set_intr_coalesce,
1563 .set_msglevel = qlcnic_set_msglevel,
1564 .get_msglevel = qlcnic_get_msglevel,
1565};
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 9890aa8abdcd..a79276d971db 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1743,7 +1743,10 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, struct net_device *netdev,
1743 1743
1744 qlcnic_change_mtu(netdev, netdev->mtu); 1744 qlcnic_change_mtu(netdev, netdev->mtu);
1745 1745
1746 SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops); 1746 if (qlcnic_sriov_vf_check(adapter))
1747 SET_ETHTOOL_OPS(netdev, &qlcnic_sriov_vf_ethtool_ops);
1748 else
1749 SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
1747 1750
1748 netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM | 1751 netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
1749 NETIF_F_IPV6_CSUM | NETIF_F_GRO | 1752 NETIF_F_IPV6_CSUM | NETIF_F_GRO |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index d5b626dad16b..44d547d78b84 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -335,7 +335,7 @@ poll:
335 /* Get the FW response data */ 335 /* Get the FW response data */
336 fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); 336 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
337 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { 337 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
338 qlcnic_83xx_process_aen(adapter); 338 __qlcnic_83xx_process_aen(adapter);
339 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); 339 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
340 if (mbx_val) 340 if (mbx_val)
341 goto poll; 341 goto poll;