diff options
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index ada5e9b..ca5acc4 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -57,8 +57,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.5.2" -#define DRV_MODULE_RELDATE "December 13, 2006" +#define DRV_MODULE_VERSION "1.5.3" +#define DRV_MODULE_RELDATE "January 8, 2007" #define RUN_AT(x) (jiffies + (x)) @@ -1345,8 +1345,6 @@ bnx2_init_copper_phy(struct bnx2 *bp) { u32 val; - bp->phy_flags |= PHY_CRC_FIX_FLAG; - if (bp->phy_flags & PHY_CRC_FIX_FLAG) { bnx2_write_phy(bp, 0x18, 0x0c00); bnx2_write_phy(bp, 0x17, 0x000a); @@ -3085,7 +3083,7 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, int buf_size) { u32 written, offset32, len32; - u8 *buf, start[4], end[4], *flash_buffer = NULL; + u8 *buf, start[4], end[4], *align_buf = NULL, *flash_buffer = NULL; int rc = 0; int align_start, align_end; @@ -3113,16 +3111,17 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, } if (align_start || align_end) { - buf = kmalloc(len32, GFP_KERNEL); - if (buf == NULL) + align_buf = kmalloc(len32, GFP_KERNEL); + if (align_buf == NULL) return -ENOMEM; if (align_start) { - memcpy(buf, start, 4); + memcpy(align_buf, start, 4); } if (align_end) { - memcpy(buf + len32 - 4, end, 4); + memcpy(align_buf + len32 - 4, end, 4); } - memcpy(buf + align_start, data_buf, buf_size); + memcpy(align_buf + align_start, data_buf, buf_size); + buf = align_buf; } if (bp->flash_info->buffered == 0) { @@ -3256,11 +3255,8 @@ bnx2_nvram_write(struct bnx2 *bp, u32 offset, u8 *data_buf, } nvram_write_end: - if (bp->flash_info->buffered == 0) - kfree(flash_buffer); - - if (align_start || align_end) - kfree(buf); + kfree(flash_buffer); + kfree(align_buf); return rc; } @@ -5645,6 +5641,44 @@ poll_bnx2(struct net_device *dev) } #endif +static void __devinit +bnx2_get_5709_media(struct bnx2 *bp) +{ + u32 val = REG_RD(bp, BNX2_MISC_DUAL_MEDIA_CTRL); + u32 bond_id = val & BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID; + u32 strap; + + if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) + return; + else if (bond_id == BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) { + bp->phy_flags |= PHY_SERDES_FLAG; + return; + } + + if (val & BNX2_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE) + strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21; + else + strap = (val & BNX2_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8; + + if (PCI_FUNC(bp->pdev->devfn) == 0) { + switch (strap) { + case 0x4: + case 0x5: + case 0x6: + bp->phy_flags |= PHY_SERDES_FLAG; + return; + } + } else { + switch (strap) { + case 0x1: + case 0x2: + case 0x4: + bp->phy_flags |= PHY_SERDES_FLAG; + return; + } + } +} + static int __devinit bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) { @@ -5865,10 +5899,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->phy_addr = 1; /* Disable WOL support if we are running on a SERDES chip. */ - if (CHIP_NUM(bp) == CHIP_NUM_5709) { - if (CHIP_BOND_ID(bp) != BNX2_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) - bp->phy_flags |= PHY_SERDES_FLAG; - } else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) + if (CHIP_NUM(bp) == CHIP_NUM_5709) + bnx2_get_5709_media(bp); + else if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) bp->phy_flags |= PHY_SERDES_FLAG; if (bp->phy_flags & PHY_SERDES_FLAG) { @@ -5880,7 +5913,9 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG; } - } + } else if (CHIP_NUM(bp) == CHIP_NUM_5706 || + CHIP_NUM(bp) == CHIP_NUM_5708) + bp->phy_flags |= PHY_CRC_FIX_FLAG; if ((CHIP_ID(bp) == CHIP_ID_5708_A0) || (CHIP_ID(bp) == CHIP_ID_5708_B0) || |