It is currently impossible to use more than one iwm or iwx interface
in a system because I don't understand C.
Trying to bring up an uninitialized interface anyway results in a
kernel panic ("bogus channel pointer" from net80211), so prevent
the device from being used in case we never managed to initialize it.
ok?
diff 239e5514c8225a567e26e4070116f5d41f8e7f87 /usr/src
blob - eece4e0d25a8eecb50627233341ffe836c5a99cb
file + sys/dev/pci/if_iwm.c
--- sys/dev/pci/if_iwm.c
+++ sys/dev/pci/if_iwm.c
@@ -9971,6 +9971,9 @@ iwm_init(struct ifnet *ifp)
struct ieee80211com *ic = &sc->sc_ic;
int err, generation;
+ if (!sc->attached)
+ return ENXIO;
+
rw_assert_wrlock(&sc->ioctl_rwl);
generation = ++sc->sc_generation;
@@ -11189,7 +11192,6 @@ iwm_preinit(struct iwm_softc *sc)
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = IC2IFP(ic);
int err;
- static int attached;
err = iwm_prepare_card_hw(sc);
if (err) {
@@ -11197,7 +11199,7 @@ iwm_preinit(struct iwm_softc *sc)
return err;
}
- if (attached) {
+ if (sc->attached) {
/* Update MAC in case the upper layers changed it. */
IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
((struct arpcom *)ifp)->ac_enaddr);
@@ -11216,7 +11218,7 @@ iwm_preinit(struct iwm_softc *sc)
return err;
/* Print version info and MAC address on first successful fw load. */
- attached = 1;
+ sc->attached = 1;
printf("%s: hw rev 0x%x, fw ver %s, address %s\n",
DEVNAME(sc), sc->sc_hw_rev & IWM_CSR_HW_REV_TYPE_MSK,
sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
blob - 4de3e2bfefe4760baecbccee7739972f6d36fb92
file + sys/dev/pci/if_iwmvar.h
--- sys/dev/pci/if_iwmvar.h
+++ sys/dev/pci/if_iwmvar.h
@@ -473,6 +473,7 @@ struct iwm_softc {
struct ieee80211com sc_ic;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
int sc_newstate_pending;
+ int attached;
struct ieee80211_amrr sc_amrr;
struct timeout sc_calib_to;
blob - ff436be11d9ff000250bc7fdc4e6056fa80a327a
file + sys/dev/pci/if_iwx.c
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -8223,6 +8223,9 @@ iwx_init(struct ifnet *ifp)
struct ieee80211com *ic = &sc->sc_ic;
int err, generation;
+ if (!sc->attached)
+ return ENXIO;
+
rw_assert_wrlock(&sc->ioctl_rwl);
generation = ++sc->sc_generation;
@@ -9470,7 +9473,6 @@ iwx_preinit(struct iwx_softc *sc)
struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = IC2IFP(ic);
int err;
- static int attached;
err = iwx_prepare_card_hw(sc);
if (err) {
@@ -9478,7 +9480,7 @@ iwx_preinit(struct iwx_softc *sc)
return err;
}
- if (attached) {
+ if (sc->attached) {
/* Update MAC in case the upper layers changed it. */
IEEE80211_ADDR_COPY(sc->sc_ic.ic_myaddr,
((struct arpcom *)ifp)->ac_enaddr);
@@ -9497,7 +9499,7 @@ iwx_preinit(struct iwx_softc *sc)
return err;
/* Print version info and MAC address on first successful fw load. */
- attached = 1;
+ sc->attached = 1;
printf("%s: hw rev 0x%x, fw ver %s, address %s\n",
DEVNAME(sc), sc->sc_hw_rev & IWX_CSR_HW_REV_TYPE_MSK,
sc->sc_fwver, ether_sprintf(sc->sc_nvm.hw_addr));
blob - 39c4c34e97ef9d27c645a73123b48fce64ba4445
file + sys/dev/pci/if_iwxvar.h
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -456,6 +456,7 @@ struct iwx_softc {
struct ieee80211com sc_ic;
int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int);
int sc_newstate_pending;
+ int attached;
struct task init_task; /* NB: not reference-counted */
struct refcnt task_refs;