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