summaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-08 09:02:07 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-12 14:22:15 -0400
commita1cf775deae9d0f1e5475337ab13c593ad427cee (patch)
tree082c8056bf934cf9d60860fcc80bbab8fe65ce23 /net/mac80211/mlme.c
parent0775f9f90cdaf40fbf69b3192b3dddb2b3436f45 (diff)
mac80211: refactor common auth/assoc setup code
As associating is possible without first authenticating (for FT over DS) association also has to be able to switch to the right channel, insert the station entry etc. Factor out this common code into a new function called ieee80211_prep_connection(). Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c121
1 files changed, 59 insertions, 62 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5c82354d18c4..81e0124e68ce 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3089,6 +3089,60 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
3089 return 0; 3089 return 0;
3090} 3090}
3091 3091
3092static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3093 struct cfg80211_bss *bss, bool assoc)
3094{
3095 struct ieee80211_local *local = sdata->local;
3096 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3097 struct sta_info *sta;
3098 bool have_sta = false;
3099 int err;
3100
3101 if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data))
3102 return -EINVAL;
3103
3104 if (assoc) {
3105 rcu_read_lock();
3106 have_sta = sta_info_get(sdata, bss->bssid);
3107 rcu_read_unlock();
3108 }
3109
3110 if (!have_sta) {
3111 sta = sta_info_alloc(sdata, bss->bssid, GFP_KERNEL);
3112 if (!sta)
3113 return -ENOMEM;
3114 }
3115
3116 mutex_lock(&local->mtx);
3117 ieee80211_recalc_idle(sdata->local);
3118 mutex_unlock(&local->mtx);
3119
3120 /* switch to the right channel */
3121 local->oper_channel = bss->channel;
3122 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3123
3124 if (!have_sta) {
3125 /* set BSSID - if STA already there this will be set too */
3126 memcpy(ifmgd->bssid, bss->bssid, ETH_ALEN);
3127 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
3128
3129 if (assoc)
3130 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
3131
3132 err = sta_info_insert(sta);
3133 sta = NULL;
3134 if (err) {
3135 printk(KERN_DEBUG
3136 "%s: failed to insert STA entry for the AP (error %d)\n",
3137 sdata->name, err);
3138 return err;
3139 }
3140 } else
3141 WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, bss->bssid));
3142
3143 return 0;
3144}
3145
3092/* config hooks */ 3146/* config hooks */
3093int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 3147int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3094 struct cfg80211_auth_request *req) 3148 struct cfg80211_auth_request *req)
@@ -3096,7 +3150,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3096 struct ieee80211_local *local = sdata->local; 3150 struct ieee80211_local *local = sdata->local;
3097 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3151 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3098 struct ieee80211_mgd_auth_data *auth_data; 3152 struct ieee80211_mgd_auth_data *auth_data;
3099 struct sta_info *sta;
3100 u16 auth_alg; 3153 u16 auth_alg;
3101 int err; 3154 int err;
3102 3155
@@ -3162,32 +3215,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3162 printk(KERN_DEBUG "%s: authenticate with %pM\n", 3215 printk(KERN_DEBUG "%s: authenticate with %pM\n",
3163 sdata->name, req->bss->bssid); 3216 sdata->name, req->bss->bssid);
3164 3217
3165 mutex_lock(&local->mtx); 3218 err = ieee80211_prep_connection(sdata, req->bss, false);
3166 ieee80211_recalc_idle(sdata->local); 3219 if (err)
3167 mutex_unlock(&local->mtx);
3168
3169 /* switch to the right channel */
3170 local->oper_channel = req->bss->channel;
3171 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3172
3173 /* set BSSID */
3174 memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
3175 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
3176
3177 /* add station entry */
3178 sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
3179 if (!sta) {
3180 err = -ENOMEM;
3181 goto err_clear;
3182 }
3183
3184 err = sta_info_insert(sta);
3185 if (err) {
3186 printk(KERN_DEBUG
3187 "%s: failed to insert STA entry for the AP %pM (error %d)\n",
3188 sdata->name, req->bss->bssid, err);
3189 goto err_clear; 3220 goto err_clear;
3190 }
3191 3221
3192 err = ieee80211_probe_auth(sdata); 3222 err = ieee80211_probe_auth(sdata);
3193 if (err) { 3223 if (err) {
@@ -3218,7 +3248,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3218 struct ieee80211_bss *bss = (void *)req->bss->priv; 3248 struct ieee80211_bss *bss = (void *)req->bss->priv;
3219 struct ieee80211_mgd_assoc_data *assoc_data; 3249 struct ieee80211_mgd_assoc_data *assoc_data;
3220 struct ieee80211_supported_band *sband; 3250 struct ieee80211_supported_band *sband;
3221 struct sta_info *sta;
3222 const u8 *ssidie; 3251 const u8 *ssidie;
3223 int i, err; 3252 int i, err;
3224 3253
@@ -3343,41 +3372,9 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3343 3372
3344 ifmgd->assoc_data = assoc_data; 3373 ifmgd->assoc_data = assoc_data;
3345 3374
3346 mutex_lock(&local->mtx); 3375 err = ieee80211_prep_connection(sdata, req->bss, true);
3347 ieee80211_recalc_idle(sdata->local); 3376 if (err)
3348 mutex_unlock(&local->mtx); 3377 goto err_clear;
3349
3350 /* switch to the right channel */
3351 local->oper_channel = req->bss->channel;
3352 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3353
3354 rcu_read_lock();
3355 sta = sta_info_get(sdata, req->bss->bssid);
3356 rcu_read_unlock();
3357
3358 if (!sta) {
3359 /* set BSSID */
3360 memcpy(ifmgd->bssid, req->bss->bssid, ETH_ALEN);
3361 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
3362
3363 sta = sta_info_alloc(sdata, req->bss->bssid, GFP_KERNEL);
3364 if (!sta) {
3365 err = -ENOMEM;
3366 goto err_clear;
3367 }
3368
3369 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
3370
3371 err = sta_info_insert(sta);
3372 sta = NULL;
3373 if (err) {
3374 printk(KERN_DEBUG
3375 "%s: failed to insert STA entry for the AP (error %d)\n",
3376 sdata->name, err);
3377 goto err_clear;
3378 }
3379 } else
3380 WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, req->bss->bssid));
3381 3378
3382 if (!bss->dtim_period && 3379 if (!bss->dtim_period &&
3383 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { 3380 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {