From patchwork Tue Jul 2 11:35:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 809318 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 63CF1153BE3 for ; Tue, 2 Jul 2024 11:36:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920172; cv=none; b=D4kDmle/J95vqyr/Igj/8iYBjJwzOPeKt7TUk6Pj/HeU0zpS97AK+eI1smKZEzcM2EBqGehMToqfj+JIFBZaTWy38A9+TKCxilnPInYHoKr5tM/Q+Zja+q8Yb2GSkBgfq5Tt6g1vBeEiS6C7UFxDCRzeFPU9aDJD5RivH1aH8RY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920172; c=relaxed/simple; bh=fzDix0avtTN+uvsT9f/yZJnVVcf4wyTqjnbc8eusqfY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sx0TBnjD338Lb+U7L4Jvkup/FrmyzdfnnthXgA4vouPRl4mNAgHmjSs8/Wey8TgR3VoWTnXOl+0zPWjn8NJHphFHEdmvqBkXVKiUiUKEur3auwNK+QFvRIppgj6fO/EQu+L2+A19vrexY0z3AT4KYH0RS0zrOkQo9zNEzHl2d9c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=qmOF1zQM; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="qmOF1zQM" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=4XJgwF6KjTKdAyuXkBxu+59gxtF/+5/4ZMJrvPcYeHM=; b=qmOF1zQMc5W6tbNsdBhbi2P8Z7 cVwpl1RRF90sn7jOrN7XphWbt4v6FXOaOIms2U6ib9xaJD+wq9Zc2rO27/00BnLBHj85Q3Tpv0Nvo mERrlHOy2ozN6Gviek4T4rThqFrKW43fQXot7XG0ImM0A3IxCEVAekEmiBddskARPMVU=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObnq-001lDm-2k; Tue, 02 Jul 2024 13:36:06 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 01/10] wifi: nl80211: split helper function from nl80211_put_iface_combinations Date: Tue, 2 Jul 2024 13:35:56 +0200 Message-ID: <22a0eee19dbcf98627239328bc66decd3395122c.1719919832.git-series.nbd@nbd.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Create a helper function that puts the data from struct ieee80211_iface_combination to a nl80211 message. This will be used for adding per-radio interface combination data. Signed-off-by: Felix Fietkau --- net/wireless/nl80211.c | 111 ++++++++++++++++++++++-------------------- 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 674368d028f3..deacd5f3f256 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1631,71 +1631,78 @@ static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes) return -ENOBUFS; } -static int nl80211_put_iface_combinations(struct wiphy *wiphy, - struct sk_buff *msg, - bool large) +static int nl80211_put_ifcomb_data(struct sk_buff *msg, bool large, int idx, + const struct ieee80211_iface_combination *c) { - struct nlattr *nl_combis; - int i, j; + struct nlattr *nl_combi, *nl_limits; + int i; - nl_combis = nla_nest_start_noflag(msg, - NL80211_ATTR_INTERFACE_COMBINATIONS); - if (!nl_combis) + nl_combi = nla_nest_start_noflag(msg, idx); + if (!nl_combi) goto nla_put_failure; - for (i = 0; i < wiphy->n_iface_combinations; i++) { - const struct ieee80211_iface_combination *c; - struct nlattr *nl_combi, *nl_limits; + nl_limits = nla_nest_start_noflag(msg, NL80211_IFACE_COMB_LIMITS); + if (!nl_limits) + goto nla_put_failure; - c = &wiphy->iface_combinations[i]; + for (i = 0; i < c->n_limits; i++) { + struct nlattr *nl_limit; - nl_combi = nla_nest_start_noflag(msg, i + 1); - if (!nl_combi) + nl_limit = nla_nest_start_noflag(msg, i + 1); + if (!nl_limit) goto nla_put_failure; - - nl_limits = nla_nest_start_noflag(msg, - NL80211_IFACE_COMB_LIMITS); - if (!nl_limits) + if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX, c->limits[i].max)) goto nla_put_failure; + if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES, + c->limits[i].types)) + goto nla_put_failure; + nla_nest_end(msg, nl_limit); + } - for (j = 0; j < c->n_limits; j++) { - struct nlattr *nl_limit; + nla_nest_end(msg, nl_limits); - nl_limit = nla_nest_start_noflag(msg, j + 1); - if (!nl_limit) - goto nla_put_failure; - if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX, - c->limits[j].max)) - goto nla_put_failure; - if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES, - c->limits[j].types)) - goto nla_put_failure; - nla_nest_end(msg, nl_limit); - } + if (c->beacon_int_infra_match && + nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH)) + goto nla_put_failure; + if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS, + c->num_different_channels) || + nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, + c->max_interfaces)) + goto nla_put_failure; + if (large && + (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, + c->radar_detect_widths) || + nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, + c->radar_detect_regions))) + goto nla_put_failure; + if (c->beacon_int_min_gcd && + nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD, + c->beacon_int_min_gcd)) + goto nla_put_failure; - nla_nest_end(msg, nl_limits); + nla_nest_end(msg, nl_combi); - if (c->beacon_int_infra_match && - nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH)) - goto nla_put_failure; - if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS, - c->num_different_channels) || - nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, - c->max_interfaces)) - goto nla_put_failure; - if (large && - (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, - c->radar_detect_widths) || - nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, - c->radar_detect_regions))) - goto nla_put_failure; - if (c->beacon_int_min_gcd && - nla_put_u32(msg, NL80211_IFACE_COMB_BI_MIN_GCD, - c->beacon_int_min_gcd)) - goto nla_put_failure; + return 0; +nla_put_failure: + return -ENOBUFS; +} - nla_nest_end(msg, nl_combi); - } +static int nl80211_put_iface_combinations(struct wiphy *wiphy, + struct sk_buff *msg, + bool large) +{ + struct nlattr *nl_combis; + int i; + + nl_combis = nla_nest_start_noflag(msg, + NL80211_ATTR_INTERFACE_COMBINATIONS); + if (!nl_combis) + goto nla_put_failure; + + for (i = 0; i < wiphy->n_iface_combinations; i++) + if (nl80211_put_ifcomb_data(msg, large, i + 1, + &wiphy->iface_combinations[i])) + goto nla_put_failure; nla_nest_end(msg, nl_combis); From patchwork Tue Jul 2 11:35:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 809317 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A4654157A47 for ; Tue, 2 Jul 2024 11:36:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920173; cv=none; b=Xak/9PnASC5T6xDsQTFjroKYUrEFwqP0BqSQIr5AJarjQd4bVGxyxwp1NhtGEIR3Eek9i6jxZ7QZ7WELAYzG1plO6aWx5jyMcFWVIUtUhmlkRgTDyiL2dbHz7aP1fPAddm9r1+M6xhLaOd30dSph8TdKxGKhtSX1J0yrB7dbSDY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920173; c=relaxed/simple; bh=GONkUTb4p0/sCI4mm6Nh8FY/gnQBngVh5tQuhPKlDIE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gnDZI+zQCd/ie7u01KlXIog/YVwHS0Pv8wVZIGHT2gQkGnqsOfjEFuX0zrbh5fH4HydaqwXmS29vYGXbGVuUchsQyfYn8JgjHxXYX/kXRLGxPB35hmUwzoR2ZPkkfU7WBmtSRqjT6XlZCapuFwW32I4Ql1H776POr0PI+lK9Prs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=rGgPK8KR; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="rGgPK8KR" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=rgXtAVij848Qw3gMF4uPtcbDP8WupjAUKFLmG7Dzq5I=; b=rGgPK8KRoznC7DXzoS/fxUUWdf 7A52hmblQVgAN+0dZgWk8sVPX2f1NerBCTm5lJQSCkjpsR3sQmyEbZ+t672+h+2dMu+AGolTWlNvw kubXN1PPoV7Xop2cEAnPNsSiWJ8fekx1gvIJk8eOHVsBpztKTEIL7of85Co+NEzxNdfw=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObnr-001lDm-0I; Tue, 02 Jul 2024 13:36:07 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 02/10] wifi: cfg80211: add support for advertising multiple radios belonging to a wiphy Date: Tue, 2 Jul 2024 13:35:57 +0200 Message-ID: <97c7167b0e753b85d942fc77ecd020eb4d5b1c36.1719919832.git-series.nbd@nbd.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 The prerequisite for MLO support in cfg80211/mac80211 is that all the links participating in MLO must be from the same wiphy/ieee80211_hw. To meet this expectation, some drivers may need to group multiple discrete hardware each acting as a link in MLO under single wiphy. With this change, supported frequencies and interface combinations of each individual radio are reported to user space. This allows user space to figure out the limitations of what combination of channels can be used concurrently. Even for non-MLO devices, this improves support for devices capable of running on multiple channels at the same time. Signed-off-by: Felix Fietkau --- include/net/cfg80211.h | 42 ++++++++++++- include/uapi/linux/nl80211.h | 65 +++++++++++++++++++++- net/wireless/nl80211.c | 113 ++++++++++++++++++++++++++++++++---- 3 files changed, 208 insertions(+), 12 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6f992aff74ae..a00cf80e61dc 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5046,7 +5046,9 @@ struct ieee80211_iface_limit { * struct ieee80211_iface_combination - possible interface combination * * With this structure the driver can describe which interface - * combinations it supports concurrently. + * combinations it supports concurrently. When set in a struct wiphy_radio, + * the combinations refer to combinations of interfaces currently active on + * that radio. * * Examples: * @@ -5406,6 +5408,38 @@ struct wiphy_iftype_akm_suites { int n_akm_suites; }; +/** + * struct wiphy_radio_freq_range - wiphy frequency range + * @start_freq: start range edge frequency (kHz) + * @end_freq: end range edge frequency (kHz) + */ +struct wiphy_radio_freq_range { + u32 start_freq; + u32 end_freq; +}; + + +/** + * struct wiphy_radio - physical radio of a wiphy + * This structure describes a physical radio belonging to a wiphy. + * It is used to describe concurrent-channel capabilities. Only one channel + * can be active on the radio described by struct wiphy_radio. + * + * @freq_range: frequency range that the radio can operate on. + * @n_freq_range: number of elements in @freq_range + * + * @iface_combinations: Valid interface combinations array, should not + * list single interface types. + * @n_iface_combinations: number of entries in @iface_combinations array. + */ +struct wiphy_radio { + const struct wiphy_radio_freq_range *freq_range; + int n_freq_range; + + const struct ieee80211_iface_combination *iface_combinations; + int n_iface_combinations; +}; + #define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff /** @@ -5624,6 +5658,9 @@ struct wiphy_iftype_akm_suites { * A value of %CFG80211_HW_TIMESTAMP_ALL_PEERS indicates the driver * supports enabling HW timestamping for all peers (i.e. no need to * specify a mac address). + * + * @radio: radios belonging to this wiphy + * @n_radio: number of radios */ struct wiphy { struct mutex mtx; @@ -5774,6 +5811,9 @@ struct wiphy { u16 hw_timestamp_max_peers; + int n_radio; + const struct wiphy_radio *radio; + char priv[] __aligned(NETDEV_ALIGN); }; diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 6ae3997061b6..f97f5adc8d51 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2052,6 +2052,10 @@ enum nl80211_commands { * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported * interface combinations. In each nested item, it contains attributes * defined in &enum nl80211_if_combination_attrs. + * If the wiphy uses multiple radios (@NL80211_ATTR_WIPHY_RADIOS is set), + * this attribute contains the interface combinations of the first radio. + * See @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS for the global wiphy + * combinations for the sum of all radios. * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that * are managed in software: interfaces of these types aren't subject to @@ -2856,6 +2860,14 @@ enum nl80211_commands { * %NL80211_CMD_ASSOCIATE indicating the SPP A-MSDUs * are used on this connection * + * @NL80211_ATTR_WIPHY_RADIOS: Nested attribute describing physical radios + * belonging to this wiphy. See &enum nl80211_wiphy_radio_attrs. + * + * @NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS: Nested attribute listing the + * supported interface combinations for all radios combined. In each + * nested item, it contains attributes defined in + * &enum nl80211_if_combination_attrs. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3401,6 +3413,9 @@ enum nl80211_attrs { NL80211_ATTR_ASSOC_SPP_AMSDU, + NL80211_ATTR_WIPHY_RADIOS, + NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -8005,4 +8020,54 @@ enum nl80211_ap_settings_flags { NL80211_AP_SETTINGS_SA_QUERY_OFFLOAD_SUPPORT = 1 << 1, }; +/** + * enum nl80211_wiphy_radio_attrs - wiphy radio attributes + * + * @__NL80211_WIPHY_RADIO_ATTR_INVALID: Invalid + * + * @NL80211_WIPHY_RADIO_ATTR_INDEX: Index of this radio (u32) + * @NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE: Frequency range supported by this + * radio. Attribute may be present multiple times. + * @NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION: Supported interface + * combination for this radio. Attribute may be present multiple times + * and contains attributes defined in &enum nl80211_if_combination_attrs. + * + * @__NL80211_WIPHY_RADIO_ATTR_LAST: Internal + * @NL80211_WIPHY_RADIO_ATTR_MAX: Highest attribute + */ +enum nl80211_wiphy_radio_attrs { + __NL80211_WIPHY_RADIO_ATTR_INVALID, + + NL80211_WIPHY_RADIO_ATTR_INDEX, + NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE, + NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION, + + /* keep last */ + __NL80211_WIPHY_RADIO_ATTR_LAST, + NL80211_WIPHY_RADIO_ATTR_MAX = __NL80211_WIPHY_RADIO_ATTR_LAST - 1, +}; + +/** + * enum nl80211_wiphy_radio_freq_range - wiphy radio frequency range + * + * @__NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID: Invalid + * + * @NL80211_WIPHY_RADIO_FREQ_ATTR_START: Frequency range start (u32). + * The unit is kHz. + * @NL80211_WIPHY_RADIO_FREQ_ATTR_END: Frequency range end (u32). + * The unit is kHz. + * + * @__NL80211_WIPHY_RADIO_FREQ_ATTR_LAST: Internal + * @NL80211_WIPHY_RADIO_FREQ_ATTR_MAX: Highest attribute + */ +enum nl80211_wiphy_radio_freq_range { + __NL80211_WIPHY_RADIO_FREQ_ATTR_INVALID, + + NL80211_WIPHY_RADIO_FREQ_ATTR_START, + NL80211_WIPHY_RADIO_FREQ_ATTR_END, + + __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST, + NL80211_WIPHY_RADIO_FREQ_ATTR_MAX = __NL80211_WIPHY_RADIO_FREQ_ATTR_LAST - 1, +}; + #endif /* __LINUX_NL80211_H */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index deacd5f3f256..7397a372c78e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1632,16 +1632,18 @@ static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes) } static int nl80211_put_ifcomb_data(struct sk_buff *msg, bool large, int idx, - const struct ieee80211_iface_combination *c) + const struct ieee80211_iface_combination *c, + u16 nested) { struct nlattr *nl_combi, *nl_limits; int i; - nl_combi = nla_nest_start_noflag(msg, idx); + nl_combi = nla_nest_start_noflag(msg, idx | nested); if (!nl_combi) goto nla_put_failure; - nl_limits = nla_nest_start_noflag(msg, NL80211_IFACE_COMB_LIMITS); + nl_limits = nla_nest_start_noflag(msg, NL80211_IFACE_COMB_LIMITS | + nested); if (!nl_limits) goto nla_put_failure; @@ -1689,19 +1691,26 @@ static int nl80211_put_ifcomb_data(struct sk_buff *msg, bool large, int idx, static int nl80211_put_iface_combinations(struct wiphy *wiphy, struct sk_buff *msg, - bool large) + int attr, int radio, + bool large, u16 nested) { + const struct ieee80211_iface_combination *c; struct nlattr *nl_combis; - int i; + int i, n; - nl_combis = nla_nest_start_noflag(msg, - NL80211_ATTR_INTERFACE_COMBINATIONS); + nl_combis = nla_nest_start_noflag(msg, attr | nested); if (!nl_combis) goto nla_put_failure; - for (i = 0; i < wiphy->n_iface_combinations; i++) - if (nl80211_put_ifcomb_data(msg, large, i + 1, - &wiphy->iface_combinations[i])) + if (radio >= 0) { + c = wiphy->radio[0].iface_combinations; + n = wiphy->radio[0].n_iface_combinations; + } else { + c = wiphy->iface_combinations; + n = wiphy->n_iface_combinations; + } + for (i = 0; i < n; i++) + if (nl80211_put_ifcomb_data(msg, large, i + 1, &c[i], nested)) goto nla_put_failure; nla_nest_end(msg, nl_combis); @@ -2408,6 +2417,80 @@ static int nl80211_put_mbssid_support(struct wiphy *wiphy, struct sk_buff *msg) return -ENOBUFS; } +static int nl80211_put_radio(struct wiphy *wiphy, struct sk_buff *msg, int idx) +{ + const struct wiphy_radio *r = &wiphy->radio[idx]; + struct nlattr *radio, *freq; + int i; + + radio = nla_nest_start(msg, idx); + if (!radio) + return -ENOBUFS; + + if (nla_put_u32(msg, NL80211_WIPHY_RADIO_ATTR_INDEX, idx)) + goto nla_put_failure; + + for (i = 0; i < r->n_freq_range; i++) { + const struct wiphy_radio_freq_range *range = &r->freq_range[i]; + + freq = nla_nest_start(msg, NL80211_WIPHY_RADIO_ATTR_FREQ_RANGE); + if (!freq) + goto nla_put_failure; + + if (nla_put_u32(msg, NL80211_WIPHY_RADIO_FREQ_ATTR_START, + range->start_freq) || + nla_put_u32(msg, NL80211_WIPHY_RADIO_FREQ_ATTR_END, + range->end_freq)) + goto nla_put_failure; + + nla_nest_end(msg, freq); + } + + for (i = 0; i < r->n_iface_combinations; i++) + if (nl80211_put_ifcomb_data(msg, true, + NL80211_WIPHY_RADIO_ATTR_INTERFACE_COMBINATION, + &r->iface_combinations[i], + NLA_F_NESTED)) + goto nla_put_failure; + + nla_nest_end(msg, radio); + + return 0; + +nla_put_failure: + return -ENOBUFS; +} + +static int nl80211_put_radios(struct wiphy *wiphy, struct sk_buff *msg) +{ + struct nlattr *radios; + int i; + + if (!wiphy->n_radio) + return 0; + + radios = nla_nest_start(msg, NL80211_ATTR_WIPHY_RADIOS); + if (!radios) + return -ENOBUFS; + + for (i = 0; i < wiphy->n_radio; i++) + if (nl80211_put_radio(wiphy, msg, i)) + goto fail; + + nla_nest_end(msg, radios); + + if (nl80211_put_iface_combinations(wiphy, msg, + NL80211_ATTR_WIPHY_INTERFACE_COMBINATIONS, + -1, true, NLA_F_NESTED)) + return -ENOBUFS; + + return 0; + +fail: + nla_nest_cancel(msg, radios); + return -ENOBUFS; +} + struct nl80211_dump_wiphy_state { s64 filter_wiphy; long start; @@ -2703,7 +2786,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, goto nla_put_failure; if (nl80211_put_iface_combinations(&rdev->wiphy, msg, - state->split)) + NL80211_ATTR_INTERFACE_COMBINATIONS, + rdev->wiphy.n_radio ? 0 : -1, + state->split, 0)) goto nla_put_failure; state->split_start++; @@ -3017,6 +3102,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, rdev->wiphy.hw_timestamp_max_peers)) goto nla_put_failure; + state->split_start++; + break; + case 17: + if (nl80211_put_radios(&rdev->wiphy, msg)) + goto nla_put_failure; + /* done */ state->split_start = 0; break; From patchwork Tue Jul 2 11:35:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 810333 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0918D158DC0 for ; Tue, 2 Jul 2024 11:36:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920173; cv=none; b=SCIlAOBkgAigD3nXBINMHgC8fqv7x8mgxhwWgDlflFTwqE+G/VjZzuNCWaoDR90o0y5Qnin3ugtWvxCuO3WxkBU1gZBwW2/wZYzYGuV/QUYyZSlEIAnWcu8l7Yo2SD0O85JGXLE1eERQc1M/+bBncECCFY8xZDeLTQczTMxmCvo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920173; c=relaxed/simple; bh=Mn2u7rdb++QJb1/dTo+5xW4IepGy9OTx7f/7/K5g79A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NCC/ib1Po7Z0q0LDETNkseCY457czeKjfNumE6l7DPqGdo4gvPl5/zXPsNfWScyYc4q4otsOoSl/806g97OdrfdFxg9we4F9vEYkWDriyb3CTz/SPbwenVggI4VHPYVnAFdXTaKf+UJu8iVppYaRrQnT8lmawXJo+1KiEU3PoJg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=SG/IgfiI; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="SG/IgfiI" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Frr/krjwbcumBgn8YBFd01TMLQJi2FyszxaFfpa1NhM=; b=SG/IgfiIE6TMMlSI3MqssZJ/4S +AiC8paBpRTeYOa1lu296pR/7nKrG/njZbbWF8j044B9gXp7IBVb9qOZJi9VwakqvZn7YfjO6aE8V GwxoC0SU3xsNNx2jVUUQ2BvamupHPg6YYv7DBRHPXMdxRi0d3/cnN7v4PkIoyO4pC7GY=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObnr-001lDm-17; Tue, 02 Jul 2024 13:36:07 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 03/10] wifi: cfg80211: extend interface combination check for multi-radio Date: Tue, 2 Jul 2024 13:35:58 +0200 Message-ID: X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add a field in struct iface_combination_params to check per-radio interface combinations instead of per-wiphy ones. Signed-off-by: Felix Fietkau --- include/net/cfg80211.h | 5 +++++ net/mac80211/util.c | 5 ++++- net/wireless/rdev-ops.h | 12 ++++++++++++ net/wireless/util.c | 33 ++++++++++++++++++++++++++------- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a00cf80e61dc..4767e2c76b01 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1598,6 +1598,7 @@ struct cfg80211_color_change_settings { * * Used to pass interface combination parameters * + * @radio_idx: wiphy radio index or -1 for global * @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 @@ -1611,6 +1612,7 @@ struct cfg80211_color_change_settings { * the verification */ struct iface_combination_params { + int radio_idx; int num_different_channels; u8 radar_detect; int iftype_num[NUM_NL80211_IFTYPES]; @@ -4580,6 +4582,8 @@ struct mgmt_frame_regs { * * @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames. * @set_ttlm: set the TID to link mapping. + * @get_radio_mask: get bitmask of radios in use. + * (invoked with the wiphy mutex held) */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -4941,6 +4945,7 @@ struct cfg80211_ops { struct cfg80211_set_hw_timestamp *hwts); int (*set_ttlm)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ttlm_params *params); + u32 (*get_radio_mask)(struct wiphy *wiphy, struct net_device *dev); }; /* diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c6d5f73119d8..27f0db2e9796 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3944,6 +3944,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, int total = 1; struct iface_combination_params params = { .radar_detect = radar_detect, + .radio_idx = -1, }; lockdep_assert_wiphy(local->hw.wiphy); @@ -4034,7 +4035,9 @@ int ieee80211_max_num_channels(struct ieee80211_local *local) struct ieee80211_chanctx *ctx; u32 max_num_different_channels = 1; int err; - struct iface_combination_params params = {0}; + struct iface_combination_params params = { + .radio_idx = -1, + }; lockdep_assert_wiphy(local->hw.wiphy); diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 8f15658002ee..ec3f4aa1c807 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h @@ -1532,4 +1532,16 @@ rdev_set_ttlm(struct cfg80211_registered_device *rdev, return ret; } + +static inline u32 +rdev_get_radio_mask(struct cfg80211_registered_device *rdev, + struct net_device *dev) +{ + struct wiphy *wiphy = &rdev->wiphy; + + if (!rdev->ops->get_radio_mask) + return 0; + + return rdev->ops->get_radio_mask(wiphy, dev); +} #endif /* __CFG80211_RDEV_OPS */ diff --git a/net/wireless/util.c b/net/wireless/util.c index af6ec719567f..2492f259621f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -2307,13 +2307,16 @@ static int cfg80211_wdev_bi(struct wireless_dev *wdev) static void cfg80211_calculate_bi_data(struct wiphy *wiphy, u32 new_beacon_int, u32 *beacon_int_gcd, - bool *beacon_int_different) + bool *beacon_int_different, + int radio_idx) { + struct cfg80211_registered_device *rdev; struct wireless_dev *wdev; *beacon_int_gcd = 0; *beacon_int_different = false; + rdev = wiphy_to_rdev(wiphy); list_for_each_entry(wdev, &wiphy->wdev_list, list) { int wdev_bi; @@ -2321,6 +2324,11 @@ static void cfg80211_calculate_bi_data(struct wiphy *wiphy, u32 new_beacon_int, if (wdev->valid_links) continue; + /* skip wdevs not active on the given wiphy radio */ + if (radio_idx >= 0 && + !(rdev_get_radio_mask(rdev, wdev->netdev) & BIT(radio_idx))) + continue; + wdev_bi = cfg80211_wdev_bi(wdev); if (!wdev_bi) @@ -2368,14 +2376,19 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, void *data), void *data) { + const struct wiphy_radio *radio = NULL; + const struct ieee80211_iface_combination *c, *cs; const struct ieee80211_regdomain *regdom; enum nl80211_dfs_regions region = 0; - int i, j, iftype; + int i, j, n, iftype; int num_interfaces = 0; u32 used_iftypes = 0; u32 beacon_int_gcd; bool beacon_int_different; + if (params->radio_idx >= 0) + radio = &wiphy->radio[params->radio_idx]; + /* * This is a bit strange, since the iteration used to rely only on * the data given by the driver, but here it now relies on context, @@ -2387,7 +2400,8 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, * interfaces (while being brought up) and channel/radar data. */ cfg80211_calculate_bi_data(wiphy, params->new_beacon_int, - &beacon_int_gcd, &beacon_int_different); + &beacon_int_gcd, &beacon_int_different, + params->radio_idx); if (params->radar_detect) { rcu_read_lock(); @@ -2404,13 +2418,18 @@ int cfg80211_iter_combinations(struct wiphy *wiphy, used_iftypes |= BIT(iftype); } - for (i = 0; i < wiphy->n_iface_combinations; i++) { - const struct ieee80211_iface_combination *c; + if (radio) { + cs = radio->iface_combinations; + n = radio->n_iface_combinations; + } else { + cs = wiphy->iface_combinations; + n = wiphy->n_iface_combinations; + } + for (i = 0; i < n; i++) { struct ieee80211_iface_limit *limits; u32 all_iftypes = 0; - c = &wiphy->iface_combinations[i]; - + c = &cs[i]; if (num_interfaces > c->max_interfaces) continue; if (params->num_different_channels > c->num_different_channels) From patchwork Tue Jul 2 11:35:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 810337 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A46A3158D98 for ; Tue, 2 Jul 2024 11:36:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; cv=none; b=aF0fIxEBbnvhIJi0aB9Gyr2x5/GDKU5ukJutaoh97NXi17b/IHiB9l+Vuj6yGfiVf6JnzVwZKWveAlLDmxjU8SGcBO4vcFoFO2jZ3SYOAadWgORaTd/2c8iZNzrl8dHJsf/AztHDGsGkZ6zHoL+6D7nffIj5J7q9H6gjuiWNduA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; c=relaxed/simple; bh=4qM7MDn6eYZpCd2hlyPZ0hPh3y/u6kcsPd1PAqv2TSg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BBBHsERu6kk0Ag+NIJI5d6Y9T++WKfJyLHsJZgjhfcx+ITZeyQiFF163lBzy4A2CcRTv3XXruy4CPIXIpRtJTSTVwFPrJVBaOYPb8aQoRsUtHR8UeV3z0zHmk2RHXLnfpgIhVKByXTLtx2Qzo4gqZOIUcoNHTgvh0DHb0kmHBdQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=fj1A6Mqg; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="fj1A6Mqg" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=OVOtZ0ZXML16TWb4NK4o5kmz91UtChMetMgVLn+f9Ns=; b=fj1A6Mqgg2Ce5j+rhiCWweJmEA d6HmxzdLXo951iIPP9nrtgHxpAPJqWmM8jKV6tngpVvkCk/AdkrlNBIJ+RDfankv/mAJLiMKxuokj mvc3tQ+kIPp6ZN45TTAHMeT7x1qCGKIwvZ608Q0fyJ9Jhd4LCr5fj7MXYdUAvldtfruA=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObnr-001lDm-21; Tue, 02 Jul 2024 13:36:07 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 04/10] wifi: cfg80211: add helper for checking if a chandef is valid on a radio Date: Tue, 2 Jul 2024 13:35:59 +0200 Message-ID: X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Check if the full channel width is in the radio's frequency range. Signed-off-by: Felix Fietkau --- include/net/cfg80211.h | 9 +++++++++ net/wireless/util.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 4767e2c76b01..75c5798a0646 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -6509,6 +6509,15 @@ static inline bool cfg80211_channel_is_psc(struct ieee80211_channel *chan) } /** + * cfg80211_radio_chandef_valid - Check if the radio supports the chandef + * + * @radio: wiphy radio + * @chandef: chandef for current channel + */ +bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio, + const struct cfg80211_chan_def *chandef); + +/** * ieee80211_get_response_rate - get basic rate for a given rate * * @sband: the band to look for rates in diff --git a/net/wireless/util.c b/net/wireless/util.c index 2492f259621f..9a7c3adc8a3b 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -2886,3 +2886,38 @@ cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype type) return NULL; } EXPORT_SYMBOL(cfg80211_get_iftype_ext_capa); + +static bool +ieee80211_radio_freq_range_valid(const struct wiphy_radio *radio, + u32 freq, u32 width) +{ + const struct wiphy_radio_freq_range *r; + int i; + + for (i = 0; i < radio->n_freq_range; i++) { + r = &radio->freq_range[i]; + if (freq - width / 2 >= r->start_freq && + freq + width / 2 <= r->end_freq) + return true; + } + + return false; +} + +bool cfg80211_radio_chandef_valid(const struct wiphy_radio *radio, + const struct cfg80211_chan_def *chandef) +{ + u32 freq, width; + + freq = ieee80211_chandef_to_khz(chandef); + width = nl80211_chan_width_to_mhz(chandef->width); + if (!ieee80211_radio_freq_range_valid(radio, freq, width)) + return false; + + freq = MHZ_TO_KHZ(chandef->center_freq2); + if (freq && !ieee80211_radio_freq_range_valid(radio, freq, width)) + return false; + + return true; +} +EXPORT_SYMBOL(cfg80211_radio_chandef_valid); From patchwork Tue Jul 2 11:36:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 809319 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4185A15B104 for ; Tue, 2 Jul 2024 11:36:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; cv=none; b=Uob/XDdq0rHNOzkjzBspaX+Nvh9rAl7bLvssgn+NKHwEej5nWbQubNBWcXGBonDn0Eg7wMA5zAAoC8NuuPYrMqhb2fNntK/XBs8nDOvV11js0wmw+Z+M5rrYO4KhsQw6YCVuE0Q/xNjhKQkYAlpAN6K0Fq21mJf2Mtq5pyto4c0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; c=relaxed/simple; bh=R5AeBIfYIcz+l5FSqDqfI9uMGsZlLa3sOz0McrICTRk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kTEmVoOMYebuenHMnqPjc91SUgjQLXn4C62+BthLTa9zqcLAfsR7o0rB+8olR3IfkCqOMbAHhSGGAIlNAtSMJr18oT0aWNM6+tOZLyHaHaypX5zAN2B0BMHUbGrOdzxUp65Eb2O8xIaFXZWu+DzC/U6uSY+KpGiawKHBRpsxXrs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=q7wo4tEs; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="q7wo4tEs" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=jP2Eybihza/RBgEQCv9/PsS0Cokn008GYzz9X6AIvjI=; b=q7wo4tEshVgj7DESAaO0SDeL8w DzH25pEkG7SM9AD6NCXfBxZ2LJN5nA0ry0q1DUbWXgBj1Pih0GCeYw0A5Wig6jWUQqxO38Hkijkd6 c1t41z7q8lTjeKpYVw1F2aAnwbGfaUmLdhJDX6xBtpf7MmoLNrbEXPOXV1hhcnVaF684=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObnr-001lDm-2n; Tue, 02 Jul 2024 13:36:07 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 05/10] wifi: mac80211: add support for DFS with multiple radios Date: Tue, 2 Jul 2024 13:36:00 +0200 Message-ID: X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 DFS can be supported with multi-channel combinations, as long as each DFS capable radio only supports one channel. Signed-off-by: Felix Fietkau --- net/mac80211/main.c | 50 ++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 7578ea56c12f..4acfb17cf626 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -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); From patchwork Tue Jul 2 11:36:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 809320 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 417E715B102 for ; Tue, 2 Jul 2024 11:36:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; cv=none; b=cWiAcLAnbzjI8GAGrG9G7ryD3+ui5URpsWZ2n8yKQdMHypVcjqqd/3tYrmdR/RNuYlhYhFs3ov4eNvdKpptNufbe6hLujjob27OlDdL1rr23ZgjuybOXp68KEZsBQx5Oqd+HFOtOlmb95xDgxqnrXmG9iPuuwBsaxFyFohKz16w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; c=relaxed/simple; bh=cTgimfrWshSaIicjkqCEGFHqZbRJ6FxTuzES2KJI+uI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ozuW5HJi0z5msBFMotaUTvpsMUHo3DwScbOgKzrvM7FKus4e9YFzhej5I8Wz5mxt1kxysiPGYqLX1FmqtiEY3YQDbZ/SbPtagWpoOZMAEACPHa4B7nWu6sdVO8odXdMPM9ysuToeouW0OZfVQuMlpvoey8UkrhRCbXrmzTOtki4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=YHKxGnds; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="YHKxGnds" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Tojz4OudxD5DBp2PA2+KRIAkcR1dJrFxmA0POn6n400=; b=YHKxGndsGJBYLewbAzNG5NU7nZ 4bqi++7t1KKgPMN+rqsDkAnyabbJxS9GkQUeGEh+h0R8z2af0OWCO0lWihrOc213ygtfMX28GAjvH U8fuHEBE1qn4NIdgj7Xq30MXej4DsQDro+4JXIAulrbBkZ9YbFqcGSOpKWtWlZyFWZpI=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObns-001lDm-0L; Tue, 02 Jul 2024 13:36:08 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 06/10] wifi: mac80211: add radio index to ieee80211_chanctx_conf Date: Tue, 2 Jul 2024 13:36:01 +0200 Message-ID: <0efa0f464e4324f5b0361095a77ff393dbf1498b.1719919832.git-series.nbd@nbd.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Will be used to explicitly assign a channel context to a wiphy radio. Signed-off-by: Felix Fietkau --- include/net/mac80211.h | 2 ++ net/mac80211/chan.c | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index bd0f8aefa797..e78ccbe38d6d 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -250,6 +250,7 @@ struct ieee80211_chan_req { * @min_def: the minimum channel definition currently required. * @ap: the channel definition the AP actually is operating as, * for use with (wider bandwidth) OFDMA + * @radio_idx: index of the wiphy radio used used for this channel * @rx_chains_static: The number of RX chains that must always be * active on the channel to receive MIMO transmissions * @rx_chains_dynamic: The number of RX chains that must be enabled @@ -264,6 +265,7 @@ struct ieee80211_chanctx_conf { struct cfg80211_chan_def min_def; struct cfg80211_chan_def ap; + int radio_idx; u8 rx_chains_static, rx_chains_dynamic; bool radar_enabled; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 06a65dc6f6c6..6c4d02cb07bb 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -656,7 +656,8 @@ ieee80211_chanctx_radar_required(struct ieee80211_local *local, static struct ieee80211_chanctx * ieee80211_alloc_chanctx(struct ieee80211_local *local, const struct ieee80211_chan_req *chanreq, - enum ieee80211_chanctx_mode mode) + enum ieee80211_chanctx_mode mode, + int radio_idx) { struct ieee80211_chanctx *ctx; @@ -674,6 +675,7 @@ ieee80211_alloc_chanctx(struct ieee80211_local *local, ctx->conf.rx_chains_dynamic = 1; ctx->mode = mode; ctx->conf.radar_enabled = false; + ctx->conf.radio_idx = radio_idx; _ieee80211_recalc_chanctx_min_def(local, ctx, NULL, false); return ctx; @@ -714,7 +716,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, lockdep_assert_wiphy(local->hw.wiphy); - ctx = ieee80211_alloc_chanctx(local, chanreq, mode); + ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1); if (!ctx) return ERR_PTR(-ENOMEM); @@ -1155,7 +1157,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, !list_empty(&curr_ctx->reserved_links)) return -EBUSY; - new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode); + new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1); if (!new_ctx) return -ENOMEM; From patchwork Tue Jul 2 11:36:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 810335 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 478C615B122 for ; Tue, 2 Jul 2024 11:36:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920172; cv=none; b=WHjEfFW8ZlSvmvuqFemb1sgflm1jPn948Lq1ePQXfQrwo70zb4GUD7jcgjn0dyhDlqXA9HYC4ZkpnRtH8B84rSQATSxEDP3XB0O2RZwt0pdFpcuwHgt11qtgIpeaYerFqHiyPrjOxd3szWQVoAFyQ/PdNe7zi63RuWXuG1nYC6M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920172; c=relaxed/simple; bh=EUi9vegq7A21nMJblMo7sd2MuXdOx9HCjiQmcECOHmk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fJoF1rTMycxAJQgLCpbUBP8bokt6wEEKQKjz5BBM/yLOMhIUJUbr0Pl0nJAs+Vl0HlG0OQLHlERtYVXwI9vGUc5rRAZoxxfmLiARo5xYJ0ildFoTlYX4hOGaaUf8s5Y9XFepqshPGToKU+/RsgXr47hzrzyUijPZfc6KDu7ngZU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=PMLl3Kx1; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="PMLl3Kx1" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=LbJtbrhgbEbR7kgZ+ImC115eAhE+YwHBhRK6izA84dE=; b=PMLl3Kx1OCM6uJao+jXNvrJonS hTv2L7BwFK30J2DXZ5fdAJ8OHoaDvvKz8Fp8464qTlMpvpTxYR0mhxOpbDQRhpajTIKdEMgVhKctI On/DIYow/lRAHFxOylxgVLQk8bsWnhDG7fLDm2gkYn3SIAzxIGApm+ZfF+CJLW0ru+hY=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObns-001lDm-17; Tue, 02 Jul 2024 13:36:08 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 07/10] wifi: mac80211: extend ifcomb check functions for multi-radio Date: Tue, 2 Jul 2024 13:36:02 +0200 Message-ID: <12a4e3fba7ffc988874e8f37319f096c51b15417.1719919832.git-series.nbd@nbd.name> X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add support for counting global and per-radio max/current number of channels, as well as checking radio-specific interface combinations. Signed-off-by: Felix Fietkau --- net/mac80211/cfg.c | 7 +- net/mac80211/chan.c | 17 +++-- net/mac80211/ibss.c | 2 +- net/mac80211/ieee80211_i.h | 5 +- net/mac80211/iface.c | 2 +- net/mac80211/util.c | 142 +++++++++++++++++++++++--------------- 6 files changed, 108 insertions(+), 67 deletions(-) diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3d49b3ee3a2b..85cb71de370f 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -263,7 +263,7 @@ static int ieee80211_start_p2p_device(struct wiphy *wiphy, lockdep_assert_wiphy(sdata->local->hw.wiphy); - ret = ieee80211_check_combinations(sdata, NULL, 0, 0); + ret = ieee80211_check_combinations(sdata, NULL, 0, 0, -1); if (ret < 0) return ret; @@ -285,7 +285,7 @@ static int ieee80211_start_nan(struct wiphy *wiphy, lockdep_assert_wiphy(sdata->local->hw.wiphy); - ret = ieee80211_check_combinations(sdata, NULL, 0, 0); + ret = ieee80211_check_combinations(sdata, NULL, 0, 0, -1); if (ret < 0) return ret; @@ -4008,7 +4008,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, goto out; /* if reservation is invalid then this will fail */ - err = ieee80211_check_combinations(sdata, NULL, chanctx->mode, 0); + err = ieee80211_check_combinations(sdata, NULL, chanctx->mode, 0, -1); if (err) { ieee80211_link_unreserve_chanctx(link_data); goto out; @@ -5203,4 +5203,5 @@ const struct cfg80211_ops mac80211_config_ops = { .del_link_station = ieee80211_del_link_station, .set_hw_timestamp = ieee80211_set_hw_timestamp, .set_ttlm = ieee80211_set_ttlm, + .get_radio_mask = ieee80211_get_radio_mask, }; diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 6c4d02cb07bb..12bad02da561 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -47,24 +47,29 @@ int ieee80211_chanctx_refcount(struct ieee80211_local *local, ieee80211_chanctx_num_reserved(local, ctx); } -static int ieee80211_num_chanctx(struct ieee80211_local *local) +static int ieee80211_num_chanctx(struct ieee80211_local *local, int radio_idx) { struct ieee80211_chanctx *ctx; int num = 0; lockdep_assert_wiphy(local->hw.wiphy); - list_for_each_entry(ctx, &local->chanctx_list, list) + list_for_each_entry(ctx, &local->chanctx_list, list) { + if (radio_idx >= 0 && ctx->conf.radio_idx != radio_idx) + continue; num++; + } return num; } -static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local) +static bool ieee80211_can_create_new_chanctx(struct ieee80211_local *local, + int radio_idx) { lockdep_assert_wiphy(local->hw.wiphy); - return ieee80211_num_chanctx(local) < ieee80211_max_num_channels(local); + return ieee80211_num_chanctx(local, radio_idx) < + ieee80211_max_num_channels(local, radio_idx); } static struct ieee80211_chanctx * @@ -1101,7 +1106,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode); if (!new_ctx) { - if (ieee80211_can_create_new_chanctx(local)) { + if (ieee80211_can_create_new_chanctx(local, -1)) { new_ctx = ieee80211_new_chanctx(local, chanreq, mode, false); if (IS_ERR(new_ctx)) @@ -1822,7 +1827,7 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link, link->radar_required = ret; ret = ieee80211_check_combinations(sdata, &chanreq->oper, mode, - radar_detect_width); + radar_detect_width, -1); if (ret < 0) goto out; diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 7db4c3ee7e6d..3f74bbceeca5 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -1746,7 +1746,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, IEEE80211_CHANCTX_SHARED : IEEE80211_CHANCTX_EXCLUSIVE; ret = ieee80211_check_combinations(sdata, ¶ms->chandef, chanmode, - radar_detect_width); + radar_detect_width, -1); if (ret < 0) return ret; diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 6349552e62a8..a3485e4c6132 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2640,8 +2640,9 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local, int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, const struct cfg80211_chan_def *chandef, enum ieee80211_chanctx_mode chanmode, - u8 radar_detect); -int ieee80211_max_num_channels(struct ieee80211_local *local); + u8 radar_detect, int radio_idx); +int ieee80211_max_num_channels(struct ieee80211_local *local, int radio_idx); +u32 ieee80211_get_radio_mask(struct wiphy *wiphy, struct net_device *dev); void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local, struct ieee80211_chanctx *ctx); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 6d969d9f1ac9..adf907e15d70 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -397,7 +397,7 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, } } - return ieee80211_check_combinations(sdata, NULL, 0, 0); + return ieee80211_check_combinations(sdata, NULL, 0, 0, -1); } static int ieee80211_check_queues(struct ieee80211_sub_if_data *sdata, diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 27f0db2e9796..f683df997114 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3932,19 +3932,97 @@ static u8 ieee80211_chanctx_radar_detect(struct ieee80211_local *local, return radar_detect; } +static u32 +__ieee80211_get_radio_mask(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_bss_conf *link_conf; + struct ieee80211_chanctx_conf *conf; + unsigned int link_id; + u32 mask = 0; + + for_each_vif_active_link(&sdata->vif, link_conf, link_id) { + conf = sdata_dereference(link_conf->chanctx_conf, sdata); + if (!conf || conf->radio_idx < 0) + continue; + + mask |= BIT(conf->radio_idx); + } + + return mask; +} + +u32 ieee80211_get_radio_mask(struct wiphy *wiphy, struct net_device *dev) +{ + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + + return __ieee80211_get_radio_mask(sdata); +} + +static bool +ieee80211_sdata_uses_radio(struct ieee80211_sub_if_data *sdata, int radio_idx) +{ + if (radio_idx < 0) + return true; + + return __ieee80211_get_radio_mask(sdata) & BIT(radio_idx); +} + +static void +ieee80211_fill_ifcomb_params(struct ieee80211_local *local, + struct iface_combination_params *params, + const struct cfg80211_chan_def *chandef, + struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_sub_if_data *sdata_iter; + struct ieee80211_chanctx *ctx; + + list_for_each_entry(ctx, &local->chanctx_list, list) { + if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) + continue; + + if (params->radio_idx >= 0 && + ctx->conf.radio_idx != params->radio_idx) + continue; + + if (chandef && + cfg80211_chandef_compatible(chandef, &ctx->conf.def)) + continue; + + params->num_different_channels++; + + params->radar_detect |= + ieee80211_chanctx_radar_detect(local, ctx); + } + + list_for_each_entry(sdata_iter, &local->interfaces, list) { + struct wireless_dev *wdev_iter; + + wdev_iter = &sdata_iter->wdev; + + if (sdata_iter == sdata || + !ieee80211_sdata_running(sdata_iter) || + cfg80211_iftype_allowed(local->hw.wiphy, + wdev_iter->iftype, 0, 1)) + continue; + + if (!ieee80211_sdata_uses_radio(sdata_iter, params->radio_idx)) + continue; + + params->iftype_num[wdev_iter->iftype]++; + } +} + int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, const struct cfg80211_chan_def *chandef, enum ieee80211_chanctx_mode chanmode, - u8 radar_detect) + u8 radar_detect, int radio_idx) { + bool shared = chanmode == IEEE80211_CHANCTX_SHARED; struct ieee80211_local *local = sdata->local; - struct ieee80211_sub_if_data *sdata_iter; enum nl80211_iftype iftype = sdata->wdev.iftype; - struct ieee80211_chanctx *ctx; - int total = 1; struct iface_combination_params params = { .radar_detect = radar_detect, - .radio_idx = -1, + .radio_idx = radio_idx, }; lockdep_assert_wiphy(local->hw.wiphy); @@ -3982,39 +4060,8 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, if (iftype != NL80211_IFTYPE_UNSPECIFIED) params.iftype_num[iftype] = 1; - list_for_each_entry(ctx, &local->chanctx_list, list) { - if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) - continue; - params.radar_detect |= - ieee80211_chanctx_radar_detect(local, ctx); - if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE) { - params.num_different_channels++; - continue; - } - if (chandef && chanmode == IEEE80211_CHANCTX_SHARED && - cfg80211_chandef_compatible(chandef, - &ctx->conf.def)) - continue; - params.num_different_channels++; - } - - list_for_each_entry_rcu(sdata_iter, &local->interfaces, list) { - struct wireless_dev *wdev_iter; - - wdev_iter = &sdata_iter->wdev; - - if (sdata_iter == sdata || - !ieee80211_sdata_running(sdata_iter) || - cfg80211_iftype_allowed(local->hw.wiphy, - wdev_iter->iftype, 0, 1)) - continue; - - params.iftype_num[wdev_iter->iftype]++; - total++; - } - - if (total == 1 && !params.radar_detect) - return 0; + ieee80211_fill_ifcomb_params(local, ¶ms, shared ? chandef : NULL, + sdata); return cfg80211_check_combinations(local->hw.wiphy, ¶ms); } @@ -4029,30 +4076,17 @@ ieee80211_iter_max_chans(const struct ieee80211_iface_combination *c, c->num_different_channels); } -int ieee80211_max_num_channels(struct ieee80211_local *local) +int ieee80211_max_num_channels(struct ieee80211_local *local, int radio_idx) { - struct ieee80211_sub_if_data *sdata; - struct ieee80211_chanctx *ctx; u32 max_num_different_channels = 1; int err; struct iface_combination_params params = { - .radio_idx = -1, + .radio_idx = radio_idx, }; lockdep_assert_wiphy(local->hw.wiphy); - list_for_each_entry(ctx, &local->chanctx_list, list) { - if (ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) - continue; - - params.num_different_channels++; - - params.radar_detect |= - ieee80211_chanctx_radar_detect(local, ctx); - } - - list_for_each_entry_rcu(sdata, &local->interfaces, list) - params.iftype_num[sdata->wdev.iftype]++; + ieee80211_fill_ifcomb_params(local, ¶ms, NULL, NULL); err = cfg80211_iter_combinations(local->hw.wiphy, ¶ms, ieee80211_iter_max_chans, From patchwork Tue Jul 2 11:36:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 810336 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 502D615B12A for ; Tue, 2 Jul 2024 11:36:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; cv=none; b=B5CVgNa94u3zO1gy2Kn8jrW/MXAAl1FGgxeOAZI7W5MRRVjVYUEx44Sq5utwFzHqfWjrj9QkylzYRsSRUVkejAEdh0+KVftBYUopDh2I11wENZ8swBRMRJF/jyj5lUX9w/h818Sa7pDvFZqR+WwDmHq/Z5pDIzAgAMeAWrLP9pI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920171; c=relaxed/simple; bh=koAI6te1uKC8LHz/l/QNRkVkIeuV5kGsso6snevHqOU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W+NkDsJXz5+guDCtF7l0S++DVoL4uV1nHk6i4rykUusRy1p8mtg+5vYvdB4aBwkcP59VX7ncvKP45hurubeK4nF+Mk46pGL1i1PeAu6ytLFBH68LtDIkT2LNtRMmdGzfFuOc4F5maU6ruCK0WPx6MeSyW6VIt1cpcmZyCCjH2XA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=O3uTO28k; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="O3uTO28k" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=B727tQC93LPex1Gn4KMsOr3W+Dt9dN6PmbRgNBVVoSA=; b=O3uTO28kTjQuLekfyJh2K/PgCq ACrwaXeb7TOhrEttSJs/Td00XpoAkA3OuBT5WKdAie4cWzZpyW/XbQCNKQppXmxXYKrsQHRi6U+kV +OAO3//9c53kNrDAQ+MPKMTsZNFG4bHDKeL5n2V9q+kyewGT3D14SiYAts4QnzeT2DY8=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObns-001lDm-1x; Tue, 02 Jul 2024 13:36:08 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 08/10] wifi: mac80211: move code in ieee80211_link_reserve_chanctx to a helper Date: Tue, 2 Jul 2024 13:36:03 +0200 Message-ID: X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Reduces indentation in preparation for further changes Signed-off-by: Felix Fietkau --- net/mac80211/chan.c | 141 ++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 12bad02da561..9aa3b9e25228 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -1089,6 +1089,71 @@ int ieee80211_link_unreserve_chanctx(struct ieee80211_link_data *link) return 0; } +static struct ieee80211_chanctx * +ieee80211_replace_chanctx(struct ieee80211_local *local, + const struct ieee80211_chan_req *chanreq, + enum ieee80211_chanctx_mode mode, + struct ieee80211_chanctx *curr_ctx) +{ + struct ieee80211_chanctx *new_ctx, *ctx; + + if (!curr_ctx || (curr_ctx->replace_state == + IEEE80211_CHANCTX_WILL_BE_REPLACED) || + !list_empty(&curr_ctx->reserved_links)) { + /* + * Another link already requested this context for a + * reservation. Find another one hoping all links assigned + * to it will also switch soon enough. + * + * TODO: This needs a little more work as some cases + * (more than 2 chanctx capable devices) may fail which could + * otherwise succeed provided some channel context juggling was + * performed. + * + * Consider ctx1..3, link1..6, each ctx has 2 links. link1 and + * link2 from ctx1 request new different chandefs starting 2 + * in-place reserations with ctx4 and ctx5 replacing ctx1 and + * ctx2 respectively. Next link5 and link6 from ctx3 reserve + * ctx4. If link3 and link4 remain on ctx2 as they are then this + * fails unless `replace_ctx` from ctx5 is replaced with ctx3. + */ + list_for_each_entry(ctx, &local->chanctx_list, list) { + if (ctx->replace_state != + IEEE80211_CHANCTX_REPLACE_NONE) + continue; + + if (!list_empty(&ctx->reserved_links)) + continue; + + curr_ctx = ctx; + break; + } + } + + /* + * If that's true then all available contexts already have reservations + * and cannot be used. + */ + if (!curr_ctx || (curr_ctx->replace_state == + IEEE80211_CHANCTX_WILL_BE_REPLACED) || + !list_empty(&curr_ctx->reserved_links)) + return ERR_PTR(-EBUSY); + + new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1); + if (!new_ctx) + return ERR_PTR(-ENOMEM); + + new_ctx->replace_ctx = curr_ctx; + new_ctx->replace_state = IEEE80211_CHANCTX_REPLACES_OTHER; + + curr_ctx->replace_ctx = new_ctx; + curr_ctx->replace_state = IEEE80211_CHANCTX_WILL_BE_REPLACED; + + list_add_rcu(&new_ctx->list, &local->chanctx_list); + + return new_ctx; +} + int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, const struct ieee80211_chan_req *chanreq, enum ieee80211_chanctx_mode mode, @@ -1096,7 +1161,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, { struct ieee80211_sub_if_data *sdata = link->sdata; struct ieee80211_local *local = sdata->local; - struct ieee80211_chanctx *new_ctx, *curr_ctx, *ctx; + struct ieee80211_chanctx *new_ctx, *curr_ctx; lockdep_assert_wiphy(local->hw.wiphy); @@ -1106,76 +1171,14 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode); if (!new_ctx) { - if (ieee80211_can_create_new_chanctx(local, -1)) { + if (ieee80211_can_create_new_chanctx(local, -1)) new_ctx = ieee80211_new_chanctx(local, chanreq, mode, false); - if (IS_ERR(new_ctx)) - return PTR_ERR(new_ctx); - } else { - if (!curr_ctx || - (curr_ctx->replace_state == - IEEE80211_CHANCTX_WILL_BE_REPLACED) || - !list_empty(&curr_ctx->reserved_links)) { - /* - * Another link already requested this context - * for a reservation. Find another one hoping - * all links assigned to it will also switch - * soon enough. - * - * TODO: This needs a little more work as some - * cases (more than 2 chanctx capable devices) - * may fail which could otherwise succeed - * provided some channel context juggling was - * performed. - * - * Consider ctx1..3, link1..6, each ctx has 2 - * links. link1 and link2 from ctx1 request new - * different chandefs starting 2 in-place - * reserations with ctx4 and ctx5 replacing - * ctx1 and ctx2 respectively. Next link5 and - * link6 from ctx3 reserve ctx4. If link3 and - * link4 remain on ctx2 as they are then this - * fails unless `replace_ctx` from ctx5 is - * replaced with ctx3. - */ - list_for_each_entry(ctx, &local->chanctx_list, - list) { - if (ctx->replace_state != - IEEE80211_CHANCTX_REPLACE_NONE) - continue; - - if (!list_empty(&ctx->reserved_links)) - continue; - - curr_ctx = ctx; - break; - } - } - - /* - * If that's true then all available contexts already - * have reservations and cannot be used. - */ - if (!curr_ctx || - (curr_ctx->replace_state == - IEEE80211_CHANCTX_WILL_BE_REPLACED) || - !list_empty(&curr_ctx->reserved_links)) - return -EBUSY; - - new_ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1); - if (!new_ctx) - return -ENOMEM; - - new_ctx->replace_ctx = curr_ctx; - new_ctx->replace_state = - IEEE80211_CHANCTX_REPLACES_OTHER; - - curr_ctx->replace_ctx = new_ctx; - curr_ctx->replace_state = - IEEE80211_CHANCTX_WILL_BE_REPLACED; - - list_add_rcu(&new_ctx->list, &local->chanctx_list); - } + else + new_ctx = ieee80211_replace_chanctx(local, chanreq, + mode, curr_ctx); + if (IS_ERR(new_ctx)) + return PTR_ERR(new_ctx); } list_add(&link->reserved_chanctx_list, &new_ctx->reserved_links); From patchwork Tue Jul 2 11:36:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 810334 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3200615B12D for ; Tue, 2 Jul 2024 11:36:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920172; cv=none; b=C/6IQBj+mXItP/pzzu2XftgNPgKUoMFwRKfKW9inFMTZ6RBrly5yP6nQIbUfV6W6wLgy3g9ox/CHtQk+MtRkBD9H7BeXrcyi++kNy/tzZDE+BqtDFU/Cq5jSALtwzXtHoXQub6xe/xTFGvqRE2mlM1nXWsQQHe6gWaZImBdMc/0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719920172; c=relaxed/simple; bh=m5fOfmaL4P5ZvIlvt1E9zjnKlngEhac9MjwaJ6sjtBI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kTI3zXFA5Ii2IPxZJt0+4Fx6T1lmdGVaIWVaQb/Wmz5Khg3b7Wc//1dcS5h7a8p5V0eD//qSkB9Z6WVugj4PuP7D5DvWWjlIwQ+j+EVfmva5tiKvZLU6VFeljFtKiViNphoEqtaT+2MLKkMGAimfZbB7aRVC581Ch+uvP0Dico4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=K+gt4X6M; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="K+gt4X6M" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=fftS+K84L8nIjshhrNW3mFUzxBeeo1mJn4mMKCfM9i4=; b=K+gt4X6M2624aBOe7cUPINGC0V e1Bneilk9UbnH0mDiLn5PvPqb2ikIc16nJCor7zSr/HcVWjeZj5EA8f6mUeyx3S3qxilDV+OStGAI r3GaqqHtQjp//jUOU/3WYWi+c7fYG68mPHF6zbgW0WVlp2TxAIil4MPHn4mYi2SO8f/M=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObns-001lDm-2l; Tue, 02 Jul 2024 13:36:08 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 09/10] wifi: mac80211: add wiphy radio assignment and validation Date: Tue, 2 Jul 2024 13:36:04 +0200 Message-ID: X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Validate number of channels and interface combinations per radio. Assign each channel context to a radio. Signed-off-by: Felix Fietkau --- net/mac80211/chan.c | 52 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 9aa3b9e25228..e8567723e94d 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -714,14 +714,15 @@ static struct ieee80211_chanctx * ieee80211_new_chanctx(struct ieee80211_local *local, const struct ieee80211_chan_req *chanreq, enum ieee80211_chanctx_mode mode, - bool assign_on_failure) + bool assign_on_failure, + int radio_idx) { struct ieee80211_chanctx *ctx; int err; lockdep_assert_wiphy(local->hw.wiphy); - ctx = ieee80211_alloc_chanctx(local, chanreq, mode, -1); + ctx = ieee80211_alloc_chanctx(local, chanreq, mode, radio_idx); if (!ctx) return ERR_PTR(-ENOMEM); @@ -1096,6 +1097,8 @@ ieee80211_replace_chanctx(struct ieee80211_local *local, struct ieee80211_chanctx *curr_ctx) { struct ieee80211_chanctx *new_ctx, *ctx; + struct wiphy *wiphy = local->hw.wiphy; + const struct wiphy_radio *radio; if (!curr_ctx || (curr_ctx->replace_state == IEEE80211_CHANCTX_WILL_BE_REPLACED) || @@ -1125,6 +1128,12 @@ ieee80211_replace_chanctx(struct ieee80211_local *local, if (!list_empty(&ctx->reserved_links)) continue; + if (ctx->conf.radio_idx >= 0) { + radio = &wiphy->radio[ctx->conf.radio_idx]; + if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) + continue; + } + curr_ctx = ctx; break; } @@ -1154,6 +1163,34 @@ ieee80211_replace_chanctx(struct ieee80211_local *local, return new_ctx; } +static bool +ieee80211_find_available_radio(struct ieee80211_local *local, + const struct ieee80211_chan_req *chanreq, + int *radio_idx) +{ + struct wiphy *wiphy = local->hw.wiphy; + const struct wiphy_radio *radio; + int i; + + *radio_idx = -1; + if (!wiphy->n_radio) + return true; + + for (i = 0; i < wiphy->n_radio; i++) { + radio = &wiphy->radio[i]; + if (!cfg80211_radio_chandef_valid(radio, &chanreq->oper)) + continue; + + if (!ieee80211_can_create_new_chanctx(local, i)) + continue; + + *radio_idx = i; + return true; + } + + return false; +} + int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, const struct ieee80211_chan_req *chanreq, enum ieee80211_chanctx_mode mode, @@ -1162,6 +1199,7 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, struct ieee80211_sub_if_data *sdata = link->sdata; struct ieee80211_local *local = sdata->local; struct ieee80211_chanctx *new_ctx, *curr_ctx; + int radio_idx; lockdep_assert_wiphy(local->hw.wiphy); @@ -1171,9 +1209,10 @@ int ieee80211_link_reserve_chanctx(struct ieee80211_link_data *link, new_ctx = ieee80211_find_reservation_chanctx(local, chanreq, mode); if (!new_ctx) { - if (ieee80211_can_create_new_chanctx(local, -1)) + if (ieee80211_can_create_new_chanctx(local, -1) && + ieee80211_find_available_radio(local, chanreq, &radio_idx)) new_ctx = ieee80211_new_chanctx(local, chanreq, mode, - false); + false, radio_idx); else new_ctx = ieee80211_replace_chanctx(local, chanreq, mode, curr_ctx); @@ -1810,6 +1849,7 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link, struct ieee80211_chanctx *ctx; u8 radar_detect_width = 0; bool reserved = false; + int radio_idx; int ret; lockdep_assert_wiphy(local->hw.wiphy); @@ -1840,9 +1880,11 @@ int _ieee80211_link_use_channel(struct ieee80211_link_data *link, /* Note: context is now reserved */ if (ctx) reserved = true; + else if (!ieee80211_find_available_radio(local, chanreq, &radio_idx)) + ctx = ERR_PTR(-EBUSY); else ctx = ieee80211_new_chanctx(local, chanreq, mode, - assign_on_failure); + assign_on_failure, radio_idx); if (IS_ERR(ctx)) { ret = PTR_ERR(ctx); goto out; From patchwork Tue Jul 2 11:36:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Felix Fietkau X-Patchwork-Id: 809316 Received: from nbd.name (nbd.name [46.4.11.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8888815B12A for ; Tue, 2 Jul 2024 11:55:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.4.11.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719921329; cv=none; b=pfKV7uMT27arg1CHvC3QqkScuPUqaUT/wn4BY1aE0lwfHQr/KsBK09puzUYA4wX0BbOGik8WL2fqn2SjKeIEq3nItGmlgpDqTsKkTRQSGlSilGeWMM4ArmY25lrH5Nv+HpaUyltSmXbhhk+NkO51bfiisazlzlHlbkEPOYaAef8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719921329; c=relaxed/simple; bh=WctNaj/0b0AhTTZL46DhT9To+2ge/g3Mk9SLXAPttwU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gFSWOBXE/2icvHHMQc94sudCamL++8zQGw1gaXxy4N/FUqVNfY36kVM5exg8MbNMw1nXYatPhKtIJpkODXYt7y8/LgrlqUSC5YykYtRPncq/veAWP+B3qAzH1e5gm97loDyIPdfeJG+PXiAkYWpLXfJFWA2nYftBnGhMgD1cjGg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name; spf=none smtp.mailfrom=nbd.name; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b=DvPfiuZP; arc=none smtp.client-ip=46.4.11.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nbd.name Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=nbd.name Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=nbd.name header.i=@nbd.name header.b="DvPfiuZP" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=nbd.name; s=20160729; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=JV/ANj3jKAjuMpJ11DXLC1T9vhymTAa8DJXksYH6ngI=; b=DvPfiuZPh3OrczUpTlHXEedC+0 lfEO1v2N4yIZzycUiAKp20x0PKdzlFNNlMM97sPCn8a2LBJpT+AtlGXwOE7CMsGhB35/N6LToQBCD 90nXcYh9prQ3NzpWZPppM/sEJiqXj0zGGIwUq687xQl0IWr61uD1E++KXcPOkcNg0cmM=; Received: from p54ae9766.dip0.t-ipconnect.de ([84.174.151.102] helo=localhost.localdomain) by ds12 with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (Exim 4.96) (envelope-from ) id 1sObnt-001lDm-0Q; Tue, 02 Jul 2024 13:36:09 +0200 From: Felix Fietkau To: linux-wireless@vger.kernel.org Cc: johannes@sipsolutions.net, quic_adisi@quicinc.com, quic_periyasa@quicinc.com, ath12k@lists.infradead.org Subject: [PATCH v4 10/10] wifi: mac80211_hwsim: add support for multi-radio wiphy Date: Tue, 2 Jul 2024 13:36:05 +0200 Message-ID: X-Mailer: git-send-email 2.44.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-wireless@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 This registers one wiphy radio per supported band. Number of different channels is set per radio. Signed-off-by: Felix Fietkau --- drivers/net/wireless/virtual/mac80211_hwsim.c | 74 +++++++++++++++++--- drivers/net/wireless/virtual/mac80211_hwsim.h | 4 +- 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c index 8491eb32f760..86ff0ad5992e 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.c +++ b/drivers/net/wireless/virtual/mac80211_hwsim.c @@ -69,6 +69,10 @@ static bool mlo; module_param(mlo, bool, 0444); MODULE_PARM_DESC(mlo, "Support MLO"); +static bool multi_radio; +module_param(multi_radio, bool, 0444); +MODULE_PARM_DESC(mlo, "Support Multiple Radios per wiphy"); + /** * enum hwsim_regtest - the type of regulatory tests we offer * @@ -669,6 +673,10 @@ struct mac80211_hwsim_data { struct ieee80211_iface_limit if_limits[3]; int n_if_limits; + struct ieee80211_iface_combination if_combination_radio; + struct wiphy_radio_freq_range radio_range[NUM_NL80211_BANDS]; + struct wiphy_radio radio[NUM_NL80211_BANDS]; + u32 ciphers[ARRAY_SIZE(hwsim_ciphers)]; struct mac_address addresses[2]; @@ -917,6 +925,7 @@ static const struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { [HWSIM_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, [HWSIM_ATTR_PMSR_SUPPORT] = NLA_POLICY_NESTED(hwsim_pmsr_capa_policy), [HWSIM_ATTR_PMSR_RESULT] = NLA_POLICY_NESTED(hwsim_pmsr_peers_result_policy), + [HWSIM_ATTR_MULTI_RADIO] = { .type = NLA_FLAG }, }; #if IS_REACHABLE(CONFIG_VIRTIO) @@ -4018,6 +4027,7 @@ struct hwsim_new_radio_params { bool reg_strict; bool p2p_device; bool use_chanctx; + bool multi_radio; bool destroy_on_close; const char *hwname; bool no_vif; @@ -4094,6 +4104,12 @@ static int append_radio_msg(struct sk_buff *skb, int id, return ret; } + if (param->multi_radio) { + ret = nla_put_flag(skb, HWSIM_ATTR_MULTI_RADIO); + if (ret < 0) + return ret; + } + if (param->hwname) { ret = nla_put(skb, HWSIM_ATTR_RADIO_NAME, strlen(param->hwname), param->hwname); @@ -5114,6 +5130,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, struct net *net; int idx, i; int n_limits = 0; + int n_bands = 0; if (WARN_ON(param->channels > 1 && !param->use_chanctx)) return -EINVAL; @@ -5217,22 +5234,22 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, n_limits++; } + data->if_combination.radar_detect_widths = + BIT(NL80211_CHAN_WIDTH_5) | + BIT(NL80211_CHAN_WIDTH_10) | + BIT(NL80211_CHAN_WIDTH_20_NOHT) | + BIT(NL80211_CHAN_WIDTH_20) | + BIT(NL80211_CHAN_WIDTH_40) | + BIT(NL80211_CHAN_WIDTH_80) | + BIT(NL80211_CHAN_WIDTH_160); + if (data->use_chanctx) { hw->wiphy->max_scan_ssids = 255; hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN; hw->wiphy->max_remain_on_channel_duration = 1000; - data->if_combination.radar_detect_widths = 0; data->if_combination.num_different_channels = data->channels; } else { data->if_combination.num_different_channels = 1; - data->if_combination.radar_detect_widths = - BIT(NL80211_CHAN_WIDTH_5) | - BIT(NL80211_CHAN_WIDTH_10) | - BIT(NL80211_CHAN_WIDTH_20_NOHT) | - BIT(NL80211_CHAN_WIDTH_20) | - BIT(NL80211_CHAN_WIDTH_40) | - BIT(NL80211_CHAN_WIDTH_80) | - BIT(NL80211_CHAN_WIDTH_160); } if (!n_limits) { @@ -5350,6 +5367,9 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { struct ieee80211_supported_band *sband = &data->bands[band]; + struct wiphy_radio_freq_range *radio_range; + const struct ieee80211_channel *c; + struct wiphy_radio *radio; sband->band = band; @@ -5423,8 +5443,36 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, mac80211_hwsim_sband_capab(sband); hw->wiphy->bands[band] = sband; + + if (!param->multi_radio) + continue; + + c = sband->channels; + radio_range = &data->radio_range[n_bands]; + radio_range->start_freq = ieee80211_channel_to_khz(c) - 10000; + + c += sband->n_channels - 1; + radio_range->end_freq = ieee80211_channel_to_khz(c) + 10000; + + radio = &data->radio[n_bands++]; + radio->freq_range = radio_range; + radio->n_freq_range = 1; + radio->iface_combinations = &data->if_combination_radio; + radio->n_iface_combinations = 1; } + if (param->multi_radio) { + hw->wiphy->radio = data->radio; + hw->wiphy->n_radio = n_bands; + + memcpy(&data->if_combination_radio, &data->if_combination, + sizeof(data->if_combination)); + data->if_combination.num_different_channels *= n_bands; + } + + if (data->use_chanctx) + data->if_combination.radar_detect_widths = 0; + /* By default all radios belong to the first group */ data->group = 1; mutex_init(&data->mutex); @@ -6042,6 +6090,9 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) else param.use_chanctx = (param.channels > 1); + if (info->attrs[HWSIM_ATTR_MULTI_RADIO]) + param.multi_radio = true; + if (info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]) param.reg_alpha2 = nla_data(info->attrs[HWSIM_ATTR_REG_HINT_ALPHA2]); @@ -6122,7 +6173,7 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info) param.mlo = info->attrs[HWSIM_ATTR_MLO_SUPPORT]; - if (param.mlo) + if (param.mlo || param.multi_radio) param.use_chanctx = true; if (info->attrs[HWSIM_ATTR_RADIO_NAME]) { @@ -6815,7 +6866,8 @@ static int __init init_mac80211_hwsim(void) param.p2p_device = support_p2p_device; param.mlo = mlo; - param.use_chanctx = channels > 1 || mlo; + param.multi_radio = multi_radio; + param.use_chanctx = channels > 1 || mlo || multi_radio; param.iftypes = HWSIM_IFTYPE_SUPPORT_MASK; if (param.p2p_device) param.iftypes |= BIT(NL80211_IFTYPE_P2P_DEVICE); diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.h b/drivers/net/wireless/virtual/mac80211_hwsim.h index 28c1db482e79..f32fc3a492b0 100644 --- a/drivers/net/wireless/virtual/mac80211_hwsim.h +++ b/drivers/net/wireless/virtual/mac80211_hwsim.h @@ -157,6 +157,9 @@ enum hwsim_commands { * to provide details about peer measurement request (nl80211_peer_measurement_attrs) * @HWSIM_ATTR_PMSR_RESULT: nested attributed used with %HWSIM_CMD_REPORT_PMSR * to provide peer measurement result (nl80211_peer_measurement_attrs) + * @HWSIM_ATTR_MULTI_RADIO: Register multiple wiphy radios (flag). + * Adds one radio for each band. Number of supported channels will be set for + * each radio instead of for the wiphy. * @__HWSIM_ATTR_MAX: enum limit */ enum hwsim_attrs { @@ -189,6 +192,7 @@ enum hwsim_attrs { HWSIM_ATTR_PMSR_SUPPORT, HWSIM_ATTR_PMSR_REQUEST, HWSIM_ATTR_PMSR_RESULT, + HWSIM_ATTR_MULTI_RADIO, __HWSIM_ATTR_MAX, }; #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)