]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/net/tg3.c
tg3: 5785: Set port mode to MII when link down
[net-next-2.6.git] / drivers / net / tg3.c
index f09bc5dfe8b2c7d652f8d3848ee204d5c2630fba..d726da8c5930e9244288e8238aac36fe52bdff80 100644 (file)
@@ -902,11 +902,12 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
        struct tg3 *tp = bp->priv;
        u32 val;
 
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
-               return -EAGAIN;
+       spin_lock_bh(&tp->lock);
 
        if (tg3_readphy(tp, reg, &val))
-               return -EIO;
+               val = -EIO;
+
+       spin_unlock_bh(&tp->lock);
 
        return val;
 }
@@ -914,14 +915,16 @@ static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
 static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
 {
        struct tg3 *tp = bp->priv;
+       u32 ret = 0;
 
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
-               return -EAGAIN;
+       spin_lock_bh(&tp->lock);
 
        if (tg3_writephy(tp, reg, val))
-               return -EIO;
+               ret = -EIO;
 
-       return 0;
+       spin_unlock_bh(&tp->lock);
+
+       return ret;
 }
 
 static int tg3_mdio_reset(struct mii_bus *bp)
@@ -934,7 +937,7 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
        u32 val;
        struct phy_device *phydev;
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
        switch (phydev->drv->phy_id & phydev->drv->phy_id_mask) {
        case TG3_PHY_ID_BCM50610:
                val = MAC_PHYCFG2_50610_LED_MODES;
@@ -1011,12 +1014,6 @@ static void tg3_mdio_config_5785(struct tg3 *tp)
 
 static void tg3_mdio_start(struct tg3 *tp)
 {
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-               mutex_lock(&tp->mdio_bus->mdio_lock);
-               tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
-               mutex_unlock(&tp->mdio_bus->mdio_lock);
-       }
-
        tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
        tw32_f(MAC_MI_MODE, tp->mi_mode);
        udelay(80);
@@ -1034,22 +1031,13 @@ static void tg3_mdio_start(struct tg3 *tp)
                if (is_serdes)
                        tp->phy_addr += 7;
        } else
-               tp->phy_addr = PHY_ADDR;
+               tp->phy_addr = TG3_PHY_MII_ADDR;
 
        if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                tg3_mdio_config_5785(tp);
 }
 
-static void tg3_mdio_stop(struct tg3 *tp)
-{
-       if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-               mutex_lock(&tp->mdio_bus->mdio_lock);
-               tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_PAUSED;
-               mutex_unlock(&tp->mdio_bus->mdio_lock);
-       }
-}
-
 static int tg3_mdio_init(struct tg3 *tp)
 {
        int i;
@@ -1074,7 +1062,7 @@ static int tg3_mdio_init(struct tg3 *tp)
        tp->mdio_bus->read     = &tg3_mdio_read;
        tp->mdio_bus->write    = &tg3_mdio_write;
        tp->mdio_bus->reset    = &tg3_mdio_reset;
-       tp->mdio_bus->phy_mask = ~(1 << PHY_ADDR);
+       tp->mdio_bus->phy_mask = ~(1 << TG3_PHY_MII_ADDR);
        tp->mdio_bus->irq      = &tp->mdio_irq[0];
 
        for (i = 0; i < PHY_MAX_ADDR; i++)
@@ -1096,7 +1084,7 @@ static int tg3_mdio_init(struct tg3 *tp)
                return i;
        }
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
        if (!phydev || !phydev->drv) {
                printk(KERN_WARNING "%s: No PHY devices\n", tp->dev->name);
@@ -1141,7 +1129,6 @@ static void tg3_mdio_fini(struct tg3 *tp)
                tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
                mdiobus_unregister(tp->mdio_bus);
                mdiobus_free(tp->mdio_bus);
-               tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
        }
 }
 
@@ -1324,7 +1311,7 @@ static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
        u32 old_tx_mode = tp->tx_mode;
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
-               autoneg = tp->mdio_bus->phy_map[PHY_ADDR]->autoneg;
+               autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg;
        else
                autoneg = tp->link_config.autoneg;
 
@@ -1361,9 +1348,9 @@ static void tg3_adjust_link(struct net_device *dev)
        u8 oldflowctrl, linkmesg = 0;
        u32 mac_mode, lcl_adv, rmt_adv;
        struct tg3 *tp = netdev_priv(dev);
-       struct phy_device *phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       struct phy_device *phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
-       spin_lock(&tp->lock);
+       spin_lock_bh(&tp->lock);
 
        mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
                                    MAC_MODE_HALF_DUPLEX);
@@ -1376,8 +1363,11 @@ static void tg3_adjust_link(struct net_device *dev)
 
                if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
                        mac_mode |= MAC_MODE_PORT_MODE_MII;
-               else
+               else if (phydev->speed == SPEED_1000 ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
                        mac_mode |= MAC_MODE_PORT_MODE_GMII;
+               else
+                       mac_mode |= MAC_MODE_PORT_MODE_MII;
 
                if (phydev->duplex == DUPLEX_HALF)
                        mac_mode |= MAC_MODE_HALF_DUPLEX;
@@ -1431,7 +1421,7 @@ static void tg3_adjust_link(struct net_device *dev)
        tp->link_config.active_speed = phydev->speed;
        tp->link_config.active_duplex = phydev->duplex;
 
-       spin_unlock(&tp->lock);
+       spin_unlock_bh(&tp->lock);
 
        if (linkmesg)
                tg3_link_report(tp);
@@ -1447,7 +1437,7 @@ static int tg3_phy_init(struct tg3 *tp)
        /* Bring the PHY back to a known state. */
        tg3_bmcr_reset(tp);
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
        /* Attach the MAC to the PHY. */
        phydev = phy_connect(tp->dev, dev_name(&phydev->dev), tg3_adjust_link,
@@ -1474,7 +1464,7 @@ static int tg3_phy_init(struct tg3 *tp)
                                      SUPPORTED_Asym_Pause);
                break;
        default:
-               phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+               phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
                return -EINVAL;
        }
 
@@ -1492,7 +1482,7 @@ static void tg3_phy_start(struct tg3 *tp)
        if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                return;
 
