Skip site navigation (1)Skip section navigation (2)
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>