FreeBSD/Linux Kernel Cross Reference
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(struct ifnet *);
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 GO_WINDOW(0);
161 CSR_WRITE_2(sc, VX_COMMAND, GLOBAL_RESET);
162 VX_BUSY_WAIT;
163
164 vx_getlink(sc);
165
166 /*
167 * Read the station address from the eeprom
168 */
169 GO_WINDOW(0);
170 for (i = 0; i < 3; i++) {
171 int x;
172
173 if (vx_busy_eeprom(sc)) {
174 mtx_destroy(&sc->vx_mtx);
175 if_free(ifp);
176 return 0;
177 }
178 CSR_WRITE_2(sc, VX_W0_EEPROM_COMMAND, EEPROM_CMD_RD
179 | (EEPROM_OEM_ADDR0 + i));
180 if (vx_busy_eeprom(sc)) {
181 mtx_destroy(&sc->vx_mtx);
182 if_free(ifp);
183 return 0;
184 }
185 x = CSR_READ_2(sc, VX_W0_EEPROM_DATA);
186 eaddr[(i << 1)] = x >> 8;
187 eaddr[(i << 1) + 1] = x;
188 }
189
190 ifp->if_mtu = ETHERMTU;
191 ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
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_watchdog = vx_watchdog;
197 ifp->if_softc = sc;
198
199 ether_ifattach(ifp, eaddr);
200
201 sc->vx_tx_start_thresh = 20; /* probably a good starting point. */
202
203 vx_stop(sc);
204
205 return 1;
206 }
207
208 /*
209 * The order in here seems important. Otherwise we may not receive
210 * interrupts. ?!
211 */
212 static void
213 vx_init(void *xsc)
214 {
215 struct vx_softc *sc = (struct vx_softc *)xsc;
216
217 VX_LOCK(sc);
218 vx_init_locked(sc);
219 VX_UNLOCK(sc);
220 }
221
222 static void
223 vx_init_locked(struct vx_softc *sc)
224 {
225 struct ifnet *ifp = sc->vx_ifp;
226 int i;
227
228 VX_LOCK_ASSERT(sc);
229
230 VX_BUSY_WAIT;
231
232 GO_WINDOW(2);
233
234 for (i = 0; i < 6; i++) /* Reload the ether_addr. */
235 CSR_WRITE_1(sc, VX_W2_ADDR_0 + i, IF_LLADDR(sc->vx_ifp)[i]);
236
237 CSR_WRITE_2(sc, VX_COMMAND, RX_RESET);
238 VX_BUSY_WAIT;
239 CSR_WRITE_2(sc, VX_COMMAND, TX_RESET);
240 VX_BUSY_WAIT;
241
242 GO_WINDOW(1); /* Window 1 is operating window */
243 for (i = 0; i < 31; i++)
244 CSR_READ_1(sc, VX_W1_TX_STATUS);
245
246 CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE |
247 S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
248 CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK | S_CARD_FAILURE |
249 S_RX_COMPLETE | S_TX_COMPLETE | S_TX_AVAIL);
250
251 /*
252 * Attempt to get rid of any stray interrupts that occured during
253 * configuration. On the i386 this isn't possible because one may
254 * already be queued. However, a single stray interrupt is
255 * unimportant.
256 */
257 CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | 0xff);
258
259 vx_setfilter(sc);
260 vx_setlink(sc);
261
262 CSR_WRITE_2(sc, VX_COMMAND, RX_ENABLE);
263 CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE);
264
265 vx_mbuf_fill(sc);
266
267 /* Interface is now `running', with no output active. */
268 ifp->if_drv_flags |= IFF_DRV_RUNNING;
269 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
270
271 /* Attempt to start output, if any. */
272 vx_start_locked(ifp);
273 }
274
275 static void
276 vx_setfilter(struct vx_softc *sc)
277 {
278 struct ifnet *ifp = sc->vx_ifp;
279
280 VX_LOCK_ASSERT(sc);
281 GO_WINDOW(1); /* Window 1 is operating window */
282 CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER |
283 FIL_INDIVIDUAL | FIL_BRDCST | FIL_MULTICAST |
284 ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0));
285 }
286
287 static void
288 vx_getlink(struct vx_softc *sc)
289 {
290 int n, k;
291
292 GO_WINDOW(3);
293 sc->vx_connectors = CSR_READ_2(sc, VX_W3_RESET_OPT) & 0x7f;
294 for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
295 if (sc->vx_connectors & conn_tab[k].bit) {
296 if (n > 0)
297 printf("/");
298 printf("%s", conn_tab[k].name);
299 n++;
300 }
301 }
302 if (sc->vx_connectors == 0) {
303 printf("no connectors!");
304 return;
305 }
306 GO_WINDOW(3);
307 sc->vx_connector =
308 (CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & INTERNAL_CONNECTOR_MASK)
309 >> INTERNAL_CONNECTOR_BITS;
310 if (sc->vx_connector & 0x10) {
311 sc->vx_connector &= 0x0f;
312 printf("[*%s*]", conn_tab[(int)sc->vx_connector].name);
313 printf(": disable 'auto select' with DOS util!");
314 } else {
315 printf("[*%s*]", conn_tab[(int)sc->vx_connector].name);
316 }
317 }
318
319 static void
320 vx_setlink(struct vx_softc *sc)
321 {
322 struct ifnet *ifp = sc->vx_ifp;
323 int i, j, k;
324 char *reason, *warning;
325 static int prev_flags;
326 static signed char prev_conn = -1;
327
328 VX_LOCK_ASSERT(sc);
329 if (prev_conn == -1)
330 prev_conn = sc->vx_connector;
331
332 /*
333 * S.B.
334 *
335 * Now behavior was slightly changed:
336 *
337 * if any of flags link[0-2] is used and its connector is
338 * physically present the following connectors are used:
339 *
340 * link0 - AUI * highest precedence
341 * link1 - BNC
342 * link2 - UTP * lowest precedence
343 *
344 * If none of them is specified then
345 * connector specified in the EEPROM is used
346 * (if present on card or UTP if not).
347 */
348 i = sc->vx_connector; /* default in EEPROM */
349 reason = "default";
350 warning = 0;
351
352 if (ifp->if_flags & IFF_LINK0) {
353 if (sc->vx_connectors & conn_tab[CONNECTOR_AUI].bit) {
354 i = CONNECTOR_AUI;
355 reason = "link0";
356 } else {
357 warning = "aui not present! (link0)";
358 }
359 } else if (ifp->if_flags & IFF_LINK1) {
360 if (sc->vx_connectors & conn_tab[CONNECTOR_BNC].bit) {
361 i = CONNECTOR_BNC;
362 reason = "link1";
363 } else {
364 warning = "bnc not present! (link1)";
365 }
366 } else if (ifp->if_flags & IFF_LINK2) {
367 if (sc->vx_connectors & conn_tab[CONNECTOR_UTP].bit) {
368 i = CONNECTOR_UTP;
369 reason = "link2";
370 } else {
371 warning = "utp not present! (link2)";
372 }
373 } else if ((sc->vx_connectors & conn_tab[(int)sc->vx_connector].bit) == 0) {
374 warning = "strange connector type in EEPROM.";
375 reason = "forced";
376 i = CONNECTOR_UTP;
377 }
378 /* Avoid unnecessary message. */
379 k = (prev_flags ^ ifp->if_flags) & (IFF_LINK0 | IFF_LINK1 | IFF_LINK2);
380 if ((k != 0) || (prev_conn != i)) {
381 if (warning != NULL)
382 if_printf(ifp, "warning: %s\n", warning);
383 if_printf(ifp, "selected %s. (%s)\n", conn_tab[i].name, reason);
384 }
385 /* Set the selected connector. */
386 GO_WINDOW(3);
387 j = CSR_READ_4(sc, VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
388 CSR_WRITE_4(sc, VX_W3_INTERNAL_CFG, j | (i << INTERNAL_CONNECTOR_BITS));
389
390 /* First, disable all. */
391 CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER);
392 DELAY(800);
393 GO_WINDOW(4);
394 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, 0);
395
396 /* Second, enable the selected one. */
397 switch (i) {
398 case CONNECTOR_UTP:
399 GO_WINDOW(4);
400 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, ENABLE_UTP);
401 break;
402 case CONNECTOR_BNC:
403 CSR_WRITE_2(sc, VX_COMMAND, START_TRANSCEIVER);
404 DELAY(800);
405 break;
406 case CONNECTOR_TX:
407 case CONNECTOR_FX:
408 GO_WINDOW(4);
409 CSR_WRITE_2(sc, VX_W4_MEDIA_TYPE, LINKBEAT_ENABLE);
410 break;
411 default: /* AUI and MII fall here */
412 break;
413 }
414 GO_WINDOW(1);
415
416 prev_flags = ifp->if_flags;
417 prev_conn = i;
418 }
419
420 static void
421 vx_start(struct ifnet *ifp)
422 {
423 struct vx_softc *sc = ifp->if_softc;
424
425 VX_LOCK(sc);
426 vx_start_locked(ifp);
427 VX_UNLOCK(sc);
428 }
429
430 static void
431 vx_start_locked(struct ifnet *ifp)
432 {
433 struct vx_softc *sc = ifp->if_softc;
434 struct mbuf *m;
435 int len, pad;
436
437 VX_LOCK_ASSERT(sc);
438
439 /* Don't transmit if interface is busy or not running */
440 if ((sc->vx_ifp->if_drv_flags &
441 (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != IFF_DRV_RUNNING)
442 return;
443
444 startagain:
445 /* Sneak a peek at the next packet */
446 m = ifp->if_snd.ifq_head;
447 if (m == NULL) {
448 return;
449 }
450 /* We need to use m->m_pkthdr.len, so require the header */
451 M_ASSERTPKTHDR(m);
452 len = m->m_pkthdr.len;
453
454 pad = (4 - len) & 3;
455
456 /*
457 * The 3c509 automatically pads short packets to minimum ethernet
458 * length, but we drop packets that are too large. Perhaps we should
459 * truncate them instead?
460 */
461 if (len + pad > ETHER_MAX_LEN) {
462 /* packet is obviously too large: toss it */
463 ++ifp->if_oerrors;
464 IF_DEQUEUE(&ifp->if_snd, m);
465 m_freem(m);
466 goto readcheck;
467 }
468 VX_BUSY_WAIT;
469 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
470 CSR_WRITE_2(sc, VX_COMMAND,
471 SET_TX_AVAIL_THRESH | ((len + pad + 4) >> 2));
472 /* not enough room in FIFO - make sure */
473 if (CSR_READ_2(sc, VX_W1_FREE_TX) < len + pad + 4) {
474 ifp->if_drv_flags |= IFF_DRV_OACTIVE;
475 ifp->if_timer = 1;
476 return;
477 }
478 }
479 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_AVAIL_THRESH | (8188 >> 2));
480 IF_DEQUEUE(&ifp->if_snd, m);
481 if (m == NULL) /* not really needed */
482 return;
483
484 VX_BUSY_WAIT;
485 CSR_WRITE_2(sc, VX_COMMAND, SET_TX_START_THRESH |
486 ((len / 4 + sc->vx_tx_start_thresh) >> 2));
487
488 BPF_MTAP(sc->vx_ifp, m);
489
490 /*
491 * Do the output at splhigh() so that an interrupt from another device
492 * won't cause a FIFO underrun.
493 *
494 * XXX: Can't enforce that anymore.
495 */
496
497 CSR_WRITE_4(sc, VX_W1_TX_PIO_WR_1, len | TX_INDICATE);
498
499 while (m) {
500 if (m->m_len > 3)
501 bus_space_write_multi_4(sc->vx_bst, sc->vx_bsh,
502 VX_W1_TX_PIO_WR_1, (u_int32_t *)mtod(m, caddr_t),
503 m->m_len / 4);
504 if (m->m_len & 3)
505 bus_space_write_multi_1(sc->vx_bst, sc->vx_bsh,
506 VX_W1_TX_PIO_WR_1,
507 mtod(m, caddr_t) + (m->m_len & ~3), m->m_len & 3);
508 m = m_free(m);
509 }
510 while (pad--)
511 CSR_WRITE_1(sc, VX_W1_TX_PIO_WR_1, 0); /* Padding */
512
513 ++ifp->if_opackets;
514 ifp->if_timer = 1;
515
516 readcheck:
517 if ((CSR_READ_2(sc, VX_W1_RX_STATUS) & ERR_INCOMPLETE) == 0) {
518 /* We received a complete packet. */
519
520 if ((CSR_READ_2(sc, VX_STATUS) & S_INTR_LATCH) == 0) {
521 /*
522 * No interrupt, read the packet and continue
523 * Is this supposed to happen? Is my motherboard
524 * completely busted?
525 */
526 vx_read(sc);
527 } else
528 /*
529 * Got an interrupt, return so that it gets
530 * serviced.
531 */
532 return;
533 } else {
534 /* Check if we are stuck and reset [see XXX comment] */
535 if (vx_status(sc)) {
536 if (ifp->if_flags & IFF_DEBUG)
537 if_printf(ifp, "adapter reset\n");
538 vx_reset(sc);
539 }
540 }
541
542 goto startagain;
543 }
544
545 /*
546 * XXX: The 3c509 card can get in a mode where both the fifo status bit
547 * FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set
548 * We detect this situation and we reset the adapter.
549 * It happens at times when there is a lot of broadcast traffic
550 * on the cable (once in a blue moon).
551 */
552 static int
553 vx_status(struct vx_softc *sc)
554 {
555 struct ifnet *ifp;
556 int fifost;
557
558 VX_LOCK_ASSERT(sc);
559
560 /*
561 * Check the FIFO status and act accordingly
562 */
563 GO_WINDOW(4);
564 fifost = CSR_READ_2(sc, VX_W4_FIFO_DIAG);
565 GO_WINDOW(1);
566
567 ifp = sc->vx_ifp;
568 if (fifost & FIFOS_RX_UNDERRUN) {
569 if (ifp->if_flags & IFF_DEBUG)
570 if_printf(ifp, "RX underrun\n");
571 vx_reset(sc);
572 return 0;
573 }
574 if (fifost & FIFOS_RX_STATUS_OVERRUN) {
575 if (ifp->if_flags & IFF_DEBUG)
576 if_printf(ifp, "RX Status overrun\n");
577 return 1;
578 }
579 if (fifost & FIFOS_RX_OVERRUN) {
580 if (ifp->if_flags & IFF_DEBUG)
581 if_printf(ifp, "RX overrun\n");
582 return 1;
583 }
584 if (fifost & FIFOS_TX_OVERRUN) {
585 if (ifp->if_flags & IFF_DEBUG)
586 if_printf(ifp, "TX overrun\n");
587 vx_reset(sc);
588 return 0;
589 }
590 return 0;
591 }
592
593 static void
594 vx_txstat(struct vx_softc *sc)
595 {
596 struct ifnet *ifp;
597 int i;
598
599 VX_LOCK_ASSERT(sc);
600
601 /*
602 * We need to read+write TX_STATUS until we get a 0 status
603 * in order to turn off the interrupt flag.
604 */
605 ifp = sc->vx_ifp;
606 while ((i = CSR_READ_1(sc, VX_W1_TX_STATUS)) & TXS_COMPLETE) {
607 CSR_WRITE_1(sc, VX_W1_TX_STATUS, 0x0);
608
609 if (i & TXS_JABBER) {
610 ++ifp->if_oerrors;
611 if (ifp->if_flags & IFF_DEBUG)
612 if_printf(ifp, "jabber (%x)\n", i);
613 vx_reset(sc);
614 } else if (i & TXS_UNDERRUN) {
615 ++ifp->if_oerrors;
616 if (ifp->if_flags & IFF_DEBUG)
617 if_printf(ifp, "fifo underrun (%x) @%d\n", i,
618 sc->vx_tx_start_thresh);
619 if (sc->vx_tx_succ_ok < 100)
620 sc->vx_tx_start_thresh =
621 min(ETHER_MAX_LEN,
622 sc->vx_tx_start_thresh + 20);
623 sc->vx_tx_succ_ok = 0;
624 vx_reset(sc);
625 } else if (i & TXS_MAX_COLLISION) {
626 ++ifp->if_collisions;
627 CSR_WRITE_2(sc, VX_COMMAND, TX_ENABLE);
628 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
629 } else
630 sc->vx_tx_succ_ok = (sc->vx_tx_succ_ok + 1) & 127;
631 }
632 }
633
634 void
635 vx_intr(void *voidsc)
636 {
637 short status;
638 struct vx_softc *sc = voidsc;
639 struct ifnet *ifp = sc->vx_ifp;
640
641 VX_LOCK(sc);
642 for (;;) {
643 CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
644
645 status = CSR_READ_2(sc, VX_STATUS);
646
647 if ((status & (S_TX_COMPLETE | S_TX_AVAIL |
648 S_RX_COMPLETE | S_CARD_FAILURE)) == 0)
649 break;
650
651 /*
652 * Acknowledge any interrupts. It's important that we do this
653 * first, since there would otherwise be a race condition.
654 * Due to the i386 interrupt queueing, we may get spurious
655 * interrupts occasionally.
656 */
657 CSR_WRITE_2(sc, VX_COMMAND, ACK_INTR | status);
658
659 if (status & S_RX_COMPLETE)
660 vx_read(sc);
661 if (status & S_TX_AVAIL) {
662 ifp->if_timer = 0;
663 sc->vx_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
664 vx_start_locked(sc->vx_ifp);
665 }
666 if (status & S_CARD_FAILURE) {
667 if_printf(ifp, "adapter failure (%x)\n", status);
668 ifp->if_timer = 0;
669 vx_reset(sc);
670 break;
671 }
672 if (status & S_TX_COMPLETE) {
673 ifp->if_timer = 0;
674 vx_txstat(sc);
675 vx_start_locked(ifp);
676 }
677 }
678 VX_UNLOCK(sc);
679
680 /* no more interrupts */
681 return;
682 }
683
684 static void
685 vx_read(struct vx_softc *sc)
686 {
687 struct ifnet *ifp = sc->vx_ifp;
688 struct mbuf *m;
689 struct ether_header *eh;
690 u_int len;
691
692 VX_LOCK_ASSERT(sc);
693 len = CSR_READ_2(sc, VX_W1_RX_STATUS);
694 again:
695
696 if (ifp->if_flags & IFF_DEBUG) {
697 int err = len & ERR_MASK;
698 char *s = NULL;
699
700 if (len & ERR_INCOMPLETE)
701 s = "incomplete packet";
702 else if (err == ERR_OVERRUN)
703 s = "packet overrun";
704 else if (err == ERR_RUNT)
705 s = "runt packet";
706 else if (err == ERR_ALIGNMENT)
707 s = "bad alignment";
708 else if (err == ERR_CRC)
709 s = "bad crc";
710 else if (err == ERR_OVERSIZE)
711 s = "oversized packet";
712 else if (err == ERR_DRIBBLE)
713 s = "dribble bits";
714
715 if (s)
716 if_printf(ifp, "%s\n", s);
717 }
718 if (len & ERR_INCOMPLETE)
719 return;
720
721 if (len & ERR_RX) {
722 ++ifp->if_ierrors;
723 goto abort;
724 }
725 len &= RX_BYTES_MASK; /* Lower 11 bits = RX bytes. */
726
727 /* Pull packet off interface. */
728 m = vx_get(sc, len);
729 if (m == 0) {
730 ifp->if_ierrors++;
731 goto abort;
732 }
733 ++ifp->if_ipackets;
734
735 {
736 struct mbuf *m0;
737
738 m0 = m_devget(mtod(m, char *), m->m_pkthdr.len, ETHER_ALIGN,
739 ifp, NULL);
740 if (m0 == NULL) {
741 ifp->if_ierrors++;
742 goto abort;
743 }
744 m_freem(m);
745 m = m0;
746 }
747
748 /* We assume the header fit entirely in one mbuf. */
749 eh = mtod(m, struct ether_header *);
750
751 /*
752 * XXX: Some cards seem to be in promiscous mode all the time.
753 * we need to make sure we only get our own stuff always.
754 * bleah!
755 */
756
757 if (!(ifp->if_flags & IFF_PROMISC)
758 && (eh->ether_dhost[0] & 1) == 0 /* !mcast and !bcast */
759 && bcmp(eh->ether_dhost, IF_LLADDR(sc->vx_ifp),
760 ETHER_ADDR_LEN) != 0) {
761 m_freem(m);
762 return;
763 }
764 VX_UNLOCK(sc);
765 (*ifp->if_input)(ifp, m);
766 VX_LOCK(sc);
767
768 /*
769 * In periods of high traffic we can actually receive enough
770 * packets so that the fifo overrun bit will be set at this point,
771 * even though we just read a packet. In this case we
772 * are not going to receive any more interrupts. We check for
773 * this condition and read again until the fifo is not full.
774 * We could simplify this test by not using vx_status(), but
775 * rechecking the RX_STATUS register directly. This test could
776 * result in unnecessary looping in cases where there is a new
777 * packet but the fifo is not full, but it will not fix the
778 * stuck behavior.
779 *
780 * Even with this improvement, we still get packet overrun errors
781 * which are hurting performance. Maybe when I get some more time
782 * I'll modify vx_read() so that it can handle RX_EARLY interrupts.
783 */
784 if (vx_status(sc)) {
785 len = CSR_READ_2(sc, VX_W1_RX_STATUS);
786 /* Check if we are stuck and reset [see XXX comment] */
787 if (len & ERR_INCOMPLETE) {
788 if (ifp->if_flags & IFF_DEBUG)
789 if_printf(ifp, "adapter reset\n");
790 vx_reset(sc);
791 return;
792 }
793 goto again;
794 }
795 return;
796
797 abort:
798 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
799 }
800
801 static struct mbuf *
802 vx_get(struct vx_softc *sc, u_int totlen)
803 {
804 struct ifnet *ifp = sc->vx_ifp;
805 struct mbuf *top, **mp, *m;
806 int len;
807
808 VX_LOCK_ASSERT(sc);
809 m = sc->vx_mb[sc->vx_next_mb];
810 sc->vx_mb[sc->vx_next_mb] = NULL;
811 if (m == NULL) {
812 MGETHDR(m, M_DONTWAIT, MT_DATA);
813 if (m == NULL)
814 return NULL;
815 } else {
816 /* If the queue is no longer full, refill. */
817 if (sc->vx_last_mb == sc->vx_next_mb &&
818 sc->vx_buffill_pending == 0) {
819 callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill,
820 sc);
821 sc->vx_buffill_pending = 1;
822 }
823 /* Convert one of our saved mbuf's. */
824 sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS;
825 m->m_data = m->m_pktdat;
826 m->m_flags = M_PKTHDR;
827 bzero(&m->m_pkthdr, sizeof(m->m_pkthdr));
828 }
829 m->m_pkthdr.rcvif = ifp;
830 m->m_pkthdr.len = totlen;
831 len = MHLEN;
832 top = NULL;
833 mp = ⊤
834
835 /*
836 * We read the packet at splhigh() so that an interrupt from another
837 * device doesn't cause the card's buffer to overflow while we're
838 * reading it. We may still lose packets at other times.
839 *
840 * XXX: Can't enforce this anymore.
841 */
842
843 /*
844 * Since we don't set allowLargePackets bit in MacControl register,
845 * we can assume that totlen <= 1500bytes.
846 * The while loop will be performed iff we have a packet with
847 * MLEN < m_len < MINCLSIZE.
848 */
849 while (totlen > 0) {
850 if (top) {
851 m = sc->vx_mb[sc->vx_next_mb];
852 sc->vx_mb[sc->vx_next_mb] = NULL;
853 if (m == NULL) {
854 MGET(m, M_DONTWAIT, MT_DATA);
855 if (m == NULL) {
856 m_freem(top);
857 return NULL;
858 }
859 } else {
860 sc->vx_next_mb = (sc->vx_next_mb + 1) % MAX_MBS;
861 }
862 len = MLEN;
863 }
864 if (totlen >= MINCLSIZE) {
865 MCLGET(m, M_DONTWAIT);
866 if (m->m_flags & M_EXT)
867 len = MCLBYTES;
868 }
869 len = min(totlen, len);
870 if (len > 3)
871 bus_space_read_multi_4(sc->vx_bst, sc->vx_bsh,
872 VX_W1_RX_PIO_RD_1, mtod(m, u_int32_t *), len / 4);
873 if (len & 3) {
874 bus_space_read_multi_1(sc->vx_bst, sc->vx_bsh,
875 VX_W1_RX_PIO_RD_1, mtod(m, u_int8_t *) + (len & ~3),
876 len & 3);
877 }
878 m->m_len = len;
879 totlen -= len;
880 *mp = m;
881 mp = &m->m_next;
882 }
883
884 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
885
886 return top;
887 }
888
889
890 static int
891 vx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
892 {
893 struct vx_softc *sc = ifp->if_softc;
894 struct ifreq *ifr = (struct ifreq *) data;
895 int error = 0;
896
897 switch (cmd) {
898 case SIOCSIFFLAGS:
899 VX_LOCK(sc);
900 if ((ifp->if_flags & IFF_UP) == 0 &&
901 (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
902 /*
903 * If interface is marked up and it is stopped, then
904 * start it.
905 */
906 vx_stop(sc);
907 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
908 } else if ((ifp->if_flags & IFF_UP) != 0 &&
909 (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
910 /*
911 * If interface is marked up and it is stopped, then
912 * start it.
913 */
914 vx_init_locked(sc);
915 } else {
916 /*
917 * deal with flags changes:
918 * IFF_MULTICAST, IFF_PROMISC,
919 * IFF_LINK0, IFF_LINK1,
920 */
921 vx_setfilter(sc);
922 vx_setlink(sc);
923 }
924 VX_UNLOCK(sc);
925 break;
926
927 case SIOCSIFMTU:
928 /*
929 * Set the interface MTU.
930 */
931 VX_LOCK(sc);
932 if (ifr->ifr_mtu > ETHERMTU) {
933 error = EINVAL;
934 } else {
935 ifp->if_mtu = ifr->ifr_mtu;
936 }
937 VX_UNLOCK(sc);
938 break;
939
940 case SIOCADDMULTI:
941 case SIOCDELMULTI:
942 /*
943 * Multicast list has changed; set the hardware filter
944 * accordingly.
945 */
946 VX_LOCK(sc);
947 vx_reset(sc);
948 VX_UNLOCK(sc);
949 error = 0;
950 break;
951
952
953 default:
954 error = ether_ioctl(ifp, cmd, data);
955 break;
956 }
957
958 return (error);
959 }
960
961 static void
962 vx_reset(struct vx_softc *sc)
963 {
964
965 VX_LOCK_ASSERT(sc);
966 vx_stop(sc);
967 vx_init_locked(sc);
968 }
969
970 static void
971 vx_watchdog(struct ifnet *ifp)
972 {
973 struct vx_softc *sc = ifp->if_softc;
974
975 VX_LOCK(sc);
976 if (ifp->if_flags & IFF_DEBUG)
977 if_printf(ifp, "device timeout\n");
978 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
979 vx_start_locked(ifp);
980 vx_intr(sc);
981 VX_UNLOCK(sc);
982 }
983
984 void
985 vx_stop(struct vx_softc *sc)
986 {
987 struct ifnet *ifp = sc->vx_ifp;
988
989 VX_LOCK_ASSERT(sc);
990 ifp->if_timer = 0;
991
992 CSR_WRITE_2(sc, VX_COMMAND, RX_DISABLE);
993 CSR_WRITE_2(sc, VX_COMMAND, RX_DISCARD_TOP_PACK);
994 VX_BUSY_WAIT;
995 CSR_WRITE_2(sc, VX_COMMAND, TX_DISABLE);
996 CSR_WRITE_2(sc, VX_COMMAND, STOP_TRANSCEIVER);
997 DELAY(800);
998 CSR_WRITE_2(sc, VX_COMMAND, RX_RESET);
999 VX_BUSY_WAIT;
1000 CSR_WRITE_2(sc, VX_COMMAND, TX_RESET);
1001 VX_BUSY_WAIT;
1002 CSR_WRITE_2(sc, VX_COMMAND, C_INTR_LATCH);
1003 CSR_WRITE_2(sc, VX_COMMAND, SET_RD_0_MASK);
1004 CSR_WRITE_2(sc, VX_COMMAND, SET_INTR_MASK);
1005 CSR_WRITE_2(sc, VX_COMMAND, SET_RX_FILTER);
1006
1007 vx_mbuf_empty(sc);
1008 }
1009
1010 int
1011 vx_busy_eeprom(struct vx_softc *sc)
1012 {
1013 int j, i = 100;
1014
1015 while (i--) {
1016 j = CSR_READ_2(sc, VX_W0_EEPROM_COMMAND);
1017 if (j & EEPROM_BUSY)
1018 DELAY(100);
1019 else
1020 break;
1021 }
1022 if (!i) {
1023 if_printf(sc->vx_ifp, "eeprom failed to come ready\n");
1024 return (1);
1025 }
1026 return (0);
1027 }
1028
1029 static void
1030 vx_mbuf_fill(void *sp)
1031 {
1032 struct vx_softc *sc = (struct vx_softc *)sp;
1033 int i;
1034
1035 VX_LOCK_ASSERT(sc);
1036 i = sc->vx_last_mb;
1037 do {
1038 if (sc->vx_mb[i] == NULL)
1039 MGET(sc->vx_mb[i], M_DONTWAIT, MT_DATA);
1040 if (sc->vx_mb[i] == NULL)
1041 break;
1042 i = (i + 1) % MAX_MBS;
1043 } while (i != sc->vx_next_mb);
1044 sc->vx_last_mb = i;
1045 /* If the queue was not filled, try again. */
1046 if (sc->vx_last_mb != sc->vx_next_mb) {
1047 callout_reset(&sc->vx_callout, hz / 100, vx_mbuf_fill, sc);
1048 sc->vx_buffill_pending = 1;
1049 } else {
1050 sc->vx_buffill_pending = 0;
1051 }
1052 }
1053
1054 static void
1055 vx_mbuf_empty(struct vx_softc *sc)
1056 {
1057 int i;
1058
1059 VX_LOCK_ASSERT(sc);
1060 for (i = 0; i < MAX_MBS; i++) {
1061 if (sc->vx_mb[i]) {
1062 m_freem(sc->vx_mb[i]);
1063 sc->vx_mb[i] = NULL;
1064 }
1065 }
1066 sc->vx_last_mb = sc->vx_next_mb = 0;
1067 if (sc->vx_buffill_pending != 0)
1068 callout_stop(&sc->vx_callout);
1069 }
Cache object: dc294578a3c2d1b2e8bcaa013b48e5d7
|