Deleted Added
sdiff udiff text old ( 155881 ) new ( 158663 )
full compact
1/* $NetBSD: am79900.c,v 1.17 2005/12/24 20:27:29 perry Exp $ */
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.

--- 96 unchanged lines hidden (view full) ---

105 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
106 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
107 * SUCH DAMAGE.
108 *
109 * @(#)if_le.c 8.2 (Berkeley) 11/16/93
110 */
111
112#include <sys/cdefs.h>
113__FBSDID("$FreeBSD: head/sys/dev/le/am79900.c 155881 2006-02-21 20:20:43Z marius $");
114
115#include <sys/param.h>
116#include <sys/bus.h>
117#include <sys/endian.h>
118#include <sys/lock.h>
119#include <sys/mbuf.h>
120#include <sys/mutex.h>
121#include <sys/socket.h>
122
123#include <net/bpf.h>
124#include <net/ethernet.h>
125#include <net/if.h>
126#include <net/if_arp.h>
127#include <net/if_dl.h>
128#include <net/if_media.h>
129#include <net/if_var.h>
130
131#include <dev/le/lancereg.h>
132#include <dev/le/lancevar.h>
133#include <dev/le/am79900reg.h>
134#include <dev/le/am79900var.h>
135
136static void am79900_meminit(struct lance_softc *);
137static void am79900_rint(struct lance_softc *);
138static void am79900_tint(struct lance_softc *);

--- 111 unchanged lines hidden (view full) ---

250 sizeof(tmd));
251 }
252}
253
254static inline void
255am79900_rint(struct lance_softc *sc)
256{
257 struct ifnet *ifp = sc->sc_ifp;
258 struct lermd rmd;
259 uint32_t rmd1;
260 int bix, rp;
261
262 bix = sc->sc_last_rd;
263
264 /* Process all buffers with valid data. */
265 for (;;) {
266 rp = LE_RMDADDR(sc, bix);
267 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd));
268
269 rmd1 = LE_LE32TOH(rmd.rmd1);
270 if (rmd1 & LE_R1_OWN)
271 break;
272
273 if (rmd1 & LE_R1_ERR) {
274 if (rmd1 & LE_R1_ENP) {
275#ifdef LEDEBUG
276 if ((rmd1 & LE_R1_OFLO) == 0) {
277 if (rmd1 & LE_R1_FRAM)
278 if_printf(ifp,
279 "framing error\n");
280 if (rmd1 & LE_R1_CRC)
281 if_printf(ifp,
282 "crc mismatch\n");
283 }
284#endif
285 } else {
286 if (rmd1 & LE_R1_OFLO)
287 if_printf(ifp, "overflow\n");
288 }
289 if (rmd1 & LE_R1_BUFF)
290 if_printf(ifp, "receive buffer error\n");
291 ifp->if_ierrors++;
292 } else if ((rmd1 & (LE_R1_STP | LE_R1_ENP)) !=
293 (LE_R1_STP | LE_R1_ENP)) {
294 if_printf(ifp, "dropping chained buffer\n");
295 ifp->if_ierrors++;
296 } else {
297#ifdef LEDEBUG
298 if (sc->sc_flags & LE_DEBUG)
299 am79900_recv_print(sc, sc->sc_last_rd);
300#endif
301 lance_read(sc, LE_RBUFADDR(sc, bix),
302 (LE_LE32TOH(rmd.rmd2) & 0xfff) - ETHER_CRC_LEN);
303 }
304
305 rmd.rmd1 = LE_HTOLE32(LE_R1_OWN | LE_R1_ONES |
306 (-LEBLEN & 0xfff));
307 rmd.rmd2 = 0;
308 rmd.rmd3 = 0;
309 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd));
310
311#ifdef LEDEBUG
312 if (sc->sc_flags & LE_DEBUG)
313 if_printf(ifp, "sc->sc_last_rd = %x, rmd: "
314 "adr %08x, flags/blen %08x\n",
315 sc->sc_last_rd, LE_LE32TOH(rmd.rmd0),
316 LE_LE32TOH(rmd.rmd1));
317#endif
318
319 if (++bix == sc->sc_nrbuf)
320 bix = 0;
321 }
322
323 sc->sc_last_rd = bix;
324}
325
326static inline void
327am79900_tint(struct lance_softc *sc)
328{

--- 6 unchanged lines hidden (view full) ---

335
336 for (;;) {
337 if (sc->sc_no_td <= 0)
338 break;
339
340 (*sc->sc_copyfromdesc)(sc, &tmd, LE_TMDADDR(sc, bix),
341 sizeof(tmd));
342
343#ifdef LEDEBUG
344 if (sc->sc_flags & LE_DEBUG)
345 if_printf(ifp, "trans tmd: "
346 "adr %08x, flags/blen %08x\n",
347 LE_LE32TOH(tmd.tmd0), LE_LE32TOH(tmd.tmd1));
348#endif
349
350 tmd1 = LE_LE32TOH(tmd.tmd1);
351 if (tmd1 & LE_T1_OWN)
352 break;
353
354 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
355
356 tmd2 = LE_LE32TOH(tmd.tmd2);
357 if (tmd1 & LE_T1_ERR) {
358 if (tmd2 & LE_T2_BUFF)
359 if_printf(ifp, "transmit buffer error\n");
360 else if (tmd2 & LE_T2_UFLO)
361 if_printf(ifp, "underflow\n");
362 if (tmd2 & (LE_T2_BUFF | LE_T2_UFLO)) {
363 lance_init_locked(sc);
364 return;
365 }

--- 63 unchanged lines hidden (view full) ---

429 if ((isr & LE_C0_INTR) == 0) {
430 LE_UNLOCK(sc);
431 return;
432 }
433
434 /*
435 * Clear interrupt source flags and turn off interrupts. If we
436 * don't clear these flags before processing their sources we
437 * could completely miss some interrupt events as the the NIC
438 * can change these flags while we're in this handler. We turn
439 * of interrupts while processing them so we don't get another
440 * one while we still process the previous one in ifp->if_input()
441 * with the driver lock dropped.
442 */
443 (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD |
444 LE_C0_STOP | LE_C0_STRT | LE_C0_INIT));
445
446 if (isr & LE_C0_ERR) {
447 if (isr & LE_C0_BABL) {
448#ifdef LEDEBUG
449 if_printf(ifp, "babble\n");

--- 117 unchanged lines hidden (view full) ---

567 LE_T1_ONES | (-len & 0xfff));
568 tmd.tmd2 = 0;
569 tmd.tmd3 = 0;
570
571 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd));
572
573#ifdef LEDEBUG
574 if (sc->sc_flags & LE_DEBUG)
575 am79900_xmit_print(sc, sc->sc_last_td);
576#endif
577
578 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD);
579 enq++;
580
581 if (++bix == sc->sc_ntbuf)
582 bix = 0;
583

--- 57 unchanged lines hidden ---