Annotation of src/sys/dev/ic/am7990.c, Revision 1.52
1.52 ! drochner 1: /* $NetBSD: am7990.c,v 1.51 1998/07/21 17:26:45 drochner Exp $ */
1.36 thorpej 2:
3: /*-
4: * Copyright (c) 1997 The NetBSD Foundation, Inc.
5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9: * NASA Ames Research Center.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
1.1 cgd 39:
40: /*-
41: * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
42: * Copyright (c) 1992, 1993
43: * The Regents of the University of California. All rights reserved.
44: *
45: * This code is derived from software contributed to Berkeley by
46: * Ralph Campbell and Rick Macklem.
47: *
48: * Redistribution and use in source and binary forms, with or without
49: * modification, are permitted provided that the following conditions
50: * are met:
51: * 1. Redistributions of source code must retain the above copyright
52: * notice, this list of conditions and the following disclaimer.
53: * 2. Redistributions in binary form must reproduce the above copyright
54: * notice, this list of conditions and the following disclaimer in the
55: * documentation and/or other materials provided with the distribution.
56: * 3. All advertising materials mentioning features or use of this software
57: * must display the following acknowledgement:
58: * This product includes software developed by the University of
59: * California, Berkeley and its contributors.
60: * 4. Neither the name of the University nor the names of its contributors
61: * may be used to endorse or promote products derived from this software
62: * without specific prior written permission.
63: *
64: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
65: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
66: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
67: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
68: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
69: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
70: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
71: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
72: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
73: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
74: * SUCH DAMAGE.
75: *
76: * @(#)if_le.c 8.2 (Berkeley) 11/16/93
77: */
78:
1.19 thorpej 79: #include "bpfilter.h"
1.38 explorer 80: #include "rnd.h"
1.19 thorpej 81:
82: #include <sys/param.h>
83: #include <sys/systm.h>
84: #include <sys/mbuf.h>
85: #include <sys/syslog.h>
86: #include <sys/socket.h>
87: #include <sys/device.h>
88: #include <sys/malloc.h>
1.1 cgd 89: #include <sys/ioctl.h>
90: #include <sys/errno.h>
1.38 explorer 91: #if NRND > 0
1.37 explorer 92: #include <sys/rnd.h>
1.38 explorer 93: #endif
1.1 cgd 94:
1.19 thorpej 95: #include <net/if.h>
1.26 is 96: #include <net/if_dl.h>
97: #include <net/if_ether.h>
1.27 thorpej 98: #include <net/if_media.h>
1.19 thorpej 99:
1.1 cgd 100: #if NBPFILTER > 0
101: #include <net/bpf.h>
102: #include <net/bpfdesc.h>
103: #endif
104:
1.51 drochner 105: #include <dev/ic/lancereg.h>
106: #include <dev/ic/lancevar.h>
1.19 thorpej 107: #include <dev/ic/am7990reg.h>
108: #include <dev/ic/am7990var.h>
109:
1.51 drochner 110: void am7990_meminit __P((struct lance_softc *));
111: void am7990_start __P((struct ifnet *));
112:
113: #if defined(_KERNEL) && !defined(_LKM)
114: #include "opt_ddb.h"
1.1 cgd 115: #endif
116:
1.51 drochner 117: #ifdef DDB
118: #define integrate
119: #define hide
1.39 gwr 120: #else
1.51 drochner 121: #define integrate static __inline
122: #define hide static
1.39 gwr 123: #endif
124:
1.51 drochner 125: integrate void am7990_rint __P((struct lance_softc *));
126: integrate void am7990_tint __P((struct lance_softc *));
1.19 thorpej 127:
1.51 drochner 128: #ifdef LEDEBUG
129: void am7990_recv_print __P((struct lance_softc *, int));
130: void am7990_xmit_print __P((struct lance_softc *, int));
131: #endif
1.13 gwr 132:
1.51 drochner 133: #define ifp (&sc->sc_ethercom.ec_if)
1.19 thorpej 134:
1.1 cgd 135: void
1.19 thorpej 136: am7990_config(sc)
137: struct am7990_softc *sc;
1.1 cgd 138: {
1.25 leo 139: int mem, i;
1.1 cgd 140:
1.51 drochner 141: sc->lsc.sc_meminit = am7990_meminit;
142: sc->lsc.sc_start = am7990_start;
1.1 cgd 143:
1.51 drochner 144: lance_config(&sc->lsc);
1.19 thorpej 145:
1.1 cgd 146: mem = 0;
1.51 drochner 147: sc->lsc.sc_initaddr = mem;
1.1 cgd 148: mem += sizeof(struct leinit);
1.51 drochner 149: sc->lsc.sc_rmdaddr = mem;
150: mem += sizeof(struct lermd) * sc->lsc.sc_nrbuf;
151: sc->lsc.sc_tmdaddr = mem;
152: mem += sizeof(struct letmd) * sc->lsc.sc_ntbuf;
153: for (i = 0; i < sc->lsc.sc_nrbuf; i++, mem += LEBLEN)
154: sc->lsc.sc_rbufaddr[i] = mem;
155: for (i = 0; i < sc->lsc.sc_ntbuf; i++, mem += LEBLEN)
156: sc->lsc.sc_tbufaddr[i] = mem;
1.1 cgd 157: #ifdef notyet
158: if (mem > ...)
159: panic(...);
160: #endif
161: }
162:
163: /*
164: * Set up the initialization block and the descriptor rings.
165: */
166: void
1.19 thorpej 167: am7990_meminit(sc)
1.51 drochner 168: register struct lance_softc *sc;
1.1 cgd 169: {
170: u_long a;
171: int bix;
172: struct leinit init;
173: struct lermd rmd;
174: struct letmd tmd;
1.28 is 175: u_int8_t *myaddr;
1.1 cgd 176:
177: #if NBPFILTER > 0
178: if (ifp->if_flags & IFF_PROMISC)
179: init.init_mode = LE_MODE_NORMAL | LE_MODE_PROM;
180: else
181: #endif
182: init.init_mode = LE_MODE_NORMAL;
1.29 veego 183: if (sc->sc_initmodemedia == 1)
184: init.init_mode |= LE_MODE_PSEL0;
1.28 is 185:
1.39 gwr 186: /*
187: * Update our private copy of the Ethernet address.
188: * We NEED the copy so we can ensure its alignment!
189: */
190: bcopy(LLADDR(ifp->if_sadl), sc->sc_enaddr, 6);
191: myaddr = sc->sc_enaddr;
192:
1.28 is 193: init.init_padr[0] = (myaddr[1] << 8) | myaddr[0];
194: init.init_padr[1] = (myaddr[3] << 8) | myaddr[2];
195: init.init_padr[2] = (myaddr[5] << 8) | myaddr[4];
1.51 drochner 196: lance_setladrf(&sc->sc_ethercom, init.init_ladrf);
1.1 cgd 197:
198: sc->sc_last_rd = 0;
199: sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
200:
201: a = sc->sc_addr + LE_RMDADDR(sc, 0);
202: init.init_rdra = a;
203: init.init_rlen = (a >> 16) | ((ffs(sc->sc_nrbuf) - 1) << 13);
204:
205: a = sc->sc_addr + LE_TMDADDR(sc, 0);
206: init.init_tdra = a;
207: init.init_tlen = (a >> 16) | ((ffs(sc->sc_ntbuf) - 1) << 13);
208:
209: (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init));
210:
211: /*
212: * Set up receive ring descriptors.
213: */
214: for (bix = 0; bix < sc->sc_nrbuf; bix++) {
215: a = sc->sc_addr + LE_RBUFADDR(sc, bix);
216: rmd.rmd0 = a;
217: rmd.rmd1_hadr = a >> 16;
218: rmd.rmd1_bits = LE_R1_OWN;
219: rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
220: rmd.rmd3 = 0;
221: (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix),
222: sizeof(rmd));
223: }
224:
225: /*
226: * Set up transmit ring descriptors.
227: */
228: for (bix = 0; bix < sc->sc_ntbuf; bix++) {
229: a = sc->sc_addr + LE_TBUFADDR(sc, bix);
230: tmd.tmd0 = a;
231: tmd.tmd1_hadr = a >> 16;
232: tmd.tmd1_bits = 0;
233: tmd.tmd2 = 0 | LE_XMD2_ONES;
234: tmd.tmd3 = 0;
235: (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix),
236: sizeof(tmd));
237: }
238: }
239:
240: integrate void
1.19 thorpej 241: am7990_rint(sc)
1.51 drochner 242: struct lance_softc *sc;
1.1 cgd 243: {
244: register int bix;
245: int rp;
246: struct lermd rmd;
247:
248: bix = sc->sc_last_rd;
249:
250: /* Process all buffers with valid data. */
251: for (;;) {
252: rp = LE_RMDADDR(sc, bix);
253: (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
254:
255: if (rmd.rmd1_bits & LE_R1_OWN)
256: break;
257:
258: if (rmd.rmd1_bits & LE_R1_ERR) {
259: if (rmd.rmd1_bits & LE_R1_ENP) {
1.6 mycroft 260: #ifdef LEDEBUG
1.1 cgd 261: if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) {
262: if (rmd.rmd1_bits & LE_R1_FRAM)
1.22 christos 263: printf("%s: framing error\n",
1.1 cgd 264: sc->sc_dev.dv_xname);
265: if (rmd.rmd1_bits & LE_R1_CRC)
1.22 christos 266: printf("%s: crc mismatch\n",
1.1 cgd 267: sc->sc_dev.dv_xname);
268: }
1.6 mycroft 269: #endif
1.1 cgd 270: } else {
271: if (rmd.rmd1_bits & LE_R1_OFLO)
1.22 christos 272: printf("%s: overflow\n",
1.1 cgd 273: sc->sc_dev.dv_xname);
274: }
275: if (rmd.rmd1_bits & LE_R1_BUFF)
1.22 christos 276: printf("%s: receive buffer error\n",
1.1 cgd 277: sc->sc_dev.dv_xname);
1.7 mycroft 278: ifp->if_ierrors++;
1.12 christos 279: } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) !=
1.1 cgd 280: (LE_R1_STP | LE_R1_ENP)) {
1.22 christos 281: printf("%s: dropping chained buffer\n",
1.1 cgd 282: sc->sc_dev.dv_xname);
1.7 mycroft 283: ifp->if_ierrors++;
1.1 cgd 284: } else {
285: #ifdef LEDEBUG
286: if (sc->sc_debug)
1.19 thorpej 287: am7990_recv_print(sc, sc->sc_last_rd);
1.1 cgd 288: #endif
1.51 drochner 289: lance_read(sc, LE_RBUFADDR(sc, bix),
290: (int)rmd.rmd3 - 4);
1.1 cgd 291: }
292:
293: rmd.rmd1_bits = LE_R1_OWN;
294: rmd.rmd2 = -LEBLEN | LE_XMD2_ONES;
295: rmd.rmd3 = 0;
296: (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
297:
298: #ifdef LEDEBUG
299: if (sc->sc_debug)
1.22 christos 300: printf("sc->sc_last_rd = %x, rmd: "
1.16 pk 301: "ladr %04x, hadr %02x, flags %02x, "
302: "bcnt %04x, mcnt %04x\n",
303: sc->sc_last_rd,
304: rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits,
305: rmd.rmd2, rmd.rmd3);
1.1 cgd 306: #endif
307:
308: if (++bix == sc->sc_nrbuf)
309: bix = 0;
310: }
311:
312: sc->sc_last_rd = bix;
313: }
314:
315: integrate void
1.19 thorpej 316: am7990_tint(sc)
1.51 drochner 317: register struct lance_softc *sc;
1.1 cgd 318: {
319: register int bix;
320: struct letmd tmd;
1.9 thorpej 321:
1.1 cgd 322: bix = sc->sc_first_td;
323:
324: for (;;) {
325: if (sc->sc_no_td <= 0)
326: break;
327:
1.50 drochner 328: (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
329: sizeof(tmd));
330:
1.1 cgd 331: #ifdef LEDEBUG
332: if (sc->sc_debug)
1.22 christos 333: printf("trans tmd: "
1.21 christos 334: "ladr %04x, hadr %02x, flags %02x, "
335: "bcnt %04x, mcnt %04x\n",
336: tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits,
337: tmd.tmd2, tmd.tmd3);
1.1 cgd 338: #endif
339:
340: if (tmd.tmd1_bits & LE_T1_OWN)
341: break;
342:
343: ifp->if_flags &= ~IFF_OACTIVE;
344:
345: if (tmd.tmd1_bits & LE_T1_ERR) {
346: if (tmd.tmd3 & LE_T3_BUFF)
1.22 christos 347: printf("%s: transmit buffer error\n",
1.19 thorpej 348: sc->sc_dev.dv_xname);
1.1 cgd 349: else if (tmd.tmd3 & LE_T3_UFLO)
1.22 christos 350: printf("%s: underflow\n", sc->sc_dev.dv_xname);
1.1 cgd 351: if (tmd.tmd3 & (LE_T3_BUFF | LE_T3_UFLO)) {
1.52 ! drochner 352: lance_reset(sc);
1.1 cgd 353: return;
354: }
1.20 abrown 355: if (tmd.tmd3 & LE_T3_LCAR) {
1.27 thorpej 356: sc->sc_havecarrier = 0;
1.20 abrown 357: if (sc->sc_nocarrier)
358: (*sc->sc_nocarrier)(sc);
359: else
1.22 christos 360: printf("%s: lost carrier\n",
1.20 abrown 361: sc->sc_dev.dv_xname);
362: }
1.1 cgd 363: if (tmd.tmd3 & LE_T3_LCOL)
364: ifp->if_collisions++;
365: if (tmd.tmd3 & LE_T3_RTRY) {
1.22 christos 366: printf("%s: excessive collisions, tdr %d\n",
1.19 thorpej 367: sc->sc_dev.dv_xname,
368: tmd.tmd3 & LE_T3_TDR_MASK);
1.1 cgd 369: ifp->if_collisions += 16;
370: }
371: ifp->if_oerrors++;
372: } else {
373: if (tmd.tmd1_bits & LE_T1_ONE)
374: ifp->if_collisions++;
375: else if (tmd.tmd1_bits & LE_T1_MORE)
376: /* Real number is unknown. */
377: ifp->if_collisions += 2;
378: ifp->if_opackets++;
379: }
380:
381: if (++bix == sc->sc_ntbuf)
382: bix = 0;
383:
384: --sc->sc_no_td;
385: }
386:
387: sc->sc_first_td = bix;
388:
1.19 thorpej 389: am7990_start(ifp);
1.1 cgd 390:
391: if (sc->sc_no_td == 0)
392: ifp->if_timer = 0;
393: }
394:
395: /*
396: * Controller interrupt.
397: */
398: int
1.19 thorpej 399: am7990_intr(arg)
1.1 cgd 400: register void *arg;
401: {
1.51 drochner 402: register struct lance_softc *sc = arg;
1.1 cgd 403: register u_int16_t isr;
404:
1.25 leo 405: isr = (*sc->sc_rdcsr)(sc, LE_CSR0) | sc->sc_saved_csr0;
406: sc->sc_saved_csr0 = 0;
1.1 cgd 407: #ifdef LEDEBUG
408: if (sc->sc_debug)
1.22 christos 409: printf("%s: am7990_intr entering with isr=%04x\n",
1.1 cgd 410: sc->sc_dev.dv_xname, isr);
411: #endif
412: if ((isr & LE_C0_INTR) == 0)
413: return (0);
414:
1.19 thorpej 415: (*sc->sc_wrcsr)(sc, LE_CSR0,
1.1 cgd 416: isr & (LE_C0_INEA | LE_C0_BABL | LE_C0_MISS | LE_C0_MERR |
417: LE_C0_RINT | LE_C0_TINT | LE_C0_IDON));
418: if (isr & LE_C0_ERR) {
419: if (isr & LE_C0_BABL) {
1.6 mycroft 420: #ifdef LEDEBUG
1.22 christos 421: printf("%s: babble\n", sc->sc_dev.dv_xname);
1.6 mycroft 422: #endif
1.7 mycroft 423: ifp->if_oerrors++;
1.1 cgd 424: }
425: #if 0
426: if (isr & LE_C0_CERR) {
1.22 christos 427: printf("%s: collision error\n", sc->sc_dev.dv_xname);
1.7 mycroft 428: ifp->if_collisions++;
1.1 cgd 429: }
430: #endif
1.6 mycroft 431: if (isr & LE_C0_MISS) {
432: #ifdef LEDEBUG
1.22 christos 433: printf("%s: missed packet\n", sc->sc_dev.dv_xname);
1.6 mycroft 434: #endif
1.7 mycroft 435: ifp->if_ierrors++;
1.6 mycroft 436: }
1.1 cgd 437: if (isr & LE_C0_MERR) {
1.22 christos 438: printf("%s: memory error\n", sc->sc_dev.dv_xname);
1.51 drochner 439: lance_reset(sc);
1.1 cgd 440: return (1);
441: }
442: }
443:
444: if ((isr & LE_C0_RXON) == 0) {
1.22 christos 445: printf("%s: receiver disabled\n", sc->sc_dev.dv_xname);
1.7 mycroft 446: ifp->if_ierrors++;
1.51 drochner 447: lance_reset(sc);
1.1 cgd 448: return (1);
449: }
450: if ((isr & LE_C0_TXON) == 0) {
1.22 christos 451: printf("%s: transmitter disabled\n", sc->sc_dev.dv_xname);
1.7 mycroft 452: ifp->if_oerrors++;
1.51 drochner 453: lance_reset(sc);
1.1 cgd 454: return (1);
455: }
456:
1.27 thorpej 457: /*
458: * Pretend we have carrier; if we don't this will be cleared
459: * shortly.
460: */
461: sc->sc_havecarrier = 1;
462:
1.1 cgd 463: if (isr & LE_C0_RINT)
1.19 thorpej 464: am7990_rint(sc);
1.1 cgd 465: if (isr & LE_C0_TINT)
1.19 thorpej 466: am7990_tint(sc);
1.37 explorer 467:
1.38 explorer 468: #if NRND > 0
1.37 explorer 469: rnd_add_uint32(&sc->rnd_source, isr);
1.38 explorer 470: #endif
1.1 cgd 471:
472: return (1);
473: }
1.7 mycroft 474:
1.51 drochner 475: #undef ifp
1.27 thorpej 476:
1.1 cgd 477: /*
478: * Setup output on interface.
479: * Get another datagram to send off of the interface queue, and map it to the
480: * interface before starting the output.
481: * Called only at splimp or interrupt level.
482: */
483: void
1.19 thorpej 484: am7990_start(ifp)
1.1 cgd 485: register struct ifnet *ifp;
486: {
1.51 drochner 487: register struct lance_softc *sc = ifp->if_softc;
1.1 cgd 488: register int bix;
489: register struct mbuf *m;
490: struct letmd tmd;
491: int rp;
492: int len;
493:
494: if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
495: return;
496:
497: bix = sc->sc_last_td;
498:
499: for (;;) {
500: rp = LE_TMDADDR(sc, bix);
501: (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd));
502:
503: if (tmd.tmd1_bits & LE_T1_OWN) {
504: ifp->if_flags |= IFF_OACTIVE;
1.22 christos 505: printf("missing buffer, no_td = %d, last_td = %d\n",
1.1 cgd 506: sc->sc_no_td, sc->sc_last_td);
507: }
508:
509: IF_DEQUEUE(&ifp->if_snd, m);
510: if (m == 0)
511: break;
512:
513: #if NBPFILTER > 0
514: /*
515: * If BPF is listening on this interface, let it see the packet
516: * before we commit it to the wire.
517: */
518: if (ifp->if_bpf)
519: bpf_mtap(ifp->if_bpf, m);
520: #endif
521:
522: /*
523: * Copy the mbuf chain into the transmit buffer.
524: */
1.51 drochner 525: len = lance_put(sc, LE_TBUFADDR(sc, bix), m);
1.1 cgd 526:
527: #ifdef LEDEBUG
1.3 mycroft 528: if (len > ETHERMTU + sizeof(struct ether_header))
1.22 christos 529: printf("packet length %d\n", len);
1.1 cgd 530: #endif
531:
532: ifp->if_timer = 5;
533:
534: /*
535: * Init transmit registers, and set transmit start flag.
536: */
537: tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP;
538: tmd.tmd2 = -len | LE_XMD2_ONES;
539: tmd.tmd3 = 0;
540:
541: (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
542:
543: #ifdef LEDEBUG
544: if (sc->sc_debug)
1.19 thorpej 545: am7990_xmit_print(sc, sc->sc_last_td);
1.1 cgd 546: #endif
547:
1.19 thorpej 548: (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
1.1 cgd 549:
550: if (++bix == sc->sc_ntbuf)
551: bix = 0;
552:
553: if (++sc->sc_no_td == sc->sc_ntbuf) {
554: ifp->if_flags |= IFF_OACTIVE;
555: break;
556: }
557:
558: }
559:
560: sc->sc_last_td = bix;
561: }
562:
563: #ifdef LEDEBUG
564: void
1.19 thorpej 565: am7990_recv_print(sc, no)
1.51 drochner 566: struct lance_softc *sc;
1.1 cgd 567: int no;
568: {
569: struct lermd rmd;
570: u_int16_t len;
571: struct ether_header eh;
572:
573: (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd));
574: len = rmd.rmd3;
1.22 christos 575: printf("%s: receive buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
1.1 cgd 576: len);
1.22 christos 577: printf("%s: status %04x\n", sc->sc_dev.dv_xname,
1.19 thorpej 578: (*sc->sc_rdcsr)(sc, LE_CSR0));
1.22 christos 579: printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
1.1 cgd 580: sc->sc_dev.dv_xname,
581: rmd.rmd0, rmd.rmd1_hadr, rmd.rmd1_bits, rmd.rmd2, rmd.rmd3);
582: if (len >= sizeof(eh)) {
583: (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh));
1.22 christos 584: printf("%s: dst %s", sc->sc_dev.dv_xname,
1.16 pk 585: ether_sprintf(eh.ether_dhost));
1.22 christos 586: printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
1.16 pk 587: ntohs(eh.ether_type));
1.1 cgd 588: }
589: }
590:
591: void
1.19 thorpej 592: am7990_xmit_print(sc, no)
1.51 drochner 593: struct lance_softc *sc;
1.1 cgd 594: int no;
595: {
596: struct letmd tmd;
597: u_int16_t len;
598: struct ether_header eh;
599:
600: (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd));
601: len = -tmd.tmd2;
1.22 christos 602: printf("%s: transmit buffer %d, len = %d\n", sc->sc_dev.dv_xname, no,
1.1 cgd 603: len);
1.22 christos 604: printf("%s: status %04x\n", sc->sc_dev.dv_xname,
1.19 thorpej 605: (*sc->sc_rdcsr)(sc, LE_CSR0));
1.22 christos 606: printf("%s: ladr %04x, hadr %02x, flags %02x, bcnt %04x, mcnt %04x\n",
1.1 cgd 607: sc->sc_dev.dv_xname,
608: tmd.tmd0, tmd.tmd1_hadr, tmd.tmd1_bits, tmd.tmd2, tmd.tmd3);
609: if (len >= sizeof(eh)) {
610: (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh));
1.22 christos 611: printf("%s: dst %s", sc->sc_dev.dv_xname,
1.16 pk 612: ether_sprintf(eh.ether_dhost));
1.22 christos 613: printf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
1.1 cgd 614: ntohs(eh.ether_type));
615: }
616: }
617: #endif /* LEDEBUG */
CVSweb <webmaster@jp.NetBSD.org>