]> Git Repo - linux.git/commitdiff
Merge branch 'upstream-next-davem' of master.kernel.org:/pub/scm/linux/kernel/git...
authorDavid S. Miller <[email protected]>
Thu, 29 May 2008 10:31:03 +0000 (03:31 -0700)
committerDavid S. Miller <[email protected]>
Thu, 29 May 2008 10:31:03 +0000 (03:31 -0700)
1  2 
drivers/net/3c509.c
drivers/net/Kconfig
drivers/net/phy/Kconfig
drivers/net/tg3.c
drivers/net/usb/rndis_host.c

diff --combined drivers/net/3c509.c
index fe6d84105e5505d8d5699a5a4a521f15b8a8d2ef,87d8795823d7a9e53d2ff8bddc762e29d6a37b69..b9d097c9f6bbb88613e71ce53a42d9388a51fbf2
@@@ -413,7 -413,7 +413,7 @@@ static int __devinit el3_pnp_probe(stru
  {
        short i;
        int ioaddr, irq, if_port;
-       u16 phys_addr[3];
+       __be16 phys_addr[3];
        struct net_device *dev = NULL;
        int err;
  
@@@ -605,7 -605,7 +605,7 @@@ static int __init el3_mca_probe(struct 
  
        short i;
        int ioaddr, irq, if_port;
-       u16 phys_addr[3];
+       __be16 phys_addr[3];
        struct net_device *dev = NULL;
        u_char pos4, pos5;
        struct mca_device *mdev = to_mca_device(device);
                        printk(KERN_DEBUG "3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
        }
        EL3WINDOW(0);
-       for (i = 0; i < 3; i++) {
-                       phys_addr[i] = htons(read_eeprom(ioaddr, i));
-       }
+       for (i = 0; i < 3; i++)
+               phys_addr[i] = htons(read_eeprom(ioaddr, i));
  
        dev = alloc_etherdev(sizeof (struct el3_private));
        if (dev == NULL) {
-                       release_region(ioaddr, EL3_IO_EXTENT);
-                       return -ENOMEM;
+               release_region(ioaddr, EL3_IO_EXTENT);
+               return -ENOMEM;
        }
  
        netdev_boot_setup_check(dev);
@@@ -668,7 -667,7 +667,7 @@@ static int __init el3_eisa_probe (struc
  {
        short i;
        int ioaddr, irq, if_port;
-       u16 phys_addr[3];
+       __be16 phys_addr[3];
        struct net_device *dev = NULL;
        struct eisa_device *edev;
        int err;
@@@ -1063,6 -1062,7 +1062,6 @@@ el3_rx(struct net_device *dev
                        struct sk_buff *skb;
  
                        skb = dev_alloc_skb(pkt_len+5);
 -                      dev->stats.rx_bytes += pkt_len;
                        if (el3_debug > 4)
                                printk("Receiving packet size %d status %4.4x.\n",
                                           pkt_len, rx_status);
                                skb->protocol = eth_type_trans(skb,dev);
                                netif_rx(skb);
                                dev->last_rx = jiffies;
 +                              dev->stats.rx_bytes += pkt_len;
                                dev->stats.rx_packets++;
                                continue;
                        }
diff --combined drivers/net/Kconfig
index 78cc9495fd463cc1875d7108d9f9f55a25d50da1,daeb23d7fec1dd35a6506ebcb24e4ae7e6845de2..8178a4dfd09cc3c4301ec67fcc6eca586bd4ea4e
@@@ -2228,7 -2228,6 +2228,7 @@@ config VIA_VELOCIT
  config TIGON3
        tristate "Broadcom Tigon3 support"
        depends on PCI
 +      select PHYLIB
        help
          This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
  
@@@ -2410,6 -2409,7 +2410,7 @@@ config CHELSIO_T
        tristate "Chelsio Communications T3 10Gb Ethernet support"
        depends on PCI
        select FW_LOADER
+       select INET_LRO
        help
          This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
          adapters.
diff --combined drivers/net/phy/Kconfig
index 6eb2d31d1e3419fb07f26ccb1d197f2aa2a79f75,35b431991cc42b3078a15a239ce81b9f94d11228..284217c12839a17b82f81c077a59443600724b93
@@@ -5,7 -5,7 +5,7 @@@
  menuconfig PHYLIB
        tristate "PHY Device support and infrastructure"
        depends on !S390
 -      depends on NET_ETHERNET && (BROKEN || !S390)
 +      depends on NET_ETHERNET
        help
          Ethernet controllers are usually attached to PHY
          devices.  This option provides infrastructure for
@@@ -53,7 -53,8 +53,8 @@@ config SMSC_PH
  config BROADCOM_PHY
        tristate "Drivers for Broadcom PHYs"
        ---help---
-         Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
+         Currently supports the BCM5411, BCM5421, BCM5461, BCM5464, BCM5481
+         and BCM5482 PHYs.
  
  config ICPLUS_PHY
        tristate "Drivers for ICPlus PHYs"
diff --combined drivers/net/tg3.c
index 20a8e399640780ad46783453182dec6d9b9468cf,ae11c672476633e54d01c68eabd15c2345a20ce2..d9f248f23b97eca6087d811023d0597ba7f37482
@@@ -32,8 -32,6 +32,8 @@@
  #include <linux/skbuff.h>
  #include <linux/ethtool.h>
  #include <linux/mii.h>
 +#include <linux/phy.h>
 +#include <linux/brcmphy.h>
  #include <linux/if_vlan.h>
  #include <linux/ip.h>
  #include <linux/tcp.h>
@@@ -66,8 -64,8 +66,8 @@@
  
  #define DRV_MODULE_NAME               "tg3"
  #define PFX DRV_MODULE_NAME   ": "
 -#define DRV_MODULE_VERSION    "3.92"
 -#define DRV_MODULE_RELDATE    "May 2, 2008"
 +#define DRV_MODULE_VERSION    "3.93"
 +#define DRV_MODULE_RELDATE    "May 22, 2008"
  
  #define TG3_DEF_MAC_MODE      0
  #define TG3_DEF_RX_MODE               0
@@@ -205,7 -203,6 +205,7 @@@ static struct pci_device_id tg3_pci_tbl
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5723)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761)},
        {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5761E)},
 +      {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5785)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9DXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_9MXX)},
        {PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1000)},
