cregit-Linux how code gets into the kernel

Release 4.8 net/mac80211/chan.c

Directory: net/mac80211
/*
 * mac80211 - channel management
 */

#include <linux/nl80211.h>
#include <linux/export.h>
#include <linux/rtnetlink.h>
#include <net/cfg80211.h>
#include "ieee80211_i.h"
#include "driver-ops.h"


static int ieee80211_chanctx_num_assigned(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { struct ieee80211_sub_if_data *sdata; int num = 0; lockdep_assert_held(&local->chanctx_mtx); list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list) num++; return num; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior3572.92%150.00%
eliad pellereliad peller1327.08%150.00%
Total48100.00%2100.00%


static int ieee80211_chanctx_num_reserved(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { struct ieee80211_sub_if_data *sdata; int num = 0; lockdep_assert_held(&local->chanctx_mtx); list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list) num++; return num; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior3470.83%150.00%
eliad pellereliad peller1429.17%150.00%
Total48100.00%2100.00%


int ieee80211_chanctx_refcount(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { return ieee80211_chanctx_num_assigned(local, ctx) + ieee80211_chanctx_num_reserved(local, ctx); }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior2376.67%150.00%
eliad pellereliad peller723.33%150.00%
Total30100.00%2100.00%


static int ieee80211_num_chanctx(struct ieee80211_local *local) { struct ieee80211_chanctx *ctx; int num = 0; lockdep_assert_held(&local->chanctx_mtx); list_for_each_entry(ctx, &local->chanctx_list, list) num++; return num; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior2455.81%150.00%
eliad pellereliad peller1944.19%150.00%
Total43100.00%2100.00%


static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local) { lockdep_assert_held(&local->chanctx_mtx); return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local); }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior1963.33%150.00%
eliad pellereliad peller1136.67%150.00%
Total30100.00%2100.00%


static struct ieee80211_chanctx * ieee80211_vif_get_chanctx(struct ieee80211_sub_if_data *sdata) { struct ieee80211_local *local __maybe_unused = sdata->local; struct ieee80211_chanctx_conf *conf; conf = rcu_dereference_protected(sdata->vif.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (!conf) return NULL; return container_of(conf, struct ieee80211_chanctx, conf); }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior6598.48%266.67%
johannes bergjohannes berg11.52%133.33%
Total66100.00%3100.00%


static const struct cfg80211_chan_def * ieee80211_chanctx_reserved_chandef(struct ieee80211_local *local, struct ieee80211_chanctx *ctx, const struct cfg80211_chan_def *compat) { struct ieee80211_sub_if_data *sdata; lockdep_assert_held(&local->chanctx_mtx); list_for_each_entry(sdata, &ctx->reserved_vifs, reserved_chanctx_list) { if (!compat) compat = &sdata->reserved_chandef; compat = cfg80211_chandef_compatible(&sdata->reserved_chandef, compat); if (!compat) break; } return compat; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior6377.78%250.00%
eliad pellereliad peller1822.22%250.00%
Total81100.00%4100.00%


static const struct cfg80211_chan_def * ieee80211_chanctx_non_reserved_chandef(struct ieee80211_local *local, struct ieee80211_chanctx *ctx, const struct cfg80211_chan_def *compat) { struct ieee80211_sub_if_data *sdata; lockdep_assert_held(&local->chanctx_mtx); list_for_each_entry(sdata, &ctx->assigned_vifs, assigned_chanctx_list) { if (sdata->reserved_chanctx != NULL) continue; if (!compat) compat = &sdata->vif.bss_conf.chandef; compat = cfg80211_chandef_compatible( &sdata->vif.bss_conf.chandef, compat); if (!compat) break; } return compat; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior6263.27%150.00%
eliad pellereliad peller3636.73%150.00%
Total98100.00%2100.00%


static const struct cfg80211_chan_def * ieee80211_chanctx_combined_chandef(struct ieee80211_local *local, struct ieee80211_chanctx *ctx, const struct cfg80211_chan_def *compat) { lockdep_assert_held(&local->chanctx_mtx); compat = ieee80211_chanctx_reserved_chandef(local, ctx, compat); if (!compat) return NULL; compat = ieee80211_chanctx_non_reserved_chandef(local, ctx, compat); if (!compat) return NULL; return compat; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior5371.62%150.00%
eliad pellereliad peller2128.38%150.00%
Total74100.00%2100.00%


static bool ieee80211_chanctx_can_reserve_chandef(struct ieee80211_local *local, struct ieee80211_chanctx *ctx, const struct cfg80211_chan_def *def) { lockdep_assert_held(&local->chanctx_mtx); if (ieee80211_chanctx_combined_chandef(local, ctx, def)) return true; if (!list_empty(&ctx->reserved_vifs) && ieee80211_chanctx_reserved_chandef(local, ctx, def)) return true; return false; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior5781.43%240.00%
johannes bergjohannes berg1217.14%240.00%
eliad pellereliad peller11.43%120.00%
Total70100.00%5100.00%


static struct ieee80211_chanctx * ieee80211_find_reservation_chanctx(struct ieee80211_local *local, const struct cfg80211_chan_def *chandef, enum ieee80211_chanctx_mode mode) { struct ieee80211_chanctx *ctx; lockdep_assert_held(&local->chanctx_mtx); if (mode == IEEE80211_CHANCTX_EXCLUSIVE) return NULL; list_for_each_entry(ctx, &local->chanctx_list, list) { if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) continue; if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) continue; if (!ieee80211_chanctx_can_reserve_chandef(local, ctx, chandef)) continue; return ctx; } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior8693.48%480.00%
johannes bergjohannes berg66.52%120.00%
Total92100.00%5100.00%


enum nl80211_chan_width ieee80211_get_sta_bw(struct ieee80211_sta *sta) { switch (sta->bandwidth) { case IEEE80211_STA_RX_BW_20: if (sta->ht_cap.ht_supported) return NL80211_CHAN_WIDTH_20; else return NL80211_CHAN_WIDTH_20_NOHT; case IEEE80211_STA_RX_BW_40: return NL80211_CHAN_WIDTH_40; case IEEE80211_STA_RX_BW_80: return NL80211_CHAN_WIDTH_80; case IEEE80211_STA_RX_BW_160: /* * This applied for both 160 and 80+80. since we use * the returned value to consider degradation of * ctx->conf.min_def, we have to make sure to take * the bigger one (NL80211_CHAN_WIDTH_160). * Otherwise we might try degrading even when not * needed, as the max required sta_bw returned (80+80) * might be smaller than the configured bw (160). */ return NL80211_CHAN_WIDTH_160; default: WARN_ON(1); return NL80211_CHAN_WIDTH_20; } }

Contributors

PersonTokensPropCommitsCommitProp
eliad pellereliad peller6092.31%150.00%
simon wunderlichsimon wunderlich57.69%150.00%
Total65100.00%2100.00%


static enum nl80211_chan_width ieee80211_get_max_required_bw(struct ieee80211_sub_if_data *sdata) { enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; struct sta_info *sta; rcu_read_lock(); list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { if (sdata != sta->sdata && !(sta->sdata->bss && sta->sdata->bss == sdata->bss)) continue; if (!sta->uploaded || !test_sta_flag(sta, WLAN_STA_ASSOC)) continue; max_bw = max(max_bw, ieee80211_get_sta_bw(&sta->sta)); } rcu_read_unlock(); return max_bw; }

Contributors

PersonTokensPropCommitsCommitProp
eliad pellereliad peller6564.36%133.33%
simon wunderlichsimon wunderlich2827.72%133.33%
ilan peerilan peer87.92%133.33%
Total101100.00%3100.00%


static enum nl80211_chan_width ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, struct ieee80211_chanctx_conf *conf) { struct ieee80211_sub_if_data *sdata; enum nl80211_chan_width max_bw = NL80211_CHAN_WIDTH_20_NOHT; rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { struct ieee80211_vif *vif = &sdata->vif; enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20_NOHT; if (!ieee80211_sdata_running(sdata)) continue; if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) continue; switch (vif->type) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP_VLAN: width = ieee80211_get_max_required_bw(sdata); break; case NL80211_IFTYPE_STATION: /* * The ap's sta->bandwidth is not set yet at this * point, so take the width from the chandef, but * account also for TDLS peers */ width = max(vif->bss_conf.chandef.width, ieee80211_get_max_required_bw(sdata)); break; case NL80211_IFTYPE_P2P_DEVICE: continue; case NL80211_IFTYPE_ADHOC: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_MESH_POINT: case NL80211_IFTYPE_OCB: width = vif->bss_conf.chandef.width; break; case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_P2P_CLIENT: case NL80211_IFTYPE_P2P_GO: WARN_ON_ONCE(1); } max_bw = max(max_bw, width); } /* use the configured bandwidth in case of monitor interface */ sdata = rcu_dereference(local->monitor_sdata); if (sdata && rcu_access_pointer(sdata->vif.chanctx_conf) == conf) max_bw = max(max_bw, conf->def.width); rcu_read_unlock(); return max_bw; }

Contributors

PersonTokensPropCommitsCommitProp
eliad pellereliad peller13861.33%220.00%
michal kaziormichal kazior3816.89%220.00%
arik nemtsovarik nemtsov2310.22%110.00%
johannes bergjohannes berg177.56%330.00%
simon wunderlichsimon wunderlich62.67%110.00%
rostislav lisovyrostislav lisovy31.33%110.00%
Total225100.00%10100.00%

/* * recalc the min required chan width of the channel context, which is * the max of min required widths of all the interfaces bound to this * channel context. */
void ieee80211_recalc_chanctx_min_def(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { enum nl80211_chan_width max_bw; struct cfg80211_chan_def min_def; lockdep_assert_held(&local->chanctx_mtx); /* don't optimize 5MHz, 10MHz, and radar_enabled confs */ if (ctx->conf.def.width == NL80211_CHAN_WIDTH_5 || ctx->conf.def.width == NL80211_CHAN_WIDTH_10 || ctx->conf.radar_enabled) { ctx->conf.min_def = ctx->conf.def; return; } max_bw = ieee80211_get_chanctx_max_required_bw(local, &ctx->conf); /* downgrade chandef up to max_bw */ min_def = ctx->conf.def; while (min_def.width > max_bw) ieee80211_chandef_downgrade(&min_def); if (cfg80211_chandef_identical(&ctx->conf.min_def, &min_def)) return; ctx->conf.min_def = min_def; if (!ctx->driver_present) return; drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_MIN_WIDTH); }

Contributors

PersonTokensPropCommitsCommitProp
eliad pellereliad peller9462.25%114.29%
michal kaziormichal kazior3120.53%228.57%
simon wunderlichsimon wunderlich1610.60%114.29%
johannes bergjohannes berg85.30%228.57%
karl beldankarl beldan21.32%114.29%
Total151100.00%7100.00%


static void ieee80211_change_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx, const struct cfg80211_chan_def *chandef) { if (cfg80211_chandef_identical(&ctx->conf.def, chandef)) { ieee80211_recalc_chanctx_min_def(local, ctx); return; } WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef)); ctx->conf.def = *chandef; drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH); ieee80211_recalc_chanctx_min_def(local, ctx); if (!local->use_chanctx) { local->_oper_chandef = *chandef; ieee80211_hw_config(local, 0); } }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior5146.36%333.33%
johannes bergjohannes berg4540.91%333.33%
arik nemtsovarik nemtsov98.18%111.11%
eliad pellereliad peller32.73%111.11%
karl beldankarl beldan21.82%111.11%
Total110100.00%9100.00%


static struct ieee80211_chanctx * ieee80211_find_chanctx(struct ieee80211_local *local, const struct cfg80211_chan_def *chandef, enum ieee80211_chanctx_mode mode) { struct ieee80211_chanctx *ctx; lockdep_assert_held(&local->chanctx_mtx); if (mode == IEEE80211_CHANCTX_EXCLUSIVE) return NULL; list_for_each_entry(ctx, &local->chanctx_list, list) { const struct cfg80211_chan_def *compat; if (ctx->replace_state != IEEE80211_CHANCTX_REPLACE_NONE) continue; if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) continue; compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef); if (!compat) continue; compat = ieee80211_chanctx_reserved_chandef(local, ctx, compat); if (!compat) continue; ieee80211_change_chanctx(local, ctx, compat); return ctx; } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior10983.21%466.67%
johannes bergjohannes berg2216.79%233.33%
Total131100.00%6100.00%


bool ieee80211_is_radar_required(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; lockdep_assert_held(&local->mtx); rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (sdata->radar_required) { rcu_read_unlock(); return true; } } rcu_read_unlock(); return false; }

Contributors

PersonTokensPropCommitsCommitProp
simon wunderlichsimon wunderlich4885.71%150.00%
michal kaziormichal kazior814.29%150.00%
Total56100.00%2100.00%


