Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 01 Mar 2003 09:39:10 -0700 (MST)
From:      "M. Warner Losh" <imp@bsdimp.com>
To:        mobile@freebsd.org
Subject:   wi patch
Message-ID:  <20030301.093910.15267989.imp@bsdimp.com>

next in thread | raw e-mail | index | archive | help
These patches make my lucent cards almost useful  They are in 1Mbps
mode, it seems, but at least they work with a fair amount of
reliability.  Don't try to set the media just yet.

They do two things.  One, they remove the "I'm racing the hardware"
junk in wi_intr.  Instead, it disables and reenables interrupts in the
ISR, like the old driver.  This is a mix of my own work and a slight
variation on Marcel's patch posted here.

Second, it limits the number of fids to 1 for lucent cards (it remains
3 for prism cards).  The old driver always used 1 fid for the cards.
I can only imagine that 3 fids was done to make prism go faster.
Well, it seems to massively destabilize the Lucent cards.

Lemme know how this works for you.  This takes my lucent card from
paperweight to useful (I can tolerate 1mbps since my dsl line is only
640kbps).  I've not used this driver with Prism 2, 2.5 or Symbol cards
(I have no prism 3 cards).  But all my lucent cards are rock solid
reliable at 1Mbps.

Warner

--- //depot/user/imp/freebsd-imp/sys/dev/wi/if_wi.c	2003/02/26 22:20:41
+++ //depot/user/imp/newcard/dev/wi/if_wi.c	2003/03/01 05:27:50
@@ -347,6 +347,7 @@
 	 */
 	switch (sc->sc_firmware_type) {
 	case WI_LUCENT:
+		sc->sc_ntxbuf = 1;
 		sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
 #ifdef WI_HERMES_AUTOINC_WAR
 		/* XXX: not confirmed, but never seen for recent firmware */
@@ -362,6 +363,7 @@
 		break;
 
 	case WI_INTERSIL:
+		sc->sc_ntxbuf = WI_NTXBUF;
 		sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR;
 		sc->sc_flags |= WI_FLAGS_HAS_ROAMING;
 		sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE;
@@ -380,6 +382,7 @@
 		break;
 
 	case WI_SYMBOL:
+		sc->sc_ntxbuf = 1;
 		sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY;
 		if (sc->sc_sta_firmware_ver >= 25000)
 			ic->ic_flags |= IEEE80211_F_HASIBSS;
@@ -555,10 +558,10 @@
 void
 wi_intr(void *arg)
 {
-	int i;
 	struct wi_softc *sc = arg;
 	struct ifnet *ifp = &sc->sc_ic.ic_if;
-	u_int16_t status, raw_status, last_status;
+	u_int16_t status;
+	int i;
 	WI_LOCK_DECL();
 
 	WI_LOCK(sc);
@@ -570,21 +573,14 @@
 		return;
 	}
 
-	/* maximum 10 loops per interrupt */
-	last_status = 0;
-	for (i = 0; i < 10; i++) {
-		/*
-		 * Only believe a status bit when we enter wi_intr, or when
-		 * the bit was "off" the last time through the loop. This is
-		 * my strategy to avoid racing the hardware/firmware if I
-		 * can re-read the event status register more quickly than
-		 * it is updated.
-		 */
-		raw_status = CSR_READ_2(sc, WI_EVENT_STAT);
-		status = raw_status & ~last_status;
+	/* Disable interrupts. */
+	CSR_WRITE_2(sc, WI_INT_EN, 0);
+
+	/* maximum 100 loops per interrupt */
+	for (i = 0; i < 100; i++) {
+		status = CSR_READ_2(sc, WI_EVENT_STAT);
 		if ((status & WI_INTRS) == 0)
 			break;
-		last_status = raw_status;
 
 		if (status & WI_EV_RX)
 			wi_rx_intr(sc);
@@ -604,6 +600,9 @@
 			wi_start(ifp);
 	}
 
+	/* Re-enable interrupts. */
+	CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS);
+
 	WI_UNLOCK(sc);
 
 	return;
@@ -728,7 +727,7 @@
 		sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame);
 		if (sc->sc_firmware_type == WI_SYMBOL)
 			sc->sc_buflen = 1585;	/* XXX */
-		for (i = 0; i < WI_NTXBUF; i++) {
+		for (i = 0; i < sc->sc_ntxbuf; i++) {
 			error = wi_alloc_fid(sc, sc->sc_buflen,
 			    &sc->sc_txd[i].d_fid);
 			if (error) {
@@ -949,7 +948,7 @@
 			sc->sc_tx_timer = 5;
 			ifp->if_timer = 1;
 		}
-		sc->sc_txnext = cur = (cur + 1) % WI_NTXBUF;
+		sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf;
 	}
 
 	WI_UNLOCK(sc);
@@ -1468,7 +1467,7 @@
 	}
 	sc->sc_tx_timer = 0;
 	sc->sc_txd[cur].d_len = 0;
-	sc->sc_txcur = cur = (cur + 1) % WI_NTXBUF;
+	sc->sc_txcur = cur = (cur + 1) % sc->sc_ntxbuf;
 	if (sc->sc_txd[cur].d_len == 0)
 		ifp->if_flags &= ~IFF_OACTIVE;
 	else {
--- //depot/user/imp/freebsd-imp/sys/dev/wi/if_wivar.h	2003/01/16 15:19:13
+++ //depot/user/imp/newcard/dev/wi/if_wivar.h	2003/02/28 23:16:30
@@ -119,6 +119,7 @@
 	char			sc_net_name[IEEE80211_NWID_LEN];
 
 	int			sc_buflen;		/* TX buffer size */
+	int			sc_ntxbuf;
 #define	WI_NTXBUF	3
 	struct {
 		int		d_fid;

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-mobile" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030301.093910.15267989.imp>