Back to home page

OSCL-LXR

 
 

    


0001 /*
0002     drivers/net/ethernet/dec/tulip/21142.c
0003 
0004     Copyright 2000,2001  The Linux Kernel Team
0005     Written/copyright 1994-2001 by Donald Becker.
0006 
0007     This software may be used and distributed according to the terms
0008     of the GNU General Public License, incorporated herein by reference.
0009 
0010     DC21143 manual "21143 PCI/CardBus 10/100Mb/s Ethernet LAN Controller
0011     Hardware Reference Manual" is currently available at :
0012     http://developer.intel.com/design/network/manuals/278074.htm
0013 
0014     Please submit bugs to http://bugzilla.kernel.org/ .
0015 */
0016 
0017 #include <linux/delay.h>
0018 #include "tulip.h"
0019 
0020 
0021 static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
0022 u16 t21142_csr14[] =        { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
0023 static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
0024 
0025 
0026 /* Handle the 21143 uniquely: do autoselect with NWay, not the EEPROM list
0027    of available transceivers.  */
0028 void t21142_media_task(struct work_struct *work)
0029 {
0030     struct tulip_private *tp =
0031         container_of(work, struct tulip_private, media_work);
0032     struct net_device *dev = tp->dev;
0033     void __iomem *ioaddr = tp->base_addr;
0034     int csr12 = ioread32(ioaddr + CSR12);
0035     int next_tick = 60*HZ;
0036     int new_csr6 = 0;
0037     int csr14 = ioread32(ioaddr + CSR14);
0038 
0039     /* CSR12[LS10,LS100] are not reliable during autonegotiation */
0040     if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
0041         csr12 |= 6;
0042     if (tulip_debug > 2)
0043         dev_info(&dev->dev, "21143 negotiation status %08x, %s\n",
0044              csr12, medianame[dev->if_port]);
0045     if (tulip_media_cap[dev->if_port] & MediaIsMII) {
0046         if (tulip_check_duplex(dev) < 0) {
0047             netif_carrier_off(dev);
0048             next_tick = 3*HZ;
0049         } else {
0050             netif_carrier_on(dev);
0051             next_tick = 60*HZ;
0052         }
0053     } else if (tp->nwayset) {
0054         /* Don't screw up a negotiated session! */
0055         if (tulip_debug > 1)
0056             dev_info(&dev->dev,
0057                  "Using NWay-set %s media, csr12 %08x\n",
0058                  medianame[dev->if_port], csr12);
0059     } else if (tp->medialock) {
0060             ;
0061     } else if (dev->if_port == 3) {
0062         if (csr12 & 2) {    /* No 100mbps link beat, revert to 10mbps. */
0063             if (tulip_debug > 1)
0064                 dev_info(&dev->dev,
0065                      "No 21143 100baseTx link beat, %08x, trying NWay\n",
0066                      csr12);
0067             t21142_start_nway(dev);
0068             next_tick = 3*HZ;
0069         }
0070     } else if ((csr12 & 0x7000) != 0x5000) {
0071         /* Negotiation failed.  Search media types. */
0072         if (tulip_debug > 1)
0073             dev_info(&dev->dev,
0074                  "21143 negotiation failed, status %08x\n",
0075                  csr12);
0076         if (!(csr12 & 4)) {     /* 10mbps link beat good. */
0077             new_csr6 = 0x82420000;
0078             dev->if_port = 0;
0079             iowrite32(0, ioaddr + CSR13);
0080             iowrite32(0x0003FFFF, ioaddr + CSR14);
0081             iowrite16(t21142_csr15[dev->if_port], ioaddr + CSR15);
0082             iowrite32(t21142_csr13[dev->if_port], ioaddr + CSR13);
0083         } else {
0084             /* Select 100mbps port to check for link beat. */
0085             new_csr6 = 0x83860000;
0086             dev->if_port = 3;
0087             iowrite32(0, ioaddr + CSR13);
0088             iowrite32(0x0003FFFF, ioaddr + CSR14);
0089             iowrite16(8, ioaddr + CSR15);
0090             iowrite32(1, ioaddr + CSR13);
0091         }
0092         if (tulip_debug > 1)
0093             dev_info(&dev->dev, "Testing new 21143 media %s\n",
0094                  medianame[dev->if_port]);
0095         if (new_csr6 != (tp->csr6 & ~0x00D5)) {
0096             tp->csr6 &= 0x00D5;
0097             tp->csr6 |= new_csr6;
0098             iowrite32(0x0301, ioaddr + CSR12);
0099             tulip_restart_rxtx(tp);
0100         }
0101         next_tick = 3*HZ;
0102     }
0103 
0104     /* mod_timer synchronizes us with potential add_timer calls
0105      * from interrupts.
0106      */
0107     mod_timer(&tp->timer, RUN_AT(next_tick));
0108 }
0109 
0110 
0111 void t21142_start_nway(struct net_device *dev)
0112 {
0113     struct tulip_private *tp = netdev_priv(dev);
0114     void __iomem *ioaddr = tp->base_addr;
0115     int csr14 = ((tp->sym_advertise & 0x0780) << 9)  |
0116         ((tp->sym_advertise & 0x0020) << 1) | 0xffbf;
0117 
0118     dev->if_port = 0;
0119     tp->nway = tp->mediasense = 1;
0120     tp->nwayset = tp->lpar = 0;
0121     if (tulip_debug > 1)
0122         netdev_dbg(dev, "Restarting 21143 autonegotiation, csr14=%08x\n",
0123                csr14);
0124     iowrite32(0x0001, ioaddr + CSR13);
0125     udelay(100);
0126     iowrite32(csr14, ioaddr + CSR14);
0127     tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? FullDuplex : 0);
0128     iowrite32(tp->csr6, ioaddr + CSR6);
0129     if (tp->mtable  &&  tp->mtable->csr15dir) {
0130         iowrite32(tp->mtable->csr15dir, ioaddr + CSR15);
0131         iowrite32(tp->mtable->csr15val, ioaddr + CSR15);
0132     } else
0133         iowrite16(0x0008, ioaddr + CSR15);
0134     iowrite32(0x1301, ioaddr + CSR12);      /* Trigger NWAY. */
0135 }
0136 
0137 
0138 
0139 void t21142_lnk_change(struct net_device *dev, int csr5)
0140 {
0141     struct tulip_private *tp = netdev_priv(dev);
0142     void __iomem *ioaddr = tp->base_addr;
0143     int csr12 = ioread32(ioaddr + CSR12);
0144     int csr14 = ioread32(ioaddr + CSR14);
0145 
0146     /* CSR12[LS10,LS100] are not reliable during autonegotiation */
0147     if ((csr14 & 0x80) && (csr12 & 0x7000) != 0x5000)
0148         csr12 |= 6;
0149     if (tulip_debug > 1)
0150         dev_info(&dev->dev,
0151              "21143 link status interrupt %08x, CSR5 %x, %08x\n",
0152              csr12, csr5, csr14);
0153 
0154     /* If NWay finished and we have a negotiated partner capability. */
0155     if (tp->nway  &&  !tp->nwayset  &&  (csr12 & 0x7000) == 0x5000) {
0156         int setup_done = 0;
0157         int negotiated = tp->sym_advertise & (csr12 >> 16);
0158         tp->lpar = csr12 >> 16;
0159         tp->nwayset = 1;
0160         /* If partner cannot negotiate, it is 10Mbps Half Duplex */
0161         if (!(csr12 & 0x8000))      dev->if_port = 0;
0162         else if (negotiated & 0x0100)   dev->if_port = 5;
0163         else if (negotiated & 0x0080)   dev->if_port = 3;
0164         else if (negotiated & 0x0040)   dev->if_port = 4;
0165         else if (negotiated & 0x0020)   dev->if_port = 0;
0166         else {
0167             tp->nwayset = 0;
0168             if ((csr12 & 2) == 0  &&  (tp->sym_advertise & 0x0180))
0169                 dev->if_port = 3;
0170         }
0171         tp->full_duplex = (tulip_media_cap[dev->if_port] & MediaAlwaysFD) ? 1:0;
0172 
0173         if (tulip_debug > 1) {
0174             if (tp->nwayset)
0175                 dev_info(&dev->dev,
0176                      "Switching to %s based on link negotiation %04x & %04x = %04x\n",
0177                      medianame[dev->if_port],
0178                      tp->sym_advertise, tp->lpar,
0179                      negotiated);
0180             else
0181                 dev_info(&dev->dev,
0182                      "Autonegotiation failed, using %s, link beat status %04x\n",
0183                      medianame[dev->if_port], csr12);
0184         }
0185 
0186         if (tp->mtable) {
0187             int i;
0188             for (i = 0; i < tp->mtable->leafcount; i++)
0189                 if (tp->mtable->mleaf[i].media == dev->if_port) {
0190                     int startup = ! ((tp->chip_id == DC21143 && (tp->revision == 48 || tp->revision == 65)));
0191                     tp->cur_index = i;
0192                     tulip_select_media(dev, startup);
0193                     setup_done = 1;
0194                     break;
0195                 }
0196         }
0197         if ( ! setup_done) {
0198             tp->csr6 = (dev->if_port & 1 ? 0x838E0000 : 0x82420000) | (tp->csr6 & 0x20ff);
0199             if (tp->full_duplex)
0200                 tp->csr6 |= 0x0200;
0201             iowrite32(1, ioaddr + CSR13);
0202         }
0203 #if 0                           /* Restart shouldn't be needed. */
0204         iowrite32(tp->csr6 | RxOn, ioaddr + CSR6);
0205         if (tulip_debug > 2)
0206             netdev_dbg(dev, " Restarting Tx and Rx, CSR5 is %08x\n",
0207                    ioread32(ioaddr + CSR5));
0208 #endif
0209         tulip_start_rxtx(tp);
0210         if (tulip_debug > 2)
0211             netdev_dbg(dev, " Setting CSR6 %08x/%x CSR12 %08x\n",
0212                    tp->csr6, ioread32(ioaddr + CSR6),
0213                    ioread32(ioaddr + CSR12));
0214     } else if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
0215             (dev->if_port == 3  ||  dev->if_port == 5) &&
0216             (csr12 & 2) == 2) ||
0217            (tp->nway && (csr5 & (TPLnkFail)))) {
0218         /* Link blew? Maybe restart NWay. */
0219         del_timer_sync(&tp->timer);
0220         t21142_start_nway(dev);
0221         tp->timer.expires = RUN_AT(3*HZ);
0222         add_timer(&tp->timer);
0223     } else if (dev->if_port == 3  ||  dev->if_port == 5) {
0224         if (tulip_debug > 1)
0225             dev_info(&dev->dev, "21143 %s link beat %s\n",
0226                  medianame[dev->if_port],
0227                  (csr12 & 2) ? "failed" : "good");
0228         if ((csr12 & 2)  &&  ! tp->medialock) {
0229             del_timer_sync(&tp->timer);
0230             t21142_start_nway(dev);
0231             tp->timer.expires = RUN_AT(3*HZ);
0232             add_timer(&tp->timer);
0233         } else if (dev->if_port == 5)
0234             iowrite32(csr14 & ~0x080, ioaddr + CSR14);
0235     } else if (dev->if_port == 0  ||  dev->if_port == 4) {
0236         if ((csr12 & 4) == 0)
0237             dev_info(&dev->dev, "21143 10baseT link beat good\n");
0238     } else if (!(csr12 & 4)) {      /* 10mbps link beat good. */
0239         if (tulip_debug)
0240             dev_info(&dev->dev, "21143 10mbps sensed media\n");
0241         dev->if_port = 0;
0242     } else if (tp->nwayset) {
0243         if (tulip_debug)
0244             dev_info(&dev->dev, "21143 using NWay-set %s, csr6 %08x\n",
0245                  medianame[dev->if_port], tp->csr6);
0246     } else {        /* 100mbps link beat good. */
0247         if (tulip_debug)
0248             dev_info(&dev->dev, "21143 100baseTx sensed media\n");
0249         dev->if_port = 3;
0250         tp->csr6 = 0x838E0000 | (tp->csr6 & 0x20ff);
0251         iowrite32(0x0003FF7F, ioaddr + CSR14);
0252         iowrite32(0x0301, ioaddr + CSR12);
0253         tulip_restart_rxtx(tp);
0254     }
0255 }
0256 
0257