/**
* cfg80211_6ghz_power_type - determine AP regulatory power type
* @control: control flags
+ * @client_flags: &enum ieee80211_channel_flags for station mode to enable
+ * SP to LPI fallback, zero otherwise.
*
* Return: regulatory power type from &enum ieee80211_ap_reg_power
*/
static inline enum ieee80211_ap_reg_power
-cfg80211_6ghz_power_type(u8 control)
+cfg80211_6ghz_power_type(u8 control, u32 client_flags)
{
switch (u8_get_bits(control, IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO)) {
case IEEE80211_6GHZ_CTRL_REG_LPI_AP:
case IEEE80211_6GHZ_CTRL_REG_INDOOR_LPI_AP:
return IEEE80211_REG_LPI_AP;
case IEEE80211_6GHZ_CTRL_REG_SP_AP:
- case IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP:
case IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP_OLD:
return IEEE80211_REG_SP_AP;
case IEEE80211_6GHZ_CTRL_REG_VLP_AP:
return IEEE80211_REG_VLP_AP;
+ case IEEE80211_6GHZ_CTRL_REG_INDOOR_SP_AP:
+ if (client_flags & IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT)
+ return IEEE80211_REG_LPI_AP;
+ return IEEE80211_REG_SP_AP;
default:
return IEEE80211_REG_UNSET_AP;
}
he_6ghz_oper = ieee80211_he_6ghz_oper(elems->he_operation);
if (he_6ghz_oper)
link->conf->power_type =
- cfg80211_6ghz_power_type(he_6ghz_oper->control);
+ cfg80211_6ghz_power_type(he_6ghz_oper->control,
+ cbss->channel->flags);
else
link_info(link,
"HE 6 GHz operation missing (on %d MHz), expect issues\n",
bool signal_valid, unsigned long ts);
enum ieee80211_ap_reg_power
-cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len);
+cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len,
+ u32 client_flags);
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
beacon_check.relax = true;
beacon_check.reg_power =
cfg80211_get_6ghz_power_type(params->beacon.tail,
- params->beacon.tail_len);
+ params->beacon.tail_len, 0);
if (!cfg80211_reg_check_beaconing(&rdev->wiphy, ¶ms->chandef,
&beacon_check)) {
err = -EINVAL;
beacon_check.relax = true;
beacon_check.reg_power =
cfg80211_get_6ghz_power_type(params->beacon.tail,
- params->beacon.tail_len);
+ params->beacon.tail_len, 0);
if (!cfg80211_reg_check_beaconing(&rdev->wiphy,
&wdev->links[link_id].ap.chandef,
&beacon_check)) {
};
enum ieee80211_ap_reg_power
-cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len)
+cfg80211_get_6ghz_power_type(const u8 *elems, size_t elems_len,
+ u32 client_flags)
{
const struct ieee80211_he_6ghz_oper *he_6ghz_oper;
struct ieee80211_he_operation *he_oper;
if (!he_6ghz_oper)
return IEEE80211_REG_UNSET_AP;
- return cfg80211_6ghz_power_type(he_6ghz_oper->control);
+ return cfg80211_6ghz_power_type(he_6ghz_oper->control, client_flags);
}
static bool cfg80211_6ghz_power_type_valid(const u8 *elems, size_t elems_len,
const u32 flags)
{
- switch (cfg80211_get_6ghz_power_type(elems, elems_len)) {
+ switch (cfg80211_get_6ghz_power_type(elems, elems_len, flags)) {
case IEEE80211_REG_LPI_AP:
return true;
case IEEE80211_REG_SP_AP: