Loading include/net/cfg80211.h +25 −23 Original line number Diff line number Diff line Loading @@ -778,6 +778,26 @@ struct cfg80211_csa_settings { u8 count; }; /** * struct iface_combination_params - input parameters for interface combinations * * Used to pass interface combination parameters * * @num_different_channels: the number of different channels we want * to use for verification * @radar_detect: a bitmap where each bit corresponds to a channel * width where radar detection is needed, as in the definition of * &struct ieee80211_iface_combination.@radar_detect_widths * @iftype_num: array with the number of interfaces of each interface * type. The index is the interface type as specified in &enum * nl80211_iftype. */ struct iface_combination_params { int num_different_channels; u8 radar_detect; int iftype_num[NUM_NL80211_IFTYPES]; }; /** * enum station_parameters_apply_mask - station parameter values to apply * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) Loading Loading @@ -5006,36 +5026,20 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); * cfg80211_check_combinations - check interface combinations * * @wiphy: the wiphy * @num_different_channels: the number of different channels we want * to use for verification * @radar_detect: a bitmap where each bit corresponds to a channel * width where radar detection is needed, as in the definition of * &struct ieee80211_iface_combination.@radar_detect_widths * @iftype_num: array with the numbers of interfaces of each interface * type. The index is the interface type as specified in &enum * nl80211_iftype. * @params: the interface combinations parameter * * This function can be called by the driver to check whether a * combination of interfaces and their types are allowed according to * the interface combinations. */ int cfg80211_check_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES]); struct iface_combination_params *params); /** * cfg80211_iter_combinations - iterate over matching combinations * * @wiphy: the wiphy * @num_different_channels: the number of different channels we want * to use for verification * @radar_detect: a bitmap where each bit corresponds to a channel * width where radar detection is needed, as in the definition of * &struct ieee80211_iface_combination.@radar_detect_widths * @iftype_num: array with the numbers of interfaces of each interface * type. The index is the interface type as specified in &enum * nl80211_iftype. * @params: the interface combinations parameter * @iter: function to call for each matching combination * @data: pointer to pass to iter function * Loading @@ -5044,9 +5048,7 @@ int cfg80211_check_combinations(struct wiphy *wiphy, * purposes. */ int cfg80211_iter_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES], struct iface_combination_params *params, void (*iter)(const struct ieee80211_iface_combination *c, void *data), void *data); Loading net/mac80211/util.c +20 −24 Original line number Diff line number Diff line Loading @@ -2997,10 +2997,11 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_sub_if_data *sdata_iter; enum nl80211_iftype iftype = sdata->wdev.iftype; int num[NUM_NL80211_IFTYPES]; struct ieee80211_chanctx *ctx; int num_different_channels = 0; int total = 1; struct iface_combination_params params = { .radar_detect = radar_detect, }; lockdep_assert_held(&local->chanctx_mtx); Loading @@ -3011,9 +3012,6 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, !chandef->chan)) return -EINVAL; if (chandef) num_different_channels = 1; if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) return -EINVAL; Loading @@ -3024,24 +3022,26 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, return 0; } memset(num, 0, sizeof(num)); if (chandef) params.num_different_channels = 1; if (iftype != NL80211_IFTYPE_UNSPECIFIED) num[iftype] = 1; params.iftype_num[iftype] = 1; list_for_each_entry(ctx, &local->chanctx_list, list) { if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) continue; radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); params.radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { num_different_channels++; params.num_different_channels++; continue; } if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && cfg80211_chandef_compatible(chandef, &ctx->conf.def)) continue; num_different_channels++; params.num_different_channels++; } list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { Loading @@ -3054,16 +3054,14 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) continue; num[wdev_iter->iftype]++; params.iftype_num[wdev_iter->iftype]++; total++; } if (total == 1 && !radar_detect) if (total == 1 && !params.radar_detect) return 0; return cfg80211_check_combinations(local->hw.wiphy, num_different_channels, radar_detect, num); return cfg80211_check_combinations(local->hw.wiphy, ¶ms); } static void Loading @@ -3079,12 +3077,10 @@ ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c, int ieee80211_max_num_channels(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int num[NUM_NL80211_IFTYPES] = {}; struct ieee80211_chanctx *ctx; int num_different_channels = 0; u8 radar_detect = 0; u32 max_num_different_channels = 1; int err; struct iface_combination_params params = {0}; lockdep_assert_held(&local->chanctx_mtx); Loading @@ -3092,17 +3088,17 @@ int ieee80211_max_num_channels(struct ieee80211_local *local) if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) continue; num_different_channels++; params.num_different_channels++; radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); params.radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); } list_for_each_entry_rcu(sdata, &local->interfaces, list) num[sdata->wdev.iftype]++; params.iftype_num[sdata->wdev.iftype]++; err = cfg80211_iter_combinations(local->hw.wiphy, num_different_channels, radar_detect, num, ieee80211_iter_max_chans, err = cfg80211_iter_combinations(local->hw.wiphy, ¶ms, ieee80211_iter_max_chans, &max_num_different_channels); if (err < 0) return err; Loading net/wireless/util.c +25 −29 Original line number Diff line number Diff line Loading @@ -1272,9 +1272,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, } int cfg80211_iter_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES], struct iface_combination_params *params, void (*iter)(const struct ieee80211_iface_combination *c, void *data), void *data) Loading @@ -1285,7 +1283,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, int num_interfaces = 0; u32 used_iftypes = 0; if (radar_detect) { if (params->radar_detect) { rcu_read_lock(); regdom = rcu_dereference(cfg80211_regdomain); if (regdom) Loading @@ -1294,8 +1292,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, } for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { num_interfaces += iftype_num[iftype]; if (iftype_num[iftype] > 0 && num_interfaces += params->iftype_num[iftype]; if (params->iftype_num[iftype] > 0 && !(wiphy->software_iftypes & BIT(iftype))) used_iftypes |= BIT(iftype); } Loading @@ -1309,7 +1307,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, if (num_interfaces > c->max_interfaces) continue; if (num_different_channels > c->num_different_channels) if (params->num_different_channels > c->num_different_channels) continue; limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, Loading @@ -1324,16 +1322,17 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, all_iftypes |= limits[j].types; if (!(limits[j].types & BIT(iftype))) continue; if (limits[j].max < iftype_num[iftype]) if (limits[j].max < params->iftype_num[iftype]) goto cont; limits[j].max -= iftype_num[iftype]; limits[j].max -= params->iftype_num[iftype]; } } if (radar_detect != (c->radar_detect_widths & radar_detect)) if (params->radar_detect != (c->radar_detect_widths & params->radar_detect)) goto cont; if (radar_detect && c->radar_detect_regions && if (params->radar_detect && c->radar_detect_regions && !(c->radar_detect_regions & BIT(region))) goto cont; Loading Loading @@ -1367,14 +1366,11 @@ cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c, } int cfg80211_check_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES]) struct iface_combination_params *params) { int err, num = 0; err = cfg80211_iter_combinations(wiphy, num_different_channels, radar_detect, iftype_num, err = cfg80211_iter_combinations(wiphy, params, cfg80211_iter_sum_ifcombs, &num); if (err) return err; Loading @@ -1393,14 +1389,15 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, u8 radar_detect) { struct wireless_dev *wdev_iter; int num[NUM_NL80211_IFTYPES]; struct ieee80211_channel *used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS]; struct ieee80211_channel *ch; enum cfg80211_chan_mode chmode; int num_different_channels = 0; int total = 1; int i; struct iface_combination_params params = { .radar_detect = radar_detect, }; ASSERT_RTNL(); Loading @@ -1417,10 +1414,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, return 0; } memset(num, 0, sizeof(num)); memset(used_channels, 0, sizeof(used_channels)); num[iftype] = 1; params.iftype_num[iftype] = 1; /* TODO: We'll probably not need this anymore, since this * should only be called with CHAN_MODE_UNDEFINED. There are Loading @@ -1433,10 +1429,10 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, case CHAN_MODE_SHARED: WARN_ON(!chan); used_channels[0] = chan; num_different_channels++; params.num_different_channels++; break; case CHAN_MODE_EXCLUSIVE: num_different_channels++; params.num_different_channels++; break; } Loading Loading @@ -1464,7 +1460,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, */ mutex_lock_nested(&wdev_iter->mtx, 1); __acquire(wdev_iter->mtx); cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect); cfg80211_get_chan_state(wdev_iter, &ch, &chmode, ¶ms.radar_detect); wdev_unlock(wdev_iter); switch (chmode) { Loading @@ -1480,23 +1477,22 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, if (used_channels[i] == NULL) { used_channels[i] = ch; num_different_channels++; params.num_different_channels++; } break; case CHAN_MODE_EXCLUSIVE: num_different_channels++; params.num_different_channels++; break; } num[wdev_iter->iftype]++; params.iftype_num[wdev_iter->iftype]++; total++; } if (total == 1 && !radar_detect) if (total == 1 && !params.radar_detect) return 0; return cfg80211_check_combinations(&rdev->wiphy, num_different_channels, radar_detect, num); return cfg80211_check_combinations(&rdev->wiphy, ¶ms); } int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, Loading Loading
include/net/cfg80211.h +25 −23 Original line number Diff line number Diff line Loading @@ -778,6 +778,26 @@ struct cfg80211_csa_settings { u8 count; }; /** * struct iface_combination_params - input parameters for interface combinations * * Used to pass interface combination parameters * * @num_different_channels: the number of different channels we want * to use for verification * @radar_detect: a bitmap where each bit corresponds to a channel * width where radar detection is needed, as in the definition of * &struct ieee80211_iface_combination.@radar_detect_widths * @iftype_num: array with the number of interfaces of each interface * type. The index is the interface type as specified in &enum * nl80211_iftype. */ struct iface_combination_params { int num_different_channels; u8 radar_detect; int iftype_num[NUM_NL80211_IFTYPES]; }; /** * enum station_parameters_apply_mask - station parameter values to apply * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) Loading Loading @@ -5006,36 +5026,20 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); * cfg80211_check_combinations - check interface combinations * * @wiphy: the wiphy * @num_different_channels: the number of different channels we want * to use for verification * @radar_detect: a bitmap where each bit corresponds to a channel * width where radar detection is needed, as in the definition of * &struct ieee80211_iface_combination.@radar_detect_widths * @iftype_num: array with the numbers of interfaces of each interface * type. The index is the interface type as specified in &enum * nl80211_iftype. * @params: the interface combinations parameter * * This function can be called by the driver to check whether a * combination of interfaces and their types are allowed according to * the interface combinations. */ int cfg80211_check_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES]); struct iface_combination_params *params); /** * cfg80211_iter_combinations - iterate over matching combinations * * @wiphy: the wiphy * @num_different_channels: the number of different channels we want * to use for verification * @radar_detect: a bitmap where each bit corresponds to a channel * width where radar detection is needed, as in the definition of * &struct ieee80211_iface_combination.@radar_detect_widths * @iftype_num: array with the numbers of interfaces of each interface * type. The index is the interface type as specified in &enum * nl80211_iftype. * @params: the interface combinations parameter * @iter: function to call for each matching combination * @data: pointer to pass to iter function * Loading @@ -5044,9 +5048,7 @@ int cfg80211_check_combinations(struct wiphy *wiphy, * purposes. */ int cfg80211_iter_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES], struct iface_combination_params *params, void (*iter)(const struct ieee80211_iface_combination *c, void *data), void *data); Loading
net/mac80211/util.c +20 −24 Original line number Diff line number Diff line Loading @@ -2997,10 +2997,11 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_sub_if_data *sdata_iter; enum nl80211_iftype iftype = sdata->wdev.iftype; int num[NUM_NL80211_IFTYPES]; struct ieee80211_chanctx *ctx; int num_different_channels = 0; int total = 1; struct iface_combination_params params = { .radar_detect = radar_detect, }; lockdep_assert_held(&local->chanctx_mtx); Loading @@ -3011,9 +3012,6 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, !chandef->chan)) return -EINVAL; if (chandef) num_different_channels = 1; if (WARN_ON(iftype >= NUM_NL80211_IFTYPES)) return -EINVAL; Loading @@ -3024,24 +3022,26 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, return 0; } memset(num, 0, sizeof(num)); if (chandef) params.num_different_channels = 1; if (iftype != NL80211_IFTYPE_UNSPECIFIED) num[iftype] = 1; params.iftype_num[iftype] = 1; list_for_each_entry(ctx, &local->chanctx_list, list) { if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) continue; radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); params.radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { num_different_channels++; params.num_different_channels++; continue; } if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && cfg80211_chandef_compatible(chandef, &ctx->conf.def)) continue; num_different_channels++; params.num_different_channels++; } list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { Loading @@ -3054,16 +3054,14 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) continue; num[wdev_iter->iftype]++; params.iftype_num[wdev_iter->iftype]++; total++; } if (total == 1 && !radar_detect) if (total == 1 && !params.radar_detect) return 0; return cfg80211_check_combinations(local->hw.wiphy, num_different_channels, radar_detect, num); return cfg80211_check_combinations(local->hw.wiphy, ¶ms); } static void Loading @@ -3079,12 +3077,10 @@ ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c, int ieee80211_max_num_channels(struct ieee80211_local *local) { struct ieee80211_sub_if_data *sdata; int num[NUM_NL80211_IFTYPES] = {}; struct ieee80211_chanctx *ctx; int num_different_channels = 0; u8 radar_detect = 0; u32 max_num_different_channels = 1; int err; struct iface_combination_params params = {0}; lockdep_assert_held(&local->chanctx_mtx); Loading @@ -3092,17 +3088,17 @@ int ieee80211_max_num_channels(struct ieee80211_local *local) if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) continue; num_different_channels++; params.num_different_channels++; radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); params.radar_detect |= ieee80211_chanctx_radar_detect(local, ctx); } list_for_each_entry_rcu(sdata, &local->interfaces, list) num[sdata->wdev.iftype]++; params.iftype_num[sdata->wdev.iftype]++; err = cfg80211_iter_combinations(local->hw.wiphy, num_different_channels, radar_detect, num, ieee80211_iter_max_chans, err = cfg80211_iter_combinations(local->hw.wiphy, ¶ms, ieee80211_iter_max_chans, &max_num_different_channels); if (err < 0) return err; Loading
net/wireless/util.c +25 −29 Original line number Diff line number Diff line Loading @@ -1272,9 +1272,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, } int cfg80211_iter_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES], struct iface_combination_params *params, void (*iter)(const struct ieee80211_iface_combination *c, void *data), void *data) Loading @@ -1285,7 +1283,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, int num_interfaces = 0; u32 used_iftypes = 0; if (radar_detect) { if (params->radar_detect) { rcu_read_lock(); regdom = rcu_dereference(cfg80211_regdomain); if (regdom) Loading @@ -1294,8 +1292,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, } for (iftype = 0; iftype < NUM_NL80211_IFTYPES; iftype++) { num_interfaces += iftype_num[iftype]; if (iftype_num[iftype] > 0 && num_interfaces += params->iftype_num[iftype]; if (params->iftype_num[iftype] > 0 && !(wiphy->software_iftypes & BIT(iftype))) used_iftypes |= BIT(iftype); } Loading @@ -1309,7 +1307,7 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, if (num_interfaces > c->max_interfaces) continue; if (num_different_channels > c->num_different_channels) if (params->num_different_channels > c->num_different_channels) continue; limits = kmemdup(c->limits, sizeof(limits[0]) * c->n_limits, Loading @@ -1324,16 +1322,17 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, all_iftypes |= limits[j].types; if (!(limits[j].types & BIT(iftype))) continue; if (limits[j].max < iftype_num[iftype]) if (limits[j].max < params->iftype_num[iftype]) goto cont; limits[j].max -= iftype_num[iftype]; limits[j].max -= params->iftype_num[iftype]; } } if (radar_detect != (c->radar_detect_widths & radar_detect)) if (params->radar_detect != (c->radar_detect_widths & params->radar_detect)) goto cont; if (radar_detect && c->radar_detect_regions && if (params->radar_detect && c->radar_detect_regions && !(c->radar_detect_regions & BIT(region))) goto cont; Loading Loading @@ -1367,14 +1366,11 @@ cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c, } int cfg80211_check_combinations(struct wiphy *wiphy, const int num_different_channels, const u8 radar_detect, const int iftype_num[NUM_NL80211_IFTYPES]) struct iface_combination_params *params) { int err, num = 0; err = cfg80211_iter_combinations(wiphy, num_different_channels, radar_detect, iftype_num, err = cfg80211_iter_combinations(wiphy, params, cfg80211_iter_sum_ifcombs, &num); if (err) return err; Loading @@ -1393,14 +1389,15 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, u8 radar_detect) { struct wireless_dev *wdev_iter; int num[NUM_NL80211_IFTYPES]; struct ieee80211_channel *used_channels[CFG80211_MAX_NUM_DIFFERENT_CHANNELS]; struct ieee80211_channel *ch; enum cfg80211_chan_mode chmode; int num_different_channels = 0; int total = 1; int i; struct iface_combination_params params = { .radar_detect = radar_detect, }; ASSERT_RTNL(); Loading @@ -1417,10 +1414,9 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, return 0; } memset(num, 0, sizeof(num)); memset(used_channels, 0, sizeof(used_channels)); num[iftype] = 1; params.iftype_num[iftype] = 1; /* TODO: We'll probably not need this anymore, since this * should only be called with CHAN_MODE_UNDEFINED. There are Loading @@ -1433,10 +1429,10 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, case CHAN_MODE_SHARED: WARN_ON(!chan); used_channels[0] = chan; num_different_channels++; params.num_different_channels++; break; case CHAN_MODE_EXCLUSIVE: num_different_channels++; params.num_different_channels++; break; } Loading Loading @@ -1464,7 +1460,8 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, */ mutex_lock_nested(&wdev_iter->mtx, 1); __acquire(wdev_iter->mtx); cfg80211_get_chan_state(wdev_iter, &ch, &chmode, &radar_detect); cfg80211_get_chan_state(wdev_iter, &ch, &chmode, ¶ms.radar_detect); wdev_unlock(wdev_iter); switch (chmode) { Loading @@ -1480,23 +1477,22 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, if (used_channels[i] == NULL) { used_channels[i] = ch; num_different_channels++; params.num_different_channels++; } break; case CHAN_MODE_EXCLUSIVE: num_different_channels++; params.num_different_channels++; break; } num[wdev_iter->iftype]++; params.iftype_num[wdev_iter->iftype]++; total++; } if (total == 1 && !radar_detect) if (total == 1 && !params.radar_detect) return 0; return cfg80211_check_combinations(&rdev->wiphy, num_different_channels, radar_detect, num); return cfg80211_check_combinations(&rdev->wiphy, ¶ms); } int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, Loading