From a80ca5c6b3cc7f46849cdc8d36d577ecc6b648ec Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 22 Oct 2013 21:01:35 +0000 Subject: [PATCH] brcm47xx: b44: detect external phy by bit set in DevControl register Without this patch we treated only phy addr 30 as an external phy, but there is a register to check that. Now we do not have to try to reset the switch to check for an external switch. Signed-off-by: Hauke Mehrtens SVN-Revision: 38502 --- .../201-b44-use-B44_FLAG_EXTERNAL_PHY.patch | 97 +++++++++++++++++++ ...HY_ADDR_NO_PHY-to-B44_PHY_ADDR_NO_LO.patch | 53 +--------- ...bort-when-no-PHY-is-available-at-all.patch | 4 +- ...ii_-read-write-to-b44_mdio_-read-wri.patch | 4 +- .../205-b44-add-phylib-support.patch | 29 +++--- ...206-b44-activate-PHY-when-MAC-is-off.patch | 6 +- ...set-phy-addr-to-30-for-every-ext-phy.patch | 25 +++++ .../patches-3.10/210-b44_phy_fix.patch | 2 +- 8 files changed, 147 insertions(+), 73 deletions(-) create mode 100644 target/linux/brcm47xx/patches-3.10/201-b44-use-B44_FLAG_EXTERNAL_PHY.patch create mode 100644 target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-phy-addr-to-30-for-every-ext-phy.patch diff --git a/target/linux/brcm47xx/patches-3.10/201-b44-use-B44_FLAG_EXTERNAL_PHY.patch b/target/linux/brcm47xx/patches-3.10/201-b44-use-B44_FLAG_EXTERNAL_PHY.patch new file mode 100644 index 0000000000..32754b0586 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/201-b44-use-B44_FLAG_EXTERNAL_PHY.patch @@ -0,0 +1,97 @@ +From 3fc36ba561bd9a9bdc097d6ace32f1303364268c Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Tue, 22 Oct 2013 21:05:25 +0200 +Subject: [PATCH 2/9] b44: use B44_FLAG_EXTERNAL_PHY + +--- + drivers/net/ethernet/broadcom/b44.c | 18 +++++++++--------- + drivers/net/ethernet/broadcom/b44.h | 2 +- + 2 files changed, 10 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/broadcom/b44.c ++++ b/drivers/net/ethernet/broadcom/b44.c +@@ -284,7 +284,7 @@ static int __b44_writephy(struct b44 *bp + + static inline int b44_readphy(struct b44 *bp, int reg, u32 *val) + { +- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) + return 0; + + return __b44_readphy(bp, bp->phy_addr, reg, val); +@@ -292,7 +292,7 @@ static inline int b44_readphy(struct b44 + + static inline int b44_writephy(struct b44 *bp, int reg, u32 val) + { +- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) + return 0; + + return __b44_writephy(bp, bp->phy_addr, reg, val); +@@ -321,7 +321,7 @@ static int b44_phy_reset(struct b44 *bp) + u32 val; + int err; + +- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) + return 0; + err = b44_writephy(bp, MII_BMCR, BMCR_RESET); + if (err) +@@ -423,7 +423,7 @@ static int b44_setup_phy(struct b44 *bp) + + b44_wap54g10_workaround(bp); + +- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) + return 0; + if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0) + goto out; +@@ -521,7 +521,7 @@ static void b44_check_phy(struct b44 *bp + { + u32 bmsr, aux; + +- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) { ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) { + bp->flags |= B44_FLAG_100_BASE_T; + bp->flags |= B44_FLAG_FULL_DUPLEX; + if (!netif_carrier_ok(bp->dev)) { +@@ -1315,7 +1315,7 @@ static void b44_chip_reset(struct b44 *b + if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) { + bw32(bp, B44_ENET_CTRL, ENET_CTRL_EPSEL); + br32(bp, B44_ENET_CTRL); +- bp->flags &= ~B44_FLAG_INTERNAL_PHY; ++ bp->flags |= B44_FLAG_EXTERNAL_PHY; + } else { + u32 val = br32(bp, B44_DEVCTRL); + +@@ -1324,7 +1324,7 @@ static void b44_chip_reset(struct b44 *b + br32(bp, B44_DEVCTRL); + udelay(100); + } +- bp->flags |= B44_FLAG_INTERNAL_PHY; ++ bp->flags &= ~B44_FLAG_EXTERNAL_PHY; + } + } + +@@ -1828,8 +1828,8 @@ static int b44_get_settings(struct net_d + 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->transceiver = (bp->flags & B44_FLAG_EXTERNAL_PHY) ? ++ XCVR_EXTERNAL : XCVR_INTERNAL; + cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ? + AUTONEG_DISABLE : AUTONEG_ENABLE; + if (cmd->autoneg == AUTONEG_ENABLE) +--- a/drivers/net/ethernet/broadcom/b44.h ++++ b/drivers/net/ethernet/broadcom/b44.h +@@ -376,7 +376,7 @@ struct b44 { + #define B44_FLAG_ADV_10FULL 0x02000000 + #define B44_FLAG_ADV_100HALF 0x04000000 + #define B44_FLAG_ADV_100FULL 0x08000000 +-#define B44_FLAG_INTERNAL_PHY 0x10000000 ++#define B44_FLAG_EXTERNAL_PHY 0x10000000 + #define B44_FLAG_RX_RING_HACK 0x20000000 + #define B44_FLAG_TX_RING_HACK 0x40000000 + #define B44_FLAG_WOL_ENABLE 0x80000000 diff --git a/target/linux/brcm47xx/patches-3.10/202-b44-rename-B44_PHY_ADDR_NO_PHY-to-B44_PHY_ADDR_NO_LO.patch b/target/linux/brcm47xx/patches-3.10/202-b44-rename-B44_PHY_ADDR_NO_PHY-to-B44_PHY_ADDR_NO_LO.patch index 8610f0c51c..4534d8da6b 100644 --- a/target/linux/brcm47xx/patches-3.10/202-b44-rename-B44_PHY_ADDR_NO_PHY-to-B44_PHY_ADDR_NO_LO.patch +++ b/target/linux/brcm47xx/patches-3.10/202-b44-rename-B44_PHY_ADDR_NO_PHY-to-B44_PHY_ADDR_NO_LO.patch @@ -1,7 +1,7 @@ -From 991b6722fb727b6e2a98e7e8b57176ac68626110 Mon Sep 17 00:00:00 2001 +From 888594b4a1f70d02b7f6b05e868b00514b5cf559 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 3 Oct 2013 20:41:29 +0200 -Subject: [PATCH 2/5] b44: rename B44_PHY_ADDR_NO_PHY to +Subject: [PATCH 3/9] b44: rename B44_PHY_ADDR_NO_PHY to B44_PHY_ADDR_NO_LOCAL_PHY The PHY address 30 means there is no local PHY, but there could be an @@ -10,57 +10,12 @@ embedded home routers where this driver is used. Signed-off-by: Hauke Mehrtens --- - drivers/net/ethernet/broadcom/b44.c | 12 ++++++------ + drivers/net/ethernet/broadcom/b44.c | 2 +- drivers/net/ethernet/broadcom/b44.h | 6 +++--- - 2 files changed, 9 insertions(+), 9 deletions(-) + 2 files changed, 4 insertions(+), 4 deletions(-) --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c -@@ -284,7 +284,7 @@ static int __b44_writephy(struct b44 *bp - - static inline int b44_readphy(struct b44 *bp, int reg, u32 *val) - { -- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) -+ if (bp->phy_addr == B44_PHY_ADDR_NO_LOACL_PHY) - return 0; - - return __b44_readphy(bp, bp->phy_addr, reg, val); -@@ -292,7 +292,7 @@ static inline int b44_readphy(struct b44 - - static inline int b44_writephy(struct b44 *bp, int reg, u32 val) - { -- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) -+ if (bp->phy_addr == B44_PHY_ADDR_NO_LOACL_PHY) - return 0; - - return __b44_writephy(bp, bp->phy_addr, reg, val); -@@ -321,7 +321,7 @@ static int b44_phy_reset(struct b44 *bp) - u32 val; - int err; - -- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) -+ if (bp->phy_addr == B44_PHY_ADDR_NO_LOACL_PHY) - return 0; - err = b44_writephy(bp, MII_BMCR, BMCR_RESET); - if (err) -@@ -423,7 +423,7 @@ static int b44_setup_phy(struct b44 *bp) - - b44_wap54g10_workaround(bp); - -- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) -+ if (bp->phy_addr == B44_PHY_ADDR_NO_LOACL_PHY) - return 0; - if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0) - goto out; -@@ -521,7 +521,7 @@ static void b44_check_phy(struct b44 *bp - { - u32 bmsr, aux; - -- if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) { -+ if (bp->phy_addr == B44_PHY_ADDR_NO_LOACL_PHY) { - bp->flags |= B44_FLAG_100_BASE_T; - bp->flags |= B44_FLAG_FULL_DUPLEX; - if (!netif_carrier_ok(bp->dev)) { @@ -2238,7 +2238,7 @@ static int b44_init_one(struct ssb_devic /* do a phy reset to test if there is an active phy */ diff --git a/target/linux/brcm47xx/patches-3.10/203-b44-abort-when-no-PHY-is-available-at-all.patch b/target/linux/brcm47xx/patches-3.10/203-b44-abort-when-no-PHY-is-available-at-all.patch index 54256dbaa0..3dec7a2cd7 100644 --- a/target/linux/brcm47xx/patches-3.10/203-b44-abort-when-no-PHY-is-available-at-all.patch +++ b/target/linux/brcm47xx/patches-3.10/203-b44-abort-when-no-PHY-is-available-at-all.patch @@ -1,7 +1,7 @@ -From 1bfdc259652abe22a587fd6d856c1b71168cccb2 Mon Sep 17 00:00:00 2001 +From d6668993d793d39e2c9d7699e8079462cae67f7e Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 3 Oct 2013 20:49:10 +0200 -Subject: [PATCH 3/5] b44: abort when no PHY is available at all +Subject: [PATCH 4/9] b44: abort when no PHY is available at all When the phy address is 31, this means that there is no PHY connected to this MAC at all, no internal and no external PHY. Reading these PHY diff --git a/target/linux/brcm47xx/patches-3.10/204-b44-rename-b44_mii_-read-write-to-b44_mdio_-read-wri.patch b/target/linux/brcm47xx/patches-3.10/204-b44-rename-b44_mii_-read-write-to-b44_mdio_-read-wri.patch index 4758875e69..00e5c23704 100644 --- a/target/linux/brcm47xx/patches-3.10/204-b44-rename-b44_mii_-read-write-to-b44_mdio_-read-wri.patch +++ b/target/linux/brcm47xx/patches-3.10/204-b44-rename-b44_mii_-read-write-to-b44_mdio_-read-wri.patch @@ -1,7 +1,7 @@ -From 6dcaccfc1e0046632dd54d91b6f679fee7f841bc Mon Sep 17 00:00:00 2001 +From 16b8dde613e5b59bee13537469f3562081da1a2c Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 6 Oct 2013 15:31:04 +0200 -Subject: [PATCH 4/5] b44: rename b44_mii_{read,write} to +Subject: [PATCH 5/9] b44: rename b44_mii_{read,write} to b44_mdio_{read,write}_mii The next patch will add these functions for phylib, and we should diff --git a/target/linux/brcm47xx/patches-3.10/205-b44-add-phylib-support.patch b/target/linux/brcm47xx/patches-3.10/205-b44-add-phylib-support.patch index 3c8e7a3714..2386fbe9a3 100644 --- a/target/linux/brcm47xx/patches-3.10/205-b44-add-phylib-support.patch +++ b/target/linux/brcm47xx/patches-3.10/205-b44-add-phylib-support.patch @@ -1,7 +1,7 @@ -From 46e5460f446109565b3f4a0cb728171d74bce33b Mon Sep 17 00:00:00 2001 +From 31963d998d2984079dc4f4b36b7df170d85f6d66 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 3 Oct 2013 22:07:11 +0200 -Subject: [PATCH 5/6] b44: add phylib support +Subject: [PATCH 6/9] b44: add phylib support Most of the older home routers based on the Broadcom BCM47XX SoC series are using a MAC that is supported by b44. On most of these routers not @@ -21,9 +21,9 @@ This was tested with a BCM4704, BCM4712 and BCM5354. Signed-off-by: Hauke Mehrtens --- drivers/net/ethernet/broadcom/Kconfig | 1 + - drivers/net/ethernet/broadcom/b44.c | 183 ++++++++++++++++++++++++++++++++- - drivers/net/ethernet/broadcom/b44.h | 5 + - 3 files changed, 186 insertions(+), 3 deletions(-) + drivers/net/ethernet/broadcom/b44.c | 181 ++++++++++++++++++++++++++++++++- + drivers/net/ethernet/broadcom/b44.h | 4 + + 3 files changed, 183 insertions(+), 3 deletions(-) --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -81,7 +81,7 @@ Signed-off-by: Hauke Mehrtens { struct b44 *bp = netdev_priv(dev); -+ if (bp->has_phy) { ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) { + BUG_ON(!bp->phydev); + return phy_ethtool_gset(bp->phydev, cmd); + } @@ -97,7 +97,7 @@ Signed-off-by: Hauke Mehrtens + u32 speed; + int ret; + -+ if (bp->has_phy) { ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) { + BUG_ON(!bp->phydev); + spin_lock_irq(&bp->lock); + if (netif_running(dev)) @@ -127,7 +127,7 @@ Signed-off-by: Hauke Mehrtens spin_lock_irq(&bp->lock); - err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL); -+ if (bp->has_phy) { ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) { + BUG_ON(bp->phydev); + err = phy_mii_ioctl(bp->phydev, ifr, cmd); + } else { @@ -261,13 +261,11 @@ Signed-off-by: Hauke Mehrtens static int b44_init_one(struct ssb_device *sdev, const struct ssb_device_id *ent) { -@@ -2246,10 +2408,22 @@ static int b44_init_one(struct ssb_devic +@@ -2246,10 +2408,20 @@ static int b44_init_one(struct ssb_devic if (b44_phy_reset(bp) < 0) bp->phy_addr = B44_PHY_ADDR_NO_LOACL_PHY; -+ bp->has_phy = bp->phy_addr == B44_PHY_ADDR_NO_LOACL_PHY; -+ -+ if (bp->has_phy) { ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) { + err = b44_register_phy_one(bp); + if (err) { + dev_err(sdev->dev, "Cannot register PHY, aborting\n"); @@ -284,25 +282,24 @@ Signed-off-by: Hauke Mehrtens err_out_powerdown: ssb_bus_may_powerdown(sdev->bus); -@@ -2263,8 +2437,11 @@ out: +@@ -2263,8 +2435,11 @@ 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); -+ if (bp->has_phy) ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) + b44_unregister_phy_one(bp); 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 -@@ -397,6 +397,11 @@ struct b44 { +@@ -397,6 +397,10 @@ struct b44 { u32 tx_pending; u8 phy_addr; u8 force_copybreak; -+ bool has_phy; + struct phy_device *phydev; + struct mii_bus *mii_bus; + int old_link; diff --git a/target/linux/brcm47xx/patches-3.10/206-b44-activate-PHY-when-MAC-is-off.patch b/target/linux/brcm47xx/patches-3.10/206-b44-activate-PHY-when-MAC-is-off.patch index e6c39b0547..abfee80109 100644 --- a/target/linux/brcm47xx/patches-3.10/206-b44-activate-PHY-when-MAC-is-off.patch +++ b/target/linux/brcm47xx/patches-3.10/206-b44-activate-PHY-when-MAC-is-off.patch @@ -1,7 +1,7 @@ -From 444044a410d4cf3b6dd462f2c9352d56039d9e07 Mon Sep 17 00:00:00 2001 +From f6a8d917c3efcfb974097ef4b345e8cda5283bab Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sun, 6 Oct 2013 17:58:24 +0200 -Subject: [PATCH 6/6] b44: activate PHY when MAC is off +Subject: [PATCH 7/9] b44: activate PHY when MAC is off Without this patch we can not access the PHY when the MAC is switched off. This PHY access is needed to configure the switch, which is done @@ -19,7 +19,7 @@ Signed-off-by: Hauke Mehrtens /* now reset the chip, but without enabling the MAC&PHY * part of it. This has to be done _after_ we shut down the PHY */ - b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL); -+ if (bp->has_phy) ++ if (bp->flags & B44_FLAG_EXTERNAL_PHY) + b44_chip_reset(bp, B44_CHIP_RESET_FULL); + else + b44_chip_reset(bp, B44_CHIP_RESET_PARTIAL); diff --git a/target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-phy-addr-to-30-for-every-ext-phy.patch b/target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-phy-addr-to-30-for-every-ext-phy.patch new file mode 100644 index 0000000000..2b0c8ff9cf --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-phy-addr-to-30-for-every-ext-phy.patch @@ -0,0 +1,25 @@ +From c2ecc401a08f0bda3b2483b93989d9792cadf6b2 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Mon, 21 Oct 2013 20:30:04 +0200 +Subject: [PATCH 8/9] b44: do not set phy addr to 30 for every ext phy + +--- + drivers/net/ethernet/broadcom/b44.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/broadcom/b44.c ++++ b/drivers/net/ethernet/broadcom/b44.c +@@ -2408,8 +2408,11 @@ static int b44_init_one(struct ssb_devic + b44_chip_reset(bp, B44_CHIP_RESET_FULL); + + /* do a phy reset to test if there is an active phy */ +- if (b44_phy_reset(bp) < 0) +- bp->phy_addr = B44_PHY_ADDR_NO_LOACL_PHY; ++ err = b44_phy_reset(bp); ++ if (err < 0) { ++ dev_err(sdev->dev, "phy reset failed\n"); ++ goto err_out_unregister_netdev; ++ } + + if (bp->flags & B44_FLAG_EXTERNAL_PHY) { + err = b44_register_phy_one(bp); diff --git a/target/linux/brcm47xx/patches-3.10/210-b44_phy_fix.patch b/target/linux/brcm47xx/patches-3.10/210-b44_phy_fix.patch index 1cafb86512..559d5a9781 100644 --- a/target/linux/brcm47xx/patches-3.10/210-b44_phy_fix.patch +++ b/target/linux/brcm47xx/patches-3.10/210-b44_phy_fix.patch @@ -41,7 +41,7 @@ b44_wap54g10_workaround(bp); + b44_bcm47xx_workarounds(bp); - if (bp->phy_addr == B44_PHY_ADDR_NO_LOACL_PHY) + if (bp->flags & B44_FLAG_EXTERNAL_PHY) return 0; @@ -2158,6 +2183,8 @@ static int b44_get_invariants(struct b44 * valid PHY address. */ -- 2.30.2