|
@@ -3053,25 +3053,11 @@ void ieee80211_csa_finish(struct ieee80211_vif *vif)
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(ieee80211_csa_finish);
|
|
EXPORT_SYMBOL(ieee80211_csa_finish);
|
|
|
|
|
|
-static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
|
|
|
|
|
|
+static int ieee80211_set_after_csa_beacon(struct ieee80211_sub_if_data *sdata,
|
|
|
|
+ u32 *changed)
|
|
{
|
|
{
|
|
- struct ieee80211_local *local = sdata->local;
|
|
|
|
- int err, changed = 0;
|
|
|
|
-
|
|
|
|
- sdata_assert_lock(sdata);
|
|
|
|
- lockdep_assert_held(&local->mtx);
|
|
|
|
-
|
|
|
|
- sdata->radar_required = sdata->csa_radar_required;
|
|
|
|
- err = ieee80211_vif_change_channel(sdata, &changed);
|
|
|
|
- if (WARN_ON(err < 0))
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- if (!local->use_chanctx) {
|
|
|
|
- local->_oper_chandef = sdata->csa_chandef;
|
|
|
|
- ieee80211_hw_config(local, 0);
|
|
|
|
- }
|
|
|
|
|
|
+ int err;
|
|
|
|
|
|
- sdata->vif.csa_active = false;
|
|
|
|
switch (sdata->vif.type) {
|
|
switch (sdata->vif.type) {
|
|
case NL80211_IFTYPE_AP:
|
|
case NL80211_IFTYPE_AP:
|
|
err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
|
|
err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon);
|
|
@@ -3079,30 +3065,57 @@ static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
|
|
sdata->u.ap.next_beacon = NULL;
|
|
sdata->u.ap.next_beacon = NULL;
|
|
|
|
|
|
if (err < 0)
|
|
if (err < 0)
|
|
- return;
|
|
|
|
- changed |= err;
|
|
|
|
|
|
+ return err;
|
|
|
|
+ *changed |= err;
|
|
break;
|
|
break;
|
|
case NL80211_IFTYPE_ADHOC:
|
|
case NL80211_IFTYPE_ADHOC:
|
|
err = ieee80211_ibss_finish_csa(sdata);
|
|
err = ieee80211_ibss_finish_csa(sdata);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
- return;
|
|
|
|
- changed |= err;
|
|
|
|
|
|
+ return err;
|
|
|
|
+ *changed |= err;
|
|
break;
|
|
break;
|
|
#ifdef CONFIG_MAC80211_MESH
|
|
#ifdef CONFIG_MAC80211_MESH
|
|
case NL80211_IFTYPE_MESH_POINT:
|
|
case NL80211_IFTYPE_MESH_POINT:
|
|
err = ieee80211_mesh_finish_csa(sdata);
|
|
err = ieee80211_mesh_finish_csa(sdata);
|
|
if (err < 0)
|
|
if (err < 0)
|
|
- return;
|
|
|
|
- changed |= err;
|
|
|
|
|
|
+ return err;
|
|
|
|
+ *changed |= err;
|
|
break;
|
|
break;
|
|
#endif
|
|
#endif
|
|
default:
|
|
default:
|
|
WARN_ON(1);
|
|
WARN_ON(1);
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void ieee80211_csa_finalize(struct ieee80211_sub_if_data *sdata)
|
|
|
|
+{
|
|
|
|
+ struct ieee80211_local *local = sdata->local;
|
|
|
|
+ u32 changed = 0;
|
|
|
|
+ int err;
|
|
|
|
+
|
|
|
|
+ sdata_assert_lock(sdata);
|
|
|
|
+ lockdep_assert_held(&local->mtx);
|
|
|
|
+
|
|
|
|
+ sdata->radar_required = sdata->csa_radar_required;
|
|
|
|
+ err = ieee80211_vif_change_channel(sdata, &changed);
|
|
|
|
+ if (WARN_ON(err < 0))
|
|
return;
|
|
return;
|
|
|
|
+
|
|
|
|
+ if (!local->use_chanctx) {
|
|
|
|
+ local->_oper_chandef = sdata->csa_chandef;
|
|
|
|
+ ieee80211_hw_config(local, 0);
|
|
}
|
|
}
|
|
|
|
|
|
- ieee80211_bss_info_change_notify(sdata, changed);
|
|
|
|
|
|
+ sdata->vif.csa_active = false;
|
|
|
|
+
|
|
|
|
+ err = ieee80211_set_after_csa_beacon(sdata, &changed);
|
|
|
|
+ if (err)
|
|
|
|
+ return;
|
|
|
|
|
|
|
|
+ ieee80211_bss_info_change_notify(sdata, changed);
|
|
cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
|
|
cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef);
|
|
|
|
|
|
if (!ieee80211_csa_needs_block_tx(local))
|
|
if (!ieee80211_csa_needs_block_tx(local))
|