Index: if_lge.c =================================================================== RCS file: /home/hiten/ncvs/src/sys/dev/lge/if_lge.c,v retrieving revision 1.15 diff -u -r1.15 if_lge.c --- if_lge.c 14 Nov 2002 23:54:52 -0000 1.15 +++ if_lge.c 23 Dec 2002 21:19:47 -0000 @@ -979,6 +979,14 @@ ifp = &sc->arpcom.ac_if; +#ifdef DEVICE_POLLING + if (ifp->if_ipending && IFF_POLLING) { + if (sc->rxcycles <= 0) + break; + sc->rxcycles--; + } +#endif /* DEVICE_POLLING */ + /* Find out how many frames were processed. */ c = cnt; i = sc->lge_cdata.lge_rx_cons; @@ -1150,6 +1158,50 @@ return; } +#ifdef DEVICE_POLLING +static poll_handler_t lge_poll; + +static void +lge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) +{ + struct lge_softc *sc = ifp->if_softc; + + if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts. */ + CSR_WRITE_4(sc, LGE_IER, 1); + return; + } + + /* + * On the lge, reading the status register also clears it. + * So before returning to intr mode we must make sure that + * all possible pending sources of interrupts have been + * served. In practice, this means run to completion the + * *eof routines, and then call the interrupt routine. + */ + sc->rxcycles = count; + lge_rxeof(sc); + lge_txeof(sc); + + if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) { + u_int32_t status; + + /* Reading the ISR register clears all interrupts. */ + status = CSR_READ_4(sc, LGE_ISR); + + if (status & (LGE_ISR_RX_ERR|LGE_ISR_RX_OFLOW)) + lge_rxeof(sc); + + if (status & (LGE_ISR_RX_IDLE)) + LGE_SETBIT(sc, LGE_CSR, LGE_CSR_RX_ENABLE); + + if (status & LGE_ISR_SYSERR) { + lge_reset(sc); + lge_init(sc); + } + } +} +#endif /* DEVICE_POLLING */ + static void lge_intr(arg) void *arg; @@ -1161,6 +1213,16 @@ sc = arg; ifp = &sc->arpcom.ac_if; +#ifdef DEVICE_POLLING + if (ifp->if_ipending & IFF_POLLING) + return; + if (ether_poll_deregister(lge_poll, ifp)) { /* ok, disable interpts */ + CSR_WRITE_4(sc, LGE_IER, 0); + lge_poll(ifp, 0, 1); + return; + } +#endif /* DEVICE_POLLING */ + /* Supress unwanted interrupts */ if (!(ifp->if_flags & IFF_UP)) { lge_stop(sc); @@ -1427,6 +1489,16 @@ /* * Enable interrupts. */ +#ifdef DEVICE_POLLING + /* + * ... only enable interrupts if we are not polling, make sure + * they are off otherwise. + */ + if (ifp->if_ipending && IFF_POLLING) + CSR_WRITE_4(sc, LGE_IER, 0); + else +#endif /* DEVICE_POLLING */ + CSR_WRITE_4(sc, LGE_IMR, LGE_IMR_SETRST_CTL0| LGE_IMR_SETRST_CTL1|LGE_IMR_INTR_ENB|LGE_INTRS); @@ -1588,6 +1660,9 @@ ifp = &sc->arpcom.ac_if; ifp->if_timer = 0; untimeout(lge_tick, sc, sc->lge_stat_ch); +#ifdef DEVICE_POLLING + ether_poll_deregister(ifp); +#endif CSR_WRITE_4(sc, LGE_IMR, LGE_IMR_INTR_ENB); /* Disable receiver and transmitter. */ Index: if_lgereg.h =================================================================== RCS file: /home/hiten/ncvs/src/sys/dev/lge/if_lgereg.h,v retrieving revision 1.3 diff -u -r1.3 if_lgereg.h --- if_lgereg.h 14 Nov 2002 23:54:52 -0000 1.3 +++ if_lgereg.h 23 Dec 2002 20:57:53 -0000 @@ -539,6 +539,9 @@ struct callout_handle lge_stat_ch; SLIST_HEAD(__lge_jfreehead, lge_jpool_entry) lge_jfree_listhead; SLIST_HEAD(__lge_jinusehead, lge_jpool_entry) lge_jinuse_listhead; +#ifdef DEVICE_POLLING + int rxcycles; +#endif }; /*