aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHimanshu Madhani <himanshu.madhani@qlogic.com>2013-04-24 12:42:42 +0000
committerDavid S. Miller <davem@davemloft.net>2013-04-24 19:34:05 -0400
commitbe273dc197eb84304b740db8965a2103005c49ba (patch)
treeca802219265eabcfea4e42096e8a538d44806000 /drivers
parentqlcnic: Add eSwitch statistics support (diff)
downloadlinux-dev-be273dc197eb84304b740db8965a2103005c49ba.tar.xz
linux-dev-be273dc197eb84304b740db8965a2103005c49ba.zip
qlcnic: Enable Interrupt Coalescing for 83xx adapter
Enable Interrupt coalescing through ethtool on 83xx adapter. Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Signed-off-by: Shahed Shaikh <shahed.shaikh@qlogic.com> Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h12
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c16
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c68
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c13
4 files changed, 87 insertions, 22 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index f699ccee65dc..767c683a4870 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -347,8 +347,14 @@ struct qlcnic_rx_buffer {
* Interrupt coalescing defaults. The defaults are for 1500 MTU. It is
* adjusted based on configured MTU.
*/
-#define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US 3
-#define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS 256
+#define QLCNIC_INTR_COAL_TYPE_RX 1
+#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_CONFIG_INTR_COALESCE 3
@@ -359,6 +365,8 @@ struct qlcnic_nic_intr_coalesce {
u8 sts_ring_mask;
u16 rx_packets;
u16 rx_time_us;
+ u16 tx_packets;
+ u16 tx_time_us;
u16 flag;
u32 timer_out;
};
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index c40b077d43da..ea790a93ee7c 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -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)
{
int err;
- u32 temp;
+ u16 temp;
struct qlcnic_cmd_args cmd;
struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
@@ -1945,10 +1945,18 @@ void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
return;
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;
- temp = coal->rx_time_us << 16;
- cmd.req.arg[2] = coal->rx_packets | temp;
err = qlcnic_issue_cmd(adapter, &cmd);
if (err != QLCNIC_RCODE_SUCCESS)
dev_info(&adapter->pdev->dev,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
index 629d901637e1..08efb4635007 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c
@@ -1303,6 +1303,9 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
struct ethtool_coalesce *ethcoal)
{
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))
return -EINVAL;
@@ -1313,8 +1316,8 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
*/
if (ethcoal->rx_coalesce_usecs > 0xffff ||
ethcoal->rx_max_coalesced_frames > 0xffff ||
- ethcoal->tx_coalesce_usecs ||
- ethcoal->tx_max_coalesced_frames ||
+ ethcoal->tx_coalesce_usecs > 0xffff ||
+ ethcoal->tx_max_coalesced_frames > 0xffff ||
ethcoal->rx_coalesce_usecs_irq ||
ethcoal->rx_max_coalesced_frames_irq ||
ethcoal->tx_coalesce_usecs_irq ||
@@ -1334,18 +1337,55 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev,
ethcoal->tx_max_coalesced_frames_high)
return -EINVAL;
- if (!ethcoal->rx_coalesce_usecs ||
- !ethcoal->rx_max_coalesced_frames) {
- adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
- adapter->ahw->coal.rx_time_us =
- QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
- adapter->ahw->coal.rx_packets =
- QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
+ coal = &adapter->ahw->coal;
+
+ if (qlcnic_83xx_check(adapter)) {
+ if (!ethcoal->tx_coalesce_usecs ||
+ !ethcoal->tx_max_coalesced_frames ||
+ !ethcoal->rx_coalesce_usecs ||
+ !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 {
- adapter->ahw->coal.flag = 0;
- adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs;
- adapter->ahw->coal.rx_packets =
- ethcoal->rx_max_coalesced_frames;
+ if (!ethcoal->rx_coalesce_usecs ||
+ !ethcoal->rx_max_coalesced_frames) {
+ coal->flag = QLCNIC_INTR_DEFAULT;
+ 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);
@@ -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_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;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 0052953a255d..4e0bcb17e209 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1587,7 +1587,9 @@ out:
static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
{
+ struct qlcnic_hardware_context *ahw = adapter->ahw;
int err = 0;
+
adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
GFP_KERNEL);
if (!adapter->recv_ctx) {
@@ -1595,9 +1597,14 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
goto err_out;
}
/* Initialize interrupt coalesce parameters */
- adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
- adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
- adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
+ ahw->coal.flag = QLCNIC_INTR_DEFAULT;
+ ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
+ 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 */
memset(&adapter->stats, 0, sizeof(adapter->stats));
err_out: