Commit a01b1e9f authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg

wifi: mac80211: add support for DFS with multiple radios

DFS can be supported with multi-channel combinations, as long as each DFS
capable radio only supports one channel.
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/4d27a4adca99fa832af1f7cda4f2e71016bd9fda.1720514221.git-series.nbd@nbd.nameSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 510dba80
...@@ -1091,6 +1091,27 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) ...@@ -1091,6 +1091,27 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
return 0; return 0;
} }
static bool
ieee80211_ifcomb_check(const struct ieee80211_iface_combination *c, int n_comb)
{
int i, j;
for (i = 0; i < n_comb; i++, c++) {
/* DFS is not supported with multi-channel combinations yet */
if (c->radar_detect_widths &&
c->num_different_channels > 1)
return false;
/* mac80211 doesn't support more than one IBSS interface */
for (j = 0; j < c->n_limits; j++)
if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) &&
c->limits[j].max > 1)
return false;
}
return true;
}
int ieee80211_register_hw(struct ieee80211_hw *hw) int ieee80211_register_hw(struct ieee80211_hw *hw)
{ {
struct ieee80211_local *local = hw_to_local(hw); struct ieee80211_local *local = hw_to_local(hw);
...@@ -1177,17 +1198,20 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) ...@@ -1177,17 +1198,20 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (comb->num_different_channels > 1) if (comb->num_different_channels > 1)
return -EINVAL; return -EINVAL;
} }
} else { }
/* DFS is not supported with multi-channel combinations yet */
for (i = 0; i < local->hw.wiphy->n_iface_combinations; i++) {
const struct ieee80211_iface_combination *comb;
comb = &local->hw.wiphy->iface_combinations[i]; if (hw->wiphy->n_radio) {
for (i = 0; i < hw->wiphy->n_radio; i++) {
const struct wiphy_radio *radio = &hw->wiphy->radio[i];
if (comb->radar_detect_widths && if (!ieee80211_ifcomb_check(radio->iface_combinations,
comb->num_different_channels > 1) radio->n_iface_combinations))
return -EINVAL; return -EINVAL;
} }
} else {
if (!ieee80211_ifcomb_check(hw->wiphy->iface_combinations,
hw->wiphy->n_iface_combinations))
return -EINVAL;
} }
/* Only HW csum features are currently compatible with mac80211 */ /* Only HW csum features are currently compatible with mac80211 */
...@@ -1317,18 +1341,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) ...@@ -1317,18 +1341,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR); hw->wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
/* mac80211 doesn't support more than one IBSS interface right now */
for (i = 0; i < hw->wiphy->n_iface_combinations; i++) {
const struct ieee80211_iface_combination *c;
int j;
c = &hw->wiphy->iface_combinations[i];
for (j = 0; j < c->n_limits; j++)
if ((c->limits[j].types & BIT(NL80211_IFTYPE_ADHOC)) &&
c->limits[j].max > 1)
return -EINVAL;
}
local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) +
sizeof(void *) * channels, GFP_KERNEL); sizeof(void *) * channels, GFP_KERNEL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment