aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_ethtool.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_ethtool.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_ethtool.c123
1 files changed, 96 insertions, 27 deletions
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index fa8f9526f93c..8fb00276dc41 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -41,19 +41,19 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
41 (bp->link_vars.link_up)) { 41 (bp->link_vars.link_up)) {
42 cmd->speed = bp->link_vars.line_speed; 42 cmd->speed = bp->link_vars.line_speed;
43 cmd->duplex = bp->link_vars.duplex; 43 cmd->duplex = bp->link_vars.duplex;
44 if (IS_MF(bp)) {
45 u16 vn_max_rate;
46
47 vn_max_rate =
48 ((bp->mf_config & FUNC_MF_CFG_MAX_BW_MASK) >>
49 FUNC_MF_CFG_MAX_BW_SHIFT) * 100;
50 if (vn_max_rate < cmd->speed)
51 cmd->speed = vn_max_rate;
52 }
53 } else { 44 } else {
45
54 cmd->speed = bp->link_params.req_line_speed[cfg_idx]; 46 cmd->speed = bp->link_params.req_line_speed[cfg_idx];
55 cmd->duplex = bp->link_params.req_duplex[cfg_idx]; 47 cmd->duplex = bp->link_params.req_duplex[cfg_idx];
56 } 48 }
49 if (IS_MF(bp)) {
50 u16 vn_max_rate = ((bp->mf_config[BP_VN(bp)] &
51 FUNC_MF_CFG_MAX_BW_MASK) >> FUNC_MF_CFG_MAX_BW_SHIFT) *
52 100;
53
54 if (vn_max_rate < cmd->speed)
55 cmd->speed = vn_max_rate;
56 }
57 57
58 if (bp->port.supported[cfg_idx] & SUPPORTED_TP) 58 if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
59 cmd->port = PORT_TP; 59 cmd->port = PORT_TP;
@@ -298,6 +298,7 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
298 298
299#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE) 299#define IS_E1_ONLINE(info) (((info) & RI_E1_ONLINE) == RI_E1_ONLINE)
300#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE) 300#define IS_E1H_ONLINE(info) (((info) & RI_E1H_ONLINE) == RI_E1H_ONLINE)
301#define IS_E2_ONLINE(info) (((info) & RI_E2_ONLINE) == RI_E2_ONLINE)
301 302
302static int bnx2x_get_regs_len(struct net_device *dev) 303static int bnx2x_get_regs_len(struct net_device *dev)
303{ 304{
@@ -315,7 +316,7 @@ static int bnx2x_get_regs_len(struct net_device *dev)
315 regdump_len += wreg_addrs_e1[i].size * 316 regdump_len += wreg_addrs_e1[i].size *
316 (1 + wreg_addrs_e1[i].read_regs_count); 317 (1 + wreg_addrs_e1[i].read_regs_count);
317 318
318 } else { /* E1H */ 319 } else if (CHIP_IS_E1H(bp)) {
319 for (i = 0; i < REGS_COUNT; i++) 320 for (i = 0; i < REGS_COUNT; i++)
320 if (IS_E1H_ONLINE(reg_addrs[i].info)) 321 if (IS_E1H_ONLINE(reg_addrs[i].info))
321 regdump_len += reg_addrs[i].size; 322 regdump_len += reg_addrs[i].size;
@@ -324,6 +325,15 @@ static int bnx2x_get_regs_len(struct net_device *dev)
324 if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info)) 325 if (IS_E1H_ONLINE(wreg_addrs_e1h[i].info))
325 regdump_len += wreg_addrs_e1h[i].size * 326 regdump_len += wreg_addrs_e1h[i].size *
326 (1 + wreg_addrs_e1h[i].read_regs_count); 327 (1 + wreg_addrs_e1h[i].read_regs_count);
328 } else if (CHIP_IS_E2(bp)) {
329 for (i = 0; i < REGS_COUNT; i++)
330 if (IS_E2_ONLINE(reg_addrs[i].info))
331 regdump_len += reg_addrs[i].size;
332
333 for (i = 0; i < WREGS_COUNT_E2; i++)
334 if (IS_E2_ONLINE(wreg_addrs_e2[i].info))
335 regdump_len += wreg_addrs_e2[i].size *
336 (1 + wreg_addrs_e2[i].read_regs_count);
327 } 337 }
328 regdump_len *= 4; 338 regdump_len *= 4;
329 regdump_len += sizeof(struct dump_hdr); 339 regdump_len += sizeof(struct dump_hdr);
@@ -331,6 +341,23 @@ static int bnx2x_get_regs_len(struct net_device *dev)
331 return regdump_len; 341 return regdump_len;
332} 342}
333 343
344static inline void bnx2x_read_pages_regs_e2(struct bnx2x *bp, u32 *p)
345{
346 u32 i, j, k, n;
347
348 for (i = 0; i < PAGE_MODE_VALUES_E2; i++) {
349 for (j = 0; j < PAGE_WRITE_REGS_E2; j++) {
350 REG_WR(bp, page_write_regs_e2[j], page_vals_e2[i]);
351 for (k = 0; k < PAGE_READ_REGS_E2; k++)
352 if (IS_E2_ONLINE(page_read_regs_e2[k].info))
353 for (n = 0; n <
354 page_read_regs_e2[k].size; n++)
355 *p++ = REG_RD(bp,
356 page_read_regs_e2[k].addr + n*4);
357 }
358 }
359}
360
334static void bnx2x_get_regs(struct net_device *dev, 361static void bnx2x_get_regs(struct net_device *dev,
335 struct ethtool_regs *regs, void *_p) 362 struct ethtool_regs *regs, void *_p)
336{ 363{
@@ -350,7 +377,14 @@ static void bnx2x_get_regs(struct net_device *dev,
350 dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR); 377 dump_hdr.tstorm_waitp = REG_RD(bp, TSTORM_WAITP_ADDR);
351 dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR); 378 dump_hdr.ustorm_waitp = REG_RD(bp, USTORM_WAITP_ADDR);
352 dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR); 379 dump_hdr.cstorm_waitp = REG_RD(bp, CSTORM_WAITP_ADDR);
353 dump_hdr.info = CHIP_IS_E1(bp) ? RI_E1_ONLINE : RI_E1H_ONLINE; 380
381 if (CHIP_IS_E1(bp))
382 dump_hdr.info = RI_E1_ONLINE;
383 else if (CHIP_IS_E1H(bp))
384 dump_hdr.info = RI_E1H_ONLINE;
385 else if (CHIP_IS_E2(bp))
386 dump_hdr.info = RI_E2_ONLINE |
387 (BP_PATH(bp) ? RI_PATH1_DUMP : RI_PATH0_DUMP);
354 388
355 memcpy(p, &dump_hdr, sizeof(struct dump_hdr)); 389 memcpy(p, &dump_hdr, sizeof(struct dump_hdr));
356 p += dump_hdr.hdr_size + 1; 390 p += dump_hdr.hdr_size + 1;
@@ -362,16 +396,25 @@ static void bnx2x_get_regs(struct net_device *dev,
362 *p++ = REG_RD(bp, 396 *p++ = REG_RD(bp,
363 reg_addrs[i].addr + j*4); 397 reg_addrs[i].addr + j*4);
364 398
365 } else { /* E1H */ 399 } else if (CHIP_IS_E1H(bp)) {
366 for (i = 0; i < REGS_COUNT; i++) 400 for (i = 0; i < REGS_COUNT; i++)
367 if (IS_E1H_ONLINE(reg_addrs[i].info)) 401 if (IS_E1H_ONLINE(reg_addrs[i].info))
368 for (j = 0; j < reg_addrs[i].size; j++) 402 for (j = 0; j < reg_addrs[i].size; j++)
369 *p++ = REG_RD(bp, 403 *p++ = REG_RD(bp,
370 reg_addrs[i].addr + j*4); 404 reg_addrs[i].addr + j*4);
405
406 } else if (CHIP_IS_E2(bp)) {
407 for (i = 0; i < REGS_COUNT; i++)
408 if (IS_E2_ONLINE(reg_addrs[i].info))
409 for (j = 0; j < reg_addrs[i].size; j++)
410 *p++ = REG_RD(bp,
411 reg_addrs[i].addr + j*4);
412
413 bnx2x_read_pages_regs_e2(bp, p);
371 } 414 }
372} 415}
373 416
374#define PHY_FW_VER_LEN 10 417#define PHY_FW_VER_LEN 20
375 418
376static void bnx2x_get_drvinfo(struct net_device *dev, 419static void bnx2x_get_drvinfo(struct net_device *dev,
377 struct ethtool_drvinfo *info) 420 struct ethtool_drvinfo *info)
@@ -474,7 +517,7 @@ static u32 bnx2x_get_link(struct net_device *dev)
474{ 517{
475 struct bnx2x *bp = netdev_priv(dev); 518 struct bnx2x *bp = netdev_priv(dev);
476 519
477 if (bp->flags & MF_FUNC_DIS) 520 if (bp->flags & MF_FUNC_DIS || (bp->state != BNX2X_STATE_OPEN))
478 return 0; 521 return 0;
479 522
480 return bp->link_vars.link_up; 523 return bp->link_vars.link_up;
@@ -1235,6 +1278,9 @@ static int bnx2x_test_registers(struct bnx2x *bp)
1235 1278
1236 for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) { 1279 for (i = 0; reg_tbl[i].offset0 != 0xffffffff; i++) {
1237 u32 offset, mask, save_val, val; 1280 u32 offset, mask, save_val, val;
1281 if (CHIP_IS_E2(bp) &&
1282 reg_tbl[i].offset0 == HC_REG_AGG_INT_0)
1283 continue;
1238 1284
1239 offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1; 1285 offset = reg_tbl[i].offset0 + port*reg_tbl[i].offset1;
1240 mask = reg_tbl[i].mask; 1286 mask = reg_tbl[i].mask;
@@ -1286,20 +1332,33 @@ static int bnx2x_test_memory(struct bnx2x *bp)
1286 u32 offset; 1332 u32 offset;
1287 u32 e1_mask; 1333 u32 e1_mask;
1288 u32 e1h_mask; 1334 u32 e1h_mask;
1335 u32 e2_mask;
1289 } prty_tbl[] = { 1336 } prty_tbl[] = {
1290 { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0 }, 1337 { "CCM_PRTY_STS", CCM_REG_CCM_PRTY_STS, 0x3ffc0, 0, 0 },
1291 { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2 }, 1338 { "CFC_PRTY_STS", CFC_REG_CFC_PRTY_STS, 0x2, 0x2, 0 },
1292 { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0 }, 1339 { "DMAE_PRTY_STS", DMAE_REG_DMAE_PRTY_STS, 0, 0, 0 },
1293 { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0 }, 1340 { "TCM_PRTY_STS", TCM_REG_TCM_PRTY_STS, 0x3ffc0, 0, 0 },
1294 { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0 }, 1341 { "UCM_PRTY_STS", UCM_REG_UCM_PRTY_STS, 0x3ffc0, 0, 0 },
1295 { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0 }, 1342 { "XCM_PRTY_STS", XCM_REG_XCM_PRTY_STS, 0x3ffc1, 0, 0 },
1296 1343
1297 { NULL, 0xffffffff, 0, 0 } 1344 { NULL, 0xffffffff, 0, 0, 0 }
1298 }; 1345 };
1299 1346
1300 if (!netif_running(bp->dev)) 1347 if (!netif_running(bp->dev))
1301 return rc; 1348 return rc;
1302 1349
1350 /* pre-Check the parity status */
1351 for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
1352 val = REG_RD(bp, prty_tbl[i].offset);
1353 if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
1354 (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) ||
1355 (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) {
1356 DP(NETIF_MSG_HW,
1357 "%s is 0x%x\n", prty_tbl[i].name, val);
1358 goto test_mem_exit;
1359 }
1360 }
1361
1303 /* Go through all the memories */ 1362 /* Go through all the memories */
1304 for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) 1363 for (i = 0; mem_tbl[i].offset != 0xffffffff; i++)
1305 for (j = 0; j < mem_tbl[i].size; j++) 1364 for (j = 0; j < mem_tbl[i].size; j++)
@@ -1309,7 +1368,8 @@ static int bnx2x_test_memory(struct bnx2x *bp)
1309 for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) { 1368 for (i = 0; prty_tbl[i].offset != 0xffffffff; i++) {
1310 val = REG_RD(bp, prty_tbl[i].offset); 1369 val = REG_RD(bp, prty_tbl[i].offset);
1311 if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) || 1370 if ((CHIP_IS_E1(bp) && (val & ~(prty_tbl[i].e1_mask))) ||
1312 (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask)))) { 1371 (CHIP_IS_E1H(bp) && (val & ~(prty_tbl[i].e1h_mask))) ||
1372 (CHIP_IS_E2(bp) && (val & ~(prty_tbl[i].e2_mask)))) {
1313 DP(NETIF_MSG_HW, 1373 DP(NETIF_MSG_HW,
1314 "%s is 0x%x\n", prty_tbl[i].name, val); 1374 "%s is 0x%x\n", prty_tbl[i].name, val);
1315 goto test_mem_exit; 1375 goto test_mem_exit;
@@ -1324,7 +1384,7 @@ test_mem_exit:
1324 1384
1325static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes) 1385static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up, u8 is_serdes)
1326{ 1386{
1327 int cnt = 1000; 1387 int cnt = 1400;
1328 1388
1329 if (link_up) 1389 if (link_up)
1330 while (bnx2x_link_test(bp, is_serdes) && cnt--) 1390 while (bnx2x_link_test(bp, is_serdes) && cnt--)
@@ -1343,7 +1403,8 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
1343 u16 pkt_prod, bd_prod; 1403 u16 pkt_prod, bd_prod;
1344 struct sw_tx_bd *tx_buf; 1404 struct sw_tx_bd *tx_buf;
1345 struct eth_tx_start_bd *tx_start_bd; 1405 struct eth_tx_start_bd *tx_start_bd;
1346 struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; 1406 struct eth_tx_parse_bd_e1x *pbd_e1x = NULL;
1407 struct eth_tx_parse_bd_e2 *pbd_e2 = NULL;
1347 dma_addr_t mapping; 1408 dma_addr_t mapping;
1348 union eth_rx_cqe *cqe; 1409 union eth_rx_cqe *cqe;
1349 u8 cqe_fp_flags; 1410 u8 cqe_fp_flags;
@@ -1411,7 +1472,9 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
1411 /* turn on parsing and get a BD */ 1472 /* turn on parsing and get a BD */
1412 bd_prod = TX_BD(NEXT_TX_IDX(bd_prod)); 1473 bd_prod = TX_BD(NEXT_TX_IDX(bd_prod));
1413 pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x; 1474 pbd_e1x = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e1x;
1475 pbd_e2 = &fp_tx->tx_desc_ring[bd_prod].parse_bd_e2;
1414 1476
1477 memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2));
1415 memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); 1478 memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x));
1416 1479
1417 wmb(); 1480 wmb();
@@ -1431,6 +1494,13 @@ static int bnx2x_run_loopback(struct bnx2x *bp, int loopback_mode, u8 link_up)
1431 if (tx_idx != tx_start_idx + num_pkts) 1494 if (tx_idx != tx_start_idx + num_pkts)
1432 goto test_loopback_exit; 1495 goto test_loopback_exit;
1433 1496
1497 /* Unlike HC IGU won't generate an interrupt for status block
1498 * updates that have been performed while interrupts were
1499 * disabled.
1500 */
1501 if (bp->common.int_block == INT_BLOCK_IGU)
1502 bnx2x_tx_int(fp_tx);
1503
1434 rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb); 1504 rx_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
1435 if (rx_idx != rx_start_idx + num_pkts) 1505 if (rx_idx != rx_start_idx + num_pkts)
1436 goto test_loopback_exit; 1506 goto test_loopback_exit;
@@ -1573,8 +1643,7 @@ static int bnx2x_test_intr(struct bnx2x *bp)
1573 1643
1574 config->hdr.length = 0; 1644 config->hdr.length = 0;
1575 if (CHIP_IS_E1(bp)) 1645 if (CHIP_IS_E1(bp))
1576 /* use last unicast entries */ 1646 config->hdr.offset = (BP_PORT(bp) ? 32 : 0);
1577 config->hdr.offset = (BP_PORT(bp) ? 63 : 31);
1578 else 1647 else
1579 config->hdr.offset = BP_FUNC(bp); 1648 config->hdr.offset = BP_FUNC(bp);
1580 config->hdr.client_id = bp->fp->cl_id; 1649 config->hdr.client_id = bp->fp->cl_id;