Pull up the following revisions, requested by msaitoh in ticket #1751:

sys/dev/pci/if_wmreg.h				1.122-1.125 via patch
	sys/dev/pci/if_wmvar.h				1.48
	sys/dev/pci/if_wm.c				1.719-1.720,1.722-1.725,
							1.727-1.740 via patch

- wm_tick: Add missing splx(s) when not WM_MPSAFE.
- Print DMA range info if the system is booting in the verbose mode.
- Micro optimization:
  - Call m_freem(m) only if m0 == NULL.
  - Call wm_xxeof() only when limit > 0.
  - Don't set the more flag when there is no packet to process.
- No functional changes:
  - Call txeof first, then rxeof for the consistency.
  - Remove duplicated break.
  - Remove stray semicolons from struct declaration.
  - Fix value return from void function.
  - Use macros.
  - Modify comment.
  - KNF.
This commit is contained in:
martin 2022-07-11 14:15:57 +00:00
parent ffb0f04832
commit e624e5bc14
3 changed files with 906 additions and 873 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wm.c,v 1.508.4.44 2021/11/20 15:11:31 martin Exp $ */ /* $NetBSD: if_wm.c,v 1.508.4.45 2022/07/11 14:15:57 martin Exp $ */
/* /*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@ -39,21 +39,21 @@
Copyright (c) 2001-2005, Intel Corporation Copyright (c) 2001-2005, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, 1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its 3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@ -82,7 +82,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.44 2021/11/20 15:11:31 martin Exp $"); __KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.508.4.45 2022/07/11 14:15:57 martin Exp $");
#ifdef _KERNEL_OPT #ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h" #include "opt_net_mpsafe.h"
@ -319,9 +319,9 @@ struct wm_softc;
#endif #endif
#ifdef WM_EVENT_COUNTERS #ifdef WM_EVENT_COUNTERS
#define WM_Q_EVCNT_DEFINE(qname, evname) \ #define WM_Q_EVCNT_DEFINE(qname, evname) \
char qname##_##evname##_evcnt_name[sizeof("qname##XX##evname")]; \ char qname##_##evname##_evcnt_name[sizeof("qname##XX##evname")]; \
struct evcnt qname##_ev_##evname; struct evcnt qname##_ev_##evname
#define WM_Q_EVCNT_ATTACH(qname, evname, q, qnum, xname, evtype) \ #define WM_Q_EVCNT_ATTACH(qname, evname, q, qnum, xname, evtype) \
do { \ do { \
@ -340,7 +340,7 @@ struct wm_softc;
WM_Q_EVCNT_ATTACH(qname, evname, q, qnum, xname, EVCNT_TYPE_INTR) WM_Q_EVCNT_ATTACH(qname, evname, q, qnum, xname, EVCNT_TYPE_INTR)
#define WM_Q_EVCNT_DETACH(qname, evname, q, qnum) \ #define WM_Q_EVCNT_DETACH(qname, evname, q, qnum) \
evcnt_detach(&(q)->qname##_ev_##evname); evcnt_detach(&(q)->qname##_ev_##evname)
#endif /* WM_EVENT_COUNTERS */ #endif /* WM_EVENT_COUNTERS */
struct wm_txqueue { struct wm_txqueue {
@ -407,27 +407,27 @@ struct wm_txqueue {
uint32_t txq_bytes; /* for AIM */ uint32_t txq_bytes; /* for AIM */
#ifdef WM_EVENT_COUNTERS #ifdef WM_EVENT_COUNTERS
/* TX event counters */ /* TX event counters */
WM_Q_EVCNT_DEFINE(txq, txsstall) /* Stalled due to no txs */ WM_Q_EVCNT_DEFINE(txq, txsstall); /* Stalled due to no txs */
WM_Q_EVCNT_DEFINE(txq, txdstall) /* Stalled due to no txd */ WM_Q_EVCNT_DEFINE(txq, txdstall); /* Stalled due to no txd */
WM_Q_EVCNT_DEFINE(txq, fifo_stall) /* FIFO stalls (82547) */ WM_Q_EVCNT_DEFINE(txq, fifo_stall); /* FIFO stalls (82547) */
WM_Q_EVCNT_DEFINE(txq, txdw) /* Tx descriptor interrupts */ WM_Q_EVCNT_DEFINE(txq, txdw); /* Tx descriptor interrupts */
WM_Q_EVCNT_DEFINE(txq, txqe) /* Tx queue empty interrupts */ WM_Q_EVCNT_DEFINE(txq, txqe); /* Tx queue empty interrupts */
/* XXX not used? */ /* XXX not used? */
WM_Q_EVCNT_DEFINE(txq, ipsum) /* IP checksums comp. */ WM_Q_EVCNT_DEFINE(txq, ipsum); /* IP checksums comp. */
WM_Q_EVCNT_DEFINE(txq, tusum) /* TCP/UDP cksums comp. */ WM_Q_EVCNT_DEFINE(txq, tusum); /* TCP/UDP cksums comp. */
WM_Q_EVCNT_DEFINE(txq, tusum6) /* TCP/UDP v6 cksums comp. */ WM_Q_EVCNT_DEFINE(txq, tusum6); /* TCP/UDP v6 cksums comp. */
WM_Q_EVCNT_DEFINE(txq, tso) /* TCP seg offload (IPv4) */ WM_Q_EVCNT_DEFINE(txq, tso); /* TCP seg offload (IPv4) */
WM_Q_EVCNT_DEFINE(txq, tso6) /* TCP seg offload (IPv6) */ WM_Q_EVCNT_DEFINE(txq, tso6); /* TCP seg offload (IPv6) */
WM_Q_EVCNT_DEFINE(txq, tsopain) /* Painful header manip. for TSO */ WM_Q_EVCNT_DEFINE(txq, tsopain); /* Painful header manip. for TSO */
WM_Q_EVCNT_DEFINE(txq, pcqdrop) /* Pkt dropped in pcq */ WM_Q_EVCNT_DEFINE(txq, pcqdrop); /* Pkt dropped in pcq */
WM_Q_EVCNT_DEFINE(txq, descdrop) /* Pkt dropped in MAC desc ring */ WM_Q_EVCNT_DEFINE(txq, descdrop); /* Pkt dropped in MAC desc ring */
/* other than toomanyseg */ /* other than toomanyseg */
WM_Q_EVCNT_DEFINE(txq, toomanyseg) /* Pkt dropped(toomany DMA segs) */ WM_Q_EVCNT_DEFINE(txq, toomanyseg); /* Pkt dropped(toomany DMA segs) */
WM_Q_EVCNT_DEFINE(txq, defrag) /* m_defrag() */ WM_Q_EVCNT_DEFINE(txq, defrag); /* m_defrag() */
WM_Q_EVCNT_DEFINE(txq, underrun) /* Tx underrun */ WM_Q_EVCNT_DEFINE(txq, underrun); /* Tx underrun */
WM_Q_EVCNT_DEFINE(txq, skipcontext) /* Tx skip wring cksum context */ WM_Q_EVCNT_DEFINE(txq, skipcontext); /* Tx skip wrong cksum context */
char txq_txseg_evcnt_names[WM_NTXSEGS][sizeof("txqXXtxsegXXX")]; char txq_txseg_evcnt_names[WM_NTXSEGS][sizeof("txqXXtxsegXXX")];
struct evcnt txq_ev_txseg[WM_NTXSEGS]; /* Tx packets w/ N segments */ struct evcnt txq_ev_txseg[WM_NTXSEGS]; /* Tx packets w/ N segments */
@ -529,7 +529,7 @@ struct wm_softc {
*/ */
bus_dma_tag_t sc_dmat; /* bus DMA tag */ bus_dma_tag_t sc_dmat; /* bus DMA tag */
struct ethercom sc_ethercom; /* ethernet common data */ struct ethercom sc_ethercom; /* Ethernet common data */
struct mii_data sc_mii; /* MII/media information */ struct mii_data sc_mii; /* MII/media information */
pci_chipset_tag_t sc_pc; pci_chipset_tag_t sc_pc;
@ -1905,10 +1905,13 @@ wm_attach(device_t parent, device_t self, void *aux)
sc->sc_pc = pa->pa_pc; sc->sc_pc = pa->pa_pc;
sc->sc_pcitag = pa->pa_tag; sc->sc_pcitag = pa->pa_tag;
if (pci_dma64_available(pa)) if (pci_dma64_available(pa)) {
aprint_verbose(", 64-bit DMA");
sc->sc_dmat = pa->pa_dmat64; sc->sc_dmat = pa->pa_dmat64;
else } else {
aprint_verbose(", 32-bit DMA");
sc->sc_dmat = pa->pa_dmat; sc->sc_dmat = pa->pa_dmat;
}
sc->sc_pcidevid = PCI_PRODUCT(pa->pa_id); sc->sc_pcidevid = PCI_PRODUCT(pa->pa_id);
sc->sc_rev = PCI_REVISION(pci_conf_read(pc, pa->pa_tag,PCI_CLASS_REG)); sc->sc_rev = PCI_REVISION(pci_conf_read(pc, pa->pa_tag,PCI_CLASS_REG));
@ -2022,8 +2025,8 @@ wm_attach(device_t parent, device_t self, void *aux)
aprint_error_dev(sc->sc_dev, aprint_error_dev(sc->sc_dev,
"WARNING: I/O BAR at zero.\n"); "WARNING: I/O BAR at zero.\n");
} else if (pci_mapreg_map(pa, i, PCI_MAPREG_TYPE_IO, } else if (pci_mapreg_map(pa, i, PCI_MAPREG_TYPE_IO,
0, &sc->sc_iot, &sc->sc_ioh, 0, &sc->sc_iot, &sc->sc_ioh, NULL, &sc->sc_ios)
NULL, &sc->sc_ios) == 0) { == 0) {
sc->sc_flags |= WM_F_IOH_VALID; sc->sc_flags |= WM_F_IOH_VALID;
} else } else
aprint_error_dev(sc->sc_dev, aprint_error_dev(sc->sc_dev,
@ -2978,7 +2981,8 @@ alloc_retry:
} else { } else {
ifp->if_start = wm_start; ifp->if_start = wm_start;
/* /*
* wm_transmit() has the same disadvantage as wm_transmit(). * wm_transmit() has the same disadvantages as wm_nq_transmit()
* described above.
*/ */
if (wm_is_using_multiqueue(sc)) if (wm_is_using_multiqueue(sc))
ifp->if_transmit = wm_transmit; ifp->if_transmit = wm_transmit;
@ -3039,7 +3043,7 @@ alloc_retry:
ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING; ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING;
/* /*
* We can perform TCPv4 and UDPv4 checkums in-bound. Only * We can perform TCPv4 and UDPv4 checksums in-bound. Only
* on i82543 and later. * on i82543 and later.
*/ */
if (sc->sc_type >= WM_T_82543) { if (sc->sc_type >= WM_T_82543) {
@ -3066,13 +3070,11 @@ alloc_retry:
* If we're a i82544 or greater (except i82547), we can do * If we're a i82544 or greater (except i82547), we can do
* TCP segmentation offload. * TCP segmentation offload.
*/ */
if (sc->sc_type >= WM_T_82544 && sc->sc_type != WM_T_82547) { if (sc->sc_type >= WM_T_82544 && sc->sc_type != WM_T_82547)
ifp->if_capabilities |= IFCAP_TSOv4; ifp->if_capabilities |= IFCAP_TSOv4;
}
if (sc->sc_type >= WM_T_82571) { if (sc->sc_type >= WM_T_82571)
ifp->if_capabilities |= IFCAP_TSOv6; ifp->if_capabilities |= IFCAP_TSOv6;
}
sc->sc_tx_process_limit = WM_TX_PROCESS_LIMIT_DEFAULT; sc->sc_tx_process_limit = WM_TX_PROCESS_LIMIT_DEFAULT;
sc->sc_tx_intr_process_limit = WM_TX_INTR_PROCESS_LIMIT_DEFAULT; sc->sc_tx_intr_process_limit = WM_TX_INTR_PROCESS_LIMIT_DEFAULT;
@ -3429,10 +3431,10 @@ wm_tick(void *arg)
+ CSR_READ(sc, WMREG_CEXTERR) + CSR_READ(sc, WMREG_CEXTERR)
+ CSR_READ(sc, WMREG_RLEC); + CSR_READ(sc, WMREG_RLEC);
/* /*
* WMREG_RNBC is incremented when there is no available buffers in host * WMREG_RNBC is incremented when there are no available buffers in host
* memory. It does not mean the number of dropped packet. Because * memory. It does not mean the number of dropped packets, because an
* ethernet controller can receive packets in such case if there is * Ethernet controller can receive packets in such case if there is
* space in phy's FIFO. * space in the phy's FIFO.
* *
* If you want to know the nubmer of WMREG_RMBC, you should use such as * If you want to know the nubmer of WMREG_RMBC, you should use such as
* own EVCNT instead of if_iqdrops. * own EVCNT instead of if_iqdrops.
@ -3448,6 +3450,9 @@ wm_tick(void *arg)
wm_tbi_tick(sc); wm_tbi_tick(sc);
WM_CORE_UNLOCK(sc); WM_CORE_UNLOCK(sc);
#ifndef WM_MPSAFE
splx(s);
#endif
wm_watchdog(ifp); wm_watchdog(ifp);
@ -4809,7 +4814,7 @@ wm_flush_desc_rings(struct wm_softc *sc)
* Remove all descriptors from the tx_ring. * Remove all descriptors from the tx_ring.
* *
* We want to clear all pending descriptors from the TX ring. Zeroing * We want to clear all pending descriptors from the TX ring. Zeroing
* happens when the HW reads the regs. We assign the ring itself as * happens when the HW reads the regs. We assign the ring itself as
* the data of the next descriptor. We don't care about the data we are * the data of the next descriptor. We don't care about the data we are
* about to reset the HW. * about to reset the HW.
*/ */
@ -4979,7 +4984,7 @@ wm_reset(struct wm_softc *sc)
} }
if (timeout == 0) if (timeout == 0)
device_printf(sc->sc_dev, device_printf(sc->sc_dev,
"failed to disable busmastering\n"); "failed to disable bus mastering\n");
} }
/* Set the completion timeout for interface */ /* Set the completion timeout for interface */
@ -5500,8 +5505,8 @@ wm_adjust_qnum(struct wm_softc *sc, int nvectors)
hw_nrxqueues = 2; hw_nrxqueues = 2;
break; break;
/* /*
* As below ethernet controllers does not support MSI-X, * The below Ethernet controllers do not support MSI-X;
* this driver let them not use multiqueue. * this driver doesn't let them use multiqueue.
* - WM_T_80003 * - WM_T_80003
* - WM_T_ICH8 * - WM_T_ICH8
* - WM_T_ICH9 * - WM_T_ICH9
@ -5528,7 +5533,7 @@ wm_adjust_qnum(struct wm_softc *sc, int nvectors)
sc->sc_nqueues = hw_nqueues; sc->sc_nqueues = hw_nqueues;
/* /*
* As queues more then cpus cannot improve scaling, we limit * As queues more than CPUs cannot improve scaling, we limit
* the number of queues used actually. * the number of queues used actually.
*/ */
if (ncpu < sc->sc_nqueues) if (ncpu < sc->sc_nqueues)
@ -5814,12 +5819,12 @@ wm_itrs_writereg(struct wm_softc *sc, struct wm_queue *wmq)
/* /*
* TODO * TODO
* Below dynamic calculation of itr is almost the same as linux igb, * Below dynamic calculation of itr is almost the same as Linux igb,
* however it does not fit to wm(4). So, we will have been disable AIM * however it does not fit to wm(4). So, we will have been disable AIM
* until we will find appropriate calculation of itr. * until we will find appropriate calculation of itr.
*/ */
/* /*
* calculate interrupt interval value to be going to write register in * Calculate interrupt interval value to be going to write register in
* wm_itrs_writereg(). This function does not write ITR/EITR register. * wm_itrs_writereg(). This function does not write ITR/EITR register.
*/ */
static void static void
@ -6123,7 +6128,7 @@ wm_init_locked(struct ifnet *ifp)
* 82574's EITR should be set same throttling value as ITR. * 82574's EITR should be set same throttling value as ITR.
* *
* For N interrupts/sec, set this value to: * For N interrupts/sec, set this value to:
* 1,000,000 / N in contrast to ITR throttoling value. * 1,000,000 / N in contrast to ITR throttling value.
*/ */
sc->sc_itr_init = 450; sc->sc_itr_init = 450;
} else if (sc->sc_type >= WM_T_82543) { } else if (sc->sc_type >= WM_T_82543) {
@ -6234,7 +6239,7 @@ wm_init_locked(struct ifnet *ifp)
reg &= ~CTRL_EXT_LINK_MODE_MASK; reg &= ~CTRL_EXT_LINK_MODE_MASK;
CSR_WRITE(sc, WMREG_CTRL_EXT, reg); CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
/* Bypass RX and TX FIFO's */ /* Bypass RX and TX FIFOs */
wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_FIFO_CTRL, wm_kmrn_writereg(sc, KUMCTRLSTA_OFFSET_FIFO_CTRL,
KUMCTRLSTA_FIFO_CTRL_RX_BYPASS KUMCTRLSTA_FIFO_CTRL_RX_BYPASS
| KUMCTRLSTA_FIFO_CTRL_TX_BYPASS); | KUMCTRLSTA_FIFO_CTRL_TX_BYPASS);
@ -6287,7 +6292,7 @@ wm_init_locked(struct ifnet *ifp)
CSR_WRITE(sc, WMREG_CTRL_EXT, reg); CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
/* /*
* Workaround issue with spurious interrupts * Work around issue with spurious interrupts
* in MSI-X mode. * in MSI-X mode.
* At wm_initialize_hardware_bits(), sc_nintrs has not * At wm_initialize_hardware_bits(), sc_nintrs has not
* initialized yet. So re-initialize WMREG_RFCTL here. * initialized yet. So re-initialize WMREG_RFCTL here.
@ -6460,12 +6465,12 @@ wm_init_locked(struct ifnet *ifp)
*/ */
} }
/* Set the VLAN ethernetype. */ /* Set the VLAN EtherType. */
CSR_WRITE(sc, WMREG_VET, ETHERTYPE_VLAN); CSR_WRITE(sc, WMREG_VET, ETHERTYPE_VLAN);
/* /*
* Set up the transmit control register; we start out with * Set up the transmit control register; we start out with
* a collision distance suitable for FDX, but update it whe * a collision distance suitable for FDX, but update it when
* we resolve the media type. * we resolve the media type.
*/ */
sc->sc_tctl = TCTL_EN | TCTL_PSP | TCTL_RTLC sc->sc_tctl = TCTL_EN | TCTL_PSP | TCTL_RTLC
@ -7136,8 +7141,10 @@ wm_alloc_txrx_queues(struct wm_softc *sc)
for (j = 0; j < WM_NTXSEGS; j++) { for (j = 0; j < WM_NTXSEGS; j++) {
snprintf(txq->txq_txseg_evcnt_names[j], snprintf(txq->txq_txseg_evcnt_names[j],
sizeof(txq->txq_txseg_evcnt_names[j]), "txq%02dtxseg%d", i, j); sizeof(txq->txq_txseg_evcnt_names[j]),
evcnt_attach_dynamic(&txq->txq_ev_txseg[j], EVCNT_TYPE_MISC, "txq%02dtxseg%d", i, j);
evcnt_attach_dynamic(&txq->txq_ev_txseg[j],
EVCNT_TYPE_MISC,
NULL, xname, txq->txq_txseg_evcnt_names[j]); NULL, xname, txq->txq_txseg_evcnt_names[j]);
} }
@ -7434,10 +7441,15 @@ wm_init_rx_regs(struct wm_softc *sc, struct wm_queue *wmq,
if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) { if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
if (MCLBYTES & ((1 << SRRCTL_BSIZEPKT_SHIFT) - 1)) if (MCLBYTES & ((1 << SRRCTL_BSIZEPKT_SHIFT) - 1))
panic("%s: MCLBYTES %d unsupported for 82575 or higher\n", __func__, MCLBYTES); panic("%s: MCLBYTES %d unsupported for 82575 "
"or higher\n", __func__, MCLBYTES);
/* Currently, support SRRCTL_DESCTYPE_ADV_ONEBUF only. */ /*
CSR_WRITE(sc, WMREG_SRRCTL(qid), SRRCTL_DESCTYPE_ADV_ONEBUF * Currently, support SRRCTL_DESCTYPE_ADV_ONEBUF
* only.
*/
CSR_WRITE(sc, WMREG_SRRCTL(qid),
SRRCTL_DESCTYPE_ADV_ONEBUF
| (MCLBYTES >> SRRCTL_BSIZEPKT_SHIFT)); | (MCLBYTES >> SRRCTL_BSIZEPKT_SHIFT));
CSR_WRITE(sc, WMREG_RXDCTL(qid), RXDCTL_QUEUE_ENABLE CSR_WRITE(sc, WMREG_RXDCTL(qid), RXDCTL_QUEUE_ENABLE
| RXDCTL_PTHRESH(16) | RXDCTL_HTHRESH(8) | RXDCTL_PTHRESH(16) | RXDCTL_HTHRESH(8)
@ -7762,7 +7774,7 @@ wm_tx_offload(struct wm_softc *sc, struct wm_txqueue *txq,
* configured checksum offload context. * configured checksum offload context.
* For TSO, in theory we can use the same TSO context only if * For TSO, in theory we can use the same TSO context only if
* frame is the same type(IP/TCP) and the same MSS. However * frame is the same type(IP/TCP) and the same MSS. However
* checking whether a frame has the same IP/TCP structure is * checking whether a frame has the same IP/TCP structure is a
* hard thing so just ignore that and always restablish a * hard thing so just ignore that and always restablish a
* new TSO context. * new TSO context.
*/ */
@ -7924,9 +7936,10 @@ wm_send_common_locked(struct ifnet *ifp, struct wm_txqueue *txq,
* increment successed packet counter as in the case * increment successed packet counter as in the case
* which the packet is discarded by link down PHY. * which the packet is discarded by link down PHY.
*/ */
if (m0 != NULL) if (m0 != NULL) {
ifp->if_opackets++; ifp->if_opackets++;
m_freem(m0); m_freem(m0);
}
} while (m0 != NULL); } while (m0 != NULL);
return; return;
} }
@ -8550,9 +8563,10 @@ wm_nq_send_common_locked(struct ifnet *ifp, struct wm_txqueue *txq,
* increment successed packet counter as in the case * increment successed packet counter as in the case
* which the packet is discarded by link down PHY. * which the packet is discarded by link down PHY.
*/ */
if (m0 != NULL) if (m0 != NULL) {
ifp->if_opackets++; ifp->if_opackets++;
m_freem(m0); m_freem(m0);
}
} while (m0 != NULL); } while (m0 != NULL);
return; return;
} }
@ -8704,7 +8718,7 @@ retry:
/* Initialize the first transmit descriptor. */ /* Initialize the first transmit descriptor. */
nexttx = txq->txq_next; nexttx = txq->txq_next;
if (!do_csum) { if (!do_csum) {
/* Setup a legacy descriptor */ /* Set up a legacy descriptor */
wm_set_dma_addr(&txq->txq_descs[nexttx].wtx_addr, wm_set_dma_addr(&txq->txq_descs[nexttx].wtx_addr,
dmamap->dm_segs[0].ds_addr); dmamap->dm_segs[0].ds_addr);
txq->txq_descs[nexttx].wtx_cmdlen = txq->txq_descs[nexttx].wtx_cmdlen =
@ -8721,7 +8735,7 @@ retry:
dcmdlen = 0; dcmdlen = 0;
} else { } else {
/* Setup an advanced data descriptor */ /* Set up an advanced data descriptor */
txq->txq_nq_descs[nexttx].nqtx_data.nqtxd_addr = txq->txq_nq_descs[nexttx].nqtx_data.nqtxd_addr =
htole64(dmamap->dm_segs[0].ds_addr); htole64(dmamap->dm_segs[0].ds_addr);
KASSERT((dmamap->dm_segs[0].ds_len & cmdlen) == 0); KASSERT((dmamap->dm_segs[0].ds_len & cmdlen) == 0);
@ -8742,8 +8756,8 @@ retry:
lasttx = nexttx; lasttx = nexttx;
nexttx = WM_NEXTTX(txq, nexttx); nexttx = WM_NEXTTX(txq, nexttx);
/* /*
* Fill in the next descriptors. legacy or advanced format * Fill in the next descriptors. Legacy or advanced format
* is the same here * is the same here.
*/ */
for (seg = 1; seg < dmamap->dm_nsegs; for (seg = 1; seg < dmamap->dm_nsegs;
seg++, nexttx = WM_NEXTTX(txq, nexttx)) { seg++, nexttx = WM_NEXTTX(txq, nexttx)) {
@ -8893,14 +8907,6 @@ wm_txeof(struct wm_txqueue *txq, u_int limit)
*/ */
for (i = txq->txq_sdirty; txq->txq_sfree != WM_TXQUEUELEN(txq); for (i = txq->txq_sdirty; txq->txq_sfree != WM_TXQUEUELEN(txq);
i = WM_NEXTTXS(txq, i), txq->txq_sfree++) { i = WM_NEXTTXS(txq, i), txq->txq_sfree++) {
if (limit-- == 0) {
more = true;
DPRINTF(sc, WM_DEBUG_TX,
("%s: TX: loop limited, job %d is not processed\n",
device_xname(sc->sc_dev), i));
break;
}
txs = &txq->txq_soft[i]; txs = &txq->txq_soft[i];
DPRINTF(sc, WM_DEBUG_TX, ("%s: TX: checking job %d\n", DPRINTF(sc, WM_DEBUG_TX, ("%s: TX: checking job %d\n",
@ -8917,6 +8923,14 @@ wm_txeof(struct wm_txqueue *txq, u_int limit)
break; break;
} }
if (limit-- == 0) {
more = true;
DPRINTF(sc, WM_DEBUG_TX,
("%s: TX: loop limited, job %d is not processed\n",
device_xname(sc->sc_dev), i));
break;
}
count++; count++;
DPRINTF(sc, WM_DEBUG_TX, DPRINTF(sc, WM_DEBUG_TX,
("%s: TX: job %d done: descs %d..%d\n", ("%s: TX: job %d done: descs %d..%d\n",
@ -9173,15 +9187,15 @@ wm_rxdesc_ensure_checksum(struct wm_rxqueue *rxq, uint32_t status,
if (!wm_rxdesc_is_set_status(sc, status, WRX_ST_IXSM, 0, 0)) { if (!wm_rxdesc_is_set_status(sc, status, WRX_ST_IXSM, 0, 0)) {
if (wm_rxdesc_is_set_status(sc, status, if (wm_rxdesc_is_set_status(sc, status,
WRX_ST_IPCS, EXTRXC_STATUS_IPCS, NQRXC_STATUS_IPCS)) { WRX_ST_IPCS, EXTRXC_STATUS_IPCS, NQRXC_STATUS_IPCS)) {
WM_Q_EVCNT_INCR(rxq, ipsum); WM_Q_EVCNT_INCR(rxq, ipsum);
m->m_pkthdr.csum_flags |= M_CSUM_IPv4; m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
if (wm_rxdesc_is_set_error(sc, errors, if (wm_rxdesc_is_set_error(sc, errors,
WRX_ER_IPE, EXTRXC_ERROR_IPE, NQRXC_ERROR_IPE)) WRX_ER_IPE, EXTRXC_ERROR_IPE, NQRXC_ERROR_IPE))
m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD; m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
} }
if (wm_rxdesc_is_set_status(sc, status, if (wm_rxdesc_is_set_status(sc, status,
WRX_ST_TCPCS, EXTRXC_STATUS_TCPCS, NQRXC_STATUS_L4I)) { WRX_ST_TCPCS, EXTRXC_STATUS_TCPCS, NQRXC_STATUS_L4I)) {
/* /*
* Note: we don't know if this was TCP or UDP, * Note: we don't know if this was TCP or UDP,
* so we just set both bits, and expect the * so we just set both bits, and expect the
@ -9219,14 +9233,6 @@ wm_rxeof(struct wm_rxqueue *rxq, u_int limit)
KASSERT(mutex_owned(rxq->rxq_lock)); KASSERT(mutex_owned(rxq->rxq_lock));
for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) { for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) {
if (limit-- == 0) {
more = true;
DPRINTF(sc, WM_DEBUG_RX,
("%s: RX: loop limited, descriptor %d is not processed\n",
device_xname(sc->sc_dev), i));
break;
}
rxs = &rxq->rxq_soft[i]; rxs = &rxq->rxq_soft[i];
DPRINTF(sc, WM_DEBUG_RX, DPRINTF(sc, WM_DEBUG_RX,
@ -9244,7 +9250,14 @@ wm_rxeof(struct wm_rxqueue *rxq, u_int limit)
uint8_t rsstype = wm_rxdesc_get_rsstype(rxq, i); uint8_t rsstype = wm_rxdesc_get_rsstype(rxq, i);
#endif #endif
if (!wm_rxdesc_dd(rxq, i, status)) { if (!wm_rxdesc_dd(rxq, i, status))
break;
if (limit-- == 0) {
more = true;
DPRINTF(sc, WM_DEBUG_RX,
("%s: RX: loop limited, descriptor %d is not processed\n",
device_xname(sc->sc_dev), i));
break; break;
} }
@ -9435,10 +9448,9 @@ wm_linkintr_gmii(struct wm_softc *sc, uint32_t icr)
if ((sc->sc_type == WM_T_ICH8) && (link == false)) if ((sc->sc_type == WM_T_ICH8) && (link == false))
wm_gig_downshift_workaround_ich8lan(sc); wm_gig_downshift_workaround_ich8lan(sc);
if ((sc->sc_type == WM_T_ICH8) if ((sc->sc_type == WM_T_ICH8) && (sc->sc_phytype == WMPHY_IGP_3))
&& (sc->sc_phytype == WMPHY_IGP_3)) {
wm_kmrn_lock_loss_workaround_ich8lan(sc); wm_kmrn_lock_loss_workaround_ich8lan(sc);
}
DPRINTF(sc, WM_DEBUG_LINK, ("%s: LINK: LSC -> mii_pollstat\n", DPRINTF(sc, WM_DEBUG_LINK, ("%s: LINK: LSC -> mii_pollstat\n",
device_xname(sc->sc_dev))); device_xname(sc->sc_dev)));
mii_pollstat(&sc->sc_mii); mii_pollstat(&sc->sc_mii);
@ -9589,7 +9601,8 @@ wm_linkintr_tbi(struct wm_softc *sc, uint32_t icr)
/* Update LED */ /* Update LED */
wm_tbi_serdes_set_linkled(sc); wm_tbi_serdes_set_linkled(sc);
} else if (icr & ICR_RXSEQ) } else if (icr & ICR_RXSEQ)
DPRINTF(sc, WM_DEBUG_LINK, ("%s: LINK: Receive sequence error\n", DPRINTF(sc, WM_DEBUG_LINK,
("%s: LINK: Receive sequence error\n",
device_xname(sc->sc_dev))); device_xname(sc->sc_dev)));
} }
@ -9664,7 +9677,8 @@ wm_linkintr_serdes(struct wm_softc *sc, uint32_t icr)
/* Update LED */ /* Update LED */
wm_tbi_serdes_set_linkled(sc); wm_tbi_serdes_set_linkled(sc);
} else } else
DPRINTF(sc, WM_DEBUG_LINK, ("%s: LINK: Receive sequence error\n", DPRINTF(sc, WM_DEBUG_LINK,
("%s: LINK: Receive sequence error\n",
device_xname(sc->sc_dev))); device_xname(sc->sc_dev)));
} }
@ -9740,32 +9754,6 @@ wm_intr_legacy(void *arg)
if (rndval == 0) if (rndval == 0)
rndval = icr; rndval = icr;
mutex_enter(rxq->rxq_lock);
if (rxq->rxq_stopping) {
mutex_exit(rxq->rxq_lock);
return 1;
}
#if defined(WM_DEBUG) || defined(WM_EVENT_COUNTERS)
if (icr & (ICR_RXDMT0 | ICR_RXT0)) {
DPRINTF(sc, WM_DEBUG_RX,
("%s: RX: got Rx intr 0x%08x\n",
device_xname(sc->sc_dev),
icr & (ICR_RXDMT0 | ICR_RXT0)));
WM_Q_EVCNT_INCR(rxq, intr);
}
#endif
/*
* wm_rxeof() does *not* call upper layer functions directly,
* as if_percpuq_enqueue() just call softint_schedule().
* So, we can call wm_rxeof() in interrupt context.
*/
more = wm_rxeof(rxq, rxlimit);
/* Fill lower bits with RX index. See below for the upper. */
rndval |= rxq->rxq_ptr & WM_NRXDESC_MASK;
mutex_exit(rxq->rxq_lock);
mutex_enter(txq->txq_lock); mutex_enter(txq->txq_lock);
if (txq->txq_stopping) { if (txq->txq_stopping) {
@ -9781,13 +9769,45 @@ wm_intr_legacy(void *arg)
WM_Q_EVCNT_INCR(txq, txdw); WM_Q_EVCNT_INCR(txq, txdw);
} }
#endif #endif
more |= wm_txeof(txq, txlimit); if (txlimit > 0) {
if (!IF_IS_EMPTY(&ifp->if_snd)) more |= wm_txeof(txq, txlimit);
if (!IF_IS_EMPTY(&ifp->if_snd))
more = true;
} else
more = true; more = true;
/* Fill upper bits with TX index. See above for the lower. */
rndval = txq->txq_next * WM_NRXDESC;
mutex_exit(txq->txq_lock); mutex_exit(txq->txq_lock);
mutex_enter(rxq->rxq_lock);
if (rxq->rxq_stopping) {
mutex_exit(rxq->rxq_lock);
return 1;
}
#if defined(WM_DEBUG) || defined(WM_EVENT_COUNTERS)
if (icr & (ICR_RXDMT0 | ICR_RXT0)) {
DPRINTF(sc, WM_DEBUG_RX,
("%s: RX: got Rx intr %#" __PRIxBIT "\n",
device_xname(sc->sc_dev),
icr & (ICR_RXDMT0 | ICR_RXT0)));
WM_Q_EVCNT_INCR(rxq, intr);
}
#endif
if (rxlimit > 0) {
/*
* wm_rxeof() does *not* call upper layer functions directly,
* as if_percpuq_enqueue() just call softint_schedule().
* So, we can call wm_rxeof() in interrupt context.
*/
more = wm_rxeof(rxq, rxlimit);
} else
more = true;
/* Fill lower bits with RX index. See below for the upper. */
rndval |= rxq->rxq_ptr & WM_NRXDESC_MASK;
mutex_exit(rxq->rxq_lock);
WM_CORE_LOCK(sc); WM_CORE_LOCK(sc);
if (sc->sc_core_stopping) { if (sc->sc_core_stopping) {
@ -9829,7 +9849,8 @@ wm_txrxintr_disable(struct wm_queue *wmq)
struct wm_softc *sc = wmq->wmq_txq.txq_sc; struct wm_softc *sc = wmq->wmq_txq.txq_sc;
if (__predict_false(!wm_is_using_msix(sc))) { if (__predict_false(!wm_is_using_msix(sc))) {
return wm_legacy_intr_disable(sc); wm_legacy_intr_disable(sc);
return;
} }
if (sc->sc_type == WM_T_82574) if (sc->sc_type == WM_T_82574)
@ -9850,7 +9871,8 @@ wm_txrxintr_enable(struct wm_queue *wmq)
wm_itrs_calculate(sc, wmq); wm_itrs_calculate(sc, wmq);
if (__predict_false(!wm_is_using_msix(sc))) { if (__predict_false(!wm_is_using_msix(sc))) {
return wm_legacy_intr_enable(sc); wm_legacy_intr_enable(sc);
return;
} }
/* /*
@ -9897,10 +9919,13 @@ wm_txrxintr_msix(void *arg)
} }
WM_Q_EVCNT_INCR(txq, txdw); WM_Q_EVCNT_INCR(txq, txdw);
txmore = wm_txeof(txq, txlimit);
/* Fill upper bits with TX index. See below for the lower. */ /* Fill upper bits with TX index. See below for the lower. */
rndval = txq->txq_next * WM_NRXDESC; rndval = txq->txq_next * WM_NRXDESC;
/* wm_deferred start() is done in wm_handle_queue(). */ if (txlimit > 0) {
txmore = wm_txeof(txq, txlimit);
/* wm_deferred start() is done in wm_handle_queue(). */
} else
txmore = true;
mutex_exit(txq->txq_lock); mutex_exit(txq->txq_lock);
DPRINTF(sc, WM_DEBUG_RX, DPRINTF(sc, WM_DEBUG_RX,
@ -9913,7 +9938,10 @@ wm_txrxintr_msix(void *arg)
} }
WM_Q_EVCNT_INCR(rxq, intr); WM_Q_EVCNT_INCR(rxq, intr);
rxmore = wm_rxeof(rxq, rxlimit); if (rxlimit > 0) {
rxmore = wm_rxeof(rxq, rxlimit);
} else
rxmore = true;
/* Fill lower bits with RX index. See above for the upper. */ /* Fill lower bits with RX index. See above for the upper. */
rndval |= rxq->rxq_ptr & WM_NRXDESC_MASK; rndval |= rxq->rxq_ptr & WM_NRXDESC_MASK;
@ -10256,7 +10284,7 @@ wm_gmii_reset(struct wm_softc *sc)
} }
/* /*
* Setup sc_phytype and mii_{read|write}reg. * Set up sc_phytype and mii_{read|write}reg.
* *
* To identify PHY type, correct read/write function should be selected. * To identify PHY type, correct read/write function should be selected.
* To select correct read/write function, PCI ID or MAC type are required * To select correct read/write function, PCI ID or MAC type are required
@ -10271,7 +10299,7 @@ wm_gmii_reset(struct wm_softc *sc)
* would be better than the first call. * would be better than the first call.
* *
* If the detected new result and previous assumption is different, * If the detected new result and previous assumption is different,
* diagnous message will be printed. * a diagnostic message will be printed.
*/ */
static void static void
wm_gmii_setup_phytype(struct wm_softc *sc, uint32_t phy_oui, wm_gmii_setup_phytype(struct wm_softc *sc, uint32_t phy_oui,
@ -10389,7 +10417,6 @@ wm_gmii_setup_phytype(struct wm_softc *sc, uint32_t phy_oui,
case MII_MODEL_INTEL_I350: case MII_MODEL_INTEL_I350:
new_phytype = WMPHY_I350; new_phytype = WMPHY_I350;
break; break;
break;
default: default:
break; break;
} }
@ -10699,7 +10726,7 @@ wm_gmii_mediainit(struct wm_softc *sc, pci_product_id_t prodid)
} }
if (LIST_FIRST(&mii->mii_phys) == NULL) { if (LIST_FIRST(&mii->mii_phys) == NULL) {
/* Any PHY wasn't find */ /* Any PHY wasn't found */
ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
sc->sc_phytype = WMPHY_NONE; sc->sc_phytype = WMPHY_NONE;
@ -10707,7 +10734,7 @@ wm_gmii_mediainit(struct wm_softc *sc, pci_product_id_t prodid)
struct mii_softc *child = LIST_FIRST(&mii->mii_phys); struct mii_softc *child = LIST_FIRST(&mii->mii_phys);
/* /*
* PHY Found! Check PHY type again by the second call of * PHY found! Check PHY type again by the second call of
* wm_gmii_setup_phytype. * wm_gmii_setup_phytype.
*/ */
wm_gmii_setup_phytype(sc, child->mii_mpd_oui, wm_gmii_setup_phytype(sc, child->mii_mpd_oui,
@ -12124,11 +12151,11 @@ wm_tbi_mediainit(struct wm_softc *sc)
CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl);
#define ADD(ss, mm, dd) \ #define ADD(ss, mm, dd) \
do { \ do { \
aprint_normal("%s%s", sep, ss); \ aprint_normal("%s%s", sep, ss); \
ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | (mm), (dd), NULL); \ ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER | (mm), (dd), NULL); \
sep = ", "; \ sep = ", "; \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
aprint_normal_dev(sc->sc_dev, ""); aprint_normal_dev(sc->sc_dev, "");
@ -12230,8 +12257,8 @@ wm_tbi_mediachange(struct ifnet *ifp)
ctrl = CSR_READ(sc, WMREG_CTRL); ctrl = CSR_READ(sc, WMREG_CTRL);
signal = wm_tbi_havesignal(sc, ctrl); signal = wm_tbi_havesignal(sc, ctrl);
DPRINTF(sc, WM_DEBUG_LINK, ("%s: signal = %d\n", device_xname(sc->sc_dev), DPRINTF(sc, WM_DEBUG_LINK,
signal)); ("%s: signal = %d\n", device_xname(sc->sc_dev), signal));
if (signal) { if (signal) {
/* Have signal; wait for the link to come up. */ /* Have signal; wait for the link to come up. */
@ -12241,12 +12268,14 @@ wm_tbi_mediachange(struct ifnet *ifp)
break; break;
} }
DPRINTF(sc, WM_DEBUG_LINK,("%s: i = %d after waiting for link\n", DPRINTF(sc, WM_DEBUG_LINK,
("%s: i = %d after waiting for link\n",
device_xname(sc->sc_dev), i)); device_xname(sc->sc_dev), i));
status = CSR_READ(sc, WMREG_STATUS); status = CSR_READ(sc, WMREG_STATUS);
DPRINTF(sc, WM_DEBUG_LINK, DPRINTF(sc, WM_DEBUG_LINK,
("%s: status after final read = 0x%x, STATUS_LU = 0x%x\n", ("%s: status after final read = 0x%x, STATUS_LU = %#"
__PRIxBIT "\n",
device_xname(sc->sc_dev), status, STATUS_LU)); device_xname(sc->sc_dev), status, STATUS_LU));
if (status & STATUS_LU) { if (status & STATUS_LU) {
/* Link is up. */ /* Link is up. */
@ -12284,7 +12313,8 @@ wm_tbi_mediachange(struct ifnet *ifp)
sc->sc_tbi_linkup = 0; sc->sc_tbi_linkup = 0;
} }
} else { } else {
DPRINTF(sc, WM_DEBUG_LINK, ("%s: LINK: set media -> no signal\n", DPRINTF(sc, WM_DEBUG_LINK,
("%s: LINK: set media -> no signal\n",
device_xname(sc->sc_dev))); device_xname(sc->sc_dev)));
sc->sc_tbi_linkup = 0; sc->sc_tbi_linkup = 0;
} }
@ -12395,8 +12425,7 @@ wm_check_for_link(struct wm_softc *sc)
&& (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)) { && (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO)) {
sc->sc_tbi_linkup = 1; sc->sc_tbi_linkup = 1;
DPRINTF(sc, WM_DEBUG_LINK, ("%s: %s: go back to autonego\n", DPRINTF(sc, WM_DEBUG_LINK, ("%s: %s: go back to autonego\n",
device_xname(sc->sc_dev), device_xname(sc->sc_dev), __func__));
__func__));
CSR_WRITE(sc, WMREG_TXCW, sc->sc_txcw); CSR_WRITE(sc, WMREG_TXCW, sc->sc_txcw);
CSR_WRITE(sc, WMREG_CTRL, (ctrl & ~CTRL_SLU)); CSR_WRITE(sc, WMREG_CTRL, (ctrl & ~CTRL_SLU));
} else if (signal && ((rxcw & RXCW_C) != 0)) } else if (signal && ((rxcw & RXCW_C) != 0))
@ -12640,7 +12669,8 @@ wm_serdes_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
/* Check flow */ /* Check flow */
reg = CSR_READ(sc, WMREG_PCS_LSTS); reg = CSR_READ(sc, WMREG_PCS_LSTS);
if ((reg & PCS_LSTS_AN_COMP) == 0) { if ((reg & PCS_LSTS_AN_COMP) == 0) {
DPRINTF(sc, WM_DEBUG_LINK, ("XXX LINKOK but not ACOMP\n")); DPRINTF(sc, WM_DEBUG_LINK,
("XXX LINKOK but not ACOMP\n"));
goto setled; goto setled;
} }
pcs_adv = CSR_READ(sc, WMREG_PCS_ANADV); pcs_adv = CSR_READ(sc, WMREG_PCS_ANADV);
@ -13926,7 +13956,7 @@ wm_nvm_version(struct wm_softc *sc)
/* /*
* XXX * XXX
* Qemu's e1000e emulation (82574L)'s SPI has only 64 words. * Qemu's e1000e emulation (82574L)'s SPI has only 64 words.
* I've never seen on real 82574 hardware with such small SPI ROM. * I've never seen real 82574 hardware with such small SPI ROM.
*/ */
if ((sc->sc_nvm_wordsize < NVM_OFF_IMAGE_UID1) if ((sc->sc_nvm_wordsize < NVM_OFF_IMAGE_UID1)
|| (wm_nvm_read(sc, NVM_OFF_IMAGE_UID1, 1, &uid1) != 0)) || (wm_nvm_read(sc, NVM_OFF_IMAGE_UID1, 1, &uid1) != 0))
@ -14199,8 +14229,7 @@ retry:
wm_put_swsm_semaphore(sc); wm_put_swsm_semaphore(sc);
goto retry; goto retry;
} }
aprint_error_dev(sc->sc_dev, aprint_error_dev(sc->sc_dev, "could not acquire SWSM SMBI\n");
"could not acquire SWSM SMBI\n");
return 1; return 1;
} }
@ -14506,9 +14535,8 @@ wm_put_swflag_ich8lan(struct wm_softc *sc)
if (ext_ctrl & EXTCNFCTR_MDIO_SW_OWNERSHIP) { if (ext_ctrl & EXTCNFCTR_MDIO_SW_OWNERSHIP) {
ext_ctrl &= ~EXTCNFCTR_MDIO_SW_OWNERSHIP; ext_ctrl &= ~EXTCNFCTR_MDIO_SW_OWNERSHIP;
CSR_WRITE(sc, WMREG_EXTCNFCTR, ext_ctrl); CSR_WRITE(sc, WMREG_EXTCNFCTR, ext_ctrl);
} else { } else
device_printf(sc->sc_dev, "Semaphore unexpectedly released\n"); device_printf(sc->sc_dev, "Semaphore unexpectedly released\n");
}
mutex_exit(sc->sc_ich_phymtx); mutex_exit(sc->sc_ich_phymtx);
} }
@ -15625,7 +15653,7 @@ wm_set_eee_i350(struct wm_softc *sc)
* Basically, PHY's workarounds are in the PHY drivers. * Basically, PHY's workarounds are in the PHY drivers.
*/ */
/* Work-around for 82566 Kumeran PCS lock loss */ /* Workaround for 82566 Kumeran PCS lock loss */
static void static void
wm_kmrn_lock_loss_workaround_ich8lan(struct wm_softc *sc) wm_kmrn_lock_loss_workaround_ich8lan(struct wm_softc *sc)
{ {
@ -15829,8 +15857,8 @@ wm_k1_workaround_lpt_lp(struct wm_softc *sc, bool link)
if (link && (speed == STATUS_SPEED_1000)) { if (link && (speed == STATUS_SPEED_1000)) {
sc->phy.acquire(sc); sc->phy.acquire(sc);
int rv = wm_kmrn_readreg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG, int rv = wm_kmrn_readreg_locked(sc,
&phyreg); KUMCTRLSTA_OFFSET_K1_CONFIG, &phyreg);
if (rv != 0) if (rv != 0)
goto release; goto release;
rv = wm_kmrn_writereg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG, rv = wm_kmrn_writereg_locked(sc, KUMCTRLSTA_OFFSET_K1_CONFIG,
@ -16446,7 +16474,7 @@ wm_sysctl_tdh_handler(SYSCTLFN_ARGS)
struct sysctlnode node = *rnode; struct sysctlnode node = *rnode;
struct wm_txqueue *txq = (struct wm_txqueue *)node.sysctl_data; struct wm_txqueue *txq = (struct wm_txqueue *)node.sysctl_data;
struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq); struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq);
struct wm_softc *sc = txq->txq_sc; struct wm_softc *sc = txq->txq_sc;
uint32_t reg; uint32_t reg;
reg = CSR_READ(sc, WMREG_TDH(wmq->wmq_id)); reg = CSR_READ(sc, WMREG_TDH(wmq->wmq_id));
@ -16460,7 +16488,7 @@ wm_sysctl_tdt_handler(SYSCTLFN_ARGS)
struct sysctlnode node = *rnode; struct sysctlnode node = *rnode;
struct wm_txqueue *txq = (struct wm_txqueue *)node.sysctl_data; struct wm_txqueue *txq = (struct wm_txqueue *)node.sysctl_data;
struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq); struct wm_queue *wmq = container_of(txq, struct wm_queue, wmq_txq);
struct wm_softc *sc = txq->txq_sc; struct wm_softc *sc = txq->txq_sc;
uint32_t reg; uint32_t reg;
reg = CSR_READ(sc, WMREG_TDT(wmq->wmq_id)); reg = CSR_READ(sc, WMREG_TDT(wmq->wmq_id));

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_wmvar.h,v 1.33.6.8 2021/10/23 11:49:22 martin Exp $ */ /* $NetBSD: if_wmvar.h,v 1.33.6.9 2022/07/11 14:15:58 martin Exp $ */
/* /*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@ -37,32 +37,32 @@
/******************************************************************************* /*******************************************************************************
Copyright (c) 2001-2005, Intel Corporation Copyright (c) 2001-2005, Intel Corporation
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, 1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright 2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. documentation and/or other materials provided with the distribution.
3. Neither the name of the Intel Corporation nor the names of its 3. Neither the name of the Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived from contributors may be used to endorse or promote products derived from
this software without specific prior written permission. this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. POSSIBILITY OF SUCH DAMAGE.