PERFORCE change 103182 for review
Paolo Pisati
piso at FreeBSD.org
Fri Aug 4 17:45:39 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=103182
Change 103182 by piso at 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)
More information about the p4-projects
mailing list