@@ -4504,6 +4504,9 @@ static inline bool for_each_element_completed(const struct element *element,
#define IEEE80211_RNR_TBTT_PARAMS_PROBE_ACTIVE 0x20
#define IEEE80211_RNR_TBTT_PARAMS_COLOC_AP 0x40
+#define IEEE80211_RNR_TBTT_PARAMS_PSD_NO_LIMIT 127
+#define IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED -128
+
struct ieee80211_neighbor_ap_info {
u8 tbtt_info_hdr;
u8 tbtt_info_len;
@@ -4539,7 +4542,7 @@ struct ieee80211_tbtt_info_7_8_9 {
/* The following element is optional, structure may not grow */
u8 bss_params;
- u8 psd_20;
+ s8 psd_20;
} __packed;
/* Format of the TBTT information element if it has >= 11 bytes */
@@ -4550,7 +4553,7 @@ struct ieee80211_tbtt_info_ge_11 {
/* The following elements are optional, structure may grow */
u8 bss_params;
- u8 psd_20;
+ s8 psd_20;
struct ieee80211_rnr_mld_params mld_params;
} __packed;
@@ -2466,6 +2466,7 @@ struct cfg80211_scan_info {
* @short_ssid_valid: @short_ssid is valid and can be used
* @psc_no_listen: when set, and the channel is a PSC channel, no need to wait
* 20 TUs before starting to send probe requests.
+ * @psd_20: The AP's 20 MHz PSD value.
*/
struct cfg80211_scan_6ghz_params {
u32 short_ssid;
@@ -2474,6 +2475,7 @@ struct cfg80211_scan_6ghz_params {
bool unsolicited_probe;
bool short_ssid_valid;
bool psc_no_listen;
+ s8 psd_20;
};
/**
@@ -96,6 +96,7 @@ MODULE_PARM_DESC(bss_entries_limit,
* colocated and can be discovered via legacy bands.
* @short_ssid_valid: short_ssid is valid and can be used
* @short_ssid: the short SSID for this SSID
+ * @psd_20: The 20MHz PSD EIRP of the primary 20MHz channel for the reported AP
*/
struct cfg80211_colocated_ap {
struct list_head list;
@@ -111,6 +112,7 @@ struct cfg80211_colocated_ap {
transmitted_bssid:1,
colocated_ess:1,
short_ssid_valid:1;
+ s8 psd_20;
};
static void bss_free(struct cfg80211_internal_bss *bss)
@@ -578,6 +580,8 @@ static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
{
u8 bss_params;
+ entry->psd_20 = IEEE80211_RNR_TBTT_PARAMS_PSD_RESERVED;
+
/* The length is already verified by the caller to contain bss_params */
if (length > sizeof(struct ieee80211_tbtt_info_7_8_9)) {
struct ieee80211_tbtt_info_ge_11 *tbtt_info = (void *)pos;
@@ -594,12 +598,20 @@ static int cfg80211_parse_ap_info(struct cfg80211_colocated_ap *entry,
IEEE80211_RNR_MLD_PARAMS_DISABLED_LINK))
return -EINVAL;
}
+
+ if (length >= offsetofend(struct ieee80211_tbtt_info_ge_11,
+ psd_20))
+ entry->psd_20 = tbtt_info->psd_20;
} else {
struct ieee80211_tbtt_info_7_8_9 *tbtt_info = (void *)pos;
memcpy(entry->bssid, tbtt_info->bssid, ETH_ALEN);
bss_params = tbtt_info->bss_params;
+
+ if (length == offsetofend(struct ieee80211_tbtt_info_7_8_9,
+ psd_20))
+ entry->psd_20 = tbtt_info->psd_20;
}
/* ignore entries with invalid BSSID */
@@ -904,6 +916,7 @@ static int cfg80211_scan_6ghz(struct cfg80211_registered_device *rdev)
scan_6ghz_params->short_ssid = ap->short_ssid;
scan_6ghz_params->short_ssid_valid = ap->short_ssid_valid;
scan_6ghz_params->unsolicited_probe = ap->unsolicited_probe;
+ scan_6ghz_params->psd_20 = ap->psd_20;
/*
* If a PSC channel is added to the scan and 'need_scan_psc' is