am7990.c (155881) | am7990.c (158663) |
---|---|
1/* $NetBSD: am7990.c,v 1.68 2005/12/11 12:21:25 christos Exp $ */ 2 3/*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace --- 58 unchanged lines hidden (view full) --- 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * @(#)if_le.c 8.2 (Berkeley) 11/16/93 72 */ 73 74#include <sys/cdefs.h> | 1/* $NetBSD: am7990.c,v 1.68 2005/12/11 12:21:25 christos Exp $ */ 2 3/*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace --- 58 unchanged lines hidden (view full) --- 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 69 * SUCH DAMAGE. 70 * 71 * @(#)if_le.c 8.2 (Berkeley) 11/16/93 72 */ 73 74#include <sys/cdefs.h> |
75__FBSDID("$FreeBSD: head/sys/dev/le/am7990.c 155881 2006-02-21 20:20:43Z marius $"); | 75__FBSDID("$FreeBSD: head/sys/dev/le/am7990.c 158663 2006-05-16 21:04:01Z marius $"); |
76 77#include <sys/param.h> 78#include <sys/bus.h> 79#include <sys/endian.h> 80#include <sys/lock.h> 81#include <sys/mbuf.h> 82#include <sys/mutex.h> 83#include <sys/socket.h> 84 85#include <net/bpf.h> 86#include <net/ethernet.h> 87#include <net/if.h> 88#include <net/if_arp.h> 89#include <net/if_dl.h> 90#include <net/if_media.h> 91#include <net/if_var.h> 92 | 76 77#include <sys/param.h> 78#include <sys/bus.h> 79#include <sys/endian.h> 80#include <sys/lock.h> 81#include <sys/mbuf.h> 82#include <sys/mutex.h> 83#include <sys/socket.h> 84 85#include <net/bpf.h> 86#include <net/ethernet.h> 87#include <net/if.h> 88#include <net/if_arp.h> 89#include <net/if_dl.h> 90#include <net/if_media.h> 91#include <net/if_var.h> 92 |
93#include <machine/bus.h> 94 |
|
93#include <dev/le/lancereg.h> 94#include <dev/le/lancevar.h> 95#include <dev/le/am7990reg.h> 96#include <dev/le/am7990var.h> 97 98static void am7990_meminit(struct lance_softc *); 99static void am7990_rint(struct lance_softc *); 100static void am7990_tint(struct lance_softc *); --- 109 unchanged lines hidden (view full) --- 210 sizeof(tmd)); 211 } 212} 213 214static void 215am7990_rint(struct lance_softc *sc) 216{ 217 struct ifnet *ifp = sc->sc_ifp; | 95#include <dev/le/lancereg.h> 96#include <dev/le/lancevar.h> 97#include <dev/le/am7990reg.h> 98#include <dev/le/am7990var.h> 99 100static void am7990_meminit(struct lance_softc *); 101static void am7990_rint(struct lance_softc *); 102static void am7990_tint(struct lance_softc *); --- 109 unchanged lines hidden (view full) --- 212 sizeof(tmd)); 213 } 214} 215 216static void 217am7990_rint(struct lance_softc *sc) 218{ 219 struct ifnet *ifp = sc->sc_ifp; |
220 struct mbuf *m; |
|
218 struct lermd rmd; 219 int bix, rp; | 221 struct lermd rmd; 222 int bix, rp; |
223#if defined(LANCE_REVC_BUG) 224 struct ether_header *eh; 225 /* Make sure this is short-aligned, for ether_cmp(). */ 226 static uint16_t bcast_enaddr[3] = { ~0, ~0, ~0 }; 227#endif |
|
220 221 bix = sc->sc_last_rd; 222 223 /* Process all buffers with valid data. */ 224 for (;;) { 225 rp = LE_RMDADDR(sc, bix); 226 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd)); 227 228 if (rmd.rmd1_bits & LE_R1_OWN) 229 break; 230 | 228 229 bix = sc->sc_last_rd; 230 231 /* Process all buffers with valid data. */ 232 for (;;) { 233 rp = LE_RMDADDR(sc, bix); 234 (*sc->sc_copyfromdesc)(sc, &rmd, rp, sizeof(rmd)); 235 236 if (rmd.rmd1_bits & LE_R1_OWN) 237 break; 238 |
231 if (rmd.rmd1_bits & LE_R1_ERR) { 232 if (rmd.rmd1_bits & LE_R1_ENP) { | 239 m = NULL; 240 if ((rmd.rmd1_bits & (LE_R1_ERR | LE_R1_STP | LE_R1_ENP)) != 241 (LE_R1_STP | LE_R1_ENP)) { 242 if (rmd.rmd1_bits & LE_R1_ERR) { |
233#ifdef LEDEBUG | 243#ifdef LEDEBUG |
234 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) { 235 if (rmd.rmd1_bits & LE_R1_FRAM) 236 if_printf(ifp, 237 "framing error\n"); 238 if (rmd.rmd1_bits & LE_R1_CRC) 239 if_printf(ifp, 240 "crc mismatch\n"); 241 } | 244 if (rmd.rmd1_bits & LE_R1_ENP) { 245 if ((rmd.rmd1_bits & LE_R1_OFLO) == 0) { 246 if (rmd.rmd1_bits & LE_R1_FRAM) 247 if_printf(ifp, 248 "framing error\n"); 249 if (rmd.rmd1_bits & LE_R1_CRC) 250 if_printf(ifp, 251 "crc mismatch\n"); 252 } 253 } else 254 if (rmd.rmd1_bits & LE_R1_OFLO) 255 if_printf(ifp, "overflow\n"); |
242#endif | 256#endif |
243 } else { 244 if (rmd.rmd1_bits & LE_R1_OFLO) 245 if_printf(ifp, "overflow\n"); 246 } 247 if (rmd.rmd1_bits & LE_R1_BUFF) 248 if_printf(ifp, "receive buffer error\n"); 249 ifp->if_ierrors++; 250 } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) != 251 (LE_R1_STP | LE_R1_ENP)) { 252 if_printf(ifp, "dropping chained buffer\n"); 253 ifp->if_ierrors++; | 257 if (rmd.rmd1_bits & LE_R1_BUFF) 258 if_printf(ifp, 259 "receive buffer error\n"); 260 } else if ((rmd.rmd1_bits & (LE_R1_STP | LE_R1_ENP)) != 261 (LE_R1_STP | LE_R1_ENP)) 262 if_printf(ifp, "dropping chained buffer\n"); |
254 } else { 255#ifdef LEDEBUG 256 if (sc->sc_flags & LE_DEBUG) | 263 } else { 264#ifdef LEDEBUG 265 if (sc->sc_flags & LE_DEBUG) |
257 am7990_recv_print(sc, sc->sc_last_rd); | 266 am7990_recv_print(sc, bix); |
258#endif | 267#endif |
259 lance_read(sc, LE_RBUFADDR(sc, bix), | 268 /* Pull the packet off the interface. */ 269 m = lance_get(sc, LE_RBUFADDR(sc, bix), |
260 (int)rmd.rmd3 - ETHER_CRC_LEN); 261 } 262 263 rmd.rmd1_bits = LE_R1_OWN; 264 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES; 265 rmd.rmd3 = 0; 266 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd)); 267 | 270 (int)rmd.rmd3 - ETHER_CRC_LEN); 271 } 272 273 rmd.rmd1_bits = LE_R1_OWN; 274 rmd.rmd2 = -LEBLEN | LE_XMD2_ONES; 275 rmd.rmd3 = 0; 276 (*sc->sc_copytodesc)(sc, &rmd, rp, sizeof(rmd)); 277 |
268#ifdef LEDEBUG 269 if (sc->sc_flags & LE_DEBUG) 270 if_printf(ifp, "sc->sc_last_rd = %x, rmd: " 271 "ladr %04x, hadr %02x, flags %02x, " 272 "bcnt %04x, mcnt %04x\n", 273 sc->sc_last_rd, rmd.rmd0, rmd.rmd1_hadr, 274 rmd.rmd1_bits, rmd.rmd2, rmd.rmd3); 275#endif 276 | |
277 if (++bix == sc->sc_nrbuf) 278 bix = 0; | 278 if (++bix == sc->sc_nrbuf) 279 bix = 0; |
280 281 if (m != NULL) { 282 ifp->if_ipackets++; 283 284#ifdef LANCE_REVC_BUG 285 /* 286 * The old LANCE (Rev. C) chips have a bug which 287 * causes garbage to be inserted in front of the 288 * received packet. The workaround is to ignore 289 * packets with an invalid destination address 290 * (garbage will usually not match). 291 * Of course, this precludes multicast support... 292 */ 293 eh = mtod(m, struct ether_header *); 294 if (ether_cmp(eh->ether_dhost, sc->sc_enaddr) && 295 ether_cmp(eh->ether_dhost, bcast_enaddr)) { 296 m_freem(m); 297 continue; 298 } 299#endif 300 301 /* Pass the packet up. */ 302 LE_UNLOCK(sc); 303 (*ifp->if_input)(ifp, m); 304 LE_LOCK(sc); 305 } else 306 ifp->if_ierrors++; |
|
279 } 280 281 sc->sc_last_rd = bix; 282} 283 284static void 285am7990_tint(struct lance_softc *sc) 286{ --- 100 unchanged lines hidden (view full) --- 387 if ((isr & LE_C0_INTR) == 0) { 388 LE_UNLOCK(sc); 389 return; 390 } 391 392 /* 393 * Clear interrupt source flags and turn off interrupts. If we 394 * don't clear these flags before processing their sources we | 307 } 308 309 sc->sc_last_rd = bix; 310} 311 312static void 313am7990_tint(struct lance_softc *sc) 314{ --- 100 unchanged lines hidden (view full) --- 415 if ((isr & LE_C0_INTR) == 0) { 416 LE_UNLOCK(sc); 417 return; 418 } 419 420 /* 421 * Clear interrupt source flags and turn off interrupts. If we 422 * don't clear these flags before processing their sources we |
395 * could completely miss some interrupt events as the the NIC 396 * can change these flags while we're in this handler. We turn 397 * of interrupts while processing them so we don't get another 398 * one while we still process the previous one in ifp->if_input() 399 * with the driver lock dropped. | 423 * could completely miss some interrupt events as the NIC can 424 * change these flags while we're in this handler. We turn off 425 * interrupts so we don't get another RX interrupt while still 426 * processing the previous one in ifp->if_input() with the 427 * driver lock dropped. |
400 */ 401 (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD | 402 LE_C0_STOP | LE_C0_STRT | LE_C0_INIT)); 403 404 if (isr & LE_C0_ERR) { 405 if (isr & LE_C0_BABL) { 406#ifdef LEDEBUG 407 if_printf(ifp, "babble\n"); --- 116 unchanged lines hidden (view full) --- 524 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP; 525 tmd.tmd2 = -len | LE_XMD2_ONES; 526 tmd.tmd3 = 0; 527 528 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd)); 529 530#ifdef LEDEBUG 531 if (sc->sc_flags & LE_DEBUG) | 428 */ 429 (*sc->sc_wrcsr)(sc, LE_CSR0, isr & ~(LE_C0_INEA | LE_C0_TDMD | 430 LE_C0_STOP | LE_C0_STRT | LE_C0_INIT)); 431 432 if (isr & LE_C0_ERR) { 433 if (isr & LE_C0_BABL) { 434#ifdef LEDEBUG 435 if_printf(ifp, "babble\n"); --- 116 unchanged lines hidden (view full) --- 552 tmd.tmd1_bits = LE_T1_OWN | LE_T1_STP | LE_T1_ENP; 553 tmd.tmd2 = -len | LE_XMD2_ONES; 554 tmd.tmd3 = 0; 555 556 (*sc->sc_copytodesc)(sc, &tmd, rp, sizeof(tmd)); 557 558#ifdef LEDEBUG 559 if (sc->sc_flags & LE_DEBUG) |
532 am7990_xmit_print(sc, sc->sc_last_td); | 560 am7990_xmit_print(sc, bix); |
533#endif 534 535 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD); 536 enq++; 537 538 if (++bix == sc->sc_ntbuf) 539 bix = 0; 540 --- 59 unchanged lines hidden --- | 561#endif 562 563 (*sc->sc_wrcsr)(sc, LE_CSR0, LE_C0_INEA | LE_C0_TDMD); 564 enq++; 565 566 if (++bix == sc->sc_ntbuf) 567 bix = 0; 568 --- 59 unchanged lines hidden --- |