2014-02-28 15:04:19

by Michal Kazior

[permalink] [raw]
Subject: [PATCH] mac80211: refactor channel switch function

The function was quite big. This splits out beacon
updating into a separate function for improved
maintenance and extension.

Signed-off-by: Michal Kazior <[email protected]>
---
net/mac80211/cfg.c | 109 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 61 insertions(+), 48 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 80534f5..776bdc8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3089,52 +3089,12 @@ unlock:
sdata_unlock(sdata);
}

-int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
- struct cfg80211_csa_settings *params)
+int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_csa_settings *params,
+ u32 *changed)
{
- struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- struct ieee80211_local *local = sdata->local;
- struct ieee80211_chanctx_conf *chanctx_conf;
- struct ieee80211_chanctx *chanctx;
- struct ieee80211_if_mesh __maybe_unused *ifmsh;
- int err, num_chanctx, changed = 0;
-
- sdata_assert_lock(sdata);
-
- if (!list_empty(&local->roc_list) || local->scanning)
- return -EBUSY;
-
- if (sdata->wdev.cac_started)
- return -EBUSY;
-
- if (cfg80211_chandef_identical(&params->chandef,
- &sdata->vif.bss_conf.chandef))
- return -EINVAL;
-
- rcu_read_lock();
- chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
- if (!chanctx_conf) {
- rcu_read_unlock();
- return -EBUSY;
- }
-
- /* don't handle for multi-VIF cases */
- chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
- if (chanctx->refcount > 1) {
- rcu_read_unlock();
- return -EBUSY;
- }
- num_chanctx = 0;
- list_for_each_entry_rcu(chanctx, &local->chanctx_list, list)
- num_chanctx++;
- rcu_read_unlock();
-
- if (num_chanctx > 1)
- return -EBUSY;
-
- /* don't allow another channel switch if one is already active. */
- if (sdata->vif.csa_active)
- return -EBUSY;
+ struct ieee80211_if_mesh *ifmsh;
+ int err;

switch (sdata->vif.type) {
case NL80211_IFTYPE_AP:
@@ -3170,7 +3130,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
kfree(sdata->u.ap.next_beacon);
return err;
}
- changed |= err;
+ *changed |= err;

break;
case NL80211_IFTYPE_ADHOC:
@@ -3204,7 +3164,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
err = ieee80211_ibss_csa_beacon(sdata, params);
if (err < 0)
return err;
- changed |= err;
+ *changed |= err;
}

ieee80211_send_action_csa(sdata, params);
@@ -3237,7 +3197,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
return err;
}
- changed |= err;
+ *changed |= err;
}

if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_INIT)
@@ -3249,6 +3209,59 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
return -EOPNOTSUPP;
}

+ return 0;
+}
+
+int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_csa_settings *params)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ struct ieee80211_local *local = sdata->local;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_chanctx *chanctx;
+ int err, num_chanctx, changed = 0;
+
+ sdata_assert_lock(sdata);
+
+ if (!list_empty(&local->roc_list) || local->scanning)
+ return -EBUSY;
+
+ if (sdata->wdev.cac_started)
+ return -EBUSY;
+
+ if (cfg80211_chandef_identical(&params->chandef,
+ &sdata->vif.bss_conf.chandef))
+ return -EINVAL;
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (!chanctx_conf) {
+ rcu_read_unlock();
+ return -EBUSY;
+ }
+
+ /* don't handle for multi-VIF cases */
+ chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
+ if (chanctx->refcount > 1) {
+ rcu_read_unlock();
+ return -EBUSY;
+ }
+ num_chanctx = 0;
+ list_for_each_entry_rcu(chanctx, &local->chanctx_list, list)
+ num_chanctx++;
+ rcu_read_unlock();
+
+ if (num_chanctx > 1)
+ return -EBUSY;
+
+ /* don't allow another channel switch if one is already active. */
+ if (sdata->vif.csa_active)
+ return -EBUSY;
+
+ err = ieee80211_set_csa_beacon(sdata, params, &changed);
+ if (err)
+ return err;
+
sdata->csa_radar_required = params->radar_required;

if (params->block_tx)
--
1.8.5.3



2014-03-03 13:02:21

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH] mac80211: refactor channel switch function

On Fri, 2014-02-28 at 15:59 +0100, Michal Kazior wrote:
> The function was quite big. This splits out beacon
> updating into a separate function for improved
> maintenance and extension.

Applied.

johannes