]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/vx/if_vx.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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_snd.ifq_maxlen = ifqmaxlen;
192         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
193         ifp->if_start = vx_start;
194         ifp->if_ioctl = vx_ioctl;
195         ifp->if_init = vx_init;
196         ifp->if_softc = sc;
197
198         ether_ifattach(ifp, eaddr);
199
200         sc->vx_tx_start_thresh = 20;    /* probably a good starting point. */
201
202         VX_LOCK(sc);
203         vx_stop(sc);
204         VX_UNLOCK(sc);
205
206         return 1;
207 }
208
209 /*
210  * The order in here seems important. Otherwise we may not receive
211  * interrupts. ?!
212  */
213 static void
214 vx_init(void *xsc)
215 {
216         struct vx_softc *sc = (struct vx_softc *)xsc;
217
218         VX_LOCK(sc);
219         vx_init_locked(sc);
220         VX_UNLOCK(sc);
221 }
222
223 static void
224 vx_init_locked(struct vx_softc *sc)
225 {
226         struct ifnet *ifp = sc->vx_ifp;
227         int i;
228
229         VX_LOCK_ASSERT(sc);
230
231         VX_BUSY_WAIT;
232
233         GO_WINDOW(2);
234
235         for (i = 0; i < 6; i++) /* Reload the ether_addr. */
236                 CSR_WRITE_1(sc, VX_W2_ADDR_0 + i, IF_LLADDR(sc->vx_ifp)[i]);
237
238         CSR_WRITE_2(sc, VX_COMMAND, RX_RESET);
239         VX_BUSY_WAIT;
240         CSR_WRITE_2(sc, VX_COMMAND, TX_RESET);
241         VX_BUSY_WAIT;
242
243         GO_WINDOW(1);           /* Window 1 is operating window */
244         for (i = 0; i < 31; i++)
245                 CSR_READ_1(sc, VX_W1_TX_STATUS);
246
247         CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE |
248             S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
249         CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK | S_CARD_FAILURE |
250             S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
251
252         /*
253          * Attempt to get rid of any stray interrupts that occured during
254          * configuration.  On the i386 this isn't possible because one may
255          * already be queued.  However, a single stray interrupt is
256          * unimportant.
257          */
258         CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | 0xff);
259
260         vx_setfilter(sc);
261         vx_setlink(sc);
262
263         CSR_WRITE_2(sc, VX_COMMAND, RX_ENABLE);
264         CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE);
265
266         vx_mbuf_fill(sc);
267
268         /* Interface is now `running', with no output active. */
269         ifp->if_drv_flags |= IFF_DRV_RUNNING;
270         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
271         callout_reset(&sc->vx_watchdog, hz, vx_watchdog, sc);
272
273         /* Attempt to start output, if any. */
274         vx_start_locked(ifp);
275 }
276
277 static void
278 vx_setfilter(struct vx_softc *sc)
279 {
280         struct ifnet *ifp = sc->vx_ifp;
281
282         VX_LOCK_ASSERT(sc);
283         GO_WINDOW(1);           /* Window 1 is operating window */
284         CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER |
285             FIL_INDIVIDUAL | FIL_BRDCST | FIL_MULTICAST |
286             ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0));
287 }
288
289 static void
290 vx_getlink(struct vx_softc *sc)
291 {
292         int n, k;
293
294         GO_WINDOW(3);
295         sc->vx_connectors = CSR_READ_2(sc, VX_W3_RESET_OPT) & 0x7f;
296         for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
297                 if (sc->vx_connectors & conn_tab[k].bit) {
298                         if (n > 0)
299                                 printf("/");
300                         printf("%s", conn_tab[k].name);
301                         n++;
302                 }
303         }
304         if (sc->vx_connectors == 0) {
305                 printf("no connectors!\n");
306                 return;
307         }
308         GO_WINDOW(3);
309         sc->vx_connector =
310             (CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & INTERNAL_CONNECTOR_MASK)
311             >> INTERNAL_CONNECTOR_BITS;
312         if (sc->vx_connector & 0x10) {
313                 sc->vx_connector &= 0x0f;
314                 printf("[*%s*]", conn_tab[(int)sc->vx_connector].name);
315                 printf(": disable 'auto select' with DOS util!\n");
316         } else {
317                 printf("[*%s*]\n", conn_tab[(int)sc->vx_connector].name);
318         }
319 }
320
321 static void
322 vx_setlink(struct vx_softc *sc)
323 {
324         struct ifnet *ifp = sc->vx_ifp;
325         int i, j, k;
326         char *reason, *warning;
327         static int prev_flags;
328         static signed char prev_conn = -1;
329
330         VX_LOCK_ASSERT(sc);
331         if (prev_conn == -1)
332                 prev_conn = sc->vx_connector;
333
334         /*
335          * S.B.
336          *
337          * Now behavior was slightly changed:
338          *
339          * if any of flags link[0-2] is used and its connector is
340          * physically present the following connectors are used:
341          *
342          *   link0 - AUI * highest precedence
343          *   link1 - BNC
344          *   link2 - UTP * lowest precedence
345          *
346          * If none of them is specified then
347          * connector specified in the EEPROM is used
348          * (if present on card or UTP if not).
349          */
350         i = sc->vx_connector;   /* default in EEPROM */
351         reason = "default";
352         warning = 0;
353
354         if (ifp->if_flags & IFF_LINK0) {
355                 if (sc->vx_connectors & conn_tab[CONNECTOR_AUI].bit) {
356                         i = CONNECTOR_AUI;
357                         reason = "link0";
358                 } else {
359                         warning = "aui not present! (link0)";
360                 }
361         } else if (ifp->if_flags & IFF_LINK1) {
362                 if (sc->vx_connectors & conn_tab[CONNECTOR_BNC].bit) {
363                         i = CONNECTOR_BNC;
364                         reason = "link1";
365                 } else {
366                         warning = "bnc not present! (link1)";
367                 }
368         } else if (ifp->if_flags & IFF_LINK2) {
369                 if (sc->vx_connectors & conn_tab[CONNECTOR_UTP].bit) {
370                         i = CONNECTOR_UTP;
371                         reason = "link2";
372                 } else {
373                         warning = "utp not present! (link2)";
374                 }
375         } else if ((sc->vx_connectors & conn_tab[(int)sc->vx_connector].bit) == 0) {
376                 warning = "strange connector type in EEPROM.";
377                 reason = "forced";
378                 i = CONNECTOR_UTP;
379         }
380         /* Avoid unnecessary message. */
381         k = (prev_flags ^ ifp->if_flags) & (IFF_LINK0 | IFF_LINK1 | IFF_LINK2);
382         if ((k != 0) || (prev_conn != i)) {
383                 if (warning != NULL)
384                         if_printf(ifp, "warning: %s\n", warning);
385                 if_printf(ifp, "selected %s. (%s)\n", conn_tab[i].name, reason);
386         }
387         /* Set the selected connector. */
388         GO_WINDOW(3);
389         j = CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
390         CSR_WRITE_4(sc, VX_W3_INTERNAL_CFG, j | (i << INTERNAL_CONNECTOR_BITS));
391
392         /* First, disable all. */
393         CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER);
394         DELAY(800);
395         GO_WINDOW(4);
396         CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, 0);
397
398         /* Second, enable the selected one. */
399         switch (i) {
400         case CONNECTOR_UTP:
401                 GO_WINDOW(4);
402                 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, ENABLE_UTP);
403                 break;
404         case CONNECTOR_BNC:
405                 CSR_WRITE_2(sc, VX_COMMAND, START_TRANSCEIVER);
406                 DELAY(800);
407                 break;
408         case CONNECTOR_TX:
409         case CONNECTOR_FX:
410                 GO_WINDOW(4);
411                 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, LINKBEAT_ENABLE);
412                 break;
413         default:                /* AUI and MII fall here */
414                 break;
415         }
416         GO_WINDOW(1);
417
418         prev_flags = ifp->if_flags;
419         prev_conn = i;
420 }
421
422 static void
423 vx_start(struct ifnet *ifp)
424 {
425         struct vx_softc *sc = ifp->if_softc;
426
427         VX_LOCK(sc);
428         vx_start_locked(ifp);
429         VX_UNLOCK(sc);
430 }
431
432 static void
433 vx_start_locked(struct ifnet *ifp)
434 {
435         struct vx_softc *sc = ifp->if_softc;
436         struct mbuf *m;
437         int len, pad;
438
439         VX_LOCK_ASSERT(sc);
440
441         /* Don't transmit if interface is busy or not running */
442         if ((sc->vx_ifp->if_drv_flags &
443             (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
444                 return;
445
446 startagain:
447         /* Sneak a peek at the next packet */
448         m = ifp->if_snd.ifq_head;
449         if (m == NULL) {
450                 return;
451         }
452         /* We need to use m->m_pkthdr.len, so require the header */
453         M_ASSERTPKTHDR(m);
454         len = m->m_pkthdr.len;
455
456         pad = (4 - len) & 3;
457
458         /*
459          * The 3c509 automatically pads short packets to minimum ethernet
460          * length, but we drop packets that are too large. Perhaps we should
461          * truncate them instead?
462          */
463         if (len + pad > ETHER_MAX_LEN) {
464                 /* packet is obviously too large: toss it */
465                 ++ifp->if_oerrors;
466                 IF_DEQUEUE(&ifp->if_snd, m);
467                 m_freem(m);
468                 goto readcheck;
469         }
470         VX_BUSY_WAIT;
471         if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
472                 CSR_WRITE_2(sc, VX_COMMAND,
473                     SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2));
474                 /* not enough room in FIFO - make sure */
475                 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
476                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
477                         sc->vx_timer = 1;
478                         return;
479                 }
480         }
481         CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2));
482         IF_DEQUEUE(&ifp->if_snd, m);
483         if (m == NULL)          /* not really needed */
484                 return;
485
486         VX_BUSY_WAIT;
487         CSR_WRITE_2(sc, VX_COMMAND, SET_TX_START_THRESH |
488             ((len / 4 + sc->vx_tx_start_thresh) >> 2));
489
490         BPF_MTAP(sc->vx_ifp, m);
491
492         /*
493          * Do the output at splhigh() so that an interrupt from another device
494          * won't cause a FIFO underrun.
495          *
496          * XXX: Can't enforce that anymore.
497          */
498
499         CSR_WRITE_4(sc, VX_W1_TX_PIO_WR_1, len | TX_INDICATE);
500
501         while (m) {
502                 if (m->m_len > 3)
503                         bus_space_write_multi_4(sc->vx_bst, sc->vx_bsh,
504                             VX_W1_TX_PIO_WR_1, (u_int32_t *)mtod(m, caddr_t),
505                             m->m_len / 4);
506                 if (m->m_len & 3)
507                         bus_space_write_multi_1(sc->vx_bst, sc->vx_bsh,
508                             VX_W1_TX_PIO_WR_1,
509                             mtod(m, caddr_t) + (m->m_len & ~3), m->m_len & 3);
510                 m = m_free(m);
511         }
512         while (pad--)
513                 CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0);  /* Padding */
514
515         ++ifp->if_opackets;
516         sc->vx_timer = 1;
517
518 readcheck:
519         if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) {
520                 /* We received a complete packet. */
521
522                 if ((CSR_READ_2(sc, VX_STATUS) & S_INTR_LATCH) == 0) {
523                         /*
524                          * No interrupt, read the packet and continue
525                          * Is this supposed to happen?  Is my motherboard
526                          * completely busted?
527                          */
528                         vx_read(sc);
529                 } else
530                         /*
531                          * Got an interrupt, return so that it gets
532                          * serviced.
533                          */
534                         return;
535         } else {
536                 /* Check if we are stuck and reset [see XXX comment] */
537                 if (vx_status(sc)) {
538                         if (ifp->if_flags & IFF_DEBUG)
539                                 if_printf(ifp, "adapter reset\n");
540                         vx_reset(sc);
541                 }
542         }
543
544         goto startagain;
545 }
546
547 /*
548  * XXX: The 3c509 card can get in a mode where both the fifo status bit
549  *      FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
550  *      We detect this situation and we reset the adapter.
551  *      It happens at times when there is a lot of broadcast traffic
552  *      on the cable (once in a blue moon).
553  */
554 static int
555 vx_status(struct vx_softc *sc)
556 {
557         struct ifnet *ifp;
558         int fifost;
559
560         VX_LOCK_ASSERT(sc);
561
562         /*
563          * Check the FIFO status and act accordingly
564          */
565         GO_WINDOW(4);
566         fifost = CSR_READ_2(sc, VX_W4_FIFO_DIAG);
567         GO_WINDOW(1);
568
569         ifp = sc->vx_ifp;
570         if (fifost & FIFOS_RX_UNDERRUN) {
571                 if (ifp->if_flags & IFF_DEBUG)
572                         if_printf(ifp, "RX underrun\n");
573                 vx_reset(sc);
574                 return 0;
575         }
576         if (fifost & FIFOS_RX_STATUS_OVERRUN) {
577                 if (ifp->if_flags & IFF_DEBUG)
578                         if_printf(ifp, "RX Status overrun\n");
579                 return 1;
580         }
581         if (fifost & FIFOS_RX_OVERRUN) {
582                 if (ifp->if_flags & IFF_DEBUG)
583                         if_printf(ifp, "RX overrun\n");
584                 return 1;
585         }
586         if (fifost & FIFOS_TX_OVERRUN) {
587                 if (ifp->if_flags & IFF_DEBUG)
588                         if_printf(ifp, "TX overrun\n");
589                 vx_reset(sc);
590                 return 0;
591         }
592         return 0;
593 }
594
595 static void
596 vx_txstat(struct vx_softc *sc)
597 {
598         struct ifnet *ifp;
599         int i;
600
601         VX_LOCK_ASSERT(sc);
602
603         /*
604         * We need to read+write TX_STATUS until we get a 0 status
605         * in order to turn off the interrupt flag.
606         */
607         ifp = sc->vx_ifp;
608         while ((i = CSR_READ_1(sc, VX_W1_TX_STATUS)) & TXS_COMPLETE) {
609                 CSR_WRITE_1(sc, VX_W1_TX_STATUS, 0x0);
610
611                 if (i & TXS_JABBER) {
612                         ++ifp->if_oerrors;
613                         if (ifp->if_flags & IFF_DEBUG)
614                                 if_printf(ifp, "jabber (%x)\n", i);
615                         vx_reset(sc);
616                 } else if (i & TXS_UNDERRUN) {
617                         ++ifp->if_oerrors;
618                         if (ifp->if_flags & IFF_DEBUG)
619                                 if_printf(ifp, "fifo underrun (%x) @%d\n", i,
620                                     sc->vx_tx_start_thresh);
621                         if (sc->vx_tx_succ_ok < 100)
622                                 sc->vx_tx_start_thresh =
623                                     min(ETHER_MAX_LEN,
624                                         sc->vx_tx_start_thresh + 20);
625                         sc->vx_tx_succ_ok = 0;
626                         vx_reset(sc);
627                 } else if (i & TXS_MAX_COLLISION) {
628                         ++ifp->if_collisions;
629                         CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE);
630                         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
631                 } else
632                         sc->vx_tx_succ_ok = (sc->vx_tx_succ_ok + 1) & 127;
633         }
634 }
635
636 void
637 vx_intr(void *voidsc)
638 {
639         short status;
640         struct vx_softc *sc = voidsc;
641         struct ifnet *ifp = sc->vx_ifp;
642
643         VX_LOCK(sc);
644         for (;;) {
645                 CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
646
647                 status = CSR_READ_2(sc, VX_STATUS);
648
649                 if ((status & (S_TX_COMPLETE | S_TX_AVAIL |
650                     S_RX_COMPLETE | S_CARD_FAILURE)) == 0)
651                         break;
652
653                 /*
654                  * Acknowledge any interrupts.  It's important that we do this
655                  * first, since there would otherwise be a race condition.
656                  * Due to the i386 interrupt queueing, we may get spurious
657                  * interrupts occasionally.
658                  */
659                 CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | status);
660
661                 if (status & S_RX_COMPLETE)
662                         vx_read(sc);
663                 if (status & S_TX_AVAIL) {
664                         sc->vx_timer = 0;
665                         sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
666                         vx_start_locked(sc->vx_ifp);
667                 }
668                 if (status & S_CARD_FAILURE) {
669                         if_printf(ifp, "adapter failure (%x)\n", status);
670                         sc->vx_timer = 0;
671                         vx_reset(sc);
672                         break;
673                 }
674                 if (status & S_TX_COMPLETE) {
675                         sc->vx_timer = 0;
676                         vx_txstat(sc);
677                         vx_start_locked(ifp);
678                 }
679         }
680         VX_UNLOCK(sc);
681
682         /* no more interrupts */
683         return;
684 }
685
686 static void
687 vx_read(struct vx_softc *sc)
688 {
689         struct ifnet *ifp = sc->vx_ifp;
690         struct mbuf *m;
691         struct ether_header *eh;
692         u_int len;
693
694         VX_LOCK_ASSERT(sc);
695         len = CSR_READ_2(sc, VX_W1_RX_STATUS);
696 again:
697
698         if (ifp->if_flags & IFF_DEBUG) {
699                 int err = len & ERR_MASK;
700                 char *s = NULL;
701
702                 if (len & ERR_INCOMPLETE)
703                         s = "incomplete packet";
704                 else if (err == ERR_OVERRUN)
705                         s = "packet overrun";
706                 else if (err == ERR_RUNT)
707                         s = "runt packet";
708                 else if (err == ERR_ALIGNMENT)
709                         s = "bad alignment";
710                 else if (err == ERR_CRC)
711                         s = "bad crc";
712                 else if (err == ERR_OVERSIZE)
713                         s = "oversized packet";
714                 else if (err == ERR_DRIBBLE)
715                         s = "dribble bits";
716
717                 if (s)
718                         if_printf(ifp, "%s\n", s);
719         }
720         if (len & ERR_INCOMPLETE)
721                 return;
722
723         if (len & ERR_RX) {
724                 ++ifp->if_ierrors;
725                 goto abort;
726         }
727         len &= RX_BYTES_MASK;   /* Lower 11 bits = RX bytes. */
728
729         /* Pull packet off interface. */
730         m = vx_get(sc, len);
731         if (m == 0) {
732                 ifp->if_ierrors++;
733                 goto abort;
734         }
735         ++ifp->if_ipackets;
736
737         {
738                 struct mbuf *m0;
739
740                 m0 = m_devget(mtod(m, char *), m->m_pkthdr.len, ETHER_ALIGN,
741                     ifp, NULL);
742                 if (m0 == NULL) {
743                         ifp->if_ierrors++;
744                         goto abort;
745                 }
746                 m_freem(m);
747                 m = m0;
748         }
749
750         /* We assume the header fit entirely in one mbuf. */
751         eh = mtod(m, struct ether_header *);
752
753         /*
754          * XXX: Some cards seem to be in promiscous mode all the time.
755          * we need to make sure we only get our own stuff always.
756          * bleah!
757          */
758
759         if (!(ifp->if_flags & IFF_PROMISC)
760             && (eh->ether_dhost[0] & 1) == 0    /* !mcast and !bcast */
761             && bcmp(eh->ether_dhost, IF_LLADDR(sc->vx_ifp),
762             ETHER_ADDR_LEN) != 0) {
763                 m_freem(m);
764                 return;
765         }
766         VX_UNLOCK(sc);
767         (*ifp->if_input)(ifp, m);
768         VX_LOCK(sc);
769
770         /*
771         * In periods of high traffic we can actually receive enough
772         * packets so that the fifo overrun bit will be set at this point,
773         * even though we just read a packet. In this case we
774         * are not going to receive any more interrupts. We check for
775         * this condition and read again until the fifo is not full.
776         * We could simplify this test by not using vx_status(), but
777         * rechecking the RX_STATUS register directly. This test could
778         * result in unnecessary looping in cases where there is a new
779         * packet but the fifo is not full, but it will not fix the
780         * stuck behavior.
781         *
782         * Even with this improvement, we still get packet overrun errors
783         * which are hurting performance. Maybe when I get some more time
784         * I'll modify vx_read() so that it can handle RX_EARLY interrupts.
785         */
786         if (vx_status(sc)) {
787                 len = CSR_READ_2(sc, VX_W1_RX_STATUS);
788                 /* Check if we are stuck and reset [see XXX comment] */
789                 if (len & ERR_INCOMPLETE) {
790                         if (ifp->if_flags & IFF_DEBUG)
791                                 if_printf(ifp, "adapter reset\n");
792                         vx_reset(sc);
793                         return;
794                 }
795                 goto again;
796         }
797         return;
798
799 abort:
800         CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
801 }
802
803 static struct mbuf *
804 vx_get(struct vx_softc *sc, u_int totlen)
805 {
806         struct ifnet *ifp = sc->vx_ifp;
807         struct mbuf *top, **mp, *m;
808         int len;
809
810         VX_LOCK_ASSERT(sc);
811         m = sc->vx_mb[sc->vx_next_mb];
812         sc->vx_mb[sc->vx_next_mb] = NULL;
813         if (m == NULL) {
814                 MGETHDR(m, M_NOWAIT, MT_DATA);
815                 if (m == NULL)
816                         return NULL;
817         } else {
818                 /* If the queue is no longer full, refill. */
819                 if (sc->vx_last_mb == sc->vx_next_mb &&
820                     sc->vx_buffill_pending == 0) {
821                         callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill,
822                             sc);
823                         sc->vx_buffill_pending = 1;
824                 }
825                 /* Convert one of our saved mbuf's. */
826                 sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS;
827                 m->m_data = m->m_pktdat;
828                 m->m_flags = M_PKTHDR;
829                 bzero(&m->m_pkthdr, sizeof(m->m_pkthdr));
830         }
831         m->m_pkthdr.rcvif = ifp;
832         m->m_pkthdr.len = totlen;
833         len = MHLEN;
834         top = NULL;
835         mp = &top;
836
837         /*
838          * We read the packet at splhigh() so that an interrupt from another
839          * device doesn't cause the card's buffer to overflow while we're
840          * reading it.  We may still lose packets at other times.
841          *
842          * XXX: Can't enforce this anymore.
843          */
844
845         /*
846          * Since we don't set allowLargePackets bit in MacControl register,
847          * we can assume that totlen <= 1500bytes.
848          * The while loop will be performed iff we have a packet with
849          * MLEN < m_len < MINCLSIZE.
850          */
851         while (totlen > 0) {
852                 if (top) {
853                         m = sc->vx_mb[sc->vx_next_mb];
854                         sc->vx_mb[sc->vx_next_mb] = NULL;
855                         if (m == NULL) {
856                                 MGET(m, M_NOWAIT, MT_DATA);
857                                 if (m == NULL) {
858                                         m_freem(top);
859                                         return NULL;
860                                 }
861                         } else {
862                                 sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS;
863                         }
864                         len = MLEN;
865                 }
866                 if (totlen >= MINCLSIZE) {
867                         MCLGET(m, M_NOWAIT);
868                         if (m->m_flags & M_EXT)
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
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
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
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
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
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
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
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 }