diff -rc linux.orig/drivers/net/tulip/21142.c linux/drivers/net/tulip/21142.c *** linux.orig/drivers/net/tulip/21142.c Tue Nov 7 20:08:09 2000 --- linux/drivers/net/tulip/21142.c Sun Jan 7 18:29:03 2001 *************** *** 99,106 **** { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; ! int csr14 = ((tp->to_advertise & 0x0780) << 9) | ! ((tp->to_advertise&0x0020)<<1) | 0xffbf; DPRINTK("ENTER\n"); --- 99,106 ---- { struct tulip_private *tp = (struct tulip_private *)dev->priv; long ioaddr = dev->base_addr; ! int csr14 = ((tp->sym_advertise & 0x0780) << 9) | ! ((tp->sym_advertise&0x0020)<<1) | 0xffbf; DPRINTK("ENTER\n"); *************** *** 114,122 **** udelay(100); outl(csr14, ioaddr + CSR14); if (tp->chip_id == PNIC2) ! tp->csr6 = 0x01a80000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); else ! tp->csr6 = 0x82420000 | (tp->to_advertise & 0x0040 ? 0x0200 : 0); tulip_outl_csr(tp, tp->csr6, CSR6); if (tp->mtable && tp->mtable->csr15dir) { outl(tp->mtable->csr15dir, ioaddr + CSR15); --- 114,122 ---- udelay(100); outl(csr14, ioaddr + CSR14); if (tp->chip_id == PNIC2) ! tp->csr6 = 0x01a80000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); else ! tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0); tulip_outl_csr(tp, tp->csr6, CSR6); if (tp->mtable && tp->mtable->csr15dir) { outl(tp->mtable->csr15dir, ioaddr + CSR15); *************** *** 140,146 **** /* If NWay finished and we have a negotiated partner capability. */ if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { int setup_done = 0; ! int negotiated = tp->to_advertise & (csr12 >> 16); tp->lpar = csr12 >> 16; tp->nwayset = 1; if (negotiated & 0x0100) dev->if_port = 5; --- 140,146 ---- /* If NWay finished and we have a negotiated partner capability. */ if (tp->nway && !tp->nwayset && (csr12 & 0x7000) == 0x5000) { int setup_done = 0; ! int negotiated = tp->sym_advertise & (csr12 >> 16); tp->lpar = csr12 >> 16; tp->nwayset = 1; if (negotiated & 0x0100) dev->if_port = 5; *************** *** 149,155 **** else if (negotiated & 0x0020) dev->if_port = 0; else { tp->nwayset = 0; ! if ((csr12 & 2) == 0 && (tp->to_advertise & 0x0180)) dev->if_port = 3; } tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0; --- 149,155 ---- else if (negotiated & 0x0020) dev->if_port = 0; else { tp->nwayset = 0; ! if ((csr12 & 2) == 0 && (tp->sym_advertise & 0x0180)) dev->if_port = 3; } tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0; *************** *** 158,164 **** if (tp->nwayset) printk(KERN_INFO "%s: Switching to %s based on link " "negotiation %4.4x & %4.4x = %4.4x.\n", ! dev->name, medianame[dev->if_port], tp->to_advertise, tp->lpar, negotiated); else printk(KERN_INFO "%s: Autonegotiation failed, using %s," --- 158,164 ---- if (tp->nwayset) printk(KERN_INFO "%s: Switching to %s based on link " "negotiation %4.4x & %4.4x = %4.4x.\n", ! dev->name, medianame[dev->if_port], tp->sym_advertise, tp->lpar, negotiated); else printk(KERN_INFO "%s: Autonegotiation failed, using %s," diff -rc linux.orig/drivers/net/tulip/eeprom.c linux/drivers/net/tulip/eeprom.c *** linux.orig/drivers/net/tulip/eeprom.c Sat Dec 30 20:23:14 2000 --- linux/drivers/net/tulip/eeprom.c Sun Jan 7 17:38:45 2001 *************** *** 207,214 **** --- 207,221 ---- p += (p[0] & 0x3f) + 1; continue; } else if (p[1] & 1) { + int gpr_len, reset_len; + mtable->has_mii = 1; leaf->media = 11; + #if 0 + gpr_len=p[3]*2; + reset_len=p[4+gpr_len]*2; + new_advertise |= get_u16(&p[7+gpr_len+reset_len]); + #endif } else { mtable->has_nonmii = 1; leaf->media = p[2] & 0x0f; *************** *** 252,258 **** block_name[leaf->type], leaf->type); } if (new_advertise) ! tp->to_advertise = new_advertise; } } /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/ --- 259,265 ---- block_name[leaf->type], leaf->type); } if (new_advertise) ! tp->sym_advertise = new_advertise; } } /* Reading a serial EEPROM is a "bit" grungy, but we work our way through:->.*/ diff -rc linux.orig/drivers/net/tulip/media.c linux/drivers/net/tulip/media.c *** linux.orig/drivers/net/tulip/media.c Mon Jan 1 18:54:07 2001 --- linux/drivers/net/tulip/media.c Sun Jan 7 17:51:16 2001 *************** *** 227,233 **** int phy_num = p[0]; int init_length = p[1]; u16 *misc_info; - u16 to_advertise; dev->if_port = 11; new_csr6 = 0x020E0000; --- 227,232 ---- *************** *** 254,266 **** for (i = 0; i < init_length; i++) outl(init_sequence[i], ioaddr + CSR12); } ! to_advertise = (get_u16(&misc_info[1]) & tp->to_advertise) | 1; ! tp->advertising[phy_num] = to_advertise; ! if (tulip_debug > 1) ! printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d (%d).\n", ! dev->name, to_advertise, phy_num, tp->phys[phy_num]); ! /* Bogus: put in by a committee? */ ! tulip_mdio_write(dev, tp->phys[phy_num], 4, to_advertise); break; } case 5: case 6: { --- 253,269 ---- for (i = 0; i < init_length; i++) outl(init_sequence[i], ioaddr + CSR12); } ! tp->advertising[phy_num] = get_u16(&misc_info[1]) | 1;; ! if(startup < 2) { ! if (tp->mii_advertise == 0) ! tp->mii_advertise = tp->advertising[phy_num]; ! if (tulip_debug > 1) ! printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d (%d).\n", ! dev->name, tp->mii_advertise, phy_num, ! tp->phys[phy_num]); ! /* Bogus: put in by a committee? */ ! tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise); ! } break; } case 5: case 6: { diff -rc linux.orig/drivers/net/tulip/tulip.h linux/drivers/net/tulip/tulip.h *** linux.orig/drivers/net/tulip/tulip.h Sat Dec 30 20:23:14 2000 --- linux/drivers/net/tulip/tulip.h Sun Jan 7 17:41:47 2001 *************** *** 22,28 **** /* undefine, or define to various debugging levels (>4 == obscene levels) */ ! #undef TULIP_DEBUG #ifdef TULIP_DEBUG --- 22,28 ---- /* undefine, or define to various debugging levels (>4 == obscene levels) */ ! #undef TULIP_DEBUG #ifdef TULIP_DEBUG *************** *** 353,359 **** unsigned int csr6; /* Current CSR6 control settings. */ unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ void (*link_change) (struct net_device * dev, int csr5); ! u16 to_advertise; /* NWay capabilities advertised. */ u16 lpar; /* 21143 Link partner ability. */ u16 advertising[4]; signed char phys[4], mii_cnt; /* MII device addresses. */ --- 353,359 ---- unsigned int csr6; /* Current CSR6 control settings. */ unsigned char eeprom[EEPROM_SIZE]; /* Serial EEPROM contents. */ void (*link_change) (struct net_device * dev, int csr5); ! u16 sym_advertise, mii_advertise; /* NWay capabilities advertised. */ u16 lpar; /* 21143 Link partner ability. */ u16 advertising[4]; signed char phys[4], mii_cnt; /* MII device addresses. */ diff -rc linux.orig/drivers/net/tulip/tulip_core.c linux/drivers/net/tulip/tulip_core.c *** linux.orig/drivers/net/tulip/tulip_core.c Thu Jan 4 21:50:17 2001 --- linux/drivers/net/tulip/tulip_core.c Sun Jan 7 20:57:01 2001 *************** *** 329,335 **** if (tp->mii_cnt) { tulip_select_media(dev, 1); if (tulip_debug > 1) ! printk(KERN_INFO "%s: Using MII transceiver %d, status " "%4.4x.\n", dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1)); tulip_outl_csr(tp, csr6_mask_defstate, CSR6); --- 329,335 ---- if (tp->mii_cnt) { tulip_select_media(dev, 1); if (tulip_debug > 1) ! printk(KERN_INFO "%s: Using mII transceiver %d, status " "%4.4x.\n", dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1)); tulip_outl_csr(tp, csr6_mask_defstate, CSR6); *************** *** 794,800 **** return -EPERM; if (data[0] == 32 && (tp->flags & HAS_NWAY)) { if (data[1] == 5) ! tp->to_advertise = data[2]; } else { spin_lock_irqsave (&tp->lock, flags); tulip_mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]); --- 794,800 ---- return -EPERM; if (data[0] == 32 && (tp->flags & HAS_NWAY)) { if (data[1] == 5) ! tp->sym_advertise = data[2]; } else { spin_lock_irqsave (&tp->lock, flags); tulip_mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]); *************** *** 1304,1314 **** if (tulip_media_cap[tp->default_port] & MediaIsMII) { u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 }; ! tp->to_advertise = media2advert[tp->default_port - 9]; ! } else if (tp->flags & HAS_8023X) ! tp->to_advertise = 0x05e1; ! else ! tp->to_advertise = 0x01e1; /* This is logically part of _init_one(), but too complex to write inline. */ if (tp->flags & HAS_MEDIA_TABLE) { --- 1304,1312 ---- if (tulip_media_cap[tp->default_port] & MediaIsMII) { u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 }; ! tp->mii_advertise = media2advert[tp->default_port - 9]; ! tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */ ! } /* This is logically part of _init_one(), but too complex to write inline. */ if (tp->flags & HAS_MEDIA_TABLE) { *************** *** 1340,1360 **** ((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); ! int reg4 = ((mii_status>>6) & tp->to_advertise) | 1; ! tp->phys[phy_idx] = phy; ! tp->advertising[phy_idx++] = reg4; printk(KERN_INFO "%s: MII transceiver #%d " "config %4.4x status %4.4x advertising %4.4x.\n", dev->name, phy, mii_reg0, mii_status, mii_advert); /* Fixup for DLink with miswired PHY. */ ! if (mii_advert != reg4) { printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d," " previously advertising %4.4x.\n", ! dev->name, reg4, phy, mii_advert); ! printk(KERN_DEBUG "%s: Advertising %4.4x (to advertise" ! " is %4.4x).\n", ! dev->name, reg4, tp->to_advertise); ! tulip_mdio_write(dev, phy, 4, reg4); } /* Enable autonegotiation: some boards default to off. */ tulip_mdio_write(dev, phy, 0, mii_reg0 | --- 1338,1362 ---- ((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); ! int to_advert; ! ! 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 "%s: MII transceiver #%d " "config %4.4x status %4.4x advertising %4.4x.\n", dev->name, phy, mii_reg0, mii_status, mii_advert); /* Fixup for DLink with miswired PHY. */ ! if (mii_advert != to_advert) { printk(KERN_DEBUG "%s: Advertising %4.4x on PHY %d," " previously advertising %4.4x.\n", ! dev->name, to_advert, phy, mii_advert); ! tulip_mdio_write(dev, phy, 4, to_advert); } /* Enable autonegotiation: some boards default to off. */ tulip_mdio_write(dev, phy, 0, mii_reg0 | *************** *** 1388,1394 **** /* Reset the xcvr interface and turn on heartbeat. */ switch (chip_idx) { case DC21041: ! tp->to_advertise = 0x0061; outl(0x00000000, ioaddr + CSR13); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */ --- 1390,1397 ---- /* Reset the xcvr interface and turn on heartbeat. */ switch (chip_idx) { case DC21041: ! if (tp->sym_advertise == 0) ! tp->sym_advertise = 0x0061; outl(0x00000000, ioaddr + CSR13); outl(0xFFFFFFFF, ioaddr + CSR14); outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */