aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHimanshu Madhani <himanshu.madhani@qlogic.com>2014-01-23 17:18:32 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-23 19:13:09 -0500
commita514722afebc59cf9d98387ee4db81ee62154df0 (patch)
treef519b29bfdd77f7601873d8cb64d5b4f01460cc0
parent2b018ad9fe26de71c56c9cfdec164cdf89cb6a1a (diff)
qlcnic: Refactor interrupt coalescing code for all adapters.
o Refactor configuration of interrupt coalescing parameters for all supported adapters. Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h9
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c133
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h5
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c99
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c27
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.h4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c40
7 files changed, 200 insertions, 117 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 26b53b5543ca..eb6df4ae3c35 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -369,6 +369,7 @@ struct qlcnic_rx_buffer {
369 */ 369 */
370#define QLCNIC_INTR_COAL_TYPE_RX 1 370#define QLCNIC_INTR_COAL_TYPE_RX 1
371#define QLCNIC_INTR_COAL_TYPE_TX 2 371#define QLCNIC_INTR_COAL_TYPE_TX 2
372#define QLCNIC_INTR_COAL_TYPE_RX_TX 3
372 373
373#define QLCNIC_DEF_INTR_COALESCE_RX_TIME_US 3 374#define QLCNIC_DEF_INTR_COALESCE_RX_TIME_US 3
374#define QLCNIC_DEF_INTR_COALESCE_RX_PACKETS 256 375#define QLCNIC_DEF_INTR_COALESCE_RX_PACKETS 256
@@ -1740,7 +1741,8 @@ struct qlcnic_hardware_ops {
1740 int (*change_macvlan) (struct qlcnic_adapter *, u8*, u16, u8); 1741 int (*change_macvlan) (struct qlcnic_adapter *, u8*, u16, u8);
1741 void (*napi_enable) (struct qlcnic_adapter *); 1742 void (*napi_enable) (struct qlcnic_adapter *);
1742 void (*napi_disable) (struct qlcnic_adapter *); 1743 void (*napi_disable) (struct qlcnic_adapter *);
1743 void (*config_intr_coal) (struct qlcnic_adapter *); 1744 int (*config_intr_coal) (struct qlcnic_adapter *,
1745 struct ethtool_coalesce *);
1744 int (*config_rss) (struct qlcnic_adapter *, int); 1746 int (*config_rss) (struct qlcnic_adapter *, int);
1745 int (*config_hw_lro) (struct qlcnic_adapter *, int); 1747 int (*config_hw_lro) (struct qlcnic_adapter *, int);
1746 int (*config_loopback) (struct qlcnic_adapter *, u8); 1748 int (*config_loopback) (struct qlcnic_adapter *, u8);
@@ -1936,9 +1938,10 @@ static inline void qlcnic_napi_disable(struct qlcnic_adapter *adapter)
1936 adapter->ahw->hw_ops->napi_disable(adapter); 1938 adapter->ahw->hw_ops->napi_disable(adapter);
1937} 1939}
1938 1940
1939static inline void qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter) 1941static inline int qlcnic_config_intr_coalesce(struct qlcnic_adapter *adapter,
1942 struct ethtool_coalesce *ethcoal)
1940{ 1943{
1941 adapter->ahw->hw_ops->config_intr_coal(adapter); 1944 return adapter->ahw->hw_ops->config_intr_coal(adapter, ethcoal);
1942} 1945}
1943 1946
1944static inline int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable) 1947static inline int qlcnic_config_rss(struct qlcnic_adapter *adapter, int enable)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index f4e267197aa1..f320eb819335 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -2102,37 +2102,130 @@ int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
2102 return err; 2102 return err;
2103} 2103}
2104 2104
2105void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) 2105static int qlcnic_83xx_set_rx_intr_coal(struct qlcnic_adapter *adapter)
2106{ 2106{
2107 int err;
2108 u16 temp;
2109 struct qlcnic_cmd_args cmd;
2110 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; 2107 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2108 struct qlcnic_cmd_args cmd;
2109 u16 temp;
2110 int err;
2111 2111
2112 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED) 2112 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2113 return; 2113 if (err)
2114 return err;
2115
2116 temp = adapter->recv_ctx->context_id;
2117 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
2118 temp = coal->rx_time_us;
2119 cmd.req.arg[2] = coal->rx_packets | temp << 16;
2120 cmd.req.arg[3] = coal->flag;
2121
2122 err = qlcnic_issue_cmd(adapter, &cmd);
2123 if (err != QLCNIC_RCODE_SUCCESS)
2124 netdev_err(adapter->netdev,
2125 "failed to set interrupt coalescing parameters\n");
2126
2127 qlcnic_free_mbx_args(&cmd);
2128
2129 return err;
2130}
2131
2132static int qlcnic_83xx_set_tx_intr_coal(struct qlcnic_adapter *adapter)
2133{
2134 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2135 struct qlcnic_cmd_args cmd;
2136 u16 temp;
2137 int err;
2114 2138
2115 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL); 2139 err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
2116 if (err) 2140 if (err)
2117 return; 2141 return err;
2118 2142
2119 if (coal->type == QLCNIC_INTR_COAL_TYPE_RX) { 2143 temp = adapter->tx_ring->ctx_id;
2120 temp = adapter->recv_ctx->context_id; 2144 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2121 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16; 2145 temp = coal->tx_time_us;
2122 temp = coal->rx_time_us; 2146 cmd.req.arg[2] = coal->tx_packets | temp << 16;
2123 cmd.req.arg[2] = coal->rx_packets | temp << 16;
2124 } else if (coal->type == QLCNIC_INTR_COAL_TYPE_TX) {
2125 temp = adapter->tx_ring->ctx_id;
2126 cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
2127 temp = coal->tx_time_us;
2128 cmd.req.arg[2] = coal->tx_packets | temp << 16;
2129 }
2130 cmd.req.arg[3] = coal->flag; 2147 cmd.req.arg[3] = coal->flag;
2148
2131 err = qlcnic_issue_cmd(adapter, &cmd); 2149 err = qlcnic_issue_cmd(adapter, &cmd);
2132 if (err != QLCNIC_RCODE_SUCCESS) 2150 if (err != QLCNIC_RCODE_SUCCESS)
2133 dev_info(&adapter->pdev->dev, 2151 netdev_err(adapter->netdev,
2134 "Failed to send interrupt coalescence parameters\n"); 2152 "failed to set interrupt coalescing parameters\n");
2153
2135 qlcnic_free_mbx_args(&cmd); 2154 qlcnic_free_mbx_args(&cmd);
2155
2156 return err;
2157}
2158
2159int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *adapter)
2160{
2161 int err = 0;
2162
2163 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2164 if (err)
2165 netdev_err(adapter->netdev,
2166 "failed to set Rx coalescing parameters\n");
2167
2168 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2169 if (err)
2170 netdev_err(adapter->netdev,
2171 "failed to set Tx coalescing parameters\n");
2172
2173 return err;
2174}
2175
2176int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter,
2177 struct ethtool_coalesce *ethcoal)
2178{
2179 struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
2180 u32 rx_coalesce_usecs, rx_max_frames;
2181 u32 tx_coalesce_usecs, tx_max_frames;
2182 int err;
2183
2184 if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
2185 return -EIO;
2186
2187 tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
2188 tx_max_frames = ethcoal->tx_max_coalesced_frames;
2189 rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
2190 rx_max_frames = ethcoal->rx_max_coalesced_frames;
2191 coal->flag = QLCNIC_INTR_DEFAULT;
2192
2193 if ((coal->rx_time_us == rx_coalesce_usecs) &&
2194 (coal->rx_packets == rx_max_frames)) {
2195 coal->type = QLCNIC_INTR_COAL_TYPE_TX;
2196 coal->tx_time_us = tx_coalesce_usecs;
2197 coal->tx_packets = tx_max_frames;
2198 } else if ((coal->tx_time_us == tx_coalesce_usecs) &&
2199 (coal->tx_packets == tx_max_frames)) {
2200 coal->type = QLCNIC_INTR_COAL_TYPE_RX;
2201 coal->rx_time_us = rx_coalesce_usecs;
2202 coal->rx_packets = rx_max_frames;
2203 } else {
2204 coal->type = QLCNIC_INTR_COAL_TYPE_RX_TX;
2205 coal->rx_time_us = rx_coalesce_usecs;
2206 coal->rx_packets = rx_max_frames;
2207 coal->tx_time_us = tx_coalesce_usecs;
2208 coal->tx_packets = tx_max_frames;
2209 }
2210
2211 switch (coal->type) {
2212 case QLCNIC_INTR_COAL_TYPE_RX:
2213 err = qlcnic_83xx_set_rx_intr_coal(adapter);
2214 break;
2215 case QLCNIC_INTR_COAL_TYPE_TX:
2216 err = qlcnic_83xx_set_tx_intr_coal(adapter);
2217 break;
2218 case QLCNIC_INTR_COAL_TYPE_RX_TX:
2219 err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
2220 break;
2221 default:
2222 err = -EINVAL;
2223 netdev_err(adapter->netdev,
2224 "Invalid Interrupt coalescing type\n");
2225 break;
2226 }
2227
2228 return err;
2136} 2229}
2137 2230
2138static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter, 2231static 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 220166f8f27d..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,7 +576,9 @@ 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 *);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 45961e310194..6d0f518d7bc6 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1495,9 +1495,7 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1495 struct ethtool_coalesce *ethcoal) 1495 struct ethtool_coalesce *ethcoal)
1496{ 1496{
1497 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1497 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1498 struct qlcnic_nic_intr_coalesce *coal; 1498 int err;
1499 u32 rx_coalesce_usecs, rx_max_frames;
1500 u32 tx_coalesce_usecs, tx_max_frames;
1501 1499
1502 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) 1500 if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
1503 return -EINVAL; 1501 return -EINVAL;
@@ -1507,82 +1505,31 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
1507 * unsupported parameters are set. 1505 * unsupported parameters are set.
1508 */ 1506 */
1509 if (ethcoal->rx_coalesce_usecs > 0xffff || 1507 if (ethcoal->rx_coalesce_usecs > 0xffff ||
1510 ethcoal->rx_max_coalesced_frames > 0xffff || 1508 ethcoal->rx_max_coalesced_frames > 0xffff ||
1511 ethcoal->tx_coalesce_usecs > 0xffff || 1509 ethcoal->tx_coalesce_usecs > 0xffff ||
1512 ethcoal->tx_max_coalesced_frames > 0xffff || 1510 ethcoal->tx_max_coalesced_frames > 0xffff ||
1513 ethcoal->rx_coalesce_usecs_irq || 1511 ethcoal->rx_coalesce_usecs_irq ||
1514 ethcoal->rx_max_coalesced_frames_irq || 1512 ethcoal->rx_max_coalesced_frames_irq ||
1515 ethcoal->tx_coalesce_usecs_irq || 1513 ethcoal->tx_coalesce_usecs_irq ||
1516 ethcoal->tx_max_coalesced_frames_irq || 1514 ethcoal->tx_max_coalesced_frames_irq ||
1517 ethcoal->stats_block_coalesce_usecs || 1515 ethcoal->stats_block_coalesce_usecs ||
1518 ethcoal->use_adaptive_rx_coalesce || 1516 ethcoal->use_adaptive_rx_coalesce ||
1519 ethcoal->use_adaptive_tx_coalesce || 1517 ethcoal->use_adaptive_tx_coalesce ||
1520 ethcoal->pkt_rate_low || 1518 ethcoal->pkt_rate_low ||
1521 ethcoal->rx_coalesce_usecs_low || 1519 ethcoal->rx_coalesce_usecs_low ||
1522 ethcoal->rx_max_coalesced_frames_low || 1520 ethcoal->rx_max_coalesced_frames_low ||
1523 ethcoal->tx_coalesce_usecs_low || 1521 ethcoal->tx_coalesce_usecs_low ||
1524 ethcoal->tx_max_coalesced_frames_low || 1522 ethcoal->tx_max_coalesced_frames_low ||
1525 ethcoal->pkt_rate_high || 1523 ethcoal->pkt_rate_high ||
1526 ethcoal->rx_coalesce_usecs_high || 1524 ethcoal->rx_coalesce_usecs_high ||
1527 ethcoal->rx_max_coalesced_frames_high || 1525 ethcoal->rx_max_coalesced_frames_high ||
1528 ethcoal->tx_coalesce_usecs_high || 1526 ethcoal->tx_coalesce_usecs_high ||
1529 ethcoal->tx_max_coalesced_frames_high) 1527 ethcoal->tx_max_coalesced_frames_high)
1530 return -EINVAL; 1528 return -EINVAL;
1531 1529
1532 coal = &adapter->ahw->coal; 1530 err = qlcnic_config_intr_coalesce(adapter, ethcoal);
1533 1531
1534 if (qlcnic_83xx_check(adapter)) { 1532 return err;
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
1585 return 0;
1586} 1533}
1587 1534
1588static int qlcnic_get_intr_coalesce(struct net_device *netdev, 1535static 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 d012e834636e..03d18a0be6ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -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_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 0cfa8a3344ac..68f792a62296 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1701,6 +1701,33 @@ static void qlcnic_get_lro_mss_capability(struct qlcnic_adapter *adapter)
1701 } 1701 }
1702} 1702}
1703 1703
1704static int qlcnic_config_def_intr_coalesce(struct qlcnic_adapter *adapter)
1705{
1706 struct qlcnic_hardware_context *ahw = adapter->ahw;
1707 int err;
1708
1709 /* Initialize interrupt coalesce parameters */
1710 ahw->coal.flag = QLCNIC_INTR_DEFAULT;
1711
1712 if (qlcnic_83xx_check(adapter)) {
1713 ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX;
1714 ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
1715 ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
1716 ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1717 ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1718
1719 err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
1720 } else {
1721 ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
1722 ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1723 ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1724
1725 err = qlcnic_82xx_set_rx_coalesce(adapter);
1726 }
1727
1728 return err;
1729}
1730
1704int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev) 1731int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
1705{ 1732{
1706 int ring; 1733 int ring;
@@ -1733,7 +1760,7 @@ int __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
1733 if (adapter->drv_sds_rings > 1) 1760 if (adapter->drv_sds_rings > 1)
1734 qlcnic_config_rss(adapter, 1); 1761 qlcnic_config_rss(adapter, 1);
1735 1762
1736 qlcnic_config_intr_coalesce(adapter); 1763 qlcnic_config_def_intr_coalesce(adapter);
1737 1764
1738 if (netdev->features & NETIF_F_LRO) 1765 if (netdev->features & NETIF_F_LRO)
1739 qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED); 1766 qlcnic_config_hw_lro(adapter, QLCNIC_LRO_ENABLED);
@@ -1901,7 +1928,6 @@ out:
1901 1928
1902static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) 1929static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
1903{ 1930{
1904 struct qlcnic_hardware_context *ahw = adapter->ahw;
1905 int err = 0; 1931 int err = 0;
1906 1932
1907 adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), 1933 adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
@@ -1910,15 +1936,7 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
1910 err = -ENOMEM; 1936 err = -ENOMEM;
1911 goto err_out; 1937 goto err_out;
1912 } 1938 }
1913 /* Initialize interrupt coalesce parameters */ 1939
1914 ahw->coal.flag = QLCNIC_INTR_DEFAULT;
1915 ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
1916 ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
1917 ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
1918 if (qlcnic_83xx_check(adapter)) {
1919 ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
1920 ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
1921 }
1922 /* clear stats */ 1940 /* clear stats */
1923 memset(&adapter->stats, 0, sizeof(adapter->stats)); 1941 memset(&adapter->stats, 0, sizeof(adapter->stats));
1924err_out: 1942err_out: