diff options
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 22 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c | 19 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | 25 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 77 | ||||
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 193 |
6 files changed, 277 insertions, 61 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 8d02dd75c9a2..90c253b145ef 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | |||
@@ -38,8 +38,8 @@ | |||
38 | 38 | ||
39 | #define _QLCNIC_LINUX_MAJOR 5 | 39 | #define _QLCNIC_LINUX_MAJOR 5 |
40 | #define _QLCNIC_LINUX_MINOR 2 | 40 | #define _QLCNIC_LINUX_MINOR 2 |
41 | #define _QLCNIC_LINUX_SUBVERSION 41 | 41 | #define _QLCNIC_LINUX_SUBVERSION 42 |
42 | #define QLCNIC_LINUX_VERSIONID "5.2.41" | 42 | #define QLCNIC_LINUX_VERSIONID "5.2.42" |
43 | #define QLCNIC_DRV_IDC_VER 0x01 | 43 | #define QLCNIC_DRV_IDC_VER 0x01 |
44 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ | 44 | #define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\ |
45 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) | 45 | (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION)) |
@@ -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 | }; |
@@ -511,13 +519,13 @@ struct qlcnic_host_sds_ring { | |||
511 | int irq; | 519 | int irq; |
512 | 520 | ||
513 | dma_addr_t phys_addr; | 521 | dma_addr_t phys_addr; |
514 | char name[IFNAMSIZ+4]; | 522 | char name[IFNAMSIZ + 12]; |
515 | } ____cacheline_internodealigned_in_smp; | 523 | } ____cacheline_internodealigned_in_smp; |
516 | 524 | ||
517 | struct qlcnic_host_tx_ring { | 525 | struct qlcnic_host_tx_ring { |
518 | int irq; | 526 | int irq; |
519 | void __iomem *crb_intr_mask; | 527 | void __iomem *crb_intr_mask; |
520 | char name[IFNAMSIZ+4]; | 528 | char name[IFNAMSIZ + 12]; |
521 | u16 ctx_id; | 529 | u16 ctx_id; |
522 | u32 producer; | 530 | u32 producer; |
523 | u32 sw_consumer; | 531 | u32 sw_consumer; |
@@ -1474,7 +1482,7 @@ void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings); | |||
1474 | int qlcnic_diag_alloc_res(struct net_device *netdev, int test); | 1482 | int qlcnic_diag_alloc_res(struct net_device *netdev, int test); |
1475 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); | 1483 | netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); |
1476 | int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, size_t); | 1484 | int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, size_t); |
1477 | int qlcnic_validate_max_rss(u8, u8); | 1485 | int qlcnic_validate_max_rss(struct qlcnic_adapter *, __u32); |
1478 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); | 1486 | void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); |
1479 | int qlcnic_enable_msix(struct qlcnic_adapter *, u32); | 1487 | int qlcnic_enable_msix(struct qlcnic_adapter *, u32); |
1480 | 1488 | ||
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index fd0829c2839d..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, |
@@ -2922,6 +2930,9 @@ static u64 *qlcnic_83xx_fill_stats(struct qlcnic_adapter *adapter, | |||
2922 | /* fill in MAC rx frame stats */ | 2930 | /* fill in MAC rx frame stats */ |
2923 | for (k += 6; k < 80; k += 2) | 2931 | for (k += 6; k < 80; k += 2) |
2924 | data = qlcnic_83xx_copy_stats(cmd, data, k); | 2932 | data = qlcnic_83xx_copy_stats(cmd, data, k); |
2933 | /* fill in eSwitch stats */ | ||
2934 | for (; k < total_regs; k += 2) | ||
2935 | data = qlcnic_83xx_copy_stats(cmd, data, k); | ||
2925 | break; | 2936 | break; |
2926 | case QLC_83XX_STAT_RX: | 2937 | case QLC_83XX_STAT_RX: |
2927 | for (k = 2; k < 8; k += 2) | 2938 | for (k = 2; k < 8; k += 2) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h index 4be411c2628a..1f1d85e6f2af 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h | |||
@@ -381,7 +381,7 @@ enum qlcnic_83xx_states { | |||
381 | #define QLC_83XX_STAT_MAC 1 | 381 | #define QLC_83XX_STAT_MAC 1 |
382 | #define QLC_83XX_TX_STAT_REGS 14 | 382 | #define QLC_83XX_TX_STAT_REGS 14 |
383 | #define QLC_83XX_RX_STAT_REGS 40 | 383 | #define QLC_83XX_RX_STAT_REGS 40 |
384 | #define QLC_83XX_MAC_STAT_REGS 80 | 384 | #define QLC_83XX_MAC_STAT_REGS 94 |
385 | 385 | ||
386 | #define QLC_83XX_GET_FUNC_PRIVILEGE(VAL, FN) (0x3 & ((VAL) >> (FN * 2))) | 386 | #define QLC_83XX_GET_FUNC_PRIVILEGE(VAL, FN) (0x3 & ((VAL) >> (FN * 2))) |
387 | #define QLC_83XX_SET_FUNC_OPMODE(VAL, FN) ((VAL) << (FN * 2)) | 387 | #define QLC_83XX_SET_FUNC_OPMODE(VAL, FN) ((VAL) << (FN * 2)) |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c index 6ea3a096054c..ab1d8d99cbd5 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c | |||
@@ -25,6 +25,17 @@ | |||
25 | #define QLC_83XX_OPCODE_TMPL_END 0x0080 | 25 | #define QLC_83XX_OPCODE_TMPL_END 0x0080 |
26 | #define QLC_83XX_OPCODE_POLL_READ_LIST 0x0100 | 26 | #define QLC_83XX_OPCODE_POLL_READ_LIST 0x0100 |
27 | 27 | ||
28 | /* EPORT control registers */ | ||
29 | #define QLC_83XX_RESET_CONTROL 0x28084E50 | ||
30 | #define QLC_83XX_RESET_REG 0x28084E60 | ||
31 | #define QLC_83XX_RESET_PORT0 0x28084E70 | ||
32 | #define QLC_83XX_RESET_PORT1 0x28084E80 | ||
33 | #define QLC_83XX_RESET_PORT2 0x28084E90 | ||
34 | #define QLC_83XX_RESET_PORT3 0x28084EA0 | ||
35 | #define QLC_83XX_RESET_SRESHIM 0x28084EB0 | ||
36 | #define QLC_83XX_RESET_EPGSHIM 0x28084EC0 | ||
37 | #define QLC_83XX_RESET_ETHERPCS 0x28084ED0 | ||
38 | |||
28 | static int qlcnic_83xx_init_default_driver(struct qlcnic_adapter *adapter); | 39 | static int qlcnic_83xx_init_default_driver(struct qlcnic_adapter *adapter); |
29 | static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev); | 40 | static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev); |
30 | static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter); | 41 | static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter); |
@@ -1374,6 +1385,19 @@ static void qlcnic_83xx_disable_pause_frames(struct qlcnic_adapter *adapter) | |||
1374 | qlcnic_83xx_unlock_driver(adapter); | 1385 | qlcnic_83xx_unlock_driver(adapter); |
1375 | } | 1386 | } |
1376 | 1387 | ||
1388 | static void qlcnic_83xx_take_eport_out_of_reset(struct qlcnic_adapter *adapter) | ||
1389 | { | ||
1390 | QLCWR32(adapter, QLC_83XX_RESET_REG, 0); | ||
1391 | QLCWR32(adapter, QLC_83XX_RESET_PORT0, 0); | ||
1392 | QLCWR32(adapter, QLC_83XX_RESET_PORT1, 0); | ||
1393 | QLCWR32(adapter, QLC_83XX_RESET_PORT2, 0); | ||
1394 | QLCWR32(adapter, QLC_83XX_RESET_PORT3, 0); | ||
1395 | QLCWR32(adapter, QLC_83XX_RESET_SRESHIM, 0); | ||
1396 | QLCWR32(adapter, QLC_83XX_RESET_EPGSHIM, 0); | ||
1397 | QLCWR32(adapter, QLC_83XX_RESET_ETHERPCS, 0); | ||
1398 | QLCWR32(adapter, QLC_83XX_RESET_CONTROL, 1); | ||
1399 | } | ||
1400 | |||
1377 | static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev) | 1401 | static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev) |
1378 | { | 1402 | { |
1379 | u32 heartbeat, peg_status; | 1403 | u32 heartbeat, peg_status; |
@@ -1395,6 +1419,7 @@ static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev) | |||
1395 | 1419 | ||
1396 | if (ret) { | 1420 | if (ret) { |
1397 | dev_err(&p_dev->pdev->dev, "firmware hang detected\n"); | 1421 | dev_err(&p_dev->pdev->dev, "firmware hang detected\n"); |
1422 | qlcnic_83xx_take_eport_out_of_reset(p_dev); | ||
1398 | qlcnic_83xx_disable_pause_frames(p_dev); | 1423 | qlcnic_83xx_disable_pause_frames(p_dev); |
1399 | peg_status = QLC_SHARED_REG_RD32(p_dev, | 1424 | peg_status = QLC_SHARED_REG_RD32(p_dev, |
1400 | QLCNIC_PEG_HALT_STATUS1); | 1425 | QLCNIC_PEG_HALT_STATUS1); |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 9f7aade4667c..08efb4635007 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | |||
@@ -115,6 +115,13 @@ static const char qlcnic_83xx_mac_stats_strings[][ETH_GSTRING_LEN] = { | |||
115 | "mac_rx_dropped", | 115 | "mac_rx_dropped", |
116 | "mac_crc_error", | 116 | "mac_crc_error", |
117 | "mac_align_error", | 117 | "mac_align_error", |
118 | "eswitch_frames", | ||
119 | "eswitch_bytes", | ||
120 | "eswitch_multicast_frames", | ||
121 | "eswitch_broadcast_frames", | ||
122 | "eswitch_unicast_frames", | ||
123 | "eswitch_error_free_frames", | ||
124 | "eswitch_error_free_bytes", | ||
118 | }; | 125 | }; |
119 | 126 | ||
120 | #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) | 127 | #define QLCNIC_STATS_LEN ARRAY_SIZE(qlcnic_gstrings_stats) |
@@ -635,7 +642,7 @@ static int qlcnic_set_channels(struct net_device *dev, | |||
635 | channel->tx_count != channel->max_tx) | 642 | channel->tx_count != channel->max_tx) |
636 | return -EINVAL; | 643 | return -EINVAL; |
637 | 644 | ||
638 | err = qlcnic_validate_max_rss(channel->max_rx, channel->rx_count); | 645 | err = qlcnic_validate_max_rss(adapter, channel->rx_count); |
639 | if (err) | 646 | if (err) |
640 | return err; | 647 | return err; |
641 | 648 | ||
@@ -1296,6 +1303,9 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, | |||
1296 | struct ethtool_coalesce *ethcoal) | 1303 | struct ethtool_coalesce *ethcoal) |
1297 | { | 1304 | { |
1298 | 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; | ||
1299 | 1309 | ||
1300 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) | 1310 | if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) |
1301 | return -EINVAL; | 1311 | return -EINVAL; |
@@ -1306,8 +1316,8 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, | |||
1306 | */ | 1316 | */ |
1307 | if (ethcoal->rx_coalesce_usecs > 0xffff || | 1317 | if (ethcoal->rx_coalesce_usecs > 0xffff || |
1308 | ethcoal->rx_max_coalesced_frames > 0xffff || | 1318 | ethcoal->rx_max_coalesced_frames > 0xffff || |
1309 | ethcoal->tx_coalesce_usecs || | 1319 | ethcoal->tx_coalesce_usecs > 0xffff || |
1310 | ethcoal->tx_max_coalesced_frames || | 1320 | ethcoal->tx_max_coalesced_frames > 0xffff || |
1311 | ethcoal->rx_coalesce_usecs_irq || | 1321 | ethcoal->rx_coalesce_usecs_irq || |
1312 | ethcoal->rx_max_coalesced_frames_irq || | 1322 | ethcoal->rx_max_coalesced_frames_irq || |
1313 | ethcoal->tx_coalesce_usecs_irq || | 1323 | ethcoal->tx_coalesce_usecs_irq || |
@@ -1327,18 +1337,55 @@ static int qlcnic_set_intr_coalesce(struct net_device *netdev, | |||
1327 | ethcoal->tx_max_coalesced_frames_high) | 1337 | ethcoal->tx_max_coalesced_frames_high) |
1328 | return -EINVAL; | 1338 | return -EINVAL; |
1329 | 1339 | ||
1330 | if (!ethcoal->rx_coalesce_usecs || | 1340 | coal = &adapter->ahw->coal; |
1331 | !ethcoal->rx_max_coalesced_frames) { | 1341 | |
1332 | adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; | 1342 | if (qlcnic_83xx_check(adapter)) { |
1333 | adapter->ahw->coal.rx_time_us = | 1343 | if (!ethcoal->tx_coalesce_usecs || |
1334 | QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; | 1344 | !ethcoal->tx_max_coalesced_frames || |
1335 | adapter->ahw->coal.rx_packets = | 1345 | !ethcoal->rx_coalesce_usecs || |
1336 | 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 | } | ||
1337 | } else { | 1378 | } else { |
1338 | adapter->ahw->coal.flag = 0; | 1379 | if (!ethcoal->rx_coalesce_usecs || |
1339 | adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs; | 1380 | !ethcoal->rx_max_coalesced_frames) { |
1340 | adapter->ahw->coal.rx_packets = | 1381 | coal->flag = QLCNIC_INTR_DEFAULT; |
1341 | 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 | } | ||
1342 | } | 1389 | } |
1343 | 1390 | ||
1344 | qlcnic_config_intr_coalesce(adapter); | 1391 | qlcnic_config_intr_coalesce(adapter); |
@@ -1356,6 +1403,8 @@ static int qlcnic_get_intr_coalesce(struct net_device *netdev, | |||
1356 | 1403 | ||
1357 | ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us; | 1404 | ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us; |
1358 | 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; | ||
1359 | 1408 | ||
1360 | return 0; | 1409 | return 0; |
1361 | } | 1410 | } |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 247a9f9b7bdc..264d5a4f8153 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -156,25 +156,112 @@ static const u32 qlcnic_reg_tbl[] = { | |||
156 | }; | 156 | }; |
157 | 157 | ||
158 | static const struct qlcnic_board_info qlcnic_boards[] = { | 158 | static const struct qlcnic_board_info qlcnic_boards[] = { |
159 | {0x1077, 0x8020, 0x1077, 0x203, | 159 | { PCI_VENDOR_ID_QLOGIC, |
160 | "8200 Series Single Port 10GbE Converged Network Adapter" | 160 | PCI_DEVICE_ID_QLOGIC_QLE834X, |
161 | "(TCP/IP Networking)"}, | 161 | PCI_VENDOR_ID_QLOGIC, |
162 | {0x1077, 0x8020, 0x1077, 0x207, | 162 | 0x24e, |
163 | "8200 Series Dual Port 10GbE Converged Network Adapter" | 163 | "8300 Series Dual Port 10GbE Converged Network Adapter " |
164 | "(TCP/IP Networking)"}, | 164 | "(TCP/IP Networking)" }, |
165 | {0x1077, 0x8020, 0x1077, 0x20b, | 165 | { PCI_VENDOR_ID_QLOGIC, |
166 | "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter"}, | 166 | PCI_DEVICE_ID_QLOGIC_QLE834X, |
167 | {0x1077, 0x8020, 0x1077, 0x20c, | 167 | PCI_VENDOR_ID_QLOGIC, |
168 | "3200 Series Quad Port 1Gb Intelligent Ethernet Adapter"}, | 168 | 0x243, |
169 | {0x1077, 0x8020, 0x1077, 0x20f, | 169 | "8300 Series Single Port 10GbE Converged Network Adapter " |
170 | "3200 Series Single Port 10Gb Intelligent Ethernet Adapter"}, | 170 | "(TCP/IP Networking)" }, |
171 | {0x1077, 0x8020, 0x103c, 0x3733, | 171 | { PCI_VENDOR_ID_QLOGIC, |
172 | "NC523SFP 10Gb 2-port Server Adapter"}, | 172 | PCI_DEVICE_ID_QLOGIC_QLE834X, |
173 | {0x1077, 0x8020, 0x103c, 0x3346, | 173 | PCI_VENDOR_ID_QLOGIC, |
174 | "CN1000Q Dual Port Converged Network Adapter"}, | 174 | 0x24a, |
175 | {0x1077, 0x8020, 0x1077, 0x210, | 175 | "8300 Series Dual Port 10GbE Converged Network Adapter " |
176 | "QME8242-k 10GbE Dual Port Mezzanine Card"}, | 176 | "(TCP/IP Networking)" }, |
177 | {0x1077, 0x8020, 0x0, 0x0, "cLOM8214 1/10GbE Controller"}, | 177 | { PCI_VENDOR_ID_QLOGIC, |
178 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
179 | PCI_VENDOR_ID_QLOGIC, | ||
180 | 0x246, | ||
181 | "8300 Series Dual Port 10GbE Converged Network Adapter " | ||
182 | "(TCP/IP Networking)" }, | ||
183 | { PCI_VENDOR_ID_QLOGIC, | ||
184 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
185 | PCI_VENDOR_ID_QLOGIC, | ||
186 | 0x252, | ||
187 | "8300 Series Dual Port 10GbE Converged Network Adapter " | ||
188 | "(TCP/IP Networking)" }, | ||
189 | { PCI_VENDOR_ID_QLOGIC, | ||
190 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
191 | PCI_VENDOR_ID_QLOGIC, | ||
192 | 0x26e, | ||
193 | "8300 Series Dual Port 10GbE Converged Network Adapter " | ||
194 | "(TCP/IP Networking)" }, | ||
195 | { PCI_VENDOR_ID_QLOGIC, | ||
196 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
197 | PCI_VENDOR_ID_QLOGIC, | ||
198 | 0x260, | ||
199 | "8300 Series Dual Port 10GbE Converged Network Adapter " | ||
200 | "(TCP/IP Networking)" }, | ||
201 | { PCI_VENDOR_ID_QLOGIC, | ||
202 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
203 | PCI_VENDOR_ID_QLOGIC, | ||
204 | 0x266, | ||
205 | "8300 Series Single Port 10GbE Converged Network Adapter " | ||
206 | "(TCP/IP Networking)" }, | ||
207 | { PCI_VENDOR_ID_QLOGIC, | ||
208 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
209 | PCI_VENDOR_ID_QLOGIC, | ||
210 | 0x269, | ||
211 | "8300 Series Dual Port 10GbE Converged Network Adapter " | ||
212 | "(TCP/IP Networking)" }, | ||
213 | { PCI_VENDOR_ID_QLOGIC, | ||
214 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
215 | PCI_VENDOR_ID_QLOGIC, | ||
216 | 0x271, | ||
217 | "8300 Series Dual Port 10GbE Converged Network Adapter " | ||
218 | "(TCP/IP Networking)" }, | ||
219 | { PCI_VENDOR_ID_QLOGIC, | ||
220 | PCI_DEVICE_ID_QLOGIC_QLE834X, | ||
221 | 0x0, 0x0, "8300 Series 1/10GbE Controller" }, | ||
222 | { PCI_VENDOR_ID_QLOGIC, | ||
223 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
224 | PCI_VENDOR_ID_QLOGIC, | ||
225 | 0x203, | ||
226 | "8200 Series Single Port 10GbE Converged Network Adapter" | ||
227 | "(TCP/IP Networking)" }, | ||
228 | { PCI_VENDOR_ID_QLOGIC, | ||
229 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
230 | PCI_VENDOR_ID_QLOGIC, | ||
231 | 0x207, | ||
232 | "8200 Series Dual Port 10GbE Converged Network Adapter" | ||
233 | "(TCP/IP Networking)" }, | ||
234 | { PCI_VENDOR_ID_QLOGIC, | ||
235 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
236 | PCI_VENDOR_ID_QLOGIC, | ||
237 | 0x20b, | ||
238 | "3200 Series Dual Port 10Gb Intelligent Ethernet Adapter" }, | ||
239 | { PCI_VENDOR_ID_QLOGIC, | ||
240 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
241 | PCI_VENDOR_ID_QLOGIC, | ||
242 | 0x20c, | ||
243 | "3200 Series Quad Port 1Gb Intelligent Ethernet Adapter" }, | ||
244 | { PCI_VENDOR_ID_QLOGIC, | ||
245 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
246 | PCI_VENDOR_ID_QLOGIC, | ||
247 | 0x20f, | ||
248 | "3200 Series Single Port 10Gb Intelligent Ethernet Adapter" }, | ||
249 | { PCI_VENDOR_ID_QLOGIC, | ||
250 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
251 | 0x103c, 0x3733, | ||
252 | "NC523SFP 10Gb 2-port Server Adapter" }, | ||
253 | { PCI_VENDOR_ID_QLOGIC, | ||
254 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
255 | 0x103c, 0x3346, | ||
256 | "CN1000Q Dual Port Converged Network Adapter" }, | ||
257 | { PCI_VENDOR_ID_QLOGIC, | ||
258 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
259 | PCI_VENDOR_ID_QLOGIC, | ||
260 | 0x210, | ||
261 | "QME8242-k 10GbE Dual Port Mezzanine Card" }, | ||
262 | { PCI_VENDOR_ID_QLOGIC, | ||
263 | PCI_DEVICE_ID_QLOGIC_QLE824X, | ||
264 | 0x0, 0x0, "cLOM8214 1/10GbE Controller" }, | ||
178 | }; | 265 | }; |
179 | 266 | ||
180 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards) | 267 | #define NUM_SUPPORTED_BOARDS ARRAY_SIZE(qlcnic_boards) |
@@ -1287,7 +1374,7 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) | |||
1287 | irq_handler_t handler; | 1374 | irq_handler_t handler; |
1288 | struct qlcnic_host_sds_ring *sds_ring; | 1375 | struct qlcnic_host_sds_ring *sds_ring; |
1289 | struct qlcnic_host_tx_ring *tx_ring; | 1376 | struct qlcnic_host_tx_ring *tx_ring; |
1290 | int err, ring; | 1377 | int err, ring, num_sds_rings; |
1291 | 1378 | ||
1292 | unsigned long flags = 0; | 1379 | unsigned long flags = 0; |
1293 | struct net_device *netdev = adapter->netdev; | 1380 | struct net_device *netdev = adapter->netdev; |
@@ -1318,10 +1405,20 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) | |||
1318 | if (qlcnic_82xx_check(adapter) || | 1405 | if (qlcnic_82xx_check(adapter) || |
1319 | (qlcnic_83xx_check(adapter) && | 1406 | (qlcnic_83xx_check(adapter) && |
1320 | (adapter->flags & QLCNIC_MSIX_ENABLED))) { | 1407 | (adapter->flags & QLCNIC_MSIX_ENABLED))) { |
1321 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 1408 | num_sds_rings = adapter->max_sds_rings; |
1409 | for (ring = 0; ring < num_sds_rings; ring++) { | ||
1322 | sds_ring = &recv_ctx->sds_rings[ring]; | 1410 | sds_ring = &recv_ctx->sds_rings[ring]; |
1323 | snprintf(sds_ring->name, sizeof(int) + IFNAMSIZ, | 1411 | if (qlcnic_82xx_check(adapter) && |
1324 | "%s[%d]", netdev->name, ring); | 1412 | (ring == (num_sds_rings - 1))) |
1413 | snprintf(sds_ring->name, | ||
1414 | sizeof(sds_ring->name), | ||
1415 | "qlcnic-%s[Tx0+Rx%d]", | ||
1416 | netdev->name, ring); | ||
1417 | else | ||
1418 | snprintf(sds_ring->name, | ||
1419 | sizeof(sds_ring->name), | ||
1420 | "qlcnic-%s[Rx%d]", | ||
1421 | netdev->name, ring); | ||
1325 | err = request_irq(sds_ring->irq, handler, flags, | 1422 | err = request_irq(sds_ring->irq, handler, flags, |
1326 | sds_ring->name, sds_ring); | 1423 | sds_ring->name, sds_ring); |
1327 | if (err) | 1424 | if (err) |
@@ -1335,9 +1432,8 @@ qlcnic_request_irq(struct qlcnic_adapter *adapter) | |||
1335 | for (ring = 0; ring < adapter->max_drv_tx_rings; | 1432 | for (ring = 0; ring < adapter->max_drv_tx_rings; |
1336 | ring++) { | 1433 | ring++) { |
1337 | tx_ring = &adapter->tx_ring[ring]; | 1434 | tx_ring = &adapter->tx_ring[ring]; |
1338 | snprintf(tx_ring->name, sizeof(int) + IFNAMSIZ, | 1435 | snprintf(tx_ring->name, sizeof(tx_ring->name), |
1339 | "%s[%d]", netdev->name, | 1436 | "qlcnic-%s[Tx%d]", netdev->name, ring); |
1340 | adapter->max_sds_rings + ring); | ||
1341 | err = request_irq(tx_ring->irq, handler, flags, | 1437 | err = request_irq(tx_ring->irq, handler, flags, |
1342 | tx_ring->name, tx_ring); | 1438 | tx_ring->name, tx_ring); |
1343 | if (err) | 1439 | if (err) |
@@ -1587,7 +1683,9 @@ out: | |||
1587 | 1683 | ||
1588 | static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) | 1684 | static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) |
1589 | { | 1685 | { |
1686 | struct qlcnic_hardware_context *ahw = adapter->ahw; | ||
1590 | int err = 0; | 1687 | int err = 0; |
1688 | |||
1591 | adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), | 1689 | adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context), |
1592 | GFP_KERNEL); | 1690 | GFP_KERNEL); |
1593 | if (!adapter->recv_ctx) { | 1691 | if (!adapter->recv_ctx) { |
@@ -1595,9 +1693,14 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) | |||
1595 | goto err_out; | 1693 | goto err_out; |
1596 | } | 1694 | } |
1597 | /* Initialize interrupt coalesce parameters */ | 1695 | /* Initialize interrupt coalesce parameters */ |
1598 | adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT; | 1696 | ahw->coal.flag = QLCNIC_INTR_DEFAULT; |
1599 | adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US; | 1697 | ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX; |
1600 | adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS; | 1698 | ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US; |
1699 | ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS; | ||
1700 | if (qlcnic_83xx_check(adapter)) { | ||
1701 | ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US; | ||
1702 | ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS; | ||
1703 | } | ||
1601 | /* clear stats */ | 1704 | /* clear stats */ |
1602 | memset(&adapter->stats, 0, sizeof(adapter->stats)); | 1705 | memset(&adapter->stats, 0, sizeof(adapter->stats)); |
1603 | err_out: | 1706 | err_out: |
@@ -3273,20 +3376,40 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter) | |||
3273 | return err; | 3376 | return err; |
3274 | } | 3377 | } |
3275 | 3378 | ||
3276 | int qlcnic_validate_max_rss(u8 max_hw, u8 val) | 3379 | int qlcnic_validate_max_rss(struct qlcnic_adapter *adapter, |
3380 | __u32 val) | ||
3277 | { | 3381 | { |
3382 | struct net_device *netdev = adapter->netdev; | ||
3383 | u8 max_hw = adapter->ahw->max_rx_ques; | ||
3278 | u32 max_allowed; | 3384 | u32 max_allowed; |
3279 | 3385 | ||
3280 | if (max_hw > QLC_MAX_SDS_RINGS) { | 3386 | if (val > QLC_MAX_SDS_RINGS) { |
3281 | max_hw = QLC_MAX_SDS_RINGS; | 3387 | netdev_err(netdev, "RSS value should not be higher than %u\n", |
3282 | pr_info("max rss reset to %d\n", QLC_MAX_SDS_RINGS); | 3388 | QLC_MAX_SDS_RINGS); |
3389 | return -EINVAL; | ||
3283 | } | 3390 | } |
3284 | 3391 | ||
3285 | max_allowed = rounddown_pow_of_two(min_t(int, max_hw, | 3392 | max_allowed = rounddown_pow_of_two(min_t(int, max_hw, |
3286 | num_online_cpus())); | 3393 | num_online_cpus())); |
3287 | if ((val > max_allowed) || (val < 2) || !is_power_of_2(val)) { | 3394 | if ((val > max_allowed) || (val < 2) || !is_power_of_2(val)) { |
3288 | pr_info("rss_ring valid range [2 - %x] in powers of 2\n", | 3395 | if (!is_power_of_2(val)) |
3289 | max_allowed); | 3396 | netdev_err(netdev, "RSS value should be a power of 2\n"); |
3397 | |||
3398 | if (val < 2) | ||
3399 | netdev_err(netdev, "RSS value should not be lower than 2\n"); | ||
3400 | |||
3401 | if (val > max_hw) | ||
3402 | netdev_err(netdev, | ||
3403 | "RSS value should not be higher than[%u], the max RSS rings supported by the adapter\n", | ||
3404 | max_hw); | ||
3405 | |||
3406 | if (val > num_online_cpus()) | ||
3407 | netdev_err(netdev, | ||
3408 | "RSS value should not be higher than[%u], number of online CPUs in the system\n", | ||
3409 | num_online_cpus()); | ||
3410 | |||
3411 | netdev_err(netdev, "Unable to configure %u RSS rings\n", val); | ||
3412 | |||
3290 | return -EINVAL; | 3413 | return -EINVAL; |
3291 | } | 3414 | } |
3292 | return 0; | 3415 | return 0; |