PERFORCE change 45412 for review
Sam Leffler
sam at FreeBSD.org
Thu Jan 15 13:56:26 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=45412
Change 45412 by sam at sam_ebb on 2004/01/15 13:55:51
Add an ic_reset callback method to notify drivers a hardware
reset (as opposed to full reset) is needed. Drivers may
implement this directly or return ENETRESET to cause a full
reset to be done after unwinding the stack.
Use this mechanism in the ath driver to reload the h/w
state w/o kicking the 802.11 state machine. Other drivers
just return ENETRESET for now.
Affected files ...
.. //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#16 edit
.. //depot/projects/netperf+sockets/sys/dev/awi/awi.c#4 edit
.. //depot/projects/netperf+sockets/sys/dev/wi/if_wi.c#6 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#8 edit
.. //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#5 edit
Differences ...
==== //depot/projects/netperf+sockets/sys/dev/ath/if_ath.c#16 (text+ko) ====
@@ -95,7 +95,7 @@
static void ath_init(void *);
static void ath_stop(struct ifnet *);
static void ath_start(struct ifnet *);
-static void ath_reset(struct ath_softc *, int);
+static int ath_reset(struct ieee80211com *);
static int ath_media_change(struct ifnet *);
static void ath_watchdog(struct ifnet *);
static int ath_ioctl(struct ifnet *, u_long, caddr_t);
@@ -328,6 +328,7 @@
ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
ic->ic_softc = sc;
+ ic->ic_reset = ath_reset;
ic->ic_newassoc = ath_newassoc;
/* XXX not right but it's not used anywhere important */
ic->ic_phytype = IEEE80211_T_OFDM;
@@ -508,7 +509,7 @@
struct ath_softc *sc = arg;
device_printf(sc->sc_dev, "hardware error; resetting\n");
- ath_reset(sc, 0);
+ ath_reset(&sc->sc_ic);
}
static void
@@ -517,7 +518,7 @@
struct ath_softc *sc = arg;
device_printf(sc->sc_dev, "rx FIFO overrun; resetting\n");
- ath_reset(sc, 0);
+ ath_reset(&sc->sc_ic);
}
static void
@@ -684,11 +685,11 @@
* operational state. Used to recover from errors rx overrun
* and to reset the hardware when rf gain settings must be reset.
*/
-static void
-ath_reset(struct ath_softc *sc, int full)
+static int
+ath_reset(struct ieee80211com *ic)
{
- struct ieee80211com *ic = &sc->sc_ic;
struct ifnet *ifp = &ic->ic_if;
+ struct ath_softc *sc = ifp->if_softc;
struct ath_hal *ah = sc->sc_ah;
struct ieee80211_channel *c;
HAL_STATUS status;
@@ -709,15 +710,19 @@
if (!ath_hal_reset(ah, ic->ic_opmode, &hchan, AH_TRUE, &status))
if_printf(ifp, "%s: unable to reset hardware; hal status %u\n",
__func__, status);
- /* NB: only needed when called from ath_ioctl */
- if (full && (ic->ic_flags & IEEE80211_F_WEPON))
- ath_initkeytable(sc);
+ /*
+ * NB: key state is preserved across resets but since we
+ * may be called after an ioctl call to update the
+ * hardware state we do this regardless.
+ */
+ ath_initkeytable(sc);
ath_hal_intrset(ah, sc->sc_imask);
if (ath_startrecv(sc) != 0) /* restart recv */
if_printf(ifp, "%s: unable to start recv logic\n", __func__);
ath_start(ifp); /* restart xmit */
if (ic->ic_state == IEEE80211_S_RUN)
ath_beacon_config(sc); /* restart beacons */
+ return 0;
}
static void
@@ -866,7 +871,7 @@
if (ath_debug & ATH_DEBUG_WATCHDOG)
ath_hal_dumpstate(sc->sc_ah);
#endif /* AR_DEBUG */
- ath_reset(sc, 0);
+ ath_reset(ic);
ifp->if_oerrors++;
sc->sc_stats.ast_watchdog++;
return;
@@ -956,20 +961,8 @@
default:
error = ieee80211_ioctl(ifp, cmd, data);
if (error == ENETRESET) {
- /*
- * If the interface is up and running then we
- * want the parameter changes to take effect
- * immediately, so reset hardware state to
- * reflect parameter change(s). We don't try to
- * intuit exactly what changed here; we just
- * bludgeon state which can have unfortunate
- * side effects.
- *
- * XXX doesn't recognize when a rescan is needed;
- * e.g. for ssid or channel change
- */
if (UP_RUNNING(ifp))
- ath_reset(sc, 1);
+ ath_init(sc);
error = 0;
}
break;
@@ -2547,7 +2540,7 @@
* to load new gain values.
*/
sc->sc_stats.ast_per_rfgain++;
- ath_reset(sc, 0);
+ ath_reset(ic);
}
if (!ath_hal_calibrate(ah, &hchan)) {
DPRINTF(ATH_DEBUG_ANY,
==== //depot/projects/netperf+sockets/sys/dev/awi/awi.c#4 (text+ko) ====
@@ -157,6 +157,7 @@
#ifdef __FreeBSD__
static void awi_init0(void *);
#endif
+static int awi_reset(struct ieee80211com *);
static int awi_init(struct ifnet *);
static void awi_stop(struct ifnet *, int);
static void awi_start(struct ifnet *);
@@ -313,6 +314,7 @@
sc->sc_mib_phy.aSuprt_Data_Rates + 2, nrate);
ic->ic_sup_rates[mode].rs_nrates = nrate;
IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->sc_mib_addr.aMAC_Address);
+ ic->ic_reset = awi_reset;
printf("%s: IEEE802.11 %s (firmware %s)\n", ifp->if_xname,
(ic->ic_phytype == IEEE80211_T_FH) ? "FH" : "DS", sc->sc_banner);
@@ -544,6 +546,12 @@
#endif
static int
+awi_reset(struct ieee80211com *ic)
+{
+ return ENETRESET; /* XXX force delayed call to awi_init */
+}
+
+static int
awi_init(struct ifnet *ifp)
{
struct awi_softc *sc = ifp->if_softc;
@@ -2155,7 +2163,7 @@
}
/* NB: EAPOL frames have their own encryption policy */
if (ic->ic_flags & IEEE80211_F_WEPON &&
- eh.ether_type != ETHERTYPE_EAPOL)
+ eh->ether_type != ETHERTYPE_EAPOL)
wh->i_fc[1] |= IEEE80211_FC1_WEP;
return m;
}
==== //depot/projects/netperf+sockets/sys/dev/wi/if_wi.c#6 (text+ko) ====
@@ -118,6 +118,7 @@
#define IFQ_POLL(ifq, m) IF_POLL((ifq), (m))
#define IFQ_DEQUEUE(ifq, m) IF_DEQUEUE((ifq), (m))
+static int wi_hwreset(struct ieee80211com *);
static void wi_start(struct ifnet *);
static int wi_reset(struct wi_softc *);
static void wi_watchdog(struct ifnet *);
@@ -313,6 +314,7 @@
ic->ic_opmode = IEEE80211_M_STA;
ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_AHDEMO;
ic->ic_state = IEEE80211_S_INIT;
+ ic->ic_reset = wi_hwreset;
/*
* Query the card for available channels and setup the
@@ -621,6 +623,12 @@
return;
}
+static int
+wi_hwreset(struct ieee80211com *arg)
+{
+ return ENETRESET; /* force delayed call to wi_init */
+}
+
void
wi_init(void *arg)
{
==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_ioctl.c#8 (text+ko) ====
@@ -564,7 +564,7 @@
return EINVAL;
setrate:
ic->ic_fixed_rate = i;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
case WI_RID_CUR_TX_RATE:
return EPERM;
@@ -622,12 +622,12 @@
return EINVAL;
if ((ic->ic_flags & IEEE80211_F_PMGTON) == 0) {
ic->ic_flags |= IEEE80211_F_PMGTON;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
}
} else {
if (ic->ic_flags & IEEE80211_F_PMGTON) {
ic->ic_flags &= ~IEEE80211_F_PMGTON;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
}
}
break;
@@ -636,7 +636,7 @@
return EINVAL;
ic->ic_lintval = le16toh(wreq.wi_val[0]);
if (ic->ic_flags & IEEE80211_F_PMGTON)
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
case WI_RID_CUR_BEACON_INT:
return EPERM;
@@ -678,6 +678,7 @@
if (i >= IEEE80211_WEP_NKID)
return EINVAL;
ic->ic_wep_txkey = i;
+ error = (*ic->ic_reset)(ic);
break;
case WI_RID_DEFLT_CRYPT_KEYS:
if (len != sizeof(struct wi_ltv_keys))
@@ -697,7 +698,7 @@
memcpy(ic->ic_nw_keys[i].wk_key,
keys->wi_keys[i].wi_keydat, len);
}
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
case WI_RID_MAX_DATALEN:
if (len != 2)
@@ -708,7 +709,7 @@
if (len != IEEE80211_MAX_LEN)
return EINVAL; /* TODO: fragment */
ic->ic_fragthreshold = len;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
case WI_RID_IFACE_STATS:
error = EPERM;
@@ -910,11 +911,16 @@
* passed in is not OFF.
*/
if (ireq->i_val == IEEE80211_WEP_OFF) {
- ic->ic_flags &= ~IEEE80211_F_WEPON;
+ if (ic->ic_flags & IEEE80211_F_WEPON) {
+ ic->ic_flags &= ~IEEE80211_F_WEPON;
+ error = ENETRESET;
+ }
} else {
- ic->ic_flags |= IEEE80211_F_WEPON;
+ if ((ic->ic_flags & IEEE80211_F_WEPON) == 0) {
+ ic->ic_flags |= IEEE80211_F_WEPON;
+ error = ENETRESET;
+ }
}
- error = ENETRESET;
break;
case IEEE80211_IOC_WEPKEY:
if ((ic->ic_caps & IEEE80211_C_WEP) == 0) {
@@ -937,7 +943,7 @@
memcpy(ic->ic_nw_keys[kid].wk_key, tmpkey,
sizeof(tmpkey));
ic->ic_nw_keys[kid].wk_len = ireq->i_len;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
case IEEE80211_IOC_WEPTXKEY:
kid = (u_int) ireq->i_val;
@@ -946,7 +952,7 @@
break;
}
ic->ic_wep_txkey = kid;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
case IEEE80211_IOC_AUTHMODE:
if (!(IEEE80211_AUTH_NONE <= ireq->i_val &&
@@ -999,7 +1005,7 @@
case IEEE80211_POWERSAVE_OFF:
if (ic->ic_flags & IEEE80211_F_PMGTON) {
ic->ic_flags &= ~IEEE80211_F_PMGTON;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
}
break;
case IEEE80211_POWERSAVE_ON:
@@ -1007,7 +1013,7 @@
error = EINVAL;
else if ((ic->ic_flags & IEEE80211_F_PMGTON) == 0) {
ic->ic_flags |= IEEE80211_F_PMGTON;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
}
break;
default:
@@ -1021,7 +1027,7 @@
break;
}
ic->ic_lintval = ireq->i_val;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
case IEEE80211_IOC_RTSTHRESHOLD:
if (!(IEEE80211_RTS_MIN < ireq->i_val &&
@@ -1030,7 +1036,7 @@
break;
}
ic->ic_rtsthreshold = ireq->i_val;
- error = ENETRESET;
+ error = (*ic->ic_reset)(ic);
break;
default:
error = EINVAL;
==== //depot/projects/netperf+sockets/sys/net80211/ieee80211_var.h#5 (text+ko) ====
@@ -150,6 +150,7 @@
struct ieee80211com {
struct arpcom ic_ac;
+ int (*ic_reset)(struct ieee80211com *);
void (*ic_recv_mgmt)(struct ieee80211com *,
struct mbuf *, struct ieee80211_node *,
int, int, u_int32_t);
More information about the p4-projects
mailing list