diff options
author | Himanshu Madhani <himanshu.madhani@qlogic.com> | 2013-04-24 08:42:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-04-24 19:34:05 -0400 |
commit | be273dc197eb84304b740db8965a2103005c49ba (patch) | |
tree | ca802219265eabcfea4e42096e8a538d44806000 /drivers/net/ethernet/qlogic/qlcnic | |
parent | 522907403b202dea8528c308ffc21e79d0636ee6 (diff) |
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/net/ethernet/qlogic/qlcnic')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 12 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 68 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 13 |
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 { | |||
347 | * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is | 347 | * Interrupt coalescing defaults. The defaults are for 1500 MTU. It is |
348 | * adjusted based on configured MTU. | 348 | * adjusted based on configured MTU. |
349 | */ | 349 | */ |
350 | #define QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US 3 | 350 | #define QLCNIC_INTR_COAL_TYPE_RX 1 |
351 | #define QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS 256 | 351 | #define QLCNIC_INTR_COAL_TYPE_TX 2 |
352 | |||
353 | #define QLCNIC_DEF_INTR_COALESCE_RX_TIME_US 3 | ||
354 | #define QLCNIC_DEF_INTR_COALESCE_RX_PACKETS 256 | ||
355 | |||
356 | #define QLCNIC_DEF_INTR_COALESCE_TX_TIME_US 64 | ||
357 | #define QLCNIC_DEF_INTR_COALESCE_TX_PACKETS 64 | ||
352 | 358 | ||
353 | #define QLCNIC_INTR_DEFAULT 0x04 | 359 | #define QLCNIC_INTR_DEFAULT 0x04 |
354 | #define QLCNIC_CONFIG_INTR_COALESCE 3 | 360 | #define QLCNIC_CONFIG_INTR_COALESCE 3 |
@@ -359,6 +365,8 @@ struct qlcnic_nic_intr_coalesce { | |||
359 | u8 sts_ring_mask; | 365 | u8 sts_ring_mask; |
360 | u16 rx_packets; | 366 | u16 rx_packets; |
361 | u16 rx_time_us; | 367 | u16 rx_time_us; |
368 | u16 tx_packets; | ||
369 | u16 tx_time_us; | ||
362 | u16 flag; | 370 | u16 flag; |
363 | u32 timer_out; | 371 | u32 timer_out; |
364 | }; | 372 | }; |
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) | |||
1937 | void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) | 1937 | void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) |
1938 | { | 1938 | { |
1939 | int err; | 1939 | int err; |
1940 | u32 temp; | 1940 | u16 temp; |
1941 | struct qlcnic_cmd_args cmd; | 1941 | struct qlcnic_cmd_args cmd; |
1942 | struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; | 1942 | struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal; |
1943 | 1943 | ||
@@ -1945,10 +1945,18 @@ void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) | |||
1945 | return; | 1945 | return; |
1946 | 1946 | ||
1947 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL); | 1947 | qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_INTR_COAL); |
1948 | cmd.req.arg[1] = 1 | (adapter->recv_ctx->context_id << 16); | 1948 | if (coal->type == QLCNIC_INTR_COAL_TYPE_RX) { |
1949 | temp = adapter->recv_ctx->context_id; | ||
1950 | cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_RX | temp << 16; | ||
1951 | temp = coal->rx_time_us; | ||
1952 | cmd.req.arg[2] = coal->rx_packets | temp << 16; | ||
1953 | } else if (coal->type == QLCNIC_INTR_COAL_TYPE_TX) { | ||
1954 | temp = adapter->tx_ring->ctx_id; | ||
1955 | cmd.req.arg[1] = QLCNIC_INTR_COAL_TYPE_TX | temp << 16; | ||
1956 | temp = coal->tx_time_us; | ||
1957 | cmd.req.arg[2] = coal->tx_packets | temp << 16; | ||
1958 | } | ||
1949 | cmd.req.arg[3] = coal->flag; | 1959 | cmd.req.arg[3] = coal->flag; |
1950 | temp = coal->rx_time_us << 16; | ||
1951 | cmd.req.arg[2] = coal->rx_packets | temp; | ||
1952 | err = qlcnic_issue_cmd(adapter, &cmd); | 1960 | err = qlcnic_issue_cmd(adapter, &cmd); |
1953 | if (err != QLCNIC_RCODE_SUCCESS) | 1961 | if (err != QLCNIC_RCODE_SUCCESS) |
1954 | dev_info(&adapter->pdev->dev, | 1962 | 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, | |||
1303 | struct ethtool_coalesce *ethcoal) | 1303 | struct ethtool_coalesce *ethcoal) |
1304 | { | 1304 | { |
1305 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1305 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1306 | struct qlcnic_nic_intr_coalesce *coal; | ||
1307 | u32 rx_coalesce_usecs, rx_max_frames; | ||
1308 | u32 tx_coalesce_usecs, tx_max_frames; | ||
1306 | 1309 | ||
1307 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) | 1310 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) |
1308 | return -EINVAL; | 1311 | return -EINVAL; |
@@ -1313,8 +1316,8 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, | |||
1313 | */ | 1316 | */ |
1314 | if (ethcoal->rx_coalesce_usecs > 0xffff || | 1317 | if (ethcoal->rx_coalesce_usecs > 0xffff || |
1315 | ethcoal->rx_max_coalesced_frames > 0xffff || | 1318 | ethcoal->rx_max_coalesced_frames > 0xffff || |
1316 | ethcoal->tx_coalesce_usecs || | 1319 | ethcoal->tx_coalesce_usecs > 0xffff || |
1317 | ethcoal->tx_max_coalesced_frames || | 1320 | ethcoal->tx_max_coalesced_frames > 0xffff || |
1318 | ethcoal->rx_coalesce_usecs_irq || | 1321 | ethcoal->rx_coalesce_usecs_irq || |
1319 | ethcoal->rx_max_coalesced_frames_irq || | 1322 | ethcoal->rx_max_coalesced_frames_irq || |
1320 | ethcoal->tx_coalesce_usecs_irq || | 1323 | ethcoal->tx_coalesce_usecs_irq || |
@@ -1334,18 +1337,55 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, | |||
1334 | ethcoal->tx_max_coalesced_frames_high) | 1337 | ethcoal->tx_max_coalesced_frames_high) |
1335 | return -EINVAL; | 1338 | return -EINVAL; |
1336 | 1339 | ||
1337 | if (!ethcoal->rx_coalesce_usecs || | 1340 | coal = &adapter->ahw->coal; |
1338 | !ethcoal->rx_max_coalesced_frames) { | 1341 | |
1339 | adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; | 1342 | if (qlcnic_83xx_check(adapter)) { |
1340 | adapter->ahw->coal.rx_time_us = | 1343 | if (!ethcoal->tx_coalesce_usecs || |
1341 | QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; | 1344 | !ethcoal->tx_max_coalesced_frames || |
1342 | adapter->ahw->coal.rx_packets = | 1345 | !ethcoal->rx_coalesce_usecs || |
1343 | QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; | 1346 | !ethcoal->rx_max_coalesced_frames) { |
1347 | coal->flag = QLCNIC_INTR_DEFAULT; | ||
1348 | coal->type = QLCNIC_INTR_COAL_TYPE_RX; | ||
1349 | coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; | ||
1350 | coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; | ||
1351 | coal->tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; | ||
1352 | coal->tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; | ||
1353 | } else { | ||
1354 | tx_coalesce_usecs = ethcoal->tx_coalesce_usecs; | ||
1355 | tx_max_frames = ethcoal->tx_max_coalesced_frames; | ||
1356 | rx_coalesce_usecs = ethcoal->rx_coalesce_usecs; | ||
1357 | rx_max_frames = ethcoal->rx_max_coalesced_frames; | ||
1358 | coal->flag = 0; | ||
1359 | |||
1360 | if ((coal->rx_time_us == rx_coalesce_usecs) && | ||
1361 | (coal->rx_packets == rx_max_frames)) { | ||
1362 | coal->type = QLCNIC_INTR_COAL_TYPE_TX; | ||
1363 | coal->tx_time_us = tx_coalesce_usecs; | ||
1364 | coal->tx_packets = tx_max_frames; | ||
1365 | } else if ((coal->tx_time_us == tx_coalesce_usecs) && | ||
1366 | (coal->tx_packets == tx_max_frames)) { | ||
1367 | coal->type = QLCNIC_INTR_COAL_TYPE_RX; | ||
1368 | coal->rx_time_us = rx_coalesce_usecs; | ||
1369 | coal->rx_packets = rx_max_frames; | ||
1370 | } else { | ||
1371 | coal->type = QLCNIC_INTR_COAL_TYPE_RX; | ||
1372 | coal->rx_time_us = rx_coalesce_usecs; | ||
1373 | coal->rx_packets = rx_max_frames; | ||
1374 | coal->tx_time_us = tx_coalesce_usecs; | ||
1375 | coal->tx_packets = tx_max_frames; | ||
1376 | } | ||
1377 | } | ||
1344 | } else { | 1378 | } else { |
1345 | adapter->ahw->coal.flag = 0; | 1379 | if (!ethcoal->rx_coalesce_usecs || |
1346 | adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs; | 1380 | !ethcoal->rx_max_coalesced_frames) { |
1347 | adapter->ahw->coal.rx_packets = | 1381 | coal->flag = QLCNIC_INTR_DEFAULT; |
1348 | ethcoal->rx_max_coalesced_frames; | 1382 | coal->rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; |
1383 | coal->rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; | ||
1384 | } else { | ||
1385 | coal->flag = 0; | ||
1386 | coal->rx_time_us = ethcoal->rx_coalesce_usecs; | ||
1387 | coal->rx_packets = ethcoal->rx_max_coalesced_frames; | ||
1388 | } | ||
1349 | } | 1389 | } |
1350 | 1390 | ||
1351 | qlcnic_config_intr_coalesce(adapter); | 1391 | qlcnic_config_intr_coalesce(adapter); |
@@ -1363,6 +1403,8 @@ static int qlcnic_get_intr_coalesce(struct net_device *netdev, | |||
1363 | 1403 | ||
1364 | ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us; | 1404 | ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us; |
1365 | ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets; | 1405 | ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets; |
1406 | ethcoal->tx_coalesce_usecs = adapter->ahw->coal.tx_time_us; | ||
1407 | ethcoal->tx_max_coalesced_frames = adapter->ahw->coal.tx_packets; | ||
1366 | 1408 | ||
1367 | return 0; | 1409 | return 0; |
1368 | } | 1410 | } |
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: | |||
1587 | 1587 | ||
1588 | static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) | 1588 | static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) |
1589 | { | 1589 | { |
1590 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
1590 | int err = 0; | 1591 | int err = 0; |
1592 | |||
1591 | adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), | 1593 | adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), |
1592 | GFP_KERNEL); | 1594 | GFP_KERNEL); |
1593 | if (!adapter->recv_ctx) { | 1595 | if (!adapter->recv_ctx) { |
@@ -1595,9 +1597,14 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) | |||
1595 | goto err_out; | 1597 | goto err_out; |
1596 | } | 1598 | } |
1597 | /* Initialize interrupt coalesce parameters */ | 1599 | /* Initialize interrupt coalesce parameters */ |
1598 | adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; | 1600 | ahw->coal.flag = QLCNIC_INTR_DEFAULT; |
1599 | adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; | 1601 | ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; |
1600 | adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; | 1602 | ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; |
1603 | ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; | ||
1604 | if (qlcnic_83xx_check(adapter)) { | ||
1605 | ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; | ||
1606 | ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; | ||
1607 | } | ||
1601 | /* clear stats */ | 1608 | /* clear stats */ |
1602 | memset(&adapter->stats, 0, sizeof(adapter->stats)); | 1609 | memset(&adapter->stats, 0, sizeof(adapter->stats)); |
1603 | err_out: | 1610 | err_out: |