aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-05-11 19:01:23 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-11 19:01:23 -0400
commit1e9e9901ee13a48e3cbb96ec3631c685590f8aea (patch)
tree6316d0b9a2dc01e9587b06f415abe0bbd1a84fe9
parent61f1598278876527314f5fc1d00cf0a4d525c1f7 (diff)
parentcbccb18f4f937132af64a95ae04186a6c2c05236 (diff)
Merge branch 'qlcnic'
Shahed Shaikh says: ==================== This patch series has following bug fixes: * Fix a bug in unicast MAC address setting in adapter. Driver was not deleting older unicast MAC while adding new one. * Fix an ethtool stats string array by adding missing string entry and fix a typo. * Fix module paramter description. Bracket ')' was missing. * Fix port status provided though 'ethtool <device>' for 83xx adapter. * Fix reset recovery path in case of transmit timeout. * Fix reset recovery during diagnostic tests by preserving current device status information. * Fix mailbox response handling. Driver was not maintaining poll time properly. * Fix validation of link event command. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c95
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c22
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c54
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c46
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c8
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c3
9 files changed, 167 insertions, 69 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 90c253b145ef..019c5f78732e 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -429,6 +429,7 @@ struct qlcnic_hardware_context {
429 429
430 u16 port_type; 430 u16 port_type;
431 u16 board_type; 431 u16 board_type;
432 u16 supported_type;
432 433
433 u16 link_speed; 434 u16 link_speed;
434 u16 link_duplex; 435 u16 link_duplex;
@@ -1514,6 +1515,7 @@ void qlcnic_create_diag_entries(struct qlcnic_adapter *adapter);
1514void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter); 1515void qlcnic_remove_diag_entries(struct qlcnic_adapter *adapter);
1515void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter); 1516void qlcnic_82xx_add_sysfs(struct qlcnic_adapter *adapter);
1516void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter); 1517void qlcnic_82xx_remove_sysfs(struct qlcnic_adapter *adapter);
1518int qlcnic_82xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
1517 1519
1518int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32); 1520int qlcnicvf_config_bridged_mode(struct qlcnic_adapter *, u32);
1519int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32); 1521int qlcnicvf_config_led(struct qlcnic_adapter *, u32, u32);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index ea790a93ee7c..b4ff1e35a11d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -696,15 +696,14 @@ u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *adapter)
696 return 1; 696 return 1;
697} 697}
698 698
699u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter) 699u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *adapter, u32 *wait_time)
700{ 700{
701 u32 data; 701 u32 data;
702 unsigned long wait_time = 0;
703 struct qlcnic_hardware_context *ahw = adapter->ahw; 702 struct qlcnic_hardware_context *ahw = adapter->ahw;
704 /* wait for mailbox completion */ 703 /* wait for mailbox completion */
705 do { 704 do {
706 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL); 705 data = QLCRDX(ahw, QLCNIC_FW_MBX_CTRL);
707 if (++wait_time > QLCNIC_MBX_TIMEOUT) { 706 if (++(*wait_time) > QLCNIC_MBX_TIMEOUT) {
708 data = QLCNIC_RCODE_TIMEOUT; 707 data = QLCNIC_RCODE_TIMEOUT;
709 break; 708 break;
710 } 709 }
@@ -720,8 +719,8 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
720 u16 opcode; 719 u16 opcode;
721 u8 mbx_err_code; 720 u8 mbx_err_code;
722 unsigned long flags; 721 unsigned long flags;
723 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd;
724 struct qlcnic_hardware_context *ahw = adapter->ahw; 722 struct qlcnic_hardware_context *ahw = adapter->ahw;
723 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, wait_time = 0;
725 724
726 opcode = LSW(cmd->req.arg[0]); 725 opcode = LSW(cmd->req.arg[0]);
727 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) { 726 if (!test_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status)) {
@@ -754,15 +753,13 @@ int qlcnic_83xx_mbx_op(struct qlcnic_adapter *adapter,
754 /* Signal FW about the impending command */ 753 /* Signal FW about the impending command */
755 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER); 754 QLCWRX(ahw, QLCNIC_HOST_MBX_CTRL, QLCNIC_SET_OWNER);
756poll: 755poll:
757 rsp = qlcnic_83xx_mbx_poll(adapter); 756 rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
758 if (rsp != QLCNIC_RCODE_TIMEOUT) { 757 if (rsp != QLCNIC_RCODE_TIMEOUT) {
759 /* Get the FW response data */ 758 /* Get the FW response data */
760 fw_data = readl(QLCNIC_MBX_FW(ahw, 0)); 759 fw_data = readl(QLCNIC_MBX_FW(ahw, 0));
761 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) { 760 if (fw_data & QLCNIC_MBX_ASYNC_EVENT) {
762 __qlcnic_83xx_process_aen(adapter); 761 __qlcnic_83xx_process_aen(adapter);
763 mbx_val = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL); 762 goto poll;
764 if (mbx_val)
765 goto poll;
766 } 763 }
767 mbx_err_code = QLCNIC_MBX_STATUS(fw_data); 764 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
768 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); 765 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
@@ -1276,11 +1273,13 @@ out:
1276 return err; 1273 return err;
1277} 1274}
1278 1275
1279static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test) 1276static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1277 int num_sds_ring)
1280{ 1278{
1281 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1279 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1282 struct qlcnic_host_sds_ring *sds_ring; 1280 struct qlcnic_host_sds_ring *sds_ring;
1283 struct qlcnic_host_rds_ring *rds_ring; 1281 struct qlcnic_host_rds_ring *rds_ring;
1282 u16 adapter_state = adapter->is_up;
1284 u8 ring; 1283 u8 ring;
1285 int ret; 1284 int ret;
1286 1285
@@ -1304,6 +1303,10 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test)
1304 ret = qlcnic_fw_create_ctx(adapter); 1303 ret = qlcnic_fw_create_ctx(adapter);
1305 if (ret) { 1304 if (ret) {
1306 qlcnic_detach(adapter); 1305 qlcnic_detach(adapter);
1306 if (adapter_state == QLCNIC_ADAPTER_UP_MAGIC) {
1307 adapter->max_sds_rings = num_sds_ring;
1308 qlcnic_attach(adapter);
1309 }
1307 netif_device_attach(netdev); 1310 netif_device_attach(netdev);
1308 return ret; 1311 return ret;
1309 } 1312 }
@@ -1596,7 +1599,8 @@ int qlcnic_83xx_loopback_test(struct net_device *netdev, u8 mode)
1596 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 1599 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
1597 return -EBUSY; 1600 return -EBUSY;
1598 1601
1599 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST); 1602 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_LOOPBACK_TEST,
1603 max_sds_rings);
1600 if (ret) 1604 if (ret)
1601 goto fail_diag_alloc; 1605 goto fail_diag_alloc;
1602 1606
@@ -2830,6 +2834,23 @@ int qlcnic_83xx_test_link(struct qlcnic_adapter *adapter)
2830 break; 2834 break;
2831 } 2835 }
2832 config = cmd.rsp.arg[3]; 2836 config = cmd.rsp.arg[3];
2837 if (QLC_83XX_SFP_PRESENT(config)) {
2838 switch (ahw->module_type) {
2839 case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
2840 case LINKEVENT_MODULE_OPTICAL_SRLR:
2841 case LINKEVENT_MODULE_OPTICAL_LRM:
2842 case LINKEVENT_MODULE_OPTICAL_SFP_1G:
2843 ahw->supported_type = PORT_FIBRE;
2844 break;
2845 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
2846 case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
2847 case LINKEVENT_MODULE_TWINAX:
2848 ahw->supported_type = PORT_TP;
2849 break;
2850 default:
2851 ahw->supported_type = PORT_OTHER;
2852 }
2853 }
2833 if (config & 1) 2854 if (config & 1)
2834 err = 1; 2855 err = 1;
2835 } 2856 }
@@ -2838,7 +2859,8 @@ out:
2838 return config; 2859 return config;
2839} 2860}
2840 2861
2841int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter) 2862int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter,
2863 struct ethtool_cmd *ecmd)
2842{ 2864{
2843 u32 config = 0; 2865 u32 config = 0;
2844 int status = 0; 2866 int status = 0;
@@ -2851,6 +2873,54 @@ int qlcnic_83xx_get_settings(struct qlcnic_adapter *adapter)
2851 ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config); 2873 ahw->module_type = QLC_83XX_SFP_MODULE_TYPE(config);
2852 /* hard code until there is a way to get it from flash */ 2874 /* hard code until there is a way to get it from flash */
2853 ahw->board_type = QLCNIC_BRDTYPE_83XX_10G; 2875 ahw->board_type = QLCNIC_BRDTYPE_83XX_10G;
2876
2877 if (netif_running(adapter->netdev) && ahw->has_link_events) {
2878 ethtool_cmd_speed_set(ecmd, ahw->link_speed);
2879 ecmd->duplex = ahw->link_duplex;
2880 ecmd->autoneg = ahw->link_autoneg;
2881 } else {
2882 ethtool_cmd_speed_set(ecmd, SPEED_UNKNOWN);
2883 ecmd->duplex = DUPLEX_UNKNOWN;
2884 ecmd->autoneg = AUTONEG_DISABLE;
2885 }
2886
2887 if (ahw->port_type == QLCNIC_XGBE) {
2888 ecmd->supported = SUPPORTED_1000baseT_Full;
2889 ecmd->advertising = ADVERTISED_1000baseT_Full;
2890 } else {
2891 ecmd->supported = (SUPPORTED_10baseT_Half |
2892 SUPPORTED_10baseT_Full |
2893 SUPPORTED_100baseT_Half |
2894 SUPPORTED_100baseT_Full |
2895 SUPPORTED_1000baseT_Half |
2896 SUPPORTED_1000baseT_Full);
2897 ecmd->advertising = (ADVERTISED_100baseT_Half |
2898 ADVERTISED_100baseT_Full |
2899 ADVERTISED_1000baseT_Half |
2900 ADVERTISED_1000baseT_Full);
2901 }
2902
2903 switch (ahw->supported_type) {
2904 case PORT_FIBRE:
2905 ecmd->supported |= SUPPORTED_FIBRE;
2906 ecmd->advertising |= ADVERTISED_FIBRE;
2907 ecmd->port = PORT_FIBRE;
2908 ecmd->transceiver = XCVR_EXTERNAL;
2909 break;
2910 case PORT_TP:
2911 ecmd->supported |= SUPPORTED_TP;
2912 ecmd->advertising |= ADVERTISED_TP;
2913 ecmd->port = PORT_TP;
2914 ecmd->transceiver = XCVR_INTERNAL;
2915 break;
2916 default:
2917 ecmd->supported |= SUPPORTED_FIBRE;
2918 ecmd->advertising |= ADVERTISED_FIBRE;
2919 ecmd->port = PORT_OTHER;
2920 ecmd->transceiver = XCVR_EXTERNAL;
2921 break;
2922 }
2923 ecmd->phy_address = ahw->physical_port;
2854 return status; 2924 return status;
2855} 2925}
2856 2926
@@ -3046,7 +3116,8 @@ int qlcnic_83xx_interrupt_test(struct net_device *netdev)
3046 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state)) 3116 if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
3047 return -EIO; 3117 return -EIO;
3048 3118
3049 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST); 3119 ret = qlcnic_83xx_diag_alloc_res(netdev, QLCNIC_INTERRUPT_TEST,
3120 max_sds_rings);
3050 if (ret) 3121 if (ret)
3051 goto fail_diag_irq; 3122 goto fail_diag_irq;
3052 3123
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index 1f1d85e6f2af..f5db67fc9f55 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -603,7 +603,7 @@ int qlcnic_83xx_get_vnic_pf_info(struct qlcnic_adapter *, struct qlcnic_info *);
603 603
604void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *); 604void qlcnic_83xx_get_minidump_template(struct qlcnic_adapter *);
605void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data); 605void qlcnic_83xx_get_stats(struct qlcnic_adapter *adapter, u64 *data);
606int qlcnic_83xx_get_settings(struct qlcnic_adapter *); 606int qlcnic_83xx_get_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
607int qlcnic_83xx_set_settings(struct qlcnic_adapter *, struct ethtool_cmd *); 607int qlcnic_83xx_set_settings(struct qlcnic_adapter *, struct ethtool_cmd *);
608void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *, 608void qlcnic_83xx_get_pauseparam(struct qlcnic_adapter *,
609 struct ethtool_pauseparam *); 609 struct ethtool_pauseparam *);
@@ -620,7 +620,7 @@ int qlcnic_83xx_flash_test(struct qlcnic_adapter *);
620int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *); 620int qlcnic_83xx_enable_flash_write(struct qlcnic_adapter *);
621int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *); 621int qlcnic_83xx_disable_flash_write(struct qlcnic_adapter *);
622u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *); 622u32 qlcnic_83xx_mac_rcode(struct qlcnic_adapter *);
623u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *); 623u32 qlcnic_83xx_mbx_poll(struct qlcnic_adapter *, u32 *);
624void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *); 624void qlcnic_83xx_enable_mbx_poll(struct qlcnic_adapter *);
625void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *); 625void qlcnic_83xx_disable_mbx_poll(struct qlcnic_adapter *);
626#endif 626#endif
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index ab1d8d99cbd5..c67d1eb35e8f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -435,10 +435,6 @@ static void qlcnic_83xx_idc_attach_driver(struct qlcnic_adapter *adapter)
435 } 435 }
436done: 436done:
437 netif_device_attach(netdev); 437 netif_device_attach(netdev);
438 if (netif_running(netdev)) {
439 netif_carrier_on(netdev);
440 netif_wake_queue(netdev);
441 }
442} 438}
443 439
444static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter, 440static int qlcnic_83xx_idc_enter_failed_state(struct qlcnic_adapter *adapter,
@@ -642,15 +638,21 @@ static int qlcnic_83xx_idc_reattach_driver(struct qlcnic_adapter *adapter)
642 638
643static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter) 639static void qlcnic_83xx_idc_update_idc_params(struct qlcnic_adapter *adapter)
644{ 640{
641 struct qlcnic_hardware_context *ahw = adapter->ahw;
642
645 qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1); 643 qlcnic_83xx_idc_update_drv_presence_reg(adapter, 1, 1);
646 clear_bit(__QLCNIC_RESETTING, &adapter->state);
647 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status); 644 set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
648 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1); 645 qlcnic_83xx_idc_update_audit_reg(adapter, 0, 1);
649 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status); 646 set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
650 adapter->ahw->idc.quiesce_req = 0; 647
651 adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY; 648 ahw->idc.quiesce_req = 0;
652 adapter->ahw->idc.err_code = 0; 649 ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
653 adapter->ahw->idc.collect_dump = 0; 650 ahw->idc.err_code = 0;
651 ahw->idc.collect_dump = 0;
652 ahw->reset_context = 0;
653 adapter->tx_timeo_cnt = 0;
654
655 clear_bit(__QLCNIC_RESETTING, &adapter->state);
654} 656}
655 657
656/** 658/**
@@ -851,6 +853,7 @@ static int qlcnic_83xx_idc_ready_state(struct qlcnic_adapter *adapter)
851 /* Check for soft reset request */ 853 /* Check for soft reset request */
852 if (ahw->reset_context && 854 if (ahw->reset_context &&
853 !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) { 855 !(val & QLC_83XX_IDC_DISABLE_FW_RESET_RECOVERY)) {
856 adapter->ahw->reset_context = 0;
854 qlcnic_83xx_idc_tx_soft_reset(adapter); 857 qlcnic_83xx_idc_tx_soft_reset(adapter);
855 return ret; 858 return ret;
856 } 859 }
@@ -914,6 +917,7 @@ static int qlcnic_83xx_idc_need_quiesce_state(struct qlcnic_adapter *adapter)
914static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter) 917static int qlcnic_83xx_idc_failed_state(struct qlcnic_adapter *adapter)
915{ 918{
916 dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__); 919 dev_err(&adapter->pdev->dev, "%s: please restart!!\n", __func__);
920 clear_bit(__QLCNIC_RESETTING, &adapter->state);
917 adapter->ahw->idc.err_code = -EIO; 921 adapter->ahw->idc.err_code = -EIO;
918 922
919 return 0; 923 return 0;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 08efb4635007..f67652de5a63 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -131,12 +131,13 @@ static const char qlcnic_83xx_rx_stats_strings[][ETH_GSTRING_LEN] = {
131 "ctx_lro_pkt_cnt", 131 "ctx_lro_pkt_cnt",
132 "ctx_ip_csum_error", 132 "ctx_ip_csum_error",
133 "ctx_rx_pkts_wo_ctx", 133 "ctx_rx_pkts_wo_ctx",
134 "ctx_rx_pkts_dropped_wo_sts", 134 "ctx_rx_pkts_drop_wo_sds_on_card",
135 "ctx_rx_pkts_drop_wo_sds_on_host",
135 "ctx_rx_osized_pkts", 136 "ctx_rx_osized_pkts",
136 "ctx_rx_pkts_dropped_wo_rds", 137 "ctx_rx_pkts_dropped_wo_rds",
137 "ctx_rx_unexpected_mcast_pkts", 138 "ctx_rx_unexpected_mcast_pkts",
138 "ctx_invalid_mac_address", 139 "ctx_invalid_mac_address",
139 "ctx_rx_rds_ring_prim_attemoted", 140 "ctx_rx_rds_ring_prim_attempted",
140 "ctx_rx_rds_ring_prim_success", 141 "ctx_rx_rds_ring_prim_success",
141 "ctx_num_lro_flows_added", 142 "ctx_num_lro_flows_added",
142 "ctx_num_lro_flows_removed", 143 "ctx_num_lro_flows_removed",
@@ -251,6 +252,18 @@ static int
251qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) 252qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
252{ 253{
253 struct qlcnic_adapter *adapter = netdev_priv(dev); 254 struct qlcnic_adapter *adapter = netdev_priv(dev);
255
256 if (qlcnic_82xx_check(adapter))
257 return qlcnic_82xx_get_settings(adapter, ecmd);
258 else if (qlcnic_83xx_check(adapter))
259 return qlcnic_83xx_get_settings(adapter, ecmd);
260
261 return -EIO;
262}
263
264int qlcnic_82xx_get_settings(struct qlcnic_adapter *adapter,
265 struct ethtool_cmd *ecmd)
266{
254 struct qlcnic_hardware_context *ahw = adapter->ahw; 267 struct qlcnic_hardware_context *ahw = adapter->ahw;
255 u32 speed, reg; 268 u32 speed, reg;
256 int check_sfp_module = 0; 269 int check_sfp_module = 0;
@@ -276,10 +289,7 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
276 289
277 } else if (adapter->ahw->port_type == QLCNIC_XGBE) { 290 } else if (adapter->ahw->port_type == QLCNIC_XGBE) {
278 u32 val = 0; 291 u32 val = 0;
279 if (qlcnic_83xx_check(adapter)) 292 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
280 qlcnic_83xx_get_settings(adapter);
281 else
282 val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
283 293
284 if (val == QLCNIC_PORT_MODE_802_3_AP) { 294 if (val == QLCNIC_PORT_MODE_802_3_AP) {
285 ecmd->supported = SUPPORTED_1000baseT_Full; 295 ecmd->supported = SUPPORTED_1000baseT_Full;
@@ -289,16 +299,13 @@ qlcnic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
289 ecmd->advertising = ADVERTISED_10000baseT_Full; 299 ecmd->advertising = ADVERTISED_10000baseT_Full;
290 } 300 }
291 301
292 if (netif_running(dev) && adapter->ahw->has_link_events) { 302 if (netif_running(adapter->netdev) && ahw->has_link_events) {
293 if (qlcnic_82xx_check(adapter)) { 303 reg = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
294 reg = QLCRD32(adapter, 304 speed = P3P_LINK_SPEED_VAL(pcifn, reg);
295 P3P_LINK_SPEED_REG(pcifn)); 305 ahw->link_speed = speed * P3P_LINK_SPEED_MHZ;
296 speed = P3P_LINK_SPEED_VAL(pcifn, reg); 306 ethtool_cmd_speed_set(ecmd, ahw->link_speed);
297 ahw->link_speed = speed * P3P_LINK_SPEED_MHZ; 307 ecmd->autoneg = ahw->link_autoneg;
298 } 308 ecmd->duplex = ahw->link_duplex;
299 ethtool_cmd_speed_set(ecmd, adapter->ahw->link_speed);
300 ecmd->autoneg = adapter->ahw->link_autoneg;
301 ecmd->duplex = adapter->ahw->link_duplex;
302 goto skip; 309 goto skip;
303 } 310 }
304 311
@@ -340,8 +347,8 @@ skip:
340 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT: 347 case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
341 ecmd->advertising |= ADVERTISED_TP; 348 ecmd->advertising |= ADVERTISED_TP;
342 ecmd->supported |= SUPPORTED_TP; 349 ecmd->supported |= SUPPORTED_TP;
343 check_sfp_module = netif_running(dev) && 350 check_sfp_module = netif_running(adapter->netdev) &&
344 adapter->ahw->has_link_events; 351 ahw->has_link_events;
345 case QLCNIC_BRDTYPE_P3P_10G_XFP: 352 case QLCNIC_BRDTYPE_P3P_10G_XFP:
346 ecmd->supported |= SUPPORTED_FIBRE; 353 ecmd->supported |= SUPPORTED_FIBRE;
347 ecmd->advertising |= ADVERTISED_FIBRE; 354 ecmd->advertising |= ADVERTISED_FIBRE;
@@ -355,8 +362,8 @@ skip:
355 ecmd->advertising |= 362 ecmd->advertising |=
356 (ADVERTISED_FIBRE | ADVERTISED_TP); 363 (ADVERTISED_FIBRE | ADVERTISED_TP);
357 ecmd->port = PORT_FIBRE; 364 ecmd->port = PORT_FIBRE;
358 check_sfp_module = netif_running(dev) && 365 check_sfp_module = netif_running(adapter->netdev) &&
359 adapter->ahw->has_link_events; 366 ahw->has_link_events;
360 } else { 367 } else {
361 ecmd->autoneg = AUTONEG_ENABLE; 368 ecmd->autoneg = AUTONEG_ENABLE;
362 ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg); 369 ecmd->supported |= (SUPPORTED_TP | SUPPORTED_Autoneg);
@@ -365,13 +372,6 @@ skip:
365 ecmd->port = PORT_TP; 372 ecmd->port = PORT_TP;
366 } 373 }
367 break; 374 break;
368 case QLCNIC_BRDTYPE_83XX_10G:
369 ecmd->autoneg = AUTONEG_DISABLE;
370 ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
371 ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP);
372 ecmd->port = PORT_FIBRE;
373 check_sfp_module = netif_running(dev) && ahw->has_link_events;
374 break;
375 default: 375 default:
376 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n", 376 dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
377 adapter->ahw->board_type); 377 adapter->ahw->board_type);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
index 95b1b5732838..b6818f4356b9 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -134,7 +134,7 @@ struct qlcnic_mailbox_metadata {
134 134
135#define QLCNIC_SET_OWNER 1 135#define QLCNIC_SET_OWNER 1
136#define QLCNIC_CLR_OWNER 0 136#define QLCNIC_CLR_OWNER 0
137#define QLCNIC_MBX_TIMEOUT 10000 137#define QLCNIC_MBX_TIMEOUT 5000
138 138
139#define QLCNIC_MBX_RSP_OK 1 139#define QLCNIC_MBX_RSP_OK 1
140#define QLCNIC_MBX_PORT_RSP_OK 0x1a 140#define QLCNIC_MBX_PORT_RSP_OK 0x1a
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 264d5a4f8153..8fb836d4129f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -37,24 +37,24 @@ MODULE_PARM_DESC(qlcnic_mac_learn,
37 "Mac Filter (0=learning is disabled, 1=Driver learning is enabled, 2=FDB learning is enabled)"); 37 "Mac Filter (0=learning is disabled, 1=Driver learning is enabled, 2=FDB learning is enabled)");
38 38
39int qlcnic_use_msi = 1; 39int qlcnic_use_msi = 1;
40MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled"); 40MODULE_PARM_DESC(use_msi, "MSI interrupt (0=disabled, 1=enabled)");
41module_param_named(use_msi, qlcnic_use_msi, int, 0444); 41module_param_named(use_msi, qlcnic_use_msi, int, 0444);
42 42
43int qlcnic_use_msi_x = 1; 43int qlcnic_use_msi_x = 1;
44MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled"); 44MODULE_PARM_DESC(use_msi_x, "MSI-X interrupt (0=disabled, 1=enabled)");
45module_param_named(use_msi_x, qlcnic_use_msi_x, int, 0444); 45module_param_named(use_msi_x, qlcnic_use_msi_x, int, 0444);
46 46
47int qlcnic_auto_fw_reset = 1; 47int qlcnic_auto_fw_reset = 1;
48MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled"); 48MODULE_PARM_DESC(auto_fw_reset, "Auto firmware reset (0=disabled, 1=enabled)");
49module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644); 49module_param_named(auto_fw_reset, qlcnic_auto_fw_reset, int, 0644);
50 50
51int qlcnic_load_fw_file; 51int qlcnic_load_fw_file;
52MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file"); 52MODULE_PARM_DESC(load_fw_file, "Load firmware from (0=flash, 1=file)");
53module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444); 53module_param_named(load_fw_file, qlcnic_load_fw_file, int, 0444);
54 54
55int qlcnic_config_npars; 55int qlcnic_config_npars;
56module_param(qlcnic_config_npars, int, 0444); 56module_param(qlcnic_config_npars, int, 0444);
57MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled"); 57MODULE_PARM_DESC(qlcnic_config_npars, "Configure NPARs (0=disabled, 1=enabled)");
58 58
59static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 59static int qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
60static void qlcnic_remove(struct pci_dev *pdev); 60static void qlcnic_remove(struct pci_dev *pdev);
@@ -308,6 +308,23 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)
308 return 0; 308 return 0;
309} 309}
310 310
311static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter)
312{
313 struct qlcnic_mac_list_s *cur;
314 struct list_head *head;
315
316 list_for_each(head, &adapter->mac_list) {
317 cur = list_entry(head, struct qlcnic_mac_list_s, list);
318 if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) {
319 qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
320 0, QLCNIC_MAC_DEL);
321 list_del(&cur->list);
322 kfree(cur);
323 return;
324 }
325 }
326}
327
311static int qlcnic_set_mac(struct net_device *netdev, void *p) 328static int qlcnic_set_mac(struct net_device *netdev, void *p)
312{ 329{
313 struct qlcnic_adapter *adapter = netdev_priv(netdev); 330 struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -322,11 +339,15 @@ static int qlcnic_set_mac(struct net_device *netdev, void *p)
322 if (!is_valid_ether_addr(addr->sa_data)) 339 if (!is_valid_ether_addr(addr->sa_data))
323 return -EINVAL; 340 return -EINVAL;
324 341
342 if (!memcmp(adapter->mac_addr, addr->sa_data, ETH_ALEN))
343 return 0;
344
325 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 345 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
326 netif_device_detach(netdev); 346 netif_device_detach(netdev);
327 qlcnic_napi_disable(adapter); 347 qlcnic_napi_disable(adapter);
328 } 348 }
329 349
350 qlcnic_delete_adapter_mac(adapter);
330 memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); 351 memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len);
331 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 352 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
332 qlcnic_set_multi(adapter->netdev); 353 qlcnic_set_multi(adapter->netdev);
@@ -2481,12 +2502,17 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
2481 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 2502 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
2482 return; 2503 return;
2483 2504
2484 dev_err(&netdev->dev, "transmit timeout, resetting.\n"); 2505 if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) {
2485 2506 netdev_info(netdev, "Tx timeout, reset the adapter.\n");
2486 if (++adapter->tx_timeo_cnt >= QLCNIC_MAX_TX_TIMEOUTS) 2507 if (qlcnic_82xx_check(adapter))
2487 adapter->need_fw_reset = 1; 2508 adapter->need_fw_reset = 1;
2488 else 2509 else if (qlcnic_83xx_check(adapter))
2510 qlcnic_83xx_idc_request_reset(adapter,
2511 QLCNIC_FORCE_FW_DUMP_KEY);
2512 } else {
2513 netdev_info(netdev, "Tx timeout, reset adapter context.\n");
2489 adapter->ahw->reset_context = 1; 2514 adapter->ahw->reset_context = 1;
2515 }
2490} 2516}
2491 2517
2492static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) 2518static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 44d547d78b84..3869c3864deb 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -280,9 +280,9 @@ void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
280static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr, 280static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
281 u32 *pay, u8 pci_func, u8 size) 281 u32 *pay, u8 pci_func, u8 size)
282{ 282{
283 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val, wait_time = 0;
283 struct qlcnic_hardware_context *ahw = adapter->ahw; 284 struct qlcnic_hardware_context *ahw = adapter->ahw;
284 unsigned long flags; 285 unsigned long flags;
285 u32 rsp, mbx_val, fw_data, rsp_num, mbx_cmd, val;
286 u16 opcode; 286 u16 opcode;
287 u8 mbx_err_code; 287 u8 mbx_err_code;
288 int i, j; 288 int i, j;
@@ -330,15 +330,13 @@ static int qlcnic_sriov_post_bc_msg(struct qlcnic_adapter *adapter, u32 *hdr,
330 * assume something is wrong. 330 * assume something is wrong.
331 */ 331 */
332poll: 332poll:
333 rsp = qlcnic_83xx_mbx_poll(adapter); 333 rsp = qlcnic_83xx_mbx_poll(adapter, &wait_time);
334 if (rsp != QLCNIC_RCODE_TIMEOUT) { 334 if (rsp != QLCNIC_RCODE_TIMEOUT) {
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 goto poll;
340 if (mbx_val)
341 goto poll;
342 } 340 }
343 mbx_err_code = QLCNIC_MBX_STATUS(fw_data); 341 mbx_err_code = QLCNIC_MBX_STATUS(fw_data);
344 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data); 342 rsp_num = QLCNIC_MBX_NUM_REGS(fw_data);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index c81be2da119b..1a66ccded235 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -1133,9 +1133,6 @@ static int qlcnic_sriov_validate_linkevent(struct qlcnic_vf_info *vf,
1133 if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id) 1133 if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
1134 return -EINVAL; 1134 return -EINVAL;
1135 1135
1136 if (!(cmd->req.arg[1] & BIT_8))
1137 return -EINVAL;
1138
1139 return 0; 1136 return 0;
1140} 1137}
1141 1138