On 12/19/05, Arnaldo Carvalho de Melo <[EMAIL PROTECTED]> wrote: > On 12/19/05, John W. Linville <[EMAIL PROTECTED]> wrote: > > On Mon, Dec 19, 2005 at 03:35:04PM +0100, Lennert Buytenhek wrote: > > > On Mon, Dec 19, 2005 at 12:20:32PM -0200, Arnaldo Carvalho de Melo wrote: > > > > > > > @@ -633,7 +643,7 @@ static int __devinit sundance_probe1 (st > > > > > > > > np->phys[0] = 1; /* Default setting */ > > > > np->mii_preamble_required++; > > > > - for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) { > > > > + for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) { > > > > int mii_status = mdio_read(dev, phy, MII_BMSR); > > > > int phyx = phy & 0x1f; > > > > if (mii_status != 0xffff && mii_status != 0x0000) { > > > > > > (Your PHY is at address 0?) Can you add some debug here to see what > > > happens in both cases (f.e. print the returned MII_BMSR values for > > > both 'start at 0' and 'start at 1')? Presumably there's something > > > about starting at 1 that gets your hardware confused, I'd like to know > > > what that is.. > > > > How about if you just ditch that hunk? The "int phyx = phy & 0x1f" > > line serves the purpose of making sure that phy addr 0 is still > > accessed, just last instead of first. Apparently this is some oral > > wisdom passed-down from Don Becker relating to some phys not dealing > > well w/ address 0 being accessed first. > > humm, interesting explanation, I'll add a comment and make phy 0 > actually be read, as it is not being right now as we have: > > int mii_status = mdio_read(dev, phy, MII_BMSR); > int phyx = phy & 0x1f; > > When we should have instead: > > int phyx = phy & 0x1f; > int mii_status = mdio_read(dev, phyx, MII_BMSR); > > so that when phy, in the end of the (phy = 1; phy <= 32...) loop gets > to 32 phyx gets to 0, i.e. we were reading at 32, when the intended > read was for 0. > > Lemme see if this works...
Yeah, it works, new patch attached. Signed-off-by: Arnaldo Carvalho de Melo <[EMAIL PROTECTED]> - Arnaldo
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 0ab9c38..146fbdb 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -94,11 +94,14 @@ Version LK1.10 (Philippe De Muyter [EMAIL PROTECTED]): - Make 'unblock interface after Tx underrun' work + Version LK1.11 (Arnaldo Carvalho de Melo [EMAIL PROTECTED]): + - Merge some bits from Encore driver sources (Jesse Huang) to + get the Encore ENL832-TX-ICNT card working. */ #define DRV_NAME "sundance" -#define DRV_VERSION "1.01+LK1.10" -#define DRV_RELDATE "28-Oct-2005" +#define DRV_VERSION "1.01+LK1.11" +#define DRV_RELDATE "19-Dec-2005" /* The user-configurable values. @@ -286,7 +289,8 @@ static struct pci_device_id sundance_pci {0x1186, 0x1002, 0x1186, 0x1012, 0, 0, 2}, {0x1186, 0x1002, 0x1186, 0x1040, 0, 0, 3}, {0x1186, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, - {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, + {0x13F0, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5}, + {0x13F0, 0x0201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6}, {0,} }; MODULE_DEVICE_TABLE(pci, sundance_pci_tbl); @@ -304,6 +308,7 @@ static struct pci_id_info pci_id_tbl[] = {"D-Link DFE-580TX 4 port Server Adapter"}, {"D-Link DFE-530TXS FAST Ethernet Adapter"}, {"D-Link DL10050-based FAST Ethernet Adapter"}, + {"ENCORE 10/100Mbps Fast Ethernet PCI Adapter" }, {"Sundance Technology Alta"}, {NULL,}, /* 0 terminated list. */ }; @@ -475,6 +480,11 @@ struct netdev_private { unsigned char pci_rev_id; }; +static inline int sundance_enl832_tx_icnt(const struct pci_dev *pd) +{ + return pd->device == 0x200 && pd->vendor == 0x13F0; +} + /* The station address location in the EEPROM. */ #define EEPROM_SA_OFFSET 0x10 #define DEFAULT_INTR (IntrRxDMADone | IntrPCIErr | \ @@ -633,9 +643,13 @@ static int __devinit sundance_probe1 (st np->phys[0] = 1; /* Default setting */ np->mii_preamble_required++; + /* + * It seems some phys doesn't deal well with address 0 being accessed + * first, so leave address zero to the end of the loop (32 & 31). + */ for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) { - int mii_status = mdio_read(dev, phy, MII_BMSR); - int phyx = phy & 0x1f; + const int phyx = phy & 0x1f; + const int mii_status = mdio_read(dev, phyx, MII_BMSR); if (mii_status != 0xffff && mii_status != 0x0000) { np->phys[phy_idx++] = phyx; np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE); @@ -700,17 +714,41 @@ static int __devinit sundance_probe1 (st /* If flow control enabled, we need to advertise it.*/ if (np->flowctrl) mdio_write (dev, np->phys[0], MII_ADVERTISE, np->mii_if.advertising | 0x0400); - mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART); + + if (!sundance_enl832_tx_icnt(pdev)) + mdio_write(dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART); /* Force media type */ if (!np->an_enable) { - mii_ctl = 0; - mii_ctl |= (np->speed == 100) ? BMCR_SPEED100 : 0; - mii_ctl |= (np->mii_if.full_duplex) ? BMCR_FULLDPLX : 0; - mdio_write (dev, np->phys[0], MII_BMCR, mii_ctl); - printk (KERN_INFO "Override speed=%d, %s duplex\n", - np->speed, np->mii_if.full_duplex ? "Full" : "Half"); + if (!sundance_enl832_tx_icnt(pdev)) { + mii_ctl = 0; + mii_ctl |= np->speed == 100 ? BMCR_SPEED100 : 0; + mii_ctl |= np->mii_if.full_duplex ? BMCR_FULLDPLX : 0; + mdio_write(dev, np->phys[0], MII_BMCR, mii_ctl); + printk(KERN_INFO "Override speed=%d, %s duplex\n", + np->speed, np->mii_if.full_duplex ? "Full" : "Half"); + } else { + u16 mii_avt; - } + mii_ctl = mdio_read(dev, np->phys[0], + MII_BMCR) & 0x0000ffff; + mii_avt = mdio_read(dev, np->phys[0], MII_ADVERTISE) & + ~(ADVERTISE_100FULL + ADVERTISE_100HALF + + ADVERTISE_10FULL + ADVERTISE_10HALF); + if (np->speed == 100) + mii_avt |= np->mii_if.full_duplex ? + ADVERTISE_100FULL : + ADVERTISE_100HALF; + else + mii_avt |= np->mii_if.full_duplex ? + ADVERTISE_10FULL : + ADVERTISE_10HALF; + + mdio_write(dev, np->phys[0], MII_ADVERTISE, mii_avt); + mdio_write(dev, np->phys[0], MII_BMCR, + mii_ctl | BMCR_ANENABLE | BMCR_ANRESTART); + } + } else if (sundance_enl832_tx_icnt(pdev)) + mdio_write(dev, np->phys[0], MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); /* Perhaps move the reset here? */ /* Reset the chip to erase previous misconfiguration. */