From: Hauke Mehrtens Date: Mon, 15 Jul 2013 11:42:54 +0000 (+0000) Subject: brcm47xx: fix name of patch X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=866e229299e5b9a00c08a07b294760ac381d7fa8;p=librecmc%2Flibrecmc.git brcm47xx: fix name of patch SVN-Revision: 37340 --- 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 index 72b374ce55..0000000000 --- a/target/linux/brcm47xx/patches-3.10/780-b43-phylib.patch +++ /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 - #include - #include -+#include - - #include - #include -@@ -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 index 0000000000..72b374ce55 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch @@ -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 + #include + #include ++#include + + #include + #include +@@ -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 */