diff options
author | Yaniv Rosner <yanivr@broadcom.com> | 2011-05-31 17:29:42 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-06-01 16:10:57 -0400 |
commit | a198c142aacf82acad29e1752191bda8b451a0c7 (patch) | |
tree | 539a2bba7ccac04fd7227dae523e118c88ad86e5 /drivers/net/bnx2x/bnx2x_link.c | |
parent | ec146a6f019923819f5ca381980248b6d154ca1a (diff) |
bnx2x: Improve cl45 access methods
Instead of setting CL45 mode for every CL45 access, apply it once during initialization.
Signed-off-by: Yaniv Rosner <yanivr@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r-- | drivers/net/bnx2x/bnx2x_link.c | 136 |
1 files changed, 65 insertions, 71 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 43e3663ab33..15b5bc17433 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c | |||
@@ -464,6 +464,29 @@ void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars, | |||
464 | /******************************************************************/ | 464 | /******************************************************************/ |
465 | /* MAC/PBF section */ | 465 | /* MAC/PBF section */ |
466 | /******************************************************************/ | 466 | /******************************************************************/ |
467 | static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port) | ||
468 | { | ||
469 | u32 mode, emac_base; | ||
470 | /** | ||
471 | * Set clause 45 mode, slow down the MDIO clock to 2.5MHz | ||
472 | * (a value of 49==0x31) and make sure that the AUTO poll is off | ||
473 | */ | ||
474 | |||
475 | if (CHIP_IS_E2(bp)) | ||
476 | emac_base = GRCBASE_EMAC0; | ||
477 | else | ||
478 | emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; | ||
479 | mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE); | ||
480 | mode &= ~(EMAC_MDIO_MODE_AUTO_POLL | | ||
481 | EMAC_MDIO_MODE_CLOCK_CNT); | ||
482 | mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT); | ||
483 | |||
484 | mode |= (EMAC_MDIO_MODE_CLAUSE_45); | ||
485 | REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode); | ||
486 | |||
487 | udelay(40); | ||
488 | } | ||
489 | |||
467 | static void bnx2x_emac_init(struct link_params *params, | 490 | static void bnx2x_emac_init(struct link_params *params, |
468 | struct link_vars *vars) | 491 | struct link_vars *vars) |
469 | { | 492 | { |
@@ -495,7 +518,7 @@ static void bnx2x_emac_init(struct link_params *params, | |||
495 | } | 518 | } |
496 | timeout--; | 519 | timeout--; |
497 | } while (val & EMAC_MODE_RESET); | 520 | } while (val & EMAC_MODE_RESET); |
498 | 521 | bnx2x_set_mdio_clk(bp, params->chip_id, port); | |
499 | /* Set mac address */ | 522 | /* Set mac address */ |
500 | val = ((params->mac_addr[0] << 8) | | 523 | val = ((params->mac_addr[0] << 8) | |
501 | params->mac_addr[1]); | 524 | params->mac_addr[1]); |
@@ -1352,144 +1375,113 @@ static u32 bnx2x_get_emac_base(struct bnx2x *bp, | |||
1352 | /******************************************************************/ | 1375 | /******************************************************************/ |
1353 | /* CL45 access functions */ | 1376 | /* CL45 access functions */ |
1354 | /******************************************************************/ | 1377 | /******************************************************************/ |
1355 | static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, | 1378 | static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, |
1356 | u8 devad, u16 reg, u16 val) | 1379 | u8 devad, u16 reg, u16 *ret_val) |
1357 | { | 1380 | { |
1358 | u32 tmp, saved_mode; | 1381 | u32 val; |
1359 | u8 i; | 1382 | u16 i; |
1360 | int rc = 0; | 1383 | int rc = 0; |
1361 | /* | ||
1362 | * Set clause 45 mode, slow down the MDIO clock to 2.5MHz | ||
1363 | * (a value of 49==0x31) and make sure that the AUTO poll is off | ||
1364 | */ | ||
1365 | |||
1366 | saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); | ||
1367 | tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL | | ||
1368 | EMAC_MDIO_MODE_CLOCK_CNT); | ||
1369 | tmp |= (EMAC_MDIO_MODE_CLAUSE_45 | | ||
1370 | (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); | ||
1371 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); | ||
1372 | REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); | ||
1373 | udelay(40); | ||
1374 | 1384 | ||
1375 | /* address */ | 1385 | /* address */ |
1376 | 1386 | val = ((phy->addr << 21) | (devad << 16) | reg | | |
1377 | tmp = ((phy->addr << 21) | (devad << 16) | reg | | ||
1378 | EMAC_MDIO_COMM_COMMAND_ADDRESS | | 1387 | EMAC_MDIO_COMM_COMMAND_ADDRESS | |
1379 | EMAC_MDIO_COMM_START_BUSY); | 1388 | EMAC_MDIO_COMM_START_BUSY); |
1380 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); | 1389 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); |
1381 | 1390 | ||
1382 | for (i = 0; i < 50; i++) { | 1391 | for (i = 0; i < 50; i++) { |
1383 | udelay(10); | 1392 | udelay(10); |
1384 | 1393 | ||
1385 | tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); | 1394 | val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); |
1386 | if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { | 1395 | if (!(val & EMAC_MDIO_COMM_START_BUSY)) { |
1387 | udelay(5); | 1396 | udelay(5); |
1388 | break; | 1397 | break; |
1389 | } | 1398 | } |
1390 | } | 1399 | } |
1391 | if (tmp & EMAC_MDIO_COMM_START_BUSY) { | 1400 | if (val & EMAC_MDIO_COMM_START_BUSY) { |
1392 | DP(NETIF_MSG_LINK, "write phy register failed\n"); | 1401 | DP(NETIF_MSG_LINK, "read phy register failed\n"); |
1393 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); | 1402 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); |
1403 | *ret_val = 0; | ||
1394 | rc = -EFAULT; | 1404 | rc = -EFAULT; |
1395 | } else { | 1405 | } else { |
1396 | /* data */ | 1406 | /* data */ |
1397 | tmp = ((phy->addr << 21) | (devad << 16) | val | | 1407 | val = ((phy->addr << 21) | (devad << 16) | |
1398 | EMAC_MDIO_COMM_COMMAND_WRITE_45 | | 1408 | EMAC_MDIO_COMM_COMMAND_READ_45 | |
1399 | EMAC_MDIO_COMM_START_BUSY); | 1409 | EMAC_MDIO_COMM_START_BUSY); |
1400 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); | 1410 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); |
1401 | 1411 | ||
1402 | for (i = 0; i < 50; i++) { | 1412 | for (i = 0; i < 50; i++) { |
1403 | udelay(10); | 1413 | udelay(10); |
1404 | 1414 | ||
1405 | tmp = REG_RD(bp, phy->mdio_ctrl + | 1415 | val = REG_RD(bp, phy->mdio_ctrl + |
1406 | EMAC_REG_EMAC_MDIO_COMM); | 1416 | EMAC_REG_EMAC_MDIO_COMM); |
1407 | if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { | 1417 | if (!(val & EMAC_MDIO_COMM_START_BUSY)) { |
1408 | udelay(5); | 1418 | *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); |
1409 | break; | 1419 | break; |
1410 | } | 1420 | } |
1411 | } | 1421 | } |
1412 | if (tmp & EMAC_MDIO_COMM_START_BUSY) { | 1422 | if (val & EMAC_MDIO_COMM_START_BUSY) { |
1413 | DP(NETIF_MSG_LINK, "write phy register failed\n"); | 1423 | DP(NETIF_MSG_LINK, "read phy register failed\n"); |
1414 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); | 1424 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); |
1425 | *ret_val = 0; | ||
1415 | rc = -EFAULT; | 1426 | rc = -EFAULT; |
1416 | } | 1427 | } |
1417 | } | 1428 | } |
1418 | 1429 | ||
1419 | /* Restore the saved mode */ | ||
1420 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); | ||
1421 | |||
1422 | return rc; | 1430 | return rc; |
1423 | } | 1431 | } |
1424 | 1432 | ||
1425 | static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, | 1433 | static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, |
1426 | u8 devad, u16 reg, u16 *ret_val) | 1434 | u8 devad, u16 reg, u16 val) |
1427 | { | 1435 | { |
1428 | u32 val, saved_mode; | 1436 | u32 tmp; |
1429 | u16 i; | 1437 | u8 i; |
1430 | int rc = 0; | 1438 | int rc = 0; |
1431 | /* | ||
1432 | * Set clause 45 mode, slow down the MDIO clock to 2.5MHz | ||
1433 | * (a value of 49==0x31) and make sure that the AUTO poll is off | ||
1434 | */ | ||
1435 | |||
1436 | saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); | ||
1437 | val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL | | ||
1438 | EMAC_MDIO_MODE_CLOCK_CNT)); | ||
1439 | val |= (EMAC_MDIO_MODE_CLAUSE_45 | | ||
1440 | (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); | ||
1441 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); | ||
1442 | REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); | ||
1443 | udelay(40); | ||
1444 | 1439 | ||
1445 | /* address */ | 1440 | /* address */ |
1446 | val = ((phy->addr << 21) | (devad << 16) | reg | | 1441 | |
1442 | tmp = ((phy->addr << 21) | (devad << 16) | reg | | ||
1447 | EMAC_MDIO_COMM_COMMAND_ADDRESS | | 1443 | EMAC_MDIO_COMM_COMMAND_ADDRESS | |
1448 | EMAC_MDIO_COMM_START_BUSY); | 1444 | EMAC_MDIO_COMM_START_BUSY); |
1449 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); | 1445 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); |
1450 | 1446 | ||
1451 | for (i = 0; i < 50; i++) { | 1447 | for (i = 0; i < 50; i++) { |
1452 | udelay(10); | 1448 | udelay(10); |
1453 | 1449 | ||
1454 | val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); | 1450 | tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); |
1455 | if (!(val & EMAC_MDIO_COMM_START_BUSY)) { | 1451 | if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { |
1456 | udelay(5); | 1452 | udelay(5); |
1457 | break; | 1453 | break; |
1458 | } | 1454 | } |
1459 | } | 1455 | } |
1460 | if (val & EMAC_MDIO_COMM_START_BUSY) { | 1456 | if (tmp & EMAC_MDIO_COMM_START_BUSY) { |
1461 | DP(NETIF_MSG_LINK, "read phy register failed\n"); | 1457 | DP(NETIF_MSG_LINK, "write phy register failed\n"); |
1462 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); | 1458 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); |
1463 | *ret_val = 0; | ||
1464 | rc = -EFAULT; | 1459 | rc = -EFAULT; |
1465 | 1460 | ||
1466 | } else { | 1461 | } else { |
1467 | /* data */ | 1462 | /* data */ |
1468 | val = ((phy->addr << 21) | (devad << 16) | | 1463 | tmp = ((phy->addr << 21) | (devad << 16) | val | |
1469 | EMAC_MDIO_COMM_COMMAND_READ_45 | | 1464 | EMAC_MDIO_COMM_COMMAND_WRITE_45 | |
1470 | EMAC_MDIO_COMM_START_BUSY); | 1465 | EMAC_MDIO_COMM_START_BUSY); |
1471 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); | 1466 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); |
1472 | 1467 | ||
1473 | for (i = 0; i < 50; i++) { | 1468 | for (i = 0; i < 50; i++) { |
1474 | udelay(10); | 1469 | udelay(10); |
1475 | 1470 | ||
1476 | val = REG_RD(bp, phy->mdio_ctrl + | 1471 | tmp = REG_RD(bp, phy->mdio_ctrl + |
1477 | EMAC_REG_EMAC_MDIO_COMM); | 1472 | EMAC_REG_EMAC_MDIO_COMM); |
1478 | if (!(val & EMAC_MDIO_COMM_START_BUSY)) { | 1473 | if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { |
1479 | *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); | 1474 | udelay(5); |
1480 | break; | 1475 | break; |
1481 | } | 1476 | } |
1482 | } | 1477 | } |
1483 | if (val & EMAC_MDIO_COMM_START_BUSY) { | 1478 | if (tmp & EMAC_MDIO_COMM_START_BUSY) { |
1484 | DP(NETIF_MSG_LINK, "read phy register failed\n"); | 1479 | DP(NETIF_MSG_LINK, "write phy register failed\n"); |
1485 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); | 1480 | netdev_err(bp->dev, "MDC/MDIO access timeout\n"); |
1486 | *ret_val = 0; | ||
1487 | rc = -EFAULT; | 1481 | rc = -EFAULT; |
1488 | } | 1482 | } |
1489 | } | 1483 | } |
1490 | 1484 | ||
1491 | /* Restore the saved mode */ | ||
1492 | REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); | ||
1493 | 1485 | ||
1494 | return rc; | 1486 | return rc; |
1495 | } | 1487 | } |
@@ -8425,6 +8417,8 @@ int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[], | |||
8425 | u32 phy_ver; | 8417 | u32 phy_ver; |
8426 | u8 phy_index; | 8418 | u8 phy_index; |
8427 | u32 ext_phy_type, ext_phy_config; | 8419 | u32 ext_phy_type, ext_phy_config; |
8420 | bnx2x_set_mdio_clk(bp, chip_id, PORT_0); | ||
8421 | bnx2x_set_mdio_clk(bp, chip_id, PORT_1); | ||
8428 | DP(NETIF_MSG_LINK, "Begin common phy init\n"); | 8422 | DP(NETIF_MSG_LINK, "Begin common phy init\n"); |
8429 | 8423 | ||
8430 | /* Check if common init was already done */ | 8424 | /* Check if common init was already done */ |