1cfa96c6cSSepherosa Ziehau /* $NetBSD: am79900.c,v 1.17 2005/12/24 20:27:29 perry Exp $ */
2cfa96c6cSSepherosa Ziehau /* $FreeBSD: src/sys/dev/le/am79900.c,v 1.3 2006/05/16 21:04:01 marius Exp $ */
3cfa96c6cSSepherosa Ziehau
4cfa96c6cSSepherosa Ziehau /*-
5cfa96c6cSSepherosa Ziehau * Copyright (c) 1997 The NetBSD Foundation, Inc.
6cfa96c6cSSepherosa Ziehau * All rights reserved.
7cfa96c6cSSepherosa Ziehau *
8cfa96c6cSSepherosa Ziehau * This code is derived from software contributed to The NetBSD Foundation
9cfa96c6cSSepherosa Ziehau * by Jason R. Thorpe.
10cfa96c6cSSepherosa Ziehau *
11cfa96c6cSSepherosa Ziehau * Redistribution and use in source and binary forms, with or without
12cfa96c6cSSepherosa Ziehau * modification, are permitted provided that the following conditions
13cfa96c6cSSepherosa Ziehau * are met:
14cfa96c6cSSepherosa Ziehau * 1. Redistributions of source code must retain the above copyright
15cfa96c6cSSepherosa Ziehau * notice, this list of conditions and the following disclaimer.
16cfa96c6cSSepherosa Ziehau * 2. Redistributions in binary form must reproduce the above copyright
17cfa96c6cSSepherosa Ziehau * notice, this list of conditions and the following disclaimer in the
18cfa96c6cSSepherosa Ziehau * documentation and/or other materials provided with the distribution.
19cfa96c6cSSepherosa Ziehau * 3. All advertising materials mentioning features or use of this software
20cfa96c6cSSepherosa Ziehau * must display the following acknowledgement:
21cfa96c6cSSepherosa Ziehau * This product includes software developed by the NetBSD
22cfa96c6cSSepherosa Ziehau * Foundation, Inc. and its contributors.
23cfa96c6cSSepherosa Ziehau * 4. Neither the name of The NetBSD Foundation nor the names of its
24cfa96c6cSSepherosa Ziehau * contributors may be used to endorse or promote products derived
25cfa96c6cSSepherosa Ziehau * from this software without specific prior written permission.
26cfa96c6cSSepherosa Ziehau *
27cfa96c6cSSepherosa Ziehau * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28cfa96c6cSSepherosa Ziehau * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29cfa96c6cSSepherosa Ziehau * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30cfa96c6cSSepherosa Ziehau * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31cfa96c6cSSepherosa Ziehau * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32cfa96c6cSSepherosa Ziehau * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33cfa96c6cSSepherosa Ziehau * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34cfa96c6cSSepherosa Ziehau * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35cfa96c6cSSepherosa Ziehau * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36cfa96c6cSSepherosa Ziehau * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37cfa96c6cSSepherosa Ziehau * POSSIBILITY OF SUCH DAMAGE.
38cfa96c6cSSepherosa Ziehau */
39cfa96c6cSSepherosa Ziehau
40cfa96c6cSSepherosa Ziehau /*-
41cfa96c6cSSepherosa Ziehau * Copyright (c) 1992, 1993
42cfa96c6cSSepherosa Ziehau * The Regents of the University of California. All rights reserved.
43cfa96c6cSSepherosa Ziehau *
44cfa96c6cSSepherosa Ziehau * This code is derived from software contributed to Berkeley by
45cfa96c6cSSepherosa Ziehau * Ralph Campbell and Rick Macklem.
46cfa96c6cSSepherosa Ziehau *
47cfa96c6cSSepherosa Ziehau * Redistribution and use in source and binary forms, with or without
48cfa96c6cSSepherosa Ziehau * modification, are permitted provided that the following conditions
49cfa96c6cSSepherosa Ziehau * are met:
50cfa96c6cSSepherosa Ziehau * 1. Redistributions of source code must retain the above copyright
51cfa96c6cSSepherosa Ziehau * notice, this list of conditions and the following disclaimer.
52cfa96c6cSSepherosa Ziehau * 2. Redistributions in binary form must reproduce the above copyright
53cfa96c6cSSepherosa Ziehau * notice, this list of conditions and the following disclaimer in the
54cfa96c6cSSepherosa Ziehau * documentation and/or other materials provided with the distribution.
55cfa96c6cSSepherosa Ziehau * 3. Neither the name of the University nor the names of its contributors
56cfa96c6cSSepherosa Ziehau * may be used to endorse or promote products derived from this software
57cfa96c6cSSepherosa Ziehau * without specific prior written permission.
58cfa96c6cSSepherosa Ziehau *
59cfa96c6cSSepherosa Ziehau * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
60cfa96c6cSSepherosa Ziehau * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61cfa96c6cSSepherosa Ziehau * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62cfa96c6cSSepherosa Ziehau * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
63cfa96c6cSSepherosa Ziehau * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64cfa96c6cSSepherosa Ziehau * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65cfa96c6cSSepherosa Ziehau * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66cfa96c6cSSepherosa Ziehau * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67cfa96c6cSSepherosa Ziehau * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68cfa96c6cSSepherosa Ziehau * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69cfa96c6cSSepherosa Ziehau * SUCH DAMAGE.
70cfa96c6cSSepherosa Ziehau *
71cfa96c6cSSepherosa Ziehau * @(#)if_le.c 8.2 (Berkeley) 11/16/93
72cfa96c6cSSepherosa Ziehau */
73cfa96c6cSSepherosa Ziehau
74cfa96c6cSSepherosa Ziehau /*-
75cfa96c6cSSepherosa Ziehau * Copyright (c) 1998
76cfa96c6cSSepherosa Ziehau * Matthias Drochner. All rights reserved.
77cfa96c6cSSepherosa Ziehau * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
78cfa96c6cSSepherosa Ziehau *
79cfa96c6cSSepherosa Ziehau * This code is derived from software contributed to Berkeley by
80cfa96c6cSSepherosa Ziehau * Ralph Campbell and Rick Macklem.
81cfa96c6cSSepherosa Ziehau *
82cfa96c6cSSepherosa Ziehau * Redistribution and use in source and binary forms, with or without
83cfa96c6cSSepherosa Ziehau * modification, are permitted provided that the following conditions
84cfa96c6cSSepherosa Ziehau * are met:
85cfa96c6cSSepherosa Ziehau * 1. Redistributions of source code must retain the above copyright
86cfa96c6cSSepherosa Ziehau * notice, this list of conditions and the following disclaimer.
87cfa96c6cSSepherosa Ziehau * 2. Redistributions in binary form must reproduce the above copyright
88cfa96c6cSSepherosa Ziehau * notice, this list of conditions and the following disclaimer in the
89cfa96c6cSSepherosa Ziehau * documentation and/or other materials provided with the distribution.
90cfa96c6cSSepherosa Ziehau * 3. All advertising materials mentioning features or use of this software
91cfa96c6cSSepherosa Ziehau * must display the following acknowledgement:
92cfa96c6cSSepherosa Ziehau * This product includes software developed by the University of
93cfa96c6cSSepherosa Ziehau * California, Berkeley and its contributors.
94cfa96c6cSSepherosa Ziehau * 4. Neither the name of the University nor the names of its contributors
95cfa96c6cSSepherosa Ziehau * may be used to endorse or promote products derived from this software
96cfa96c6cSSepherosa Ziehau * without specific prior written permission.
97cfa96c6cSSepherosa Ziehau *
98cfa96c6cSSepherosa Ziehau * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
99cfa96c6cSSepherosa Ziehau * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100cfa96c6cSSepherosa Ziehau * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
101cfa96c6cSSepherosa Ziehau * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
102cfa96c6cSSepherosa Ziehau * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
103cfa96c6cSSepherosa Ziehau * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
104cfa96c6cSSepherosa Ziehau * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
105cfa96c6cSSepherosa Ziehau * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
106cfa96c6cSSepherosa Ziehau * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
107cfa96c6cSSepherosa Ziehau * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
108cfa96c6cSSepherosa Ziehau * SUCH DAMAGE.
109cfa96c6cSSepherosa Ziehau *
110cfa96c6cSSepherosa Ziehau * @(#)if_le.c 8.2 (Berkeley) 11/16/93
111cfa96c6cSSepherosa Ziehau */
112cfa96c6cSSepherosa Ziehau
113cfa96c6cSSepherosa Ziehau #include <sys/param.h>
114cfa96c6cSSepherosa Ziehau #include <sys/bus.h>
115cfa96c6cSSepherosa Ziehau #include <sys/endian.h>
116cfa96c6cSSepherosa Ziehau #include <sys/lock.h>
117cfa96c6cSSepherosa Ziehau #include <sys/mbuf.h>
118cfa96c6cSSepherosa Ziehau #include <sys/socket.h>
119cfa96c6cSSepherosa Ziehau
120cfa96c6cSSepherosa Ziehau #include <net/bpf.h>
121cfa96c6cSSepherosa Ziehau #include <net/ethernet.h>
122cfa96c6cSSepherosa Ziehau #include <net/if.h>
123cfa96c6cSSepherosa Ziehau #include <net/if_arp.h>
124cfa96c6cSSepherosa Ziehau #include <net/if_dl.h>
125cfa96c6cSSepherosa Ziehau #include <net/if_media.h>
126cfa96c6cSSepherosa Ziehau #include <net/if_var.h>
127cfa96c6cSSepherosa Ziehau #include <net/ifq_var.h>
128cfa96c6cSSepherosa Ziehau
129cfa96c6cSSepherosa Ziehau #include <dev/netif/lnc/lancereg.h>
130cfa96c6cSSepherosa Ziehau #include <dev/netif/lnc/lancevar.h>
131cfa96c6cSSepherosa Ziehau #include <dev/netif/lnc/am79900reg.h>
132cfa96c6cSSepherosa Ziehau #include <dev/netif/lnc/am79900var.h>
133cfa96c6cSSepherosa Ziehau
134cfa96c6cSSepherosa Ziehau static void am79900_meminit(struct lance_softc *);
135cfa96c6cSSepherosa Ziehau static void am79900_rint(struct lance_softc *);
136cfa96c6cSSepherosa Ziehau static void am79900_tint(struct lance_softc *);
137cfa96c6cSSepherosa Ziehau static void am79900_start_locked(struct lance_softc *sc);
138cfa96c6cSSepherosa Ziehau
139cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
140cfa96c6cSSepherosa Ziehau static void am79900_recv_print(struct lance_softc *, int);
141cfa96c6cSSepherosa Ziehau static void am79900_xmit_print(struct lance_softc *, int);
142cfa96c6cSSepherosa Ziehau #endif
143cfa96c6cSSepherosa Ziehau
144cfa96c6cSSepherosa Ziehau int
am79900_config(struct am79900_softc * sc,const char * name,int unit)145cfa96c6cSSepherosa Ziehau am79900_config(struct am79900_softc *sc, const char* name, int unit)
146cfa96c6cSSepherosa Ziehau {
147e7a56c3eSSepherosa Ziehau int mem;
148cfa96c6cSSepherosa Ziehau
149cfa96c6cSSepherosa Ziehau sc->lsc.sc_meminit = am79900_meminit;
150cfa96c6cSSepherosa Ziehau sc->lsc.sc_start_locked = am79900_start_locked;
151cfa96c6cSSepherosa Ziehau
152e7a56c3eSSepherosa Ziehau lance_config(&sc->lsc, name, unit);
153cfa96c6cSSepherosa Ziehau
154cfa96c6cSSepherosa Ziehau mem = 0;
155cfa96c6cSSepherosa Ziehau sc->lsc.sc_initaddr = mem;
156cfa96c6cSSepherosa Ziehau mem += sizeof(struct leinit);
157cfa96c6cSSepherosa Ziehau sc->lsc.sc_rmdaddr = mem;
158cfa96c6cSSepherosa Ziehau mem += sizeof(struct lermd) * sc->lsc.sc_nrbuf;
159cfa96c6cSSepherosa Ziehau sc->lsc.sc_tmdaddr = mem;
160cfa96c6cSSepherosa Ziehau mem += sizeof(struct letmd) * sc->lsc.sc_ntbuf;
161cfa96c6cSSepherosa Ziehau sc->lsc.sc_rbufaddr = mem;
162cfa96c6cSSepherosa Ziehau mem += LEBLEN * sc->lsc.sc_nrbuf;
163cfa96c6cSSepherosa Ziehau sc->lsc.sc_tbufaddr = mem;
164cfa96c6cSSepherosa Ziehau mem += LEBLEN * sc->lsc.sc_ntbuf;
165cfa96c6cSSepherosa Ziehau
166cfa96c6cSSepherosa Ziehau if (mem > sc->lsc.sc_memsize)
167cfa96c6cSSepherosa Ziehau panic("%s: memsize", __func__);
168cfa96c6cSSepherosa Ziehau
169cfa96c6cSSepherosa Ziehau return (0);
170cfa96c6cSSepherosa Ziehau }
171cfa96c6cSSepherosa Ziehau
172cfa96c6cSSepherosa Ziehau void
am79900_detach(struct am79900_softc * sc)173cfa96c6cSSepherosa Ziehau am79900_detach(struct am79900_softc *sc)
174cfa96c6cSSepherosa Ziehau {
175cfa96c6cSSepherosa Ziehau
176cfa96c6cSSepherosa Ziehau ether_ifdetach(sc->lsc.ifp);
177cfa96c6cSSepherosa Ziehau }
178cfa96c6cSSepherosa Ziehau
179cfa96c6cSSepherosa Ziehau /*
180cfa96c6cSSepherosa Ziehau * Set up the initialization block and the descriptor rings.
181cfa96c6cSSepherosa Ziehau */
182cfa96c6cSSepherosa Ziehau static void
am79900_meminit(struct lance_softc * sc)183cfa96c6cSSepherosa Ziehau am79900_meminit(struct lance_softc *sc)
184cfa96c6cSSepherosa Ziehau {
185cfa96c6cSSepherosa Ziehau struct ifnet *ifp = sc->ifp;
186cfa96c6cSSepherosa Ziehau struct leinit init;
187cfa96c6cSSepherosa Ziehau struct lermd rmd;
188cfa96c6cSSepherosa Ziehau struct letmd tmd;
189cfa96c6cSSepherosa Ziehau u_long a;
190cfa96c6cSSepherosa Ziehau int bix;
191cfa96c6cSSepherosa Ziehau
192cfa96c6cSSepherosa Ziehau if (ifp->if_flags & IFF_PROMISC)
193cfa96c6cSSepherosa Ziehau init.init_mode = LE_HTOLE32(LE_MODE_NORMAL | LE_MODE_PROM);
194cfa96c6cSSepherosa Ziehau else
195cfa96c6cSSepherosa Ziehau init.init_mode = LE_HTOLE32(LE_MODE_NORMAL);
196cfa96c6cSSepherosa Ziehau
197cfa96c6cSSepherosa Ziehau init.init_mode |= LE_HTOLE32(((ffs(sc->sc_ntbuf) - 1) << 28) |
198cfa96c6cSSepherosa Ziehau ((ffs(sc->sc_nrbuf) - 1) << 20));
199cfa96c6cSSepherosa Ziehau
200cfa96c6cSSepherosa Ziehau init.init_padr[0] = LE_HTOLE32(sc->sc_enaddr[0] |
201cfa96c6cSSepherosa Ziehau (sc->sc_enaddr[1] << 8) | (sc->sc_enaddr[2] << 16) |
202cfa96c6cSSepherosa Ziehau (sc->sc_enaddr[3] << 24));
203cfa96c6cSSepherosa Ziehau init.init_padr[1] = LE_HTOLE32(sc->sc_enaddr[4] |
204cfa96c6cSSepherosa Ziehau (sc->sc_enaddr[5] << 8));
205cfa96c6cSSepherosa Ziehau lance_setladrf(sc, init.init_ladrf);
206cfa96c6cSSepherosa Ziehau
207cfa96c6cSSepherosa Ziehau sc->sc_last_rd = 0;
208cfa96c6cSSepherosa Ziehau sc->sc_first_td = sc->sc_last_td = sc->sc_no_td = 0;
209cfa96c6cSSepherosa Ziehau
210cfa96c6cSSepherosa Ziehau a = sc->sc_addr + LE_RMDADDR(sc, 0);
211cfa96c6cSSepherosa Ziehau init.init_rdra = LE_HTOLE32(a);
212cfa96c6cSSepherosa Ziehau
213cfa96c6cSSepherosa Ziehau a = sc->sc_addr + LE_TMDADDR(sc, 0);
214cfa96c6cSSepherosa Ziehau init.init_tdra = LE_HTOLE32(a);
215cfa96c6cSSepherosa Ziehau
216cfa96c6cSSepherosa Ziehau (*sc->sc_copytodesc)(sc, &init, LE_INITADDR(sc), sizeof(init));
217cfa96c6cSSepherosa Ziehau
218cfa96c6cSSepherosa Ziehau /*
219cfa96c6cSSepherosa Ziehau * Set up receive ring descriptors.
220cfa96c6cSSepherosa Ziehau */
221cfa96c6cSSepherosa Ziehau for (bix = 0; bix < sc->sc_nrbuf; bix++) {
222cfa96c6cSSepherosa Ziehau a = sc->sc_addr + LE_RBUFADDR(sc, bix);
223cfa96c6cSSepherosa Ziehau rmd.rmd0 = LE_HTOLE32(a);
224cfa96c6cSSepherosa Ziehau rmd.rmd1 = LE_HTOLE32(LE_R1_OWN | LE_R1_ONES |
225cfa96c6cSSepherosa Ziehau (-LEBLEN & 0xfff));
226cfa96c6cSSepherosa Ziehau rmd.rmd2 = 0;
227cfa96c6cSSepherosa Ziehau rmd.rmd3 = 0;
228cfa96c6cSSepherosa Ziehau (*sc->sc_copytodesc)(sc, &rmd, LE_RMDADDR(sc, bix),
229cfa96c6cSSepherosa Ziehau sizeof(rmd));
230cfa96c6cSSepherosa Ziehau }
231cfa96c6cSSepherosa Ziehau
232cfa96c6cSSepherosa Ziehau /*
233cfa96c6cSSepherosa Ziehau * Set up transmit ring descriptors.
234cfa96c6cSSepherosa Ziehau */
235cfa96c6cSSepherosa Ziehau for (bix = 0; bix < sc->sc_ntbuf; bix++) {
236cfa96c6cSSepherosa Ziehau a = sc->sc_addr + LE_TBUFADDR(sc, bix);
237cfa96c6cSSepherosa Ziehau tmd.tmd0 = LE_HTOLE32(a);
238cfa96c6cSSepherosa Ziehau tmd.tmd1 = LE_HTOLE32(LE_T1_ONES);
239cfa96c6cSSepherosa Ziehau tmd.tmd2 = 0;
240cfa96c6cSSepherosa Ziehau tmd.tmd3 = 0;
241cfa96c6cSSepherosa Ziehau (*sc->sc_copytodesc)(sc, &tmd, LE_TMDADDR(sc, bix),
242cfa96c6cSSepherosa Ziehau sizeof(tmd));
243cfa96c6cSSepherosa Ziehau }
244cfa96c6cSSepherosa Ziehau }
245cfa96c6cSSepherosa Ziehau
246cfa96c6cSSepherosa Ziehau static void
am79900_rint(struct lance_softc * sc)247cfa96c6cSSepherosa Ziehau am79900_rint(struct lance_softc *sc)
248cfa96c6cSSepherosa Ziehau {
249cfa96c6cSSepherosa Ziehau struct ifnet *ifp = sc->ifp;
250cfa96c6cSSepherosa Ziehau struct mbuf *m;
251cfa96c6cSSepherosa Ziehau struct lermd rmd;
252cfa96c6cSSepherosa Ziehau uint32_t rmd1;
253cfa96c6cSSepherosa Ziehau int bix, rp;
254*afbe4b80SSascha Wildner #if defined(__x86_64__)
255cfa96c6cSSepherosa Ziehau struct ether_header *eh;
256cfa96c6cSSepherosa Ziehau #endif
257cfa96c6cSSepherosa Ziehau
258cfa96c6cSSepherosa Ziehau bix = sc->sc_last_rd;
259cfa96c6cSSepherosa Ziehau
260cfa96c6cSSepherosa Ziehau /* Process all buffers with valid data. */
261cfa96c6cSSepherosa Ziehau for (;;) {
262cfa96c6cSSepherosa Ziehau rp = LE_RMDADDR(sc, bix);
263cfa96c6cSSepherosa Ziehau (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
264cfa96c6cSSepherosa Ziehau
265cfa96c6cSSepherosa Ziehau rmd1 = LE_LE32TOH(rmd.rmd1);
266cfa96c6cSSepherosa Ziehau if (rmd1 & LE_R1_OWN)
267cfa96c6cSSepherosa Ziehau break;
268cfa96c6cSSepherosa Ziehau
269cfa96c6cSSepherosa Ziehau m = NULL;
270cfa96c6cSSepherosa Ziehau if ((rmd1 & (LE_R1_ERR | LE_R1_STP | LE_R1_ENP)) !=
271cfa96c6cSSepherosa Ziehau (LE_R1_STP | LE_R1_ENP)){
272cfa96c6cSSepherosa Ziehau if (rmd1 & LE_R1_ERR) {
273cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
274cfa96c6cSSepherosa Ziehau if (rmd1 & LE_R1_ENP) {
275cfa96c6cSSepherosa Ziehau if ((rmd1 & LE_R1_OFLO) == 0) {
276cfa96c6cSSepherosa Ziehau if (rmd1 & LE_R1_FRAM)
277cfa96c6cSSepherosa Ziehau if_printf(ifp,
278cfa96c6cSSepherosa Ziehau "framing error\n");
279cfa96c6cSSepherosa Ziehau if (rmd1 & LE_R1_CRC)
280cfa96c6cSSepherosa Ziehau if_printf(ifp,
281cfa96c6cSSepherosa Ziehau "crc mismatch\n");
282cfa96c6cSSepherosa Ziehau }
283cfa96c6cSSepherosa Ziehau } else
284cfa96c6cSSepherosa Ziehau if (rmd1 & LE_R1_OFLO)
285cfa96c6cSSepherosa Ziehau if_printf(ifp, "overflow\n");
286cfa96c6cSSepherosa Ziehau #endif
287cfa96c6cSSepherosa Ziehau if (rmd1 & LE_R1_BUFF)
288cfa96c6cSSepherosa Ziehau if_printf(ifp,
289cfa96c6cSSepherosa Ziehau "receive buffer error\n");
290cfa96c6cSSepherosa Ziehau } else if ((rmd1 & (LE_R1_STP | LE_R1_ENP)) !=
291cfa96c6cSSepherosa Ziehau (LE_R1_STP | LE_R1_ENP))
292cfa96c6cSSepherosa Ziehau if_printf(ifp, "dropping chained buffer\n");
293cfa96c6cSSepherosa Ziehau } else {
294cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
295cfa96c6cSSepherosa Ziehau if (sc->sc_flags & LE_DEBUG)
296cfa96c6cSSepherosa Ziehau am79900_recv_print(sc, bix);
297cfa96c6cSSepherosa Ziehau #endif
298cfa96c6cSSepherosa Ziehau /* Pull the packet off the interface. */
299cfa96c6cSSepherosa Ziehau m = lance_get(sc, LE_RBUFADDR(sc, bix),
300cfa96c6cSSepherosa Ziehau (LE_LE32TOH(rmd.rmd2) & 0xfff) - ETHER_CRC_LEN);
301cfa96c6cSSepherosa Ziehau }
302cfa96c6cSSepherosa Ziehau
303cfa96c6cSSepherosa Ziehau rmd.rmd1 = LE_HTOLE32(LE_R1_OWN | LE_R1_ONES |
304cfa96c6cSSepherosa Ziehau (-LEBLEN & 0xfff));
305cfa96c6cSSepherosa Ziehau rmd.rmd2 = 0;
306cfa96c6cSSepherosa Ziehau rmd.rmd3 = 0;
307cfa96c6cSSepherosa Ziehau (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
308cfa96c6cSSepherosa Ziehau
309cfa96c6cSSepherosa Ziehau if (++bix == sc->sc_nrbuf)
310cfa96c6cSSepherosa Ziehau bix = 0;
311cfa96c6cSSepherosa Ziehau
312cfa96c6cSSepherosa Ziehau if (m != NULL) {
313d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, ipackets, 1);
314cfa96c6cSSepherosa Ziehau
315*afbe4b80SSascha Wildner #ifdef __x86_64__
316cfa96c6cSSepherosa Ziehau /*
317cfa96c6cSSepherosa Ziehau * The VMware LANCE does not present IFF_SIMPLEX
318cfa96c6cSSepherosa Ziehau * behavior on multicast packets. Thus drop the
319cfa96c6cSSepherosa Ziehau * packet if it is from ourselves.
320cfa96c6cSSepherosa Ziehau */
321cfa96c6cSSepherosa Ziehau eh = mtod(m, struct ether_header *);
322cfa96c6cSSepherosa Ziehau if (memcmp(eh->ether_shost, sc->sc_enaddr,
323cfa96c6cSSepherosa Ziehau ETHER_ADDR_LEN) == 0) {
324cfa96c6cSSepherosa Ziehau m_freem(m);
325cfa96c6cSSepherosa Ziehau continue;
326cfa96c6cSSepherosa Ziehau }
327cfa96c6cSSepherosa Ziehau #endif
328cfa96c6cSSepherosa Ziehau
329cfa96c6cSSepherosa Ziehau /* Pass the packet up. */
33073029d08SFranco Fichtner ifp->if_input(ifp, m, NULL, -1);
331cfa96c6cSSepherosa Ziehau } else
332d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, ierrors, 1);
333cfa96c6cSSepherosa Ziehau }
334cfa96c6cSSepherosa Ziehau
335cfa96c6cSSepherosa Ziehau sc->sc_last_rd = bix;
336cfa96c6cSSepherosa Ziehau }
337cfa96c6cSSepherosa Ziehau
338cfa96c6cSSepherosa Ziehau static void
am79900_tint(struct lance_softc * sc)339cfa96c6cSSepherosa Ziehau am79900_tint(struct lance_softc *sc)
340cfa96c6cSSepherosa Ziehau {
341cfa96c6cSSepherosa Ziehau struct ifnet *ifp = sc->ifp;
342cfa96c6cSSepherosa Ziehau struct letmd tmd;
343cfa96c6cSSepherosa Ziehau uint32_t tmd1, tmd2;
344cfa96c6cSSepherosa Ziehau int bix;
345cfa96c6cSSepherosa Ziehau
346cfa96c6cSSepherosa Ziehau bix = sc->sc_first_td;
347cfa96c6cSSepherosa Ziehau
348cfa96c6cSSepherosa Ziehau for (;;) {
349cfa96c6cSSepherosa Ziehau if (sc->sc_no_td <= 0)
350cfa96c6cSSepherosa Ziehau break;
351cfa96c6cSSepherosa Ziehau
352cfa96c6cSSepherosa Ziehau (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
353cfa96c6cSSepherosa Ziehau sizeof(tmd));
354cfa96c6cSSepherosa Ziehau
355cfa96c6cSSepherosa Ziehau tmd1 = LE_LE32TOH(tmd.tmd1);
356cfa96c6cSSepherosa Ziehau
357cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
358cfa96c6cSSepherosa Ziehau if (sc->sc_flags & LE_DEBUG)
359cfa96c6cSSepherosa Ziehau if_printf(ifp, "trans tmd: "
360cfa96c6cSSepherosa Ziehau "adr %08x, flags/blen %08x\n",
361cfa96c6cSSepherosa Ziehau LE_LE32TOH(tmd.tmd0), tmd1);
362cfa96c6cSSepherosa Ziehau #endif
363cfa96c6cSSepherosa Ziehau
364cfa96c6cSSepherosa Ziehau if (tmd1 & LE_T1_OWN)
365cfa96c6cSSepherosa Ziehau break;
366cfa96c6cSSepherosa Ziehau
3679ed293e0SSepherosa Ziehau ifq_clr_oactive(&ifp->if_snd);
368cfa96c6cSSepherosa Ziehau
369cfa96c6cSSepherosa Ziehau if (tmd1 & LE_T1_ERR) {
370cfa96c6cSSepherosa Ziehau tmd2 = LE_LE32TOH(tmd.tmd2);
371cfa96c6cSSepherosa Ziehau if (tmd2 & LE_T2_BUFF)
372cfa96c6cSSepherosa Ziehau if_printf(ifp, "transmit buffer error\n");
373cfa96c6cSSepherosa Ziehau else if (tmd2 & LE_T2_UFLO)
374cfa96c6cSSepherosa Ziehau if_printf(ifp, "underflow\n");
375cfa96c6cSSepherosa Ziehau if (tmd2 & (LE_T2_BUFF | LE_T2_UFLO)) {
376cfa96c6cSSepherosa Ziehau lance_init_locked(sc);
377cfa96c6cSSepherosa Ziehau return;
378cfa96c6cSSepherosa Ziehau }
379cfa96c6cSSepherosa Ziehau if (tmd2 & LE_T2_LCAR) {
38074e34c07SSepherosa Ziehau if (sc->sc_flags & LE_CARRIER) {
38174e34c07SSepherosa Ziehau ifp->if_link_state = LINK_STATE_DOWN;
38274e34c07SSepherosa Ziehau if_link_state_change(ifp);
38374e34c07SSepherosa Ziehau }
384cfa96c6cSSepherosa Ziehau sc->sc_flags &= ~LE_CARRIER;
385cfa96c6cSSepherosa Ziehau if (sc->sc_nocarrier)
386cfa96c6cSSepherosa Ziehau (*sc->sc_nocarrier)(sc);
387cfa96c6cSSepherosa Ziehau else
388cfa96c6cSSepherosa Ziehau if_printf(ifp, "lost carrier\n");
389cfa96c6cSSepherosa Ziehau }
390cfa96c6cSSepherosa Ziehau if (tmd2 & LE_T2_LCOL)
391d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, collisions, 1);
392cfa96c6cSSepherosa Ziehau if (tmd2 & LE_T2_RTRY) {
393cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
394cfa96c6cSSepherosa Ziehau if_printf(ifp, "excessive collisions\n");
395cfa96c6cSSepherosa Ziehau #endif
396d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, collisions, 16);
397cfa96c6cSSepherosa Ziehau }
398d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, oerrors, 1);
399cfa96c6cSSepherosa Ziehau } else {
400cfa96c6cSSepherosa Ziehau if (tmd1 & LE_T1_ONE)
401d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, collisions, 1);
402cfa96c6cSSepherosa Ziehau else if (tmd1 & LE_T1_MORE)
403cfa96c6cSSepherosa Ziehau /* Real number is unknown. */
404d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, collisions, 2);
405d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, opackets, 1);
406cfa96c6cSSepherosa Ziehau }
407cfa96c6cSSepherosa Ziehau
408cfa96c6cSSepherosa Ziehau if (++bix == sc->sc_ntbuf)
409cfa96c6cSSepherosa Ziehau bix = 0;
410cfa96c6cSSepherosa Ziehau
411cfa96c6cSSepherosa Ziehau --sc->sc_no_td;
412cfa96c6cSSepherosa Ziehau }
413cfa96c6cSSepherosa Ziehau
414cfa96c6cSSepherosa Ziehau sc->sc_first_td = bix;
415cfa96c6cSSepherosa Ziehau
416cfa96c6cSSepherosa Ziehau ifp->if_timer = sc->sc_no_td > 0 ? 5 : 0;
417cfa96c6cSSepherosa Ziehau }
418cfa96c6cSSepherosa Ziehau
419cfa96c6cSSepherosa Ziehau /*
420cfa96c6cSSepherosa Ziehau * Controller interrupt
421cfa96c6cSSepherosa Ziehau */
422cfa96c6cSSepherosa Ziehau void
am79900_intr(void * arg)423cfa96c6cSSepherosa Ziehau am79900_intr(void *arg)
424cfa96c6cSSepherosa Ziehau {
425cfa96c6cSSepherosa Ziehau struct lance_softc *sc = arg;
426cfa96c6cSSepherosa Ziehau struct ifnet *ifp = sc->ifp;
427cfa96c6cSSepherosa Ziehau uint16_t isr;
428cfa96c6cSSepherosa Ziehau
429cfa96c6cSSepherosa Ziehau if (sc->sc_hwintr && (*sc->sc_hwintr)(sc) == -1) {
430d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, ierrors, 1);
431cfa96c6cSSepherosa Ziehau lance_init_locked(sc);
432cfa96c6cSSepherosa Ziehau return;
433cfa96c6cSSepherosa Ziehau }
434cfa96c6cSSepherosa Ziehau
435cfa96c6cSSepherosa Ziehau isr = (*sc->sc_rdcsr)(sc, LE_CSR0);
436cfa96c6cSSepherosa Ziehau #if defined(LEDEBUG) && LEDEBUG > 1
437cfa96c6cSSepherosa Ziehau if (sc->sc_flags & LE_DEBUG)
438cfa96c6cSSepherosa Ziehau if_printf(ifp, "%s: entering with isr=%04x\n", __func__, isr);
439cfa96c6cSSepherosa Ziehau #endif
440cfa96c6cSSepherosa Ziehau if ((isr & LE_C0_INTR) == 0) {
441cfa96c6cSSepherosa Ziehau return;
442cfa96c6cSSepherosa Ziehau }
443cfa96c6cSSepherosa Ziehau
444cfa96c6cSSepherosa Ziehau /*
445cfa96c6cSSepherosa Ziehau * Clear interrupt source flags and turn off interrupts. If we
446cfa96c6cSSepherosa Ziehau * don't clear these flags before processing their sources we
447cfa96c6cSSepherosa Ziehau * could completely miss some interrupt events as the NIC can
448cfa96c6cSSepherosa Ziehau * change these flags while we're in this handler. We turn off
449cfa96c6cSSepherosa Ziehau * interrupts so we don't get another RX interrupt while still
450cfa96c6cSSepherosa Ziehau * processing the previous one in ifp->if_input() with the
451cfa96c6cSSepherosa Ziehau * driver lock dropped.
452cfa96c6cSSepherosa Ziehau */
453cfa96c6cSSepherosa Ziehau (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD |
454cfa96c6cSSepherosa Ziehau LE_C0_STOP | LE_C0_STRT | LE_C0_INIT));
455cfa96c6cSSepherosa Ziehau
456cfa96c6cSSepherosa Ziehau if (isr & LE_C0_ERR) {
457cfa96c6cSSepherosa Ziehau if (isr & LE_C0_BABL) {
458cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
459cfa96c6cSSepherosa Ziehau if_printf(ifp, "babble\n");
460cfa96c6cSSepherosa Ziehau #endif
461d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, oerrors, 1);
462cfa96c6cSSepherosa Ziehau }
463cfa96c6cSSepherosa Ziehau #if 0
464cfa96c6cSSepherosa Ziehau if (isr & LE_C0_CERR) {
465cfa96c6cSSepherosa Ziehau if_printf(ifp, "collision error\n");
466cfa96c6cSSepherosa Ziehau ifp->if_collisions++;
467cfa96c6cSSepherosa Ziehau }
468cfa96c6cSSepherosa Ziehau #endif
469cfa96c6cSSepherosa Ziehau if (isr & LE_C0_MISS) {
470cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
471cfa96c6cSSepherosa Ziehau if_printf(ifp, "missed packet\n");
472cfa96c6cSSepherosa Ziehau #endif
473d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, ierrors, 1);
474cfa96c6cSSepherosa Ziehau }
475cfa96c6cSSepherosa Ziehau if (isr & LE_C0_MERR) {
476cfa96c6cSSepherosa Ziehau if_printf(ifp, "memory error\n");
477cfa96c6cSSepherosa Ziehau lance_init_locked(sc);
478cfa96c6cSSepherosa Ziehau return;
479cfa96c6cSSepherosa Ziehau }
480cfa96c6cSSepherosa Ziehau }
481cfa96c6cSSepherosa Ziehau
482cfa96c6cSSepherosa Ziehau if ((isr & LE_C0_RXON) == 0) {
483cfa96c6cSSepherosa Ziehau if_printf(ifp, "receiver disabled\n");
484d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, ierrors, 1);
485cfa96c6cSSepherosa Ziehau lance_init_locked(sc);
486cfa96c6cSSepherosa Ziehau return;
487cfa96c6cSSepherosa Ziehau }
488cfa96c6cSSepherosa Ziehau if ((isr & LE_C0_TXON) == 0) {
489cfa96c6cSSepherosa Ziehau if_printf(ifp, "transmitter disabled\n");
490d40991efSSepherosa Ziehau IFNET_STAT_INC(ifp, oerrors, 1);
491cfa96c6cSSepherosa Ziehau lance_init_locked(sc);
492cfa96c6cSSepherosa Ziehau return;
493cfa96c6cSSepherosa Ziehau }
494cfa96c6cSSepherosa Ziehau
495cfa96c6cSSepherosa Ziehau /*
496cfa96c6cSSepherosa Ziehau * Pretend we have carrier; if we don't this will be cleared shortly.
497cfa96c6cSSepherosa Ziehau */
49874e34c07SSepherosa Ziehau if (!(sc->sc_flags & LE_CARRIER)) {
49974e34c07SSepherosa Ziehau ifp->if_link_state = LINK_STATE_UP;
50074e34c07SSepherosa Ziehau if_link_state_change(ifp);
50174e34c07SSepherosa Ziehau }
502cfa96c6cSSepherosa Ziehau sc->sc_flags |= LE_CARRIER;
503cfa96c6cSSepherosa Ziehau
504cfa96c6cSSepherosa Ziehau if (isr & LE_C0_RINT)
505cfa96c6cSSepherosa Ziehau am79900_rint(sc);
506cfa96c6cSSepherosa Ziehau if (isr & LE_C0_TINT)
507cfa96c6cSSepherosa Ziehau am79900_tint(sc);
508cfa96c6cSSepherosa Ziehau
509cfa96c6cSSepherosa Ziehau /* Enable interrupts again. */
510cfa96c6cSSepherosa Ziehau (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA);
511cfa96c6cSSepherosa Ziehau
512cfa96c6cSSepherosa Ziehau if (!ifq_is_empty(&ifp->if_snd))
5139db4b353SSepherosa Ziehau if_devstart(ifp);
514cfa96c6cSSepherosa Ziehau }
515cfa96c6cSSepherosa Ziehau
516cfa96c6cSSepherosa Ziehau /*
517cfa96c6cSSepherosa Ziehau * Set up output on interface.
518cfa96c6cSSepherosa Ziehau * Get another datagram to send off of the interface queue, and map it to the
519cfa96c6cSSepherosa Ziehau * interface before starting the output.
520cfa96c6cSSepherosa Ziehau */
521cfa96c6cSSepherosa Ziehau static void
am79900_start_locked(struct lance_softc * sc)522cfa96c6cSSepherosa Ziehau am79900_start_locked(struct lance_softc *sc)
523cfa96c6cSSepherosa Ziehau {
524cfa96c6cSSepherosa Ziehau struct ifnet *ifp = sc->ifp;
525cfa96c6cSSepherosa Ziehau struct letmd tmd;
526cfa96c6cSSepherosa Ziehau struct mbuf *m;
527cfa96c6cSSepherosa Ziehau int bix, enq, len, rp;
528cfa96c6cSSepherosa Ziehau
5299ed293e0SSepherosa Ziehau if ((ifp->if_flags & IFF_RUNNING) == 0 || ifq_is_oactive(&ifp->if_snd))
530cfa96c6cSSepherosa Ziehau return;
531cfa96c6cSSepherosa Ziehau
532cfa96c6cSSepherosa Ziehau bix = sc->sc_last_td;
533cfa96c6cSSepherosa Ziehau enq = 0;
534cfa96c6cSSepherosa Ziehau
535cfa96c6cSSepherosa Ziehau for (; sc->sc_no_td < sc->sc_ntbuf &&
536cfa96c6cSSepherosa Ziehau !ifq_is_empty(&ifp->if_snd);) {
537cfa96c6cSSepherosa Ziehau rp = LE_TMDADDR(sc, bix);
538cfa96c6cSSepherosa Ziehau (*sc->sc_copyfromdesc)(sc, &tmd, rp, sizeof(tmd));
539cfa96c6cSSepherosa Ziehau
540cfa96c6cSSepherosa Ziehau if (LE_LE32TOH(tmd.tmd1) & LE_T1_OWN) {
5419ed293e0SSepherosa Ziehau ifq_set_oactive(&ifp->if_snd);
542cfa96c6cSSepherosa Ziehau if_printf(ifp,
543cfa96c6cSSepherosa Ziehau "missing buffer, no_td = %d, last_td = %d\n",
544cfa96c6cSSepherosa Ziehau sc->sc_no_td, sc->sc_last_td);
545cfa96c6cSSepherosa Ziehau }
546cfa96c6cSSepherosa Ziehau
547ac9843a1SSepherosa Ziehau m = ifq_dequeue(&ifp->if_snd);
5489db4b353SSepherosa Ziehau if (m == NULL)
549cfa96c6cSSepherosa Ziehau break;
550cfa96c6cSSepherosa Ziehau
551cfa96c6cSSepherosa Ziehau /*
552cfa96c6cSSepherosa Ziehau * If BPF is listening on this interface, let it see the packet
553cfa96c6cSSepherosa Ziehau * before we commit it to the wire.
554cfa96c6cSSepherosa Ziehau */
555cfa96c6cSSepherosa Ziehau BPF_MTAP(ifp, m);
556cfa96c6cSSepherosa Ziehau
557cfa96c6cSSepherosa Ziehau /*
558cfa96c6cSSepherosa Ziehau * Copy the mbuf chain into the transmit buffer.
559cfa96c6cSSepherosa Ziehau */
560cfa96c6cSSepherosa Ziehau len = lance_put(sc, LE_TBUFADDR(sc, bix), m);
561cfa96c6cSSepherosa Ziehau
562cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
563cfa96c6cSSepherosa Ziehau if (len > ETHERMTU + ETHER_HDR_LEN)
564cfa96c6cSSepherosa Ziehau if_printf(ifp, "packet length %d\n", len);
565cfa96c6cSSepherosa Ziehau #endif
566cfa96c6cSSepherosa Ziehau
567cfa96c6cSSepherosa Ziehau /*
568cfa96c6cSSepherosa Ziehau * Init transmit registers, and set transmit start flag.
569cfa96c6cSSepherosa Ziehau */
570cfa96c6cSSepherosa Ziehau tmd.tmd1 = LE_HTOLE32(LE_T1_OWN | LE_T1_STP | LE_T1_ENP |
571cfa96c6cSSepherosa Ziehau LE_T1_ONES | (-len & 0xfff));
572cfa96c6cSSepherosa Ziehau tmd.tmd2 = 0;
573cfa96c6cSSepherosa Ziehau tmd.tmd3 = 0;
574cfa96c6cSSepherosa Ziehau
575cfa96c6cSSepherosa Ziehau (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
576cfa96c6cSSepherosa Ziehau
577cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
578cfa96c6cSSepherosa Ziehau if (sc->sc_flags & LE_DEBUG)
579cfa96c6cSSepherosa Ziehau am79900_xmit_print(sc, bix);
580cfa96c6cSSepherosa Ziehau #endif
581cfa96c6cSSepherosa Ziehau
582cfa96c6cSSepherosa Ziehau (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
583cfa96c6cSSepherosa Ziehau enq++;
584cfa96c6cSSepherosa Ziehau
585cfa96c6cSSepherosa Ziehau if (++bix == sc->sc_ntbuf)
586cfa96c6cSSepherosa Ziehau bix = 0;
587cfa96c6cSSepherosa Ziehau
588cfa96c6cSSepherosa Ziehau if (++sc->sc_no_td == sc->sc_ntbuf) {
5899ed293e0SSepherosa Ziehau ifq_set_oactive(&ifp->if_snd);
590cfa96c6cSSepherosa Ziehau break;
591cfa96c6cSSepherosa Ziehau }
592cfa96c6cSSepherosa Ziehau }
593cfa96c6cSSepherosa Ziehau
594cfa96c6cSSepherosa Ziehau sc->sc_last_td = bix;
595cfa96c6cSSepherosa Ziehau
596cfa96c6cSSepherosa Ziehau if (enq > 0)
597cfa96c6cSSepherosa Ziehau ifp->if_timer = 5;
598cfa96c6cSSepherosa Ziehau }
599cfa96c6cSSepherosa Ziehau
600cfa96c6cSSepherosa Ziehau #ifdef LEDEBUG
601cfa96c6cSSepherosa Ziehau static void
am79900_recv_print(struct lance_softc * sc,int no)602cfa96c6cSSepherosa Ziehau am79900_recv_print(struct lance_softc *sc, int no)
603cfa96c6cSSepherosa Ziehau {
604cfa96c6cSSepherosa Ziehau struct ifnet *ifp = sc->ifp;
605cfa96c6cSSepherosa Ziehau struct ether_header eh;
606cfa96c6cSSepherosa Ziehau struct lermd rmd;
607cfa96c6cSSepherosa Ziehau uint16_t len;
608cfa96c6cSSepherosa Ziehau
609cfa96c6cSSepherosa Ziehau (*sc->sc_copyfromdesc)(sc, &rmd, LE_RMDADDR(sc, no), sizeof(rmd));
610cfa96c6cSSepherosa Ziehau len = LE_LE32TOH(rmd.rmd2) & 0xfff;
611cfa96c6cSSepherosa Ziehau if_printf(ifp, "receive buffer %d, len = %d\n", no, len);
612cfa96c6cSSepherosa Ziehau if_printf(ifp, "status %04x\n", (*sc->sc_rdcsr)(sc, LE_CSR0));
613cfa96c6cSSepherosa Ziehau if_printf(ifp, "adr %08x, flags/blen %08x\n", LE_LE32TOH(rmd.rmd0),
614cfa96c6cSSepherosa Ziehau LE_LE32TOH(rmd.rmd1));
615cfa96c6cSSepherosa Ziehau if (len - ETHER_CRC_LEN >= sizeof(eh)) {
616cfa96c6cSSepherosa Ziehau (*sc->sc_copyfrombuf)(sc, &eh, LE_RBUFADDR(sc, no), sizeof(eh));
617cfa96c6cSSepherosa Ziehau if_printf(ifp, "dst %s", ether_sprintf(eh.ether_dhost));
618e3869ec7SSascha Wildner kprintf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
619cfa96c6cSSepherosa Ziehau ntohs(eh.ether_type));
620cfa96c6cSSepherosa Ziehau }
621cfa96c6cSSepherosa Ziehau }
622cfa96c6cSSepherosa Ziehau
623cfa96c6cSSepherosa Ziehau static void
am79900_xmit_print(struct lance_softc * sc,int no)624cfa96c6cSSepherosa Ziehau am79900_xmit_print(struct lance_softc *sc, int no)
625cfa96c6cSSepherosa Ziehau {
626cfa96c6cSSepherosa Ziehau struct ifnet *ifp = sc->ifp;
627cfa96c6cSSepherosa Ziehau struct ether_header eh;
628cfa96c6cSSepherosa Ziehau struct letmd tmd;
629cfa96c6cSSepherosa Ziehau uint16_t len;
630cfa96c6cSSepherosa Ziehau
631cfa96c6cSSepherosa Ziehau (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, no), sizeof(tmd));
632cfa96c6cSSepherosa Ziehau len = -(LE_LE32TOH(tmd.tmd1) & 0xfff);
633cfa96c6cSSepherosa Ziehau if_printf(ifp, "transmit buffer %d, len = %d\n", no, len);
634cfa96c6cSSepherosa Ziehau if_printf(ifp, "status %04x\n", (*sc->sc_rdcsr)(sc, LE_CSR0));
635cfa96c6cSSepherosa Ziehau if_printf(ifp, "adr %08x, flags/blen %08x\n", LE_LE32TOH(tmd.tmd0),
636cfa96c6cSSepherosa Ziehau LE_LE32TOH(tmd.tmd1));
637cfa96c6cSSepherosa Ziehau if (len >= sizeof(eh)) {
638cfa96c6cSSepherosa Ziehau (*sc->sc_copyfrombuf)(sc, &eh, LE_TBUFADDR(sc, no), sizeof(eh));
639cfa96c6cSSepherosa Ziehau if_printf(ifp, "dst %s", ether_sprintf(eh.ether_dhost));
640e3869ec7SSascha Wildner kprintf(" src %s type %04x\n", ether_sprintf(eh.ether_shost),
641cfa96c6cSSepherosa Ziehau ntohs(eh.ether_type));
642cfa96c6cSSepherosa Ziehau }
643cfa96c6cSSepherosa Ziehau }
644cfa96c6cSSepherosa Ziehau #endif /* LEDEBUG */
645