@@@ -807,569 -804,6 +807,569 @@@ static int tg3_writephy(struct tg3 *tp
        return ret;
  }
  
 +static int tg3_bmcr_reset(struct tg3 *tp)
 +{
 +      u32 phy_control;
 +      int limit, err;
 +
 +      /* OK, reset it, and poll the BMCR_RESET bit until it
 +       * clears or we time out.
 +       */
 +      phy_control = BMCR_RESET;
 +      err = tg3_writephy(tp, MII_BMCR, phy_control);
 +      if (err != 0)
 +              return -EBUSY;
 +
 +      limit = 5000;
 +      while (limit--) {
 +              err = tg3_readphy(tp, MII_BMCR, &phy_control);
 +              if (err != 0)
 +                      return -EBUSY;
 +
 +              if ((phy_control & BMCR_RESET) == 0) {
 +                      udelay(40);
 +                      break;
 +              }
 +              udelay(10);
 +      }
 +      if (limit <= 0)
 +              return -EBUSY;
 +
 +      return 0;
 +}
 +
 +static int tg3_mdio_read(struct mii_bus *bp, int mii_id, int reg)
 +{
 +      struct tg3 *tp = (struct tg3 *)bp->priv;
 +      u32 val;
 +
 +      if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
 +              return -EAGAIN;
 +
 +      if (tg3_readphy(tp, reg, &val))
 +              return -EIO;
 +
 +      return val;
 +}
 +
 +static int tg3_mdio_write(struct mii_bus *bp, int mii_id, int reg, u16 val)
 +{
 +      struct tg3 *tp = (struct tg3 *)bp->priv;
 +
 +      if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_PAUSED)
 +              return -EAGAIN;
 +
 +      if (tg3_writephy(tp, reg, val))
 +              return -EIO;
 +
 +      return 0;
 +}
 +
 +static int tg3_mdio_reset(struct mii_bus *bp)
 +{
 +      return 0;
 +}
 +
 +static void tg3_mdio_config(struct tg3 *tp)
 +{
 +      u32 val;
 +
 +      if (tp->mdio_bus.phy_map[PHY_ADDR]->interface !=
 +          PHY_INTERFACE_MODE_RGMII)
 +              return;
 +
 +      val = tr32(MAC_PHYCFG1) & ~(MAC_PHYCFG1_RGMII_EXT_RX_DEC |
 +                                  MAC_PHYCFG1_RGMII_SND_STAT_EN);
 +      if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
 +              if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
 +                      val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
 +              if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
 +                      val |= MAC_PHYCFG1_RGMII_SND_STAT_EN;
 +      }
 +      tw32(MAC_PHYCFG1, val | MAC_PHYCFG1_RGMII_INT | MAC_PHYCFG1_TXC_DRV);
 +
 +      val = tr32(MAC_PHYCFG2) & ~(MAC_PHYCFG2_INBAND_ENABLE);
 +      if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE))
 +              val |= MAC_PHYCFG2_INBAND_ENABLE;
 +      tw32(MAC_PHYCFG2, val);
 +
 +      val = tr32(MAC_EXT_RGMII_MODE);
 +      val &= ~(MAC_RGMII_MODE_RX_INT_B |
 +               MAC_RGMII_MODE_RX_QUALITY |
 +               MAC_RGMII_MODE_RX_ACTIVITY |
 +               MAC_RGMII_MODE_RX_ENG_DET |
 +               MAC_RGMII_MODE_TX_ENABLE |
 +               MAC_RGMII_MODE_TX_LOWPWR |
 +               MAC_RGMII_MODE_TX_RESET);
 +      if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE) {
 +              if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
 +                      val |= MAC_RGMII_MODE_RX_INT_B |
 +                             MAC_RGMII_MODE_RX_QUALITY |
 +                             MAC_RGMII_MODE_RX_ACTIVITY |
 +                             MAC_RGMII_MODE_RX_ENG_DET;
 +              if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
 +                      val |= MAC_RGMII_MODE_TX_ENABLE |
 +                             MAC_RGMII_MODE_TX_LOWPWR |
 +                             MAC_RGMII_MODE_TX_RESET;
 +      }
 +      tw32(MAC_EXT_RGMII_MODE, val);
 +}
 +
 +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);
 +
 +      if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED)
 +              tg3_mdio_config(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;
 +      u32 reg;
 +      struct phy_device *phydev;
 +      struct mii_bus *mdio_bus = &tp->mdio_bus;
 +
 +      tg3_mdio_start(tp);
 +
 +      if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) ||
 +          (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED))
 +              return 0;
 +
 +      memset(mdio_bus, 0, sizeof(*mdio_bus));
 +
 +      mdio_bus->name     = "tg3 mdio bus";
 +      snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%x",
 +               (tp->pdev->bus->number << 8) | tp->pdev->devfn);
 +      mdio_bus->priv     = tp;
 +      mdio_bus->dev      = &tp->pdev->dev;
 +      mdio_bus->read     = &tg3_mdio_read;
 +      mdio_bus->write    = &tg3_mdio_write;
 +      mdio_bus->reset    = &tg3_mdio_reset;
 +      mdio_bus->phy_mask = ~(1 << PHY_ADDR);
 +      mdio_bus->irq      = &tp->mdio_irq[0];
 +
 +      for (i = 0; i < PHY_MAX_ADDR; i++)
 +              mdio_bus->irq[i] = PHY_POLL;
 +
 +      /* The bus registration will look for all the PHYs on the mdio bus.
 +       * Unfortunately, it does not ensure the PHY is powered up before
 +       * accessing the PHY ID registers.  A chip reset is the
 +       * quickest way to bring the device back to an operational state..
 +       */
 +      if (tg3_readphy(tp, MII_BMCR, &reg) || (reg & BMCR_PDOWN))
 +              tg3_bmcr_reset(tp);
 +
 +      i = mdiobus_register(mdio_bus);
 +      if (i) {
 +              printk(KERN_WARNING "%s: mdiobus_reg failed (0x%x)\n",
 +                      tp->dev->name, i);
 +              return i;
 +      }
 +
 +      tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
 +
 +      phydev = tp->mdio_bus.phy_map[PHY_ADDR];
 +
 +      switch (phydev->phy_id) {
 +      case TG3_PHY_ID_BCM50610:
 +              phydev->interface = PHY_INTERFACE_MODE_RGMII;
 +              if (tp->tg3_flags3 & TG3_FLG3_RGMII_STD_IBND_DISABLE)
 +                      phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
 +              if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
 +                      phydev->dev_flags |= PHY_BRCM_EXT_IBND_RX_ENABLE;
 +              if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
 +                      phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
 +              break;
 +      case TG3_PHY_ID_BCMAC131:
 +              phydev->interface = PHY_INTERFACE_MODE_MII;
 +              break;
 +      }
 +
 +      tg3_mdio_config(tp);
 +
 +      return 0;
 +}
 +
 +static void tg3_mdio_fini(struct tg3 *tp)
 +{
 +      if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
 +              tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
 +              mdiobus_unregister(&tp->mdio_bus);
 +              tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_PAUSED;
 +      }
 +}
 +
 +/* tp->lock is held. */
 +static void tg3_wait_for_event_ack(struct tg3 *tp)
 +{
 +      int i;
 +
 +      /* Wait for up to 2.5 milliseconds */
 +      for (i = 0; i < 250000; i++) {
 +              if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
 +                      break;
 +              udelay(10);
 +      }
 +}
 +
 +/* tp->lock is held. */
 +static void tg3_ump_link_report(struct tg3 *tp)
 +{
 +      u32 reg;
 +      u32 val;
 +
 +      if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
 +          !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
 +              return;
 +
 +      tg3_wait_for_event_ack(tp);
 +
 +      tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
 +
 +      tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
 +
 +      val = 0;
 +      if (!tg3_readphy(tp, MII_BMCR, &reg))
 +              val = reg << 16;
 +      if (!tg3_readphy(tp, MII_BMSR, &reg))
 +              val |= (reg & 0xffff);
 +      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val);
 +
 +      val = 0;
 +      if (!tg3_readphy(tp, MII_ADVERTISE, &reg))
 +              val = reg << 16;
 +      if (!tg3_readphy(tp, MII_LPA, &reg))
 +              val |= (reg & 0xffff);
 +      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
 +
 +      val = 0;
 +      if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) {
 +              if (!tg3_readphy(tp, MII_CTRL1000, &reg))
 +                      val = reg << 16;
 +              if (!tg3_readphy(tp, MII_STAT1000, &reg))
 +                      val |= (reg & 0xffff);
 +      }
 +      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val);
 +
 +      if (!tg3_readphy(tp, MII_PHYADDR, &reg))
 +              val = reg << 16;
 +      else
 +              val = 0;
 +      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
 +
 +      val = tr32(GRC_RX_CPU_EVENT);
 +      val |= GRC_RX_CPU_DRIVER_EVENT;
 +      tw32_f(GRC_RX_CPU_EVENT, val);
 +}
 +
 +static void tg3_link_report(struct tg3 *tp)
 +{
 +      if (!netif_carrier_ok(tp->dev)) {
 +              if (netif_msg_link(tp))
 +                      printk(KERN_INFO PFX "%s: Link is down.\n",
 +                             tp->dev->name);
 +              tg3_ump_link_report(tp);
 +      } else if (netif_msg_link(tp)) {
 +              printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
 +                     tp->dev->name,
 +                     (tp->link_config.active_speed == SPEED_1000 ?
 +                      1000 :
 +                      (tp->link_config.active_speed == SPEED_100 ?
 +                       100 : 10)),
 +                     (tp->link_config.active_duplex == DUPLEX_FULL ?
 +                      "full" : "half"));
 +
 +              printk(KERN_INFO PFX
 +                     "%s: Flow control is %s for TX and %s for RX.\n",
 +                     tp->dev->name,
 +                     (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
 +                     "on" : "off",
 +                     (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
 +                     "on" : "off");
 +              tg3_ump_link_report(tp);
 +      }
 +}
 +
 +static u16 tg3_advert_flowctrl_1000T(u8 flow_ctrl)
 +{
 +      u16 miireg;
 +
 +      if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
 +              miireg = ADVERTISE_PAUSE_CAP;
 +      else if (flow_ctrl & TG3_FLOW_CTRL_TX)
 +              miireg = ADVERTISE_PAUSE_ASYM;
 +      else if (flow_ctrl & TG3_FLOW_CTRL_RX)
 +              miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 +      else
 +              miireg = 0;
 +
 +      return miireg;
 +}
 +
 +static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
 +{
 +      u16 miireg;
 +
 +      if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
 +              miireg = ADVERTISE_1000XPAUSE;
 +      else if (flow_ctrl & TG3_FLOW_CTRL_TX)
 +              miireg = ADVERTISE_1000XPSE_ASYM;
 +      else if (flow_ctrl & TG3_FLOW_CTRL_RX)
 +              miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
 +      else
 +              miireg = 0;
 +
 +      return miireg;
 +}
 +
 +static u8 tg3_resolve_flowctrl_1000T(u16 lcladv, u16 rmtadv)
 +{
 +      u8 cap = 0;
 +
 +      if (lcladv & ADVERTISE_PAUSE_CAP) {
 +              if (lcladv & ADVERTISE_PAUSE_ASYM) {
 +                      if (rmtadv & LPA_PAUSE_CAP)
 +                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 +                      else if (rmtadv & LPA_PAUSE_ASYM)
 +                              cap = TG3_FLOW_CTRL_RX;
 +              } else {
 +                      if (rmtadv & LPA_PAUSE_CAP)
 +                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 +              }
 +      } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
 +              if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
 +                      cap = TG3_FLOW_CTRL_TX;
 +      }
 +
 +      return cap;
 +}
 +
 +static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
 +{
 +      u8 cap = 0;
 +
 +      if (lcladv & ADVERTISE_1000XPAUSE) {
 +              if (lcladv & ADVERTISE_1000XPSE_ASYM) {
 +                      if (rmtadv & LPA_1000XPAUSE)
 +                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 +                      else if (rmtadv & LPA_1000XPAUSE_ASYM)
 +                              cap = TG3_FLOW_CTRL_RX;
 +              } else {
 +                      if (rmtadv & LPA_1000XPAUSE)
 +                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 +              }
 +      } else if (lcladv & ADVERTISE_1000XPSE_ASYM) {
 +              if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM))
 +                      cap = TG3_FLOW_CTRL_TX;
 +      }
 +
 +      return cap;
 +}
 +
 +static void tg3_setup_flow_control(struct tg3 *tp, u32 lcladv, u32 rmtadv)
 +{
 +      u8 autoneg;
 +      u8 flowctrl = 0;
 +      u32 old_rx_mode = tp->rx_mode;
 +      u32 old_tx_mode = tp->tx_mode;
 +
 +      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
 +              autoneg = tp->mdio_bus.phy_map[PHY_ADDR]->autoneg;
 +      else
 +              autoneg = tp->link_config.autoneg;
 +
 +      if (autoneg == AUTONEG_ENABLE &&
 +          (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
 +              if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
 +                      flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv);
 +              else
 +                      flowctrl = tg3_resolve_flowctrl_1000T(lcladv, rmtadv);
 +      } else
 +              flowctrl = tp->link_config.flowctrl;
 +
 +      tp->link_config.active_flowctrl = flowctrl;
 +
 +      if (flowctrl & TG3_FLOW_CTRL_RX)
 +              tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
 +      else
 +              tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
 +
 +      if (old_rx_mode != tp->rx_mode)
 +              tw32_f(MAC_RX_MODE, tp->rx_mode);
 +
 +      if (flowctrl & TG3_FLOW_CTRL_TX)
 +              tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
 +      else
 +              tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
 +
 +      if (old_tx_mode != tp->tx_mode)
 +              tw32_f(MAC_TX_MODE, tp->tx_mode);
 +}
 +
 +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];
 +
 +      spin_lock(&tp->lock);
 +
 +      mac_mode = tp->mac_mode & ~(MAC_MODE_PORT_MODE_MASK |
 +                                  MAC_MODE_HALF_DUPLEX);
 +
 +      oldflowctrl = tp->link_config.active_flowctrl;
 +
 +      if (phydev->link) {
 +              lcl_adv = 0;
 +              rmt_adv = 0;
 +
 +              if (phydev->speed == SPEED_100 || phydev->speed == SPEED_10)
 +                      mac_mode |= MAC_MODE_PORT_MODE_MII;
 +              else
 +                      mac_mode |= MAC_MODE_PORT_MODE_GMII;
 +
 +              if (phydev->duplex == DUPLEX_HALF)
 +                      mac_mode |= MAC_MODE_HALF_DUPLEX;
 +              else {
 +                      lcl_adv = tg3_advert_flowctrl_1000T(
 +                                tp->link_config.flowctrl);
 +
 +                      if (phydev->pause)
 +                              rmt_adv = LPA_PAUSE_CAP;
 +                      if (phydev->asym_pause)
 +                              rmt_adv |= LPA_PAUSE_ASYM;
 +              }
 +
 +              tg3_setup_flow_control(tp, lcl_adv, rmt_adv);
 +      } else
 +              mac_mode |= MAC_MODE_PORT_MODE_GMII;
 +
 +      if (mac_mode != tp->mac_mode) {
 +              tp->mac_mode = mac_mode;
 +              tw32_f(MAC_MODE, tp->mac_mode);
 +              udelay(40);
 +      }
 +
 +      if (phydev->speed == SPEED_1000 && phydev->duplex == DUPLEX_HALF)
 +              tw32(MAC_TX_LENGTHS,
 +                   ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
 +                    (6 << TX_LENGTHS_IPG_SHIFT) |
 +                    (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
 +      else
 +              tw32(MAC_TX_LENGTHS,
 +                   ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
 +                    (6 << TX_LENGTHS_IPG_SHIFT) |
 +                    (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
 +
 +      if ((phydev->link && tp->link_config.active_speed == SPEED_INVALID) ||
 +          (!phydev->link && tp->link_config.active_speed != SPEED_INVALID) ||
 +          phydev->speed != tp->link_config.active_speed ||
 +          phydev->duplex != tp->link_config.active_duplex ||
 +          oldflowctrl != tp->link_config.active_flowctrl)
 +          linkmesg = 1;
 +
 +      tp->link_config.active_speed = phydev->speed;
 +      tp->link_config.active_duplex = phydev->duplex;
 +
 +      spin_unlock(&tp->lock);
 +
 +      if (linkmesg)
 +              tg3_link_report(tp);
 +}
 +
 +static int tg3_phy_init(struct tg3 *tp)
 +{
 +      struct phy_device *phydev;
 +
 +      if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED)
 +              return 0;
 +
 +      /* Bring the PHY back to a known state. */
 +      tg3_bmcr_reset(tp);
 +
 +      phydev = tp->mdio_bus.phy_map[PHY_ADDR];
 +
 +      /* Attach the MAC to the PHY. */
 +      phydev = phy_connect(tp->dev, phydev->dev.bus_id, tg3_adjust_link,
 +                           phydev->dev_flags, phydev->interface);
 +      if (IS_ERR(phydev)) {
 +              printk(KERN_ERR "%s: Could not attach to PHY\n", tp->dev->name);
 +              return PTR_ERR(phydev);
 +      }
 +
 +      tp->tg3_flags3 |= TG3_FLG3_PHY_CONNECTED;
 +
 +      /* Mask with MAC supported features. */
 +      phydev->supported &= (PHY_GBIT_FEATURES |
 +                            SUPPORTED_Pause |
 +                            SUPPORTED_Asym_Pause);
 +
 +      phydev->advertising = phydev->supported;
 +
 +      printk(KERN_INFO
 +             "%s: attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
 +             tp->dev->name, phydev->drv->name, phydev->dev.bus_id);
 +
 +      return 0;
 +}
 +
 +static void tg3_phy_start(struct tg3 *tp)
 +{
 +      struct phy_device *phydev;
 +
 +      if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 +              return;
 +
 +      phydev = tp->mdio_bus.phy_map[PHY_ADDR];
 +
 +      if (tp->link_config.phy_is_low_power) {
 +              tp->link_config.phy_is_low_power = 0;
 +              phydev->speed = tp->link_config.orig_speed;
 +              phydev->duplex = tp->link_config.orig_duplex;
 +              phydev->autoneg = tp->link_config.orig_autoneg;
 +              phydev->advertising = tp->link_config.orig_advertising;
 +      }
 +
 +      phy_start(phydev);
 +
 +      phy_start_aneg(phydev);
 +}
 +
 +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]);
 +}
 +
 +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]);
 +              tp->tg3_flags3 &= ~TG3_FLG3_PHY_CONNECTED;
 +      }
 +}
 +
  static void tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
  {
        tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
@@@ -1427,6 -861,37 +1427,6 @@@ static void tg3_phy_set_wirespeed(struc
                             (val | (1 << 15) | (1 << 4)));
  }
  
 -static int tg3_bmcr_reset(struct tg3 *tp)
 -{
 -      u32 phy_control;
 -      int limit, err;
 -
 -      /* OK, reset it, and poll the BMCR_RESET bit until it
 -       * clears or we time out.
 -       */
 -      phy_control = BMCR_RESET;
 -      err = tg3_writephy(tp, MII_BMCR, phy_control);
 -      if (err != 0)
 -              return -EBUSY;
 -
 -      limit = 5000;
 -      while (limit--) {
 -              err = tg3_readphy(tp, MII_BMCR, &phy_control);
 -              if (err != 0)
 -                      return -EBUSY;
 -
 -              if ((phy_control & BMCR_RESET) == 0) {
 -                      udelay(40);
 -                      break;
 -              }
 -              udelay(10);
 -      }
 -      if (limit <= 0)
 -              return -EBUSY;
 -
 -      return 0;
 -}
 -
  static void tg3_phy_apply_otp(struct tg3 *tp)
  {
        u32 otp, phy;
@@@ -1650,6 -1115,8 +1650,6 @@@ static int tg3_phy_reset_5703_4_5(struc
        return err;
  }
  
 -static void tg3_link_report(struct tg3 *);
 -
  /* This will reset the tigon3 PHY if there is no valid
   * link unless the FORCE argument is non-zero.
   */
@@@ -1939,7 -1406,7 +1939,7 @@@ static void tg3_power_down_phy(struct t
                tw32_f(GRC_MISC_CFG, val | GRC_MISC_CFG_EPHY_IDDQ);
                udelay(40);
                return;
 -      } else {
 +      } else if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
                tg3_writephy(tp, MII_TG3_EXT_CTRL,
                             MII_TG3_EXT_CTRL_FORCE_LED_OFF);
                tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x01b2);
