cfg80211: allow drivers to iterate over matching combinations
authorMichal Kazior <michal.kazior@tieto.com>
Wed, 9 Apr 2014 13:29:22 +0000 (15:29 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 25 Apr 2014 15:08:14 +0000 (17:08 +0200)
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>
include/net/cfg80211.h
net/wireless/util.c

index 9496fe5..3dd2cb4 100644 (file)
@@ -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 */
index d032a31..d8b5995 100644 (file)
@@ -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);