Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / drivers / net / tulip / timer.c
1 /*
2         drivers/net/tulip/timer.c
3
4         Maintained by Valerie Henson <val_henson@linux.intel.com>
5         Copyright 2000,2001  The Linux Kernel Team
6         Written/copyright 1994-2001 by Donald Becker.
7
8         This software may be used and distributed according to the terms
9         of the GNU General Public License, incorporated herein by reference.
10
11         Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
12         for more information on this driver, or visit the project
13         Web page at http://sourceforge.net/projects/tulip/
14
15 */
16
17 #include <linux/pci.h>
18 #include "tulip.h"
19
20
21 void tulip_media_task(struct work_struct *work)
22 {
23         struct tulip_private *tp =
24                 container_of(work, struct tulip_private, media_work);
25         struct net_device *dev = tp->dev;
26         void __iomem *ioaddr = tp->base_addr;
27         u32 csr12 = ioread32(ioaddr + CSR12);
28         int next_tick = 2*HZ;
29         unsigned long flags;
30
31         if (tulip_debug > 2) {
32                 printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
33                            " %8.8x SIA %8.8x %8.8x %8.8x %8.8x.\n",
34                            dev->name, medianame[dev->if_port], ioread32(ioaddr + CSR5),
35                            ioread32(ioaddr + CSR6), csr12, ioread32(ioaddr + CSR13),
36                            ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
37         }
38         switch (tp->chip_id) {
39         case DC21140:
40         case DC21142:
41         case MX98713:
42         case COMPEX9881:
43         case DM910X:
44         default: {
45                 struct medialeaf *mleaf;
46                 unsigned char *p;
47                 if (tp->mtable == NULL) {       /* No EEPROM info, use generic code. */
48                         /* Not much that can be done.
49                            Assume this a generic MII or SYM transceiver. */
50                         next_tick = 60*HZ;
51                         if (tulip_debug > 2)
52                                 printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "
53                                            "CSR12 0x%2.2x.\n",
54                                            dev->name, ioread32(ioaddr + CSR6), csr12 & 0xff);
55                         break;
56                 }
57                 mleaf = &tp->mtable->mleaf[tp->cur_index];
58                 p = mleaf->leafdata;
59                 switch (mleaf->type) {
60                 case 0: case 4: {
61                         /* Type 0 serial or 4 SYM transceiver.  Check the link beat bit. */
62                         int offset = mleaf->type == 4 ? 5 : 2;
63                         s8 bitnum = p[offset];
64                         if (p[offset+1] & 0x80) {
65                                 if (tulip_debug > 1)
66                                         printk(KERN_DEBUG"%s: Transceiver monitor tick "
67                                                    "CSR12=%#2.2x, no media sense.\n",
68                                                    dev->name, csr12);
69                                 if (mleaf->type == 4) {
70                                         if (mleaf->media == 3 && (csr12 & 0x02))
71                                                 goto select_next_media;
72                                 }
73                                 break;
74                         }
75                         if (tulip_debug > 2)
76                                 printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x"
77                                            " bit %d is %d, expecting %d.\n",
78                                            dev->name, csr12, (bitnum >> 1) & 7,
79                                            (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
80                                            (bitnum >= 0));
81                         /* Check that the specified bit has the proper value. */
82                         if ((bitnum < 0) !=
83                                 ((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
84                                 if (tulip_debug > 2)
85                                         printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,
86                                                medianame[mleaf->media & MEDIA_MASK]);
87                                 if ((p[2] & 0x61) == 0x01)      /* Bogus Znyx board. */
88                                         goto actually_mii;
89                                 netif_carrier_on(dev);
90                                 break;
91                         }
92                         netif_carrier_off(dev);
93                         if (tp->medialock)
94                                 break;
95           select_next_media:
96                         if (--tp->cur_index < 0) {
97                                 /* We start again, but should instead look for default. */
98                                 tp->cur_index = tp->mtable->leafcount - 1;
99                         }
100                         dev->if_port = tp->mtable->mleaf[tp->cur_index].media;
101                         if (tulip_media_cap[dev->if_port] & MediaIsFD)
102                                 goto select_next_media; /* Skip FD entries. */
103                         if (tulip_debug > 1)
104                                 printk(KERN_DEBUG "%s: No link beat on media %s,"
105                                        " trying transceiver type %s.\n",
106                                        dev->name, medianame[mleaf->media & MEDIA_MASK],
107                                        medianame[tp->mtable->mleaf[tp->cur_index].media]);
108                         tulip_select_media(dev, 0);
109                         /* Restart the transmit process. */
110                         tulip_restart_rxtx(tp);
111                         next_tick = (24*HZ)/10;
112                         break;
113                 }
114                 case 1:  case 3:                /* 21140, 21142 MII */
115                 actually_mii:
116                         if (tulip_check_duplex(dev) < 0) {
117                                 netif_carrier_off(dev);
118                                 next_tick = 3*HZ;
119                         } else {
120                                 netif_carrier_on(dev);
121                                 next_tick = 60*HZ;
122                         }
123                         break;
124                 case 2:                                 /* 21142 serial block has no link beat. */
125                 default:
126                         break;
127                 }
128         }
129         break;
130         }
131
132
133         spin_lock_irqsave(&tp->lock, flags);
134         if (tp->timeout_recovery) {
135                 tulip_tx_timeout_complete(tp, ioaddr);
136                 tp->timeout_recovery = 0;
137         }
138         spin_unlock_irqrestore(&tp->lock, flags);
139
140         /* mod_timer synchronizes us with potential add_timer calls
141          * from interrupts.
142          */
143         mod_timer(&tp->timer, RUN_AT(next_tick));
144 }
145
146
147 void mxic_timer(unsigned long data)
148 {
149         struct net_device *dev = (struct net_device *)data;
150         struct tulip_private *tp = netdev_priv(dev);
151         void __iomem *ioaddr = tp->base_addr;
152         int next_tick = 60*HZ;
153
154         if (tulip_debug > 3) {
155                 printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,
156                            ioread32(ioaddr + CSR12));
157         }
158         if (next_tick) {
159                 mod_timer(&tp->timer, RUN_AT(next_tick));
160         }
161 }
162
163
164 void comet_timer(unsigned long data)
165 {
166         struct net_device *dev = (struct net_device *)data;
167         struct tulip_private *tp = netdev_priv(dev);
168         int next_tick = 60*HZ;
169
170         if (tulip_debug > 1)
171                 printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability "
172                            "%4.4x.\n",
173                            dev->name,
174                            tulip_mdio_read(dev, tp->phys[0], 1),
175                            tulip_mdio_read(dev, tp->phys[0], 5));
176         /* mod_timer synchronizes us with potential add_timer calls
177          * from interrupts.
178          */
179         if (tulip_check_duplex(dev) < 0)
180                 { netif_carrier_off(dev); }
181         else
182                 { netif_carrier_on(dev); }
183         mod_timer(&tp->timer, RUN_AT(next_tick));
184 }
185