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.c98
1 files changed, 47 insertions, 51 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index f44f4caa69ee..ad9bb9e10cbb 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -880,6 +880,10 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
880 880
881 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | 881 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
882 IEEE80211_TX_INTFL_OFFCHAN_TX_OK; 882 IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
883
884 if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
885 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
886
883 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 887 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
884 IEEE80211_STA_CONNECTION_POLL)) 888 IEEE80211_STA_CONNECTION_POLL))
885 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; 889 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
@@ -1356,7 +1360,7 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
1356 IEEE80211_STA_CONNECTION_POLL)) 1360 IEEE80211_STA_CONNECTION_POLL))
1357 return false; 1361 return false;
1358 1362
1359 if (!sdata->vif.bss_conf.dtim_period) 1363 if (!mgd->have_beacon)
1360 return false; 1364 return false;
1361 1365
1362 rcu_read_lock(); 1366 rcu_read_lock();
@@ -1767,7 +1771,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1767 1771
1768 ieee80211_led_assoc(local, 1); 1772 ieee80211_led_assoc(local, 1);
1769 1773
1770 if (sdata->u.mgd.assoc_data->have_beacon) { 1774 if (sdata->u.mgd.have_beacon) {
1771 /* 1775 /*
1772 * If the AP is buggy we may get here with no DTIM period 1776 * If the AP is buggy we may get here with no DTIM period
1773 * known, so assume it's 1 which is the only safe assumption 1777 * known, so assume it's 1 which is the only safe assumption
@@ -1775,7 +1779,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1775 * probably just won't work at all. 1779 * probably just won't work at all.
1776 */ 1780 */
1777 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; 1781 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1;
1778 bss_info_changed |= BSS_CHANGED_DTIM_PERIOD; 1782 bss_info_changed |= BSS_CHANGED_BEACON_INFO;
1779 } else { 1783 } else {
1780 bss_conf->dtim_period = 0; 1784 bss_conf->dtim_period = 0;
1781 } 1785 }
@@ -1899,6 +1903,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1899 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1903 del_timer_sync(&sdata->u.mgd.chswitch_timer);
1900 1904
1901 sdata->vif.bss_conf.dtim_period = 0; 1905 sdata->vif.bss_conf.dtim_period = 0;
1906 ifmgd->have_beacon = false;
1902 1907
1903 ifmgd->flags = 0; 1908 ifmgd->flags = 0;
1904 ieee80211_vif_release_channel(sdata); 1909 ieee80211_vif_release_channel(sdata);
@@ -2151,7 +2156,8 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
2151 IEEE80211_MAX_QUEUE_MAP, 2156 IEEE80211_MAX_QUEUE_MAP,
2152 IEEE80211_QUEUE_STOP_REASON_CSA); 2157 IEEE80211_QUEUE_STOP_REASON_CSA);
2153 2158
2154 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 2159 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
2160 IEEE80211_DEAUTH_FRAME_LEN);
2155 sdata_unlock(sdata); 2161 sdata_unlock(sdata);
2156} 2162}
2157 2163
@@ -2298,7 +2304,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2298 sdata_info(sdata, "%pM denied authentication (status %d)\n", 2304 sdata_info(sdata, "%pM denied authentication (status %d)\n",
2299 mgmt->sa, status_code); 2305 mgmt->sa, status_code);
2300 ieee80211_destroy_auth_data(sdata, false); 2306 ieee80211_destroy_auth_data(sdata, false);
2301 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); 2307 cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2302 return; 2308 return;
2303 } 2309 }
2304 2310
@@ -2333,7 +2339,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2333 * Report auth frame to user space for processing since another 2339 * Report auth frame to user space for processing since another
2334 * round of Authentication frames is still needed. 2340 * round of Authentication frames is still needed.
2335 */ 2341 */
2336 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); 2342 cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2337 return; 2343 return;
2338 } 2344 }
2339 2345
@@ -2350,7 +2356,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
2350 } 2356 }
2351 mutex_unlock(&sdata->local->sta_mtx); 2357 mutex_unlock(&sdata->local->sta_mtx);
2352 2358
2353 cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); 2359 cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2354 return; 2360 return;
2355 out_err: 2361 out_err:
2356 mutex_unlock(&sdata->local->sta_mtx); 2362 mutex_unlock(&sdata->local->sta_mtx);
@@ -2383,7 +2389,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2383 2389
2384 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2390 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2385 2391
2386 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, len); 2392 cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2387} 2393}
2388 2394
2389 2395
@@ -2409,7 +2415,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2409 2415
2410 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2416 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2411 2417
2412 cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, len); 2418 cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
2413} 2419}
2414 2420
2415static void ieee80211_get_rates(struct ieee80211_supported_band *sband, 2421static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
@@ -2707,7 +2713,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2707 /* oops -- internal error -- send timeout for now */ 2713 /* oops -- internal error -- send timeout for now */
2708 ieee80211_destroy_assoc_data(sdata, false); 2714 ieee80211_destroy_assoc_data(sdata, false);
2709 cfg80211_put_bss(sdata->local->hw.wiphy, bss); 2715 cfg80211_put_bss(sdata->local->hw.wiphy, bss);
2710 cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid); 2716 cfg80211_assoc_timeout(sdata->dev, mgmt->bssid);
2711 return; 2717 return;
2712 } 2718 }
2713 sdata_info(sdata, "associated\n"); 2719 sdata_info(sdata, "associated\n");
@@ -2720,7 +2726,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2720 ieee80211_destroy_assoc_data(sdata, true); 2726 ieee80211_destroy_assoc_data(sdata, true);
2721 } 2727 }
2722 2728
2723 cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len); 2729 cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len);
2724} 2730}
2725 2731
2726static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, 2732static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -2732,24 +2738,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2732 int freq; 2738 int freq;
2733 struct ieee80211_bss *bss; 2739 struct ieee80211_bss *bss;
2734 struct ieee80211_channel *channel; 2740 struct ieee80211_channel *channel;
2735 bool need_ps = false;
2736 2741
2737 sdata_assert_lock(sdata); 2742 sdata_assert_lock(sdata);
2738 2743
2739 if ((sdata->u.mgd.associated &&
2740 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) ||
2741 (sdata->u.mgd.assoc_data &&
2742 ether_addr_equal(mgmt->bssid,
2743 sdata->u.mgd.assoc_data->bss->bssid))) {
2744 /* not previously set so we may need to recalc */
2745 need_ps = sdata->u.mgd.associated && !sdata->u.mgd.dtim_period;
2746
2747 if (elems->tim && !elems->parse_error) {
2748 const struct ieee80211_tim_ie *tim_ie = elems->tim;
2749 sdata->u.mgd.dtim_period = tim_ie->dtim_period;
2750 }
2751 }
2752
2753 if (elems->ds_params) 2744 if (elems->ds_params)
2754 freq = ieee80211_channel_to_frequency(elems->ds_params[0], 2745 freq = ieee80211_channel_to_frequency(elems->ds_params[0],
2755 rx_status->band); 2746 rx_status->band);
@@ -2770,12 +2761,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2770 !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) 2761 !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid))
2771 return; 2762 return;
2772 2763
2773 if (need_ps) {
2774 mutex_lock(&local->iflist_mtx);
2775 ieee80211_recalc_ps(local, -1);
2776 mutex_unlock(&local->iflist_mtx);
2777 }
2778
2779 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, 2764 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
2780 elems, true); 2765 elems, true);
2781 2766
@@ -2889,7 +2874,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2889 len - baselen, false, &elems); 2874 len - baselen, false, &elems);
2890 2875
2891 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 2876 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
2892 ifmgd->assoc_data->have_beacon = true; 2877 if (elems.tim && !elems.parse_error) {
2878 const struct ieee80211_tim_ie *tim_ie = elems.tim;
2879 ifmgd->dtim_period = tim_ie->dtim_period;
2880 }
2881 ifmgd->have_beacon = true;
2893 ifmgd->assoc_data->need_beacon = false; 2882 ifmgd->assoc_data->need_beacon = false;
2894 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { 2883 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
2895 sdata->vif.bss_conf.sync_tsf = 2884 sdata->vif.bss_conf.sync_tsf =
@@ -3071,7 +3060,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3071 * If we haven't had a beacon before, tell the driver about the 3060 * If we haven't had a beacon before, tell the driver about the
3072 * DTIM period (and beacon timing if desired) now. 3061 * DTIM period (and beacon timing if desired) now.
3073 */ 3062 */
3074 if (!bss_conf->dtim_period) { 3063 if (!ifmgd->have_beacon) {
3075 /* a few bogus AP send dtim_period = 0 or no TIM IE */ 3064 /* a few bogus AP send dtim_period = 0 or no TIM IE */
3076 if (elems.tim) 3065 if (elems.tim)
3077 bss_conf->dtim_period = elems.tim->dtim_period ?: 1; 3066 bss_conf->dtim_period = elems.tim->dtim_period ?: 1;
@@ -3090,7 +3079,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3090 sdata->vif.bss_conf.sync_dtim_count = 0; 3079 sdata->vif.bss_conf.sync_dtim_count = 0;
3091 } 3080 }
3092 3081
3093 changed |= BSS_CHANGED_DTIM_PERIOD; 3082 changed |= BSS_CHANGED_BEACON_INFO;
3083 ifmgd->have_beacon = true;
3084
3085 mutex_lock(&local->iflist_mtx);
3086 ieee80211_recalc_ps(local, -1);
3087 mutex_unlock(&local->iflist_mtx);
3088
3094 ieee80211_recalc_ps_vif(sdata); 3089 ieee80211_recalc_ps_vif(sdata);
3095 } 3090 }
3096 3091
@@ -3113,8 +3108,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3113 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 3108 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3114 WLAN_REASON_DEAUTH_LEAVING, 3109 WLAN_REASON_DEAUTH_LEAVING,
3115 true, deauth_buf); 3110 true, deauth_buf);
3116 cfg80211_send_deauth(sdata->dev, deauth_buf, 3111 cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf,
3117 sizeof(deauth_buf)); 3112 sizeof(deauth_buf));
3118 return; 3113 return;
3119 } 3114 }
3120 3115
@@ -3232,7 +3227,8 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
3232 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, 3227 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
3233 tx, frame_buf); 3228 tx, frame_buf);
3234 3229
3235 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 3230 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
3231 IEEE80211_DEAUTH_FRAME_LEN);
3236} 3232}
3237 3233
3238static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) 3234static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
@@ -3423,15 +3419,14 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3423 3419
3424 ieee80211_destroy_auth_data(sdata, false); 3420 ieee80211_destroy_auth_data(sdata, false);
3425 3421
3426 cfg80211_send_auth_timeout(sdata->dev, bssid); 3422 cfg80211_auth_timeout(sdata->dev, bssid);
3427 } 3423 }
3428 } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) 3424 } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started)
3429 run_again(sdata, ifmgd->auth_data->timeout); 3425 run_again(sdata, ifmgd->auth_data->timeout);
3430 3426
3431 if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && 3427 if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started &&
3432 time_after(jiffies, ifmgd->assoc_data->timeout)) { 3428 time_after(jiffies, ifmgd->assoc_data->timeout)) {
3433 if ((ifmgd->assoc_data->need_beacon && 3429 if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
3434 !ifmgd->assoc_data->have_beacon) ||
3435 ieee80211_do_assoc(sdata)) { 3430 ieee80211_do_assoc(sdata)) {
3436 u8 bssid[ETH_ALEN]; 3431 u8 bssid[ETH_ALEN];
3437 3432
@@ -3439,7 +3434,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3439 3434
3440 ieee80211_destroy_assoc_data(sdata, false); 3435 ieee80211_destroy_assoc_data(sdata, false);
3441 3436
3442 cfg80211_send_assoc_timeout(sdata->dev, bssid); 3437 cfg80211_assoc_timeout(sdata->dev, bssid);
3443 } 3438 }
3444 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3439 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
3445 run_again(sdata, ifmgd->assoc_data->timeout); 3440 run_again(sdata, ifmgd->assoc_data->timeout);
@@ -3988,8 +3983,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3988 WLAN_REASON_UNSPECIFIED, 3983 WLAN_REASON_UNSPECIFIED,
3989 false, frame_buf); 3984 false, frame_buf);
3990 3985
3991 cfg80211_send_deauth(sdata->dev, frame_buf, 3986 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
3992 sizeof(frame_buf)); 3987 sizeof(frame_buf));
3993 } 3988 }
3994 3989
3995 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); 3990 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
@@ -4051,8 +4046,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4051 WLAN_REASON_UNSPECIFIED, 4046 WLAN_REASON_UNSPECIFIED,
4052 false, frame_buf); 4047 false, frame_buf);
4053 4048
4054 cfg80211_send_deauth(sdata->dev, frame_buf, 4049 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
4055 sizeof(frame_buf)); 4050 sizeof(frame_buf));
4056 } 4051 }
4057 4052
4058 if (ifmgd->auth_data && !ifmgd->auth_data->done) { 4053 if (ifmgd->auth_data && !ifmgd->auth_data->done) {
@@ -4199,6 +4194,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4199 4194
4200 ifmgd->assoc_data = assoc_data; 4195 ifmgd->assoc_data = assoc_data;
4201 ifmgd->dtim_period = 0; 4196 ifmgd->dtim_period = 0;
4197 ifmgd->have_beacon = false;
4202 4198
4203 err = ieee80211_prep_connection(sdata, req->bss, true); 4199 err = ieee80211_prep_connection(sdata, req->bss, true);
4204 if (err) 4200 if (err)
@@ -4230,7 +4226,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4230 ifmgd->dtim_period = tim->dtim_period; 4226 ifmgd->dtim_period = tim->dtim_period;
4231 dtim_count = tim->dtim_count; 4227 dtim_count = tim->dtim_count;
4232 } 4228 }
4233 assoc_data->have_beacon = true; 4229 ifmgd->have_beacon = true;
4234 assoc_data->timeout = jiffies; 4230 assoc_data->timeout = jiffies;
4235 assoc_data->timeout_started = true; 4231 assoc_data->timeout_started = true;
4236 4232
@@ -4305,8 +4301,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4305 4301
4306 out: 4302 out:
4307 if (report_frame) 4303 if (report_frame)
4308 cfg80211_send_deauth(sdata->dev, frame_buf, 4304 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
4309 IEEE80211_DEAUTH_FRAME_LEN); 4305 IEEE80211_DEAUTH_FRAME_LEN);
4310 4306
4311 return 0; 4307 return 0;
4312} 4308}
@@ -4336,8 +4332,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4336 req->reason_code, !req->local_state_change, 4332 req->reason_code, !req->local_state_change,
4337 frame_buf); 4333 frame_buf);
4338 4334
4339 cfg80211_send_disassoc(sdata->dev, frame_buf, 4335 cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
4340 IEEE80211_DEAUTH_FRAME_LEN); 4336 IEEE80211_DEAUTH_FRAME_LEN);
4341 4337
4342 return 0; 4338 return 0;
4343} 4339}