aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/msk
diff options
context:
space:
mode:
authorPyun YongHyeon <yongari@FreeBSD.org>2010-03-01 23:39:43 +0000
committerPyun YongHyeon <yongari@FreeBSD.org>2010-03-01 23:39:43 +0000
commitcf570c1f348776087b1554f4ced39a6e90be9bf3 (patch)
tree7b58d7878a8aa9605be6628a83174aa409d0933f /sys/dev/msk
parent42f3ea9fc2a52610d6c10b8ff52eff92937f885b (diff)
Notes
Diffstat (limited to 'sys/dev/msk')
-rw-r--r--sys/dev/msk/if_msk.c40
-rw-r--r--sys/dev/msk/if_mskreg.h3
2 files changed, 23 insertions, 20 deletions
diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c
index ce210378c6c5..f8d4f174983a 100644
--- a/sys/dev/msk/if_msk.c
+++ b/sys/dev/msk/if_msk.c
@@ -1659,6 +1659,14 @@ mskc_attach(device_t dev)
}
}
+ sc->msk_int_holdoff = MSK_INT_HOLDOFF_DEFAULT;
+ SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+ "int_holdoff", CTLFLAG_RW, &sc->msk_int_holdoff, 0,
+ "Maximum number of time to delay interrupts");
+ resource_int_value(device_get_name(dev), device_get_unit(dev),
+ "int_holdoff", &sc->msk_int_holdoff);
+
/* Soft reset. */
CSR_WRITE_2(sc, B0_CTST, CS_RST_SET);
CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR);
@@ -2801,8 +2809,6 @@ static void
msk_watchdog(struct msk_if_softc *sc_if)
{
struct ifnet *ifp;
- uint32_t ridx;
- int idx;
MSK_IF_LOCK_ASSERT(sc_if);
@@ -2819,24 +2825,6 @@ msk_watchdog(struct msk_if_softc *sc_if)
return;
}
- /*
- * Reclaim first as there is a possibility of losing Tx completion
- * interrupts.
- */
- ridx = sc_if->msk_port == MSK_PORT_A ? STAT_TXA1_RIDX : STAT_TXA2_RIDX;
- idx = CSR_READ_2(sc_if->msk_softc, ridx);
- if (sc_if->msk_cdata.msk_tx_cons != idx) {
- msk_txeof(sc_if, idx);
- if (sc_if->msk_cdata.msk_tx_cnt == 0) {
- if_printf(ifp, "watchdog timeout (missed Tx interrupts) "
- "-- recovering\n");
- if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
- taskqueue_enqueue(taskqueue_fast,
- &sc_if->msk_tx_task);
- return;
- }
- }
-
if_printf(ifp, "watchdog timeout\n");
ifp->if_oerrors++;
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
@@ -3166,6 +3154,7 @@ msk_tick(void *xsc_if)
mii_tick(mii);
if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0)
msk_miibus_statchg(sc_if->msk_if_dev);
+ msk_handle_events(sc_if->msk_softc);
msk_watchdog(sc_if);
callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if);
}
@@ -3904,6 +3893,17 @@ msk_init_locked(struct msk_if_softc *sc_if)
sc->msk_intrmask |= Y2_IS_PORT_B;
sc->msk_intrhwemask |= Y2_HWE_L2_MASK;
}
+ /* Configure IRQ moderation mask. */
+ CSR_WRITE_4(sc, B2_IRQM_MSK, sc->msk_intrmask);
+ if (sc->msk_int_holdoff > 0) {
+ /* Configure initial IRQ moderation timer value. */
+ CSR_WRITE_4(sc, B2_IRQM_INI,
+ MSK_USECS(sc, sc->msk_int_holdoff));
+ CSR_WRITE_4(sc, B2_IRQM_VAL,
+ MSK_USECS(sc, sc->msk_int_holdoff));
+ /* Start IRQ moderation. */
+ CSR_WRITE_1(sc, B2_IRQM_CTRL, TIM_START);
+ }
CSR_WRITE_4(sc, B0_HWE_IMSK, sc->msk_intrhwemask);
CSR_READ_4(sc, B0_HWE_IMSK);
CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h
index 9e2adc359ee2..c773742454fb 100644
--- a/sys/dev/msk/if_mskreg.h
+++ b/sys/dev/msk/if_mskreg.h
@@ -2406,6 +2406,8 @@ struct msk_ring_data {
#define MSK_PROC_MIN 30
#define MSK_PROC_MAX (MSK_RX_RING_CNT - 1)
+#define MSK_INT_HOLDOFF_DEFAULT 100
+
#define MSK_TX_TIMEOUT 5
#define MSK_PUT_WM 10
@@ -2496,6 +2498,7 @@ struct msk_softc {
bus_dmamap_t msk_stat_map;
struct msk_stat_desc *msk_stat_ring;
bus_addr_t msk_stat_ring_paddr;
+ int msk_int_holdoff;
int msk_process_limit;
int msk_stat_cons;
struct taskqueue *msk_tq;