aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPyun YongHyeon <yongari@FreeBSD.org>2010-03-02 01:45:02 +0000
committerPyun YongHyeon <yongari@FreeBSD.org>2010-03-02 01:45:02 +0000
commitc876b43f42a1e768f8df09ba52ddf8a658810d9d (patch)
tree310062e26473d4a1f0ecb8a0cd3dea1c7203c576
parentd6c57df72b086660f9933c77957ebc40864382c4 (diff)
downloadsrc-c876b43f42a1e768f8df09ba52ddf8a658810d9d.tar.gz
src-c876b43f42a1e768f8df09ba52ddf8a658810d9d.zip
Remove taskqueue based interrupt handling. After r204541 msk(4)
does not generate excessive interrupts any more so we don't need to have two copies of interrupt handler. While I'm here remove two STAT_PUT_IDX register accesses in LE status event handler. After r204539 msk(4) always sync status LEs so there is no need to resort to reading STAT_PUT_IDX register to know the end of status LE processing. Just trust status LE's ownership bit.
Notes
Notes: svn path=/head/; revision=204545
-rw-r--r--sys/dev/msk/if_msk.c178
-rw-r--r--sys/dev/msk/if_mskreg.h3
2 files changed, 26 insertions, 155 deletions
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index f8d4f174983a..d087195dde33 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -113,7 +113,6 @@ __FBSDID("$FreeBSD$");
#include <sys/sockio.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
-#include <sys/taskqueue.h>
#include <net/bpf.h>
#include <net/ethernet.h>
@@ -257,9 +256,7 @@ static int msk_attach(device_t);
static int msk_detach(device_t);
static void msk_tick(void *);
-static void msk_legacy_intr(void *);
-static int msk_intr(void *);
-static void msk_int_task(void *, int);
+static void msk_intr(void *);
static void msk_intr_phy(struct msk_if_softc *);
static void msk_intr_gmac(struct msk_if_softc *);
static __inline void msk_rxput(struct msk_if_softc *);
@@ -273,8 +270,8 @@ static void msk_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
static void msk_jumbo_rxeof(struct msk_if_softc *, uint32_t, uint32_t, int);
static void msk_txeof(struct msk_if_softc *, int);
static int msk_encap(struct msk_if_softc *, struct mbuf **);
-static void msk_tx_task(void *, int);
static void msk_start(struct ifnet *);
+static void msk_start_locked(struct ifnet *);
static int msk_ioctl(struct ifnet *, u_long, caddr_t);
static void msk_set_prefetch(struct msk_softc *, int, bus_addr_t, uint32_t);
static void msk_set_rambuffer(struct msk_if_softc *);
@@ -1511,9 +1508,6 @@ msk_attach(device_t dev)
IFQ_SET_MAXLEN(&ifp->if_snd, MSK_TX_RING_CNT - 1);
ifp->if_snd.ifq_drv_maxlen = MSK_TX_RING_CNT - 1;
IFQ_SET_READY(&ifp->if_snd);
-
- TASK_INIT(&sc_if->msk_tx_task, 1, msk_tx_task, ifp);
-
/*
* Get station address for this interface. Note that
* dual port cards actually come with three station
@@ -1836,25 +1830,10 @@ mskc_attach(device_t dev)
}
/* Hook interrupt last to avoid having to lock softc. */
- if (legacy_intr)
- error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
- INTR_MPSAFE, NULL, msk_legacy_intr, sc,
- &sc->msk_intrhand);
- else {
- TASK_INIT(&sc->msk_int_task, 0, msk_int_task, sc);
- sc->msk_tq = taskqueue_create_fast("msk_taskq", M_WAITOK,
- taskqueue_thread_enqueue, &sc->msk_tq);
- taskqueue_start_threads(&sc->msk_tq, 1, PI_NET, "%s taskq",
- device_get_nameunit(sc->msk_dev));
- error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
- INTR_MPSAFE, msk_intr, NULL, sc, &sc->msk_intrhand);
- }
-
+ error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
+ INTR_MPSAFE, NULL, msk_intr, sc, &sc->msk_intrhand);
if (error != 0) {
device_printf(dev, "couldn't set up interrupt handler\n");
- if (legacy_intr == 0)
- taskqueue_free(sc->msk_tq);
- sc->msk_tq = NULL;
goto fail;
}
fail:
@@ -1891,7 +1870,6 @@ msk_detach(device_t dev)
/* Can't hold locks while calling detach. */
MSK_IF_UNLOCK(sc_if);
callout_drain(&sc_if->msk_tick_ch);
- taskqueue_drain(taskqueue_fast, &sc_if->msk_tx_task);
ether_ifdetach(ifp);
MSK_IF_LOCK(sc_if);
}
@@ -1956,11 +1934,6 @@ mskc_detach(device_t dev)
msk_status_dma_free(sc);
- if (legacy_intr == 0 && sc->msk_tq != NULL) {
- taskqueue_drain(sc->msk_tq, &sc->msk_int_task);
- taskqueue_free(sc->msk_tq);
- sc->msk_tq = NULL;
- }
if (sc->msk_intrhand) {
bus_teardown_intr(dev, sc->msk_irq[0], sc->msk_intrhand);
sc->msk_intrhand = NULL;
@@ -2740,30 +2713,29 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head)
}
static void
-msk_tx_task(void *arg, int pending)
+msk_start(struct ifnet *ifp)
{
- struct ifnet *ifp;
+ struct msk_if_softc *sc_if;
- ifp = arg;
- msk_start(ifp);
+ sc_if = ifp->if_softc;
+ MSK_IF_LOCK(sc_if);
+ msk_start_locked(ifp);
+ MSK_IF_UNLOCK(sc_if);
}
static void
-msk_start(struct ifnet *ifp)
+msk_start_locked(struct ifnet *ifp)
{
- struct msk_if_softc *sc_if;
- struct mbuf *m_head;
+ struct msk_if_softc *sc_if;
+ struct mbuf *m_head;
int enq;
sc_if = ifp->if_softc;
-
- MSK_IF_LOCK(sc_if);
+ MSK_IF_LOCK_ASSERT(sc_if);
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
- IFF_DRV_RUNNING || (sc_if->msk_flags & MSK_FLAG_LINK) == 0) {
- MSK_IF_UNLOCK(sc_if);
+ IFF_DRV_RUNNING || (sc_if->msk_flags & MSK_FLAG_LINK) == 0)
return;
- }
for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
sc_if->msk_cdata.msk_tx_cnt <
@@ -2801,8 +2773,6 @@ msk_start(struct ifnet *ifp)
/* Set a timeout in case the chip goes out to lunch. */
sc_if->msk_watchdog_timer = MSK_TX_TIMEOUT;
}
-
- MSK_IF_UNLOCK(sc_if);
}
static void
@@ -2830,7 +2800,7 @@ msk_watchdog(struct msk_if_softc *sc_if)
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
msk_init_locked(sc_if);
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- taskqueue_enqueue(taskqueue_fast, &sc_if->msk_tx_task);
+ msk_start_locked(ifp);
}
static int
@@ -3353,20 +3323,16 @@ msk_handle_events(struct msk_softc *sc)
int rxput[2];
struct msk_stat_desc *sd;
uint32_t control, status;
- int cons, idx, len, port, rxprog;
-
- idx = CSR_READ_2(sc, STAT_PUT_IDX);
- if (idx == sc->msk_stat_cons)
- return (0);
+ int cons, len, port, rxprog;
/* Sync status LEs. */
bus_dmamap_sync(sc->msk_stat_tag, sc->msk_stat_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
rxput[MSK_PORT_A] = rxput[MSK_PORT_B] = 0;
-
rxprog = 0;
- for (cons = sc->msk_stat_cons; cons != idx;) {
+ cons = sc->msk_stat_cons;
+ for (;;) {
sd = &sc->msk_stat_ring[cons];
control = le32toh(sd->msk_control);
if ((control & HW_OWNER) == 0)
@@ -3439,17 +3405,17 @@ msk_handle_events(struct msk_softc *sc)
if (rxput[MSK_PORT_B] > 0)
msk_rxput(sc->msk_if[MSK_PORT_B]);
- return (sc->msk_stat_cons != CSR_READ_2(sc, STAT_PUT_IDX));
+ return (rxprog > sc->msk_process_limit ? EAGAIN : 0);
}
-/* Legacy interrupt handler for shared interrupt. */
static void
-msk_legacy_intr(void *xsc)
+msk_intr(void *xsc)
{
struct msk_softc *sc;
struct msk_if_softc *sc_if0, *sc_if1;
struct ifnet *ifp0, *ifp1;
uint32_t status;
+ int domore;
sc = xsc;
MSK_LOCK(sc);
@@ -3494,9 +3460,8 @@ msk_legacy_intr(void *xsc)
if ((status & Y2_IS_HW_ERR) != 0)
msk_intr_hwerr(sc);
- while (msk_handle_events(sc) != 0)
- ;
- if ((status & Y2_IS_STAT_BMU) != 0)
+ domore = msk_handle_events(sc);
+ if ((status & Y2_IS_STAT_BMU) != 0 && domore == 0)
CSR_WRITE_4(sc, STAT_CTRL, SC_STAT_CLR_IRQ);
/* Reenable interrupts. */
@@ -3504,103 +3469,12 @@ msk_legacy_intr(void *xsc)
if (ifp0 != NULL && (ifp0->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
!IFQ_DRV_IS_EMPTY(&ifp0->if_snd))
- taskqueue_enqueue(taskqueue_fast, &sc_if0->msk_tx_task);
- if (ifp1 != NULL && (ifp1->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
- !IFQ_DRV_IS_EMPTY(&ifp1->if_snd))
- taskqueue_enqueue(taskqueue_fast, &sc_if1->msk_tx_task);
-
- MSK_UNLOCK(sc);
-}
-
-static int
-msk_intr(void *xsc)
-{
- struct msk_softc *sc;
- uint32_t status;
-
- sc = xsc;
- status = CSR_READ_4(sc, B0_Y2_SP_ISRC2);
- /* Reading B0_Y2_SP_ISRC2 masks further interrupts. */
- if (status == 0 || status == 0xffffffff) {
- CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
- return (FILTER_STRAY);
- }
-
- taskqueue_enqueue(sc->msk_tq, &sc->msk_int_task);
- return (FILTER_HANDLED);
-}
-
-static void
-msk_int_task(void *arg, int pending)
-{
- struct msk_softc *sc;
- struct msk_if_softc *sc_if0, *sc_if1;
- struct ifnet *ifp0, *ifp1;
- uint32_t status;
- int domore;
-
- sc = arg;
- MSK_LOCK(sc);
-
- /* Get interrupt source. */
- status = CSR_READ_4(sc, B0_ISRC);
- if (status == 0 || status == 0xffffffff ||
- (sc->msk_pflags & MSK_FLAG_SUSPEND) != 0 ||
- (status & sc->msk_intrmask) == 0)
- goto done;
-
- sc_if0 = sc->msk_if[MSK_PORT_A];
- sc_if1 = sc->msk_if[MSK_PORT_B];
- ifp0 = ifp1 = NULL;
- if (sc_if0 != NULL)
- ifp0 = sc_if0->msk_ifp;
- if (sc_if1 != NULL)
- ifp1 = sc_if1->msk_ifp;
-
- if ((status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL)
- msk_intr_phy(sc_if0);
- if ((status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL)
- msk_intr_phy(sc_if1);
- if ((status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL)
- msk_intr_gmac(sc_if0);
- if ((status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL)
- msk_intr_gmac(sc_if1);
- if ((status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) {
- device_printf(sc->msk_dev, "Rx descriptor error\n");
- sc->msk_intrmask &= ~(Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2);
- CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
- CSR_READ_4(sc, B0_IMSK);
- }
- if ((status & (Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2)) != 0) {
- device_printf(sc->msk_dev, "Tx descriptor error\n");
- sc->msk_intrmask &= ~(Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2);
- CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
- CSR_READ_4(sc, B0_IMSK);
- }
- if ((status & Y2_IS_HW_ERR) != 0)
- msk_intr_hwerr(sc);
-
- domore = msk_handle_events(sc);
- if ((status & Y2_IS_STAT_BMU) != 0)
- CSR_WRITE_4(sc, STAT_CTRL, SC_STAT_CLR_IRQ);
-
- if (ifp0 != NULL && (ifp0->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
- !IFQ_DRV_IS_EMPTY(&ifp0->if_snd))
- taskqueue_enqueue(taskqueue_fast, &sc_if0->msk_tx_task);
+ msk_start_locked(ifp0);
if (ifp1 != NULL && (ifp1->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
!IFQ_DRV_IS_EMPTY(&ifp1->if_snd))
- taskqueue_enqueue(taskqueue_fast, &sc_if1->msk_tx_task);
+ msk_start_locked(ifp1);
- if (domore > 0) {
- taskqueue_enqueue(sc->msk_tq, &sc->msk_int_task);
- MSK_UNLOCK(sc);
- return;
- }
-done:
MSK_UNLOCK(sc);
-
- /* Reenable interrupts. */
- CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
}
static void
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index c773742454fb..9c18ba719867 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -2501,8 +2501,6 @@ struct msk_softc {
int msk_int_holdoff;
int msk_process_limit;
int msk_stat_cons;
- struct taskqueue *msk_tq;
- struct task msk_int_task;
struct mtx msk_mtx;
};
@@ -2547,7 +2545,6 @@ struct msk_if_softc {
struct msk_ring_data msk_rdata;
struct msk_softc *msk_softc; /* parent controller */
struct msk_hw_stats msk_stats;
- struct task msk_tx_task;
int msk_if_flags;
uint16_t msk_vtag; /* VLAN tag id. */
};