aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-08 09:02:08 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-12 14:22:16 -0400
commit5d6a1b069b7f72298aff2306a2d02b0188668218 (patch)
tree124f4597695863d763cc835399dec27b21c18ac1 /net
parenta1cf775deae9d0f1e5475337ab13c593ad427cee (diff)
mac80211: set basic rates earlier
The authentication and association handshake already happens in the context of the new BSS, and the basic rates are needed at least for the ACK response frame to the authentication or association response frames. Therefore the basic rates should already be configured into the driver when those frames are sent. Change the logic to set up the basic rates in the connection preparation that happens for authentication and association (if needed). Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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 81e0124e68c..39c13939008 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}