diff options
| author | Gleb Smirnoff <glebius@FreeBSD.org> | 2005-10-01 18:56:19 +0000 |
|---|---|---|
| committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2005-10-01 18:56:19 +0000 |
| commit | 40929967748cc0fadf124a871e7dae69f57f5f63 (patch) | |
| tree | b78f9e953b7b58b2789d042cf37cc725045fdcf1 /sys/dev/nge | |
| parent | 5997cae9a49122373c3ede4af507b10d8e4d8f1c (diff) | |
Notes
Diffstat (limited to 'sys/dev/nge')
| -rw-r--r-- | sys/dev/nge/if_nge.c | 62 |
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); |
