Commit ddd7f45c authored by Wen Gong's avatar Wen Gong Committed by Johannes Berg

wifi: cfg80211: save power spectral density(psd) of regulatory rule

6 GHz regulatory domains introduces Power Spectral Density (PSD).
The PSD value of the regulatory rule should be taken into effect
for the ieee80211_channels falling into that particular regulatory
rule. Save the values in the channel which has PSD value and add
nl80211 attributes accordingly to handle it.
Co-developed-by: default avatarAditya Kumar Singh <quic_adisi@quicinc.com>
Signed-off-by: default avatarAditya Kumar Singh <quic_adisi@quicinc.com>
Signed-off-by: default avatarWen Gong <quic_wgong@quicinc.com>
Link: https://lore.kernel.org/r/20230914082026.3709-1-quic_wgong@quicinc.com
[use hole in chan flags, reword docs]
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 9c386911
...@@ -76,6 +76,8 @@ struct wiphy; ...@@ -76,6 +76,8 @@ struct wiphy;
* @IEEE80211_CHAN_DISABLED: This channel is disabled. * @IEEE80211_CHAN_DISABLED: This channel is disabled.
* @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes * @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes
* sending probe requests or beaconing. * sending probe requests or beaconing.
* @IEEE80211_CHAN_PSD: Power spectral density (in dBm) is set for this
* channel.
* @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
* @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel
* is not permitted. * is not permitted.
...@@ -119,7 +121,7 @@ struct wiphy; ...@@ -119,7 +121,7 @@ struct wiphy;
enum ieee80211_channel_flags { enum ieee80211_channel_flags {
IEEE80211_CHAN_DISABLED = 1<<0, IEEE80211_CHAN_DISABLED = 1<<0,
IEEE80211_CHAN_NO_IR = 1<<1, IEEE80211_CHAN_NO_IR = 1<<1,
/* hole at 1<<2 */ IEEE80211_CHAN_PSD = 1<<2,
IEEE80211_CHAN_RADAR = 1<<3, IEEE80211_CHAN_RADAR = 1<<3,
IEEE80211_CHAN_NO_HT40PLUS = 1<<4, IEEE80211_CHAN_NO_HT40PLUS = 1<<4,
IEEE80211_CHAN_NO_HT40MINUS = 1<<5, IEEE80211_CHAN_NO_HT40MINUS = 1<<5,
...@@ -171,6 +173,7 @@ enum ieee80211_channel_flags { ...@@ -171,6 +173,7 @@ enum ieee80211_channel_flags {
* on this channel. * on this channel.
* @dfs_state_entered: timestamp (jiffies) when the dfs state was entered. * @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. * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
* @psd: power spectral density (in dBm)
*/ */
struct ieee80211_channel { struct ieee80211_channel {
enum nl80211_band band; enum nl80211_band band;
...@@ -187,6 +190,7 @@ struct ieee80211_channel { ...@@ -187,6 +190,7 @@ struct ieee80211_channel {
enum nl80211_dfs_state dfs_state; enum nl80211_dfs_state dfs_state;
unsigned long dfs_state_entered; unsigned long dfs_state_entered;
unsigned int dfs_cac_ms; unsigned int dfs_cac_ms;
s8 psd;
}; };
/** /**
......
...@@ -213,6 +213,7 @@ struct ieee80211_reg_rule { ...@@ -213,6 +213,7 @@ struct ieee80211_reg_rule {
u32 flags; u32 flags;
u32 dfs_cac_ms; u32 dfs_cac_ms;
bool has_wmm; bool has_wmm;
s8 psd;
}; };
struct ieee80211_regdomain { struct ieee80211_regdomain {
......
...@@ -4215,6 +4215,8 @@ enum nl80211_wmm_rule { ...@@ -4215,6 +4215,8 @@ enum nl80211_wmm_rule {
* as the primary or any of the secondary channels isn't possible * as the primary or any of the secondary channels isn't possible
* @NL80211_FREQUENCY_ATTR_NO_EHT: EHT operation is not allowed on this channel * @NL80211_FREQUENCY_ATTR_NO_EHT: EHT operation is not allowed on this channel
* in current regulatory domain. * in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_PSD: Power spectral density (in dBm) that
* is allowed on this channel in current regulatory domain.
* @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
* currently defined * currently defined
* @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
...@@ -4253,6 +4255,7 @@ enum nl80211_frequency_attr { ...@@ -4253,6 +4255,7 @@ enum nl80211_frequency_attr {
NL80211_FREQUENCY_ATTR_16MHZ, NL80211_FREQUENCY_ATTR_16MHZ,
NL80211_FREQUENCY_ATTR_NO_320MHZ, NL80211_FREQUENCY_ATTR_NO_320MHZ,
NL80211_FREQUENCY_ATTR_NO_EHT, NL80211_FREQUENCY_ATTR_NO_EHT,
NL80211_FREQUENCY_ATTR_PSD,
/* keep last */ /* keep last */
__NL80211_FREQUENCY_ATTR_AFTER_LAST, __NL80211_FREQUENCY_ATTR_AFTER_LAST,
...@@ -4353,6 +4356,8 @@ enum nl80211_reg_type { ...@@ -4353,6 +4356,8 @@ enum nl80211_reg_type {
* a given frequency range. The value is in mBm (100 * dBm). * a given frequency range. The value is in mBm (100 * dBm).
* @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
* If not present or 0 default CAC time will be used. * 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 * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
* currently defined * currently defined
* @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
...@@ -4370,6 +4375,8 @@ enum nl80211_reg_rule_attr { ...@@ -4370,6 +4375,8 @@ enum nl80211_reg_rule_attr {
NL80211_ATTR_DFS_CAC_TIME, NL80211_ATTR_DFS_CAC_TIME,
NL80211_ATTR_POWER_RULE_PSD,
/* keep last */ /* keep last */
__NL80211_REG_RULE_ATTR_AFTER_LAST, __NL80211_REG_RULE_ATTR_AFTER_LAST,
NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
...@@ -4453,6 +4460,7 @@ enum nl80211_sched_scan_match_attr { ...@@ -4453,6 +4460,7 @@ enum nl80211_sched_scan_match_attr {
* @NL80211_RRF_NO_HE: HE operation not allowed * @NL80211_RRF_NO_HE: HE operation not allowed
* @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed * @NL80211_RRF_NO_320MHZ: 320MHz operation not allowed
* @NL80211_RRF_NO_EHT: EHT operation not allowed * @NL80211_RRF_NO_EHT: EHT operation not allowed
* @NL80211_RRF_PSD: Ruleset has power spectral density value
*/ */
enum nl80211_reg_rule_flags { enum nl80211_reg_rule_flags {
NL80211_RRF_NO_OFDM = 1<<0, NL80211_RRF_NO_OFDM = 1<<0,
...@@ -4473,6 +4481,7 @@ enum nl80211_reg_rule_flags { ...@@ -4473,6 +4481,7 @@ enum nl80211_reg_rule_flags {
NL80211_RRF_NO_HE = 1<<17, NL80211_RRF_NO_HE = 1<<17,
NL80211_RRF_NO_320MHZ = 1<<18, NL80211_RRF_NO_320MHZ = 1<<18,
NL80211_RRF_NO_EHT = 1<<19, NL80211_RRF_NO_EHT = 1<<19,
NL80211_RRF_PSD = 1<<20,
}; };
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR
......
...@@ -1115,6 +1115,10 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, struct wiphy *wiphy, ...@@ -1115,6 +1115,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)) if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_OFFSET, chan->freq_offset))
goto nla_put_failure; 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) && if ((chan->flags & IEEE80211_CHAN_DISABLED) &&
nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED))
goto nla_put_failure; goto nla_put_failure;
...@@ -8529,6 +8533,11 @@ static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom, ...@@ -8529,6 +8533,11 @@ static int nl80211_put_regdom(const struct ieee80211_regdomain *regdom,
reg_rule->dfs_cac_ms)) reg_rule->dfs_cac_ms))
goto nla_put_failure; 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); nla_nest_end(msg, nl_reg_rule);
} }
......
...@@ -1589,6 +1589,8 @@ static u32 map_regdom_flags(u32 rd_flags) ...@@ -1589,6 +1589,8 @@ static u32 map_regdom_flags(u32 rd_flags)
channel_flags |= IEEE80211_CHAN_NO_320MHZ; channel_flags |= IEEE80211_CHAN_NO_320MHZ;
if (rd_flags & NL80211_RRF_NO_EHT) if (rd_flags & NL80211_RRF_NO_EHT)
channel_flags |= IEEE80211_CHAN_NO_EHT; channel_flags |= IEEE80211_CHAN_NO_EHT;
if (rd_flags & NL80211_RRF_PSD)
channel_flags |= IEEE80211_CHAN_PSD;
return channel_flags; return channel_flags;
} }
...@@ -1795,6 +1797,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy, ...@@ -1795,6 +1797,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy,
chan->dfs_cac_ms = reg_rule->dfs_cac_ms; chan->dfs_cac_ms = reg_rule->dfs_cac_ms;
} }
if (chan->flags & IEEE80211_CHAN_PSD)
chan->psd = reg_rule->psd;
return; return;
} }
...@@ -1815,6 +1820,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy, ...@@ -1815,6 +1820,9 @@ static void handle_channel_single_rule(struct wiphy *wiphy,
chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; 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) { if (chan->orig_mpwr) {
/* /*
* Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER * Devices that use REGULATORY_COUNTRY_IE_FOLLOW_POWER
...@@ -1884,6 +1892,12 @@ static void handle_channel_adjacent_rules(struct wiphy *wiphy, ...@@ -1884,6 +1892,12 @@ static void handle_channel_adjacent_rules(struct wiphy *wiphy,
rrule2->dfs_cac_ms); 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; return;
} }
...@@ -2570,6 +2584,9 @@ static void handle_channel_custom(struct wiphy *wiphy, ...@@ -2570,6 +2584,9 @@ static void handle_channel_custom(struct wiphy *wiphy,
chan->dfs_cac_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; 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; chan->max_power = chan->max_reg_power;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment