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