Module Name: src
Committed By: knakahara
Date: Thu May 19 08:27:57 UTC 2016
Modified Files:
src/sys/dev/pci: if_wm.c
Log Message:
unify TX and RX interrupt handler to use MSI-X vector efficiently
To generate a diff of this commit:
cvs rdiff -u -r1.404 -r1.405 src/sys/dev/pci/if_wm.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/if_wm.c
diff -u src/sys/dev/pci/if_wm.c:1.404 src/sys/dev/pci/if_wm.c:1.405
--- src/sys/dev/pci/if_wm.c:1.404 Thu May 19 08:22:37 2016
+++ src/sys/dev/pci/if_wm.c Thu May 19 08:27:57 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.404 2016/05/19 08:22:37 knakahara Exp $ */
+/* $NetBSD: if_wm.c,v 1.405 2016/05/19 08:27:57 knakahara Exp $ */
/*
* Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc.
@@ -83,7 +83,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.404 2016/05/19 08:22:37 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.405 2016/05/19 08:27:57 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -164,9 +164,8 @@ int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX
/*
* This device driver's max interrupt numbers.
*/
-#define WM_MAX_NTXINTR 16
-#define WM_MAX_NRXINTR 16
-#define WM_MAX_NINTR (WM_MAX_NTXINTR + WM_MAX_NRXINTR + 1)
+#define WM_MAX_NQUEUEINTR 16
+#define WM_MAX_NINTR (WM_MAX_NQUEUEINTR + 1)
/*
* Transmit descriptor list size. Due to errata, we can only have
@@ -256,10 +255,7 @@ struct wm_softc;
struct wm_txqueue {
kmutex_t *txq_lock; /* lock for tx operations */
- struct wm_softc *txq_sc;
-
- int txq_id; /* index of transmit queues */
- int txq_intr_idx; /* index of MSI-X tables */
+ struct wm_softc *txq_sc; /* shortcut (skip struct wm_queue) */
/* Software state for the transmit descriptors. */
int txq_num; /* must be a power of two */
@@ -310,10 +306,7 @@ struct wm_txqueue {
struct wm_rxqueue {
kmutex_t *rxq_lock; /* lock for rx operations */
- struct wm_softc *rxq_sc;
-
- int rxq_id; /* index of receive queues */
- int rxq_intr_idx; /* index of MSI-X tables */
+ struct wm_softc *rxq_sc; /* shortcut (skip struct wm_queue) */
/* Software state for the receive descriptors. */
wiseman_rxdesc_t *rxq_descs;
@@ -338,6 +331,14 @@ struct wm_rxqueue {
/* XXX which event counter is required? */
};
+struct wm_queue {
+ int wmq_id; /* index of transmit and receive queues */
+ int wmq_intr_idx; /* index of MSI-X tables */
+
+ struct wm_txqueue wmq_txq;
+ struct wm_rxqueue wmq_rxq;
+};
+
/*
* Software state per device.
*/
@@ -402,11 +403,8 @@ struct wm_softc {
int sc_ich8_flash_bank_size;
int sc_nvm_k1_enabled;
- int sc_ntxqueues;
- struct wm_txqueue *sc_txq;
-
- int sc_nrxqueues;
- struct wm_rxqueue *sc_rxq;
+ int sc_nqueues;
+ struct wm_queue *sc_queue;
int sc_affinity_offset;
@@ -609,18 +607,22 @@ static int wm_82547_txfifo_bugchk(struct
static int wm_alloc_tx_descs(struct wm_softc *, struct wm_txqueue *);
static void wm_free_tx_descs(struct wm_softc *, struct wm_txqueue *);
static void wm_init_tx_descs(struct wm_softc *, struct wm_txqueue *);
-static void wm_init_tx_regs(struct wm_softc *, struct wm_txqueue *);
+static void wm_init_tx_regs(struct wm_softc *, struct wm_queue *,
+ struct wm_txqueue *);
static int wm_alloc_rx_descs(struct wm_softc *, struct wm_rxqueue *);
static void wm_free_rx_descs(struct wm_softc *, struct wm_rxqueue *);
-static void wm_init_rx_regs(struct wm_softc *, struct wm_rxqueue *);
+static void wm_init_rx_regs(struct wm_softc *, struct wm_queue *,
+ struct wm_rxqueue *);
static int wm_alloc_tx_buffer(struct wm_softc *, struct wm_txqueue *);
static void wm_free_tx_buffer(struct wm_softc *, struct wm_txqueue *);
static void wm_init_tx_buffer(struct wm_softc *, struct wm_txqueue *);
static int wm_alloc_rx_buffer(struct wm_softc *, struct wm_rxqueue *);
static void wm_free_rx_buffer(struct wm_softc *, struct wm_rxqueue *);
static int wm_init_rx_buffer(struct wm_softc *, struct wm_rxqueue *);
-static void wm_init_tx_queue(struct wm_softc *, struct wm_txqueue *);
-static int wm_init_rx_queue(struct wm_softc *, struct wm_rxqueue *);
+static void wm_init_tx_queue(struct wm_softc *, struct wm_queue *,
+ struct wm_txqueue *);
+static int wm_init_rx_queue(struct wm_softc *, struct wm_queue *,
+ struct wm_rxqueue *);
static int wm_alloc_txrx_queues(struct wm_softc *);
static void wm_free_txrx_queues(struct wm_softc *);
static int wm_init_txrx_queues(struct wm_softc *);
@@ -645,8 +647,7 @@ static void wm_linkintr_tbi(struct wm_so
static void wm_linkintr_serdes(struct wm_softc *, uint32_t);
static void wm_linkintr(struct wm_softc *, uint32_t);
static int wm_intr_legacy(void *);
-static int wm_txintr_msix(void *);
-static int wm_rxintr_msix(void *);
+static int wm_txrxintr_msix(void *);
static int wm_linkintr_msix(void *);
/*
@@ -1675,7 +1676,7 @@ wm_attach(device_t parent, device_t self
/* Allocation settings */
max_type = PCI_INTR_TYPE_MSIX;
- counts[PCI_INTR_TYPE_MSIX] = sc->sc_ntxqueues + sc->sc_nrxqueues + 1;
+ counts[PCI_INTR_TYPE_MSIX] = sc->sc_nqueues + 1;
counts[PCI_INTR_TYPE_MSI] = 1;
counts[PCI_INTR_TYPE_INTX] = 1;
@@ -2414,7 +2415,7 @@ alloc_retry:
ifp->if_ioctl = wm_ioctl;
if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
ifp->if_start = wm_nq_start;
- if (sc->sc_ntxqueues > 1)
+ if (sc->sc_nqueues > 1)
ifp->if_transmit = wm_nq_transmit;
} else
ifp->if_start = wm_start;
@@ -2635,8 +2636,8 @@ wm_detach(device_t self, int flags __unu
if_percpuq_destroy(sc->sc_ipq);
/* Unload RX dmamaps and free mbufs */
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq;
WM_RX_LOCK(rxq);
wm_rxdrain(rxq);
WM_RX_UNLOCK(rxq);
@@ -2709,8 +2710,8 @@ wm_watchdog(struct ifnet *ifp)
int qid;
struct wm_softc *sc = ifp->if_softc;
- for (qid = 0; qid < sc->sc_ntxqueues; qid++) {
- struct wm_txqueue *txq = &sc->sc_txq[qid];
+ for (qid = 0; qid < sc->sc_nqueues; qid++) {
+ struct wm_txqueue *txq = &sc->sc_queue[qid].wmq_txq;
wm_watchdog_txq(ifp, txq);
}
@@ -3695,8 +3696,8 @@ wm_reset(struct wm_softc *sc)
case WM_T_82547_2:
sc->sc_pba = sc->sc_ethercom.ec_if.if_mtu > 8192 ?
PBA_22K : PBA_30K;
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- struct wm_txqueue *txq = &sc->sc_txq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq;
txq->txq_fifo_head = 0;
txq->txq_fifo_addr = sc->sc_pba << PBA_ADDR_SHIFT;
txq->txq_fifo_size =
@@ -4195,7 +4196,7 @@ wm_init_rss(struct wm_softc *sc)
for (i = 0; i < RETA_NUM_ENTRIES; i++) {
int qid, reta_ent;
- qid = i % sc->sc_nrxqueues;
+ qid = i % sc->sc_nqueues;
switch(sc->sc_type) {
case WM_T_82574:
reta_ent = __SHIFTIN(qid,
@@ -4248,11 +4249,10 @@ wm_init_rss(struct wm_softc *sc)
static void
wm_adjust_qnum(struct wm_softc *sc, int nvectors)
{
- int hw_ntxqueues, hw_nrxqueues;
+ int hw_ntxqueues, hw_nrxqueues, hw_nqueues;
- if (nvectors < 3) {
- sc->sc_ntxqueues = 1;
- sc->sc_nrxqueues = 1;
+ if (nvectors < 2) {
+ sc->sc_nqueues = 1;
return;
}
@@ -4304,33 +4304,24 @@ wm_adjust_qnum(struct wm_softc *sc, int
break;
}
+ hw_nqueues = min(hw_ntxqueues, hw_nrxqueues);
+
/*
- * As queues more then MSI-X vectors cannot improve scaling, we limit
+ * As queues more than MSI-X vectors cannot improve scaling, we limit
* the number of queues used actually.
- *
- * XXX
- * Currently, we separate TX queue interrupts and RX queue interrupts.
- * Howerver, the number of MSI-X vectors of recent controllers (such as
- * I354) expects that drivers bundle a TX queue interrupt and a RX
- * interrupt to one interrupt. e.g. FreeBSD's igb deals interrupts in
- * such a way.
- */
- if (nvectors < hw_ntxqueues + hw_nrxqueues + 1) {
- sc->sc_ntxqueues = (nvectors - 1) / 2;
- sc->sc_nrxqueues = (nvectors - 1) / 2;
+ */
+ if (nvectors < hw_nqueues + 1) {
+ sc->sc_nqueues = nvectors - 1;
} else {
- sc->sc_ntxqueues = hw_ntxqueues;
- sc->sc_nrxqueues = hw_nrxqueues;
+ sc->sc_nqueues = hw_nqueues;
}
/*
* As queues more then cpus cannot improve scaling, we limit
* the number of queues used actually.
*/
- if (ncpu < sc->sc_ntxqueues)
- sc->sc_ntxqueues = ncpu;
- if (ncpu < sc->sc_nrxqueues)
- sc->sc_nrxqueues = ncpu;
+ if (ncpu < sc->sc_nqueues)
+ sc->sc_nqueues = ncpu;
}
/*
@@ -4374,13 +4365,13 @@ wm_setup_msix(struct wm_softc *sc)
{
void *vih;
kcpuset_t *affinity;
- int qidx, error, intr_idx, tx_established, rx_established;
+ int qidx, error, intr_idx, txrx_established;
pci_chipset_tag_t pc = sc->sc_pc;
const char *intrstr = NULL;
char intrbuf[PCI_INTRSTR_LEN];
char intr_xname[INTRDEVNAMEBUF];
- if (sc->sc_ntxqueues + sc->sc_nrxqueues < ncpu) {
+ if (sc->sc_nqueues < ncpu) {
/*
* To avoid other devices' interrupts, the affinity of Tx/Rx
* interrupts start from CPU#1.
@@ -4405,58 +4396,11 @@ wm_setup_msix(struct wm_softc *sc)
intr_idx = 0;
/*
- * TX
- */
- tx_established = 0;
- for (qidx = 0; qidx < sc->sc_ntxqueues; qidx++) {
- struct wm_txqueue *txq = &sc->sc_txq[qidx];
- int affinity_to = (sc->sc_affinity_offset + intr_idx) % ncpu;
-
- intrstr = pci_intr_string(pc, sc->sc_intrs[intr_idx], intrbuf,
- sizeof(intrbuf));
-#ifdef WM_MPSAFE
- pci_intr_setattr(pc, &sc->sc_intrs[intr_idx],
- PCI_INTR_MPSAFE, true);
-#endif
- memset(intr_xname, 0, sizeof(intr_xname));
- snprintf(intr_xname, sizeof(intr_xname), "%sTX%d",
- device_xname(sc->sc_dev), qidx);
- vih = pci_intr_establish_xname(pc, sc->sc_intrs[intr_idx],
- IPL_NET, wm_txintr_msix, txq, intr_xname);
- if (vih == NULL) {
- aprint_error_dev(sc->sc_dev,
- "unable to establish MSI-X(for TX)%s%s\n",
- intrstr ? " at " : "",
- intrstr ? intrstr : "");
-
- goto fail_0;
- }
- kcpuset_zero(affinity);
- /* Round-robin affinity */
- kcpuset_set(affinity, affinity_to);
- error = interrupt_distribute(vih, affinity, NULL);
- if (error == 0) {
- aprint_normal_dev(sc->sc_dev,
- "for TX interrupting at %s affinity to %u\n",
- intrstr, affinity_to);
- } else {
- aprint_normal_dev(sc->sc_dev,
- "for TX interrupting at %s\n", intrstr);
- }
- sc->sc_ihs[intr_idx] = vih;
- txq->txq_id = qidx;
- txq->txq_intr_idx = intr_idx;
-
- tx_established++;
- intr_idx++;
- }
-
- /*
- * RX
+ * TX and RX
*/
- rx_established = 0;
- for (qidx = 0; qidx < sc->sc_nrxqueues; qidx++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[qidx];
+ txrx_established = 0;
+ for (qidx = 0; qidx < sc->sc_nqueues; qidx++) {
+ struct wm_queue *wmq = &sc->sc_queue[qidx];
int affinity_to = (sc->sc_affinity_offset + intr_idx) % ncpu;
intrstr = pci_intr_string(pc, sc->sc_intrs[intr_idx], intrbuf,
@@ -4466,17 +4410,17 @@ wm_setup_msix(struct wm_softc *sc)
PCI_INTR_MPSAFE, true);
#endif
memset(intr_xname, 0, sizeof(intr_xname));
- snprintf(intr_xname, sizeof(intr_xname), "%sRX%d",
+ snprintf(intr_xname, sizeof(intr_xname), "%sTXRX%d",
device_xname(sc->sc_dev), qidx);
vih = pci_intr_establish_xname(pc, sc->sc_intrs[intr_idx],
- IPL_NET, wm_rxintr_msix, rxq, intr_xname);
+ IPL_NET, wm_txrxintr_msix, wmq, intr_xname);
if (vih == NULL) {
aprint_error_dev(sc->sc_dev,
- "unable to establish MSI-X(for RX)%s%s\n",
+ "unable to establish MSI-X(for TX and RX)%s%s\n",
intrstr ? " at " : "",
intrstr ? intrstr : "");
- goto fail_1;
+ goto fail;
}
kcpuset_zero(affinity);
/* Round-robin affinity */
@@ -4484,17 +4428,17 @@ wm_setup_msix(struct wm_softc *sc)
error = interrupt_distribute(vih, affinity, NULL);
if (error == 0) {
aprint_normal_dev(sc->sc_dev,
- "for RX interrupting at %s affinity to %u\n",
+ "for TX and RX interrupting at %s affinity to %u\n",
intrstr, affinity_to);
} else {
aprint_normal_dev(sc->sc_dev,
- "for RX interrupting at %s\n", intrstr);
+ "for TX and RX interrupting at %s\n", intrstr);
}
sc->sc_ihs[intr_idx] = vih;
- rxq->rxq_id = qidx;
- rxq->rxq_intr_idx = intr_idx;
+ wmq->wmq_id= qidx;
+ wmq->wmq_intr_idx = intr_idx;
- rx_established++;
+ txrx_established++;
intr_idx++;
}
@@ -4517,7 +4461,7 @@ wm_setup_msix(struct wm_softc *sc)
intrstr ? " at " : "",
intrstr ? intrstr : "");
- goto fail_1;
+ goto fail;
}
/* keep default affinity to LINK interrupt */
aprint_normal_dev(sc->sc_dev,
@@ -4525,21 +4469,15 @@ wm_setup_msix(struct wm_softc *sc)
sc->sc_ihs[intr_idx] = vih;
sc->sc_link_intr_idx = intr_idx;
- sc->sc_nintrs = sc->sc_ntxqueues + sc->sc_nrxqueues + 1;
+ sc->sc_nintrs = sc->sc_nqueues + 1;
kcpuset_destroy(affinity);
return 0;
- fail_1:
- for (qidx = 0; qidx < rx_established; qidx++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[qidx];
- pci_intr_disestablish(sc->sc_pc,sc->sc_ihs[rxq->rxq_intr_idx]);
- sc->sc_ihs[rxq->rxq_intr_idx] = NULL;
- }
- fail_0:
- for (qidx = 0; qidx < tx_established; qidx++) {
- struct wm_txqueue *txq = &sc->sc_txq[qidx];
- pci_intr_disestablish(sc->sc_pc,sc->sc_ihs[txq->txq_intr_idx]);
- sc->sc_ihs[txq->txq_intr_idx] = NULL;
+ fail:
+ for (qidx = 0; qidx < txrx_established; qidx++) {
+ struct wm_queue *wmq = &sc->sc_queue[qidx];
+ pci_intr_disestablish(sc->sc_pc,sc->sc_ihs[wmq->wmq_intr_idx]);
+ sc->sc_ihs[wmq->wmq_intr_idx] = NULL;
}
kcpuset_destroy(affinity);
@@ -4767,9 +4705,8 @@ wm_init_locked(struct ifnet *ifp)
/* Set up MSI-X */
if (sc->sc_nintrs > 1) {
uint32_t ivar;
- struct wm_txqueue *txq;
- struct wm_rxqueue *rxq;
- int qid;
+ struct wm_queue *wmq;
+ int qid, qintr_idx;
if (sc->sc_type == WM_T_82575) {
/* Interrupt control */
@@ -4777,17 +4714,12 @@ wm_init_locked(struct ifnet *ifp)
reg |= CTRL_EXT_PBA | CTRL_EXT_EIAME | CTRL_EXT_NSICR;
CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
- /* TX */
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- txq = &sc->sc_txq[i];
- CSR_WRITE(sc, WMREG_MSIXBM(txq->txq_intr_idx),
- EITR_TX_QUEUE(txq->txq_id));
- }
- /* RX */
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- rxq = &sc->sc_rxq[i];
- CSR_WRITE(sc, WMREG_MSIXBM(rxq->rxq_intr_idx),
- EITR_RX_QUEUE(rxq->rxq_id));
+ /* TX and RX */
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ wmq = &sc->sc_queue[i];
+ CSR_WRITE(sc, WMREG_MSIXBM(wmq->wmq_intr_idx),
+ EITR_TX_QUEUE(wmq->wmq_id)
+ | EITR_RX_QUEUE(wmq->wmq_id));
}
/* Link status */
CSR_WRITE(sc, WMREG_MSIXBM(sc->sc_link_intr_idx),
@@ -4799,19 +4731,16 @@ wm_init_locked(struct ifnet *ifp)
CSR_WRITE(sc, WMREG_CTRL_EXT, reg);
ivar = 0;
- /* TX */
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- txq = &sc->sc_txq[i];
- ivar |= __SHIFTIN((IVAR_VALID_82574
- | txq->txq_intr_idx),
- IVAR_TX_MASK_Q_82574(txq->txq_id));
- }
- /* RX */
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- rxq = &sc->sc_rxq[i];
- ivar |= __SHIFTIN((IVAR_VALID_82574
- | rxq->rxq_intr_idx),
- IVAR_RX_MASK_Q_82574(rxq->rxq_id));
+ /* TX and RX */
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ wmq = &sc->sc_queue[i];
+ qid = wmq->wmq_id;
+ qintr_idx = wmq->wmq_intr_idx;
+
+ ivar |= __SHIFTIN((IVAR_VALID_82574|qintr_idx),
+ IVAR_TX_MASK_Q_82574(qid));
+ ivar |= __SHIFTIN((IVAR_VALID_82574|qintr_idx),
+ IVAR_RX_MASK_Q_82574(qid));
}
/* Link status */
ivar |= __SHIFTIN((IVAR_VALID_82574
@@ -4828,53 +4757,39 @@ wm_init_locked(struct ifnet *ifp)
case WM_T_I354:
case WM_T_I210:
case WM_T_I211:
- /* TX */
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- txq = &sc->sc_txq[i];
- qid = txq->txq_id;
+ /* TX and RX */
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ wmq = &sc->sc_queue[i];
+ qid = wmq->wmq_id;
+ qintr_idx = wmq->wmq_intr_idx;
+
ivar = CSR_READ(sc, WMREG_IVAR_Q(qid));
ivar &= ~IVAR_TX_MASK_Q(qid);
- ivar |= __SHIFTIN((txq->txq_intr_idx
+ ivar |= __SHIFTIN((qintr_idx
| IVAR_VALID),
IVAR_TX_MASK_Q(qid));
- CSR_WRITE(sc, WMREG_IVAR_Q(qid), ivar);
- }
-
- /* RX */
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- rxq = &sc->sc_rxq[i];
- qid = rxq->rxq_id;
- ivar = CSR_READ(sc, WMREG_IVAR_Q(qid));
ivar &= ~IVAR_RX_MASK_Q(qid);
- ivar |= __SHIFTIN((rxq->rxq_intr_idx
+ ivar |= __SHIFTIN((qintr_idx
| IVAR_VALID),
IVAR_RX_MASK_Q(qid));
CSR_WRITE(sc, WMREG_IVAR_Q(qid), ivar);
}
break;
case WM_T_82576:
- /* TX */
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- txq = &sc->sc_txq[i];
- qid = txq->txq_id;
+ /* TX and RX */
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ wmq = &sc->sc_queue[i];
+ qid = wmq->wmq_id;
+ qintr_idx = wmq->wmq_intr_idx;
+
ivar = CSR_READ(sc,
WMREG_IVAR_Q_82576(qid));
ivar &= ~IVAR_TX_MASK_Q_82576(qid);
- ivar |= __SHIFTIN((txq->txq_intr_idx
+ ivar |= __SHIFTIN((qintr_idx
| IVAR_VALID),
IVAR_TX_MASK_Q_82576(qid));
- CSR_WRITE(sc, WMREG_IVAR_Q_82576(qid),
- ivar);
- }
-
- /* RX */
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- rxq = &sc->sc_rxq[i];
- qid = rxq->rxq_id;
- ivar = CSR_READ(sc,
- WMREG_IVAR_Q_82576(qid));
ivar &= ~IVAR_RX_MASK_Q_82576(qid);
- ivar |= __SHIFTIN((rxq->rxq_intr_idx
+ ivar |= __SHIFTIN((qintr_idx
| IVAR_VALID),
IVAR_RX_MASK_Q_82576(qid));
CSR_WRITE(sc, WMREG_IVAR_Q_82576(qid),
@@ -4891,7 +4806,7 @@ wm_init_locked(struct ifnet *ifp)
CSR_WRITE(sc, WMREG_IVAR_MISC, ivar);
}
- if (sc->sc_nrxqueues > 1) {
+ if (sc->sc_nqueues > 1) {
wm_init_rss(sc);
/*
@@ -4912,8 +4827,7 @@ wm_init_locked(struct ifnet *ifp)
ICR_RXO | ICR_RXT0;
if (sc->sc_nintrs > 1) {
uint32_t mask;
- struct wm_txqueue *txq;
- struct wm_rxqueue *rxq;
+ struct wm_queue *wmq;
switch (sc->sc_type) {
case WM_T_82574:
@@ -4925,24 +4839,17 @@ wm_init_locked(struct ifnet *ifp)
default:
if (sc->sc_type == WM_T_82575) {
mask = 0;
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- txq = &sc->sc_txq[i];
- mask |= EITR_TX_QUEUE(txq->txq_id);
- }
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- rxq = &sc->sc_rxq[i];
- mask |= EITR_RX_QUEUE(rxq->rxq_id);
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ wmq = &sc->sc_queue[i];
+ mask |= EITR_TX_QUEUE(wmq->wmq_id);
+ mask |= EITR_RX_QUEUE(wmq->wmq_id);
}
mask |= EITR_OTHER;
} else {
mask = 0;
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- txq = &sc->sc_txq[i];
- mask |= 1 << txq->txq_intr_idx;
- }
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- rxq = &sc->sc_rxq[i];
- mask |= 1 << rxq->rxq_intr_idx;
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ wmq = &sc->sc_queue[i];
+ mask |= 1 << wmq->wmq_intr_idx;
}
mask |= 1 << sc->sc_link_intr_idx;
}
@@ -4974,14 +4881,9 @@ wm_init_locked(struct ifnet *ifp)
*/
if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
int qidx;
- for (qidx = 0; qidx < sc->sc_ntxqueues; qidx++) {
- struct wm_txqueue *txq = &sc->sc_txq[qidx];
- CSR_WRITE(sc, WMREG_EITR(txq->txq_intr_idx),
- sc->sc_itr);
- }
- for (qidx = 0; qidx < sc->sc_nrxqueues; qidx++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[qidx];
- CSR_WRITE(sc, WMREG_EITR(rxq->rxq_intr_idx),
+ for (qidx = 0; qidx < sc->sc_nqueues; qidx++) {
+ struct wm_queue *wmq = &sc->sc_queue[qidx];
+ CSR_WRITE(sc, WMREG_EITR(wmq->wmq_intr_idx),
sc->sc_itr);
}
/*
@@ -5104,8 +5006,8 @@ wm_init_locked(struct ifnet *ifp)
/* On 575 and later set RDT only if RX enabled */
if ((sc->sc_flags & WM_F_NEWQUEUE) != 0) {
int qidx;
- for (qidx = 0; qidx < sc->sc_nrxqueues; qidx++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[qidx];
+ for (qidx = 0; qidx < sc->sc_nqueues; qidx++) {
+ struct wm_rxqueue *rxq = &sc->sc_queue[qidx].wmq_rxq;
for (i = 0; i < WM_NRXDESC; i++) {
WM_RX_LOCK(rxq);
wm_init_rxdesc(rxq, i);
@@ -5199,8 +5101,9 @@ wm_stop_locked(struct ifnet *ifp, int di
}
/* Release any queued transmit buffers. */
- for (qidx = 0; qidx < sc->sc_ntxqueues; qidx++) {
- struct wm_txqueue *txq = &sc->sc_txq[qidx];
+ for (qidx = 0; qidx < sc->sc_nqueues; qidx++) {
+ struct wm_queue *wmq = &sc->sc_queue[qidx];
+ struct wm_txqueue *txq = &wmq->wmq_txq;
WM_TX_LOCK(txq);
for (i = 0; i < WM_TXQUEUELEN(txq); i++) {
txs = &txq->txq_soft[i];
@@ -5231,7 +5134,7 @@ wm_stop_locked(struct ifnet *ifp, int di
printf("XXX need TX flush (reg = %08x)\n",
preg);
wm_init_tx_descs(sc, txq);
- wm_init_tx_regs(sc, txq);
+ wm_init_tx_regs(sc, wmq, txq);
nexttx = txq->txq_next;
wm_set_dma_addr(
&txq->txq_descs[nexttx].wtx_addr,
@@ -5261,8 +5164,8 @@ wm_stop_locked(struct ifnet *ifp, int di
ifp->if_timer = 0;
if (disable) {
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq;
WM_RX_LOCK(rxq);
wm_rxdrain(rxq);
WM_RX_UNLOCK(rxq);
@@ -5300,7 +5203,7 @@ static void
wm_82547_txfifo_stall(void *arg)
{
struct wm_softc *sc = arg;
- struct wm_txqueue *txq = sc->sc_txq;
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
#ifndef WM_MPSAFE
int s;
@@ -5366,7 +5269,7 @@ out:
static int
wm_82547_txfifo_bugchk(struct wm_softc *sc, struct mbuf *m0)
{
- struct wm_txqueue *txq = &sc->sc_txq[0];
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
int space = txq->txq_fifo_size - txq->txq_fifo_head;
int len = roundup(m0->m_pkthdr.len + WM_FIFO_HDR, WM_FIFO_HDR);
@@ -5637,21 +5540,21 @@ wm_alloc_txrx_queues(struct wm_softc *sc
{
int i, error, tx_done, rx_done;
- /*
- * For transmission
- */
- sc->sc_txq = kmem_zalloc(sizeof(struct wm_txqueue) * sc->sc_ntxqueues,
+ sc->sc_queue = kmem_zalloc(sizeof(struct wm_queue) * sc->sc_nqueues,
KM_SLEEP);
- if (sc->sc_txq == NULL) {
- aprint_error_dev(sc->sc_dev,"unable to allocate wm_txqueue\n");
+ if (sc->sc_queue == NULL) {
+ aprint_error_dev(sc->sc_dev,"unable to allocate wm_queue\n");
error = ENOMEM;
goto fail_0;
}
+ /*
+ * For transmission
+ */
error = 0;
tx_done = 0;
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- struct wm_txqueue *txq = &sc->sc_txq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq;
txq->txq_sc = sc;
#ifdef WM_MPSAFE
txq->txq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
@@ -5681,18 +5584,10 @@ wm_alloc_txrx_queues(struct wm_softc *sc
/*
* For recieve
*/
- sc->sc_rxq = kmem_zalloc(sizeof(struct wm_rxqueue) * sc->sc_nrxqueues,
- KM_SLEEP);
- if (sc->sc_rxq == NULL) {
- aprint_error_dev(sc->sc_dev,"unable to allocate wm_rxqueue\n");
- error = ENOMEM;
- goto fail_1;
- }
-
error = 0;
rx_done = 0;
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq;
rxq->rxq_sc = sc;
#ifdef WM_MPSAFE
rxq->rxq_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET);
@@ -5718,25 +5613,24 @@ wm_alloc_txrx_queues(struct wm_softc *sc
fail_2:
for (i = 0; i < rx_done; i++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[i];
+ struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq;
wm_free_rx_buffer(sc, rxq);
wm_free_rx_descs(sc, rxq);
if (rxq->rxq_lock)
mutex_obj_free(rxq->rxq_lock);
}
- kmem_free(sc->sc_rxq,
- sizeof(struct wm_rxqueue) * sc->sc_nrxqueues);
fail_1:
for (i = 0; i < tx_done; i++) {
- struct wm_txqueue *txq = &sc->sc_txq[i];
+ struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq;
pcq_destroy(txq->txq_interq);
wm_free_tx_buffer(sc, txq);
wm_free_tx_descs(sc, txq);
if (txq->txq_lock)
mutex_obj_free(txq->txq_lock);
}
- kmem_free(sc->sc_txq,
- sizeof(struct wm_txqueue) * sc->sc_ntxqueues);
+
+ kmem_free(sc->sc_queue,
+ sizeof(struct wm_queue) * sc->sc_nqueues);
fail_0:
return error;
}
@@ -5750,23 +5644,23 @@ wm_free_txrx_queues(struct wm_softc *sc)
{
int i;
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq;
wm_free_rx_buffer(sc, rxq);
wm_free_rx_descs(sc, rxq);
if (rxq->rxq_lock)
mutex_obj_free(rxq->rxq_lock);
}
- kmem_free(sc->sc_rxq, sizeof(struct wm_rxqueue) * sc->sc_nrxqueues);
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- struct wm_txqueue *txq = &sc->sc_txq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq;
wm_free_tx_buffer(sc, txq);
wm_free_tx_descs(sc, txq);
if (txq->txq_lock)
mutex_obj_free(txq->txq_lock);
}
- kmem_free(sc->sc_txq, sizeof(struct wm_txqueue) * sc->sc_ntxqueues);
+
+ kmem_free(sc->sc_queue, sizeof(struct wm_queue) * sc->sc_nqueues);
}
static void
@@ -5784,7 +5678,8 @@ wm_init_tx_descs(struct wm_softc *sc __u
}
static void
-wm_init_tx_regs(struct wm_softc *sc, struct wm_txqueue *txq)
+wm_init_tx_regs(struct wm_softc *sc, struct wm_queue *wmq,
+ struct wm_txqueue *txq)
{
KASSERT(WM_TX_LOCKED(txq));
@@ -5797,7 +5692,7 @@ wm_init_tx_regs(struct wm_softc *sc, str
CSR_WRITE(sc, WMREG_OLD_TDT, 0);
CSR_WRITE(sc, WMREG_OLD_TIDV, 128);
} else {
- int qid = txq->txq_id;
+ int qid = wmq->wmq_id;
CSR_WRITE(sc, WMREG_TDBAH(qid), WM_CDTXADDR_HI(txq, 0));
CSR_WRITE(sc, WMREG_TDBAL(qid), WM_CDTXADDR_LO(txq, 0));
@@ -5843,7 +5738,8 @@ wm_init_tx_buffer(struct wm_softc *sc __
}
static void
-wm_init_tx_queue(struct wm_softc *sc, struct wm_txqueue *txq)
+wm_init_tx_queue(struct wm_softc *sc, struct wm_queue *wmq,
+ struct wm_txqueue *txq)
{
KASSERT(WM_TX_LOCKED(txq));
@@ -5855,15 +5751,16 @@ wm_init_tx_queue(struct wm_softc *sc, st
if (sc->sc_type < WM_T_82543)
txq->txq_tdt_reg = WMREG_OLD_TDT;
else
- txq->txq_tdt_reg = WMREG_TDT(txq->txq_id);
+ txq->txq_tdt_reg = WMREG_TDT(wmq->wmq_id);
wm_init_tx_descs(sc, txq);
- wm_init_tx_regs(sc, txq);
+ wm_init_tx_regs(sc, wmq, txq);
wm_init_tx_buffer(sc, txq);
}
static void
-wm_init_rx_regs(struct wm_softc *sc, struct wm_rxqueue *rxq)
+wm_init_rx_regs(struct wm_softc *sc, struct wm_queue *wmq,
+ struct wm_rxqueue *rxq)
{
KASSERT(WM_RX_LOCKED(rxq));
@@ -5888,7 +5785,7 @@ wm_init_rx_regs(struct wm_softc *sc, str
CSR_WRITE(sc, WMREG_OLD_RDT1, 0);
CSR_WRITE(sc, WMREG_OLD_RDTR1, 0);
} else {
- int qid = rxq->rxq_id;
+ int qid = wmq->wmq_id;
CSR_WRITE(sc, WMREG_RDBAH(qid), WM_CDRXADDR_HI(rxq, 0));
CSR_WRITE(sc, WMREG_RDBAL(qid), WM_CDRXADDR_LO(rxq, 0));
@@ -5957,7 +5854,8 @@ wm_init_rx_buffer(struct wm_softc *sc, s
}
static int
-wm_init_rx_queue(struct wm_softc *sc, struct wm_rxqueue *rxq)
+wm_init_rx_queue(struct wm_softc *sc, struct wm_queue *wmq,
+ struct wm_rxqueue *rxq)
{
KASSERT(WM_RX_LOCKED(rxq));
@@ -5969,9 +5867,9 @@ wm_init_rx_queue(struct wm_softc *sc, st
if (sc->sc_type < WM_T_82543)
rxq->rxq_rdt_reg = WMREG_OLD_RDT0;
else
- rxq->rxq_rdt_reg = WMREG_RDT(rxq->rxq_id);
+ rxq->rxq_rdt_reg = WMREG_RDT(wmq->wmq_id);
- wm_init_rx_regs(sc, rxq);
+ wm_init_rx_regs(sc, wmq, rxq);
return wm_init_rx_buffer(sc, rxq);
}
@@ -5986,18 +5884,17 @@ wm_init_txrx_queues(struct wm_softc *sc)
DPRINTF(WM_DEBUG_INIT, ("%s: %s called\n",
device_xname(sc->sc_dev), __func__));
- for (i = 0; i < sc->sc_ntxqueues; i++) {
- struct wm_txqueue *txq = &sc->sc_txq[i];
+ for (i = 0; i < sc->sc_nqueues; i++) {
+ struct wm_queue *wmq = &sc->sc_queue[i];
+ struct wm_txqueue *txq = &wmq->wmq_txq;
+ struct wm_rxqueue *rxq = &wmq->wmq_rxq;
+
WM_TX_LOCK(txq);
- wm_init_tx_queue(sc, txq);
+ wm_init_tx_queue(sc, wmq, txq);
WM_TX_UNLOCK(txq);
- }
- error = 0;
- for (i = 0; i < sc->sc_nrxqueues; i++) {
- struct wm_rxqueue *rxq = &sc->sc_rxq[i];
WM_RX_LOCK(rxq);
- error = wm_init_rx_queue(sc, rxq);
+ error = wm_init_rx_queue(sc, wmq, rxq);
WM_RX_UNLOCK(rxq);
if (error)
break;
@@ -6016,7 +5913,7 @@ static int
wm_tx_offload(struct wm_softc *sc, struct wm_txsoft *txs, uint32_t *cmdp,
uint8_t *fieldsp)
{
- struct wm_txqueue *txq = &sc->sc_txq[0];
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
struct mbuf *m0 = txs->txs_mbuf;
struct livengood_tcpip_ctxdesc *t;
uint32_t ipcs, tucs, cmd, cmdlen, seg;
@@ -6211,7 +6108,7 @@ static void
wm_start(struct ifnet *ifp)
{
struct wm_softc *sc = ifp->if_softc;
- struct wm_txqueue *txq = &sc->sc_txq[0];
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
WM_TX_LOCK(txq);
if (!sc->sc_stopping)
@@ -6223,7 +6120,7 @@ static void
wm_start_locked(struct ifnet *ifp)
{
struct wm_softc *sc = ifp->if_softc;
- struct wm_txqueue *txq = &sc->sc_txq[0];
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
struct mbuf *m0;
struct m_tag *mtag;
struct wm_txsoft *txs;
@@ -6728,7 +6625,7 @@ static void
wm_nq_start(struct ifnet *ifp)
{
struct wm_softc *sc = ifp->if_softc;
- struct wm_txqueue *txq = &sc->sc_txq[0];
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
WM_TX_LOCK(txq);
if (!sc->sc_stopping)
@@ -6740,7 +6637,7 @@ static void
wm_nq_start_locked(struct ifnet *ifp)
{
struct wm_softc *sc = ifp->if_softc;
- struct wm_txqueue *txq = &sc->sc_txq[0];
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
wm_nq_send_common_locked(ifp, txq, false);
}
@@ -6756,7 +6653,7 @@ wm_nq_select_txqueue(struct ifnet *ifp,
* TODO:
* destribute by flowid(RSS has value).
*/
- return (cpuid + sc->sc_affinity_offset) % sc->sc_ntxqueues;
+ return (cpuid + sc->sc_affinity_offset) % sc->sc_nqueues;
}
static int
@@ -6767,7 +6664,7 @@ wm_nq_transmit(struct ifnet *ifp, struct
struct wm_txqueue *txq;
qid = wm_nq_select_txqueue(ifp, m);
- txq = &sc->sc_txq[qid];
+ txq = &sc->sc_queue[qid].wmq_txq;
if (__predict_false(!pcq_put(txq->txq_interq, m))) {
m_freem(m);
@@ -7092,6 +6989,8 @@ wm_txeof(struct wm_softc *sc, struct wm_
int i;
uint8_t status;
+ KASSERT(WM_TX_LOCKED(txq));
+
if (sc->sc_stopping)
return 0;
@@ -7193,6 +7092,8 @@ wm_rxeof(struct wm_rxqueue *rxq)
uint8_t status, errors;
uint16_t vlantag;
+ KASSERT(WM_RX_LOCKED(rxq));
+
for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) {
rxs = &rxq->rxq_soft[i];
@@ -7630,8 +7531,8 @@ static int
wm_intr_legacy(void *arg)
{
struct wm_softc *sc = arg;
- struct wm_txqueue *txq = &sc->sc_txq[0];
- struct wm_rxqueue *rxq = &sc->sc_rxq[0];
+ struct wm_txqueue *txq = &sc->sc_queue[0].wmq_txq;
+ struct wm_rxqueue *rxq = &sc->sc_queue[0].wmq_rxq;
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
uint32_t icr, rndval = 0;
int handled = 0;
@@ -7706,102 +7607,63 @@ wm_intr_legacy(void *arg)
return handled;
}
-/*
- * wm_txintr_msix:
- *
- * Interrupt service routine for TX complete interrupt for MSI-X.
- */
static int
-wm_txintr_msix(void *arg)
+wm_txrxintr_msix(void *arg)
{
- struct wm_txqueue *txq = arg;
+ struct wm_queue *wmq = arg;
+ struct wm_txqueue *txq = &wmq->wmq_txq;
+ struct wm_rxqueue *rxq = &wmq->wmq_rxq;
struct wm_softc *sc = txq->txq_sc;
struct ifnet *ifp = &sc->sc_ethercom.ec_if;
+ KASSERT(wmq->wmq_intr_idx == wmq->wmq_id);
+
DPRINTF(WM_DEBUG_TX,
("%s: TX: got Tx intr\n", device_xname(sc->sc_dev)));
if (sc->sc_type == WM_T_82574)
- CSR_WRITE(sc, WMREG_IMC, ICR_TXQ(txq->txq_id));
+ CSR_WRITE(sc, WMREG_IMC, ICR_TXQ(wmq->wmq_id) | ICR_RXQ(wmq->wmq_id));
else if (sc->sc_type == WM_T_82575)
- CSR_WRITE(sc, WMREG_EIMC, EITR_TX_QUEUE(txq->txq_id));
+ CSR_WRITE(sc, WMREG_EIMC, EITR_TX_QUEUE(wmq->wmq_id) | EITR_RX_QUEUE(wmq->wmq_id));
else
- CSR_WRITE(sc, WMREG_EIMC, 1 << txq->txq_intr_idx);
-
- WM_TX_LOCK(txq);
-
- if (sc->sc_stopping)
- goto out;
+ CSR_WRITE(sc, WMREG_EIMC, 1 << wmq->wmq_intr_idx);
- WM_EVCNT_INCR(&sc->sc_ev_txdw);
- wm_txeof(sc, txq);
-
-out:
- WM_TX_UNLOCK(txq);
+ if (!sc->sc_stopping) {
+ WM_TX_LOCK(txq);
- if (sc->sc_type == WM_T_82574)
- CSR_WRITE(sc, WMREG_IMS, ICR_TXQ(txq->txq_id));
- else if (sc->sc_type == WM_T_82575)
- CSR_WRITE(sc, WMREG_EIMS, EITR_TX_QUEUE(txq->txq_id));
- else
- CSR_WRITE(sc, WMREG_EIMS, 1 << txq->txq_intr_idx);
+ WM_EVCNT_INCR(&sc->sc_ev_txdw);
+ wm_txeof(sc, txq);
- /* Try to get more packets going. */
- if (pcq_peek(txq->txq_interq) != NULL) {
- WM_TX_LOCK(txq);
- wm_nq_transmit_locked(ifp, txq);
+ /* Try to get more packets going. */
+ if (pcq_peek(txq->txq_interq) != NULL)
+ wm_nq_transmit_locked(ifp, txq);
+ /*
+ * There are still some upper layer processing which call
+ * ifp->if_start(). e.g. ALTQ
+ */
+ if (wmq->wmq_id == 0) {
+ if (!IFQ_IS_EMPTY(&ifp->if_snd))
+ wm_nq_start_locked(ifp);
+ }
WM_TX_UNLOCK(txq);
}
- /*
- * There are still some upper layer processing which call
- * ifp->if_start(). e.g. ALTQ
- */
- if (txq->txq_id == 0) {
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- ifp->if_start(ifp);
- }
-
- return 1;
-}
-
-/*
- * wm_rxintr_msix:
- *
- * Interrupt service routine for RX interrupt for MSI-X.
- */
-static int
-wm_rxintr_msix(void *arg)
-{
- struct wm_rxqueue *rxq = arg;
- struct wm_softc *sc = rxq->rxq_sc;
DPRINTF(WM_DEBUG_RX,
("%s: RX: got Rx intr\n", device_xname(sc->sc_dev)));
- if (sc->sc_type == WM_T_82574)
- CSR_WRITE(sc, WMREG_IMC, ICR_RXQ(rxq->rxq_id));
- else if (sc->sc_type == WM_T_82575)
- CSR_WRITE(sc, WMREG_EIMC, EITR_RX_QUEUE(rxq->rxq_id));
- else
- CSR_WRITE(sc, WMREG_EIMC, 1 << rxq->rxq_intr_idx);
-
- WM_RX_LOCK(rxq);
-
- if (sc->sc_stopping)
- goto out;
-
- WM_EVCNT_INCR(&sc->sc_ev_rxintr);
- wm_rxeof(rxq);
-
-out:
- WM_RX_UNLOCK(rxq);
+ if (!sc->sc_stopping) {
+ WM_RX_LOCK(rxq);
+ WM_EVCNT_INCR(&sc->sc_ev_rxintr);
+ wm_rxeof(rxq);
+ WM_RX_UNLOCK(rxq);
+ }
if (sc->sc_type == WM_T_82574)
- CSR_WRITE(sc, WMREG_IMS, ICR_RXQ(rxq->rxq_id));
+ CSR_WRITE(sc, WMREG_IMS, ICR_TXQ(wmq->wmq_id) | ICR_RXQ(wmq->wmq_id));
else if (sc->sc_type == WM_T_82575)
- CSR_WRITE(sc, WMREG_EIMS, EITR_RX_QUEUE(rxq->rxq_id));
+ CSR_WRITE(sc, WMREG_EIMS, EITR_TX_QUEUE(wmq->wmq_id) | EITR_RX_QUEUE(wmq->wmq_id));
else
- CSR_WRITE(sc, WMREG_EIMS, 1 << rxq->rxq_intr_idx);
+ CSR_WRITE(sc, WMREG_EIMS, 1 << wmq->wmq_intr_idx);
return 1;
}