aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h22
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c19
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c25
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c77
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c193
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
517struct qlcnic_host_tx_ring { 525struct 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);
1474int qlcnic_diag_alloc_res(struct net_device *netdev, int test); 1482int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
1475netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev); 1483netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
1476int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, size_t); 1484int qlcnic_set_max_rss(struct qlcnic_adapter *, u8, size_t);
1477int qlcnic_validate_max_rss(u8, u8); 1485int qlcnic_validate_max_rss(struct qlcnic_adapter *, __u32);
1478void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter); 1486void qlcnic_alloc_lb_filters_mem(struct qlcnic_adapter *adapter);
1479int qlcnic_enable_msix(struct qlcnic_adapter *, u32); 1487int 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)
1937void qlcnic_83xx_config_intr_coal(struct qlcnic_adapter *adapter) 1937void 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
28static int qlcnic_83xx_init_default_driver(struct qlcnic_adapter *adapter); 39static int qlcnic_83xx_init_default_driver(struct qlcnic_adapter *adapter);
29static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev); 40static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev);
30static int qlcnic_83xx_restart_hw(struct qlcnic_adapter *adapter); 41static 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
1388static 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
1377static int qlcnic_83xx_check_heartbeat(struct qlcnic_adapter *p_dev) 1401static 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
158static const struct qlcnic_board_info qlcnic_boards[] = { 158static 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
1588static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter) 1684static 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));
1603err_out: 1706err_out:
@@ -3273,20 +3376,40 @@ qlcnicvf_start_firmware(struct qlcnic_adapter *adapter)
3273 return err; 3376 return err;
3274} 3377}
3275 3378
3276int qlcnic_validate_max_rss(u8 max_hw, u8 val) 3379int 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;