eht.c 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * EHT handling
  4. *
  5. * Copyright(c) 2021-2022 Intel Corporation
  6. */
  7. #include "ieee80211_i.h"
  8. void
  9. ieee80211_eht_cap_ie_to_sta_eht_cap(struct ieee80211_sub_if_data *sdata,
  10. struct ieee80211_supported_band *sband,
  11. const u8 *he_cap_ie, u8 he_cap_len,
  12. const struct ieee80211_eht_cap_elem *eht_cap_ie_elem,
  13. u8 eht_cap_len,
  14. struct link_sta_info *link_sta)
  15. {
  16. struct ieee80211_sta_eht_cap *eht_cap = &link_sta->pub->eht_cap;
  17. struct ieee80211_he_cap_elem *he_cap_ie_elem = (void *)he_cap_ie;
  18. u8 eht_ppe_size = 0;
  19. u8 mcs_nss_size;
  20. u8 eht_total_size = sizeof(eht_cap->eht_cap_elem);
  21. u8 *pos = (u8 *)eht_cap_ie_elem;
  22. memset(eht_cap, 0, sizeof(*eht_cap));
  23. if (!eht_cap_ie_elem ||
  24. !ieee80211_get_eht_iftype_cap(sband,
  25. ieee80211_vif_type_p2p(&sdata->vif)))
  26. return;
  27. mcs_nss_size = ieee80211_eht_mcs_nss_size(he_cap_ie_elem,
  28. &eht_cap_ie_elem->fixed,
  29. sdata->vif.type ==
  30. NL80211_IFTYPE_STATION);
  31. eht_total_size += mcs_nss_size;
  32. /* Calculate the PPE thresholds length only if the header is present */
  33. if (eht_cap_ie_elem->fixed.phy_cap_info[5] &
  34. IEEE80211_EHT_PHY_CAP5_PPE_THRESHOLD_PRESENT) {
  35. u16 eht_ppe_hdr;
  36. if (eht_cap_len < eht_total_size + sizeof(u16))
  37. return;
  38. eht_ppe_hdr = get_unaligned_le16(eht_cap_ie_elem->optional + mcs_nss_size);
  39. eht_ppe_size =
  40. ieee80211_eht_ppe_size(eht_ppe_hdr,
  41. eht_cap_ie_elem->fixed.phy_cap_info);
  42. eht_total_size += eht_ppe_size;
  43. /* we calculate as if NSS > 8 are valid, but don't handle that */
  44. if (eht_ppe_size > sizeof(eht_cap->eht_ppe_thres))
  45. return;
  46. }
  47. if (eht_cap_len < eht_total_size)
  48. return;
  49. /* Copy the static portion of the EHT capabilities */
  50. memcpy(&eht_cap->eht_cap_elem, pos, sizeof(eht_cap->eht_cap_elem));
  51. pos += sizeof(eht_cap->eht_cap_elem);
  52. /* Copy MCS/NSS which depends on the peer capabilities */
  53. memset(&eht_cap->eht_mcs_nss_supp, 0,
  54. sizeof(eht_cap->eht_mcs_nss_supp));
  55. memcpy(&eht_cap->eht_mcs_nss_supp, pos, mcs_nss_size);
  56. if (eht_ppe_size)
  57. memcpy(eht_cap->eht_ppe_thres,
  58. &eht_cap_ie_elem->optional[mcs_nss_size],
  59. eht_ppe_size);
  60. eht_cap->has_eht = true;
  61. link_sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(link_sta);
  62. link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta);
  63. }