Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+843 -847
+5 -6
Documentation/DocBook/80211.tmpl
··· 127 127 !Finclude/net/cfg80211.h cfg80211_ibss_params 128 128 !Finclude/net/cfg80211.h cfg80211_connect_params 129 129 !Finclude/net/cfg80211.h cfg80211_pmksa 130 - !Finclude/net/cfg80211.h cfg80211_send_rx_auth 131 - !Finclude/net/cfg80211.h cfg80211_send_auth_timeout 132 - !Finclude/net/cfg80211.h cfg80211_send_rx_assoc 133 - !Finclude/net/cfg80211.h cfg80211_send_assoc_timeout 134 - !Finclude/net/cfg80211.h cfg80211_send_deauth 135 - !Finclude/net/cfg80211.h cfg80211_send_disassoc 130 + !Finclude/net/cfg80211.h cfg80211_rx_mlme_mgmt 131 + !Finclude/net/cfg80211.h cfg80211_auth_timeout 132 + !Finclude/net/cfg80211.h cfg80211_rx_assoc_resp 133 + !Finclude/net/cfg80211.h cfg80211_assoc_timeout 134 + !Finclude/net/cfg80211.h cfg80211_tx_mlme_mgmt 136 135 !Finclude/net/cfg80211.h cfg80211_ibss_joined 137 136 !Finclude/net/cfg80211.h cfg80211_connect_result 138 137 !Finclude/net/cfg80211.h cfg80211_roamed
+32 -19
drivers/net/wireless/ath/ath6kl/cfg80211.c
··· 3175 3175 { 3176 3176 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); 3177 3177 struct ath6kl *ar = ath6kl_priv(vif->ndev); 3178 - u32 id; 3178 + u32 id, freq; 3179 3179 const struct ieee80211_mgmt *mgmt; 3180 3180 bool more_data, queued; 3181 + 3182 + /* default to the current channel, but use the one specified as argument 3183 + * if any 3184 + */ 3185 + freq = vif->ch_hint; 3186 + if (chan) 3187 + freq = chan->center_freq; 3188 + 3189 + /* never send freq zero to the firmware */ 3190 + if (WARN_ON(freq == 0)) 3191 + return -EINVAL; 3181 3192 3182 3193 mgmt = (const struct ieee80211_mgmt *) buf; 3183 3194 if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) && ··· 3199 3188 * command to allow the target to fill in the generic IEs. 3200 3189 */ 3201 3190 *cookie = 0; /* TX status not supported */ 3202 - return ath6kl_send_go_probe_resp(vif, buf, len, 3203 - chan->center_freq); 3191 + return ath6kl_send_go_probe_resp(vif, buf, len, freq); 3204 3192 } 3205 3193 3206 3194 id = vif->send_action_id++; ··· 3215 3205 3216 3206 /* AP mode Power saving processing */ 3217 3207 if (vif->nw_type == AP_NETWORK) { 3218 - queued = ath6kl_mgmt_powersave_ap(vif, 3219 - id, chan->center_freq, 3220 - wait, buf, 3221 - len, &more_data, no_cck); 3208 + queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len, 3209 + &more_data, no_cck); 3222 3210 if (queued) 3223 3211 return 0; 3224 3212 } 3225 3213 3226 - return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, 3227 - chan->center_freq, wait, 3228 - buf, len, no_cck); 3214 + return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq, 3215 + wait, buf, len, no_cck); 3229 3216 } 3230 3217 3231 3218 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, ··· 3686 3679 return NULL; 3687 3680 } 3688 3681 3682 + #ifdef CONFIG_PM 3683 + static const struct wiphy_wowlan_support ath6kl_wowlan_support = { 3684 + .flags = WIPHY_WOWLAN_MAGIC_PKT | 3685 + WIPHY_WOWLAN_DISCONNECT | 3686 + WIPHY_WOWLAN_GTK_REKEY_FAILURE | 3687 + WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 3688 + WIPHY_WOWLAN_EAP_IDENTITY_REQ | 3689 + WIPHY_WOWLAN_4WAY_HANDSHAKE, 3690 + .n_patterns = WOW_MAX_FILTERS_PER_LIST, 3691 + .pattern_min_len = 1, 3692 + .pattern_max_len = WOW_PATTERN_SIZE, 3693 + }; 3694 + #endif 3695 + 3689 3696 int ath6kl_cfg80211_init(struct ath6kl *ar) 3690 3697 { 3691 3698 struct wiphy *wiphy = ar->wiphy; ··· 3793 3772 wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); 3794 3773 3795 3774 #ifdef CONFIG_PM 3796 - wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 3797 - WIPHY_WOWLAN_DISCONNECT | 3798 - WIPHY_WOWLAN_GTK_REKEY_FAILURE | 3799 - WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 3800 - WIPHY_WOWLAN_EAP_IDENTITY_REQ | 3801 - WIPHY_WOWLAN_4WAY_HANDSHAKE; 3802 - wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; 3803 - wiphy->wowlan.pattern_min_len = 1; 3804 - wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; 3775 + wiphy->wowlan = &ath6kl_wowlan_support; 3805 3776 #endif 3806 3777 3807 3778 wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
+11 -7
drivers/net/wireless/ath/ath9k/init.c
··· 755 755 } 756 756 }; 757 757 758 + #ifdef CONFIG_PM 759 + static const struct wiphy_wowlan_support ath9k_wowlan_support = { 760 + .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, 761 + .n_patterns = MAX_NUM_USER_PATTERN, 762 + .pattern_min_len = 1, 763 + .pattern_max_len = MAX_PATTERN_SIZE, 764 + }; 765 + #endif 766 + 758 767 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) 759 768 { 760 769 struct ath_hw *ah = sc->sc_ah; ··· 811 802 812 803 #ifdef CONFIG_PM_SLEEP 813 804 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 814 - device_can_wakeup(sc->dev)) { 815 - hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 816 - WIPHY_WOWLAN_DISCONNECT; 817 - hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN; 818 - hw->wiphy->wowlan.pattern_min_len = 1; 819 - hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE; 820 - } 805 + device_can_wakeup(sc->dev)) 806 + hw->wiphy->wowlan = &ath9k_wowlan_support; 821 807 822 808 atomic_set(&sc->wow_sleep_proc_intr, -1); 823 809 atomic_set(&sc->wow_got_bmiss_intr, -1);
+12 -3
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
··· 3982 3982 struct brcmf_fil_af_params_le *af_params; 3983 3983 bool ack; 3984 3984 s32 chan_nr; 3985 + u32 freq; 3985 3986 3986 3987 brcmf_dbg(TRACE, "Enter\n"); 3987 3988 ··· 3994 3993 brcmf_err("Driver only allows MGMT packet type\n"); 3995 3994 return -EPERM; 3996 3995 } 3996 + 3997 + vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); 3997 3998 3998 3999 if (ieee80211_is_probe_resp(mgmt->frame_control)) { 3999 4000 /* Right now the only reason to get a probe response */ ··· 4012 4009 ie_offset = DOT11_MGMT_HDR_LEN + 4013 4010 DOT11_BCN_PRB_FIXED_LEN; 4014 4011 ie_len = len - ie_offset; 4015 - vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev); 4016 4012 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) 4017 4013 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif; 4018 4014 err = brcmf_vif_set_mgmt_ie(vif, ··· 4035 4033 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN); 4036 4034 /* Add the length exepted for 802.11 header */ 4037 4035 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN); 4038 - /* Add the channel */ 4039 - chan_nr = ieee80211_frequency_to_channel(chan->center_freq); 4036 + /* Add the channel. Use the one specified as parameter if any or 4037 + * the current one (got from the firmware) otherwise 4038 + */ 4039 + if (chan) 4040 + freq = chan->center_freq; 4041 + else 4042 + brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL, 4043 + &freq); 4044 + chan_nr = ieee80211_frequency_to_channel(freq); 4040 4045 af_params->channel = cpu_to_le32(chan_nr); 4041 4046 4042 4047 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
+9 -4
drivers/net/wireless/cw1200/main.c
··· 245 245 MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs"); 246 246 MODULE_PARM_DESC(cw1200_ba_tx_tids, "Block ACK TX TIDs"); 247 247 248 + #ifdef CONFIG_PM 249 + static const struct wiphy_wowlan_support cw1200_wowlan_support = { 250 + /* Support only for limited wowlan functionalities */ 251 + .flags = WIPHY_WOWLAN_ANY | WIPHY_WOWLAN_DISCONNECT, 252 + }; 253 + #endif 254 + 255 + 248 256 static struct ieee80211_hw *cw1200_init_common(const u8 *macaddr, 249 257 const bool have_5ghz) 250 258 { ··· 297 289 BIT(NL80211_IFTYPE_P2P_GO); 298 290 299 291 #ifdef CONFIG_PM 300 - /* Support only for limited wowlan functionalities */ 301 - hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY | 302 - WIPHY_WOWLAN_DISCONNECT; 303 - hw->wiphy->wowlan.n_patterns = 0; 292 + hw->wiphy->wowlan = &cw1200_wowlan_support; 304 293 #endif 305 294 306 295 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
+3
drivers/net/wireless/iwlwifi/dvm/dev.h
··· 915 915 __le64 replay_ctr; 916 916 __le16 last_seq_ctl; 917 917 bool have_rekey_data; 918 + #ifdef CONFIG_PM_SLEEP 919 + struct wiphy_wowlan_support wowlan_support; 920 + #endif 918 921 919 922 /* device_pointers: pointers to ucode event tables */ 920 923 struct {
+9 -8
drivers/net/wireless/iwlwifi/dvm/mac80211.c
··· 208 208 priv->trans->ops->d3_suspend && 209 209 priv->trans->ops->d3_resume && 210 210 device_can_wakeup(priv->trans->dev)) { 211 - hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 212 - WIPHY_WOWLAN_DISCONNECT | 213 - WIPHY_WOWLAN_EAP_IDENTITY_REQ | 214 - WIPHY_WOWLAN_RFKILL_RELEASE; 211 + priv->wowlan_support.flags = WIPHY_WOWLAN_MAGIC_PKT | 212 + WIPHY_WOWLAN_DISCONNECT | 213 + WIPHY_WOWLAN_EAP_IDENTITY_REQ | 214 + WIPHY_WOWLAN_RFKILL_RELEASE; 215 215 if (!iwlwifi_mod_params.sw_crypto) 216 - hw->wiphy->wowlan.flags |= 216 + priv->wowlan_support.flags |= 217 217 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 218 218 WIPHY_WOWLAN_GTK_REKEY_FAILURE; 219 219 220 - hw->wiphy->wowlan.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; 221 - hw->wiphy->wowlan.pattern_min_len = 220 + priv->wowlan_support.n_patterns = IWLAGN_WOWLAN_MAX_PATTERNS; 221 + priv->wowlan_support.pattern_min_len = 222 222 IWLAGN_WOWLAN_MIN_PATTERN_LEN; 223 - hw->wiphy->wowlan.pattern_max_len = 223 + priv->wowlan_support.pattern_max_len = 224 224 IWLAGN_WOWLAN_MAX_PATTERN_LEN; 225 + hw->wiphy->wowlan = &priv->wowlan_support; 225 226 } 226 227 #endif 227 228
+13 -13
drivers/net/wireless/iwlwifi/mvm/mac80211.c
··· 236 236 mvm->trans->ops->d3_suspend && 237 237 mvm->trans->ops->d3_resume && 238 238 device_can_wakeup(mvm->trans->dev)) { 239 - hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 240 - WIPHY_WOWLAN_DISCONNECT | 241 - WIPHY_WOWLAN_EAP_IDENTITY_REQ | 242 - WIPHY_WOWLAN_RFKILL_RELEASE; 239 + mvm->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | 240 + WIPHY_WOWLAN_DISCONNECT | 241 + WIPHY_WOWLAN_EAP_IDENTITY_REQ | 242 + WIPHY_WOWLAN_RFKILL_RELEASE; 243 243 if (!iwlwifi_mod_params.sw_crypto) 244 - hw->wiphy->wowlan.flags |= 245 - WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 246 - WIPHY_WOWLAN_GTK_REKEY_FAILURE | 247 - WIPHY_WOWLAN_4WAY_HANDSHAKE; 244 + mvm->wowlan.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | 245 + WIPHY_WOWLAN_GTK_REKEY_FAILURE | 246 + WIPHY_WOWLAN_4WAY_HANDSHAKE; 248 247 249 - hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; 250 - hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; 251 - hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; 252 - hw->wiphy->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; 248 + mvm->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS; 249 + mvm->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN; 250 + mvm->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN; 251 + mvm->wowlan.tcp = &iwl_mvm_wowlan_tcp_support; 252 + hw->wiphy->wowlan = &mvm->wowlan; 253 253 } 254 254 #endif 255 255 ··· 777 777 ret = iwl_mvm_power_update_mode(mvm, vif); 778 778 if (ret) 779 779 IWL_ERR(mvm, "failed to update power mode\n"); 780 - } else if (changes & BSS_CHANGED_DTIM_PERIOD) { 780 + } else if (changes & BSS_CHANGED_BEACON_INFO) { 781 781 /* 782 782 * We received a beacon _after_ association so 783 783 * remove the session protection.
+1
drivers/net/wireless/iwlwifi/mvm/mvm.h
··· 458 458 struct ieee80211_vif *p2p_device_vif; 459 459 460 460 #ifdef CONFIG_PM_SLEEP 461 + struct wiphy_wowlan_support wowlan; 461 462 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 462 463 #ifdef CONFIG_IWLWIFI_DEBUGFS 463 464 bool d3_test_active;
+11 -5
drivers/net/wireless/mwifiex/cfg80211.c
··· 2475 2475 #endif 2476 2476 }; 2477 2477 2478 + #ifdef CONFIG_PM 2479 + static const struct wiphy_wowlan_support mwifiex_wowlan_support = { 2480 + .flags = WIPHY_WOWLAN_MAGIC_PKT, 2481 + .n_patterns = MWIFIEX_MAX_FILTERS, 2482 + .pattern_min_len = 1, 2483 + .pattern_max_len = MWIFIEX_MAX_PATTERN_LEN, 2484 + .max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN, 2485 + }; 2486 + #endif 2487 + 2478 2488 /* 2479 2489 * This function registers the device with CFG802.11 subsystem. 2480 2490 * ··· 2542 2532 wiphy_apply_custom_regulatory(wiphy, &mwifiex_world_regdom_custom); 2543 2533 2544 2534 #ifdef CONFIG_PM 2545 - wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT; 2546 - wiphy->wowlan.n_patterns = MWIFIEX_MAX_FILTERS; 2547 - wiphy->wowlan.pattern_min_len = 1; 2548 - wiphy->wowlan.pattern_max_len = MWIFIEX_MAX_PATTERN_LEN; 2549 - wiphy->wowlan.max_pkt_offset = MWIFIEX_MAX_OFFSET_LEN; 2535 + wiphy->wowlan = &mwifiex_wowlan_support; 2550 2536 #endif 2551 2537 2552 2538 wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
+11 -8
drivers/net/wireless/ti/wlcore/main.c
··· 6018 6018 } 6019 6019 EXPORT_SYMBOL_GPL(wlcore_free_hw); 6020 6020 6021 + #ifdef CONFIG_PM 6022 + static const struct wiphy_wowlan_support wlcore_wowlan_support = { 6023 + .flags = WIPHY_WOWLAN_ANY, 6024 + .n_patterns = WL1271_MAX_RX_FILTERS, 6025 + .pattern_min_len = 1, 6026 + .pattern_max_len = WL1271_RX_FILTER_MAX_PATTERN_SIZE, 6027 + }; 6028 + #endif 6029 + 6021 6030 static void wlcore_nvs_cb(const struct firmware *fw, void *context) 6022 6031 { 6023 6032 struct wl1271 *wl = context; ··· 6080 6071 if (!ret) { 6081 6072 wl->irq_wake_enabled = true; 6082 6073 device_init_wakeup(wl->dev, 1); 6083 - if (pdata->pwr_in_suspend) { 6084 - wl->hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY; 6085 - wl->hw->wiphy->wowlan.n_patterns = 6086 - WL1271_MAX_RX_FILTERS; 6087 - wl->hw->wiphy->wowlan.pattern_min_len = 1; 6088 - wl->hw->wiphy->wowlan.pattern_max_len = 6089 - WL1271_RX_FILTER_MAX_PATTERN_SIZE; 6090 - } 6074 + if (pdata->pwr_in_suspend) 6075 + wl->hw->wiphy->wowlan = &wlcore_wowlan_support; 6091 6076 } 6092 6077 #endif 6093 6078 disable_irq(wl->irq);
+1
include/linux/ieee80211.h
··· 146 146 #define IEEE80211_MAX_RTS_THRESHOLD 2353 147 147 #define IEEE80211_MAX_AID 2007 148 148 #define IEEE80211_MAX_TIM_LEN 251 149 + #define IEEE80211_MAX_MESH_PEERINGS 63 149 150 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section 150 151 6.2.1.1.2. 151 152
+53 -62
include/net/cfg80211.h
··· 1124 1124 * setting for new peer links. 1125 1125 * @dot11MeshAwakeWindowDuration: The duration in TUs the STA will remain awake 1126 1126 * after transmitting its beacon. 1127 + * @plink_timeout: If no tx activity is seen from a STA we've established 1128 + * peering with for longer than this time (in seconds), then remove it 1129 + * from the STA's list of peers. Default is 30 minutes. 1127 1130 */ 1128 1131 struct mesh_config { 1129 1132 u16 dot11MeshRetryTimeout; ··· 1156 1153 u16 dot11MeshHWMPconfirmationInterval; 1157 1154 enum nl80211_mesh_power_mode power_mode; 1158 1155 u16 dot11MeshAwakeWindowDuration; 1156 + u32 plink_timeout; 1159 1157 }; 1160 1158 1161 1159 /** ··· 1176 1172 * @dtim_period: DTIM period to use 1177 1173 * @beacon_interval: beacon interval to use 1178 1174 * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a] 1175 + * @basic_rates: basic rates to use when creating the mesh 1179 1176 * 1180 1177 * These parameters are fixed when the mesh is created. 1181 1178 */ ··· 1196 1191 u8 dtim_period; 1197 1192 u16 beacon_interval; 1198 1193 int mcast_rate[IEEE80211_NUM_BANDS]; 1194 + u32 basic_rates; 1199 1195 }; 1200 1196 1201 1197 /** ··· 2660 2654 u32 hw_version; 2661 2655 2662 2656 #ifdef CONFIG_PM 2663 - struct wiphy_wowlan_support wowlan; 2657 + const struct wiphy_wowlan_support *wowlan; 2664 2658 struct cfg80211_wowlan *wowlan_config; 2665 2659 #endif 2666 2660 ··· 2859 2853 * @current_bss: (private) Used by the internal configuration code 2860 2854 * @channel: (private) Used by the internal configuration code to track 2861 2855 * the user-set AP, monitor and WDS channel 2862 - * @preset_chan: (private) Used by the internal configuration code to 2856 + * @preset_chandef: (private) Used by the internal configuration code to 2863 2857 * track the channel to be used for AP later 2864 2858 * @bssid: (private) Used by the internal configuration code 2865 2859 * @ssid: (private) Used by the internal configuration code ··· 2881 2875 * @p2p_started: true if this is a P2P Device that has been started 2882 2876 * @cac_started: true if DFS channel availability check has been started 2883 2877 * @cac_start_time: timestamp (jiffies) when the dfs state was entered. 2878 + * @ps: powersave mode is enabled 2879 + * @ps_timeout: dynamic powersave timeout 2880 + * @ap_unexpected_nlportid: (private) netlink port ID of application 2881 + * registered for unexpected class 3 frames (AP mode) 2882 + * @conn: (private) cfg80211 software SME connection state machine data 2883 + * @connect_keys: (private) keys to set after connection is established 2884 + * @ibss_fixed: (private) IBSS is using fixed BSSID 2885 + * @event_list: (private) list for internal event processing 2886 + * @event_lock: (private) lock for event list 2884 2887 */ 2885 2888 struct wireless_dev { 2886 2889 struct wiphy *wiphy; ··· 2913 2898 /* currently used for IBSS and SME - might be rearranged later */ 2914 2899 u8 ssid[IEEE80211_MAX_SSID_LEN]; 2915 2900 u8 ssid_len, mesh_id_len, mesh_id_up_len; 2916 - enum { 2917 - CFG80211_SME_IDLE, 2918 - CFG80211_SME_CONNECTING, 2919 - CFG80211_SME_CONNECTED, 2920 - } sme_state; 2921 2901 struct cfg80211_conn *conn; 2922 2902 struct cfg80211_cached_keys *connect_keys; 2923 2903 ··· 3442 3432 void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); 3443 3433 3444 3434 /** 3445 - * cfg80211_send_rx_auth - notification of processed authentication 3435 + * cfg80211_rx_mlme_mgmt - notification of processed MLME management frame 3446 3436 * @dev: network device 3447 3437 * @buf: authentication frame (header + body) 3448 3438 * @len: length of the frame data 3449 3439 * 3450 - * This function is called whenever an authentication has been processed in 3451 - * station mode. The driver is required to call either this function or 3452 - * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth() 3453 - * call. This function may sleep. The caller must hold the corresponding wdev's 3454 - * mutex. 3440 + * This function is called whenever an authentication, disassociation or 3441 + * deauthentication frame has been received and processed in station mode. 3442 + * After being asked to authenticate via cfg80211_ops::auth() the driver must 3443 + * call either this function or cfg80211_auth_timeout(). 3444 + * After being asked to associate via cfg80211_ops::assoc() the driver must 3445 + * call either this function or cfg80211_auth_timeout(). 3446 + * While connected, the driver must calls this for received and processed 3447 + * disassociation and deauthentication frames. If the frame couldn't be used 3448 + * because it was unprotected, the driver must call the function 3449 + * cfg80211_rx_unprot_mlme_mgmt() instead. 3450 + * 3451 + * This function may sleep. The caller must hold the corresponding wdev's mutex. 3455 3452 */ 3456 - void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); 3453 + void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len); 3457 3454 3458 3455 /** 3459 - * cfg80211_send_auth_timeout - notification of timed out authentication 3456 + * cfg80211_auth_timeout - notification of timed out authentication 3460 3457 * @dev: network device 3461 3458 * @addr: The MAC address of the device with which the authentication timed out 3462 3459 * 3463 3460 * This function may sleep. The caller must hold the corresponding wdev's 3464 3461 * mutex. 3465 3462 */ 3466 - void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); 3463 + void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr); 3467 3464 3468 3465 /** 3469 - * cfg80211_send_rx_assoc - notification of processed association 3466 + * cfg80211_rx_assoc_resp - notification of processed association response 3470 3467 * @dev: network device 3471 - * @bss: the BSS struct association was requested for, the struct reference 3472 - * is owned by cfg80211 after this call 3473 - * @buf: (re)association response frame (header + body) 3468 + * @bss: the BSS that association was requested with, ownership of the pointer 3469 + * moves to cfg80211 in this call 3470 + * @buf: authentication frame (header + body) 3474 3471 * @len: length of the frame data 3475 3472 * 3476 - * This function is called whenever a (re)association response has been 3477 - * processed in station mode. The driver is required to call either this 3478 - * function or cfg80211_send_assoc_timeout() to indicate the result of 3479 - * cfg80211_ops::assoc() call. This function may sleep. The caller must hold 3480 - * the corresponding wdev's mutex. 3473 + * After being asked to associate via cfg80211_ops::assoc() the driver must 3474 + * call either this function or cfg80211_auth_timeout(). 3475 + * 3476 + * This function may sleep. The caller must hold the corresponding wdev's mutex. 3481 3477 */ 3482 - void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, 3478 + void cfg80211_rx_assoc_resp(struct net_device *dev, 3479 + struct cfg80211_bss *bss, 3483 3480 const u8 *buf, size_t len); 3484 3481 3485 3482 /** 3486 - * cfg80211_send_assoc_timeout - notification of timed out association 3483 + * cfg80211_assoc_timeout - notification of timed out association 3487 3484 * @dev: network device 3488 3485 * @addr: The MAC address of the device with which the association timed out 3489 3486 * 3490 3487 * This function may sleep. The caller must hold the corresponding wdev's mutex. 3491 3488 */ 3492 - void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); 3489 + void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr); 3493 3490 3494 3491 /** 3495 - * cfg80211_send_deauth - notification of processed deauthentication 3492 + * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame 3496 3493 * @dev: network device 3497 - * @buf: deauthentication frame (header + body) 3494 + * @buf: 802.11 frame (header + body) 3498 3495 * @len: length of the frame data 3499 3496 * 3500 3497 * This function is called whenever deauthentication has been processed in ··· 3509 3492 * locally generated ones. This function may sleep. The caller must hold the 3510 3493 * corresponding wdev's mutex. 3511 3494 */ 3512 - void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); 3495 + void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len); 3513 3496 3514 3497 /** 3515 - * cfg80211_send_disassoc - notification of processed disassociation 3516 - * @dev: network device 3517 - * @buf: disassociation response frame (header + body) 3518 - * @len: length of the frame data 3519 - * 3520 - * This function is called whenever disassociation has been processed in 3521 - * station mode. This includes both received disassociation frames and locally 3522 - * generated ones. This function may sleep. The caller must hold the 3523 - * corresponding wdev's mutex. 3524 - */ 3525 - void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); 3526 - 3527 - /** 3528 - * cfg80211_send_unprot_deauth - notification of unprotected deauthentication 3498 + * cfg80211_rx_unprot_mlme_mgmt - notification of unprotected mlme mgmt frame 3529 3499 * @dev: network device 3530 3500 * @buf: deauthentication frame (header + body) 3531 3501 * @len: length of the frame data 3532 3502 * 3533 - * This function is called whenever a received Deauthentication frame has been 3534 - * dropped in station mode because of MFP being used but the Deauthentication 3503 + * This function is called whenever a received deauthentication or dissassoc 3504 + * frame has been dropped in station mode because of MFP being used but the 3535 3505 * frame was not protected. This function may sleep. 3536 3506 */ 3537 - void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, 3538 - size_t len); 3539 - 3540 - /** 3541 - * cfg80211_send_unprot_disassoc - notification of unprotected disassociation 3542 - * @dev: network device 3543 - * @buf: disassociation frame (header + body) 3544 - * @len: length of the frame data 3545 - * 3546 - * This function is called whenever a received Disassociation frame has been 3547 - * dropped in station mode because of MFP being used but the Disassociation 3548 - * frame was not protected. This function may sleep. 3549 - */ 3550 - void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, 3551 - size_t len); 3507 + void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, 3508 + const u8 *buf, size_t len); 3552 3509 3553 3510 /** 3554 3511 * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
+7 -4
include/net/mac80211.h
··· 217 217 * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface 218 218 * @BSS_CHANGED_P2P_PS: P2P powersave settings (CTWindow, opportunistic PS) 219 219 * changed (currently only in P2P client mode, GO mode will be later) 220 - * @BSS_CHANGED_DTIM_PERIOD: the DTIM period value was changed (set when 221 - * it becomes valid, managed mode only) 220 + * @BSS_CHANGED_BEACON_INFO: Data from the AP's beacon became available: 221 + * currently dtim_period only is under consideration. 222 222 * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed, 223 223 * note that this is only called when it changes after the channel 224 224 * context had been assigned. ··· 244 244 BSS_CHANGED_PS = 1<<17, 245 245 BSS_CHANGED_TXPOWER = 1<<18, 246 246 BSS_CHANGED_P2P_PS = 1<<19, 247 - BSS_CHANGED_DTIM_PERIOD = 1<<20, 247 + BSS_CHANGED_BEACON_INFO = 1<<20, 248 248 BSS_CHANGED_BANDWIDTH = 1<<21, 249 249 250 250 /* when adding here, make sure to change ieee80211_reconfig */ ··· 288 288 * IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag 289 289 * @dtim_period: num of beacons before the next DTIM, for beaconing, 290 290 * valid in station mode only if after the driver was notified 291 - * with the %BSS_CHANGED_DTIM_PERIOD flag, will be non-zero then. 291 + * with the %BSS_CHANGED_BEACON_INFO flag, will be non-zero then. 292 292 * @sync_tsf: last beacon's/probe response's TSF timestamp (could be old 293 293 * as it may have been received during scanning long ago). If the 294 294 * HW flag %IEEE80211_HW_TIMING_BEACON_ONLY is set, then this can ··· 460 460 * @IEEE80211_TX_CTL_DONTFRAG: Don't fragment this packet even if it 461 461 * would be fragmented by size (this is optional, only used for 462 462 * monitor injection). 463 + * @IEEE80211_TX_CTL_PS_RESPONSE: This frame is a response to a poll 464 + * frame (PS-Poll or uAPSD). 463 465 * 464 466 * Note: If you have to add new flags to the enumeration, then don't 465 467 * forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary. ··· 497 495 IEEE80211_TX_STATUS_EOSP = BIT(28), 498 496 IEEE80211_TX_CTL_USE_MINRATE = BIT(29), 499 497 IEEE80211_TX_CTL_DONTFRAG = BIT(30), 498 + IEEE80211_TX_CTL_PS_RESPONSE = BIT(31), 500 499 }; 501 500 502 501 #define IEEE80211_TX_CTL_STBC_SHIFT 23
+9
include/uapi/linux/nl80211.h
··· 2577 2577 * 2578 2578 * @NL80211_MESHCONF_AWAKE_WINDOW: awake window duration (in TUs) 2579 2579 * 2580 + * @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've 2581 + * established peering with for longer than this time (in seconds), then 2582 + * remove it from the STA's list of peers. Default is 30 minutes. 2583 + * 2580 2584 * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use 2581 2585 */ 2582 2586 enum nl80211_meshconf_params { ··· 2612 2608 NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, 2613 2609 NL80211_MESHCONF_POWER_MODE, 2614 2610 NL80211_MESHCONF_AWAKE_WINDOW, 2611 + NL80211_MESHCONF_PLINK_TIMEOUT, 2615 2612 2616 2613 /* keep last */ 2617 2614 __NL80211_MESHCONF_ATTR_AFTER_LAST, ··· 3584 3579 * Peering Management entity which may be implemented by registering for 3585 3580 * beacons or NL80211_CMD_NEW_PEER_CANDIDATE events. The mesh beacon is 3586 3581 * still generated by the driver. 3582 + * @NL80211_FEATURE_ACTIVE_MONITOR: This driver supports an active monitor 3583 + * interface. An active monitor interface behaves like a normal monitor 3584 + * interface, but gets added to the driver. It ensures that incoming 3585 + * unicast packets directed at the configured interface address get ACKed. 3587 3586 */ 3588 3587 enum nl80211_feature_flags { 3589 3588 NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
+17 -3
net/mac80211/cfg.c
··· 1759 1759 /* mcast rate setting in Mesh Node */ 1760 1760 memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, 1761 1761 sizeof(setup->mcast_rate)); 1762 + sdata->vif.bss_conf.basic_rates = setup->basic_rates; 1762 1763 1763 1764 sdata->vif.bss_conf.beacon_int = setup->beacon_interval; 1764 1765 sdata->vif.bss_conf.dtim_period = setup->dtim_period; ··· 1872 1871 if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask)) 1873 1872 conf->dot11MeshAwakeWindowDuration = 1874 1873 nconf->dot11MeshAwakeWindowDuration; 1874 + if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask)) 1875 + conf->plink_timeout = nconf->plink_timeout; 1875 1876 ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); 1876 1877 return 0; 1877 1878 } ··· 2841 2838 return -EOPNOTSUPP; 2842 2839 } 2843 2840 2841 + /* configurations requiring offchan cannot work if no channel has been 2842 + * specified 2843 + */ 2844 + if (need_offchan && !chan) 2845 + return -EINVAL; 2846 + 2844 2847 mutex_lock(&local->mtx); 2845 2848 2846 2849 /* Check if the operating channel is the requested channel */ ··· 2856 2847 rcu_read_lock(); 2857 2848 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 2858 2849 2859 - if (chanctx_conf) 2860 - need_offchan = chan != chanctx_conf->def.chan; 2861 - else 2850 + if (chanctx_conf) { 2851 + need_offchan = chan && (chan != chanctx_conf->def.chan); 2852 + } else if (!chan) { 2853 + ret = -EINVAL; 2854 + rcu_read_unlock(); 2855 + goto out_unlock; 2856 + } else { 2862 2857 need_offchan = true; 2858 + } 2863 2859 rcu_read_unlock(); 2864 2860 } 2865 2861
+2 -1
net/mac80211/ieee80211_i.h
··· 366 366 u8 ssid_len; 367 367 u8 supp_rates_len; 368 368 bool wmm, uapsd; 369 - bool have_beacon, need_beacon; 369 + bool need_beacon; 370 370 bool synced; 371 371 bool timeout_started; 372 372 ··· 404 404 405 405 bool powersave; /* powersave requested for this iface */ 406 406 bool broken_ap; /* AP is broken -- turn off powersave */ 407 + bool have_beacon; 407 408 u8 dtim_period; 408 409 enum ieee80211_smps_mode req_smps, /* requested smps mode */ 409 410 driver_smps_mode; /* smps mode request */
+1 -2
net/mac80211/main.c
··· 686 686 return -EINVAL; 687 687 688 688 #ifdef CONFIG_PM 689 - if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) && 690 - (!local->ops->suspend || !local->ops->resume)) 689 + if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume)) 691 690 return -EINVAL; 692 691 #endif 693 692
+19 -19
net/mac80211/mesh.c
··· 274 274 *pos++ = ifmsh->mesh_auth_id; 275 275 /* Mesh Formation Info - number of neighbors */ 276 276 neighbors = atomic_read(&ifmsh->estab_plinks); 277 - /* Number of neighbor mesh STAs or 15 whichever is smaller */ 278 - neighbors = (neighbors > 15) ? 15 : neighbors; 277 + neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS); 279 278 *pos++ = neighbors << 1; 280 279 /* Mesh capability */ 281 280 *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING; ··· 575 576 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 576 577 u32 changed; 577 578 578 - ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); 579 + ieee80211_sta_expire(sdata, ifmsh->mshcfg.plink_timeout * HZ); 579 580 mesh_path_expire(sdata); 580 581 581 582 changed = mesh_accept_plinks_update(sdata); 582 - sdata_lock(sdata); 583 583 ieee80211_mbss_info_change_notify(sdata, changed); 584 - sdata_unlock(sdata); 585 584 586 585 mod_timer(&ifmsh->housekeeping_timer, 587 586 round_jiffies(jiffies + ··· 738 741 BSS_CHANGED_HT | 739 742 BSS_CHANGED_BASIC_RATES | 740 743 BSS_CHANGED_BEACON_INT; 741 - enum ieee80211_band band = ieee80211_get_sdata_band(sdata); 742 - struct ieee80211_supported_band *sband = 743 - sdata->local->hw.wiphy->bands[band]; 744 744 745 745 local->fif_other_bss++; 746 746 /* mesh ifaces must set allmulti to forward mcast traffic */ ··· 755 761 sdata->vif.bss_conf.ht_operation_mode = 756 762 ifmsh->mshcfg.ht_opmode; 757 763 sdata->vif.bss_conf.enable_beacon = true; 758 - sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband); 759 764 760 765 changed |= ieee80211_mps_local_status_update(sdata); 761 766 ··· 782 789 sdata->vif.bss_conf.enable_beacon = false; 783 790 clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); 784 791 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); 785 - sdata_lock(sdata); 786 792 bcn = rcu_dereference_protected(ifmsh->beacon, 787 793 lockdep_is_held(&sdata->wdev.mtx)); 788 794 rcu_assign_pointer(ifmsh->beacon, NULL); 789 795 kfree_rcu(bcn, rcu_head); 790 - sdata_unlock(sdata); 791 796 792 797 /* flush STAs and mpaths on this iface */ 793 798 sta_info_flush(sdata); ··· 798 807 del_timer_sync(&sdata->u.mesh.housekeeping_timer); 799 808 del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); 800 809 del_timer_sync(&sdata->u.mesh.mesh_path_timer); 801 - /* 802 - * If the timer fired while we waited for it, it will have 803 - * requeued the work. Now the work will be running again 804 - * but will not rearm the timer again because it checks 805 - * whether the interface is running, which, at this point, 806 - * it no longer is. 807 - */ 808 - cancel_work_sync(&sdata->work); 809 810 810 811 local->fif_other_bss--; 811 812 atomic_dec(&local->iff_allmultis); ··· 938 955 struct ieee80211_mgmt *mgmt; 939 956 u16 stype; 940 957 958 + sdata_lock(sdata); 959 + 960 + /* mesh already went down */ 961 + if (!sdata->wdev.mesh_id_len) 962 + goto out; 963 + 941 964 rx_status = IEEE80211_SKB_RXCB(skb); 942 965 mgmt = (struct ieee80211_mgmt *) skb->data; 943 966 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; ··· 961 972 ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status); 962 973 break; 963 974 } 975 + out: 976 + sdata_unlock(sdata); 964 977 } 965 978 966 979 void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) 967 980 { 968 981 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 982 + 983 + sdata_lock(sdata); 984 + 985 + /* mesh already went down */ 986 + if (!sdata->wdev.mesh_id_len) 987 + goto out; 969 988 970 989 if (ifmsh->preq_queue_len && 971 990 time_after(jiffies, ··· 994 997 995 998 if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) 996 999 mesh_sync_adjust_tbtt(sdata); 1000 + 1001 + out: 1002 + sdata_unlock(sdata); 997 1003 } 998 1004 999 1005 void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
+2 -3
net/mac80211/mesh.h
··· 188 188 u32 idx_mask; 189 189 }; 190 190 191 - #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) 192 191 #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) 193 192 194 193 #define MESH_PATH_EXPIRE (600 * HZ) ··· 323 324 u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 324 325 { 325 326 atomic_inc(&sdata->u.mesh.estab_plinks); 326 - return mesh_accept_plinks_update(sdata); 327 + return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON; 327 328 } 328 329 329 330 static inline 330 331 u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 331 332 { 332 333 atomic_dec(&sdata->u.mesh.estab_plinks); 333 - return mesh_accept_plinks_update(sdata); 334 + return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON; 334 335 } 335 336 336 337 static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
+1 -6
net/mac80211/mesh_plink.c
··· 517 517 ieee80211_mps_frame_release(sta, elems); 518 518 out: 519 519 rcu_read_unlock(); 520 - sdata_lock(sdata); 521 520 ieee80211_mbss_info_change_notify(sdata, changed); 522 - sdata_unlock(sdata); 523 521 } 524 522 525 523 static void mesh_plink_timer(unsigned long data) ··· 1068 1070 1069 1071 rcu_read_unlock(); 1070 1072 1071 - if (changed) { 1072 - sdata_lock(sdata); 1073 + if (changed) 1073 1074 ieee80211_mbss_info_change_notify(sdata, changed); 1074 - sdata_unlock(sdata); 1075 - } 1076 1075 }
+47 -51
net/mac80211/mlme.c
··· 880 880 881 881 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | 882 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 887 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 884 888 IEEE80211_STA_CONNECTION_POLL)) 885 889 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; ··· 1360 1356 IEEE80211_STA_CONNECTION_POLL)) 1361 1357 return false; 1362 1358 1363 - if (!sdata->vif.bss_conf.dtim_period) 1359 + if (!mgd->have_beacon) 1364 1360 return false; 1365 1361 1366 1362 rcu_read_lock(); ··· 1771 1767 1772 1768 ieee80211_led_assoc(local, 1); 1773 1769 1774 - if (sdata->u.mgd.assoc_data->have_beacon) { 1770 + if (sdata->u.mgd.have_beacon) { 1775 1771 /* 1776 1772 * If the AP is buggy we may get here with no DTIM period 1777 1773 * known, so assume it's 1 which is the only safe assumption ··· 1779 1775 * probably just won't work at all. 1780 1776 */ 1781 1777 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; 1782 - bss_info_changed |= BSS_CHANGED_DTIM_PERIOD; 1778 + bss_info_changed |= BSS_CHANGED_BEACON_INFO; 1783 1779 } else { 1784 1780 bss_conf->dtim_period = 0; 1785 1781 } ··· 1903 1899 del_timer_sync(&sdata->u.mgd.chswitch_timer); 1904 1900 1905 1901 sdata->vif.bss_conf.dtim_period = 0; 1902 + ifmgd->have_beacon = false; 1906 1903 1907 1904 ifmgd->flags = 0; 1908 1905 ieee80211_vif_release_channel(sdata); ··· 2156 2151 IEEE80211_MAX_QUEUE_MAP, 2157 2152 IEEE80211_QUEUE_STOP_REASON_CSA); 2158 2153 2159 - cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 2154 + cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 2155 + IEEE80211_DEAUTH_FRAME_LEN); 2160 2156 sdata_unlock(sdata); 2161 2157 } 2162 2158 ··· 2304 2298 sdata_info(sdata, "%pM denied authentication (status %d)\n", 2305 2299 mgmt->sa, status_code); 2306 2300 ieee80211_destroy_auth_data(sdata, false); 2307 - cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); 2301 + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); 2308 2302 return; 2309 2303 } 2310 2304 ··· 2339 2333 * Report auth frame to user space for processing since another 2340 2334 * round of Authentication frames is still needed. 2341 2335 */ 2342 - cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); 2336 + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); 2343 2337 return; 2344 2338 } 2345 2339 ··· 2356 2350 } 2357 2351 mutex_unlock(&sdata->local->sta_mtx); 2358 2352 2359 - cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); 2353 + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); 2360 2354 return; 2361 2355 out_err: 2362 2356 mutex_unlock(&sdata->local->sta_mtx); ··· 2389 2383 2390 2384 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2391 2385 2392 - cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, len); 2386 + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); 2393 2387 } 2394 2388 2395 2389 ··· 2415 2409 2416 2410 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2417 2411 2418 - cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, len); 2412 + cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); 2419 2413 } 2420 2414 2421 2415 static void ieee80211_get_rates(struct ieee80211_supported_band *sband, ··· 2713 2707 /* oops -- internal error -- send timeout for now */ 2714 2708 ieee80211_destroy_assoc_data(sdata, false); 2715 2709 cfg80211_put_bss(sdata->local->hw.wiphy, bss); 2716 - cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid); 2710 + cfg80211_assoc_timeout(sdata->dev, mgmt->bssid); 2717 2711 return; 2718 2712 } 2719 2713 sdata_info(sdata, "associated\n"); ··· 2726 2720 ieee80211_destroy_assoc_data(sdata, true); 2727 2721 } 2728 2722 2729 - cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len); 2723 + cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len); 2730 2724 } 2731 2725 2732 2726 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, ··· 2738 2732 int freq; 2739 2733 struct ieee80211_bss *bss; 2740 2734 struct ieee80211_channel *channel; 2741 - bool need_ps = false; 2742 2735 2743 2736 sdata_assert_lock(sdata); 2744 - 2745 - if ((sdata->u.mgd.associated && 2746 - ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || 2747 - (sdata->u.mgd.assoc_data && 2748 - ether_addr_equal(mgmt->bssid, 2749 - sdata->u.mgd.assoc_data->bss->bssid))) { 2750 - /* not previously set so we may need to recalc */ 2751 - need_ps = sdata->u.mgd.associated && !sdata->u.mgd.dtim_period; 2752 - 2753 - if (elems->tim && !elems->parse_error) { 2754 - const struct ieee80211_tim_ie *tim_ie = elems->tim; 2755 - sdata->u.mgd.dtim_period = tim_ie->dtim_period; 2756 - } 2757 - } 2758 2737 2759 2738 if (elems->ds_params) 2760 2739 freq = ieee80211_channel_to_frequency(elems->ds_params[0], ··· 2760 2769 if (!sdata->u.mgd.associated || 2761 2770 !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) 2762 2771 return; 2763 - 2764 - if (need_ps) { 2765 - mutex_lock(&local->iflist_mtx); 2766 - ieee80211_recalc_ps(local, -1); 2767 - mutex_unlock(&local->iflist_mtx); 2768 - } 2769 2772 2770 2773 ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, 2771 2774 elems, true); ··· 2874 2889 len - baselen, false, &elems); 2875 2890 2876 2891 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 2877 - ifmgd->assoc_data->have_beacon = true; 2892 + if (elems.tim && !elems.parse_error) { 2893 + const struct ieee80211_tim_ie *tim_ie = elems.tim; 2894 + ifmgd->dtim_period = tim_ie->dtim_period; 2895 + } 2896 + ifmgd->have_beacon = true; 2878 2897 ifmgd->assoc_data->need_beacon = false; 2879 2898 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { 2880 2899 sdata->vif.bss_conf.sync_tsf = ··· 3060 3071 * If we haven't had a beacon before, tell the driver about the 3061 3072 * DTIM period (and beacon timing if desired) now. 3062 3073 */ 3063 - if (!bss_conf->dtim_period) { 3074 + if (!ifmgd->have_beacon) { 3064 3075 /* a few bogus AP send dtim_period = 0 or no TIM IE */ 3065 3076 if (elems.tim) 3066 3077 bss_conf->dtim_period = elems.tim->dtim_period ?: 1; ··· 3079 3090 sdata->vif.bss_conf.sync_dtim_count = 0; 3080 3091 } 3081 3092 3082 - changed |= BSS_CHANGED_DTIM_PERIOD; 3093 + changed |= BSS_CHANGED_BEACON_INFO; 3094 + ifmgd->have_beacon = true; 3095 + 3096 + mutex_lock(&local->iflist_mtx); 3097 + ieee80211_recalc_ps(local, -1); 3098 + mutex_unlock(&local->iflist_mtx); 3099 + 3083 3100 ieee80211_recalc_ps_vif(sdata); 3084 3101 } 3085 3102 ··· 3108 3113 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 3109 3114 WLAN_REASON_DEAUTH_LEAVING, 3110 3115 true, deauth_buf); 3111 - cfg80211_send_deauth(sdata->dev, deauth_buf, 3112 - sizeof(deauth_buf)); 3116 + cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf, 3117 + sizeof(deauth_buf)); 3113 3118 return; 3114 3119 } 3115 3120 ··· 3227 3232 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, 3228 3233 tx, frame_buf); 3229 3234 3230 - cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 3235 + cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 3236 + IEEE80211_DEAUTH_FRAME_LEN); 3231 3237 } 3232 3238 3233 3239 static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) ··· 3419 3423 3420 3424 ieee80211_destroy_auth_data(sdata, false); 3421 3425 3422 - cfg80211_send_auth_timeout(sdata->dev, bssid); 3426 + cfg80211_auth_timeout(sdata->dev, bssid); 3423 3427 } 3424 3428 } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) 3425 3429 run_again(sdata, ifmgd->auth_data->timeout); 3426 3430 3427 3431 if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && 3428 3432 time_after(jiffies, ifmgd->assoc_data->timeout)) { 3429 - if ((ifmgd->assoc_data->need_beacon && 3430 - !ifmgd->assoc_data->have_beacon) || 3433 + if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || 3431 3434 ieee80211_do_assoc(sdata)) { 3432 3435 u8 bssid[ETH_ALEN]; 3433 3436 ··· 3434 3439 3435 3440 ieee80211_destroy_assoc_data(sdata, false); 3436 3441 3437 - cfg80211_send_assoc_timeout(sdata->dev, bssid); 3442 + cfg80211_assoc_timeout(sdata->dev, bssid); 3438 3443 } 3439 3444 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3440 3445 run_again(sdata, ifmgd->assoc_data->timeout); ··· 3983 3988 WLAN_REASON_UNSPECIFIED, 3984 3989 false, frame_buf); 3985 3990 3986 - cfg80211_send_deauth(sdata->dev, frame_buf, 3987 - sizeof(frame_buf)); 3991 + cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 3992 + sizeof(frame_buf)); 3988 3993 } 3989 3994 3990 3995 sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); ··· 4046 4051 WLAN_REASON_UNSPECIFIED, 4047 4052 false, frame_buf); 4048 4053 4049 - cfg80211_send_deauth(sdata->dev, frame_buf, 4050 - sizeof(frame_buf)); 4054 + cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 4055 + sizeof(frame_buf)); 4051 4056 } 4052 4057 4053 4058 if (ifmgd->auth_data && !ifmgd->auth_data->done) { ··· 4194 4199 4195 4200 ifmgd->assoc_data = assoc_data; 4196 4201 ifmgd->dtim_period = 0; 4202 + ifmgd->have_beacon = false; 4197 4203 4198 4204 err = ieee80211_prep_connection(sdata, req->bss, true); 4199 4205 if (err) ··· 4226 4230 ifmgd->dtim_period = tim->dtim_period; 4227 4231 dtim_count = tim->dtim_count; 4228 4232 } 4229 - assoc_data->have_beacon = true; 4233 + ifmgd->have_beacon = true; 4230 4234 assoc_data->timeout = jiffies; 4231 4235 assoc_data->timeout_started = true; 4232 4236 ··· 4301 4305 4302 4306 out: 4303 4307 if (report_frame) 4304 - cfg80211_send_deauth(sdata->dev, frame_buf, 4305 - IEEE80211_DEAUTH_FRAME_LEN); 4308 + cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 4309 + IEEE80211_DEAUTH_FRAME_LEN); 4306 4310 4307 4311 return 0; 4308 4312 } ··· 4332 4336 req->reason_code, !req->local_state_change, 4333 4337 frame_buf); 4334 4338 4335 - cfg80211_send_disassoc(sdata->dev, frame_buf, 4336 - IEEE80211_DEAUTH_FRAME_LEN); 4339 + cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, 4340 + IEEE80211_DEAUTH_FRAME_LEN); 4337 4341 4338 4342 return 0; 4339 4343 }
+10 -16
net/mac80211/rx.c
··· 1747 1747 if (unlikely(!ieee80211_has_protected(fc) && 1748 1748 ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && 1749 1749 rx->key)) { 1750 - if (ieee80211_is_deauth(fc)) 1751 - cfg80211_send_unprot_deauth(rx->sdata->dev, 1752 - rx->skb->data, 1753 - rx->skb->len); 1754 - else if (ieee80211_is_disassoc(fc)) 1755 - cfg80211_send_unprot_disassoc(rx->sdata->dev, 1756 - rx->skb->data, 1757 - rx->skb->len); 1750 + if (ieee80211_is_deauth(fc) || 1751 + ieee80211_is_disassoc(fc)) 1752 + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, 1753 + rx->skb->data, 1754 + rx->skb->len); 1758 1755 return -EACCES; 1759 1756 } 1760 1757 /* BIP does not use Protected field, so need to check MMIE */ 1761 1758 if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && 1762 1759 ieee80211_get_mmie_keyidx(rx->skb) < 0)) { 1763 - if (ieee80211_is_deauth(fc)) 1764 - cfg80211_send_unprot_deauth(rx->sdata->dev, 1765 - rx->skb->data, 1766 - rx->skb->len); 1767 - else if (ieee80211_is_disassoc(fc)) 1768 - cfg80211_send_unprot_disassoc(rx->sdata->dev, 1769 - rx->skb->data, 1770 - rx->skb->len); 1760 + if (ieee80211_is_deauth(fc) || 1761 + ieee80211_is_disassoc(fc)) 1762 + cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, 1763 + rx->skb->data, 1764 + rx->skb->len); 1771 1765 return -EACCES; 1772 1766 } 1773 1767 /*
+3 -1
net/mac80211/sta_info.c
··· 1132 1132 * ends the poll/service period. 1133 1133 */ 1134 1134 info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | 1135 + IEEE80211_TX_CTL_PS_RESPONSE | 1135 1136 IEEE80211_TX_STATUS_EOSP | 1136 1137 IEEE80211_TX_CTL_REQ_TX_STATUS; 1137 1138 ··· 1270 1269 * STA may still remain is PS mode after this frame 1271 1270 * exchange. 1272 1271 */ 1273 - info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; 1272 + info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | 1273 + IEEE80211_TX_CTL_PS_RESPONSE; 1274 1274 1275 1275 /* 1276 1276 * Use MoreData flag to indicate whether there are
+3
net/mac80211/sta_info.h
··· 297 297 * @rcu_head: RCU head used for freeing this station struct 298 298 * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, 299 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 */ 301 304 struct sta_info { 302 305 /* General information, mostly static */
-6
net/mac80211/tx.c
··· 1790 1790 break; 1791 1791 #ifdef CONFIG_MAC80211_MESH 1792 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 1793 if (!is_multicast_ether_addr(skb->data)) { 1800 1794 struct sta_info *next_hop; 1801 1795 bool mpp_lookup = true;
+3 -2
net/mac80211/util.c
··· 1584 1584 BSS_CHANGED_ARP_FILTER | 1585 1585 BSS_CHANGED_PS; 1586 1586 1587 - if (sdata->u.mgd.dtim_period) 1588 - changed |= BSS_CHANGED_DTIM_PERIOD; 1587 + /* Re-send beacon info report to the driver */ 1588 + if (sdata->u.mgd.have_beacon) 1589 + changed |= BSS_CHANGED_BEACON_INFO; 1589 1590 1590 1591 sdata_lock(sdata); 1591 1592 ieee80211_bss_info_change_notify(sdata, changed);
+23 -24
net/wireless/core.c
··· 301 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 307 /* give it a proper name */ 305 308 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); 306 309 ··· 452 449 u16 ifmodes = wiphy->interface_modes; 453 450 454 451 #ifdef CONFIG_PM 455 - if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 456 - !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) 452 + if (WARN_ON(wiphy->wowlan && 453 + (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 454 + !(wiphy->wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) 455 + return -EINVAL; 456 + if (WARN_ON(wiphy->wowlan && 457 + !wiphy->wowlan->flags && !wiphy->wowlan->n_patterns && 458 + !wiphy->wowlan->tcp)) 457 459 return -EINVAL; 458 460 #endif 459 461 ··· 548 540 } 549 541 550 542 #ifdef CONFIG_PM 551 - if (rdev->wiphy.wowlan.n_patterns) { 552 - if (WARN_ON(!rdev->wiphy.wowlan.pattern_min_len || 553 - rdev->wiphy.wowlan.pattern_min_len > 554 - rdev->wiphy.wowlan.pattern_max_len)) 555 - return -EINVAL; 556 - } 543 + if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns && 544 + (!rdev->wiphy.wowlan->pattern_min_len || 545 + rdev->wiphy.wowlan->pattern_min_len > 546 + rdev->wiphy.wowlan->pattern_max_len))) 547 + return -EINVAL; 557 548 #endif 558 549 559 550 /* check and set up bitrates */ 560 551 ieee80211_set_bitrate_flags(wiphy); 561 552 562 - rtnl_lock(); 563 553 564 554 res = device_add(&rdev->wiphy.dev); 555 + if (res) 556 + return res; 557 + 558 + res = rfkill_register(rdev->rfkill); 565 559 if (res) { 566 - rtnl_unlock(); 560 + device_del(&rdev->wiphy.dev); 567 561 return res; 568 562 } 569 563 564 + rtnl_lock(); 570 565 /* set up regulatory info */ 571 566 wiphy_regulatory_register(wiphy); 572 567 ··· 595 584 } 596 585 597 586 cfg80211_debugfs_rdev_add(rdev); 598 - 599 - res = rfkill_register(rdev->rfkill); 600 - if (res) { 601 - device_del(&rdev->wiphy.dev); 602 - 603 - debugfs_remove_recursive(rdev->wiphy.debugfsdir); 604 - list_del_rcu(&rdev->list); 605 - wiphy_regulatory_deregister(wiphy); 606 - rtnl_unlock(); 607 - return res; 608 - } 609 587 610 588 rdev->wiphy.registered = true; 611 589 rtnl_unlock(); ··· 632 632 rtnl_unlock(); 633 633 __count == 0; })); 634 634 635 + rfkill_unregister(rdev->rfkill); 636 + 635 637 rtnl_lock(); 636 638 rdev->wiphy.registered = false; 637 - 638 - rfkill_unregister(rdev->rfkill); 639 639 640 640 BUG_ON(!list_empty(&rdev->wdev_list)); 641 641 ··· 817 817 pr_err("failed to add phy80211 symlink to netdev!\n"); 818 818 } 819 819 wdev->netdev = dev; 820 - wdev->sme_state = CFG80211_SME_IDLE; 821 820 #ifdef CONFIG_CFG80211_WEXT 822 821 wdev->wext.default_key = -1; 823 822 wdev->wext.default_mgmt_key = -1;
+16 -14
net/wireless/core.h
··· 308 308 bool local_state_change); 309 309 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, 310 310 struct net_device *dev); 311 - void __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); 316 311 int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, 317 312 u16 frame_type, const u8 *match_data, 318 313 int match_len); ··· 323 328 void cfg80211_oper_and_vht_capa(struct ieee80211_vht_cap *vht_capa, 324 329 const struct ieee80211_vht_cap *vht_capa_mask); 325 330 326 - /* SME */ 331 + /* SME events */ 327 332 int cfg80211_connect(struct cfg80211_registered_device *rdev, 328 333 struct net_device *dev, 329 334 struct cfg80211_connect_params *connect, 330 335 struct cfg80211_cached_keys *connkeys, 331 336 const u8 *prev_bssid); 337 + void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 338 + const u8 *req_ie, size_t req_ie_len, 339 + const u8 *resp_ie, size_t resp_ie_len, 340 + u16 status, bool wextev, 341 + struct cfg80211_bss *bss); 342 + void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 343 + size_t ie_len, u16 reason, bool from_ap); 332 344 int cfg80211_disconnect(struct cfg80211_registered_device *rdev, 333 345 struct net_device *dev, u16 reason, 334 346 bool wextev); ··· 346 344 int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 347 345 struct wireless_dev *wdev); 348 346 347 + /* SME implementation */ 349 348 void cfg80211_conn_work(struct work_struct *work); 350 - void cfg80211_sme_failed_assoc(struct wireless_dev *wdev); 351 - bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev); 349 + void cfg80211_sme_scan_done(struct net_device *dev); 350 + bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status); 351 + void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len); 352 + void cfg80211_sme_disassoc(struct wireless_dev *wdev); 353 + void cfg80211_sme_deauth(struct wireless_dev *wdev); 354 + void cfg80211_sme_auth_timeout(struct wireless_dev *wdev); 355 + void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev); 352 356 353 357 /* internal helpers */ 354 358 bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher); 355 359 int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev, 356 360 struct key_params *params, int key_idx, 357 361 bool pairwise, const u8 *mac_addr); 358 - void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 359 - size_t ie_len, u16 reason, bool from_ap); 360 - void cfg80211_sme_scan_done(struct net_device *dev); 361 - void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len); 362 - void cfg80211_sme_disassoc(struct net_device *dev, 363 - struct cfg80211_internal_bss *bss); 364 362 void __cfg80211_scan_done(struct work_struct *wk); 365 363 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak); 366 364 void __cfg80211_sched_scan_results(struct work_struct *wk);
-6
net/wireless/ibss.c
··· 43 43 cfg80211_hold_bss(bss_from_pub(bss)); 44 44 wdev->current_bss = bss_from_pub(bss); 45 45 46 - wdev->sme_state = CFG80211_SME_CONNECTED; 47 46 cfg80211_upload_connect_keys(wdev); 48 47 49 48 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, ··· 62 63 unsigned long flags; 63 64 64 65 trace_cfg80211_ibss_joined(dev, bssid); 65 - 66 - CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING); 67 66 68 67 ev = kzalloc(sizeof(*ev), gfp); 69 68 if (!ev) ··· 117 120 #ifdef CONFIG_CFG80211_WEXT 118 121 wdev->wext.ibss.chandef = params->chandef; 119 122 #endif 120 - wdev->sme_state = CFG80211_SME_CONNECTING; 121 123 122 124 err = cfg80211_can_use_chan(rdev, wdev, params->chandef.chan, 123 125 params->channel_fixed ··· 130 134 err = rdev_join_ibss(rdev, dev, params); 131 135 if (err) { 132 136 wdev->connect_keys = NULL; 133 - wdev->sme_state = CFG80211_SME_IDLE; 134 137 return err; 135 138 } 136 139 ··· 181 186 } 182 187 183 188 wdev->current_bss = NULL; 184 - wdev->sme_state = CFG80211_SME_IDLE; 185 189 wdev->ssid_len = 0; 186 190 #ifdef CONFIG_CFG80211_WEXT 187 191 if (!nowext)
+12
net/wireless/mesh.c
··· 18 18 #define MESH_PATH_TO_ROOT_TIMEOUT 6000 19 19 #define MESH_ROOT_INTERVAL 5000 20 20 #define MESH_ROOT_CONFIRMATION_INTERVAL 2000 21 + #define MESH_DEFAULT_PLINK_TIMEOUT 1800 /* timeout in seconds */ 21 22 22 23 /* 23 24 * Minimum interval between two consecutive PREQs originated by the same ··· 76 75 .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, 77 76 .power_mode = NL80211_MESH_POWER_ACTIVE, 78 77 .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW, 78 + .plink_timeout = MESH_DEFAULT_PLINK_TIMEOUT, 79 79 }; 80 80 81 81 const struct mesh_setup default_mesh_setup = { ··· 160 158 161 159 setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT; 162 160 setup->chandef.center_freq1 = setup->chandef.chan->center_freq; 161 + } 162 + 163 + /* 164 + * check if basic rates are available otherwise use mandatory rates as 165 + * basic rates 166 + */ 167 + if (!setup->basic_rates) { 168 + struct ieee80211_supported_band *sband = 169 + rdev->wiphy.bands[setup->chandef.chan->band]; 170 + setup->basic_rates = ieee80211_mandatory_rates(sband); 163 171 } 164 172 165 173 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
+104 -153
net/wireless/mlme.c
··· 18 18 #include "rdev-ops.h" 19 19 20 20 21 - void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len) 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 - } 32 - EXPORT_SYMBOL(cfg80211_send_rx_auth); 33 - 34 - void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, 21 + void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, 35 22 const u8 *buf, size_t len) 36 23 { 37 - u16 status_code; 38 24 struct wireless_dev *wdev = dev->ieee80211_ptr; 39 25 struct wiphy *wiphy = wdev->wiphy; 40 26 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 41 27 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 42 28 u8 *ie = mgmt->u.assoc_resp.variable; 43 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 32 trace_cfg80211_send_rx_assoc(dev, bss); 46 - 47 - status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); 48 33 49 34 /* 50 35 * This is a bit of a hack, we don't notify userspace of ··· 37 52 * and got a reject -- we only try again with an assoc 38 53 * frame instead of reassoc. 39 54 */ 40 - if (status_code != WLAN_STATUS_SUCCESS && wdev->conn && 41 - cfg80211_sme_failed_reassoc(wdev)) { 55 + if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { 42 56 cfg80211_put_bss(wiphy, bss); 43 57 return; 44 58 } 45 59 46 60 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 47 - 48 - if (status_code != WLAN_STATUS_SUCCESS && wdev->conn) { 49 - cfg80211_sme_failed_assoc(wdev); 50 - /* 51 - * do not call connect_result() now because the 52 - * sme will schedule work that does it later. 53 - */ 54 - cfg80211_put_bss(wiphy, bss); 55 - return; 56 - } 57 - 58 - if (!wdev->conn && wdev->sme_state == CFG80211_SME_IDLE) { 59 - /* 60 - * This is for the userspace SME, the CONNECTING 61 - * state will be changed to CONNECTED by 62 - * __cfg80211_connect_result() below. 63 - */ 64 - wdev->sme_state = CFG80211_SME_CONNECTING; 65 - } 66 - 67 - /* this consumes the bss reference */ 61 + /* update current_bss etc., consumes the bss reference */ 68 62 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, 69 63 status_code, 70 64 status_code == WLAN_STATUS_SUCCESS, bss); 71 65 } 72 - EXPORT_SYMBOL(cfg80211_send_rx_assoc); 66 + EXPORT_SYMBOL(cfg80211_rx_assoc_resp); 73 67 74 - void cfg80211_send_deauth(struct net_device *dev, 75 - const u8 *buf, size_t len) 68 + static void cfg80211_process_auth(struct wireless_dev *wdev, 69 + const u8 *buf, size_t len) 76 70 { 77 - struct wireless_dev *wdev = dev->ieee80211_ptr; 78 - struct wiphy *wiphy = wdev->wiphy; 79 - struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 80 - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 81 - const u8 *bssid = mgmt->bssid; 82 - bool was_current = false; 71 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 83 72 84 - trace_cfg80211_send_deauth(dev); 85 - ASSERT_WDEV_LOCK(wdev); 86 - 87 - if (wdev->current_bss && 88 - ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 89 - cfg80211_unhold_bss(wdev->current_bss); 90 - cfg80211_put_bss(wiphy, &wdev->current_bss->pub); 91 - wdev->current_bss = NULL; 92 - was_current = true; 93 - } 94 - 95 - nl80211_send_deauth(rdev, dev, buf, len, GFP_KERNEL); 96 - 97 - if (wdev->sme_state == CFG80211_SME_CONNECTED && was_current) { 98 - u16 reason_code; 99 - bool from_ap; 100 - 101 - reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 102 - 103 - from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); 104 - __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 105 - } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { 106 - __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 107 - WLAN_STATUS_UNSPECIFIED_FAILURE, 108 - false, NULL); 109 - } 73 + nl80211_send_rx_auth(rdev, wdev->netdev, buf, len, GFP_KERNEL); 74 + cfg80211_sme_rx_auth(wdev, buf, len); 110 75 } 111 - EXPORT_SYMBOL(cfg80211_send_deauth); 112 76 113 - void cfg80211_send_disassoc(struct net_device *dev, 114 - const u8 *buf, size_t len) 77 + static void cfg80211_process_deauth(struct wireless_dev *wdev, 78 + const u8 *buf, size_t len) 115 79 { 116 - struct wireless_dev *wdev = dev->ieee80211_ptr; 117 - struct wiphy *wiphy = wdev->wiphy; 118 - struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 80 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 119 81 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 120 82 const u8 *bssid = mgmt->bssid; 121 - u16 reason_code; 122 - bool from_ap; 83 + u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 84 + bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr); 123 85 124 - trace_cfg80211_send_disassoc(dev); 125 - ASSERT_WDEV_LOCK(wdev); 86 + nl80211_send_deauth(rdev, wdev->netdev, buf, len, GFP_KERNEL); 126 87 127 - nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 128 - 129 - if (wdev->sme_state != CFG80211_SME_CONNECTED) 88 + if (!wdev->current_bss || 89 + !ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) 130 90 return; 131 91 132 - if (wdev->current_bss && 133 - ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) { 134 - cfg80211_sme_disassoc(dev, wdev->current_bss); 135 - cfg80211_unhold_bss(wdev->current_bss); 136 - cfg80211_put_bss(wiphy, &wdev->current_bss->pub); 137 - wdev->current_bss = NULL; 138 - } else 139 - WARN_ON(1); 140 - 141 - 142 - reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 143 - 144 - from_ap = !ether_addr_equal(mgmt->sa, dev->dev_addr); 145 - __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 92 + __cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap); 93 + cfg80211_sme_deauth(wdev); 146 94 } 147 - EXPORT_SYMBOL(cfg80211_send_disassoc); 148 95 149 - void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr) 96 + static void cfg80211_process_disassoc(struct wireless_dev *wdev, 97 + const u8 *buf, size_t len) 98 + { 99 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 100 + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 101 + const u8 *bssid = mgmt->bssid; 102 + u16 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 103 + bool from_ap = !ether_addr_equal(mgmt->sa, wdev->netdev->dev_addr); 104 + 105 + nl80211_send_disassoc(rdev, wdev->netdev, buf, len, GFP_KERNEL); 106 + 107 + if (WARN_ON(!wdev->current_bss || 108 + !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) 109 + return; 110 + 111 + __cfg80211_disconnected(wdev->netdev, NULL, 0, reason_code, from_ap); 112 + cfg80211_sme_disassoc(wdev); 113 + } 114 + 115 + void cfg80211_rx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len) 116 + { 117 + struct wireless_dev *wdev = dev->ieee80211_ptr; 118 + struct ieee80211_mgmt *mgmt = (void *)buf; 119 + 120 + ASSERT_WDEV_LOCK(wdev); 121 + 122 + trace_cfg80211_rx_mlme_mgmt(dev, buf, len); 123 + 124 + if (WARN_ON(len < 2)) 125 + return; 126 + 127 + if (ieee80211_is_auth(mgmt->frame_control)) 128 + cfg80211_process_auth(wdev, buf, len); 129 + else if (ieee80211_is_deauth(mgmt->frame_control)) 130 + cfg80211_process_deauth(wdev, buf, len); 131 + else if (ieee80211_is_disassoc(mgmt->frame_control)) 132 + cfg80211_process_disassoc(wdev, buf, len); 133 + } 134 + EXPORT_SYMBOL(cfg80211_rx_mlme_mgmt); 135 + 136 + void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr) 150 137 { 151 138 struct wireless_dev *wdev = dev->ieee80211_ptr; 152 139 struct wiphy *wiphy = wdev->wiphy; ··· 127 170 trace_cfg80211_send_auth_timeout(dev, addr); 128 171 129 172 nl80211_send_auth_timeout(rdev, dev, addr, GFP_KERNEL); 130 - if (wdev->sme_state == CFG80211_SME_CONNECTING) 131 - __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 132 - WLAN_STATUS_UNSPECIFIED_FAILURE, 133 - false, NULL); 173 + cfg80211_sme_auth_timeout(wdev); 134 174 } 135 - EXPORT_SYMBOL(cfg80211_send_auth_timeout); 175 + EXPORT_SYMBOL(cfg80211_auth_timeout); 136 176 137 - void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr) 177 + void cfg80211_assoc_timeout(struct net_device *dev, const u8 *addr) 138 178 { 139 179 struct wireless_dev *wdev = dev->ieee80211_ptr; 140 180 struct wiphy *wiphy = wdev->wiphy; ··· 140 186 trace_cfg80211_send_assoc_timeout(dev, addr); 141 187 142 188 nl80211_send_assoc_timeout(rdev, dev, addr, GFP_KERNEL); 143 - if (wdev->sme_state == CFG80211_SME_CONNECTING) 144 - __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 145 - WLAN_STATUS_UNSPECIFIED_FAILURE, 146 - false, NULL); 189 + cfg80211_sme_assoc_timeout(wdev); 147 190 } 148 - EXPORT_SYMBOL(cfg80211_send_assoc_timeout); 191 + EXPORT_SYMBOL(cfg80211_assoc_timeout); 192 + 193 + void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len) 194 + { 195 + struct wireless_dev *wdev = dev->ieee80211_ptr; 196 + struct ieee80211_mgmt *mgmt = (void *)buf; 197 + 198 + ASSERT_WDEV_LOCK(wdev); 199 + 200 + trace_cfg80211_tx_mlme_mgmt(dev, buf, len); 201 + 202 + if (WARN_ON(len < 2)) 203 + return; 204 + 205 + if (ieee80211_is_deauth(mgmt->frame_control)) 206 + cfg80211_process_deauth(wdev, buf, len); 207 + else 208 + cfg80211_process_disassoc(wdev, buf, len); 209 + } 210 + EXPORT_SYMBOL(cfg80211_tx_mlme_mgmt); 149 211 150 212 void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, 151 213 enum nl80211_key_type key_type, int key_id, ··· 284 314 { 285 315 struct wireless_dev *wdev = dev->ieee80211_ptr; 286 316 int err; 287 - bool was_connected = false; 288 317 289 318 ASSERT_WDEV_LOCK(wdev); 290 319 291 - if (wdev->current_bss && req->prev_bssid && 292 - ether_addr_equal(wdev->current_bss->pub.bssid, req->prev_bssid)) { 293 - /* 294 - * Trying to reassociate: Allow this to proceed and let the old 295 - * association to be dropped when the new one is completed. 296 - */ 297 - if (wdev->sme_state == CFG80211_SME_CONNECTED) { 298 - was_connected = true; 299 - wdev->sme_state = CFG80211_SME_CONNECTING; 300 - } 301 - } else if (wdev->current_bss) 320 + if (wdev->current_bss && 321 + (!req->prev_bssid || !ether_addr_equal(wdev->current_bss->pub.bssid, 322 + req->prev_bssid))) 302 323 return -EALREADY; 303 324 304 325 cfg80211_oper_and_ht_capa(&req->ht_capa_mask, ··· 299 338 300 339 req->bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 301 340 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 302 - if (!req->bss) { 303 - if (was_connected) 304 - wdev->sme_state = CFG80211_SME_CONNECTED; 341 + if (!req->bss) 305 342 return -ENOENT; 306 - } 307 343 308 344 err = cfg80211_can_use_chan(rdev, wdev, chan, CHAN_MODE_SHARED); 309 345 if (err) ··· 309 351 err = rdev_assoc(rdev, dev, req); 310 352 311 353 out: 312 - if (err) { 313 - if (was_connected) 314 - wdev->sme_state = CFG80211_SME_CONNECTED; 354 + if (err) 315 355 cfg80211_put_bss(&rdev->wiphy, req->bss); 316 - } 317 356 318 357 return err; 319 358 } ··· 331 376 332 377 ASSERT_WDEV_LOCK(wdev); 333 378 334 - if (local_state_change && (!wdev->current_bss || 335 - !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) 379 + if (local_state_change && 380 + (!wdev->current_bss || 381 + !ether_addr_equal(wdev->current_bss->pub.bssid, bssid))) 336 382 return 0; 337 383 338 384 return rdev_deauth(rdev, dev, &req); ··· 351 395 .ie = ie, 352 396 .ie_len = ie_len, 353 397 }; 398 + int err; 354 399 355 400 ASSERT_WDEV_LOCK(wdev); 356 401 357 - if (wdev->sme_state != CFG80211_SME_CONNECTED) 358 - return -ENOTCONN; 359 - 360 - if (WARN(!wdev->current_bss, "sme_state=%d\n", wdev->sme_state)) 402 + if (!wdev->current_bss) 361 403 return -ENOTCONN; 362 404 363 405 if (ether_addr_equal(wdev->current_bss->pub.bssid, bssid)) ··· 363 409 else 364 410 return -ENOTCONN; 365 411 366 - return rdev_disassoc(rdev, dev, &req); 412 + err = rdev_disassoc(rdev, dev, &req); 413 + if (err) 414 + return err; 415 + 416 + /* driver should have reported the disassoc */ 417 + WARN_ON(wdev->current_bss); 418 + return 0; 367 419 } 368 420 369 421 void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, ··· 377 417 { 378 418 struct wireless_dev *wdev = dev->ieee80211_ptr; 379 419 u8 bssid[ETH_ALEN]; 380 - struct cfg80211_deauth_request req = { 381 - .reason_code = WLAN_REASON_DEAUTH_LEAVING, 382 - .bssid = bssid, 383 - }; 384 420 385 421 ASSERT_WDEV_LOCK(wdev); 386 422 ··· 387 431 return; 388 432 389 433 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN); 390 - rdev_deauth(rdev, dev, &req); 391 - 392 - if (wdev->current_bss) { 393 - cfg80211_unhold_bss(wdev->current_bss); 394 - cfg80211_put_bss(&rdev->wiphy, &wdev->current_bss->pub); 395 - wdev->current_bss = NULL; 396 - } 434 + cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, 435 + WLAN_REASON_DEAUTH_LEAVING, false); 397 436 } 398 437 399 438 struct cfg80211_mgmt_registration {
+100 -96
net/wireless/nl80211.c
··· 800 800 case NL80211_IFTYPE_MESH_POINT: 801 801 break; 802 802 case NL80211_IFTYPE_ADHOC: 803 - if (!wdev->current_bss) 804 - return -ENOLINK; 805 - break; 806 803 case NL80211_IFTYPE_STATION: 807 804 case NL80211_IFTYPE_P2P_CLIENT: 808 - if (wdev->sme_state != CFG80211_SME_CONNECTED) 805 + if (!wdev->current_bss) 809 806 return -ENOLINK; 810 807 break; 811 808 default: ··· 905 908 static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev, 906 909 struct sk_buff *msg) 907 910 { 908 - const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp; 911 + const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan->tcp; 909 912 struct nlattr *nl_tcp; 910 913 911 914 if (!tcp) ··· 948 951 { 949 952 struct nlattr *nl_wowlan; 950 953 951 - if (!dev->wiphy.wowlan.flags && !dev->wiphy.wowlan.n_patterns) 954 + if (!dev->wiphy.wowlan) 952 955 return 0; 953 956 954 957 nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED); 955 958 if (!nl_wowlan) 956 959 return -ENOBUFS; 957 960 958 - if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) && 961 + if (((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_ANY) && 959 962 nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || 960 - ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) && 963 + ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_DISCONNECT) && 961 964 nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || 962 - ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) && 965 + ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT) && 963 966 nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || 964 - ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) && 967 + ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) && 965 968 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) || 966 - ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 969 + ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 967 970 nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || 968 - ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) && 971 + ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) && 969 972 nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || 970 - ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) && 973 + ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) && 971 974 nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || 972 - ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) && 975 + ((dev->wiphy.wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE) && 973 976 nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) 974 977 return -ENOBUFS; 975 978 976 - if (dev->wiphy.wowlan.n_patterns) { 979 + if (dev->wiphy.wowlan->n_patterns) { 977 980 struct nl80211_wowlan_pattern_support pat = { 978 - .max_patterns = dev->wiphy.wowlan.n_patterns, 979 - .min_pattern_len = dev->wiphy.wowlan.pattern_min_len, 980 - .max_pattern_len = dev->wiphy.wowlan.pattern_max_len, 981 - .max_pkt_offset = dev->wiphy.wowlan.max_pkt_offset, 981 + .max_patterns = dev->wiphy.wowlan->n_patterns, 982 + .min_pattern_len = dev->wiphy.wowlan->pattern_min_len, 983 + .max_pattern_len = dev->wiphy.wowlan->pattern_max_len, 984 + .max_pkt_offset = dev->wiphy.wowlan->max_pkt_offset, 982 985 }; 983 986 984 987 if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, ··· 1541 1544 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); 1542 1545 1543 1546 netdev = dev_get_by_index(sock_net(skb->sk), ifidx); 1544 - if (!netdev) 1547 + if (!netdev) { 1548 + rtnl_unlock(); 1545 1549 return -ENODEV; 1550 + } 1546 1551 if (netdev->ieee80211_ptr) { 1547 1552 dev = wiphy_to_dev( 1548 1553 netdev->ieee80211_ptr->wiphy); ··· 1588 1589 !skb->len && 1589 1590 cb->min_dump_alloc < 4096) { 1590 1591 cb->min_dump_alloc = 4096; 1592 + rtnl_unlock(); 1591 1593 return 1; 1592 1594 } 1593 1595 idx--; ··· 3975 3975 params.listen_interval = 3976 3976 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 3977 3977 3978 - if (info->attrs[NL80211_ATTR_STA_AID]) 3979 - params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 3980 - else 3978 + if (info->attrs[NL80211_ATTR_PEER_AID]) 3981 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 3982 if (!params.aid || params.aid > IEEE80211_MAX_AID) 3983 3983 return -EINVAL; 3984 3984 ··· 4030 4030 params.sta_modify_mask &= ~STATION_PARAM_APPLY_UAPSD; 4031 4031 4032 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 4035 return -EINVAL; 4035 4036 /* but don't bother the driver with it */ 4036 4037 params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); ··· 4057 4056 if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) 4058 4057 return -EINVAL; 4059 4058 /* TDLS peers cannot be added */ 4060 - if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) 4059 + if ((params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) || 4060 + info->attrs[NL80211_ATTR_PEER_AID]) 4061 4061 return -EINVAL; 4062 4062 break; 4063 4063 case NL80211_IFTYPE_STATION: ··· 4580 4578 nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE, 4581 4579 cur_params.power_mode) || 4582 4580 nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW, 4583 - cur_params.dot11MeshAwakeWindowDuration)) 4581 + cur_params.dot11MeshAwakeWindowDuration) || 4582 + nla_put_u32(msg, NL80211_MESHCONF_PLINK_TIMEOUT, 4583 + cur_params.plink_timeout)) 4584 4584 goto nla_put_failure; 4585 4585 nla_nest_end(msg, pinfoattr); 4586 4586 genlmsg_end(msg, hdr); ··· 4623 4619 [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, 4624 4620 [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 }, 4625 4621 [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, 4622 + [NL80211_MESHCONF_PLINK_TIMEOUT] = { .type = NLA_U32 }, 4626 4623 }; 4627 4624 4628 4625 static const struct nla_policy ··· 4761 4756 FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, 4762 4757 0, 65535, mask, 4763 4758 NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16); 4759 + FILL_IN_MESH_PARAM_IF_SET(tb, cfg, plink_timeout, 1, 0xffffffff, 4760 + mask, NL80211_MESHCONF_PLINK_TIMEOUT, 4761 + nla_get_u32); 4764 4762 if (mask_out) 4765 4763 *mask_out = mask; 4766 4764 ··· 7150 7142 return -EOPNOTSUPP; 7151 7143 7152 7144 switch (wdev->iftype) { 7145 + case NL80211_IFTYPE_P2P_DEVICE: 7146 + if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) 7147 + return -EINVAL; 7153 7148 case NL80211_IFTYPE_STATION: 7154 7149 case NL80211_IFTYPE_ADHOC: 7155 7150 case NL80211_IFTYPE_P2P_CLIENT: ··· 7160 7149 case NL80211_IFTYPE_AP_VLAN: 7161 7150 case NL80211_IFTYPE_MESH_POINT: 7162 7151 case NL80211_IFTYPE_P2P_GO: 7163 - case NL80211_IFTYPE_P2P_DEVICE: 7164 7152 break; 7165 7153 default: 7166 7154 return -EOPNOTSUPP; ··· 7187 7177 7188 7178 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 7189 7179 7190 - err = nl80211_parse_chandef(rdev, info, &chandef); 7191 - if (err) 7192 - return err; 7180 + /* get the channel if any has been specified, otherwise pass NULL to 7181 + * the driver. The latter will use the current one 7182 + */ 7183 + chandef.chan = NULL; 7184 + if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 7185 + err = nl80211_parse_chandef(rdev, info, &chandef); 7186 + if (err) 7187 + return err; 7188 + } 7189 + 7190 + if (!chandef.chan && offchan) 7191 + return -EINVAL; 7193 7192 7194 7193 if (!dont_wait_for_ack) { 7195 7194 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); ··· 7503 7484 setup.chandef.chan = NULL; 7504 7485 } 7505 7486 7487 + if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { 7488 + u8 *rates = nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 7489 + int n_rates = 7490 + nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 7491 + struct ieee80211_supported_band *sband; 7492 + 7493 + if (!setup.chandef.chan) 7494 + return -EINVAL; 7495 + 7496 + sband = rdev->wiphy.bands[setup.chandef.chan->band]; 7497 + 7498 + err = ieee80211_get_ratemask(sband, rates, n_rates, 7499 + &setup.basic_rates); 7500 + if (err) 7501 + return err; 7502 + } 7503 + 7506 7504 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 7507 7505 } 7508 7506 ··· 7616 7580 void *hdr; 7617 7581 u32 size = NLMSG_DEFAULT_SIZE; 7618 7582 7619 - if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns && 7620 - !rdev->wiphy.wowlan.tcp) 7583 + if (!rdev->wiphy.wowlan) 7621 7584 return -EOPNOTSUPP; 7622 7585 7623 7586 if (rdev->wiphy.wowlan_config && rdev->wiphy.wowlan_config->tcp) { ··· 7689 7654 u32 data_size, wake_size, tokens_size = 0, wake_mask_size; 7690 7655 int err, port; 7691 7656 7692 - if (!rdev->wiphy.wowlan.tcp) 7657 + if (!rdev->wiphy.wowlan->tcp) 7693 7658 return -EINVAL; 7694 7659 7695 7660 err = nla_parse(tb, MAX_NL80211_WOWLAN_TCP, ··· 7709 7674 return -EINVAL; 7710 7675 7711 7676 data_size = nla_len(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD]); 7712 - if (data_size > rdev->wiphy.wowlan.tcp->data_payload_max) 7677 + if (data_size > rdev->wiphy.wowlan->tcp->data_payload_max) 7713 7678 return -EINVAL; 7714 7679 7715 7680 if (nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) > 7716 - rdev->wiphy.wowlan.tcp->data_interval_max || 7681 + rdev->wiphy.wowlan->tcp->data_interval_max || 7717 7682 nla_get_u32(tb[NL80211_WOWLAN_TCP_DATA_INTERVAL]) == 0) 7718 7683 return -EINVAL; 7719 7684 7720 7685 wake_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_PAYLOAD]); 7721 - if (wake_size > rdev->wiphy.wowlan.tcp->wake_payload_max) 7686 + if (wake_size > rdev->wiphy.wowlan->tcp->wake_payload_max) 7722 7687 return -EINVAL; 7723 7688 7724 7689 wake_mask_size = nla_len(tb[NL80211_WOWLAN_TCP_WAKE_MASK]); ··· 7733 7698 7734 7699 if (!tok->len || tokens_size % tok->len) 7735 7700 return -EINVAL; 7736 - if (!rdev->wiphy.wowlan.tcp->tok) 7701 + if (!rdev->wiphy.wowlan->tcp->tok) 7737 7702 return -EINVAL; 7738 - if (tok->len > rdev->wiphy.wowlan.tcp->tok->max_len) 7703 + if (tok->len > rdev->wiphy.wowlan->tcp->tok->max_len) 7739 7704 return -EINVAL; 7740 - if (tok->len < rdev->wiphy.wowlan.tcp->tok->min_len) 7705 + if (tok->len < rdev->wiphy.wowlan->tcp->tok->min_len) 7741 7706 return -EINVAL; 7742 - if (tokens_size > rdev->wiphy.wowlan.tcp->tok->bufsize) 7707 + if (tokens_size > rdev->wiphy.wowlan->tcp->tok->bufsize) 7743 7708 return -EINVAL; 7744 7709 if (tok->offset + tok->len > data_size) 7745 7710 return -EINVAL; ··· 7747 7712 7748 7713 if (tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]) { 7749 7714 seq = nla_data(tb[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ]); 7750 - if (!rdev->wiphy.wowlan.tcp->seq) 7715 + if (!rdev->wiphy.wowlan->tcp->seq) 7751 7716 return -EINVAL; 7752 7717 if (seq->len == 0 || seq->len > 4) 7753 7718 return -EINVAL; ··· 7828 7793 struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; 7829 7794 struct cfg80211_wowlan new_triggers = {}; 7830 7795 struct cfg80211_wowlan *ntrig; 7831 - struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; 7796 + const struct wiphy_wowlan_support *wowlan = rdev->wiphy.wowlan; 7832 7797 int err, i; 7833 7798 bool prev_enabled = rdev->wiphy.wowlan_config; 7834 7799 7835 - if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns && 7836 - !rdev->wiphy.wowlan.tcp) 7800 + if (!wowlan) 7837 7801 return -EOPNOTSUPP; 7838 7802 7839 7803 if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { ··· 9349 9315 NL80211_CMD_DISASSOCIATE, gfp); 9350 9316 } 9351 9317 9352 - void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, 9353 - size_t len) 9318 + void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, 9319 + size_t len) 9354 9320 { 9355 9321 struct wireless_dev *wdev = dev->ieee80211_ptr; 9356 9322 struct wiphy *wiphy = wdev->wiphy; 9357 9323 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 9324 + const struct ieee80211_mgmt *mgmt = (void *)buf; 9325 + u32 cmd; 9358 9326 9359 - trace_cfg80211_send_unprot_deauth(dev); 9360 - nl80211_send_mlme_event(rdev, dev, buf, len, 9361 - NL80211_CMD_UNPROT_DEAUTHENTICATE, GFP_ATOMIC); 9327 + if (WARN_ON(len < 2)) 9328 + return; 9329 + 9330 + if (ieee80211_is_deauth(mgmt->frame_control)) 9331 + cmd = NL80211_CMD_UNPROT_DEAUTHENTICATE; 9332 + else 9333 + cmd = NL80211_CMD_UNPROT_DISASSOCIATE; 9334 + 9335 + trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); 9336 + nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC); 9362 9337 } 9363 - EXPORT_SYMBOL(cfg80211_send_unprot_deauth); 9364 - 9365 - void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, 9366 - size_t len) 9367 - { 9368 - struct wireless_dev *wdev = dev->ieee80211_ptr; 9369 - struct wiphy *wiphy = wdev->wiphy; 9370 - struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 9371 - 9372 - trace_cfg80211_send_unprot_disassoc(dev); 9373 - nl80211_send_mlme_event(rdev, dev, buf, len, 9374 - NL80211_CMD_UNPROT_DISASSOCIATE, GFP_ATOMIC); 9375 - } 9376 - EXPORT_SYMBOL(cfg80211_send_unprot_disassoc); 9338 + EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); 9377 9339 9378 9340 static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, 9379 9341 struct net_device *netdev, int cmd, ··· 9880 9850 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 9881 9851 struct sk_buff *msg; 9882 9852 void *hdr; 9883 - int err; 9884 9853 u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid); 9885 9854 9886 9855 if (!nlportid) ··· 9900 9871 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) 9901 9872 goto nla_put_failure; 9902 9873 9903 - err = genlmsg_end(msg, hdr); 9904 - if (err < 0) { 9905 - nlmsg_free(msg); 9906 - return true; 9907 - } 9908 - 9874 + genlmsg_end(msg, hdr); 9909 9875 genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); 9910 9876 return true; 9911 9877 ··· 10343 10319 if (nl80211_send_chandef(msg, chandef)) 10344 10320 goto nla_put_failure; 10345 10321 10346 - if (genlmsg_end(msg, hdr) < 0) { 10347 - nlmsg_free(msg); 10348 - return; 10349 - } 10322 + genlmsg_end(msg, hdr); 10350 10323 10351 10324 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10352 10325 nl80211_mlme_mcgrp.id, gfp); ··· 10409 10388 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 10410 10389 struct sk_buff *msg; 10411 10390 void *hdr; 10412 - int err; 10413 10391 10414 10392 trace_cfg80211_probe_status(dev, addr, cookie, acked); 10415 10393 ··· 10430 10410 (acked && nla_put_flag(msg, NL80211_ATTR_ACK))) 10431 10411 goto nla_put_failure; 10432 10412 10433 - err = genlmsg_end(msg, hdr); 10434 - if (err < 0) { 10435 - nlmsg_free(msg); 10436 - return; 10437 - } 10413 + genlmsg_end(msg, hdr); 10438 10414 10439 10415 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10440 10416 nl80211_mlme_mcgrp.id, gfp); ··· 10496 10480 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 10497 10481 struct sk_buff *msg; 10498 10482 void *hdr; 10499 - int err, size = 200; 10483 + int size = 200; 10500 10484 10501 10485 trace_cfg80211_report_wowlan_wakeup(wdev->wiphy, wdev, wakeup); 10502 10486 ··· 10582 10566 nla_nest_end(msg, reasons); 10583 10567 } 10584 10568 10585 - err = genlmsg_end(msg, hdr); 10586 - if (err < 0) 10587 - goto free_msg; 10569 + genlmsg_end(msg, hdr); 10588 10570 10589 10571 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10590 10572 nl80211_mlme_mcgrp.id, gfp); ··· 10602 10588 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 10603 10589 struct sk_buff *msg; 10604 10590 void *hdr; 10605 - int err; 10606 10591 10607 10592 trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper, 10608 10593 reason_code); ··· 10624 10611 nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code))) 10625 10612 goto nla_put_failure; 10626 10613 10627 - err = genlmsg_end(msg, hdr); 10628 - if (err < 0) { 10629 - nlmsg_free(msg); 10630 - return; 10631 - } 10614 + genlmsg_end(msg, hdr); 10632 10615 10633 10616 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10634 10617 nl80211_mlme_mcgrp.id, gfp); ··· 10682 10673 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 10683 10674 struct sk_buff *msg; 10684 10675 void *hdr; 10685 - int err; 10686 10676 10687 10677 trace_cfg80211_ft_event(wiphy, netdev, ft_event); 10688 10678 ··· 10707 10699 nla_put(msg, NL80211_ATTR_IE_RIC, ft_event->ric_ies_len, 10708 10700 ft_event->ric_ies); 10709 10701 10710 - err = genlmsg_end(msg, hdr); 10711 - if (err < 0) { 10712 - nlmsg_free(msg); 10713 - return; 10714 - } 10702 + genlmsg_end(msg, hdr); 10715 10703 10716 10704 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, 10717 10705 nl80211_mlme_mcgrp.id, GFP_KERNEL);
+1 -1
net/wireless/reg.c
··· 1345 1345 return REG_REQ_OK; 1346 1346 return REG_REQ_ALREADY_SET; 1347 1347 } 1348 - return 0; 1348 + return REG_REQ_OK; 1349 1349 case NL80211_REGDOM_SET_BY_DRIVER: 1350 1350 if (lr->initiator == NL80211_REGDOM_SET_BY_CORE) { 1351 1351 if (regdom_changes(pending_request->alpha2))
+254 -288
net/wireless/sme.c
··· 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 6 * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> 5 7 * Copyright (C) 2009 Intel Corporation. All rights reserved. ··· 20 18 #include "reg.h" 21 19 #include "rdev-ops.h" 22 20 21 + /* 22 + * Software SME in cfg80211, using auth/assoc/deauth calls to the 23 + * driver. This is is for implementing nl80211's connect/disconnect 24 + * and wireless extensions (if configured.) 25 + */ 26 + 23 27 struct cfg80211_conn { 24 28 struct cfg80211_connect_params params; 25 29 /* these are sub-states of the _CONNECTING sme_state */ 26 30 enum { 27 - CFG80211_CONN_IDLE, 28 31 CFG80211_CONN_SCANNING, 29 32 CFG80211_CONN_SCAN_AGAIN, 30 33 CFG80211_CONN_AUTHENTICATE_NEXT, 31 34 CFG80211_CONN_AUTHENTICATING, 32 35 CFG80211_CONN_ASSOCIATE_NEXT, 33 36 CFG80211_CONN_ASSOCIATING, 34 - CFG80211_CONN_DEAUTH_ASSOC_FAIL, 37 + CFG80211_CONN_DEAUTH, 38 + CFG80211_CONN_CONNECTED, 35 39 } state; 36 40 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; 37 41 u8 *ie; ··· 45 37 bool auto_auth, prev_bssid_valid; 46 38 }; 47 39 48 - static bool cfg80211_is_all_idle(void) 40 + static void cfg80211_sme_free(struct wireless_dev *wdev) 49 41 { 50 - struct cfg80211_registered_device *rdev; 51 - struct wireless_dev *wdev; 52 - bool is_all_idle = true; 42 + if (!wdev->conn) 43 + return; 53 44 54 - /* 55 - * All devices must be idle as otherwise if you are actively 56 - * scanning some new beacon hints could be learned and would 57 - * count as new regulatory hints. 58 - */ 59 - list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 60 - list_for_each_entry(wdev, &rdev->wdev_list, list) { 61 - wdev_lock(wdev); 62 - if (wdev->sme_state != CFG80211_SME_IDLE) 63 - is_all_idle = false; 64 - wdev_unlock(wdev); 65 - } 66 - } 67 - 68 - return is_all_idle; 45 + kfree(wdev->conn->ie); 46 + kfree(wdev->conn); 47 + wdev->conn = NULL; 69 48 } 70 - 71 - static void disconnect_work(struct work_struct *work) 72 - { 73 - rtnl_lock(); 74 - if (cfg80211_is_all_idle()) 75 - regulatory_hint_disconnect(); 76 - rtnl_unlock(); 77 - } 78 - 79 - static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); 80 49 81 50 static int cfg80211_conn_scan(struct wireless_dev *wdev) 82 51 { ··· 149 164 params = &wdev->conn->params; 150 165 151 166 switch (wdev->conn->state) { 167 + case CFG80211_CONN_SCANNING: 168 + /* didn't find it during scan ... */ 169 + return -ENOENT; 152 170 case CFG80211_CONN_SCAN_AGAIN: 153 171 return cfg80211_conn_scan(wdev); 154 172 case CFG80211_CONN_AUTHENTICATE_NEXT: ··· 188 200 WLAN_REASON_DEAUTH_LEAVING, 189 201 false); 190 202 return err; 191 - case CFG80211_CONN_DEAUTH_ASSOC_FAIL: 203 + case CFG80211_CONN_DEAUTH: 192 204 cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid, 193 205 NULL, 0, 194 206 WLAN_REASON_DEAUTH_LEAVING, false); 195 - /* return an error so that we call __cfg80211_connect_result() */ 196 - return -EINVAL; 207 + return 0; 197 208 default: 198 209 return 0; 199 210 } ··· 216 229 wdev_unlock(wdev); 217 230 continue; 218 231 } 219 - if (wdev->sme_state != CFG80211_SME_CONNECTING || !wdev->conn) { 232 + if (!wdev->conn || 233 + wdev->conn->state == CFG80211_CONN_CONNECTED) { 220 234 wdev_unlock(wdev); 221 235 continue; 222 236 } ··· 225 237 memcpy(bssid_buf, wdev->conn->params.bssid, ETH_ALEN); 226 238 bssid = bssid_buf; 227 239 } 228 - if (cfg80211_conn_do_work(wdev)) 240 + if (cfg80211_conn_do_work(wdev)) { 229 241 __cfg80211_connect_result( 230 242 wdev->netdev, bssid, 231 243 NULL, 0, NULL, 0, 232 244 WLAN_STATUS_UNSPECIFIED_FAILURE, 233 245 false, NULL); 246 + cfg80211_sme_free(wdev); 247 + } 234 248 wdev_unlock(wdev); 235 249 } 236 250 ··· 276 286 277 287 ASSERT_WDEV_LOCK(wdev); 278 288 279 - if (wdev->sme_state != CFG80211_SME_CONNECTING) 280 - return; 281 - 282 289 if (!wdev->conn) 283 290 return; 284 291 ··· 284 297 return; 285 298 286 299 bss = cfg80211_get_conn_bss(wdev); 287 - if (bss) { 300 + if (bss) 288 301 cfg80211_put_bss(&rdev->wiphy, bss); 289 - } else { 290 - /* not found */ 291 - if (wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) 292 - schedule_work(&rdev->conn_work); 293 - else 294 - __cfg80211_connect_result( 295 - wdev->netdev, 296 - wdev->conn->params.bssid, 297 - NULL, 0, NULL, 0, 298 - WLAN_STATUS_UNSPECIFIED_FAILURE, 299 - false, NULL); 300 - } 302 + else 303 + schedule_work(&rdev->conn_work); 301 304 } 302 305 303 306 void cfg80211_sme_scan_done(struct net_device *dev) ··· 299 322 wdev_unlock(wdev); 300 323 } 301 324 302 - void cfg80211_sme_rx_auth(struct net_device *dev, 303 - const u8 *buf, size_t len) 325 + void cfg80211_sme_rx_auth(struct wireless_dev *wdev, const u8 *buf, size_t len) 304 326 { 305 - struct wireless_dev *wdev = dev->ieee80211_ptr; 306 327 struct wiphy *wiphy = wdev->wiphy; 307 328 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 308 329 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; ··· 308 333 309 334 ASSERT_WDEV_LOCK(wdev); 310 335 311 - /* should only RX auth frames when connecting */ 312 - if (wdev->sme_state != CFG80211_SME_CONNECTING) 313 - return; 314 - 315 - if (WARN_ON(!wdev->conn)) 336 + if (!wdev->conn || wdev->conn->state == CFG80211_CONN_CONNECTED) 316 337 return; 317 338 318 339 if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG && ··· 337 366 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; 338 367 schedule_work(&rdev->conn_work); 339 368 } else if (status_code != WLAN_STATUS_SUCCESS) { 340 - __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 369 + __cfg80211_connect_result(wdev->netdev, mgmt->bssid, 370 + NULL, 0, NULL, 0, 341 371 status_code, false, NULL); 342 - } else if (wdev->sme_state == CFG80211_SME_CONNECTING && 343 - wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { 372 + } else if (wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { 344 373 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 345 374 schedule_work(&rdev->conn_work); 346 375 } 347 376 } 348 377 349 - bool cfg80211_sme_failed_reassoc(struct wireless_dev *wdev) 378 + bool cfg80211_sme_rx_assoc_resp(struct wireless_dev *wdev, u16 status) 350 379 { 351 - struct wiphy *wiphy = wdev->wiphy; 352 - struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 380 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 353 381 354 - if (WARN_ON(!wdev->conn)) 382 + if (!wdev->conn) 355 383 return false; 356 384 357 - if (!wdev->conn->prev_bssid_valid) 385 + if (status == WLAN_STATUS_SUCCESS) { 386 + wdev->conn->state = CFG80211_CONN_CONNECTED; 358 387 return false; 388 + } 389 + 390 + if (wdev->conn->prev_bssid_valid) { 391 + /* 392 + * Some stupid APs don't accept reassoc, so we 393 + * need to fall back to trying regular assoc; 394 + * return true so no event is sent to userspace. 395 + */ 396 + wdev->conn->prev_bssid_valid = false; 397 + wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 398 + schedule_work(&rdev->conn_work); 399 + return true; 400 + } 401 + 402 + wdev->conn->state = CFG80211_CONN_DEAUTH; 403 + schedule_work(&rdev->conn_work); 404 + return false; 405 + } 406 + 407 + void cfg80211_sme_deauth(struct wireless_dev *wdev) 408 + { 409 + cfg80211_sme_free(wdev); 410 + } 411 + 412 + void cfg80211_sme_auth_timeout(struct wireless_dev *wdev) 413 + { 414 + cfg80211_sme_free(wdev); 415 + } 416 + 417 + void cfg80211_sme_disassoc(struct wireless_dev *wdev) 418 + { 419 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 420 + 421 + if (!wdev->conn) 422 + return; 423 + 424 + wdev->conn->state = CFG80211_CONN_DEAUTH; 425 + schedule_work(&rdev->conn_work); 426 + } 427 + 428 + void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev) 429 + { 430 + cfg80211_sme_disassoc(wdev); 431 + } 432 + 433 + static int cfg80211_sme_connect(struct wireless_dev *wdev, 434 + struct cfg80211_connect_params *connect, 435 + const u8 *prev_bssid) 436 + { 437 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 438 + struct cfg80211_bss *bss; 439 + int err; 440 + 441 + if (!rdev->ops->auth || !rdev->ops->assoc) 442 + return -EOPNOTSUPP; 443 + 444 + if (wdev->current_bss) 445 + return -EALREADY; 446 + 447 + if (WARN_ON(wdev->conn)) 448 + return -EINPROGRESS; 449 + 450 + wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL); 451 + if (!wdev->conn) 452 + return -ENOMEM; 359 453 360 454 /* 361 - * Some stupid APs don't accept reassoc, so we 362 - * need to fall back to trying regular assoc. 455 + * Copy all parameters, and treat explicitly IEs, BSSID, SSID. 363 456 */ 364 - wdev->conn->prev_bssid_valid = false; 365 - wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 366 - schedule_work(&rdev->conn_work); 457 + memcpy(&wdev->conn->params, connect, sizeof(*connect)); 458 + if (connect->bssid) { 459 + wdev->conn->params.bssid = wdev->conn->bssid; 460 + memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN); 461 + } 367 462 368 - return true; 463 + if (connect->ie) { 464 + wdev->conn->ie = kmemdup(connect->ie, connect->ie_len, 465 + GFP_KERNEL); 466 + wdev->conn->params.ie = wdev->conn->ie; 467 + if (!wdev->conn->ie) { 468 + kfree(wdev->conn); 469 + wdev->conn = NULL; 470 + return -ENOMEM; 471 + } 472 + } 473 + 474 + if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { 475 + wdev->conn->auto_auth = true; 476 + /* start with open system ... should mostly work */ 477 + wdev->conn->params.auth_type = 478 + NL80211_AUTHTYPE_OPEN_SYSTEM; 479 + } else { 480 + wdev->conn->auto_auth = false; 481 + } 482 + 483 + wdev->conn->params.ssid = wdev->ssid; 484 + wdev->conn->params.ssid_len = connect->ssid_len; 485 + 486 + /* see if we have the bss already */ 487 + bss = cfg80211_get_conn_bss(wdev); 488 + 489 + if (prev_bssid) { 490 + memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN); 491 + wdev->conn->prev_bssid_valid = true; 492 + } 493 + 494 + /* we're good if we have a matching bss struct */ 495 + if (bss) { 496 + wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; 497 + err = cfg80211_conn_do_work(wdev); 498 + cfg80211_put_bss(wdev->wiphy, bss); 499 + } else { 500 + /* otherwise we'll need to scan for the AP first */ 501 + err = cfg80211_conn_scan(wdev); 502 + 503 + /* 504 + * If we can't scan right now, then we need to scan again 505 + * after the current scan finished, since the parameters 506 + * changed (unless we find a good AP anyway). 507 + */ 508 + if (err == -EBUSY) { 509 + err = 0; 510 + wdev->conn->state = CFG80211_CONN_SCAN_AGAIN; 511 + } 512 + } 513 + 514 + if (err) 515 + cfg80211_sme_free(wdev); 516 + 517 + return err; 369 518 } 370 519 371 - void cfg80211_sme_failed_assoc(struct wireless_dev *wdev) 520 + static int cfg80211_sme_disconnect(struct wireless_dev *wdev, u16 reason) 372 521 { 373 - struct wiphy *wiphy = wdev->wiphy; 374 - struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); 522 + struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 523 + int err; 375 524 376 - wdev->conn->state = CFG80211_CONN_DEAUTH_ASSOC_FAIL; 377 - schedule_work(&rdev->conn_work); 525 + if (!wdev->conn) 526 + return 0; 527 + 528 + if (!rdev->ops->deauth) 529 + return -EOPNOTSUPP; 530 + 531 + if (wdev->conn->state == CFG80211_CONN_SCANNING || 532 + wdev->conn->state == CFG80211_CONN_SCAN_AGAIN) { 533 + err = 0; 534 + goto out; 535 + } 536 + 537 + /* wdev->conn->params.bssid must be set if > SCANNING */ 538 + err = cfg80211_mlme_deauth(rdev, wdev->netdev, 539 + wdev->conn->params.bssid, 540 + NULL, 0, reason, false); 541 + out: 542 + cfg80211_sme_free(wdev); 543 + return err; 378 544 } 545 + 546 + /* 547 + * code shared for in-device and software SME 548 + */ 549 + 550 + static bool cfg80211_is_all_idle(void) 551 + { 552 + struct cfg80211_registered_device *rdev; 553 + struct wireless_dev *wdev; 554 + bool is_all_idle = true; 555 + 556 + /* 557 + * All devices must be idle as otherwise if you are actively 558 + * scanning some new beacon hints could be learned and would 559 + * count as new regulatory hints. 560 + */ 561 + list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 562 + list_for_each_entry(wdev, &rdev->wdev_list, list) { 563 + wdev_lock(wdev); 564 + if (wdev->conn || wdev->current_bss) 565 + is_all_idle = false; 566 + wdev_unlock(wdev); 567 + } 568 + } 569 + 570 + return is_all_idle; 571 + } 572 + 573 + static void disconnect_work(struct work_struct *work) 574 + { 575 + rtnl_lock(); 576 + if (cfg80211_is_all_idle()) 577 + regulatory_hint_disconnect(); 578 + rtnl_unlock(); 579 + } 580 + 581 + static DECLARE_WORK(cfg80211_disconnect_work, disconnect_work); 582 + 583 + 584 + /* 585 + * API calls for drivers implementing connect/disconnect and 586 + * SME event handling 587 + */ 379 588 380 589 void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 381 590 const u8 *req_ie, size_t req_ie_len, ··· 573 422 574 423 if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION && 575 424 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 576 - return; 577 - 578 - if (wdev->sme_state != CFG80211_SME_CONNECTING) 579 425 return; 580 426 581 427 nl80211_send_connect_result(wiphy_to_dev(wdev->wiphy), dev, ··· 611 463 wdev->current_bss = NULL; 612 464 } 613 465 614 - if (wdev->conn) 615 - wdev->conn->state = CFG80211_CONN_IDLE; 616 - 617 466 if (status != WLAN_STATUS_SUCCESS) { 618 - wdev->sme_state = CFG80211_SME_IDLE; 619 - if (wdev->conn) 620 - kfree(wdev->conn->ie); 621 - kfree(wdev->conn); 622 - wdev->conn = NULL; 623 467 kfree(wdev->connect_keys); 624 468 wdev->connect_keys = NULL; 625 469 wdev->ssid_len = 0; ··· 620 480 } 621 481 622 482 if (!bss) 623 - bss = cfg80211_get_bss(wdev->wiphy, 624 - wdev->conn ? wdev->conn->params.channel : 625 - NULL, 626 - bssid, 483 + bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 627 484 wdev->ssid, wdev->ssid_len, 628 485 WLAN_CAPABILITY_ESS, 629 486 WLAN_CAPABILITY_ESS); 630 - 631 487 if (WARN_ON(!bss)) 632 488 return; 633 489 634 490 cfg80211_hold_bss(bss_from_pub(bss)); 635 491 wdev->current_bss = bss_from_pub(bss); 636 492 637 - wdev->sme_state = CFG80211_SME_CONNECTED; 638 493 cfg80211_upload_connect_keys(wdev); 639 494 640 495 rcu_read_lock(); ··· 664 529 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 665 530 struct cfg80211_event *ev; 666 531 unsigned long flags; 667 - 668 - CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING); 669 532 670 533 ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp); 671 534 if (!ev) ··· 705 572 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 706 573 goto out; 707 574 708 - if (wdev->sme_state != CFG80211_SME_CONNECTED) 575 + if (WARN_ON(!wdev->current_bss)) 709 576 goto out; 710 - 711 - /* internal error -- how did we get to CONNECTED w/o BSS? */ 712 - if (WARN_ON(!wdev->current_bss)) { 713 - goto out; 714 - } 715 577 716 578 cfg80211_unhold_bss(wdev->current_bss); 717 579 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); ··· 756 628 struct wireless_dev *wdev = dev->ieee80211_ptr; 757 629 struct cfg80211_bss *bss; 758 630 759 - CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED); 760 - 761 631 bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid, 762 632 wdev->ssid_len, WLAN_CAPABILITY_ESS, 763 633 WLAN_CAPABILITY_ESS); ··· 776 650 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 777 651 struct cfg80211_event *ev; 778 652 unsigned long flags; 779 - 780 - CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED); 781 653 782 654 if (WARN_ON(!bss)) 783 655 return; ··· 818 694 wdev->iftype != NL80211_IFTYPE_P2P_CLIENT)) 819 695 return; 820 696 821 - if (wdev->sme_state != CFG80211_SME_CONNECTED) 822 - return; 823 - 824 697 if (wdev->current_bss) { 825 698 cfg80211_unhold_bss(wdev->current_bss); 826 699 cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub); 827 700 } 828 701 829 702 wdev->current_bss = NULL; 830 - wdev->sme_state = CFG80211_SME_IDLE; 831 703 wdev->ssid_len = 0; 832 - 833 - if (wdev->conn) { 834 - kfree(wdev->conn->ie); 835 - wdev->conn->ie = NULL; 836 - kfree(wdev->conn); 837 - wdev->conn = NULL; 838 - } 839 704 840 705 nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap); 841 706 ··· 854 741 struct cfg80211_event *ev; 855 742 unsigned long flags; 856 743 857 - CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTED); 858 - 859 744 ev = kzalloc(sizeof(*ev) + ie_len, gfp); 860 745 if (!ev) 861 746 return; ··· 871 760 } 872 761 EXPORT_SYMBOL(cfg80211_disconnected); 873 762 763 + /* 764 + * API calls for nl80211/wext compatibility code 765 + */ 874 766 int cfg80211_connect(struct cfg80211_registered_device *rdev, 875 767 struct net_device *dev, 876 768 struct cfg80211_connect_params *connect, ··· 881 767 const u8 *prev_bssid) 882 768 { 883 769 struct wireless_dev *wdev = dev->ieee80211_ptr; 884 - struct cfg80211_bss *bss = NULL; 885 770 int err; 886 771 887 772 ASSERT_WDEV_LOCK(wdev); 888 - 889 - if (wdev->sme_state != CFG80211_SME_IDLE) 890 - return -EALREADY; 891 773 892 774 if (WARN_ON(wdev->connect_keys)) { 893 775 kfree(wdev->connect_keys); ··· 920 810 } 921 811 } 922 812 923 - if (!rdev->ops->connect) { 924 - if (!rdev->ops->auth || !rdev->ops->assoc) 925 - return -EOPNOTSUPP; 813 + wdev->connect_keys = connkeys; 814 + memcpy(wdev->ssid, connect->ssid, connect->ssid_len); 815 + wdev->ssid_len = connect->ssid_len; 926 816 927 - if (WARN_ON(wdev->conn)) 928 - return -EINPROGRESS; 929 - 930 - wdev->conn = kzalloc(sizeof(*wdev->conn), GFP_KERNEL); 931 - if (!wdev->conn) 932 - return -ENOMEM; 933 - 934 - /* 935 - * Copy all parameters, and treat explicitly IEs, BSSID, SSID. 936 - */ 937 - memcpy(&wdev->conn->params, connect, sizeof(*connect)); 938 - if (connect->bssid) { 939 - wdev->conn->params.bssid = wdev->conn->bssid; 940 - memcpy(wdev->conn->bssid, connect->bssid, ETH_ALEN); 941 - } 942 - 943 - if (connect->ie) { 944 - wdev->conn->ie = kmemdup(connect->ie, connect->ie_len, 945 - GFP_KERNEL); 946 - wdev->conn->params.ie = wdev->conn->ie; 947 - if (!wdev->conn->ie) { 948 - kfree(wdev->conn); 949 - wdev->conn = NULL; 950 - return -ENOMEM; 951 - } 952 - } 953 - 954 - if (connect->auth_type == NL80211_AUTHTYPE_AUTOMATIC) { 955 - wdev->conn->auto_auth = true; 956 - /* start with open system ... should mostly work */ 957 - wdev->conn->params.auth_type = 958 - NL80211_AUTHTYPE_OPEN_SYSTEM; 959 - } else { 960 - wdev->conn->auto_auth = false; 961 - } 962 - 963 - memcpy(wdev->ssid, connect->ssid, connect->ssid_len); 964 - wdev->ssid_len = connect->ssid_len; 965 - wdev->conn->params.ssid = wdev->ssid; 966 - wdev->conn->params.ssid_len = connect->ssid_len; 967 - 968 - /* see if we have the bss already */ 969 - bss = cfg80211_get_conn_bss(wdev); 970 - 971 - wdev->sme_state = CFG80211_SME_CONNECTING; 972 - wdev->connect_keys = connkeys; 973 - 974 - if (prev_bssid) { 975 - memcpy(wdev->conn->prev_bssid, prev_bssid, ETH_ALEN); 976 - wdev->conn->prev_bssid_valid = true; 977 - } 978 - 979 - /* we're good if we have a matching bss struct */ 980 - if (bss) { 981 - wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; 982 - err = cfg80211_conn_do_work(wdev); 983 - cfg80211_put_bss(wdev->wiphy, bss); 984 - } else { 985 - /* otherwise we'll need to scan for the AP first */ 986 - err = cfg80211_conn_scan(wdev); 987 - /* 988 - * If we can't scan right now, then we need to scan again 989 - * after the current scan finished, since the parameters 990 - * changed (unless we find a good AP anyway). 991 - */ 992 - if (err == -EBUSY) { 993 - err = 0; 994 - wdev->conn->state = CFG80211_CONN_SCAN_AGAIN; 995 - } 996 - } 997 - if (err) { 998 - kfree(wdev->conn->ie); 999 - kfree(wdev->conn); 1000 - wdev->conn = NULL; 1001 - wdev->sme_state = CFG80211_SME_IDLE; 1002 - wdev->connect_keys = NULL; 1003 - wdev->ssid_len = 0; 1004 - } 1005 - 1006 - return err; 1007 - } else { 1008 - wdev->sme_state = CFG80211_SME_CONNECTING; 1009 - wdev->connect_keys = connkeys; 817 + if (!rdev->ops->connect) 818 + err = cfg80211_sme_connect(wdev, connect, prev_bssid); 819 + else 1010 820 err = rdev_connect(rdev, dev, connect); 1011 - if (err) { 1012 - wdev->connect_keys = NULL; 1013 - wdev->sme_state = CFG80211_SME_IDLE; 1014 - return err; 1015 - } 1016 821 1017 - memcpy(wdev->ssid, connect->ssid, connect->ssid_len); 1018 - wdev->ssid_len = connect->ssid_len; 1019 - 1020 - return 0; 822 + if (err) { 823 + wdev->connect_keys = NULL; 824 + wdev->ssid_len = 0; 825 + return err; 1021 826 } 827 + 828 + return 0; 1022 829 } 1023 830 1024 831 int cfg80211_disconnect(struct cfg80211_registered_device *rdev, ··· 946 919 947 920 ASSERT_WDEV_LOCK(wdev); 948 921 949 - if (wdev->sme_state == CFG80211_SME_IDLE) 950 - return -EINVAL; 951 - 952 922 kfree(wdev->connect_keys); 953 923 wdev->connect_keys = NULL; 954 924 955 - if (!rdev->ops->disconnect) { 956 - if (!rdev->ops->deauth) 957 - return -EOPNOTSUPP; 958 - 959 - /* was it connected by userspace SME? */ 960 - if (!wdev->conn) { 961 - cfg80211_mlme_down(rdev, dev); 962 - goto disconnect; 963 - } 964 - 965 - if (wdev->sme_state == CFG80211_SME_CONNECTING && 966 - (wdev->conn->state == CFG80211_CONN_SCANNING || 967 - wdev->conn->state == CFG80211_CONN_SCAN_AGAIN)) { 968 - wdev->sme_state = CFG80211_SME_IDLE; 969 - kfree(wdev->conn->ie); 970 - kfree(wdev->conn); 971 - wdev->conn = NULL; 972 - wdev->ssid_len = 0; 973 - return 0; 974 - } 975 - 976 - /* wdev->conn->params.bssid must be set if > SCANNING */ 977 - err = cfg80211_mlme_deauth(rdev, dev, 978 - wdev->conn->params.bssid, 979 - NULL, 0, reason, false); 980 - if (err) 981 - return err; 925 + if (wdev->conn) { 926 + err = cfg80211_sme_disconnect(wdev, reason); 927 + } else if (!rdev->ops->disconnect) { 928 + cfg80211_mlme_down(rdev, dev); 929 + err = 0; 982 930 } else { 983 931 err = rdev_disconnect(rdev, dev, reason); 984 - if (err) 985 - return err; 986 932 } 987 933 988 - disconnect: 989 - if (wdev->sme_state == CFG80211_SME_CONNECTED) 990 - __cfg80211_disconnected(dev, NULL, 0, 0, false); 991 - else if (wdev->sme_state == CFG80211_SME_CONNECTING) 992 - __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, 993 - WLAN_STATUS_UNSPECIFIED_FAILURE, 994 - wextev, NULL); 995 - 996 - return 0; 997 - } 998 - 999 - void cfg80211_sme_disassoc(struct net_device *dev, 1000 - struct cfg80211_internal_bss *bss) 1001 - { 1002 - struct wireless_dev *wdev = dev->ieee80211_ptr; 1003 - struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1004 - u8 bssid[ETH_ALEN]; 1005 - 1006 - ASSERT_WDEV_LOCK(wdev); 1007 - 1008 - if (!wdev->conn) 1009 - return; 1010 - 1011 - if (wdev->conn->state == CFG80211_CONN_IDLE) 1012 - return; 1013 - 1014 - /* 1015 - * Ok, so the association was made by this SME -- we don't 1016 - * want it any more so deauthenticate too. 1017 - */ 1018 - 1019 - memcpy(bssid, bss->pub.bssid, ETH_ALEN); 1020 - 1021 - cfg80211_mlme_deauth(rdev, dev, bssid, NULL, 0, 1022 - WLAN_REASON_DEAUTH_LEAVING, false); 934 + return err; 1023 935 }
+34 -12
net/wireless/trace.h
··· 1911 1911 NETDEV_PR_ARG, MAC_PR_ARG(bssid), CHAN_PR_ARG) 1912 1912 ); 1913 1913 1914 - DEFINE_EVENT(netdev_evt_only, cfg80211_send_deauth, 1915 - TP_PROTO(struct net_device *netdev), 1916 - TP_ARGS(netdev) 1914 + DECLARE_EVENT_CLASS(netdev_frame_event, 1915 + TP_PROTO(struct net_device *netdev, const u8 *buf, int len), 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 1919 - DEFINE_EVENT(netdev_evt_only, cfg80211_send_disassoc, 1920 - TP_PROTO(struct net_device *netdev), 1921 - TP_ARGS(netdev) 1930 + DEFINE_EVENT(netdev_frame_event, cfg80211_rx_unprot_mlme_mgmt, 1931 + TP_PROTO(struct net_device *netdev, const u8 *buf, int len), 1932 + TP_ARGS(netdev, buf, len) 1922 1933 ); 1923 1934 1924 - DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_deauth, 1925 - TP_PROTO(struct net_device *netdev), 1926 - TP_ARGS(netdev) 1935 + DEFINE_EVENT(netdev_frame_event, cfg80211_rx_mlme_mgmt, 1936 + TP_PROTO(struct net_device *netdev, const u8 *buf, int len), 1937 + TP_ARGS(netdev, buf, len) 1927 1938 ); 1928 1939 1929 - DEFINE_EVENT(netdev_evt_only, cfg80211_send_unprot_disassoc, 1930 - TP_PROTO(struct net_device *netdev), 1931 - TP_ARGS(netdev) 1940 + TRACE_EVENT(cfg80211_tx_mlme_mgmt, 1941 + TP_PROTO(struct net_device *netdev, const u8 *buf, int len), 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 1934 1956 DECLARE_EVENT_CLASS(netdev_mac_evt,
+4 -4
net/wireless/wext-sme.c
··· 89 89 90 90 wdev_lock(wdev); 91 91 92 - if (wdev->sme_state != CFG80211_SME_IDLE) { 92 + if (wdev->conn) { 93 93 bool event = true; 94 94 95 95 if (wdev->wext.connect.channel == chan) { ··· 188 188 189 189 err = 0; 190 190 191 - if (wdev->sme_state != CFG80211_SME_IDLE) { 191 + if (wdev->conn) { 192 192 bool event = true; 193 193 194 194 if (wdev->wext.connect.ssid && len && ··· 277 277 278 278 wdev_lock(wdev); 279 279 280 - if (wdev->sme_state != CFG80211_SME_IDLE) { 280 + if (wdev->conn) { 281 281 err = 0; 282 282 /* both automatic */ 283 283 if (!bssid && !wdev->wext.connect.bssid) ··· 364 364 wdev->wext.ie = ie; 365 365 wdev->wext.ie_len = ie_len; 366 366 367 - if (wdev->sme_state != CFG80211_SME_IDLE) { 367 + if (wdev->conn) { 368 368 err = cfg80211_disconnect(rdev, dev, 369 369 WLAN_REASON_DEAUTH_LEAVING, false); 370 370 if (err)