[PATCH v5] cfg80211: save power spectral density(psd) of regulatory rule

vnaralas at codeaurora.org vnaralas at codeaurora.org
Tue Sep 28 06:12:31 PDT 2021


On 2021-09-28 14:22, Wen Gong wrote:
> 6 GHz regulatory domains introduces power spectral density(psd).
> The power spectral density(psd) of regulatory rule should be take
> effect to the channels. Save the values to the channel which has
> psd value and add nl80211 attributes for it.
> 
> Signed-off-by: Wen Gong <wgong at codeaurora.org>
> ---
> v5: change by comments of johannes.
>     1. add handler for nl80211 attributes
>     2. add indentation for NL80211_RRF_PSD
>     3. squashed with "cfg80211: add definition for 6 GHz power
> spectral density(psd)"
>     4. remove all other patches
> 
> v4:
>     1. rebased to top commit id 9e263e193af7 
> kernel/git/jberg/mac80211-next.git
>     2. add NULL check for "mac80211: use ieee802_11_parse_elems() to
> find ies instead of ieee80211_bss_get_ie()"
>     3. remove the 3 patches which already upstream:
>        "mac80211: parse transmit power envelope element"
>        "ieee80211: add definition for transmit power envelope element"
>        "ieee80211: add definition of regulatory info in 6 GHz
> operation information"
> 
> v3: change per comments of Johannes.
>     1. add patch "mac80211: use ieee802_11_parse_elems() to find ies
> instead of ieee80211_bss_get_ie()"
>     2. move nl80211_ap_reg_power to ieee80211
>     3. change some comments, length check, stack big size variable...
> 
> v2: change per comments of johannes.
>     including code style, code logic, patch merge, commit log...
> 
>  include/net/cfg80211.h       |  5 +++++
>  include/net/regulatory.h     |  1 +
>  include/uapi/linux/nl80211.h |  9 +++++++++
>  net/wireless/nl80211.c       | 18 ++++++++++++++++++
>  net/wireless/reg.c           | 17 +++++++++++++++++
>  5 files changed, 50 insertions(+)
> 
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 62dd8422e0dc..f8e0cc19e0ce 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -109,6 +109,8 @@ struct wiphy;
>   *	on this channel.
>   * @IEEE80211_CHAN_16MHZ: 16 MHz bandwidth is permitted
>   *	on this channel.
> + * @IEEE80211_CHAN_PSD: power spectral density (in dBm)
> + *	on this channel.
>   *
>   */
>  enum ieee80211_channel_flags {
> @@ -131,6 +133,7 @@ enum ieee80211_channel_flags {
>  	IEEE80211_CHAN_4MHZ		= 1<<16,
>  	IEEE80211_CHAN_8MHZ		= 1<<17,
>  	IEEE80211_CHAN_16MHZ		= 1<<18,
> +	IEEE80211_CHAN_PSD		= 1<<19,
>  };
> 
>  #define IEEE80211_CHAN_NO_HT40 \
> @@ -164,6 +167,7 @@ enum ieee80211_channel_flags {
>   *	on this channel.
>   * @dfs_state_entered: timestamp (jiffies) when the dfs state was 
> entered.
>   * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS 
> channels.
> + * @psd: power spectral density (in dBm)
>   */
>  struct ieee80211_channel {
>  	enum nl80211_band band;
> @@ -180,6 +184,7 @@ struct ieee80211_channel {
>  	enum nl80211_dfs_state dfs_state;
>  	unsigned long dfs_state_entered;
>  	unsigned int dfs_cac_ms;
> +	s8 psd;
>  };
> 
>  /**
> diff --git a/include/net/regulatory.h b/include/net/regulatory.h
> index 47f06f6f5a67..ed20004fb6a9 100644
> --- a/include/net/regulatory.h
> +++ b/include/net/regulatory.h
> @@ -221,6 +221,7 @@ struct ieee80211_reg_rule {
>  	u32 flags;
>  	u32 dfs_cac_ms;
>  	bool has_wmm;
> +	s8 psd;
>  };
> 
>  struct ieee80211_regdomain {
> diff --git a/include/uapi/linux/nl80211.h 
> b/include/uapi/linux/nl80211.h
> index c2efea98e060..ae5f69aa727b 100644
> --- a/include/uapi/linux/nl80211.h
> +++ b/include/uapi/linux/nl80211.h
> @@ -3851,6 +3851,8 @@ enum nl80211_wmm_rule {
>   *	on this channel in current regulatory domain.
>   * @NL80211_FREQUENCY_ATTR_16MHZ: 16 MHz operation is allowed
>   *	on this channel in current regulatory domain.
> + * @NL80211_FREQUENCY_ATTR_PSD: power spectral density (in dBm)
> + *	is allowed on this channel in current regulatory domain.
>   * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
>   *	currently defined
>   * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
> @@ -3887,6 +3889,7 @@ enum nl80211_frequency_attr {
>  	NL80211_FREQUENCY_ATTR_4MHZ,
>  	NL80211_FREQUENCY_ATTR_8MHZ,
>  	NL80211_FREQUENCY_ATTR_16MHZ,
> +	NL80211_FREQUENCY_ATTR_PSD,
> 
>  	/* keep last */
>  	__NL80211_FREQUENCY_ATTR_AFTER_LAST,
> @@ -3987,6 +3990,8 @@ enum nl80211_reg_type {
>   * 	a given frequency range. The value is in mBm (100 * dBm).
>   * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
>   *	If not present or 0 default CAC time will be used.
> + * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm).
> + *	This could be negative.
>   * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute 
> number
>   *	currently defined
>   * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
> @@ -4004,6 +4009,8 @@ enum nl80211_reg_rule_attr {
> 
>  	NL80211_ATTR_DFS_CAC_TIME,
> 
> +	NL80211_ATTR_POWER_RULE_PSD,
> +
>  	/* keep last */
>  	__NL80211_REG_RULE_ATTR_AFTER_LAST,
>  	NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
> @@ -4085,6 +4092,7 @@ enum nl80211_sched_scan_match_attr {
>   * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
>   * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
>   * @NL80211_RRF_NO_HE: HE operation not allowed
> + * @NL80211_RRF_PSD: channels has power spectral density value
>   */
>  enum nl80211_reg_rule_flags {
>  	NL80211_RRF_NO_OFDM		= 1<<0,
> @@ -4103,6 +4111,7 @@ enum nl80211_reg_rule_flags {
>  	NL80211_RRF_NO_80MHZ		= 1<<15,
>  	NL80211_RRF_NO_160MHZ		= 1<<16,
>  	NL80211_RRF_NO_HE		= 1<<17,
> +	NL80211_RRF_PSD			= 1<<18,
>  };
> 
>  #define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 0b4f29d689d2..9f1c5be11c95 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -1055,6 +1055,10 @@ static int nl80211_msg_put_channel(struct
> sk_buff *msg, struct wiphy *wiphy,
>  	if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, 
> chan->freq_offset))
>  		goto nla_put_failure;
> 
> +	if ((chan->flags & IEEE80211_CHAN_PSD) &&
> +	    nla_put_s8(msg, NL80211_FREQUENCY_ATTR_PSD, chan->psd))
> +		goto nla_put_failure;
> +
>  	if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
>  	    nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
>  		goto nla_put_failure;
> @@ -7755,6 +7759,11 @@ static int nl80211_put_regdom(const struct
> ieee80211_regdomain *regdom,
>  				reg_rule->dfs_cac_ms))
>  			goto nla_put_failure;
> 
> +		if ((reg_rule->flags & NL80211_RRF_PSD) &&
> +		    nla_put_s8(msg, NL80211_ATTR_POWER_RULE_PSD,
> +			       reg_rule->psd))
> +			goto nla_put_failure;
> +
>  		nla_nest_end(msg, nl_reg_rule);
>  	}
> 
> @@ -7926,6 +7935,7 @@ static const struct nla_policy
> reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] =
>  	[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]	= { .type = NLA_U32 },
>  	[NL80211_ATTR_POWER_RULE_MAX_EIRP]	= { .type = NLA_U32 },
>  	[NL80211_ATTR_DFS_CAC_TIME]		= { .type = NLA_U32 },
> +	[NL80211_ATTR_POWER_RULE_PSD]		= { .type = NLA_S8 },
>  };
> 
>  static int parse_reg_rule(struct nlattr *tb[],
> @@ -7947,6 +7957,14 @@ static int parse_reg_rule(struct nlattr *tb[],
> 
>  	reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
> 
> +	if (reg_rule->flags & NL80211_RRF_PSD) {
> +		if (!tb[NL80211_ATTR_POWER_RULE_PSD])
> +			return -EINVAL;
> +
> +		reg_rule->psd =
> +			nla_get_s8(tb[NL80211_ATTR_POWER_RULE_PSD]);
> +	}
> +
>  	freq_range->start_freq_khz =
>  		nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
>  	freq_range->end_freq_khz =
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index df87c7f3a049..8f765befb9bc 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -1590,6 +1590,8 @@ static u32 map_regdom_flags(u32 rd_flags)
>  		channel_flags |= IEEE80211_CHAN_NO_160MHZ;
>  	if (rd_flags & NL80211_RRF_NO_HE)
>  		channel_flags |= IEEE80211_CHAN_NO_HE;
> +	if (rd_flags & NL80211_RRF_PSD)
> +		channel_flags |= IEEE80211_CHAN_PSD;
>  	return channel_flags;
>  }
> 
> @@ -1794,6 +1796,9 @@ static void handle_channel_single_rule(struct
> wiphy *wiphy,
>  				chan->dfs_cac_ms = reg_rule->dfs_cac_ms;
>  		}
> 
> +		if (chan->flags & IEEE80211_CHAN_PSD)
> +			chan->psd = reg_rule->psd;
> +
>  		return;
>  	}
> 
> @@ -1814,6 +1819,9 @@ static void handle_channel_single_rule(struct
> wiphy *wiphy,
>  			chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
>  	}
> 
> +	if (chan->flags & IEEE80211_CHAN_PSD)
> +		chan->psd = reg_rule->psd;
> +
>  	if (chan->orig_mpwr) {
>  		/*
>  		 * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
> @@ -1883,6 +1891,12 @@ static void
> handle_channel_adjacent_rules(struct wiphy *wiphy,
>  							 rrule2->dfs_cac_ms);
>  		}
> 
> +		if ((rrule1->flags & NL80211_RRF_PSD) &&
> +		    (rrule2->flags & NL80211_RRF_PSD))
> +			chan->psd = min_t(s8, rrule1->psd, rrule2->psd);
> +		else
> +			chan->flags &= ~NL80211_RRF_PSD;
> +
>  		return;
>  	}
> 
> @@ -2540,6 +2554,9 @@ static void handle_channel_custom(struct wiphy 
> *wiphy,
>  			chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
>  	}
> 
> +	if (chan->flags & IEEE80211_CHAN_PSD)
> +		chan->psd = reg_rule->psd;
> +
>  	chan->max_power = chan->max_reg_power;

What about the case AP + STA concurrency? are we going to overwrite the 
PSD power and channel flags?

>  }



More information about the ath11k mailing list