Adopt <net/if_stats.h>.diff -r1.19 -r1.20 src/sys/dev/ic/bwfm.c
(thorpej)
--- src/sys/dev/ic/bwfm.c 2019/12/27 09:22:20 1.19
+++ src/sys/dev/ic/bwfm.c 2020/01/29 14:14:55 1.20
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: bwfm.c,v 1.19 2019/12/27 09:22:20 msaitoh Exp $ */ | 1 | /* $NetBSD: bwfm.c,v 1.20 2020/01/29 14:14:55 thorpej Exp $ */ | |
2 | /* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */ | 2 | /* $OpenBSD: bwfm.c,v 1.5 2017/10/16 22:27:16 patrick Exp $ */ | |
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010-2016 Broadcom Corporation | 4 | * Copyright (c) 2010-2016 Broadcom Corporation | |
5 | * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> | 5 | * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> | |
6 | * | 6 | * | |
7 | * Permission to use, copy, modify, and/or distribute this software for any | 7 | * Permission to use, copy, modify, and/or distribute this software for any | |
8 | * purpose with or without fee is hereby granted, provided that the above | 8 | * purpose with or without fee is hereby granted, provided that the above | |
9 | * copyright notice and this permission notice appear in all copies. | 9 | * copyright notice and this permission notice appear in all copies. | |
10 | * | 10 | * | |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
@@ -319,27 +319,27 @@ bwfm_start(struct ifnet *ifp) | @@ -319,27 +319,27 @@ bwfm_start(struct ifnet *ifp) | |||
319 | } | 319 | } | |
320 | 320 | |||
321 | IFQ_DEQUEUE(&ifp->if_snd, m); | 321 | IFQ_DEQUEUE(&ifp->if_snd, m); | |
322 | if (m == NULL) | 322 | if (m == NULL) | |
323 | break; | 323 | break; | |
324 | 324 | |||
325 | error = sc->sc_bus_ops->bs_txdata(sc, &m); | 325 | error = sc->sc_bus_ops->bs_txdata(sc, &m); | |
326 | if (error == ENOBUFS) { | 326 | if (error == ENOBUFS) { | |
327 | IF_PREPEND(&ifp->if_snd, m); | 327 | IF_PREPEND(&ifp->if_snd, m); | |
328 | ifp->if_flags |= IFF_OACTIVE; | 328 | ifp->if_flags |= IFF_OACTIVE; | |
329 | break; | 329 | break; | |
330 | } | 330 | } | |
331 | if (error != 0) { | 331 | if (error != 0) { | |
332 | ifp->if_oerrors++; | 332 | if_statinc(ifp, if_oerrors); | |
333 | m_freem(m); | 333 | m_freem(m); | |
334 | continue; | 334 | continue; | |
335 | } | 335 | } | |
336 | 336 | |||
337 | bpf_mtap(ifp, m, BPF_D_OUT); | 337 | bpf_mtap(ifp, m, BPF_D_OUT); | |
338 | } | 338 | } | |
339 | } | 339 | } | |
340 | 340 | |||
341 | int | 341 | int | |
342 | bwfm_init(struct ifnet *ifp) | 342 | bwfm_init(struct ifnet *ifp) | |
343 | { | 343 | { | |
344 | struct bwfm_softc *sc = ifp->if_softc; | 344 | struct bwfm_softc *sc = ifp->if_softc; | |
345 | struct ieee80211com *ic = &sc->sc_ic; | 345 | struct ieee80211com *ic = &sc->sc_ic; | |
@@ -501,27 +501,27 @@ bwfm_stop(struct ifnet *ifp, int disable | @@ -501,27 +501,27 @@ bwfm_stop(struct ifnet *ifp, int disable | |||
501 | } | 501 | } | |
502 | 502 | |||
503 | void | 503 | void | |
504 | bwfm_watchdog(struct ifnet *ifp) | 504 | bwfm_watchdog(struct ifnet *ifp) | |
505 | { | 505 | { | |
506 | struct bwfm_softc *sc = ifp->if_softc; | 506 | struct bwfm_softc *sc = ifp->if_softc; | |
507 | struct ieee80211com *ic = &sc->sc_ic; | 507 | struct ieee80211com *ic = &sc->sc_ic; | |
508 | 508 | |||
509 | ifp->if_timer = 0; | 509 | ifp->if_timer = 0; | |
510 | 510 | |||
511 | if (sc->sc_tx_timer > 0) { | 511 | if (sc->sc_tx_timer > 0) { | |
512 | if (--sc->sc_tx_timer == 0) { | 512 | if (--sc->sc_tx_timer == 0) { | |
513 | printf("%s: device timeout\n", DEVNAME(sc)); | 513 | printf("%s: device timeout\n", DEVNAME(sc)); | |
514 | ifp->if_oerrors++; | 514 | if_statinc(ifp, if_oerrors); | |
515 | return; | 515 | return; | |
516 | } | 516 | } | |
517 | ifp->if_timer = 1; | 517 | ifp->if_timer = 1; | |
518 | } | 518 | } | |
519 | ieee80211_watchdog(ic); | 519 | ieee80211_watchdog(ic); | |
520 | } | 520 | } | |
521 | 521 | |||
522 | int | 522 | int | |
523 | bwfm_ioctl(struct ifnet *ifp, u_long cmd, void *data) | 523 | bwfm_ioctl(struct ifnet *ifp, u_long cmd, void *data) | |
524 | { | 524 | { | |
525 | struct bwfm_softc *sc = ifp->if_softc; | 525 | struct bwfm_softc *sc = ifp->if_softc; | |
526 | struct ieee80211com *ic = &sc->sc_ic; | 526 | struct ieee80211com *ic = &sc->sc_ic; | |
527 | int s, error = 0; | 527 | int s, error = 0; |
--- src/sys/dev/ic/bwi.c 2018/12/22 14:07:53 1.36
+++ src/sys/dev/ic/bwi.c 2020/01/29 14:14:55 1.37
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: bwi.c,v 1.36 2018/12/22 14:07:53 maxv Exp $ */ | 1 | /* $NetBSD: bwi.c,v 1.37 2020/01/29 14:14:55 thorpej Exp $ */ | |
2 | /* $OpenBSD: bwi.c,v 1.74 2008/02/25 21:13:30 mglocker Exp $ */ | 2 | /* $OpenBSD: bwi.c,v 1.74 2008/02/25 21:13:30 mglocker Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 2007 The DragonFly Project. All rights reserved. | 5 | * Copyright (c) 2007 The DragonFly Project. All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The DragonFly Project | 7 | * This code is derived from software contributed to The DragonFly Project | |
8 | * by Sepherosa Ziehau <sepherosa@gmail.com> | 8 | * by Sepherosa Ziehau <sepherosa@gmail.com> | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * | 13 | * | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -38,27 +38,27 @@ | @@ -38,27 +38,27 @@ | |||
38 | */ | 38 | */ | |
39 | 39 | |||
40 | /* | 40 | /* | |
41 | * Broadcom AirForce BCM43xx IEEE 802.11b/g wireless network driver | 41 | * Broadcom AirForce BCM43xx IEEE 802.11b/g wireless network driver | |
42 | * Generic back end | 42 | * Generic back end | |
43 | */ | 43 | */ | |
44 | 44 | |||
45 | /* [TRC: XXX Names beginning with `bwi_ieee80211_*' are those that I | 45 | /* [TRC: XXX Names beginning with `bwi_ieee80211_*' are those that I | |
46 | think should be in NetBSD's generic 802.11 code, not in this | 46 | think should be in NetBSD's generic 802.11 code, not in this | |
47 | driver.] */ | 47 | driver.] */ | |
48 | 48 | |||
49 | 49 | |||
50 | #include <sys/cdefs.h> | 50 | #include <sys/cdefs.h> | |
51 | __KERNEL_RCSID(0, "$NetBSD: bwi.c,v 1.36 2018/12/22 14:07:53 maxv Exp $"); | 51 | __KERNEL_RCSID(0, "$NetBSD: bwi.c,v 1.37 2020/01/29 14:14:55 thorpej Exp $"); | |
52 | 52 | |||
53 | #include <sys/param.h> | 53 | #include <sys/param.h> | |
54 | #include <sys/callout.h> | 54 | #include <sys/callout.h> | |
55 | #include <sys/device.h> | 55 | #include <sys/device.h> | |
56 | #include <sys/kernel.h> | 56 | #include <sys/kernel.h> | |
57 | #include <sys/malloc.h> | 57 | #include <sys/malloc.h> | |
58 | #include <sys/mbuf.h> | 58 | #include <sys/mbuf.h> | |
59 | #include <sys/socket.h> | 59 | #include <sys/socket.h> | |
60 | #include <sys/sockio.h> | 60 | #include <sys/sockio.h> | |
61 | #include <sys/sysctl.h> | 61 | #include <sys/sysctl.h> | |
62 | #include <sys/systm.h> | 62 | #include <sys/systm.h> | |
63 | #include <sys/bus.h> | 63 | #include <sys/bus.h> | |
64 | #include <sys/intr.h> | 64 | #include <sys/intr.h> | |
@@ -7410,95 +7410,95 @@ bwi_start(struct ifnet *ifp) | @@ -7410,95 +7410,95 @@ bwi_start(struct ifnet *ifp) | |||
7410 | } else { | 7410 | } else { | |
7411 | struct ether_header *eh; | 7411 | struct ether_header *eh; | |
7412 | 7412 | |||
7413 | if (ic->ic_state != IEEE80211_S_RUN) | 7413 | if (ic->ic_state != IEEE80211_S_RUN) | |
7414 | break; | 7414 | break; | |
7415 | 7415 | |||
7416 | IFQ_DEQUEUE(&ifp->if_snd, m); | 7416 | IFQ_DEQUEUE(&ifp->if_snd, m); | |
7417 | if (m == NULL) | 7417 | if (m == NULL) | |
7418 | break; | 7418 | break; | |
7419 | 7419 | |||
7420 | if (m->m_len < sizeof(*eh)) { | 7420 | if (m->m_len < sizeof(*eh)) { | |
7421 | m = m_pullup(m, sizeof(*eh)); | 7421 | m = m_pullup(m, sizeof(*eh)); | |
7422 | if (m == NULL) { | 7422 | if (m == NULL) { | |
7423 | ifp->if_oerrors++; | 7423 | if_statinc(ifp, if_oerrors); | |
7424 | continue; | 7424 | continue; | |
7425 | } | 7425 | } | |
7426 | } | 7426 | } | |
7427 | eh = mtod(m, struct ether_header *); | 7427 | eh = mtod(m, struct ether_header *); | |
7428 | 7428 | |||
7429 | ni = ieee80211_find_txnode(ic, eh->ether_dhost); | 7429 | ni = ieee80211_find_txnode(ic, eh->ether_dhost); | |
7430 | if (ni == NULL) { | 7430 | if (ni == NULL) { | |
7431 | ifp->if_oerrors++; | 7431 | if_statinc(ifp, if_oerrors); | |
7432 | m_freem(m); | 7432 | m_freem(m); | |
7433 | continue; | 7433 | continue; | |
7434 | } | 7434 | } | |
7435 | 7435 | |||
7436 | /* [TRC: XXX Superstitiously cargo-culted from | 7436 | /* [TRC: XXX Superstitiously cargo-culted from | |
7437 | ath(4) and wi(4).] */ | 7437 | ath(4) and wi(4).] */ | |
7438 | if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && | 7438 | if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && | |
7439 | (m->m_flags & M_PWR_SAV) == 0) { | 7439 | (m->m_flags & M_PWR_SAV) == 0) { | |
7440 | ieee80211_pwrsave(ic, ni, m); | 7440 | ieee80211_pwrsave(ic, ni, m); | |
7441 | ieee80211_free_node(ni); | 7441 | ieee80211_free_node(ni); | |
7442 | continue; | 7442 | continue; | |
7443 | } | 7443 | } | |
7444 | 7444 | |||
7445 | /* [TRC: XXX I *think* we're supposed to do | 7445 | /* [TRC: XXX I *think* we're supposed to do | |
7446 | this, but honestly I have no clue. We don't | 7446 | this, but honestly I have no clue. We don't | |
7447 | use M_WME_GETAC, so...] */ | 7447 | use M_WME_GETAC, so...] */ | |
7448 | if (ieee80211_classify(ic, m, ni)) { | 7448 | if (ieee80211_classify(ic, m, ni)) { | |
7449 | /* [TRC: XXX What debug flag?] */ | 7449 | /* [TRC: XXX What debug flag?] */ | |
7450 | DPRINTF(sc, BWI_DBG_MISC, | 7450 | DPRINTF(sc, BWI_DBG_MISC, | |
7451 | "%s: discard, classification failure\n", | 7451 | "%s: discard, classification failure\n", | |
7452 | __func__); | 7452 | __func__); | |
7453 | ifp->if_oerrors++; | 7453 | if_statinc(ifp, if_oerrors); | |
7454 | m_freem(m); | 7454 | m_freem(m); | |
7455 | ieee80211_free_node(ni); | 7455 | ieee80211_free_node(ni); | |
7456 | continue; | 7456 | continue; | |
7457 | } | 7457 | } | |
7458 | 7458 | |||
7459 | /* [TRC: XXX wi(4) and awi(4) do this; iwi(4) | 7459 | /* [TRC: XXX wi(4) and awi(4) do this; iwi(4) | |
7460 | doesn't.] */ | 7460 | doesn't.] */ | |
7461 | ifp->if_opackets++; | 7461 | if_statinc(ifp, if_opackets); | |
7462 | 7462 | |||
7463 | /* [TRC: XXX When should the packet be | 7463 | /* [TRC: XXX When should the packet be | |
7464 | filtered? Different drivers appear to do it | 7464 | filtered? Different drivers appear to do it | |
7465 | at different times.] */ | 7465 | at different times.] */ | |
7466 | /* TODO: PS */ | 7466 | /* TODO: PS */ | |
7467 | bpf_mtap(ifp, m, BPF_D_OUT); | 7467 | bpf_mtap(ifp, m, BPF_D_OUT); | |
7468 | m = ieee80211_encap(ic, m, ni); | 7468 | m = ieee80211_encap(ic, m, ni); | |
7469 | if (m == NULL) { | 7469 | if (m == NULL) { | |
7470 | ifp->if_oerrors++; | 7470 | if_statinc(ifp, if_oerrors); | |
7471 | ieee80211_free_node(ni); | 7471 | ieee80211_free_node(ni); | |
7472 | continue; | 7472 | continue; | |
7473 | } | 7473 | } | |
7474 | } | 7474 | } | |
7475 | bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); | 7475 | bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); | |
7476 | 7476 | |||
7477 | wh = mtod(m, struct ieee80211_frame *); | 7477 | wh = mtod(m, struct ieee80211_frame *); | |
7478 | /* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */ | 7478 | /* [TRC: XXX What about ic->ic_flags & IEEE80211_F_PRIVACY?] */ | |
7479 | if (wh->i_fc[1] & IEEE80211_FC1_WEP) { | 7479 | if (wh->i_fc[1] & IEEE80211_FC1_WEP) { | |
7480 | if (ieee80211_crypto_encap(ic, ni, m) == NULL) { | 7480 | if (ieee80211_crypto_encap(ic, ni, m) == NULL) { | |
7481 | ifp->if_oerrors++; | 7481 | if_statinc(ifp, if_oerrors); | |
7482 | m_freem(m); | 7482 | m_freem(m); | |
7483 | ieee80211_free_node(ni); | 7483 | ieee80211_free_node(ni); | |
7484 | continue; | 7484 | continue; | |
7485 | } | 7485 | } | |
7486 | } | 7486 | } | |
7487 | wh = NULL; /* [TRC: XXX Huh?] */ | 7487 | wh = NULL; /* [TRC: XXX Huh?] */ | |
7488 | 7488 | |||
7489 | if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) { | 7489 | if (bwi_encap(sc, idx, m, &ni, mgt_pkt) != 0) { | |
7490 | /* 'm' is freed in bwi_encap() if we reach here */ | 7490 | /* 'm' is freed in bwi_encap() if we reach here */ | |
7491 | ifp->if_oerrors++; | 7491 | if_statinc(ifp, if_oerrors); | |
7492 | if (ni != NULL) | 7492 | if (ni != NULL) | |
7493 | ieee80211_free_node(ni); | 7493 | ieee80211_free_node(ni); | |
7494 | continue; | 7494 | continue; | |
7495 | } | 7495 | } | |
7496 | 7496 | |||
7497 | trans = 1; | 7497 | trans = 1; | |
7498 | tbd->tbd_used++; | 7498 | tbd->tbd_used++; | |
7499 | idx = (idx + 1) % BWI_TX_NDESC; | 7499 | idx = (idx + 1) % BWI_TX_NDESC; | |
7500 | 7500 | |||
7501 | if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { | 7501 | if (tbd->tbd_used + BWI_TX_NSPRDESC >= BWI_TX_NDESC) { | |
7502 | ifp->if_flags |= IFF_OACTIVE; | 7502 | ifp->if_flags |= IFF_OACTIVE; | |
7503 | break; | 7503 | break; | |
7504 | } | 7504 | } | |
@@ -7514,27 +7514,27 @@ static void | @@ -7514,27 +7514,27 @@ static void | |||
7514 | bwi_watchdog(struct ifnet *ifp) | 7514 | bwi_watchdog(struct ifnet *ifp) | |
7515 | { | 7515 | { | |
7516 | struct bwi_softc *sc = ifp->if_softc; | 7516 | struct bwi_softc *sc = ifp->if_softc; | |
7517 | 7517 | |||
7518 | ifp->if_timer = 0; | 7518 | ifp->if_timer = 0; | |
7519 | 7519 | |||
7520 | if ((ifp->if_flags & IFF_RUNNING) == 0 || | 7520 | if ((ifp->if_flags & IFF_RUNNING) == 0 || | |
7521 | !device_is_active(sc->sc_dev)) | 7521 | !device_is_active(sc->sc_dev)) | |
7522 | return; | 7522 | return; | |
7523 | 7523 | |||
7524 | if (sc->sc_tx_timer) { | 7524 | if (sc->sc_tx_timer) { | |
7525 | if (--sc->sc_tx_timer == 0) { | 7525 | if (--sc->sc_tx_timer == 0) { | |
7526 | aprint_error_dev(sc->sc_dev, "device timeout\n"); | 7526 | aprint_error_dev(sc->sc_dev, "device timeout\n"); | |
7527 | ifp->if_oerrors++; | 7527 | if_statinc(ifp, if_oerrors); | |
7528 | /* TODO */ | 7528 | /* TODO */ | |
7529 | /* [TRC: XXX TODO what? Stop the device? | 7529 | /* [TRC: XXX TODO what? Stop the device? | |
7530 | Bring it down? iwi(4) does this.] */ | 7530 | Bring it down? iwi(4) does this.] */ | |
7531 | } else | 7531 | } else | |
7532 | ifp->if_timer = 1; | 7532 | ifp->if_timer = 1; | |
7533 | } | 7533 | } | |
7534 | 7534 | |||
7535 | ieee80211_watchdog(&sc->sc_ic); | 7535 | ieee80211_watchdog(&sc->sc_ic); | |
7536 | } | 7536 | } | |
7537 | 7537 | |||
7538 | static void | 7538 | static void | |
7539 | bwi_stop(struct ifnet *ifp, int state_chg) | 7539 | bwi_stop(struct ifnet *ifp, int state_chg) | |
7540 | { | 7540 | { | |
@@ -8465,43 +8465,43 @@ bwi_rxeof(struct bwi_softc *sc, int end_ | @@ -8465,43 +8465,43 @@ bwi_rxeof(struct bwi_softc *sc, int end_ | |||
8465 | struct bwi_rxbuf_hdr *hdr; | 8465 | struct bwi_rxbuf_hdr *hdr; | |
8466 | struct ieee80211_frame_min *wh; | 8466 | struct ieee80211_frame_min *wh; | |
8467 | struct ieee80211_node *ni; | 8467 | struct ieee80211_node *ni; | |
8468 | struct mbuf *m; | 8468 | struct mbuf *m; | |
8469 | const void *plcp; | 8469 | const void *plcp; | |
8470 | uint16_t flags2; | 8470 | uint16_t flags2; | |
8471 | int buflen, wh_ofs, hdr_extra, rssi, type, rate; | 8471 | int buflen, wh_ofs, hdr_extra, rssi, type, rate; | |
8472 | 8472 | |||
8473 | m = rb->rb_mbuf; | 8473 | m = rb->rb_mbuf; | |
8474 | bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0, | 8474 | bus_dmamap_sync(sc->sc_dmat, rb->rb_dmap, 0, | |
8475 | rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); | 8475 | rb->rb_dmap->dm_mapsize, BUS_DMASYNC_POSTREAD); | |
8476 | 8476 | |||
8477 | if (bwi_newbuf(sc, idx, 0)) { | 8477 | if (bwi_newbuf(sc, idx, 0)) { | |
8478 | ifp->if_ierrors++; | 8478 | if_statinc(ifp, if_ierrors); | |
8479 | goto next; | 8479 | goto next; | |
8480 | } | 8480 | } | |
8481 | 8481 | |||
8482 | hdr = mtod(m, struct bwi_rxbuf_hdr *); | 8482 | hdr = mtod(m, struct bwi_rxbuf_hdr *); | |
8483 | flags2 = le16toh(hdr->rxh_flags2); | 8483 | flags2 = le16toh(hdr->rxh_flags2); | |
8484 | 8484 | |||
8485 | hdr_extra = 0; | 8485 | hdr_extra = 0; | |
8486 | if (flags2 & BWI_RXH_F2_TYPE2FRAME) | 8486 | if (flags2 & BWI_RXH_F2_TYPE2FRAME) | |
8487 | hdr_extra = 2; | 8487 | hdr_extra = 2; | |
8488 | wh_ofs = hdr_extra + 6; /* XXX magic number */ | 8488 | wh_ofs = hdr_extra + 6; /* XXX magic number */ | |
8489 | 8489 | |||
8490 | buflen = le16toh(hdr->rxh_buflen); | 8490 | buflen = le16toh(hdr->rxh_buflen); | |
8491 | if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { | 8491 | if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) { | |
8492 | aprint_error_dev(sc->sc_dev, "short frame %d," | 8492 | aprint_error_dev(sc->sc_dev, "short frame %d," | |
8493 | " hdr_extra %d\n", buflen, hdr_extra); | 8493 | " hdr_extra %d\n", buflen, hdr_extra); | |
8494 | ifp->if_ierrors++; | 8494 | if_statinc(ifp, if_ierrors); | |
8495 | m_freem(m); | 8495 | m_freem(m); | |
8496 | goto next; | 8496 | goto next; | |
8497 | } | 8497 | } | |
8498 | 8498 | |||
8499 | plcp = ((const uint8_t *)(hdr + 1) + hdr_extra); | 8499 | plcp = ((const uint8_t *)(hdr + 1) + hdr_extra); | |
8500 | rssi = bwi_calc_rssi(sc, hdr); | 8500 | rssi = bwi_calc_rssi(sc, hdr); | |
8501 | 8501 | |||
8502 | m_set_rcvif(m, ifp); | 8502 | m_set_rcvif(m, ifp); | |
8503 | m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); | 8503 | m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr); | |
8504 | m_adj(m, sizeof(*hdr) + wh_ofs); | 8504 | m_adj(m, sizeof(*hdr) + wh_ofs); | |
8505 | 8505 | |||
8506 | if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM) | 8506 | if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM) | |
8507 | rate = bwi_ofdm_plcp2rate(plcp); | 8507 | rate = bwi_ofdm_plcp2rate(plcp); | |
@@ -9385,27 +9385,27 @@ bwi_txeof(struct bwi_softc *sc) | @@ -9385,27 +9385,27 @@ bwi_txeof(struct bwi_softc *sc) | |||
9385 | tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0); | 9385 | tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS_0); | |
9386 | if ((tx_status0 & BWI_TXSTATUS_0_MORE) == 0) | 9386 | if ((tx_status0 & BWI_TXSTATUS_0_MORE) == 0) | |
9387 | break; | 9387 | break; | |
9388 | (void)CSR_READ_4(sc, BWI_TXSTATUS_1); | 9388 | (void)CSR_READ_4(sc, BWI_TXSTATUS_1); | |
9389 | 9389 | |||
9390 | tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK); | 9390 | tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS_0_TXID_MASK); | |
9391 | tx_info = BWI_TXSTATUS_0_INFO(tx_status0); | 9391 | tx_info = BWI_TXSTATUS_0_INFO(tx_status0); | |
9392 | 9392 | |||
9393 | if (tx_info & 0x30) /* XXX */ | 9393 | if (tx_info & 0x30) /* XXX */ | |
9394 | continue; | 9394 | continue; | |
9395 | 9395 | |||
9396 | _bwi_txeof(sc, tx_id); | 9396 | _bwi_txeof(sc, tx_id); | |
9397 | 9397 | |||
9398 | ifp->if_opackets++; | 9398 | if_statinc(ifp, if_opackets); | |
9399 | } | 9399 | } | |
9400 | 9400 | |||
9401 | if ((ifp->if_flags & IFF_OACTIVE) == 0) | 9401 | if ((ifp->if_flags & IFF_OACTIVE) == 0) | |
9402 | ifp->if_start(ifp); | 9402 | ifp->if_start(ifp); | |
9403 | 9403 | |||
9404 | splx(s); | 9404 | splx(s); | |
9405 | } | 9405 | } | |
9406 | 9406 | |||
9407 | static int | 9407 | static int | |
9408 | bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) | 9408 | bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode) | |
9409 | { | 9409 | { | |
9410 | bwi_power_on(sc, 1); | 9410 | bwi_power_on(sc, 1); | |
9411 | 9411 |
--- src/sys/dev/ic/cs89x0.c 2019/05/29 10:07:29 1.47
+++ src/sys/dev/ic/cs89x0.c 2020/01/29 14:14:55 1.48
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: cs89x0.c,v 1.47 2019/05/29 10:07:29 msaitoh Exp $ */ | 1 | /* $NetBSD: cs89x0.c,v 1.48 2020/01/29 14:14:55 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2004 Christopher Gilbert | 4 | * Copyright (c) 2004 Christopher Gilbert | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * 1. Redistributions of source code must retain the above copyright | 7 | * 1. Redistributions of source code must retain the above copyright | |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. | |
9 | * 2. Redistributions in binary form must reproduce the above copyright | 9 | * 2. Redistributions in binary form must reproduce the above copyright | |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the | |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. | |
12 | * 3. The name of the company nor the name of the author may be used to | 12 | * 3. The name of the company nor the name of the author may be used to | |
13 | * endorse or promote products derived from this software without specific | 13 | * endorse or promote products derived from this software without specific | |
14 | * prior written permission. | 14 | * prior written permission. | |
@@ -202,27 +202,27 @@ | @@ -202,27 +202,27 @@ | |||
202 | ** potentially more efficient. That function needs to be gutted (to | 202 | ** potentially more efficient. That function needs to be gutted (to | |
203 | ** deal properly with alignment issues, which it currently does wrong), | 203 | ** deal properly with alignment issues, which it currently does wrong), | |
204 | ** however, and the change doesn't gain much, so there's no point in | 204 | ** however, and the change doesn't gain much, so there's no point in | |
205 | ** enabling it now. | 205 | ** enabling it now. | |
206 | ** | 206 | ** | |
207 | ** Revision 1.8 1997/05/19 01:17:10 cgd | 207 | ** Revision 1.8 1997/05/19 01:17:10 cgd | |
208 | ** fix a comment re: the setting of the TxConfig register. Clean up | 208 | ** fix a comment re: the setting of the TxConfig register. Clean up | |
209 | ** interface counter maintenance (make it use standard idiom). | 209 | ** interface counter maintenance (make it use standard idiom). | |
210 | ** | 210 | ** | |
211 | **-- | 211 | **-- | |
212 | */ | 212 | */ | |
213 | 213 | |||
214 | #include <sys/cdefs.h> | 214 | #include <sys/cdefs.h> | |
215 | __KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.47 2019/05/29 10:07:29 msaitoh Exp $"); | 215 | __KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.48 2020/01/29 14:14:55 thorpej Exp $"); | |
216 | 216 | |||
217 | #include "opt_inet.h" | 217 | #include "opt_inet.h" | |
218 | 218 | |||
219 | #include <sys/param.h> | 219 | #include <sys/param.h> | |
220 | #include <sys/systm.h> | 220 | #include <sys/systm.h> | |
221 | #include <sys/mbuf.h> | 221 | #include <sys/mbuf.h> | |
222 | #include <sys/syslog.h> | 222 | #include <sys/syslog.h> | |
223 | #include <sys/socket.h> | 223 | #include <sys/socket.h> | |
224 | #include <sys/device.h> | 224 | #include <sys/device.h> | |
225 | #include <sys/malloc.h> | 225 | #include <sys/malloc.h> | |
226 | #include <sys/ioctl.h> | 226 | #include <sys/ioctl.h> | |
227 | #include <sys/errno.h> | 227 | #include <sys/errno.h> | |
228 | #include <sys/bus.h> | 228 | #include <sys/bus.h> | |
@@ -1452,27 +1452,27 @@ cs_counter_event(struct cs_softc *sc, ui | @@ -1452,27 +1452,27 @@ cs_counter_event(struct cs_softc *sc, ui | |||
1452 | * The tramsit event routine always checks the number of | 1452 | * The tramsit event routine always checks the number of | |
1453 | * collisions for any packet so we don't increment any | 1453 | * collisions for any packet so we don't increment any | |
1454 | * counters here, as they should already have been | 1454 | * counters here, as they should already have been | |
1455 | * considered. | 1455 | * considered. | |
1456 | */ | 1456 | */ | |
1457 | break; | 1457 | break; | |
1458 | case REG_NUM_RX_MISS: | 1458 | case REG_NUM_RX_MISS: | |
1459 | /* The count should be read before an overflow occurs. */ | 1459 | /* The count should be read before an overflow occurs. */ | |
1460 | errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_RX_MISS); | 1460 | errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_RX_MISS); | |
1461 | /* | 1461 | /* | |
1462 | * Increment the input error count, the first 6bits are the | 1462 | * Increment the input error count, the first 6bits are the | |
1463 | * register id. | 1463 | * register id. | |
1464 | */ | 1464 | */ | |
1465 | ifp->if_ierrors += ((errorCount & 0xffC0) >> 6); | 1465 | if_statadd(ifp, if_ierrors, (errorCount & 0xffC0) >> 6); | |
1466 | break; | 1466 | break; | |
1467 | default: | 1467 | default: | |
1468 | /* Do nothing */ | 1468 | /* Do nothing */ | |
1469 | break; | 1469 | break; | |
1470 | } | 1470 | } | |
1471 | } | 1471 | } | |
1472 | 1472 | |||
1473 | void | 1473 | void | |
1474 | cs_buffer_event(struct cs_softc *sc, uint16_t bufEvent) | 1474 | cs_buffer_event(struct cs_softc *sc, uint16_t bufEvent) | |
1475 | { | 1475 | { | |
1476 | 1476 | |||
1477 | /* | 1477 | /* | |
1478 | * Multiple events can be in the buffer event register at one time so | 1478 | * Multiple events can be in the buffer event register at one time so | |
@@ -1518,27 +1518,27 @@ cs_buffer_event(struct cs_softc *sc, uin | @@ -1518,27 +1518,27 @@ cs_buffer_event(struct cs_softc *sc, uin | |||
1518 | printf("%s: software initiated interrupt\n", | 1518 | printf("%s: software initiated interrupt\n", | |
1519 | device_xname(sc->sc_dev)); | 1519 | device_xname(sc->sc_dev)); | |
1520 | } | 1520 | } | |
1521 | 1521 | |||
1522 | void | 1522 | void | |
1523 | cs_transmit_event(struct cs_softc *sc, uint16_t txEvent) | 1523 | cs_transmit_event(struct cs_softc *sc, uint16_t txEvent) | |
1524 | { | 1524 | { | |
1525 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | 1525 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | |
1526 | 1526 | |||
1527 | /* If there were any errors transmitting this frame */ | 1527 | /* If there were any errors transmitting this frame */ | |
1528 | if (txEvent & (TX_EVENT_LOSS_CRS | TX_EVENT_SQE_ERR | | 1528 | if (txEvent & (TX_EVENT_LOSS_CRS | TX_EVENT_SQE_ERR | | |
1529 | TX_EVENT_OUT_WIN | TX_EVENT_JABBER | TX_EVENT_16_COLL)) { | 1529 | TX_EVENT_OUT_WIN | TX_EVENT_JABBER | TX_EVENT_16_COLL)) { | |
1530 | /* Increment the output error count */ | 1530 | /* Increment the output error count */ | |
1531 | ifp->if_oerrors++; | 1531 | if_statinc(ifp, if_oerrors); | |
1532 | 1532 | |||
1533 | /* Note carrier loss. */ | 1533 | /* Note carrier loss. */ | |
1534 | if (txEvent & TX_EVENT_LOSS_CRS) | 1534 | if (txEvent & TX_EVENT_LOSS_CRS) | |
1535 | sc->sc_carrier = 0; | 1535 | sc->sc_carrier = 0; | |
1536 | 1536 | |||
1537 | /* If debugging is enabled then log error messages */ | 1537 | /* If debugging is enabled then log error messages */ | |
1538 | if (ifp->if_flags & IFF_DEBUG) { | 1538 | if (ifp->if_flags & IFF_DEBUG) { | |
1539 | if (txEvent & TX_EVENT_LOSS_CRS) | 1539 | if (txEvent & TX_EVENT_LOSS_CRS) | |
1540 | aprint_error_dev(sc->sc_dev, "lost carrier\n"); | 1540 | aprint_error_dev(sc->sc_dev, "lost carrier\n"); | |
1541 | 1541 | |||
1542 | if (txEvent & TX_EVENT_SQE_ERR) | 1542 | if (txEvent & TX_EVENT_SQE_ERR) | |
1543 | aprint_error_dev(sc->sc_dev, "SQE error\n"); | 1543 | aprint_error_dev(sc->sc_dev, "SQE error\n"); | |
1544 | 1544 | |||
@@ -1552,32 +1552,35 @@ cs_transmit_event(struct cs_softc *sc, u | @@ -1552,32 +1552,35 @@ cs_transmit_event(struct cs_softc *sc, u | |||
1552 | if (txEvent & TX_EVENT_16_COLL) | 1552 | if (txEvent & TX_EVENT_16_COLL) | |
1553 | aprint_error_dev(sc->sc_dev, | 1553 | aprint_error_dev(sc->sc_dev, | |
1554 | "16 collisions\n"); | 1554 | "16 collisions\n"); | |
1555 | } | 1555 | } | |
1556 | } else { | 1556 | } else { | |
1557 | /* Transmission successful, carrier is up. */ | 1557 | /* Transmission successful, carrier is up. */ | |
1558 | sc->sc_carrier = 1; | 1558 | sc->sc_carrier = 1; | |
1559 | #ifdef SHARK | 1559 | #ifdef SHARK | |
1560 | ledNetActive(); | 1560 | ledNetActive(); | |
1561 | #endif | 1561 | #endif | |
1562 | } | 1562 | } | |
1563 | 1563 | |||
1564 | /* Add the number of collisions for this frame */ | 1564 | /* Add the number of collisions for this frame */ | |
1565 | net_stat_ref_t nsr = IF_STAT_GETREF(ifp); | |||
1565 | if (txEvent & TX_EVENT_16_COLL) | 1566 | if (txEvent & TX_EVENT_16_COLL) | |
1566 | ifp->if_collisions += 16; | 1567 | if_statadd_ref(nsr, if_collisions, 16); | |
1567 | else | 1568 | else | |
1568 | ifp->if_collisions += ((txEvent & TX_EVENT_COLL_MASK) >> 11); | 1569 | if_statadd_ref(nsr, if_collisions, | |
1570 | ((txEvent & TX_EVENT_COLL_MASK) >> 11)); | |||
1569 | 1571 | |||
1570 | ifp->if_opackets++; | 1572 | if_statinc_ref(nsr, if_opackets); | |
1573 | IF_STAT_PUTREF(ifp); | |||
1571 | 1574 | |||
1572 | /* Transmission is no longer in progress */ | 1575 | /* Transmission is no longer in progress */ | |
1573 | sc->sc_txbusy = FALSE; | 1576 | sc->sc_txbusy = FALSE; | |
1574 | 1577 | |||
1575 | /* If there is more to transmit, start the next transmission */ | 1578 | /* If there is more to transmit, start the next transmission */ | |
1576 | if_schedule_deferred_start(ifp); | 1579 | if_schedule_deferred_start(ifp); | |
1577 | } | 1580 | } | |
1578 | 1581 | |||
1579 | void | 1582 | void | |
1580 | cs_print_rx_errors(struct cs_softc *sc, uint16_t rxEvent) | 1583 | cs_print_rx_errors(struct cs_softc *sc, uint16_t rxEvent) | |
1581 | { | 1584 | { | |
1582 | 1585 | |||
1583 | if (rxEvent & RX_EVENT_RUNT) | 1586 | if (rxEvent & RX_EVENT_RUNT) | |
@@ -1595,27 +1598,27 @@ cs_print_rx_errors(struct cs_softc *sc, | @@ -1595,27 +1598,27 @@ cs_print_rx_errors(struct cs_softc *sc, | |||
1595 | if (rxEvent & RX_EVENT_DRIBBLE) | 1598 | if (rxEvent & RX_EVENT_DRIBBLE) | |
1596 | aprint_error_dev(sc->sc_dev, "dribble bits\n"); | 1599 | aprint_error_dev(sc->sc_dev, "dribble bits\n"); | |
1597 | } | 1600 | } | |
1598 | } | 1601 | } | |
1599 | 1602 | |||
1600 | void | 1603 | void | |
1601 | cs_receive_event(struct cs_softc *sc, uint16_t rxEvent) | 1604 | cs_receive_event(struct cs_softc *sc, uint16_t rxEvent) | |
1602 | { | 1605 | { | |
1603 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | 1606 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | |
1604 | 1607 | |||
1605 | /* If the frame was not received OK */ | 1608 | /* If the frame was not received OK */ | |
1606 | if (!(rxEvent & RX_EVENT_RX_OK)) { | 1609 | if (!(rxEvent & RX_EVENT_RX_OK)) { | |
1607 | /* Increment the input error count */ | 1610 | /* Increment the input error count */ | |
1608 | ifp->if_ierrors++; | 1611 | if_statinc(ifp, if_ierrors); | |
1609 | 1612 | |||
1610 | /* If debugging is enabled then log error messages. */ | 1613 | /* If debugging is enabled then log error messages. */ | |
1611 | if (ifp->if_flags & IFF_DEBUG) { | 1614 | if (ifp->if_flags & IFF_DEBUG) { | |
1612 | if (rxEvent != REG_NUM_RX_EVENT) { | 1615 | if (rxEvent != REG_NUM_RX_EVENT) { | |
1613 | cs_print_rx_errors(sc, rxEvent); | 1616 | cs_print_rx_errors(sc, rxEvent); | |
1614 | 1617 | |||
1615 | /* | 1618 | /* | |
1616 | * Must read the length of all received | 1619 | * Must read the length of all received | |
1617 | * frames | 1620 | * frames | |
1618 | */ | 1621 | */ | |
1619 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); | 1622 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); | |
1620 | 1623 | |||
1621 | /* Skip the received frame */ | 1624 | /* Skip the received frame */ | |
@@ -1681,27 +1684,27 @@ cs_process_receive(struct cs_softc *sc) | @@ -1681,27 +1684,27 @@ cs_process_receive(struct cs_softc *sc) | |||
1681 | aprint_error_dev(sc->sc_dev, "invalid packet length %d\n", | 1684 | aprint_error_dev(sc->sc_dev, "invalid packet length %d\n", | |
1682 | totlen); | 1685 | totlen); | |
1683 | 1686 | |||
1684 | /* Skip the received frame */ | 1687 | /* Skip the received frame */ | |
1685 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, | 1688 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, | |
1686 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); | 1689 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); | |
1687 | return; | 1690 | return; | |
1688 | } | 1691 | } | |
1689 | 1692 | |||
1690 | MGETHDR(m, M_DONTWAIT, MT_DATA); | 1693 | MGETHDR(m, M_DONTWAIT, MT_DATA); | |
1691 | if (m == 0) { | 1694 | if (m == 0) { | |
1692 | aprint_error_dev(sc->sc_dev, | 1695 | aprint_error_dev(sc->sc_dev, | |
1693 | "cs_process_receive: unable to allocate mbuf\n"); | 1696 | "cs_process_receive: unable to allocate mbuf\n"); | |
1694 | ifp->if_ierrors++; | 1697 | if_statinc(ifp, if_ierrors); | |
1695 | /* | 1698 | /* | |
1696 | * Couldn't allocate an mbuf so things are not good, may as | 1699 | * Couldn't allocate an mbuf so things are not good, may as | |
1697 | * well drop the packet I think. | 1700 | * well drop the packet I think. | |
1698 | * | 1701 | * | |
1699 | * have already read the length so we should be right to skip | 1702 | * have already read the length so we should be right to skip | |
1700 | * the packet. | 1703 | * the packet. | |
1701 | */ | 1704 | */ | |
1702 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, | 1705 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, | |
1703 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); | 1706 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); | |
1704 | return; | 1707 | return; | |
1705 | } | 1708 | } | |
1706 | m_set_rcvif(m, ifp); | 1709 | m_set_rcvif(m, ifp); | |
1707 | m->m_pkthdr.len = totlen; | 1710 | m->m_pkthdr.len = totlen; | |
@@ -1763,27 +1766,27 @@ cs_process_rx_early(struct cs_softc *sc) | @@ -1763,27 +1766,27 @@ cs_process_rx_early(struct cs_softc *sc) | |||
1763 | unsigned int frameOffset; | 1766 | unsigned int frameOffset; | |
1764 | 1767 | |||
1765 | 1768 | |||
1766 | ifp = &sc->sc_ethercom.ec_if; | 1769 | ifp = &sc->sc_ethercom.ec_if; | |
1767 | 1770 | |||
1768 | /* Initialize the frame offset */ | 1771 | /* Initialize the frame offset */ | |
1769 | frameOffset = PKTPG_RX_FRAME; | 1772 | frameOffset = PKTPG_RX_FRAME; | |
1770 | frameCount = 0; | 1773 | frameCount = 0; | |
1771 | 1774 | |||
1772 | MGETHDR(m, M_DONTWAIT, MT_DATA); | 1775 | MGETHDR(m, M_DONTWAIT, MT_DATA); | |
1773 | if (m == 0) { | 1776 | if (m == 0) { | |
1774 | aprint_error_dev(sc->sc_dev, | 1777 | aprint_error_dev(sc->sc_dev, | |
1775 | "cs_process_rx_early: unable to allocate mbuf\n"); | 1778 | "cs_process_rx_early: unable to allocate mbuf\n"); | |
1776 | ifp->if_ierrors++; | 1779 | if_statinc(ifp, if_ierrors); | |
1777 | /* | 1780 | /* | |
1778 | * Couldn't allocate an mbuf so things are not good, may as | 1781 | * Couldn't allocate an mbuf so things are not good, may as | |
1779 | * well drop the packet I think. | 1782 | * well drop the packet I think. | |
1780 | * | 1783 | * | |
1781 | * have already read the length so we should be right to skip | 1784 | * have already read the length so we should be right to skip | |
1782 | * the packet. | 1785 | * the packet. | |
1783 | */ | 1786 | */ | |
1784 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, | 1787 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, | |
1785 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); | 1788 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); | |
1786 | return; | 1789 | return; | |
1787 | } | 1790 | } | |
1788 | m_set_rcvif(m, ifp); | 1791 | m_set_rcvif(m, ifp); | |
1789 | /* | 1792 | /* | |
@@ -1838,27 +1841,27 @@ cs_process_rx_early(struct cs_softc *sc) | @@ -1838,27 +1841,27 @@ cs_process_rx_early(struct cs_softc *sc) | |||
1838 | * forced skip. | 1841 | * forced skip. | |
1839 | */ | 1842 | */ | |
1840 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_STATUS); | 1843 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_STATUS); | |
1841 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); | 1844 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); | |
1842 | 1845 | |||
1843 | /* | 1846 | /* | |
1844 | * Now read the RX_EVENT register to perform an implied skip. | 1847 | * Now read the RX_EVENT register to perform an implied skip. | |
1845 | */ | 1848 | */ | |
1846 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT); | 1849 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT); | |
1847 | 1850 | |||
1848 | cs_ether_input(sc, m); | 1851 | cs_ether_input(sc, m); | |
1849 | } else { | 1852 | } else { | |
1850 | m_freem(m); | 1853 | m_freem(m); | |
1851 | ifp->if_ierrors++; | 1854 | if_statinc(ifp, if_ierrors); | |
1852 | } | 1855 | } | |
1853 | } | 1856 | } | |
1854 | 1857 | |||
1855 | void | 1858 | void | |
1856 | cs_start_output(struct ifnet *ifp) | 1859 | cs_start_output(struct ifnet *ifp) | |
1857 | { | 1860 | { | |
1858 | struct cs_softc *sc; | 1861 | struct cs_softc *sc; | |
1859 | struct mbuf *pMbuf; | 1862 | struct mbuf *pMbuf; | |
1860 | struct mbuf *pMbufChain; | 1863 | struct mbuf *pMbufChain; | |
1861 | uint16_t BusStatus; | 1864 | uint16_t BusStatus; | |
1862 | uint16_t Length; | 1865 | uint16_t Length; | |
1863 | int txLoop = 0; | 1866 | int txLoop = 0; | |
1864 | int dropout = 0; | 1867 | int dropout = 0; | |
@@ -1932,27 +1935,27 @@ cs_start_output(struct ifnet *ifp) | @@ -1932,27 +1935,27 @@ cs_start_output(struct ifnet *ifp) | |||
1932 | BusStatus = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_ST); | 1935 | BusStatus = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_ST); | |
1933 | 1936 | |||
1934 | /* | 1937 | /* | |
1935 | * If there was an error in the transmit bid free the | 1938 | * If there was an error in the transmit bid free the | |
1936 | * mbuf and go on. This is presuming that mbuf is | 1939 | * mbuf and go on. This is presuming that mbuf is | |
1937 | * corrupt. | 1940 | * corrupt. | |
1938 | */ | 1941 | */ | |
1939 | if (BusStatus & BUS_ST_TX_BID_ERR) { | 1942 | if (BusStatus & BUS_ST_TX_BID_ERR) { | |
1940 | aprint_error_dev(sc->sc_dev, | 1943 | aprint_error_dev(sc->sc_dev, | |
1941 | "transmit bid error (too big)"); | 1944 | "transmit bid error (too big)"); | |
1942 | 1945 | |||
1943 | /* Discard the bad mbuf chain */ | 1946 | /* Discard the bad mbuf chain */ | |
1944 | m_freem(pMbufChain); | 1947 | m_freem(pMbufChain); | |
1945 | sc->sc_ethercom.ec_if.if_oerrors++; | 1948 | if_statinc(&sc->sc_ethercom.ec_if, if_oerrors); | |
1946 | 1949 | |||
1947 | /* Loop up to transmit the next chain */ | 1950 | /* Loop up to transmit the next chain */ | |
1948 | txLoop = 0; | 1951 | txLoop = 0; | |
1949 | } else { | 1952 | } else { | |
1950 | if (BusStatus & BUS_ST_RDY4TXNOW) { | 1953 | if (BusStatus & BUS_ST_RDY4TXNOW) { | |
1951 | /* | 1954 | /* | |
1952 | * The chip is ready for transmission | 1955 | * The chip is ready for transmission | |
1953 | * now | 1956 | * now | |
1954 | */ | 1957 | */ | |
1955 | /* | 1958 | /* | |
1956 | * Copy the frame to the chip to | 1959 | * Copy the frame to the chip to | |
1957 | * start transmission | 1960 | * start transmission | |
1958 | */ | 1961 | */ | |
@@ -1973,27 +1976,27 @@ cs_start_output(struct ifnet *ifp) | @@ -1973,27 +1976,27 @@ cs_start_output(struct ifnet *ifp) | |||
1973 | txLoop++; | 1976 | txLoop++; | |
1974 | if (txLoop > CS_OUTPUT_LOOP_MAX) { | 1977 | if (txLoop > CS_OUTPUT_LOOP_MAX) { | |
1975 | /* Free the mbuf chain */ | 1978 | /* Free the mbuf chain */ | |
1976 | m_freem(pMbufChain); | 1979 | m_freem(pMbufChain); | |
1977 | /* | 1980 | /* | |
1978 | * Transmission is not in | 1981 | * Transmission is not in | |
1979 | * progress | 1982 | * progress | |
1980 | */ | 1983 | */ | |
1981 | sc->sc_txbusy = FALSE; | 1984 | sc->sc_txbusy = FALSE; | |
1982 | /* | 1985 | /* | |
1983 | * Increment the output error | 1986 | * Increment the output error | |
1984 | * count | 1987 | * count | |
1985 | */ | 1988 | */ | |
1986 | ifp->if_oerrors++; | 1989 | if_statinc(ifp, if_oerrors); | |
1987 | /* | 1990 | /* | |
1988 | * exit the routine and drop | 1991 | * exit the routine and drop | |
1989 | * the packet. | 1992 | * the packet. | |
1990 | */ | 1993 | */ | |
1991 | txLoop = 0; | 1994 | txLoop = 0; | |
1992 | dropout = 1; | 1995 | dropout = 1; | |
1993 | } | 1996 | } | |
1994 | } | 1997 | } | |
1995 | } | 1998 | } | |
1996 | } while (txLoop); | 1999 | } while (txLoop); | |
1997 | } | 2000 | } | |
1998 | } | 2001 | } | |
1999 | 2002 |
--- src/sys/dev/ic/dm9000.c 2019/05/29 10:07:29 1.21
+++ src/sys/dev/ic/dm9000.c 2020/01/29 14:14:55 1.22
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: dm9000.c,v 1.21 2019/05/29 10:07:29 msaitoh Exp $ */ | 1 | /* $NetBSD: dm9000.c,v 1.22 2020/01/29 14:14:55 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2009 Paul Fleischer | 4 | * Copyright (c) 2009 Paul Fleischer | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * 1. Redistributions of source code must retain the above copyright | 7 | * 1. Redistributions of source code must retain the above copyright | |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. | |
9 | * 2. Redistributions in binary form must reproduce the above copyright | 9 | * 2. Redistributions in binary form must reproduce the above copyright | |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the | |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. | |
12 | * 3. The name of the company nor the name of the author may be used to | 12 | * 3. The name of the company nor the name of the author may be used to | |
13 | * endorse or promote products derived from this software without specific | 13 | * endorse or promote products derived from this software without specific | |
14 | * prior written permission. | 14 | * prior written permission. | |
@@ -550,29 +550,29 @@ int dme_intr(void *arg) | @@ -550,29 +550,29 @@ int dme_intr(void *arg) | |||
550 | 550 | |||
551 | nsr = dme_read(sc, DM9000_NSR); | 551 | nsr = dme_read(sc, DM9000_NSR); | |
552 | 552 | |||
553 | if (nsr & DM9000_NSR_TX1END) { | 553 | if (nsr & DM9000_NSR_TX1END) { | |
554 | tx_status = dme_read(sc, DM9000_TSR1); | 554 | tx_status = dme_read(sc, DM9000_TSR1); | |
555 | TX_DPRINTF(("dme_intr: Sent using channel 0\n")); | 555 | TX_DPRINTF(("dme_intr: Sent using channel 0\n")); | |
556 | } else if (nsr & DM9000_NSR_TX2END) { | 556 | } else if (nsr & DM9000_NSR_TX2END) { | |
557 | tx_status = dme_read(sc, DM9000_TSR2); | 557 | tx_status = dme_read(sc, DM9000_TSR2); | |
558 | TX_DPRINTF(("dme_intr: Sent using channel 1\n")); | 558 | TX_DPRINTF(("dme_intr: Sent using channel 1\n")); | |
559 | } | 559 | } | |
560 | 560 | |||
561 | if (tx_status == 0x0) { | 561 | if (tx_status == 0x0) { | |
562 | /* Frame successfully sent */ | 562 | /* Frame successfully sent */ | |
563 | ifp->if_opackets++; | 563 | if_statinc(ifp, if_opackets); | |
564 | } else { | 564 | } else { | |
565 | ifp->if_oerrors++; | 565 | if_statinc(ifp, if_oerrors); | |
566 | } | 566 | } | |
567 | 567 | |||
568 | /* If we have nothing ready to transmit, prepare something */ | 568 | /* If we have nothing ready to transmit, prepare something */ | |
569 | if (!sc->txready) | 569 | if (!sc->txready) | |
570 | dme_prepare(sc, ifp); | 570 | dme_prepare(sc, ifp); | |
571 | 571 | |||
572 | if (sc->txready) | 572 | if (sc->txready) | |
573 | dme_transmit(sc); | 573 | dme_transmit(sc); | |
574 | 574 | |||
575 | /* Prepare the next frame */ | 575 | /* Prepare the next frame */ | |
576 | dme_prepare(sc, ifp); | 576 | dme_prepare(sc, ifp); | |
577 | 577 | |||
578 | } | 578 | } | |
@@ -787,38 +787,38 @@ dme_receive(struct dme_softc *sc, struct | @@ -787,38 +787,38 @@ dme_receive(struct dme_softc *sc, struct | |||
787 | ready = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); | 787 | ready = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); | |
788 | ready &= 0x03; /* we only want bits 1:0 */ | 788 | ready &= 0x03; /* we only want bits 1:0 */ | |
789 | if (ready == 0x01) { | 789 | if (ready == 0x01) { | |
790 | uint8_t rx_status; | 790 | uint8_t rx_status; | |
791 | struct mbuf *m; | 791 | struct mbuf *m; | |
792 | 792 | |||
793 | /* Read with address increment. */ | 793 | /* Read with address increment. */ | |
794 | bus_space_write_1(sc->sc_iot, sc->sc_ioh, | 794 | bus_space_write_1(sc->sc_iot, sc->sc_ioh, | |
795 | sc->dme_io, DM9000_MRCMD); | 795 | sc->dme_io, DM9000_MRCMD); | |
796 | 796 | |||
797 | rx_status = sc->sc_pkt_read(sc, ifp, &m); | 797 | rx_status = sc->sc_pkt_read(sc, ifp, &m); | |
798 | if (m == NULL) { | 798 | if (m == NULL) { | |
799 | /* failed to allocate a receive buffer */ | 799 | /* failed to allocate a receive buffer */ | |
800 | ifp->if_ierrors++; | 800 | if_statinc(ifp, if_ierrors); | |
801 | RX_DPRINTF(("dme_receive: " | 801 | RX_DPRINTF(("dme_receive: " | |
802 | "Error allocating buffer\n")); | 802 | "Error allocating buffer\n")); | |
803 | } else if (rx_status & (DM9000_RSR_CE | DM9000_RSR_PLE)) { | 803 | } else if (rx_status & (DM9000_RSR_CE | DM9000_RSR_PLE)) { | |
804 | /* Error while receiving the packet, | 804 | /* Error while receiving the packet, | |
805 | * discard it and keep track of counters | 805 | * discard it and keep track of counters | |
806 | */ | 806 | */ | |
807 | ifp->if_ierrors++; | 807 | if_statinc(ifp, if_ierrors); | |
808 | RX_DPRINTF(("dme_receive: " | 808 | RX_DPRINTF(("dme_receive: " | |
809 | "Error reciving packet\n")); | 809 | "Error reciving packet\n")); | |
810 | } else if (rx_status & DM9000_RSR_LCS) { | 810 | } else if (rx_status & DM9000_RSR_LCS) { | |
811 | ifp->if_collisions++; | 811 | if_statinc(ifp, if_collisions); | |
812 | } else { | 812 | } else { | |
813 | if_percpuq_enqueue(ifp->if_percpuq, m); | 813 | if_percpuq_enqueue(ifp->if_percpuq, m); | |
814 | } | 814 | } | |
815 | 815 | |||
816 | } else if (ready != 0x00) { | 816 | } else if (ready != 0x00) { | |
817 | /* Should this be logged somehow? */ | 817 | /* Should this be logged somehow? */ | |
818 | printf("%s: Resetting chip\n", | 818 | printf("%s: Resetting chip\n", | |
819 | device_xname(sc->sc_dev)); | 819 | device_xname(sc->sc_dev)); | |
820 | dme_reset(sc); | 820 | dme_reset(sc); | |
821 | } | 821 | } | |
822 | } | 822 | } | |
823 | } | 823 | } | |
824 | 824 |
--- src/sys/dev/ic/dp8390.c 2019/05/29 10:07:29 1.95
+++ src/sys/dev/ic/dp8390.c 2020/01/29 14:14:55 1.96
@@ -1,30 +1,30 @@ | @@ -1,30 +1,30 @@ | |||
1 | /* $NetBSD: dp8390.c,v 1.95 2019/05/29 10:07:29 msaitoh Exp $ */ | 1 | /* $NetBSD: dp8390.c,v 1.96 2020/01/29 14:14:55 thorpej Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Device driver for National Semiconductor DS8390/WD83C690 based ethernet | 4 | * Device driver for National Semiconductor DS8390/WD83C690 based ethernet | |
5 | * adapters. | 5 | * adapters. | |
6 | * | 6 | * | |
7 | * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. | 7 | * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved. | |
8 | * | 8 | * | |
9 | * Copyright (C) 1993, David Greenman. This software may be used, modified, | 9 | * Copyright (C) 1993, David Greenman. This software may be used, modified, | |
10 | * copied, distributed, and sold, in both source and binary form provided that | 10 | * copied, distributed, and sold, in both source and binary form provided that | |
11 | * the above copyright and these terms are retained. Under no circumstances is | 11 | * the above copyright and these terms are retained. Under no circumstances is | |
12 | * the author responsible for the proper functioning of this software, nor does | 12 | * the author responsible for the proper functioning of this software, nor does | |
13 | * the author assume any responsibility for damages incurred with its use. | 13 | * the author assume any responsibility for damages incurred with its use. | |
14 | */ | 14 | */ | |
15 | 15 | |||
16 | #include <sys/cdefs.h> | 16 | #include <sys/cdefs.h> | |
17 | __KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.95 2019/05/29 10:07:29 msaitoh Exp $"); | 17 | __KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.96 2020/01/29 14:14:55 thorpej Exp $"); | |
18 | 18 | |||
19 | #include "opt_inet.h" | 19 | #include "opt_inet.h" | |
20 | 20 | |||
21 | #include <sys/param.h> | 21 | #include <sys/param.h> | |
22 | #include <sys/systm.h> | 22 | #include <sys/systm.h> | |
23 | #include <sys/device.h> | 23 | #include <sys/device.h> | |
24 | #include <sys/errno.h> | 24 | #include <sys/errno.h> | |
25 | #include <sys/ioctl.h> | 25 | #include <sys/ioctl.h> | |
26 | #include <sys/mbuf.h> | 26 | #include <sys/mbuf.h> | |
27 | #include <sys/socket.h> | 27 | #include <sys/socket.h> | |
28 | #include <sys/syslog.h> | 28 | #include <sys/syslog.h> | |
29 | #include <sys/rndsource.h> | 29 | #include <sys/rndsource.h> | |
30 | #include <sys/bus.h> | 30 | #include <sys/bus.h> | |
@@ -227,27 +227,27 @@ dp8390_stop(struct dp8390_softc *sc) | @@ -227,27 +227,27 @@ dp8390_stop(struct dp8390_softc *sc) | |||
227 | } | 227 | } | |
228 | 228 | |||
229 | /* | 229 | /* | |
230 | * Device timeout/watchdog routine. Entered if the device neglects to generate | 230 | * Device timeout/watchdog routine. Entered if the device neglects to generate | |
231 | * an interrupt after a transmit has been started on it. | 231 | * an interrupt after a transmit has been started on it. | |
232 | */ | 232 | */ | |
233 | 233 | |||
234 | void | 234 | void | |
235 | dp8390_watchdog(struct ifnet *ifp) | 235 | dp8390_watchdog(struct ifnet *ifp) | |
236 | { | 236 | { | |
237 | struct dp8390_softc *sc = ifp->if_softc; | 237 | struct dp8390_softc *sc = ifp->if_softc; | |
238 | 238 | |||
239 | log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); | 239 | log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); | |
240 | ++sc->sc_ec.ec_if.if_oerrors; | 240 | if_statinc(ifp, if_oerrors); | |
241 | 241 | |||
242 | dp8390_reset(sc); | 242 | dp8390_reset(sc); | |
243 | } | 243 | } | |
244 | 244 | |||
245 | /* | 245 | /* | |
246 | * Initialize device. | 246 | * Initialize device. | |
247 | */ | 247 | */ | |
248 | void | 248 | void | |
249 | dp8390_init(struct dp8390_softc *sc) | 249 | dp8390_init(struct dp8390_softc *sc) | |
250 | { | 250 | { | |
251 | bus_space_tag_t regt = sc->sc_regt; | 251 | bus_space_tag_t regt = sc->sc_regt; | |
252 | bus_space_handle_t regh = sc->sc_regh; | 252 | bus_space_handle_t regh = sc->sc_regh; | |
253 | struct ifnet *ifp = &sc->sc_ec.ec_if; | 253 | struct ifnet *ifp = &sc->sc_ec.ec_if; | |
@@ -571,27 +571,27 @@ dp8390_rint(struct dp8390_softc *sc) | @@ -571,27 +571,27 @@ dp8390_rint(struct dp8390_softc *sc) | |||
571 | */ | 571 | */ | |
572 | if (len <= MCLBYTES && | 572 | if (len <= MCLBYTES && | |
573 | packet_hdr.next_packet >= sc->rec_page_start && | 573 | packet_hdr.next_packet >= sc->rec_page_start && | |
574 | packet_hdr.next_packet < sc->rec_page_stop) { | 574 | packet_hdr.next_packet < sc->rec_page_stop) { | |
575 | /* Go get packet. */ | 575 | /* Go get packet. */ | |
576 | dp8390_read(sc, | 576 | dp8390_read(sc, | |
577 | packet_ptr + sizeof(struct dp8390_ring), | 577 | packet_ptr + sizeof(struct dp8390_ring), | |
578 | len - sizeof(struct dp8390_ring)); | 578 | len - sizeof(struct dp8390_ring)); | |
579 | } else { | 579 | } else { | |
580 | /* Really BAD. The ring pointers are corrupted. */ | 580 | /* Really BAD. The ring pointers are corrupted. */ | |
581 | log(LOG_ERR, "%s: NIC memory corrupt - " | 581 | log(LOG_ERR, "%s: NIC memory corrupt - " | |
582 | "invalid packet length %d\n", | 582 | "invalid packet length %d\n", | |
583 | device_xname(sc->sc_dev), len); | 583 | device_xname(sc->sc_dev), len); | |
584 | ++sc->sc_ec.ec_if.if_ierrors; | 584 | if_statinc(&sc->sc_ec.ec_if, if_ierrors); | |
585 | dp8390_reset(sc); | 585 | dp8390_reset(sc); | |
586 | return; | 586 | return; | |
587 | } | 587 | } | |
588 | 588 | |||
589 | /* Update next packet pointer. */ | 589 | /* Update next packet pointer. */ | |
590 | sc->next_packet = packet_hdr.next_packet; | 590 | sc->next_packet = packet_hdr.next_packet; | |
591 | 591 | |||
592 | /* | 592 | /* | |
593 | * Update NIC boundary pointer - being careful to keep it one | 593 | * Update NIC boundary pointer - being careful to keep it one | |
594 | * buffer behind (as recommended by NS databook). | 594 | * buffer behind (as recommended by NS databook). | |
595 | */ | 595 | */ | |
596 | boundary = sc->next_packet - 1; | 596 | boundary = sc->next_packet - 1; | |
597 | if (boundary < sc->rec_page_start) | 597 | if (boundary < sc->rec_page_start) | |
@@ -643,118 +643,122 @@ dp8390_intr(void *arg) | @@ -643,118 +643,122 @@ dp8390_intr(void *arg) | |||
643 | NIC_PUT(regt, regh, ED_P0_ISR, isr); | 643 | NIC_PUT(regt, regh, ED_P0_ISR, isr); | |
644 | } | 644 | } | |
645 | 645 | |||
646 | /* | 646 | /* | |
647 | * Handle transmitter interrupts. Handle these first because | 647 | * Handle transmitter interrupts. Handle these first because | |
648 | * the receiver will reset the board under some conditions. | 648 | * the receiver will reset the board under some conditions. | |
649 | * | 649 | * | |
650 | * If the chip was reset while a packet was transmitting, it | 650 | * If the chip was reset while a packet was transmitting, it | |
651 | * may still deliver a TX interrupt. In this case, just ignore | 651 | * may still deliver a TX interrupt. In this case, just ignore | |
652 | * the interrupt. | 652 | * the interrupt. | |
653 | */ | 653 | */ | |
654 | if ((isr & (ED_ISR_PTX | ED_ISR_TXE)) != 0 && | 654 | if ((isr & (ED_ISR_PTX | ED_ISR_TXE)) != 0 && | |
655 | sc->txb_inuse != 0) { | 655 | sc->txb_inuse != 0) { | |
656 | net_stat_ref_t nsr = IF_STAT_GETREF(ifp); | |||
656 | uint8_t collisions = | 657 | uint8_t collisions = | |
657 | NIC_GET(regt, regh, ED_P0_NCR) & 0x0f; | 658 | NIC_GET(regt, regh, ED_P0_NCR) & 0x0f; | |
658 | 659 | |||
659 | /* | 660 | /* | |
660 | * Check for transmit error. If a TX completed with an | 661 | * Check for transmit error. If a TX completed with an | |
661 | * error, we end up throwing the packet away. Really | 662 | * error, we end up throwing the packet away. Really | |
662 | * the only error that is possible is excessive | 663 | * the only error that is possible is excessive | |
663 | * collisions, and in this case it is best to allow the | 664 | * collisions, and in this case it is best to allow the | |
664 | * automatic mechanisms of TCP to backoff the flow. Of | 665 | * automatic mechanisms of TCP to backoff the flow. Of | |
665 | * course, with UDP we're screwed, but this is expected | 666 | * course, with UDP we're screwed, but this is expected | |
666 | * when a network is heavily loaded. | 667 | * when a network is heavily loaded. | |
667 | */ | 668 | */ | |
668 | if ((isr & ED_ISR_TXE) != 0) { | 669 | if ((isr & ED_ISR_TXE) != 0) { | |
669 | /* Excessive collisions (16). */ | 670 | /* Excessive collisions (16). */ | |
670 | if ((NIC_GET(regt, regh, ED_P0_TSR) | 671 | if ((NIC_GET(regt, regh, ED_P0_TSR) | |
671 | & ED_TSR_ABT) && (collisions == 0)) { | 672 | & ED_TSR_ABT) && (collisions == 0)) { | |
672 | /* | 673 | /* | |
673 | * When collisions total 16, the P0_NCR | 674 | * When collisions total 16, the P0_NCR | |
674 | * will indicate 0, and the TSR_ABT is | 675 | * will indicate 0, and the TSR_ABT is | |
675 | * set. | 676 | * set. | |
676 | */ | 677 | */ | |
677 | collisions = 16; | 678 | collisions = 16; | |
678 | } | 679 | } | |
679 | 680 | |||
680 | /* Update output errors counter. */ | 681 | /* Update output errors counter. */ | |
681 | ++ifp->if_oerrors; | 682 | if_statinc_ref(nsr, if_oerrors); | |
682 | } else { | 683 | } else { | |
683 | /* | 684 | /* | |
684 | * Throw away the non-error status bits. | 685 | * Throw away the non-error status bits. | |
685 | * | 686 | * | |
686 | * XXX | 687 | * XXX | |
687 | * It may be useful to detect loss of carrier | 688 | * It may be useful to detect loss of carrier | |
688 | * and late collisions here. | 689 | * and late collisions here. | |
689 | */ | 690 | */ | |
690 | (void)NIC_GET(regt, regh, ED_P0_TSR); | 691 | (void)NIC_GET(regt, regh, ED_P0_TSR); | |
691 | 692 | |||
692 | /* | 693 | /* | |
693 | * Update total number of successfully | 694 | * Update total number of successfully | |
694 | * transmitted packets. | 695 | * transmitted packets. | |
695 | */ | 696 | */ | |
696 | ++ifp->if_opackets; | 697 | if_statinc_ref(nsr, if_opackets); | |
697 | } | 698 | } | |
698 | 699 | |||
699 | /* Clear watchdog timer. */ | 700 | /* Clear watchdog timer. */ | |
700 | ifp->if_timer = 0; | 701 | ifp->if_timer = 0; | |
701 | ifp->if_flags &= ~IFF_OACTIVE; | 702 | ifp->if_flags &= ~IFF_OACTIVE; | |
702 | 703 | |||
703 | /* | 704 | /* | |
704 | * Add in total number of collisions on last | 705 | * Add in total number of collisions on last | |
705 | * transmission. | 706 | * transmission. | |
706 | */ | 707 | */ | |
707 | ifp->if_collisions += collisions; | 708 | if (collisions) | |
709 | if_statadd_ref(nsr, if_collisions, collisions); | |||
710 | ||||
711 | IF_STAT_PUTREF(ifp); | |||
708 | 712 | |||
709 | /* | 713 | /* | |
710 | * Decrement buffer in-use count if not zero (can only | 714 | * Decrement buffer in-use count if not zero (can only | |
711 | * be zero if a transmitter interrupt occurred while | 715 | * be zero if a transmitter interrupt occurred while | |
712 | * not actually transmitting). | 716 | * not actually transmitting). | |
713 | * If data is ready to transmit, start it transmitting, | 717 | * If data is ready to transmit, start it transmitting, | |
714 | * otherwise defer until after handling receiver. | 718 | * otherwise defer until after handling receiver. | |
715 | */ | 719 | */ | |
716 | if (--sc->txb_inuse != 0) | 720 | if (--sc->txb_inuse != 0) | |
717 | dp8390_xmit(sc); | 721 | dp8390_xmit(sc); | |
718 | } | 722 | } | |
719 | 723 | |||
720 | /* Handle receiver interrupts. */ | 724 | /* Handle receiver interrupts. */ | |
721 | if ((isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) != 0) { | 725 | if ((isr & (ED_ISR_PRX | ED_ISR_RXE | ED_ISR_OVW)) != 0) { | |
722 | /* | 726 | /* | |
723 | * Overwrite warning. In order to make sure that a | 727 | * Overwrite warning. In order to make sure that a | |
724 | * lockup of the local DMA hasn't occurred, we reset | 728 | * lockup of the local DMA hasn't occurred, we reset | |
725 | * and re-init the NIC. The NSC manual suggests only a | 729 | * and re-init the NIC. The NSC manual suggests only a | |
726 | * partial reset/re-init is necessary - but some chips | 730 | * partial reset/re-init is necessary - but some chips | |
727 | * seem to want more. The DMA lockup has been seen | 731 | * seem to want more. The DMA lockup has been seen | |
728 | * only with early rev chips - Methinks this bug was | 732 | * only with early rev chips - Methinks this bug was | |
729 | * fixed in later revs. -DG | 733 | * fixed in later revs. -DG | |
730 | */ | 734 | */ | |
731 | if ((isr & ED_ISR_OVW) != 0) { | 735 | if ((isr & ED_ISR_OVW) != 0) { | |
732 | ++ifp->if_ierrors; | 736 | if_statinc(ifp, if_ierrors); | |
733 | #ifdef DIAGNOSTIC | 737 | #ifdef DIAGNOSTIC | |
734 | log(LOG_WARNING, "%s: warning - receiver " | 738 | log(LOG_WARNING, "%s: warning - receiver " | |
735 | "ring buffer overrun\n", | 739 | "ring buffer overrun\n", | |
736 | device_xname(sc->sc_dev)); | 740 | device_xname(sc->sc_dev)); | |
737 | #endif | 741 | #endif | |
738 | /* Stop/reset/re-init NIC. */ | 742 | /* Stop/reset/re-init NIC. */ | |
739 | dp8390_reset(sc); | 743 | dp8390_reset(sc); | |
740 | } else { | 744 | } else { | |
741 | /* | 745 | /* | |
742 | * Receiver Error. One or more of: CRC error, | 746 | * Receiver Error. One or more of: CRC error, | |
743 | * frame alignment error FIFO overrun, or | 747 | * frame alignment error FIFO overrun, or | |
744 | * missed packet. | 748 | * missed packet. | |
745 | */ | 749 | */ | |
746 | if ((isr & ED_ISR_RXE) != 0) { | 750 | if ((isr & ED_ISR_RXE) != 0) { | |
747 | ++ifp->if_ierrors; | 751 | if_statinc(ifp, if_ierrors); | |
748 | #ifdef DEBUG | 752 | #ifdef DEBUG | |
749 | if (dp8390_debug) { | 753 | if (dp8390_debug) { | |
750 | printf("%s: receive error %x\n", | 754 | printf("%s: receive error %x\n", | |
751 | device_xname(sc->sc_dev), | 755 | device_xname(sc->sc_dev), | |
752 | NIC_GET(regt, regh, | 756 | NIC_GET(regt, regh, | |
753 | ED_P0_RSR)); | 757 | ED_P0_RSR)); | |
754 | } | 758 | } | |
755 | #endif | 759 | #endif | |
756 | } | 760 | } | |
757 | 761 | |||
758 | /* | 762 | /* | |
759 | * Go get the packet(s) | 763 | * Go get the packet(s) | |
760 | * XXX - Doing this on an error is dubious | 764 | * XXX - Doing this on an error is dubious | |
@@ -904,27 +908,27 @@ dp8390_ioctl(struct ifnet *ifp, u_long c | @@ -904,27 +908,27 @@ dp8390_ioctl(struct ifnet *ifp, u_long c | |||
904 | /* | 908 | /* | |
905 | * Retrieve packet from buffer memory and send to the next level up via | 909 | * Retrieve packet from buffer memory and send to the next level up via | |
906 | * ether_input(). If there is a BPF listener, give a copy to BPF, too. | 910 | * ether_input(). If there is a BPF listener, give a copy to BPF, too. | |
907 | */ | 911 | */ | |
908 | void | 912 | void | |
909 | dp8390_read(struct dp8390_softc *sc, int buf, u_short len) | 913 | dp8390_read(struct dp8390_softc *sc, int buf, u_short len) | |
910 | { | 914 | { | |
911 | struct ifnet *ifp = &sc->sc_ec.ec_if; | 915 | struct ifnet *ifp = &sc->sc_ec.ec_if; | |
912 | struct mbuf *m; | 916 | struct mbuf *m; | |
913 | 917 | |||
914 | /* Pull packet off interface. */ | 918 | /* Pull packet off interface. */ | |
915 | m = dp8390_get(sc, buf, len); | 919 | m = dp8390_get(sc, buf, len); | |
916 | if (m == NULL) { | 920 | if (m == NULL) { | |
917 | ifp->if_ierrors++; | 921 | if_statinc(ifp, if_ierrors); | |
918 | return; | 922 | return; | |
919 | } | 923 | } | |
920 | 924 | |||
921 | if_percpuq_enqueue(ifp->if_percpuq, m); | 925 | if_percpuq_enqueue(ifp->if_percpuq, m); | |
922 | } | 926 | } | |
923 | 927 | |||
924 | 928 | |||
925 | /* | 929 | /* | |
926 | * Supporting routines. | 930 | * Supporting routines. | |
927 | */ | 931 | */ | |
928 | 932 | |||
929 | /* | 933 | /* | |
930 | * Compute the multicast address filter from the list of multicast addresses we | 934 | * Compute the multicast address filter from the list of multicast addresses we |
--- src/sys/dev/ic/dp83932.c 2019/05/28 07:41:48 1.44
+++ src/sys/dev/ic/dp83932.c 2020/01/29 14:14:55 1.45
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: dp83932.c,v 1.44 2019/05/28 07:41:48 msaitoh Exp $ */ | 1 | /* $NetBSD: dp83932.c,v 1.45 2020/01/29 14:14:55 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2001 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2001 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Jason R. Thorpe. | 8 | * by Jason R. Thorpe. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -25,27 +25,27 @@ | @@ -25,27 +25,27 @@ | |||
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | /* | 32 | /* | |
33 | * Device driver for the National Semiconductor DP83932 | 33 | * Device driver for the National Semiconductor DP83932 | |
34 | * Systems-Oriented Network Interface Controller (SONIC). | 34 | * Systems-Oriented Network Interface Controller (SONIC). | |
35 | */ | 35 | */ | |
36 | 36 | |||
37 | #include <sys/cdefs.h> | 37 | #include <sys/cdefs.h> | |
38 | __KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.44 2019/05/28 07:41:48 msaitoh Exp $"); | 38 | __KERNEL_RCSID(0, "$NetBSD: dp83932.c,v 1.45 2020/01/29 14:14:55 thorpej Exp $"); | |
39 | 39 | |||
40 | 40 | |||
41 | #include <sys/param.h> | 41 | #include <sys/param.h> | |
42 | #include <sys/systm.h> | 42 | #include <sys/systm.h> | |
43 | #include <sys/mbuf.h> | 43 | #include <sys/mbuf.h> | |
44 | #include <sys/malloc.h> | 44 | #include <sys/malloc.h> | |
45 | #include <sys/kernel.h> | 45 | #include <sys/kernel.h> | |
46 | #include <sys/socket.h> | 46 | #include <sys/socket.h> | |
47 | #include <sys/ioctl.h> | 47 | #include <sys/ioctl.h> | |
48 | #include <sys/errno.h> | 48 | #include <sys/errno.h> | |
49 | #include <sys/device.h> | 49 | #include <sys/device.h> | |
50 | 50 | |||
51 | #include <net/if.h> | 51 | #include <net/if.h> | |
@@ -524,27 +524,27 @@ sonic_start(struct ifnet *ifp) | @@ -524,27 +524,27 @@ sonic_start(struct ifnet *ifp) | |||
524 | } | 524 | } | |
525 | 525 | |||
526 | /* | 526 | /* | |
527 | * sonic_watchdog: [ifnet interface function] | 527 | * sonic_watchdog: [ifnet interface function] | |
528 | * | 528 | * | |
529 | * Watchdog timer handler. | 529 | * Watchdog timer handler. | |
530 | */ | 530 | */ | |
531 | void | 531 | void | |
532 | sonic_watchdog(struct ifnet *ifp) | 532 | sonic_watchdog(struct ifnet *ifp) | |
533 | { | 533 | { | |
534 | struct sonic_softc *sc = ifp->if_softc; | 534 | struct sonic_softc *sc = ifp->if_softc; | |
535 | 535 | |||
536 | printf("%s: device timeout\n", device_xname(sc->sc_dev)); | 536 | printf("%s: device timeout\n", device_xname(sc->sc_dev)); | |
537 | ifp->if_oerrors++; | 537 | if_statinc(ifp, if_oerrors); | |
538 | 538 | |||
539 | (void)sonic_init(ifp); | 539 | (void)sonic_init(ifp); | |
540 | } | 540 | } | |
541 | 541 | |||
542 | /* | 542 | /* | |
543 | * sonic_ioctl: [ifnet interface function] | 543 | * sonic_ioctl: [ifnet interface function] | |
544 | * | 544 | * | |
545 | * Handle control requests from the operator. | 545 | * Handle control requests from the operator. | |
546 | */ | 546 | */ | |
547 | int | 547 | int | |
548 | sonic_ioctl(struct ifnet *ifp, u_long cmd, void *data) | 548 | sonic_ioctl(struct ifnet *ifp, u_long cmd, void *data) | |
549 | { | 549 | { | |
550 | int s, error; | 550 | int s, error; | |
@@ -658,31 +658,35 @@ sonic_txintr(struct sonic_softc *sc) | @@ -658,31 +658,35 @@ sonic_txintr(struct sonic_softc *sc) | |||
658 | break; | 658 | break; | |
659 | 659 | |||
660 | totstat |= status; | 660 | totstat |= status; | |
661 | 661 | |||
662 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | 662 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | |
663 | ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); | 663 | ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTWRITE); | |
664 | bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); | 664 | bus_dmamap_unload(sc->sc_dmat, ds->ds_dmamap); | |
665 | m_freem(ds->ds_mbuf); | 665 | m_freem(ds->ds_mbuf); | |
666 | ds->ds_mbuf = NULL; | 666 | ds->ds_mbuf = NULL; | |
667 | 667 | |||
668 | /* | 668 | /* | |
669 | * Check for errors and collisions. | 669 | * Check for errors and collisions. | |
670 | */ | 670 | */ | |
671 | net_stat_ref_t nsr = IF_STAT_GETREF(ifp); | |||
671 | if (status & TCR_PTX) | 672 | if (status & TCR_PTX) | |
672 | ifp->if_opackets++; | 673 | if_statinc_ref(nsr, if_opackets); | |
673 | else | 674 | else | |
674 | ifp->if_oerrors++; | 675 | if_statinc_ref(nsr, if_oerrors); | |
675 | ifp->if_collisions += TDA_STATUS_NCOL(status); | 676 | if (TDA_STATUS_NCOL(status)) | |
677 | if_statadd_ref(nsr, if_collisions, | |||
678 | TDA_STATUS_NCOL(status)); | |||
679 | IF_STAT_PUTREF(ifp); | |||
676 | } | 680 | } | |
677 | 681 | |||
678 | /* Update the dirty transmit buffer pointer. */ | 682 | /* Update the dirty transmit buffer pointer. */ | |
679 | sc->sc_txdirty = i; | 683 | sc->sc_txdirty = i; | |
680 | 684 | |||
681 | /* | 685 | /* | |
682 | * Cancel the watchdog timer if there are no pending | 686 | * Cancel the watchdog timer if there are no pending | |
683 | * transmissions. | 687 | * transmissions. | |
684 | */ | 688 | */ | |
685 | if (sc->sc_txpending == 0) | 689 | if (sc->sc_txpending == 0) | |
686 | ifp->if_timer = 0; | 690 | ifp->if_timer = 0; | |
687 | 691 | |||
688 | return totstat; | 692 | return totstat; | |
@@ -745,27 +749,27 @@ sonic_rxintr(struct sonic_softc *sc) | @@ -745,27 +749,27 @@ sonic_rxintr(struct sonic_softc *sc) | |||
745 | /* | 749 | /* | |
746 | * Make sure the packet arrived OK. If an error occurred, | 750 | * Make sure the packet arrived OK. If an error occurred, | |
747 | * update stats and reset the descriptor. The buffer will | 751 | * update stats and reset the descriptor. The buffer will | |
748 | * be reused the next time the descriptor comes up in the | 752 | * be reused the next time the descriptor comes up in the | |
749 | * ring. | 753 | * ring. | |
750 | */ | 754 | */ | |
751 | if ((status & RCR_PRX) == 0) { | 755 | if ((status & RCR_PRX) == 0) { | |
752 | if (status & RCR_FAER) | 756 | if (status & RCR_FAER) | |
753 | printf("%s: Rx frame alignment error\n", | 757 | printf("%s: Rx frame alignment error\n", | |
754 | device_xname(sc->sc_dev)); | 758 | device_xname(sc->sc_dev)); | |
755 | else if (status & RCR_CRCR) | 759 | else if (status & RCR_CRCR) | |
756 | printf("%s: Rx CRC error\n", | 760 | printf("%s: Rx CRC error\n", | |
757 | device_xname(sc->sc_dev)); | 761 | device_xname(sc->sc_dev)); | |
758 | ifp->if_ierrors++; | 762 | if_statinc(ifp, if_ierrors); | |
759 | SONIC_INIT_RXDESC(sc, i); | 763 | SONIC_INIT_RXDESC(sc, i); | |
760 | continue; | 764 | continue; | |
761 | } | 765 | } | |
762 | 766 | |||
763 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | 767 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | |
764 | ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); | 768 | ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD); | |
765 | 769 | |||
766 | /* | 770 | /* | |
767 | * The SONIC includes the CRC with every packet. | 771 | * The SONIC includes the CRC with every packet. | |
768 | */ | 772 | */ | |
769 | len = bytecount - ETHER_CRC_LEN; | 773 | len = bytecount - ETHER_CRC_LEN; | |
770 | 774 | |||
771 | /* | 775 | /* | |
@@ -817,27 +821,27 @@ sonic_rxintr(struct sonic_softc *sc) | @@ -817,27 +821,27 @@ sonic_rxintr(struct sonic_softc *sc) | |||
817 | /* | 821 | /* | |
818 | * Note that we use a cluster for incoming frames, | 822 | * Note that we use a cluster for incoming frames, | |
819 | * so the buffer is virtually contiguous. | 823 | * so the buffer is virtually contiguous. | |
820 | */ | 824 | */ | |
821 | memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *), | 825 | memcpy(mtod(m, void *), mtod(ds->ds_mbuf, void *), | |
822 | len); | 826 | len); | |
823 | SONIC_INIT_RXDESC(sc, i); | 827 | SONIC_INIT_RXDESC(sc, i); | |
824 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | 828 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | |
825 | ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); | 829 | ds->ds_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD); | |
826 | } else { | 830 | } else { | |
827 | m = ds->ds_mbuf; | 831 | m = ds->ds_mbuf; | |
828 | if (sonic_add_rxbuf(sc, i) != 0) { | 832 | if (sonic_add_rxbuf(sc, i) != 0) { | |
829 | dropit: | 833 | dropit: | |
830 | ifp->if_ierrors++; | 834 | if_statinc(ifp, if_ierrors); | |
831 | SONIC_INIT_RXDESC(sc, i); | 835 | SONIC_INIT_RXDESC(sc, i); | |
832 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | 836 | bus_dmamap_sync(sc->sc_dmat, ds->ds_dmamap, 0, | |
833 | ds->ds_dmamap->dm_mapsize, | 837 | ds->ds_dmamap->dm_mapsize, | |
834 | BUS_DMASYNC_PREREAD); | 838 | BUS_DMASYNC_PREREAD); | |
835 | continue; | 839 | continue; | |
836 | } | 840 | } | |
837 | } | 841 | } | |
838 | 842 | |||
839 | m_set_rcvif(m, ifp); | 843 | m_set_rcvif(m, ifp); | |
840 | m->m_pkthdr.len = m->m_len = len; | 844 | m->m_pkthdr.len = m->m_len = len; | |
841 | 845 | |||
842 | /* Pass it on. */ | 846 | /* Pass it on. */ | |
843 | if_percpuq_enqueue(ifp->if_percpuq, m); | 847 | if_percpuq_enqueue(ifp->if_percpuq, m); |
--- src/sys/dev/ic/dwc_gmac.c 2019/10/19 06:40:20 1.68
+++ src/sys/dev/ic/dwc_gmac.c 2020/01/29 14:14:55 1.69
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: dwc_gmac.c,v 1.68 2019/10/19 06:40:20 tnn Exp $ */ | 1 | /* $NetBSD: dwc_gmac.c,v 1.69 2020/01/29 14:14:55 thorpej Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Matt Thomas of 3am Software Foundry and Martin Husemann. | 8 | * by Matt Thomas of 3am Software Foundry and Martin Husemann. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -31,27 +31,27 @@ | @@ -31,27 +31,27 @@ | |||
31 | 31 | |||
32 | /* | 32 | /* | |
33 | * This driver supports the Synopsis Designware GMAC core, as found | 33 | * This driver supports the Synopsis Designware GMAC core, as found | |
34 | * on Allwinner A20 cores and others. | 34 | * on Allwinner A20 cores and others. | |
35 | * | 35 | * | |
36 | * Real documentation seems to not be available, the marketing product | 36 | * Real documentation seems to not be available, the marketing product | |
37 | * documents could be found here: | 37 | * documents could be found here: | |
38 | * | 38 | * | |
39 | * http://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_mac10_100_1000_unive | 39 | * http://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_mac10_100_1000_unive | |
40 | */ | 40 | */ | |
41 | 41 | |||
42 | #include <sys/cdefs.h> | 42 | #include <sys/cdefs.h> | |
43 | 43 | |||
44 | __KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.68 2019/10/19 06:40:20 tnn Exp $"); | 44 | __KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.69 2020/01/29 14:14:55 thorpej Exp $"); | |
45 | 45 | |||
46 | /* #define DWC_GMAC_DEBUG 1 */ | 46 | /* #define DWC_GMAC_DEBUG 1 */ | |
47 | 47 | |||
48 | #ifdef _KERNEL_OPT | 48 | #ifdef _KERNEL_OPT | |
49 | #include "opt_inet.h" | 49 | #include "opt_inet.h" | |
50 | #include "opt_net_mpsafe.h" | 50 | #include "opt_net_mpsafe.h" | |
51 | #endif | 51 | #endif | |
52 | 52 | |||
53 | #include <sys/param.h> | 53 | #include <sys/param.h> | |
54 | #include <sys/bus.h> | 54 | #include <sys/bus.h> | |
55 | #include <sys/device.h> | 55 | #include <sys/device.h> | |
56 | #include <sys/intr.h> | 56 | #include <sys/intr.h> | |
57 | #include <sys/systm.h> | 57 | #include <sys/systm.h> | |
@@ -1182,27 +1182,27 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc * | @@ -1182,27 +1182,27 @@ dwc_gmac_tx_intr(struct dwc_gmac_softc * | |||
1182 | * a single tx descriptor (i) | 1182 | * a single tx descriptor (i) | |
1183 | */ | 1183 | */ | |
1184 | dwc_gmac_txdesc_sync(sc, i, i+1, | 1184 | dwc_gmac_txdesc_sync(sc, i, i+1, | |
1185 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | 1185 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | |
1186 | 1186 | |||
1187 | desc = &sc->sc_txq.t_desc[i]; | 1187 | desc = &sc->sc_txq.t_desc[i]; | |
1188 | if (sc->sc_descm->tx_is_owned_by_dev(desc)) | 1188 | if (sc->sc_descm->tx_is_owned_by_dev(desc)) | |
1189 | break; | 1189 | break; | |
1190 | 1190 | |||
1191 | data = &sc->sc_txq.t_data[i]; | 1191 | data = &sc->sc_txq.t_data[i]; | |
1192 | if (data->td_m == NULL) | 1192 | if (data->td_m == NULL) | |
1193 | continue; | 1193 | continue; | |
1194 | 1194 | |||
1195 | ifp->if_opackets++; | 1195 | if_statinc(ifp, if_opackets); | |
1196 | nsegs = data->td_active->dm_nsegs; | 1196 | nsegs = data->td_active->dm_nsegs; | |
1197 | bus_dmamap_sync(sc->sc_dmat, data->td_active, 0, | 1197 | bus_dmamap_sync(sc->sc_dmat, data->td_active, 0, | |
1198 | data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE); | 1198 | data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE); | |
1199 | bus_dmamap_unload(sc->sc_dmat, data->td_active); | 1199 | bus_dmamap_unload(sc->sc_dmat, data->td_active); | |
1200 | 1200 | |||
1201 | #ifdef DWC_GMAC_DEBUG | 1201 | #ifdef DWC_GMAC_DEBUG | |
1202 | aprint_normal_dev(sc->sc_dev, | 1202 | aprint_normal_dev(sc->sc_dev, | |
1203 | "dwc_gmac_tx_intr: done with packet at desc #%d, " | 1203 | "dwc_gmac_tx_intr: done with packet at desc #%d, " | |
1204 | "freeing mbuf %p\n", i, data->td_m); | 1204 | "freeing mbuf %p\n", i, data->td_m); | |
1205 | #endif | 1205 | #endif | |
1206 | 1206 | |||
1207 | m_freem(data->td_m); | 1207 | m_freem(data->td_m); | |
1208 | data->td_m = NULL; | 1208 | data->td_m = NULL; | |
@@ -1235,77 +1235,77 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * | @@ -1235,77 +1235,77 @@ dwc_gmac_rx_intr(struct dwc_gmac_softc * | |||
1235 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | 1235 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | |
1236 | desc = &sc->sc_rxq.r_desc[i]; | 1236 | desc = &sc->sc_rxq.r_desc[i]; | |
1237 | data = &sc->sc_rxq.r_data[i]; | 1237 | data = &sc->sc_rxq.r_data[i]; | |
1238 | 1238 | |||
1239 | if (sc->sc_descm->rx_is_owned_by_dev(desc)) | 1239 | if (sc->sc_descm->rx_is_owned_by_dev(desc)) | |
1240 | break; | 1240 | break; | |
1241 | 1241 | |||
1242 | if (sc->sc_descm->rx_has_error(desc)) { | 1242 | if (sc->sc_descm->rx_has_error(desc)) { | |
1243 | #ifdef DWC_GMAC_DEBUG | 1243 | #ifdef DWC_GMAC_DEBUG | |
1244 | aprint_normal_dev(sc->sc_dev, | 1244 | aprint_normal_dev(sc->sc_dev, | |
1245 | "RX error: descriptor status %08x, skipping\n", | 1245 | "RX error: descriptor status %08x, skipping\n", | |
1246 | le32toh(desc->ddesc_status0)); | 1246 | le32toh(desc->ddesc_status0)); | |
1247 | #endif | 1247 | #endif | |
1248 | ifp->if_ierrors++; | 1248 | if_statinc(ifp, if_ierrors); | |
1249 | goto skip; | 1249 | goto skip; | |
1250 | } | 1250 | } | |
1251 | 1251 | |||
1252 | len = sc->sc_descm->rx_get_len(desc); | 1252 | len = sc->sc_descm->rx_get_len(desc); | |
1253 | 1253 | |||
1254 | #ifdef DWC_GMAC_DEBUG | 1254 | #ifdef DWC_GMAC_DEBUG | |
1255 | aprint_normal_dev(sc->sc_dev, | 1255 | aprint_normal_dev(sc->sc_dev, | |
1256 | "rx int: device is done with descriptor #%d, len: %d\n", | 1256 | "rx int: device is done with descriptor #%d, len: %d\n", | |
1257 | i, len); | 1257 | i, len); | |
1258 | #endif | 1258 | #endif | |
1259 | 1259 | |||
1260 | /* | 1260 | /* | |
1261 | * Try to get a new mbuf before passing this one | 1261 | * Try to get a new mbuf before passing this one | |
1262 | * up, if that fails, drop the packet and reuse | 1262 | * up, if that fails, drop the packet and reuse | |
1263 | * the existing one. | 1263 | * the existing one. | |
1264 | */ | 1264 | */ | |
1265 | MGETHDR(mnew, M_DONTWAIT, MT_DATA); | 1265 | MGETHDR(mnew, M_DONTWAIT, MT_DATA); | |
1266 | if (mnew == NULL) { | 1266 | if (mnew == NULL) { | |
1267 | ifp->if_ierrors++; | 1267 | if_statinc(ifp, if_ierrors); | |
1268 | goto skip; | 1268 | goto skip; | |
1269 | } | 1269 | } | |
1270 | MCLGET(mnew, M_DONTWAIT); | 1270 | MCLGET(mnew, M_DONTWAIT); | |
1271 | if ((mnew->m_flags & M_EXT) == 0) { | 1271 | if ((mnew->m_flags & M_EXT) == 0) { | |
1272 | m_freem(mnew); | 1272 | m_freem(mnew); | |
1273 | ifp->if_ierrors++; | 1273 | if_statinc(ifp, if_ierrors); | |
1274 | goto skip; | 1274 | goto skip; | |
1275 | } | 1275 | } | |
1276 | mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size; | 1276 | mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size; | |
1277 | if (mnew->m_len > AWGE_MAX_PACKET) { | 1277 | if (mnew->m_len > AWGE_MAX_PACKET) { | |
1278 | mnew->m_len = mnew->m_pkthdr.len = AWGE_MAX_PACKET; | 1278 | mnew->m_len = mnew->m_pkthdr.len = AWGE_MAX_PACKET; | |
1279 | } | 1279 | } | |
1280 | 1280 | |||
1281 | /* unload old DMA map */ | 1281 | /* unload old DMA map */ | |
1282 | bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, | 1282 | bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, | |
1283 | data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD); | 1283 | data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD); | |
1284 | bus_dmamap_unload(sc->sc_dmat, data->rd_map); | 1284 | bus_dmamap_unload(sc->sc_dmat, data->rd_map); | |
1285 | 1285 | |||
1286 | /* and reload with new mbuf */ | 1286 | /* and reload with new mbuf */ | |
1287 | error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, | 1287 | error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, | |
1288 | mnew, BUS_DMA_READ | BUS_DMA_NOWAIT); | 1288 | mnew, BUS_DMA_READ | BUS_DMA_NOWAIT); | |
1289 | if (error != 0) { | 1289 | if (error != 0) { | |
1290 | m_freem(mnew); | 1290 | m_freem(mnew); | |
1291 | /* try to reload old mbuf */ | 1291 | /* try to reload old mbuf */ | |
1292 | error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, | 1292 | error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, | |
1293 | data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT); | 1293 | data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT); | |
1294 | if (error != 0) { | 1294 | if (error != 0) { | |
1295 | panic("%s: could not load old rx mbuf", | 1295 | panic("%s: could not load old rx mbuf", | |
1296 | device_xname(sc->sc_dev)); | 1296 | device_xname(sc->sc_dev)); | |
1297 | } | 1297 | } | |
1298 | ifp->if_ierrors++; | 1298 | if_statinc(ifp, if_ierrors); | |
1299 | goto skip; | 1299 | goto skip; | |
1300 | } | 1300 | } | |
1301 | physaddr = data->rd_map->dm_segs[0].ds_addr; | 1301 | physaddr = data->rd_map->dm_segs[0].ds_addr; | |
1302 | 1302 | |||
1303 | /* | 1303 | /* | |
1304 | * New mbuf loaded, update RX ring and continue | 1304 | * New mbuf loaded, update RX ring and continue | |
1305 | */ | 1305 | */ | |
1306 | m = data->rd_m; | 1306 | m = data->rd_m; | |
1307 | data->rd_m = mnew; | 1307 | data->rd_m = mnew; | |
1308 | desc->ddesc_data = htole32(physaddr); | 1308 | desc->ddesc_data = htole32(physaddr); | |
1309 | 1309 | |||
1310 | /* finalize mbuf */ | 1310 | /* finalize mbuf */ | |
1311 | m->m_pkthdr.len = m->m_len = len; | 1311 | m->m_pkthdr.len = m->m_len = len; | |
@@ -1449,27 +1449,27 @@ dwc_gmac_intr(struct dwc_gmac_softc *sc) | @@ -1449,27 +1449,27 @@ dwc_gmac_intr(struct dwc_gmac_softc *sc) | |||
1449 | if (dma_status & (GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE)) | 1449 | if (dma_status & (GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE)) | |
1450 | rv = 1; | 1450 | rv = 1; | |
1451 | 1451 | |||
1452 | if (dma_status & GMAC_DMA_INT_TIE) | 1452 | if (dma_status & GMAC_DMA_INT_TIE) | |
1453 | dwc_gmac_tx_intr(sc); | 1453 | dwc_gmac_tx_intr(sc); | |
1454 | 1454 | |||
1455 | if (dma_status & GMAC_DMA_INT_RIE) | 1455 | if (dma_status & GMAC_DMA_INT_RIE) | |
1456 | dwc_gmac_rx_intr(sc); | 1456 | dwc_gmac_rx_intr(sc); | |
1457 | 1457 | |||
1458 | /* | 1458 | /* | |
1459 | * Check error conditions | 1459 | * Check error conditions | |
1460 | */ | 1460 | */ | |
1461 | if (dma_status & GMAC_DMA_INT_ERRORS) { | 1461 | if (dma_status & GMAC_DMA_INT_ERRORS) { | |
1462 | sc->sc_ec.ec_if.if_oerrors++; | 1462 | if_statinc(&sc->sc_ec.ec_if, if_oerrors); | |
1463 | #ifdef DWC_GMAC_DEBUG | 1463 | #ifdef DWC_GMAC_DEBUG | |
1464 | dwc_dump_and_abort(sc, "interrupt error condition"); | 1464 | dwc_dump_and_abort(sc, "interrupt error condition"); | |
1465 | #endif | 1465 | #endif | |
1466 | } | 1466 | } | |
1467 | 1467 | |||
1468 | rnd_add_uint32(&sc->rnd_source, dma_status); | 1468 | rnd_add_uint32(&sc->rnd_source, dma_status); | |
1469 | 1469 | |||
1470 | /* ack interrupt */ | 1470 | /* ack interrupt */ | |
1471 | if (dma_status) | 1471 | if (dma_status) | |
1472 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, | 1472 | bus_space_write_4(sc->sc_bst, sc->sc_bsh, | |
1473 | AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK); | 1473 | AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK); | |
1474 | 1474 | |||
1475 | /* | 1475 | /* |