diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2013-12-19 20:16:13 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-12-20 20:48:49 -0500 |
commit | b04138b335203b79ffe1b14750fa245a4dab7191 (patch) | |
tree | 34b919de0a5f3ab927dda225a84cc624ab624741 | |
parent | 656a7c2b1210deddf76444ecc76e058c0404ce80 (diff) |
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 <hauke@hauke-m.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | arch/mips/bcm47xx/setup.c | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/b44.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/broadcom/b44.h | 3 |
3 files changed, 28 insertions, 1 deletions
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 1f30571968e7..9057728ac56b 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -28,6 +28,9 @@ | |||
28 | 28 | ||
29 | #include <linux/export.h> | 29 | #include <linux/export.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/ethtool.h> | ||
32 | #include <linux/phy.h> | ||
33 | #include <linux/phy_fixed.h> | ||
31 | #include <linux/ssb/ssb.h> | 34 | #include <linux/ssb/ssb.h> |
32 | #include <linux/ssb/ssb_embedded.h> | 35 | #include <linux/ssb/ssb_embedded.h> |
33 | #include <linux/bcma/bcma_soc.h> | 36 | #include <linux/bcma/bcma_soc.h> |
@@ -225,6 +228,12 @@ void __init plat_mem_setup(void) | |||
225 | bcm47xx_board_detect(); | 228 | bcm47xx_board_detect(); |
226 | } | 229 | } |
227 | 230 | ||
231 | static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = { | ||
232 | .link = 1, | ||
233 | .speed = SPEED_100, | ||
234 | .duplex = DUPLEX_FULL, | ||
235 | }; | ||
236 | |||
228 | static int __init bcm47xx_register_bus_complete(void) | 237 | static int __init bcm47xx_register_bus_complete(void) |
229 | { | 238 | { |
230 | switch (bcm47xx_bus_type) { | 239 | switch (bcm47xx_bus_type) { |
@@ -239,6 +248,7 @@ static int __init bcm47xx_register_bus_complete(void) | |||
239 | break; | 248 | break; |
240 | #endif | 249 | #endif |
241 | } | 250 | } |
251 | fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status); | ||
242 | return 0; | 252 | return 0; |
243 | } | 253 | } |
244 | device_initcall(bcm47xx_register_bus_complete); | 254 | device_initcall(bcm47xx_register_bus_complete); |
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 839dd9092b17..1f7b5aa114fa 100644 --- 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 b44 *bp) | |||
2233 | struct ssb_device *sdev = bp->sdev; | 2233 | struct ssb_device *sdev = bp->sdev; |
2234 | struct phy_device *phydev; | 2234 | struct phy_device *phydev; |
2235 | char bus_id[MII_BUS_ID_SIZE + 3]; | 2235 | char bus_id[MII_BUS_ID_SIZE + 3]; |
2236 | struct ssb_sprom *sprom = &sdev->bus->sprom; | ||
2236 | int err; | 2237 | int err; |
2237 | 2238 | ||
2238 | mii_bus = mdiobus_alloc(); | 2239 | mii_bus = mdiobus_alloc(); |
@@ -2266,7 +2267,20 @@ static int b44_register_phy_one(struct b44 *bp) | |||
2266 | goto err_out_mdiobus_irq; | 2267 | goto err_out_mdiobus_irq; |
2267 | } | 2268 | } |
2268 | 2269 | ||
2269 | snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id, bp->phy_addr); | 2270 | if (!bp->mii_bus->phy_map[bp->phy_addr] && |
2271 | (sprom->boardflags_lo & (B44_BOARDFLAG_ROBO | B44_BOARDFLAG_ADM))) { | ||
2272 | |||
2273 | dev_info(sdev->dev, | ||
2274 | "could not find PHY at %i, use fixed one\n", | ||
2275 | bp->phy_addr); | ||
2276 | |||
2277 | bp->phy_addr = 0; | ||
2278 | snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, "fixed-0", | ||
2279 | bp->phy_addr); | ||
2280 | } else { | ||
2281 | snprintf(bus_id, sizeof(bus_id), PHY_ID_FMT, mii_bus->id, | ||
2282 | bp->phy_addr); | ||
2283 | } | ||
2270 | 2284 | ||
2271 | phydev = phy_connect(bp->dev, bus_id, &b44_adjust_link, | 2285 | phydev = phy_connect(bp->dev, bus_id, &b44_adjust_link, |
2272 | PHY_INTERFACE_MODE_MII); | 2286 | PHY_INTERFACE_MODE_MII); |
diff --git a/drivers/net/ethernet/broadcom/b44.h b/drivers/net/ethernet/broadcom/b44.h index de81639d9236..3e9c3fc7591b 100644 --- a/drivers/net/ethernet/broadcom/b44.h +++ b/drivers/net/ethernet/broadcom/b44.h | |||
@@ -345,6 +345,9 @@ B44_STAT_REG_DECLARE | |||
345 | struct u64_stats_sync syncp; | 345 | struct u64_stats_sync syncp; |
346 | }; | 346 | }; |
347 | 347 | ||
348 | #define B44_BOARDFLAG_ROBO 0x0010 /* Board has robo switch */ | ||
349 | #define B44_BOARDFLAG_ADM 0x0080 /* Board has ADMtek switch */ | ||
350 | |||
348 | struct ssb_device; | 351 | struct ssb_device; |
349 | 352 | ||
350 | struct b44 { | 353 | struct b44 { |