diff options
author | Michael Chan <mchan@broadcom.com> | 2005-11-04 11:51:21 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2005-11-05 21:00:03 -0500 |
commit | e3648b3d8de3b37fae7acbb57db1e001a19cd3b7 (patch) | |
tree | 3de20299e878d60d7b5904f572f325f432e8891e /drivers/net/bnx2.c | |
parent | 371377091dff14090cbe995d0a9291364f8583cb (diff) |
[PATCH] bnx2: update firmware handshake for 5708
Dynamically determine the shared memory location where eeprom
parameters are stored instead of using a fixed location.
Add speed reporting to management firmware. This allows management
firmware to know the current speed without contending for MII
registers.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 94 |
1 files changed, 79 insertions, 15 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 08086a9e5411..affb67372e02 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -437,6 +437,62 @@ alloc_mem_err: | |||
437 | } | 437 | } |
438 | 438 | ||
439 | static void | 439 | static void |
440 | bnx2_report_fw_link(struct bnx2 *bp) | ||
441 | { | ||
442 | u32 fw_link_status = 0; | ||
443 | |||
444 | if (bp->link_up) { | ||
445 | u32 bmsr; | ||
446 | |||
447 | switch (bp->line_speed) { | ||
448 | case SPEED_10: | ||
449 | if (bp->duplex == DUPLEX_HALF) | ||
450 | fw_link_status = BNX2_LINK_STATUS_10HALF; | ||
451 | else | ||
452 | fw_link_status = BNX2_LINK_STATUS_10FULL; | ||
453 | break; | ||
454 | case SPEED_100: | ||
455 | if (bp->duplex == DUPLEX_HALF) | ||
456 | fw_link_status = BNX2_LINK_STATUS_100HALF; | ||
457 | else | ||
458 | fw_link_status = BNX2_LINK_STATUS_100FULL; | ||
459 | break; | ||
460 | case SPEED_1000: | ||
461 | if (bp->duplex == DUPLEX_HALF) | ||
462 | fw_link_status = BNX2_LINK_STATUS_1000HALF; | ||
463 | else | ||
464 | fw_link_status = BNX2_LINK_STATUS_1000FULL; | ||
465 | break; | ||
466 | case SPEED_2500: | ||
467 | if (bp->duplex == DUPLEX_HALF) | ||
468 | fw_link_status = BNX2_LINK_STATUS_2500HALF; | ||
469 | else | ||
470 | fw_link_status = BNX2_LINK_STATUS_2500FULL; | ||
471 | break; | ||
472 | } | ||
473 | |||
474 | fw_link_status |= BNX2_LINK_STATUS_LINK_UP; | ||
475 | |||
476 | if (bp->autoneg) { | ||
477 | fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED; | ||
478 | |||
479 | bnx2_read_phy(bp, MII_BMSR, &bmsr); | ||
480 | bnx2_read_phy(bp, MII_BMSR, &bmsr); | ||
481 | |||
482 | if (!(bmsr & BMSR_ANEGCOMPLETE) || | ||
483 | bp->phy_flags & PHY_PARALLEL_DETECT_FLAG) | ||
484 | fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET; | ||
485 | else | ||
486 | fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE; | ||
487 | } | ||
488 | } | ||
489 | else | ||
490 | fw_link_status = BNX2_LINK_STATUS_LINK_DOWN; | ||
491 | |||
492 | REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status); | ||
493 | } | ||
494 | |||
495 | static void | ||
440 | bnx2_report_link(struct bnx2 *bp) | 496 | bnx2_report_link(struct bnx2 *bp) |
441 | { | 497 | { |
442 | if (bp->link_up) { | 498 | if (bp->link_up) { |
@@ -467,6 +523,8 @@ bnx2_report_link(struct bnx2 *bp) | |||
467 | netif_carrier_off(bp->dev); | 523 | netif_carrier_off(bp->dev); |
468 | printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name); | 524 | printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name); |
469 | } | 525 | } |
526 | |||
527 | bnx2_report_fw_link(bp); | ||
470 | } | 528 | } |
471 | 529 | ||
472 | static void | 530 | static void |
@@ -1123,13 +1181,13 @@ bnx2_init_5708s_phy(struct bnx2 *bp) | |||
1123 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); | 1181 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG); |
1124 | } | 1182 | } |
1125 | 1183 | ||
1126 | val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_CONFIG) & | 1184 | val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) & |
1127 | BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK; | 1185 | BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK; |
1128 | 1186 | ||
1129 | if (val) { | 1187 | if (val) { |
1130 | u32 is_backplane; | 1188 | u32 is_backplane; |
1131 | 1189 | ||
1132 | is_backplane = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | 1190 | is_backplane = REG_RD_IND(bp, bp->shmem_base + |
1133 | BNX2_SHARED_HW_CFG_CONFIG); | 1191 | BNX2_SHARED_HW_CFG_CONFIG); |
1134 | if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) { | 1192 | if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) { |
1135 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, | 1193 | bnx2_write_phy(bp, BCM5708S_BLK_ADDR, |
@@ -1280,13 +1338,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data) | |||
1280 | bp->fw_wr_seq++; | 1338 | bp->fw_wr_seq++; |
1281 | msg_data |= bp->fw_wr_seq; | 1339 | msg_data |= bp->fw_wr_seq; |
1282 | 1340 | ||
1283 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); | 1341 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); |
1284 | 1342 | ||
1285 | /* wait for an acknowledgement. */ | 1343 | /* wait for an acknowledgement. */ |
1286 | for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) { | 1344 | for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) { |
1287 | udelay(5); | 1345 | udelay(5); |
1288 | 1346 | ||
1289 | val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB); | 1347 | val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB); |
1290 | 1348 | ||
1291 | if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) | 1349 | if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ)) |
1292 | break; | 1350 | break; |
@@ -1299,7 +1357,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data) | |||
1299 | msg_data &= ~BNX2_DRV_MSG_CODE; | 1357 | msg_data &= ~BNX2_DRV_MSG_CODE; |
1300 | msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; | 1358 | msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT; |
1301 | 1359 | ||
1302 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data); | 1360 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data); |
1303 | 1361 | ||
1304 | bp->fw_timed_out = 1; | 1362 | bp->fw_timed_out = 1; |
1305 | 1363 | ||
@@ -2935,7 +2993,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |||
2935 | 2993 | ||
2936 | /* Deposit a driver reset signature so the firmware knows that | 2994 | /* Deposit a driver reset signature so the firmware knows that |
2937 | * this is a soft reset. */ | 2995 | * this is a soft reset. */ |
2938 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE, | 2996 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE, |
2939 | BNX2_DRV_RESET_SIGNATURE_MAGIC); | 2997 | BNX2_DRV_RESET_SIGNATURE_MAGIC); |
2940 | 2998 | ||
2941 | bp->fw_timed_out = 0; | 2999 | bp->fw_timed_out = 0; |
@@ -4012,7 +4070,7 @@ bnx2_timer(unsigned long data) | |||
4012 | goto bnx2_restart_timer; | 4070 | goto bnx2_restart_timer; |
4013 | 4071 | ||
4014 | msg = (u32) ++bp->fw_drv_pulse_wr_seq; | 4072 | msg = (u32) ++bp->fw_drv_pulse_wr_seq; |
4015 | REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg); | 4073 | REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg); |
4016 | 4074 | ||
4017 | if ((bp->phy_flags & PHY_SERDES_FLAG) && | 4075 | if ((bp->phy_flags & PHY_SERDES_FLAG) && |
4018 | (CHIP_NUM(bp) == CHIP_NUM_5706)) { | 4076 | (CHIP_NUM(bp) == CHIP_NUM_5706)) { |
@@ -5483,10 +5541,18 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5483 | 5541 | ||
5484 | bnx2_init_nvram(bp); | 5542 | bnx2_init_nvram(bp); |
5485 | 5543 | ||
5544 | reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE); | ||
5545 | |||
5546 | if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) == | ||
5547 | BNX2_SHM_HDR_SIGNATURE_SIG) | ||
5548 | bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0); | ||
5549 | else | ||
5550 | bp->shmem_base = HOST_VIEW_SHMEM_BASE; | ||
5551 | |||
5486 | /* Get the permanent MAC address. First we need to make sure the | 5552 | /* Get the permanent MAC address. First we need to make sure the |
5487 | * firmware is actually running. | 5553 | * firmware is actually running. |
5488 | */ | 5554 | */ |
5489 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE); | 5555 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE); |
5490 | 5556 | ||
5491 | if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != | 5557 | if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) != |
5492 | BNX2_DEV_INFO_SIGNATURE_MAGIC) { | 5558 | BNX2_DEV_INFO_SIGNATURE_MAGIC) { |
@@ -5495,14 +5561,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5495 | goto err_out_unmap; | 5561 | goto err_out_unmap; |
5496 | } | 5562 | } |
5497 | 5563 | ||
5498 | bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | 5564 | bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV); |
5499 | BNX2_DEV_INFO_BC_REV); | ||
5500 | 5565 | ||
5501 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER); | 5566 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER); |
5502 | bp->mac_addr[0] = (u8) (reg >> 8); | 5567 | bp->mac_addr[0] = (u8) (reg >> 8); |
5503 | bp->mac_addr[1] = (u8) reg; | 5568 | bp->mac_addr[1] = (u8) reg; |
5504 | 5569 | ||
5505 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER); | 5570 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER); |
5506 | bp->mac_addr[2] = (u8) (reg >> 24); | 5571 | bp->mac_addr[2] = (u8) (reg >> 24); |
5507 | bp->mac_addr[3] = (u8) (reg >> 16); | 5572 | bp->mac_addr[3] = (u8) (reg >> 16); |
5508 | bp->mac_addr[4] = (u8) (reg >> 8); | 5573 | bp->mac_addr[4] = (u8) (reg >> 8); |
@@ -5538,7 +5603,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5538 | bp->flags |= NO_WOL_FLAG; | 5603 | bp->flags |= NO_WOL_FLAG; |
5539 | if (CHIP_NUM(bp) == CHIP_NUM_5708) { | 5604 | if (CHIP_NUM(bp) == CHIP_NUM_5708) { |
5540 | bp->phy_addr = 2; | 5605 | bp->phy_addr = 2; |
5541 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | 5606 | reg = REG_RD_IND(bp, bp->shmem_base + |
5542 | BNX2_SHARED_HW_CFG_CONFIG); | 5607 | BNX2_SHARED_HW_CFG_CONFIG); |
5543 | if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) | 5608 | if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) |
5544 | bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; | 5609 | bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; |
@@ -5562,8 +5627,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) | |||
5562 | if (bp->phy_flags & PHY_SERDES_FLAG) { | 5627 | if (bp->phy_flags & PHY_SERDES_FLAG) { |
5563 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; | 5628 | bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg; |
5564 | 5629 | ||
5565 | reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + | 5630 | reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG); |
5566 | BNX2_PORT_HW_CFG_CONFIG); | ||
5567 | reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; | 5631 | reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK; |
5568 | if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { | 5632 | if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) { |
5569 | bp->autoneg = 0; | 5633 | bp->autoneg = 0; |