aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/mlme.c97
1 files changed, 49 insertions, 48 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 81e0124e68ce..39c13939008b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1344,12 +1344,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1344 bss_conf->dtim_period = 0; 1344 bss_conf->dtim_period = 0;
1345 1345
1346 bss_conf->assoc = 1; 1346 bss_conf->assoc = 1;
1347 /*
1348 * For now just always ask the driver to update the basic rateset
1349 * when we have associated, we aren't checking whether it actually
1350 * changed or not.
1351 */
1352 bss_info_changed |= BSS_CHANGED_BASIC_RATES;
1353 1347
1354 /* Tell the driver to monitor connection quality (if supported) */ 1348 /* Tell the driver to monitor connection quality (if supported) */
1355 if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && 1349 if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
@@ -2001,15 +1995,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2001 struct ieee80211_supported_band *sband; 1995 struct ieee80211_supported_band *sband;
2002 struct sta_info *sta; 1996 struct sta_info *sta;
2003 u8 *pos; 1997 u8 *pos;
2004 u32 rates, basic_rates;
2005 u16 capab_info, aid; 1998 u16 capab_info, aid;
2006 struct ieee802_11_elems elems; 1999 struct ieee802_11_elems elems;
2007 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; 2000 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
2008 u32 changed = 0; 2001 u32 changed = 0;
2009 int err; 2002 int err;
2010 bool have_higher_than_11mbit = false;
2011 u16 ap_ht_cap_flags; 2003 u16 ap_ht_cap_flags;
2012 int min_rate = INT_MAX, min_rate_index = -1;
2013 2004
2014 /* AssocResp and ReassocResp have identical structure */ 2005 /* AssocResp and ReassocResp have identical structure */
2015 2006
@@ -2054,39 +2045,8 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2054 return false; 2045 return false;
2055 } 2046 }
2056 2047
2057 rates = 0;
2058 basic_rates = 0;
2059 sband = local->hw.wiphy->bands[local->oper_channel->band]; 2048 sband = local->hw.wiphy->bands[local->oper_channel->band];
2060 2049
2061 ieee80211_get_rates(sband, elems.supp_rates, elems.supp_rates_len,
2062 &rates, &basic_rates, &have_higher_than_11mbit,
2063 &min_rate, &min_rate_index);
2064
2065 ieee80211_get_rates(sband, elems.ext_supp_rates,
2066 elems.ext_supp_rates_len, &rates, &basic_rates,
2067 &have_higher_than_11mbit,
2068 &min_rate, &min_rate_index);
2069
2070 /*
2071 * some buggy APs don't advertise basic_rates. use the lowest
2072 * supported rate instead.
2073 */
2074 if (unlikely(!basic_rates) && min_rate_index >= 0) {
2075 printk(KERN_DEBUG "%s: No basic rates in AssocResp. "
2076 "Using min supported rate instead.\n", sdata->name);
2077 basic_rates = BIT(min_rate_index);
2078 }
2079
2080 sta->sta.supp_rates[local->oper_channel->band] = rates;
2081 sdata->vif.bss_conf.basic_rates = basic_rates;
2082
2083 /* cf. IEEE 802.11 9.2.12 */
2084 if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
2085 have_higher_than_11mbit)
2086 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
2087 else
2088 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
2089
2090 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) 2050 if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_11N))
2091 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 2051 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
2092 elems.ht_cap_elem, &sta->sta.ht_cap); 2052 elems.ht_cap_elem, &sta->sta.ht_cap);
@@ -3090,10 +3050,11 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
3090} 3050}
3091 3051
3092static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, 3052static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3093 struct cfg80211_bss *bss, bool assoc) 3053 struct cfg80211_bss *cbss, bool assoc)
3094{ 3054{
3095 struct ieee80211_local *local = sdata->local; 3055 struct ieee80211_local *local = sdata->local;
3096 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3056 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3057 struct ieee80211_bss *bss = (void *)cbss->priv;
3097 struct sta_info *sta; 3058 struct sta_info *sta;
3098 bool have_sta = false; 3059 bool have_sta = false;
3099 int err; 3060 int err;
@@ -3103,12 +3064,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3103 3064
3104 if (assoc) { 3065 if (assoc) {
3105 rcu_read_lock(); 3066 rcu_read_lock();
3106 have_sta = sta_info_get(sdata, bss->bssid); 3067 have_sta = sta_info_get(sdata, cbss->bssid);
3107 rcu_read_unlock(); 3068 rcu_read_unlock();
3108 } 3069 }
3109 3070
3110 if (!have_sta) { 3071 if (!have_sta) {
3111 sta = sta_info_alloc(sdata, bss->bssid, GFP_KERNEL); 3072 sta = sta_info_alloc(sdata, cbss->bssid, GFP_KERNEL);
3112 if (!sta) 3073 if (!sta)
3113 return -ENOMEM; 3074 return -ENOMEM;
3114 } 3075 }
@@ -3118,13 +3079,53 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3118 mutex_unlock(&local->mtx); 3079 mutex_unlock(&local->mtx);
3119 3080
3120 /* switch to the right channel */ 3081 /* switch to the right channel */
3121 local->oper_channel = bss->channel; 3082 local->oper_channel = cbss->channel;
3122 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); 3083 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
3123 3084
3124 if (!have_sta) { 3085 if (!have_sta) {
3125 /* set BSSID - if STA already there this will be set too */ 3086 struct ieee80211_supported_band *sband;
3126 memcpy(ifmgd->bssid, bss->bssid, ETH_ALEN); 3087 u32 rates = 0, basic_rates = 0;
3127 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); 3088 bool have_higher_than_11mbit;
3089 int min_rate = INT_MAX, min_rate_index = -1;
3090
3091 sband = sdata->local->hw.wiphy->bands[cbss->channel->band];
3092
3093 ieee80211_get_rates(sband, bss->supp_rates,
3094 bss->supp_rates_len,
3095 &rates, &basic_rates,
3096 &have_higher_than_11mbit,
3097 &min_rate, &min_rate_index);
3098
3099 /*
3100 * This used to be a workaround for basic rates missing
3101 * in the association response frame. Now that we no
3102 * longer use the basic rates from there, it probably
3103 * doesn't happen any more, but keep the workaround so
3104 * in case some *other* APs are buggy in different ways
3105 * we can connect -- with a warning.
3106 */
3107 if (!basic_rates && min_rate_index >= 0) {
3108 printk(KERN_DEBUG
3109 "%s: No basic rates, using min rate instead.\n",
3110 sdata->name);
3111 basic_rates = BIT(min_rate_index);
3112 }
3113
3114 sta->sta.supp_rates[cbss->channel->band] = rates;
3115 sdata->vif.bss_conf.basic_rates = basic_rates;
3116
3117 /* cf. IEEE 802.11 9.2.12 */
3118 if (local->oper_channel->band == IEEE80211_BAND_2GHZ &&
3119 have_higher_than_11mbit)
3120 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
3121 else
3122 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
3123
3124 memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN);
3125
3126 /* tell driver about BSSID and basic rates */
3127 ieee80211_bss_info_change_notify(sdata,
3128 BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES);
3128 3129
3129 if (assoc) 3130 if (assoc)
3130 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 3131 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
@@ -3138,7 +3139,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3138 return err; 3139 return err;
3139 } 3140 }
3140 } else 3141 } else
3141 WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, bss->bssid)); 3142 WARN_ON_ONCE(compare_ether_addr(ifmgd->bssid, cbss->bssid));
3142 3143
3143 return 0; 3144 return 0;
3144} 3145}