2013.12.17. 1:12 keltezéssel, Felix Kaechele írta: > The bootloader on the WD My Net N750 disables the ports on it's internal > AR8327N switch by powering them down. The stock firmware then brings the > ports back up again by starting the auto negotiation process on each > port. > > There is one big disadvantage of this approach: In tests I noticed that > PHYs on this platform that are powered down can be written but not read. > As a result the scan on the mdio bus fails to detect the ports on the > switch. > > This workaround adds an option to the mdio bus platform data that > enables toggling of an early reset of all available PHYs before the mdio > bus scan is performed. On the test platform this brings the PHYs back to > life in time to be detected by the mdio bus scan. > > Signed-off-by: Felix Kaechele <hef...@fedoraproject.org> > --- > .../linux/ar71xx/files/arch/mips/ath79/dev-eth.c | 4 +-- > .../linux/ar71xx/files/arch/mips/ath79/dev-eth.h | 2 ++ > .../mips/include/asm/mach-ath79/ag71xx_platform.h | 1 + > .../net/ethernet/atheros/ag71xx/ag71xx_mdio.c | 30 > ++++++++++++++-------- > 4 files changed, 24 insertions(+), 13 deletions(-) > > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c > b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c > index 4a2b1db..742218b 100644 > --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c > +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c > @@ -39,7 +39,7 @@ static struct resource ath79_mdio0_resources[] = { > } > }; > > -static struct ag71xx_mdio_platform_data ath79_mdio0_data; > +struct ag71xx_mdio_platform_data ath79_mdio0_data; > > struct platform_device ath79_mdio0_device = { > .name = "ag71xx-mdio", > @@ -60,7 +60,7 @@ static struct resource ath79_mdio1_resources[] = { > } > }; > > -static struct ag71xx_mdio_platform_data ath79_mdio1_data; > +struct ag71xx_mdio_platform_data ath79_mdio1_data;
Making the ath79_mdio[01]_data visible is not strictly related to the patch. I would do it in a separate change ... > > struct platform_device ath79_mdio1_device = { > .name = "ag71xx-mdio", > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h > b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h > index bc608da..08a59ef 100644 > --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h > +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.h > @@ -39,6 +39,8 @@ void ath79_register_eth(unsigned int id); > > extern struct ag71xx_switch_platform_data ath79_switch_data; > > +extern struct ag71xx_mdio_platform_data ath79_mdio0_data; > +extern struct ag71xx_mdio_platform_data ath79_mdio0_data; ... and the second line should refer to ath79_mdio*1*_data. > extern struct platform_device ath79_mdio0_device; > extern struct platform_device ath79_mdio1_device; > void ath79_register_mdio(unsigned int id, u32 phy_mask); > diff --git > a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h > > b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h > index 656a6ef..333daa9 100644 > --- > a/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h > +++ > b/target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h > @@ -53,6 +53,7 @@ struct ag71xx_mdio_platform_data { > u8 is_ar7240:1; > u8 is_ar9330:1; > u8 is_ar934x:1; > + u8 wake_phys:1; To be honest, I would like to avoid any board specific workaround in the ag71xx/mdio driver. Even if there is no other alternative to make it working on the My Net N750 , this should be done in a more generic way. It would be better to add a 'void (*reset)(struct mii_bus *bus);' callback to the ag71xx_mdio_platform_data and call that from the ag71xx_mdio_reset function. In that way, the extra functionality can be implemented within the board specific code. > unsigned long mdio_clock; > unsigned long ref_clock; > }; > diff --git > a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c > b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c > index ec88233..0f3ed63 100644 > --- > a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c > +++ > b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_mdio.c > @@ -156,10 +156,22 @@ static int ag71xx_mdio_get_divider(struct ag71xx_mdio > *am, u32 *div) > return -ENOENT; > } > > +static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) > +{ > + struct ag71xx_mdio *am = bus->priv; > + > + if (am->pdata->builtin_switch) > + ar7240sw_phy_write(bus, addr, reg, val); > + else > + ag71xx_mdio_mii_write(am, addr, reg, val); > + return 0; > +} > + > static int ag71xx_mdio_reset(struct mii_bus *bus) > { > struct ag71xx_mdio *am = bus->priv; > u32 t; > + int i; > int err; > > err = ag71xx_mdio_get_divider(am, &t); > @@ -181,6 +193,13 @@ static int ag71xx_mdio_reset(struct mii_bus *bus) > ag71xx_mdio_wr(am, AG71XX_REG_MII_CFG, t); > udelay(100); > > + if(am->pdata->wake_phys) { > + for (i = 0; i < PHY_MAX_ADDR; i++) Another advantage of a separate callback is that you can optimize the loop. It makes no sense to write to the non existing PHYs. > + ag71xx_mdio_write(bus, i, MII_BMCR, (BMCR_RESET | > + BMCR_ANENABLE | BMCR_SPEED1000)); > + msleep(1000); > + } > + > return 0; > } > > @@ -194,17 +213,6 @@ static int ag71xx_mdio_read(struct mii_bus *bus, int > addr, int reg) > return ag71xx_mdio_mii_read(am, addr, reg); > } > > -static int ag71xx_mdio_write(struct mii_bus *bus, int addr, int reg, u16 val) > -{ > - struct ag71xx_mdio *am = bus->priv; > - > - if (am->pdata->builtin_switch) > - ar7240sw_phy_write(bus, addr, reg, val); > - else > - ag71xx_mdio_mii_write(am, addr, reg, val); > - return 0; > -} > - Additionally, you would not have to move the 'ag71xx_mdio_write' function at all. From the board specific callback, you can use the mdiobus_write() function instead. > static int ag71xx_mdio_probe(struct platform_device *pdev) > { > struct ag71xx_mdio_platform_data *pdata; > -Gabor _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel