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: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/4d27a4adca99fa832af1f7cda4f2e71016bd9fda.1720514221.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Felix Fietkau 2024-07-09 10:38:33 +02:00 committed by Johannes Berg
parent 510dba80ed
commit a01b1e9f99

View File

@ -1091,6 +1091,27 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local)
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)
{
struct ieee80211_local *local = hw_to_local(hw);
@ -1177,17 +1198,20 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
if (comb->num_different_channels > 1)
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 &&
comb->num_different_channels > 1)
if (!ieee80211_ifcomb_check(radio->iface_combinations,
radio->n_iface_combinations))
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 */
@ -1317,18 +1341,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
hw->wiphy->interface_modes |= 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) +
sizeof(void *) * channels, GFP_KERNEL);