]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/vx/if_vx.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / vx / if_vx.c
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
70 #include <net/ethernet.h>
71 #include <net/if_dl.h>
72 #include <net/if_types.h>
73
74 #include <machine/bus.h>
75
76 #include <sys/bus.h>
77
78 #include <net/bpf.h>
79
80 #include <dev/vx/if_vxreg.h>
81 #include <dev/vx/if_vxvar.h>
82
83 #define ETHER_MAX_LEN   1518
84 #define ETHER_ADDR_LEN  6
85 #define ETHER_ALIGN     2
86
87 static struct connector_entry {
88         int bit;
89         char *name;
90 } conn_tab[VX_CONNECTORS] = {
91
92 #define CONNECTOR_UTP   0
93         {
94                 0x08, "utp"
95         },
96 #define CONNECTOR_AUI   1
97         {
98                 0x20, "aui"
99         },
100 /* dummy */
101         {
102                 0, "???"
103         },
104 #define CONNECTOR_BNC   3
105         {
106                 0x10, "bnc"
107         },
108 #define CONNECTOR_TX    4
109         {
110                 0x02, "tx"
111         },
112 #define CONNECTOR_FX    5
113         {
114                 0x04, "fx"
115         },
116 #define CONNECTOR_MII   6
117         {
118                 0x40, "mii"
119         },
120         {
121                 0, "???"
122         }
123 };
124
125 static void vx_txstat(struct vx_softc *);
126 static int vx_status(struct vx_softc *);
127 static void vx_init(void *);
128 static void vx_init_locked(struct vx_softc *);
129 static int vx_ioctl(struct ifnet *, u_long, caddr_t);
130 static void vx_start(struct ifnet *);
131 static void vx_start_locked(struct ifnet *);
132 static void vx_watchdog(void *);
133 static void vx_reset(struct vx_softc *);
134 static void vx_read(struct vx_softc *);
135 static struct mbuf *vx_get(struct vx_softc *, u_int);
136 static void vx_mbuf_fill(void *);
137 static void vx_mbuf_empty(struct vx_softc *);
138 static void vx_setfilter(struct vx_softc *);
139 static void vx_getlink(struct vx_softc *);
140 static void vx_setlink(struct vx_softc *);
141
142 int
143 vx_attach(device_t dev)
144 {
145         struct vx_softc *sc = device_get_softc(dev);
146         struct ifnet *ifp;
147         int i;
148         u_char eaddr[6];
149
150         ifp = sc->vx_ifp = if_alloc(IFT_ETHER);
151         if (ifp == NULL) {
152                 device_printf(dev, "can not if_alloc()\n");
153                 return 0;
154         }
155         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
156
157         mtx_init(&sc->vx_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
158             MTX_DEF);
159         callout_init_mtx(&sc->vx_callout, &sc->vx_mtx, 0);
160         callout_init_mtx(&sc->vx_watchdog, &sc->vx_mtx, 0);
161         GO_WINDOW(0);
162         CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET);
163         VX_BUSY_WAIT;
164
165         vx_getlink(sc);
166
167         /*
168          * Read the station address from the eeprom
169          */
170         GO_WINDOW(0);
171         for (i = 0; i < 3; i++) {
172                 int x;
173
174                 if (vx_busy_eeprom(sc)) {
175                         mtx_destroy(&sc->vx_mtx);
176                         if_free(ifp);
177                         return 0;
178                 }
179                 CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND, EEPROM_CMD_RD
180                     | (EEPROM_OEM_ADDR0 + i));
181                 if (vx_busy_eeprom(sc)) {
182                         mtx_destroy(&sc->vx_mtx);
183                         if_free(ifp);
184                         return 0;
185                 }
186                 x = CSR_READ_2(sc, VX_W0_EEPROM_DATA);
187                 eaddr[(i << 1)] = x >> 8;
188                 eaddr[(i << 1) + 1] = x;
189         }
190
191         ifp->if_mtu = ETHERMTU;
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
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
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
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
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
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
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
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                 ++ifp->if_oerrors;
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         ++ifp->if_opackets;
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
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
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                         ++ifp->if_oerrors;
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                         ++ifp->if_oerrors;
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                         ++ifp->if_collisions;
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
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
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                 ++ifp->if_ierrors;
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                 ifp->if_ierrors++;
734                 goto abort;
735         }
736         ++ifp->if_ipackets;
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                         ifp->if_ierrors++;
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 *
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                         MCLGET(m, M_NOWAIT);
869                         if (m->m_flags & M_EXT)
870                                 len = MCLBYTES;
871                 }
872                 len = min(totlen, len);
873                 if (len > 3)
874                         bus_space_read_multi_4(sc->vx_bst, sc->vx_bsh,
875                             VX_W1_RX_PIO_RD_1, mtod(m, u_int32_t *), len / 4);
876                 if (len & 3) {
877                         bus_space_read_multi_1(sc->vx_bst, sc->vx_bsh,
878                             VX_W1_RX_PIO_RD_1, mtod(m, u_int8_t *) + (len & ~3),
879                             len & 3);
880                 }
881                 m->m_len = len;
882                 totlen -= len;
883                 *mp = m;
884                 mp = &m->m_next;
885         }
886
887         CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
888
889         return top;
890 }
891
892
893 static int
894 vx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
895 {
896         struct vx_softc *sc = ifp->if_softc;
897         struct ifreq *ifr = (struct ifreq *) data;
898         int error = 0;
899
900         switch (cmd) {
901         case SIOCSIFFLAGS:
902                 VX_LOCK(sc);
903                 if ((ifp->if_flags & IFF_UP) == 0 &&
904                     (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
905                         /*
906                          * If interface is marked up and it is stopped, then
907                          * start it.
908                          */
909                         vx_stop(sc);
910                         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
911                 } else if ((ifp->if_flags & IFF_UP) != 0 &&
912                     (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
913                         /*
914                          * If interface is marked up and it is stopped, then
915                          * start it.
916                          */
917                         vx_init_locked(sc);
918                 } else {
919                         /*
920                          * deal with flags changes:
921                          * IFF_MULTICAST, IFF_PROMISC,
922                          * IFF_LINK0, IFF_LINK1,
923                          */
924                         vx_setfilter(sc);
925                         vx_setlink(sc);
926                 }
927                 VX_UNLOCK(sc);
928                 break;
929
930         case SIOCSIFMTU:
931                 /*
932                  * Set the interface MTU.
933                  */
934                 VX_LOCK(sc);
935                 if (ifr->ifr_mtu > ETHERMTU) {
936                         error = EINVAL;
937                 } else {
938                         ifp->if_mtu = ifr->ifr_mtu;
939                 }
940                 VX_UNLOCK(sc);
941                 break;
942
943         case SIOCADDMULTI:
944         case SIOCDELMULTI:
945                 /*
946                  * Multicast list has changed; set the hardware filter
947                  * accordingly.
948                  */
949                 VX_LOCK(sc);
950                 vx_reset(sc);
951                 VX_UNLOCK(sc);
952                 error = 0;
953                 break;
954
955
956         default:
957                 error = ether_ioctl(ifp, cmd, data);
958                 break;
959         }
960
961         return (error);
962 }
963
964 static void
965 vx_reset(struct vx_softc *sc)
966 {
967
968         VX_LOCK_ASSERT(sc);
969         vx_stop(sc);
970         vx_init_locked(sc);
971 }
972
973 static void
974 vx_watchdog(void *arg)
975 {
976         struct vx_softc *sc;
977         struct ifnet *ifp;
978
979         sc = arg;
980         VX_LOCK_ASSERT(sc);
981         callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc);
982         if (sc->vx_timer == 0 || --sc->vx_timer > 0)
983                 return;
984
985         ifp = sc->vx_ifp;
986         if (ifp->if_flags & IFF_DEBUG)
987                 if_printf(ifp, "device timeout\n");
988         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
989         vx_start_locked(ifp);
990         vx_intr(sc);
991 }
992
993 void
994 vx_stop(struct vx_softc *sc)
995 {
996
997         VX_LOCK_ASSERT(sc);
998         sc->vx_timer = 0;
999         callout_stop(&sc->vx_watchdog);
1000
1001         CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE);
1002         CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
1003         VX_BUSY_WAIT;
1004         CSR_WRITE_2(sc, VX_COMMAND, TX_DISABLE);
1005         CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER);
1006         DELAY(800);
1007         CSR_WRITE_2(sc, VX_COMMAND, RX_RESET);
1008         VX_BUSY_WAIT;
1009         CSR_WRITE_2(sc, VX_COMMAND, TX_RESET);
1010         VX_BUSY_WAIT;
1011         CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
1012         CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK);
1013         CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK);
1014         CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER);
1015
1016         vx_mbuf_empty(sc);
1017 }
1018
1019 int
1020 vx_busy_eeprom(struct vx_softc *sc)
1021 {
1022         int j, i = 100;
1023
1024         while (i--) {
1025                 j = CSR_READ_2(sc, VX_W0_EEPROM_COMMAND);
1026                 if (j & EEPROM_BUSY)
1027                         DELAY(100);
1028                 else
1029                         break;
1030         }
1031         if (!i) {
1032                 if_printf(sc->vx_ifp, "eeprom failed to come ready\n");
1033                 return (1);
1034         }
1035         return (0);
1036 }
1037
1038 static void
1039 vx_mbuf_fill(void *sp)
1040 {
1041         struct vx_softc *sc = (struct vx_softc *)sp;
1042         int i;
1043
1044         VX_LOCK_ASSERT(sc);
1045         i = sc->vx_last_mb;
1046         do {
1047                 if (sc->vx_mb[i] == NULL)
1048                         MGET(sc->vx_mb[i], M_NOWAIT, MT_DATA);
1049                 if (sc->vx_mb[i] == NULL)
1050                         break;
1051                 i = (i + 1) % MAX_MBS;
1052         } while (i != sc->vx_next_mb);
1053         sc->vx_last_mb = i;
1054         /* If the queue was not filled, try again. */
1055         if (sc->vx_last_mb != sc->vx_next_mb) {
1056                 callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill, sc);
1057                 sc->vx_buffill_pending = 1;
1058         } else {
1059                 sc->vx_buffill_pending = 0;
1060         }
1061 }
1062
1063 static void
1064 vx_mbuf_empty(struct vx_softc *sc)
1065 {
1066         int i;
1067
1068         VX_LOCK_ASSERT(sc);
1069         for (i = 0; i < MAX_MBS; i++) {
1070                 if (sc->vx_mb[i]) {
1071                         m_freem(sc->vx_mb[i]);
1072                         sc->vx_mb[i] = NULL;
1073                 }
1074         }
1075         sc->vx_last_mb = sc->vx_next_mb = 0;
1076         if (sc->vx_buffill_pending != 0)
1077                 callout_stop(&sc->vx_callout);
1078 }