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