summaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorMichal Kazior <michal.kazior@tieto.com>2014-02-28 09:59:06 -0500
committerJohannes Berg <johannes.berg@intel.com>2014-03-03 09:07:29 -0500
commit37fa2bdd16a12fef7804606f56525ba5747bf172 (patch)
tree42f90bba49c690ba64e79bfcd61c959324c35f0b /net/mac80211
parent7c8d5e03acc680eb433b0d5dbacbb6cc9db663a1 (diff)
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 <michal.kazior@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c113
1 files changed, 63 insertions, 50 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 80534f524fd6..aaa59d719592 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3089,52 +3089,11 @@ unlock:
3089 sdata_unlock(sdata); 3089 sdata_unlock(sdata);
3090} 3090}
3091 3091
3092int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, 3092static int ieee80211_set_csa_beacon(struct ieee80211_sub_if_data *sdata,
3093 struct cfg80211_csa_settings *params) 3093 struct cfg80211_csa_settings *params,
3094 u32 *changed)
3094{ 3095{
3095 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3096 int err;
3096 struct ieee80211_local *local = sdata->local;
3097 struct ieee80211_chanctx_conf *chanctx_conf;
3098 struct ieee80211_chanctx *chanctx;
3099 struct ieee80211_if_mesh __maybe_unused *ifmsh;
3100 int err, num_chanctx, changed = 0;
3101
3102 sdata_assert_lock(sdata);
3103
3104 if (!list_empty(&local->roc_list) || local->scanning)
3105 return -EBUSY;
3106
3107 if (sdata->wdev.cac_started)
3108 return -EBUSY;
3109
3110 if (cfg80211_chandef_identical(&params->chandef,
3111 &sdata->vif.bss_conf.chandef))
3112 return -EINVAL;
3113
3114 rcu_read_lock();
3115 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3116 if (!chanctx_conf) {
3117 rcu_read_unlock();
3118 return -EBUSY;
3119 }
3120
3121 /* don't handle for multi-VIF cases */
3122 chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
3123 if (chanctx->refcount > 1) {
3124 rcu_read_unlock();
3125 return -EBUSY;
3126 }
3127 num_chanctx = 0;
3128 list_for_each_entry_rcu(chanctx, &local->chanctx_list, list)
3129 num_chanctx++;
3130 rcu_read_unlock();
3131
3132 if (num_chanctx > 1)
3133 return -EBUSY;
3134
3135 /* don't allow another channel switch if one is already active. */
3136 if (sdata->vif.csa_active)
3137 return -EBUSY;
3138 3097
3139 switch (sdata->vif.type) { 3098 switch (sdata->vif.type) {
3140 case NL80211_IFTYPE_AP: 3099 case NL80211_IFTYPE_AP:
@@ -3170,7 +3129,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3170 kfree(sdata->u.ap.next_beacon); 3129 kfree(sdata->u.ap.next_beacon);
3171 return err; 3130 return err;
3172 } 3131 }
3173 changed |= err; 3132 *changed |= err;
3174 3133
3175 break; 3134 break;
3176 case NL80211_IFTYPE_ADHOC: 3135 case NL80211_IFTYPE_ADHOC:
@@ -3204,15 +3163,15 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3204 err = ieee80211_ibss_csa_beacon(sdata, params); 3163 err = ieee80211_ibss_csa_beacon(sdata, params);
3205 if (err < 0) 3164 if (err < 0)
3206 return err; 3165 return err;
3207 changed |= err; 3166 *changed |= err;
3208 } 3167 }
3209 3168
3210 ieee80211_send_action_csa(sdata, params); 3169 ieee80211_send_action_csa(sdata, params);
3211 3170
3212 break; 3171 break;
3213#ifdef CONFIG_MAC80211_MESH 3172#ifdef CONFIG_MAC80211_MESH
3214 case NL80211_IFTYPE_MESH_POINT: 3173 case NL80211_IFTYPE_MESH_POINT: {
3215 ifmsh = &sdata->u.mesh; 3174 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
3216 3175
3217 if (params->chandef.width != sdata->vif.bss_conf.chandef.width) 3176 if (params->chandef.width != sdata->vif.bss_conf.chandef.width)
3218 return -EINVAL; 3177 return -EINVAL;
@@ -3237,18 +3196,72 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3237 ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE; 3196 ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
3238 return err; 3197 return err;
3239 } 3198 }
3240 changed |= err; 3199 *changed |= err;
3241 } 3200 }
3242 3201
3243 if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_INIT) 3202 if (ifmsh->csa_role == IEEE80211_MESH_CSA_ROLE_INIT)
3244 ieee80211_send_action_csa(sdata, params); 3203 ieee80211_send_action_csa(sdata, params);
3245 3204
3246 break; 3205 break;
3206 }
3247#endif 3207#endif
3248 default: 3208 default:
3249 return -EOPNOTSUPP; 3209 return -EOPNOTSUPP;
3250 } 3210 }
3251 3211
3212 return 0;
3213}
3214
3215int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
3216 struct cfg80211_csa_settings *params)
3217{
3218 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3219 struct ieee80211_local *local = sdata->local;
3220 struct ieee80211_chanctx_conf *chanctx_conf;
3221 struct ieee80211_chanctx *chanctx;
3222 int err, num_chanctx, changed = 0;
3223
3224 sdata_assert_lock(sdata);
3225
3226 if (!list_empty(&local->roc_list) || local->scanning)
3227 return -EBUSY;
3228
3229 if (sdata->wdev.cac_started)
3230 return -EBUSY;
3231
3232 if (cfg80211_chandef_identical(&params->chandef,
3233 &sdata->vif.bss_conf.chandef))
3234 return -EINVAL;
3235
3236 rcu_read_lock();
3237 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3238 if (!chanctx_conf) {
3239 rcu_read_unlock();
3240 return -EBUSY;
3241 }
3242
3243 /* don't handle for multi-VIF cases */
3244 chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
3245 if (chanctx->refcount > 1) {
3246 rcu_read_unlock();
3247 return -EBUSY;
3248 }
3249 num_chanctx = 0;
3250 list_for_each_entry_rcu(chanctx, &local->chanctx_list, list)
3251 num_chanctx++;
3252 rcu_read_unlock();
3253
3254 if (num_chanctx > 1)
3255 return -EBUSY;
3256
3257 /* don't allow another channel switch if one is already active. */
3258 if (sdata->vif.csa_active)
3259 return -EBUSY;
3260
3261 err = ieee80211_set_csa_beacon(sdata, params, &changed);
3262 if (err)
3263 return err;
3264
3252 sdata->csa_radar_required = params->radar_required; 3265 sdata->csa_radar_required = params->radar_required;
3253 3266
3254 if (params->block_tx) 3267 if (params->block_tx)