1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-02-01 17:00:36 +00:00

Fix Lucent cards.

o Back out workaround for not resetting lucent cards more than once.  With
  these fixes, it appaers they are no longer necessary.
o Set wi_gone when the card goes awol: typically when we get 0xffff back from
  the card.  Also, don't interact with a card that's gone, so we fail in
  seconds rather than minutes.  Also reduce amount of time we wait to .5s
  in wi_cmd.
o clear wi_gone on ifconfig down to give some cards a chance after they wedge
  (this appears to unwedge one of my prism cards with old firmware).  ifconfig
  up will fail quickly enough if the card really is out to lunch.
o Add delay in wi_init of 100ms.
o wi_stop(ifp, 0->1) changes so that we clear sc_enabled so that we
  exit out of the interrupt routine by just acking the interrupt

Submitted by: iedowse
Approved by: re@ (scottl)

# after the freeze I'll fix some of the minor style issues that reviewers
# of this patch have told me about.
This commit is contained in:
Warner Losh 2003-12-02 04:59:59 +00:00
parent cba6cccff8
commit 51c3136508
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=123098

View File

@ -501,7 +501,7 @@ wi_detach(device_t dev)
WI_LOCK(sc);
/* check if device was removed */
sc->wi_gone = !bus_child_present(dev);
sc->wi_gone |= !bus_child_present(dev);
wi_stop(ifp, 0);
@ -584,9 +584,9 @@ wi_intr(void *arg)
WI_LOCK(sc);
if (sc->wi_gone || (ifp->if_flags & IFF_UP) == 0) {
if (sc->wi_gone || !sc->sc_enabled || (ifp->if_flags & IFF_UP) == 0) {
CSR_WRITE_2(sc, WI_INT_EN, 0);
CSR_WRITE_2(sc, WI_EVENT_ACK, ~0);
CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF);
WI_UNLOCK(sc);
return;
}
@ -637,7 +637,7 @@ wi_init(void *arg)
}
if ((wasenabled = sc->sc_enabled))
wi_stop(ifp, 0);
wi_stop(ifp, 1);
wi_reset(sc);
/* common 802.11 configuration */
@ -800,7 +800,7 @@ wi_init(void *arg)
out:
if (error) {
if_printf(ifp, "interface not running\n");
wi_stop(ifp, 0);
wi_stop(ifp, 1);
}
WI_UNLOCK(sc);
DPRINTF(("wi_init: return %d\n", error));
@ -816,6 +816,8 @@ wi_stop(struct ifnet *ifp, int disable)
WI_LOCK(sc);
DELAY(100000);
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
if (sc->sc_enabled && !sc->wi_gone) {
CSR_WRITE_2(sc, WI_INT_EN, 0);
@ -827,7 +829,8 @@ wi_stop(struct ifnet *ifp, int disable)
#endif
sc->sc_enabled = 0;
}
}
} else if (sc->wi_gone && disable) /* gone --> not enabled */
sc->sc_enabled = 0;
sc->sc_tx_timer = 0;
sc->sc_scan_timer = 0;
@ -991,7 +994,7 @@ wi_reset(struct wi_softc *sc)
int tries;
/* Symbol firmware cannot be initialized more than once */
if (sc->sc_firmware_type != WI_INTERSIL && sc->sc_reset)
if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_reset)
return (0);
if (sc->sc_firmware_type == WI_SYMBOL)
tries = 1;
@ -1113,8 +1116,9 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
} else {
if (ifp->if_flags & IFF_RUNNING) {
wi_stop(ifp, 0);
wi_stop(ifp, 1);
}
sc->wi_gone = 0;
}
sc->sc_if_flags = ifp->if_flags;
error = 0;
@ -1605,6 +1609,9 @@ wi_tx_intr(struct wi_softc *sc)
struct ifnet *ifp = &ic->ic_if;
int fid, cur;
if (sc->wi_gone)
return;
fid = CSR_READ_2(sc, WI_ALLOC_FID);
CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_ALLOC);
@ -2375,18 +2382,22 @@ wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
int i, s = 0;
static volatile int count = 0;
if (sc->wi_gone)
return (ENODEV);
if (count > 0)
panic("Hey partner, hold on there!");
count++;
/* wait for the busy bit to clear */
for (i = 500; i > 0; i--) { /* 5s */
for (i = 500; i > 0; i--) { /* 500ms */
if (!(CSR_READ_2(sc, WI_COMMAND) & WI_CMD_BUSY))
break;
DELAY(10*1000); /* 10 m sec */
DELAY(1*1000); /* 1ms */
}
if (i == 0) {
device_printf(sc->sc_dev, "wi_cmd: busy bit won't clear.\n" );
sc->wi_gone = 1;
count--;
return(ETIMEDOUT);
}
@ -2423,6 +2434,8 @@ wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2)
if (i == WI_TIMEOUT) {
device_printf(sc->sc_dev,
"timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s);
if (s == 0xffff)
sc->wi_gone = 1;
return(ETIMEDOUT);
}
return (0);
@ -2444,6 +2457,8 @@ wi_seek_bap(struct wi_softc *sc, int id, int off)
device_printf(sc->sc_dev, "timeout in wi_seek to %x/%x\n",
id, off);
sc->sc_bap_off = WI_OFF_ERR; /* invalidate */
if (status == 0xffff)
sc->wi_gone = 1;
return ETIMEDOUT;
}
DELAY(1);