summaryrefslogtreecommitdiff
path: root/target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch
diff options
context:
space:
mode:
authorhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>2013-10-06 18:31:32 +0000
committerhauke <hauke@3c298f89-4303-0410-b956-a3cf2f4a3e73>2013-10-06 18:31:32 +0000
commit943d5f1181d42f26356649d208cebd82929d8e77 (patch)
tree7b5b4605847117ea899238febafe37a380647fa8 /target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch
parentc26a3589020c44740293aebea97f04ab2c82f3ea (diff)
brcm47xx: b44: fix some problems with the phy
* do not try initialize a unused phy * some improvements to the phylib patch * do not turn the phy off when mac is off Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@38306 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch')
-rw-r--r--target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch325
1 files changed, 0 insertions, 325 deletions
diff --git a/target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch b/target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch
deleted file mode 100644
index 0295ca0e4d..0000000000
--- a/target/linux/brcm47xx/patches-3.10/780-b44-phylib.patch
+++ /dev/null
@@ -1,325 +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)
-@@ -1831,102 +1834,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,
-@@ -2102,20 +2027,74 @@ 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;
-+ bool 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)
-+ phy_print_status(phydev);
-+}
-+
-+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\n", 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;
-@@ -2235,12 +2214,40 @@ 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";
-+ bp->mii_bus->parent = sdev->dev;
-+ bp->mii_bus->phy_mask = ~(1 << bp->phy_addr);
-+ 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 |
-@@ -2272,6 +2279,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);
-
-@@ -2285,8 +2302,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 */