From: Himanshu Madhani Date: Wed, 24 Apr 2013 12:42:42 +0000 (+0000) Subject: qlcnic: Enable Interrupt Coalescing for 83xx adapter X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=be273dc197eb84304b740db8965a2103005c49ba;p=linux-beck.git qlcnic: Enable Interrupt Coalescing for 83xx adapter Enable Interrupt coalescing through ethtool on 83xx adapter. Signed-off-by: Himanshu Madhani Signed-off-by: Shahed Shaikh Signed-off-by: Jitendra Kalsaria Signed-off-by: David S. Miller --- 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: