*     changed (currently only in P2P client mode, GO mode will be later)
  * @BSS_CHANGED_DTIM_PERIOD: the DTIM period value was changed (set when
  *     it becomes valid, managed mode only)
+ * @BSS_CHANGED_BANDWIDTH: The bandwidth used by this interface changed,
+ *     note that this is only called when it changes after the channel
+ *     context had been assigned.
  */
 enum ieee80211_bss_change {
        BSS_CHANGED_ASSOC               = 1<<0,
        BSS_CHANGED_TXPOWER             = 1<<18,
        BSS_CHANGED_P2P_PS              = 1<<19,
        BSS_CHANGED_DTIM_PERIOD         = 1<<20,
+       BSS_CHANGED_BANDWIDTH           = 1<<21,
 
        /* when adding here, make sure to change ieee80211_reconfig */
 };
 
        return ret;
 }
 
+int ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
+                                  const struct cfg80211_chan_def *chandef,
+                                  u32 *changed)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_chanctx_conf *conf;
+       struct ieee80211_chanctx *ctx;
+       int ret;
+
+       if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
+                                    IEEE80211_CHAN_DISABLED))
+               return -EINVAL;
+
+       mutex_lock(&local->chanctx_mtx);
+       if (cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) {
+               ret = 0;
+               goto out;
+       }
+
+       if (chandef->width == NL80211_CHAN_WIDTH_20_NOHT ||
+           sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
+                                        lockdep_is_held(&local->chanctx_mtx));
+       if (!conf) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       ctx = container_of(conf, struct ieee80211_chanctx, conf);
+       if (!cfg80211_chandef_compatible(&conf->def, chandef)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       sdata->vif.bss_conf.chandef = *chandef;
+
+       ieee80211_recalc_chanctx_chantype(local, ctx);
+
+       *changed |= BSS_CHANGED_BANDWIDTH;
+       ret = 0;
+ out:
+       mutex_unlock(&local->chanctx_mtx);
+       return ret;
+}
+
 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
 {
        WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
 
 ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
                          const struct cfg80211_chan_def *chandef,
                          enum ieee80211_chanctx_mode mode);
+int __must_check
+ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
+                              const struct cfg80211_chan_def *chandef,
+                              u32 *changed);
 void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata);
 void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
 void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,