-       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
        if (tp->link_config.phy_is_low_power) {
                tp->link_config.phy_is_low_power = 0;
@@ -1512,13 +1502,13 @@ static void tg3_phy_stop(struct tg3 *tp)
        if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                return;
 
-       phy_stop(tp->mdio_bus->phy_map[PHY_ADDR]);
+       phy_stop(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
 }
 
 static void tg3_phy_fini(struct tg3 *tp)
 {
        if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
-               phy_disconnect(tp->mdio_bus->phy_map[PHY_ADDR]);
+               phy_disconnect(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
                tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
        }
 }
@@ -2162,6 +2152,26 @@ static void tg3_power_down_phy(struct tg3 *tp, bool do_low_power)
                tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
                udelay(40);
                return;
+       } else if (tp->tg3_flags3 & TG3_FLG3_PHY_IS_FET) {
+               u32 phytest;
+               if (!tg3_readphy(tp, MII_TG3_FET_TEST, &phytest)) {
+                       u32 phy;
+
+                       tg3_writephy(tp, MII_ADVERTISE, 0);
+                       tg3_writephy(tp, MII_BMCR,
+                                    BMCR_ANENABLE | BMCR_ANRESTART);
+
+                       tg3_writephy(tp, MII_TG3_FET_TEST,
+                                    phytest | MII_TG3_FET_SHADOW_EN);
+                       if (!tg3_readphy(tp, MII_TG3_FET_SHDW_AUXMODE4, &phy)) {
+                               phy |= MII_TG3_FET_SHDW_AUXMODE4_SBPD;
+                               tg3_writephy(tp,
+                                            MII_TG3_FET_SHDW_AUXMODE4,
+                                            phy);
+                       }
+                       tg3_writephy(tp, MII_TG3_FET_TEST, phytest);
+               }
+               return;
        } else if (do_low_power) {
                tg3_writephy(tp, MII_TG3_EXT_CTRL,
                             MII_TG3_EXT_CTRL_FORCE_LED_OFF);
@@ -2487,7 +2497,7 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                        struct phy_device *phydev;
                        u32 phyid, advertising;
 
-                       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+                       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
                        tp->link_config.phy_is_low_power = 1;
 
@@ -3256,15 +3266,6 @@ relink:
                        pci_write_config_word(tp->pdev,
                                              tp->pcie_cap + PCI_EXP_LNKCTL,
                                              newlnkctl);
-       } else if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
-               u32 newreg, oldreg = tr32(TG3_PCIE_LNKCTL);
-               if (tp->link_config.active_speed == SPEED_100 ||
-                   tp->link_config.active_speed == SPEED_10)
-                       newreg = oldreg & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
-               else
-                       newreg = oldreg | TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
-               if (newreg != oldreg)
-                       tw32(TG3_PCIE_LNKCTL, newreg);
        }
 
        if (current_link_up != netif_carrier_ok(tp->dev)) {
@@ -4448,6 +4449,10 @@ static int tg3_alloc_rx_skb(struct tg3_napi *tnapi, u32 opaque_key,
 
        mapping = pci_map_single(tp->pdev, skb->data, skb_size,
                                 PCI_DMA_FROMDEVICE);
+       if (pci_dma_mapping_error(tp->pdev, mapping)) {
+               dev_kfree_skb(skb);
+               return -EIO;
+       }
 
        map->skb = skb;
        pci_unmap_addr_set(map, mapping, mapping);
@@ -5137,7 +5142,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
                /* Make sure new skb does not cross any 4G boundaries.
                 * Drop the packet if it does.
                 */
-               if (ret || tg3_4g_overflow_test(new_addr, new_skb->len)) {
+               if (ret || ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+                           tg3_4g_overflow_test(new_addr, new_skb->len))) {
                        if (!ret)
                                skb_dma_unmap(&tp->pdev->dev, new_skb,
                                              DMA_TO_DEVICE);
@@ -5405,7 +5411,7 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
        mss = 0;
        if ((mss = skb_shinfo(skb)->gso_size) != 0) {
                struct iphdr *iph;
-               int tcp_opt_len, ip_tcp_len, hdr_len;
+               u32 tcp_opt_len, ip_tcp_len, hdr_len;
 
                if (skb_header_cloned(skb) &&
                    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
@@ -5436,8 +5442,10 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
                                                                 IPPROTO_TCP,
                                                                 0);
 
-               if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
-                   (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
+               if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
+                       mss |= hdr_len << 9;
+               else if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1) ||
+                        GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
                        if (tcp_opt_len || iph->ihl > 5) {
                                int tsflags;
 
@@ -5472,9 +5480,18 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
 
        would_hit_hwbug = 0;
 
-       if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+       if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && len <= 8)
                would_hit_hwbug = 1;
-       else if (tg3_4g_overflow_test(mapping, len))
+
+       if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+           tg3_4g_overflow_test(mapping, len))
+               would_hit_hwbug = 1;
+
+       if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+           tg3_40bit_overflow_test(tp, mapping, len))
+               would_hit_hwbug = 1;
+
+       if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
                would_hit_hwbug = 1;
 
        tg3_set_txd(tnapi, entry, mapping, len, base_flags,
@@ -5495,10 +5512,16 @@ static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
 
                        tnapi->tx_buffers[entry].skb = NULL;
 
-                       if (tg3_4g_overflow_test(mapping, len))
+                       if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) &&
+                           len <= 8)
                                would_hit_hwbug = 1;
 
-                       if (tg3_40bit_overflow_test(tp, mapping, len))
+                       if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+                           tg3_4g_overflow_test(mapping, len))
+                               would_hit_hwbug = 1;
+
+                       if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+                           tg3_40bit_overflow_test(tp, mapping, len))
                                would_hit_hwbug = 1;
 
                        if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
