| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: if_wm.c,v 1.732 2022/05/19 02:22:59 msaitoh Exp $ */ | | 1 | /* $NetBSD: if_wm.c,v 1.733 2022/05/19 02:23:59 msaitoh Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. | | 4 | * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. | | 7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -72,27 +72,27 @@ | | | @@ -72,27 +72,27 @@ |
72 | * | | 72 | * |
73 | * TODO (in order of importance): | | 73 | * TODO (in order of importance): |
74 | * | | 74 | * |
75 | * - Check XXX'ed comments | | 75 | * - Check XXX'ed comments |
76 | * - TX Multi queue improvement (refine queue selection logic) | | 76 | * - TX Multi queue improvement (refine queue selection logic) |
77 | * - Split header buffer for newer descriptors | | 77 | * - Split header buffer for newer descriptors |
78 | * - EEE (Energy Efficiency Ethernet) for I354 | | 78 | * - EEE (Energy Efficiency Ethernet) for I354 |
79 | * - Virtual Function | | 79 | * - Virtual Function |
80 | * - Set LED correctly (based on contents in EEPROM) | | 80 | * - Set LED correctly (based on contents in EEPROM) |
81 | * - Rework how parameters are loaded from the EEPROM. | | 81 | * - Rework how parameters are loaded from the EEPROM. |
82 | */ | | 82 | */ |
83 | | | 83 | |
84 | #include <sys/cdefs.h> | | 84 | #include <sys/cdefs.h> |
85 | __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.732 2022/05/19 02:22:59 msaitoh Exp $"); | | 85 | __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.733 2022/05/19 02:23:59 msaitoh Exp $"); |
86 | | | 86 | |
87 | #ifdef _KERNEL_OPT | | 87 | #ifdef _KERNEL_OPT |
88 | #include "opt_net_mpsafe.h" | | 88 | #include "opt_net_mpsafe.h" |
89 | #include "opt_if_wm.h" | | 89 | #include "opt_if_wm.h" |
90 | #endif | | 90 | #endif |
91 | | | 91 | |
92 | #include <sys/param.h> | | 92 | #include <sys/param.h> |
93 | #include <sys/systm.h> | | 93 | #include <sys/systm.h> |
94 | #include <sys/callout.h> | | 94 | #include <sys/callout.h> |
95 | #include <sys/mbuf.h> | | 95 | #include <sys/mbuf.h> |
96 | #include <sys/malloc.h> | | 96 | #include <sys/malloc.h> |
97 | #include <sys/kmem.h> | | 97 | #include <sys/kmem.h> |
98 | #include <sys/kernel.h> | | 98 | #include <sys/kernel.h> |
| @@ -8958,50 +8958,50 @@ wm_txeof(struct wm_txqueue *txq, u_int l | | | @@ -8958,50 +8958,50 @@ wm_txeof(struct wm_txqueue *txq, u_int l |
8958 | KASSERT(mutex_owned(txq->txq_lock)); | | 8958 | KASSERT(mutex_owned(txq->txq_lock)); |
8959 | | | 8959 | |
8960 | if (txq->txq_stopping) | | 8960 | if (txq->txq_stopping) |
8961 | return false; | | 8961 | return false; |
8962 | | | 8962 | |
8963 | txq->txq_flags &= ~WM_TXQ_NO_SPACE; | | 8963 | txq->txq_flags &= ~WM_TXQ_NO_SPACE; |
8964 | | | 8964 | |
8965 | /* | | 8965 | /* |
8966 | * Go through the Tx list and free mbufs for those | | 8966 | * Go through the Tx list and free mbufs for those |
8967 | * frames which have been transmitted. | | 8967 | * frames which have been transmitted. |
8968 | */ | | 8968 | */ |
8969 | for (i = txq->txq_sdirty; txq->txq_sfree != WM_TXQUEUELEN(txq); | | 8969 | for (i = txq->txq_sdirty; txq->txq_sfree != WM_TXQUEUELEN(txq); |
8970 | i = WM_NEXTTXS(txq, i), txq->txq_sfree++) { | | 8970 | i = WM_NEXTTXS(txq, i), txq->txq_sfree++) { |
8971 | if (limit-- == 0) { | | | |
8972 | more = true; | | | |
8973 | DPRINTF(sc, WM_DEBUG_TX, | | | |
8974 | ("%s: TX: loop limited, job %d is not processed\n", | | | |
8975 | device_xname(sc->sc_dev), i)); | | | |
8976 | break; | | | |
8977 | } | | | |
8978 | | | | |
8979 | txs = &txq->txq_soft[i]; | | 8971 | txs = &txq->txq_soft[i]; |
8980 | | | 8972 | |
8981 | DPRINTF(sc, WM_DEBUG_TX, ("%s: TX: checking job %d\n", | | 8973 | DPRINTF(sc, WM_DEBUG_TX, ("%s: TX: checking job %d\n", |
8982 | device_xname(sc->sc_dev), i)); | | 8974 | device_xname(sc->sc_dev), i)); |
8983 | | | 8975 | |
8984 | wm_cdtxsync(txq, txs->txs_firstdesc, txs->txs_ndesc, | | 8976 | wm_cdtxsync(txq, txs->txs_firstdesc, txs->txs_ndesc, |
8985 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | | 8977 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
8986 | | | 8978 | |
8987 | status = | | 8979 | status = |
8988 | txq->txq_descs[txs->txs_lastdesc].wtx_fields.wtxu_status; | | 8980 | txq->txq_descs[txs->txs_lastdesc].wtx_fields.wtxu_status; |
8989 | if ((status & WTX_ST_DD) == 0) { | | 8981 | if ((status & WTX_ST_DD) == 0) { |
8990 | wm_cdtxsync(txq, txs->txs_lastdesc, 1, | | 8982 | wm_cdtxsync(txq, txs->txs_lastdesc, 1, |
8991 | BUS_DMASYNC_PREREAD); | | 8983 | BUS_DMASYNC_PREREAD); |
8992 | break; | | 8984 | break; |
8993 | } | | 8985 | } |
8994 | | | 8986 | |
| | | 8987 | if (limit-- == 0) { |
| | | 8988 | more = true; |
| | | 8989 | DPRINTF(sc, WM_DEBUG_TX, |
| | | 8990 | ("%s: TX: loop limited, job %d is not processed\n", |
| | | 8991 | device_xname(sc->sc_dev), i)); |
| | | 8992 | break; |
| | | 8993 | } |
| | | 8994 | |
8995 | count++; | | 8995 | count++; |
8996 | DPRINTF(sc, WM_DEBUG_TX, | | 8996 | DPRINTF(sc, WM_DEBUG_TX, |
8997 | ("%s: TX: job %d done: descs %d..%d\n", | | 8997 | ("%s: TX: job %d done: descs %d..%d\n", |
8998 | device_xname(sc->sc_dev), i, txs->txs_firstdesc, | | 8998 | device_xname(sc->sc_dev), i, txs->txs_firstdesc, |
8999 | txs->txs_lastdesc)); | | 8999 | txs->txs_lastdesc)); |
9000 | | | 9000 | |
9001 | /* | | 9001 | /* |
9002 | * XXX We should probably be using the statistics | | 9002 | * XXX We should probably be using the statistics |
9003 | * XXX registers, but I don't know if they exist | | 9003 | * XXX registers, but I don't know if they exist |
9004 | * XXX on chips before the i82544. | | 9004 | * XXX on chips before the i82544. |
9005 | */ | | 9005 | */ |
9006 | | | 9006 | |
9007 | #ifdef WM_EVENT_COUNTERS | | 9007 | #ifdef WM_EVENT_COUNTERS |
| @@ -9287,55 +9287,55 @@ wm_rxeof(struct wm_rxqueue *rxq, u_int l | | | @@ -9287,55 +9287,55 @@ wm_rxeof(struct wm_rxqueue *rxq, u_int l |
9287 | struct wm_softc *sc = rxq->rxq_sc; | | 9287 | struct wm_softc *sc = rxq->rxq_sc; |
9288 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | | 9288 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
9289 | struct wm_rxsoft *rxs; | | 9289 | struct wm_rxsoft *rxs; |
9290 | struct mbuf *m; | | 9290 | struct mbuf *m; |
9291 | int i, len; | | 9291 | int i, len; |
9292 | int count = 0; | | 9292 | int count = 0; |
9293 | uint32_t status, errors; | | 9293 | uint32_t status, errors; |
9294 | uint16_t vlantag; | | 9294 | uint16_t vlantag; |
9295 | bool more = false; | | 9295 | bool more = false; |
9296 | | | 9296 | |
9297 | KASSERT(mutex_owned(rxq->rxq_lock)); | | 9297 | KASSERT(mutex_owned(rxq->rxq_lock)); |
9298 | | | 9298 | |
9299 | for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) { | | 9299 | for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) { |
9300 | if (limit-- == 0) { | | | |
9301 | more = true; | | | |
9302 | DPRINTF(sc, WM_DEBUG_RX, | | | |
9303 | ("%s: RX: loop limited, descriptor %d is not processed\n", | | | |
9304 | device_xname(sc->sc_dev), i)); | | | |
9305 | break; | | | |
9306 | } | | | |
9307 | | | | |
9308 | rxs = &rxq->rxq_soft[i]; | | 9300 | rxs = &rxq->rxq_soft[i]; |
9309 | | | 9301 | |
9310 | DPRINTF(sc, WM_DEBUG_RX, | | 9302 | DPRINTF(sc, WM_DEBUG_RX, |
9311 | ("%s: RX: checking descriptor %d\n", | | 9303 | ("%s: RX: checking descriptor %d\n", |
9312 | device_xname(sc->sc_dev), i)); | | 9304 | device_xname(sc->sc_dev), i)); |
9313 | wm_cdrxsync(rxq, i, | | 9305 | wm_cdrxsync(rxq, i, |
9314 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); | | 9306 | BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); |
9315 | | | 9307 | |
9316 | status = wm_rxdesc_get_status(rxq, i); | | 9308 | status = wm_rxdesc_get_status(rxq, i); |
9317 | errors = wm_rxdesc_get_errors(rxq, i); | | 9309 | errors = wm_rxdesc_get_errors(rxq, i); |
9318 | len = le16toh(wm_rxdesc_get_pktlen(rxq, i)); | | 9310 | len = le16toh(wm_rxdesc_get_pktlen(rxq, i)); |
9319 | vlantag = wm_rxdesc_get_vlantag(rxq, i); | | 9311 | vlantag = wm_rxdesc_get_vlantag(rxq, i); |
9320 | #ifdef WM_DEBUG | | 9312 | #ifdef WM_DEBUG |
9321 | uint32_t rsshash = le32toh(wm_rxdesc_get_rsshash(rxq, i)); | | 9313 | uint32_t rsshash = le32toh(wm_rxdesc_get_rsshash(rxq, i)); |
9322 | uint8_t rsstype = wm_rxdesc_get_rsstype(rxq, i); | | 9314 | uint8_t rsstype = wm_rxdesc_get_rsstype(rxq, i); |
9323 | #endif | | 9315 | #endif |
9324 | | | 9316 | |
9325 | if (!wm_rxdesc_dd(rxq, i, status)) { | | 9317 | if (!wm_rxdesc_dd(rxq, i, status)) { |
9326 | break; | | 9318 | break; |
9327 | } | | 9319 | } |
9328 | | | 9320 | |
| | | 9321 | if (limit-- == 0) { |
| | | 9322 | more = true; |
| | | 9323 | DPRINTF(sc, WM_DEBUG_RX, |
| | | 9324 | ("%s: RX: loop limited, descriptor %d is not processed\n", |
| | | 9325 | device_xname(sc->sc_dev), i)); |
| | | 9326 | break; |
| | | 9327 | } |
| | | 9328 | |
9329 | count++; | | 9329 | count++; |
9330 | if (__predict_false(rxq->rxq_discard)) { | | 9330 | if (__predict_false(rxq->rxq_discard)) { |
9331 | DPRINTF(sc, WM_DEBUG_RX, | | 9331 | DPRINTF(sc, WM_DEBUG_RX, |
9332 | ("%s: RX: discarding contents of descriptor %d\n", | | 9332 | ("%s: RX: discarding contents of descriptor %d\n", |
9333 | device_xname(sc->sc_dev), i)); | | 9333 | device_xname(sc->sc_dev), i)); |
9334 | wm_init_rxdesc(rxq, i); | | 9334 | wm_init_rxdesc(rxq, i); |
9335 | if (wm_rxdesc_is_eop(rxq, status)) { | | 9335 | if (wm_rxdesc_is_eop(rxq, status)) { |
9336 | /* Reset our state. */ | | 9336 | /* Reset our state. */ |
9337 | DPRINTF(sc, WM_DEBUG_RX, | | 9337 | DPRINTF(sc, WM_DEBUG_RX, |
9338 | ("%s: RX: resetting rxdiscard -> 0\n", | | 9338 | ("%s: RX: resetting rxdiscard -> 0\n", |
9339 | device_xname(sc->sc_dev))); | | 9339 | device_xname(sc->sc_dev))); |
9340 | rxq->rxq_discard = 0; | | 9340 | rxq->rxq_discard = 0; |
9341 | } | | 9341 | } |