aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bnx2.c277
1 files changed, 269 insertions, 8 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 56bc41ee9a47..c571da60241d 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -550,6 +550,9 @@ bnx2_report_fw_link(struct bnx2 *bp)
550{ 550{
551 u32 fw_link_status = 0; 551 u32 fw_link_status = 0;
552 552
553 if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
554 return;
555
553 if (bp->link_up) { 556 if (bp->link_up) {
554 u32 bmsr; 557 u32 bmsr;
555 558
@@ -1100,6 +1103,9 @@ bnx2_set_link(struct bnx2 *bp)
1100 return 0; 1103 return 0;
1101 } 1104 }
1102 1105
1106 if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
1107 return 0;
1108
1103 link_up = bp->link_up; 1109 link_up = bp->link_up;
1104 1110
1105 bnx2_enable_bmsr1(bp); 1111 bnx2_enable_bmsr1(bp);
@@ -1210,12 +1216,74 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
1210 return adv; 1216 return adv;
1211} 1217}
1212 1218
1219static int bnx2_fw_sync(struct bnx2 *, u32, int);
1220
1213static int 1221static int
1214bnx2_setup_serdes_phy(struct bnx2 *bp) 1222bnx2_setup_remote_phy(struct bnx2 *bp, u8 port)
1223{
1224 u32 speed_arg = 0, pause_adv;
1225
1226 pause_adv = bnx2_phy_get_pause_adv(bp);
1227
1228 if (bp->autoneg & AUTONEG_SPEED) {
1229 speed_arg |= BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG;
1230 if (bp->advertising & ADVERTISED_10baseT_Half)
1231 speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_10HALF;
1232 if (bp->advertising & ADVERTISED_10baseT_Full)
1233 speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_10FULL;
1234 if (bp->advertising & ADVERTISED_100baseT_Half)
1235 speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_100HALF;
1236 if (bp->advertising & ADVERTISED_100baseT_Full)
1237 speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_100FULL;
1238 if (bp->advertising & ADVERTISED_1000baseT_Full)
1239 speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_1GFULL;
1240 if (bp->advertising & ADVERTISED_2500baseX_Full)
1241 speed_arg |= BNX2_NETLINK_SET_LINK_SPEED_2G5FULL;
1242 } else {
1243 if (bp->req_line_speed == SPEED_2500)
1244 speed_arg = BNX2_NETLINK_SET_LINK_SPEED_2G5FULL;
1245 else if (bp->req_line_speed == SPEED_1000)
1246 speed_arg = BNX2_NETLINK_SET_LINK_SPEED_1GFULL;
1247 else if (bp->req_line_speed == SPEED_100) {
1248 if (bp->req_duplex == DUPLEX_FULL)
1249 speed_arg = BNX2_NETLINK_SET_LINK_SPEED_100FULL;
1250 else
1251 speed_arg = BNX2_NETLINK_SET_LINK_SPEED_100HALF;
1252 } else if (bp->req_line_speed == SPEED_10) {
1253 if (bp->req_duplex == DUPLEX_FULL)
1254 speed_arg = BNX2_NETLINK_SET_LINK_SPEED_10FULL;
1255 else
1256 speed_arg = BNX2_NETLINK_SET_LINK_SPEED_10HALF;
1257 }
1258 }
1259
1260 if (pause_adv & (ADVERTISE_1000XPAUSE | ADVERTISE_PAUSE_CAP))
1261 speed_arg |= BNX2_NETLINK_SET_LINK_FC_SYM_PAUSE;
1262 if (pause_adv & (ADVERTISE_1000XPSE_ASYM | ADVERTISE_1000XPSE_ASYM))
1263 speed_arg |= BNX2_NETLINK_SET_LINK_FC_ASYM_PAUSE;
1264
1265 if (port == PORT_TP)
1266 speed_arg |= BNX2_NETLINK_SET_LINK_PHY_APP_REMOTE |
1267 BNX2_NETLINK_SET_LINK_ETH_AT_WIRESPEED;
1268
1269 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB_ARG0, speed_arg);
1270
1271 spin_unlock_bh(&bp->phy_lock);
1272 bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_CMD_SET_LINK, 0);
1273 spin_lock_bh(&bp->phy_lock);
1274
1275 return 0;
1276}
1277
1278static int
1279bnx2_setup_serdes_phy(struct bnx2 *bp, u8 port)
1215{ 1280{
1216 u32 adv, bmcr; 1281 u32 adv, bmcr;
1217 u32 new_adv = 0; 1282 u32 new_adv = 0;
1218 1283
1284 if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
1285 return (bnx2_setup_remote_phy(bp, port));
1286
1219 if (!(bp->autoneg & AUTONEG_SPEED)) { 1287 if (!(bp->autoneg & AUTONEG_SPEED)) {
1220 u32 new_bmcr; 1288 u32 new_bmcr;
1221 int force_link_down = 0; 1289 int force_link_down = 0;
@@ -1338,8 +1406,58 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
1338#define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL) 1406#define PHY_ALL_1000_SPEED (ADVERTISE_1000HALF | ADVERTISE_1000FULL)
1339 1407
1340static void 1408static void
1409bnx2_set_default_remote_link(struct bnx2 *bp)
1410{
1411 u32 link;
1412
1413 if (bp->phy_port == PORT_TP)
1414 link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_COPPER_LINK);
1415 else
1416 link = REG_RD_IND(bp, bp->shmem_base + BNX2_RPHY_SERDES_LINK);
1417
1418 if (link & BNX2_NETLINK_SET_LINK_ENABLE_AUTONEG) {
1419 bp->req_line_speed = 0;
1420 bp->autoneg |= AUTONEG_SPEED;
1421 bp->advertising = ADVERTISED_Autoneg;
1422 if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
1423 bp->advertising |= ADVERTISED_10baseT_Half;
1424 if (link & BNX2_NETLINK_SET_LINK_SPEED_10FULL)
1425 bp->advertising |= ADVERTISED_10baseT_Full;
1426 if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
1427 bp->advertising |= ADVERTISED_100baseT_Half;
1428 if (link & BNX2_NETLINK_SET_LINK_SPEED_100FULL)
1429 bp->advertising |= ADVERTISED_100baseT_Full;
1430 if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
1431 bp->advertising |= ADVERTISED_1000baseT_Full;
1432 if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
1433 bp->advertising |= ADVERTISED_2500baseX_Full;
1434 } else {
1435 bp->autoneg = 0;
1436 bp->advertising = 0;
1437 bp->req_duplex = DUPLEX_FULL;
1438 if (link & BNX2_NETLINK_SET_LINK_SPEED_10) {
1439 bp->req_line_speed = SPEED_10;
1440 if (link & BNX2_NETLINK_SET_LINK_SPEED_10HALF)
1441 bp->req_duplex = DUPLEX_HALF;
1442 }
1443 if (link & BNX2_NETLINK_SET_LINK_SPEED_100) {
1444 bp->req_line_speed = SPEED_100;
1445 if (link & BNX2_NETLINK_SET_LINK_SPEED_100HALF)
1446 bp->req_duplex = DUPLEX_HALF;
1447 }
1448 if (link & BNX2_NETLINK_SET_LINK_SPEED_1GFULL)
1449 bp->req_line_speed = SPEED_1000;
1450 if (link & BNX2_NETLINK_SET_LINK_SPEED_2G5FULL)
1451 bp->req_line_speed = SPEED_2500;
1452 }
1453}
1454
1455static void
1341bnx2_set_default_link(struct bnx2 *bp) 1456bnx2_set_default_link(struct bnx2 *bp)
1342{ 1457{
1458 if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
1459 return bnx2_set_default_remote_link(bp);
1460
1343 bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL; 1461 bp->autoneg = AUTONEG_SPEED | AUTONEG_FLOW_CTRL;
1344 bp->req_line_speed = 0; 1462 bp->req_line_speed = 0;
1345 if (bp->phy_flags & PHY_SERDES_FLAG) { 1463 if (bp->phy_flags & PHY_SERDES_FLAG) {
@@ -1358,6 +1476,97 @@ bnx2_set_default_link(struct bnx2 *bp)
1358 bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg; 1476 bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
1359} 1477}
1360 1478
1479static void
1480bnx2_remote_phy_event(struct bnx2 *bp)
1481{
1482 u32 msg;
1483 u8 link_up = bp->link_up;
1484 u8 old_port;
1485
1486 msg = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
1487
1488 if ((msg & BNX2_LINK_STATUS_LINK_UP) == BNX2_LINK_STATUS_LINK_DOWN)
1489 bp->link_up = 0;
1490 else {
1491 u32 speed;
1492
1493 bp->link_up = 1;
1494 speed = msg & BNX2_LINK_STATUS_SPEED_MASK;
1495 bp->duplex = DUPLEX_FULL;
1496 switch (speed) {
1497 case BNX2_LINK_STATUS_10HALF:
1498 bp->duplex = DUPLEX_HALF;
1499 case BNX2_LINK_STATUS_10FULL:
1500 bp->line_speed = SPEED_10;
1501 break;
1502 case BNX2_LINK_STATUS_100HALF:
1503 bp->duplex = DUPLEX_HALF;
1504 case BNX2_LINK_STATUS_100BASE_T4:
1505 case BNX2_LINK_STATUS_100FULL:
1506 bp->line_speed = SPEED_100;
1507 break;
1508 case BNX2_LINK_STATUS_1000HALF:
1509 bp->duplex = DUPLEX_HALF;
1510 case BNX2_LINK_STATUS_1000FULL:
1511 bp->line_speed = SPEED_1000;
1512 break;
1513 case BNX2_LINK_STATUS_2500HALF:
1514 bp->duplex = DUPLEX_HALF;
1515 case BNX2_LINK_STATUS_2500FULL:
1516 bp->line_speed = SPEED_2500;
1517 break;
1518 default:
1519 bp->line_speed = 0;
1520 break;
1521 }
1522
1523 spin_lock(&bp->phy_lock);
1524 bp->flow_ctrl = 0;
1525 if ((bp->autoneg & (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) !=
1526 (AUTONEG_SPEED | AUTONEG_FLOW_CTRL)) {
1527 if (bp->duplex == DUPLEX_FULL)
1528 bp->flow_ctrl = bp->req_flow_ctrl;
1529 } else {
1530 if (msg & BNX2_LINK_STATUS_TX_FC_ENABLED)
1531 bp->flow_ctrl |= FLOW_CTRL_TX;
1532 if (msg & BNX2_LINK_STATUS_RX_FC_ENABLED)
1533 bp->flow_ctrl |= FLOW_CTRL_RX;
1534 }
1535
1536 old_port = bp->phy_port;
1537 if (msg & BNX2_LINK_STATUS_SERDES_LINK)
1538 bp->phy_port = PORT_FIBRE;
1539 else
1540 bp->phy_port = PORT_TP;
1541
1542 if (old_port != bp->phy_port)
1543 bnx2_set_default_link(bp);
1544
1545 spin_unlock(&bp->phy_lock);
1546 }
1547 if (bp->link_up != link_up)
1548 bnx2_report_link(bp);
1549
1550 bnx2_set_mac_link(bp);
1551}
1552
1553static int
1554bnx2_set_remote_link(struct bnx2 *bp)
1555{
1556 u32 evt_code;
1557
1558 evt_code = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_EVT_CODE_MB);
1559 switch (evt_code) {
1560 case BNX2_FW_EVT_CODE_LINK_EVENT:
1561 bnx2_remote_phy_event(bp);
1562 break;
1563 case BNX2_FW_EVT_CODE_SW_TIMER_EXPIRATION_EVENT:
1564 default:
1565 break;
1566 }
1567 return 0;
1568}
1569
1361static int 1570static int
1362bnx2_setup_copper_phy(struct bnx2 *bp) 1571bnx2_setup_copper_phy(struct bnx2 *bp)
1363{ 1572{
@@ -1456,13 +1665,13 @@ bnx2_setup_copper_phy(struct bnx2 *bp)
1456} 1665}
1457 1666
1458static int 1667static int
1459bnx2_setup_phy(struct bnx2 *bp) 1668bnx2_setup_phy(struct bnx2 *bp, u8 port)
1460{ 1669{
1461 if (bp->loopback == MAC_LOOPBACK) 1670 if (bp->loopback == MAC_LOOPBACK)
1462 return 0; 1671 return 0;
1463 1672
1464 if (bp->phy_flags & PHY_SERDES_FLAG) { 1673 if (bp->phy_flags & PHY_SERDES_FLAG) {
1465 return (bnx2_setup_serdes_phy(bp)); 1674 return (bnx2_setup_serdes_phy(bp, port));
1466 } 1675 }
1467 else { 1676 else {
1468 return (bnx2_setup_copper_phy(bp)); 1677 return (bnx2_setup_copper_phy(bp));
@@ -1682,6 +1891,9 @@ bnx2_init_phy(struct bnx2 *bp)
1682 1891
1683 REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK); 1892 REG_WR(bp, BNX2_EMAC_ATTENTION_ENA, BNX2_EMAC_ATTENTION_ENA_LINK);
1684 1893
1894 if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
1895 goto setup_phy;
1896
1685 bnx2_read_phy(bp, MII_PHYSID1, &val); 1897 bnx2_read_phy(bp, MII_PHYSID1, &val);
1686 bp->phy_id = val << 16; 1898 bp->phy_id = val << 16;
1687 bnx2_read_phy(bp, MII_PHYSID2, &val); 1899 bnx2_read_phy(bp, MII_PHYSID2, &val);
@@ -1699,7 +1911,9 @@ bnx2_init_phy(struct bnx2 *bp)
1699 rc = bnx2_init_copper_phy(bp); 1911 rc = bnx2_init_copper_phy(bp);
1700 } 1912 }
1701 1913
1702 bnx2_setup_phy(bp); 1914setup_phy:
1915 if (!rc)
1916 rc = bnx2_setup_phy(bp, bp->phy_port);
1703 1917
1704 return rc; 1918 return rc;
1705} 1919}
@@ -2007,6 +2221,9 @@ bnx2_phy_int(struct bnx2 *bp)
2007 bnx2_set_link(bp); 2221 bnx2_set_link(bp);
2008 spin_unlock(&bp->phy_lock); 2222 spin_unlock(&bp->phy_lock);
2009 } 2223 }
2224 if (bnx2_phy_event_is_set(bp, STATUS_ATTN_BITS_TIMER_ABORT))
2225 bnx2_set_remote_link(bp);
2226
2010} 2227}
2011 2228
2012static void 2229static void
@@ -2345,7 +2562,8 @@ bnx2_interrupt(int irq, void *dev_instance)
2345 return IRQ_HANDLED; 2562 return IRQ_HANDLED;
2346} 2563}
2347 2564
2348#define STATUS_ATTN_EVENTS STATUS_ATTN_BITS_LINK_STATE 2565#define STATUS_ATTN_EVENTS (STATUS_ATTN_BITS_LINK_STATE | \
2566 STATUS_ATTN_BITS_TIMER_ABORT)
2349 2567
2350static inline int 2568static inline int
2351bnx2_has_work(struct bnx2 *bp) 2569bnx2_has_work(struct bnx2 *bp)
@@ -3585,6 +3803,36 @@ nvram_write_end:
3585 return rc; 3803 return rc;
3586} 3804}
3587 3805
3806static void
3807bnx2_init_remote_phy(struct bnx2 *bp)
3808{
3809 u32 val;
3810
3811 bp->phy_flags &= ~REMOTE_PHY_CAP_FLAG;
3812 if (!(bp->phy_flags & PHY_SERDES_FLAG))
3813 return;
3814
3815 val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_CAP_MB);
3816 if ((val & BNX2_FW_CAP_SIGNATURE_MASK) != BNX2_FW_CAP_SIGNATURE)
3817 return;
3818
3819 if (val & BNX2_FW_CAP_REMOTE_PHY_CAPABLE) {
3820 if (netif_running(bp->dev)) {
3821 val = BNX2_DRV_ACK_CAP_SIGNATURE |
3822 BNX2_FW_CAP_REMOTE_PHY_CAPABLE;
3823 REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_ACK_CAP_MB,
3824 val);
3825 }
3826 bp->phy_flags |= REMOTE_PHY_CAP_FLAG;
3827
3828 val = REG_RD_IND(bp, bp->shmem_base + BNX2_LINK_STATUS);
3829 if (val & BNX2_LINK_STATUS_SERDES_LINK)
3830 bp->phy_port = PORT_FIBRE;
3831 else
3832 bp->phy_port = PORT_TP;
3833 }
3834}
3835
3588static int 3836static int
3589bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) 3837bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
3590{ 3838{
@@ -3665,6 +3913,12 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
3665 if (rc) 3913 if (rc)
3666 return rc; 3914 return rc;
3667 3915
3916 spin_lock_bh(&bp->phy_lock);
3917 bnx2_init_remote_phy(bp);
3918 if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
3919 bnx2_set_default_remote_link(bp);
3920 spin_unlock_bh(&bp->phy_lock);
3921
3668 if (CHIP_ID(bp) == CHIP_ID_5706_A0) { 3922 if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
3669 /* Adjust the voltage regular to two steps lower. The default 3923 /* Adjust the voltage regular to two steps lower. The default
3670 * of this register is 0x0000000e. */ 3924 * of this register is 0x0000000e. */
@@ -4092,8 +4346,8 @@ bnx2_init_nic(struct bnx2 *bp)
4092 4346
4093 spin_lock_bh(&bp->phy_lock); 4347 spin_lock_bh(&bp->phy_lock);
4094 bnx2_init_phy(bp); 4348 bnx2_init_phy(bp);
4095 spin_unlock_bh(&bp->phy_lock);
4096 bnx2_set_link(bp); 4349 bnx2_set_link(bp);
4350 spin_unlock_bh(&bp->phy_lock);
4097 return 0; 4351 return 0;
4098} 4352}
4099 4353
@@ -4623,6 +4877,9 @@ bnx2_5706_serdes_timer(struct bnx2 *bp)
4623static void 4877static void
4624bnx2_5708_serdes_timer(struct bnx2 *bp) 4878bnx2_5708_serdes_timer(struct bnx2 *bp)
4625{ 4879{
4880 if (bp->phy_flags & REMOTE_PHY_CAP_FLAG)
4881 return;
4882
4626 if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) { 4883 if ((bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) == 0) {
4627 bp->serdes_an_pending = 0; 4884 bp->serdes_an_pending = 0;
4628 return; 4885 return;
@@ -5222,7 +5479,7 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
5222 5479
5223 spin_lock_bh(&bp->phy_lock); 5480 spin_lock_bh(&bp->phy_lock);
5224 5481
5225 bnx2_setup_phy(bp); 5482 bnx2_setup_phy(bp, bp->phy_port);
5226 5483
5227 spin_unlock_bh(&bp->phy_lock); 5484 spin_unlock_bh(&bp->phy_lock);
5228 5485
@@ -5566,7 +5823,7 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
5566 5823
5567 spin_lock_bh(&bp->phy_lock); 5824 spin_lock_bh(&bp->phy_lock);
5568 5825
5569 bnx2_setup_phy(bp); 5826 bnx2_setup_phy(bp, bp->phy_port);
5570 5827
5571 spin_unlock_bh(&bp->phy_lock); 5828 spin_unlock_bh(&bp->phy_lock);
5572 5829
@@ -6338,7 +6595,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
6338 else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) 6595 else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT)
6339 bp->phy_flags |= PHY_SERDES_FLAG; 6596 bp->phy_flags |= PHY_SERDES_FLAG;
6340 6597
6598 bp->phy_port = PORT_TP;
6341 if (bp->phy_flags & PHY_SERDES_FLAG) { 6599 if (bp->phy_flags & PHY_SERDES_FLAG) {
6600 bp->phy_port = PORT_FIBRE;
6342 bp->flags |= NO_WOL_FLAG; 6601 bp->flags |= NO_WOL_FLAG;
6343 if (CHIP_NUM(bp) != CHIP_NUM_5706) { 6602 if (CHIP_NUM(bp) != CHIP_NUM_5706) {
6344 bp->phy_addr = 2; 6603 bp->phy_addr = 2;
@@ -6347,6 +6606,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
6347 if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) 6606 if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
6348 bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; 6607 bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
6349 } 6608 }
6609 bnx2_init_remote_phy(bp);
6610
6350 } else if (CHIP_NUM(bp) == CHIP_NUM_5706 || 6611 } else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
6351 CHIP_NUM(bp) == CHIP_NUM_5708) 6612 CHIP_NUM(bp) == CHIP_NUM_5708)
6352 bp->phy_flags |= PHY_CRC_FIX_FLAG; 6613 bp->phy_flags |= PHY_CRC_FIX_FLAG;