@@ -6392,8 +6415,6 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        tg3_nvram_lock(tp);
 
-       tg3_mdio_stop(tp);
-
        tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
 
        /* No matching tg3_nvram_unlock() after this because
@@ -6595,6 +6616,30 @@ static int tg3_chip_reset(struct tg3 *tp)
 
        tg3_mdio_start(tp);
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               u8 phy_addr;
+
+               phy_addr = tp->phy_addr;
+               tp->phy_addr = TG3_PHY_PCIE_ADDR;
+
+               tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
+                            TG3_PCIEPHY_TXB_BLK << TG3_PCIEPHY_BLOCK_SHIFT);
+               val = TG3_PCIEPHY_TX0CTRL1_TXOCM | TG3_PCIEPHY_TX0CTRL1_RDCTL |
+                     TG3_PCIEPHY_TX0CTRL1_TXCMV | TG3_PCIEPHY_TX0CTRL1_TKSEL |
+                     TG3_PCIEPHY_TX0CTRL1_NB_EN;
+               tg3_writephy(tp, TG3_PCIEPHY_TX0CTRL1, val);
+               udelay(10);
+
+               tg3_writephy(tp, TG3_PCIEPHY_BLOCK_ADDR,
+                            TG3_PCIEPHY_XGXS_BLK1 << TG3_PCIEPHY_BLOCK_SHIFT);
+               val = TG3_PCIEPHY_PWRMGMT4_LOWPWR_EN |
+                     TG3_PCIEPHY_PWRMGMT4_L1PLLPD_EN;
+               tg3_writephy(tp, TG3_PCIEPHY_PWRMGMT4, val);
+               udelay(10);
+
+               tp->phy_addr = phy_addr;
+       }
+
        if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
            tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
            GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
@@ -7177,15 +7222,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(TG3_PCIE_EIDLE_DELAY, val | TG3_PCIE_EIDLE_DELAY_13_CLKS);
 
                tw32(TG3_CORR_ERR_STAT, TG3_CORR_ERR_STAT_CLEAR);
-       }
 
-       if (tp->tg3_flags3 & TG3_FLG3_TOGGLE_10_100_L1PLLPD) {
-               val = tr32(TG3_PCIE_LNKCTL);
-               if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG)
-                       val |= TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
-               else
-                       val &= ~TG3_PCIE_LNKCTL_L1_PLL_PD_DIS;
-               tw32(TG3_PCIE_LNKCTL, val);
+               val = tr32(TG3_PCIE_LNKCTL) & ~TG3_PCIE_LNKCTL_L1_PLL_PD_EN;
+               tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
        }
 
        /* This works around an issue with Athlon chipsets on
@@ -7617,6 +7656,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                val |= WDMAC_MODE_STATUS_TAG_FIX;
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
+               val |= WDMAC_MODE_BURST_ALL_DATA;
+
        tw32_f(WDMAC_MODE, val);
        udelay(40);
 
@@ -8698,6 +8740,8 @@ static int tg3_close(struct net_device *dev)
 
        del_timer_sync(&tp->timer);
 
+       tg3_phy_stop(tp);
+
        tg3_full_lock(tp, 1);
 #if 0
        tg3_dump_state(tp);
@@ -9253,9 +9297,11 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        struct tg3 *tp = netdev_priv(dev);
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+               struct phy_device *phydev;
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               return phy_ethtool_gset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+               return phy_ethtool_gset(phydev, cmd);
        }
 
        cmd->supported = (SUPPORTED_Autoneg);
@@ -9294,9 +9340,11 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        struct tg3 *tp = netdev_priv(dev);
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+               struct phy_device *phydev;
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+               return phy_ethtool_sset(phydev, cmd);
        }
 
        if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -9479,7 +9527,7 @@ static int tg3_nway_reset(struct net_device *dev)
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               r = phy_start_aneg(tp->mdio_bus->phy_map[PHY_ADDR]);
+               r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
        } else {
                u32 bmcr;
 
@@ -9598,7 +9646,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam
                        u32 newadv;
                        struct phy_device *phydev;
 
-                       phydev = tp->mdio_bus->phy_map[PHY_ADDR];
+                       phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
 
                        if (epause->rx_pause) {
                                if (epause->tx_pause)
@@ -10351,7 +10399,10 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
        for (i = 14; i < tx_len; i++)
                tx_data[i] = (u8) (i & 0xff);
 
-       map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
+       if (skb_dma_map(&tp->pdev->dev, skb, DMA_TO_DEVICE)) {
+               dev_kfree_skb(skb);
+               return -EIO;
+       }
 
        tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE |
               rnapi->coal_now);
@@ -10362,7 +10413,8 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
 
        num_pkts = 0;
 
-       tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, 0, 1);
+       tg3_set_txd(tnapi, tnapi->tx_prod,
+                   skb_shinfo(skb)->dma_head, tx_len, 0, 1);
 
        tnapi->tx_prod++;
        num_pkts++;
@@ -10386,7 +10438,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
                        break;
        }
 
-       pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE);
+       skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
        dev_kfree_skb(skb);
 
        if (tx_idx != tnapi->tx_prod)
@@ -10578,9 +10630,11 @@ static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        int err;
 
        if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+               struct phy_device *phydev;
                if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
                        return -EAGAIN;
-               return phy_mii_ioctl(tp->mdio_bus->phy_map[PHY_ADDR], data, cmd);
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
+               return phy_mii_ioctl(phydev, data, cmd);
        }
 
        switch(cmd) {
@@ -12623,12 +12677,19 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
 
        tp->irq_max = 1;
 
-#ifdef TG3_NAPI
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
                tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
                tp->irq_max = TG3_IRQ_MAX_VECS;
        }
-#endif
+
+       if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
+               if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+                       tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
+               else {
+                       tp->tg3_flags3 |= TG3_FLG3_4G_DMA_BNDRY_BUG;
+                       tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
+               }
+       }
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
             (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
@@ -12939,11 +13000,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
 
-       if ((tp->pci_chip_rev_id == CHIPREV_ID_57780_A1 &&
-            tr32(RCVLPC_STATS_ENABLE) & RCVLPC_STATSENAB_ASF_FIX) ||
-           tp->pci_chip_rev_id == CHIPREV_ID_57780_A0)
-               tp->tg3_flags3 |= TG3_FLG3_TOGGLE_10_100_L1PLLPD;
-
        err = tg3_mdio_init(tp);
        if (err)
                return err;
@@ -13988,8 +14044,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
-       if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
-           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
+       if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
                dev->netdev_ops = &tg3_netdev_ops;
        else
                dev->netdev_ops = &tg3_netdev_ops_dma_bug;
@@ -14144,13 +14199,14 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
               tg3_bus_string(tp, str),
               dev->dev_addr);
 
-       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
+       if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
+               struct phy_device *phydev;
+               phydev = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR];
                printk(KERN_INFO
                       "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
-                      tp->dev->name,
-                      tp->mdio_bus->phy_map[PHY_ADDR]->drv->name,
-                      dev_name(&tp->mdio_bus->phy_map[PHY_ADDR]->dev));
-       else
+                      tp->dev->name, phydev->drv->name,
+                      dev_name(&phydev->dev));
+       } else
                printk(KERN_INFO
                       "%s: attached PHY is %s (%s Ethernet) (WireSpeed[%d])\n",
                       tp->dev->name, tg3_phy_string(tp),