From: Hauke Mehrtens Date: Thu, 26 Dec 2013 23:27:52 +0000 (+0000) Subject: brcm47xx: b44: This updates the phylib patches to the version send upstream X-Git-Tag: reboot~8297 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=961d5b4453e785abd2b053977af54681d64b0b09;p=oweals%2Fopenwrt.git brcm47xx: b44: This updates the phylib patches to the version send upstream This uses a fixed phy instead of a dummy one. Signed-off-by: Hauke Mehrtens SVN-Revision: 39166 --- diff --git a/target/linux/brcm47xx/config-3.10 b/target/linux/brcm47xx/config-3.10 index 6d9f237cd6..c35f872ede 100644 --- a/target/linux/brcm47xx/config-3.10 +++ b/target/linux/brcm47xx/config-3.10 @@ -50,6 +50,7 @@ CONFIG_CPU_SUPPORTS_HIGHMEM=y CONFIG_CSRC_R4K=y CONFIG_DMA_NONCOHERENT=y # CONFIG_EARLY_PRINTK is not set +CONFIG_FIXED_PHY=y CONFIG_GENERIC_ATOMIC64=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BUILD=y diff --git a/target/linux/brcm47xx/patches-3.10/201-b44-check-register-instead-of-PHY-address-to-detect-.patch b/target/linux/brcm47xx/patches-3.10/201-b44-check-register-instead-of-PHY-address-to-detect-.patch new file mode 100644 index 0000000000..a9b3fa87c6 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/201-b44-check-register-instead-of-PHY-address-to-detect-.patch @@ -0,0 +1,116 @@ +From d61941952d5e7d062c3884e6d81bd503a37702b4 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Fri, 20 Dec 2013 02:16:06 +0100 +Subject: [PATCH 201/208] b44: check register instead of PHY address to detect + external PHY + +The Ethernet core supported by b44 supports an internal PHY integrated +into the mac core, which is supported by the b44 driver and an external +PHY to which the mac core is connected. This external PHY could be a +switch connected through MII, which is often the case when this core is +used on home routers. The usage of an external PHY was assumed when the +PHY address 30 was used and an internal PHY was assumed when the PHY +address was different. To verify that b44_phy_reset() was called and +checked if it worked, otherwise PHY address 30 was assumed, an external +PHY. It is better to check the register which says which PHY is +connected to the MAC instead of checking the PHY address. +The interface to an external PHY was only activated when this register +was set. + +This also changes B44_FLAG_INTERNAL_PHY to B44_FLAG_EXTERNAL_PHY, it is +easier to check. + +Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller +--- + 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/201-b44-use-B44_FLAG_EXTERNAL_PHY.patch b/target/linux/brcm47xx/patches-3.10/201-b44-use-B44_FLAG_EXTERNAL_PHY.patch deleted file mode 100644 index 32754b0586..0000000000 --- a/target/linux/brcm47xx/patches-3.10/201-b44-use-B44_FLAG_EXTERNAL_PHY.patch +++ /dev/null @@ -1,97 +0,0 @@ -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 4534d8da6b..a1ae7f4a44 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 888594b4a1f70d02b7f6b05e868b00514b5cf559 Mon Sep 17 00:00:00 2001 +From 5ab6329c5224d8135d76da18066edf3395f679f5 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens -Date: Thu, 3 Oct 2013 20:41:29 +0200 -Subject: [PATCH 3/9] b44: rename B44_PHY_ADDR_NO_PHY to +Date: Fri, 20 Dec 2013 02:16:07 +0100 +Subject: [PATCH 202/208] 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 @@ -9,6 +9,7 @@ external PHY like a switch connected via MII. This is the case on most embedded home routers where this driver is used. Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/b44.c | 2 +- drivers/net/ethernet/broadcom/b44.h | 6 +++--- @@ -21,7 +22,7 @@ Signed-off-by: Hauke Mehrtens /* 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_PHY; -+ bp->phy_addr = B44_PHY_ADDR_NO_LOACL_PHY; ++ bp->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY; netdev_info(dev, "%s %pM\n", DRV_DESCRIPTION, dev->dev_addr); @@ -35,7 +36,7 @@ Signed-off-by: Hauke Mehrtens -#define B44_PHY_ADDR_NO_PHY 30 -#define B44_MDC_RATIO 5000000 +#define B44_MCAST_TABLE_SIZE 32 -+#define B44_PHY_ADDR_NO_LOACL_PHY 30 /* no local phy regs */ ++#define B44_PHY_ADDR_NO_LOCAL_PHY 30 /* no local phy regs */ +#define B44_MDC_RATIO 5000000 #define B44_STAT_REG_DECLARE \ 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 3dec7a2cd7..8ed078a3f1 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,13 +1,14 @@ -From d6668993d793d39e2c9d7699e8079462cae67f7e Mon Sep 17 00:00:00 2001 +From 7befa6abe09c84269b8af614a166409090346cf8 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens -Date: Thu, 3 Oct 2013 20:49:10 +0200 -Subject: [PATCH 4/9] b44: abort when no PHY is available at all +Date: Fri, 20 Dec 2013 02:16:08 +0100 +Subject: [PATCH 203/208] 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 registers causes a system reset on some routers. Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/b44.c | 6 ++++++ drivers/net/ethernet/broadcom/b44.h | 1 + @@ -33,7 +34,7 @@ Signed-off-by: Hauke Mehrtens @@ -282,6 +282,7 @@ struct ring_info { #define B44_MCAST_TABLE_SIZE 32 - #define B44_PHY_ADDR_NO_LOACL_PHY 30 /* no local phy regs */ + #define B44_PHY_ADDR_NO_LOCAL_PHY 30 /* no local phy regs */ +#define B44_PHY_ADDR_NO_PHY 31 /* no phy present at all */ #define B44_MDC_RATIO 5000000 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 00e5c23704..09e3315025 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,14 +1,15 @@ -From 16b8dde613e5b59bee13537469f3562081da1a2c Mon Sep 17 00:00:00 2001 +From 348baa6c81cf774811040e4da01438d077a08301 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens -Date: Sun, 6 Oct 2013 15:31:04 +0200 -Subject: [PATCH 5/9] b44: rename b44_mii_{read,write} to - b44_mdio_{read,write}_mii +Date: Fri, 20 Dec 2013 02:16:09 +0100 +Subject: [PATCH 204/208] b44: rename b44_mii_{read, write} to b44_mdio_{read, + write}_mii The next patch will add these functions for phylib, and we should rename the old ones before. This now indicates that these functions are used for the mdio registers and on the mii interface. Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/b44.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 8c7ba9ccff..82fd96515d 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 31963d998d2984079dc4f4b36b7df170d85f6d66 Mon Sep 17 00:00:00 2001 +From 86f4ea63e696db996f68d1065b55506e75a7d765 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens -Date: Thu, 3 Oct 2013 22:07:11 +0200 -Subject: [PATCH 6/9] b44: add phylib support +Date: Fri, 20 Dec 2013 02:16:10 +0100 +Subject: [PATCH 205/208] 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 @@ -13,17 +13,23 @@ Broadcom home networking SoCs which are using different Ethernet MAC drivers. This was tested with the b53 switch driver which is currently on its way to mainline. +If the internal PHY is not used, b44 will now search on the MDIO bus +for a phy and use the Linux phylib subsystem to register a driver. +Support for the internal PHY must stay here, because there are some +device which are suing the internal phy. + With this patch we scan the mdio bus when the sprom or nvram says that the PHY address is 30, if a PHY was found at this address b44 uses it. This was tested with a BCM4704, BCM4712 and BCM5354. Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/Kconfig | 1 + - drivers/net/ethernet/broadcom/b44.c | 181 ++++++++++++++++++++++++++++++++- - drivers/net/ethernet/broadcom/b44.h | 4 + - 3 files changed, 183 insertions(+), 3 deletions(-) + drivers/net/ethernet/broadcom/b44.c | 190 ++++++++++++++++++++++++++++++++- + drivers/net/ethernet/broadcom/b44.h | 3 + + 3 files changed, 189 insertions(+), 5 deletions(-) --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig @@ -77,7 +83,22 @@ Signed-off-by: Hauke Mehrtens static int b44_phy_reset(struct b44 *bp) { u32 val; -@@ -1805,6 +1824,11 @@ static int b44_get_settings(struct net_d +@@ -523,10 +542,12 @@ static void b44_check_phy(struct b44 *bp + + 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)) { + u32 val = br32(bp, B44_TX_CTRL); +- val |= TX_CTRL_DUPLEX; ++ if (bp->flags & B44_FLAG_FULL_DUPLEX) ++ val |= TX_CTRL_DUPLEX; ++ else ++ val &= ~TX_CTRL_DUPLEX; + bw32(bp, B44_TX_CTRL, val); + netif_carrier_on(bp->dev); + b44_link_report(bp); +@@ -1805,6 +1826,11 @@ static int b44_get_settings(struct net_d { struct b44 *bp = netdev_priv(dev); @@ -89,7 +110,7 @@ Signed-off-by: Hauke Mehrtens cmd->supported = (SUPPORTED_Autoneg); cmd->supported |= (SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | -@@ -1846,7 +1870,23 @@ static int b44_get_settings(struct net_d +@@ -1846,7 +1872,23 @@ static int b44_get_settings(struct net_d static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct b44 *bp = netdev_priv(dev); @@ -114,7 +135,7 @@ Signed-off-by: Hauke Mehrtens /* We do not support gigabit. */ if (cmd->autoneg == AUTONEG_ENABLE) { -@@ -2076,7 +2116,6 @@ static const struct ethtool_ops b44_etht +@@ -2076,7 +2118,6 @@ static const struct ethtool_ops b44_etht static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { @@ -122,7 +143,7 @@ Signed-off-by: Hauke Mehrtens struct b44 *bp = netdev_priv(dev); int err = -EINVAL; -@@ -2084,7 +2123,12 @@ static int b44_ioctl(struct net_device * +@@ -2084,7 +2125,12 @@ static int b44_ioctl(struct net_device * goto out; spin_lock_irq(&bp->lock); @@ -136,7 +157,7 @@ Signed-off-by: Hauke Mehrtens spin_unlock_irq(&bp->lock); out: return err; -@@ -2146,6 +2190,124 @@ static const struct net_device_ops b44_n +@@ -2146,6 +2192,127 @@ static const struct net_device_ops b44_n #endif }; @@ -154,13 +175,22 @@ Signed-off-by: Hauke Mehrtens + } + + /* reflect duplex change */ -+ if (phydev->link && (bp->old_duplex != phydev->duplex)) { -+ status_changed = 1; -+ bp->old_duplex = phydev->duplex; ++ if (phydev->link) { ++ if ((phydev->duplex == DUPLEX_HALF) && ++ (bp->flags & B44_FLAG_FULL_DUPLEX)) { ++ status_changed = 1; ++ bp->flags &= ~B44_FLAG_FULL_DUPLEX; ++ } else if ((phydev->duplex == DUPLEX_FULL) && ++ !(bp->flags & B44_FLAG_FULL_DUPLEX)) { ++ status_changed = 1; ++ bp->flags |= B44_FLAG_FULL_DUPLEX; ++ } + } + -+ if (status_changed) ++ if (status_changed) { ++ b44_check_phy(bp); + phy_print_status(phydev); ++ } +} + +static int b44_register_phy_one(struct b44 *bp) @@ -168,6 +198,7 @@ Signed-off-by: Hauke Mehrtens + struct mii_bus *mii_bus; + struct ssb_device *sdev = bp->sdev; + struct phy_device *phydev; ++ char bus_id[MII_BUS_ID_SIZE + 3]; + int err; + + mii_bus = mdiobus_alloc(); @@ -201,25 +232,19 @@ Signed-off-by: Hauke Mehrtens + goto err_out_mdiobus_irq; + } + -+ phydev = bp->mii_bus->phy_map[bp->phy_addr]; -+ if (!phydev) { -+ dev_err(sdev->dev, "could not find PHY at %i\n", bp->phy_addr); -+ err = -ENODEV; -+ goto err_out_mdiobus_unregister; -+ } ++ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id, bp->phy_addr); + -+ err = phy_connect_direct(bp->dev, phydev, &b44_adjust_link, -+ PHY_INTERFACE_MODE_MII); -+ if (err < 0) { ++ phydev = phy_connect(bp->dev, bus_id, &b44_adjust_link, ++ PHY_INTERFACE_MODE_MII); ++ if (IS_ERR(phydev)) { + dev_err(sdev->dev, "could not attach PHY at %i\n", + bp->phy_addr); ++ err = PTR_ERR(phydev); + goto err_out_mdiobus_unregister; + } + + /* mask with MAC supported features */ -+ phydev->supported &= (SUPPORTED_10baseT_Half | -+ SUPPORTED_10baseT_Full | -+ SUPPORTED_100baseT_Half | ++ phydev->supported &= (SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_MII); @@ -227,7 +252,6 @@ Signed-off-by: Hauke Mehrtens + + bp->phydev = phydev; + bp->old_link = 0; -+ bp->old_duplex = -1; + bp->phy_addr = phydev->addr; + + dev_info(sdev->dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n", @@ -261,9 +285,9 @@ Signed-off-by: Hauke Mehrtens static int b44_init_one(struct ssb_device *sdev, const struct ssb_device_id *ent) { -@@ -2246,10 +2408,20 @@ static int b44_init_one(struct ssb_devic +@@ -2246,10 +2413,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->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY; + if (bp->flags & B44_FLAG_EXTERNAL_PHY) { + err = b44_register_phy_one(bp); @@ -282,7 +306,7 @@ Signed-off-by: Hauke Mehrtens err_out_powerdown: ssb_bus_may_powerdown(sdev->bus); -@@ -2263,8 +2435,11 @@ out: +@@ -2263,8 +2440,11 @@ out: static void b44_remove_one(struct ssb_device *sdev) { struct net_device *dev = ssb_get_drvdata(sdev); @@ -296,14 +320,13 @@ Signed-off-by: Hauke Mehrtens free_netdev(dev); --- a/drivers/net/ethernet/broadcom/b44.h +++ b/drivers/net/ethernet/broadcom/b44.h -@@ -397,6 +397,10 @@ struct b44 { +@@ -397,6 +397,9 @@ struct b44 { u32 tx_pending; u8 phy_addr; u8 force_copybreak; + struct phy_device *phydev; + struct mii_bus *mii_bus; + int old_link; -+ int old_duplex; struct mii_if_info mii_if; }; 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 abfee80109..57212bb95c 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,20 +1,21 @@ -From f6a8d917c3efcfb974097ef4b345e8cda5283bab Mon Sep 17 00:00:00 2001 +From bea69c47f5b93b3142f8833f8a34b666d5d7d6a7 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens -Date: Sun, 6 Oct 2013 17:58:24 +0200 -Subject: [PATCH 7/9] b44: activate PHY when MAC is off +Date: Fri, 20 Dec 2013 02:16:11 +0100 +Subject: [PATCH 206/208] 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 through PHY registers. Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/b44.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c -@@ -1358,7 +1358,10 @@ static void b44_halt(struct b44 *bp) +@@ -1360,7 +1360,10 @@ static void b44_halt(struct b44 *bp) bw32(bp, B44_MAC_CTRL, MAC_CTRL_PHY_PDOWN); /* now reset the chip, but without enabling the MAC&PHY * part of it. This has to be done _after_ we shut down the PHY */ diff --git a/target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-PHY-address-to-30-for-every-ext-PHY.patch b/target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-PHY-address-to-30-for-every-ext-PHY.patch new file mode 100644 index 0000000000..d4eda982ee --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-PHY-address-to-30-for-every-ext-PHY.patch @@ -0,0 +1,32 @@ +From 656a7c2b1210deddf76444ecc76e058c0404ce80 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Fri, 20 Dec 2013 02:16:12 +0100 +Subject: [PATCH 207/208] b44: do not set PHY address to 30 for every ext PHY + +b44_phy_reset() will fail for an external PHY and only work with the +internal PHY, this was an old workaround when the detection of an +external switch based on the PHY address failed and it is not needed +any more. + +Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller +--- + 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 +@@ -2413,8 +2413,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_LOCAL_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/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 deleted file mode 100644 index 2b0c8ff9cf..0000000000 --- a/target/linux/brcm47xx/patches-3.10/207-b44-do-not-set-phy-addr-to-30-for-every-ext-phy.patch +++ /dev/null @@ -1,25 +0,0 @@ -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/208-b44-add-dummy-phy-device-if-we-do-not-find-any.patch b/target/linux/brcm47xx/patches-3.10/208-b44-add-dummy-phy-device-if-we-do-not-find-any.patch deleted file mode 100644 index db6e5e3eba..0000000000 --- a/target/linux/brcm47xx/patches-3.10/208-b44-add-dummy-phy-device-if-we-do-not-find-any.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 1a900b17b34ddca0336c739a2836bcb7f8aad5a8 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Fri, 25 Oct 2013 00:03:33 +0200 -Subject: [PATCH 9/9] b44: add dummy phy device if we do not find any - ---- - drivers/net/ethernet/broadcom/b44.c | 25 +++++++++++++++++++++---- - 1 file changed, 21 insertions(+), 4 deletions(-) - ---- a/drivers/net/ethernet/broadcom/b44.c -+++ b/drivers/net/ethernet/broadcom/b44.c -@@ -2222,6 +2222,7 @@ static int b44_register_phy_one(struct b - struct ssb_device *sdev = bp->sdev; - struct phy_device *phydev; - int err; -+ struct phy_c45_device_ids c45_ids = {0}; - - mii_bus = mdiobus_alloc(); - if (!mii_bus) { -@@ -2256,9 +2257,20 @@ static int b44_register_phy_one(struct b - - phydev = bp->mii_bus->phy_map[bp->phy_addr]; - if (!phydev) { -- dev_err(sdev->dev, "could not find PHY at %i\n", bp->phy_addr); -- err = -ENODEV; -- goto err_out_mdiobus_unregister; -+ dev_info(sdev->dev, "could not find PHY at %i, create dummy one\n", -+ bp->phy_addr); -+ -+ phydev = phy_device_create(bp->mii_bus, bp->phy_addr, 0x0, false, &c45_ids); -+ if (IS_ERR(phydev)) { -+ err = PTR_ERR(phydev); -+ dev_err(sdev->dev, "Can not create dummy PHY\n"); -+ goto err_out_mdiobus_unregister; -+ } -+ err = phy_device_register(phydev); -+ if (err) { -+ dev_err(sdev->dev, "failed to register MII bus\n"); -+ goto err_out_mdiobus_unregister; -+ } - } - - err = phy_connect_direct(bp->dev, phydev, &b44_adjust_link, diff --git a/target/linux/brcm47xx/patches-3.10/208-b44-use-fixed-PHY-device-if-we-do-not-find-any.patch b/target/linux/brcm47xx/patches-3.10/208-b44-use-fixed-PHY-device-if-we-do-not-find-any.patch new file mode 100644 index 0000000000..972cd07966 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.10/208-b44-use-fixed-PHY-device-if-we-do-not-find-any.patch @@ -0,0 +1,97 @@ +From b04138b335203b79ffe1b14750fa245a4dab7191 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Fri, 20 Dec 2013 02:16:13 +0100 +Subject: [PATCH 208/208] b44: use fixed PHY device if we do not find any + +The ADM6996L switch and some Broadcom switches with two MII interfaces +like the BCM5325F connected to two MACs on the SoC, used on some +routers do not return a valid value when reading the PHY id register +and Linux thinks there is no PHY at all, but that is wrong. +This patch registers a fixed phy in the arch code and then searches it +when there is no other phy in the Ethernet driver code. + +Signed-off-by: Hauke Mehrtens +Signed-off-by: David S. Miller +--- + arch/mips/bcm47xx/setup.c | 10 ++++++++++ + drivers/net/ethernet/broadcom/b44.c | 16 +++++++++++++++- + drivers/net/ethernet/broadcom/b44.h | 3 +++ + 3 files changed, 28 insertions(+), 1 deletion(-) + +--- a/arch/mips/bcm47xx/setup.c ++++ b/arch/mips/bcm47xx/setup.c +@@ -28,6 +28,9 @@ + + #include + #include ++#include ++#include ++#include + #include + #include + #include +@@ -239,6 +242,12 @@ void __init plat_mem_setup(void) + mips_set_machine_name(bcm47xx_board_get_name()); + } + ++static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = { ++ .link = 1, ++ .speed = SPEED_100, ++ .duplex = DUPLEX_FULL, ++}; ++ + static int __init bcm47xx_register_bus_complete(void) + { + switch (bcm47xx_bus_type) { +@@ -253,6 +262,7 @@ static int __init bcm47xx_register_bus_c + break; + #endif + } ++ fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status); + return 0; + } + device_initcall(bcm47xx_register_bus_complete); +--- a/drivers/net/ethernet/broadcom/b44.c ++++ b/drivers/net/ethernet/broadcom/b44.c +@@ -2233,6 +2233,7 @@ static int b44_register_phy_one(struct b + struct ssb_device *sdev = bp->sdev; + struct phy_device *phydev; + char bus_id[MII_BUS_ID_SIZE + 3]; ++ struct ssb_sprom *sprom = &sdev->bus->sprom; + int err; + + mii_bus = mdiobus_alloc(); +@@ -2266,7 +2267,20 @@ static int b44_register_phy_one(struct b + goto err_out_mdiobus_irq; + } + +- snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id, bp->phy_addr); ++ if (!bp->mii_bus->phy_map[bp->phy_addr] && ++ (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) { ++ ++ dev_info(sdev->dev, ++ "could not find PHY at %i, use fixed one\n", ++ bp->phy_addr); ++ ++ bp->phy_addr = 0; ++ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, "fixed-0", ++ bp->phy_addr); ++ } else { ++ snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id, ++ bp->phy_addr); ++ } + + phydev = phy_connect(bp->dev, bus_id, &b44_adjust_link, + PHY_INTERFACE_MODE_MII); +--- a/drivers/net/ethernet/broadcom/b44.h ++++ b/drivers/net/ethernet/broadcom/b44.h +@@ -345,6 +345,9 @@ B44_STAT_REG_DECLARE + struct u64_stats_sync syncp; + }; + ++#define B44_BOARDFLAG_ROBO 0x0010 /* Board has robo switch */ ++#define B44_BOARDFLAG_ADM 0x0080 /* Board has ADMtek switch */ ++ + struct ssb_device; + + struct b44 { diff --git a/target/linux/brcm47xx/patches-3.10/209-b44-register-adm-switch.patch b/target/linux/brcm47xx/patches-3.10/209-b44-register-adm-switch.patch index 3f01286646..d44432cafb 100644 --- a/target/linux/brcm47xx/patches-3.10/209-b44-register-adm-switch.patch +++ b/target/linux/brcm47xx/patches-3.10/209-b44-register-adm-switch.patch @@ -1,12 +1,12 @@ -From b52546f8af54b78050f84ab031ad1aaf6507ed95 Mon Sep 17 00:00:00 2001 +From b36f694256f41bc71571f467646d015dda128d14 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 9 Nov 2013 17:03:59 +0100 -Subject: [PATCH 10/10] b44: register adm switch +Subject: [PATCH 210/210] b44: register adm switch --- - drivers/net/ethernet/broadcom/b44.c | 64 ++++++++++++++++++++++++++++++++++- + drivers/net/ethernet/broadcom/b44.c | 57 +++++++++++++++++++++++++++++++++++ drivers/net/ethernet/broadcom/b44.h | 3 ++ - 2 files changed, 66 insertions(+), 1 deletion(-) + 2 files changed, 60 insertions(+) --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -19,8 +19,8 @@ Subject: [PATCH 10/10] b44: register adm switch #include #include -@@ -2216,6 +2218,58 @@ static void b44_adjust_link(struct net_d - phy_print_status(phydev); +@@ -2227,6 +2229,58 @@ static void b44_adjust_link(struct net_d + } } +#ifdef CONFIG_BCM47XX @@ -78,42 +78,21 @@ Subject: [PATCH 10/10] b44: register adm switch static int b44_register_phy_one(struct b44 *bp) { struct mii_bus *mii_bus; -@@ -2223,6 +2277,7 @@ static int b44_register_phy_one(struct b - struct phy_device *phydev; - int err; - struct phy_c45_device_ids c45_ids = {0}; -+ struct ssb_sprom *sprom = &sdev->bus->sprom; - - mii_bus = mdiobus_alloc(); - if (!mii_bus) { -@@ -2256,7 +2311,11 @@ static int b44_register_phy_one(struct b - } +@@ -2270,6 +2324,9 @@ static int b44_register_phy_one(struct b + if (!bp->mii_bus->phy_map[bp->phy_addr] && + (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) { - phydev = bp->mii_bus->phy_map[bp->phy_addr]; -- if (!phydev) { -+ if (!phydev && -+ (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) { + if (sprom->boardflags_lo & B44_BOARDFLAG_ADM) + b44_register_adm_switch(bp); + - dev_info(sdev->dev, "could not find PHY at %i, create dummy one\n", + dev_info(sdev->dev, + "could not find PHY at %i, use fixed one\n", bp->phy_addr); - --- a/drivers/net/ethernet/broadcom/b44.h +++ b/drivers/net/ethernet/broadcom/b44.h -@@ -345,6 +345,9 @@ B44_STAT_REG_DECLARE - struct u64_stats_sync syncp; - }; - -+#define B44_BOARDFLAG_ROBO 0x0010 /* Board has robo switch or core */ -+#define B44_BOARDFLAG_ADM 0x0080 /* Board has ADMtek switch */ -+ - struct ssb_device; - - struct b44 { -@@ -402,6 +405,9 @@ struct b44 { +@@ -404,6 +404,9 @@ struct b44 { + struct mii_bus *mii_bus; int old_link; - int old_duplex; struct mii_if_info mii_if; + + /* platform device for associated switch */ 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 53989ef094..452ea2eb0a 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 @@ -12,14 +12,14 @@ + + /* Toshiba WRC-1000, Siemens SE505 v1, Askey RT-210W, RT-220W */ + if (sdev->bus->sprom.board_num == 100) { -+ bp->phy_addr = B44_PHY_ADDR_NO_LOACL_PHY; ++ bp->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY; + } else { + /* WL-HDD */ + if (bcm47xx_nvram_getenv("hardware_version", buf, sizeof(buf)) >= 0 && + !strncmp(buf, "WL300-", strlen("WL300-"))) { + if (sdev->bus->sprom.et0phyaddr == 0 && + sdev->bus->sprom.et1phyaddr == 1) -+ bp->phy_addr = B44_PHY_ADDR_NO_LOACL_PHY; ++ bp->phy_addr = B44_PHY_ADDR_NO_LOCAL_PHY; + } + } + return; @@ -43,7 +43,7 @@ if (bp->flags & B44_FLAG_EXTERNAL_PHY) return 0; -@@ -2160,6 +2185,8 @@ static int b44_get_invariants(struct b44 +@@ -2162,6 +2187,8 @@ static int b44_get_invariants(struct b44 * valid PHY address. */ bp->phy_addr &= 0x1F; diff --git a/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch b/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch index ec3818981d..c61254db02 100644 --- a/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch +++ b/target/linux/brcm47xx/patches-3.10/830-huawei_e970_support.patch @@ -1,6 +1,6 @@ --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c -@@ -31,6 +31,7 @@ +@@ -34,6 +34,7 @@ #include #include #include @@ -8,9 +8,9 @@ #include #include #include -@@ -239,6 +240,33 @@ void __init plat_mem_setup(void) - mips_set_machine_name(bcm47xx_board_get_name()); - } +@@ -248,6 +249,33 @@ static struct fixed_phy_status bcm47xx_f + .duplex = DUPLEX_FULL, + }; +static struct gpio_wdt_platform_data gpio_wdt_data; + @@ -42,10 +42,10 @@ static int __init bcm47xx_register_bus_complete(void) { switch (bcm47xx_bus_type) { -@@ -253,6 +281,8 @@ static int __init bcm47xx_register_bus_c - break; +@@ -263,6 +291,8 @@ static int __init bcm47xx_register_bus_c #endif } + fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status); + bcm47xx_register_gpio_watchdog(); + return 0; diff --git a/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch b/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch index f30a4fbd75..84be5121d5 100644 --- a/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch +++ b/target/linux/brcm47xx/patches-3.10/980-wnr834b_no_cardbus_invariant.patch @@ -1,6 +1,6 @@ --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c -@@ -122,6 +122,10 @@ static int bcm47xx_get_invariants(struct +@@ -125,6 +125,10 @@ static int bcm47xx_get_invariants(struct if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);