summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorru <ru@FreeBSD.org>2004-03-31 20:39:20 +0000
committerru <ru@FreeBSD.org>2004-03-31 20:39:20 +0000
commit86d52db7bc2c03ac25c2253320d6727db236fc1a (patch)
tree400d6288a5aced013f4cc991f47634c3978220fd /sys
parentd83ab3689dda455f8bc801062a8c77b1db6b4601 (diff)
downloadFreeBSD-src-86d52db7bc2c03ac25c2253320d6727db236fc1a.zip
FreeBSD-src-86d52db7bc2c03ac25c2253320d6727db236fc1a.tar.gz
Added polling(4) support for ste(4).
MFC after: 5 days
Diffstat (limited to 'sys')
-rw-r--r--sys/pci/if_ste.c80
-rw-r--r--sys/pci/if_stereg.h3
2 files changed, 80 insertions, 3 deletions
diff --git a/sys/pci/if_ste.c b/sys/pci/if_ste.c
index 8982f4e..9fe4613 100644
--- a/sys/pci/if_ste.c
+++ b/sys/pci/if_ste.c
@@ -622,6 +622,52 @@ ste_setmulti(sc)
return;
}
+#ifdef DEVICE_POLLING
+static poll_handler_t ste_poll;
+
+static void
+ste_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
+{
+ struct ste_softc *sc = ifp->if_softc;
+
+ STE_LOCK(sc);
+ if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
+ CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
+ goto done;
+ }
+
+ sc->rxcycles = count;
+ ste_rxeof(sc);
+ ste_txeof(sc);
+ if (ifp->if_snd.ifq_head != NULL)
+ ste_start(ifp);
+
+ if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
+ u_int16_t status;
+
+ status = CSR_READ_2(sc, STE_ISR_ACK);
+
+ if (status & STE_ISR_TX_DONE)
+ ste_txeoc(sc);
+
+ if (status & STE_ISR_STATS_OFLOW) {
+ untimeout(ste_stats_update, sc, sc->ste_stat_ch);
+ ste_stats_update(sc);
+ }
+
+ if (status & STE_ISR_LINKEVENT)
+ mii_pollstat(device_get_softc(sc->ste_miibus));
+
+ if (status & STE_ISR_HOSTERR) {
+ ste_reset(sc);
+ ste_init(sc);
+ }
+ }
+done:
+ STE_UNLOCK(sc);
+}
+#endif /* DEVICE_POLLING */
+
static void
ste_intr(xsc)
void *xsc;
@@ -634,6 +680,16 @@ ste_intr(xsc)
STE_LOCK(sc);
ifp = &sc->arpcom.ac_if;
+#ifdef DEVICE_POLLING
+ if (ifp->if_flags & IFF_POLLING)
+ goto done;
+ if (ether_poll_register(ste_poll, ifp)) { /* ok, disable interrupts */
+ CSR_WRITE_2(sc, STE_IMR, 0);
+ ste_poll(ifp, 0, 1);
+ goto done;
+ }
+#endif /* DEVICE_POLLING */
+
/* See if this is really our interrupt. */
if (!(CSR_READ_2(sc, STE_ISR) & STE_ISR_INTLATCH)) {
STE_UNLOCK(sc);
@@ -676,6 +732,9 @@ ste_intr(xsc)
if (ifp->if_snd.ifq_head != NULL)
ste_start(ifp);
+#ifdef DEVICE_POLLING
+done:
+#endif /* DEVICE_POLLING */
STE_UNLOCK(sc);
return;
@@ -701,6 +760,13 @@ ste_rxeof(sc)
while((rxstat = sc->ste_cdata.ste_rx_head->ste_ptr->ste_status)
& STE_RXSTAT_DMADONE) {
+#ifdef DEVICE_POLLING
+ if (ifp->if_flags & IFF_POLLING) {
+ if (sc->rxcycles <= 0)
+ break;
+ sc->rxcycles--;
+ }
+#endif /* DEVICE_POLLING */
if ((STE_RX_LIST_CNT - count) < 3) {
break;
}
@@ -1305,8 +1371,14 @@ ste_init(xsc)
/* Enable stats counters. */
STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_STATS_ENABLE);
- /* Enable interrupts. */
CSR_WRITE_2(sc, STE_ISR, 0xFFFF);
+#ifdef DEVICE_POLLING
+ /* Disable interrupts if we are polling. */
+ if (ifp->if_flags & IFF_POLLING)
+ CSR_WRITE_2(sc, STE_IMR, 0);
+ else
+#endif /* DEVICE_POLLING */
+ /* Enable interrupts. */
CSR_WRITE_2(sc, STE_IMR, STE_INTRS);
/* Accept VLAN length packets */
@@ -1334,6 +1406,10 @@ ste_stop(sc)
ifp = &sc->arpcom.ac_if;
untimeout(ste_stats_update, sc, sc->ste_stat_ch);
+ ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
+#ifdef DEVICE_POLLING
+ ether_poll_deregister(ifp);
+#endif /* DEVICE_POLLING */
CSR_WRITE_2(sc, STE_IMR, 0);
STE_SETBIT2(sc, STE_MACCTL1, STE_MACCTL1_TX_DISABLE);
@@ -1365,8 +1441,6 @@ ste_stop(sc)
}
bzero(sc->ste_ldata, sizeof(struct ste_list_data));
-
- ifp->if_flags &= ~(IFF_RUNNING|IFF_OACTIVE);
STE_UNLOCK(sc);
return;
diff --git a/sys/pci/if_stereg.h b/sys/pci/if_stereg.h
index 99295ac..0de4f78d 100644
--- a/sys/pci/if_stereg.h
+++ b/sys/pci/if_stereg.h
@@ -526,6 +526,9 @@ struct ste_softc {
struct callout_handle ste_stat_ch;
struct mtx ste_mtx;
u_int8_t ste_one_phy;
+#ifdef DEVICE_POLLING
+ int rxcycles;
+#endif
};
#define STE_LOCK(_sc) mtx_lock(&(_sc)->ste_mtx)
OpenPOWER on IntegriCloud