Commit be273dc1 authored by Himanshu Madhani's avatar Himanshu Madhani Committed by David S. Miller

qlcnic: Enable Interrupt Coalescing for 83xx adapter

Enable Interrupt coalescing through ethtool on 83xx adapter.
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: default avatarShahed Shaikh <shahed.shaikh@qlogic.com>
Signed-off-by: default avatarJitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 52290740
...@@ -347,8 +347,14 @@ struct qlcnic_rx_buffer { ...@@ -347,8 +347,14 @@ struct qlcnic_rx_buffer {
* Interrupt coalescing defaults. The defaults are for 1500 MTU. It is * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
* adjusted based on configured MTU. * adjusted based on configured MTU.
*/ */
#define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US 3 #define QLCNIC_INTR_COAL_TYPE_RX 1
#define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS 256 #define QLCNIC_INTR_COAL_TYPE_TX 2
#define QLCNIC_DEF_INTR_COALESCE_RX_TIME_US 3
#define QLCNIC_DEF_INTR_COALESCE_RX_PACKETS 256
#define QLCNIC_DEF_INTR_COALESCE_TX_TIME_US 64
#define QLCNIC_DEF_INTR_COALESCE_TX_PACKETS 64
#define QLCNIC_INTR_DEFAULT 0x04 #define QLCNIC_INTR_DEFAULT 0x04
#define QLCNIC_CONFIG_INTR_COALESCE 3 #define QLCNIC_CONFIG_INTR_COALESCE 3
...@@ -359,6 +365,8 @@ struct qlcnic_nic_intr_coalesce { ...@@ -359,6 +365,8 @@ struct qlcnic_nic_intr_coalesce {
u8 sts_ring_mask; u8 sts_ring_mask;
u16 rx_packets; u16 rx_packets;
u16 rx_time_us; u16 rx_time_us;
u16 tx_packets;
u16 tx_time_us;
u16 flag; u16 flag;
u32 timer_out; u32 timer_out;
}; };
......
...@@ -1937,7 +1937,7 @@ int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac) ...@@ -1937,7 +1937,7 @@ int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac)
void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
{ {
int err; int err;
u32 temp; u16 temp;
struct qlcnic_cmd_args cmd; struct qlcnic_cmd_args cmd;
struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
...@@ -1945,10 +1945,18 @@ void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) ...@@ -1945,10 +1945,18 @@ void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
return; return;
qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL); qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
cmd.req.arg[1] = 1 | (adapter->recv_ctx->context_id << 16); if (coal->type == QLCNIC_INTR_COAL_TYPE_RX) {
temp = adapter->recv_ctx->context_id;
cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16;
temp = coal->rx_time_us;
cmd.req.arg[2] = coal->rx_packets | temp << 16;
} else if (coal->type == QLCNIC_INTR_COAL_TYPE_TX) {
temp = adapter->tx_ring->ctx_id;
cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16;
temp = coal->tx_time_us;
cmd.req.arg[2] = coal->tx_packets | temp << 16;
}
cmd.req.arg[3] = coal->flag; cmd.req.arg[3] = coal->flag;
temp = coal->rx_time_us << 16;
cmd.req.arg[2] = coal->rx_packets | temp;
err = qlcnic_issue_cmd(adapter, &cmd); err = qlcnic_issue_cmd(adapter, &cmd);
if (err != QLCNIC_RCODE_SUCCESS) if (err != QLCNIC_RCODE_SUCCESS)
dev_info(&adapter->pdev->dev, dev_info(&adapter->pdev->dev,
......
...@@ -1303,6 +1303,9 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, ...@@ -1303,6 +1303,9 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ethcoal) struct ethtool_coalesce *ethcoal)
{ {
struct qlcnic_adapter *adapter = netdev_priv(netdev); struct qlcnic_adapter *adapter = netdev_priv(netdev);
struct qlcnic_nic_intr_coalesce *coal;
u32 rx_coalesce_usecs, rx_max_frames;
u32 tx_coalesce_usecs, tx_max_frames;
if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) if (!test_bit(__QLCNIC_DEV_UP, &adapter->state))
return -EINVAL; return -EINVAL;
...@@ -1313,8 +1316,8 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, ...@@ -1313,8 +1316,8 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
*/ */
if (ethcoal->rx_coalesce_usecs > 0xffff || if (ethcoal->rx_coalesce_usecs > 0xffff ||
ethcoal->rx_max_coalesced_frames > 0xffff || ethcoal->rx_max_coalesced_frames > 0xffff ||
ethcoal->tx_coalesce_usecs || ethcoal->tx_coalesce_usecs > 0xffff ||
ethcoal->tx_max_coalesced_frames || ethcoal->tx_max_coalesced_frames > 0xffff ||
ethcoal->rx_coalesce_usecs_irq || ethcoal->rx_coalesce_usecs_irq ||
ethcoal->rx_max_coalesced_frames_irq || ethcoal->rx_max_coalesced_frames_irq ||
ethcoal->tx_coalesce_usecs_irq || ethcoal->tx_coalesce_usecs_irq ||
...@@ -1334,18 +1337,55 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, ...@@ -1334,18 +1337,55 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
ethcoal->tx_max_coalesced_frames_high) ethcoal->tx_max_coalesced_frames_high)
return -EINVAL; return -EINVAL;
if (!ethcoal->rx_coalesce_usecs || coal = &adapter->ahw->coal;
!ethcoal->rx_max_coalesced_frames) {
adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; if (qlcnic_83xx_check(adapter)) {
adapter->ahw->coal.rx_time_us = if (!ethcoal->tx_coalesce_usecs ||
QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; !ethcoal->tx_max_coalesced_frames ||
adapter->ahw->coal.rx_packets = !ethcoal->rx_coalesce_usecs ||
QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; !ethcoal->rx_max_coalesced_frames) {
coal->flag = QLCNIC_INTR_DEFAULT;
coal->type = QLCNIC_INTR_COAL_TYPE_RX;
coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
coal->tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
coal->tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
} else {
tx_coalesce_usecs = ethcoal->tx_coalesce_usecs;
tx_max_frames = ethcoal->tx_max_coalesced_frames;
rx_coalesce_usecs = ethcoal->rx_coalesce_usecs;
rx_max_frames = ethcoal->rx_max_coalesced_frames;
coal->flag = 0;
if ((coal->rx_time_us == rx_coalesce_usecs) &&
(coal->rx_packets == rx_max_frames)) {
coal->type = QLCNIC_INTR_COAL_TYPE_TX;
coal->tx_time_us = tx_coalesce_usecs;
coal->tx_packets = tx_max_frames;
} else if ((coal->tx_time_us == tx_coalesce_usecs) &&
(coal->tx_packets == tx_max_frames)) {
coal->type = QLCNIC_INTR_COAL_TYPE_RX;
coal->rx_time_us = rx_coalesce_usecs;
coal->rx_packets = rx_max_frames;
} else {
coal->type = QLCNIC_INTR_COAL_TYPE_RX;
coal->rx_time_us = rx_coalesce_usecs;
coal->rx_packets = rx_max_frames;
coal->tx_time_us = tx_coalesce_usecs;
coal->tx_packets = tx_max_frames;
}
}
} else { } else {
adapter->ahw->coal.flag = 0; if (!ethcoal->rx_coalesce_usecs ||
adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs; !ethcoal->rx_max_coalesced_frames) {
adapter->ahw->coal.rx_packets = coal->flag = QLCNIC_INTR_DEFAULT;
ethcoal->rx_max_coalesced_frames; coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
} else {
coal->flag = 0;
coal->rx_time_us = ethcoal->rx_coalesce_usecs;
coal->rx_packets = ethcoal->rx_max_coalesced_frames;
}
} }
qlcnic_config_intr_coalesce(adapter); qlcnic_config_intr_coalesce(adapter);
...@@ -1363,6 +1403,8 @@ static int qlcnic_get_intr_coalesce(struct net_device *netdev, ...@@ -1363,6 +1403,8 @@ static int qlcnic_get_intr_coalesce(struct net_device *netdev,
ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us; ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets; ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us;
ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets;
return 0; return 0;
} }
......
...@@ -1587,7 +1587,9 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings) ...@@ -1587,7 +1587,9 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings)
static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
{ {
struct qlcnic_hardware_context *ahw = adapter->ahw;
int err = 0; int err = 0;
adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
GFP_KERNEL); GFP_KERNEL);
if (!adapter->recv_ctx) { if (!adapter->recv_ctx) {
...@@ -1595,9 +1597,14 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) ...@@ -1595,9 +1597,14 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
goto err_out; goto err_out;
} }
/* Initialize interrupt coalesce parameters */ /* Initialize interrupt coalesce parameters */
adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; ahw->coal.flag = QLCNIC_INTR_DEFAULT;
adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
if (qlcnic_83xx_check(adapter)) {
ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
}
/* clear stats */ /* clear stats */
memset(&adapter->stats, 0, sizeof(adapter->stats)); memset(&adapter->stats, 0, sizeof(adapter->stats));
err_out: err_out:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment