Annotation of sys/dev/ic/dp8390.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: dp8390.c,v 1.39 2007/05/07 18:53:04 deraadt Exp $ */
2: /* $NetBSD: dp8390.c,v 1.13 1998/07/05 06:49:11 jonathan Exp $ */
3:
4: /*
5: * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
6: * adapters.
7: *
8: * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
9: *
10: * Copyright (C) 1993, David Greenman. This software may be used, modified,
11: * copied, distributed, and sold, in both source and binary form provided that
12: * the above copyright and these terms are retained. Under no circumstances is
13: * the author responsible for the proper functioning of this software, nor does
14: * the author assume any responsibility for damages incurred with its use.
15: */
16:
17: #include "bpfilter.h"
18:
19: #include <sys/param.h>
20: #include <sys/systm.h>
21: #include <sys/device.h>
22: #include <sys/errno.h>
23: #include <sys/ioctl.h>
24: #include <sys/mbuf.h>
25: #include <sys/socket.h>
26: #include <sys/syslog.h>
27:
28: #include <net/if.h>
29: #include <net/if_dl.h>
30: #include <net/if_types.h>
31: #include <net/if_media.h>
32:
33: #ifdef INET
34: #include <netinet/in.h>
35: #include <netinet/in_systm.h>
36: #include <netinet/in_var.h>
37: #include <netinet/ip.h>
38: #include <netinet/if_ether.h>
39: #endif
40:
41: #if NBPFILTER > 0
42: #include <net/bpf.h>
43: #endif
44:
45: #include <machine/bus.h>
46:
47: #include <dev/ic/dp8390reg.h>
48: #include <dev/ic/dp8390var.h>
49:
50: #ifdef DEBUG
51: #define __inline__ /* XXX for debugging porpoises */
52: #endif
53:
54: static __inline__ void dp8390_xmit(struct dp8390_softc *);
55:
56: static __inline__ void dp8390_read_hdr(struct dp8390_softc *,
57: int, struct dp8390_ring *);
58: static __inline__ int dp8390_ring_copy(struct dp8390_softc *,
59: int, caddr_t, u_short);
60: static __inline__ int dp8390_write_mbuf(struct dp8390_softc *,
61: struct mbuf *, int);
62:
63: static int dp8390_test_mem(struct dp8390_softc *);
64:
65: int dp8390_enable(struct dp8390_softc *);
66: void dp8390_disable(struct dp8390_softc *);
67:
68: #ifdef DEBUG
69: int dp8390_debug = 0;
70: #endif
71:
72: /*
73: * Standard media init routine for the dp8390.
74: */
75: void
76: dp8390_media_init(struct dp8390_softc *sc)
77: {
78: ifmedia_init(&sc->sc_media, 0, dp8390_mediachange, dp8390_mediastatus);
79: ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
80: ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
81: }
82:
83: /*
84: * Do bus-independent setup.
85: */
86: int
87: dp8390_config(struct dp8390_softc *sc)
88: {
89: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
90: int rv;
91:
92: rv = 1;
93:
94: if (!sc->test_mem)
95: sc->test_mem = dp8390_test_mem;
96:
97: /* Allocate one xmit buffer if < 16k, two buffers otherwise. */
98: if ((sc->mem_size < 16384) ||
99: (sc->sc_flags & DP8390_NO_MULTI_BUFFERING))
100: sc->txb_cnt = 1;
101: else if (sc->mem_size < 8192 * 3)
102: sc->txb_cnt = 2;
103: else
104: sc->txb_cnt = 3;
105:
106: sc->tx_page_start = sc->mem_start >> ED_PAGE_SHIFT;
107: sc->rec_page_start = sc->tx_page_start + sc->txb_cnt * ED_TXBUF_SIZE;
108: sc->rec_page_stop = sc->tx_page_start + (sc->mem_size >> ED_PAGE_SHIFT);
109: sc->mem_ring = sc->mem_start + (sc->rec_page_start << ED_PAGE_SHIFT);
110: sc->mem_end = sc->mem_start + sc->mem_size;
111:
112: /* Now zero memory and verify that it is clear. */
113: if ((*sc->test_mem)(sc))
114: goto out;
115:
116: /* Set interface to stopped condition (reset). */
117: dp8390_stop(sc);
118:
119: /* Initialize ifnet structure. */
120: bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
121: ifp->if_softc = sc;
122: ifp->if_start = dp8390_start;
123: ifp->if_ioctl = dp8390_ioctl;
124: if (!ifp->if_watchdog)
125: ifp->if_watchdog = dp8390_watchdog;
126: ifp->if_flags =
127: IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
128: IFQ_SET_READY(&ifp->if_snd);
129:
130: ifp->if_capabilities = IFCAP_VLAN_MTU;
131:
132: /* Print additional info when attached. */
133: printf(", address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
134:
135: /* Initialize media goo. */
136: (*sc->sc_media_init)(sc);
137:
138: /* Attach the interface. */
139: if_attach(ifp);
140: ether_ifattach(ifp);
141:
142: rv = 0;
143: out:
144: return (rv);
145: }
146:
147: /*
148: * Media change callback.
149: */
150: int
151: dp8390_mediachange(struct ifnet *ifp)
152: {
153: struct dp8390_softc *sc = ifp->if_softc;
154:
155: if (sc->sc_mediachange)
156: return ((*sc->sc_mediachange)(sc));
157:
158: return (0);
159: }
160:
161: /*
162: * Media status callback.
163: */
164: void
165: dp8390_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
166: {
167: struct dp8390_softc *sc = ifp->if_softc;
168:
169: if (sc->sc_enabled == 0) {
170: ifmr->ifm_active = IFM_ETHER | IFM_NONE;
171: ifmr->ifm_status = 0;
172: return;
173: }
174:
175: if (sc->sc_mediastatus)
176: (*sc->sc_mediastatus)(sc, ifmr);
177: }
178:
179: /*
180: * Reset interface.
181: */
182: void
183: dp8390_reset(struct dp8390_softc *sc)
184: {
185: int s;
186:
187: s = splnet();
188: dp8390_stop(sc);
189: dp8390_init(sc);
190: splx(s);
191: }
192:
193: /*
194: * Take interface offline.
195: */
196: void
197: dp8390_stop(struct dp8390_softc *sc)
198: {
199: bus_space_tag_t regt = sc->sc_regt;
200: bus_space_handle_t regh = sc->sc_regh;
201: int n = 5000;
202:
203: /* Stop everything on the interface, and select page 0 registers. */
204: NIC_BARRIER(regt, regh);
205: NIC_PUT(regt, regh, ED_P0_CR,
206: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
207: NIC_BARRIER(regt, regh);
208:
209: /*
210: * Wait for interface to enter stopped state, but limit # of checks to
211: * 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but
212: * just in case it's an old one.
213: */
214: while (((NIC_GET(regt, regh,
215: ED_P0_ISR) & ED_ISR_RST) == 0) && --n)
216: DELAY(1);
217:
218: if (sc->stop_card != NULL)
219: (*sc->stop_card)(sc);
220: }
221:
222: /*
223: * Device timeout/watchdog routine. Entered if the device neglects to generate
224: * an interrupt after a transmit has been started on it.
225: */
226:
227: void
228: dp8390_watchdog(struct ifnet *ifp)
229: {
230: struct dp8390_softc *sc = ifp->if_softc;
231:
232: log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
233: ++sc->sc_arpcom.ac_if.if_oerrors;
234:
235: dp8390_reset(sc);
236: }
237:
238: /*
239: * Initialize device.
240: */
241: void
242: dp8390_init(struct dp8390_softc *sc)
243: {
244: bus_space_tag_t regt = sc->sc_regt;
245: bus_space_handle_t regh = sc->sc_regh;
246: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
247: u_int8_t mcaf[8];
248: int i;
249:
250: /*
251: * Initialize the NIC in the exact order outlined in the NS manual.
252: * This init procedure is "mandatory"...don't change what or when
253: * things happen.
254: */
255:
256: /* Reset transmitter flags. */
257: ifp->if_timer = 0;
258:
259: sc->txb_inuse = 0;
260: sc->txb_new = 0;
261: sc->txb_next_tx = 0;
262:
263: /* Set interface for page 0, remote DMA complete, stopped. */
264: NIC_BARRIER(regt, regh);
265: NIC_PUT(regt, regh, ED_P0_CR,
266: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
267: NIC_BARRIER(regt, regh);
268:
269: if (sc->dcr_reg & ED_DCR_LS) {
270: NIC_PUT(regt, regh, ED_P0_DCR, sc->dcr_reg);
271: } else {
272: /*
273: * Set FIFO threshold to 8, No auto-init Remote DMA, byte
274: * order=80x86, byte-wide DMA xfers,
275: */
276: NIC_PUT(regt, regh, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
277: }
278:
279: /* Clear remote byte count registers. */
280: NIC_PUT(regt, regh, ED_P0_RBCR0, 0);
281: NIC_PUT(regt, regh, ED_P0_RBCR1, 0);
282:
283: /* Tell RCR to do nothing for now. */
284: NIC_PUT(regt, regh, ED_P0_RCR, ED_RCR_MON | sc->rcr_proto);
285:
286: /* Place NIC in internal loopback mode. */
287: NIC_PUT(regt, regh, ED_P0_TCR, ED_TCR_LB0);
288:
289: /* Set lower bits of byte addressable framing to 0. */
290: if (sc->is790)
291: NIC_PUT(regt, regh, 0x09, 0);
292:
293: /* Initialize receive buffer ring. */
294: NIC_PUT(regt, regh, ED_P0_BNRY, sc->rec_page_start);
295: NIC_PUT(regt, regh, ED_P0_PSTART, sc->rec_page_start);
296: NIC_PUT(regt, regh, ED_P0_PSTOP, sc->rec_page_stop);
297:
298: /*
299: * Enable the following interrupts: receive/transmit complete,
300: * receive/transmit error, and Receiver OverWrite.
301: *
302: * Counter overflow and Remote DMA complete are *not* enabled.
303: */
304: NIC_PUT(regt, regh, ED_P0_IMR,
305: ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE |
306: ED_IMR_OVWE);
307:
308: /*
309: * Clear all interrupts. A '1' in each bit position clears the
310: * corresponding flag.
311: */
312: NIC_PUT(regt, regh, ED_P0_ISR, 0xff);
313:
314: /* Program command register for page 1. */
315: NIC_BARRIER(regt, regh);
316: NIC_PUT(regt, regh, ED_P0_CR,
317: sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
318: NIC_BARRIER(regt, regh);
319:
320: /* Copy out our station address. */
321: for (i = 0; i < ETHER_ADDR_LEN; ++i)
322: NIC_PUT(regt, regh, ED_P1_PAR0 + i,
323: sc->sc_arpcom.ac_enaddr[i]);
324:
325: /* Set multicast filter on chip. */
326: dp8390_getmcaf(&sc->sc_arpcom, mcaf);
327: for (i = 0; i < 8; i++)
328: NIC_PUT(regt, regh, ED_P1_MAR0 + i, mcaf[i]);
329:
330: /*
331: * Set current page pointer to one page after the boundary pointer, as
332: * recommended in the National manual.
333: */
334: sc->next_packet = sc->rec_page_start + 1;
335: NIC_PUT(regt, regh, ED_P1_CURR, sc->next_packet);
336:
337: /* Program command register for page 0. */
338: NIC_BARRIER(regt, regh);
339: NIC_PUT(regt, regh, ED_P1_CR,
340: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
341: NIC_BARRIER(regt, regh);
342:
343: /* Accept broadcast and multicast packets by default. */
344: i = ED_RCR_AB | ED_RCR_AM | sc->rcr_proto;
345: if (ifp->if_flags & IFF_PROMISC) {
346: /*
347: * Set promiscuous mode. Multicast filter was set earlier so
348: * that we should receive all multicast packets.
349: */
350: i |= ED_RCR_PRO | ED_RCR_AR | ED_RCR_SEP;
351: }
352: NIC_PUT(regt, regh, ED_P0_RCR, i);
353:
354: /* Take interface out of loopback. */
355: NIC_PUT(regt, regh, ED_P0_TCR, 0);
356:
357: /* Do any card-specific initialization, if applicable. */
358: if (sc->init_card)
359: (*sc->init_card)(sc);
360:
361: /* Fire up the interface. */
362: NIC_BARRIER(regt, regh);
363: NIC_PUT(regt, regh, ED_P0_CR,
364: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
365:
366: /* Set 'running' flag, and clear output active flag. */
367: ifp->if_flags |= IFF_RUNNING;
368: ifp->if_flags &= ~IFF_OACTIVE;
369:
370: /* ...and attempt to start output. */
371: dp8390_start(ifp);
372: }
373:
374: /*
375: * This routine actually starts the transmission on the interface.
376: */
377: static __inline__ void
378: dp8390_xmit(struct dp8390_softc *sc)
379: {
380: bus_space_tag_t regt = sc->sc_regt;
381: bus_space_handle_t regh = sc->sc_regh;
382: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
383: u_short len;
384:
385: #ifdef DIAGNOSTIC
386: if ((sc->txb_next_tx + sc->txb_inuse) % sc->txb_cnt != sc->txb_new)
387: panic("dp8390_xmit: desync, next_tx=%d inuse=%d cnt=%d new=%d",
388: sc->txb_next_tx, sc->txb_inuse, sc->txb_cnt, sc->txb_new);
389:
390: if (sc->txb_inuse == 0)
391: panic("dp8390_xmit: no packets to xmit");
392: #endif
393:
394: len = sc->txb_len[sc->txb_next_tx];
395:
396: /* Set NIC for page 0 register access. */
397: NIC_BARRIER(regt, regh);
398: NIC_PUT(regt, regh, ED_P0_CR,
399: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
400: NIC_BARRIER(regt, regh);
401:
402: /* Set TX buffer start page. */
403: NIC_PUT(regt, regh, ED_P0_TPSR, sc->tx_page_start +
404: sc->txb_next_tx * ED_TXBUF_SIZE);
405:
406: /* Set TX length. */
407: NIC_PUT(regt, regh, ED_P0_TBCR0, len);
408: NIC_PUT(regt, regh, ED_P0_TBCR1, len >> 8);
409:
410: /* Set page 0, remote DMA complete, transmit packet, and *start*. */
411: NIC_BARRIER(regt, regh);
412: NIC_PUT(regt, regh, ED_P0_CR,
413: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
414:
415: /* Point to next transmit buffer slot and wrap if necessary. */
416: if (++sc->txb_next_tx == sc->txb_cnt)
417: sc->txb_next_tx = 0;
418:
419: /* Set a timer just in case we never hear from the board again. */
420: ifp->if_timer = 2;
421: }
422:
423: /*
424: * Start output on interface.
425: * We make two assumptions here:
426: * 1) that the current priority is set to splnet _before_ this code
427: * is called *and* is returned to the appropriate priority after
428: * return
429: * 2) that the IFF_OACTIVE flag is checked before this code is called
430: * (i.e. that the output part of the interface is idle)
431: */
432: void
433: dp8390_start(struct ifnet *ifp)
434: {
435: struct dp8390_softc *sc = ifp->if_softc;
436: struct mbuf *m0;
437: int buffer;
438: int len;
439:
440: if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
441: return;
442:
443: outloop:
444: /* See if there is room to put another packet in the buffer. */
445: if (sc->txb_inuse == sc->txb_cnt) {
446: /* No room. Indicate this to the outside world and exit. */
447: ifp->if_flags |= IFF_OACTIVE;
448: return;
449: }
450: IFQ_DEQUEUE(&ifp->if_snd, m0);
451: if (m0 == 0)
452: return;
453:
454: /* We need to use m->m_pkthdr.len, so require the header */
455: if ((m0->m_flags & M_PKTHDR) == 0)
456: panic("dp8390_start: no header mbuf");
457:
458: #if NBPFILTER > 0
459: /* Tap off here if there is a BPF listener. */
460: if (ifp->if_bpf)
461: bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
462: #endif
463:
464: /* txb_new points to next open buffer slot. */
465: buffer = sc->mem_start +
466: ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
467:
468: if (sc->write_mbuf)
469: len = (*sc->write_mbuf)(sc, m0, buffer);
470: else
471: len = dp8390_write_mbuf(sc, m0, buffer);
472:
473: m_freem(m0);
474: sc->txb_len[sc->txb_new] = max(len, ETHER_MIN_LEN - ETHER_CRC_LEN);
475:
476: /* Point to next buffer slot and wrap if necessary. */
477: if (++sc->txb_new == sc->txb_cnt)
478: sc->txb_new = 0;
479:
480: /* Start the first packet transmitting. */
481: if (sc->txb_inuse++ == 0)
482: dp8390_xmit(sc);
483:
484: /* Loop back to the top to possibly buffer more packets. */
485: goto outloop;
486: }
487:
488: /*
489: * Ethernet interface receiver interrupt.
490: */
491: void
492: dp8390_rint(struct dp8390_softc *sc)
493: {
494: bus_space_tag_t regt = sc->sc_regt;
495: bus_space_handle_t regh = sc->sc_regh;
496: struct dp8390_ring packet_hdr;
497: int packet_ptr;
498: u_short len;
499: u_char boundary, current;
500: u_char nlen;
501:
502: loop:
503: /* Set NIC to page 1 registers to get 'current' pointer. */
504: NIC_BARRIER(regt, regh);
505: NIC_PUT(regt, regh, ED_P0_CR,
506: sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
507: NIC_BARRIER(regt, regh);
508:
509: /*
510: * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
511: * it points to where new data has been buffered. The 'CURR' (current)
512: * register points to the logical end of the ring-buffer - i.e. it
513: * points to where additional new data will be added. We loop here
514: * until the logical beginning equals the logical end (or in other
515: * words, until the ring-buffer is empty).
516: */
517: current = NIC_GET(regt, regh, ED_P1_CURR);
518: if (sc->next_packet == current)
519: return;
520:
521: /* Set NIC to page 0 registers to update boundary register. */
522: NIC_BARRIER(regt, regh);
523: NIC_PUT(regt, regh, ED_P1_CR,
524: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
525: NIC_BARRIER(regt, regh);
526:
527: do {
528: /* Get pointer to this buffer's header structure. */
529: packet_ptr = sc->mem_ring +
530: ((sc->next_packet - sc->rec_page_start) << ED_PAGE_SHIFT);
531:
532: if (sc->read_hdr)
533: (*sc->read_hdr)(sc, packet_ptr, &packet_hdr);
534: else
535: dp8390_read_hdr(sc, packet_ptr, &packet_hdr);
536: len = packet_hdr.count;
537:
538: /*
539: * Try do deal with old, buggy chips that sometimes duplicate
540: * the low byte of the length into the high byte. We do this
541: * by simply ignoring the high byte of the length and always
542: * recalculating it.
543: *
544: * NOTE: sc->next_packet is pointing at the current packet.
545: */
546: if (packet_hdr.next_packet >= sc->next_packet)
547: nlen = (packet_hdr.next_packet - sc->next_packet);
548: else
549: nlen = ((packet_hdr.next_packet - sc->rec_page_start) +
550: (sc->rec_page_stop - sc->next_packet));
551: --nlen;
552: if ((len & ED_PAGE_MASK) + sizeof(packet_hdr) > ED_PAGE_SIZE)
553: --nlen;
554: len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
555: #ifdef DIAGNOSTIC
556: if (len != packet_hdr.count) {
557: printf("%s: length does not match "
558: "next packet pointer\n", sc->sc_dev.dv_xname);
559: printf("%s: len %04x nlen %04x start %02x "
560: "first %02x curr %02x next %02x stop %02x\n",
561: sc->sc_dev.dv_xname, packet_hdr.count, len,
562: sc->rec_page_start, sc->next_packet, current,
563: packet_hdr.next_packet, sc->rec_page_stop);
564: }
565: #endif
566:
567: /*
568: * Be fairly liberal about what we allow as a "reasonable"
569: * length so that a [crufty] packet will make it to BPF (and
570: * can thus be analyzed). Note that all that is really
571: * important is that we have a length that will fit into one
572: * mbuf cluster or less; the upper layer protocols can then
573: * figure out the length from their own length field(s).
574: */
575: if (len <= MCLBYTES &&
576: packet_hdr.next_packet >= sc->rec_page_start &&
577: packet_hdr.next_packet < sc->rec_page_stop) {
578: /* Go get packet. */
579: dp8390_read(sc,
580: packet_ptr + sizeof(struct dp8390_ring),
581: len - sizeof(struct dp8390_ring));
582: } else {
583: /* Really BAD. The ring pointers are corrupted. */
584: log(LOG_ERR, "%s: NIC memory corrupt - "
585: "invalid packet length %d\n",
586: sc->sc_dev.dv_xname, len);
587: ++sc->sc_arpcom.ac_if.if_ierrors;
588: dp8390_reset(sc);
589: return;
590: }
591:
592: /* Update next packet pointer. */
593: sc->next_packet = packet_hdr.next_packet;
594:
595: /*
596: * Update NIC boundary pointer - being careful to keep it one
597: * buffer behind (as recommended by NS databook).
598: */
599: boundary = sc->next_packet - 1;
600: if (boundary < sc->rec_page_start)
601: boundary = sc->rec_page_stop - 1;
602: NIC_PUT(regt, regh, ED_P0_BNRY, boundary);
603: } while (sc->next_packet != current);
604:
605: goto loop;
606: }
607:
608: /* Ethernet interface interrupt processor. */
609: int
610: dp8390_intr(void *arg)
611: {
612: struct dp8390_softc *sc = (struct dp8390_softc *)arg;
613: bus_space_tag_t regt = sc->sc_regt;
614: bus_space_handle_t regh = sc->sc_regh;
615: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
616: u_char isr;
617:
618: if (sc->sc_enabled == 0)
619: return (0);
620:
621: /* Set NIC to page 0 registers. */
622: NIC_BARRIER(regt, regh);
623: NIC_PUT(regt, regh, ED_P0_CR,
624: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
625: NIC_BARRIER(regt, regh);
626:
627: isr = NIC_GET(regt, regh, ED_P0_ISR);
628: if (!isr)
629: return (0);
630:
631: /* Loop until there are no more new interrupts. */
632: for (;;) {
633: /*
634: * Reset all the bits that we are 'acknowledging' by writing a
635: * '1' to each bit position that was set.
636: * (Writing a '1' *clears* the bit.)
637: */
638: NIC_PUT(regt, regh, ED_P0_ISR, isr);
639:
640: /* Work around for AX88190 bug */
641: if ((sc->sc_flags & DP8390_DO_AX88190_WORKAROUND) != 0)
642: while ((NIC_GET(regt, regh, ED_P0_ISR) & isr) != 0) {
643: NIC_PUT(regt, regh, ED_P0_ISR, 0);
644: NIC_PUT(regt, regh, ED_P0_ISR, isr);
645: }
646:
647: /*
648: * Handle transmitter interrupts. Handle these first because
649: * the receiver will reset the board under some conditions.
650: *
651: * If the chip was reset while a packet was transmitting, it
652: * may still deliver a TX interrupt. In this case, just ignore
653: * the interrupt.
654: */
655: if (isr & (ED_ISR_PTX | ED_ISR_TXE) &&
656: sc->txb_inuse != 0) {
657: u_char collisions =
658: NIC_GET(regt, regh, ED_P0_NCR) & 0x0f;
659:
660: /*
661: * Check for transmit error. If a TX completed with an
662: * error, we end up throwing the packet away. Really
663: * the only error that is possible is excessive
664: * collisions, and in this case it is best to allow the
665: * automatic mechanisms of TCP to backoff the flow. Of
666: * course, with UDP we're screwed, but this is expected
667: * when a network is heavily loaded.
668: */
669: if (isr & ED_ISR_TXE) {
670: /*
671: * Excessive collisions (16).
672: */
673: if ((NIC_GET(regt, regh, ED_P0_TSR)
674: & ED_TSR_ABT) && (collisions == 0)) {
675: /*
676: * When collisions total 16, the P0_NCR
677: * will indicate 0, and the TSR_ABT is
678: * set.
679: */
680: collisions = 16;
681: }
682:
683: /* Update output errors counter. */
684: ++ifp->if_oerrors;
685: } else {
686: /*
687: * Throw away the non-error status bits.
688: *
689: * XXX
690: * It may be useful to detect loss of carrier
691: * and late collisions here.
692: */
693: (void)NIC_GET(regt, regh, ED_P0_TSR);
694:
695: /*
696: * Update total number of successfully
697: * transmitted packets.
698: */
699: ++ifp->if_opackets;
700: }
701:
702: /* Clear watchdog timer. */
703: ifp->if_timer = 0;
704: ifp->if_flags &= ~IFF_OACTIVE;
705:
706: /*
707: * Add in total number of collisions on last
708: * transmission.
709: */
710: ifp->if_collisions += collisions;
711:
712: /*
713: * Decrement buffer in-use count if not zero (can only
714: * be zero if a transmitter interrupt occurred while not
715: * actually transmitting).
716: * If data is ready to transmit, start it transmitting,
717: * otherwise defer until after handling receiver.
718: */
719: if (--sc->txb_inuse != 0)
720: dp8390_xmit(sc);
721: }
722:
723: /* Handle receiver interrupts. */
724: if (isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) {
725: /*
726: * Overwrite warning. In order to make sure that a
727: * lockup of the local DMA hasn't occurred, we reset
728: * and re-init the NIC. The NSC manual suggests only a
729: * partial reset/re-init is necessary - but some chips
730: * seem to want more. The DMA lockup has been seen
731: * only with early rev chips - Methinks this bug was
732: * fixed in later revs. -DG
733: */
734: if (isr & ED_ISR_OVW) {
735: ++ifp->if_ierrors;
736: #ifdef DEBUG
737: log(LOG_WARNING, "%s: warning - receiver "
738: "ring buffer overrun\n",
739: sc->sc_dev.dv_xname);
740: #endif
741: /* Stop/reset/re-init NIC. */
742: dp8390_reset(sc);
743: } else {
744: /*
745: * Receiver Error. One or more of: CRC error,
746: * frame alignment error FIFO overrun, or
747: * missed packet.
748: */
749: if (isr & ED_ISR_RXE) {
750: ++ifp->if_ierrors;
751: #ifdef DEBUG
752: if (dp8390_debug) {
753: printf("%s: receive error %x\n",
754: sc->sc_dev.dv_xname,
755: NIC_GET(regt, regh,
756: ED_P0_RSR));
757: }
758: #endif
759: }
760:
761: /*
762: * Go get the packet(s)
763: * XXX - Doing this on an error is dubious
764: * because there shouldn't be any data to get
765: * (we've configured the interface to not
766: * accept packets with errors).
767: */
768: if (sc->recv_int)
769: (*sc->recv_int)(sc);
770: else
771: dp8390_rint(sc);
772: }
773: }
774:
775: /*
776: * If it looks like the transmitter can take more data, attempt
777: * to start output on the interface. This is done after
778: * handling the receiver to give the receiver priority.
779: */
780: dp8390_start(ifp);
781:
782: /*
783: * Return NIC CR to standard state: page 0, remote DMA
784: * complete, start (toggling the TXP bit off, even if was just
785: * set in the transmit routine, is *okay* - it is 'edge'
786: * triggered from low to high).
787: */
788: NIC_BARRIER(regt, regh);
789: NIC_PUT(regt, regh, ED_P0_CR,
790: sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
791: NIC_BARRIER(regt, regh);
792:
793: /*
794: * If the Network Talley Counters overflow, read them to reset
795: * them. It appears that old 8390's won't clear the ISR flag
796: * otherwise - resulting in an infinite loop.
797: */
798: if (isr & ED_ISR_CNT) {
799: (void)NIC_GET(regt, regh, ED_P0_CNTR0);
800: (void)NIC_GET(regt, regh, ED_P0_CNTR1);
801: (void)NIC_GET(regt, regh, ED_P0_CNTR2);
802: }
803:
804: isr = NIC_GET(regt, regh, ED_P0_ISR);
805: if (!isr)
806: return (1);
807: }
808: }
809:
810: /*
811: * Process an ioctl request. This code needs some work - it looks pretty ugly.
812: */
813: int
814: dp8390_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
815: {
816: struct dp8390_softc *sc = ifp->if_softc;
817: struct ifaddr *ifa = (struct ifaddr *) data;
818: struct ifreq *ifr = (struct ifreq *) data;
819: int s, error = 0;
820:
821: s = splnet();
822:
823: switch (cmd) {
824:
825: case SIOCSIFADDR:
826: if ((error = dp8390_enable(sc)) != 0)
827: break;
828: ifp->if_flags |= IFF_UP;
829:
830: switch (ifa->ifa_addr->sa_family) {
831: #ifdef INET
832: case AF_INET:
833: dp8390_init(sc);
834: arp_ifinit(&sc->sc_arpcom, ifa);
835: break;
836: #endif
837: default:
838: dp8390_init(sc);
839: break;
840: }
841: break;
842:
843: case SIOCSIFMTU:
844: if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
845: error = EINVAL;
846: } else if (ifp->if_mtu != ifr->ifr_mtu) {
847: ifp->if_mtu = ifr->ifr_mtu;
848: }
849: break;
850:
851: case SIOCSIFFLAGS:
852: if ((ifp->if_flags & IFF_UP) == 0 &&
853: (ifp->if_flags & IFF_RUNNING) != 0) {
854: /*
855: * If interface is marked down and it is running, then
856: * stop it.
857: */
858: dp8390_stop(sc);
859: ifp->if_flags &= ~IFF_RUNNING;
860: dp8390_disable(sc);
861: } else if ((ifp->if_flags & IFF_UP) != 0 &&
862: (ifp->if_flags & IFF_RUNNING) == 0) {
863: /*
864: * If interface is marked up and it is stopped, then
865: * start it.
866: */
867: if ((error = dp8390_enable(sc)) != 0)
868: break;
869: dp8390_init(sc);
870: } else if ((ifp->if_flags & IFF_UP) != 0) {
871: /*
872: * Reset the interface to pick up changes in any other
873: * flags that affect hardware registers.
874: */
875: dp8390_stop(sc);
876: dp8390_init(sc);
877: }
878: break;
879:
880: case SIOCADDMULTI:
881: case SIOCDELMULTI:
882: if (sc->sc_enabled == 0) {
883: error = EIO;
884: break;
885: }
886:
887: /* Update our multicast list. */
888: error = (cmd == SIOCADDMULTI) ?
889: ether_addmulti(ifr, &sc->sc_arpcom) :
890: ether_delmulti(ifr, &sc->sc_arpcom);
891:
892: if (error == ENETRESET) {
893: /*
894: * Multicast list has changed; set the hardware filter
895: * accordingly.
896: */
897: if (ifp->if_flags & IFF_RUNNING) {
898: dp8390_stop(sc); /* XXX for ds_setmcaf? */
899: dp8390_init(sc);
900: }
901: error = 0;
902: }
903: break;
904:
905: case SIOCGIFMEDIA:
906: case SIOCSIFMEDIA:
907: error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
908: break;
909:
910: default:
911: error = EINVAL;
912: break;
913: }
914:
915: splx(s);
916: return (error);
917: }
918:
919: /*
920: * Retrieve packet from buffer memory and send to the next level up via
921: * ether_input(). If there is a BPF listener, give a copy to BPF, too.
922: */
923: void
924: dp8390_read(struct dp8390_softc *sc, int buf, u_short len)
925: {
926: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
927: struct mbuf *m;
928:
929: /* Pull packet off interface. */
930: m = dp8390_get(sc, buf, len);
931: if (m == 0) {
932: ifp->if_ierrors++;
933: return;
934: }
935:
936: ifp->if_ipackets++;
937:
938: #if NBPFILTER > 0
939: /*
940: * Check if there's a BPF listener on this interface.
941: * If so, hand off the raw packet to bpf.
942: */
943: if (ifp->if_bpf)
944: bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
945: #endif
946:
947: ether_input_mbuf(ifp, m);
948: }
949:
950:
951: /*
952: * Supporting routines.
953: */
954:
955: /*
956: * Compute the multicast address filter from the list of multicast addresses we
957: * need to listen to.
958: */
959: void
960: dp8390_getmcaf(struct arpcom *ac, u_int8_t *af)
961: {
962: struct ifnet *ifp = &ac->ac_if;
963: struct ether_multi *enm;
964: u_int32_t crc;
965: int i;
966: struct ether_multistep step;
967:
968: /*
969: * Set up multicast address filter by passing all multicast addresses
970: * through a crc generator, and then using the high order 6 bits as an
971: * index into the 64 bit logical address filter. The high order bit
972: * selects the word, while the rest of the bits select the bit within
973: * the word.
974: */
975:
976: if (ifp->if_flags & IFF_PROMISC) {
977: ifp->if_flags |= IFF_ALLMULTI;
978: for (i = 0; i < 8; i++)
979: af[i] = 0xff;
980: return;
981: }
982: for (i = 0; i < 8; i++)
983: af[i] = 0;
984: ETHER_FIRST_MULTI(step, ac, enm);
985: while (enm != NULL) {
986: if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
987: sizeof(enm->enm_addrlo)) != 0) {
988: /*
989: * We must listen to a range of multicast addresses.
990: * For now, just accept all multicasts, rather than
991: * trying to set only those filter bits needed to match
992: * the range. (At this time, the only use of address
993: * ranges is for IP multicast routing, for which the
994: * range is big enough to require all bits set.)
995: */
996: ifp->if_flags |= IFF_ALLMULTI;
997: for (i = 0; i < 8; i++)
998: af[i] = 0xff;
999: return;
1000: }
1001:
1002: /* Just want the 6 most significant bits. */
1003: crc = ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26;
1004:
1005: /* Turn on the corresponding bit in the filter. */
1006: af[crc >> 3] |= 1 << (crc & 0x7);
1007:
1008: ETHER_NEXT_MULTI(step, enm);
1009: }
1010: ifp->if_flags &= ~IFF_ALLMULTI;
1011: }
1012:
1013: /*
1014: * Copy data from receive buffer to a new mbuf chain allocating mbufs
1015: * as needed. Return pointer to first mbuf in chain.
1016: * sc = dp8390 info (softc)
1017: * src = pointer in dp8390 ring buffer
1018: * total_len = amount of data to copy
1019: */
1020: struct mbuf *
1021: dp8390_get(struct dp8390_softc *sc, int src, u_short total_len)
1022: {
1023: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1024: struct mbuf *m, *m0, *newm;
1025: u_short len;
1026:
1027: MGETHDR(m0, M_DONTWAIT, MT_DATA);
1028: if (m0 == NULL)
1029: return (0);
1030: m0->m_pkthdr.rcvif = ifp;
1031: m0->m_pkthdr.len = total_len;
1032: len = MHLEN;
1033: m = m0;
1034:
1035: while (total_len > 0) {
1036: if (total_len >= MINCLSIZE) {
1037: MCLGET(m, M_DONTWAIT);
1038: if (!(m->m_flags & M_EXT))
1039: goto bad;
1040: len = MCLBYTES;
1041: }
1042:
1043: /*
1044: * Make sure the data after the Ethernet header is aligned.
1045: */
1046: if (m == m0) {
1047: caddr_t newdata = (caddr_t)
1048: ALIGN(m->m_data + sizeof(struct ether_header)) -
1049: sizeof(struct ether_header);
1050: len -= newdata - m->m_data;
1051: m->m_data = newdata;
1052: }
1053:
1054: m->m_len = len = min(total_len, len);
1055: if (sc->ring_copy)
1056: src = (*sc->ring_copy)(sc, src, mtod(m, caddr_t), len);
1057: else
1058: src = dp8390_ring_copy(sc, src, mtod(m, caddr_t), len);
1059:
1060: total_len -= len;
1061: if (total_len > 0) {
1062: MGET(newm, M_DONTWAIT, MT_DATA);
1063: if (newm == NULL)
1064: goto bad;
1065: len = MLEN;
1066: m = m->m_next = newm;
1067: }
1068: }
1069:
1070: return (m0);
1071:
1072: bad:
1073: m_freem(m0);
1074: return (0);
1075: }
1076:
1077:
1078: /*
1079: * Default driver support functions.
1080: *
1081: * NOTE: all support functions assume 8-bit shared memory.
1082: */
1083: /*
1084: * Zero NIC buffer memory and verify that it is clear.
1085: */
1086: static int
1087: dp8390_test_mem(struct dp8390_softc *sc)
1088: {
1089: bus_space_tag_t buft = sc->sc_buft;
1090: bus_space_handle_t bufh = sc->sc_bufh;
1091: int i;
1092:
1093: bus_space_set_region_1(buft, bufh, sc->mem_start, 0, sc->mem_size);
1094:
1095: for (i = 0; i < sc->mem_size; ++i) {
1096: if (bus_space_read_1(buft, bufh, sc->mem_start + i)) {
1097: printf(": failed to clear NIC buffer at offset %x - "
1098: "check configuration\n", (sc->mem_start + i));
1099: return 1;
1100: }
1101: }
1102:
1103: return 0;
1104: }
1105:
1106: /*
1107: * Read a packet header from the ring, given the source offset.
1108: */
1109: static __inline__ void
1110: dp8390_read_hdr(struct dp8390_softc *sc, int src, struct dp8390_ring *hdrp)
1111: {
1112: bus_space_tag_t buft = sc->sc_buft;
1113: bus_space_handle_t bufh = sc->sc_bufh;
1114:
1115: /*
1116: * The byte count includes a 4 byte header that was added by
1117: * the NIC.
1118: */
1119: hdrp->rsr = bus_space_read_1(buft, bufh, src);
1120: hdrp->next_packet = bus_space_read_1(buft, bufh, src + 1);
1121: hdrp->count = bus_space_read_1(buft, bufh, src + 2) |
1122: (bus_space_read_1(buft, bufh, src + 3) << 8);
1123: }
1124:
1125: /*
1126: * Copy `amount' bytes from a packet in the ring buffer to a linear
1127: * destination buffer, given a source offset and destination address.
1128: * Takes into account ring-wrap.
1129: */
1130: static __inline__ int
1131: dp8390_ring_copy(struct dp8390_softc *sc, int src, caddr_t dst, u_short amount)
1132: {
1133: bus_space_tag_t buft = sc->sc_buft;
1134: bus_space_handle_t bufh = sc->sc_bufh;
1135: u_short tmp_amount;
1136:
1137: /* Does copy wrap to lower addr in ring buffer? */
1138: if (src + amount > sc->mem_end) {
1139: tmp_amount = sc->mem_end - src;
1140:
1141: /* Copy amount up to end of NIC memory. */
1142: bus_space_read_region_1(buft, bufh, src, dst, tmp_amount);
1143:
1144: amount -= tmp_amount;
1145: src = sc->mem_ring;
1146: dst += tmp_amount;
1147: }
1148: bus_space_read_region_1(buft, bufh, src, dst, amount);
1149:
1150: return (src + amount);
1151: }
1152:
1153: /*
1154: * Copy a packet from an mbuf to the transmit buffer on the card.
1155: *
1156: * Currently uses an extra buffer/extra memory copy, unless the whole
1157: * packet fits in one mbuf.
1158: */
1159: static __inline__ int
1160: dp8390_write_mbuf(struct dp8390_softc *sc, struct mbuf *m, int buf)
1161: {
1162: bus_space_tag_t buft = sc->sc_buft;
1163: bus_space_handle_t bufh = sc->sc_bufh;
1164: u_char *data;
1165: int len, totlen = 0;
1166:
1167: for (; m ; m = m->m_next) {
1168: data = mtod(m, u_char *);
1169: len = m->m_len;
1170: if (len > 0) {
1171: bus_space_write_region_1(buft, bufh, buf, data, len);
1172: totlen += len;
1173: buf += len;
1174: }
1175: }
1176:
1177: return (totlen);
1178: }
1179:
1180: /*
1181: * Enable power on the interface.
1182: */
1183: int
1184: dp8390_enable(struct dp8390_softc *sc)
1185: {
1186:
1187: if (sc->sc_enabled == 0 && sc->sc_enable != NULL) {
1188: if ((*sc->sc_enable)(sc) != 0) {
1189: printf("%s: device enable failed\n",
1190: sc->sc_dev.dv_xname);
1191: return (EIO);
1192: }
1193: }
1194:
1195: sc->sc_enabled = 1;
1196: return (0);
1197: }
1198:
1199: /*
1200: * Disable power on the interface.
1201: */
1202: void
1203: dp8390_disable(struct dp8390_softc *sc)
1204: {
1205: if (sc->sc_enabled != 0 && sc->sc_disable != NULL) {
1206: (*sc->sc_disable)(sc);
1207: sc->sc_enabled = 0;
1208: }
1209: }
1210:
1211: int
1212: dp8390_detach(struct dp8390_softc *sc, int flags)
1213: {
1214: struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1215:
1216: /* dp8390_disable() checks sc->sc_enabled */
1217: dp8390_disable(sc);
1218:
1219: if (sc->sc_media_fini != NULL)
1220: (*sc->sc_media_fini)(sc);
1221:
1222: /* Delete all reamining media. */
1223: ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY);
1224:
1225: ether_ifdetach(ifp);
1226: if_detach(ifp);
1227:
1228: return (0);
1229: }
CVSweb