Subject: Re: kern/32168
To: None <skrll@netbsd.org, gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: Nick Hudson <skrll@netbsd.org>
List: netbsd-bugs
Date: 12/03/2005 08:12:02
The following reply was made to PR kern/32168; it has been noted by GNATS.
From: Nick Hudson <skrll@netbsd.org>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/32168
Date: Sat, 3 Dec 2005 08:11:34 +0000
--Boundary-00=_3MVkD1tYz/KcDgc
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Here's a new patch that adds
- don't do an iwi_init when doing SIOCADDMULTI/SIOCDELMULTI
- marks the i/f IFF_RUNNING before kicking the net80211 state machine
Please test.
Thanks,
Nick
--Boundary-00=_3MVkD1tYz/KcDgc
Content-Type: text/x-diff;
charset="us-ascii";
name="iwi.32168.diffs"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="iwi.32168.diffs"
Index: if_iwi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/if_iwi.c,v
retrieving revision 1.42
diff -u -p -u -r1.42 if_iwi.c
--- if_iwi.c 29 Nov 2005 13:57:00 -0000 1.42
+++ if_iwi.c 3 Dec 2005 07:57:51 -0000
@@ -1893,9 +1893,12 @@ iwi_get_radio(struct iwi_softc *sc, int
static int
iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
+#define IS_RUNNING(ifp) \
+ ((ifp->if_flags & IFF_UP) && (ifp->if_flags & IFF_RUNNING))
+
struct iwi_softc *sc = ifp->if_softc;
struct ieee80211com *ic = &sc->sc_ic;
- struct ifreq *ifr;
+ struct ifreq *ifr = (struct ifreq *)data;
int s, error = 0;
s = splnet();
@@ -1911,13 +1914,22 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd,
}
break;
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ error = (cmd == SIOCADDMULTI) ?
+ ether_addmulti(ifr, &sc->sc_ec) :
+ ether_delmulti(ifr, &sc->sc_ec);
+ if (error == ENETRESET) {
+ /* setup multicast filter, etc */
+ error = 0;
+ }
+ break;
+
case SIOCGTABLE0:
- ifr = (struct ifreq *)data;
error = iwi_get_table0(sc, (uint32_t *)ifr->ifr_data);
break;
case SIOCGRADIO:
- ifr = (struct ifreq *)data;
error = iwi_get_radio(sc, (int *)ifr->ifr_data);
break;
@@ -1926,7 +1938,6 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd,
if ((error = suser(curproc->p_ucred, &curproc->p_acflag)) != 0)
break;
- ifr = (struct ifreq *)data;
error = iwi_cache_firmware(sc, ifr->ifr_data);
break;
@@ -1942,18 +1953,18 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd,
default:
error = ieee80211_ioctl(&sc->sc_ic, cmd, data);
- }
- if (error == ENETRESET) {
- if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) ==
- (IFF_UP | IFF_RUNNING) &&
- (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
- iwi_init(ifp);
- error = 0;
+ if (error == ENETRESET) {
+ if (IS_RUNNING(ifp) &&
+ (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
+ iwi_init(ifp);
+ error = 0;
+ }
}
splx(s);
return error;
+#undef IS_RUNNING
}
static void
@@ -2711,15 +2722,17 @@ iwi_init(struct ifnet *ifp)
goto fail;
}
+ ic->ic_state = IEEE80211_S_INIT;
+
+ ifp->if_flags &= ~IFF_OACTIVE;
+ ifp->if_flags |= IFF_RUNNING;
+
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
} else
ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
- ifp->if_flags &= ~IFF_OACTIVE;
- ifp->if_flags |= IFF_RUNNING;
-
return 0;
fail: ifp->if_flags &= ~IFF_UP;
--Boundary-00=_3MVkD1tYz/KcDgc--