aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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. */
};