summaryrefslogtreecommitdiff
path: root/sys/dev/nge
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2005-10-01 18:56:19 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2005-10-01 18:56:19 +0000
commit40929967748cc0fadf124a871e7dae69f57f5f63 (patch)
treeb78f9e953b7b58b2789d042cf37cc725045fdcf1 /sys/dev/nge
parent5997cae9a49122373c3ede4af507b10d8e4d8f1c (diff)
Notes
Diffstat (limited to 'sys/dev/nge')
-rw-r--r--sys/dev/nge/if_nge.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c
index a14d4ef080e4..e8a89ea43dd2 100644
--- a/sys/dev/nge/if_nge.c
+++ b/sys/dev/nge/if_nge.c
@@ -869,10 +869,10 @@ nge_attach(dev)
ifp->if_snd.ifq_maxlen = NGE_TX_LIST_CNT - 1;
ifp->if_hwassist = NGE_CSUM_FEATURES;
ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING;
+ ifp->if_capenable = ifp->if_capabilities;
#ifdef DEVICE_POLLING
ifp->if_capabilities |= IFCAP_POLLING;
#endif
- ifp->if_capenable = ifp->if_capabilities;
/*
* Do MII setup.
@@ -958,6 +958,10 @@ nge_detach(dev)
sc = device_get_softc(dev);
ifp = sc->nge_ifp;
+#ifdef DEVICE_POLLING
+ if (ifp->if_capenable & IFCAP_POLLING)
+ ether_poll_deregister(ifp);
+#endif
NGE_LOCK(sc);
nge_reset(sc);
nge_stop(sc);
@@ -1126,12 +1130,12 @@ nge_rxeof(sc)
u_int32_t extsts;
#ifdef DEVICE_POLLING
- if (ifp->if_flags & IFF_POLLING) {
+ if (ifp->if_capenable & IFCAP_POLLING) {
if (sc->rxcycles <= 0)
break;
sc->rxcycles--;
}
-#endif /* DEVICE_POLLING */
+#endif
cur_rx = &sc->nge_ldata->nge_rx_list[i];
rxstat = cur_rx->nge_rxstat;
@@ -1376,12 +1380,7 @@ nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
struct nge_softc *sc = ifp->if_softc;
NGE_LOCK(sc);
- if (!(ifp->if_capenable & IFCAP_POLLING)) {
- ether_poll_deregister(ifp);
- cmd = POLL_DEREGISTER;
- }
- if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
- CSR_WRITE_4(sc, NGE_IER, 1);
+ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
NGE_UNLOCK(sc);
return;
}
@@ -1433,18 +1432,11 @@ nge_intr(arg)
NGE_LOCK(sc);
#ifdef DEVICE_POLLING
- if (ifp->if_flags & IFF_POLLING) {
- NGE_UNLOCK(sc);
- return;
- }
- if ((ifp->if_capenable & IFCAP_POLLING) &&
- ether_poll_register(nge_poll, ifp)) { /* ok, disable interrupts */
- CSR_WRITE_4(sc, NGE_IER, 0);
+ if (ifp->if_capenable & IFCAP_POLLING) {
NGE_UNLOCK(sc);
- nge_poll(ifp, 0, 1);
return;
}
-#endif /* DEVICE_POLLING */
+#endif
/* Supress unwanted interrupts */
if (!(ifp->if_flags & IFF_UP)) {
@@ -1840,10 +1832,10 @@ nge_init_locked(sc)
* ... only enable interrupts if we are not polling, make sure
* they are off otherwise.
*/
- if (ifp->if_flags & IFF_POLLING)
+ if (ifp->if_capenable & IFCAP_POLLING)
CSR_WRITE_4(sc, NGE_IER, 0);
else
-#endif /* DEVICE_POLLING */
+#endif
CSR_WRITE_4(sc, NGE_IER, 1);
/* Enable receiver and transmitter. */
@@ -2047,8 +2039,31 @@ nge_ioctl(ifp, command, data)
}
break;
case SIOCSIFCAP:
- ifp->if_capenable &= ~IFCAP_POLLING;
- ifp->if_capenable |= ifr->ifr_reqcap & IFCAP_POLLING;
+#ifdef DEVICE_POLLING
+ if (ifr->ifr_reqcap & IFCAP_POLLING &&
+ !(ifp->if_capenable & IFCAP_POLLING)) {
+ error = ether_poll_register(nge_poll, ifp);
+ if (error)
+ return(error);
+ NGE_LOCK(sc);
+ /* Disable interrupts */
+ CSR_WRITE_4(sc, NGE_IER, 0);
+ ifp->if_capenable |= IFCAP_POLLING;
+ NGE_UNLOCK(sc);
+ return (error);
+
+ }
+ if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
+ ifp->if_capenable & IFCAP_POLLING) {
+ error = ether_poll_deregister(ifp);
+ /* Enable interrupts. */
+ NGE_LOCK(sc);
+ CSR_WRITE_4(sc, NGE_IER, 1);
+ ifp->if_capenable &= ~IFCAP_POLLING;
+ NGE_UNLOCK(sc);
+ return (error);
+ }
+#endif /* DEVICE_POLLING */
break;
default:
error = ether_ioctl(ifp, command, data);
@@ -2105,9 +2120,6 @@ nge_stop(sc)
}
callout_stop(&sc->nge_stat_ch);
-#ifdef DEVICE_POLLING
- ether_poll_deregister(ifp);
-#endif
CSR_WRITE_4(sc, NGE_IER, 0);
CSR_WRITE_4(sc, NGE_IMR, 0);
NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE);