0076-wifi-ath11k-MBSSID-beacon-support.patch 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. From 335a92765d308dfe22826f5562cd4b4389b45e71 Mon Sep 17 00:00:00 2001
  2. From: Aloka Dixit <quic_alokad@quicinc.com>
  3. Date: Fri, 5 May 2023 16:11:28 +0300
  4. Subject: [PATCH 76/77] wifi: ath11k: MBSSID beacon support
  5. - Split ath11k_mac_setup_bcn_tmpl() to move the beacon retrieval and
  6. WMI command to a new function, ath11k_mac_setup_bcn_tmpl_legacy().
  7. In the original function add checks to use the transmitting interface
  8. when MBSSID is enabled.
  9. - Set rsnie_present and wpaie_present fields for the non-transmitting
  10. interfaces when MBSSID is enabled.
  11. Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
  12. Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
  13. Co-developed-by: John Crispin <john@phrozen.org>
  14. Signed-off-by: John Crispin <john@phrozen.org>
  15. Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
  16. Link: https://lore.kernel.org/r/20230405221648.17950-7-quic_alokad@quicinc.com
  17. ---
  18. drivers/net/wireless/ath/ath11k/mac.c | 116 ++++++++++++++++++++++++--
  19. drivers/net/wireless/ath/ath11k/wmi.c | 1 +
  20. 2 files changed, 112 insertions(+), 5 deletions(-)
  21. --- a/drivers/net/wireless/ath/ath11k/mac.c
  22. +++ b/drivers/net/wireless/ath/ath11k/mac.c
  23. @@ -1351,6 +1351,84 @@ err_mon_del:
  24. return ret;
  25. }
  26. +static void ath11k_mac_setup_nontx_vif_rsnie(struct ath11k_vif *arvif,
  27. + bool tx_arvif_rsnie_present,
  28. + const u8 *profile, u8 profile_len)
  29. +{
  30. + if (cfg80211_find_ie(WLAN_EID_RSN, profile, profile_len)) {
  31. + arvif->rsnie_present = true;
  32. + } else if (tx_arvif_rsnie_present) {
  33. + int i;
  34. + u8 nie_len;
  35. + const u8 *nie = cfg80211_find_ext_ie(WLAN_EID_EXT_NON_INHERITANCE,
  36. + profile, profile_len);
  37. + if (!nie)
  38. + return;
  39. +
  40. + nie_len = nie[1];
  41. + nie += 2;
  42. + for (i = 0; i < nie_len; i++) {
  43. + if (nie[i] == WLAN_EID_RSN) {
  44. + arvif->rsnie_present = false;
  45. + break;
  46. + }
  47. + }
  48. + }
  49. +}
  50. +
  51. +static bool ath11k_mac_set_nontx_vif_params(struct ath11k_vif *tx_arvif,
  52. + struct ath11k_vif *arvif,
  53. + struct sk_buff *bcn)
  54. +{
  55. + struct ieee80211_mgmt *mgmt;
  56. + const u8 *ies, *profile, *next_profile;
  57. + int ies_len;
  58. +
  59. + ies = bcn->data + ieee80211_get_hdrlen_from_skb(bcn);
  60. + mgmt = (struct ieee80211_mgmt *)bcn->data;
  61. + ies += sizeof(mgmt->u.beacon);
  62. + ies_len = skb_tail_pointer(bcn) - ies;
  63. +
  64. + ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ies, ies_len);
  65. + arvif->rsnie_present = tx_arvif->rsnie_present;
  66. +
  67. + while (ies) {
  68. + u8 mbssid_len;
  69. +
  70. + ies_len -= (2 + ies[1]);
  71. + mbssid_len = ies[1] - 1;
  72. + profile = &ies[3];
  73. +
  74. + while (mbssid_len) {
  75. + u8 profile_len;
  76. +
  77. + profile_len = profile[1];
  78. + next_profile = profile + (2 + profile_len);
  79. + mbssid_len -= (2 + profile_len);
  80. +
  81. + profile += 2;
  82. + profile_len -= (2 + profile[1]);
  83. + profile += (2 + profile[1]); /* nontx capabilities */
  84. + profile_len -= (2 + profile[1]);
  85. + profile += (2 + profile[1]); /* SSID */
  86. + if (profile[2] == arvif->vif->bss_conf.bssid_index) {
  87. + profile_len -= 5;
  88. + profile = profile + 5;
  89. + ath11k_mac_setup_nontx_vif_rsnie(arvif,
  90. + tx_arvif->rsnie_present,
  91. + profile,
  92. + profile_len);
  93. + return true;
  94. + }
  95. + profile = next_profile;
  96. + }
  97. + ies = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, profile,
  98. + ies_len);
  99. + }
  100. +
  101. + return false;
  102. +}
  103. +
  104. static void ath11k_mac_set_vif_params(struct ath11k_vif *arvif,
  105. struct sk_buff *bcn)
  106. {
  107. @@ -1374,18 +1452,26 @@ static void ath11k_mac_set_vif_params(st
  108. arvif->wpaie_present = false;
  109. }
  110. -static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
  111. +static int ath11k_mac_setup_bcn_tmpl_mbssid(struct ath11k_vif *arvif)
  112. {
  113. struct ath11k *ar = arvif->ar;
  114. struct ath11k_base *ab = ar->ab;
  115. + struct ath11k_vif *tx_arvif = arvif;
  116. struct ieee80211_hw *hw = ar->hw;
  117. struct ieee80211_vif *vif = arvif->vif;
  118. struct ieee80211_mutable_offsets offs = {};
  119. struct sk_buff *bcn;
  120. int ret;
  121. - if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
  122. - return 0;
  123. + if (arvif->vif->mbssid_tx_vif) {
  124. + tx_arvif = (void *)arvif->vif->mbssid_tx_vif->drv_priv;
  125. + if (tx_arvif != arvif) {
  126. + ar = tx_arvif->ar;
  127. + ab = ar->ab;
  128. + hw = ar->hw;
  129. + vif = tx_arvif->vif;
  130. + }
  131. + }
  132. bcn = ieee80211_beacon_get_template(hw, vif, &offs, 0);
  133. if (!bcn) {
  134. @@ -1393,9 +1479,12 @@ static int ath11k_mac_setup_bcn_tmpl(str
  135. return -EPERM;
  136. }
  137. - ath11k_mac_set_vif_params(arvif, bcn);
  138. - ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
  139. + if (tx_arvif == arvif)
  140. + ath11k_mac_set_vif_params(tx_arvif, bcn);
  141. + else if (!ath11k_mac_set_nontx_vif_params(tx_arvif, arvif, bcn))
  142. + return -EINVAL;
  143. + ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn);
  144. kfree_skb(bcn);
  145. if (ret)
  146. @@ -1405,6 +1494,23 @@ static int ath11k_mac_setup_bcn_tmpl(str
  147. return ret;
  148. }
  149. +static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif)
  150. +{
  151. + struct ieee80211_vif *vif = arvif->vif;
  152. +
  153. + if (arvif->vdev_type != WMI_VDEV_TYPE_AP)
  154. + return 0;
  155. +
  156. + /* Target does not expect beacon templates for the already up
  157. + * non-transmitting interfaces, and results in a crash if sent.
  158. + */
  159. + if (vif->mbssid_tx_vif &&
  160. + arvif != (void *)vif->mbssid_tx_vif->drv_priv && arvif->is_up)
  161. + return 0;
  162. +
  163. + return ath11k_mac_setup_bcn_tmpl_mbssid(arvif);
  164. +}
  165. +
  166. void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
  167. {
  168. struct ieee80211_vif *vif = arvif->vif;
  169. --- a/drivers/net/wireless/ath/ath11k/wmi.c
  170. +++ b/drivers/net/wireless/ath/ath11k/wmi.c
  171. @@ -1737,6 +1737,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *a
  172. }
  173. cmd->buf_len = bcn->len;
  174. + cmd->mbssid_ie_offset = offs->mbssid_off;
  175. ptr = skb->data + sizeof(*cmd);