@@@ -2013,7 -1480,7 +2013,7 @@@ static int tg3_set_power_state(struct t
                       "requested.\n",
                       tp->dev->name, state);
                return -EINVAL;
-       };
+       }
  
        power_control |= PCI_PM_CTRL_PME_ENABLE;
  
        tw32(TG3PCI_MISC_HOST_CTRL,
             misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
  
 -      if (tp->link_config.phy_is_low_power == 0) {
 -              tp->link_config.phy_is_low_power = 1;
 -              tp->link_config.orig_speed = tp->link_config.speed;
 -              tp->link_config.orig_duplex = tp->link_config.duplex;
 -              tp->link_config.orig_autoneg = tp->link_config.autoneg;
 -      }
 +      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 +              if ((tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) &&
 +                  !tp->link_config.phy_is_low_power) {
 +                      struct phy_device *phydev;
 +                      u32 advertising;
 +
 +                      phydev = tp->mdio_bus.phy_map[PHY_ADDR];
 +
 +                      tp->link_config.phy_is_low_power = 1;
 +
 +                      tp->link_config.orig_speed = phydev->speed;
 +                      tp->link_config.orig_duplex = phydev->duplex;
 +                      tp->link_config.orig_autoneg = phydev->autoneg;
 +                      tp->link_config.orig_advertising = phydev->advertising;
 +
 +                      advertising = ADVERTISED_TP |
 +                                    ADVERTISED_Pause |
 +                                    ADVERTISED_Autoneg |
 +                                    ADVERTISED_10baseT_Half;
 +
 +                      if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
 +                          (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
 +                              if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
 +                                      advertising |=
 +                                              ADVERTISED_100baseT_Half |
 +                                              ADVERTISED_100baseT_Full |
 +                                              ADVERTISED_10baseT_Full;
 +                              else
 +                                      advertising |= ADVERTISED_10baseT_Full;
 +                      }
  
 -      if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
 -              tp->link_config.speed = SPEED_10;
 -              tp->link_config.duplex = DUPLEX_HALF;
 -              tp->link_config.autoneg = AUTONEG_ENABLE;
 -              tg3_setup_phy(tp, 0);
 +                      phydev->advertising = advertising;
 +
 +                      phy_start_aneg(phydev);
 +              }
 +      } else {
 +              if (tp->link_config.phy_is_low_power == 0) {
 +                      tp->link_config.phy_is_low_power = 1;
 +                      tp->link_config.orig_speed = tp->link_config.speed;
 +                      tp->link_config.orig_duplex = tp->link_config.duplex;
 +                      tp->link_config.orig_autoneg = tp->link_config.autoneg;
 +              }
 +
 +              if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)) {
 +                      tp->link_config.speed = SPEED_10;
 +                      tp->link_config.duplex = DUPLEX_HALF;
 +                      tp->link_config.autoneg = AUTONEG_ENABLE;
 +                      tg3_setup_phy(tp, 0);
 +              }
        }
  
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                u32 mac_mode;
  
                if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
 -                      tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
 -                      udelay(40);
 +                      if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
 +                              tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
 +                              udelay(40);
 +                      }
  
                        if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES)
                                mac_mode = MAC_MODE_PORT_MODE_GMII;
        if (!(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) &&
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
             GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
 -              u32 base_val;
 -
 -              base_val = tp->pci_clock_ctrl;
 -              base_val |= (CLOCK_CTRL_RXCLK_DISABLE |
 -                           CLOCK_CTRL_TXCLK_DISABLE);
 -
 -              tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
 -                          CLOCK_CTRL_PWRDOWN_PLL133, 40);
 -      } else if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
 -                 (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
 -                 (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)) {
 -              /* do nothing */
 -      } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
 -                   (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
 -              u32 newbits1, newbits2;
 -
 -              if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 -                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
 -                      newbits1 = (CLOCK_CTRL_RXCLK_DISABLE |
 -                                  CLOCK_CTRL_TXCLK_DISABLE |
 -                                  CLOCK_CTRL_ALTCLK);
 -                      newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
 -              } else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
 -                      newbits1 = CLOCK_CTRL_625_CORE;
 -                      newbits2 = newbits1 | CLOCK_CTRL_ALTCLK;
 -              } else {
 -                      newbits1 = CLOCK_CTRL_ALTCLK;
 -                      newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
 -              }
 -
 -              tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1,
 -                          40);
 -
 -              tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
 -                          40);
 -
 -              if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
 -                      u32 newbits3;
 -
 -                      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 -                          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
 -                              newbits3 = (CLOCK_CTRL_RXCLK_DISABLE |
 -                                          CLOCK_CTRL_TXCLK_DISABLE |
 -                                          CLOCK_CTRL_44MHZ_CORE);
 -                      } else {
 -                              newbits3 = CLOCK_CTRL_44MHZ_CORE;
 -                      }
 -
 -                      tw32_wait_f(TG3PCI_CLOCK_CTRL,
 -                                  tp->pci_clock_ctrl | newbits3, 40);
 -              }
 -      }
 -
 -      if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
 -          !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
 -          !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
 -              tg3_power_down_phy(tp);
 -
 -      tg3_frob_aux_power(tp);
 -
 -      /* Workaround for unstable PLL clock */
 -      if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
 -          (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX)) {
 -              u32 val = tr32(0x7d00);
 -
 -              val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
 -              tw32(0x7d00, val);
 -              if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
 -                      int err;
 -
 -                      err = tg3_nvram_lock(tp);
 -                      tg3_halt_cpu(tp, RX_CPU_BASE);
 -                      if (!err)
 -                              tg3_nvram_unlock(tp);
 -              }
 -      }
 -
 -      tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
 -
 -      /* Finally, set the new power state. */
 -      pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
 -      udelay(100);    /* Delay after power state change */
 -
 -      return 0;
 -}
 -
 -/* tp->lock is held. */
 -static void tg3_wait_for_event_ack(struct tg3 *tp)
 -{
 -      int i;
 -
 -      /* Wait for up to 2.5 milliseconds */
 -      for (i = 0; i < 250000; i++) {
 -              if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
 -                      break;
 -              udelay(10);
 -      }
 -}
 -
 -/* tp->lock is held. */
 -static void tg3_ump_link_report(struct tg3 *tp)
 -{
 -      u32 reg;
 -      u32 val;
 -
 -      if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
 -          !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
 -              return;
 -
 -      tg3_wait_for_event_ack(tp);
 -
 -      tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_LINK_UPDATE);
 -
 -      tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 14);
 -
 -      val = 0;
 -      if (!tg3_readphy(tp, MII_BMCR, &reg))
 -              val = reg << 16;
 -      if (!tg3_readphy(tp, MII_BMSR, &reg))
 -              val |= (reg & 0xffff);
 -      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, val);
 -
 -      val = 0;
 -      if (!tg3_readphy(tp, MII_ADVERTISE, &reg))
 -              val = reg << 16;
 -      if (!tg3_readphy(tp, MII_LPA, &reg))
 -              val |= (reg & 0xffff);
 -      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 4, val);
 -
 -      val = 0;
 -      if (!(tp->tg3_flags2 & TG3_FLG2_MII_SERDES)) {
 -              if (!tg3_readphy(tp, MII_CTRL1000, &reg))
 -                      val = reg << 16;
 -              if (!tg3_readphy(tp, MII_STAT1000, &reg))
 -                      val |= (reg & 0xffff);
 -      }
 -      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 8, val);
 -
 -      if (!tg3_readphy(tp, MII_PHYADDR, &reg))
 -              val = reg << 16;
 -      else
 -              val = 0;
 -      tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
 -
 -      val = tr32(GRC_RX_CPU_EVENT);
 -      val |= GRC_RX_CPU_DRIVER_EVENT;
 -      tw32_f(GRC_RX_CPU_EVENT, val);
 -}
 -
 -static void tg3_link_report(struct tg3 *tp)
 -{
 -      if (!netif_carrier_ok(tp->dev)) {
 -              if (netif_msg_link(tp))
 -                      printk(KERN_INFO PFX "%s: Link is down.\n",
 -                             tp->dev->name);
 -              tg3_ump_link_report(tp);
 -      } else if (netif_msg_link(tp)) {
 -              printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n",
 -                     tp->dev->name,
 -                     (tp->link_config.active_speed == SPEED_1000 ?
 -                      1000 :
 -                      (tp->link_config.active_speed == SPEED_100 ?
 -                       100 : 10)),
 -                     (tp->link_config.active_duplex == DUPLEX_FULL ?
 -                      "full" : "half"));
 -
 -              printk(KERN_INFO PFX
 -                     "%s: Flow control is %s for TX and %s for RX.\n",
 -                     tp->dev->name,
 -                     (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_TX) ?
 -                     "on" : "off",
 -                     (tp->link_config.active_flowctrl & TG3_FLOW_CTRL_RX) ?
 -                     "on" : "off");
 -              tg3_ump_link_report(tp);
 -      }
 -}
 -
 -static u16 tg3_advert_flowctrl_1000T(u8 flow_ctrl)
 -{
 -      u16 miireg;
 -
 -      if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
 -              miireg = ADVERTISE_PAUSE_CAP;
 -      else if (flow_ctrl & TG3_FLOW_CTRL_TX)
 -              miireg = ADVERTISE_PAUSE_ASYM;
 -      else if (flow_ctrl & TG3_FLOW_CTRL_RX)
 -              miireg = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 -      else
 -              miireg = 0;
 -
 -      return miireg;
 -}
 -
 -static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl)
 -{
 -      u16 miireg;
 -
 -      if ((flow_ctrl & TG3_FLOW_CTRL_TX) && (flow_ctrl & TG3_FLOW_CTRL_RX))
 -              miireg = ADVERTISE_1000XPAUSE;
 -      else if (flow_ctrl & TG3_FLOW_CTRL_TX)
 -              miireg = ADVERTISE_1000XPSE_ASYM;
 -      else if (flow_ctrl & TG3_FLOW_CTRL_RX)
 -              miireg = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM;
 -      else
 -              miireg = 0;
 +              u32 base_val;
  
 -      return miireg;
 -}
 +              base_val = tp->pci_clock_ctrl;
 +              base_val |= (CLOCK_CTRL_RXCLK_DISABLE |
 +                           CLOCK_CTRL_TXCLK_DISABLE);
  
 -static u8 tg3_resolve_flowctrl_1000T(u16 lcladv, u16 rmtadv)
 -{
 -      u8 cap = 0;
 +              tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
 +                          CLOCK_CTRL_PWRDOWN_PLL133, 40);
 +      } else if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
 +                 (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
 +                 (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)) {
 +              /* do nothing */
 +      } else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
 +                   (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
 +              u32 newbits1, newbits2;
  
 -      if (lcladv & ADVERTISE_PAUSE_CAP) {
 -              if (lcladv & ADVERTISE_PAUSE_ASYM) {
 -                      if (rmtadv & LPA_PAUSE_CAP)
 -                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 -                      else if (rmtadv & LPA_PAUSE_ASYM)
 -                              cap = TG3_FLOW_CTRL_RX;
 +              if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 +                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
 +                      newbits1 = (CLOCK_CTRL_RXCLK_DISABLE |
 +                                  CLOCK_CTRL_TXCLK_DISABLE |
 +                                  CLOCK_CTRL_ALTCLK);
 +                      newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
 +              } else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
 +                      newbits1 = CLOCK_CTRL_625_CORE;
 +                      newbits2 = newbits1 | CLOCK_CTRL_ALTCLK;
                } else {
 -                      if (rmtadv & LPA_PAUSE_CAP)
 -                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 +                      newbits1 = CLOCK_CTRL_ALTCLK;
 +                      newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
                }
 -      } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
 -              if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
 -                      cap = TG3_FLOW_CTRL_TX;
 -      }
  
 -      return cap;
 -}
 +              tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits1,
 +                          40);
  
 -static u8 tg3_resolve_flowctrl_1000X(u16 lcladv, u16 rmtadv)
 -{
 -      u8 cap = 0;
 +              tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
 +                          40);
  
 -      if (lcladv & ADVERTISE_1000XPAUSE) {
 -              if (lcladv & ADVERTISE_1000XPSE_ASYM) {
 -                      if (rmtadv & LPA_1000XPAUSE)
 -                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 -                      else if (rmtadv & LPA_1000XPAUSE_ASYM)
 -                              cap = TG3_FLOW_CTRL_RX;
 -              } else {
 -                      if (rmtadv & LPA_1000XPAUSE)
 -                              cap = TG3_FLOW_CTRL_TX | TG3_FLOW_CTRL_RX;
 +              if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
 +                      u32 newbits3;
 +
 +                      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 +                          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
 +                              newbits3 = (CLOCK_CTRL_RXCLK_DISABLE |
 +                                          CLOCK_CTRL_TXCLK_DISABLE |
 +                                          CLOCK_CTRL_44MHZ_CORE);
 +                      } else {
 +                              newbits3 = CLOCK_CTRL_44MHZ_CORE;
 +                      }
 +
 +                      tw32_wait_f(TG3PCI_CLOCK_CTRL,
 +                                  tp->pci_clock_ctrl | newbits3, 40);
                }
 -      } else if (lcladv & ADVERTISE_1000XPSE_ASYM) {
 -              if ((rmtadv & LPA_1000XPAUSE) && (rmtadv & LPA_1000XPAUSE_ASYM))
 -                      cap = TG3_FLOW_CTRL_TX;
        }
  
 -      return cap;
 -}
 -
 -static void tg3_setup_flow_control(struct tg3 *tp, u32 local_adv, u32 remote_adv)
 -{
 -      u8 new_tg3_flags = 0;
 -      u32 old_rx_mode = tp->rx_mode;
 -      u32 old_tx_mode = tp->tx_mode;
 +      if (!(tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
 +          !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
 +          !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
 +              tg3_power_down_phy(tp);
  
 -      if (tp->link_config.autoneg == AUTONEG_ENABLE &&
 -          (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
 -              if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES)
 -                      new_tg3_flags = tg3_resolve_flowctrl_1000X(local_adv,
 -                                                                 remote_adv);
 -              else
 -                      new_tg3_flags = tg3_resolve_flowctrl_1000T(local_adv,
 -                                                                 remote_adv);
 -      } else {
 -              new_tg3_flags = tp->link_config.flowctrl;
 -      }
 +      tg3_frob_aux_power(tp);
  
 -      tp->link_config.active_flowctrl = new_tg3_flags;
 +      /* Workaround for unstable PLL clock */
 +      if ((GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX) ||
 +          (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX)) {
 +              u32 val = tr32(0x7d00);
  
 -      if (new_tg3_flags & TG3_FLOW_CTRL_RX)
 -              tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
 -      else
 -              tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
 +              val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
 +              tw32(0x7d00, val);
 +              if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
 +                      int err;
  
 -      if (old_rx_mode != tp->rx_mode) {
 -              tw32_f(MAC_RX_MODE, tp->rx_mode);
 +                      err = tg3_nvram_lock(tp);
 +                      tg3_halt_cpu(tp, RX_CPU_BASE);
 +                      if (!err)
 +                              tg3_nvram_unlock(tp);
 +              }
        }
  
 -      if (new_tg3_flags & TG3_FLOW_CTRL_TX)
 -              tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
 -      else
 -              tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
 +      tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN);
  
 -      if (old_tx_mode != tp->tx_mode) {
 -              tw32_f(MAC_TX_MODE, tp->tx_mode);
 -      }
 +      /* Finally, set the new power state. */
 +      pci_write_config_word(tp->pdev, pm + PCI_PM_CTRL, power_control);
 +      udelay(100);    /* Delay after power state change */
 +
 +      return 0;
  }
  
  static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
                *speed = SPEED_INVALID;
                *duplex = DUPLEX_INVALID;
                break;
-       };
+       }
  }
  
  static void tg3_phy_copper_begin(struct tg3 *tp)
                case SPEED_1000:
                        bmcr |= TG3_BMCR_SPEED1000;
                        break;
