xref: /NextBSD/sys/dev/vx/if_vx.c (revision 287e3b14e9552995def1802ec9c5034f4adf28ec)
1 /*-
2  * Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Herb Peyerl.
16  * 4. The name of Herb Peyerl may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  *
31  */
32 
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35 
36 /*
37  * Created from if_ep.c driver by Fred Gray (fgray@rice.edu) to support
38  * the 3c590 family.
39  */
40 
41 /*
42  *	Modified from the FreeBSD 1.1.5.1 version by:
43  *		 	Andres Vega Garcia
44  *			INRIA - Sophia Antipolis, France
45  *			avega@sophia.inria.fr
46  */
47 
48 /*
49  *  Promiscuous mode added and interrupt logic slightly changed
50  *  to reduce the number of adapter failures. Transceiver select
51  *  logic changed to use value from EEPROM. Autoconfiguration
52  *  features added.
53  *  Done by:
54  *          Serge Babkin
55  *          Chelindbank (Chelyabinsk, Russia)
56  *          babkin@hq.icb.chel.su
57  */
58 
59 
60 #include <sys/param.h>
61 #include <sys/systm.h>
62 #include <sys/sockio.h>
63 #include <sys/kernel.h>
64 #include <sys/malloc.h>
65 #include <sys/mbuf.h>
66 #include <sys/socket.h>
67 
68 #include <net/if.h>
69 #include <net/if_var.h>
70 
71 #include <net/ethernet.h>
72 #include <net/if_dl.h>
73 #include <net/if_types.h>
74 
75 #include <machine/bus.h>
76 
77 #include <sys/bus.h>
78 
79 #include <net/bpf.h>
80 
81 #include <dev/vx/if_vxreg.h>
82 #include <dev/vx/if_vxvar.h>
83 
84 #define ETHER_MAX_LEN	1518
85 #define ETHER_ADDR_LEN	6
86 #define ETHER_ALIGN 	2
87 
88 static struct connector_entry {
89 	int bit;
90 	char *name;
91 } conn_tab[VX_CONNECTORS] = {
92 
93 #define CONNECTOR_UTP	0
94 	{
95 		0x08, "utp"
96 	},
97 #define CONNECTOR_AUI	1
98 	{
99 		0x20, "aui"
100 	},
101 /* dummy */
102 	{
103 		0, "???"
104 	},
105 #define CONNECTOR_BNC	3
106 	{
107 		0x10, "bnc"
108 	},
109 #define CONNECTOR_TX	4
110 	{
111 		0x02, "tx"
112 	},
113 #define CONNECTOR_FX	5
114 	{
115 		0x04, "fx"
116 	},
117 #define CONNECTOR_MII	6
118 	{
119 		0x40, "mii"
120 	},
121 	{
122 		0, "???"
123 	}
124 };
125 
126 static void vx_txstat(struct vx_softc *);
127 static int vx_status(struct vx_softc *);
128 static void vx_init(void *);
129 static void vx_init_locked(struct vx_softc *);
130 static int vx_ioctl(struct ifnet *, u_long, caddr_t);
131 static void vx_start(struct ifnet *);
132 static void vx_start_locked(struct ifnet *);
133 static void vx_watchdog(void *);
134 static void vx_reset(struct vx_softc *);
135 static void vx_read(struct vx_softc *);
136 static struct mbuf *vx_get(struct vx_softc *, u_int);
137 static void vx_mbuf_fill(void *);
138 static void vx_mbuf_empty(struct vx_softc *);
139 static void vx_setfilter(struct vx_softc *);
140 static void vx_getlink(struct vx_softc *);
141 static void vx_setlink(struct vx_softc *);
142 
143 int
vx_attach(device_t dev)144 vx_attach(device_t dev)
145 {
146 	struct vx_softc *sc = device_get_softc(dev);
147 	struct ifnet *ifp;
148 	int i;
149 	u_char eaddr[6];
150 
151 	ifp = sc->vx_ifp = if_alloc(IFT_ETHER);
152 	if (ifp == NULL) {
153 		device_printf(dev, "can not if_alloc()\n");
154 		return 0;
155 	}
156 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
157 
158 	mtx_init(&sc->vx_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
159 	    MTX_DEF);
160 	callout_init_mtx(&sc->vx_callout, &sc->vx_mtx, 0);
161 	callout_init_mtx(&sc->vx_watchdog, &sc->vx_mtx, 0);
162 	GO_WINDOW(0);
163 	CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET);
164 	VX_BUSY_WAIT;
165 
166 	vx_getlink(sc);
167 
168 	/*
169          * Read the station address from the eeprom
170          */
171 	GO_WINDOW(0);
172 	for (i = 0; i < 3; i++) {
173 		int x;
174 
175 		if (vx_busy_eeprom(sc)) {
176 			mtx_destroy(&sc->vx_mtx);
177 			if_free(ifp);
178 			return 0;
179 		}
180 		CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND, EEPROM_CMD_RD
181 		    | (EEPROM_OEM_ADDR0 + i));
182 		if (vx_busy_eeprom(sc)) {
183 			mtx_destroy(&sc->vx_mtx);
184 			if_free(ifp);
185 			return 0;
186 		}
187 		x = CSR_READ_2(sc, VX_W0_EEPROM_DATA);
188 		eaddr[(i << 1)] = x >> 8;
189 		eaddr[(i << 1) + 1] = x;
190 	}
191 
192 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
193 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
194 	ifp->if_start = vx_start;
195 	ifp->if_ioctl = vx_ioctl;
196 	ifp->if_init = vx_init;
197 	ifp->if_softc = sc;
198 
199 	ether_ifattach(ifp, eaddr);
200 
201 	sc->vx_tx_start_thresh = 20;	/* probably a good starting point. */
202 
203 	VX_LOCK(sc);
204 	vx_stop(sc);
205 	VX_UNLOCK(sc);
206 
207 	return 1;
208 }
209 
210 /*
211  * The order in here seems important. Otherwise we may not receive
212  * interrupts. ?!
213  */
214 static void
vx_init(void * xsc)215 vx_init(void *xsc)
216 {
217 	struct vx_softc *sc = (struct vx_softc *)xsc;
218 
219 	VX_LOCK(sc);
220 	vx_init_locked(sc);
221 	VX_UNLOCK(sc);
222 }
223 
224 static void
vx_init_locked(struct vx_softc * sc)225 vx_init_locked(struct vx_softc *sc)
226 {
227 	struct ifnet *ifp = sc->vx_ifp;
228 	int i;
229 
230 	VX_LOCK_ASSERT(sc);
231 
232 	VX_BUSY_WAIT;
233 
234 	GO_WINDOW(2);
235 
236 	for (i = 0; i < 6; i++)	/* Reload the ether_addr. */
237 		CSR_WRITE_1(sc, VX_W2_ADDR_0 + i, IF_LLADDR(sc->vx_ifp)[i]);
238 
239 	CSR_WRITE_2(sc, VX_COMMAND, RX_RESET);
240 	VX_BUSY_WAIT;
241 	CSR_WRITE_2(sc, VX_COMMAND, TX_RESET);
242 	VX_BUSY_WAIT;
243 
244 	GO_WINDOW(1);		/* Window 1 is operating window */
245 	for (i = 0; i < 31; i++)
246 		CSR_READ_1(sc, VX_W1_TX_STATUS);
247 
248 	CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE |
249 	    S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
250 	CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK | S_CARD_FAILURE |
251 	    S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
252 
253 	/*
254          * Attempt to get rid of any stray interrupts that occured during
255          * configuration.  On the i386 this isn't possible because one may
256          * already be queued.  However, a single stray interrupt is
257          * unimportant.
258          */
259 	CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | 0xff);
260 
261 	vx_setfilter(sc);
262 	vx_setlink(sc);
263 
264 	CSR_WRITE_2(sc, VX_COMMAND, RX_ENABLE);
265 	CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE);
266 
267 	vx_mbuf_fill(sc);
268 
269 	/* Interface is now `running', with no output active. */
270 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
271 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
272 	callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc);
273 
274 	/* Attempt to start output, if any. */
275 	vx_start_locked(ifp);
276 }
277 
278 static void
vx_setfilter(struct vx_softc * sc)279 vx_setfilter(struct vx_softc *sc)
280 {
281 	struct ifnet *ifp = sc->vx_ifp;
282 
283 	VX_LOCK_ASSERT(sc);
284 	GO_WINDOW(1);		/* Window 1 is operating window */
285 	CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER |
286 	    FIL_INDIVIDUAL | FIL_BRDCST | FIL_MULTICAST |
287 	    ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0));
288 }
289 
290 static void
vx_getlink(struct vx_softc * sc)291 vx_getlink(struct vx_softc *sc)
292 {
293 	int n, k;
294 
295 	GO_WINDOW(3);
296 	sc->vx_connectors = CSR_READ_2(sc, VX_W3_RESET_OPT) & 0x7f;
297 	for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
298 		if (sc->vx_connectors & conn_tab[k].bit) {
299 			if (n > 0)
300 				printf("/");
301 			printf("%s", conn_tab[k].name);
302 			n++;
303 		}
304 	}
305 	if (sc->vx_connectors == 0) {
306 		printf("no connectors!\n");
307 		return;
308 	}
309 	GO_WINDOW(3);
310 	sc->vx_connector =
311 	    (CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & INTERNAL_CONNECTOR_MASK)
312 	    >> INTERNAL_CONNECTOR_BITS;
313 	if (sc->vx_connector & 0x10) {
314 		sc->vx_connector &= 0x0f;
315 		printf("[*%s*]", conn_tab[(int)sc->vx_connector].name);
316 		printf(": disable 'auto select' with DOS util!\n");
317 	} else {
318 		printf("[*%s*]\n", conn_tab[(int)sc->vx_connector].name);
319 	}
320 }
321 
322 static void
vx_setlink(struct vx_softc * sc)323 vx_setlink(struct vx_softc *sc)
324 {
325 	struct ifnet *ifp = sc->vx_ifp;
326 	int i, j, k;
327 	char *reason, *warning;
328 	static int prev_flags;
329 	static signed char prev_conn = -1;
330 
331 	VX_LOCK_ASSERT(sc);
332 	if (prev_conn == -1)
333 		prev_conn = sc->vx_connector;
334 
335 	/*
336          * S.B.
337          *
338          * Now behavior was slightly changed:
339          *
340          * if any of flags link[0-2] is used and its connector is
341          * physically present the following connectors are used:
342          *
343          *   link0 - AUI * highest precedence
344          *   link1 - BNC
345          *   link2 - UTP * lowest precedence
346          *
347          * If none of them is specified then
348          * connector specified in the EEPROM is used
349          * (if present on card or UTP if not).
350          */
351 	i = sc->vx_connector;	/* default in EEPROM */
352 	reason = "default";
353 	warning = 0;
354 
355 	if (ifp->if_flags & IFF_LINK0) {
356 		if (sc->vx_connectors & conn_tab[CONNECTOR_AUI].bit) {
357 			i = CONNECTOR_AUI;
358 			reason = "link0";
359 		} else {
360 			warning = "aui not present! (link0)";
361 		}
362 	} else if (ifp->if_flags & IFF_LINK1) {
363 		if (sc->vx_connectors & conn_tab[CONNECTOR_BNC].bit) {
364 			i = CONNECTOR_BNC;
365 			reason = "link1";
366 		} else {
367 			warning = "bnc not present! (link1)";
368 		}
369 	} else if (ifp->if_flags & IFF_LINK2) {
370 		if (sc->vx_connectors & conn_tab[CONNECTOR_UTP].bit) {
371 			i = CONNECTOR_UTP;
372 			reason = "link2";
373 		} else {
374 			warning = "utp not present! (link2)";
375 		}
376 	} else if ((sc->vx_connectors & conn_tab[(int)sc->vx_connector].bit) == 0) {
377 		warning = "strange connector type in EEPROM.";
378 		reason = "forced";
379 		i = CONNECTOR_UTP;
380 	}
381 	/* Avoid unnecessary message. */
382 	k = (prev_flags ^ ifp->if_flags) & (IFF_LINK0 | IFF_LINK1 | IFF_LINK2);
383 	if ((k != 0) || (prev_conn != i)) {
384 		if (warning != NULL)
385 			if_printf(ifp, "warning: %s\n", warning);
386 		if_printf(ifp, "selected %s. (%s)\n", conn_tab[i].name, reason);
387 	}
388 	/* Set the selected connector. */
389 	GO_WINDOW(3);
390 	j = CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
391 	CSR_WRITE_4(sc, VX_W3_INTERNAL_CFG, j | (i << INTERNAL_CONNECTOR_BITS));
392 
393 	/* First, disable all. */
394 	CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER);
395 	DELAY(800);
396 	GO_WINDOW(4);
397 	CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, 0);
398 
399 	/* Second, enable the selected one. */
400 	switch (i) {
401 	case CONNECTOR_UTP:
402 		GO_WINDOW(4);
403 		CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, ENABLE_UTP);
404 		break;
405 	case CONNECTOR_BNC:
406 		CSR_WRITE_2(sc, VX_COMMAND, START_TRANSCEIVER);
407 		DELAY(800);
408 		break;
409 	case CONNECTOR_TX:
410 	case CONNECTOR_FX:
411 		GO_WINDOW(4);
412 		CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, LINKBEAT_ENABLE);
413 		break;
414 	default:		/* AUI and MII fall here */
415 		break;
416 	}
417 	GO_WINDOW(1);
418 
419 	prev_flags = ifp->if_flags;
420 	prev_conn = i;
421 }
422 
423 static void
vx_start(struct ifnet * ifp)424 vx_start(struct ifnet *ifp)
425 {
426 	struct vx_softc *sc = ifp->if_softc;
427 
428 	VX_LOCK(sc);
429 	vx_start_locked(ifp);
430 	VX_UNLOCK(sc);
431 }
432 
433 static void
vx_start_locked(struct ifnet * ifp)434 vx_start_locked(struct ifnet *ifp)
435 {
436 	struct vx_softc *sc = ifp->if_softc;
437 	struct mbuf *m;
438 	int len, pad;
439 
440 	VX_LOCK_ASSERT(sc);
441 
442 	/* Don't transmit if interface is busy or not running */
443 	if ((sc->vx_ifp->if_drv_flags &
444 	    (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
445 		return;
446 
447 startagain:
448 	/* Sneak a peek at the next packet */
449 	m = ifp->if_snd.ifq_head;
450 	if (m == NULL) {
451 		return;
452 	}
453 	/* We need to use m->m_pkthdr.len, so require the header */
454 	M_ASSERTPKTHDR(m);
455 	len = m->m_pkthdr.len;
456 
457 	pad = (4 - len) & 3;
458 
459 	/*
460          * The 3c509 automatically pads short packets to minimum ethernet
461 	 * length, but we drop packets that are too large. Perhaps we should
462 	 * truncate them instead?
463          */
464 	if (len + pad > ETHER_MAX_LEN) {
465 		/* packet is obviously too large: toss it */
466 		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
467 		IF_DEQUEUE(&ifp->if_snd, m);
468 		m_freem(m);
469 		goto readcheck;
470 	}
471 	VX_BUSY_WAIT;
472 	if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
473 		CSR_WRITE_2(sc, VX_COMMAND,
474 		    SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2));
475 		/* not enough room in FIFO - make sure */
476 		if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
477 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
478 			sc->vx_timer = 1;
479 			return;
480 		}
481 	}
482 	CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2));
483 	IF_DEQUEUE(&ifp->if_snd, m);
484 	if (m == NULL)		/* not really needed */
485 		return;
486 
487 	VX_BUSY_WAIT;
488 	CSR_WRITE_2(sc, VX_COMMAND, SET_TX_START_THRESH |
489 	    ((len / 4 + sc->vx_tx_start_thresh) >> 2));
490 
491 	BPF_MTAP(sc->vx_ifp, m);
492 
493 	/*
494          * Do the output at splhigh() so that an interrupt from another device
495          * won't cause a FIFO underrun.
496 	 *
497 	 * XXX: Can't enforce that anymore.
498          */
499 
500 	CSR_WRITE_4(sc, VX_W1_TX_PIO_WR_1, len | TX_INDICATE);
501 
502 	while (m) {
503 		if (m->m_len > 3)
504 			bus_space_write_multi_4(sc->vx_bst, sc->vx_bsh,
505 			    VX_W1_TX_PIO_WR_1, (u_int32_t *)mtod(m, caddr_t),
506 			    m->m_len / 4);
507 		if (m->m_len & 3)
508 			bus_space_write_multi_1(sc->vx_bst, sc->vx_bsh,
509 			    VX_W1_TX_PIO_WR_1,
510 			    mtod(m, caddr_t) + (m->m_len & ~3), m->m_len & 3);
511 		m = m_free(m);
512 	}
513 	while (pad--)
514 		CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0);	/* Padding */
515 
516 	if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
517 	sc->vx_timer = 1;
518 
519 readcheck:
520 	if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) {
521 		/* We received a complete packet. */
522 
523 		if ((CSR_READ_2(sc, VX_STATUS) & S_INTR_LATCH) == 0) {
524 			/*
525 		         * No interrupt, read the packet and continue
526 		         * Is this supposed to happen?  Is my motherboard
527 		         * completely busted?
528 		         */
529 			vx_read(sc);
530 		} else
531 			/*
532 			 * Got an interrupt, return so that it gets
533 			 * serviced.
534 			 */
535 			return;
536 	} else {
537 		/* Check if we are stuck and reset [see XXX comment] */
538 		if (vx_status(sc)) {
539 			if (ifp->if_flags & IFF_DEBUG)
540 				if_printf(ifp, "adapter reset\n");
541 			vx_reset(sc);
542 		}
543 	}
544 
545 	goto startagain;
546 }
547 
548 /*
549  * XXX: The 3c509 card can get in a mode where both the fifo status bit
550  *      FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
551  *      We detect this situation and we reset the adapter.
552  *      It happens at times when there is a lot of broadcast traffic
553  *      on the cable (once in a blue moon).
554  */
555 static int
vx_status(struct vx_softc * sc)556 vx_status(struct vx_softc *sc)
557 {
558 	struct ifnet *ifp;
559 	int fifost;
560 
561 	VX_LOCK_ASSERT(sc);
562 
563 	/*
564          * Check the FIFO status and act accordingly
565          */
566 	GO_WINDOW(4);
567 	fifost = CSR_READ_2(sc, VX_W4_FIFO_DIAG);
568 	GO_WINDOW(1);
569 
570 	ifp = sc->vx_ifp;
571 	if (fifost & FIFOS_RX_UNDERRUN) {
572 		if (ifp->if_flags & IFF_DEBUG)
573 			if_printf(ifp, "RX underrun\n");
574 		vx_reset(sc);
575 		return 0;
576 	}
577 	if (fifost & FIFOS_RX_STATUS_OVERRUN) {
578 		if (ifp->if_flags & IFF_DEBUG)
579 			if_printf(ifp, "RX Status overrun\n");
580 		return 1;
581 	}
582 	if (fifost & FIFOS_RX_OVERRUN) {
583 		if (ifp->if_flags & IFF_DEBUG)
584 			if_printf(ifp, "RX overrun\n");
585 		return 1;
586 	}
587 	if (fifost & FIFOS_TX_OVERRUN) {
588 		if (ifp->if_flags & IFF_DEBUG)
589 			if_printf(ifp, "TX overrun\n");
590 		vx_reset(sc);
591 		return 0;
592 	}
593 	return 0;
594 }
595 
596 static void
vx_txstat(struct vx_softc * sc)597 vx_txstat(struct vx_softc *sc)
598 {
599 	struct ifnet *ifp;
600 	int i;
601 
602 	VX_LOCK_ASSERT(sc);
603 
604 	/*
605         * We need to read+write TX_STATUS until we get a 0 status
606         * in order to turn off the interrupt flag.
607         */
608 	ifp = sc->vx_ifp;
609 	while ((i = CSR_READ_1(sc, VX_W1_TX_STATUS)) & TXS_COMPLETE) {
610 		CSR_WRITE_1(sc, VX_W1_TX_STATUS, 0x0);
611 
612 		if (i & TXS_JABBER) {
613 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
614 			if (ifp->if_flags & IFF_DEBUG)
615 				if_printf(ifp, "jabber (%x)\n", i);
616 			vx_reset(sc);
617 		} else if (i & TXS_UNDERRUN) {
618 			if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
619 			if (ifp->if_flags & IFF_DEBUG)
620 				if_printf(ifp, "fifo underrun (%x) @%d\n", i,
621 				    sc->vx_tx_start_thresh);
622 			if (sc->vx_tx_succ_ok < 100)
623 				sc->vx_tx_start_thresh =
624 				    min(ETHER_MAX_LEN,
625 					sc->vx_tx_start_thresh + 20);
626 			sc->vx_tx_succ_ok = 0;
627 			vx_reset(sc);
628 		} else if (i & TXS_MAX_COLLISION) {
629 			if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
630 			CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE);
631 			ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
632 		} else
633 			sc->vx_tx_succ_ok = (sc->vx_tx_succ_ok + 1) & 127;
634 	}
635 }
636 
637 void
vx_intr(void * voidsc)638 vx_intr(void *voidsc)
639 {
640 	short status;
641 	struct vx_softc *sc = voidsc;
642 	struct ifnet *ifp = sc->vx_ifp;
643 
644 	VX_LOCK(sc);
645 	for (;;) {
646 		CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
647 
648 		status = CSR_READ_2(sc, VX_STATUS);
649 
650 		if ((status & (S_TX_COMPLETE | S_TX_AVAIL |
651 		    S_RX_COMPLETE | S_CARD_FAILURE)) == 0)
652 			break;
653 
654 		/*
655 		 * Acknowledge any interrupts.  It's important that we do this
656 		 * first, since there would otherwise be a race condition.
657 		 * Due to the i386 interrupt queueing, we may get spurious
658 		 * interrupts occasionally.
659 		 */
660 		CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | status);
661 
662 		if (status & S_RX_COMPLETE)
663 			vx_read(sc);
664 		if (status & S_TX_AVAIL) {
665 			sc->vx_timer = 0;
666 			sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
667 			vx_start_locked(sc->vx_ifp);
668 		}
669 		if (status & S_CARD_FAILURE) {
670 			if_printf(ifp, "adapter failure (%x)\n", status);
671 			sc->vx_timer = 0;
672 			vx_reset(sc);
673 			break;
674 		}
675 		if (status & S_TX_COMPLETE) {
676 			sc->vx_timer = 0;
677 			vx_txstat(sc);
678 			vx_start_locked(ifp);
679 		}
680 	}
681 	VX_UNLOCK(sc);
682 
683 	/* no more interrupts */
684 	return;
685 }
686 
687 static void
vx_read(struct vx_softc * sc)688 vx_read(struct vx_softc *sc)
689 {
690 	struct ifnet *ifp = sc->vx_ifp;
691 	struct mbuf *m;
692 	struct ether_header *eh;
693 	u_int len;
694 
695 	VX_LOCK_ASSERT(sc);
696 	len = CSR_READ_2(sc, VX_W1_RX_STATUS);
697 again:
698 
699 	if (ifp->if_flags & IFF_DEBUG) {
700 		int err = len & ERR_MASK;
701 		char *s = NULL;
702 
703 		if (len & ERR_INCOMPLETE)
704 			s = "incomplete packet";
705 		else if (err == ERR_OVERRUN)
706 			s = "packet overrun";
707 		else if (err == ERR_RUNT)
708 			s = "runt packet";
709 		else if (err == ERR_ALIGNMENT)
710 			s = "bad alignment";
711 		else if (err == ERR_CRC)
712 			s = "bad crc";
713 		else if (err == ERR_OVERSIZE)
714 			s = "oversized packet";
715 		else if (err == ERR_DRIBBLE)
716 			s = "dribble bits";
717 
718 		if (s)
719 			if_printf(ifp, "%s\n", s);
720 	}
721 	if (len & ERR_INCOMPLETE)
722 		return;
723 
724 	if (len & ERR_RX) {
725 		if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
726 		goto abort;
727 	}
728 	len &= RX_BYTES_MASK;	/* Lower 11 bits = RX bytes. */
729 
730 	/* Pull packet off interface. */
731 	m = vx_get(sc, len);
732 	if (m == 0) {
733 		if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
734 		goto abort;
735 	}
736 	if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
737 
738 	{
739 		struct mbuf *m0;
740 
741 		m0 = m_devget(mtod(m, char *), m->m_pkthdr.len, ETHER_ALIGN,
742 		    ifp, NULL);
743 		if (m0 == NULL) {
744 			if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
745 			goto abort;
746 		}
747 		m_freem(m);
748 		m = m0;
749 	}
750 
751 	/* We assume the header fit entirely in one mbuf. */
752 	eh = mtod(m, struct ether_header *);
753 
754 	/*
755          * XXX: Some cards seem to be in promiscous mode all the time.
756          * we need to make sure we only get our own stuff always.
757          * bleah!
758          */
759 
760 	if (!(ifp->if_flags & IFF_PROMISC)
761 	    && (eh->ether_dhost[0] & 1) == 0	/* !mcast and !bcast */
762 	    && bcmp(eh->ether_dhost, IF_LLADDR(sc->vx_ifp),
763 	    ETHER_ADDR_LEN) != 0) {
764 		m_freem(m);
765 		return;
766 	}
767 	VX_UNLOCK(sc);
768 	(*ifp->if_input)(ifp, m);
769 	VX_LOCK(sc);
770 
771 	/*
772         * In periods of high traffic we can actually receive enough
773         * packets so that the fifo overrun bit will be set at this point,
774         * even though we just read a packet. In this case we
775         * are not going to receive any more interrupts. We check for
776         * this condition and read again until the fifo is not full.
777         * We could simplify this test by not using vx_status(), but
778         * rechecking the RX_STATUS register directly. This test could
779         * result in unnecessary looping in cases where there is a new
780         * packet but the fifo is not full, but it will not fix the
781         * stuck behavior.
782         *
783         * Even with this improvement, we still get packet overrun errors
784         * which are hurting performance. Maybe when I get some more time
785         * I'll modify vx_read() so that it can handle RX_EARLY interrupts.
786         */
787 	if (vx_status(sc)) {
788 		len = CSR_READ_2(sc, VX_W1_RX_STATUS);
789 		/* Check if we are stuck and reset [see XXX comment] */
790 		if (len & ERR_INCOMPLETE) {
791 			if (ifp->if_flags & IFF_DEBUG)
792 				if_printf(ifp, "adapter reset\n");
793 			vx_reset(sc);
794 			return;
795 		}
796 		goto again;
797 	}
798 	return;
799 
800 abort:
801 	CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
802 }
803 
804 static struct mbuf *
vx_get(struct vx_softc * sc,u_int totlen)805 vx_get(struct vx_softc *sc, u_int totlen)
806 {
807 	struct ifnet *ifp = sc->vx_ifp;
808 	struct mbuf *top, **mp, *m;
809 	int len;
810 
811 	VX_LOCK_ASSERT(sc);
812 	m = sc->vx_mb[sc->vx_next_mb];
813 	sc->vx_mb[sc->vx_next_mb] = NULL;
814 	if (m == NULL) {
815 		MGETHDR(m, M_NOWAIT, MT_DATA);
816 		if (m == NULL)
817 			return NULL;
818 	} else {
819 		/* If the queue is no longer full, refill. */
820 		if (sc->vx_last_mb == sc->vx_next_mb &&
821 		    sc->vx_buffill_pending == 0) {
822 			callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill,
823 			    sc);
824 			sc->vx_buffill_pending = 1;
825 		}
826 		/* Convert one of our saved mbuf's. */
827 		sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS;
828 		m->m_data = m->m_pktdat;
829 		m->m_flags = M_PKTHDR;
830 		bzero(&m->m_pkthdr, sizeof(m->m_pkthdr));
831 	}
832 	m->m_pkthdr.rcvif = ifp;
833 	m->m_pkthdr.len = totlen;
834 	len = MHLEN;
835 	top = NULL;
836 	mp = &top;
837 
838 	/*
839          * We read the packet at splhigh() so that an interrupt from another
840          * device doesn't cause the card's buffer to overflow while we're
841          * reading it.  We may still lose packets at other times.
842 	 *
843 	 * XXX: Can't enforce this anymore.
844          */
845 
846 	/*
847          * Since we don't set allowLargePackets bit in MacControl register,
848          * we can assume that totlen <= 1500bytes.
849          * The while loop will be performed iff we have a packet with
850          * MLEN < m_len < MINCLSIZE.
851          */
852 	while (totlen > 0) {
853 		if (top) {
854 			m = sc->vx_mb[sc->vx_next_mb];
855 			sc->vx_mb[sc->vx_next_mb] = NULL;
856 			if (m == NULL) {
857 				MGET(m, M_NOWAIT, MT_DATA);
858 				if (m == NULL) {
859 					m_freem(top);
860 					return NULL;
861 				}
862 			} else {
863 				sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS;
864 			}
865 			len = MLEN;
866 		}
867 		if (totlen >= MINCLSIZE) {
868 			if (MCLGET(m, M_NOWAIT))
869 				len = MCLBYTES;
870 		}
871 		len = min(totlen, len);
872 		if (len > 3)
873 			bus_space_read_multi_4(sc->vx_bst, sc->vx_bsh,
874 			    VX_W1_RX_PIO_RD_1, mtod(m, u_int32_t *), len / 4);
875 		if (len & 3) {
876 			bus_space_read_multi_1(sc->vx_bst, sc->vx_bsh,
877 			    VX_W1_RX_PIO_RD_1, mtod(m, u_int8_t *) + (len & ~3),
878 			    len & 3);
879 		}
880 		m->m_len = len;
881 		totlen -= len;
882 		*mp = m;
883 		mp = &m->m_next;
884 	}
885 
886 	CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
887 
888 	return top;
889 }
890 
891 
892 static int
vx_ioctl(struct ifnet * ifp,u_long cmd,caddr_t data)893 vx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
894 {
895 	struct vx_softc *sc = ifp->if_softc;
896 	struct ifreq *ifr = (struct ifreq *) data;
897 	int error = 0;
898 
899 	switch (cmd) {
900 	case SIOCSIFFLAGS:
901 		VX_LOCK(sc);
902 		if ((ifp->if_flags & IFF_UP) == 0 &&
903 		    (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
904 			/*
905 	                 * If interface is marked up and it is stopped, then
906 	                 * start it.
907 	                 */
908 			vx_stop(sc);
909 			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
910 		} else if ((ifp->if_flags & IFF_UP) != 0 &&
911 		    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
912 			/*
913 	                 * If interface is marked up and it is stopped, then
914 	                 * start it.
915 	                 */
916 			vx_init_locked(sc);
917 		} else {
918 			/*
919 	                 * deal with flags changes:
920 	                 * IFF_MULTICAST, IFF_PROMISC,
921 	                 * IFF_LINK0, IFF_LINK1,
922 	                 */
923 			vx_setfilter(sc);
924 			vx_setlink(sc);
925 		}
926 		VX_UNLOCK(sc);
927 		break;
928 
929 	case SIOCSIFMTU:
930 		/*
931 	         * Set the interface MTU.
932 	         */
933 		VX_LOCK(sc);
934 		if (ifr->ifr_mtu > ETHERMTU) {
935 			error = EINVAL;
936 		} else {
937 			ifp->if_mtu = ifr->ifr_mtu;
938 		}
939 		VX_UNLOCK(sc);
940 		break;
941 
942 	case SIOCADDMULTI:
943 	case SIOCDELMULTI:
944 		/*
945 		 * Multicast list has changed; set the hardware filter
946 		 * accordingly.
947 		 */
948 		VX_LOCK(sc);
949 		vx_reset(sc);
950 		VX_UNLOCK(sc);
951 		error = 0;
952 		break;
953 
954 
955 	default:
956 		error = ether_ioctl(ifp, cmd, data);
957 		break;
958 	}
959 
960 	return (error);
961 }
962 
963 static void
vx_reset(struct vx_softc * sc)964 vx_reset(struct vx_softc *sc)
965 {
966 
967 	VX_LOCK_ASSERT(sc);
968 	vx_stop(sc);
969 	vx_init_locked(sc);
970 }
971 
972 static void
vx_watchdog(void * arg)973 vx_watchdog(void *arg)
974 {
975 	struct vx_softc *sc;
976 	struct ifnet *ifp;
977 
978 	sc = arg;
979 	VX_LOCK_ASSERT(sc);
980 	callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc);
981 	if (sc->vx_timer == 0 || --sc->vx_timer > 0)
982 		return;
983 
984 	ifp = sc->vx_ifp;
985 	if (ifp->if_flags & IFF_DEBUG)
986 		if_printf(ifp, "device timeout\n");
987 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
988 	vx_start_locked(ifp);
989 	vx_intr(sc);
990 }
991 
992 void
vx_stop(struct vx_softc * sc)993 vx_stop(struct vx_softc *sc)
994 {
995 
996 	VX_LOCK_ASSERT(sc);
997 	sc->vx_timer = 0;
998 	callout_stop(&sc->vx_watchdog);
999 
1000 	CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE);
1001 	CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
1002 	VX_BUSY_WAIT;
1003 	CSR_WRITE_2(sc, VX_COMMAND, TX_DISABLE);
1004 	CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER);
1005 	DELAY(800);
1006 	CSR_WRITE_2(sc, VX_COMMAND, RX_RESET);
1007 	VX_BUSY_WAIT;
1008 	CSR_WRITE_2(sc, VX_COMMAND, TX_RESET);
1009 	VX_BUSY_WAIT;
1010 	CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
1011 	CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK);
1012 	CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK);
1013 	CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER);
1014 
1015 	vx_mbuf_empty(sc);
1016 }
1017 
1018 int
vx_busy_eeprom(struct vx_softc * sc)1019 vx_busy_eeprom(struct vx_softc *sc)
1020 {
1021 	int j, i = 100;
1022 
1023 	while (i--) {
1024 		j = CSR_READ_2(sc, VX_W0_EEPROM_COMMAND);
1025 		if (j & EEPROM_BUSY)
1026 			DELAY(100);
1027 		else
1028 			break;
1029 	}
1030 	if (!i) {
1031 		if_printf(sc->vx_ifp, "eeprom failed to come ready\n");
1032 		return (1);
1033 	}
1034 	return (0);
1035 }
1036 
1037 static void
vx_mbuf_fill(void * sp)1038 vx_mbuf_fill(void *sp)
1039 {
1040 	struct vx_softc *sc = (struct vx_softc *)sp;
1041 	int i;
1042 
1043 	VX_LOCK_ASSERT(sc);
1044 	i = sc->vx_last_mb;
1045 	do {
1046 		if (sc->vx_mb[i] == NULL)
1047 			MGET(sc->vx_mb[i], M_NOWAIT, MT_DATA);
1048 		if (sc->vx_mb[i] == NULL)
1049 			break;
1050 		i = (i + 1) % MAX_MBS;
1051 	} while (i != sc->vx_next_mb);
1052 	sc->vx_last_mb = i;
1053 	/* If the queue was not filled, try again. */
1054 	if (sc->vx_last_mb != sc->vx_next_mb) {
1055 		callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill, sc);
1056 		sc->vx_buffill_pending = 1;
1057 	} else {
1058 		sc->vx_buffill_pending = 0;
1059 	}
1060 }
1061 
1062 static void
vx_mbuf_empty(struct vx_softc * sc)1063 vx_mbuf_empty(struct vx_softc *sc)
1064 {
1065 	int i;
1066 
1067 	VX_LOCK_ASSERT(sc);
1068 	for (i = 0; i < MAX_MBS; i++) {
1069 		if (sc->vx_mb[i]) {
1070 			m_freem(sc->vx_mb[i]);
1071 			sc->vx_mb[i] = NULL;
1072 		}
1073 	}
1074 	sc->vx_last_mb = sc->vx_next_mb = 0;
1075 	if (sc->vx_buffill_pending != 0)
1076 		callout_stop(&sc->vx_callout);
1077 }
1078