Add ifpoll, which support hardware TX/RX queues based polling.
[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);
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     ifp->if_flags &= ~IFF_OACTIVE;
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)
386 {
387     struct vx_softc *sc = ifp->if_softc;
388     struct mbuf *m0;
389     int len, pad;
390
391     /* Don't transmit if interface is busy or not running */
392     if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
393         return;
394
395 startagain:
396     /* Sneak a peek at the next packet */
397     m0 = ifq_dequeue(&ifp->if_snd, NULL);
398     if (m0 == NULL)
399         return;
400
401     /* We need to use m->m_pkthdr.len, so require the header */
402     M_ASSERTPKTHDR(m0);
403     len = m0->m_pkthdr.len;
404
405     pad = (4 - len) & 3;
406
407     /*
408      * The 3c509 automatically pads short packets to minimum ethernet length,
409      * but we drop packets that are too large. Perhaps we should truncate
410      * them instead?
411      */
412     if (len + pad > ETHER_MAX_LEN) {
413         /* packet is obviously too large: toss it */
414         ++ifp->if_oerrors;
415         m_freem(m0);
416         goto readcheck;
417     }
418     VX_BUSY_WAIT;
419     if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
420         CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2));
421         /* not enough room in FIFO */
422         if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) { /* make sure */
423             ifp->if_flags |= IFF_OACTIVE;
424             ifp->if_timer = 1;
425             ifq_prepend(&ifp->if_snd, m0);
426             return;
427         }
428     }
429     CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2));
430
431     VX_BUSY_WAIT;
432     CSR_WRITE_2(sc, VX_COMMAND, SET_TX_START_THRESH |
433         ((len / 4 + sc->tx_start_thresh) >> 2));
434
435     BPF_MTAP(ifp, m0);
436
437     /*
438      * Do the output in a critical section so that an interrupt from
439      * another device won't cause a FIFO underrun.
440      */
441     crit_enter();
442
443     CSR_WRITE_4(sc, VX_W1_TX_PIO_WR_1, len | TX_INDICATE);
444
445     while (m0) {
446         if (m0->m_len > 3)
447             bus_space_write_multi_4(sc->vx_btag, sc->vx_bhandle,
448                 VX_W1_TX_PIO_WR_1,
449                 (u_int32_t *)mtod(m0, caddr_t), m0->m_len / 4);
450         if (m0->m_len & 3)
451             bus_space_write_multi_1(sc->vx_btag, sc->vx_bhandle,
452                 VX_W1_TX_PIO_WR_1,
453                 mtod(m0, caddr_t) + (m0->m_len & ~3), m0->m_len & 3);
454         m0 = m_free(m0);
455     }
456     while (pad--)
457         CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0);  /* Padding */
458
459     crit_exit();
460
461     ++ifp->if_opackets;
462     ifp->if_timer = 1;
463
464 readcheck:
465     if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) {
466         /* We received a complete packet. */
467         
468         if ((CSR_READ_2(sc, VX_STATUS) & S_INTR_LATCH) != 0) {
469             /* Got an interrupt, return so that it gets serviced. */
470             return;
471         }
472         /*
473          * No interrupt, read the packet and continue
474          * Is  this supposed to happen? Is my motherboard
475          * completely busted?
476          */
477         vxread(sc);
478     } else {
479         /* Check if we are stuck and reset [see XXX comment] */
480         if (vxstatus(sc)) {
481             if (ifp->if_flags & IFF_DEBUG)
482                if_printf(ifp, "adapter reset\n");
483             vxreset(sc);
484         }
485     }
486
487     goto startagain;
488 }
489
490 /*
491  * XXX: The 3c509 card can get in a mode where both the fifo status bit
492  *      FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
493  *      We detect this situation and we reset the adapter.
494  *      It happens at times when there is a lot of broadcast traffic
495  *      on the cable (once in a blue moon).
496  */
497 static int
498 vxstatus(struct vx_softc *sc)
499 {
500     int fifost;
501     struct ifnet *ifp = &sc->arpcom.ac_if;
502
503     /*
504      * Check the FIFO status and act accordingly
505      */
506     GO_WINDOW(4);
507     fifost = CSR_READ_2(sc, VX_W4_FIFO_DIAG);
508     GO_WINDOW(1);
509
510     if (fifost & FIFOS_RX_UNDERRUN) {
511         if (ifp->if_flags & IFF_DEBUG)
512             if_printf(ifp, "RX underrun\n");
513         vxreset(sc);
514         return 0;
515     }
516
517     if (fifost & FIFOS_RX_STATUS_OVERRUN) {
518         if (ifp->if_flags & IFF_DEBUG)
519             if_printf(ifp, "RX Status overrun\n");
520         return 1;
521     }
522
523     if (fifost & FIFOS_RX_OVERRUN) {
524         if (ifp->if_flags & IFF_DEBUG)
525             if_printf(ifp, "RX overrun\n");
526         return 1;
527     }
528
529     if (fifost & FIFOS_TX_OVERRUN) {
530         if (ifp->if_flags & IFF_DEBUG)
531             if_printf(ifp, "TX overrun\n");
532         vxreset(sc);
533     }
534
535     return 0;
536 }
537
538 static void     
539 vxtxstat(struct vx_softc *sc)
540 {
541         int i;
542         struct ifnet *ifp = &sc->arpcom.ac_if;
543
544         /*
545          * We need to read+write TX_STATUS until we get a 0 status
546          * in order to turn off the interrupt flag.
547          */
548         while ((i = CSR_READ_1(sc, VX_W1_TX_STATUS)) & TXS_COMPLETE) {
549                 CSR_WRITE_1(sc, VX_W1_TX_STATUS, 0x0);
550
551                 if (i & TXS_JABBER) {
552                         ++ifp->if_oerrors;
553                         if (ifp->if_flags & IFF_DEBUG)
554                                 if_printf(ifp, "jabber (%x)\n", i);
555                         vxreset(sc);
556                 } else if (i & TXS_UNDERRUN) {
557                         ++ifp->if_oerrors;
558                         if (ifp->if_flags & IFF_DEBUG) {
559                                 if_printf(ifp, "fifo underrun (%x) @%d\n",
560                                           i, sc->tx_start_thresh);
561                         }
562                         if (sc->tx_succ_ok < 100) {
563                                 sc->tx_start_thresh = min(
564                                     ETHER_MAX_LEN, sc->tx_start_thresh + 20);
565                         }
566                         sc->tx_succ_ok = 0;
567                         vxreset(sc);
568                 } else if (i & TXS_MAX_COLLISION) {
569                         ++ifp->if_collisions;
570                         CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE);
571                         ifp->if_flags &= ~IFF_OACTIVE;
572                 } else {
573                         sc->tx_succ_ok = (sc->tx_succ_ok+1) & 127;
574                 }
575         }
576 }
577
578 void
579 vxintr(void *voidsc)
580 {
581     short status;
582     struct vx_softc *sc = voidsc;
583     struct ifnet *ifp = &sc->arpcom.ac_if;
584
585     for (;;) {
586         CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
587
588         status = CSR_READ_2(sc, VX_STATUS);
589
590         if ((status & (S_TX_COMPLETE | S_TX_AVAIL |
591                 S_RX_COMPLETE | S_CARD_FAILURE)) == 0)
592             break;
593
594         /*
595          * Acknowledge any interrupts.  It's important that we do this
596          * first, since there would otherwise be a race condition.
597          * Due to the i386 interrupt queueing, we may get spurious
598          * interrupts occasionally.
599          */
600         CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | status);
601
602         if (status & S_RX_COMPLETE)
603             vxread(sc);
604         if (status & S_TX_AVAIL) {
605             ifp->if_timer = 0;
606             ifp->if_flags &= ~IFF_OACTIVE;
607             if_devstart(ifp);
608         }
609         if (status & S_CARD_FAILURE) {
610             if_printf(ifp, "adapter failure (%x)\n", status);
611             ifp->if_timer = 0;
612             vxreset(sc);
613             return;
614         }
615         if (status & S_TX_COMPLETE) {
616             ifp->if_timer = 0;
617             vxtxstat(sc);
618             if_devstart(ifp);
619         }
620     }
621     /* no more interrupts */
622 }
623
624 static void
625 vxread(struct vx_softc *sc)
626 {
627     struct ifnet *ifp = &sc->arpcom.ac_if;
628     struct mbuf *m;
629     struct ether_header *eh;
630     u_int len;
631
632     len = CSR_READ_2(sc, VX_W1_RX_STATUS);
633
634 again:
635
636     if (ifp->if_flags & IFF_DEBUG) {
637         int err = len & ERR_MASK;
638         const char *s = NULL;
639
640         if (len & ERR_INCOMPLETE)
641             s = "incomplete packet";
642         else if (err == ERR_OVERRUN)
643             s = "packet overrun";
644         else if (err == ERR_RUNT)
645             s = "runt packet";
646         else if (err == ERR_ALIGNMENT)
647             s = "bad alignment";
648         else if (err == ERR_CRC)
649             s = "bad crc";
650         else if (err == ERR_OVERSIZE)
651             s = "oversized packet";
652         else if (err == ERR_DRIBBLE)
653             s = "dribble bits";
654
655         if (s)
656             if_printf(ifp, "%s\n", s);
657     }
658
659     if (len & ERR_INCOMPLETE)
660         return;
661
662     if (len & ERR_RX) {
663         ++ifp->if_ierrors;
664         goto abort;
665     }
666
667     len &= RX_BYTES_MASK;       /* Lower 11 bits = RX bytes. */
668
669     /* Pull packet off interface. */
670     m = vxget(sc, len);
671     if (m == NULL) {
672         ifp->if_ierrors++;
673         goto abort;
674     }
675
676     ++ifp->if_ipackets;
677
678     /* We assume the header fit entirely in one mbuf. */
679     eh = mtod(m, struct ether_header *);
680
681     /*
682      * XXX: Some cards seem to be in promiscous mode all the time.
683      * we need to make sure we only get our own stuff always.
684      * bleah!
685      */
686
687     if ((eh->ether_dhost[0] & 1) == 0           /* !mcast and !bcast */
688       && bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) != 0) {
689         m_freem(m);
690         return;
691     }
692
693     ifp->if_input(ifp, m);
694
695     /*
696     * In periods of high traffic we can actually receive enough
697     * packets so that the fifo overrun bit will be set at this point,
698     * even though we just read a packet. In this case we
699     * are not going to receive any more interrupts. We check for
700     * this condition and read again until the fifo is not full.
701     * We could simplify this test by not using vxstatus(), but
702     * rechecking the RX_STATUS register directly. This test could
703     * result in unnecessary looping in cases where there is a new
704     * packet but the fifo is not full, but it will not fix the
705     * stuck behavior.
706     *
707     * Even with this improvement, we still get packet overrun errors
708     * which are hurting performance. Maybe when I get some more time
709     * I'll modify vxread() so that it can handle RX_EARLY interrupts.
710     */
711     if (vxstatus(sc)) {
712         len = CSR_READ_2(sc, VX_W1_RX_STATUS);
713         /* Check if we are stuck and reset [see XXX comment] */
714         if (len & ERR_INCOMPLETE) {
715             if (ifp->if_flags & IFF_DEBUG)
716                 if_printf(ifp, "adapter reset\n");
717             vxreset(sc);
718             return;
719         }
720         goto again;
721     }
722
723     return;
724
725 abort:
726     CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
727 }
728
729 static struct mbuf *
730 vxget(struct vx_softc *sc, u_int totlen)
731 {
732     struct ifnet *ifp = &sc->arpcom.ac_if;
733     struct mbuf *top, **mp, *m;
734     int len;
735
736     m = sc->mb[sc->next_mb];
737     sc->mb[sc->next_mb] = NULL;
738     if (m == NULL) {
739         MGETHDR(m, MB_DONTWAIT, MT_DATA);
740         if (m == NULL)
741             return NULL;
742     } else {
743         /* If the queue is no longer full, refill. */
744         if (sc->last_mb == sc->next_mb && sc->buffill_pending == 0) {
745             callout_reset(&sc->vx_timer, 1, vxmbuffill, sc);
746             sc->buffill_pending = 1;
747         }
748         /* Convert one of our saved mbuf's. */
749         sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
750         m->m_data = m->m_pktdat;
751         m->m_flags = M_PKTHDR;
752         bzero(&m->m_pkthdr, sizeof(m->m_pkthdr));
753     }
754     m->m_pkthdr.rcvif = ifp;
755     m->m_pkthdr.len = totlen;
756     len = MHLEN;
757     top = NULL;
758     mp = &top;
759
760     /*
761      * We read the packet in a critical section so that an interrupt
762      * from another device doesn't cause the card's buffer to overflow
763      * while we're reading it.  We may still lose packets at other times.
764      */
765     crit_enter();
766
767     /*
768      * Since we don't set allowLargePackets bit in MacControl register,
769      * we can assume that totlen <= 1500bytes.
770      * The while loop will be performed if we have a packet with
771      * MLEN < m_len < MINCLSIZE.
772      */
773     while (totlen > 0) {
774         if (top) {
775             m = sc->mb[sc->next_mb];
776             sc->mb[sc->next_mb] = NULL;
777             if (m == NULL) {
778                 MGET(m, MB_DONTWAIT, MT_DATA);
779                 if (m == NULL) {
780                     crit_exit();
781                     m_freem(top);
782                     return NULL;
783                 }
784             } else {
785                 sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
786             }
787             len = MLEN;
788         }
789         if (totlen >= MINCLSIZE) {
790             MCLGET(m, MB_DONTWAIT);
791             if (m->m_flags & M_EXT)
792                 len = MCLBYTES;
793         }
794         len = min(totlen, len);
795         if (len > 3)
796             bus_space_read_multi_4(sc->vx_btag, sc->vx_bhandle,
797                 VX_W1_RX_PIO_RD_1, mtod(m, u_int32_t *), len / 4);
798         if (len & 3) {
799             bus_space_read_multi_1(sc->vx_btag, sc->vx_bhandle,
800                 VX_W1_RX_PIO_RD_1, mtod(m, u_int8_t *) + (len & ~3),
801                 len & 3);
802         }
803         m->m_len = len;
804         totlen -= len;
805         *mp = m;
806         mp = &m->m_next;
807     }
808
809     CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
810
811     crit_exit();
812
813     return top;
814 }
815
816
817 static int
818 vxioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
819 {
820     struct vx_softc *sc = ifp->if_softc;
821     struct ifreq *ifr = (struct ifreq *) data;
822     int error = 0;
823
824     switch (cmd) {
825     case SIOCSIFFLAGS:
826         if ((ifp->if_flags & IFF_UP) == 0 &&
827             (ifp->if_flags & IFF_RUNNING) != 0) {
828             /*
829              * If interface is marked up and it is stopped, then
830              * start it.
831              */
832             vxstop(sc);
833             ifp->if_flags &= ~IFF_RUNNING;
834         } else if ((ifp->if_flags & IFF_UP) != 0 &&
835                    (ifp->if_flags & IFF_RUNNING) == 0) {
836             /*
837              * If interface is marked up and it is stopped, then
838              * start it.
839              */
840             vxinit(sc);
841         } else {
842             /*
843              * deal with flags changes:
844              * IFF_MULTICAST, IFF_PROMISC,
845              * IFF_LINK0, IFF_LINK1,
846              */
847             vxsetfilter(sc);
848             vxsetlink(sc);
849         }
850         break;
851
852     case SIOCSIFMTU:
853         /*
854          * Set the interface MTU.
855          */
856         if (ifr->ifr_mtu > ETHERMTU) {
857             error = EINVAL;
858         } else {
859             ifp->if_mtu = ifr->ifr_mtu;
860         }
861         break;
862
863     case SIOCADDMULTI:
864     case SIOCDELMULTI:
865         /*
866          * Multicast list has changed; set the hardware filter
867          * accordingly.
868          */
869         vxreset(sc);
870         error = 0;
871         break;
872
873
874     default:
875         ether_ioctl(ifp, cmd, data);
876         break;
877     }
878     return (error);
879 }
880
881 static void
882 vxreset(struct vx_softc *sc)
883 {
884     vxstop(sc);
885     vxinit(sc);
886 }
887
888 static void
889 vxwatchdog(struct ifnet *ifp)
890 {
891     struct vx_softc *sc = ifp->if_softc;
892
893     if (ifp->if_flags & IFF_DEBUG)
894         if_printf(ifp, "device timeout\n");
895     ifp->if_flags &= ~IFF_OACTIVE;
896     if_devstart(ifp);
897     vxintr(sc);
898 }
899
900 void
901 vxstop(struct vx_softc *sc)
902 {
903     struct ifnet *ifp = &sc->arpcom.ac_if;
904
905     ifp->if_timer = 0;
906
907     CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE);
908     CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
909     VX_BUSY_WAIT;
910     CSR_WRITE_2(sc, VX_COMMAND, TX_DISABLE);
911     CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER);
912     DELAY(800);
913     CSR_WRITE_2(sc, VX_COMMAND, RX_RESET);
914     VX_BUSY_WAIT;
915     CSR_WRITE_2(sc, VX_COMMAND, TX_RESET);
916     VX_BUSY_WAIT;
917     CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
918     CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK);
919     CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK);
920     CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER);
921
922     vxmbufempty(sc);
923 }
924
925 int
926 vxbusyeeprom(struct vx_softc *sc)
927 {
928     int j, i = 100;
929
930     while (i--) {
931         j = CSR_READ_2(sc, VX_W0_EEPROM_COMMAND);
932         if (j & EEPROM_BUSY)
933             DELAY(100);
934         else
935             break;
936     }
937     if (!i) {
938         if_printf(&sc->arpcom.ac_if, "eeprom failed to come ready\n");
939         return (1);
940     }
941     return (0);
942 }
943
944 static void
945 vxmbuffill(void *sp)
946 {
947     struct vx_softc *sc = (struct vx_softc *) sp;
948     struct ifnet *ifp = &sc->arpcom.ac_if;
949
950     lwkt_serialize_enter(ifp->if_serializer);
951     vxmbuffill_serialized(sp);
952     lwkt_serialize_exit(ifp->if_serializer);
953 }
954
955 static void
956 vxmbuffill_serialized(void *sp)
957 {
958     struct vx_softc *sc = (struct vx_softc *) sp;
959     int i;
960
961     i = sc->last_mb;
962     do {
963         if (sc->mb[i] == NULL)
964             MGET(sc->mb[i], MB_DONTWAIT, MT_DATA);
965         if (sc->mb[i] == NULL)
966             break;
967         i = (i + 1) % MAX_MBS;
968     } while (i != sc->next_mb);
969     sc->last_mb = i;
970     /* If the queue was not filled, try again. */
971     if (sc->last_mb != sc->next_mb) {
972         callout_reset(&sc->vx_timer, 1, vxmbuffill, sc);
973         sc->buffill_pending = 1;
974     } else {
975         sc->buffill_pending = 0;
976     }
977 }
978
979 static void
980 vxmbufempty(struct vx_softc *sc)
981 {
982     int i;
983
984     for (i = 0; i < MAX_MBS; i++) {
985         if (sc->mb[i]) {
986             m_freem(sc->mb[i]);
987             sc->mb[i] = NULL;
988         }
989     }
990     sc->last_mb = sc->next_mb = 0;
991     if (sc->buffill_pending != 0)
992         callout_stop(&sc->vx_timer);
993 }