ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / net / tulip / timer.c
1 /*
2         drivers/net/tulip/timer.c
3
4         Maintained by Jeff Garzik <jgarzik@pobox.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 "tulip.h"
18
19
20 void tulip_timer(unsigned long data)
21 {
22         struct net_device *dev = (struct net_device *)data;
23         struct tulip_private *tp = netdev_priv(dev);
24         long ioaddr = dev->base_addr;
25         u32 csr12 = inl(ioaddr + CSR12);
26         int next_tick = 2*HZ;
27
28         if (tulip_debug > 2) {
29                 printk(KERN_DEBUG "%s: Media selection tick, %s, status %8.8x mode"
30                            " %8.8x SIA %8.8x %8.8x %8.8x %8.8x.\n",
31                            dev->name, medianame[dev->if_port], inl(ioaddr + CSR5),
32                            inl(ioaddr + CSR6), csr12, inl(ioaddr + CSR13),
33                            inl(ioaddr + CSR14), inl(ioaddr + CSR15));
34         }
35         switch (tp->chip_id) {
36         case DC21140:
37         case DC21142:
38         case MX98713:
39         case COMPEX9881:
40         case DM910X:
41         default: {
42                 struct medialeaf *mleaf;
43                 unsigned char *p;
44                 if (tp->mtable == NULL) {       /* No EEPROM info, use generic code. */
45                         /* Not much that can be done.
46                            Assume this a generic MII or SYM transceiver. */
47                         next_tick = 60*HZ;
48                         if (tulip_debug > 2)
49                                 printk(KERN_DEBUG "%s: network media monitor CSR6 %8.8x "
50                                            "CSR12 0x%2.2x.\n",
51                                            dev->name, inl(ioaddr + CSR6), csr12 & 0xff);
52                         break;
53                 }
54                 mleaf = &tp->mtable->mleaf[tp->cur_index];
55                 p = mleaf->leafdata;
56                 switch (mleaf->type) {
57                 case 0: case 4: {
58                         /* Type 0 serial or 4 SYM transceiver.  Check the link beat bit. */
59                         int offset = mleaf->type == 4 ? 5 : 2;
60                         s8 bitnum = p[offset];
61                         if (p[offset+1] & 0x80) {
62                                 if (tulip_debug > 1)
63                                         printk(KERN_DEBUG"%s: Transceiver monitor tick "
64                                                    "CSR12=%#2.2x, no media sense.\n",
65                                                    dev->name, csr12);
66                                 if (mleaf->type == 4) {
67                                         if (mleaf->media == 3 && (csr12 & 0x02))
68                                                 goto select_next_media;
69                                 }
70                                 break;
71                         }
72                         if (tulip_debug > 2)
73                                 printk(KERN_DEBUG "%s: Transceiver monitor tick: CSR12=%#2.2x"
74                                            " bit %d is %d, expecting %d.\n",
75                                            dev->name, csr12, (bitnum >> 1) & 7,
76                                            (csr12 & (1 << ((bitnum >> 1) & 7))) != 0,
77                                            (bitnum >= 0));
78                         /* Check that the specified bit has the proper value. */
79                         if ((bitnum < 0) !=
80                                 ((csr12 & (1 << ((bitnum >> 1) & 7))) != 0)) {
81                                 if (tulip_debug > 2)
82                                         printk(KERN_DEBUG "%s: Link beat detected for %s.\n", dev->name,
83                                                medianame[mleaf->media & MEDIA_MASK]);
84                                 if ((p[2] & 0x61) == 0x01)      /* Bogus Znyx board. */
85                                         goto actually_mii;
86                                 netif_carrier_on(dev);
87                                 break;
88                         }
89                         netif_carrier_off(dev);
90                         if (tp->medialock)
91                                 break;
92           select_next_media:
93                         if (--tp->cur_index < 0) {
94                                 /* We start again, but should instead look for default. */
95                                 tp->cur_index = tp->mtable->leafcount - 1;
96                         }
97                         dev->if_port = tp->mtable->mleaf[tp->cur_index].media;
98                         if (tulip_media_cap[dev->if_port] & MediaIsFD)
99                                 goto select_next_media; /* Skip FD entries. */
100                         if (tulip_debug > 1)
101                                 printk(KERN_DEBUG "%s: No link beat on media %s,"
102                                        " trying transceiver type %s.\n",
103                                        dev->name, medianame[mleaf->media & MEDIA_MASK],
104                                        medianame[tp->mtable->mleaf[tp->cur_index].media]);
105                         tulip_select_media(dev, 0);
106                         /* Restart the transmit process. */
107                         tulip_restart_rxtx(tp);
108                         next_tick = (24*HZ)/10;
109                         break;
110                 }
111                 case 1:  case 3:                /* 21140, 21142 MII */
112                 actually_mii:
113                         if (tulip_check_duplex(dev) < 0) {
114                                 netif_carrier_off(dev);
115                                 next_tick = 3*HZ;
116                         } else {
117                                 netif_carrier_on(dev);
118                                 next_tick = 60*HZ;
119                         }
120                         break;
121                 case 2:                                 /* 21142 serial block has no link beat. */
122                 default:
123                         break;
124                 }
125         }
126         break;
127         }
128         /* mod_timer synchronizes us with potential add_timer calls
129          * from interrupts.
130          */
131         mod_timer(&tp->timer, RUN_AT(next_tick));
132 }
133
134
135 void mxic_timer(unsigned long data)
136 {
137         struct net_device *dev = (struct net_device *)data;
138         struct tulip_private *tp = netdev_priv(dev);
139         long ioaddr = dev->base_addr;
140         int next_tick = 60*HZ;
141
142         if (tulip_debug > 3) {
143                 printk(KERN_INFO"%s: MXIC negotiation status %8.8x.\n", dev->name,
144                            inl(ioaddr + CSR12));
145         }
146         if (next_tick) {
147                 mod_timer(&tp->timer, RUN_AT(next_tick));
148         }
149 }
150
151
152 void comet_timer(unsigned long data)
153 {
154         struct net_device *dev = (struct net_device *)data;
155         struct tulip_private *tp = netdev_priv(dev);
156         int next_tick = 60*HZ;
157
158         if (tulip_debug > 1)
159                 printk(KERN_DEBUG "%s: Comet link status %4.4x partner capability "
160                            "%4.4x.\n",
161                            dev->name,
162                            tulip_mdio_read(dev, tp->phys[0], 1),
163                            tulip_mdio_read(dev, tp->phys[0], 5));
164         /* mod_timer synchronizes us with potential add_timer calls
165          * from interrupts.
166          */
167         if (tulip_check_duplex(dev) < 0)
168                 { netif_carrier_off(dev); }
169         else
170                 { netif_carrier_on(dev); }
171         mod_timer(&tp->timer, RUN_AT(next_tick));
172 }
173