summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
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 /net/mac80211/mlme.c
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>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c85
1 files changed, 72 insertions, 13 deletions
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) {