Date: Fri, 4 Aug 2006 17:45:37 GMT From: Paolo Pisati <piso@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 103182 for review Message-ID: <200608041745.k74HjbL4019315@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=103182 Change 103182 by piso@piso_newluxor on 2006/08/04 17:44:37 Even for iwi, use the main ithread handler for the rx path, and spawn as many tasks as necessary for all the auxiliary operations. Affected files ... .. //depot/projects/soc2006/intr_filter/dev/iwi/if_iwi.c#4 edit .. //depot/projects/soc2006/intr_filter/dev/iwi/if_iwivar.h#3 edit Differences ... ==== //depot/projects/soc2006/intr_filter/dev/iwi/if_iwi.c#4 (text+ko) ==== @@ -141,9 +141,12 @@ static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int, struct iwi_frame *); static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *); -static void iwi_rx_intr(struct iwi_softc *); +static void iwi_rx_intr(void *); static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *); -static void iwi_intr(void *); +static void iwi_tx_intr1(void *c, int p __unused); +static void iwi_tx_intr2(void *c, int p __unused); +static void iwi_tx_intr3(void *c, int p __unused); +static void iwi_tx_intr4(void *c, int p __unused); static int iwi_filter(void *); static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t); static void iwi_write_ibssnode(struct iwi_softc *, const u_int8_t [], int); @@ -263,8 +266,6 @@ mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF); - mtx_init(&sc->sc_smtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_SPIN); sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx); @@ -288,6 +289,10 @@ TASK_INIT(&sc->sc_setwmetask, 0, iwi_wme_setparams, sc); TASK_INIT(&sc->sc_downtask, 0, iwi_down, sc); TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc); + TASK_INIT(&sc->sc_tx1_done, 0, iwi_tx_intr1, sc); + TASK_INIT(&sc->sc_tx2_done, 0, iwi_tx_intr2, sc); + TASK_INIT(&sc->sc_tx3_done, 0, iwi_tx_intr3, sc); + TASK_INIT(&sc->sc_tx4_done, 0, iwi_tx_intr4, sc); if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { device_printf(dev, "chip is in D%d power mode " @@ -468,7 +473,7 @@ * Hook our interrupt after all initialization is complete. */ error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE, - iwi_filter, iwi_intr, sc, &sc->sc_ih); + iwi_filter, iwi_rx_intr, sc, &sc->sc_ih); if (error != 0) { device_printf(dev, "could not set up interrupt\n"); goto fail; @@ -522,7 +527,6 @@ delete_unrhdr(sc->sc_unr); mtx_destroy(&sc->sc_mtx); - mtx_destroy(&sc->sc_smtx); return 0; } @@ -1563,12 +1567,15 @@ } static void -iwi_rx_intr(struct iwi_softc *sc) +iwi_rx_intr(void *arg) { + struct iwi_softc *sc = arg; struct iwi_rx_data *data; struct iwi_hdr *hdr; uint32_t hw; + IWI_LOCK_DECL; + IWI_LOCK(sc); hw = CSR_READ_4(sc, IWI_CSR_RX_RIDX); for (; sc->rxq.cur != hw;) { @@ -1603,6 +1610,8 @@ /* tell the firmware what we have processed */ hw = (hw == 0) ? IWI_RX_RING_COUNT - 1 : hw - 1; CSR_WRITE_4(sc, IWI_CSR_RX_WIDX, hw); + CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK); + IWI_UNLOCK(sc); } static void @@ -1612,7 +1621,9 @@ struct ifnet *ifp = ic->ic_ifp; struct iwi_tx_data *data; uint32_t hw; + IWI_LOCK_DECL; + IWI_LOCK(sc); hw = CSR_READ_4(sc, txq->csr_ridx); for (; txq->next != hw;) { @@ -1641,8 +1652,40 @@ iwi_led_event(sc, IWI_LED_TX); iwi_start(ifp); + IWI_UNLOCK(sc); +} + +static void +iwi_tx_intr1(void *arg, int p __unused) { + struct iwi_softc *sc = arg; + + iwi_tx_intr(sc, &sc->txq[0]); +} + +static void +iwi_tx_intr2(void *arg, int p __unused) { + struct iwi_softc *sc = arg; + + iwi_tx_intr(sc, &sc->txq[1]); +} + +static void +iwi_tx_intr3(void *arg, int p __unused) { + struct iwi_softc *sc = arg; + + iwi_tx_intr(sc, &sc->txq[2]); } +static void +iwi_tx_intr4(void *arg, int p __unused) { + struct iwi_softc *sc = arg; + IWI_LOCK_DECL; + + IWI_LOCK(sc); + iwi_tx_intr(sc, &sc->txq[3]); + IWI_UNLOCK(sc); +} + static int iwi_filter(void *arg) { @@ -1650,11 +1693,8 @@ uint32_t r; int ret = FILTER_HANDLED; - mtx_lock_spin(&sc->sc_smtx); - if ((r = CSR_READ_4(sc, IWI_CSR_INTR)) == 0 || r == 0xffffffff) { - mtx_unlock_spin(&sc->sc_smtx); + if ((r = CSR_READ_4(sc, IWI_CSR_INTR)) == 0 || r == 0xffffffff) return (FILTER_STRAY); - } /* acknowledge interrupts */ CSR_WRITE_4(sc, IWI_CSR_INTR, r); @@ -1662,43 +1702,18 @@ if (r & IWI_INTR_FW_INITED) { if (!(r & (IWI_INTR_FATAL_ERROR | IWI_INTR_PARITY_ERROR))) wakeup(sc); - r &= ~(IWI_INTR_FW_INITED | IWI_INTR_FATAL_ERROR | - IWI_INTR_PARITY_ERROR); } if (r & IWI_INTR_CMD_DONE) { sc->flags &= ~IWI_FLAG_BUSY; wakeup(sc); - r &= ~IWI_INTR_CMD_DONE; } if (r & IWI_INTR_PARITY_ERROR) { /* XXX rate-limit */ device_printf(sc->sc_dev, "parity error\n"); - r &= ~IWI_INTR_PARITY_ERROR; } - if (r) { - /* disable interrupts */ - CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0); - ret |= FILTER_SCHEDULE_THREAD; - } - sc->intr = r; - mtx_unlock_spin(&sc->sc_smtx); - return (ret); -} - -static void -iwi_intr(void *arg) -{ - struct iwi_softc *sc = arg; - uint32_t r; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - mtx_lock_spin(&sc->sc_smtx); - r = sc->intr; - if (r & IWI_INTR_FATAL_ERROR) { device_printf(sc->sc_dev, "firmware error\n"); taskqueue_enqueue(sc->sc_tq, &sc->sc_restarttask); @@ -1706,25 +1721,25 @@ if (r & IWI_INTR_RADIO_OFF) taskqueue_enqueue(sc->sc_tq, &sc->sc_radiofftask); - + if (r & IWI_INTR_TX1_DONE) - iwi_tx_intr(sc, &sc->txq[0]); + taskqueue_enqueue(sc->sc_tq, &sc->sc_tx1_done); if (r & IWI_INTR_TX2_DONE) - iwi_tx_intr(sc, &sc->txq[1]); + taskqueue_enqueue(sc->sc_tq, &sc->sc_tx2_done); if (r & IWI_INTR_TX3_DONE) - iwi_tx_intr(sc, &sc->txq[2]); + taskqueue_enqueue(sc->sc_tq, &sc->sc_tx3_done); if (r & IWI_INTR_TX4_DONE) - iwi_tx_intr(sc, &sc->txq[3]); - - if (r & IWI_INTR_RX_DONE) - iwi_rx_intr(sc); - - IWI_UNLOCK(sc); - CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK); - mtx_unlock_spin(&sc->sc_smtx); + taskqueue_enqueue(sc->sc_tq, &sc->sc_tx4_done); + + if (r & IWI_INTR_RX_DONE) { + /* disable interrupts */ + CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0); + ret |= FILTER_SCHEDULE_THREAD; + } + return (ret); } static int @@ -2130,10 +2145,8 @@ uint32_t tmp; int ntries; - mtx_lock_spin(&sc->sc_smtx); /* disable interrupts */ CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, 0); - mtx_unlock_spin(&sc->sc_smtx); CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_STOP_MASTER); for (ntries = 0; ntries < 5; ntries++) { @@ -2535,10 +2548,8 @@ /* we're done with command blocks processing */ MEM_WRITE_4(sc, 0x3000a4, 0x540c00); - mtx_lock_spin(&sc->sc_smtx); /* allow interrupts so we know when the firmware is ready */ CSR_WRITE_4(sc, IWI_CSR_INTR_MASK, IWI_INTR_MASK); - mtx_unlock_spin(&sc->sc_smtx); /* tell the adapter to initialize the firmware */ CSR_WRITE_4(sc, IWI_CSR_RST, 0); @@ -3239,6 +3250,7 @@ struct ifnet *ifp = ic->ic_ifp; if (sc->sc_softled) { + IWI_ASSERT_OWNED(sc); callout_stop(&sc->sc_ledtimer); sc->sc_blinking = 0; } @@ -3300,11 +3312,14 @@ iwi_radio_off(void *arg, int pending) { struct iwi_softc *sc = arg; + IWI_LOCK_DECL; + IWI_LOCK(sc); device_printf(sc->sc_dev, "radio turned off\n"); iwi_stop(sc); sc->sc_rfkill_timer = 2; sc->sc_ifp->if_timer = 1; + IWI_UNLOCK(sc); } static int ==== //depot/projects/soc2006/intr_filter/dev/iwi/if_iwivar.h#3 (text+ko) ==== @@ -123,7 +123,6 @@ device_t sc_dev; struct mtx sc_mtx; - struct mtx sc_smtx; uint8_t sc_mcast[IEEE80211_ADDR_LEN]; struct unrhdr *sc_unr; struct taskqueue *sc_tq; /* private task queue */ @@ -132,7 +131,6 @@ #endif uint32_t flags; - uint32_t intr; #define IWI_FLAG_FW_INITED (1 << 0) #define IWI_FLAG_SCANNING (1 << 1) #define IWI_FLAG_FW_LOADING (1 << 2) @@ -177,6 +175,10 @@ struct task sc_setwmetask; /* set wme params processing */ struct task sc_downtask; /* disassociate processing */ struct task sc_restarttask; /* restart adapter processing */ + struct task sc_tx1_done; + struct task sc_tx2_done; + struct task sc_tx3_done; + struct task sc_tx4_done; unsigned int sc_softled : 1, /* enable LED gpio status */ sc_ledstate: 1, /* LED on/off state */ @@ -226,3 +228,7 @@ if (!__waslocked) \ mtx_unlock(&(sc)->sc_mtx); \ } while (0) + +#define IWI_ASSERT_OWNED(sc) do { \ + mtx_assert(&(sc)->sc_mtx, MA_OWNED); \ +} while (0)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608041745.k74HjbL4019315>