diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2.c | 60 |
1 files changed, 42 insertions, 18 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index d9980ad00b4b..9d2dedadf2df 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -23,7 +23,6 @@ #include <linux/vmalloc.h> #include <linux/interrupt.h> #include <linux/pci.h> -#include <linux/init.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> @@ -58,8 +57,8 @@ #include "bnx2_fw.h" #define DRV_MODULE_NAME "bnx2" -#define DRV_MODULE_VERSION "2.2.4" -#define DRV_MODULE_RELDATE "Aug 05, 2013" +#define DRV_MODULE_VERSION "2.2.5" +#define DRV_MODULE_RELDATE "December 20, 2013" #define FW_MIPS_FILE_06 "bnx2/bnx2-mips-06-6.2.3.fw" #define FW_RV2P_FILE_06 "bnx2/bnx2-rv2p-06-6.0.15.fw" #define FW_MIPS_FILE_09 "bnx2/bnx2-mips-09-6.2.1b.fw" @@ -1197,6 +1196,8 @@ bnx2_copper_linkup(struct bnx2 *bp) { u32 bmcr; + bp->phy_flags &= ~BNX2_PHY_FLAG_MDIX; + bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); if (bmcr & BMCR_ANENABLE) { u32 local_adv, remote_adv, common; @@ -1255,6 +1256,14 @@ bnx2_copper_linkup(struct bnx2 *bp) } } + if (bp->link_up) { + u32 ext_status; + + bnx2_read_phy(bp, MII_BNX2_EXT_STATUS, &ext_status); + if (ext_status & EXT_STATUS_MDIX) + bp->phy_flags |= BNX2_PHY_FLAG_MDIX; + } + return 0; } @@ -2048,29 +2057,27 @@ bnx2_setup_copper_phy(struct bnx2 *bp) __releases(&bp->phy_lock) __acquires(&bp->phy_lock) { - u32 bmcr; + u32 bmcr, adv_reg, new_adv = 0; u32 new_bmcr; bnx2_read_phy(bp, bp->mii_bmcr, &bmcr); + bnx2_read_phy(bp, bp->mii_adv, &adv_reg); + adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | + ADVERTISE_PAUSE_ASYM); + + new_adv = ADVERTISE_CSMA | ethtool_adv_to_mii_adv_t(bp->advertising); + if (bp->autoneg & AUTONEG_SPEED) { - u32 adv_reg, adv1000_reg; - u32 new_adv = 0; + u32 adv1000_reg; u32 new_adv1000 = 0; - bnx2_read_phy(bp, bp->mii_adv, &adv_reg); - adv_reg &= (PHY_ALL_10_100_SPEED | ADVERTISE_PAUSE_CAP | - ADVERTISE_PAUSE_ASYM); + new_adv |= bnx2_phy_get_pause_adv(bp); bnx2_read_phy(bp, MII_CTRL1000, &adv1000_reg); adv1000_reg &= PHY_ALL_1000_SPEED; - new_adv = ethtool_adv_to_mii_adv_t(bp->advertising); - new_adv |= ADVERTISE_CSMA; - new_adv |= bnx2_phy_get_pause_adv(bp); - new_adv1000 |= ethtool_adv_to_mii_ctrl1000_t(bp->advertising); - if ((adv1000_reg != new_adv1000) || (adv_reg != new_adv) || ((bmcr & BMCR_ANENABLE) == 0)) { @@ -2090,6 +2097,10 @@ __acquires(&bp->phy_lock) return 0; } + /* advertise nothing when forcing speed */ + if (adv_reg != new_adv) + bnx2_write_phy(bp, bp->mii_adv, new_adv); + new_bmcr = 0; if (bp->req_line_speed == SPEED_100) { new_bmcr |= BMCR_SPEED100; @@ -2341,9 +2352,15 @@ bnx2_init_copper_phy(struct bnx2 *bp, int reset_phy) } /* ethernet@wirespeed */ - bnx2_write_phy(bp, 0x18, 0x7007); - bnx2_read_phy(bp, 0x18, &val); - bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4)); + bnx2_write_phy(bp, MII_BNX2_AUX_CTL, AUX_CTL_MISC_CTL); + bnx2_read_phy(bp, MII_BNX2_AUX_CTL, &val); + val |= AUX_CTL_MISC_CTL_WR | AUX_CTL_MISC_CTL_WIRESPEED; + + /* auto-mdix */ + if (BNX2_CHIP(bp) == BNX2_CHIP_5709) + val |= AUX_CTL_MISC_CTL_AUTOMDIX; + + bnx2_write_phy(bp, MII_BNX2_AUX_CTL, val); return 0; } @@ -3234,7 +3251,8 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) if ((bp->dev->features & NETIF_F_RXHASH) && ((status & L2_FHDR_STATUS_USE_RXHASH) == L2_FHDR_STATUS_USE_RXHASH)) - skb->rxhash = rx_hdr->l2_fhdr_hash; + skb_set_hash(skb, rx_hdr->l2_fhdr_hash, + PKT_HASH_TYPE_L3); skb_record_rx_queue(skb, bnapi - &bp->bnx2_napi[0]); napi_gro_receive(&bnapi->napi, skb); @@ -6865,6 +6883,12 @@ bnx2_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) if (netif_carrier_ok(dev)) { ethtool_cmd_speed_set(cmd, bp->line_speed); cmd->duplex = bp->duplex; + if (!(bp->phy_flags & BNX2_PHY_FLAG_SERDES)) { + if (bp->phy_flags & BNX2_PHY_FLAG_MDIX) + cmd->eth_tp_mdix = ETH_TP_MDI_X; + else + cmd->eth_tp_mdix = ETH_TP_MDI; + } } else { ethtool_cmd_speed_set(cmd, -1); |