From: Vasanthakumar Thiagarajan <quic_vthiagar@xxxxxxxxxxx> Move the interface combination limit check validation into a helper function. This will make the iface combination limit validation functionality more scalable for supporting multiple physical hardware interface combination. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00188-QCAHKSWPL_SILICONZ-1 Signed-off-by: Vasanthakumar Thiagarajan <quic_vthiagar@xxxxxxxxxxx> Co-developed-by: Karthikeyan Periyasamy <quic_periyasa@xxxxxxxxxxx> Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@xxxxxxxxxxx> --- net/wireless/core.c | 114 +++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/net/wireless/core.c b/net/wireless/core.c index 119937d0f2e0..2b810855a805 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -600,10 +600,69 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, } EXPORT_SYMBOL(wiphy_new_nm); +static int +wiphy_verify_comb_limit(struct wiphy *wiphy, + const struct ieee80211_iface_limit *limits, + u8 n_limits, u32 bcn_int_min_gcd, u32 *iface_cnt, + u16 *all_iftypes) +{ + int i; + + for (i = 0; i < n_limits; i++) { + u16 types = limits[i].types; + + /* Don't advertise an unsupported type + * in a combination. + */ + if (WARN_ON((wiphy->interface_modes & types) != types)) + return -EINVAL; + + if (WARN_ON(!limits[i].max)) + return -EINVAL; + + /* interface types shouldn't overlap */ + if (WARN_ON(types & *all_iftypes)) + return -EINVAL; + + *all_iftypes |= types; + + /* Shouldn't list software iftypes in combinations! */ + 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) && + limits[i].max > 1)) + return -EINVAL; + + /* Only a single NAN can be allowed */ + if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && + limits[i].max > 1)) + return -EINVAL; + + /* This isn't well-defined right now. If you have an + * IBSS interface, then its beacon interval may change + * by joining other networks, and nothing prevents it + * from doing that. + * So technically we probably shouldn't even allow AP + * and IBSS in the same interface, but it seems that + * some drivers support that, possibly only with fixed + * beacon intervals for IBSS. + */ + if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) && + bcn_int_min_gcd)) + return -EINVAL; + + *iface_cnt += limits[i].max; + } + + return 0; +} + static int wiphy_verify_combinations(struct wiphy *wiphy) { const struct ieee80211_iface_combination *c; - int i, j; + int i, ret; for (i = 0; i < wiphy->n_iface_combinations; i++) { u32 cnt = 0; @@ -630,54 +689,11 @@ static int wiphy_verify_combinations(struct wiphy *wiphy) if (WARN_ON(!c->n_limits)) return -EINVAL; - for (j = 0; j < c->n_limits; j++) { - u16 types = c->limits[j].types; - - /* interface types shouldn't overlap */ - if (WARN_ON(types & all_iftypes)) - return -EINVAL; - all_iftypes |= types; - - if (WARN_ON(!c->limits[j].max)) - return -EINVAL; - - /* Shouldn't list software iftypes in combinations! */ - 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) && - c->limits[j].max > 1)) - return -EINVAL; - - /* Only a single NAN can be allowed */ - if (WARN_ON(types & BIT(NL80211_IFTYPE_NAN) && - c->limits[j].max > 1)) - return -EINVAL; - - /* - * This isn't well-defined right now. If you have an - * IBSS interface, then its beacon interval may change - * by joining other networks, and nothing prevents it - * from doing that. - * So technically we probably shouldn't even allow AP - * and IBSS in the same interface, but it seems that - * some drivers support that, possibly only with fixed - * beacon intervals for IBSS. - */ - if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) && - c->beacon_int_min_gcd)) { - return -EINVAL; - } - - cnt += c->limits[j].max; - /* - * Don't advertise an unsupported type - * in a combination. - */ - if (WARN_ON((wiphy->interface_modes & types) != types)) - return -EINVAL; - } + ret = wiphy_verify_comb_limit(wiphy, c->limits, c->n_limits, + c->beacon_int_min_gcd, + &cnt, &all_iftypes); + if (ret) + return ret; if (WARN_ON(all_iftypes & BIT(NL80211_IFTYPE_WDS))) return -EINVAL; -- 2.34.1