|
@@ -2102,37 +2102,130 @@ int qlcnic_83xx_get_mac_address(struct qlcnic_adapter *adapter, u8 *mac,
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter)
|
|
|
|
|
|
+static int qlcnic_83xx_set_rx_intr_coal(struct qlcnic_adapter *adapter)
|
|
{
|
|
{
|
|
- int err;
|
|
|
|
- u16 temp;
|
|
|
|
- struct qlcnic_cmd_args cmd;
|
|
|
|
struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
|
|
struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
|
|
|
|
+ struct qlcnic_cmd_args cmd;
|
|
|
|
+ u16 temp;
|
|
|
|
+ int err;
|
|
|
|
|
|
- if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
|
|
|
|
- return;
|
|
|
|
|
|
+ err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+
|
|
|
|
+ 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;
|
|
|
|
+ cmd.req.arg[3] = coal->flag;
|
|
|
|
+
|
|
|
|
+ err = qlcnic_issue_cmd(adapter, &cmd);
|
|
|
|
+ if (err != QLCNIC_RCODE_SUCCESS)
|
|
|
|
+ netdev_err(adapter->netdev,
|
|
|
|
+ "failed to set interrupt coalescing parameters\n");
|
|
|
|
+
|
|
|
|
+ qlcnic_free_mbx_args(&cmd);
|
|
|
|
+
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int qlcnic_83xx_set_tx_intr_coal(struct qlcnic_adapter *adapter)
|
|
|
|
+{
|
|
|
|
+ struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
|
|
|
|
+ struct qlcnic_cmd_args cmd;
|
|
|
|
+ u16 temp;
|
|
|
|
+ int err;
|
|
|
|
|
|
err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
|
|
err = qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL);
|
|
if (err)
|
|
if (err)
|
|
- return;
|
|
|
|
|
|
+ return err;
|
|
|
|
|
|
- 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;
|
|
|
|
- }
|
|
|
|
|
|
+ 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;
|
|
|
|
+
|
|
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,
|
|
|
|
- "Failed to send interrupt coalescence parameters\n");
|
|
|
|
|
|
+ netdev_err(adapter->netdev,
|
|
|
|
+ "failed to set interrupt coalescing parameters\n");
|
|
|
|
+
|
|
qlcnic_free_mbx_args(&cmd);
|
|
qlcnic_free_mbx_args(&cmd);
|
|
|
|
+
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qlcnic_83xx_set_rx_tx_intr_coal(struct qlcnic_adapter *adapter)
|
|
|
|
+{
|
|
|
|
+ int err = 0;
|
|
|
|
+
|
|
|
|
+ err = qlcnic_83xx_set_rx_intr_coal(adapter);
|
|
|
|
+ if (err)
|
|
|
|
+ netdev_err(adapter->netdev,
|
|
|
|
+ "failed to set Rx coalescing parameters\n");
|
|
|
|
+
|
|
|
|
+ err = qlcnic_83xx_set_tx_intr_coal(adapter);
|
|
|
|
+ if (err)
|
|
|
|
+ netdev_err(adapter->netdev,
|
|
|
|
+ "failed to set Tx coalescing parameters\n");
|
|
|
|
+
|
|
|
|
+ return err;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter,
|
|
|
|
+ struct ethtool_coalesce *ethcoal)
|
|
|
|
+{
|
|
|
|
+ struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
|
|
|
|
+ u32 rx_coalesce_usecs, rx_max_frames;
|
|
|
|
+ u32 tx_coalesce_usecs, tx_max_frames;
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
|
|
|
|
+ return -EIO;
|
|
|
|
+
|
|
|
|
+ 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 = QLCNIC_INTR_DEFAULT;
|
|
|
|
+
|
|
|
|
+ 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_TX;
|
|
|
|
+ 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;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ switch (coal->type) {
|
|
|
|
+ case QLCNIC_INTR_COAL_TYPE_RX:
|
|
|
|
+ err = qlcnic_83xx_set_rx_intr_coal(adapter);
|
|
|
|
+ break;
|
|
|
|
+ case QLCNIC_INTR_COAL_TYPE_TX:
|
|
|
|
+ err = qlcnic_83xx_set_tx_intr_coal(adapter);
|
|
|
|
+ break;
|
|
|
|
+ case QLCNIC_INTR_COAL_TYPE_RX_TX:
|
|
|
|
+ err = qlcnic_83xx_set_rx_tx_intr_coal(adapter);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ err = -EINVAL;
|
|
|
|
+ netdev_err(adapter->netdev,
|
|
|
|
+ "Invalid Interrupt coalescing type\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return err;
|
|
}
|
|
}
|
|
|
|
|
|
static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
|
|
static void qlcnic_83xx_handle_link_aen(struct qlcnic_adapter *adapter,
|