-               };
+               }
  
                if (tp->link_config.duplex == DUPLEX_FULL)
                        bmcr |= BMCR_FULLDPLX;
@@@ -3082,7 -2716,7 +3082,7 @@@ static int tg3_fiber_aneg_smachine(stru
        default:
                ret = ANEG_FAILED;
                break;
-       };
+       }
  
        return ret;
  }
@@@ -3924,7 -3558,7 +3924,7 @@@ static int tg3_alloc_rx_skb(struct tg3 
  
        default:
                return -EINVAL;
-       };
+       }
  
        /* Do not overwrite any of the map or rp information
         * until we are sure we can commit to a new buffer.
@@@ -3984,7 -3618,7 +3984,7 @@@ static void tg3_recycle_rx(struct tg3 *
  
        default:
                return;
-       };
+       }
  
        dest_map->skb = src_map->skb;
        pci_unmap_addr_set(dest_map, mapping,
@@@ -4194,15 -3828,7 +4194,15 @@@ static int tg3_poll_work(struct tg3 *tp
                        sblk->status = SD_STATUS_UPDATED |
                                (sblk->status & ~SD_STATUS_LINK_CHG);
                        spin_lock(&tp->lock);
 -                      tg3_setup_phy(tp, 0);
 +                      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 +                              tw32_f(MAC_STATUS,
 +                                   (MAC_STATUS_SYNC_CHANGED |
 +                                    MAC_STATUS_CFG_CHANGED |
 +                                    MAC_STATUS_MI_COMPLETION |
 +                                    MAC_STATUS_LNKSTATE_CHANGED));
 +                              udelay(40);
 +                      } else
 +                              tg3_setup_phy(tp, 0);
                        spin_unlock(&tp->lock);
                }
        }
@@@ -4490,7 -4116,6 +4490,7 @@@ static void tg3_poll_controller(struct 
  static void tg3_reset_task(struct work_struct *work)
  {
        struct tg3 *tp = container_of(work, struct tg3, reset_task);
 +      int err;
        unsigned int restart_timer;
  
        tg3_full_lock(tp, 0);
  
        tg3_full_unlock(tp);
  
 +      tg3_phy_stop(tp);
 +
        tg3_netif_stop(tp);
  
        tg3_full_lock(tp, 1);
        }
  
        tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
 -      if (tg3_init_hw(tp, 1))
 +      err = tg3_init_hw(tp, 1);
 +      if (err)
                goto out;
  
        tg3_netif_start(tp);
  
  out:
        tg3_full_unlock(tp);
 +
 +      if (!err)
 +              tg3_phy_start(tp);
  }
  
  static void tg3_dump_short_state(struct tg3 *tp)
@@@ -5036,8 -4655,6 +5036,8 @@@ static int tg3_change_mtu(struct net_de
                return 0;
        }
  
 +      tg3_phy_stop(tp);
 +
        tg3_netif_stop(tp);
  
        tg3_full_lock(tp, 1);
  
        tg3_full_unlock(tp);
  
 +      if (!err)
 +              tg3_phy_start(tp);
 +
        return err;
  }
  
@@@ -5347,7 -4961,7 +5347,7 @@@ static int tg3_stop_block(struct tg3 *t
  
                default:
                        break;
-               };
+               }
        }
  
        val = tr32(ofs);
@@@ -5589,7 -5203,7 +5589,7 @@@ static void tg3_write_sig_pre_reset(str
  
                default:
                        break;
-               };
+               }
        }
  
        if (kind == RESET_KIND_INIT ||
@@@ -5614,7 -5228,7 +5614,7 @@@ static void tg3_write_sig_post_reset(st
  
                default:
                        break;
-               };
+               }
        }
  
        if (kind == RESET_KIND_SHUTDOWN)
@@@ -5643,7 -5257,7 +5643,7 @@@ static void tg3_write_sig_legacy(struc
  
                default:
                        break;
-               };
+               }
        }
  }
  
@@@ -5765,8 -5379,6 +5765,8 @@@ static int tg3_chip_reset(struct tg3 *t
  
        tg3_nvram_lock(tp);
  
 +      tg3_mdio_stop(tp);
 +
        /* No matching tg3_nvram_unlock() after this because
         * chip reset below will undo the nvram lock.
         */
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                tw32(GRC_FASTBOOT_PC, 0);
  
        /*
                tw32_f(MAC_MODE, 0);
        udelay(40);
  
 +      tg3_mdio_start(tp);
 +
        err = tg3_poll_fw(tp);
        if (err)
                return err;
@@@ -7000,8 -6609,7 +7000,8 @@@ static int tg3_reset_hw(struct tg3 *tp
                tg3_abort_hw(tp, 1);
        }
  
 -      if (reset_phy)
 +      if (reset_phy &&
 +          !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB))
                tg3_phy_reset(tp);
  
        err = tg3_chip_reset(tp);
                return err;
  
        if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
 +          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
 +          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
                /* This value is determined during the probe time DMA
                 * engine test, tg3_test_dma.
                 */
                      RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
                      RDMAC_MODE_LNGREAD_ENAB);
  
 -      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)
 +      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                rdmac_mode |= RDMAC_MODE_BD_SBD_CRPT_ENAB |
                              RDMAC_MODE_MBUF_RBD_CRPT_ENAB |
                              RDMAC_MODE_MBUF_SBD_CRPT_ENAB;
        if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755) ||
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787) ||
            (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784) ||
 -          (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761))
 -              val |= (1 << 29);
 +          (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) ||
 +          (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785))
 +              val |= WDMAC_MODE_STATUS_TAG_FIX;
  
        tw32_f(WDMAC_MODE, val);
        udelay(40);
  
        tp->rx_mode = RX_MODE_ENABLE;
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
 -          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
  
        tw32_f(MAC_RX_MODE, tp->rx_mode);
        udelay(10);
  
 -      if (tp->link_config.phy_is_low_power) {
 -              tp->link_config.phy_is_low_power = 0;
 -              tp->link_config.speed = tp->link_config.orig_speed;
 -              tp->link_config.duplex = tp->link_config.orig_duplex;
 -              tp->link_config.autoneg = tp->link_config.orig_autoneg;
 -      }
 -
 -      tp->mi_mode &= ~MAC_MI_MODE_AUTO_POLL;
 -      tw32_f(MAC_MI_MODE, tp->mi_mode);
 -      udelay(80);
 -
        tw32(MAC_LED_CTRL, tp->led_ctrl);
  
        tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
                tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
        }
  
 -      err = tg3_setup_phy(tp, 0);
 -      if (err)
 -              return err;
 +      if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
 +              if (tp->link_config.phy_is_low_power) {
 +                      tp->link_config.phy_is_low_power = 0;
 +                      tp->link_config.speed = tp->link_config.orig_speed;
 +                      tp->link_config.duplex = tp->link_config.orig_duplex;
 +                      tp->link_config.autoneg = tp->link_config.orig_autoneg;
 +              }
  
 -      if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
 -              u32 tmp;
 +              err = tg3_setup_phy(tp, 0);
 +              if (err)
 +                      return err;
  
 -              /* Clear CRC stats. */
 -              if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
 -                      tg3_writephy(tp, MII_TG3_TEST1,
 -                                   tmp | MII_TG3_TEST1_CRC_EN);
 -                      tg3_readphy(tp, 0x14, &tmp);
 +              if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
 +                  GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906) {
 +                      u32 tmp;
 +
 +                      /* Clear CRC stats. */
 +                      if (!tg3_readphy(tp, MII_TG3_TEST1, &tmp)) {
 +                              tg3_writephy(tp, MII_TG3_TEST1,
 +                                           tmp | MII_TG3_TEST1_CRC_EN);
 +                              tg3_readphy(tp, 0x14, &tmp);
 +                      }
                }
        }
  
  
        default:
                break;
