aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-07 11:36:12 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-15 03:41:32 -0500
commit1128958dc22cbfa2562082da2621a06ba71bdce2 (patch)
treed5242d14a78bc701ea65976a2cf04f046652e485
parent0af83d3df5863224336a18c24a14fda542b712f5 (diff)
mac80211: init HT TX data before rate control
In case of connection, the station data is initialised from the beacon/probe response first and then updated from the association response. If the latter is different we update the rate control algorithm and driver. Instead of doing it this way, set the station data properly with data from the association response before initializing rate control. Also simplify the code by passing the station pointer. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/mlme.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index be1147286801..b97b615d5711 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -175,6 +175,7 @@ static int ecw2cw(int ecw)
175} 175}
176 176
177static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata, 177static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
178 struct sta_info *sta,
178 struct ieee80211_ht_operation *ht_oper, 179 struct ieee80211_ht_operation *ht_oper,
179 const u8 *bssid, bool reconfig) 180 const u8 *bssid, bool reconfig)
180{ 181{
@@ -182,11 +183,13 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
182 struct ieee80211_supported_band *sband; 183 struct ieee80211_supported_band *sband;
183 struct ieee80211_chanctx_conf *chanctx_conf; 184 struct ieee80211_chanctx_conf *chanctx_conf;
184 struct ieee80211_channel *chan; 185 struct ieee80211_channel *chan;
185 struct sta_info *sta;
186 u32 changed = 0; 186 u32 changed = 0;
187 u16 ht_opmode; 187 u16 ht_opmode;
188 bool disable_40 = false; 188 bool disable_40 = false;
189 189
190 if (WARN_ON_ONCE(!sta))
191 return 0;
192
190 rcu_read_lock(); 193 rcu_read_lock();
191 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 194 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
192 if (WARN_ON(!chanctx_conf)) { 195 if (WARN_ON(!chanctx_conf)) {
@@ -216,28 +219,19 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
216 if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) 219 if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
217 disable_40 = true; 220 disable_40 = true;
218 221
219 mutex_lock(&local->sta_mtx);
220 sta = sta_info_get(sdata, bssid);
221
222 if (WARN_ON_ONCE(!sta)) {
223 mutex_unlock(&local->sta_mtx);
224 return changed;
225 }
226
227 if (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) 222 if (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
228 disable_40 = true; 223 disable_40 = true;
229 224
230 if (!reconfig || 225 if (disable_40 != (sta->sta.bandwidth < IEEE80211_STA_RX_BW_40)) {
231 disable_40 != (sta->sta.bandwidth < IEEE80211_STA_RX_BW_40)) {
232 if (disable_40) 226 if (disable_40)
233 sta->sta.bandwidth = IEEE80211_STA_RX_BW_20; 227 sta->sta.bandwidth = IEEE80211_STA_RX_BW_20;
234 else 228 else
235 sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta); 229 sta->sta.bandwidth = ieee80211_sta_cur_vht_bw(sta);
236 230
237 rate_control_rate_update(local, sband, sta, 231 if (reconfig)
238 IEEE80211_RC_BW_CHANGED); 232 rate_control_rate_update(local, sband, sta,
233 IEEE80211_RC_BW_CHANGED);
239 } 234 }
240 mutex_unlock(&local->sta_mtx);
241 235
242 ht_opmode = le16_to_cpu(ht_oper->operation_mode); 236 ht_opmode = le16_to_cpu(ht_oper->operation_mode);
243 237
@@ -2217,6 +2211,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2217 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband, 2211 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
2218 elems.vht_cap_elem, sta); 2212 elems.vht_cap_elem, sta);
2219 2213
2214 if (elems.ht_operation && elems.wmm_param &&
2215 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2216 changed |= ieee80211_config_ht_tx(sdata, sta,
2217 elems.ht_operation,
2218 cbss->bssid, false);
2219
2220 rate_control_rate_init(sta); 2220 rate_control_rate_init(sta);
2221 2221
2222 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) 2222 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
@@ -2254,11 +2254,6 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2254 ieee80211_set_wmm_default(sdata, false); 2254 ieee80211_set_wmm_default(sdata, false);
2255 changed |= BSS_CHANGED_QOS; 2255 changed |= BSS_CHANGED_QOS;
2256 2256
2257 if (elems.ht_operation && elems.wmm_param &&
2258 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2259 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation,
2260 cbss->bssid, false);
2261
2262 /* set AID and assoc capability, 2257 /* set AID and assoc capability,
2263 * ieee80211_set_associated() will tell the driver */ 2258 * ieee80211_set_associated() will tell the driver */
2264 bss_conf->aid = aid; 2259 bss_conf->aid = aid;
@@ -2734,10 +2729,14 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2734 erp_valid, erp_value); 2729 erp_valid, erp_value);
2735 2730
2736 2731
2732 mutex_lock(&local->sta_mtx);
2737 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param && 2733 if (elems.ht_cap_elem && elems.ht_operation && elems.wmm_param &&
2738 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) 2734 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
2739 changed |= ieee80211_config_ht_tx(sdata, elems.ht_operation, 2735 changed |= ieee80211_config_ht_tx(sdata,
2736 sta_info_get(sdata, bssid),
2737 elems.ht_operation,
2740 bssid, true); 2738 bssid, true);
2739 mutex_unlock(&local->sta_mtx);
2741 2740
2742 if (elems.country_elem && elems.pwr_constr_elem && 2741 if (elems.country_elem && elems.pwr_constr_elem &&
2743 mgmt->u.probe_resp.capab_info & 2742 mgmt->u.probe_resp.capab_info &