static bool ieee80211_chanctx_radar_required(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { struct ieee80211_chanctx_conf *conf = &ctx->conf; struct ieee80211_sub_if_data *sdata; bool required = false; lockdep_assert_held(&local->chanctx_mtx); lockdep_assert_held(&local->mtx); rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) continue; if (!sdata->radar_required) continue; required = true; break; } rcu_read_unlock(); return required; }

Contributors

PersonTokensPropCommitsCommitProp
eliad pellereliad peller10699.07%150.00%
michal kaziormichal kazior10.93%150.00%
Total107100.00%2100.00%


static struct ieee80211_chanctx * ieee80211_alloc_chanctx(struct ieee80211_local *local, const struct cfg80211_chan_def *chandef, enum ieee80211_chanctx_mode mode) { struct ieee80211_chanctx *ctx; lockdep_assert_held(&local->chanctx_mtx); ctx = kzalloc(sizeof(*ctx) + local->hw.chanctx_data_size, GFP_KERNEL); if (!ctx) return NULL; INIT_LIST_HEAD(&ctx->assigned_vifs); INIT_LIST_HEAD(&ctx->reserved_vifs); ctx->conf.def = *chandef; ctx->conf.rx_chains_static = 1; ctx->conf.rx_chains_dynamic = 1; ctx->mode = mode; ctx->conf.radar_enabled = false; ieee80211_recalc_chanctx_min_def(local, ctx); return ctx; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior9070.31%444.44%
johannes bergjohannes berg2217.19%222.22%
eliad pellereliad peller97.03%222.22%
simon wunderlichsimon wunderlich75.47%111.11%
Total128100.00%9100.00%


static int ieee80211_add_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { u32 changed; int err; lockdep_assert_held(&local->mtx); lockdep_assert_held(&local->chanctx_mtx); if (!local->use_chanctx) local->hw.conf.radar_enabled = ctx->conf.radar_enabled; /* turn idle off *before* setting channel -- some drivers need that */ changed = ieee80211_idle_off(local); if (changed) ieee80211_hw_config(local, changed); if (!local->use_chanctx) { local->_oper_chandef = ctx->conf.def; ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); } else { err = drv_add_chanctx(local, ctx); if (err) { ieee80211_recalc_idle(local); return err; } } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior7052.63%228.57%
johannes bergjohannes berg4030.08%228.57%
simon wunderlichsimon wunderlich2115.79%114.29%
karl beldankarl beldan10.75%114.29%
john w. linvillejohn w. linville10.75%114.29%
Total133100.00%7100.00%


static struct ieee80211_chanctx * ieee80211_new_chanctx(struct ieee80211_local *local, const struct cfg80211_chan_def *chandef, enum ieee80211_chanctx_mode mode) { struct ieee80211_chanctx *ctx; int err; lockdep_assert_held(&local->mtx); lockdep_assert_held(&local->chanctx_mtx); ctx = ieee80211_alloc_chanctx(local, chandef, mode); if (!ctx) return ERR_PTR(-ENOMEM); err = ieee80211_add_chanctx(local, ctx); if (err) { kfree(ctx); return ERR_PTR(err); } list_add_rcu(&ctx->list, &local->chanctx_list); return ctx; }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior10190.18%350.00%
johannes bergjohannes berg119.82%350.00%
Total112100.00%6100.00%


static void ieee80211_del_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { lockdep_assert_held(&local->chanctx_mtx); if (!local->use_chanctx) { struct cfg80211_chan_def *chandef = &local->_oper_chandef; chandef->width = NL80211_CHAN_WIDTH_20_NOHT; chandef->center_freq1 = chandef->chan->center_freq; chandef->center_freq2 = 0; /* NOTE: Disabling radar is only valid here for * single channel context. To be sure, check it ... */ WARN_ON(local->hw.conf.radar_enabled && !list_empty(&local->chanctx_list)); local->hw.conf.radar_enabled = false; ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); } else { drv_remove_chanctx(local, ctx); } ieee80211_recalc_idle(local); }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior4840.68%342.86%
karl beldankarl beldan2823.73%114.29%
johannes bergjohannes berg2218.64%114.29%
simon wunderlichsimon wunderlich1916.10%114.29%
john w. linvillejohn w. linville10.85%114.29%
Total118100.00%7100.00%