-       };
+       }
  
        if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
                /* Write our heartbeat update interval to APE. */
@@@ -8139,8 -7744,6 +8139,8 @@@ static int tg3_open(struct net_device *
                }
        }
  
 +      tg3_phy_start(tp);
 +
        tg3_full_lock(tp, 0);
  
        add_timer(&tp->timer);
@@@ -8942,13 -8545,7 +8942,13 @@@ static int tg3_set_eeprom(struct net_de
  
  static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  {
 -      struct tg3 *tp = netdev_priv(dev);
 +      struct tg3 *tp = netdev_priv(dev);
 +
 +      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 +              if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 +                      return -EAGAIN;
 +              return phy_ethtool_gset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
 +      }
  
        cmd->supported = (SUPPORTED_Autoneg);
  
@@@ -8985,12 -8582,6 +8985,12 @@@ static int tg3_set_settings(struct net_
  {
        struct tg3 *tp = netdev_priv(dev);
  
 +      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 +              if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 +                      return -EAGAIN;
 +              return phy_ethtool_sset(tp->mdio_bus.phy_map[PHY_ADDR], cmd);
 +      }
 +
        if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
                /* These are the only valid advertisement bits allowed.  */
                if (cmd->autoneg == AUTONEG_ENABLE &&
                tp->link_config.advertising = 0;
                tp->link_config.speed = cmd->speed;
                tp->link_config.duplex = cmd->duplex;
 -      }
 +      }
  
        tp->link_config.orig_speed = tp->link_config.speed;
        tp->link_config.orig_duplex = tp->link_config.duplex;
@@@ -9106,10 -8697,7 +9106,10 @@@ static int tg3_set_tso(struct net_devic
            (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)) {
                if (value) {
                        dev->features |= NETIF_F_TSO6;
 -                      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +                      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +                          (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
 +                           GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
 +                          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                                dev->features |= NETIF_F_TSO_ECN;
                } else
                        dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
  static int tg3_nway_reset(struct net_device *dev)
  {
        struct tg3 *tp = netdev_priv(dev);
 -      u32 bmcr;
        int r;
  
        if (!netif_running(dev))
        if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)
                return -EINVAL;
  
 -      spin_lock_bh(&tp->lock);
 -      r = -EINVAL;
 -      tg3_readphy(tp, MII_BMCR, &bmcr);
 -      if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
 -          ((bmcr & BMCR_ANENABLE) ||
 -           (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
 -              tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
 -                                         BMCR_ANENABLE);
 -              r = 0;
 +      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]);
 +      } else {
 +              u32 bmcr;
 +
 +              spin_lock_bh(&tp->lock);
 +              r = -EINVAL;
 +              tg3_readphy(tp, MII_BMCR, &bmcr);
 +              if (!tg3_readphy(tp, MII_BMCR, &bmcr) &&
 +                  ((bmcr & BMCR_ANENABLE) ||
 +                   (tp->tg3_flags2 & TG3_FLG2_PARALLEL_DETECT))) {
 +                      tg3_writephy(tp, MII_BMCR, bmcr | BMCR_ANRESTART |
 +                                                 BMCR_ANENABLE);
 +                      r = 0;
 +              }
 +              spin_unlock_bh(&tp->lock);
        }
 -      spin_unlock_bh(&tp->lock);
  
        return r;
  }
