diff options
author | Rajesh Borundia <rajesh.borundia@qlogic.com> | 2013-04-19 03:01:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-19 16:14:53 -0400 |
commit | d1a1105efd901481b0dbba2ad07156a293a0dbe6 (patch) | |
tree | af160f484cf8663b233b1fb1100ea184fa73e85a | |
parent | 91b7282b613d4da65e8b4c87d521156cdc64c169 (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>
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 | ||
1871 | extern const struct ethtool_ops qlcnic_sriov_vf_ethtool_ops; | ||
1871 | extern const struct ethtool_ops qlcnic_ethtool_ops; | 1872 | extern const struct ethtool_ops qlcnic_ethtool_ops; |
1872 | extern const struct ethtool_ops qlcnic_ethtool_failed_ops; | 1873 | extern 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 | |||
406 | out: | 407 | out: |
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 | ||
865 | void qlcnic_83xx_process_aen(struct qlcnic_adapter *adapter) | 866 | void __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 | ||
911 | static 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 | |||
910 | static int qlcnic_83xx_add_rings(struct qlcnic_adapter *adapter) | 929 | static 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); |
1928 | out: | 1956 | out: |
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 *); |
559 | void qlcnic_83xx_check_vf(struct qlcnic_adapter *, | 559 | void qlcnic_83xx_check_vf(struct qlcnic_adapter *, |
560 | const struct pci_device_id *); | 560 | const struct pci_device_id *); |
561 | void qlcnic_83xx_process_aen(struct qlcnic_adapter *); | 561 | void __qlcnic_83xx_process_aen(struct qlcnic_adapter *); |
562 | int qlcnic_83xx_get_port_config(struct qlcnic_adapter *); | 562 | int qlcnic_83xx_get_port_config(struct qlcnic_adapter *); |
563 | int qlcnic_83xx_set_port_config(struct qlcnic_adapter *); | 563 | int qlcnic_83xx_set_port_config(struct qlcnic_adapter *); |
564 | int qlcnic_enable_eswitch(struct qlcnic_adapter *, u8, u8); | 564 | int 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 | ||
866 | static void qlcnic_create_loopback_buff(unsigned char *data, u8 mac[]) | 868 | static 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 | |||
1545 | const 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; |