And advertise EHT capabilities to user space when supported.
Unified · Split
| @@ -360,6 +360,48 @@ struct ieee80211_sta_he_cap { · 359 unmodified lines | |||
| 360 | u8 ppe_thres[IEEE80211_HE_PPE_THRES_MAX_LEN]; | 360 | u8 ppe_thres[IEEE80211_HE_PPE_THRES_MAX_LEN]; |
| 361 | }; | 361 | }; |
| 362 | 362 | ||
| 363 | /** | ||
| 364 | * struct ieee80211_eht_mcs_nss_supp - EHT max supported NSS per MCS | ||
| 365 | * | ||
| 366 | * See P802.11be_D1.3 Table 9-401k - "Subfields of the Supported EHT-MCS | ||
| 367 | * and NSS Set field" | ||
| 368 | * | ||
| 369 | * @only_20mhz: MCS/NSS support for 20 MHz-only STA. | ||
| 370 | * @bw._80: MCS/NSS support for BW <= 80 MHz | ||
| 371 | * @bw._160: MCS/NSS support for BW = 160 MHz | ||
| 372 | * @bw._320: MCS/NSS support for BW = 320 MHz | ||
| 373 | */ | ||
| 374 | struct ieee80211_eht_mcs_nss_supp { | ||
| 375 | union { | ||
| 376 | struct ieee80211_eht_mcs_nss_supp_20mhz_only only_20mhz; | ||
| 377 | struct { | ||
| 378 | struct ieee80211_eht_mcs_nss_supp_bw _80; | ||
| 379 | struct ieee80211_eht_mcs_nss_supp_bw _160; | ||
| 380 | struct ieee80211_eht_mcs_nss_supp_bw _320; | ||
| 381 | } __packed bw; | ||
| 382 | } __packed; | ||
| 383 | } __packed; | ||
| 384 | |||
| 385 | #define IEEE80211_EHT_PPE_THRES_MAX_LEN 32 | ||
| 386 | |||
| 387 | /** | ||
| 388 | * struct ieee80211_sta_eht_cap - STA's EHT capabilities | ||
| 389 | * | ||
| 390 | * This structure describes most essential parameters needed | ||
| 391 | * to describe 802.11be EHT capabilities for a STA. | ||
| 392 | * | ||
| 393 | * @has_eht: true iff EHT data is valid. | ||
| 394 | * @eht_cap_elem: Fixed portion of the eht capabilities element. | ||
| 395 | * @eht_mcs_nss_supp: The supported NSS/MCS combinations. | ||
| 396 | * @eht_ppe_thres: Holds the PPE Thresholds data. | ||
| 397 | */ | ||
| 398 | struct ieee80211_sta_eht_cap { | ||
| 399 | bool has_eht; | ||
| 400 | struct ieee80211_eht_cap_elem_fixed eht_cap_elem; | ||
| 401 | struct ieee80211_eht_mcs_nss_supp eht_mcs_nss_supp; | ||
| 402 | u8 eht_ppe_thres[IEEE80211_EHT_PPE_THRES_MAX_LEN]; | ||
| 403 | }; | ||
| 404 | |||
| 363 | /** | 405 | /** |
| 364 | * struct ieee80211_sband_iftype_data - sband data per interface type | 406 | * struct ieee80211_sband_iftype_data - sband data per interface type |
| 365 | * | 407 | * |
| @@ -379,6 +421,7 @@ struct ieee80211_sband_iftype_data { · 13 unmodified lines | |||
| 379 | u16 types_mask; | 421 | u16 types_mask; |
| 380 | struct ieee80211_sta_he_cap he_cap; | 422 | struct ieee80211_sta_he_cap he_cap; |
| 381 | struct ieee80211_he_6ghz_capa he_6ghz_capa; | 423 | struct ieee80211_he_6ghz_capa he_6ghz_capa; |
| 424 | struct ieee80211_sta_eht_cap eht_cap; | ||
| 382 | struct { | 425 | struct { |
| 383 | const u8 *data; | 426 | const u8 *data; |
| 384 | unsigned int len; | 427 | unsigned int len; |
| @@ -561,6 +604,26 @@ ieee80211_get_he_6ghz_capa(const struct ieee80211_supported_band *sband, · 176 unmodified lines | |||
| 561 | return data->he_6ghz_capa.capa; | 604 | return data->he_6ghz_capa.capa; |
| 562 | } | 605 | } |
| 563 | 606 | ||
| 607 | /** | ||
| 608 | * ieee80211_get_eht_iftype_cap - return ETH capabilities for an sband's iftype | ||
| 609 | * @sband: the sband to search for the iftype on | ||
| 610 | * @iftype: enum nl80211_iftype | ||
| 611 | * | ||
| 612 | * Return: pointer to the struct ieee80211_sta_eht_cap, or NULL is none found | ||
| 613 | */ | ||
| 614 | static inline const struct ieee80211_sta_eht_cap * | ||
| 615 | ieee80211_get_eht_iftype_cap(const struct ieee80211_supported_band *sband, | ||
| 616 | enum nl80211_iftype iftype) | ||
| 617 | { | ||
| 618 | const struct ieee80211_sband_iftype_data *data = | ||
| 619 | ieee80211_get_sband_iftype_data(sband, iftype); | ||
| 620 | |||
| 621 | if (data && data->eht_cap.has_eht) | ||
| 622 | return &data->eht_cap; | ||
| 623 | |||
| 624 | return NULL; | ||
| 625 | } | ||
| 626 | |||
| 564 | /** | 627 | /** |
| 565 | * wiphy_read_of_freq_limits - read frequency limits from device tree | 628 | * wiphy_read_of_freq_limits - read frequency limits from device tree |
| 566 | * | 629 | * |
| @@ -3766,6 +3766,14 @@ enum nl80211_mpath_info { · 3765 unmodified lines | |||
| 3766 | * given for all 6 GHz band channels | 3766 | * given for all 6 GHz band channels |
| 3767 | * @NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS: vendor element capabilities that are | 3767 | * @NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS: vendor element capabilities that are |
| 3768 | * advertised on this band/for this iftype (binary) | 3768 | * advertised on this band/for this iftype (binary) |
| 3769 | * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC: EHT MAC capabilities as in EHT | ||
| 3770 | * capabilities element | ||
| 3771 | * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY: EHT PHY capabilities as in EHT | ||
| 3772 | * capabilities element | ||
| 3773 | * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET: EHT supported NSS/MCS as in EHT | ||
| 3774 | * capabilities element | ||
| 3775 | * @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE: EHT PPE thresholds information as | ||
| 3776 | * defined in EHT capabilities element | ||
| 3769 | * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use | 3777 | * @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use |
| 3770 | * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band attribute currently defined | 3778 | * @NL80211_BAND_IFTYPE_ATTR_MAX: highest band attribute currently defined |
| 3771 | */ | 3779 | */ |
| @@ -3779,6 +3787,10 @@ enum nl80211_band_iftype_attr { · 7 unmodified lines | |||
| 3779 | NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE, | 3787 | NL80211_BAND_IFTYPE_ATTR_HE_CAP_PPE, |
| 3780 | NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, | 3788 | NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, |
| 3781 | NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS, | 3789 | NL80211_BAND_IFTYPE_ATTR_VENDOR_ELEMS, |
| 3790 | NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC, | ||
| 3791 | NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY, | ||
| 3792 | NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET, | ||
| 3793 | NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE, | ||
| 3782 | 3794 | ||
| 3783 | /* keep last */ | 3795 | /* keep last */ |
| 3784 | __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST, | 3796 | __NL80211_BAND_IFTYPE_ATTR_AFTER_LAST, |
| @@ -1737,6 +1737,7 @@ nl80211_send_iftype_data(struct sk_buff *msg, · 1736 unmodified lines | |||
| 1737 | const struct ieee80211_sband_iftype_data *iftdata) | 1737 | const struct ieee80211_sband_iftype_data *iftdata) |
| 1738 | { | 1738 | { |
| 1739 | const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap; | 1739 | const struct ieee80211_sta_he_cap *he_cap = &iftdata->he_cap; |
| 1740 | const struct ieee80211_sta_eht_cap *eht_cap = &iftdata->eht_cap; | ||
| 1740 | 1741 | ||
| 1741 | if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES, | 1742 | if (nl80211_put_iftypes(msg, NL80211_BAND_IFTYPE_ATTR_IFTYPES, |
| 1742 | iftdata->types_mask)) | 1743 | iftdata->types_mask)) |
| @@ -1757,6 +1758,32 @@ nl80211_send_iftype_data(struct sk_buff *msg, · 14 unmodified lines | |||
| 1757 | return -ENOBUFS; | 1758 | return -ENOBUFS; |
| 1758 | } | 1759 | } |
| 1759 | 1760 | ||
| 1761 | if (eht_cap->has_eht && he_cap->has_he) { | ||
| 1762 | u8 mcs_nss_size, ppe_thresh_size; | ||
| 1763 | u16 ppe_thres_hdr; | ||
| 1764 | |||
| 1765 | mcs_nss_size = | ||
| 1766 | ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem, | ||
| 1767 | &eht_cap->eht_cap_elem); | ||
| 1768 | |||
| 1769 | ppe_thres_hdr = get_unaligned_le16(&eht_cap->eht_ppe_thres[0]); | ||
| 1770 | ppe_thresh_size = | ||
| 1771 | ieee80211_eht_ppe_size(ppe_thres_hdr, | ||
| 1772 | eht_cap->eht_cap_elem.phy_cap_info); | ||
| 1773 | |||
| 1774 | if (nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MAC, | ||
| 1775 | sizeof(eht_cap->eht_cap_elem.mac_cap_info), | ||
| 1776 | eht_cap->eht_cap_elem.mac_cap_info) || | ||
| 1777 | nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY, | ||
| 1778 | sizeof(eht_cap->eht_cap_elem.phy_cap_info), | ||
| 1779 | eht_cap->eht_cap_elem.phy_cap_info) || | ||
| 1780 | nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET, | ||
| 1781 | mcs_nss_size, &eht_cap->eht_mcs_nss_supp) || | ||
| 1782 | nla_put(msg, NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE, | ||
| 1783 | ppe_thresh_size, eht_cap->eht_ppe_thres)) | ||
| 1784 | return -ENOBUFS; | ||
| 1785 | } | ||
| 1786 | |||
| 1760 | if (sband->band == NL80211_BAND_6GHZ && | 1787 | if (sband->band == NL80211_BAND_6GHZ && |
| 1761 | nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, | 1788 | nla_put(msg, NL80211_BAND_IFTYPE_ATTR_HE_6GHZ_CAPA, |
| 1762 | sizeof(iftdata->he_6ghz_capa), | 1789 | sizeof(iftdata->he_6ghz_capa), |