aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-06-12 15:39:05 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-06-12 15:39:05 -0400
commit812fd645968118c35a3f4d0d18dd3f4d07221df0 (patch)
treeb68ee223f22a811e9743b193872052cd264fe2d0 /net
parentcb180840a0c6bff7c0787373c23cefdf20417a27 (diff)
parent940d0ac9dbe3fb9d4806e96f006286c2e476deed (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Conflicts: drivers/net/wireless/iwlwifi/mvm/mac80211.c
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c20
-rw-r--r--net/mac80211/ieee80211_i.h3
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh.c38
-rw-r--r--net/mac80211/mesh.h5
-rw-r--r--net/mac80211/mesh_plink.c7
-rw-r--r--net/mac80211/mlme.c98
-rw-r--r--net/mac80211/rx.c26
-rw-r--r--net/mac80211/sta_info.c4
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/tx.c6
-rw-r--r--net/mac80211/util.c5
-rw-r--r--net/wireless/core.c47
-rw-r--r--net/wireless/core.h30
-rw-r--r--net/wireless/ibss.c6
-rw-r--r--net/wireless/mesh.c12
-rw-r--r--net/wireless/mlme.c241
-rw-r--r--net/wireless/nl80211.c192
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/sme.c542
-rw-r--r--net/wireless/trace.h46
-rw-r--r--net/wireless/wext-sme.c8
22 files changed, 646 insertions, 698 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 30622101d3b5..64cf294c2b96 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1759,6 +1759,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1759 /* mcast rate setting in Mesh Node */ 1759 /* mcast rate setting in Mesh Node */
1760 memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, 1760 memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate,
1761 sizeof(setup->mcast_rate)); 1761 sizeof(setup->mcast_rate));
1762 sdata->vif.bss_conf.basic_rates = setup->basic_rates;
1762 1763
1763 sdata->vif.bss_conf.beacon_int = setup->beacon_interval; 1764 sdata->vif.bss_conf.beacon_int = setup->beacon_interval;
1764 sdata->vif.bss_conf.dtim_period = setup->dtim_period; 1765 sdata->vif.bss_conf.dtim_period = setup->dtim_period;
@@ -1871,6 +1872,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy,
1871 if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask)) 1872 if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask))
1872 conf->dot11MeshAwakeWindowDuration = 1873 conf->dot11MeshAwakeWindowDuration =
1873 nconf->dot11MeshAwakeWindowDuration; 1874 nconf->dot11MeshAwakeWindowDuration;
1875 if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask))
1876 conf->plink_timeout = nconf->plink_timeout;
1874 ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); 1877 ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON);
1875 return 0; 1878 return 0;
1876} 1879}
@@ -2838,6 +2841,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2838 return -EOPNOTSUPP; 2841 return -EOPNOTSUPP;
2839 } 2842 }
2840 2843
2844 /* configurations requiring offchan cannot work if no channel has been
2845 * specified
2846 */
2847 if (need_offchan && !chan)
2848 return -EINVAL;
2849
2841 mutex_lock(&local->mtx); 2850 mutex_lock(&local->mtx);
2842 2851
2843 /* Check if the operating channel is the requested channel */ 2852 /* Check if the operating channel is the requested channel */
@@ -2847,10 +2856,15 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
2847 rcu_read_lock(); 2856 rcu_read_lock();
2848 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2857 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
2849 2858
2850 if (chanctx_conf) 2859 if (chanctx_conf) {
2851 need_offchan = chan != chanctx_conf->def.chan; 2860 need_offchan = chan && (chan != chanctx_conf->def.chan);
2852 else 2861 } else if (!chan) {
2862 ret = -EINVAL;
2863 rcu_read_unlock();
2864 goto out_unlock;
2865 } else {
2853 need_offchan = true; 2866 need_offchan = true;
2867 }
2854 rcu_read_unlock(); 2868 rcu_read_unlock();
2855 } 2869 }
2856 2870
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 9eed6f1d1614..7a6f1a0207ec 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -366,7 +366,7 @@ struct ieee80211_mgd_assoc_data {
366 u8 ssid_len; 366 u8 ssid_len;
367 u8 supp_rates_len; 367 u8 supp_rates_len;
368 bool wmm, uapsd; 368 bool wmm, uapsd;
369 bool have_beacon, need_beacon; 369 bool need_beacon;
370 bool synced; 370 bool synced;
371 bool timeout_started; 371 bool timeout_started;
372 372
@@ -404,6 +404,7 @@ struct ieee80211_if_managed {
404 404
405 bool powersave; /* powersave requested for this iface */ 405 bool powersave; /* powersave requested for this iface */
406 bool broken_ap; /* AP is broken -- turn off powersave */ 406 bool broken_ap; /* AP is broken -- turn off powersave */
407 bool have_beacon;
407 u8 dtim_period; 408 u8 dtim_period;
408 enum ieee80211_smps_mode req_smps, /* requested smps mode */ 409 enum ieee80211_smps_mode req_smps, /* requested smps mode */
409 driver_smps_mode; /* smps mode request */ 410 driver_smps_mode; /* smps mode request */
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 1998f1475267..626c83c042d7 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -686,8 +686,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
686 return -EINVAL; 686 return -EINVAL;
687 687
688#ifdef CONFIG_PM 688#ifdef CONFIG_PM
689 if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) && 689 if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume))
690 (!local->ops->suspend || !local->ops->resume))
691 return -EINVAL; 690 return -EINVAL;
692#endif 691#endif
693 692
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index b3d1fdd46368..6c33af482df4 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -274,8 +274,7 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata,
274 *pos++ = ifmsh->mesh_auth_id; 274 *pos++ = ifmsh->mesh_auth_id;
275 /* Mesh Formation Info - number of neighbors */ 275 /* Mesh Formation Info - number of neighbors */
276 neighbors = atomic_read(&ifmsh->estab_plinks); 276 neighbors = atomic_read(&ifmsh->estab_plinks);
277 /* Number of neighbor mesh STAs or 15 whichever is smaller */ 277 neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS);
278 neighbors = (neighbors > 15) ? 15 : neighbors;
279 *pos++ = neighbors << 1; 278 *pos++ = neighbors << 1;
280 /* Mesh capability */ 279 /* Mesh capability */
281 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING; 280 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING;
@@ -576,13 +575,11 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
576 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 575 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
577 u32 changed; 576 u32 changed;
578 577
579 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 578 ieee80211_sta_expire(sdata, ifmsh->mshcfg.plink_timeout * HZ);
580 mesh_path_expire(sdata); 579 mesh_path_expire(sdata);
581 580
582 changed = mesh_accept_plinks_update(sdata); 581 changed = mesh_accept_plinks_update(sdata);
583 sdata_lock(sdata);
584 ieee80211_mbss_info_change_notify(sdata, changed); 582 ieee80211_mbss_info_change_notify(sdata, changed);
585 sdata_unlock(sdata);
586 583
587 mod_timer(&ifmsh->housekeeping_timer, 584 mod_timer(&ifmsh->housekeeping_timer,
588 round_jiffies(jiffies + 585 round_jiffies(jiffies +
@@ -741,9 +738,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
741 BSS_CHANGED_HT | 738 BSS_CHANGED_HT |
742 BSS_CHANGED_BASIC_RATES | 739 BSS_CHANGED_BASIC_RATES |
743 BSS_CHANGED_BEACON_INT; 740 BSS_CHANGED_BEACON_INT;
744 enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
745 struct ieee80211_supported_band *sband =
746 sdata->local->hw.wiphy->bands[band];
747 741
748 local->fif_other_bss++; 742 local->fif_other_bss++;
749 /* mesh ifaces must set allmulti to forward mcast traffic */ 743 /* mesh ifaces must set allmulti to forward mcast traffic */
@@ -761,7 +755,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
761 sdata->vif.bss_conf.ht_operation_mode = 755 sdata->vif.bss_conf.ht_operation_mode =
762 ifmsh->mshcfg.ht_opmode; 756 ifmsh->mshcfg.ht_opmode;
763 sdata->vif.bss_conf.enable_beacon = true; 757 sdata->vif.bss_conf.enable_beacon = true;
764 sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband);
765 758
766 changed |= ieee80211_mps_local_status_update(sdata); 759 changed |= ieee80211_mps_local_status_update(sdata);
767 760
@@ -789,12 +782,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
789 sdata->vif.bss_conf.enable_beacon = false; 782 sdata->vif.bss_conf.enable_beacon = false;
790 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 783 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
791 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 784 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
792 sdata_lock(sdata);
793 bcn = rcu_dereference_protected(ifmsh->beacon, 785 bcn = rcu_dereference_protected(ifmsh->beacon,
794 lockdep_is_held(&sdata->wdev.mtx)); 786 lockdep_is_held(&sdata->wdev.mtx));
795 rcu_assign_pointer(ifmsh->beacon, NULL); 787 rcu_assign_pointer(ifmsh->beacon, NULL);
796 kfree_rcu(bcn, rcu_head); 788 kfree_rcu(bcn, rcu_head);
797 sdata_unlock(sdata);
798 789
799 /* flush STAs and mpaths on this iface */ 790 /* flush STAs and mpaths on this iface */
800 sta_info_flush(sdata); 791 sta_info_flush(sdata);
@@ -807,14 +798,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
807 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 798 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
808 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); 799 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
809 del_timer_sync(&sdata->u.mesh.mesh_path_timer); 800 del_timer_sync(&sdata->u.mesh.mesh_path_timer);
810 /*
811 * If the timer fired while we waited for it, it will have
812 * requeued the work. Now the work will be running again
813 * but will not rearm the timer again because it checks
814 * whether the interface is running, which, at this point,
815 * it no longer is.
816 */
817 cancel_work_sync(&sdata->work);
818 801
819 local->fif_other_bss--; 802 local->fif_other_bss--;
820 atomic_dec(&local->iff_allmultis); 803 atomic_dec(&local->iff_allmultis);
@@ -955,6 +938,12 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
955 struct ieee80211_mgmt *mgmt; 938 struct ieee80211_mgmt *mgmt;
956 u16 stype; 939 u16 stype;
957 940
941 sdata_lock(sdata);
942
943 /* mesh already went down */
944 if (!sdata->wdev.mesh_id_len)
945 goto out;
946
958 rx_status = IEEE80211_SKB_RXCB(skb); 947 rx_status = IEEE80211_SKB_RXCB(skb);
959 mgmt = (struct ieee80211_mgmt *) skb->data; 948 mgmt = (struct ieee80211_mgmt *) skb->data;
960 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; 949 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
@@ -972,12 +961,20 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
972 ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status); 961 ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status);
973 break; 962 break;
974 } 963 }
964out:
965 sdata_unlock(sdata);
975} 966}
976 967
977void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) 968void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
978{ 969{
979 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 970 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
980 971
972 sdata_lock(sdata);
973
974 /* mesh already went down */
975 if (!sdata->wdev.mesh_id_len)
976 goto out;
977
981 if (ifmsh->preq_queue_len && 978 if (ifmsh->preq_queue_len &&
982 time_after(jiffies, 979 time_after(jiffies,
983 ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) 980 ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval)))
@@ -997,6 +994,9 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
997 994
998 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) 995 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags))
999 mesh_sync_adjust_tbtt(sdata); 996 mesh_sync_adjust_tbtt(sdata);
997
998out:
999 sdata_unlock(sdata);
1000} 1000}
1001 1001
1002void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) 1002void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index da158774eebb..01a28bca6e9b 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -188,7 +188,6 @@ struct mesh_rmc {
188 u32 idx_mask; 188 u32 idx_mask;
189}; 189};
190 190
191#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
192#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) 191#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
193 192
194#define MESH_PATH_EXPIRE (600 * HZ) 193#define MESH_PATH_EXPIRE (600 * HZ)
@@ -324,14 +323,14 @@ static inline
324u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 323u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
325{ 324{
326 atomic_inc(&sdata->u.mesh.estab_plinks); 325 atomic_inc(&sdata->u.mesh.estab_plinks);
327 return mesh_accept_plinks_update(sdata); 326 return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON;
328} 327}
329 328
330static inline 329static inline
331u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 330u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
332{ 331{
333 atomic_dec(&sdata->u.mesh.estab_plinks); 332 atomic_dec(&sdata->u.mesh.estab_plinks);
334 return mesh_accept_plinks_update(sdata); 333 return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON;
335} 334}
336 335
337static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) 336static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 6c4da99bc4fb..09bebed99416 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -517,9 +517,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
517 ieee80211_mps_frame_release(sta, elems); 517 ieee80211_mps_frame_release(sta, elems);
518out: 518out:
519 rcu_read_unlock(); 519 rcu_read_unlock();
520 sdata_lock(sdata);
521 ieee80211_mbss_info_change_notify(sdata, changed); 520 ieee80211_mbss_info_change_notify(sdata, changed);
522 sdata_unlock(sdata);
523} 521}
524 522
525static void mesh_plink_timer(unsigned long data) 523static void mesh_plink_timer(unsigned long data)
@@ -1070,9 +1068,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1070 1068
1071 rcu_read_unlock(); 1069 rcu_read_unlock();
1072 1070
1073 if (changed) { 1071 if (changed)
1074 sdata_lock(sdata);
1075 ieee80211_mbss_info_change_notify(sdata, changed); 1072 ieee80211_mbss_info_change_notify(sdata, changed);
1076 sdata_unlock(sdata);
1077 }
1078} 1073}
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}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bdd7b4a719e9..23dbcfc69b3b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1747,27 +1747,21 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)
1747 if (unlikely(!ieee80211_has_protected(fc) && 1747 if (unlikely(!ieee80211_has_protected(fc) &&
1748 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1748 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
1749 rx->key)) { 1749 rx->key)) {
1750 if (ieee80211_is_deauth(fc)) 1750 if (ieee80211_is_deauth(fc) ||
1751 cfg80211_send_unprot_deauth(rx->sdata->dev, 1751 ieee80211_is_disassoc(fc))
1752 rx->skb->data, 1752 cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
1753 rx->skb->len); 1753 rx->skb->data,
1754 else if (ieee80211_is_disassoc(fc)) 1754 rx->skb->len);
1755 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1756 rx->skb->data,
1757 rx->skb->len);
1758 return -EACCES; 1755 return -EACCES;
1759 } 1756 }
1760 /* BIP does not use Protected field, so need to check MMIE */ 1757 /* BIP does not use Protected field, so need to check MMIE */
1761 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1758 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
1762 ieee80211_get_mmie_keyidx(rx->skb) < 0)) { 1759 ieee80211_get_mmie_keyidx(rx->skb) < 0)) {
1763 if (ieee80211_is_deauth(fc)) 1760 if (ieee80211_is_deauth(fc) ||
1764 cfg80211_send_unprot_deauth(rx->sdata->dev, 1761 ieee80211_is_disassoc(fc))
1765 rx->skb->data, 1762 cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
1766 rx->skb->len); 1763 rx->skb->data,
1767 else if (ieee80211_is_disassoc(fc)) 1764 rx->skb->len);
1768 cfg80211_send_unprot_disassoc(rx->sdata->dev,
1769 rx->skb->data,
1770 rx->skb->len);
1771 return -EACCES; 1765 return -EACCES;
1772 } 1766 }
1773 /* 1767 /*
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index a04c5671d7fd..b4297982d34a 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1132,6 +1132,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
1132 * ends the poll/service period. 1132 * ends the poll/service period.
1133 */ 1133 */
1134 info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | 1134 info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER |
1135 IEEE80211_TX_CTL_PS_RESPONSE |
1135 IEEE80211_TX_STATUS_EOSP | 1136 IEEE80211_TX_STATUS_EOSP |
1136 IEEE80211_TX_CTL_REQ_TX_STATUS; 1137 IEEE80211_TX_CTL_REQ_TX_STATUS;
1137 1138
@@ -1269,7 +1270,8 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta,
1269 * STA may still remain is PS mode after this frame 1270 * STA may still remain is PS mode after this frame
1270 * exchange. 1271 * exchange.
1271 */ 1272 */
1272 info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; 1273 info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER |
1274 IEEE80211_TX_CTL_PS_RESPONSE;
1273 1275
1274 /* 1276 /*
1275 * Use MoreData flag to indicate whether there are 1277 * Use MoreData flag to indicate whether there are
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 41c28b977f7c..bd12fc54266c 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -297,6 +297,9 @@ struct sta_ampdu_mlme {
297 * @rcu_head: RCU head used for freeing this station struct 297 * @rcu_head: RCU head used for freeing this station struct
298 * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, 298 * @cur_max_bandwidth: maximum bandwidth to use for TX to the station,
299 * taken from HT/VHT capabilities or VHT operating mode notification 299 * taken from HT/VHT capabilities or VHT operating mode notification
300 * @chains: chains ever used for RX from this station
301 * @chain_signal_last: last signal (per chain)
302 * @chain_signal_avg: signal average (per chain)
300 */ 303 */
301struct sta_info { 304struct sta_info {
302 /* General information, mostly static */ 305 /* General information, mostly static */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 34be9336b5d1..4105d0ca963e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1790,12 +1790,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1790 break; 1790 break;
1791#ifdef CONFIG_MAC80211_MESH 1791#ifdef CONFIG_MAC80211_MESH
1792 case NL80211_IFTYPE_MESH_POINT: 1792 case NL80211_IFTYPE_MESH_POINT:
1793 if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
1794 /* Do not send frames with mesh_ttl == 0 */
1795 sdata->u.mesh.mshstats.dropped_frames_ttl++;
1796 goto fail_rcu;
1797 }
1798
1799 if (!is_multicast_ether_addr(skb->data)) { 1793 if (!is_multicast_ether_addr(skb->data)) {
1800 struct sta_info *next_hop; 1794 struct sta_info *next_hop;
1801 bool mpp_lookup = true; 1795 bool mpp_lookup = true;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 89a83770d152..5a6c1351d1d3 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1584,8 +1584,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1584 BSS_CHANGED_ARP_FILTER | 1584 BSS_CHANGED_ARP_FILTER |
1585 BSS_CHANGED_PS; 1585 BSS_CHANGED_PS;
1586 1586
1587 if (sdata->u.mgd.dtim_period) 1587 /* Re-send beacon info report to the driver */
1588 changed |= BSS_CHANGED_DTIM_PERIOD; 1588 if (sdata->u.mgd.have_beacon)
1589 changed |= BSS_CHANGED_BEACON_INFO;
1589 1590
1590 sdata_lock(sdata); 1591 sdata_lock(sdata);
1591 ieee80211_bss_info_change_notify(sdata, changed); 1592 ieee80211_bss_info_change_notify(sdata, changed);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 41cec1776f4f..4224e7554a76 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -301,6 +301,9 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
301 return NULL; 301 return NULL;
302 } 302 }
303 303
304 /* atomic_inc_return makes it start at 1, make it start at 0 */
305 rdev->wiphy_idx--;
306
304 /* give it a proper name */ 307 /* give it a proper name */
305 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 308 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
306 309
@@ -449,8 +452,13 @@ int wiphy_register(struct wiphy *wiphy)
449 u16 ifmodes = wiphy->interface_modes; 452 u16 ifmodes = wiphy->interface_modes;
450 453
451#ifdef CONFIG_PM 454#ifdef CONFIG_PM
452 if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 455 if (WARN_ON(wiphy->wowlan &&
453 !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) 456 (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
457 !(wiphy->wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
458 return -EINVAL;
459 if (WARN_ON(wiphy->wowlan &&
460 !wiphy->wowlan->flags && !wiphy->wowlan->n_patterns &&
461 !wiphy->wowlan->tcp))
454 return -EINVAL; 462 return -EINVAL;
455#endif 463#endif
456 464
@@ -540,25 +548,28 @@ int wiphy_register(struct wiphy *wiphy)
540 } 548 }
541 549
542#ifdef CONFIG_PM 550#ifdef CONFIG_PM
543 if (rdev->wiphy.wowlan.n_patterns) { 551 if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns &&
544 if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len || 552 (!rdev->wiphy.wowlan->pattern_min_len ||
545 rdev->wiphy.wowlan.pattern_min_len > 553 rdev->wiphy.wowlan->pattern_min_len >
546 rdev->wiphy.wowlan.pattern_max_len)) 554 rdev->wiphy.wowlan->pattern_max_len)))
547 return -EINVAL; 555 return -EINVAL;
548 }
549#endif 556#endif
550 557
551 /* check and set up bitrates */ 558 /* check and set up bitrates */
552 ieee80211_set_bitrate_flags(wiphy); 559 ieee80211_set_bitrate_flags(wiphy);
553 560
554 rtnl_lock();
555 561
556 res = device_add(&rdev->wiphy.dev); 562 res = device_add(&rdev->wiphy.dev);
563 if (res)
564 return res;
565
566 res = rfkill_register(rdev->rfkill);
557 if (res) { 567 if (res) {
558 rtnl_unlock(); 568 device_del(&rdev->wiphy.dev);
559 return res; 569 return res;
560 } 570 }
561 571
572 rtnl_lock();
562 /* set up regulatory info */ 573 /* set up regulatory info */
563 wiphy_regulatory_register(wiphy); 574 wiphy_regulatory_register(wiphy);
564 575
@@ -585,17 +596,6 @@ int wiphy_register(struct wiphy *wiphy)
585 596
586 cfg80211_debugfs_rdev_add(rdev); 597 cfg80211_debugfs_rdev_add(rdev);
587 598
588 res = rfkill_register(rdev->rfkill);
589 if (res) {
590 device_del(&rdev->wiphy.dev);
591
592 debugfs_remove_recursive(rdev->wiphy.debugfsdir);
593 list_del_rcu(&rdev->list);
594 wiphy_regulatory_deregister(wiphy);
595 rtnl_unlock();
596 return res;
597 }
598
599 rdev->wiphy.registered = true; 599 rdev->wiphy.registered = true;
600 rtnl_unlock(); 600 rtnl_unlock();
601 return 0; 601 return 0;
@@ -632,11 +632,11 @@ void wiphy_unregister(struct wiphy *wiphy)
632 rtnl_unlock(); 632 rtnl_unlock();
633 __count == 0; })); 633 __count == 0; }));
634 634
635 rfkill_unregister(rdev->rfkill);
636
635 rtnl_lock(); 637 rtnl_lock();
636 rdev->wiphy.registered = false; 638 rdev->wiphy.registered = false;
637 639
638 rfkill_unregister(rdev->rfkill);
639
640 BUG_ON(!list_empty(&rdev->wdev_list)); 640 BUG_ON(!list_empty(&rdev->wdev_list));
641 641
642 /* 642 /*
@@ -817,7 +817,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
817 pr_err("failed to add phy80211 symlink to netdev!\n"); 817 pr_err("failed to add phy80211 symlink to netdev!\n");
818 } 818 }
819 wdev->netdev = dev; 819 wdev->netdev = dev;
820 wdev->sme_state = CFG80211_SME_IDLE;
821#ifdef CONFIG_CFG80211_WEXT 820#ifdef CONFIG_CFG80211_WEXT
822 wdev->wext.default_key = -1; 821 wdev->wext.default_key = -1;
823 wdev->wext.default_mgmt_key = -1; 822 wdev->wext.default_mgmt_key = -1;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a65eaf8a84c1..a6b45bf00f33 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -308,11 +308,6 @@ int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
308 bool local_state_change); 308 bool local_state_change);
309void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 309void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
310 struct net_device *dev); 310 struct net_device *dev);
311void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
312 const u8 *req_ie, size_t req_ie_len,
313 const u8 *resp_ie, size_t resp_ie_len,
314 u16 status, bool wextev,
315 struct cfg80211_bss *bss);
316int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 311int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
317 u16 frame_type, const u8 *match_data, 312 u16 frame_type, const u8 *match_data,
318 int match_len); 313 int match_len);
@@ -328,12 +323,19 @@ void cfg80211_oper_and_ht_capa(struct ieee80211_ht_cap *ht_capa,
328void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa, 323void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa,
329 const struct ieee80211_vht_cap *vht_capa_mask); 324 const struct ieee80211_vht_cap *vht_capa_mask);
330 325
331/* SME */ 326/* SME events */
332int cfg80211_connect(struct cfg80211_registered_device *rdev, 327int cfg80211_connect(struct cfg80211_registered_device *rdev,
333 struct net_device *dev, 328 struct net_device *dev,
334 struct cfg80211_connect_params *connect, 329 struct cfg80211_connect_params *connect,
335 struct cfg80211_cached_keys *connkeys, 330 struct cfg80211_cached_keys *connkeys,
336 const u8 *prev_bssid); 331 const u8 *prev_bssid);
332void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
333 const u8 *req_ie, size_t req_ie_len,
334 const u8 *resp_ie, size_t resp_ie_len,
335 u16 status, bool wextev,
336 struct cfg80211_bss *bss);
337void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
338 size_t ie_len, u16 reason, bool from_ap);
337int cfg80211_disconnect(struct cfg80211_registered_device *rdev, 339int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
338 struct net_device *dev, u16 reason, 340 struct net_device *dev, u16 reason,
339 bool wextev); 341 bool wextev);
@@ -344,21 +346,21 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
344int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 346int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
345 struct wireless_dev *wdev); 347 struct wireless_dev *wdev);
346 348
349/* SME implementation */
347void cfg80211_conn_work(struct work_struct *work); 350void cfg80211_conn_work(struct work_struct *work);
348void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); 351void cfg80211_sme_scan_done(struct net_device *dev);
349bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); 352bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status);
353void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len);
354void cfg80211_sme_disassoc(struct wireless_dev *wdev);
355void cfg80211_sme_deauth(struct wireless_dev *wdev);
356void cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
357void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
350 358
351/* internal helpers */ 359/* internal helpers */
352bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); 360bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
353int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 361int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
354 struct key_params *params, int key_idx, 362 struct key_params *params, int key_idx,
355 bool pairwise, const u8 *mac_addr); 363 bool pairwise, const u8 *mac_addr);
356void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
357 size_t ie_len, u16 reason, bool from_ap);
358void cfg80211_sme_scan_done(struct net_device *dev);
359void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
360void cfg80211_sme_disassoc(struct net_device *dev,
361 struct cfg80211_internal_bss *bss);
362void __cfg80211_scan_done(struct work_struct *wk); 364void __cfg80211_scan_done(struct work_struct *wk);
363void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak); 365void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
364void __cfg80211_sched_scan_results(struct work_struct *wk); 366void __cfg80211_sched_scan_results(struct work_struct *wk);
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 5449c5a6de84..39bff7d36768 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -43,7 +43,6 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
43 cfg80211_hold_bss(bss_from_pub(bss)); 43 cfg80211_hold_bss(bss_from_pub(bss));
44 wdev->current_bss = bss_from_pub(bss); 44 wdev->current_bss = bss_from_pub(bss);
45 45
46 wdev->sme_state = CFG80211_SME_CONNECTED;
47 cfg80211_upload_connect_keys(wdev); 46 cfg80211_upload_connect_keys(wdev);
48 47
49 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, 48 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
@@ -64,8 +63,6 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
64 63
65 trace_cfg80211_ibss_joined(dev, bssid); 64 trace_cfg80211_ibss_joined(dev, bssid);
66 65
67 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
68
69 ev = kzalloc(sizeof(*ev), gfp); 66 ev = kzalloc(sizeof(*ev), gfp);
70 if (!ev) 67 if (!ev)
71 return; 68 return;
@@ -120,7 +117,6 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
120#ifdef CONFIG_CFG80211_WEXT 117#ifdef CONFIG_CFG80211_WEXT
121 wdev->wext.ibss.chandef = params->chandef; 118 wdev->wext.ibss.chandef = params->chandef;
122#endif 119#endif
123 wdev->sme_state = CFG80211_SME_CONNECTING;
124 120
125 err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan, 121 err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan,
126 params->channel_fixed 122 params->channel_fixed
@@ -134,7 +130,6 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
134 err = rdev_join_ibss(rdev, dev, params); 130 err = rdev_join_ibss(rdev, dev, params);
135 if (err) { 131 if (err) {
136 wdev->connect_keys = NULL; 132 wdev->connect_keys = NULL;
137 wdev->sme_state = CFG80211_SME_IDLE;
138 return err; 133 return err;
139 } 134 }
140 135
@@ -186,7 +181,6 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
186 } 181 }
187 182
188 wdev->current_bss = NULL; 183 wdev->current_bss = NULL;
189 wdev->sme_state = CFG80211_SME_IDLE;
190 wdev->ssid_len = 0; 184 wdev->ssid_len = 0;
191#ifdef CONFIG_CFG80211_WEXT 185#ifdef CONFIG_CFG80211_WEXT
192 if (!nowext) 186 if (!nowext)
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 5dfb289ab761..30c49202ee4d 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -18,6 +18,7 @@
18#define MESH_PATH_TO_ROOT_TIMEOUT 6000 18#define MESH_PATH_TO_ROOT_TIMEOUT 6000
19#define MESH_ROOT_INTERVAL 5000 19#define MESH_ROOT_INTERVAL 5000
20#define MESH_ROOT_CONFIRMATION_INTERVAL 2000 20#define MESH_ROOT_CONFIRMATION_INTERVAL 2000
21#define MESH_DEFAULT_PLINK_TIMEOUT 1800 /* timeout in seconds */
21 22
22/* 23/*
23 * Minimum interval between two consecutive PREQs originated by the same 24 * Minimum interval between two consecutive PREQs originated by the same
@@ -75,6 +76,7 @@ const struct mesh_config default_mesh_config = {
75 .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, 76 .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL,
76 .power_mode = NL80211_MESH_POWER_ACTIVE, 77 .power_mode = NL80211_MESH_POWER_ACTIVE,
77 .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW, 78 .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW,
79 .plink_timeout = MESH_DEFAULT_PLINK_TIMEOUT,
78}; 80};
79 81
80const struct mesh_setup default_mesh_setup = { 82const struct mesh_setup default_mesh_setup = {
@@ -160,6 +162,16 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
160 setup->chandef.center_freq1 = setup->chandef.chan->center_freq; 162 setup->chandef.center_freq1 = setup->chandef.chan->center_freq;
161 } 163 }
162 164
165 /*
166 * check if basic rates are available otherwise use mandatory rates as
167 * basic rates
168 */
169 if (!setup->basic_rates) {
170 struct ieee80211_supported_band *sband =
171 rdev->wiphy.bands[setup->chandef.chan->band];
172 setup->basic_rates = ieee80211_mandatory_rates(sband);
173 }
174
163 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef)) 175 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
164 return -EINVAL; 176 return -EINVAL;
165 177
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 7bde5d9c0003..a61a44bc6cf0 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -18,150 +18,107 @@
18#include "rdev-ops.h" 18#include "rdev-ops.h"
19 19
20 20
21void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) 21void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
22{
23 struct wireless_dev *wdev = dev->ieee80211_ptr;
24 struct wiphy *wiphy = wdev->wiphy;
25 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
26
27 trace_cfg80211_send_rx_auth(dev);
28
29 nl80211_send_rx_auth(rdev, dev, buf, len, GFP_KERNEL);
30 cfg80211_sme_rx_auth(dev, buf, len);
31}
32EXPORT_SYMBOL(cfg80211_send_rx_auth);
33
34void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss,
35 const u8 *buf, size_t len) 22 const u8 *buf, size_t len)
36{ 23{
37 u16 status_code;
38 struct wireless_dev *wdev = dev->ieee80211_ptr; 24 struct wireless_dev *wdev = dev->ieee80211_ptr;
39 struct wiphy *wiphy = wdev->wiphy; 25 struct wiphy *wiphy = wdev->wiphy;
40 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 26 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
41 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 27 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
42 u8 *ie = mgmt->u.assoc_resp.variable; 28 u8 *ie = mgmt->u.assoc_resp.variable;
43 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 29 int ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
30 u16 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
44 31
45 trace_cfg80211_send_rx_assoc(dev, bss); 32 trace_cfg80211_send_rx_assoc(dev, bss);
46 33
47 status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
48
49 /* 34 /*
50 * This is a bit of a hack, we don't notify userspace of 35 * This is a bit of a hack, we don't notify userspace of
51 * a (re-)association reply if we tried to send a reassoc 36 * a (re-)association reply if we tried to send a reassoc
52 * and got a reject -- we only try again with an assoc 37 * and got a reject -- we only try again with an assoc
53 * frame instead of reassoc. 38 * frame instead of reassoc.
54 */ 39 */
55 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 40 if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {
56 cfg80211_sme_failed_reassoc(wdev)) {
57 cfg80211_put_bss(wiphy, bss); 41 cfg80211_put_bss(wiphy, bss);
58 return; 42 return;
59 } 43 }
60 44
61 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 45 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
62 46 /* update current_bss etc., consumes the bss reference */
63 if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) {
64 cfg80211_sme_failed_assoc(wdev);
65 /*
66 * do not call connect_result() now because the
67 * sme will schedule work that does it later.
68 */
69 cfg80211_put_bss(wiphy, bss);
70 return;
71 }
72
73 if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) {
74 /*
75 * This is for the userspace SME, the CONNECTING
76 * state will be changed to CONNECTED by
77 * __cfg80211_connect_result() below.
78 */
79 wdev->sme_state = CFG80211_SME_CONNECTING;
80 }
81
82 /* this consumes the bss reference */
83 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 47 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
84 status_code, 48 status_code,
85 status_code == WLAN_STATUS_SUCCESS, bss); 49 status_code == WLAN_STATUS_SUCCESS, bss);
86} 50}
87EXPORT_SYMBOL(cfg80211_send_rx_assoc); 51EXPORT_SYMBOL(cfg80211_rx_assoc_resp);
88 52
89void cfg80211_send_deauth(struct net_device *dev, 53static void cfg80211_process_auth(struct wireless_dev *wdev,
90 const u8 *buf, size_t len) 54 const u8 *buf, size_t len)
91{ 55{
92 struct wireless_dev *wdev = dev->ieee80211_ptr; 56 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
93 struct wiphy *wiphy = wdev->wiphy; 57
94 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 58 nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
59 cfg80211_sme_rx_auth(wdev, buf, len);
60}
61
62static void cfg80211_process_deauth(struct wireless_dev *wdev,
63 const u8 *buf, size_t len)
64{
65 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
95 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 66 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
96 const u8 *bssid = mgmt->bssid; 67 const u8 *bssid = mgmt->bssid;
97 bool was_current = false; 68 u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
69 bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
98 70
99 trace_cfg80211_send_deauth(dev); 71 nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL);
100 ASSERT_WDEV_LOCK(wdev);
101 72
102 if (wdev->current_bss && 73 if (!wdev->current_bss ||
103 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 74 !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
104 cfg80211_unhold_bss(wdev->current_bss); 75 return;
105 cfg80211_put_bss(wiphy, &wdev->current_bss->pub); 76
106 wdev->current_bss = NULL; 77 __cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
107 was_current = true; 78 cfg80211_sme_deauth(wdev);
108 } 79}
109 80
110 nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL); 81static void cfg80211_process_disassoc(struct wireless_dev *wdev,
82 const u8 *buf, size_t len)
83{
84 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
85 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
86 const u8 *bssid = mgmt->bssid;
87 u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
88 bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr);
111 89
112 if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) { 90 nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL);
113 u16 reason_code;
114 bool from_ap;
115 91
116 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 92 if (WARN_ON(!wdev->current_bss ||
93 !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
94 return;
117 95
118 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); 96 __cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap);
119 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 97 cfg80211_sme_disassoc(wdev);
120 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
121 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
122 WLAN_STATUS_UNSPECIFIED_FAILURE,
123 false, NULL);
124 }
125} 98}
126EXPORT_SYMBOL(cfg80211_send_deauth);
127 99
128void cfg80211_send_disassoc(struct net_device *dev, 100void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
129 const u8 *buf, size_t len)
130{ 101{
131 struct wireless_dev *wdev = dev->ieee80211_ptr; 102 struct wireless_dev *wdev = dev->ieee80211_ptr;
132 struct wiphy *wiphy = wdev->wiphy; 103 struct ieee80211_mgmt *mgmt = (void *)buf;
133 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
134 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
135 const u8 *bssid = mgmt->bssid;
136 u16 reason_code;
137 bool from_ap;
138 104
139 trace_cfg80211_send_disassoc(dev);
140 ASSERT_WDEV_LOCK(wdev); 105 ASSERT_WDEV_LOCK(wdev);
141 106
142 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 107 trace_cfg80211_rx_mlme_mgmt(dev, buf, len);
143 108
144 if (wdev->sme_state != CFG80211_SME_CONNECTED) 109 if (WARN_ON(len < 2))
145 return; 110 return;
146 111
147 if (wdev->current_bss && 112 if (ieee80211_is_auth(mgmt->frame_control))
148 ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 113 cfg80211_process_auth(wdev, buf, len);
149 cfg80211_sme_disassoc(dev, wdev->current_bss); 114 else if (ieee80211_is_deauth(mgmt->frame_control))
150 cfg80211_unhold_bss(wdev->current_bss); 115 cfg80211_process_deauth(wdev, buf, len);
151 cfg80211_put_bss(wiphy, &wdev->current_bss->pub); 116 else if (ieee80211_is_disassoc(mgmt->frame_control))
152 wdev->current_bss = NULL; 117 cfg80211_process_disassoc(wdev, buf, len);
153 } else
154 WARN_ON(1);
155
156
157 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
158
159 from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr);
160 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
161} 118}
162EXPORT_SYMBOL(cfg80211_send_disassoc); 119EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt);
163 120
164void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 121void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr)
165{ 122{
166 struct wireless_dev *wdev = dev->ieee80211_ptr; 123 struct wireless_dev *wdev = dev->ieee80211_ptr;
167 struct wiphy *wiphy = wdev->wiphy; 124 struct wiphy *wiphy = wdev->wiphy;
@@ -170,14 +127,11 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
170 trace_cfg80211_send_auth_timeout(dev, addr); 127 trace_cfg80211_send_auth_timeout(dev, addr);
171 128
172 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); 129 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL);
173 if (wdev->sme_state == CFG80211_SME_CONNECTING) 130 cfg80211_sme_auth_timeout(wdev);
174 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
175 WLAN_STATUS_UNSPECIFIED_FAILURE,
176 false, NULL);
177} 131}
178EXPORT_SYMBOL(cfg80211_send_auth_timeout); 132EXPORT_SYMBOL(cfg80211_auth_timeout);
179 133
180void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr) 134void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr)
181{ 135{
182 struct wireless_dev *wdev = dev->ieee80211_ptr; 136 struct wireless_dev *wdev = dev->ieee80211_ptr;
183 struct wiphy *wiphy = wdev->wiphy; 137 struct wiphy *wiphy = wdev->wiphy;
@@ -186,12 +140,28 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
186 trace_cfg80211_send_assoc_timeout(dev, addr); 140 trace_cfg80211_send_assoc_timeout(dev, addr);
187 141
188 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 142 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL);
189 if (wdev->sme_state == CFG80211_SME_CONNECTING) 143 cfg80211_sme_assoc_timeout(wdev);
190 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
191 WLAN_STATUS_UNSPECIFIED_FAILURE,
192 false, NULL);
193} 144}
194EXPORT_SYMBOL(cfg80211_send_assoc_timeout); 145EXPORT_SYMBOL(cfg80211_assoc_timeout);
146
147void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
148{
149 struct wireless_dev *wdev = dev->ieee80211_ptr;
150 struct ieee80211_mgmt *mgmt = (void *)buf;
151
152 ASSERT_WDEV_LOCK(wdev);
153
154 trace_cfg80211_tx_mlme_mgmt(dev, buf, len);
155
156 if (WARN_ON(len < 2))
157 return;
158
159 if (ieee80211_is_deauth(mgmt->frame_control))
160 cfg80211_process_deauth(wdev, buf, len);
161 else
162 cfg80211_process_disassoc(wdev, buf, len);
163}
164EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt);
195 165
196void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, 166void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
197 enum nl80211_key_type key_type, int key_id, 167 enum nl80211_key_type key_type, int key_id,
@@ -314,21 +284,12 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
314{ 284{
315 struct wireless_dev *wdev = dev->ieee80211_ptr; 285 struct wireless_dev *wdev = dev->ieee80211_ptr;
316 int err; 286 int err;
317 bool was_connected = false;
318 287
319 ASSERT_WDEV_LOCK(wdev); 288 ASSERT_WDEV_LOCK(wdev);
320 289
321 if (wdev->current_bss && req->prev_bssid && 290 if (wdev->current_bss &&
322 ether_addr_equal(wdev->current_bss->pub.bssid, req->prev_bssid)) { 291 (!req->prev_bssid || !ether_addr_equal(wdev->current_bss->pub.bssid,
323 /* 292 req->prev_bssid)))
324 * Trying to reassociate: Allow this to proceed and let the old
325 * association to be dropped when the new one is completed.
326 */
327 if (wdev->sme_state == CFG80211_SME_CONNECTED) {
328 was_connected = true;
329 wdev->sme_state = CFG80211_SME_CONNECTING;
330 }
331 } else if (wdev->current_bss)
332 return -EALREADY; 293 return -EALREADY;
333 294
334 cfg80211_oper_and_ht_capa(&req->ht_capa_mask, 295 cfg80211_oper_and_ht_capa(&req->ht_capa_mask,
@@ -338,11 +299,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
338 299
339 req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 300 req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
340 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 301 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
341 if (!req->bss) { 302 if (!req->bss)
342 if (was_connected)
343 wdev->sme_state = CFG80211_SME_CONNECTED;
344 return -ENOENT; 303 return -ENOENT;
345 }
346 304
347 err = cfg80211_can_use_chan(rdev, wdev, chan, CHAN_MODE_SHARED); 305 err = cfg80211_can_use_chan(rdev, wdev, chan, CHAN_MODE_SHARED);
348 if (err) 306 if (err)
@@ -351,11 +309,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
351 err = rdev_assoc(rdev, dev, req); 309 err = rdev_assoc(rdev, dev, req);
352 310
353out: 311out:
354 if (err) { 312 if (err)
355 if (was_connected)
356 wdev->sme_state = CFG80211_SME_CONNECTED;
357 cfg80211_put_bss(&rdev->wiphy, req->bss); 313 cfg80211_put_bss(&rdev->wiphy, req->bss);
358 }
359 314
360 return err; 315 return err;
361} 316}
@@ -376,8 +331,9 @@ int cfg80211_mlme_deauth(struct cfg80211_registered_device *rdev,
376 331
377 ASSERT_WDEV_LOCK(wdev); 332 ASSERT_WDEV_LOCK(wdev);
378 333
379 if (local_state_change && (!wdev->current_bss || 334 if (local_state_change &&
380 !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) 335 (!wdev->current_bss ||
336 !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
381 return 0; 337 return 0;
382 338
383 return rdev_deauth(rdev, dev, &req); 339 return rdev_deauth(rdev, dev, &req);
@@ -395,13 +351,11 @@ int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
395 .ie = ie, 351 .ie = ie,
396 .ie_len = ie_len, 352 .ie_len = ie_len,
397 }; 353 };
354 int err;
398 355
399 ASSERT_WDEV_LOCK(wdev); 356 ASSERT_WDEV_LOCK(wdev);
400 357
401 if (wdev->sme_state != CFG80211_SME_CONNECTED) 358 if (!wdev->current_bss)
402 return -ENOTCONN;
403
404 if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state))
405 return -ENOTCONN; 359 return -ENOTCONN;
406 360
407 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) 361 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid))
@@ -409,7 +363,13 @@ int cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
409 else 363 else
410 return -ENOTCONN; 364 return -ENOTCONN;
411 365
412 return rdev_disassoc(rdev, dev, &req); 366 err = rdev_disassoc(rdev, dev, &req);
367 if (err)
368 return err;
369
370 /* driver should have reported the disassoc */
371 WARN_ON(wdev->current_bss);
372 return 0;
413} 373}
414 374
415void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 375void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
@@ -417,10 +377,6 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
417{ 377{
418 struct wireless_dev *wdev = dev->ieee80211_ptr; 378 struct wireless_dev *wdev = dev->ieee80211_ptr;
419 u8 bssid[ETH_ALEN]; 379 u8 bssid[ETH_ALEN];
420 struct cfg80211_deauth_request req = {
421 .reason_code = WLAN_REASON_DEAUTH_LEAVING,
422 .bssid = bssid,
423 };
424 380
425 ASSERT_WDEV_LOCK(wdev); 381 ASSERT_WDEV_LOCK(wdev);
426 382
@@ -431,13 +387,8 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
431 return; 387 return;
432 388
433 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); 389 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
434 rdev_deauth(rdev, dev, &req); 390 cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
435 391 WLAN_REASON_DEAUTH_LEAVING, false);
436 if (wdev->current_bss) {
437 cfg80211_unhold_bss(wdev->current_bss);
438 cfg80211_put_bss(&rdev->wiphy, &wdev->current_bss->pub);
439 wdev->current_bss = NULL;
440 }
441} 392}
442 393
443struct cfg80211_mgmt_registration { 394struct cfg80211_mgmt_registration {
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 31d265f36d2c..e4028197b75d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -800,12 +800,9 @@ static int nl80211_key_allowed(struct wireless_dev *wdev)
800 case NL80211_IFTYPE_MESH_POINT: 800 case NL80211_IFTYPE_MESH_POINT:
801 break; 801 break;
802 case NL80211_IFTYPE_ADHOC: 802 case NL80211_IFTYPE_ADHOC:
803 if (!wdev->current_bss)
804 return -ENOLINK;
805 break;
806 case NL80211_IFTYPE_STATION: 803 case NL80211_IFTYPE_STATION:
807 case NL80211_IFTYPE_P2P_CLIENT: 804 case NL80211_IFTYPE_P2P_CLIENT:
808 if (wdev->sme_state != CFG80211_SME_CONNECTED) 805 if (!wdev->current_bss)
809 return -ENOLINK; 806 return -ENOLINK;
810 break; 807 break;
811 default: 808 default:
@@ -908,7 +905,7 @@ nla_put_failure:
908static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev, 905static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
909 struct sk_buff *msg) 906 struct sk_buff *msg)
910{ 907{
911 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp; 908 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp;
912 struct nlattr *nl_tcp; 909 struct nlattr *nl_tcp;
913 910
914 if (!tcp) 911 if (!tcp)
@@ -951,37 +948,37 @@ static int nl80211_send_wowlan(struct sk_buff *msg,
951{ 948{
952 struct nlattr *nl_wowlan; 949 struct nlattr *nl_wowlan;
953 950
954 if (!dev->wiphy.wowlan.flags && !dev->wiphy.wowlan.n_patterns) 951 if (!dev->wiphy.wowlan)
955 return 0; 952 return 0;
956 953
957 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED); 954 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED);
958 if (!nl_wowlan) 955 if (!nl_wowlan)
959 return -ENOBUFS; 956 return -ENOBUFS;
960 957
961 if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) && 958 if (((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) &&
962 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || 959 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) ||
963 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) && 960 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) &&
964 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || 961 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) ||
965 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) && 962 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) &&
966 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || 963 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) ||
967 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) && 964 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) &&
968 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) || 965 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) ||
969 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 966 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
970 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || 967 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) ||
971 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) && 968 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) &&
972 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || 969 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) ||
973 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) && 970 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) &&
974 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || 971 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) ||
975 ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) && 972 ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) &&
976 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) 973 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE)))
977 return -ENOBUFS; 974 return -ENOBUFS;
978 975
979 if (dev->wiphy.wowlan.n_patterns) { 976 if (dev->wiphy.wowlan->n_patterns) {
980 struct nl80211_wowlan_pattern_support pat = { 977 struct nl80211_wowlan_pattern_support pat = {
981 .max_patterns = dev->wiphy.wowlan.n_patterns, 978 .max_patterns = dev->wiphy.wowlan->n_patterns,
982 .min_pattern_len = dev->wiphy.wowlan.pattern_min_len, 979 .min_pattern_len = dev->wiphy.wowlan->pattern_min_len,
983 .max_pattern_len = dev->wiphy.wowlan.pattern_max_len, 980 .max_pattern_len = dev->wiphy.wowlan->pattern_max_len,
984 .max_pkt_offset = dev->wiphy.wowlan.max_pkt_offset, 981 .max_pkt_offset = dev->wiphy.wowlan->max_pkt_offset,
985 }; 982 };
986 983
987 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, 984 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN,
@@ -1544,8 +1541,10 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1544 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); 1541 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1545 1542
1546 netdev = dev_get_by_index(sock_net(skb->sk), ifidx); 1543 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1547 if (!netdev) 1544 if (!netdev) {
1545 rtnl_unlock();
1548 return -ENODEV; 1546 return -ENODEV;
1547 }
1549 if (netdev->ieee80211_ptr) { 1548 if (netdev->ieee80211_ptr) {
1550 dev = wiphy_to_dev( 1549 dev = wiphy_to_dev(
1551 netdev->ieee80211_ptr->wiphy); 1550 netdev->ieee80211_ptr->wiphy);
@@ -1589,6 +1588,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1589 !skb->len && 1588 !skb->len &&
1590 cb->min_dump_alloc < 4096) { 1589 cb->min_dump_alloc < 4096) {
1591 cb->min_dump_alloc = 4096; 1590 cb->min_dump_alloc = 4096;
1591 rtnl_unlock();
1592 return 1; 1592 return 1;
1593 } 1593 }
1594 idx--; 1594 idx--;
@@ -3975,10 +3975,10 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
3975 params.listen_interval = 3975 params.listen_interval =
3976 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 3976 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
3977 3977
3978 if (info->attrs[NL80211_ATTR_STA_AID]) 3978 if (info->attrs[NL80211_ATTR_PEER_AID])
3979 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
3980 else
3981 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]); 3979 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_PEER_AID]);
3980 else
3981 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
3982 if (!params.aid || params.aid > IEEE80211_MAX_AID) 3982 if (!params.aid || params.aid > IEEE80211_MAX_AID)
3983 return -EINVAL; 3983 return -EINVAL;
3984 3984
@@ -4030,7 +4030,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
4030 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD; 4030 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD;
4031 4031
4032 /* TDLS peers cannot be added */ 4032 /* TDLS peers cannot be added */
4033 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) 4033 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
4034 info->attrs[NL80211_ATTR_PEER_AID])
4034 return -EINVAL; 4035 return -EINVAL;
4035 /* but don't bother the driver with it */ 4036 /* but don't bother the driver with it */
4036 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); 4037 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
@@ -4056,7 +4057,8 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
4056 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) 4057 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED))
4057 return -EINVAL; 4058 return -EINVAL;
4058 /* TDLS peers cannot be added */ 4059 /* TDLS peers cannot be added */
4059 if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) 4060 if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) ||
4061 info->attrs[NL80211_ATTR_PEER_AID])
4060 return -EINVAL; 4062 return -EINVAL;
4061 break; 4063 break;
4062 case NL80211_IFTYPE_STATION: 4064 case NL80211_IFTYPE_STATION:
@@ -4578,7 +4580,9 @@ static int nl80211_get_mesh_config(struct sk_buff *skb,
4578 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE, 4580 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE,
4579 cur_params.power_mode) || 4581 cur_params.power_mode) ||
4580 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW, 4582 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW,
4581 cur_params.dot11MeshAwakeWindowDuration)) 4583 cur_params.dot11MeshAwakeWindowDuration) ||
4584 nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT,
4585 cur_params.plink_timeout))
4582 goto nla_put_failure; 4586 goto nla_put_failure;
4583 nla_nest_end(msg, pinfoattr); 4587 nla_nest_end(msg, pinfoattr);
4584 genlmsg_end(msg, hdr); 4588 genlmsg_end(msg, hdr);
@@ -4619,6 +4623,7 @@ static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_A
4619 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, 4623 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 },
4620 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 }, 4624 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 },
4621 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, 4625 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 },
4626 [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 },
4622}; 4627};
4623 4628
4624static const struct nla_policy 4629static const struct nla_policy
@@ -4756,6 +4761,9 @@ do { \
4756 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, 4761 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration,
4757 0, 65535, mask, 4762 0, 65535, mask,
4758 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16); 4763 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16);
4764 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 1, 0xffffffff,
4765 mask, NL80211_MESHCONF_PLINK_TIMEOUT,
4766 nla_get_u32);
4759 if (mask_out) 4767 if (mask_out)
4760 *mask_out = mask; 4768 *mask_out = mask;
4761 4769
@@ -7142,6 +7150,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
7142 return -EOPNOTSUPP; 7150 return -EOPNOTSUPP;
7143 7151
7144 switch (wdev->iftype) { 7152 switch (wdev->iftype) {
7153 case NL80211_IFTYPE_P2P_DEVICE:
7154 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
7155 return -EINVAL;
7145 case NL80211_IFTYPE_STATION: 7156 case NL80211_IFTYPE_STATION:
7146 case NL80211_IFTYPE_ADHOC: 7157 case NL80211_IFTYPE_ADHOC:
7147 case NL80211_IFTYPE_P2P_CLIENT: 7158 case NL80211_IFTYPE_P2P_CLIENT:
@@ -7149,7 +7160,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
7149 case NL80211_IFTYPE_AP_VLAN: 7160 case NL80211_IFTYPE_AP_VLAN:
7150 case NL80211_IFTYPE_MESH_POINT: 7161 case NL80211_IFTYPE_MESH_POINT:
7151 case NL80211_IFTYPE_P2P_GO: 7162 case NL80211_IFTYPE_P2P_GO:
7152 case NL80211_IFTYPE_P2P_DEVICE:
7153 break; 7163 break;
7154 default: 7164 default:
7155 return -EOPNOTSUPP; 7165 return -EOPNOTSUPP;
@@ -7177,9 +7187,18 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
7177 7187
7178 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 7188 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
7179 7189
7180 err = nl80211_parse_chandef(rdev, info, &chandef); 7190 /* get the channel if any has been specified, otherwise pass NULL to
7181 if (err) 7191 * the driver. The latter will use the current one
7182 return err; 7192 */
7193 chandef.chan = NULL;
7194 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
7195 err = nl80211_parse_chandef(rdev, info, &chandef);
7196 if (err)
7197 return err;
7198 }
7199
7200 if (!chandef.chan && offchan)
7201 return -EINVAL;
7183 7202
7184 if (!dont_wait_for_ack) { 7203 if (!dont_wait_for_ack) {
7185 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 7204 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -7484,6 +7503,23 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
7484 setup.chandef.chan = NULL; 7503 setup.chandef.chan = NULL;
7485 } 7504 }
7486 7505
7506 if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) {
7507 u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7508 int n_rates =
7509 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
7510 struct ieee80211_supported_band *sband;
7511
7512 if (!setup.chandef.chan)
7513 return -EINVAL;
7514
7515 sband = rdev->wiphy.bands[setup.chandef.chan->band];
7516
7517 err = ieee80211_get_ratemask(sband, rates, n_rates,
7518 &setup.basic_rates);
7519 if (err)
7520 return err;
7521 }
7522
7487 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 7523 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
7488} 7524}
7489 7525
@@ -7580,8 +7616,7 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
7580 void *hdr; 7616 void *hdr;
7581 u32 size = NLMSG_DEFAULT_SIZE; 7617 u32 size = NLMSG_DEFAULT_SIZE;
7582 7618
7583 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns && 7619 if (!rdev->wiphy.wowlan)
7584 !rdev->wiphy.wowlan.tcp)
7585 return -EOPNOTSUPP; 7620 return -EOPNOTSUPP;
7586 7621
7587 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) { 7622 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) {
@@ -7654,7 +7689,7 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
7654 u32 data_size, wake_size, tokens_size = 0, wake_mask_size; 7689 u32 data_size, wake_size, tokens_size = 0, wake_mask_size;
7655 int err, port; 7690 int err, port;
7656 7691
7657 if (!rdev->wiphy.wowlan.tcp) 7692 if (!rdev->wiphy.wowlan->tcp)
7658 return -EINVAL; 7693 return -EINVAL;
7659 7694
7660 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP, 7695 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP,
@@ -7674,16 +7709,16 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
7674 return -EINVAL; 7709 return -EINVAL;
7675 7710
7676 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]); 7711 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]);
7677 if (data_size > rdev->wiphy.wowlan.tcp->data_payload_max) 7712 if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max)
7678 return -EINVAL; 7713 return -EINVAL;
7679 7714
7680 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) > 7715 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) >
7681 rdev->wiphy.wowlan.tcp->data_interval_max || 7716 rdev->wiphy.wowlan->tcp->data_interval_max ||
7682 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0) 7717 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0)
7683 return -EINVAL; 7718 return -EINVAL;
7684 7719
7685 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]); 7720 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]);
7686 if (wake_size > rdev->wiphy.wowlan.tcp->wake_payload_max) 7721 if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max)
7687 return -EINVAL; 7722 return -EINVAL;
7688 7723
7689 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]); 7724 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]);
@@ -7698,13 +7733,13 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
7698 7733
7699 if (!tok->len || tokens_size % tok->len) 7734 if (!tok->len || tokens_size % tok->len)
7700 return -EINVAL; 7735 return -EINVAL;
7701 if (!rdev->wiphy.wowlan.tcp->tok) 7736 if (!rdev->wiphy.wowlan->tcp->tok)
7702 return -EINVAL; 7737 return -EINVAL;
7703 if (tok->len > rdev->wiphy.wowlan.tcp->tok->max_len) 7738 if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len)
7704 return -EINVAL; 7739 return -EINVAL;
7705 if (tok->len < rdev->wiphy.wowlan.tcp->tok->min_len) 7740 if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len)
7706 return -EINVAL; 7741 return -EINVAL;
7707 if (tokens_size > rdev->wiphy.wowlan.tcp->tok->bufsize) 7742 if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize)
7708 return -EINVAL; 7743 return -EINVAL;
7709 if (tok->offset + tok->len > data_size) 7744 if (tok->offset + tok->len > data_size)
7710 return -EINVAL; 7745 return -EINVAL;
@@ -7712,7 +7747,7 @@ static int nl80211_parse_wowlan_tcp(struct cfg80211_registered_device *rdev,
7712 7747
7713 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) { 7748 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) {
7714 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]); 7749 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]);
7715 if (!rdev->wiphy.wowlan.tcp->seq) 7750 if (!rdev->wiphy.wowlan->tcp->seq)
7716 return -EINVAL; 7751 return -EINVAL;
7717 if (seq->len == 0 || seq->len > 4) 7752 if (seq->len == 0 || seq->len > 4)
7718 return -EINVAL; 7753 return -EINVAL;
@@ -7793,12 +7828,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
7793 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; 7828 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG];
7794 struct cfg80211_wowlan new_triggers = {}; 7829 struct cfg80211_wowlan new_triggers = {};
7795 struct cfg80211_wowlan *ntrig; 7830 struct cfg80211_wowlan *ntrig;
7796 struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; 7831 const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan;
7797 int err, i; 7832 int err, i;
7798 bool prev_enabled = rdev->wiphy.wowlan_config; 7833 bool prev_enabled = rdev->wiphy.wowlan_config;
7799 7834
7800 if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns && 7835 if (!wowlan)
7801 !rdev->wiphy.wowlan.tcp)
7802 return -EOPNOTSUPP; 7836 return -EOPNOTSUPP;
7803 7837
7804 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { 7838 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) {
@@ -9315,31 +9349,27 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
9315 NL80211_CMD_DISASSOCIATE, gfp); 9349 NL80211_CMD_DISASSOCIATE, gfp);
9316} 9350}
9317 9351
9318void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, 9352void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf,
9319 size_t len) 9353 size_t len)
9320{ 9354{
9321 struct wireless_dev *wdev = dev->ieee80211_ptr; 9355 struct wireless_dev *wdev = dev->ieee80211_ptr;
9322 struct wiphy *wiphy = wdev->wiphy; 9356 struct wiphy *wiphy = wdev->wiphy;
9323 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 9357 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9358 const struct ieee80211_mgmt *mgmt = (void *)buf;
9359 u32 cmd;
9324 9360
9325 trace_cfg80211_send_unprot_deauth(dev); 9361 if (WARN_ON(len < 2))
9326 nl80211_send_mlme_event(rdev, dev, buf, len, 9362 return;
9327 NL80211_CMD_UNPROT_DEAUTHENTICATE, GFP_ATOMIC);
9328}
9329EXPORT_SYMBOL(cfg80211_send_unprot_deauth);
9330 9363
9331void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, 9364 if (ieee80211_is_deauth(mgmt->frame_control))
9332 size_t len) 9365 cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE;
9333{ 9366 else
9334 struct wireless_dev *wdev = dev->ieee80211_ptr; 9367 cmd = NL80211_CMD_UNPROT_DISASSOCIATE;
9335 struct wiphy *wiphy = wdev->wiphy;
9336 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
9337 9368
9338 trace_cfg80211_send_unprot_disassoc(dev); 9369 trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len);
9339 nl80211_send_mlme_event(rdev, dev, buf, len, 9370 nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC);
9340 NL80211_CMD_UNPROT_DISASSOCIATE, GFP_ATOMIC);
9341} 9371}
9342EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); 9372EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt);
9343 9373
9344static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 9374static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
9345 struct net_device *netdev, int cmd, 9375 struct net_device *netdev, int cmd,
@@ -9850,7 +9880,6 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
9850 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 9880 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
9851 struct sk_buff *msg; 9881 struct sk_buff *msg;
9852 void *hdr; 9882 void *hdr;
9853 int err;
9854 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid); 9883 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid);
9855 9884
9856 if (!nlportid) 9885 if (!nlportid)
@@ -9871,12 +9900,7 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
9871 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) 9900 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr))
9872 goto nla_put_failure; 9901 goto nla_put_failure;
9873 9902
9874 err = genlmsg_end(msg, hdr); 9903 genlmsg_end(msg, hdr);
9875 if (err < 0) {
9876 nlmsg_free(msg);
9877 return true;
9878 }
9879
9880 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); 9904 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid);
9881 return true; 9905 return true;
9882 9906
@@ -10319,10 +10343,7 @@ nl80211_radar_notify(struct cfg80211_registered_device *rdev,
10319 if (nl80211_send_chandef(msg, chandef)) 10343 if (nl80211_send_chandef(msg, chandef))
10320 goto nla_put_failure; 10344 goto nla_put_failure;
10321 10345
10322 if (genlmsg_end(msg, hdr) < 0) { 10346 genlmsg_end(msg, hdr);
10323 nlmsg_free(msg);
10324 return;
10325 }
10326 10347
10327 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10348 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
10328 nl80211_mlme_mcgrp.id, gfp); 10349 nl80211_mlme_mcgrp.id, gfp);
@@ -10388,7 +10409,6 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
10388 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 10409 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
10389 struct sk_buff *msg; 10410 struct sk_buff *msg;
10390 void *hdr; 10411 void *hdr;
10391 int err;
10392 10412
10393 trace_cfg80211_probe_status(dev, addr, cookie, acked); 10413 trace_cfg80211_probe_status(dev, addr, cookie, acked);
10394 10414
@@ -10410,11 +10430,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
10410 (acked && nla_put_flag(msg, NL80211_ATTR_ACK))) 10430 (acked && nla_put_flag(msg, NL80211_ATTR_ACK)))
10411 goto nla_put_failure; 10431 goto nla_put_failure;
10412 10432
10413 err = genlmsg_end(msg, hdr); 10433 genlmsg_end(msg, hdr);
10414 if (err < 0) {
10415 nlmsg_free(msg);
10416 return;
10417 }
10418 10434
10419 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10435 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
10420 nl80211_mlme_mcgrp.id, gfp); 10436 nl80211_mlme_mcgrp.id, gfp);
@@ -10480,7 +10496,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
10480 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 10496 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
10481 struct sk_buff *msg; 10497 struct sk_buff *msg;
10482 void *hdr; 10498 void *hdr;
10483 int err, size = 200; 10499 int size = 200;
10484 10500
10485 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup); 10501 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup);
10486 10502
@@ -10566,9 +10582,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
10566 nla_nest_end(msg, reasons); 10582 nla_nest_end(msg, reasons);
10567 } 10583 }
10568 10584
10569 err = genlmsg_end(msg, hdr); 10585 genlmsg_end(msg, hdr);
10570 if (err < 0)
10571 goto free_msg;
10572 10586
10573 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10587 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
10574 nl80211_mlme_mcgrp.id, gfp); 10588 nl80211_mlme_mcgrp.id, gfp);
@@ -10588,7 +10602,6 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
10588 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 10602 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
10589 struct sk_buff *msg; 10603 struct sk_buff *msg;
10590 void *hdr; 10604 void *hdr;
10591 int err;
10592 10605
10593 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper, 10606 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper,
10594 reason_code); 10607 reason_code);
@@ -10611,11 +10624,7 @@ void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer,
10611 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code))) 10624 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code)))
10612 goto nla_put_failure; 10625 goto nla_put_failure;
10613 10626
10614 err = genlmsg_end(msg, hdr); 10627 genlmsg_end(msg, hdr);
10615 if (err < 0) {
10616 nlmsg_free(msg);
10617 return;
10618 }
10619 10628
10620 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10629 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
10621 nl80211_mlme_mcgrp.id, gfp); 10630 nl80211_mlme_mcgrp.id, gfp);
@@ -10673,7 +10682,6 @@ void cfg80211_ft_event(struct net_device *netdev,
10673 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 10682 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
10674 struct sk_buff *msg; 10683 struct sk_buff *msg;
10675 void *hdr; 10684 void *hdr;
10676 int err;
10677 10685
10678 trace_cfg80211_ft_event(wiphy, netdev, ft_event); 10686 trace_cfg80211_ft_event(wiphy, netdev, ft_event);
10679 10687
@@ -10699,11 +10707,7 @@ void cfg80211_ft_event(struct net_device *netdev,
10699 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, 10707 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len,
10700 ft_event->ric_ies); 10708 ft_event->ric_ies);
10701 10709
10702 err = genlmsg_end(msg, hdr); 10710 genlmsg_end(msg, hdr);
10703 if (err < 0) {
10704 nlmsg_free(msg);
10705 return;
10706 }
10707 10711
10708 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10712 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
10709 nl80211_mlme_mcgrp.id, GFP_KERNEL); 10713 nl80211_mlme_mcgrp.id, GFP_KERNEL);
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index e1d6749234c6..5a24c986f34b 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1345,7 +1345,7 @@ get_reg_request_treatment(struct wiphy *wiphy,
1345 return REG_REQ_OK; 1345 return REG_REQ_OK;
1346 return REG_REQ_ALREADY_SET; 1346 return REG_REQ_ALREADY_SET;
1347 } 1347 }
1348 return 0; 1348 return REG_REQ_OK;
1349 case NL80211_REGDOM_SET_BY_DRIVER: 1349 case NL80211_REGDOM_SET_BY_DRIVER:
1350 if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { 1350 if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) {
1351 if (regdom_changes(pending_request->alpha2)) 1351 if (regdom_changes(pending_request->alpha2))
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 81be95f3be74..ae7e2cbf45cb 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -1,5 +1,7 @@
1/* 1/*
2 * SME code for cfg80211's connect emulation. 2 * SME code for cfg80211
3 * both driver SME event handling and the SME implementation
4 * (for nl80211's connect() and wext)
3 * 5 *
4 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright (C) 2009 Intel Corporation. All rights reserved. 7 * Copyright (C) 2009 Intel Corporation. All rights reserved.
@@ -18,18 +20,24 @@
18#include "reg.h" 20#include "reg.h"
19#include "rdev-ops.h" 21#include "rdev-ops.h"
20 22
23/*
24 * Software SME in cfg80211, using auth/assoc/deauth calls to the
25 * driver. This is is for implementing nl80211's connect/disconnect
26 * and wireless extensions (if configured.)
27 */
28
21struct cfg80211_conn { 29struct cfg80211_conn {
22 struct cfg80211_connect_params params; 30 struct cfg80211_connect_params params;
23 /* these are sub-states of the _CONNECTING sme_state */ 31 /* these are sub-states of the _CONNECTING sme_state */
24 enum { 32 enum {
25 CFG80211_CONN_IDLE,
26 CFG80211_CONN_SCANNING, 33 CFG80211_CONN_SCANNING,
27 CFG80211_CONN_SCAN_AGAIN, 34 CFG80211_CONN_SCAN_AGAIN,
28 CFG80211_CONN_AUTHENTICATE_NEXT, 35 CFG80211_CONN_AUTHENTICATE_NEXT,
29 CFG80211_CONN_AUTHENTICATING, 36 CFG80211_CONN_AUTHENTICATING,
30 CFG80211_CONN_ASSOCIATE_NEXT, 37 CFG80211_CONN_ASSOCIATE_NEXT,
31 CFG80211_CONN_ASSOCIATING, 38 CFG80211_CONN_ASSOCIATING,
32 CFG80211_CONN_DEAUTH_ASSOC_FAIL, 39 CFG80211_CONN_DEAUTH,
40 CFG80211_CONN_CONNECTED,
33 } state; 41 } state;
34 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; 42 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
35 u8 *ie; 43 u8 *ie;
@@ -37,39 +45,16 @@ struct cfg80211_conn {
37 bool auto_auth, prev_bssid_valid; 45 bool auto_auth, prev_bssid_valid;
38}; 46};
39 47
40static bool cfg80211_is_all_idle(void) 48static void cfg80211_sme_free(struct wireless_dev *wdev)
41{ 49{
42 struct cfg80211_registered_device *rdev; 50 if (!wdev->conn)
43 struct wireless_dev *wdev; 51 return;
44 bool is_all_idle = true;
45
46 /*
47 * All devices must be idle as otherwise if you are actively
48 * scanning some new beacon hints could be learned and would
49 * count as new regulatory hints.
50 */
51 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
52 list_for_each_entry(wdev, &rdev->wdev_list, list) {
53 wdev_lock(wdev);
54 if (wdev->sme_state != CFG80211_SME_IDLE)
55 is_all_idle = false;
56 wdev_unlock(wdev);
57 }
58 }
59
60 return is_all_idle;
61}
62 52
63static void disconnect_work(struct work_struct *work) 53 kfree(wdev->conn->ie);
64{ 54 kfree(wdev->conn);
65 rtnl_lock(); 55 wdev->conn = NULL;
66 if (cfg80211_is_all_idle())
67 regulatory_hint_disconnect();
68 rtnl_unlock();
69} 56}
70 57
71static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
72
73static int cfg80211_conn_scan(struct wireless_dev *wdev) 58static int cfg80211_conn_scan(struct wireless_dev *wdev)
74{ 59{
75 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 60 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -164,6 +149,9 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
164 params = &wdev->conn->params; 149 params = &wdev->conn->params;
165 150
166 switch (wdev->conn->state) { 151 switch (wdev->conn->state) {
152 case CFG80211_CONN_SCANNING:
153 /* didn't find it during scan ... */
154 return -ENOENT;
167 case CFG80211_CONN_SCAN_AGAIN: 155 case CFG80211_CONN_SCAN_AGAIN:
168 return cfg80211_conn_scan(wdev); 156 return cfg80211_conn_scan(wdev);
169 case CFG80211_CONN_AUTHENTICATE_NEXT: 157 case CFG80211_CONN_AUTHENTICATE_NEXT:
@@ -200,12 +188,11 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
200 WLAN_REASON_DEAUTH_LEAVING, 188 WLAN_REASON_DEAUTH_LEAVING,
201 false); 189 false);
202 return err; 190 return err;
203 case CFG80211_CONN_DEAUTH_ASSOC_FAIL: 191 case CFG80211_CONN_DEAUTH:
204 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 192 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
205 NULL, 0, 193 NULL, 0,
206 WLAN_REASON_DEAUTH_LEAVING, false); 194 WLAN_REASON_DEAUTH_LEAVING, false);
207 /* return an error so that we call __cfg80211_connect_result() */ 195 return 0;
208 return -EINVAL;
209 default: 196 default:
210 return 0; 197 return 0;
211 } 198 }
@@ -229,7 +216,8 @@ void cfg80211_conn_work(struct work_struct *work)
229 wdev_unlock(wdev); 216 wdev_unlock(wdev);
230 continue; 217 continue;
231 } 218 }
232 if (wdev->sme_state != CFG80211_SME_CONNECTING || !wdev->conn) { 219 if (!wdev->conn ||
220 wdev->conn->state == CFG80211_CONN_CONNECTED) {
233 wdev_unlock(wdev); 221 wdev_unlock(wdev);
234 continue; 222 continue;
235 } 223 }
@@ -237,12 +225,14 @@ void cfg80211_conn_work(struct work_struct *work)
237 memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN); 225 memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN);
238 bssid = bssid_buf; 226 bssid = bssid_buf;
239 } 227 }
240 if (cfg80211_conn_do_work(wdev)) 228 if (cfg80211_conn_do_work(wdev)) {
241 __cfg80211_connect_result( 229 __cfg80211_connect_result(
242 wdev->netdev, bssid, 230 wdev->netdev, bssid,
243 NULL, 0, NULL, 0, 231 NULL, 0, NULL, 0,
244 WLAN_STATUS_UNSPECIFIED_FAILURE, 232 WLAN_STATUS_UNSPECIFIED_FAILURE,
245 false, NULL); 233 false, NULL);
234 cfg80211_sme_free(wdev);
235 }
246 wdev_unlock(wdev); 236 wdev_unlock(wdev);
247 } 237 }
248 238
@@ -286,9 +276,6 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
286 276
287 ASSERT_WDEV_LOCK(wdev); 277 ASSERT_WDEV_LOCK(wdev);
288 278
289 if (wdev->sme_state != CFG80211_SME_CONNECTING)
290 return;
291
292 if (!wdev->conn) 279 if (!wdev->conn)
293 return; 280 return;
294 281
@@ -297,20 +284,10 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
297 return; 284 return;
298 285
299 bss = cfg80211_get_conn_bss(wdev); 286 bss = cfg80211_get_conn_bss(wdev);
300 if (bss) { 287 if (bss)
301 cfg80211_put_bss(&rdev->wiphy, bss); 288 cfg80211_put_bss(&rdev->wiphy, bss);
302 } else { 289 else
303 /* not found */ 290 schedule_work(&rdev->conn_work);
304 if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)
305 schedule_work(&rdev->conn_work);
306 else
307 __cfg80211_connect_result(
308 wdev->netdev,
309 wdev->conn->params.bssid,
310 NULL, 0, NULL, 0,
311 WLAN_STATUS_UNSPECIFIED_FAILURE,
312 false, NULL);
313 }
314} 291}
315 292
316void cfg80211_sme_scan_done(struct net_device *dev) 293void cfg80211_sme_scan_done(struct net_device *dev)
@@ -322,10 +299,8 @@ void cfg80211_sme_scan_done(struct net_device *dev)
322 wdev_unlock(wdev); 299 wdev_unlock(wdev);
323} 300}
324 301
325void cfg80211_sme_rx_auth(struct net_device *dev, 302void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len)
326 const u8 *buf, size_t len)
327{ 303{
328 struct wireless_dev *wdev = dev->ieee80211_ptr;
329 struct wiphy *wiphy = wdev->wiphy; 304 struct wiphy *wiphy = wdev->wiphy;
330 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 305 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
331 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 306 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
@@ -333,11 +308,7 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
333 308
334 ASSERT_WDEV_LOCK(wdev); 309 ASSERT_WDEV_LOCK(wdev);
335 310
336 /* should only RX auth frames when connecting */ 311 if (!wdev->conn || wdev->conn->state == CFG80211_CONN_CONNECTED)
337 if (wdev->sme_state != CFG80211_SME_CONNECTING)
338 return;
339
340 if (WARN_ON(!wdev->conn))
341 return; 312 return;
342 313
343 if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG && 314 if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG &&
@@ -366,46 +337,226 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
366 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; 337 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
367 schedule_work(&rdev->conn_work); 338 schedule_work(&rdev->conn_work);
368 } else if (status_code != WLAN_STATUS_SUCCESS) { 339 } else if (status_code != WLAN_STATUS_SUCCESS) {
369 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 340 __cfg80211_connect_result(wdev->netdev, mgmt->bssid,
341 NULL, 0, NULL, 0,
370 status_code, false, NULL); 342 status_code, false, NULL);
371 } else if (wdev->sme_state == CFG80211_SME_CONNECTING && 343 } else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
372 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
373 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 344 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
374 schedule_work(&rdev->conn_work); 345 schedule_work(&rdev->conn_work);
375 } 346 }
376} 347}
377 348
378bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev) 349bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status)
379{ 350{
380 struct wiphy *wiphy = wdev->wiphy; 351 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
381 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
382 352
383 if (WARN_ON(!wdev->conn)) 353 if (!wdev->conn)
384 return false; 354 return false;
385 355
386 if (!wdev->conn->prev_bssid_valid) 356 if (status == WLAN_STATUS_SUCCESS) {
357 wdev->conn->state = CFG80211_CONN_CONNECTED;
387 return false; 358 return false;
359 }
388 360
389 /* 361 if (wdev->conn->prev_bssid_valid) {
390 * Some stupid APs don't accept reassoc, so we 362 /*
391 * need to fall back to trying regular assoc. 363 * Some stupid APs don't accept reassoc, so we
392 */ 364 * need to fall back to trying regular assoc;
393 wdev->conn->prev_bssid_valid = false; 365 * return true so no event is sent to userspace.
394 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 366 */
367 wdev->conn->prev_bssid_valid = false;
368 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
369 schedule_work(&rdev->conn_work);
370 return true;
371 }
372
373 wdev->conn->state = CFG80211_CONN_DEAUTH;
395 schedule_work(&rdev->conn_work); 374 schedule_work(&rdev->conn_work);
375 return false;
376}
396 377
397 return true; 378void cfg80211_sme_deauth(struct wireless_dev *wdev)
379{
380 cfg80211_sme_free(wdev);
398} 381}
399 382
400void cfg80211_sme_failed_assoc(struct wireless_dev *wdev) 383void cfg80211_sme_auth_timeout(struct wireless_dev *wdev)
401{ 384{
402 struct wiphy *wiphy = wdev->wiphy; 385 cfg80211_sme_free(wdev);
403 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 386}
404 387
405 wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL; 388void cfg80211_sme_disassoc(struct wireless_dev *wdev)
389{
390 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
391
392 if (!wdev->conn)
393 return;
394
395 wdev->conn->state = CFG80211_CONN_DEAUTH;
406 schedule_work(&rdev->conn_work); 396 schedule_work(&rdev->conn_work);
407} 397}
408 398
399void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
400{
401 cfg80211_sme_disassoc(wdev);
402}
403
404static int cfg80211_sme_connect(struct wireless_dev *wdev,
405 struct cfg80211_connect_params *connect,
406 const u8 *prev_bssid)
407{
408 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
409 struct cfg80211_bss *bss;
410 int err;
411
412 if (!rdev->ops->auth || !rdev->ops->assoc)
413 return -EOPNOTSUPP;
414
415 if (wdev->current_bss)
416 return -EALREADY;
417
418 if (WARN_ON(wdev->conn))
419 return -EINPROGRESS;
420
421 wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
422 if (!wdev->conn)
423 return -ENOMEM;
424
425 /*
426 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
427 */
428 memcpy(&wdev->conn->params, connect, sizeof(*connect));
429 if (connect->bssid) {
430 wdev->conn->params.bssid = wdev->conn->bssid;
431 memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
432 }
433
434 if (connect->ie) {
435 wdev->conn->ie = kmemdup(connect->ie, connect->ie_len,
436 GFP_KERNEL);
437 wdev->conn->params.ie = wdev->conn->ie;
438 if (!wdev->conn->ie) {
439 kfree(wdev->conn);
440 wdev->conn = NULL;
441 return -ENOMEM;
442 }
443 }
444
445 if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
446 wdev->conn->auto_auth = true;
447 /* start with open system ... should mostly work */
448 wdev->conn->params.auth_type =
449 NL80211_AUTHTYPE_OPEN_SYSTEM;
450 } else {
451 wdev->conn->auto_auth = false;
452 }
453
454 wdev->conn->params.ssid = wdev->ssid;
455 wdev->conn->params.ssid_len = connect->ssid_len;
456
457 /* see if we have the bss already */
458 bss = cfg80211_get_conn_bss(wdev);
459
460 if (prev_bssid) {
461 memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
462 wdev->conn->prev_bssid_valid = true;
463 }
464
465 /* we're good if we have a matching bss struct */
466 if (bss) {
467 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
468 err = cfg80211_conn_do_work(wdev);
469 cfg80211_put_bss(wdev->wiphy, bss);
470 } else {
471 /* otherwise we'll need to scan for the AP first */
472 err = cfg80211_conn_scan(wdev);
473
474 /*
475 * If we can't scan right now, then we need to scan again
476 * after the current scan finished, since the parameters
477 * changed (unless we find a good AP anyway).
478 */
479 if (err == -EBUSY) {
480 err = 0;
481 wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
482 }
483 }
484
485 if (err)
486 cfg80211_sme_free(wdev);
487
488 return err;
489}
490
491static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason)
492{
493 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
494 int err;
495
496 if (!wdev->conn)
497 return 0;
498
499 if (!rdev->ops->deauth)
500 return -EOPNOTSUPP;
501
502 if (wdev->conn->state == CFG80211_CONN_SCANNING ||
503 wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) {
504 err = 0;
505 goto out;
506 }
507
508 /* wdev->conn->params.bssid must be set if > SCANNING */
509 err = cfg80211_mlme_deauth(rdev, wdev->netdev,
510 wdev->conn->params.bssid,
511 NULL, 0, reason, false);
512 out:
513 cfg80211_sme_free(wdev);
514 return err;
515}
516
517/*
518 * code shared for in-device and software SME
519 */
520
521static bool cfg80211_is_all_idle(void)
522{
523 struct cfg80211_registered_device *rdev;
524 struct wireless_dev *wdev;
525 bool is_all_idle = true;
526
527 /*
528 * All devices must be idle as otherwise if you are actively
529 * scanning some new beacon hints could be learned and would
530 * count as new regulatory hints.
531 */
532 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
533 list_for_each_entry(wdev, &rdev->wdev_list, list) {
534 wdev_lock(wdev);
535 if (wdev->conn || wdev->current_bss)
536 is_all_idle = false;
537 wdev_unlock(wdev);
538 }
539 }
540
541 return is_all_idle;
542}
543
544static void disconnect_work(struct work_struct *work)
545{
546 rtnl_lock();
547 if (cfg80211_is_all_idle())
548 regulatory_hint_disconnect();
549 rtnl_unlock();
550}
551
552static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work);
553
554
555/*
556 * API calls for drivers implementing connect/disconnect and
557 * SME event handling
558 */
559
409void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 560void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
410 const u8 *req_ie, size_t req_ie_len, 561 const u8 *req_ie, size_t req_ie_len,
411 const u8 *resp_ie, size_t resp_ie_len, 562 const u8 *resp_ie, size_t resp_ie_len,
@@ -424,9 +575,6 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
424 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 575 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
425 return; 576 return;
426 577
427 if (wdev->sme_state != CFG80211_SME_CONNECTING)
428 return;
429
430 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, 578 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev,
431 bssid, req_ie, req_ie_len, 579 bssid, req_ie, req_ie_len,
432 resp_ie, resp_ie_len, 580 resp_ie, resp_ie_len,
@@ -463,15 +611,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
463 wdev->current_bss = NULL; 611 wdev->current_bss = NULL;
464 } 612 }
465 613
466 if (wdev->conn)
467 wdev->conn->state = CFG80211_CONN_IDLE;
468
469 if (status != WLAN_STATUS_SUCCESS) { 614 if (status != WLAN_STATUS_SUCCESS) {
470 wdev->sme_state = CFG80211_SME_IDLE;
471 if (wdev->conn)
472 kfree(wdev->conn->ie);
473 kfree(wdev->conn);
474 wdev->conn = NULL;
475 kfree(wdev->connect_keys); 615 kfree(wdev->connect_keys);
476 wdev->connect_keys = NULL; 616 wdev->connect_keys = NULL;
477 wdev->ssid_len = 0; 617 wdev->ssid_len = 0;
@@ -480,21 +620,16 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
480 } 620 }
481 621
482 if (!bss) 622 if (!bss)
483 bss = cfg80211_get_bss(wdev->wiphy, 623 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
484 wdev->conn ? wdev->conn->params.channel :
485 NULL,
486 bssid,
487 wdev->ssid, wdev->ssid_len, 624 wdev->ssid, wdev->ssid_len,
488 WLAN_CAPABILITY_ESS, 625 WLAN_CAPABILITY_ESS,
489 WLAN_CAPABILITY_ESS); 626 WLAN_CAPABILITY_ESS);
490
491 if (WARN_ON(!bss)) 627 if (WARN_ON(!bss))
492 return; 628 return;
493 629
494 cfg80211_hold_bss(bss_from_pub(bss)); 630 cfg80211_hold_bss(bss_from_pub(bss));
495 wdev->current_bss = bss_from_pub(bss); 631 wdev->current_bss = bss_from_pub(bss);
496 632
497 wdev->sme_state = CFG80211_SME_CONNECTED;
498 cfg80211_upload_connect_keys(wdev); 633 cfg80211_upload_connect_keys(wdev);
499 634
500 rcu_read_lock(); 635 rcu_read_lock();
@@ -530,8 +665,6 @@ void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
530 struct cfg80211_event *ev; 665 struct cfg80211_event *ev;
531 unsigned long flags; 666 unsigned long flags;
532 667
533 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
534
535 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); 668 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
536 if (!ev) 669 if (!ev)
537 return; 670 return;
@@ -572,13 +705,8 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
572 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 705 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
573 goto out; 706 goto out;
574 707
575 if (wdev->sme_state != CFG80211_SME_CONNECTED) 708 if (WARN_ON(!wdev->current_bss))
576 goto out;
577
578 /* internal error -- how did we get to CONNECTED w/o BSS? */
579 if (WARN_ON(!wdev->current_bss)) {
580 goto out; 709 goto out;
581 }
582 710
583 cfg80211_unhold_bss(wdev->current_bss); 711 cfg80211_unhold_bss(wdev->current_bss);
584 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); 712 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
@@ -628,8 +756,6 @@ void cfg80211_roamed(struct net_device *dev,
628 struct wireless_dev *wdev = dev->ieee80211_ptr; 756 struct wireless_dev *wdev = dev->ieee80211_ptr;
629 struct cfg80211_bss *bss; 757 struct cfg80211_bss *bss;
630 758
631 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
632
633 bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, 759 bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid,
634 wdev->ssid_len, WLAN_CAPABILITY_ESS, 760 wdev->ssid_len, WLAN_CAPABILITY_ESS,
635 WLAN_CAPABILITY_ESS); 761 WLAN_CAPABILITY_ESS);
@@ -651,8 +777,6 @@ void cfg80211_roamed_bss(struct net_device *dev,
651 struct cfg80211_event *ev; 777 struct cfg80211_event *ev;
652 unsigned long flags; 778 unsigned long flags;
653 779
654 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
655
656 if (WARN_ON(!bss)) 780 if (WARN_ON(!bss))
657 return; 781 return;
658 782
@@ -694,25 +818,14 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
694 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 818 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT))
695 return; 819 return;
696 820
697 if (wdev->sme_state != CFG80211_SME_CONNECTED)
698 return;
699
700 if (wdev->current_bss) { 821 if (wdev->current_bss) {
701 cfg80211_unhold_bss(wdev->current_bss); 822 cfg80211_unhold_bss(wdev->current_bss);
702 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); 823 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
703 } 824 }
704 825
705 wdev->current_bss = NULL; 826 wdev->current_bss = NULL;
706 wdev->sme_state = CFG80211_SME_IDLE;
707 wdev->ssid_len = 0; 827 wdev->ssid_len = 0;
708 828
709 if (wdev->conn) {
710 kfree(wdev->conn->ie);
711 wdev->conn->ie = NULL;
712 kfree(wdev->conn);
713 wdev->conn = NULL;
714 }
715
716 nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); 829 nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
717 830
718 /* 831 /*
@@ -741,8 +854,6 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
741 struct cfg80211_event *ev; 854 struct cfg80211_event *ev;
742 unsigned long flags; 855 unsigned long flags;
743 856
744 CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED);
745
746 ev = kzalloc(sizeof(*ev) + ie_len, gfp); 857 ev = kzalloc(sizeof(*ev) + ie_len, gfp);
747 if (!ev) 858 if (!ev)
748 return; 859 return;
@@ -760,6 +871,9 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason,
760} 871}
761EXPORT_SYMBOL(cfg80211_disconnected); 872EXPORT_SYMBOL(cfg80211_disconnected);
762 873
874/*
875 * API calls for nl80211/wext compatibility code
876 */
763int cfg80211_connect(struct cfg80211_registered_device *rdev, 877int cfg80211_connect(struct cfg80211_registered_device *rdev,
764 struct net_device *dev, 878 struct net_device *dev,
765 struct cfg80211_connect_params *connect, 879 struct cfg80211_connect_params *connect,
@@ -767,14 +881,10 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
767 const u8 *prev_bssid) 881 const u8 *prev_bssid)
768{ 882{
769 struct wireless_dev *wdev = dev->ieee80211_ptr; 883 struct wireless_dev *wdev = dev->ieee80211_ptr;
770 struct cfg80211_bss *bss = NULL;
771 int err; 884 int err;
772 885
773 ASSERT_WDEV_LOCK(wdev); 886 ASSERT_WDEV_LOCK(wdev);
774 887
775 if (wdev->sme_state != CFG80211_SME_IDLE)
776 return -EALREADY;
777
778 if (WARN_ON(wdev->connect_keys)) { 888 if (WARN_ON(wdev->connect_keys)) {
779 kfree(wdev->connect_keys); 889 kfree(wdev->connect_keys);
780 wdev->connect_keys = NULL; 890 wdev->connect_keys = NULL;
@@ -810,105 +920,22 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev,
810 } 920 }
811 } 921 }
812 922
813 if (!rdev->ops->connect) { 923 wdev->connect_keys = connkeys;
814 if (!rdev->ops->auth || !rdev->ops->assoc) 924 memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
815 return -EOPNOTSUPP; 925 wdev->ssid_len = connect->ssid_len;
816
817 if (WARN_ON(wdev->conn))
818 return -EINPROGRESS;
819
820 wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL);
821 if (!wdev->conn)
822 return -ENOMEM;
823
824 /*
825 * Copy all parameters, and treat explicitly IEs, BSSID, SSID.
826 */
827 memcpy(&wdev->conn->params, connect, sizeof(*connect));
828 if (connect->bssid) {
829 wdev->conn->params.bssid = wdev->conn->bssid;
830 memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN);
831 }
832 926
833 if (connect->ie) { 927 if (!rdev->ops->connect)
834 wdev->conn->ie = kmemdup(connect->ie, connect->ie_len, 928 err = cfg80211_sme_connect(wdev, connect, prev_bssid);
835 GFP_KERNEL); 929 else
836 wdev->conn->params.ie = wdev->conn->ie;
837 if (!wdev->conn->ie) {
838 kfree(wdev->conn);
839 wdev->conn = NULL;
840 return -ENOMEM;
841 }
842 }
843
844 if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) {
845 wdev->conn->auto_auth = true;
846 /* start with open system ... should mostly work */
847 wdev->conn->params.auth_type =
848 NL80211_AUTHTYPE_OPEN_SYSTEM;
849 } else {
850 wdev->conn->auto_auth = false;
851 }
852
853 memcpy(wdev->ssid, connect->ssid, connect->ssid_len);
854 wdev->ssid_len = connect->ssid_len;
855 wdev->conn->params.ssid = wdev->ssid;
856 wdev->conn->params.ssid_len = connect->ssid_len;
857
858 /* see if we have the bss already */
859 bss = cfg80211_get_conn_bss(wdev);
860
861 wdev->sme_state = CFG80211_SME_CONNECTING;
862 wdev->connect_keys = connkeys;
863
864 if (prev_bssid) {
865 memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN);
866 wdev->conn->prev_bssid_valid = true;
867 }
868
869 /* we're good if we have a matching bss struct */
870 if (bss) {
871 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
872 err = cfg80211_conn_do_work(wdev);
873 cfg80211_put_bss(wdev->wiphy, bss);
874 } else {
875 /* otherwise we'll need to scan for the AP first */
876 err = cfg80211_conn_scan(wdev);
877 /*
878 * If we can't scan right now, then we need to scan again
879 * after the current scan finished, since the parameters
880 * changed (unless we find a good AP anyway).
881 */
882 if (err == -EBUSY) {
883 err = 0;
884 wdev->conn->state = CFG80211_CONN_SCAN_AGAIN;
885 }
886 }
887 if (err) {
888 kfree(wdev->conn->ie);
889 kfree(wdev->conn);
890 wdev->conn = NULL;
891 wdev->sme_state = CFG80211_SME_IDLE;
892 wdev->connect_keys = NULL;
893 wdev->ssid_len = 0;
894 }
895
896 return err;
897 } else {
898 wdev->sme_state = CFG80211_SME_CONNECTING;
899 wdev->connect_keys = connkeys;
900 err = rdev_connect(rdev, dev, connect); 930 err = rdev_connect(rdev, dev, connect);
901 if (err) {
902 wdev->connect_keys = NULL;
903 wdev->sme_state = CFG80211_SME_IDLE;
904 return err;
905 }
906 931
907 memcpy(wdev->ssid, connect->ssid, connect->ssid_len); 932 if (err) {
908 wdev->ssid_len = connect->ssid_len; 933 wdev->connect_keys = NULL;
909 934 wdev->ssid_len = 0;
910 return 0; 935 return err;
911 } 936 }
937
938 return 0;
912} 939}
913 940
914int cfg80211_disconnect(struct cfg80211_registered_device *rdev, 941int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
@@ -919,78 +946,17 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
919 946
920 ASSERT_WDEV_LOCK(wdev); 947 ASSERT_WDEV_LOCK(wdev);
921 948
922 if (wdev->sme_state == CFG80211_SME_IDLE)
923 return -EINVAL;
924
925 kfree(wdev->connect_keys); 949 kfree(wdev->connect_keys);
926 wdev->connect_keys = NULL; 950 wdev->connect_keys = NULL;
927 951
928 if (!rdev->ops->disconnect) { 952 if (wdev->conn) {
929 if (!rdev->ops->deauth) 953 err = cfg80211_sme_disconnect(wdev, reason);
930 return -EOPNOTSUPP; 954 } else if (!rdev->ops->disconnect) {
931 955 cfg80211_mlme_down(rdev, dev);
932 /* was it connected by userspace SME? */ 956 err = 0;
933 if (!wdev->conn) {
934 cfg80211_mlme_down(rdev, dev);
935 goto disconnect;
936 }
937
938 if (wdev->sme_state == CFG80211_SME_CONNECTING &&
939 (wdev->conn->state == CFG80211_CONN_SCANNING ||
940 wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) {
941 wdev->sme_state = CFG80211_SME_IDLE;
942 kfree(wdev->conn->ie);
943 kfree(wdev->conn);
944 wdev->conn = NULL;
945 wdev->ssid_len = 0;
946 return 0;
947 }
948
949 /* wdev->conn->params.bssid must be set if > SCANNING */
950 err = cfg80211_mlme_deauth(rdev, dev,
951 wdev->conn->params.bssid,
952 NULL, 0, reason, false);
953 if (err)
954 return err;
955 } else { 957 } else {
956 err = rdev_disconnect(rdev, dev, reason); 958 err = rdev_disconnect(rdev, dev, reason);
957 if (err)
958 return err;
959 } 959 }
960 960
961 disconnect: 961 return err;
962 if (wdev->sme_state == CFG80211_SME_CONNECTED)
963 __cfg80211_disconnected(dev, NULL, 0, 0, false);
964 else if (wdev->sme_state == CFG80211_SME_CONNECTING)
965 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
966 WLAN_STATUS_UNSPECIFIED_FAILURE,
967 wextev, NULL);
968
969 return 0;
970}
971
972void cfg80211_sme_disassoc(struct net_device *dev,
973 struct cfg80211_internal_bss *bss)
974{
975 struct wireless_dev *wdev = dev->ieee80211_ptr;
976 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
977 u8 bssid[ETH_ALEN];
978
979 ASSERT_WDEV_LOCK(wdev);
980
981 if (!wdev->conn)
982 return;
983
984 if (wdev->conn->state == CFG80211_CONN_IDLE)
985 return;
986
987 /*
988 * Ok, so the association was made by this SME -- we don't
989 * want it any more so deauthenticate too.
990 */
991
992 memcpy(bssid, bss->pub.bssid, ETH_ALEN);
993
994 cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0,
995 WLAN_REASON_DEAUTH_LEAVING, false);
996} 962}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 23fafeae8a10..e1534baf2ebb 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -1911,24 +1911,46 @@ TRACE_EVENT(cfg80211_send_rx_assoc,
1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) 1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG)
1912); 1912);
1913 1913
1914DEFINE_EVENT(netdev_evt_only, cfg80211_send_deauth, 1914DECLARE_EVENT_CLASS(netdev_frame_event,
1915 TP_PROTO(struct net_device *netdev), 1915 TP_PROTO(struct net_device *netdev, const u8 *buf, int len),
1916 TP_ARGS(netdev) 1916 TP_ARGS(netdev, buf, len),
1917 TP_STRUCT__entry(
1918 NETDEV_ENTRY
1919 __dynamic_array(u8, frame, len)
1920 ),
1921 TP_fast_assign(
1922 NETDEV_ASSIGN;
1923 memcpy(__get_dynamic_array(frame), buf, len);
1924 ),
1925 TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x",
1926 NETDEV_PR_ARG,
1927 le16_to_cpup((__le16 *)__get_dynamic_array(frame)))
1917); 1928);
1918 1929
1919DEFINE_EVENT(netdev_evt_only, cfg80211_send_disassoc, 1930DEFINE_EVENT(netdev_frame_event, cfg80211_rx_unprot_mlme_mgmt,
1920 TP_PROTO(struct net_device *netdev), 1931 TP_PROTO(struct net_device *netdev, const u8 *buf, int len),
1921 TP_ARGS(netdev) 1932 TP_ARGS(netdev, buf, len)
1922); 1933);
1923 1934
1924DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_deauth, 1935DEFINE_EVENT(netdev_frame_event, cfg80211_rx_mlme_mgmt,
1925 TP_PROTO(struct net_device *netdev), 1936 TP_PROTO(struct net_device *netdev, const u8 *buf, int len),
1926 TP_ARGS(netdev) 1937 TP_ARGS(netdev, buf, len)
1927); 1938);
1928 1939
1929DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_disassoc, 1940TRACE_EVENT(cfg80211_tx_mlme_mgmt,
1930 TP_PROTO(struct net_device *netdev), 1941 TP_PROTO(struct net_device *netdev, const u8 *buf, int len),
1931 TP_ARGS(netdev) 1942 TP_ARGS(netdev, buf, len),
1943 TP_STRUCT__entry(
1944 NETDEV_ENTRY
1945 __dynamic_array(u8, frame, len)
1946 ),
1947 TP_fast_assign(
1948 NETDEV_ASSIGN;
1949 memcpy(__get_dynamic_array(frame), buf, len);
1950 ),
1951 TP_printk(NETDEV_PR_FMT ", ftype:0x%.2x",
1952 NETDEV_PR_ARG,
1953 le16_to_cpup((__le16 *)__get_dynamic_array(frame)))
1932); 1954);
1933 1955
1934DECLARE_EVENT_CLASS(netdev_mac_evt, 1956DECLARE_EVENT_CLASS(netdev_mac_evt,
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index a53f8404f451..14c9a2583ba0 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -89,7 +89,7 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
89 89
90 wdev_lock(wdev); 90 wdev_lock(wdev);
91 91
92 if (wdev->sme_state != CFG80211_SME_IDLE) { 92 if (wdev->conn) {
93 bool event = true; 93 bool event = true;
94 94
95 if (wdev->wext.connect.channel == chan) { 95 if (wdev->wext.connect.channel == chan) {
@@ -188,7 +188,7 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
188 188
189 err = 0; 189 err = 0;
190 190
191 if (wdev->sme_state != CFG80211_SME_IDLE) { 191 if (wdev->conn) {
192 bool event = true; 192 bool event = true;
193 193
194 if (wdev->wext.connect.ssid && len && 194 if (wdev->wext.connect.ssid && len &&
@@ -277,7 +277,7 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
277 277
278 wdev_lock(wdev); 278 wdev_lock(wdev);
279 279
280 if (wdev->sme_state != CFG80211_SME_IDLE) { 280 if (wdev->conn) {
281 err = 0; 281 err = 0;
282 /* both automatic */ 282 /* both automatic */
283 if (!bssid && !wdev->wext.connect.bssid) 283 if (!bssid && !wdev->wext.connect.bssid)
@@ -364,7 +364,7 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
364 wdev->wext.ie = ie; 364 wdev->wext.ie = ie;
365 wdev->wext.ie_len = ie_len; 365 wdev->wext.ie_len = ie_len;
366 366
367 if (wdev->sme_state != CFG80211_SME_IDLE) { 367 if (wdev->conn) {
368 err = cfg80211_disconnect(rdev, dev, 368 err = cfg80211_disconnect(rdev, dev,
369 WLAN_REASON_DEAUTH_LEAVING, false); 369 WLAN_REASON_DEAUTH_LEAVING, false);
370 if (err) 370 if (err)