aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-01-23 19:13:39 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-23 19:13:39 -0500
commit9fac865db04b4ee39c84fbcb461c38585acaff27 (patch)
tree960bf3a54564857ad296fe2ed76799b837eef48d
parent0681a28264dcf948e0236adb7bf505a638c4dec1 (diff)
parent18cae184e4364b4177561e271a8ca51568e031f0 (diff)
Merge branch 'qlcnic'
Himanshu Madhani says: ==================== qlcnic: Refactoring and enhancements for all adapters. This patch series contains following patches. o Enhanced debug data collection when we are in Tx-timeout situation. o Enhanced MSI-x vector calculation for defualt load path as well as for TSS/RSS ring change path. o Refactored interrupt coalescing code for all adapters. o Refactored interrupt handling as well as cleanup of poll controller code patch for all adapters. o changed rx_mac_learn type to boolean. Please apply to net-next. ==================== Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h129
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c235
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h9
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c106
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c31
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c55
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c343
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c2
11 files changed, 601 insertions, 321 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 69a6ca086d5c..f19f81cde134 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -38,8 +38,8 @@
38 38
39#define _QLCNIC_LINUX_MAJOR 5 39#define _QLCNIC_LINUX_MAJOR 5
40#define _QLCNIC_LINUX_MINOR 3 40#define _QLCNIC_LINUX_MINOR 3
41#define _QLCNIC_LINUX_SUBVERSION 54 41#define _QLCNIC_LINUX_SUBVERSION 55
42#define QLCNIC_LINUX_VERSIONID "5.3.54" 42#define QLCNIC_LINUX_VERSIONID "5.3.55"
43#define QLCNIC_DRV_IDC_VER 0x01 43#define QLCNIC_DRV_IDC_VER 0x01
44#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ 44#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
45 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) 45 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -105,6 +105,8 @@
105#define QLCNIC_DEF_TX_RINGS 4 105#define QLCNIC_DEF_TX_RINGS 4
106#define QLCNIC_MAX_VNIC_TX_RINGS 4 106#define QLCNIC_MAX_VNIC_TX_RINGS 4
107#define QLCNIC_MAX_VNIC_SDS_RINGS 4 107#define QLCNIC_MAX_VNIC_SDS_RINGS 4
108#define QLCNIC_83XX_MINIMUM_VECTOR 3
109#define QLCNIC_82XX_MINIMUM_VECTOR 2
108 110
109enum qlcnic_queue_type { 111enum qlcnic_queue_type {
110 QLCNIC_TX_QUEUE = 1, 112 QLCNIC_TX_QUEUE = 1,
@@ -369,6 +371,7 @@ struct qlcnic_rx_buffer {
369 */ 371 */
370#define QLCNIC_INTR_COAL_TYPE_RX 1 372#define QLCNIC_INTR_COAL_TYPE_RX 1
371#define QLCNIC_INTR_COAL_TYPE_TX 2 373#define QLCNIC_INTR_COAL_TYPE_TX 2
374#define QLCNIC_INTR_COAL_TYPE_RX_TX 3
372 375
373#define QLCNIC_DEF_INTR_COALESCE_RX_TIME_US 3 376#define QLCNIC_DEF_INTR_COALESCE_RX_TIME_US 3
374#define QLCNIC_DEF_INTR_COALESCE_RX_PACKETS 256 377#define QLCNIC_DEF_INTR_COALESCE_RX_PACKETS 256
@@ -961,6 +964,7 @@ struct qlcnic_ipaddr {
961#define QLCNIC_TX_INTR_SHARED 0x10000 964#define QLCNIC_TX_INTR_SHARED 0x10000
962#define QLCNIC_APP_CHANGED_FLAGS 0x20000 965#define QLCNIC_APP_CHANGED_FLAGS 0x20000
963#define QLCNIC_HAS_PHYS_PORT_ID 0x40000 966#define QLCNIC_HAS_PHYS_PORT_ID 0x40000
967#define QLCNIC_TSS_RSS 0x80000
964 968
965#define QLCNIC_IS_MSI_FAMILY(adapter) \ 969#define QLCNIC_IS_MSI_FAMILY(adapter) \
966 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED)) 970 ((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
@@ -1057,6 +1061,9 @@ struct qlcnic_adapter {
1057 u8 drv_tx_rings; /* max tx rings supported by driver */ 1061 u8 drv_tx_rings; /* max tx rings supported by driver */
1058 u8 drv_sds_rings; /* max sds rings supported by driver */ 1062 u8 drv_sds_rings; /* max sds rings supported by driver */
1059 1063
1064 u8 drv_tss_rings; /* tss ring input */
1065 u8 drv_rss_rings; /* rss ring input */
1066
1060 u8 rx_csum; 1067 u8 rx_csum;
1061 u8 portnum; 1068 u8 portnum;
1062 1069
@@ -1082,7 +1089,7 @@ struct qlcnic_adapter {
1082 u64 dev_rst_time; 1089 u64 dev_rst_time;
1083 bool drv_mac_learn; 1090 bool drv_mac_learn;
1084 bool fdb_mac_learn; 1091 bool fdb_mac_learn;
1085 u8 rx_mac_learn; 1092 bool rx_mac_learn;
1086 unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)]; 1093 unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)];
1087 u8 flash_mfg_id; 1094 u8 flash_mfg_id;
1088 struct qlcnic_npar_info *npars; 1095 struct qlcnic_npar_info *npars;
@@ -1573,7 +1580,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int);
1573netdev_tx_t qlcnic_xmit_frame(struct sk_buff *, struct net_device *); 1580netdev_tx_t qlcnic_xmit_frame(struct sk_buff *, struct net_device *);
1574void qlcnic_set_tx_ring_count(struct qlcnic_adapter *, u8); 1581void qlcnic_set_tx_ring_count(struct qlcnic_adapter *, u8);
1575void qlcnic_set_sds_ring_count(struct qlcnic_adapter *, u8); 1582void qlcnic_set_sds_ring_count(struct qlcnic_adapter *, u8);
1576int qlcnic_setup_rings(struct qlcnic_adapter *, u8, u8); 1583int qlcnic_setup_rings(struct qlcnic_adapter *);
1577int qlcnic_validate_rings(struct qlcnic_adapter *, __u32, int); 1584int qlcnic_validate_rings(struct qlcnic_adapter *, __u32, int);
1578void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); 1585void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
1579int qlcnic_enable_msix(struct qlcnic_adapter *, u32); 1586int qlcnic_enable_msix(struct qlcnic_adapter *, u32);
@@ -1613,7 +1620,7 @@ void qlcnic_set_vlan_config(struct qlcnic_adapter *,
1613 struct qlcnic_esw_func_cfg *); 1620 struct qlcnic_esw_func_cfg *);
1614void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *, 1621void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *,
1615 struct qlcnic_esw_func_cfg *); 1622 struct qlcnic_esw_func_cfg *);
1616 1623int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *);
1617void qlcnic_down(struct qlcnic_adapter *, struct net_device *); 1624void qlcnic_down(struct qlcnic_adapter *, struct net_device *);
1618int qlcnic_up(struct qlcnic_adapter *, struct net_device *); 1625int qlcnic_up(struct qlcnic_adapter *, struct net_device *);
1619void __qlcnic_down(struct qlcnic_adapter *, struct net_device *); 1626void __qlcnic_down(struct qlcnic_adapter *, struct net_device *);
@@ -1670,11 +1677,8 @@ static inline int qlcnic_set_real_num_queues(struct qlcnic_adapter *adapter,
1670 1677
1671 err = netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings); 1678 err = netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings);
1672 if (err) 1679 if (err)
1673 dev_err(&adapter->pdev->dev, "failed to set %d Tx queues\n", 1680 netdev_err(netdev, "failed to set %d Tx queues\n",
1674 adapter->drv_tx_rings); 1681 adapter->drv_tx_rings);
1675 else
1676 dev_info(&adapter->pdev->dev, "Set %d Tx queues\n",
1677 adapter->drv_tx_rings);
1678 1682
1679 return err; 1683 return err;
1680} 1684}
@@ -1740,7 +1744,8 @@ struct qlcnic_hardware_ops {
1740 int (*change_macvlan) (struct qlcnic_adapter *, u8*, u16, u8); 1744 int (*change_macvlan) (struct qlcnic_adapter *, u8*, u16, u8);
1741 void (*napi_enable) (struct qlcnic_adapter *); 1745 void (*napi_enable) (struct qlcnic_adapter *);
1742 void (*napi_disable) (struct qlcnic_adapter *); 1746 void (*napi_disable) (struct qlcnic_adapter *);
1743 void (*config_intr_coal) (struct qlcnic_adapter *); 1747 int (*config_intr_coal) (struct qlcnic_adapter *,
1748 struct ethtool_coalesce *);
1744 int (*config_rss) (struct qlcnic_adapter *, int); 1749 int (*config_rss) (struct qlcnic_adapter *, int);
1745 int (*config_hw_lro) (struct qlcnic_adapter *, int); 1750 int (*config_hw_lro) (struct qlcnic_adapter *, int);
1746 int (*config_loopback) (struct qlcnic_adapter *, u8); 1751 int (*config_loopback) (struct qlcnic_adapter *, u8);
@@ -1756,6 +1761,14 @@ struct qlcnic_hardware_ops {
1756 pci_ers_result_t (*io_slot_reset) (struct pci_dev *); 1761 pci_ers_result_t (*io_slot_reset) (struct pci_dev *);
1757 void (*io_resume) (struct pci_dev *); 1762 void (*io_resume) (struct pci_dev *);
1758 void (*get_beacon_state)(struct qlcnic_adapter *); 1763 void (*get_beacon_state)(struct qlcnic_adapter *);
1764 void (*enable_sds_intr) (struct qlcnic_adapter *,
1765 struct qlcnic_host_sds_ring *);
1766 void (*disable_sds_intr) (struct qlcnic_adapter *,
1767 struct qlcnic_host_sds_ring *);
1768 void (*enable_tx_intr) (struct qlcnic_adapter *,
1769 struct qlcnic_host_tx_ring *);
1770 void (*disable_tx_intr) (struct qlcnic_adapter *,
1771 struct qlcnic_host_tx_ring *);
1759}; 1772};
1760 1773
1761extern struct qlcnic_nic_template qlcnic_vf_ops; 1774extern struct qlcnic_nic_template qlcnic_vf_ops;
@@ -1928,9 +1941,10 @@ static inline void qlcnic_napi_disable(struct qlcnic_adapter *adapter)
1928 adapter->ahw->hw_ops->napi_disable(adapter); 1941 adapter->ahw->hw_ops->napi_disable(adapter);
1929} 1942}
1930 1943
1931static inline void qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) 1944static inline int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter,
1945 struct ethtool_coalesce *ethcoal)
1932{ 1946{
1933 adapter->ahw->hw_ops->config_intr_coal(adapter); 1947 return adapter->ahw->hw_ops->config_intr_coal(adapter, ethcoal);
1934} 1948}
1935 1949
1936static inline int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) 1950static inline int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable)
@@ -2029,6 +2043,54 @@ static inline bool qlcnic_check_multi_tx(struct qlcnic_adapter *adapter)
2029 return test_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state); 2043 return test_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
2030} 2044}
2031 2045
2046static inline void
2047qlcnic_82xx_enable_tx_intr(struct qlcnic_adapter *adapter,
2048 struct qlcnic_host_tx_ring *tx_ring)
2049{
2050 if (qlcnic_check_multi_tx(adapter) &&
2051 !adapter->ahw->diag_test)
2052 writel(0x0, tx_ring->crb_intr_mask);
2053}
2054
2055static inline void
2056qlcnic_82xx_disable_tx_intr(struct qlcnic_adapter *adapter,
2057 struct qlcnic_host_tx_ring *tx_ring)
2058{
2059 if (qlcnic_check_multi_tx(adapter) &&
2060 !adapter->ahw->diag_test)
2061 writel(1, tx_ring->crb_intr_mask);
2062}
2063
2064static inline void
2065qlcnic_83xx_enable_tx_intr(struct qlcnic_adapter *adapter,
2066 struct qlcnic_host_tx_ring *tx_ring)
2067{
2068 writel(0, tx_ring->crb_intr_mask);
2069}
2070
2071static inline void
2072qlcnic_83xx_disable_tx_intr(struct qlcnic_adapter *adapter,
2073 struct qlcnic_host_tx_ring *tx_ring)
2074{
2075 writel(1, tx_ring->crb_intr_mask);
2076}
2077
2078/* Enable MSI-x and INT-x interrupts */
2079static inline void
2080qlcnic_83xx_enable_sds_intr(struct qlcnic_adapter *adapter,
2081 struct qlcnic_host_sds_ring *sds_ring)
2082{
2083 writel(0, sds_ring->crb_intr_mask);
2084}
2085
2086/* Disable MSI-x and INT-x interrupts */
2087static inline void
2088qlcnic_83xx_disable_sds_intr(struct qlcnic_adapter *adapter,
2089 struct qlcnic_host_sds_ring *sds_ring)
2090{
2091 writel(1, sds_ring->crb_intr_mask);
2092}
2093
2032static inline void qlcnic_disable_multi_tx(struct qlcnic_adapter *adapter) 2094static inline void qlcnic_disable_multi_tx(struct qlcnic_adapter *adapter)
2033{ 2095{
2034 test_and_clear_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state); 2096 test_and_clear_bit(__QLCNIC_MULTI_TX_UNIQUE, &adapter->state);
@@ -2038,10 +2100,10 @@ static inline void qlcnic_disable_multi_tx(struct qlcnic_adapter *adapter)
2038/* When operating in a muti tx mode, driver needs to write 0x1 2100/* When operating in a muti tx mode, driver needs to write 0x1
2039 * to src register, instead of 0x0 to disable receiving interrupt. 2101 * to src register, instead of 0x0 to disable receiving interrupt.
2040 */ 2102 */
2041static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring) 2103static inline void
2104qlcnic_82xx_disable_sds_intr(struct qlcnic_adapter *adapter,
2105 struct qlcnic_host_sds_ring *sds_ring)
2042{ 2106{
2043 struct qlcnic_adapter *adapter = sds_ring->adapter;
2044
2045 if (qlcnic_check_multi_tx(adapter) && 2107 if (qlcnic_check_multi_tx(adapter) &&
2046 !adapter->ahw->diag_test && 2108 !adapter->ahw->diag_test &&
2047 (adapter->flags & QLCNIC_MSIX_ENABLED)) 2109 (adapter->flags & QLCNIC_MSIX_ENABLED))
@@ -2050,13 +2112,42 @@ static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring)
2050 writel(0, sds_ring->crb_intr_mask); 2112 writel(0, sds_ring->crb_intr_mask);
2051} 2113}
2052 2114
2115static inline void qlcnic_enable_sds_intr(struct qlcnic_adapter *adapter,
2116 struct qlcnic_host_sds_ring *sds_ring)
2117{
2118 if (adapter->ahw->hw_ops->enable_sds_intr)
2119 adapter->ahw->hw_ops->enable_sds_intr(adapter, sds_ring);
2120}
2121
2122static inline void
2123qlcnic_disable_sds_intr(struct qlcnic_adapter *adapter,
2124 struct qlcnic_host_sds_ring *sds_ring)
2125{
2126 if (adapter->ahw->hw_ops->disable_sds_intr)
2127 adapter->ahw->hw_ops->disable_sds_intr(adapter, sds_ring);
2128}
2129
2130static inline void qlcnic_enable_tx_intr(struct qlcnic_adapter *adapter,
2131 struct qlcnic_host_tx_ring *tx_ring)
2132{
2133 if (adapter->ahw->hw_ops->enable_tx_intr)
2134 adapter->ahw->hw_ops->enable_tx_intr(adapter, tx_ring);
2135}
2136
2137static inline void qlcnic_disable_tx_intr(struct qlcnic_adapter *adapter,
2138 struct qlcnic_host_tx_ring *tx_ring)
2139{
2140 if (adapter->ahw->hw_ops->disable_tx_intr)
2141 adapter->ahw->hw_ops->disable_tx_intr(adapter, tx_ring);
2142}
2143
2053/* When operating in a muti tx mode, driver needs to write 0x0 2144/* When operating in a muti tx mode, driver needs to write 0x0
2054 * to src register, instead of 0x1 to enable receiving interrupts. 2145 * to src register, instead of 0x1 to enable receiving interrupts.
2055 */ 2146 */
2056static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring) 2147static inline void
2148qlcnic_82xx_enable_sds_intr(struct qlcnic_adapter *adapter,
2149 struct qlcnic_host_sds_ring *sds_ring)
2057{ 2150{
2058 struct qlcnic_adapter *adapter = sds_ring->adapter;
2059
2060 if (qlcnic_check_multi_tx(adapter) && 2151 if (qlcnic_check_multi_tx(adapter) &&
2061 !adapter->ahw->diag_test && 2152 !adapter->ahw->diag_test &&
2062 (adapter->flags & QLCNIC_MSIX_ENABLED)) 2153 (adapter->flags & QLCNIC_MSIX_ENABLED))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 294984584d1a..4146664d4d6a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -199,6 +199,11 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
199 .io_slot_reset = qlcnic_83xx_io_slot_reset, 199 .io_slot_reset = qlcnic_83xx_io_slot_reset,
200 .io_resume = qlcnic_83xx_io_resume, 200 .io_resume = qlcnic_83xx_io_resume,
201 .get_beacon_state = qlcnic_83xx_get_beacon_state, 201 .get_beacon_state = qlcnic_83xx_get_beacon_state,
202 .enable_sds_intr = qlcnic_83xx_enable_sds_intr,
203 .disable_sds_intr = qlcnic_83xx_disable_sds_intr,
204 .enable_tx_intr = qlcnic_83xx_enable_tx_intr,
205 .disable_tx_intr = qlcnic_83xx_disable_tx_intr,
206
202}; 207};
203 208
204static struct qlcnic_nic_template qlcnic_83xx_ops = { 209static struct qlcnic_nic_template qlcnic_83xx_ops = {
@@ -285,11 +290,22 @@ int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *adapter, ulong addr,
285 } 290 }
286} 291}
287 292
288int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) 293static void qlcnic_83xx_enable_legacy(struct qlcnic_adapter *adapter)
289{ 294{
290 int err, i, num_msix;
291 struct qlcnic_hardware_context *ahw = adapter->ahw; 295 struct qlcnic_hardware_context *ahw = adapter->ahw;
292 296
297 /* MSI-X enablement failed, use legacy interrupt */
298 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR;
299 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
300 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
301 adapter->msix_entries[0].vector = adapter->pdev->irq;
302 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
303}
304
305static int qlcnic_83xx_calculate_msix_vector(struct qlcnic_adapter *adapter)
306{
307 int num_msix;
308
293 num_msix = adapter->drv_sds_rings; 309 num_msix = adapter->drv_sds_rings;
294 310
295 /* account for AEN interrupt MSI-X based interrupts */ 311 /* account for AEN interrupt MSI-X based interrupts */
@@ -298,30 +314,44 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
298 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED)) 314 if (!(adapter->flags & QLCNIC_TX_INTR_SHARED))
299 num_msix += adapter->drv_tx_rings; 315 num_msix += adapter->drv_tx_rings;
300 316
301 err = qlcnic_enable_msix(adapter, num_msix); 317 return num_msix;
302 if (err == -ENOMEM) 318}
303 return err; 319
304 if (adapter->flags & QLCNIC_MSIX_ENABLED) 320int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
305 num_msix = adapter->ahw->num_msix; 321{
306 else { 322 struct qlcnic_hardware_context *ahw = adapter->ahw;
307 if (qlcnic_sriov_vf_check(adapter)) 323 int err, i, num_msix;
308 return -EINVAL; 324
309 num_msix = 1; 325 if (adapter->flags & QLCNIC_TSS_RSS) {
310 adapter->drv_tx_rings = QLCNIC_SINGLE_RING; 326 err = qlcnic_setup_tss_rss_intr(adapter);
327 if (err < 0)
328 return err;
329 num_msix = ahw->num_msix;
330 } else {
331 num_msix = qlcnic_83xx_calculate_msix_vector(adapter);
332
333 err = qlcnic_enable_msix(adapter, num_msix);
334 if (err == -ENOMEM)
335 return err;
336
337 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
338 num_msix = ahw->num_msix;
339 } else {
340 if (qlcnic_sriov_vf_check(adapter))
341 return -EINVAL;
342 num_msix = 1;
343 adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
344 }
311 } 345 }
346
312 /* setup interrupt mapping table for fw */ 347 /* setup interrupt mapping table for fw */
313 ahw->intr_tbl = vzalloc(num_msix * 348 ahw->intr_tbl = vzalloc(num_msix *
314 sizeof(struct qlcnic_intrpt_config)); 349 sizeof(struct qlcnic_intrpt_config));
315 if (!ahw->intr_tbl) 350 if (!ahw->intr_tbl)
316 return -ENOMEM; 351 return -ENOMEM;
317 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { 352
318 /* MSI-X enablement failed, use legacy interrupt */ 353 if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
319 adapter->tgt_status_reg = ahw->pci_base0 + QLC_83XX_INTX_PTR; 354 qlcnic_83xx_enable_legacy(adapter);
320 adapter->tgt_mask_reg = ahw->pci_base0 + QLC_83XX_INTX_MASK;
321 adapter->isr_int_vec = ahw->pci_base0 + QLC_83XX_INTX_TRGR;
322 adapter->msix_entries[0].vector = adapter->pdev->irq;
323 dev_info(&adapter->pdev->dev, "using legacy interrupt\n");
324 }
325 355
326 for (i = 0; i < num_msix; i++) { 356 for (i = 0; i < num_msix; i++) {
327 if (adapter->flags & QLCNIC_MSIX_ENABLED) 357 if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -331,6 +361,7 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
331 ahw->intr_tbl[i].id = i; 361 ahw->intr_tbl[i].id = i;
332 ahw->intr_tbl[i].src = 0; 362 ahw->intr_tbl[i].src = 0;
333 } 363 }
364
334 return 0; 365 return 0;
335} 366}
336 367
@@ -345,20 +376,6 @@ static inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapt
345 writel(1, adapter->tgt_mask_reg); 376 writel(1, adapter->tgt_mask_reg);
346} 377}
347 378
348/* Enable MSI-x and INT-x interrupts */
349void qlcnic_83xx_enable_intr(struct qlcnic_adapter *adapter,
350 struct qlcnic_host_sds_ring *sds_ring)
351{
352 writel(0, sds_ring->crb_intr_mask);
353}
354
355/* Disable MSI-x and INT-x interrupts */
356void qlcnic_83xx_disable_intr(struct qlcnic_adapter *adapter,
357 struct qlcnic_host_sds_ring *sds_ring)
358{
359 writel(1, sds_ring->crb_intr_mask);
360}
361
362static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter 379static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
363 *adapter) 380 *adapter)
364{ 381{
@@ -496,7 +513,7 @@ irqreturn_t qlcnic_83xx_tmp_intr(int irq, void *data)
496 513
497done: 514done:
498 adapter->ahw->diag_cnt++; 515 adapter->ahw->diag_cnt++;
499 qlcnic_83xx_enable_intr(adapter, sds_ring); 516 qlcnic_enable_sds_intr(adapter, sds_ring);
500 517
501 return IRQ_HANDLED; 518 return IRQ_HANDLED;
502} 519}
@@ -1295,8 +1312,8 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1295 /* send the mailbox command*/ 1312 /* send the mailbox command*/
1296 err = qlcnic_issue_cmd(adapter, &cmd); 1313 err = qlcnic_issue_cmd(adapter, &cmd);
1297 if (err) { 1314 if (err) {
1298 dev_err(&adapter->pdev->dev, 1315 netdev_err(adapter->netdev,
1299 "Failed to create Tx ctx in firmware 0x%x\n", err); 1316 "Failed to create Tx ctx in firmware 0x%x\n", err);
1300 goto out; 1317 goto out;
1301 } 1318 }
1302 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2]; 1319 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd.rsp.arg[2];
@@ -1307,8 +1324,9 @@ int qlcnic_83xx_create_tx_ctx(struct qlcnic_adapter *adapter,
1307 intr_mask = ahw->intr_tbl[adapter->drv_sds_rings + ring].src; 1324 intr_mask = ahw->intr_tbl[adapter->drv_sds_rings + ring].src;
1308 tx->crb_intr_mask = ahw->pci_base0 + intr_mask; 1325 tx->crb_intr_mask = ahw->pci_base0 + intr_mask;
1309 } 1326 }
1310 dev_info(&adapter->pdev->dev, "Tx Context[0x%x] Created, state:0x%x\n", 1327 netdev_info(adapter->netdev,
1311 tx->ctx_id, mbx_out->state); 1328 "Tx Context[0x%x] Created, state:0x%x\n",
1329 tx->ctx_id, mbx_out->state);
1312out: 1330out:
1313 qlcnic_free_mbx_args(&cmd); 1331 qlcnic_free_mbx_args(&cmd);
1314 return err; 1332 return err;
@@ -1360,7 +1378,7 @@ static int qlcnic_83xx_diag_alloc_res(struct net_device *netdev, int test,
1360 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 1378 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1361 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1379 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1362 sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1380 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1363 qlcnic_83xx_enable_intr(adapter, sds_ring); 1381 qlcnic_enable_sds_intr(adapter, sds_ring);
1364 } 1382 }
1365 } 1383 }
1366 1384
@@ -1385,7 +1403,7 @@ static void qlcnic_83xx_diag_free_res(struct net_device *netdev,
1385 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1403 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1386 sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1404 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1387 if (adapter->flags & QLCNIC_MSIX_ENABLED) 1405 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1388 qlcnic_83xx_disable_intr(adapter, sds_ring); 1406 qlcnic_disable_sds_intr(adapter, sds_ring);
1389 } 1407 }
1390 } 1408 }
1391 1409
@@ -1637,7 +1655,7 @@ static void qlcnic_83xx_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1637 if (qlcnic_sriov_pf_check(adapter)) { 1655 if (qlcnic_sriov_pf_check(adapter)) {
1638 qlcnic_alloc_lb_filters_mem(adapter); 1656 qlcnic_alloc_lb_filters_mem(adapter);
1639 qlcnic_pf_set_interface_id_promisc(adapter, interface_id); 1657 qlcnic_pf_set_interface_id_promisc(adapter, interface_id);
1640 adapter->rx_mac_learn = 1; 1658 adapter->rx_mac_learn = true;
1641 } else { 1659 } else {
1642 if (!qlcnic_sriov_vf_check(adapter)) 1660 if (!qlcnic_sriov_vf_check(adapter))
1643 *interface_id = adapter->recv_ctx->context_id << 16; 1661 *interface_id = adapter->recv_ctx->context_id << 16;
@@ -2111,37 +2129,130 @@ int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
2111 return err; 2129 return err;
2112} 2130}
2113 2131
2114void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) 2132static int qlcnic_83xx_set_rx_intr_coal(struct qlcnic_adapter *adapter)
2115{ 2133{
2116 int err;
2117 u16 temp;
2118 struct qlcnic_cmd_args cmd;
2119 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; 2134 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2135 struct qlcnic_cmd_args cmd;
2136 u16 temp;
2137 int err;
2120 2138
2121 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) 2139 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2122 return; 2140 if (err)
2141 return err;
2142
2143 temp = adapter->recv_ctx->context_id;
2144 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
2145 temp = coal->rx_time_us;
2146 cmd.req.arg[2] = coal->rx_packets | temp << 16;
2147 cmd.req.arg[3] = coal->flag;
2148
2149 err = qlcnic_issue_cmd(adapter, &cmd);
2150 if (err != QLCNIC_RCODE_SUCCESS)
2151 netdev_err(adapter->netdev,
2152 "failed to set interrupt coalescing parameters\n");
2153
2154 qlcnic_free_mbx_args(&cmd);
2155
2156 return err;
2157}
2158
2159static int qlcnic_83xx_set_tx_intr_coal(struct qlcnic_adapter *adapter)
2160{
2161 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2162 struct qlcnic_cmd_args cmd;
2163 u16 temp;
2164 int err;
2123 2165
2124 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL); 2166 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2125 if (err) 2167 if (err)
2126 return; 2168 return err;
2127 2169
2128 if (coal->type == QLCNIC_INTR_COAL_TYPE_RX) { 2170 temp = adapter->tx_ring->ctx_id;
2129 temp = adapter->recv_ctx->context_id; 2171 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2130 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16; 2172 temp = coal->tx_time_us;
2131 temp = coal->rx_time_us; 2173 cmd.req.arg[2] = coal->tx_packets | temp << 16;
2132 cmd.req.arg[2] = coal->rx_packets | temp << 16;
2133 } else if (coal->type == QLCNIC_INTR_COAL_TYPE_TX) {
2134 temp = adapter->tx_ring->ctx_id;
2135 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2136 temp = coal->tx_time_us;
2137 cmd.req.arg[2] = coal->tx_packets | temp << 16;
2138 }
2139 cmd.req.arg[3] = coal->flag; 2174 cmd.req.arg[3] = coal->flag;
2175
2140 err = qlcnic_issue_cmd(adapter, &cmd); 2176 err = qlcnic_issue_cmd(adapter, &cmd);
2141 if (err != QLCNIC_RCODE_SUCCESS) 2177 if (err != QLCNIC_RCODE_SUCCESS)
2142 dev_info(&adapter->pdev->dev, 2178 netdev_err(adapter->netdev,
2143 "Failed to send interrupt coalescence parameters\n"); 2179 "failed to set interrupt coalescing parameters\n");
2180
2144 qlcnic_free_mbx_args(&cmd); 2181 qlcnic_free_mbx_args(&cmd);
2182
2183 return err;
2184}
2185
2186int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *adapter)
2187{
2188 int err = 0;
2189
2190 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2191 if (err)
2192 netdev_err(adapter->netdev,
2193 "failed to set Rx coalescing parameters\n");
2194
2195 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2196 if (err)
2197 netdev_err(adapter->netdev,
2198 "failed to set Tx coalescing parameters\n");
2199
2200 return err;
2201}
2202
2203int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter,
2204 struct ethtool_coalesce *ethcoal)
2205{
2206 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2207 u32 rx_coalesce_usecs, rx_max_frames;
2208 u32 tx_coalesce_usecs, tx_max_frames;
2209 int err;
2210
2211 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2212 return -EIO;
2213
2214 tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
2215 tx_max_frames = ethcoal->tx_max_coalesced_frames;
2216 rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
2217 rx_max_frames = ethcoal->rx_max_coalesced_frames;
2218 coal->flag = QLCNIC_INTR_DEFAULT;
2219
2220 if ((coal->rx_time_us == rx_coalesce_usecs) &&
2221 (coal->rx_packets == rx_max_frames)) {
2222 coal->type = QLCNIC_INTR_COAL_TYPE_TX;
2223 coal->tx_time_us = tx_coalesce_usecs;
2224 coal->tx_packets = tx_max_frames;
2225 } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
2226 (coal->tx_packets == tx_max_frames)) {
2227 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
2228 coal->rx_time_us = rx_coalesce_usecs;
2229 coal->rx_packets = rx_max_frames;
2230 } else {
2231 coal->type = QLCNIC_INTR_COAL_TYPE_RX_TX;
2232 coal->rx_time_us = rx_coalesce_usecs;
2233 coal->rx_packets = rx_max_frames;
2234 coal->tx_time_us = tx_coalesce_usecs;
2235 coal->tx_packets = tx_max_frames;
2236 }
2237
2238 switch (coal->type) {
2239 case QLCNIC_INTR_COAL_TYPE_RX:
2240 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2241 break;
2242 case QLCNIC_INTR_COAL_TYPE_TX:
2243 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2244 break;
2245 case QLCNIC_INTR_COAL_TYPE_RX_TX:
2246 err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
2247 break;
2248 default:
2249 err = -EINVAL;
2250 netdev_err(adapter->netdev,
2251 "Invalid Interrupt coalescing type\n");
2252 break;
2253 }
2254
2255 return err;
2145} 2256}
2146 2257
2147static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter, 2258static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
index a5ca3f460b2d..f92485ca21d1 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h
@@ -547,7 +547,6 @@ int qlcnic_83xx_wrt_reg_indirect(struct qlcnic_adapter *, ulong, u32);
547int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32); 547int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32);
548int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *, int); 548int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *, int);
549int qlcnic_83xx_config_rss(struct qlcnic_adapter *, int); 549int qlcnic_83xx_config_rss(struct qlcnic_adapter *, int);
550int qlcnic_83xx_config_intr_coalesce(struct qlcnic_adapter *);
551void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16); 550void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16);
552int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *); 551int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *);
553int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); 552int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *);
@@ -577,17 +576,15 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *,
577void qlcnic_free_mbx_args(struct qlcnic_cmd_args *); 576void qlcnic_free_mbx_args(struct qlcnic_cmd_args *);
578void qlcnic_set_npar_data(struct qlcnic_adapter *, const struct qlcnic_info *, 577void qlcnic_set_npar_data(struct qlcnic_adapter *, const struct qlcnic_info *,
579 struct qlcnic_info *); 578 struct qlcnic_info *);
580void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *); 579int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *,
580 struct ethtool_coalesce *);
581int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *);
581int qlcnic_83xx_get_port_info(struct qlcnic_adapter *); 582int qlcnic_83xx_get_port_info(struct qlcnic_adapter *);
582void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *); 583void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *);
583void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *); 584void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *);
584irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *); 585irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *);
585irqreturn_t qlcnic_83xx_intr(int, void *); 586irqreturn_t qlcnic_83xx_intr(int, void *);
586irqreturn_t qlcnic_83xx_tmp_intr(int, void *); 587irqreturn_t qlcnic_83xx_tmp_intr(int, void *);
587void qlcnic_83xx_enable_intr(struct qlcnic_adapter *,
588 struct qlcnic_host_sds_ring *);
589void qlcnic_83xx_disable_intr(struct qlcnic_adapter *,
590 struct qlcnic_host_sds_ring *);
591void qlcnic_83xx_check_vf(struct qlcnic_adapter *, 588void qlcnic_83xx_check_vf(struct qlcnic_adapter *,
592 const struct pci_device_id *); 589 const struct pci_device_id *);
593int qlcnic_83xx_config_default_opmode(struct qlcnic_adapter *); 590int qlcnic_83xx_config_default_opmode(struct qlcnic_adapter *);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index 6d7f6a170869..90a2dda351ec 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -383,7 +383,7 @@ static int qlcnic_83xx_idc_tx_soft_reset(struct qlcnic_adapter *adapter)
383 qlcnic_up(adapter, netdev); 383 qlcnic_up(adapter, netdev);
384 netif_device_attach(netdev); 384 netif_device_attach(netdev);
385 clear_bit(__QLCNIC_RESETTING, &adapter->state); 385 clear_bit(__QLCNIC_RESETTING, &adapter->state);
386 dev_err(&adapter->pdev->dev, "%s:\n", __func__); 386 netdev_info(adapter->netdev, "%s: soft reset complete.\n", __func__);
387 387
388 return 0; 388 return 0;
389} 389}
@@ -2217,7 +2217,7 @@ int qlcnic_83xx_init(struct qlcnic_adapter *adapter, int pci_using_dac)
2217 struct qlcnic_hardware_context *ahw = adapter->ahw; 2217 struct qlcnic_hardware_context *ahw = adapter->ahw;
2218 int err = 0; 2218 int err = 0;
2219 2219
2220 adapter->rx_mac_learn = 0; 2220 adapter->rx_mac_learn = false;
2221 ahw->msix_supported = !!qlcnic_use_msi_x; 2221 ahw->msix_supported = !!qlcnic_use_msi_x;
2222 2222
2223 qlcnic_83xx_init_rings(adapter); 2223 qlcnic_83xx_init_rings(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
index e26c49fa87ab..be7d7a62cc0d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c
@@ -227,10 +227,10 @@ int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
227 if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) { 227 if (ahw->capabilities & QLC_83XX_ESWITCH_CAPABILITY) {
228 adapter->flags |= QLCNIC_ESWITCH_ENABLED; 228 adapter->flags |= QLCNIC_ESWITCH_ENABLED;
229 if (adapter->drv_mac_learn) 229 if (adapter->drv_mac_learn)
230 adapter->rx_mac_learn = 1; 230 adapter->rx_mac_learn = true;
231 } else { 231 } else {
232 adapter->flags &= ~QLCNIC_ESWITCH_ENABLED; 232 adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
233 adapter->rx_mac_learn = 0; 233 adapter->rx_mac_learn = false;
234 } 234 }
235 235
236 ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER; 236 ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 45961e310194..acee1a5d80c6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -736,6 +736,7 @@ static int qlcnic_set_channels(struct net_device *dev,
736 channel->rx_count); 736 channel->rx_count);
737 return err; 737 return err;
738 } 738 }
739 adapter->drv_rss_rings = channel->rx_count;
739 } 740 }
740 741
741 if (channel->tx_count) { 742 if (channel->tx_count) {
@@ -746,10 +747,12 @@ static int qlcnic_set_channels(struct net_device *dev,
746 channel->tx_count); 747 channel->tx_count);
747 return err; 748 return err;
748 } 749 }
750 adapter->drv_tss_rings = channel->tx_count;
749 } 751 }
750 752
751 err = qlcnic_setup_rings(adapter, channel->rx_count, 753 adapter->flags |= QLCNIC_TSS_RSS;
752 channel->tx_count); 754
755 err = qlcnic_setup_rings(adapter);
753 netdev_info(dev, "Allocated %d SDS rings and %d Tx rings\n", 756 netdev_info(dev, "Allocated %d SDS rings and %d Tx rings\n",
754 adapter->drv_sds_rings, adapter->drv_tx_rings); 757 adapter->drv_sds_rings, adapter->drv_tx_rings);
755 758
@@ -1495,9 +1498,7 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1495 struct ethtool_coalesce *ethcoal) 1498 struct ethtool_coalesce *ethcoal)
1496{ 1499{
1497 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1500 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1498 struct qlcnic_nic_intr_coalesce *coal; 1501 int err;
1499 u32 rx_coalesce_usecs, rx_max_frames;
1500 u32 tx_coalesce_usecs, tx_max_frames;
1501 1502
1502 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1503 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1503 return -EINVAL; 1504 return -EINVAL;
@@ -1507,82 +1508,31 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1507 * unsupported parameters are set. 1508 * unsupported parameters are set.
1508 */ 1509 */
1509 if (ethcoal->rx_coalesce_usecs > 0xffff || 1510 if (ethcoal->rx_coalesce_usecs > 0xffff ||
1510 ethcoal->rx_max_coalesced_frames > 0xffff || 1511 ethcoal->rx_max_coalesced_frames > 0xffff ||
1511 ethcoal->tx_coalesce_usecs > 0xffff || 1512 ethcoal->tx_coalesce_usecs > 0xffff ||
1512 ethcoal->tx_max_coalesced_frames > 0xffff || 1513 ethcoal->tx_max_coalesced_frames > 0xffff ||
1513 ethcoal->rx_coalesce_usecs_irq || 1514 ethcoal->rx_coalesce_usecs_irq ||
1514 ethcoal->rx_max_coalesced_frames_irq || 1515 ethcoal->rx_max_coalesced_frames_irq ||
1515 ethcoal->tx_coalesce_usecs_irq || 1516 ethcoal->tx_coalesce_usecs_irq ||
1516 ethcoal->tx_max_coalesced_frames_irq || 1517 ethcoal->tx_max_coalesced_frames_irq ||
1517 ethcoal->stats_block_coalesce_usecs || 1518 ethcoal->stats_block_coalesce_usecs ||
1518 ethcoal->use_adaptive_rx_coalesce || 1519 ethcoal->use_adaptive_rx_coalesce ||
1519 ethcoal->use_adaptive_tx_coalesce || 1520 ethcoal->use_adaptive_tx_coalesce ||
1520 ethcoal->pkt_rate_low || 1521 ethcoal->pkt_rate_low ||
1521 ethcoal->rx_coalesce_usecs_low || 1522 ethcoal->rx_coalesce_usecs_low ||
1522 ethcoal->rx_max_coalesced_frames_low || 1523 ethcoal->rx_max_coalesced_frames_low ||
1523 ethcoal->tx_coalesce_usecs_low || 1524 ethcoal->tx_coalesce_usecs_low ||
1524 ethcoal->tx_max_coalesced_frames_low || 1525 ethcoal->tx_max_coalesced_frames_low ||
1525 ethcoal->pkt_rate_high || 1526 ethcoal->pkt_rate_high ||
1526 ethcoal->rx_coalesce_usecs_high || 1527 ethcoal->rx_coalesce_usecs_high ||
1527 ethcoal->rx_max_coalesced_frames_high || 1528 ethcoal->rx_max_coalesced_frames_high ||
1528 ethcoal->tx_coalesce_usecs_high || 1529 ethcoal->tx_coalesce_usecs_high ||
1529 ethcoal->tx_max_coalesced_frames_high) 1530 ethcoal->tx_max_coalesced_frames_high)
1530 return -EINVAL; 1531 return -EINVAL;
1531 1532
1532 coal = &adapter->ahw->coal; 1533 err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1533
1534 if (qlcnic_83xx_check(adapter)) {
1535 if (!ethcoal->tx_coalesce_usecs ||
1536 !ethcoal->tx_max_coalesced_frames ||
1537 !ethcoal->rx_coalesce_usecs ||
1538 !ethcoal->rx_max_coalesced_frames) {
1539 coal->flag = QLCNIC_INTR_DEFAULT;
1540 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
1541 coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1542 coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1543 coal->tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
1544 coal->tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
1545 } else {
1546 tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
1547 tx_max_frames = ethcoal->tx_max_coalesced_frames;
1548 rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
1549 rx_max_frames = ethcoal->rx_max_coalesced_frames;
1550 coal->flag = 0;
1551
1552 if ((coal->rx_time_us == rx_coalesce_usecs) &&
1553 (coal->rx_packets == rx_max_frames)) {
1554 coal->type = QLCNIC_INTR_COAL_TYPE_TX;
1555 coal->tx_time_us = tx_coalesce_usecs;
1556 coal->tx_packets = tx_max_frames;
1557 } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
1558 (coal->tx_packets == tx_max_frames)) {
1559 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
1560 coal->rx_time_us = rx_coalesce_usecs;
1561 coal->rx_packets = rx_max_frames;
1562 } else {
1563 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
1564 coal->rx_time_us = rx_coalesce_usecs;
1565 coal->rx_packets = rx_max_frames;
1566 coal->tx_time_us = tx_coalesce_usecs;
1567 coal->tx_packets = tx_max_frames;
1568 }
1569 }
1570 } else {
1571 if (!ethcoal->rx_coalesce_usecs ||
1572 !ethcoal->rx_max_coalesced_frames) {
1573 coal->flag = QLCNIC_INTR_DEFAULT;
1574 coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1575 coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1576 } else {
1577 coal->flag = 0;
1578 coal->rx_time_us = ethcoal->rx_coalesce_usecs;
1579 coal->rx_packets = ethcoal->rx_max_coalesced_frames;
1580 }
1581 }
1582
1583 qlcnic_config_intr_coalesce(adapter);
1584 1534
1585 return 0; 1535 return err;
1586} 1536}
1587 1537
1588static int qlcnic_get_intr_coalesce(struct net_device *netdev, 1538static int qlcnic_get_intr_coalesce(struct net_device *netdev,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index e86147912922..03d18a0be6ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -547,10 +547,10 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
547 qlcnic_alloc_lb_filters_mem(adapter); 547 qlcnic_alloc_lb_filters_mem(adapter);
548 adapter->drv_mac_learn = 1; 548 adapter->drv_mac_learn = 1;
549 if (adapter->flags & QLCNIC_ESWITCH_ENABLED) 549 if (adapter->flags & QLCNIC_ESWITCH_ENABLED)
550 adapter->rx_mac_learn = 1; 550 adapter->rx_mac_learn = true;
551 } else { 551 } else {
552 adapter->drv_mac_learn = 0; 552 adapter->drv_mac_learn = 0;
553 adapter->rx_mac_learn = 0; 553 adapter->rx_mac_learn = false;
554 } 554 }
555 555
556 qlcnic_nic_set_promisc(adapter, mode); 556 qlcnic_nic_set_promisc(adapter, mode);
@@ -755,10 +755,7 @@ int qlcnic_82xx_read_phys_port_id(struct qlcnic_adapter *adapter)
755 return 0; 755 return 0;
756} 756}
757 757
758/* 758int qlcnic_82xx_set_rx_coalesce(struct qlcnic_adapter *adapter)
759 * Send the interrupt coalescing parameter set by ethtool to the card.
760 */
761void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter)
762{ 759{
763 struct qlcnic_nic_req req; 760 struct qlcnic_nic_req req;
764 int rv; 761 int rv;
@@ -780,6 +777,28 @@ void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter)
780 if (rv != 0) 777 if (rv != 0)
781 dev_err(&adapter->netdev->dev, 778 dev_err(&adapter->netdev->dev,
782 "Could not send interrupt coalescing parameters\n"); 779 "Could not send interrupt coalescing parameters\n");
780
781 return rv;
782}
783
784/* Send the interrupt coalescing parameter set by ethtool to the card. */
785int qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter,
786 struct ethtool_coalesce *ethcoal)
787{
788 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
789 int rv;
790
791 coal->flag = QLCNIC_INTR_DEFAULT;
792 coal->rx_time_us = ethcoal->rx_coalesce_usecs;
793 coal->rx_packets = ethcoal->rx_max_coalesced_frames;
794
795 rv = qlcnic_82xx_set_rx_coalesce(adapter);
796
797 if (rv)
798 netdev_err(adapter->netdev,
799 "Failed to set Rx coalescing parametrs\n");
800
801 return rv;
783} 802}
784 803
785#define QLCNIC_ENABLE_IPV4_LRO BIT_0 804#define QLCNIC_ENABLE_IPV4_LRO BIT_0
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
index 17f563de90f1..63d75617d445 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h
@@ -171,7 +171,9 @@ int qlcnic_82xx_napi_add(struct qlcnic_adapter *adapter,
171void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *); 171void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *);
172void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, 172void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter,
173 u64 *uaddr, u16 vlan_id); 173 u64 *uaddr, u16 vlan_id);
174void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter); 174int qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *,
175 struct ethtool_coalesce *);
176int qlcnic_82xx_set_rx_coalesce(struct qlcnic_adapter *);
175int qlcnic_82xx_config_rss(struct qlcnic_adapter *adapter, int); 177int qlcnic_82xx_config_rss(struct qlcnic_adapter *adapter, int);
176void qlcnic_82xx_config_ipaddr(struct qlcnic_adapter *adapter, 178void qlcnic_82xx_config_ipaddr(struct qlcnic_adapter *adapter,
177 __be32, int); 179 __be32, int);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 0df6988e42a9..30874cda8476 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -131,35 +131,6 @@ static struct sk_buff *qlcnic_process_rxbuf(struct qlcnic_adapter *,
131 struct qlcnic_host_rds_ring *, 131 struct qlcnic_host_rds_ring *,
132 u16, u16); 132 u16, u16);
133 133
134static inline void qlcnic_enable_tx_intr(struct qlcnic_adapter *adapter,
135 struct qlcnic_host_tx_ring *tx_ring)
136{
137 if (qlcnic_check_multi_tx(adapter) &&
138 !adapter->ahw->diag_test)
139 writel(0x0, tx_ring->crb_intr_mask);
140}
141
142
143static inline void qlcnic_disable_tx_int(struct qlcnic_adapter *adapter,
144 struct qlcnic_host_tx_ring *tx_ring)
145{
146 if (qlcnic_check_multi_tx(adapter) &&
147 !adapter->ahw->diag_test)
148 writel(1, tx_ring->crb_intr_mask);
149}
150
151static inline void qlcnic_83xx_enable_tx_intr(struct qlcnic_adapter *adapter,
152 struct qlcnic_host_tx_ring *tx_ring)
153{
154 writel(0, tx_ring->crb_intr_mask);
155}
156
157static inline void qlcnic_83xx_disable_tx_intr(struct qlcnic_adapter *adapter,
158 struct qlcnic_host_tx_ring *tx_ring)
159{
160 writel(1, tx_ring->crb_intr_mask);
161}
162
163static inline u8 qlcnic_mac_hash(u64 mac, u16 vlan) 134static inline u8 qlcnic_mac_hash(u64 mac, u16 vlan)
164{ 135{
165 return (u8)((mac & 0xff) ^ ((mac >> 40) & 0xff) ^ (vlan & 0xff)); 136 return (u8)((mac & 0xff) ^ ((mac >> 40) & 0xff) ^ (vlan & 0xff));
@@ -885,7 +856,7 @@ static int qlcnic_poll(struct napi_struct *napi, int budget)
885 if ((work_done < budget) && tx_complete) { 856 if ((work_done < budget) && tx_complete) {
886 napi_complete(&sds_ring->napi); 857 napi_complete(&sds_ring->napi);
887 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) { 858 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
888 qlcnic_enable_int(sds_ring); 859 qlcnic_enable_sds_intr(adapter, sds_ring);
889 qlcnic_enable_tx_intr(adapter, tx_ring); 860 qlcnic_enable_tx_intr(adapter, tx_ring);
890 } 861 }
891 } 862 }
@@ -926,7 +897,7 @@ static int qlcnic_rx_poll(struct napi_struct *napi, int budget)
926 if (work_done < budget) { 897 if (work_done < budget) {
927 napi_complete(&sds_ring->napi); 898 napi_complete(&sds_ring->napi);
928 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 899 if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
929 qlcnic_enable_int(sds_ring); 900 qlcnic_enable_sds_intr(adapter, sds_ring);
930 } 901 }
931 902
932 return work_done; 903 return work_done;
@@ -1557,7 +1528,7 @@ void qlcnic_82xx_napi_enable(struct qlcnic_adapter *adapter)
1557 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1528 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1558 sds_ring = &recv_ctx->sds_rings[ring]; 1529 sds_ring = &recv_ctx->sds_rings[ring];
1559 napi_enable(&sds_ring->napi); 1530 napi_enable(&sds_ring->napi);
1560 qlcnic_enable_int(sds_ring); 1531 qlcnic_enable_sds_intr(adapter, sds_ring);
1561 } 1532 }
1562 1533
1563 if (qlcnic_check_multi_tx(adapter) && 1534 if (qlcnic_check_multi_tx(adapter) &&
@@ -1583,7 +1554,7 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter)
1583 1554
1584 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1555 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1585 sds_ring = &recv_ctx->sds_rings[ring]; 1556 sds_ring = &recv_ctx->sds_rings[ring];
1586 qlcnic_disable_int(sds_ring); 1557 qlcnic_disable_sds_intr(adapter, sds_ring);
1587 napi_synchronize(&sds_ring->napi); 1558 napi_synchronize(&sds_ring->napi);
1588 napi_disable(&sds_ring->napi); 1559 napi_disable(&sds_ring->napi);
1589 } 1560 }
@@ -1593,7 +1564,7 @@ void qlcnic_82xx_napi_disable(struct qlcnic_adapter *adapter)
1593 qlcnic_check_multi_tx(adapter)) { 1564 qlcnic_check_multi_tx(adapter)) {
1594 for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 1565 for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1595 tx_ring = &adapter->tx_ring[ring]; 1566 tx_ring = &adapter->tx_ring[ring];
1596 qlcnic_disable_tx_int(adapter, tx_ring); 1567 qlcnic_disable_tx_intr(adapter, tx_ring);
1597 napi_synchronize(&tx_ring->napi); 1568 napi_synchronize(&tx_ring->napi);
1598 napi_disable(&tx_ring->napi); 1569 napi_disable(&tx_ring->napi);
1599 } 1570 }
@@ -1856,7 +1827,7 @@ static int qlcnic_83xx_msix_sriov_vf_poll(struct napi_struct *napi, int budget)
1856 work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget); 1827 work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
1857 if ((work_done < budget) && tx_complete) { 1828 if ((work_done < budget) && tx_complete) {
1858 napi_complete(&sds_ring->napi); 1829 napi_complete(&sds_ring->napi);
1859 qlcnic_83xx_enable_intr(adapter, sds_ring); 1830 qlcnic_enable_sds_intr(adapter, sds_ring);
1860 } 1831 }
1861 1832
1862 return work_done; 1833 return work_done;
@@ -1879,7 +1850,7 @@ static int qlcnic_83xx_poll(struct napi_struct *napi, int budget)
1879 work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget); 1850 work_done = qlcnic_83xx_process_rcv_ring(sds_ring, budget);
1880 if ((work_done < budget) && tx_complete) { 1851 if ((work_done < budget) && tx_complete) {
1881 napi_complete(&sds_ring->napi); 1852 napi_complete(&sds_ring->napi);
1882 qlcnic_83xx_enable_intr(adapter, sds_ring); 1853 qlcnic_enable_sds_intr(adapter, sds_ring);
1883 } 1854 }
1884 1855
1885 return work_done; 1856 return work_done;
@@ -1898,7 +1869,7 @@ static int qlcnic_83xx_msix_tx_poll(struct napi_struct *napi, int budget)
1898 if (work_done) { 1869 if (work_done) {
1899 napi_complete(&tx_ring->napi); 1870 napi_complete(&tx_ring->napi);
1900 if (test_bit(__QLCNIC_DEV_UP , &adapter->state)) 1871 if (test_bit(__QLCNIC_DEV_UP , &adapter->state))
1901 qlcnic_83xx_enable_tx_intr(adapter, tx_ring); 1872 qlcnic_enable_tx_intr(adapter, tx_ring);
1902 } 1873 }
1903 1874
1904 return work_done; 1875 return work_done;
@@ -1916,7 +1887,7 @@ static int qlcnic_83xx_rx_poll(struct napi_struct *napi, int budget)
1916 if (work_done < budget) { 1887 if (work_done < budget) {
1917 napi_complete(&sds_ring->napi); 1888 napi_complete(&sds_ring->napi);
1918 if (test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1889 if (test_bit(__QLCNIC_DEV_UP, &adapter->state))
1919 qlcnic_83xx_enable_intr(adapter, sds_ring); 1890 qlcnic_enable_sds_intr(adapter, sds_ring);
1920 } 1891 }
1921 1892
1922 return work_done; 1893 return work_done;
@@ -1936,7 +1907,7 @@ void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter)
1936 sds_ring = &recv_ctx->sds_rings[ring]; 1907 sds_ring = &recv_ctx->sds_rings[ring];
1937 napi_enable(&sds_ring->napi); 1908 napi_enable(&sds_ring->napi);
1938 if (adapter->flags & QLCNIC_MSIX_ENABLED) 1909 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1939 qlcnic_83xx_enable_intr(adapter, sds_ring); 1910 qlcnic_enable_sds_intr(adapter, sds_ring);
1940 } 1911 }
1941 1912
1942 if ((adapter->flags & QLCNIC_MSIX_ENABLED) && 1913 if ((adapter->flags & QLCNIC_MSIX_ENABLED) &&
@@ -1944,7 +1915,7 @@ void qlcnic_83xx_napi_enable(struct qlcnic_adapter *adapter)
1944 for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 1915 for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1945 tx_ring = &adapter->tx_ring[ring]; 1916 tx_ring = &adapter->tx_ring[ring];
1946 napi_enable(&tx_ring->napi); 1917 napi_enable(&tx_ring->napi);
1947 qlcnic_83xx_enable_tx_intr(adapter, tx_ring); 1918 qlcnic_enable_tx_intr(adapter, tx_ring);
1948 } 1919 }
1949 } 1920 }
1950} 1921}
@@ -1962,7 +1933,7 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter)
1962 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1933 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1963 sds_ring = &recv_ctx->sds_rings[ring]; 1934 sds_ring = &recv_ctx->sds_rings[ring];
1964 if (adapter->flags & QLCNIC_MSIX_ENABLED) 1935 if (adapter->flags & QLCNIC_MSIX_ENABLED)
1965 qlcnic_83xx_disable_intr(adapter, sds_ring); 1936 qlcnic_disable_sds_intr(adapter, sds_ring);
1966 napi_synchronize(&sds_ring->napi); 1937 napi_synchronize(&sds_ring->napi);
1967 napi_disable(&sds_ring->napi); 1938 napi_disable(&sds_ring->napi);
1968 } 1939 }
@@ -1971,7 +1942,7 @@ void qlcnic_83xx_napi_disable(struct qlcnic_adapter *adapter)
1971 !(adapter->flags & QLCNIC_TX_INTR_SHARED)) { 1942 !(adapter->flags & QLCNIC_TX_INTR_SHARED)) {
1972 for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 1943 for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
1973 tx_ring = &adapter->tx_ring[ring]; 1944 tx_ring = &adapter->tx_ring[ring];
1974 qlcnic_83xx_disable_tx_intr(adapter, tx_ring); 1945 qlcnic_disable_tx_intr(adapter, tx_ring);
1975 napi_synchronize(&tx_ring->napi); 1946 napi_synchronize(&tx_ring->napi);
1976 napi_disable(&tx_ring->napi); 1947 napi_disable(&tx_ring->napi);
1977 } 1948 }
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index e2ee2bb5cd5c..1f79d47c45fa 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -557,6 +557,10 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
557 .io_slot_reset = qlcnic_82xx_io_slot_reset, 557 .io_slot_reset = qlcnic_82xx_io_slot_reset,
558 .io_resume = qlcnic_82xx_io_resume, 558 .io_resume = qlcnic_82xx_io_resume,
559 .get_beacon_state = qlcnic_82xx_get_beacon_state, 559 .get_beacon_state = qlcnic_82xx_get_beacon_state,
560 .enable_sds_intr = qlcnic_82xx_enable_sds_intr,
561 .disable_sds_intr = qlcnic_82xx_disable_sds_intr,
562 .enable_tx_intr = qlcnic_82xx_enable_tx_intr,
563 .disable_tx_intr = qlcnic_82xx_disable_tx_intr,
560}; 564};
561 565
562static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) 566static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter)
@@ -599,9 +603,6 @@ void qlcnic_set_tx_ring_count(struct qlcnic_adapter *adapter, u8 tx_cnt)
599 QLCNIC_TX_QUEUE); 603 QLCNIC_TX_QUEUE);
600 else 604 else
601 adapter->drv_tx_rings = tx_cnt; 605 adapter->drv_tx_rings = tx_cnt;
602
603 dev_info(&adapter->pdev->dev, "Set %d Tx rings\n",
604 adapter->drv_tx_rings);
605} 606}
606 607
607void qlcnic_set_sds_ring_count(struct qlcnic_adapter *adapter, u8 rx_cnt) 608void qlcnic_set_sds_ring_count(struct qlcnic_adapter *adapter, u8 rx_cnt)
@@ -612,25 +613,79 @@ void qlcnic_set_sds_ring_count(struct qlcnic_adapter *adapter, u8 rx_cnt)
612 QLCNIC_RX_QUEUE); 613 QLCNIC_RX_QUEUE);
613 else 614 else
614 adapter->drv_sds_rings = rx_cnt; 615 adapter->drv_sds_rings = rx_cnt;
615
616 dev_info(&adapter->pdev->dev, "Set %d SDS rings\n",
617 adapter->drv_sds_rings);
618} 616}
619 617
620int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) 618int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter)
621{ 619{
622 struct pci_dev *pdev = adapter->pdev; 620 struct pci_dev *pdev = adapter->pdev;
623 int drv_tx_rings, drv_sds_rings, tx_vector; 621 int num_msix = 0, err = 0, vector;
624 int err = -1, i; 622
623 adapter->flags &= ~QLCNIC_TSS_RSS;
624
625 if (adapter->drv_tss_rings > 0)
626 num_msix += adapter->drv_tss_rings;
627 else
628 num_msix += adapter->drv_tx_rings;
629
630 if (adapter->drv_rss_rings > 0)
631 num_msix += adapter->drv_rss_rings;
632 else
633 num_msix += adapter->drv_sds_rings;
625 634
626 if (adapter->flags & QLCNIC_TX_INTR_SHARED) { 635 if (qlcnic_83xx_check(adapter))
627 drv_tx_rings = 0; 636 num_msix += 1;
628 tx_vector = 0; 637
638 if (!adapter->msix_entries) {
639 adapter->msix_entries = kcalloc(num_msix,
640 sizeof(struct msix_entry),
641 GFP_KERNEL);
642 if (!adapter->msix_entries)
643 return -ENOMEM;
644 }
645
646restore:
647 for (vector = 0; vector < num_msix; vector++)
648 adapter->msix_entries[vector].entry = vector;
649
650 err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
651 if (err == 0) {
652 adapter->ahw->num_msix = num_msix;
653 if (adapter->drv_tss_rings > 0)
654 adapter->drv_tx_rings = adapter->drv_tss_rings;
655
656 if (adapter->drv_rss_rings > 0)
657 adapter->drv_sds_rings = adapter->drv_rss_rings;
629 } else { 658 } else {
630 drv_tx_rings = adapter->drv_tx_rings; 659 netdev_info(adapter->netdev,
631 tx_vector = 1; 660 "Unable to allocate %d MSI-X vectors, Available vectors %d\n",
661 num_msix, err);
662
663 num_msix = adapter->drv_tx_rings + adapter->drv_sds_rings;
664
665 /* Set rings to 0 so we can restore original TSS/RSS count */
666 adapter->drv_tss_rings = 0;
667 adapter->drv_rss_rings = 0;
668
669 if (qlcnic_83xx_check(adapter))
670 num_msix += 1;
671
672 netdev_info(adapter->netdev,
673 "Restoring %d Tx, %d SDS rings for total %d vectors.\n",
674 adapter->drv_tx_rings, adapter->drv_sds_rings,
675 num_msix);
676 goto restore;
677
678 err = -EIO;
632 } 679 }
633 680
681 return err;
682}
683
684int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
685{
686 struct pci_dev *pdev = adapter->pdev;
687 int err = -1, vector;
688
634 if (!adapter->msix_entries) { 689 if (!adapter->msix_entries) {
635 adapter->msix_entries = kcalloc(num_msix, 690 adapter->msix_entries = kcalloc(num_msix,
636 sizeof(struct msix_entry), 691 sizeof(struct msix_entry),
@@ -639,47 +694,43 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
639 return -ENOMEM; 694 return -ENOMEM;
640 } 695 }
641 696
642 adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
643 adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED); 697 adapter->flags &= ~(QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED);
644 698
645 if (adapter->ahw->msix_supported) { 699 if (adapter->ahw->msix_supported) {
646 enable_msix: 700enable_msix:
647 for (i = 0; i < num_msix; i++) 701 for (vector = 0; vector < num_msix; vector++)
648 adapter->msix_entries[i].entry = i; 702 adapter->msix_entries[vector].entry = vector;
703
649 err = pci_enable_msix(pdev, adapter->msix_entries, num_msix); 704 err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
650 if (err == 0) { 705 if (err == 0) {
651 adapter->flags |= QLCNIC_MSIX_ENABLED; 706 adapter->flags |= QLCNIC_MSIX_ENABLED;
652 if (qlcnic_83xx_check(adapter)) { 707 adapter->ahw->num_msix = num_msix;
653 adapter->ahw->num_msix = num_msix;
654 /* subtract mail box and tx ring vectors */
655 adapter->drv_sds_rings = num_msix -
656 drv_tx_rings - 1;
657 } else {
658 adapter->ahw->num_msix = num_msix;
659 if (qlcnic_check_multi_tx(adapter) &&
660 !adapter->ahw->diag_test)
661 drv_sds_rings = num_msix - drv_tx_rings;
662 else
663 drv_sds_rings = num_msix;
664
665 adapter->drv_sds_rings = drv_sds_rings;
666 }
667 dev_info(&pdev->dev, "using msi-x interrupts\n"); 708 dev_info(&pdev->dev, "using msi-x interrupts\n");
668 return err; 709 return err;
669 } else if (err > 0) { 710 } else if (err > 0) {
670 dev_info(&pdev->dev, 711 dev_info(&pdev->dev,
671 "Unable to allocate %d MSI-X interrupt vectors\n", 712 "Unable to allocate %d MSI-X vectors, Available vectors %d\n",
672 num_msix); 713 num_msix, err);
673 if (qlcnic_83xx_check(adapter)) { 714
674 if (err < (QLC_83XX_MINIMUM_VECTOR - tx_vector)) 715 if (qlcnic_82xx_check(adapter)) {
675 return err;
676 err -= drv_tx_rings + 1;
677 num_msix = rounddown_pow_of_two(err); 716 num_msix = rounddown_pow_of_two(err);
678 num_msix += drv_tx_rings + 1; 717 if (err < QLCNIC_82XX_MINIMUM_VECTOR)
718 return -EIO;
679 } else { 719 } else {
680 num_msix = rounddown_pow_of_two(err); 720 num_msix = rounddown_pow_of_two(err - 1);
681 if (qlcnic_check_multi_tx(adapter)) 721 num_msix += 1;
682 num_msix += drv_tx_rings; 722 if (err < QLCNIC_83XX_MINIMUM_VECTOR)
723 return -EIO;
724 }
725
726 if (qlcnic_82xx_check(adapter) &&
727 !qlcnic_check_multi_tx(adapter)) {
728 adapter->drv_sds_rings = num_msix;
729 adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
730 } else {
731 /* Distribute vectors equally */
732 adapter->drv_tx_rings = num_msix / 2;
733 adapter->drv_sds_rings = adapter->drv_tx_rings;
683 } 734 }
684 735
685 if (num_msix) { 736 if (num_msix) {
@@ -690,14 +741,29 @@ int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
690 } 741 }
691 } else { 742 } else {
692 dev_info(&pdev->dev, 743 dev_info(&pdev->dev,
693 "Unable to allocate %d MSI-X interrupt vectors\n", 744 "Unable to allocate %d MSI-X vectors, err=%d\n",
694 num_msix); 745 num_msix, err);
746 return err;
695 } 747 }
696 } 748 }
697 749
698 return err; 750 return err;
699} 751}
700 752
753static int qlcnic_82xx_calculate_msix_vector(struct qlcnic_adapter *adapter)
754{
755 int num_msix;
756
757 num_msix = adapter->drv_sds_rings;
758
759 if (qlcnic_check_multi_tx(adapter))
760 num_msix += adapter->drv_tx_rings;
761 else
762 num_msix += QLCNIC_SINGLE_RING;
763
764 return num_msix;
765}
766
701static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) 767static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
702{ 768{
703 int err = 0; 769 int err = 0;
@@ -736,21 +802,25 @@ static int qlcnic_82xx_setup_intr(struct qlcnic_adapter *adapter)
736{ 802{
737 int num_msix, err = 0; 803 int num_msix, err = 0;
738 804
739 num_msix = adapter->drv_sds_rings; 805 if (adapter->flags & QLCNIC_TSS_RSS) {
740 806 err = qlcnic_setup_tss_rss_intr(adapter);
741 if (qlcnic_check_multi_tx(adapter)) 807 if (err < 0)
742 num_msix += adapter->drv_tx_rings; 808 return err;
809 num_msix = adapter->ahw->num_msix;
810 } else {
811 num_msix = qlcnic_82xx_calculate_msix_vector(adapter);
743 812
744 err = qlcnic_enable_msix(adapter, num_msix); 813 err = qlcnic_enable_msix(adapter, num_msix);
745 if (err == -ENOMEM) 814 if (err == -ENOMEM)
746 return err; 815 return err;
747 816
748 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) { 817 if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
749 qlcnic_disable_multi_tx(adapter); 818 qlcnic_disable_multi_tx(adapter);
750 819
751 err = qlcnic_enable_msi_legacy(adapter); 820 err = qlcnic_enable_msi_legacy(adapter);
752 if (!err) 821 if (!err)
753 return err; 822 return err;
823 }
754 } 824 }
755 825
756 return 0; 826 return 0;
@@ -1697,6 +1767,33 @@ static void qlcnic_get_lro_mss_capability(struct qlcnic_adapter *adapter)
1697 } 1767 }
1698} 1768}
1699 1769
1770static int qlcnic_config_def_intr_coalesce(struct qlcnic_adapter *adapter)
1771{
1772 struct qlcnic_hardware_context *ahw = adapter->ahw;
1773 int err;
1774
1775 /* Initialize interrupt coalesce parameters */
1776 ahw->coal.flag = QLCNIC_INTR_DEFAULT;
1777
1778 if (qlcnic_83xx_check(adapter)) {
1779 ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX;
1780 ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
1781 ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
1782 ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1783 ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1784
1785 err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
1786 } else {
1787 ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
1788 ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1789 ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1790
1791 err = qlcnic_82xx_set_rx_coalesce(adapter);
1792 }
1793
1794 return err;
1795}
1796
1700int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1797int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
1701{ 1798{
1702 int ring; 1799 int ring;
@@ -1729,7 +1826,7 @@ int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
1729 if (adapter->drv_sds_rings > 1) 1826 if (adapter->drv_sds_rings > 1)
1730 qlcnic_config_rss(adapter, 1); 1827 qlcnic_config_rss(adapter, 1);
1731 1828
1732 qlcnic_config_intr_coalesce(adapter); 1829 qlcnic_config_def_intr_coalesce(adapter);
1733 1830
1734 if (netdev->features & NETIF_F_LRO) 1831 if (netdev->features & NETIF_F_LRO)
1735 qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); 1832 qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED);
@@ -1874,7 +1971,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int drv_sds_rings)
1874 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 1971 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1875 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 1972 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1876 sds_ring = &adapter->recv_ctx->sds_rings[ring]; 1973 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1877 qlcnic_disable_int(sds_ring); 1974 qlcnic_disable_sds_intr(adapter, sds_ring);
1878 } 1975 }
1879 } 1976 }
1880 1977
@@ -1897,7 +1994,6 @@ out:
1897 1994
1898static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) 1995static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
1899{ 1996{
1900 struct qlcnic_hardware_context *ahw = adapter->ahw;
1901 int err = 0; 1997 int err = 0;
1902 1998
1903 adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), 1999 adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
@@ -1906,15 +2002,7 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
1906 err = -ENOMEM; 2002 err = -ENOMEM;
1907 goto err_out; 2003 goto err_out;
1908 } 2004 }
1909 /* Initialize interrupt coalesce parameters */ 2005
1910 ahw->coal.flag = QLCNIC_INTR_DEFAULT;
1911 ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
1912 ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1913 ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1914 if (qlcnic_83xx_check(adapter)) {
1915 ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
1916 ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
1917 }
1918 /* clear stats */ 2006 /* clear stats */
1919 memset(&adapter->stats, 0, sizeof(adapter->stats)); 2007 memset(&adapter->stats, 0, sizeof(adapter->stats));
1920err_out: 2008err_out:
@@ -1975,7 +2063,7 @@ int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
1975 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) { 2063 if (adapter->ahw->diag_test == QLCNIC_INTERRUPT_TEST) {
1976 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 2064 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
1977 sds_ring = &adapter->recv_ctx->sds_rings[ring]; 2065 sds_ring = &adapter->recv_ctx->sds_rings[ring];
1978 qlcnic_enable_int(sds_ring); 2066 qlcnic_enable_sds_intr(adapter, sds_ring);
1979 } 2067 }
1980 } 2068 }
1981 2069
@@ -2007,7 +2095,7 @@ qlcnic_reset_hw_context(struct qlcnic_adapter *adapter)
2007 netif_device_attach(netdev); 2095 netif_device_attach(netdev);
2008 2096
2009 clear_bit(__QLCNIC_RESETTING, &adapter->state); 2097 clear_bit(__QLCNIC_RESETTING, &adapter->state);
2010 dev_err(&adapter->pdev->dev, "%s:\n", __func__); 2098 netdev_info(adapter->netdev, "%s: soft reset complete\n", __func__);
2011 return 0; 2099 return 0;
2012} 2100}
2013 2101
@@ -2747,12 +2835,58 @@ int qlcnic_check_temp(struct qlcnic_adapter *adapter)
2747 return rv; 2835 return rv;
2748} 2836}
2749 2837
2750static void qlcnic_tx_timeout(struct net_device *netdev) 2838static inline void dump_tx_ring_desc(struct qlcnic_host_tx_ring *tx_ring)
2751{ 2839{
2752 struct qlcnic_adapter *adapter = netdev_priv(netdev); 2840 int i;
2841 struct cmd_desc_type0 *tx_desc_info;
2842
2843 for (i = 0; i < tx_ring->num_desc; i++) {
2844 tx_desc_info = &tx_ring->desc_head[i];
2845 pr_info("TX Desc: %d\n", i);
2846 print_hex_dump(KERN_INFO, "TX: ", DUMP_PREFIX_OFFSET, 16, 1,
2847 &tx_ring->desc_head[i],
2848 sizeof(struct cmd_desc_type0), true);
2849 }
2850}
2851
2852static void qlcnic_dump_tx_rings(struct qlcnic_adapter *adapter)
2853{
2854 struct net_device *netdev = adapter->netdev;
2753 struct qlcnic_host_tx_ring *tx_ring; 2855 struct qlcnic_host_tx_ring *tx_ring;
2754 int ring; 2856 int ring;
2755 2857
2858 if (!netdev || !netif_running(netdev))
2859 return;
2860
2861 for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
2862 tx_ring = &adapter->tx_ring[ring];
2863 netdev_info(netdev, "Tx ring=%d Context Id=0x%x\n",
2864 ring, tx_ring->ctx_id);
2865 netdev_info(netdev,
2866 "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n",
2867 tx_ring->tx_stats.xmit_finished,
2868 tx_ring->tx_stats.xmit_called,
2869 tx_ring->tx_stats.xmit_on,
2870 tx_ring->tx_stats.xmit_off);
2871 netdev_info(netdev,
2872 "crb_intr_mask=%d, hw_producer=%d, sw_producer=%d sw_consumer=%d, hw_consumer=%d\n",
2873 readl(tx_ring->crb_intr_mask),
2874 readl(tx_ring->crb_cmd_producer),
2875 tx_ring->producer, tx_ring->sw_consumer,
2876 le32_to_cpu(*(tx_ring->hw_consumer)));
2877
2878 netdev_info(netdev, "Total desc=%d, Available desc=%d\n",
2879 tx_ring->num_desc, qlcnic_tx_avail(tx_ring));
2880
2881 if (netif_msg_tx_done(adapter->ahw))
2882 dump_tx_ring_desc(tx_ring);
2883 }
2884}
2885
2886static void qlcnic_tx_timeout(struct net_device *netdev)
2887{
2888 struct qlcnic_adapter *adapter = netdev_priv(netdev);
2889
2756 if (test_bit(__QLCNIC_RESETTING, &adapter->state)) 2890 if (test_bit(__QLCNIC_RESETTING, &adapter->state))
2757 return; 2891 return;
2758 2892
@@ -2765,22 +2899,7 @@ static void qlcnic_tx_timeout(struct net_device *netdev)
2765 QLCNIC_FORCE_FW_DUMP_KEY); 2899 QLCNIC_FORCE_FW_DUMP_KEY);
2766 } else { 2900 } else {
2767 netdev_info(netdev, "Tx timeout, reset adapter context.\n"); 2901 netdev_info(netdev, "Tx timeout, reset adapter context.\n");
2768 for (ring = 0; ring < adapter->drv_tx_rings; ring++) { 2902 qlcnic_dump_tx_rings(adapter);
2769 tx_ring = &adapter->tx_ring[ring];
2770 netdev_info(netdev, "Tx ring=%d\n", ring);
2771 netdev_info(netdev,
2772 "crb_intr_mask=%d, producer=%d, sw_consumer=%d, hw_consumer=%d\n",
2773 readl(tx_ring->crb_intr_mask),
2774 readl(tx_ring->crb_cmd_producer),
2775 tx_ring->sw_consumer,
2776 le32_to_cpu(*(tx_ring->hw_consumer)));
2777 netdev_info(netdev,
2778 "xmit_finished=%llu, xmit_called=%llu, xmit_on=%llu, xmit_off=%llu\n",
2779 tx_ring->tx_stats.xmit_finished,
2780 tx_ring->tx_stats.xmit_called,
2781 tx_ring->tx_stats.xmit_on,
2782 tx_ring->tx_stats.xmit_off);
2783 }
2784 adapter->ahw->reset_context = 1; 2903 adapter->ahw->reset_context = 1;
2785 } 2904 }
2786} 2905}
@@ -2842,7 +2961,7 @@ static irqreturn_t qlcnic_tmp_intr(int irq, void *data)
2842 2961
2843done: 2962done:
2844 adapter->ahw->diag_cnt++; 2963 adapter->ahw->diag_cnt++;
2845 qlcnic_enable_int(sds_ring); 2964 qlcnic_enable_sds_intr(adapter, sds_ring);
2846 return IRQ_HANDLED; 2965 return IRQ_HANDLED;
2847} 2966}
2848 2967
@@ -2890,17 +3009,39 @@ static irqreturn_t qlcnic_msix_tx_intr(int irq, void *data)
2890#ifdef CONFIG_NET_POLL_CONTROLLER 3009#ifdef CONFIG_NET_POLL_CONTROLLER
2891static void qlcnic_poll_controller(struct net_device *netdev) 3010static void qlcnic_poll_controller(struct net_device *netdev)
2892{ 3011{
2893 int ring;
2894 struct qlcnic_host_sds_ring *sds_ring;
2895 struct qlcnic_adapter *adapter = netdev_priv(netdev); 3012 struct qlcnic_adapter *adapter = netdev_priv(netdev);
2896 struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx; 3013 struct qlcnic_host_sds_ring *sds_ring;
3014 struct qlcnic_recv_context *recv_ctx;
3015 struct qlcnic_host_tx_ring *tx_ring;
3016 int ring;
3017
3018 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
3019 return;
3020
3021 recv_ctx = adapter->recv_ctx;
2897 3022
2898 disable_irq(adapter->irq);
2899 for (ring = 0; ring < adapter->drv_sds_rings; ring++) { 3023 for (ring = 0; ring < adapter->drv_sds_rings; ring++) {
2900 sds_ring = &recv_ctx->sds_rings[ring]; 3024 sds_ring = &recv_ctx->sds_rings[ring];
2901 qlcnic_intr(adapter->irq, sds_ring); 3025 qlcnic_disable_sds_intr(adapter, sds_ring);
3026 napi_schedule(&sds_ring->napi);
3027 }
3028
3029 if (adapter->flags & QLCNIC_MSIX_ENABLED) {
3030 /* Only Multi-Tx queue capable devices need to
3031 * schedule NAPI for TX rings
3032 */
3033 if ((qlcnic_83xx_check(adapter) &&
3034 (adapter->flags & QLCNIC_TX_INTR_SHARED)) ||
3035 (qlcnic_82xx_check(adapter) &&
3036 !qlcnic_check_multi_tx(adapter)))
3037 return;
3038
3039 for (ring = 0; ring < adapter->drv_tx_rings; ring++) {
3040 tx_ring = &adapter->tx_ring[ring];
3041 qlcnic_disable_tx_intr(adapter, tx_ring);
3042 napi_schedule(&tx_ring->napi);
3043 }
2902 } 3044 }
2903 enable_irq(adapter->irq);
2904} 3045}
2905#endif 3046#endif
2906 3047
@@ -3759,7 +3900,7 @@ int qlcnic_validate_rings(struct qlcnic_adapter *adapter, __u32 ring_cnt,
3759 return 0; 3900 return 0;
3760} 3901}
3761 3902
3762int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt) 3903int qlcnic_setup_rings(struct qlcnic_adapter *adapter)
3763{ 3904{
3764 struct net_device *netdev = adapter->netdev; 3905 struct net_device *netdev = adapter->netdev;
3765 int err; 3906 int err;
@@ -3780,12 +3921,6 @@ int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt)
3780 3921
3781 qlcnic_teardown_intr(adapter); 3922 qlcnic_teardown_intr(adapter);
3782 3923
3783 /* compute and set default and max tx/sds rings */
3784 qlcnic_set_tx_ring_count(adapter, tx_cnt);
3785 qlcnic_set_sds_ring_count(adapter, rx_cnt);
3786
3787 netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings);
3788
3789 err = qlcnic_setup_intr(adapter); 3924 err = qlcnic_setup_intr(adapter);
3790 if (err) { 3925 if (err) {
3791 kfree(adapter->msix_entries); 3926 kfree(adapter->msix_entries);
@@ -3793,6 +3928,8 @@ int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt)
3793 return err; 3928 return err;
3794 } 3929 }
3795 3930
3931 netif_set_real_num_tx_queues(netdev, adapter->drv_tx_rings);
3932
3796 if (qlcnic_83xx_check(adapter)) { 3933 if (qlcnic_83xx_check(adapter)) {
3797 qlcnic_83xx_initialize_nic(adapter, 1); 3934 qlcnic_83xx_initialize_nic(adapter, 1);
3798 err = qlcnic_83xx_setup_mbx_intr(adapter); 3935 err = qlcnic_83xx_setup_mbx_intr(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index db819e1b9469..17a1ca2050f4 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -71,6 +71,8 @@ static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
71 .change_l2_filter = qlcnic_83xx_change_l2_filter, 71 .change_l2_filter = qlcnic_83xx_change_l2_filter,
72 .get_board_info = qlcnic_83xx_get_port_info, 72 .get_board_info = qlcnic_83xx_get_port_info,
73 .free_mac_list = qlcnic_sriov_vf_free_mac_list, 73 .free_mac_list = qlcnic_sriov_vf_free_mac_list,
74 .enable_sds_intr = qlcnic_83xx_enable_sds_intr,
75 .disable_sds_intr = qlcnic_83xx_disable_sds_intr,
74}; 76};
75 77
76static struct qlcnic_nic_template qlcnic_sriov_vf_ops = { 78static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {