summaryrefslogtreecommitdiffstats
path: root/sys/net80211
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211_output.c26
-rw-r--r--sys/net80211/ieee80211_proto.c4
-rw-r--r--sys/net80211/ieee80211_proto.h2
3 files changed, 24 insertions, 8 deletions
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 5d958d1..f7388ba 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -2736,20 +2736,35 @@ ieee80211_alloc_cts(struct ieee80211com *ic,
static void
ieee80211_tx_mgt_timeout(void *arg)
{
- struct ieee80211_node *ni = arg;
- struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211vap *vap = arg;
+ IEEE80211_LOCK(vap->iv_ic);
if (vap->iv_state != IEEE80211_S_INIT &&
(vap->iv_ic->ic_flags & IEEE80211_F_SCAN) == 0) {
/*
* NB: it's safe to specify a timeout as the reason here;
* it'll only be used in the right state.
*/
- ieee80211_new_state(vap, IEEE80211_S_SCAN,
+ ieee80211_new_state_locked(vap, IEEE80211_S_SCAN,
IEEE80211_SCAN_FAIL_TIMEOUT);
}
+ IEEE80211_UNLOCK(vap->iv_ic);
}
+/*
+ * This is the callback set on net80211-sourced transmitted
+ * authentication request frames.
+ *
+ * This does a couple of things:
+ *
+ * + If the frame transmitted was a success, it schedules a future
+ * event which will transition the interface to scan.
+ * If a state transition _then_ occurs before that event occurs,
+ * said state transition will cancel this callout.
+ *
+ * + If the frame transmit was a failure, it immediately schedules
+ * the transition back to scan.
+ */
static void
ieee80211_tx_mgt_cb(struct ieee80211_node *ni, void *arg, int status)
{
@@ -2767,10 +2782,11 @@ ieee80211_tx_mgt_cb(struct ieee80211_node *ni, void *arg, int status)
*
* XXX what happens if !acked but response shows up before callback?
*/
- if (vap->iv_state == ostate)
+ if (vap->iv_state == ostate) {
callout_reset(&vap->iv_mgtsend,
status == 0 ? IEEE80211_TRANS_WAIT*hz : 0,
- ieee80211_tx_mgt_timeout, ni);
+ ieee80211_tx_mgt_timeout, vap);
+ }
}
static void
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index 605c771..ca91b4d 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -107,8 +107,6 @@ static void update_promisc(void *, int);
static void update_channel(void *, int);
static void update_chw(void *, int);
static void ieee80211_newstate_cb(void *, int);
-static int ieee80211_new_state_locked(struct ieee80211vap *,
- enum ieee80211_state, int);
static int
null_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
@@ -1834,7 +1832,7 @@ done:
* is usually a mistake and indicates lack of proper integration
* with the net80211 layer.
*/
-static int
+int
ieee80211_new_state_locked(struct ieee80211vap *vap,
enum ieee80211_state nstate, int arg)
{
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 5ec8459..8df5116 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -332,6 +332,8 @@ void ieee80211_dturbo_switch(struct ieee80211vap *, int newflags);
void ieee80211_swbmiss(void *arg);
void ieee80211_beacon_miss(struct ieee80211com *);
int ieee80211_new_state(struct ieee80211vap *, enum ieee80211_state, int);
+int ieee80211_new_state_locked(struct ieee80211vap *, enum ieee80211_state,
+ int);
void ieee80211_print_essid(const uint8_t *, int);
void ieee80211_dump_pkt(struct ieee80211com *,
const uint8_t *, int, int, int);
OpenPOWER on IntegriCloud