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 <[email protected]>
> ---
> .../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
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel