Back to home page

OSCL-LXR

 
 

    


0001 /*
0002     drivers/net/ethernet/dec/tulip/pnic2.c
0003 
0004     Copyright 2000,2001  The Linux Kernel Team
0005     Written/copyright 1994-2001 by Donald Becker.
0006         Modified to hep support PNIC_II by Kevin B. Hendricks
0007 
0008     This software may be used and distributed according to the terms
0009     of the GNU General Public License, incorporated herein by reference.
0010 
0011         Please submit bugs to http://bugzilla.kernel.org/ .
0012 */
0013 
0014 
0015 /* Understanding the PNIC_II - everything is this file is based
0016  * on the PNIC_II_PDF datasheet which is sorely lacking in detail
0017  *
0018  * As I understand things, here are the registers and bits that
0019  * explain the masks and constants used in this file that are
0020  * either different from the 21142/3 or important for basic operation.
0021  *
0022  *
0023  * CSR 6  (mask = 0xfe3bd1fd of bits not to change)
0024  * -----
0025  * Bit 24    - SCR
0026  * Bit 23    - PCS
0027  * Bit 22    - TTM (Trasmit Threshold Mode)
0028  * Bit 18    - Port Select
0029  * Bit 13    - Start - 1, Stop - 0 Transmissions
0030  * Bit 11:10 - Loop Back Operation Mode
0031  * Bit 9     - Full Duplex mode (Advertise 10BaseT-FD is CSR14<7> is set)
0032  * Bit 1     - Start - 1, Stop - 0 Receive
0033  *
0034  *
0035  * CSR 14  (mask = 0xfff0ee39 of bits not to change)
0036  * ------
0037  * Bit 19    - PAUSE-Pause
0038  * Bit 18    - Advertise T4
0039  * Bit 17    - Advertise 100baseTx-FD
0040  * Bit 16    - Advertise 100baseTx-HD
0041  * Bit 12    - LTE - Link Test Enable
0042  * Bit 7     - ANE - Auto Negotiate Enable
0043  * Bit 6     - HDE - Advertise 10baseT-HD
0044  * Bit 2     - Reset to Power down - kept as 1 for normal operation
0045  * Bit 1     -  Loop Back enable for 10baseT MCC
0046  *
0047  *
0048  * CSR 12
0049  * ------
0050  * Bit 25    - Partner can do T4
0051  * Bit 24    - Partner can do 100baseTx-FD
0052  * Bit 23    - Partner can do 100baseTx-HD
0053  * Bit 22    - Partner can do 10baseT-FD
0054  * Bit 21    - Partner can do 10baseT-HD
0055  * Bit 15    - LPN is 1 if all above bits are valid other wise 0
0056  * Bit 14:12 - autonegotiation state (write 001 to start autonegotiate)
0057  * Bit 3     - Autopolarity state
0058  * Bit 2     - LS10B - link state of 10baseT 0 - good, 1 - failed
0059  * Bit 1     - LS100B - link state of 100baseT 0 - good, 1 - failed
0060  *
0061  *
0062  * Data Port Selection Info
0063  *-------------------------
0064  *
0065  * CSR14<7>   CSR6<18>    CSR6<22>    CSR6<23>    CSR6<24>   MODE/PORT
0066  *   1           0           0 (X)       0 (X)       1        NWAY
0067  *   0           0           1           0 (X)       0        10baseT
0068  *   0           1           0           1           1 (X)    100baseT
0069  *
0070  *
0071  */
0072 
0073 
0074 
0075 #include "tulip.h"
0076 #include <linux/delay.h>
0077 
0078 
0079 void pnic2_timer(struct timer_list *t)
0080 {
0081     struct tulip_private *tp = from_timer(tp, t, timer);
0082     struct net_device *dev = tp->dev;
0083     void __iomem *ioaddr = tp->base_addr;
0084     int next_tick = 60*HZ;
0085 
0086     if (tulip_debug > 3)
0087         dev_info(&dev->dev, "PNIC2 negotiation status %08x\n",
0088              ioread32(ioaddr + CSR12));
0089 
0090     if (next_tick) {
0091         mod_timer(&tp->timer, RUN_AT(next_tick));
0092     }
0093 }
0094 
0095 
0096 void pnic2_start_nway(struct net_device *dev)
0097 {
0098     struct tulip_private *tp = netdev_priv(dev);
0099     void __iomem *ioaddr = tp->base_addr;
0100         int csr14;
0101         int csr12;
0102 
0103         /* set up what to advertise during the negotiation */
0104 
0105         /* load in csr14  and mask off bits not to touch
0106          * comment at top of file explains mask value
0107          */
0108     csr14 = (ioread32(ioaddr + CSR14) & 0xfff0ee39);
0109 
0110         /* bit 17 - advetise 100baseTx-FD */
0111         if (tp->sym_advertise & 0x0100) csr14 |= 0x00020000;
0112 
0113         /* bit 16 - advertise 100baseTx-HD */
0114         if (tp->sym_advertise & 0x0080) csr14 |= 0x00010000;
0115 
0116         /* bit 6 - advertise 10baseT-HD */
0117         if (tp->sym_advertise & 0x0020) csr14 |= 0x00000040;
0118 
0119         /* Now set bit 12 Link Test Enable, Bit 7 Autonegotiation Enable
0120          * and bit 0 Don't PowerDown 10baseT
0121          */
0122         csr14 |= 0x00001184;
0123 
0124     if (tulip_debug > 1)
0125         netdev_dbg(dev, "Restarting PNIC2 autonegotiation, csr14=%08x\n",
0126                csr14);
0127 
0128         /* tell pnic2_lnk_change we are doing an nway negotiation */
0129     dev->if_port = 0;
0130     tp->nway = tp->mediasense = 1;
0131     tp->nwayset = tp->lpar = 0;
0132 
0133         /* now we have to set up csr6 for NWAY state */
0134 
0135     tp->csr6 = ioread32(ioaddr + CSR6);
0136     if (tulip_debug > 1)
0137         netdev_dbg(dev, "On Entry to Nway, csr6=%08x\n", tp->csr6);
0138 
0139         /* mask off any bits not to touch
0140          * comment at top of file explains mask value
0141          */
0142     tp->csr6 = tp->csr6 & 0xfe3bd1fd;
0143 
0144         /* don't forget that bit 9 is also used for advertising */
0145         /* advertise 10baseT-FD for the negotiation (bit 9) */
0146         if (tp->sym_advertise & 0x0040) tp->csr6 |= 0x00000200;
0147 
0148         /* set bit 24 for nway negotiation mode ...
0149          * see Data Port Selection comment at top of file
0150          * and "Stop" - reset both Transmit (bit 13) and Receive (bit 1)
0151          */
0152         tp->csr6 |= 0x01000000;
0153     iowrite32(csr14, ioaddr + CSR14);
0154     iowrite32(tp->csr6, ioaddr + CSR6);
0155         udelay(100);
0156 
0157         /* all set up so now force the negotiation to begin */
0158 
0159         /* read in current values and mask off all but the
0160      * Autonegotiation bits 14:12.  Writing a 001 to those bits
0161          * should start the autonegotiation
0162          */
0163         csr12 = (ioread32(ioaddr + CSR12) & 0xffff8fff);
0164         csr12 |= 0x1000;
0165     iowrite32(csr12, ioaddr + CSR12);
0166 }
0167 
0168 
0169 
0170 void pnic2_lnk_change(struct net_device *dev, int csr5)
0171 {
0172     struct tulip_private *tp = netdev_priv(dev);
0173     void __iomem *ioaddr = tp->base_addr;
0174         int csr14;
0175 
0176         /* read the staus register to find out what is up */
0177     int csr12 = ioread32(ioaddr + CSR12);
0178 
0179     if (tulip_debug > 1)
0180         dev_info(&dev->dev,
0181              "PNIC2 link status interrupt %08x,  CSR5 %x, %08x\n",
0182              csr12, csr5, ioread32(ioaddr + CSR14));
0183 
0184     /* If NWay finished and we have a negotiated partner capability.
0185          * check bits 14:12 for bit pattern 101 - all is good
0186          */
0187     if (tp->nway  &&  !tp->nwayset) {
0188 
0189             /* we did an auto negotiation */
0190 
0191                 if ((csr12 & 0x7000) == 0x5000) {
0192 
0193                    /* negotiation ended successfully */
0194 
0195                    /* get the link partners reply and mask out all but
0196                         * bits 24-21 which show the partners capabilities
0197                         * and match those to what we advertised
0198                         *
0199                         * then begin to interpret the results of the negotiation.
0200                         * Always go in this order : (we are ignoring T4 for now)
0201                         *     100baseTx-FD, 100baseTx-HD, 10baseT-FD, 10baseT-HD
0202                         */
0203 
0204                 int negotiated = ((csr12 >> 16) & 0x01E0) & tp->sym_advertise;
0205                 tp->lpar = (csr12 >> 16);
0206                 tp->nwayset = 1;
0207 
0208                         if (negotiated & 0x0100)        dev->if_port = 5;
0209                 else if (negotiated & 0x0080)   dev->if_port = 3;
0210                 else if (negotiated & 0x0040)   dev->if_port = 4;
0211             else if (negotiated & 0x0020)   dev->if_port = 0;
0212             else {
0213                  if (tulip_debug > 1)
0214                      dev_info(&dev->dev,
0215                           "funny autonegotiate result csr12 %08x advertising %04x\n",
0216                           csr12, tp->sym_advertise);
0217                  tp->nwayset = 0;
0218                  /* so check  if 100baseTx link state is okay */
0219                  if ((csr12 & 2) == 0  &&  (tp->sym_advertise & 0x0180))
0220                    dev->if_port = 3;
0221             }
0222 
0223             /* now record the duplex that was negotiated */
0224             tp->full_duplex = 0;
0225             if ((dev->if_port == 4) || (dev->if_port == 5))
0226                    tp->full_duplex = 1;
0227 
0228             if (tulip_debug > 1) {
0229                    if (tp->nwayset)
0230                        dev_info(&dev->dev,
0231                         "Switching to %s based on link negotiation %04x & %04x = %04x\n",
0232                         medianame[dev->if_port],
0233                         tp->sym_advertise, tp->lpar,
0234                         negotiated);
0235             }
0236 
0237                         /* remember to turn off bit 7 - autonegotiate
0238                          * enable so we can properly end nway mode and
0239                          * set duplex (ie. use csr6<9> again)
0240                          */
0241                     csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
0242                         iowrite32(csr14,ioaddr + CSR14);
0243 
0244 
0245                         /* now set the data port and operating mode
0246              * (see the Data Port Selection comments at
0247              * the top of the file
0248              */
0249 
0250             /* get current csr6 and mask off bits not to touch */
0251             /* see comment at top of file */
0252 
0253             tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
0254 
0255             /* so if using if_port 3 or 5 then select the 100baseT
0256              * port else select the 10baseT port.
0257              * See the Data Port Selection table at the top
0258              * of the file which was taken from the PNIC_II.PDF
0259              * datasheet
0260              */
0261             if (dev->if_port & 1) tp->csr6 |= 0x01840000;
0262             else tp->csr6 |= 0x00400000;
0263 
0264             /* now set the full duplex bit appropriately */
0265             if (tp->full_duplex) tp->csr6 |= 0x00000200;
0266 
0267             iowrite32(1, ioaddr + CSR13);
0268 
0269             if (tulip_debug > 2)
0270                 netdev_dbg(dev, "Setting CSR6 %08x/%x CSR12 %08x\n",
0271                        tp->csr6,
0272                        ioread32(ioaddr + CSR6),
0273                        ioread32(ioaddr + CSR12));
0274 
0275             /* now the following actually writes out the
0276              * new csr6 values
0277              */
0278             tulip_start_rxtx(tp);
0279 
0280                         return;
0281 
0282             } else {
0283                     dev_info(&dev->dev,
0284                  "Autonegotiation failed, using %s, link beat status %04x\n",
0285                  medianame[dev->if_port], csr12);
0286 
0287                         /* remember to turn off bit 7 - autonegotiate
0288                          * enable so we don't forget
0289                          */
0290                     csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
0291                         iowrite32(csr14,ioaddr + CSR14);
0292 
0293                         /* what should we do when autonegotiate fails?
0294                          * should we try again or default to baseline
0295                          * case.  I just don't know.
0296                          *
0297                          * for now default to some baseline case
0298                          */
0299 
0300                      dev->if_port = 0;
0301                          tp->nway = 0;
0302                          tp->nwayset = 1;
0303 
0304                          /* set to 10baseTx-HD - see Data Port Selection
0305                           * comment given at the top of the file
0306                           */
0307                      tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
0308                          tp->csr6 |= 0x00400000;
0309 
0310                      tulip_restart_rxtx(tp);
0311 
0312                          return;
0313 
0314         }
0315     }
0316 
0317     if ((tp->nwayset  &&  (csr5 & 0x08000000) &&
0318          (dev->if_port == 3  ||  dev->if_port == 5) &&
0319          (csr12 & 2) == 2) || (tp->nway && (csr5 & (TPLnkFail)))) {
0320 
0321         /* Link blew? Maybe restart NWay. */
0322 
0323         if (tulip_debug > 2)
0324             netdev_dbg(dev, "Ugh! Link blew?\n");
0325 
0326         del_timer_sync(&tp->timer);
0327         pnic2_start_nway(dev);
0328         tp->timer.expires = RUN_AT(3*HZ);
0329         add_timer(&tp->timer);
0330 
0331                 return;
0332     }
0333 
0334 
0335         if (dev->if_port == 3  ||  dev->if_port == 5) {
0336 
0337             /* we are at 100mb and a potential link change occurred */
0338 
0339         if (tulip_debug > 1)
0340             dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
0341                  medianame[dev->if_port],
0342                  (csr12 & 2) ? "failed" : "good");
0343 
0344                 /* check 100 link beat */
0345 
0346                 tp->nway = 0;
0347                 tp->nwayset = 1;
0348 
0349                 /* if failed then try doing an nway to get in sync */
0350         if ((csr12 & 2)  &&  ! tp->medialock) {
0351             del_timer_sync(&tp->timer);
0352             pnic2_start_nway(dev);
0353             tp->timer.expires = RUN_AT(3*HZ);
0354             add_timer(&tp->timer);
0355                 }
0356 
0357                 return;
0358         }
0359 
0360     if (dev->if_port == 0  ||  dev->if_port == 4) {
0361 
0362             /* we are at 10mb and a potential link change occurred */
0363 
0364         if (tulip_debug > 1)
0365             dev_info(&dev->dev, "PNIC2 %s link beat %s\n",
0366                  medianame[dev->if_port],
0367                  (csr12 & 4) ? "failed" : "good");
0368 
0369 
0370                 tp->nway = 0;
0371                 tp->nwayset = 1;
0372 
0373                 /* if failed, try doing an nway to get in sync */
0374         if ((csr12 & 4)  &&  ! tp->medialock) {
0375             del_timer_sync(&tp->timer);
0376             pnic2_start_nway(dev);
0377             tp->timer.expires = RUN_AT(3*HZ);
0378             add_timer(&tp->timer);
0379                 }
0380 
0381                 return;
0382         }
0383 
0384 
0385     if (tulip_debug > 1)
0386         dev_info(&dev->dev, "PNIC2 Link Change Default?\n");
0387 
0388         /* if all else fails default to trying 10baseT-HD */
0389     dev->if_port = 0;
0390 
0391         /* make sure autonegotiate enable is off */
0392     csr14 = (ioread32(ioaddr + CSR14) & 0xffffff7f);
0393         iowrite32(csr14,ioaddr + CSR14);
0394 
0395         /* set to 10baseTx-HD - see Data Port Selection
0396          * comment given at the top of the file
0397          */
0398     tp->csr6 = (ioread32(ioaddr + CSR6) & 0xfe3bd1fd);
0399         tp->csr6 |= 0x00400000;
0400 
0401     tulip_restart_rxtx(tp);
0402 }
0403