@@@ -9188,7 -8769,6 +9188,7 @@@ static int tg3_set_ringparam(struct net
                return -EINVAL;
  
        if (netif_running(dev)) {
 +              tg3_phy_stop(tp);
                tg3_netif_stop(tp);
                irq_sync = 1;
        }
  
        tg3_full_unlock(tp);
  
 +      if (irq_sync && !err)
 +              tg3_phy_start(tp);
 +
        return err;
  }
  
@@@ -9238,92 -8815,36 +9238,92 @@@ static void tg3_get_pauseparam(struct n
  static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
  {
        struct tg3 *tp = netdev_priv(dev);
 -      int irq_sync = 0, err = 0;
 +      int err = 0;
  
 -      if (netif_running(dev)) {
 -              tg3_netif_stop(tp);
 -              irq_sync = 1;
 -      }
 +      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 +              if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 +                      return -EAGAIN;
  
 -      tg3_full_lock(tp, irq_sync);
 +              if (epause->autoneg) {
 +                      u32 newadv;
 +                      struct phy_device *phydev;
  
 -      if (epause->autoneg)
 -              tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
 -      else
 -              tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
 -      if (epause->rx_pause)
 -              tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
 -      else
 -              tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
 -      if (epause->tx_pause)
 -              tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
 -      else
 -              tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
 +                      phydev = tp->mdio_bus.phy_map[PHY_ADDR];
  
 -      if (netif_running(dev)) {
 -              tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 -              err = tg3_restart_hw(tp, 1);
 -              if (!err)
 -                      tg3_netif_start(tp);
 -      }
 +                      if (epause->rx_pause) {
 +                              if (epause->tx_pause)
 +                                      newadv = ADVERTISED_Pause;
 +                              else
 +                                      newadv = ADVERTISED_Pause |
 +                                               ADVERTISED_Asym_Pause;
 +                      } else if (epause->tx_pause) {
 +                              newadv = ADVERTISED_Asym_Pause;
 +                      } else
 +                              newadv = 0;
 +
 +                      if (tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED) {
 +                              u32 oldadv = phydev->advertising &
 +                                           (ADVERTISED_Pause |
 +                                            ADVERTISED_Asym_Pause);
 +                              if (oldadv != newadv) {
 +                                      phydev->advertising &=
 +                                              ~(ADVERTISED_Pause |
 +                                                ADVERTISED_Asym_Pause);
 +                                      phydev->advertising |= newadv;
 +                                      err = phy_start_aneg(phydev);
 +                              }
 +                      } else {
 +                              tp->link_config.advertising &=
 +                                              ~(ADVERTISED_Pause |
 +                                                ADVERTISED_Asym_Pause);
 +                              tp->link_config.advertising |= newadv;
 +                      }
 +              } else {
 +                      if (epause->rx_pause)
 +                              tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
 +                      else
 +                              tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
  
 -      tg3_full_unlock(tp);
 +                      if (epause->tx_pause)
 +                              tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
 +                      else
 +                              tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
 +
 +                      if (netif_running(dev))
 +                              tg3_setup_flow_control(tp, 0, 0);
 +              }
 +      } else {
 +              int irq_sync = 0;
 +
 +              if (netif_running(dev)) {
 +                      tg3_netif_stop(tp);
 +                      irq_sync = 1;
 +              }
 +
 +              tg3_full_lock(tp, irq_sync);
 +
 +              if (epause->autoneg)
 +                      tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
 +              else
 +                      tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
 +              if (epause->rx_pause)
 +                      tp->link_config.flowctrl |= TG3_FLOW_CTRL_RX;
 +              else
 +                      tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_RX;
 +              if (epause->tx_pause)
 +                      tp->link_config.flowctrl |= TG3_FLOW_CTRL_TX;
 +              else
 +                      tp->link_config.flowctrl &= ~TG3_FLOW_CTRL_TX;
 +
 +              if (netif_running(dev)) {
 +                      tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 +                      err = tg3_restart_hw(tp, 1);
 +                      if (!err)
 +                              tg3_netif_start(tp);
 +              }
 +
 +              tg3_full_unlock(tp);
 +      }
  
        return err;
  }
