aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-01-29 09:02:27 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-31 08:28:43 -0500
commit1672c0e31917f49d31d30d79067103432bc20cc7 (patch)
treecc5b6b0017129b5748cfa2bace537d43c991d66c
parent3ff9a827c683353b9826ef57366b0f313acc21b0 (diff)
mac80211: start auth/assoc timeout on frame status
When sending authentication/association frames they might take a bit of time to go out because we may have to synchronise with the AP, in particular in the case where it's really a P2P GO. In this case the 200ms fixed timeout could potentially be too short if the beacon interval is relatively large. For drivers that report TX status we can do better. Instead of starting the timeout directly, start it only when the frame status arrives. Since then the frame was out on the air, we can wait shorter (the typical response time is supposed to be 30ms, wait 100ms.) Also, if the frame failed to be transmitted try again right away instead of waiting. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h5
-rw-r--r--net/mac80211/ibss.c4
-rw-r--r--net/mac80211/ieee80211_i.h11
-rw-r--r--net/mac80211/mlme.c85
-rw-r--r--net/mac80211/scan.c3
-rw-r--r--net/mac80211/status.c12
-rw-r--r--net/mac80211/util.c12
7 files changed, 103 insertions, 29 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 398b6ca4a9c5..164fd4b6503c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -408,6 +408,9 @@ struct ieee80211_bss_conf {
408 * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted 408 * @IEEE80211_TX_INTFL_RETRANSMISSION: This frame is being retransmitted
409 * after TX status because the destination was asleep, it must not 409 * after TX status because the destination was asleep, it must not
410 * be modified again (no seqno assignment, crypto, etc.) 410 * be modified again (no seqno assignment, crypto, etc.)
411 * @IEEE80211_TX_INTFL_MLME_CONN_TX: This frame was transmitted by the MLME
412 * code for connection establishment, this indicates that its status
413 * should kick the MLME state machine.
411 * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211 414 * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211
412 * MLME command (internal to mac80211 to figure out whether to send TX 415 * MLME command (internal to mac80211 to figure out whether to send TX
413 * status to user space) 416 * status to user space)
@@ -459,7 +462,7 @@ enum mac80211_tx_control_flags {
459 IEEE80211_TX_CTL_NO_PS_BUFFER = BIT(17), 462 IEEE80211_TX_CTL_NO_PS_BUFFER = BIT(17),
460 IEEE80211_TX_CTL_MORE_FRAMES = BIT(18), 463 IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),
461 IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19), 464 IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),
462 /* hole at 20, use later */ 465 IEEE80211_TX_INTFL_MLME_CONN_TX = BIT(20),
463 IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21), 466 IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21),
464 IEEE80211_TX_CTL_LDPC = BIT(22), 467 IEEE80211_TX_CTL_LDPC = BIT(22),
465 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24), 468 IEEE80211_TX_CTL_STBC = BIT(23) | BIT(24),
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index b4b866f41919..a54c8248e0e0 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -302,7 +302,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
302 "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", 302 "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
303 sdata->vif.addr, addr, sdata->u.ibss.bssid); 303 sdata->vif.addr, addr, sdata->u.ibss.bssid);
304 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0, 304 ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0,
305 addr, sdata->u.ibss.bssid, NULL, 0, 0); 305 addr, sdata->u.ibss.bssid, NULL, 0, 0, 0);
306 } 306 }
307 return sta; 307 return sta;
308} 308}
@@ -422,7 +422,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
422 * has actually implemented this. 422 * has actually implemented this.
423 */ 423 */
424 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, 0, NULL, 0, 424 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, 0, NULL, 0,
425 mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0); 425 mgmt->sa, sdata->u.ibss.bssid, NULL, 0, 0, 0);
426} 426}
427 427
428static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 428static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index e4ee16839c6d..c9c66dec170a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -415,6 +415,10 @@ struct ieee80211_if_managed {
415 bool beacon_crc_valid; 415 bool beacon_crc_valid;
416 u32 beacon_crc; 416 u32 beacon_crc;
417 417
418 bool status_acked;
419 bool status_received;
420 __le16 status_fc;
421
418 enum { 422 enum {
419 IEEE80211_MFP_DISABLED, 423 IEEE80211_MFP_DISABLED,
420 IEEE80211_MFP_OPTIONAL, 424 IEEE80211_MFP_OPTIONAL,
@@ -1284,6 +1288,8 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1284void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata); 1288void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata);
1285void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata); 1289void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata);
1286void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata); 1290void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
1291void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
1292 __le16 fc, bool acked);
1287 1293
1288/* IBSS code */ 1294/* IBSS code */
1289void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 1295void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1544,7 +1550,8 @@ static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local,
1544void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1550void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1545 u16 transaction, u16 auth_alg, u16 status, 1551 u16 transaction, u16 auth_alg, u16 status,
1546 u8 *extra, size_t extra_len, const u8 *bssid, 1552 u8 *extra, size_t extra_len, const u8 *bssid,
1547 const u8 *da, const u8 *key, u8 key_len, u8 key_idx); 1553 const u8 *da, const u8 *key, u8 key_len, u8 key_idx,
1554 u32 tx_flags);
1548void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, 1555void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1549 const u8 *bssid, u16 stype, u16 reason, 1556 const u8 *bssid, u16 stype, u16 reason,
1550 bool send_frame, u8 *frame_buf); 1557 bool send_frame, u8 *frame_buf);
@@ -1561,7 +1568,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1561void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1568void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1562 const u8 *ssid, size_t ssid_len, 1569 const u8 *ssid, size_t ssid_len,
1563 const u8 *ie, size_t ie_len, 1570 const u8 *ie, size_t ie_len,
1564 u32 ratemask, bool directed, bool no_cck, 1571 u32 ratemask, bool directed, u32 tx_flags,
1565 struct ieee80211_channel *channel, bool scan); 1572 struct ieee80211_channel *channel, bool scan);
1566 1573
1567void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 1574void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index a5dba67bbe0b..4ff52d0aaf9c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -30,11 +30,13 @@
30#include "rate.h" 30#include "rate.h"
31#include "led.h" 31#include "led.h"
32 32
33#define IEEE80211_AUTH_TIMEOUT (HZ / 5) 33#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
34#define IEEE80211_AUTH_MAX_TRIES 3 34#define IEEE80211_AUTH_TIMEOUT_SHORT (HZ / 10)
35#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5) 35#define IEEE80211_AUTH_MAX_TRIES 3
36#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 36#define IEEE80211_AUTH_WAIT_ASSOC (HZ * 5)
37#define IEEE80211_ASSOC_MAX_TRIES 3 37#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
38#define IEEE80211_ASSOC_TIMEOUT_SHORT (HZ / 10)
39#define IEEE80211_ASSOC_MAX_TRIES 3
38 40
39static int max_nullfunc_tries = 2; 41static int max_nullfunc_tries = 2;
40module_param(max_nullfunc_tries, int, 0644); 42module_param(max_nullfunc_tries, int, 0644);
@@ -644,6 +646,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
644 drv_mgd_prepare_tx(local, sdata); 646 drv_mgd_prepare_tx(local, sdata);
645 647
646 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 648 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
649 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
650 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
651 IEEE80211_TX_INTFL_MLME_CONN_TX;
647 ieee80211_tx_skb(sdata, skb); 652 ieee80211_tx_skb(sdata, skb);
648} 653}
649 654
@@ -1707,7 +1712,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1707 ssid_len = ssid[1]; 1712 ssid_len = ssid[1];
1708 1713
1709 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, 1714 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL,
1710 0, (u32) -1, true, false, 1715 0, (u32) -1, true, 0,
1711 ifmgd->associated->channel, false); 1716 ifmgd->associated->channel, false);
1712 rcu_read_unlock(); 1717 rcu_read_unlock();
1713 } 1718 }
@@ -1937,9 +1942,11 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1937static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, 1942static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1938 struct ieee80211_mgmt *mgmt, size_t len) 1943 struct ieee80211_mgmt *mgmt, size_t len)
1939{ 1944{
1945 struct ieee80211_local *local = sdata->local;
1940 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; 1946 struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
1941 u8 *pos; 1947 u8 *pos;
1942 struct ieee802_11_elems elems; 1948 struct ieee802_11_elems elems;
1949 u32 tx_flags = 0;
1943 1950
1944 pos = mgmt->u.auth.variable; 1951 pos = mgmt->u.auth.variable;
1945 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); 1952 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
@@ -1947,11 +1954,14 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1947 return; 1954 return;
1948 auth_data->expected_transaction = 4; 1955 auth_data->expected_transaction = 4;
1949 drv_mgd_prepare_tx(sdata->local, sdata); 1956 drv_mgd_prepare_tx(sdata->local, sdata);
1957 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
1958 tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
1959 IEEE80211_TX_INTFL_MLME_CONN_TX;
1950 ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0, 1960 ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0,
1951 elems.challenge - 2, elems.challenge_len + 2, 1961 elems.challenge - 2, elems.challenge_len + 2,
1952 auth_data->bss->bssid, auth_data->bss->bssid, 1962 auth_data->bss->bssid, auth_data->bss->bssid,
1953 auth_data->key, auth_data->key_len, 1963 auth_data->key, auth_data->key_len,
1954 auth_data->key_idx); 1964 auth_data->key_idx, tx_flags);
1955} 1965}
1956 1966
1957static enum rx_mgmt_action __must_check 1967static enum rx_mgmt_action __must_check
@@ -2869,12 +2879,17 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2869 struct ieee80211_local *local = sdata->local; 2879 struct ieee80211_local *local = sdata->local;
2870 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2880 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2871 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data; 2881 struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
2882 u32 tx_flags = 0;
2872 2883
2873 lockdep_assert_held(&ifmgd->mtx); 2884 lockdep_assert_held(&ifmgd->mtx);
2874 2885
2875 if (WARN_ON_ONCE(!auth_data)) 2886 if (WARN_ON_ONCE(!auth_data))
2876 return -EINVAL; 2887 return -EINVAL;
2877 2888
2889 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
2890 tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
2891 IEEE80211_TX_INTFL_MLME_CONN_TX;
2892
2878 auth_data->tries++; 2893 auth_data->tries++;
2879 2894
2880 if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { 2895 if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
@@ -2911,7 +2926,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2911 ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, 2926 ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
2912 auth_data->data, auth_data->data_len, 2927 auth_data->data, auth_data->data_len,
2913 auth_data->bss->bssid, 2928 auth_data->bss->bssid,
2914 auth_data->bss->bssid, NULL, 0, 0); 2929 auth_data->bss->bssid, NULL, 0, 0,
2930 tx_flags);
2915 } else { 2931 } else {
2916 const u8 *ssidie; 2932 const u8 *ssidie;
2917 2933
@@ -2930,13 +2946,15 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2930 * will not answer to direct packet in unassociated state. 2946 * will not answer to direct packet in unassociated state.
2931 */ 2947 */
2932 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], 2948 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
2933 NULL, 0, (u32) -1, true, false, 2949 NULL, 0, (u32) -1, true, tx_flags,
2934 auth_data->bss->channel, false); 2950 auth_data->bss->channel, false);
2935 rcu_read_unlock(); 2951 rcu_read_unlock();
2936 } 2952 }
2937 2953
2938 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 2954 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
2939 run_again(ifmgd, auth_data->timeout); 2955 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
2956 run_again(ifmgd, auth_data->timeout);
2957 }
2940 2958
2941 return 0; 2959 return 0;
2942} 2960}
@@ -2967,12 +2985,26 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
2967 IEEE80211_ASSOC_MAX_TRIES); 2985 IEEE80211_ASSOC_MAX_TRIES);
2968 ieee80211_send_assoc(sdata); 2986 ieee80211_send_assoc(sdata);
2969 2987
2970 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; 2988 if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
2971 run_again(&sdata->u.mgd, assoc_data->timeout); 2989 assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
2990 run_again(&sdata->u.mgd, assoc_data->timeout);
2991 }
2972 2992
2973 return 0; 2993 return 0;
2974} 2994}
2975 2995
2996void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
2997 __le16 fc, bool acked)
2998{
2999 struct ieee80211_local *local = sdata->local;
3000
3001 sdata->u.mgd.status_fc = fc;
3002 sdata->u.mgd.status_acked = acked;
3003 sdata->u.mgd.status_received = true;
3004
3005 ieee80211_queue_work(&local->hw, &sdata->work);
3006}
3007
2976void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) 3008void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2977{ 3009{
2978 struct ieee80211_local *local = sdata->local; 3010 struct ieee80211_local *local = sdata->local;
@@ -2980,6 +3012,33 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
2980 3012
2981 mutex_lock(&ifmgd->mtx); 3013 mutex_lock(&ifmgd->mtx);
2982 3014
3015 if (ifmgd->status_received) {
3016 __le16 fc = ifmgd->status_fc;
3017 bool status_acked = ifmgd->status_acked;
3018
3019 ifmgd->status_received = false;
3020 if (ifmgd->auth_data &&
3021 (ieee80211_is_probe_req(fc) || ieee80211_is_auth(fc))) {
3022 if (status_acked) {
3023 ifmgd->auth_data->timeout =
3024 jiffies + IEEE80211_AUTH_TIMEOUT_SHORT;
3025 run_again(ifmgd, ifmgd->auth_data->timeout);
3026 } else {
3027 ifmgd->auth_data->timeout = jiffies - 1;
3028 }
3029 } else if (ifmgd->assoc_data &&
3030 (ieee80211_is_assoc_req(fc) ||
3031 ieee80211_is_reassoc_req(fc))) {
3032 if (status_acked) {
3033 ifmgd->assoc_data->timeout =
3034 jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT;
3035 run_again(ifmgd, ifmgd->assoc_data->timeout);
3036 } else {
3037 ifmgd->assoc_data->timeout = jiffies - 1;
3038 }
3039 }
3040 }
3041
2983 if (ifmgd->auth_data && 3042 if (ifmgd->auth_data &&
2984 time_after(jiffies, ifmgd->auth_data->timeout)) { 3043 time_after(jiffies, ifmgd->auth_data->timeout)) {
2985 if (ifmgd->auth_data->done) { 3044 if (ifmgd->auth_data->done) {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 061595ae513b..85d0e5ee55a2 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -389,7 +389,8 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
389 local->scan_req->ssids[i].ssid_len, 389 local->scan_req->ssids[i].ssid_len,
390 local->scan_req->ie, local->scan_req->ie_len, 390 local->scan_req->ie, local->scan_req->ie_len,
391 local->scan_req->rates[band], false, 391 local->scan_req->rates[band], false,
392 local->scan_req->no_cck, 392 local->scan_req->no_cck ?
393 IEEE80211_TX_CTL_NO_CCK_RATE : 0,
393 local->hw.conf.channel, true); 394 local->hw.conf.channel, true);
394 395
395 /* 396 /*
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index ab50285fcbab..d041de056b7f 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -335,7 +335,8 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
335 if (dropped) 335 if (dropped)
336 acked = false; 336 acked = false;
337 337
338 if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { 338 if (info->flags & (IEEE80211_TX_INTFL_NL80211_FRAME_TX |
339 IEEE80211_TX_INTFL_MLME_CONN_TX)) {
339 struct ieee80211_sub_if_data *sdata = NULL; 340 struct ieee80211_sub_if_data *sdata = NULL;
340 struct ieee80211_sub_if_data *iter_sdata; 341 struct ieee80211_sub_if_data *iter_sdata;
341 u64 cookie = (unsigned long)skb; 342 u64 cookie = (unsigned long)skb;
@@ -357,10 +358,13 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local,
357 sdata = rcu_dereference(local->p2p_sdata); 358 sdata = rcu_dereference(local->p2p_sdata);
358 } 359 }
359 360
360 if (!sdata) 361 if (!sdata) {
361 skb->dev = NULL; 362 skb->dev = NULL;
362 else if (ieee80211_is_nullfunc(hdr->frame_control) || 363 } else if (info->flags & IEEE80211_TX_INTFL_MLME_CONN_TX) {
363 ieee80211_is_qos_nullfunc(hdr->frame_control)) { 364 ieee80211_mgd_conn_tx_status(sdata, hdr->frame_control,
365 acked);
366 } else if (ieee80211_is_nullfunc(hdr->frame_control) ||
367 ieee80211_is_qos_nullfunc(hdr->frame_control)) {
364 cfg80211_probe_status(sdata->dev, hdr->addr1, 368 cfg80211_probe_status(sdata->dev, hdr->addr1,
365 cookie, acked, GFP_ATOMIC); 369 cookie, acked, GFP_ATOMIC);
366 } else { 370 } else {
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 1c74512697f0..139ad9b66c39 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1030,7 +1030,8 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
1030void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1030void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1031 u16 transaction, u16 auth_alg, u16 status, 1031 u16 transaction, u16 auth_alg, u16 status,
1032 u8 *extra, size_t extra_len, const u8 *da, 1032 u8 *extra, size_t extra_len, const u8 *da,
1033 const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx) 1033 const u8 *bssid, const u8 *key, u8 key_len, u8 key_idx,
1034 u32 tx_flags)
1034{ 1035{
1035 struct ieee80211_local *local = sdata->local; 1036 struct ieee80211_local *local = sdata->local;
1036 struct sk_buff *skb; 1037 struct sk_buff *skb;
@@ -1063,7 +1064,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1063 WARN_ON(err); 1064 WARN_ON(err);
1064 } 1065 }
1065 1066
1066 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 1067 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
1068 tx_flags;
1067 ieee80211_tx_skb(sdata, skb); 1069 ieee80211_tx_skb(sdata, skb);
1068} 1070}
1069 1071
@@ -1277,7 +1279,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1277void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1279void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1278 const u8 *ssid, size_t ssid_len, 1280 const u8 *ssid, size_t ssid_len,
1279 const u8 *ie, size_t ie_len, 1281 const u8 *ie, size_t ie_len,
1280 u32 ratemask, bool directed, bool no_cck, 1282 u32 ratemask, bool directed, u32 tx_flags,
1281 struct ieee80211_channel *channel, bool scan) 1283 struct ieee80211_channel *channel, bool scan)
1282{ 1284{
1283 struct sk_buff *skb; 1285 struct sk_buff *skb;
@@ -1286,9 +1288,7 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1286 ssid, ssid_len, 1288 ssid, ssid_len,
1287 ie, ie_len, directed); 1289 ie, ie_len, directed);
1288 if (skb) { 1290 if (skb) {
1289 if (no_cck) 1291 IEEE80211_SKB_CB(skb)->flags |= tx_flags;
1290 IEEE80211_SKB_CB(skb)->flags |=
1291 IEEE80211_TX_CTL_NO_CCK_RATE;
1292 if (scan) 1292 if (scan)
1293 ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band); 1293 ieee80211_tx_skb_tid_band(sdata, skb, 7, channel->band);
1294 else 1294 else