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