@@@ -9367,8 -8888,7 +9367,8 @@@ static int tg3_set_tx_csum(struct net_d
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                ethtool_op_set_tx_ipv6_csum(dev, data);
        else
                ethtool_op_set_tx_csum(dev, data);
@@@ -9889,8 -9409,7 +9889,8 @@@ static int tg3_test_memory(struct tg3 *
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                        mem_tbl = mem_tbl_5755;
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                        mem_tbl = mem_tbl_5906;
@@@ -10097,8 -9616,7 +10097,8 @@@ static int tg3_test_loopback(struct tg
                return TG3_LOOPBACK_FAILED;
  
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
                int i;
                u32 status;
  
                err |= TG3_MAC_LOOPBACK_FAILED;
  
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
                tw32(TG3_CPMU_CTRL, cpmuctrl);
  
                /* Release the mutex */
                tw32(TG3_CPMU_MUTEX_GNT, CPMU_MUTEX_GNT_DRIVER);
        }
  
 -      if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) {
 +      if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
 +          !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
                if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK))
                        err |= TG3_PHY_LOOPBACK_FAILED;
        }
@@@ -10162,10 -9678,9 +10162,10 @@@ static void tg3_self_test(struct net_de
                data[1] = 1;
        }
        if (etest->flags & ETH_TEST_FL_OFFLINE) {
 -              int err, irq_sync = 0;
 +              int err, err2 = 0, irq_sync = 0;
  
                if (netif_running(dev)) {
 +                      tg3_phy_stop(tp);
                        tg3_netif_stop(tp);
                        irq_sync = 1;
                }
                tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
                if (netif_running(dev)) {
                        tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
 -                      if (!tg3_restart_hw(tp, 1))
 +                      err2 = tg3_restart_hw(tp, 1);
 +                      if (!err2)
                                tg3_netif_start(tp);
                }
  
                tg3_full_unlock(tp);
 +
 +              if (irq_sync && !err2)
 +                      tg3_phy_start(tp);
        }
        if (tp->link_config.phy_is_low_power)
                tg3_set_power_state(tp, PCI_D3hot);
