brcm47xx: fix name of patch
authorhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 15 Jul 2013 11:42:54 +0000 (11:42 +0000)
committerhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 15 Jul 2013 11:42:54 +0000 (11:42 +0000)
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37340 3c298f89-4303-0410-b956-a3cf2f4a3e73

target/linux/brcm47xx/patches-3.10/780-b43-phylib.patch [deleted file]
target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch [new file with mode: 0644]

diff --git a/target/linux/brcm47xx/patches-3.10/780-b43-phylib.patch b/target/linux/brcm47xx/patches-3.10/780-b43-phylib.patch
deleted file mode 100644 (file)
index 72b374c..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
---- a/drivers/net/ethernet/broadcom/Kconfig
-+++ b/drivers/net/ethernet/broadcom/Kconfig
-@@ -24,6 +24,7 @@ config B44
-       select SSB
-       select NET_CORE
-       select MII
-+      select PHYLIB
-       ---help---
-         If you have a network (Ethernet) controller of this type, say Y
-         or M and read the Ethernet-HOWTO, available from
---- a/drivers/net/ethernet/broadcom/b44.c
-+++ b/drivers/net/ethernet/broadcom/b44.c
-@@ -29,6 +29,7 @@
- #include <linux/dma-mapping.h>
- #include <linux/ssb/ssb.h>
- #include <linux/slab.h>
-+#include <linux/phy.h>
- #include <asm/uaccess.h>
- #include <asm/io.h>
-@@ -300,21 +301,23 @@ static inline int b44_writephy(struct b4
- }
- /* miilib interface */
--static int b44_mii_read(struct net_device *dev, int phy_id, int location)
-+static int b44_mii_read(struct mii_bus *bus, int phy_id, int location)
- {
-       u32 val;
--      struct b44 *bp = netdev_priv(dev);
-+      struct b44 *bp = bus->priv;
-       int rc = __b44_readphy(bp, phy_id, location, &val);
-       if (rc)
-               return 0xffffffff;
-       return val;
- }
--static void b44_mii_write(struct net_device *dev, int phy_id, int location,
--                       int val)
-+static int b44_mii_write(struct mii_bus *bus, int phy_id, int location,
-+                       u16 val)
- {
--      struct b44 *bp = netdev_priv(dev);
-+      struct b44 *bp = bus->priv;
-       __b44_writephy(bp, phy_id, location, val);
-+
-+      return 0;
- }
- static int b44_phy_reset(struct b44 *bp)
-@@ -1821,102 +1824,24 @@ static int b44_get_settings(struct net_d
- {
-       struct b44 *bp = netdev_priv(dev);
--      cmd->supported = (SUPPORTED_Autoneg);
--      cmd->supported |= (SUPPORTED_100baseT_Half |
--                        SUPPORTED_100baseT_Full |
--                        SUPPORTED_10baseT_Half |
--                        SUPPORTED_10baseT_Full |
--                        SUPPORTED_MII);
--
--      cmd->advertising = 0;
--      if (bp->flags & B44_FLAG_ADV_10HALF)
--              cmd->advertising |= ADVERTISED_10baseT_Half;
--      if (bp->flags & B44_FLAG_ADV_10FULL)
--              cmd->advertising |= ADVERTISED_10baseT_Full;
--      if (bp->flags & B44_FLAG_ADV_100HALF)
--              cmd->advertising |= ADVERTISED_100baseT_Half;
--      if (bp->flags & B44_FLAG_ADV_100FULL)
--              cmd->advertising |= ADVERTISED_100baseT_Full;
--      cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
--      ethtool_cmd_speed_set(cmd, ((bp->flags & B44_FLAG_100_BASE_T) ?
--                                  SPEED_100 : SPEED_10));
--      cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
--              DUPLEX_FULL : DUPLEX_HALF;
--      cmd->port = 0;
--      cmd->phy_address = bp->phy_addr;
--      cmd->transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
--              XCVR_INTERNAL : XCVR_EXTERNAL;
--      cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
--              AUTONEG_DISABLE : AUTONEG_ENABLE;
--      if (cmd->autoneg == AUTONEG_ENABLE)
--              cmd->advertising |= ADVERTISED_Autoneg;
--      if (!netif_running(dev)){
--              ethtool_cmd_speed_set(cmd, 0);
--              cmd->duplex = 0xff;
--      }
--      cmd->maxtxpkt = 0;
--      cmd->maxrxpkt = 0;
--      return 0;
-+      return phy_ethtool_gset(bp->phydev, cmd);
- }
- static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
- {
-       struct b44 *bp = netdev_priv(dev);
--      u32 speed = ethtool_cmd_speed(cmd);
--
--      /* We do not support gigabit. */
--      if (cmd->autoneg == AUTONEG_ENABLE) {
--              if (cmd->advertising &
--                  (ADVERTISED_1000baseT_Half |
--                   ADVERTISED_1000baseT_Full))
--                      return -EINVAL;
--      } else if ((speed != SPEED_100 &&
--                  speed != SPEED_10) ||
--                 (cmd->duplex != DUPLEX_HALF &&
--                  cmd->duplex != DUPLEX_FULL)) {
--                      return -EINVAL;
--      }
-+      int ret;
-       spin_lock_irq(&bp->lock);
--      if (cmd->autoneg == AUTONEG_ENABLE) {
--              bp->flags &= ~(B44_FLAG_FORCE_LINK |
--                             B44_FLAG_100_BASE_T |
--                             B44_FLAG_FULL_DUPLEX |
--                             B44_FLAG_ADV_10HALF |
--                             B44_FLAG_ADV_10FULL |
--                             B44_FLAG_ADV_100HALF |
--                             B44_FLAG_ADV_100FULL);
--              if (cmd->advertising == 0) {
--                      bp->flags |= (B44_FLAG_ADV_10HALF |
--                                    B44_FLAG_ADV_10FULL |
--                                    B44_FLAG_ADV_100HALF |
--                                    B44_FLAG_ADV_100FULL);
--              } else {
--                      if (cmd->advertising & ADVERTISED_10baseT_Half)
--                              bp->flags |= B44_FLAG_ADV_10HALF;
--                      if (cmd->advertising & ADVERTISED_10baseT_Full)
--                              bp->flags |= B44_FLAG_ADV_10FULL;
--                      if (cmd->advertising & ADVERTISED_100baseT_Half)
--                              bp->flags |= B44_FLAG_ADV_100HALF;
--                      if (cmd->advertising & ADVERTISED_100baseT_Full)
--                              bp->flags |= B44_FLAG_ADV_100FULL;
--              }
--      } else {
--              bp->flags |= B44_FLAG_FORCE_LINK;
--              bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
--              if (speed == SPEED_100)
--                      bp->flags |= B44_FLAG_100_BASE_T;
--              if (cmd->duplex == DUPLEX_FULL)
--                      bp->flags |= B44_FLAG_FULL_DUPLEX;
--      }
--
-       if (netif_running(dev))
-               b44_setup_phy(bp);
-+      ret = phy_ethtool_sset(bp->phydev, cmd);
-+
-       spin_unlock_irq(&bp->lock);
--      return 0;
-+      return ret;
- }
- static void b44_get_ringparam(struct net_device *dev,
-@@ -2092,20 +2017,81 @@ static const struct ethtool_ops b44_etht
- static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
- {
--      struct mii_ioctl_data *data = if_mii(ifr);
-       struct b44 *bp = netdev_priv(dev);
-       int err = -EINVAL;
-       if (!netif_running(dev))
-               goto out;
-+      if (!bp->phydev)
-+              return -EINVAL;
-+
-       spin_lock_irq(&bp->lock);
--      err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
-+      err = phy_mii_ioctl(bp->phydev, ifr, cmd);
-       spin_unlock_irq(&bp->lock);
- out:
-       return err;
- }
-+static void b44_adjust_link(struct net_device *dev)
-+{
-+      struct b44 *bp = netdev_priv(dev);
-+      struct phy_device *phydev = bp->phydev;
-+      int status_changed = 0;
-+
-+      BUG_ON(!phydev);
-+
-+      if (bp->old_link != phydev->link) {
-+              status_changed = 1;
-+              bp->old_link = phydev->link;
-+      }
-+
-+      /* reflect duplex change */
-+      if (phydev->link && (bp->old_duplex != phydev->duplex)) {
-+              status_changed = 1;
-+              bp->old_duplex = phydev->duplex;
-+      }
-+
-+      if (status_changed) {
-+              pr_info("%s: link %s", dev->name, phydev->link ?
-+                      "UP" : "DOWN");
-+              if (phydev->link)
-+                      pr_cont(" - %d/%s", phydev->speed,
-+                      phydev->duplex == DUPLEX_FULL ? "full" : "half");
-+              pr_cont("\n");
-+      }
-+}
-+
-+static int b44_mii_probe(struct net_device *dev)
-+{
-+      struct b44 *bp = netdev_priv(dev);
-+      struct phy_device *phydev = NULL;
-+      char phy_id[MII_BUS_ID_SIZE + 3];
-+
-+      /* connect to PHY */
-+      snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
-+               bp->mii_bus->id, bp->phy_addr);
-+
-+      phydev = phy_connect(dev, phy_id, &b44_adjust_link,
-+                           PHY_INTERFACE_MODE_MII);
-+      if (IS_ERR(phydev)) {
-+              netdev_err(dev, "could not attach PHY: %s", phy_id);
-+              bp->phy_addr = B44_PHY_ADDR_NO_PHY;
-+              return PTR_ERR(phydev);
-+      }
-+
-+      bp->phydev = phydev;
-+      bp->old_link = 0;
-+      bp->old_duplex = -1;
-+      bp->phy_addr = phydev->addr;
-+
-+      netdev_info(dev, "attached PHY driver [%s] "
-+              "(mii_bus:phy_addr=%s)\n",
-+              phydev->drv->name, dev_name(&phydev->dev));
-+
-+      return 0;
-+}
-+
- static int b44_get_invariants(struct b44 *bp)
- {
-       struct ssb_device *sdev = bp->sdev;
-@@ -2225,12 +2211,38 @@ static int b44_init_one(struct ssb_devic
-               goto err_out_powerdown;
-       }
--      bp->mii_if.dev = dev;
--      bp->mii_if.mdio_read = b44_mii_read;
--      bp->mii_if.mdio_write = b44_mii_write;
--      bp->mii_if.phy_id = bp->phy_addr;
--      bp->mii_if.phy_id_mask = 0x1f;
--      bp->mii_if.reg_num_mask = 0x1f;
-+      bp->mii_bus = mdiobus_alloc();
-+      if (!bp->mii_bus) {
-+              dev_err(sdev->dev, "mdiobus_alloc() failed\n");
-+              err = -ENOMEM;
-+              goto err_out_powerdown;
-+      }
-+
-+      bp->mii_bus->priv = bp;
-+      bp->mii_bus->read = b44_mii_read;
-+      bp->mii_bus->write = b44_mii_write;
-+      bp->mii_bus->name = "b44_eth_mii";
-+      snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", instance);
-+      bp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
-+      if (!bp->mii_bus->irq) {
-+              dev_err(sdev->dev, "mii_bus irq allocation failed\n");
-+              err = -ENOMEM;
-+              goto err_out_mdiobus;
-+      }
-+
-+      memset(bp->mii_bus->irq, PHY_POLL, sizeof(int) * PHY_MAX_ADDR);
-+
-+      err = mdiobus_register(bp->mii_bus);
-+      if (err) {
-+              dev_err(sdev->dev, "failed to register MII bus\n");
-+              goto err_out_mdiobus_irq;
-+      }
-+
-+      err = b44_mii_probe(dev);
-+      if (err) {
-+              dev_err(sdev->dev, "failed to probe MII bus\n");
-+              goto err_out_mdiobus_unregister;
-+      }
-       /* By default, advertise all speed/duplex settings. */
-       bp->flags |= (B44_FLAG_ADV_10HALF | B44_FLAG_ADV_10FULL |
-@@ -2262,6 +2274,16 @@ static int b44_init_one(struct ssb_devic
-       return 0;
-+
-+err_out_mdiobus_unregister:
-+      mdiobus_unregister(bp->mii_bus);
-+
-+err_out_mdiobus_irq:
-+      kfree(bp->mii_bus->irq);
-+
-+err_out_mdiobus:
-+      mdiobus_free(bp->mii_bus);
-+
- err_out_powerdown:
-       ssb_bus_may_powerdown(sdev->bus);
-@@ -2275,8 +2297,12 @@ out:
- static void b44_remove_one(struct ssb_device *sdev)
- {
-       struct net_device *dev = ssb_get_drvdata(sdev);
-+      struct b44 *bp = netdev_priv(dev);
-       unregister_netdev(dev);
-+      mdiobus_unregister(bp->mii_bus);
-+      kfree(bp->mii_bus->irq);
-+      mdiobus_free(bp->mii_bus);
-       ssb_device_disable(sdev, 0);
-       ssb_bus_may_powerdown(sdev->bus);
-       free_netdev(dev);
---- a/drivers/net/ethernet/broadcom/b44.h
-+++ b/drivers/net/ethernet/broadcom/b44.h
-@@ -396,7 +396,10 @@ struct b44 {
-       u32                     tx_pending;
-       u8                      phy_addr;
-       u8                      force_copybreak;
--      struct mii_if_info      mii_if;
-+      struct phy_device       *phydev;
-+      struct mii_bus          *mii_bus;
-+      int                     old_link;
-+      int                     old_duplex;
- };
- #endif /* _B44_H */
diff --git a/target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch b/target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch
new file mode 100644 (file)
index 0000000..72b374c
--- /dev/null
@@ -0,0 +1,330 @@
+--- a/drivers/net/ethernet/broadcom/Kconfig
++++ b/drivers/net/ethernet/broadcom/Kconfig
+@@ -24,6 +24,7 @@ config B44
+       select SSB
+       select NET_CORE
+       select MII
++      select PHYLIB
+       ---help---
+         If you have a network (Ethernet) controller of this type, say Y
+         or M and read the Ethernet-HOWTO, available from
+--- a/drivers/net/ethernet/broadcom/b44.c
++++ b/drivers/net/ethernet/broadcom/b44.c
+@@ -29,6 +29,7 @@
+ #include <linux/dma-mapping.h>
+ #include <linux/ssb/ssb.h>
+ #include <linux/slab.h>
++#include <linux/phy.h>
+ #include <asm/uaccess.h>
+ #include <asm/io.h>
+@@ -300,21 +301,23 @@ static inline int b44_writephy(struct b4
+ }
+ /* miilib interface */
+-static int b44_mii_read(struct net_device *dev, int phy_id, int location)
++static int b44_mii_read(struct mii_bus *bus, int phy_id, int location)
+ {
+       u32 val;
+-      struct b44 *bp = netdev_priv(dev);
++      struct b44 *bp = bus->priv;
+       int rc = __b44_readphy(bp, phy_id, location, &val);
+       if (rc)
+               return 0xffffffff;
+       return val;
+ }
+-static void b44_mii_write(struct net_device *dev, int phy_id, int location,
+-                       int val)
++static int b44_mii_write(struct mii_bus *bus, int phy_id, int location,
++                       u16 val)
+ {
+-      struct b44 *bp = netdev_priv(dev);
++      struct b44 *bp = bus->priv;
+       __b44_writephy(bp, phy_id, location, val);
++
++      return 0;
+ }
+ static int b44_phy_reset(struct b44 *bp)
+@@ -1821,102 +1824,24 @@ static int b44_get_settings(struct net_d
+ {
+       struct b44 *bp = netdev_priv(dev);
+-      cmd->supported = (SUPPORTED_Autoneg);
+-      cmd->supported |= (SUPPORTED_100baseT_Half |
+-                        SUPPORTED_100baseT_Full |
+-                        SUPPORTED_10baseT_Half |
+-                        SUPPORTED_10baseT_Full |
+-                        SUPPORTED_MII);
+-
+-      cmd->advertising = 0;
+-      if (bp->flags & B44_FLAG_ADV_10HALF)
+-              cmd->advertising |= ADVERTISED_10baseT_Half;
+-      if (bp->flags & B44_FLAG_ADV_10FULL)
+-              cmd->advertising |= ADVERTISED_10baseT_Full;
+-      if (bp->flags & B44_FLAG_ADV_100HALF)
+-              cmd->advertising |= ADVERTISED_100baseT_Half;
+-      if (bp->flags & B44_FLAG_ADV_100FULL)
+-              cmd->advertising |= ADVERTISED_100baseT_Full;
+-      cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
+-      ethtool_cmd_speed_set(cmd, ((bp->flags & B44_FLAG_100_BASE_T) ?
+-                                  SPEED_100 : SPEED_10));
+-      cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
+-              DUPLEX_FULL : DUPLEX_HALF;
+-      cmd->port = 0;
+-      cmd->phy_address = bp->phy_addr;
+-      cmd->transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
+-              XCVR_INTERNAL : XCVR_EXTERNAL;
+-      cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
+-              AUTONEG_DISABLE : AUTONEG_ENABLE;
+-      if (cmd->autoneg == AUTONEG_ENABLE)
+-              cmd->advertising |= ADVERTISED_Autoneg;
+-      if (!netif_running(dev)){
+-              ethtool_cmd_speed_set(cmd, 0);
+-              cmd->duplex = 0xff;
+-      }
+-      cmd->maxtxpkt = 0;
+-      cmd->maxrxpkt = 0;
+-      return 0;
++      return phy_ethtool_gset(bp->phydev, cmd);
+ }
+ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+       struct b44 *bp = netdev_priv(dev);
+-      u32 speed = ethtool_cmd_speed(cmd);
+-
+-      /* We do not support gigabit. */
+-      if (cmd->autoneg == AUTONEG_ENABLE) {
+-              if (cmd->advertising &
+-                  (ADVERTISED_1000baseT_Half |
+-                   ADVERTISED_1000baseT_Full))
+-                      return -EINVAL;
+-      } else if ((speed != SPEED_100 &&
+-                  speed != SPEED_10) ||
+-                 (cmd->duplex != DUPLEX_HALF &&
+-                  cmd->duplex != DUPLEX_FULL)) {
+-                      return -EINVAL;
+-      }
++      int ret;
+       spin_lock_irq(&bp->lock);
+-      if (cmd->autoneg == AUTONEG_ENABLE) {
+-              bp->flags &= ~(B44_FLAG_FORCE_LINK |
+-                             B44_FLAG_100_BASE_T |
+-                             B44_FLAG_FULL_DUPLEX |
+-                             B44_FLAG_ADV_10HALF |
+-                             B44_FLAG_ADV_10FULL |
+-                             B44_FLAG_ADV_100HALF |
+-                             B44_FLAG_ADV_100FULL);
+-              if (cmd->advertising == 0) {
+-                      bp->flags |= (B44_FLAG_ADV_10HALF |
+-                                    B44_FLAG_ADV_10FULL |
+-                                    B44_FLAG_ADV_100HALF |
+-                                    B44_FLAG_ADV_100FULL);
+-              } else {
+-                      if (cmd->advertising & ADVERTISED_10baseT_Half)
+-                              bp->flags |= B44_FLAG_ADV_10HALF;
+-                      if (cmd->advertising & ADVERTISED_10baseT_Full)
+-                              bp->flags |= B44_FLAG_ADV_10FULL;
+-                      if (cmd->advertising & ADVERTISED_100baseT_Half)
+-                              bp->flags |= B44_FLAG_ADV_100HALF;
+-                      if (cmd->advertising & ADVERTISED_100baseT_Full)
+-                              bp->flags |= B44_FLAG_ADV_100FULL;
+-              }
+-      } else {
+-              bp->flags |= B44_FLAG_FORCE_LINK;
+-              bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
+-              if (speed == SPEED_100)
+-                      bp->flags |= B44_FLAG_100_BASE_T;
+-              if (cmd->duplex == DUPLEX_FULL)
+-                      bp->flags |= B44_FLAG_FULL_DUPLEX;
+-      }
+-
+       if (netif_running(dev))
+               b44_setup_phy(bp);
++      ret = phy_ethtool_sset(bp->phydev, cmd);
++
+       spin_unlock_irq(&bp->lock);
+-      return 0;
++      return ret;
+ }
+ static void b44_get_ringparam(struct net_device *dev,
+@@ -2092,20 +2017,81 @@ static const struct ethtool_ops b44_etht
+ static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+ {
+-      struct mii_ioctl_data *data = if_mii(ifr);
+       struct b44 *bp = netdev_priv(dev);
+       int err = -EINVAL;
+       if (!netif_running(dev))
+               goto out;
++      if (!bp->phydev)
++              return -EINVAL;
++
+       spin_lock_irq(&bp->lock);
+-      err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
++      err = phy_mii_ioctl(bp->phydev, ifr, cmd);
+       spin_unlock_irq(&bp->lock);
+ out:
+       return err;
+ }
++static void b44_adjust_link(struct net_device *dev)
++{
++      struct b44 *bp = netdev_priv(dev);
++      struct phy_device *phydev = bp->phydev;
++      int status_changed = 0;
++
++      BUG_ON(!phydev);
++
++      if (bp->old_link != phydev->link) {
++              status_changed = 1;
++              bp->old_link = phydev->link;
++      }
++
++      /* reflect duplex change */
++      if (phydev->link && (bp->old_duplex != phydev->duplex)) {
++              status_changed = 1;
++              bp->old_duplex = phydev->duplex;
++      }
++
++      if (status_changed) {
++              pr_info("%s: link %s", dev->name, phydev->link ?
++                      "UP" : "DOWN");
++              if (phydev->link)
++                      pr_cont(" - %d/%s", phydev->speed,
++                      phydev->duplex == DUPLEX_FULL ? "full" : "half");
++              pr_cont("\n");
++      }
++}
++
++static int b44_mii_probe(struct net_device *dev)
++{
++      struct b44 *bp = netdev_priv(dev);
++      struct phy_device *phydev = NULL;
++      char phy_id[MII_BUS_ID_SIZE + 3];
++
++      /* connect to PHY */
++      snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
++               bp->mii_bus->id, bp->phy_addr);
++
++      phydev = phy_connect(dev, phy_id, &b44_adjust_link,
++                           PHY_INTERFACE_MODE_MII);
++      if (IS_ERR(phydev)) {
++              netdev_err(dev, "could not attach PHY: %s", phy_id);
++              bp->phy_addr = B44_PHY_ADDR_NO_PHY;
++              return PTR_ERR(phydev);
++      }
++
++      bp->phydev = phydev;
++      bp->old_link = 0;
++      bp->old_duplex = -1;
++      bp->phy_addr = phydev->addr;
++
++      netdev_info(dev, "attached PHY driver [%s] "
++              "(mii_bus:phy_addr=%s)\n",
++              phydev->drv->name, dev_name(&phydev->dev));
++
++      return 0;
++}
++
+ static int b44_get_invariants(struct b44 *bp)
+ {
+       struct ssb_device *sdev = bp->sdev;
+@@ -2225,12 +2211,38 @@ static int b44_init_one(struct ssb_devic
+               goto err_out_powerdown;
+       }
+-      bp->mii_if.dev = dev;
+-      bp->mii_if.mdio_read = b44_mii_read;
+-      bp->mii_if.mdio_write = b44_mii_write;
+-      bp->mii_if.phy_id = bp->phy_addr;
+-      bp->mii_if.phy_id_mask = 0x1f;
+-      bp->mii_if.reg_num_mask = 0x1f;
++      bp->mii_bus = mdiobus_alloc();
++      if (!bp->mii_bus) {
++              dev_err(sdev->dev, "mdiobus_alloc() failed\n");
++              err = -ENOMEM;
++              goto err_out_powerdown;
++      }
++
++      bp->mii_bus->priv = bp;
++      bp->mii_bus->read = b44_mii_read;
++      bp->mii_bus->write = b44_mii_write;
++      bp->mii_bus->name = "b44_eth_mii";
++      snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", instance);
++      bp->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
++      if (!bp->mii_bus->irq) {
++              dev_err(sdev->dev, "mii_bus irq allocation failed\n");
++              err = -ENOMEM;
++              goto err_out_mdiobus;
++      }
++
++      memset(bp->mii_bus->irq, PHY_POLL, sizeof(int) * PHY_MAX_ADDR);
++
++      err = mdiobus_register(bp->mii_bus);
++      if (err) {
++              dev_err(sdev->dev, "failed to register MII bus\n");
++              goto err_out_mdiobus_irq;
++      }
++
++      err = b44_mii_probe(dev);
++      if (err) {
++              dev_err(sdev->dev, "failed to probe MII bus\n");
++              goto err_out_mdiobus_unregister;
++      }
+       /* By default, advertise all speed/duplex settings. */
+       bp->flags |= (B44_FLAG_ADV_10HALF | B44_FLAG_ADV_10FULL |
+@@ -2262,6 +2274,16 @@ static int b44_init_one(struct ssb_devic
+       return 0;
++
++err_out_mdiobus_unregister:
++      mdiobus_unregister(bp->mii_bus);
++
++err_out_mdiobus_irq:
++      kfree(bp->mii_bus->irq);
++
++err_out_mdiobus:
++      mdiobus_free(bp->mii_bus);
++
+ err_out_powerdown:
+       ssb_bus_may_powerdown(sdev->bus);
+@@ -2275,8 +2297,12 @@ out:
+ static void b44_remove_one(struct ssb_device *sdev)
+ {
+       struct net_device *dev = ssb_get_drvdata(sdev);
++      struct b44 *bp = netdev_priv(dev);
+       unregister_netdev(dev);
++      mdiobus_unregister(bp->mii_bus);
++      kfree(bp->mii_bus->irq);
++      mdiobus_free(bp->mii_bus);
+       ssb_device_disable(sdev, 0);
+       ssb_bus_may_powerdown(sdev->bus);
+       free_netdev(dev);
+--- a/drivers/net/ethernet/broadcom/b44.h
++++ b/drivers/net/ethernet/broadcom/b44.h
+@@ -396,7 +396,10 @@ struct b44 {
+       u32                     tx_pending;
+       u8                      phy_addr;
+       u8                      force_copybreak;
+-      struct mii_if_info      mii_if;
++      struct phy_device       *phydev;
++      struct mii_bus          *mii_bus;
++      int                     old_link;
++      int                     old_duplex;
+ };
+ #endif /* _B44_H */