diff options
author | David S. Miller <davem@davemloft.net> | 2014-01-23 19:13:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-23 19:13:39 -0500 |
commit | 9fac865db04b4ee39c84fbcb461c38585acaff27 (patch) | |
tree | 960bf3a54564857ad296fe2ed76799b837eef48d | |
parent | 0681a28264dcf948e0236adb7bf505a638c4dec1 (diff) | |
parent | 18cae184e4364b4177561e271a8ca51568e031f0 (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.h | 129 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 235 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 9 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_vnic.c | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 106 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c | 55 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 343 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | 2 |
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 | ||
109 | enum qlcnic_queue_type { | 111 | enum 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); | |||
1573 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *, struct net_device *); | 1580 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *, struct net_device *); |
1574 | void qlcnic_set_tx_ring_count(struct qlcnic_adapter *, u8); | 1581 | void qlcnic_set_tx_ring_count(struct qlcnic_adapter *, u8); |
1575 | void qlcnic_set_sds_ring_count(struct qlcnic_adapter *, u8); | 1582 | void qlcnic_set_sds_ring_count(struct qlcnic_adapter *, u8); |
1576 | int qlcnic_setup_rings(struct qlcnic_adapter *, u8, u8); | 1583 | int qlcnic_setup_rings(struct qlcnic_adapter *); |
1577 | int qlcnic_validate_rings(struct qlcnic_adapter *, __u32, int); | 1584 | int qlcnic_validate_rings(struct qlcnic_adapter *, __u32, int); |
1578 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); | 1585 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); |
1579 | int qlcnic_enable_msix(struct qlcnic_adapter *, u32); | 1586 | int 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 *); |
1614 | void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *, | 1621 | void qlcnic_set_eswitch_port_features(struct qlcnic_adapter *, |
1615 | struct qlcnic_esw_func_cfg *); | 1622 | struct qlcnic_esw_func_cfg *); |
1616 | 1623 | int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *); | |
1617 | void qlcnic_down(struct qlcnic_adapter *, struct net_device *); | 1624 | void qlcnic_down(struct qlcnic_adapter *, struct net_device *); |
1618 | int qlcnic_up(struct qlcnic_adapter *, struct net_device *); | 1625 | int qlcnic_up(struct qlcnic_adapter *, struct net_device *); |
1619 | void __qlcnic_down(struct qlcnic_adapter *, struct net_device *); | 1626 | void __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 | ||
1761 | extern struct qlcnic_nic_template qlcnic_vf_ops; | 1774 | extern 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 | ||
1931 | static inline void qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) | 1944 | static 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 | ||
1936 | static inline int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) | 1950 | static 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 | ||
2046 | static inline void | ||
2047 | qlcnic_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 | |||
2055 | static inline void | ||
2056 | qlcnic_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 | |||
2064 | static inline void | ||
2065 | qlcnic_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 | |||
2071 | static inline void | ||
2072 | qlcnic_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 */ | ||
2079 | static inline void | ||
2080 | qlcnic_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 */ | ||
2087 | static inline void | ||
2088 | qlcnic_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 | |||
2032 | static inline void qlcnic_disable_multi_tx(struct qlcnic_adapter *adapter) | 2094 | static 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 | */ |
2041 | static inline void qlcnic_disable_int(struct qlcnic_host_sds_ring *sds_ring) | 2103 | static inline void |
2104 | qlcnic_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 | ||
2115 | static 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 | |||
2122 | static inline void | ||
2123 | qlcnic_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 | |||
2130 | static 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 | |||
2137 | static 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 | */ |
2056 | static inline void qlcnic_enable_int(struct qlcnic_host_sds_ring *sds_ring) | 2147 | static inline void |
2148 | qlcnic_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 | ||
204 | static struct qlcnic_nic_template qlcnic_83xx_ops = { | 209 | static 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 | ||
288 | int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter) | 293 | static 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 | |||
305 | static 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) | 320 | int 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 */ | ||
349 | void 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 */ | ||
356 | void 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 | |||
362 | static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter | 379 | static 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 | ||
497 | done: | 514 | done: |
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); | ||
1312 | out: | 1330 | out: |
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 | ||
2114 | void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) | 2132 | static 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 | |||
2159 | static 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 | |||
2186 | int 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 | |||
2203 | int 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 | ||
2147 | static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter, | 2258 | static 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); | |||
547 | int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32); | 547 | int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *, u32); |
548 | int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *, int); | 548 | int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *, int); |
549 | int qlcnic_83xx_config_rss(struct qlcnic_adapter *, int); | 549 | int qlcnic_83xx_config_rss(struct qlcnic_adapter *, int); |
550 | int qlcnic_83xx_config_intr_coalesce(struct qlcnic_adapter *); | ||
551 | void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16); | 550 | void qlcnic_83xx_change_l2_filter(struct qlcnic_adapter *, u64 *, u16); |
552 | int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *); | 551 | int qlcnic_83xx_get_pci_info(struct qlcnic_adapter *, struct qlcnic_pci_info *); |
553 | int qlcnic_83xx_set_nic_info(struct qlcnic_adapter *, struct qlcnic_info *); | 552 | int 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 *, | |||
577 | void qlcnic_free_mbx_args(struct qlcnic_cmd_args *); | 576 | void qlcnic_free_mbx_args(struct qlcnic_cmd_args *); |
578 | void qlcnic_set_npar_data(struct qlcnic_adapter *, const struct qlcnic_info *, | 577 | void qlcnic_set_npar_data(struct qlcnic_adapter *, const struct qlcnic_info *, |
579 | struct qlcnic_info *); | 578 | struct qlcnic_info *); |
580 | void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *); | 579 | int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *, |
580 | struct ethtool_coalesce *); | ||
581 | int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *); | ||
581 | int qlcnic_83xx_get_port_info(struct qlcnic_adapter *); | 582 | int qlcnic_83xx_get_port_info(struct qlcnic_adapter *); |
582 | void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *); | 583 | void qlcnic_83xx_enable_mbx_interrupt(struct qlcnic_adapter *); |
583 | void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *); | 584 | void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *); |
584 | irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *); | 585 | irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *); |
585 | irqreturn_t qlcnic_83xx_intr(int, void *); | 586 | irqreturn_t qlcnic_83xx_intr(int, void *); |
586 | irqreturn_t qlcnic_83xx_tmp_intr(int, void *); | 587 | irqreturn_t qlcnic_83xx_tmp_intr(int, void *); |
587 | void qlcnic_83xx_enable_intr(struct qlcnic_adapter *, | ||
588 | struct qlcnic_host_sds_ring *); | ||
589 | void qlcnic_83xx_disable_intr(struct qlcnic_adapter *, | ||
590 | struct qlcnic_host_sds_ring *); | ||
591 | void qlcnic_83xx_check_vf(struct qlcnic_adapter *, | 588 | void qlcnic_83xx_check_vf(struct qlcnic_adapter *, |
592 | const struct pci_device_id *); | 589 | const struct pci_device_id *); |
593 | int qlcnic_83xx_config_default_opmode(struct qlcnic_adapter *); | 590 | int 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 | ||
1588 | static int qlcnic_get_intr_coalesce(struct net_device *netdev, | 1538 | static 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 | /* | 758 | int qlcnic_82xx_set_rx_coalesce(struct qlcnic_adapter *adapter) |
759 | * Send the interrupt coalescing parameter set by ethtool to the card. | ||
760 | */ | ||
761 | void 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. */ | ||
785 | int 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, | |||
171 | void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *); | 171 | void qlcnic_82xx_get_beacon_state(struct qlcnic_adapter *); |
172 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, | 172 | void qlcnic_82xx_change_filter(struct qlcnic_adapter *adapter, |
173 | u64 *uaddr, u16 vlan_id); | 173 | u64 *uaddr, u16 vlan_id); |
174 | void qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *adapter); | 174 | int qlcnic_82xx_config_intr_coalesce(struct qlcnic_adapter *, |
175 | struct ethtool_coalesce *); | ||
176 | int qlcnic_82xx_set_rx_coalesce(struct qlcnic_adapter *); | ||
175 | int qlcnic_82xx_config_rss(struct qlcnic_adapter *adapter, int); | 177 | int qlcnic_82xx_config_rss(struct qlcnic_adapter *adapter, int); |
176 | void qlcnic_82xx_config_ipaddr(struct qlcnic_adapter *adapter, | 178 | void 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 | ||
134 | static 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 | |||
143 | static 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 | |||
151 | static 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 | |||
157 | static 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 | |||
163 | static inline u8 qlcnic_mac_hash(u64 mac, u16 vlan) | 134 | static 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 | ||
562 | static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter) | 566 | static 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 | ||
607 | void qlcnic_set_sds_ring_count(struct qlcnic_adapter *adapter, u8 rx_cnt) | 608 | void 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 | ||
620 | int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix) | 618 | int 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 | |||
646 | restore: | ||
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 | |||
684 | int 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: | 700 | enable_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 | ||
753 | static 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 | |||
701 | static int qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter) | 767 | static 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 | ||
1770 | static 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 | |||
1700 | int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) | 1797 | int __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 | ||
1898 | static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) | 1995 | static 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)); |
1920 | err_out: | 2008 | err_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 | ||
2750 | static void qlcnic_tx_timeout(struct net_device *netdev) | 2838 | static 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 | |||
2852 | static 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 | |||
2886 | static 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 | ||
2843 | done: | 2962 | done: |
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 |
2891 | static void qlcnic_poll_controller(struct net_device *netdev) | 3010 | static 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 | ||
3762 | int qlcnic_setup_rings(struct qlcnic_adapter *adapter, u8 rx_cnt, u8 tx_cnt) | 3903 | int 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 | ||
76 | static struct qlcnic_nic_template qlcnic_sriov_vf_ops = { | 78 | static struct qlcnic_nic_template qlcnic_sriov_vf_ops = { |