@@@ -10227,12 -9738,6 +10227,12 @@@ static int tg3_ioctl(struct net_device 
        struct tg3 *tp = netdev_priv(dev);
        int err;
  
 +      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 +              if (!(tp->tg3_flags3 & TG3_FLG3_PHY_CONNECTED))
 +                      return -EAGAIN;
 +              return phy_mii_ioctl(tp->mdio_bus.phy_map[PHY_ADDR], data, cmd);
 +      }
 +
        switch(cmd) {
        case SIOCGMIIPHY:
                data->phy_id = PHY_ADDR;
@@@ -10775,8 -10280,7 +10775,8 @@@ static void __devinit tg3_nvram_init(st
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
                        tg3_get_5755_nvram_info(tp);
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
 -                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784)
 +                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 +                       GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                        tg3_get_5787_nvram_info(tp);
                else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
                        tg3_get_5761_nvram_info(tp);
@@@ -11107,7 -10611,6 +11107,7 @@@ static int tg3_nvram_write_block_buffer
                    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787) &&
                    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784) &&
                    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) &&
 +                  (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) &&
                    (tp->nvram_jedecnum == JEDEC_ST) &&
                    (nvram_cmd & NVRAM_CMD_FIRST)) {
  
@@@ -11290,7 -10793,7 +11290,7 @@@ static void __devinit tg3_get_eeprom_hw
        tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
        if (val == NIC_SRAM_DATA_SIG_MAGIC) {
                u32 nic_cfg, led_cfg;
 -              u32 nic_phy_id, ver, cfg2 = 0, eeprom_phy_id;
 +              u32 nic_phy_id, ver, cfg2 = 0, cfg4 = 0, eeprom_phy_id;
                int eeprom_phy_serdes = 0;
  
                tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
                    (ver > 0) && (ver < 0x100))
                        tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
  
 +              if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
 +                      tg3_read_mem(tp, NIC_SRAM_DATA_CFG_4, &cfg4);
 +
                if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
                    NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER)
                        eeprom_phy_serdes = 1;
                                                 LED_CTRL_MODE_PHY_2);
                        break;
  
-               };
+               }
  
                if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
                     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) &&
                        if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)
                                tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
                }
 +
 +              if (cfg4 & NIC_SRAM_RGMII_STD_IBND_DISABLE)
 +                      tp->tg3_flags3 |= TG3_FLG3_RGMII_STD_IBND_DISABLE;
 +              if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN)
 +                      tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN;
 +              if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
 +                      tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
        }
  }
  
@@@ -11496,9 -10989,6 +11496,9 @@@ static int __devinit tg3_phy_probe(stru
        u32 hw_phy_id, hw_phy_id_masked;
        int err;
  
 +      if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
 +              return tg3_phy_init(tp);
 +
        /* Reading the PHY ID register can conflict with ASF
         * firwmare access to the PHY hardware.
         */
@@@ -12021,7 -11511,6 +12021,7 @@@ static int __devinit tg3_get_invariants
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
            (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                        tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
                        tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
                }
        }
  
 -      if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5750 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5755 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5787 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761 &&
 -          GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
 +      if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
 +           (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
                tp->tg3_flags2 |= TG3_FLG2_JUMBO_CAPABLE;
  
        pcie_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_EXP);
        }
  
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761) {
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
                tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
  
                if (tp->pci_chip_rev_id == CHIPREV_ID_5784_A0 ||
                                tp->tg3_flags2 |= TG3_FLG2_PHY_JITTER_BUG;
                        if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5755M)
                                tp->tg3_flags2 |= TG3_FLG2_PHY_ADJUST_TRIM;
 -              } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906)
 +              } else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906 &&
 +                         GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785)
                        tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG;
        }
  
                        tp->phy_otp = TG3_OTP_DEFAULT;
        }
  
 -      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +      if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)
                tp->mi_mode = MAC_MI_MODE_500KHZ_CONST;
        else
                tp->mi_mode = MAC_MI_MODE_BASE;
            GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
                tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
  
 -      /* Initialize MAC MI mode, polling disabled. */
 -      tw32_f(MAC_MI_MODE, tp->mi_mode);
 -      udelay(80);
 +      if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
 +              tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
 +
 +      err = tg3_mdio_init(tp);
 +      if (err)
 +              return err;
  
        /* Initialize data/descriptor byte/word swapping. */
        val = tr32(GRC_MODE);
                printk(KERN_ERR PFX "(%s) phy probe failed, err %d\n",
                       pci_name(tp->pdev), err);
                /* ... but do not return immediately ... */
 +              tg3_mdio_fini(tp);
        }
  
        tg3_read_partno(tp);
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +          GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                tp->dev->hard_start_xmit = tg3_start_xmit;
        else
@@@ -12690,7 -12178,7 +12690,7 @@@ static u32 __devinit tg3_calc_dma_bndry
                        val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX |
                                DMA_RWCTRL_WRITE_BNDRY_384_PCIX);
                        break;
-               };
+               }
        } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
                switch (cacheline_size) {
                case 16:
                        val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE;
                        val |= DMA_RWCTRL_WRITE_BNDRY_128_PCIE;
                        break;
-               };
+               }
        } else {
                switch (cacheline_size) {
                case 16:
                        val |= (DMA_RWCTRL_READ_BNDRY_1024 |
                                DMA_RWCTRL_WRITE_BNDRY_1024);
                        break;
-               };
+               }
        }
  
  out:
@@@ -13111,7 -12599,7 +13111,7 @@@ static char * __devinit tg3_phy_string(
        case PHY_ID_BCM8002:    return "8002/serdes";
        case 0:                 return "serdes";
        default:                return "unknown";
-       };
+       }
  }
  
  static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
@@@ -13412,10 -12900,7 +13412,10 @@@ static int __devinit tg3_init_one(struc
                if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) &&
                    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5906))
                        dev->features |= NETIF_F_TSO6;
 -              if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +              if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +                  (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
 +                   GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
 +                      GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                        dev->features |= NETIF_F_TSO_ECN;
        }
  
                if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
                    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 -                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
 +                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 +                  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
                        dev->features |= NETIF_F_IPV6_CSUM;
  
                tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
@@@ -13564,12 -13048,6 +13564,12 @@@ static void __devexit tg3_remove_one(st
                struct tg3 *tp = netdev_priv(dev);
  
                flush_scheduled_work();
 +
 +              if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
 +                      tg3_phy_fini(tp);
 +                      tg3_mdio_fini(tp);
 +              }
 +
                unregister_netdev(dev);
                if (tp->aperegs) {
                        iounmap(tp->aperegs);
@@@ -13602,7 -13080,6 +13602,7 @@@ static int tg3_suspend(struct pci_dev *
                return 0;
  
        flush_scheduled_work();
 +      tg3_phy_stop(tp);
        tg3_netif_stop(tp);
  
        del_timer_sync(&tp->timer);
  
        err = tg3_set_power_state(tp, pci_choose_state(pdev, state));
        if (err) {
 +              int err2;
 +
                tg3_full_lock(tp, 0);
  
                tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
 -              if (tg3_restart_hw(tp, 1))
 +              err2 = tg3_restart_hw(tp, 1);
 +              if (err2)
                        goto out;
  
                tp->timer.expires = jiffies + tp->timer_offset;
  
  out:
                tg3_full_unlock(tp);
 +
 +              if (!err2)
 +                      tg3_phy_start(tp);
        }
  
        return err;
@@@ -13677,9 -13148,6 +13677,9 @@@ static int tg3_resume(struct pci_dev *p
  out:
        tg3_full_unlock(tp);
  
 +      if (!err)
 +              tg3_phy_start(tp);
 +
        return err;
  }
  
index e1177cca8a760394c346ffd9038a00c7ae3db152,3969b7a2b8e6529d5b06cc7ed5c55db2041ae8a2..ae467f182c4025958b00060ee1b29972c0467d25
@@@ -194,7 -194,7 +194,7 @@@ int rndis_command(struct usbnet *dev, s
                        dev_dbg(&info->control->dev,
                                "rndis response error, code %d\n", retval);
                }
 -              msleep(2);
 +              msleep(20);
        }
        dev_dbg(&info->control->dev, "rndis response timeout\n");
        return -ETIMEDOUT;
@@@ -283,8 -283,8 +283,8 @@@ generic_rndis_bind(struct usbnet *dev, 
                struct rndis_set_c      *set_c;
                struct rndis_halt       *halt;
        } u;
-       u32                     tmp, phym_unspec;
-       __le32                  *phym;
+       u32                     tmp;
+       __le32                  phym_unspec, *phym;
        int                     reply_len;
        unsigned char           *bp;
  
This page took 0.152385 seconds and 4 git commands to generate.