diff -ur /spare/tmp/linux_2_4/drivers/net/tulip/ChangeLog linux_2_4/drivers/net/tulip/ChangeLog --- /spare/tmp/linux_2_4/drivers/net/tulip/ChangeLog Sat May 12 10:47:08 2001 +++ linux_2_4/drivers/net/tulip/ChangeLog Sat May 12 15:18:47 2001 @@ -1,3 +1,49 @@ +2001-05-12 Jeff Garzik + + * tulip_core (tulip_init_one): Do not call + unregister_netdev in error cleanup. Remnant of old + usage of init_etherdev. + +2001-05-12 Jeff Garzik + + * media.c (tulip_find_mii): Simple write the updated BMCR + twice, as it seems the best thing to do for both broken and + sane chips. + If the mii_advert value, as read from MII_ADVERTISE, is zero, + then generate a value we should advertise from the capability + bits in BMSR. + Fill in tp->advertising for all cases. + Just to be safe, clear all unwanted bits. + +2001-05-12 Jeff Garzik + + * tulip_core.c (private_ioctl): Fill in tp->advertising + when advertising value is changed by the user. + +2001-05-12 Jeff Garzik + + * tulip_core.c: Mark Comet chips as needed the updated MWI + csr0 configuration. + +2001-05-12 Jeff Garzik + + * media.c, tulip_core.c: Move MII scan into + from inlined inside tulip_init_one to new function + tulip_find_mii in media.c. + +2001-05-12 Jeff Garzik + + * media.c (tulip_check_duplex): + Only restart Rx/Tx engines if they are active + (and csr6 changes) + +2001-05-12 Jeff Garzik + + * tulip_core.c (tulip_mwi_config): + Clamp values read from PCI cache line size register to + values acceptable to tulip chip. Done for safety and + -almost- certainly unneeded. + 2001-05-11 Jeff Garzik * tulip_core.c (tulip_init_one): @@ -93,15 +139,15 @@ 2001-05-09 Jeff Garzik - * 21142.c (t21142_lnk_change): Pass arg startup==1 - to tulip_select_media, in order to force csr13 to be - zeroed out prior to going to full duplex mode. Fixes - autonegotiation on a quad-port Znyx card. - (from Stephen Dengler) + * 21142.c (t21142_lnk_change): Pass arg startup==1 + to tulip_select_media, in order to force csr13 to be + zeroed out prior to going to full duplex mode. Fixes + autonegotiation on a quad-port Znyx card. + (from Stephen Dengler) 2001-05-09 Russell King - * interrupt.c: Better PCI bus error reporting. + * interrupt.c: Better PCI bus error reporting. 2001-04-03 Jeff Garzik @@ -134,7 +180,7 @@ the following defines existed. These defines were never used by normal users in practice: TULIP_FULL_DUPLEX, TULIP_DEFAULT_MEDIA, and TULIP_NO_MEDIA_SWITCH. - + * tulip.h, eeprom.c: Move EE_* constants from tulip.h to eeprom.c. * tulip.h, media.c: Move MDIO_* constants from tulip.h to media.c. diff -ur /spare/tmp/linux_2_4/drivers/net/tulip/media.c linux_2_4/drivers/net/tulip/media.c --- /spare/tmp/linux_2_4/drivers/net/tulip/media.c Sat May 12 10:47:08 2001 +++ linux_2_4/drivers/net/tulip/media.c Sat May 12 13:08:31 2001 @@ -16,6 +16,8 @@ #include #include +#include +#include #include "tulip.h" @@ -409,6 +411,7 @@ */ int tulip_check_duplex(struct net_device *dev) { + long ioaddr = dev->base_addr; struct tulip_private *tp = dev->priv; unsigned int bmsr, lpa, negotiated, new_csr6; @@ -439,7 +442,10 @@ else new_csr6 &= ~FullDuplex; if (new_csr6 != tp->csr6) { - tulip_restart_rxtx(tp, new_csr6); + if (inl(ioaddr + CSR6) & (csr6_st | csr6_sr)) + tulip_restart_rxtx(tp, new_csr6); + else + outl(new_csr6, ioaddr + CSR6); tp->csr6 = new_csr6; if (tulip_debug > 0) @@ -451,4 +457,111 @@ } return 0; +} + +void __devinit tulip_find_mii (struct net_device *dev, int board_idx) +{ + struct tulip_private *tp = dev->priv; + int phyn, phy_idx = 0; + int mii_reg0; + int mii_advert; + unsigned int to_advert, new_bmcr, ane_switch; + + /* Find the connected MII xcvrs. + Doing this in open() would allow detecting external xcvrs later, + but takes much time. */ + for (phyn = 1; phyn <= 32 && phy_idx < sizeof (tp->phys); phyn++) { + int phy = phyn & 0x1f; + int mii_status = tulip_mdio_read (dev, phy, MII_BMSR); + if ((mii_status & 0x8301) == 0x8001 || + ((mii_status & BMSR_100BASE4) == 0 + && (mii_status & 0x7800) != 0)) { + /* preserve Becker logic, gain indentation level */ + } else { + continue; + } + + mii_reg0 = tulip_mdio_read (dev, phy, MII_BMCR); + mii_advert = tulip_mdio_read (dev, phy, MII_ADVERTISE); + ane_switch = 0; + + /* if not advertising at all, gen an + * advertising value from the capability + * bits in BMSR + */ + if ((mii_advert & ADVERTISE_ALL) == 0) { + unsigned int tmpadv = tulip_mdio_read (dev, phy, MII_BMSR); + mii_advert = ((tmpadv >> 6) & 0x3e0) | 1; + } + + if (tp->mii_advertise) { + tp->advertising[phy_idx] = + to_advert = tp->mii_advertise; + } else if (tp->advertising[phy_idx]) { + to_advert = tp->advertising[phy_idx]; + } else { + tp->advertising[phy_idx] = + tp->mii_advertise = + to_advert = mii_advert; + } + + tp->phys[phy_idx++] = phy; + + printk (KERN_INFO "tulip%d: MII transceiver #%d " + "config %4.4x status %4.4x advertising %4.4x.\n", + board_idx, phy, mii_reg0, mii_status, mii_advert); + + /* Fixup for DLink with miswired PHY. */ + if (mii_advert != to_advert) { + printk (KERN_DEBUG "tulip%d: Advertising %4.4x on PHY %d," + " previously advertising %4.4x.\n", + board_idx, to_advert, phy, mii_advert); + tulip_mdio_write (dev, phy, 4, to_advert); + } + + /* Enable autonegotiation: some boards default to off. */ + if (tp->default_port == 0) { + new_bmcr = mii_reg0 | BMCR_ANENABLE; + if (new_bmcr != mii_reg0) { + new_bmcr |= BMCR_ANRESTART; + ane_switch = 1; + } + } + /* ...or disable nway, if forcing media */ + else { + new_bmcr = mii_reg0 & ~BMCR_ANENABLE; + if (new_bmcr != mii_reg0) + ane_switch = 1; + } + + /* clear out bits we never want at this point */ + new_bmcr &= ~(BMCR_CTST | BMCR_FULLDPLX | BMCR_ISOLATE | + BMCR_PDOWN | BMCR_SPEED100 | BMCR_LOOPBACK | + BMCR_RESET); + + if (tp->full_duplex) + new_bmcr |= BMCR_FULLDPLX; + if (tulip_media_cap[tp->default_port] & MediaIs100) + new_bmcr |= BMCR_SPEED100; + + if (new_bmcr != mii_reg0) { + /* some phys need the ANE switch to + * happen before forced media settings + * will "take." However, we write the + * same value twice in order not to + * confuse the sane phys. + */ + if (ane_switch) { + tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr); + udelay (10); + } + tulip_mdio_write (dev, phy, MII_BMCR, new_bmcr); + } + } + tp->mii_cnt = phy_idx; + if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { + printk (KERN_INFO "tulip%d: ***WARNING***: No MII transceiver found!\n", + board_idx); + tp->phys[0] = 1; + } } diff -ur /spare/tmp/linux_2_4/drivers/net/tulip/tulip.h linux_2_4/drivers/net/tulip/tulip.h --- /spare/tmp/linux_2_4/drivers/net/tulip/tulip.h Sat May 12 10:47:08 2001 +++ linux_2_4/drivers/net/tulip/tulip.h Sat May 12 13:07:51 2001 @@ -404,6 +404,7 @@ void tulip_mdio_write(struct net_device *dev, int phy_id, int location, int value); void tulip_select_media(struct net_device *dev, int startup); int tulip_check_duplex(struct net_device *dev); +void tulip_find_mii (struct net_device *dev, int board_idx); /* pnic.c */ void pnic_do_nway(struct net_device *dev); diff -ur /spare/tmp/linux_2_4/drivers/net/tulip/tulip_core.c linux_2_4/drivers/net/tulip/tulip_core.c --- /spare/tmp/linux_2_4/drivers/net/tulip/tulip_core.c Sat May 12 10:47:08 2001 +++ linux_2_4/drivers/net/tulip/tulip_core.c Sat May 12 13:07:47 2001 @@ -24,7 +24,7 @@ #include static char version[] __devinitdata = - "Linux Tulip driver version 0.9.14g (May 11, 2001)\n"; + "Linux Tulip driver version 0.9.14h (May 12, 2001)\n"; /* A few user-configurable values. */ @@ -162,7 +162,7 @@ /* COMET */ { "ADMtek Comet", 256, 0x0001abef, - MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer }, + MC_HASH_ONLY | COMET_MAC_ADDR | HAS_PCI_MWI, comet_timer }, /* COMPEX9881 */ { "Compex 9881 PMAC", 128, 0x0001ebef, @@ -824,7 +824,8 @@ struct tulip_private *tp = dev->priv; long ioaddr = dev->base_addr; u16 *data = (u16 *) & rq->ifr_data; - int phy = tp->phys[0] & 0x1f; + const unsigned int phy_idx = 0; + int phy = tp->phys[phy_idx] & 0x1f; unsigned int regnum = data[1]; switch (cmd) { @@ -886,7 +887,10 @@ if (tp->full_duplex_lock) tp->full_duplex = (value & 0x0100) ? 1 : 0; break; - case 4: tp->mii_advertise = data[2]; break; + case 4: + tp->advertising[phy_idx] = + tp->mii_advertise = data[2]; + break; } } if (data[0] == 32 && (tp->flags & HAS_NWAY)) { @@ -1167,6 +1171,19 @@ if (!pci_cacheline || (tp->chip_id == DC21143 && tp->revision == 65)) mwi = 0; + /* re-clamp cache line values to ones supported by tulip */ + /* From this point forward, 'pci_cacheline' is really + * the value used for csr0 cache alignment and + * csr0 programmable burst length + */ + switch (pci_cacheline) { + case 0: + case 8: + case 16: + case 32: break; + default: pci_cacheline = TULIP_MIN_CACHE_LINE; break; + } + /* set or disable MWI in the standard PCI command bit. * Check for the case where mwi is desired but not available */ @@ -1497,7 +1514,6 @@ if ((tp->flags & ALWAYS_CHECK_MII) || (tp->mtable && tp->mtable->has_mii) || ( ! tp->mtable && (tp->flags & HAS_MII))) { - int phyn, phy_idx = 0; if (tp->mtable && tp->mtable->has_mii) { for (i = 0; i < tp->mtable->leafcount; i++) if (tp->mtable->mleaf[i].media == 11) { @@ -1508,69 +1524,11 @@ break; } } - /* Find the connected MII xcvrs. - Doing this in open() would allow detecting external xcvrs later, - but takes much time. */ - for (phyn = 1; phyn <= 32 && phy_idx < sizeof(tp->phys); phyn++) { - int phy = phyn & 0x1f; - int mii_status = tulip_mdio_read(dev, phy, 1); - if ((mii_status & 0x8301) == 0x8001 || - ((mii_status & 0x8000) == 0 && (mii_status & 0x7800) != 0)) { - int mii_reg0 = tulip_mdio_read(dev, phy, 0); - int mii_advert = tulip_mdio_read(dev, phy, 4); - unsigned int to_advert, new_bmcr; - - if (tp->mii_advertise) - to_advert = tp->mii_advertise; - else if (tp->advertising[phy_idx]) - to_advert = tp->advertising[phy_idx]; - else - tp->mii_advertise = to_advert = mii_advert; - tp->phys[phy_idx++] = phy; - - printk(KERN_INFO "tulip%d: MII transceiver #%d " - "config %4.4x status %4.4x advertising %4.4x.\n", - board_idx, phy, mii_reg0, mii_status, mii_advert); - /* Fixup for DLink with miswired PHY. */ - if (mii_advert != to_advert) { - printk(KERN_DEBUG "tulip%d: Advertising %4.4x on PHY %d," - " previously advertising %4.4x.\n", - board_idx, to_advert, phy, mii_advert); - tulip_mdio_write(dev, phy, 4, to_advert); - } - - /* Enable autonegotiation: some boards default to off. */ - if (tp->default_port == 0) { - new_bmcr = mii_reg0 | BMCR_ANENABLE; - if (new_bmcr != mii_reg0) - new_bmcr |= BMCR_ANRESTART; - } - /* ...or disable nway, if forcing media */ - else - new_bmcr = mii_reg0 & ~BMCR_ANENABLE; - - if (new_bmcr != mii_reg0) - tulip_mdio_write(dev, phy, MII_BMCR, new_bmcr); - - if (tp->full_duplex) new_bmcr |= BMCR_FULLDPLX; - else new_bmcr &= ~BMCR_FULLDPLX; - if (tulip_media_cap[tp->default_port] & MediaIs100) - new_bmcr |= BMCR_SPEED100; - else new_bmcr &= ~BMCR_SPEED100; - - if (new_bmcr != mii_reg0) { - udelay(10); - tulip_mdio_write(dev, phy, MII_BMCR, new_bmcr); - } - } - } - tp->mii_cnt = phy_idx; - if (tp->mtable && tp->mtable->has_mii && phy_idx == 0) { - printk(KERN_INFO "tulip%d: ***WARNING***: No MII transceiver found!\n", - board_idx); - tp->phys[0] = 1; - } + /* Find the connected MII xcvrs. + Doing this in open() would allow detecting external xcvrs + later, but takes much time. */ + tulip_find_mii (dev, board_idx); } /* The Tulip-specific entries in the device structure. */ @@ -1676,7 +1634,6 @@ err_out_free_res: pci_release_regions (pdev); err_out_free_netdev: - unregister_netdev (dev); kfree (dev); return -ENODEV; }