aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-07 15:37:29 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-15 03:41:36 -0500
commit2c9b735982ee8a2d34e7eeb3e26b683f81872fdb (patch)
treef2f0f0b741aa0b1ffaa2a95c0533d1eeba745868
parentf2d9330ee820b01e2b1caf46370bc7963d259908 (diff)
mac80211: add ieee80211_vif_change_bandwidth
For HT and VHT the current bandwidth can change, add the function ieee80211_vif_change_bandwidth() to take care of this. It returns a failure if the new bandwidth isn't compatible with the existing channel context, the caller has to handle that. When it happens, also inform the driver that the bandwidth changed for this virtual interface (no drivers would actually care today though.) Changing to/from HT/VHT isn't allowed though. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/mac80211/chan.c49
-rw-r--r--net/mac80211/ieee80211_i.h4
3 files changed, 57 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index b7fb311e83f4..54e2add8429f 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -215,6 +215,9 @@ struct ieee80211_chanctx_conf {
215 * changed (currently only in P2P client mode, GO mode will be later) 215 * changed (currently only in P2P client mode, GO mode will be later)
216 * @BSS_CHANGED_DTIM_PERIOD: the DTIM period value was changed (set when 216 * @BSS_CHANGED_DTIM_PERIOD: the DTIM period value was changed (set when
217 * it becomes valid, managed mode only) 217 * it becomes valid, managed mode only)
218 * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed,
219 * note that this is only called when it changes after the channel
220 * context had been assigned.
218 */ 221 */
219enum ieee80211_bss_change { 222enum ieee80211_bss_change {
220 BSS_CHANGED_ASSOC = 1<<0, 223 BSS_CHANGED_ASSOC = 1<<0,
@@ -238,6 +241,7 @@ enum ieee80211_bss_change {
238 BSS_CHANGED_TXPOWER = 1<<18, 241 BSS_CHANGED_TXPOWER = 1<<18,
239 BSS_CHANGED_P2P_PS = 1<<19, 242 BSS_CHANGED_P2P_PS = 1<<19,
240 BSS_CHANGED_DTIM_PERIOD = 1<<20, 243 BSS_CHANGED_DTIM_PERIOD = 1<<20,
244 BSS_CHANGED_BANDWIDTH = 1<<21,
241 245
242 /* when adding here, make sure to change ieee80211_reconfig */ 246 /* when adding here, make sure to change ieee80211_reconfig */
243}; 247};
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 78dbb371f16e..78c0d90dd641 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -375,6 +375,55 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
375 return ret; 375 return ret;
376} 376}
377 377
378int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
379 const struct cfg80211_chan_def *chandef,
380 u32 *changed)
381{
382 struct ieee80211_local *local = sdata->local;
383 struct ieee80211_chanctx_conf *conf;
384 struct ieee80211_chanctx *ctx;
385 int ret;
386
387 if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
388 IEEE80211_CHAN_DISABLED))
389 return -EINVAL;
390
391 mutex_lock(&local->chanctx_mtx);
392 if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) {
393 ret = 0;
394 goto out;
395 }
396
397 if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT ||
398 sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) {
399 ret = -EINVAL;
400 goto out;
401 }
402
403 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
404 lockdep_is_held(&local->chanctx_mtx));
405 if (!conf) {
406 ret = -EINVAL;
407 goto out;
408 }
409
410 ctx = container_of(conf, struct ieee80211_chanctx, conf);
411 if (!cfg80211_chandef_compatible(&conf->def, chandef)) {
412 ret = -EINVAL;
413 goto out;
414 }
415
416 sdata->vif.bss_conf.chandef = *chandef;
417
418 ieee80211_recalc_chanctx_chantype(local, ctx);
419
420 *changed |= BSS_CHANGED_BANDWIDTH;
421 ret = 0;
422 out:
423 mutex_unlock(&local->chanctx_mtx);
424 return ret;
425}
426
378void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) 427void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
379{ 428{
380 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev)); 429 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 892bac64a189..d1074442f1b5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1613,6 +1613,10 @@ int __must_check
1613ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, 1613ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1614 const struct cfg80211_chan_def *chandef, 1614 const struct cfg80211_chan_def *chandef,
1615 enum ieee80211_chanctx_mode mode); 1615 enum ieee80211_chanctx_mode mode);
1616int __must_check
1617ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
1618 const struct cfg80211_chan_def *chandef,
1619 u32 *changed);
1616void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); 1620void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
1617void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); 1621void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
1618void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 1622void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,