static void ieee80211_free_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { lockdep_assert_held(&local->chanctx_mtx); WARN_ON_ONCE(ieee80211_chanctx_refcount(local, ctx) != 0); list_del_rcu(&ctx->list); ieee80211_del_chanctx(local, ctx); kfree_rcu(ctx, rcu_head); }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior4984.48%360.00%
simon wunderlichsimon wunderlich58.62%120.00%
johannes bergjohannes berg46.90%120.00%
Total58100.00%5100.00%


void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, struct ieee80211_chanctx *ctx) { struct ieee80211_chanctx_conf *conf = &ctx->conf; struct ieee80211_sub_if_data *sdata; const struct cfg80211_chan_def *compat = NULL; struct sta_info *sta; lockdep_assert_held(&local->chanctx_mtx); rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { if (!ieee80211_sdata_running(sdata)) continue; if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf) continue; if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) continue; if (!compat) compat = &sdata->vif.bss_conf.chandef; compat = cfg80211_chandef_compatible( &sdata->vif.bss_conf.chandef, compat); if (WARN_ON_ONCE(!compat)) break; } /* TDLS peers can sometimes affect the chandef width */ list_for_each_entry_rcu(sta, &local->sta_list, list) { if (!sta->uploaded || !test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW) || !test_sta_flag(sta, WLAN_STA_AUTHORIZED) || !sta->tdls_chandef.chan) continue; compat = cfg80211_chandef_compatible(&sta->tdls_chandef, compat); if (WARN_ON_ONCE(!compat)) break; } rcu_read_unlock(); if (!compat) return; ieee80211_change_chanctx(local, ctx, compat); }

Contributors

PersonTokensPropCommitsCommitProp
michal kaziormichal kazior9844.55%233.33%
arik nemtsovarik nemtsov6830.91%116.67%
johannes bergjohannes berg4319.55%233.33%
felix fietkaufelix fietkau115.00%116.67%
Total220100.00%6100.00%


static void ieee80211_recalc_radar_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *chanctx) { bool radar_enabled; lockdep_assert_held(&local->chanctx_mtx); /* for ieee80211_is_radar_required */ lockdep_assert_held(&local->mtx); radar_enabled = ieee80211_chanctx_radar_required(local, chanctx); if (radar_enabled == chanctx->conf.radar_enabled) return; chanctx->conf.radar_enabled = radar_enabled; if (!local->use_chanctx) { local->hw.conf.radar_enabled = chanctx->conf.radar_enabled; ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); } drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RADAR); }

Contributors

PersonTokensPropCommitsCommitProp
johannes bergjohannes berg9996.12%250.00%
eliad pellereliad peller43.88%250.00%
Total103100.00%4100.00%


static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, struct ieee80211_chanctx *new_ctx) { struct ieee80211_local *local = sdata->local; struct ieee80211_chanctx_conf *conf; struct ieee80211_chanctx *curr_ctx = NULL; int ret = 0; conf = rcu_dereference_protected(sdata->vif.chanctx_conf, lockdep_is_held(&local->chanctx_mtx)); if (conf) { curr_ctx = container_of(conf, struct ieee80211_chanctx, conf); drv_unassign_vif_chanctx(local, sdata, curr_ctx); conf = NULL; list_del(&sdata->assigned_chanctx_list); } if (new_ctx) { ret = drv_assign_vif_chanctx(local, sdata, new_ctx); if (ret) goto out; conf = &new_ctx->conf; list_add(&sdata->assigned_chanctx_list, &new_ctx->assigned_vifs); } out: rcu_assign_pointer(sdata->vif.chanctx_conf, conf); sdata->vif.bss_conf.idle = !conf; if (curr_ctx && ieee80211_chanctx_num_assigned(local, curr_ctx) > 0) { ieee80211_recalc_chanctx_chantype(local, curr_ctx); ieee80211_recalc_smps_chanctx(local, curr_ctx); ieee80211_recalc_radar_chanctx(local, curr_ctx); ieee80211_recalc_chanctx_min_def(local, curr_ctx); } if (new_ctx && ieee80211_chanctx_num_assigned(local, new_ctx) > 0) { ieee80211_recalc_txpower(sdata, false); ieee80211_recalc_chanctx_min_def(local, new_ctx); } if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && sdata->vif.type != NL80211_IFTYPE_MONITOR) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); ieee80211_check_fast_xmit_iface(sdata); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
luciano coelholuciano coelho15255.68%17.69%
michal kaziormichal kazior8531.14%538.46%
johannes bergjohannes berg259.16%430.77%
simon wunderlichsimon wunderlich51.83%17.69%
eliad pellereliad peller41.47%17.69%
lorenzo bianconilorenzo bianconi20.73%17.69%
Total273100.00%13100.00%


void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *chanctx) { struct ieee80211_sub_if_data *sdata; u8 rx_chains_static, rx_chains_dynamic; lockdep_assert_held(&local->chanctx_mtx); rx_chains_static = 1; rx_chains_dynamic = 1; rcu_read_lock(); list_for_each_entry_rcu(sdata, &local->interfaces, list) { u8 needed_static, needed_dynamic; if (!ieee80211_sdata_running(sdata)) continue; if (rcu_access_pointer(sdata->vif.