aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2012-03-28 04:58:37 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-04-10 14:54:08 -0400
commit64f68e5d15bee47e0d6d0c57a1cf52cedd9b3527 (patch)
treee000cea46fd57d876d725224d2b51b74cec35572
parent24398e39c8ee4a9d9123eed322b859ece4d16cac (diff)
mac80211: remove channel type argument from rate_update
The channel type argument to the rate_update() callback isn't really the correct way to give the rate control algorithm about the desired RX bandwidth of the peer. Remove this argument, and instead update the STA capabilities with 20/40 appropriately. The SMPS update done by this callback works in the same way, so this makes the callback cleaner. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rc.c3
-rw-r--r--include/net/mac80211.h5
-rw-r--r--net/mac80211/chan.c26
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/mlme.c51
-rw-r--r--net/mac80211/rate.h5
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c15
-rw-r--r--net/mac80211/rx.c7
-rw-r--r--net/mac80211/sta_info.h2
10 files changed, 50 insertions, 74 deletions
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 4f848493fece..4e39f27af077 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1436,7 +1436,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1436 1436
1437static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband, 1437static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1438 struct ieee80211_sta *sta, void *priv_sta, 1438 struct ieee80211_sta *sta, void *priv_sta,
1439 u32 changed, enum nl80211_channel_type oper_chan_type) 1439 u32 changed)
1440{ 1440{
1441 struct ath_softc *sc = priv; 1441 struct ath_softc *sc = priv;
1442 struct ath_rate_priv *ath_rc_priv = priv_sta; 1442 struct ath_rate_priv *ath_rc_priv = priv_sta;
@@ -1451,8 +1451,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
1451 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) 1451 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
1452 return; 1452 return;
1453 1453
1454 if (oper_chan_type == NL80211_CHAN_HT40MINUS || 1454 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
1455 oper_chan_type == NL80211_CHAN_HT40PLUS)
1456 oper_cw40 = true; 1455 oper_cw40 = true;
1457 1456
1458 if (oper_cw40) 1457 if (oper_cw40)
diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c
index c66f08a0524a..d5cbf01da8ac 100644
--- a/drivers/net/wireless/rtlwifi/rc.c
+++ b/drivers/net/wireless/rtlwifi/rc.c
@@ -225,8 +225,7 @@ static void rtl_rate_init(void *ppriv,
225static void rtl_rate_update(void *ppriv, 225static void rtl_rate_update(void *ppriv,
226 struct ieee80211_supported_band *sband, 226 struct ieee80211_supported_band *sband,
227 struct ieee80211_sta *sta, void *priv_sta, 227 struct ieee80211_sta *sta, void *priv_sta,
228 u32 changed, 228 u32 changed)
229 enum nl80211_channel_type oper_chan_type)
230{ 229{
231} 230}
232 231
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 81cb66c3989e..21c653415d84 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3569,9 +3569,8 @@ struct rate_control_ops {
3569 void (*rate_init)(void *priv, struct ieee80211_supported_band *sband, 3569 void (*rate_init)(void *priv, struct ieee80211_supported_band *sband,
3570 struct ieee80211_sta *sta, void *priv_sta); 3570 struct ieee80211_sta *sta, void *priv_sta);
3571 void (*rate_update)(void *priv, struct ieee80211_supported_band *sband, 3571 void (*rate_update)(void *priv, struct ieee80211_supported_band *sband,
3572 struct ieee80211_sta *sta, 3572 struct ieee80211_sta *sta, void *priv_sta,
3573 void *priv_sta, u32 changed, 3573 u32 changed);
3574 enum nl80211_channel_type oper_chan_type);
3575 void (*free_sta)(void *priv, struct ieee80211_sta *sta, 3574 void (*free_sta)(void *priv, struct ieee80211_sta *sta,
3576 void *priv_sta); 3575 void *priv_sta);
3577 3576
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index e00ce8c3e28e..c76cf7230c7d 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -135,29 +135,3 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
135 135
136 return result; 136 return result;
137} 137}
138
139/*
140 * ieee80211_get_tx_channel_type returns the channel type we should
141 * use for packet transmission, given the channel capability and
142 * whatever regulatory flags we have been given.
143 */
144enum nl80211_channel_type ieee80211_get_tx_channel_type(
145 struct ieee80211_local *local,
146 enum nl80211_channel_type channel_type)
147{
148 switch (channel_type) {
149 case NL80211_CHAN_HT40PLUS:
150 if (local->hw.conf.channel->flags &
151 IEEE80211_CHAN_NO_HT40PLUS)
152 return NL80211_CHAN_HT20;
153 break;
154 case NL80211_CHAN_HT40MINUS:
155 if (local->hw.conf.channel->flags &
156 IEEE80211_CHAN_NO_HT40MINUS)
157 return NL80211_CHAN_HT20;
158 break;
159 default:
160 break;
161 }
162 return channel_type;
163}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a67ba7c85a1e..867b8eec1e9e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -512,8 +512,6 @@ struct ieee80211_if_managed {
512 int rssi_min_thold, rssi_max_thold; 512 int rssi_min_thold, rssi_max_thold;
513 int last_ave_beacon_signal; 513 int last_ave_beacon_signal;
514 514
515 enum nl80211_channel_type tx_chantype;
516
517 struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */ 515 struct ieee80211_ht_cap ht_capa; /* configured ht-cap over-rides */
518 struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */ 516 struct ieee80211_ht_cap ht_capa_mask; /* Valid parts of ht_capa */
519}; 517};
@@ -1501,9 +1499,6 @@ bool ieee80211_set_channel_type(struct ieee80211_local *local,
1501 enum nl80211_channel_type chantype); 1499 enum nl80211_channel_type chantype);
1502enum nl80211_channel_type 1500enum nl80211_channel_type
1503ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper); 1501ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper);
1504enum nl80211_channel_type ieee80211_get_tx_channel_type(
1505 struct ieee80211_local *local,
1506 enum nl80211_channel_type channel_type);
1507 1502
1508#ifdef CONFIG_MAC80211_NOINLINE 1503#ifdef CONFIG_MAC80211_NOINLINE
1509#define debug_noinline noinline 1504#define debug_noinline noinline
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 30259a73195c..9cc5dda68219 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -180,21 +180,38 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
180 struct sta_info *sta; 180 struct sta_info *sta;
181 u32 changed = 0; 181 u32 changed = 0;
182 u16 ht_opmode; 182 u16 ht_opmode;
183 enum nl80211_channel_type channel_type; 183 bool disable_40 = false;
184 184
185 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 185 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
186 channel_type = local->hw.conf.channel_type;
187 186
188 if (WARN_ON_ONCE(channel_type == NL80211_CHAN_NO_HT)) 187 switch (sdata->vif.bss_conf.channel_type) {
189 return 0; 188 case NL80211_CHAN_HT40PLUS:
190 189 if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40PLUS)
191 channel_type = ieee80211_get_tx_channel_type(local, channel_type); 190 disable_40 = true;
191 break;
192 case NL80211_CHAN_HT40MINUS:
193 if (local->hw.conf.channel->flags & IEEE80211_CHAN_NO_HT40MINUS)
194 disable_40 = true;
195 break;
196 default:
197 break;
198 }
192 199
193 /* This can change during the lifetime of the BSS */ 200 /* This can change during the lifetime of the BSS */
194 if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) 201 if (!(ht_oper->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
195 channel_type = NL80211_CHAN_HT20; 202 disable_40 = true;
196 203
197 if (!reconfig || (sdata->u.mgd.tx_chantype != channel_type)) { 204 mutex_lock(&local->sta_mtx);
205 sta = sta_info_get(sdata, bssid);
206
207 WARN_ON_ONCE(!sta);
208
209 if (sta && !sta->supports_40mhz)
210 disable_40 = true;
211
212 if (sta && (!reconfig ||
213 (disable_40 != !!(sta->sta.ht_cap.cap &
214 IEEE80211_HT_CAP_SUP_WIDTH_20_40)))) {
198 if (reconfig) { 215 if (reconfig) {
199 /* 216 /*
200 * Whenever the AP announces the HT mode changed 217 * Whenever the AP announces the HT mode changed
@@ -211,20 +228,19 @@ static u32 ieee80211_config_ht_tx(struct ieee80211_sub_if_data *sdata,
211 drv_flush(local, false); 228 drv_flush(local, false);
212 } 229 }
213 230
214 rcu_read_lock(); 231 if (disable_40)
215 sta = sta_info_get(sdata, bssid); 232 sta->sta.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
216 if (sta) 233 else
217 rate_control_rate_update(local, sband, sta, 234 sta->sta.ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
218 IEEE80211_RC_HT_CHANGED,
219 channel_type);
220 rcu_read_unlock();
221 235
222 sdata->u.mgd.tx_chantype = channel_type; 236 rate_control_rate_update(local, sband, sta,
237 IEEE80211_RC_HT_CHANGED);
223 238
224 if (reconfig) 239 if (reconfig)
225 ieee80211_wake_queues_by_reason(&sdata->local->hw, 240 ieee80211_wake_queues_by_reason(&sdata->local->hw,
226 IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE); 241 IEEE80211_QUEUE_STOP_REASON_CHTYPE_CHANGE);
227 } 242 }
243 mutex_unlock(&local->sta_mtx);
228 244
229 ht_opmode = le16_to_cpu(ht_oper->operation_mode); 245 ht_opmode = le16_to_cpu(ht_oper->operation_mode);
230 246
@@ -2006,6 +2022,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2006 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, 2022 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
2007 elems.ht_cap_elem, &sta->sta.ht_cap); 2023 elems.ht_cap_elem, &sta->sta.ht_cap);
2008 2024
2025 sta->supports_40mhz =
2026 sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
2027
2009 rate_control_rate_init(sta); 2028 rate_control_rate_init(sta);
2010 2029
2011 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) 2030 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index fbb1efdc4d04..27b66be8ac8f 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -63,8 +63,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
63 63
64static inline void rate_control_rate_update(struct ieee80211_local *local, 64static inline void rate_control_rate_update(struct ieee80211_local *local,
65 struct ieee80211_supported_band *sband, 65 struct ieee80211_supported_band *sband,
66 struct sta_info *sta, u32 changed, 66 struct sta_info *sta, u32 changed)
67 enum nl80211_channel_type oper_chan_type)
68{ 67{
69 struct rate_control_ref *ref = local->rate_ctrl; 68 struct rate_control_ref *ref = local->rate_ctrl;
70 struct ieee80211_sta *ista = &sta->sta; 69 struct ieee80211_sta *ista = &sta->sta;
@@ -72,7 +71,7 @@ static inline void rate_control_rate_update(struct ieee80211_local *local,
72 71
73 if (ref && ref->ops->rate_update) 72 if (ref && ref->ops->rate_update)
74 ref->ops->rate_update(ref->priv, sband, ista, 73 ref->ops->rate_update(ref->priv, sband, ista,
75 priv_sta, changed, oper_chan_type); 74 priv_sta, changed);
76} 75}
77 76
78static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, 77static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 16e0b277b9a8..3b3dcae13bbc 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -686,8 +686,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
686 686
687static void 687static void
688minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, 688minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
689 struct ieee80211_sta *sta, void *priv_sta, 689 struct ieee80211_sta *sta, void *priv_sta)
690 enum nl80211_channel_type oper_chan_type)
691{ 690{
692 struct minstrel_priv *mp = priv; 691 struct minstrel_priv *mp = priv;
693 struct minstrel_ht_sta_priv *msp = priv_sta; 692 struct minstrel_ht_sta_priv *msp = priv_sta;
@@ -735,10 +734,6 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband,
735 if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) 734 if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING)
736 mi->tx_flags |= IEEE80211_TX_CTL_LDPC; 735 mi->tx_flags |= IEEE80211_TX_CTL_LDPC;
737 736
738 if (oper_chan_type != NL80211_CHAN_HT40MINUS &&
739 oper_chan_type != NL80211_CHAN_HT40PLUS)
740 sta_cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
741
742 smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >> 737 smps = (sta_cap & IEEE80211_HT_CAP_SM_PS) >>
743 IEEE80211_HT_CAP_SM_PS_SHIFT; 738 IEEE80211_HT_CAP_SM_PS_SHIFT;
744 739
@@ -788,17 +783,15 @@ static void
788minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband, 783minstrel_ht_rate_init(void *priv, struct ieee80211_supported_band *sband,
789 struct ieee80211_sta *sta, void *priv_sta) 784 struct ieee80211_sta *sta, void *priv_sta)
790{ 785{
791 struct minstrel_priv *mp = priv; 786 minstrel_ht_update_caps(priv, sband, sta, priv_sta);
792
793 minstrel_ht_update_caps(priv, sband, sta, priv_sta, mp->hw->conf.channel_type);
794} 787}
795 788
796static void 789static void
797minstrel_ht_rate_update(void *priv, struct ieee80211_supported_band *sband, 790minstrel_ht_rate_update(void *priv, struct ieee80211_supported_band *sband,
798 struct ieee80211_sta *sta, void *priv_sta, 791 struct ieee80211_sta *sta, void *priv_sta,
799 u32 changed, enum nl80211_channel_type oper_chan_type) 792 u32 changed)
800{ 793{
801 minstrel_ht_update_caps(priv, sband, sta, priv_sta, oper_chan_type); 794 minstrel_ht_update_caps(priv, sband, sta, priv_sta);
802} 795}
803 796
804static void * 797static void *
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8da3b36c287a..54a049123a60 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2268,11 +2268,8 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2268 2268
2269 sband = rx->local->hw.wiphy->bands[status->band]; 2269 sband = rx->local->hw.wiphy->bands[status->band];
2270 2270
2271 rate_control_rate_update( 2271 rate_control_rate_update(local, sband, rx->sta,
2272 local, sband, rx->sta, 2272 IEEE80211_RC_SMPS_CHANGED);
2273 IEEE80211_RC_SMPS_CHANGED,
2274 ieee80211_get_tx_channel_type(
2275 local, local->_oper_channel_type));
2276 goto handled; 2273 goto handled;
2277 } 2274 }
2278 default: 2275 default:
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index e21652bccf7c..b1b4b1413c74 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -369,6 +369,8 @@ struct sta_info {
369 unsigned int lost_packets; 369 unsigned int lost_packets;
370 unsigned int beacon_loss_count; 370 unsigned int beacon_loss_count;
371 371
372 bool supports_40mhz;
373
372 /* keep last! */ 374 /* keep last! */
373 struct ieee80211_sta sta; 375 struct ieee80211_sta sta;
374}; 376};