diff options
author | Michal Kazior <michal.kazior@tieto.com> | 2014-04-09 09:29:30 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2014-04-25 11:08:30 -0400 |
commit | ed68ebcaf9688a15cbd249476334d37717d49468 (patch) | |
tree | ed42b8b6a854a5b1f5a10772bcfb2b5163a4e92f /net | |
parent | 13f348a814e75667a9cc0b00f9a87dae5ab9b943 (diff) |
mac80211: split ieee80211_new_chanctx()
The function did a little too much. Split it up so
the code can be easily reused in the future.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/chan.c | 56 |
1 files changed, 43 insertions, 13 deletions
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 7303eddb1895..247133fe36bc 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -351,19 +351,17 @@ static bool ieee80211_is_radar_required(struct ieee80211_local *local) | |||
351 | } | 351 | } |
352 | 352 | ||
353 | static struct ieee80211_chanctx * | 353 | static struct ieee80211_chanctx * |
354 | ieee80211_new_chanctx(struct ieee80211_local *local, | 354 | ieee80211_alloc_chanctx(struct ieee80211_local *local, |
355 | const struct cfg80211_chan_def *chandef, | 355 | const struct cfg80211_chan_def *chandef, |
356 | enum ieee80211_chanctx_mode mode) | 356 | enum ieee80211_chanctx_mode mode) |
357 | { | 357 | { |
358 | struct ieee80211_chanctx *ctx; | 358 | struct ieee80211_chanctx *ctx; |
359 | u32 changed; | ||
360 | int err; | ||
361 | 359 | ||
362 | lockdep_assert_held(&local->chanctx_mtx); | 360 | lockdep_assert_held(&local->chanctx_mtx); |
363 | 361 | ||
364 | ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); | 362 | ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); |
365 | if (!ctx) | 363 | if (!ctx) |
366 | return ERR_PTR(-ENOMEM); | 364 | return NULL; |
367 | 365 | ||
368 | INIT_LIST_HEAD(&ctx->assigned_vifs); | 366 | INIT_LIST_HEAD(&ctx->assigned_vifs); |
369 | INIT_LIST_HEAD(&ctx->reserved_vifs); | 367 | INIT_LIST_HEAD(&ctx->reserved_vifs); |
@@ -373,31 +371,63 @@ ieee80211_new_chanctx(struct ieee80211_local *local, | |||
373 | ctx->mode = mode; | 371 | ctx->mode = mode; |
374 | ctx->conf.radar_enabled = ieee80211_is_radar_required(local); | 372 | ctx->conf.radar_enabled = ieee80211_is_radar_required(local); |
375 | ieee80211_recalc_chanctx_min_def(local, ctx); | 373 | ieee80211_recalc_chanctx_min_def(local, ctx); |
374 | |||
375 | return ctx; | ||
376 | } | ||
377 | |||
378 | static int ieee80211_add_chanctx(struct ieee80211_local *local, | ||
379 | struct ieee80211_chanctx *ctx) | ||
380 | { | ||
381 | u32 changed; | ||
382 | int err; | ||
383 | |||
384 | lockdep_assert_held(&local->mtx); | ||
385 | lockdep_assert_held(&local->chanctx_mtx); | ||
386 | |||
376 | if (!local->use_chanctx) | 387 | if (!local->use_chanctx) |
377 | local->hw.conf.radar_enabled = ctx->conf.radar_enabled; | 388 | local->hw.conf.radar_enabled = ctx->conf.radar_enabled; |
378 | 389 | ||
379 | /* we hold the mutex to prevent idle from changing */ | ||
380 | lockdep_assert_held(&local->mtx); | ||
381 | /* turn idle off *before* setting channel -- some drivers need that */ | 390 | /* turn idle off *before* setting channel -- some drivers need that */ |
382 | changed = ieee80211_idle_off(local); | 391 | changed = ieee80211_idle_off(local); |
383 | if (changed) | 392 | if (changed) |
384 | ieee80211_hw_config(local, changed); | 393 | ieee80211_hw_config(local, changed); |
385 | 394 | ||
386 | if (!local->use_chanctx) { | 395 | if (!local->use_chanctx) { |
387 | local->_oper_chandef = *chandef; | 396 | local->_oper_chandef = ctx->conf.def; |
388 | ieee80211_hw_config(local, 0); | 397 | ieee80211_hw_config(local, 0); |
389 | } else { | 398 | } else { |
390 | err = drv_add_chanctx(local, ctx); | 399 | err = drv_add_chanctx(local, ctx); |
391 | if (err) { | 400 | if (err) { |
392 | kfree(ctx); | ||
393 | ieee80211_recalc_idle(local); | 401 | ieee80211_recalc_idle(local); |
394 | return ERR_PTR(err); | 402 | return err; |
395 | } | 403 | } |
396 | } | 404 | } |
397 | 405 | ||
398 | /* and keep the mutex held until the new chanctx is on the list */ | 406 | return 0; |
399 | list_add_rcu(&ctx->list, &local->chanctx_list); | 407 | } |
408 | |||
409 | static struct ieee80211_chanctx * | ||
410 | ieee80211_new_chanctx(struct ieee80211_local *local, | ||
411 | const struct cfg80211_chan_def *chandef, | ||
412 | enum ieee80211_chanctx_mode mode) | ||
413 | { | ||
414 | struct ieee80211_chanctx *ctx; | ||
415 | int err; | ||
416 | |||
417 | lockdep_assert_held(&local->mtx); | ||
418 | lockdep_assert_held(&local->chanctx_mtx); | ||
419 | |||
420 | ctx = ieee80211_alloc_chanctx(local, chandef, mode); | ||
421 | if (!ctx) | ||
422 | return ERR_PTR(-ENOMEM); | ||
400 | 423 | ||
424 | err = ieee80211_add_chanctx(local, ctx); | ||
425 | if (err) { | ||
426 | kfree(ctx); | ||
427 | return ERR_PTR(err); | ||
428 | } | ||
429 | |||
430 | list_add_rcu(&ctx->list, &local->chanctx_list); | ||
401 | return ctx; | 431 | return ctx; |
402 | } | 432 | } |
403 | 433 | ||