Re: r6040 mac driver issue and solution

From: Florian Fainelli
Date: Fri Jun 07 2013 - 08:15:35 EST


Dear Bruce,

2013/6/7 Bruce Ye (èäæ) <Bruce.Ye@xxxxxxxxxx>:
> Dear Florian:
> For RDC R6040 FAST ETHERNET DRIVER.
> There's an issue in r6040 driver and for some RDC platform. It only occurs when there's more than one Ethernet port.
> When initializing the MAC in boot up, r6040 driver set the same phy address to different ports.
> It also display in boot log as below.
> mii_bus:phy_addr=0:01
> mii_bus:phy_addr=1:01
>
> It will let the eth0 and eth1 work not in independent.
> That is, if there is a connection on eth1 but not on eth0. The eth1 can not work only if link up the eth0.
> To fix this problem is that giving the different phy address to different ports.
> I already tested it on r6040.c version 0.27 and version 0.28 by the change and is worked.

I see, thanks for the change. Have you verified that simply changing
mii_bus->phy_mask is sufficient? This should prevent the second MII
bus from probing the PHY at address 1. I will add this patch to my
patchqueue for r6040, thank you!

>
> Below is the change
>
> --- linux-3.7.2/drivers/net/ethernet/rdc/r6040.c.orig 2013-06-07 03:00:05.670250988 -0700
> +++ linux-3.7.2/drivers/net/ethernet/rdc/r6040.c 2013-06-07 03:05:01.666407765 -0700
> @@ -1037,8 +1037,18 @@ static int r6040_mii_probe(struct net_de
> {
> struct r6040_private *lp = netdev_priv(dev);
> struct phy_device *phydev = NULL;
> + static int first_find_addr = 0;
> + int addr;
> + for ( addr = first_find_addr; addr < PHY_MAX_ADDR; addr++ ) {
> +
> + if ( lp->mii_bus->phy_map[addr] )
> + phydev = lp->mii_bus->phy_map[addr];
> +
> + if(phydev)
> + break;
> + }
> + first_find_addr++ ;
>
> - phydev = phy_find_first(lp->mii_bus);
> if (!phydev) {
> dev_err(&lp->pdev->dev, "no PHY found\n");
> return -ENODEV;
> @@ -1194,6 +1204,10 @@ static int __devinit r6040_init_one(stru
> lp->mii_bus->write = r6040_mdiobus_write;
> lp->mii_bus->reset = r6040_mdiobus_reset;
> lp->mii_bus->name = "r6040_eth_mii";
> + if ( card_idx == 0 )
> + lp->mii_bus->phy_mask = 0x1;
> + else
> + lp->mii_bus->phy_mask = 0x3;
> snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
> dev_name(&pdev->dev), card_idx);
> lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
>
>
>
> Signed-off-by: Bruce Ye Developer <Bruce.Ye@xxxxxxxxxx>
>
> Best Regards
> Bruce
> RDC Semiconductor
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/