cfg80211: allow drivers to iterate over matching combinations
The patch splits cfg80211_check_combinations() into an iterator function and a simple iteration user. This makes it possible for drivers to asses how many channels can use given iftype setup. This in turn can be used for future multi-interface/multi-channel channel switching. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
46d537245d
commit
65a124dd71
2 changed files with 64 additions and 7 deletions
|
@ -4715,6 +4715,33 @@ int cfg80211_check_combinations(struct wiphy *wiphy,
|
|||
const u8 radar_detect,
|
||||
const int iftype_num[NUM_NL80211_IFTYPES]);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @iter: function to call for each matching combination
|
||||
* @data: pointer to pass to iter function
|
||||
*
|
||||
* This function can be called by the driver to check what possible
|
||||
* combinations it fits in at a given moment, e.g. for channel switching
|
||||
* purposes.
|
||||
*/
|
||||
int cfg80211_iter_combinations(struct wiphy *wiphy,
|
||||
const int num_different_channels,
|
||||
const u8 radar_detect,
|
||||
const int iftype_num[NUM_NL80211_IFTYPES],
|
||||
void (*iter)(const struct ieee80211_iface_combination *c,
|
||||
void *data),
|
||||
void *data);
|
||||
|
||||
/* Logging, debugging and troubleshooting/diagnostic helpers. */
|
||||
|
||||
/* wiphy_printk helpers, similar to dev_printk */
|
||||
|
|
|
@ -1263,10 +1263,13 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
|
|||
return res;
|
||||
}
|
||||
|
||||
int cfg80211_check_combinations(struct wiphy *wiphy,
|
||||
const int num_different_channels,
|
||||
const u8 radar_detect,
|
||||
const int iftype_num[NUM_NL80211_IFTYPES])
|
||||
int cfg80211_iter_combinations(struct wiphy *wiphy,
|
||||
const int num_different_channels,
|
||||
const u8 radar_detect,
|
||||
const int iftype_num[NUM_NL80211_IFTYPES],
|
||||
void (*iter)(const struct ieee80211_iface_combination *c,
|
||||
void *data),
|
||||
void *data)
|
||||
{
|
||||
int i, j, iftype;
|
||||
int num_interfaces = 0;
|
||||
|
@ -1323,13 +1326,40 @@ int cfg80211_check_combinations(struct wiphy *wiphy,
|
|||
/* This combination covered all interface types and
|
||||
* supported the requested numbers, so we're good.
|
||||
*/
|
||||
kfree(limits);
|
||||
return 0;
|
||||
|
||||
(*iter)(c, data);
|
||||
cont:
|
||||
kfree(limits);
|
||||
}
|
||||
|
||||
return -EBUSY;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_iter_combinations);
|
||||
|
||||
static void
|
||||
cfg80211_iter_sum_ifcombs(const struct ieee80211_iface_combination *c,
|
||||
void *data)
|
||||
{
|
||||
int *num = data;
|
||||
(*num)++;
|
||||
}
|
||||
|
||||
int cfg80211_check_combinations(struct wiphy *wiphy,
|
||||
const int num_different_channels,
|
||||
const u8 radar_detect,
|
||||
const int iftype_num[NUM_NL80211_IFTYPES])
|
||||
{
|
||||
int err, num = 0;
|
||||
|
||||
err = cfg80211_iter_combinations(wiphy, num_different_channels,
|
||||
radar_detect, iftype_num,
|
||||
cfg80211_iter_sum_ifcombs, &num);
|
||||
if (err)
|
||||
return err;
|
||||
if (num == 0)
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_check_combinations);
|
||||
|
||||
|
|
Loading…
Reference in a new issue