aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
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) {