forked from Minki/linux
[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>
This commit is contained in:
parent
371377091d
commit
e3648b3d8d
@ -436,6 +436,62 @@ alloc_mem_err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void
|
||||
bnx2_report_fw_link(struct bnx2 *bp)
|
||||
{
|
||||
u32 fw_link_status = 0;
|
||||
|
||||
if (bp->link_up) {
|
||||
u32 bmsr;
|
||||
|
||||
switch (bp->line_speed) {
|
||||
case SPEED_10:
|
||||
if (bp->duplex == DUPLEX_HALF)
|
||||
fw_link_status = BNX2_LINK_STATUS_10HALF;
|
||||
else
|
||||
fw_link_status = BNX2_LINK_STATUS_10FULL;
|
||||
break;
|
||||
case SPEED_100:
|
||||
if (bp->duplex == DUPLEX_HALF)
|
||||
fw_link_status = BNX2_LINK_STATUS_100HALF;
|
||||
else
|
||||
fw_link_status = BNX2_LINK_STATUS_100FULL;
|
||||
break;
|
||||
case SPEED_1000:
|
||||
if (bp->duplex == DUPLEX_HALF)
|
||||
fw_link_status = BNX2_LINK_STATUS_1000HALF;
|
||||
else
|
||||
fw_link_status = BNX2_LINK_STATUS_1000FULL;
|
||||
break;
|
||||
case SPEED_2500:
|
||||
if (bp->duplex == DUPLEX_HALF)
|
||||
fw_link_status = BNX2_LINK_STATUS_2500HALF;
|
||||
else
|
||||
fw_link_status = BNX2_LINK_STATUS_2500FULL;
|
||||
break;
|
||||
}
|
||||
|
||||
fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
|
||||
|
||||
if (bp->autoneg) {
|
||||
fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
|
||||
|
||||
bnx2_read_phy(bp, MII_BMSR, &bmsr);
|
||||
bnx2_read_phy(bp, MII_BMSR, &bmsr);
|
||||
|
||||
if (!(bmsr & BMSR_ANEGCOMPLETE) ||
|
||||
bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
|
||||
fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
|
||||
else
|
||||
fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
|
||||
}
|
||||
}
|
||||
else
|
||||
fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
|
||||
|
||||
REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
|
||||
}
|
||||
|
||||
static void
|
||||
bnx2_report_link(struct bnx2 *bp)
|
||||
{
|
||||
@ -467,6 +523,8 @@ bnx2_report_link(struct bnx2 *bp)
|
||||
netif_carrier_off(bp->dev);
|
||||
printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
|
||||
}
|
||||
|
||||
bnx2_report_fw_link(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1123,13 +1181,13 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
|
||||
bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
|
||||
}
|
||||
|
||||
val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_CONFIG) &
|
||||
val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
|
||||
BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
|
||||
|
||||
if (val) {
|
||||
u32 is_backplane;
|
||||
|
||||
is_backplane = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
|
||||
is_backplane = REG_RD_IND(bp, bp->shmem_base +
|
||||
BNX2_SHARED_HW_CFG_CONFIG);
|
||||
if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
|
||||
bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
|
||||
@ -1280,13 +1338,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
|
||||
bp->fw_wr_seq++;
|
||||
msg_data |= bp->fw_wr_seq;
|
||||
|
||||
REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
|
||||
REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
|
||||
|
||||
/* wait for an acknowledgement. */
|
||||
for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) {
|
||||
udelay(5);
|
||||
|
||||
val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB);
|
||||
val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
|
||||
|
||||
if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
|
||||
break;
|
||||
@ -1299,7 +1357,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_data)
|
||||
msg_data &= ~BNX2_DRV_MSG_CODE;
|
||||
msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
|
||||
|
||||
REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
|
||||
REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
|
||||
|
||||
bp->fw_timed_out = 1;
|
||||
|
||||
@ -2935,7 +2993,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
|
||||
|
||||
/* Deposit a driver reset signature so the firmware knows that
|
||||
* this is a soft reset. */
|
||||
REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE,
|
||||
REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
|
||||
BNX2_DRV_RESET_SIGNATURE_MAGIC);
|
||||
|
||||
bp->fw_timed_out = 0;
|
||||
@ -4012,7 +4070,7 @@ bnx2_timer(unsigned long data)
|
||||
goto bnx2_restart_timer;
|
||||
|
||||
msg = (u32) ++bp->fw_drv_pulse_wr_seq;
|
||||
REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg);
|
||||
REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
|
||||
|
||||
if ((bp->phy_flags & PHY_SERDES_FLAG) &&
|
||||
(CHIP_NUM(bp) == CHIP_NUM_5706)) {
|
||||
@ -5483,10 +5541,18 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
||||
|
||||
bnx2_init_nvram(bp);
|
||||
|
||||
reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
|
||||
|
||||
if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
|
||||
BNX2_SHM_HDR_SIGNATURE_SIG)
|
||||
bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
|
||||
else
|
||||
bp->shmem_base = HOST_VIEW_SHMEM_BASE;
|
||||
|
||||
/* Get the permanent MAC address. First we need to make sure the
|
||||
* firmware is actually running.
|
||||
*/
|
||||
reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE);
|
||||
reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
|
||||
|
||||
if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
|
||||
BNX2_DEV_INFO_SIGNATURE_MAGIC) {
|
||||
@ -5495,14 +5561,13 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
||||
goto err_out_unmap;
|
||||
}
|
||||
|
||||
bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
|
||||
BNX2_DEV_INFO_BC_REV);
|
||||
bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
|
||||
|
||||
reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER);
|
||||
reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
|
||||
bp->mac_addr[0] = (u8) (reg >> 8);
|
||||
bp->mac_addr[1] = (u8) reg;
|
||||
|
||||
reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER);
|
||||
reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
|
||||
bp->mac_addr[2] = (u8) (reg >> 24);
|
||||
bp->mac_addr[3] = (u8) (reg >> 16);
|
||||
bp->mac_addr[4] = (u8) (reg >> 8);
|
||||
@ -5538,7 +5603,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
||||
bp->flags |= NO_WOL_FLAG;
|
||||
if (CHIP_NUM(bp) == CHIP_NUM_5708) {
|
||||
bp->phy_addr = 2;
|
||||
reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
|
||||
reg = REG_RD_IND(bp, bp->shmem_base +
|
||||
BNX2_SHARED_HW_CFG_CONFIG);
|
||||
if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
|
||||
bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
|
||||
@ -5562,8 +5627,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
||||
if (bp->phy_flags & PHY_SERDES_FLAG) {
|
||||
bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
|
||||
|
||||
reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
|
||||
BNX2_PORT_HW_CFG_CONFIG);
|
||||
reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
|
||||
reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
|
||||
if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
|
||||
bp->autoneg = 0;
|
||||
|
@ -3715,6 +3715,15 @@ struct l2_fhdr {
|
||||
#define BNX2_MCP_ROM 0x00150000
|
||||
#define BNX2_MCP_SCRATCH 0x00160000
|
||||
|
||||
#define BNX2_SHM_HDR_SIGNATURE BNX2_MCP_SCRATCH
|
||||
#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK 0xffff0000
|
||||
#define BNX2_SHM_HDR_SIGNATURE_SIG 0x53530000
|
||||
#define BNX2_SHM_HDR_SIGNATURE_VER_MASK 0x000000ff
|
||||
#define BNX2_SHM_HDR_SIGNATURE_VER_ONE 0x00000001
|
||||
|
||||
#define BNX2_SHM_HDR_ADDR_0 BNX2_MCP_SCRATCH + 4
|
||||
#define BNX2_SHM_HDR_ADDR_1 BNX2_MCP_SCRATCH + 8
|
||||
|
||||
|
||||
#define NUM_MC_HASH_REGISTERS 8
|
||||
|
||||
@ -4052,6 +4061,8 @@ struct bnx2 {
|
||||
|
||||
u8 mac_addr[8];
|
||||
|
||||
u32 shmem_base;
|
||||
|
||||
u32 fw_ver;
|
||||
|
||||
int pm_cap;
|
||||
@ -4191,6 +4202,38 @@ struct fw_info {
|
||||
#define BNX2_FW_MSG_STATUS_FAILURE 0x00ff0000
|
||||
|
||||
#define BNX2_LINK_STATUS 0x0000000c
|
||||
#define BNX2_LINK_STATUS_INIT_VALUE 0xffffffff
|
||||
#define BNX2_LINK_STATUS_LINK_UP 0x1
|
||||
#define BNX2_LINK_STATUS_LINK_DOWN 0x0
|
||||
#define BNX2_LINK_STATUS_SPEED_MASK 0x1e
|
||||
#define BNX2_LINK_STATUS_AN_INCOMPLETE (0<<1)
|
||||
#define BNX2_LINK_STATUS_10HALF (1<<1)
|
||||
#define BNX2_LINK_STATUS_10FULL (2<<1)
|
||||
#define BNX2_LINK_STATUS_100HALF (3<<1)
|
||||
#define BNX2_LINK_STATUS_100BASE_T4 (4<<1)
|
||||
#define BNX2_LINK_STATUS_100FULL (5<<1)
|
||||
#define BNX2_LINK_STATUS_1000HALF (6<<1)
|
||||
#define BNX2_LINK_STATUS_1000FULL (7<<1)
|
||||
#define BNX2_LINK_STATUS_2500HALF (8<<1)
|
||||
#define BNX2_LINK_STATUS_2500FULL (9<<1)
|
||||
#define BNX2_LINK_STATUS_AN_ENABLED (1<<5)
|
||||
#define BNX2_LINK_STATUS_AN_COMPLETE (1<<6)
|
||||
#define BNX2_LINK_STATUS_PARALLEL_DET (1<<7)
|
||||
#define BNX2_LINK_STATUS_RESERVED (1<<8)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_1000FULL (1<<9)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_1000HALF (1<<10)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_100BT4 (1<<11)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_100FULL (1<<12)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_100HALF (1<<13)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_10FULL (1<<14)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_10HALF (1<<15)
|
||||
#define BNX2_LINK_STATUS_TX_FC_ENABLED (1<<16)
|
||||
#define BNX2_LINK_STATUS_RX_FC_ENABLED (1<<17)
|
||||
#define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP (1<<18)
|
||||
#define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP (1<<19)
|
||||
#define BNX2_LINK_STATUS_SERDES_LINK (1<<20)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_2500FULL (1<<21)
|
||||
#define BNX2_LINK_STATUS_PARTNER_AD_2500HALF (1<<22)
|
||||
|
||||
#define BNX2_DRV_PULSE_MB 0x00000010
|
||||
#define BNX2_DRV_PULSE_SEQ_MASK 0x00007fff
|
||||
|
Loading…
Reference in New Issue
Block a user