mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 23:12:32 +00:00
87033c3a0b
- add support for configuring allowed radios for a vif - add support for monitor mode on multiple channels Signed-off-by: Felix Fietkau <nbd@nbd.name>
123 lines
3.9 KiB
Diff
123 lines
3.9 KiB
Diff
From: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
|
Date: Tue, 17 Sep 2024 19:32:39 +0530
|
|
Subject: [PATCH] wifi: cfg80211: check radio iface combination for multi radio
|
|
per wiphy
|
|
|
|
Currently, wiphy_verify_combinations() fails for the multi-radio per wiphy
|
|
due to the condition check on new global interface combination that DFS
|
|
only works on one channel. In a multi-radio scenario, new global interface
|
|
combination encompasses the capabilities of all radio combinations, so it
|
|
supports more than one channel with DFS. For multi-radio per wiphy,
|
|
interface combination verification needs to be performed for radio specific
|
|
interface combinations. This is necessary as the new global interface
|
|
combination combines the capabilities of all radio combinations.
|
|
|
|
Fixes: a01b1e9f9955 ("wifi: mac80211: add support for DFS with multiple radios")
|
|
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
|
|
---
|
|
|
|
--- a/net/wireless/core.c
|
|
+++ b/net/wireless/core.c
|
|
@@ -599,16 +599,20 @@ use_default_name:
|
|
}
|
|
EXPORT_SYMBOL(wiphy_new_nm);
|
|
|
|
-static int wiphy_verify_combinations(struct wiphy *wiphy)
|
|
+static
|
|
+int wiphy_verify_iface_combinations(struct wiphy *wiphy,
|
|
+ const struct ieee80211_iface_combination *iface_comb,
|
|
+ int n_iface_comb,
|
|
+ bool combined_radio)
|
|
{
|
|
const struct ieee80211_iface_combination *c;
|
|
int i, j;
|
|
|
|
- for (i = 0; i < wiphy->n_iface_combinations; i++) {
|
|
+ for (i = 0; i < n_iface_comb; i++) {
|
|
u32 cnt = 0;
|
|
u16 all_iftypes = 0;
|
|
|
|
- c = &wiphy->iface_combinations[i];
|
|
+ c = &iface_comb[i];
|
|
|
|
/*
|
|
* Combinations with just one interface aren't real,
|
|
@@ -621,9 +625,13 @@ static int wiphy_verify_combinations(str
|
|
if (WARN_ON(!c->num_different_channels))
|
|
return -EINVAL;
|
|
|
|
- /* DFS only works on one channel. */
|
|
- if (WARN_ON(c->radar_detect_widths &&
|
|
- (c->num_different_channels > 1)))
|
|
+ /* DFS only works on one channel. Avoid this check
|
|
+ * for multi-radio global combination, since it hold
|
|
+ * the capabilities of all radio combinations.
|
|
+ */
|
|
+ if (!combined_radio &&
|
|
+ WARN_ON(c->radar_detect_widths &&
|
|
+ c->num_different_channels > 1))
|
|
return -EINVAL;
|
|
|
|
if (WARN_ON(!c->n_limits))
|
|
@@ -644,13 +652,21 @@ static int wiphy_verify_combinations(str
|
|
if (WARN_ON(wiphy->software_iftypes & types))
|
|
return -EINVAL;
|
|
|
|
- /* Only a single P2P_DEVICE can be allowed */
|
|
- if (WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
|
|
+ /* Only a single P2P_DEVICE can be allowed, avoid this
|
|
+ * check for multi-radio global combination, since it
|
|
+ * hold the capabilities of all radio combinations.
|
|
+ */
|
|
+ if (!combined_radio &&
|
|
+ WARN_ON(types & BIT(NL80211_IFTYPE_P2P_DEVICE) &&
|
|
c->limits[j].max > 1))
|
|
return -EINVAL;
|
|
|
|
- /* Only a single NAN can be allowed */
|
|
- if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
|
|
+ /* Only a single NAN can be allowed, avoid this
|
|
+ * check for multi-radio global combination, since it
|
|
+ * hold the capabilities of all radio combinations.
|
|
+ */
|
|
+ if (!combined_radio &&
|
|
+ WARN_ON(types & BIT(NL80211_IFTYPE_NAN) &&
|
|
c->limits[j].max > 1))
|
|
return -EINVAL;
|
|
|
|
@@ -674,6 +690,34 @@ static int wiphy_verify_combinations(str
|
|
return 0;
|
|
}
|
|
|
|
+static int wiphy_verify_combinations(struct wiphy *wiphy)
|
|
+{
|
|
+ int i, ret;
|
|
+ bool combined_radio = false;
|
|
+
|
|
+ if (wiphy->n_radio) {
|
|
+ for (i = 0; i < wiphy->n_radio; i++) {
|
|
+ const struct wiphy_radio *radio = &wiphy->radio[i];
|
|
+
|
|
+ ret = wiphy_verify_iface_combinations(wiphy,
|
|
+ radio->iface_combinations,
|
|
+ radio->n_iface_combinations,
|
|
+ false);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ combined_radio = true;
|
|
+ }
|
|
+
|
|
+ ret = wiphy_verify_iface_combinations(wiphy,
|
|
+ wiphy->iface_combinations,
|
|
+ wiphy->n_iface_combinations,
|
|
+ combined_radio);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int wiphy_register(struct wiphy *wiphy)
|
|
{
|
|
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|