1 /*
2 * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for
6 * any purpose with or without fee is hereby granted, provided that the
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19
20 /**
21 * DOC: wma_he.c
22 *
23 * WLAN Host Device Driver 802.11ax - High Efficiency Implementation
24 */
25
26 #include "wma_he.h"
27 #include "wmi_unified_api.h"
28 #include "cds_utils.h"
29 #include "wma_internal.h"
30
31 /**
32 * wma_he_ppet_merge() - Merge PPET8 and PPET16 for a given ru and nss
33 * @host_ppet: pointer to dot11f array
34 * @byte_idx_p: pointer to byte index position where ppet should be added
35 * @used_p: pointer to used position
36 * @ppet: incoming PPET to be merged
37 *
38 * This function does the actual packing of dot11f structure. Split the
39 * incoming PPET(3 bits) to fit into an octet. If there are more than
40 * 3 bits available in a given byte_idx no splitting is required.
41 *
42 * Return: None
43 */
wma_he_ppet_merge(uint8_t * host_ppet,int * byte_idx_p,int * used_p,uint8_t ppet)44 static void wma_he_ppet_merge(uint8_t *host_ppet, int *byte_idx_p, int *used_p,
45 uint8_t ppet)
46 {
47 int byte_idx = *byte_idx_p, used = *used_p;
48 int lshift, rshift;
49
50 if (used <= (HE_BYTE_SIZE - HE_PPET_SIZE)) {
51 /* Enough space to fit the incoming PPET */
52 lshift = used;
53 host_ppet[byte_idx] |= (ppet << lshift);
54 used += HE_PPET_SIZE;
55 if (used == HE_BYTE_SIZE) {
56 used = 0;
57 byte_idx++;
58 }
59 } else {
60 /* Need to split the PPET */
61 lshift = used;
62 rshift = HE_BYTE_SIZE - used;
63 host_ppet[byte_idx] |= (ppet << lshift);
64 byte_idx++;
65 used = 0;
66 host_ppet[byte_idx] |= (ppet >> rshift);
67 used += HE_PPET_SIZE - rshift;
68 }
69
70 *byte_idx_p = byte_idx;
71 *used_p = used;
72 }
73
74 /**
75 * wma_he_populate_ppet() - Helper function for PPET conversion
76 * @ppet: pointer to fw array
77 * @nss: Number of NSS
78 * @ru: Number of RU
79 * @host_ppet: pointer to dot11f array
80 * @req_byte: Number of bytes in dot11f array
81 *
82 * This function retrieves PPET16/PPET8 pair for combination of NSS/RU
83 * and try to pack them in the OTA type dot11f structure by calling
84 * wma_he_ppet_merge.
85 *
86 * Return: None
87 */
wma_he_populate_ppet(uint32_t * ppet,int nss,int ru,uint8_t * host_ppet,int req_byte)88 static void wma_he_populate_ppet(uint32_t *ppet, int nss, int ru,
89 uint8_t *host_ppet, int req_byte)
90 {
91 int byte_idx = 0, used, i, j;
92 uint8_t ppet16, ppet8;
93
94 wma_debug("nss: %d ru: %d req_byte: %d", nss, ru, req_byte);
95 /* NSS and RU_IDX are already populated */
96 used = HE_PPET_NSS_RU_LEN;
97
98 for (i = 0; i < nss; i++) {
99 for (j = 1; j <= ru; j++) {
100 ppet16 = WMI_GET_PPET16(ppet, j, i);
101 ppet8 = WMI_GET_PPET8(ppet, j, i);
102 wma_nofl_debug("ppet16 (nss:%d ru:%d): %04x",
103 i, j, ppet16);
104 wma_nofl_debug("ppet8 (nss:%d ru:%d): %04x",
105 i, j, ppet8);
106 wma_he_ppet_merge(host_ppet, &byte_idx, &used, ppet16);
107 wma_he_ppet_merge(host_ppet, &byte_idx, &used, ppet8);
108 }
109 }
110
111 }
112
113 /**
114 * wma_convert_he_ppet() - convert WMI ppet structure to dot11f structure
115 * @he_ppet: pointer to dot11f ppet structure
116 * @ppet: pointer to FW ppet structure
117 *
118 * PPET info coming from FW is stored as described in WMI definition. Convert
119 * that into equivalent dot11f structure.
120 *
121 * Return: None
122 */
wma_convert_he_ppet(uint8_t * he_ppet,struct wmi_host_ppe_threshold * ppet)123 static void wma_convert_he_ppet(uint8_t *he_ppet,
124 struct wmi_host_ppe_threshold *ppet)
125 {
126 int bits, req_byte;
127 struct ppet_hdr *hdr;
128 uint8_t ru_count, mask;
129 struct ppe_threshold *ppet_1;
130
131 ppet_1 = NULL;
132 if (!ppet) {
133 wma_err("PPET is NULL");
134 qdf_mem_zero(he_ppet, HE_MAX_PPET_SIZE);
135 return;
136 }
137
138 hdr = (struct ppet_hdr *)he_ppet;
139 hdr->nss = ppet->numss_m1;
140 hdr->ru_idx_mask = ppet->ru_bit_mask;
141 mask = hdr->ru_idx_mask;
142 for (ru_count = 0; mask; mask >>= 1)
143 if (mask & 0x01)
144 ru_count++;
145
146 /*
147 * there will be two PPET for each NSS/RU pair
148 * PPET8 and PPET16, hence HE_PPET_SIZE * 2 bits for PPET
149 */
150 bits = HE_PPET_NSS_RU_LEN + ((hdr->nss + 1) * ru_count) *
151 (HE_PPET_SIZE * 2);
152
153 req_byte = (bits / HE_BYTE_SIZE) + 1;
154 wma_he_populate_ppet(ppet->ppet16_ppet8_ru3_ru0, hdr->nss + 1,
155 ru_count, he_ppet, req_byte);
156 }
157
158 /**
159 * wma_convert_he_cap() - convert HE capabilities into dot11f structure
160 * @he_cap: pointer to dot11f structure
161 * @mac_cap: Received HE MAC capability
162 * @phy_cap: Received HE PHY capability
163 * @supp_mcs: Max MCS supported (Tx/Rx)
164 * @tx_chain_mask: Tx chain mask
165 * @rx_chain_mask: Rx chain mask
166 * @mcs_12_13_support: Store the supported MCS 12/13 capability
167 *
168 * This function converts various HE capability received as part of extended
169 * service ready event into dot11f structure. GET macros are defined at WMI
170 * layer, use them to unpack the incoming FW capability.
171 *
172 * Return: None
173 */
wma_convert_he_cap(tDot11fIEhe_cap * he_cap,uint32_t * mac_cap,uint32_t * phy_cap,uint32_t supp_mcs,uint32_t tx_chain_mask,uint32_t rx_chain_mask,uint16_t * mcs_12_13_supp)174 static void wma_convert_he_cap(tDot11fIEhe_cap *he_cap, uint32_t *mac_cap,
175 uint32_t *phy_cap, uint32_t supp_mcs,
176 uint32_t tx_chain_mask, uint32_t rx_chain_mask,
177 uint16_t *mcs_12_13_supp)
178 {
179 uint8_t nss, chan_width;
180 uint16_t rx_mcs_le_80, tx_mcs_le_80, rx_mcs_160, tx_mcs_160;
181
182 nss = QDF_MAX(wma_get_num_of_setbits_from_bitmask(tx_chain_mask),
183 wma_get_num_of_setbits_from_bitmask(rx_chain_mask));
184
185 he_cap->present = true;
186 /* HE MAC capabilities */
187 he_cap->htc_he = WMI_HECAP_MAC_HECTRL_GET(mac_cap[0]);
188 he_cap->twt_request = WMI_HECAP_MAC_TWTREQ_GET(mac_cap[0]);
189 he_cap->twt_responder = WMI_HECAP_MAC_TWTRSP_GET(mac_cap[0]);
190 he_cap->fragmentation = WMI_HECAP_MAC_HEFRAG_GET(mac_cap[0]);
191 he_cap->max_num_frag_msdu_amsdu_exp =
192 WMI_HECAP_MAC_MAXFRAGMSDU_GET(mac_cap[0]);
193 he_cap->min_frag_size = WMI_HECAP_MAC_MINFRAGSZ_GET(mac_cap[0]);
194 he_cap->trigger_frm_mac_pad = WMI_HECAP_MAC_TRIGPADDUR_GET(mac_cap[0]);
195 he_cap->multi_tid_aggr_rx_supp =
196 WMI_HECAP_MAC_ACKMTIDAMPDU_GET(mac_cap[0]);
197 he_cap->he_link_adaptation = WMI_HECAP_MAC_HELINK_ADPT_GET(mac_cap[0]);
198 he_cap->all_ack = WMI_HECAP_MAC_AACK_GET(mac_cap[0]);
199 he_cap->trigd_rsp_sched = WMI_HECAP_MAC_TRS_GET(mac_cap[0]);
200 he_cap->a_bsr = WMI_HECAP_MAC_BSR_GET(mac_cap[0]);
201 he_cap->broadcast_twt = WMI_HECAP_MAC_BCSTTWT_GET(mac_cap[0]);
202 he_cap->ba_32bit_bitmap = WMI_HECAP_MAC_32BITBA_GET(mac_cap[0]);
203 he_cap->mu_cascade = WMI_HECAP_MAC_MUCASCADE_GET(mac_cap[0]);
204 he_cap->ack_enabled_multitid =
205 WMI_HECAP_MAC_ACKMTIDAMPDU_GET(mac_cap[0]);
206 he_cap->omi_a_ctrl = WMI_HECAP_MAC_OMI_GET(mac_cap[0]);
207 he_cap->ofdma_ra = WMI_HECAP_MAC_OFDMARA_GET(mac_cap[0]);
208 he_cap->max_ampdu_len_exp_ext =
209 WMI_HECAP_MAC_MAXAMPDULEN_EXP_GET(mac_cap[0]);
210 he_cap->amsdu_frag = WMI_HECAP_MAC_AMSDUFRAG_GET(mac_cap[0]);
211 he_cap->flex_twt_sched = WMI_HECAP_MAC_FLEXTWT_GET(mac_cap[0]);
212 he_cap->rx_ctrl_frame = WMI_HECAP_MAC_MBSS_GET(mac_cap[0]);
213 he_cap->bsrp_ampdu_aggr = WMI_HECAP_MAC_BSRPAMPDU_GET(mac_cap[1]);
214 he_cap->qtp = WMI_HECAP_MAC_QTP_GET(mac_cap[1]);
215 he_cap->a_bqr = WMI_HECAP_MAC_ABQR_GET(mac_cap[1]);
216 he_cap->spatial_reuse_param_rspder =
217 WMI_HECAP_MAC_SRPRESP_GET(mac_cap[1]);
218 he_cap->ndp_feedback_supp = WMI_HECAP_MAC_NDPFDBKRPT_GET(mac_cap[1]);
219 he_cap->ops_supp = WMI_HECAP_MAC_OPS_GET(mac_cap[1]);
220 he_cap->amsdu_in_ampdu = WMI_HECAP_MAC_AMSDUINAMPDU_GET(mac_cap[1]);
221 he_cap->multi_tid_aggr_tx_supp = WMI_HECAP_MAC_MTID_TX_GET(mac_cap[1]);
222 he_cap->he_sub_ch_sel_tx_supp =
223 WMI_HECAP_MAC_SUBCHANSELTX_GET(mac_cap[1]);
224 he_cap->ul_2x996_tone_ru_supp = WMI_HECAP_MAC_UL2X996RU_GET(mac_cap[1]);
225 he_cap->om_ctrl_ul_mu_data_dis_rx =
226 WMI_HECAP_MAC_OMCULMUDDIS_GET(mac_cap[1]);
227 he_cap->he_dynamic_smps =
228 WMI_HECAP_MAC_DYNSMPWRSAVE_GET(mac_cap[1]);
229 he_cap->punctured_sounding_supp =
230 WMI_HECAP_MAC_PUNCSOUNDING_GET(mac_cap[1]);
231 he_cap->ht_vht_trg_frm_rx_supp =
232 WMI_HECAP_MAC_HTVHTTRIGRX_GET(mac_cap[1]);
233 *mcs_12_13_supp = WMI_GET_BITS(mac_cap[1], 16, 16);
234 /* HE PHY capabilities */
235 chan_width = WMI_HECAP_PHY_CBW_GET(phy_cap);
236 he_cap->chan_width_0 = HE_CH_WIDTH_GET_BIT(chan_width, 0);
237 he_cap->chan_width_1 = HE_CH_WIDTH_GET_BIT(chan_width, 1);
238 he_cap->chan_width_2 = HE_CH_WIDTH_GET_BIT(chan_width, 2);
239 he_cap->chan_width_3 = HE_CH_WIDTH_GET_BIT(chan_width, 3);
240 he_cap->chan_width_4 = HE_CH_WIDTH_GET_BIT(chan_width, 4);
241 he_cap->chan_width_5 = HE_CH_WIDTH_GET_BIT(chan_width, 5);
242 he_cap->chan_width_6 = HE_CH_WIDTH_GET_BIT(chan_width, 6);
243 he_cap->rx_pream_puncturing = WMI_HECAP_PHY_PREAMBLEPUNCRX_GET(phy_cap);
244 he_cap->device_class = WMI_HECAP_PHY_COD_GET(phy_cap);
245 he_cap->ldpc_coding = WMI_HECAP_PHY_LDPC_GET(phy_cap);
246 he_cap->he_1x_ltf_800_gi_ppdu = WMI_HECAP_PHY_LTFGIFORHE_GET(phy_cap);
247 he_cap->midamble_tx_rx_max_nsts =
248 WMI_HECAP_PHY_MIDAMBLETXRXMAXNSTS_GET(phy_cap);
249 he_cap->he_4x_ltf_3200_gi_ndp = WMI_HECAP_PHY_LTFGIFORNDP_GET(phy_cap);
250 he_cap->rx_stbc_lt_80mhz = WMI_HECAP_PHY_RXSTBC_GET(phy_cap);
251 he_cap->tb_ppdu_tx_stbc_lt_80mhz = WMI_HECAP_PHY_TXSTBC_GET(phy_cap);
252 he_cap->rx_stbc_gt_80mhz = WMI_HECAP_PHY_STBCRXGT80_GET(phy_cap);
253 he_cap->tb_ppdu_tx_stbc_gt_80mhz =
254 WMI_HECAP_PHY_STBCTXGT80_GET(phy_cap);
255
256 he_cap->doppler = (WMI_HECAP_PHY_RXDOPPLER_GET(phy_cap) << 1) |
257 WMI_HECAP_PHY_TXDOPPLER(phy_cap);
258 he_cap->ul_mu = (WMI_HECAP_PHY_ULMUMIMOOFDMA_GET(phy_cap) << 1) |
259 WMI_HECAP_PHY_UL_MU_MIMO_GET(phy_cap);
260 he_cap->dcm_enc_tx = WMI_HECAP_PHY_DCMTX_GET(phy_cap);
261 he_cap->dcm_enc_rx = WMI_HECAP_PHY_DCMRX_GET(phy_cap);
262 he_cap->ul_he_mu = WMI_HECAP_PHY_ULHEMU_GET(phy_cap);
263 he_cap->su_beamformer = WMI_HECAP_PHY_SUBFMR_GET(phy_cap);
264 he_cap->su_beamformee = WMI_HECAP_PHY_SUBFME_GET(phy_cap);
265 he_cap->mu_beamformer = WMI_HECAP_PHY_MUBFMR_GET(phy_cap);
266 he_cap->bfee_sts_lt_80 = WMI_HECAP_PHY_BFMESTSLT80MHZ_GET(phy_cap);
267 he_cap->bfee_sts_gt_80 = WMI_HECAP_PHY_BFMESTSGT80MHZ_GET(phy_cap);
268 he_cap->num_sounding_lt_80 = WMI_HECAP_PHY_NUMSOUNDLT80MHZ_GET(phy_cap);
269 he_cap->num_sounding_gt_80 = WMI_HECAP_PHY_NUMSOUNDGT80MHZ_GET(phy_cap);
270 he_cap->su_feedback_tone16 =
271 WMI_HECAP_PHY_NG16SUFEEDBACKLT80_GET(phy_cap);
272 he_cap->mu_feedback_tone16 =
273 WMI_HECAP_PHY_NG16MUFEEDBACKGT80_GET(phy_cap);
274 he_cap->codebook_su = WMI_HECAP_PHY_CODBK42SU_GET(phy_cap);
275 he_cap->codebook_mu = WMI_HECAP_PHY_CODBK75MU_GET(phy_cap);
276 he_cap->beamforming_feedback =
277 WMI_HECAP_PHY_BFFEEDBACKTRIG_GET(phy_cap);
278 he_cap->he_er_su_ppdu = WMI_HECAP_PHY_HEERSU_GET(phy_cap);
279 he_cap->dl_mu_mimo_part_bw =
280 WMI_HECAP_PHY_DLMUMIMOPARTIALBW_GET(phy_cap);
281 he_cap->ppet_present = WMI_HECAP_PHY_PETHRESPRESENT_GET(phy_cap);
282 he_cap->srp = WMI_HECAP_PHY_SRPSPRESENT_GET(phy_cap);
283 he_cap->power_boost = WMI_HECAP_PHY_PWRBOOSTAR_GET(phy_cap);
284 he_cap->he_ltf_800_gi_4x =
285 WMI_HECAP_PHY_4XLTFAND800NSECSGI_GET(phy_cap);
286 he_cap->max_nc = WMI_HECAP_PHY_MAXNC_GET(phy_cap);
287 he_cap->tb_ppdu_tx_stbc_gt_80mhz =
288 WMI_HECAP_PHY_STBCTXGT80_GET(phy_cap);
289 he_cap->rx_stbc_gt_80mhz = WMI_HECAP_PHY_STBCRXGT80_GET(phy_cap);
290 he_cap->er_he_ltf_800_gi_4x =
291 WMI_HECAP_PHY_ERSU4X800NSECGI_GET(phy_cap);
292 he_cap->he_ppdu_20_in_40Mhz_2G =
293 WMI_HECAP_PHY_HEPPDU20IN40MHZ2G_GET(phy_cap);
294 he_cap->he_ppdu_20_in_160_80p80Mhz =
295 WMI_HECAP_PHY_HEPPDU20IN160OR80P80MHZ_GET(phy_cap);
296 he_cap->he_ppdu_80_in_160_80p80Mhz =
297 WMI_HECAP_PHY_HEPPDU80IN160OR80P80MHZ_GET(phy_cap);
298 he_cap->er_1x_he_ltf_gi = WMI_HECAP_PHY_ERSU1X800NSECGI_GET(phy_cap);
299 he_cap->midamble_tx_rx_1x_he_ltf =
300 WMI_HECAP_PHY_MIDAMBLETXRX2XAND1XHELTF_GET(phy_cap);
301
302 he_cap->dcm_max_bw = WMI_HECAP_PHY_DCMMAXBW_GET(phy_cap);
303 he_cap->longer_than_16_he_sigb_ofdm_sym =
304 WMI_HECAP_PHY_LNG16SIGBSYMBSUPRT_GET(phy_cap);
305 he_cap->non_trig_cqi_feedback =
306 WMI_HECAP_PHY_NONTRIGCQIFEEDBK_GET(phy_cap);
307 he_cap->tx_1024_qam_lt_242_tone_ru =
308 WMI_HECAP_PHY_TX1024QAM242RUSUPRT_GET(phy_cap);
309 he_cap->rx_1024_qam_lt_242_tone_ru =
310 WMI_HECAP_PHY_RX1024QAM242RUSUPRT_GET(phy_cap);
311 he_cap->rx_full_bw_su_he_mu_compress_sigb =
312 WMI_HECAP_PHY_RXFULBWSUWCMPRSSIGB_GET(phy_cap);
313 he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb =
314 WMI_HECAP_PHY_RXFULBWSUWNONCMPRSSIGB_GET(phy_cap);
315
316 /*
317 * supp_mcs is split into 16 bits with lower indicating le_80 and
318 * upper indicating 160 and 80_80.
319 */
320 wma_debug("supported_mcs: 0x%08x", supp_mcs);
321 rx_mcs_le_80 = supp_mcs & 0xFFFF;
322 tx_mcs_le_80 = supp_mcs & 0xFFFF;
323 rx_mcs_160 = (supp_mcs & 0xFFFF0000) >> 16;
324 tx_mcs_160 = (supp_mcs & 0xFFFF0000) >> 16;
325 /* if FW indicated it is using 1x1 disable upper NSS-MCS sets */
326 if (nss == NSS_1x1_MODE) {
327 rx_mcs_le_80 |= HE_MCS_INV_MSK_4_NSS(1);
328 tx_mcs_le_80 |= HE_MCS_INV_MSK_4_NSS(1);
329 rx_mcs_160 |= HE_MCS_INV_MSK_4_NSS(1);
330 tx_mcs_160 |= HE_MCS_INV_MSK_4_NSS(1);
331 }
332 he_cap->rx_he_mcs_map_lt_80 = rx_mcs_le_80;
333 he_cap->tx_he_mcs_map_lt_80 = tx_mcs_le_80;
334 *((uint16_t *)he_cap->tx_he_mcs_map_160) = rx_mcs_160;
335 *((uint16_t *)he_cap->rx_he_mcs_map_160) = tx_mcs_160;
336 *((uint16_t *)he_cap->rx_he_mcs_map_80_80) = rx_mcs_160;
337 *((uint16_t *)he_cap->tx_he_mcs_map_80_80) = tx_mcs_160;
338 }
339
340 /**
341 * wma_derive_ext_he_cap() - Derive HE caps based on given value
342 * @he_cap: pointer to given HE caps to be filled
343 * @new_he_cap: new HE cap info provided.
344 *
345 * This function takes the value provided in and combines it wht the incoming
346 * HE capability. After decoding, what ever value it gets,
347 * it takes the union(max) or intersection(min) with previously derived values.
348 * Currently, intersection(min) is taken for all the capabilities.
349 *
350 * Return: none
351 */
wma_derive_ext_he_cap(tDot11fIEhe_cap * he_cap,tDot11fIEhe_cap * new_cap,bool is_5g_cap)352 static void wma_derive_ext_he_cap(tDot11fIEhe_cap *he_cap,
353 tDot11fIEhe_cap *new_cap,
354 bool is_5g_cap)
355 {
356 uint16_t mcs_1, mcs_2;
357
358 if (!he_cap->present) {
359 /* First time update, copy the capability as is */
360 qdf_mem_copy(he_cap, new_cap, sizeof(*he_cap));
361 he_cap->present = true;
362 return;
363 }
364 /* Take union(max) or intersection(min) of the capabilities */
365 he_cap->htc_he = QDF_MIN(he_cap->htc_he, new_cap->htc_he);
366 he_cap->twt_request = QDF_MIN(he_cap->twt_request,
367 new_cap->twt_request);
368 he_cap->twt_responder = QDF_MIN(he_cap->twt_responder,
369 new_cap->twt_responder);
370 he_cap->fragmentation = QDF_MIN(he_cap->fragmentation,
371 new_cap->fragmentation);
372 he_cap->max_num_frag_msdu_amsdu_exp = QDF_MIN(
373 he_cap->max_num_frag_msdu_amsdu_exp,
374 new_cap->max_num_frag_msdu_amsdu_exp);
375 he_cap->min_frag_size = QDF_MIN(he_cap->min_frag_size,
376 new_cap->min_frag_size);
377 he_cap->trigger_frm_mac_pad =
378 QDF_MIN(he_cap->trigger_frm_mac_pad,
379 new_cap->trigger_frm_mac_pad);
380 he_cap->multi_tid_aggr_rx_supp = QDF_MIN(he_cap->multi_tid_aggr_rx_supp,
381 new_cap->multi_tid_aggr_rx_supp);
382 he_cap->he_link_adaptation = QDF_MIN(he_cap->he_link_adaptation,
383 new_cap->he_link_adaptation);
384 he_cap->all_ack = QDF_MIN(he_cap->all_ack,
385 new_cap->all_ack);
386 he_cap->trigd_rsp_sched = QDF_MIN(he_cap->trigd_rsp_sched,
387 new_cap->trigd_rsp_sched);
388 he_cap->a_bsr = QDF_MIN(he_cap->a_bsr,
389 new_cap->a_bsr);
390 he_cap->broadcast_twt = QDF_MIN(he_cap->broadcast_twt,
391 new_cap->broadcast_twt);
392 he_cap->ba_32bit_bitmap = QDF_MIN(he_cap->ba_32bit_bitmap,
393 new_cap->ba_32bit_bitmap);
394 he_cap->mu_cascade = QDF_MIN(he_cap->mu_cascade,
395 new_cap->mu_cascade);
396 he_cap->ack_enabled_multitid =
397 QDF_MIN(he_cap->ack_enabled_multitid,
398 new_cap->ack_enabled_multitid);
399 he_cap->omi_a_ctrl = QDF_MIN(he_cap->omi_a_ctrl,
400 new_cap->omi_a_ctrl);
401 he_cap->ofdma_ra = QDF_MIN(he_cap->ofdma_ra,
402 new_cap->ofdma_ra);
403 he_cap->max_ampdu_len_exp_ext = QDF_MIN(he_cap->max_ampdu_len_exp_ext,
404 new_cap->max_ampdu_len_exp_ext);
405 he_cap->amsdu_frag = QDF_MIN(he_cap->amsdu_frag,
406 new_cap->amsdu_frag);
407 he_cap->flex_twt_sched = QDF_MIN(he_cap->flex_twt_sched,
408 new_cap->flex_twt_sched);
409 he_cap->rx_ctrl_frame = QDF_MIN(he_cap->rx_ctrl_frame,
410 new_cap->rx_ctrl_frame);
411 he_cap->bsrp_ampdu_aggr = QDF_MIN(he_cap->bsrp_ampdu_aggr,
412 new_cap->bsrp_ampdu_aggr);
413 he_cap->qtp = QDF_MIN(he_cap->qtp, new_cap->qtp);
414 he_cap->a_bqr = QDF_MIN(he_cap->a_bqr, new_cap->a_bqr);
415 he_cap->spatial_reuse_param_rspder = QDF_MIN(
416 he_cap->spatial_reuse_param_rspder,
417 new_cap->spatial_reuse_param_rspder);
418 he_cap->ndp_feedback_supp = QDF_MIN(he_cap->ndp_feedback_supp,
419 new_cap->ndp_feedback_supp);
420 he_cap->ops_supp = QDF_MIN(he_cap->ops_supp, new_cap->ops_supp);
421 he_cap->amsdu_in_ampdu = QDF_MIN(he_cap->amsdu_in_ampdu,
422 new_cap->amsdu_in_ampdu);
423
424 he_cap->chan_width_0 = he_cap->chan_width_0 | new_cap->chan_width_0;
425 he_cap->chan_width_1 = he_cap->chan_width_1 | new_cap->chan_width_1;
426 he_cap->chan_width_2 = he_cap->chan_width_2 | new_cap->chan_width_2;
427 he_cap->chan_width_3 = he_cap->chan_width_3 | new_cap->chan_width_3;
428 he_cap->chan_width_4 = he_cap->chan_width_4 | new_cap->chan_width_4;
429 he_cap->chan_width_5 = he_cap->chan_width_5 | new_cap->chan_width_5;
430 he_cap->chan_width_6 = he_cap->chan_width_6 | new_cap->chan_width_6;
431
432 he_cap->device_class = QDF_MIN(he_cap->device_class,
433 new_cap->device_class);
434 he_cap->ldpc_coding = QDF_MIN(he_cap->ldpc_coding,
435 new_cap->ldpc_coding);
436 he_cap->he_1x_ltf_800_gi_ppdu =
437 QDF_MIN(he_cap->he_1x_ltf_800_gi_ppdu,
438 new_cap->he_1x_ltf_800_gi_ppdu);
439 he_cap->midamble_tx_rx_max_nsts =
440 QDF_MIN(he_cap->midamble_tx_rx_max_nsts,
441 new_cap->midamble_tx_rx_max_nsts);
442 he_cap->he_4x_ltf_3200_gi_ndp =
443 QDF_MIN(he_cap->he_4x_ltf_3200_gi_ndp,
444 new_cap->he_4x_ltf_3200_gi_ndp);
445 he_cap->tb_ppdu_tx_stbc_lt_80mhz = QDF_MIN(
446 he_cap->tb_ppdu_tx_stbc_lt_80mhz,
447 new_cap->tb_ppdu_tx_stbc_lt_80mhz);
448 he_cap->rx_stbc_lt_80mhz = QDF_MIN(he_cap->rx_stbc_lt_80mhz,
449 new_cap->rx_stbc_lt_80mhz);
450 he_cap->doppler = QDF_MIN(he_cap->doppler,
451 new_cap->doppler);
452 he_cap->ul_mu = QDF_MIN(he_cap->ul_mu, new_cap->ul_mu);
453 he_cap->dcm_enc_tx = QDF_MIN(he_cap->dcm_enc_tx,
454 new_cap->dcm_enc_tx);
455 he_cap->dcm_enc_rx = QDF_MIN(he_cap->dcm_enc_rx,
456 new_cap->dcm_enc_rx);
457 he_cap->ul_he_mu = QDF_MIN(he_cap->ul_he_mu, new_cap->ul_he_mu);
458 he_cap->su_beamformer = QDF_MIN(he_cap->su_beamformer,
459 new_cap->su_beamformer);
460 he_cap->su_beamformee = QDF_MIN(he_cap->su_beamformee,
461 new_cap->su_beamformee);
462 he_cap->mu_beamformer = QDF_MIN(he_cap->mu_beamformer,
463 new_cap->mu_beamformer);
464 he_cap->bfee_sts_lt_80 = QDF_MIN(he_cap->bfee_sts_lt_80,
465 new_cap->bfee_sts_lt_80);
466 he_cap->bfee_sts_gt_80 = QDF_MIN(he_cap->bfee_sts_gt_80,
467 new_cap->bfee_sts_gt_80);
468 he_cap->num_sounding_lt_80 = QDF_MIN(he_cap->num_sounding_lt_80,
469 new_cap->num_sounding_lt_80);
470 he_cap->num_sounding_gt_80 = QDF_MIN(he_cap->num_sounding_gt_80,
471 new_cap->num_sounding_gt_80);
472 he_cap->su_feedback_tone16 = QDF_MIN(he_cap->su_feedback_tone16,
473 new_cap->su_feedback_tone16);
474 he_cap->mu_feedback_tone16 = QDF_MIN(he_cap->mu_feedback_tone16,
475 new_cap->mu_feedback_tone16);
476 he_cap->codebook_su = QDF_MIN(he_cap->codebook_su,
477 new_cap->codebook_su);
478 he_cap->codebook_mu = QDF_MIN(he_cap->codebook_mu,
479 new_cap->codebook_mu);
480 he_cap->beamforming_feedback =
481 QDF_MIN(he_cap->beamforming_feedback,
482 new_cap->beamforming_feedback);
483 he_cap->he_er_su_ppdu = QDF_MIN(he_cap->he_er_su_ppdu,
484 new_cap->he_er_su_ppdu);
485 he_cap->dl_mu_mimo_part_bw = QDF_MIN(he_cap->dl_mu_mimo_part_bw,
486 new_cap->dl_mu_mimo_part_bw);
487 he_cap->ppet_present = QDF_MIN(he_cap->ppet_present,
488 new_cap->ppet_present);
489 he_cap->srp = QDF_MIN(he_cap->srp, new_cap->srp);
490 he_cap->power_boost = QDF_MIN(he_cap->power_boost,
491 new_cap->power_boost);
492 he_cap->he_ltf_800_gi_4x = QDF_MIN(he_cap->he_ltf_800_gi_4x,
493 new_cap->he_ltf_800_gi_4x);
494 he_cap->er_he_ltf_800_gi_4x =
495 QDF_MIN(he_cap->er_he_ltf_800_gi_4x,
496 new_cap->er_he_ltf_800_gi_4x);
497 he_cap->he_ppdu_20_in_40Mhz_2G =
498 QDF_MIN(he_cap->he_ppdu_20_in_40Mhz_2G,
499 new_cap->he_ppdu_20_in_40Mhz_2G);
500 he_cap->he_ppdu_20_in_160_80p80Mhz =
501 QDF_MIN(he_cap->he_ppdu_20_in_160_80p80Mhz,
502 new_cap->he_ppdu_20_in_160_80p80Mhz);
503 he_cap->he_ppdu_80_in_160_80p80Mhz =
504 QDF_MIN(he_cap->he_ppdu_80_in_160_80p80Mhz,
505 new_cap->he_ppdu_80_in_160_80p80Mhz);
506 he_cap->er_1x_he_ltf_gi = QDF_MIN(he_cap->er_1x_he_ltf_gi,
507 new_cap->er_1x_he_ltf_gi);
508 he_cap->midamble_tx_rx_1x_he_ltf =
509 QDF_MIN(he_cap->midamble_tx_rx_1x_he_ltf,
510 new_cap->midamble_tx_rx_1x_he_ltf);
511 he_cap->reserved2 = QDF_MIN(he_cap->reserved2,
512 new_cap->reserved2);
513
514 /* take intersection for MCS map */
515 mcs_1 = he_cap->rx_he_mcs_map_lt_80;
516 mcs_2 = new_cap->rx_he_mcs_map_lt_80;
517 he_cap->rx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(mcs_1, mcs_2);
518 mcs_1 = he_cap->tx_he_mcs_map_lt_80;
519 mcs_2 = new_cap->tx_he_mcs_map_lt_80;
520 he_cap->tx_he_mcs_map_lt_80 = HE_INTERSECT_MCS(mcs_1, mcs_2);
521 if (is_5g_cap) {
522 he_cap->rx_pream_puncturing =
523 QDF_MIN(he_cap->rx_pream_puncturing,
524 new_cap->rx_pream_puncturing);
525 *((uint16_t *)he_cap->rx_he_mcs_map_160) =
526 *((uint16_t *)new_cap->rx_he_mcs_map_160);
527 *((uint16_t *)he_cap->tx_he_mcs_map_160) =
528 *((uint16_t *)new_cap->tx_he_mcs_map_160);
529 *((uint16_t *)he_cap->rx_he_mcs_map_80_80) =
530 *((uint16_t *)new_cap->rx_he_mcs_map_80_80);
531 *((uint16_t *)he_cap->tx_he_mcs_map_80_80) =
532 *((uint16_t *)new_cap->tx_he_mcs_map_80_80);
533 }
534 }
535
wma_print_he_cap(tDot11fIEhe_cap * he_cap)536 void wma_print_he_cap(tDot11fIEhe_cap *he_cap)
537 {
538 uint8_t chan_width;
539 struct ppet_hdr *hdr;
540
541 if (!he_cap->present)
542 return;
543
544 /* HE MAC capabilities */
545 wma_debug("HE Cap: HTC-HE 0x%01x, TWT: Reqstor 0x%01x Respder 0x%01x, Frag 0x%02x, Max MSDUs 0x%03x, Min frag 0x%02x, Trigg MAC pad duration 0x%02x",
546 he_cap->htc_he, he_cap->twt_request, he_cap->twt_responder,
547 he_cap->fragmentation, he_cap->max_num_frag_msdu_amsdu_exp,
548 he_cap->min_frag_size, he_cap->trigger_frm_mac_pad);
549
550 wma_nofl_debug(" Multi-TID aggr RX 0x%03x, Link adapt 0x%02x, All ACK 0x%01x, Trigg resp sched 0x%01x, A-Buff status rpt 0x%01x, BC TWT 0x%01x, 32bit BA 0x%01x",
551 he_cap->multi_tid_aggr_rx_supp,
552 he_cap->he_link_adaptation, he_cap->all_ack,
553 he_cap->trigd_rsp_sched, he_cap->a_bsr,
554 he_cap->broadcast_twt, he_cap->ba_32bit_bitmap);
555
556 wma_nofl_debug(" MU Cascading 0x%01x, ACK enabled Multi-TID 0x%01x, OMI A-Cntrl 0x%01x, OFDMA RA 0x%01x, Max A-MPDU 0x%02x, A-MSDU Frag 0x%01x, Flex TWT sched 0x%01x",
557 he_cap->mu_cascade, he_cap->ack_enabled_multitid,
558 he_cap->omi_a_ctrl, he_cap->ofdma_ra,
559 he_cap->max_ampdu_len_exp_ext, he_cap->amsdu_frag,
560 he_cap->flex_twt_sched);
561
562 wma_nofl_debug(" Rx Ctrl frame MBSS 0x%01x, BSRP A-MPDU Aggr 0x%01x, Quite Time Period 0x%01x, A-BQR 0x%01x, SR Respder 0x%01x, ndp FB 0x%01x, ops supp 0x%01x",
563 he_cap->rx_ctrl_frame, he_cap->bsrp_ampdu_aggr,
564 he_cap->qtp, he_cap->a_bqr,
565 he_cap->spatial_reuse_param_rspder,
566 he_cap->ndp_feedback_supp, he_cap->ops_supp);
567
568 wma_nofl_debug(" Amsdu in ampdu 0x%01x, Multi-TID aggr 0x%03x, sub ch sel tx 0x%01x, UL 2x996tone RU 0x%01x, OM ctrl ULMU dis rx 0x%01x, DSMPS 0x%01x",
569 he_cap->amsdu_in_ampdu, he_cap->multi_tid_aggr_tx_supp,
570 he_cap->he_sub_ch_sel_tx_supp,
571 he_cap->ul_2x996_tone_ru_supp,
572 he_cap->om_ctrl_ul_mu_data_dis_rx,
573 he_cap->he_dynamic_smps);
574
575 /* HE PHY capabilities */
576 chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
577 he_cap->chan_width_1, he_cap->chan_width_2,
578 he_cap->chan_width_3, he_cap->chan_width_4,
579 he_cap->chan_width_5, he_cap->chan_width_6);
580
581 wma_nofl_debug(" Punctured sounding 0x%01x, HTVHT Trigg frame Rx 0x%01x, Chan width 0x%07x, Preamble punct Rx 0x%04x, device class 0x%01x, LDPC 0x%01x",
582 he_cap->punctured_sounding_supp,
583 he_cap->ht_vht_trg_frm_rx_supp, chan_width,
584 he_cap->rx_pream_puncturing, he_cap->device_class,
585 he_cap->ldpc_coding);
586
587 wma_nofl_debug(" LTF and GI for HE PPDUs 0x%02x, Midamble Tx Rx MAX NSTS 0x%02x, LTF and GI for NDP 0x%02x, TB PPDU STBC Tx support LE 80MHz 0x%01x",
588 he_cap->he_1x_ltf_800_gi_ppdu,
589 he_cap->midamble_tx_rx_max_nsts,
590 he_cap->he_4x_ltf_3200_gi_ndp,
591 he_cap->tb_ppdu_tx_stbc_lt_80mhz);
592
593 wma_nofl_debug(" STBC Rx support LE 80Mhz 0x%01x, Doppler 0x%02x, UL MU: 0x%02x, DCM encoding: Tx 0x%03x Rx 0x%03x, HE MU PPDU payload 0x%01x",
594 he_cap->rx_stbc_lt_80mhz, he_cap->doppler, he_cap->ul_mu,
595 he_cap->dcm_enc_tx, he_cap->dcm_enc_rx,
596 he_cap->ul_he_mu);
597
598 wma_nofl_debug(" SU: Bfer 0x%01x Bfee 0x%01x, MU Bfer 0x%01x, Bfee STS: LE 80Mhz 0x%03x GT 80Mhz 0x%03x, No. of sounding dim: LE 80Mhz 0x%03x GT 80Mhz 0x%03x",
599 he_cap->su_beamformer, he_cap->su_beamformee,
600 he_cap->mu_beamformer, he_cap->bfee_sts_lt_80,
601 he_cap->bfee_sts_gt_80, he_cap->num_sounding_lt_80,
602 he_cap->num_sounding_gt_80);
603
604 wma_nofl_debug(" Ng=16 FB: SU 0x%01x MU 0x%01x, Codebook size: SU 0x%01x MU 0x%01x, Bfing trigger w/ Trigger 0x%01x, ER SU PPDU payload 0x%01x",
605 he_cap->su_feedback_tone16, he_cap->mu_feedback_tone16,
606 he_cap->codebook_su, he_cap->codebook_mu,
607 he_cap->beamforming_feedback, he_cap->he_er_su_ppdu);
608
609 wma_nofl_debug(" DL MUMIMO on partial BW: 0x%01x, PPET 0x%01x, SRP 0x%01x, Power boost 0x%01x, 4x HE LTF 0x%01x, Max NC 0x%01x, TB PPDU stbc Tx GT 80Mhz 0x%01x",
610 he_cap->dl_mu_mimo_part_bw, he_cap->ppet_present,
611 he_cap->srp, he_cap->power_boost,
612 he_cap->he_ltf_800_gi_4x, he_cap->max_nc,
613 he_cap->tb_ppdu_tx_stbc_gt_80mhz);
614
615 wma_nofl_debug(" STBC Rx GT 80Mhz 0x%01x, er ltf 800 gt 4x 0x%01x, ppdu 20: 40Mhz 2G 0x%01x 160_80p80Mhz 0x%01x, ppdu 80 160_80p80Mhz 0x%01x",
616 he_cap->rx_stbc_gt_80mhz,
617 he_cap->er_he_ltf_800_gi_4x,
618 he_cap->he_ppdu_20_in_40Mhz_2G,
619 he_cap->he_ppdu_20_in_160_80p80Mhz,
620 he_cap->he_ppdu_80_in_160_80p80Mhz);
621
622 wma_nofl_debug(" ER 1X LTF GI 0x%01x, midamble tx/rx 1x LTF 0x%01x, DCM max BW 0x%02x, LT 16 sigb ofdm sym 0x%01x, non-trig cqi fb 0x%01x",
623 he_cap->er_1x_he_ltf_gi,
624 he_cap->midamble_tx_rx_1x_he_ltf, he_cap->dcm_max_bw,
625 he_cap->longer_than_16_he_sigb_ofdm_sym,
626 he_cap->non_trig_cqi_feedback);
627
628 wma_nofl_debug(" 1024 QAM LT 242 tone ru: Tx 0x%01x RX 0x%01x, RX full BW SU MU SIGB: Compress 0x%01x non compress 0x%01x",
629 he_cap->tx_1024_qam_lt_242_tone_ru,
630 he_cap->rx_1024_qam_lt_242_tone_ru,
631 he_cap->rx_full_bw_su_he_mu_compress_sigb,
632 he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb);
633
634 /* HE PPET */
635 hdr = (struct ppet_hdr *)&he_cap->ppet.ppe_threshold.ppe_th[0];
636 wma_nofl_debug(" RX MCS: LE 80MHz 0x%x 160MHz 0x%x 80+80MHz 0x%x, TX MCS: LE 80MHz 0x%x 160MHz 0x%x 80+80MHz 0x%x, NSS %d, RU index 0x%04x, num ppet %d",
637 he_cap->rx_he_mcs_map_lt_80,
638 *((uint16_t *)he_cap->rx_he_mcs_map_160),
639 *((uint16_t *)he_cap->rx_he_mcs_map_80_80),
640 he_cap->tx_he_mcs_map_lt_80,
641 *((uint16_t *)he_cap->tx_he_mcs_map_160),
642 *((uint16_t *)he_cap->tx_he_mcs_map_80_80),
643 hdr->nss + 1, hdr->ru_idx_mask,
644 he_cap->ppet.ppe_threshold.num_ppe_th);
645 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG,
646 he_cap->ppet.ppe_threshold.ppe_th,
647 he_cap->ppet.ppe_threshold.num_ppe_th);
648 }
649
wma_print_he_ppet(void * he_ppet)650 void wma_print_he_ppet(void *he_ppet)
651 {
652 int numss, ru_count, ru_bit_mask, i, j;
653 struct wmi_host_ppe_threshold *ppet = he_ppet;
654
655 if (!ppet) {
656 wma_err("PPET is NULL");
657 return;
658 }
659
660 numss = ppet->numss_m1 + 1;
661 ru_bit_mask = ppet->ru_bit_mask;
662
663 wma_debug("HE PPET: ru_idx_mask: %04x", ru_bit_mask);
664 for (ru_count = 0; ru_bit_mask; ru_bit_mask >>= 1)
665 if (ru_bit_mask & 0x1)
666 ru_count++;
667 if (numss > WMI_HOST_MAX_NUM_SS) {
668 wma_err("invalid numss_m1 %d", ppet->numss_m1);
669 return;
670 }
671 if (ru_count > HE_PEPT_RU_IDX_LEN) {
672 wma_err("invalid ru_count 0x%08x", ppet->ru_bit_mask);
673 return;
674 }
675
676 if (ru_count > 0) {
677 wma_debug("PPET has following RU INDEX,");
678 if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX0_MASK)
679 wma_nofl_debug("\tRU ALLOCATION INDEX 0");
680 if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX1_MASK)
681 wma_nofl_debug("\tRU ALLOCATION INDEX 1");
682 if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX2_MASK)
683 wma_nofl_debug("\tRU ALLOCATION INDEX 2");
684 if (ppet->ru_bit_mask & HE_RU_ALLOC_INDX3_MASK)
685 wma_nofl_debug("\tRU ALLOCATION INDEX 3");
686 }
687
688 wma_debug("HE PPET: nss: %d, ru_count: %d", numss, ru_count);
689
690 for (i = 0; i < numss; i++) {
691 wma_nofl_debug("PPET for NSS[%d]", i);
692 for (j = 1; j <= ru_count; j++) {
693 wma_nofl_debug("\tNSS[%d],RU[%d]: PPET16: %02x PPET8: %02x",
694 i, j,
695 WMI_GET_PPET16(ppet->ppet16_ppet8_ru3_ru0, j, i),
696 WMI_GET_PPET8(ppet->ppet16_ppet8_ru3_ru0, j, i));
697 }
698 }
699
700 }
701
wma_print_he_phy_cap(uint32_t * phy_cap)702 void wma_print_he_phy_cap(uint32_t *phy_cap)
703 {
704 wma_debug("HE PHY Caps: Chan width 0x%07x, Preamble punct Rx 0x%04x, dev class 0x%01x, LDPC 0x%01x, LTF and GI: HE PPDUs 0x%02x NDP 0x%02x",
705 WMI_HECAP_PHY_CBW_GET(phy_cap),
706 WMI_HECAP_PHY_PREAMBLEPUNCRX_GET(phy_cap),
707 WMI_HECAP_PHY_COD_GET(phy_cap),
708 WMI_HECAP_PHY_LDPC_GET(phy_cap),
709 WMI_HECAP_PHY_LTFGIFORHE_GET(phy_cap),
710 WMI_HECAP_PHY_LTFGIFORNDP_GET(phy_cap));
711
712 wma_nofl_debug(" STBC Tx & Rx support LE 80Mhz 0x%02x, Doppler 0x%02x, UL MU: Full BW 0x%01x Partial BW 0x%01x, DCM encoding: TX 0x%03x RX 0x%03x",
713 (WMI_HECAP_PHY_RXSTBC_GET(phy_cap) << 1) |
714 WMI_HECAP_PHY_TXSTBC_GET(phy_cap),
715 (WMI_HECAP_PHY_RXDOPPLER_GET(phy_cap) << 1) |
716 WMI_HECAP_PHY_TXDOPPLER(phy_cap),
717 WMI_HECAP_PHY_UL_MU_MIMO_GET(phy_cap),
718 WMI_HECAP_PHY_ULMUMIMOOFDMA_GET(phy_cap),
719 WMI_HECAP_PHY_DCMTX_GET(phy_cap),
720 WMI_HECAP_PHY_DCMRX_GET(phy_cap));
721
722 wma_nofl_debug(" HE MU PPDU payload 0x%01x, SU: Bfer 0x%01x Bfee 0x%01x, MU Bfer 0x%01x, Bfee STS: LE 80Mhz 0x%03x GT 80Mhz 0x%03x",
723 WMI_HECAP_PHY_ULHEMU_GET(phy_cap),
724 WMI_HECAP_PHY_SUBFMR_GET(phy_cap),
725 WMI_HECAP_PHY_SUBFME_GET(phy_cap),
726 WMI_HECAP_PHY_MUBFMR_GET(phy_cap),
727 WMI_HECAP_PHY_BFMESTSLT80MHZ_GET(phy_cap),
728 WMI_HECAP_PHY_BFMESTSGT80MHZ_GET(phy_cap));
729
730 wma_nofl_debug(" NSTS: LE 80Mhz 0x%03x GT 80Mhz 0x%03x, No of Sounding dim: LE 80Mhz 0x%03x GT 80Mhz 0x%03x, Ng=16 FB: SU 0x%01x MU 0x%01x",
731 WMI_HECAP_PHY_NSTSLT80MHZ_GET(phy_cap),
732 WMI_HECAP_PHY_NSTSGT80MHZ_GET(phy_cap),
733 WMI_HECAP_PHY_NUMSOUNDLT80MHZ_GET(phy_cap),
734 WMI_HECAP_PHY_NUMSOUNDGT80MHZ_GET(phy_cap),
735 WMI_HECAP_PHY_NG16SUFEEDBACKLT80_GET(phy_cap),
736 WMI_HECAP_PHY_NG16MUFEEDBACKGT80_GET(phy_cap));
737
738 wma_nofl_debug(" Codebook size: SU 0x%01x MU 0x%01x, Beamforming trigger w/ Trigger 0x%01x, HE ER SU PPDU 0x%01x, DL MUMIMO on partial BW 0x%01x",
739 WMI_HECAP_PHY_CODBK42SU_GET(phy_cap),
740 WMI_HECAP_PHY_CODBK75MU_GET(phy_cap),
741 WMI_HECAP_PHY_BFFEEDBACKTRIG_GET(phy_cap),
742 WMI_HECAP_PHY_HEERSU_GET(phy_cap),
743 WMI_HECAP_PHY_DLMUMIMOPARTIALBW_GET(phy_cap));
744 wma_nofl_debug(" PPET 0x%01x, SRP based SR 0x%01x, Power boost 0x%01x, 4x HE LTF 0x%01x, Max Nc 0x%03x, STBC Tx/Rx GT 80Mhz 0x%02x, ER 4x HE LTF 0x%01x",
745 WMI_HECAP_PHY_PETHRESPRESENT_GET(phy_cap),
746 WMI_HECAP_PHY_SRPSPRESENT_GET(phy_cap),
747 WMI_HECAP_PHY_PWRBOOSTAR_GET(phy_cap),
748 WMI_HECAP_PHY_4XLTFAND800NSECSGI_GET(phy_cap),
749 WMI_HECAP_PHY_MAXNC_GET(phy_cap),
750 (WMI_HECAP_PHY_STBCRXGT80_GET(phy_cap) << 1) |
751 WMI_HECAP_PHY_STBCTXGT80_GET(phy_cap),
752 WMI_HECAP_PHY_ERSU4X800NSECGI_GET(phy_cap));
753 }
754
wma_print_he_mac_cap_w1(uint32_t mac_cap)755 void wma_print_he_mac_cap_w1(uint32_t mac_cap)
756 {
757 wma_debug("HE MAC Caps: HTC-HE control 0x%01x, TWT Requestor 0x%01x, TWT Responder 0x%01x, Fragmentation 0x%02x, Max no.of MSDUs 0x%03x, Min. frag 0x%02x",
758 WMI_HECAP_MAC_HECTRL_GET(mac_cap),
759 WMI_HECAP_MAC_TWTREQ_GET(mac_cap),
760 WMI_HECAP_MAC_TWTRSP_GET(mac_cap),
761 WMI_HECAP_MAC_HEFRAG_GET(mac_cap),
762 WMI_HECAP_MAC_MAXFRAGMSDU_GET(mac_cap),
763 WMI_HECAP_MAC_MINFRAGSZ_GET(mac_cap));
764
765 wma_nofl_debug(" Trigger MAC pad dur 0x%02x, Multi-TID aggr Rx 0x%03x, Link adaptation 0x%02x, All ACK 0x%01x, UL MU resp sched 0x%01x, A-Buff status 0x%01x",
766 WMI_HECAP_MAC_TRIGPADDUR_GET(mac_cap),
767 WMI_HECAP_MAC_MTID_RX_GET(mac_cap),
768 WMI_HECAP_MAC_HELINK_ADPT_GET(mac_cap),
769 WMI_HECAP_MAC_AACK_GET(mac_cap),
770 WMI_HECAP_MAC_TRS_GET(mac_cap),
771 WMI_HECAP_MAC_BSR_GET(mac_cap));
772 wma_nofl_debug(" BC TWT 0x%01x, 32bit BA 0x%01x, MU Cascading 0x%01x, ACK enabled Multi-TID 0x%01x, OMI A-Control 0x%01x, OFDMA RA 0x%01x, Max A-MPDU 0x%02x",
773 WMI_HECAP_MAC_BCSTTWT_GET(mac_cap),
774 WMI_HECAP_MAC_32BITBA_GET(mac_cap),
775 WMI_HECAP_MAC_MUCASCADE_GET(mac_cap),
776 WMI_HECAP_MAC_ACKMTIDAMPDU_GET(mac_cap),
777 WMI_HECAP_MAC_OMI_GET(mac_cap),
778 WMI_HECAP_MAC_OFDMARA_GET(mac_cap),
779 WMI_HECAP_MAC_MAXAMPDULEN_EXP_GET(mac_cap));
780 wma_nofl_debug(" A-MSDU Fragmentation: 0x%01x, Flex. TWT sched 0x%01x, Rx Ctrl frame to MBSS: 0x%01x",
781 WMI_HECAP_MAC_AMSDUFRAG_GET(mac_cap),
782 WMI_HECAP_MAC_FLEXTWT_GET(mac_cap),
783 WMI_HECAP_MAC_MBSS_GET(mac_cap));
784 }
785
wma_print_he_mac_cap_w2(uint32_t mac_cap)786 void wma_print_he_mac_cap_w2(uint32_t mac_cap)
787 {
788 wma_nofl_debug(" BSRP A-MPDU Aggregation 0x%01x, Quite Time Period 0x%01x, A-BQR 0x%01x, SR Responder 0x%01x, NDP Feedback 0x%01x, OPS 0x%01x",
789 WMI_HECAP_MAC_BSRPAMPDU_GET(mac_cap),
790 WMI_HECAP_MAC_QTP_GET(mac_cap),
791 WMI_HECAP_MAC_ABQR_GET(mac_cap),
792 WMI_HECAP_MAC_SRPRESP_GET(mac_cap),
793 WMI_HECAP_MAC_NDPFDBKRPT_GET(mac_cap),
794 WMI_HECAP_MAC_OPS_GET(mac_cap));
795 wma_nofl_debug(" Multi-TID aggr Tx 0x%03x, Sub Ch selective Tx 0x%01x, UL 2x996 tone RU 0x%01x, OM ctrl UL MU data disable Rx: 0x%01x",
796 WMI_HECAP_MAC_MTID_TX_GET(mac_cap),
797 WMI_HECAP_MAC_SUBCHANSELTX_GET(mac_cap),
798 WMI_HECAP_MAC_UL2X996RU_GET(mac_cap),
799 WMI_HECAP_MAC_OMCULMUDDIS_GET(mac_cap));
800 }
801
wma_update_target_ext_he_cap(struct target_psoc_info * tgt_hdl,struct wma_tgt_cfg * tgt_cfg)802 void wma_update_target_ext_he_cap(struct target_psoc_info *tgt_hdl,
803 struct wma_tgt_cfg *tgt_cfg)
804 {
805 tDot11fIEhe_cap *he_cap = &tgt_cfg->he_cap;
806 int i, num_hw_modes, total_mac_phy_cnt;
807 struct wlan_psoc_host_mac_phy_caps *mac_cap, *mac_phy_cap;
808 tDot11fIEhe_cap he_cap_mac;
809 tDot11fIEhe_cap tmp_he_cap = {0};
810 bool is_5g_cap;
811
812 qdf_mem_zero(&tgt_cfg->he_cap_2g, sizeof(tgt_cfg->he_cap_2g));
813 qdf_mem_zero(&tgt_cfg->he_cap_5g, sizeof(tgt_cfg->he_cap_5g));
814 num_hw_modes = target_psoc_get_num_hw_modes(tgt_hdl);
815 mac_phy_cap = target_psoc_get_mac_phy_cap(tgt_hdl);
816 total_mac_phy_cnt = target_psoc_get_total_mac_phy_cnt(tgt_hdl);
817
818 if (!mac_phy_cap) {
819 wma_err("Invalid MAC PHY capabilities handle");
820 he_cap->present = false;
821 return;
822 }
823
824 if (!num_hw_modes) {
825 wma_err("No extended HE cap for current SOC");
826 he_cap->present = false;
827 return;
828 }
829
830 if (!tgt_cfg->services.en_11ax) {
831 wma_info("Target does not support 11AX");
832 he_cap->present = false;
833 return;
834 }
835
836 for (i = 0; i < total_mac_phy_cnt; i++) {
837 qdf_mem_zero(&he_cap_mac,
838 sizeof(tDot11fIEhe_cap));
839 mac_cap = &mac_phy_cap[i];
840 is_5g_cap = false;
841 if (mac_cap->supported_bands & WLAN_2G_CAPABILITY) {
842 wma_convert_he_cap(&he_cap_mac,
843 mac_cap->he_cap_info_2G,
844 mac_cap->he_cap_phy_info_2G,
845 mac_cap->he_supp_mcs_2G,
846 mac_cap->tx_chain_mask_2G,
847 mac_cap->rx_chain_mask_2G,
848 &tgt_cfg->he_mcs_12_13_supp_2g);
849 wma_debug("2g phy: nss: %d, ru_idx_msk: %d",
850 mac_cap->he_ppet2G.numss_m1,
851 mac_cap->he_ppet2G.ru_bit_mask);
852 wma_convert_he_ppet(tgt_cfg->ppet_2g,
853 (struct wmi_host_ppe_threshold *)
854 &mac_cap->he_ppet2G);
855 }
856
857 if (he_cap_mac.present) {
858 wma_derive_ext_he_cap(&tmp_he_cap,
859 &he_cap_mac,
860 is_5g_cap);
861 wma_derive_ext_he_cap(&tgt_cfg->he_cap_2g,
862 &he_cap_mac,
863 is_5g_cap);
864 }
865
866 qdf_mem_zero(&he_cap_mac,
867 sizeof(tDot11fIEhe_cap));
868 if (mac_cap->supported_bands & WLAN_5G_CAPABILITY) {
869 wma_convert_he_cap(&he_cap_mac,
870 mac_cap->he_cap_info_5G,
871 mac_cap->he_cap_phy_info_5G,
872 mac_cap->he_supp_mcs_5G,
873 mac_cap->tx_chain_mask_5G,
874 mac_cap->rx_chain_mask_5G,
875 &tgt_cfg->he_mcs_12_13_supp_5g);
876 wma_debug("5g phy: nss: %d, ru_idx_msk: %d",
877 mac_cap->he_ppet5G.numss_m1,
878 mac_cap->he_ppet5G.ru_bit_mask);
879 wma_convert_he_ppet(tgt_cfg->ppet_5g,
880 (struct wmi_host_ppe_threshold *)
881 &mac_cap->he_ppet5G);
882 is_5g_cap = true;
883 }
884 if (he_cap_mac.present) {
885 wma_derive_ext_he_cap(&tmp_he_cap,
886 &he_cap_mac,
887 is_5g_cap);
888 wma_derive_ext_he_cap(&tgt_cfg->he_cap_5g,
889 &he_cap_mac,
890 is_5g_cap);
891 }
892 }
893
894 qdf_mem_copy(he_cap, &tmp_he_cap, sizeof(*he_cap));
895 wma_print_he_cap(he_cap);
896 wma_debug("5 GHz HE caps:");
897 wma_print_he_cap(&tgt_cfg->he_cap_5g);
898 wma_debug("2.4 GHz HE caps:");
899 wma_print_he_cap(&tgt_cfg->he_cap_2g);
900 }
901
wma_he_update_tgt_services(struct wmi_unified * wmi_handle,struct wma_tgt_services * cfg)902 void wma_he_update_tgt_services(struct wmi_unified *wmi_handle,
903 struct wma_tgt_services *cfg)
904 {
905 if (wmi_service_enabled(wmi_handle, wmi_service_11ax)) {
906 cfg->en_11ax = true;
907 wma_set_fw_wlan_feat_caps(DOT11AX);
908 wma_debug("11ax is enabled");
909 } else {
910 wma_debug("11ax is not enabled");
911 }
912 }
913
wma_print_he_op(tDot11fIEhe_op * he_ops)914 void wma_print_he_op(tDot11fIEhe_op *he_ops)
915 {
916 wma_debug("bss_color %0x def_pe_dur %0x twt_req %0x txop_rts_thre %0x vht_oper %0x part_bss_color %0x, MBSSID AP %0x BSS color dis %0x",
917 he_ops->bss_color, he_ops->default_pe,
918 he_ops->twt_required, he_ops->txop_rts_threshold,
919 he_ops->vht_oper_present, he_ops->partial_bss_col,
920 he_ops->co_located_bss, he_ops->bss_col_disabled);
921 }
922
923 /**
924 * wma_parse_he_ppet() - Convert PPET stored in dot11f structure into FW
925 * structure.
926 * @rcvd_ppet: pointer to dot11f format PPET
927 * @peer_ppet: pointer peer_ppet to be sent in peer assoc
928 *
929 * This function converts the sequence of PPET stored in the host in OTA type
930 * structure into FW understandable structure to be sent as part of peer assoc
931 * command.
932 *
933 * Return: None
934 */
wma_parse_he_ppet(int8_t * rcvd_ppet,struct wmi_host_ppe_threshold * peer_ppet)935 static void wma_parse_he_ppet(int8_t *rcvd_ppet,
936 struct wmi_host_ppe_threshold *peer_ppet)
937 {
938 struct ppet_hdr *hdr;
939 uint8_t num_ppet, mask, mask1, mask2;
940 uint32_t ppet1, ppet2, ppet;
941 uint8_t bits, pad, pad_bits, req_byte;
942 uint8_t byte_idx, start, i, j, parsed;
943 uint32_t *ppet_r = peer_ppet->ppet16_ppet8_ru3_ru0;
944 uint8_t nss, ru;
945
946 hdr = (struct ppet_hdr *)rcvd_ppet;
947 nss = hdr->nss + 1;
948 mask = hdr->ru_idx_mask;
949 peer_ppet->numss_m1 = nss - 1;
950 peer_ppet->ru_bit_mask = mask;
951
952 for (ru = 0; mask; mask >>= 1) {
953 if (mask & 0x1)
954 ru++;
955 }
956
957 wma_debug("Rcvd nss=%d ru_idx_mask: %0x ru_count=%d",
958 nss, hdr->ru_idx_mask, ru);
959
960 /* each nss-ru pair have 2 PPET (PPET8/PPET16) */
961 bits = HE_PPET_NSS_RU_LEN + (nss + ru) * (HE_PPET_SIZE * 2);
962 pad = bits % HE_BYTE_SIZE;
963 pad_bits = HE_BYTE_SIZE - pad;
964 req_byte = (bits + pad_bits) / HE_BYTE_SIZE;
965
966 /*
967 * PPE Threshold Field Format
968 * +-----------+--------------+--------------------+-------------+
969 * | NSS | RU idx mask | PPE Threshold info | Padding |
970 * +-----------+--------------+--------------------+-------------+
971 * 3 4 1 + variable variable (bits)
972 *
973 * PPE Threshold Info field:
974 * number of NSS:n, number of RU: m
975 * +------------+-----------+-----+------------+-----------+-----+-----------+-----------+
976 * | PPET16 for | PPET8 for | ... | PPET16 for | PPET8 for | ... | PET16 for | PPET8 for |
977 * | NSS1, RU1 | NSS1, RU1 | ... | NSS1, RUm | NSS1, RUm | ... | NSSn, RUm | NSSn, RUm |
978 * +------------+-----------+-----+------------+-----------+-----+-----------+-----------+
979 * 3 3 ... 3 3 ... 3 3
980 */
981
982 /* first bit of first PPET is in the last bit of first byte */
983 parsed = HE_PPET_NSS_RU_LEN;
984
985 /*
986 * refer wmi_ppe_threshold defn to understand how ppet is stored.
987 * Index of ppet array(ppet16_ppet8_ru3_ru0) is the NSS value.
988 * Each item in ppet16_ppet8_ru3_ru0 holds ppet for all the RUs.
989 */
990 num_ppet = ru * 2; /* for each NSS */
991 for (i = 0; i < nss; i++) {
992 for (j = 1; j <= num_ppet; j++) {
993 start = parsed + (i * (num_ppet * HE_PPET_SIZE)) +
994 (j-1) * HE_PPET_SIZE;
995 byte_idx = start / HE_BYTE_SIZE;
996 start = start % HE_BYTE_SIZE;
997
998 if (start <= HE_BYTE_SIZE - HE_PPET_SIZE) {
999 mask = 0x07 << start;
1000 ppet = (rcvd_ppet[byte_idx] & mask) >> start;
1001 ppet_r[i] |= (ppet << (j - 1) * HE_PPET_SIZE);
1002 } else {
1003 mask1 = 0x07 << start;
1004 ppet1 = (rcvd_ppet[byte_idx] & mask1) >> start;
1005 mask2 = 0x07 >> (HE_BYTE_SIZE - start);
1006 ppet2 = (rcvd_ppet[byte_idx + 1] & mask2) <<
1007 (HE_BYTE_SIZE - start);
1008 ppet = ppet1 | ppet2;
1009 ppet_r[i] |= (ppet << (j - 1) * HE_PPET_SIZE);
1010 }
1011 wma_nofl_debug(" nss:%d ru:%d ppet_r:%0x", i, j / 2,
1012 ppet_r[i]);
1013 }
1014 }
1015 }
1016
wma_populate_peer_he_cap(struct peer_assoc_params * peer,tpAddStaParams params)1017 void wma_populate_peer_he_cap(struct peer_assoc_params *peer,
1018 tpAddStaParams params)
1019 {
1020 tDot11fIEhe_cap *he_cap = ¶ms->he_config;
1021 tDot11fIEhe_op *he_op = ¶ms->he_op;
1022 uint32_t *phy_cap = peer->peer_he_cap_phyinfo;
1023 uint32_t mac_cap[PSOC_HOST_MAX_MAC_SIZE] = {0}, he_ops = 0;
1024 uint8_t temp, i, chan_width;
1025
1026 if (!params->he_capable)
1027 return;
1028
1029 peer->he_flag = 1;
1030 peer->qos_flag = 1;
1031
1032 /* HE MAC capabilities */
1033 WMI_HECAP_MAC_HECTRL_SET(mac_cap[0], he_cap->htc_he);
1034 WMI_HECAP_MAC_TWTREQ_SET(mac_cap[0], he_cap->twt_request);
1035 WMI_HECAP_MAC_TWTRSP_SET(mac_cap[0], he_cap->twt_responder);
1036 WMI_HECAP_MAC_HEFRAG_SET(mac_cap[0], he_cap->fragmentation);
1037 WMI_HECAP_MAC_MAXFRAGMSDU_SET(mac_cap[0],
1038 he_cap->max_num_frag_msdu_amsdu_exp);
1039 WMI_HECAP_MAC_MINFRAGSZ_SET(mac_cap[0], he_cap->min_frag_size);
1040 WMI_HECAP_MAC_TRIGPADDUR_SET(mac_cap[0], he_cap->trigger_frm_mac_pad);
1041 WMI_HECAP_MAC_ACKMTIDAMPDU_SET(mac_cap[0],
1042 he_cap->multi_tid_aggr_rx_supp);
1043 WMI_HECAP_MAC_HELKAD_SET(mac_cap[0], he_cap->he_link_adaptation);
1044 WMI_HECAP_MAC_AACK_SET(mac_cap[0], he_cap->all_ack);
1045 WMI_HECAP_MAC_TRS_SET(mac_cap[0], he_cap->trigd_rsp_sched);
1046 WMI_HECAP_MAC_BSR_SET(mac_cap[0], he_cap->a_bsr);
1047 WMI_HECAP_MAC_BCSTTWT_SET(mac_cap[0], he_cap->broadcast_twt);
1048 WMI_HECAP_MAC_32BITBA_SET(mac_cap[0], he_cap->ba_32bit_bitmap);
1049 WMI_HECAP_MAC_MUCASCADE_SET(mac_cap[0], he_cap->mu_cascade);
1050 WMI_HECAP_MAC_ACKMTIDAMPDU_SET(mac_cap[0],
1051 he_cap->ack_enabled_multitid);
1052 WMI_HECAP_MAC_OMI_SET(mac_cap[0], he_cap->omi_a_ctrl);
1053 WMI_HECAP_MAC_OFDMARA_SET(mac_cap[0], he_cap->ofdma_ra);
1054 WMI_HECAP_MAC_MAXAMPDULEN_EXP_SET(mac_cap[0],
1055 he_cap->max_ampdu_len_exp_ext);
1056 WMI_HECAP_MAC_AMSDUFRAG_SET(mac_cap[0], he_cap->amsdu_frag);
1057 WMI_HECAP_MAC_FLEXTWT_SET(mac_cap[0], he_cap->flex_twt_sched);
1058 WMI_HECAP_MAC_MBSS_SET(mac_cap[0], he_cap->rx_ctrl_frame);
1059 WMI_HECAP_MAC_BSRPAMPDU_SET(mac_cap[1], he_cap->bsrp_ampdu_aggr);
1060 WMI_HECAP_MAC_QTP_SET(mac_cap[1], he_cap->qtp);
1061 WMI_HECAP_MAC_ABQR_SET(mac_cap[1], he_cap->a_bqr);
1062 WMI_HECAP_MAC_SRPRESP_SET(mac_cap[1],
1063 he_cap->spatial_reuse_param_rspder);
1064 WMI_HECAP_MAC_OPS_SET(mac_cap[1], he_cap->ops_supp);
1065 WMI_HECAP_MAC_NDPFDBKRPT_SET(mac_cap[1], he_cap->ndp_feedback_supp);
1066 WMI_HECAP_MAC_AMSDUINAMPDU_SET(mac_cap[1], he_cap->amsdu_in_ampdu);
1067 WMI_HECAP_MAC_MTID_TX_SET(mac_cap[1], he_cap->multi_tid_aggr_tx_supp);
1068 WMI_HECAP_MAC_SUBCHANSELTX_SET(mac_cap[1],
1069 he_cap->he_sub_ch_sel_tx_supp);
1070 WMI_HECAP_MAC_UL2X996RU_SET(mac_cap[1], he_cap->ul_2x996_tone_ru_supp);
1071 WMI_HECAP_MAC_OMCULMUDDIS_SET(mac_cap[1],
1072 he_cap->om_ctrl_ul_mu_data_dis_rx);
1073 WMI_HECAP_MAC_DYNSMPWRSAVE_SET(mac_cap[1], he_cap->he_dynamic_smps);
1074 WMI_HECAP_MAC_PUNCSOUNDING_SET(mac_cap[1],
1075 he_cap->punctured_sounding_supp);
1076 WMI_HECAP_MAC_HTVHTTRIGRX_SET(mac_cap[1],
1077 he_cap->ht_vht_trg_frm_rx_supp);
1078 qdf_mem_copy(peer->peer_he_cap_macinfo, mac_cap, sizeof(mac_cap));
1079
1080 /* HE PHY capabilities */
1081 chan_width = HE_CH_WIDTH_COMBINE(he_cap->chan_width_0,
1082 he_cap->chan_width_1, he_cap->chan_width_2,
1083 he_cap->chan_width_3, he_cap->chan_width_4,
1084 he_cap->chan_width_5, he_cap->chan_width_6);
1085 WMI_HECAP_PHY_CBW_SET(phy_cap, chan_width);
1086 WMI_HECAP_PHY_PREAMBLEPUNCRX_SET(phy_cap, he_cap->rx_pream_puncturing);
1087 WMI_HECAP_PHY_COD_SET(phy_cap, he_cap->device_class);
1088 WMI_HECAP_PHY_LDPC_SET(phy_cap, he_cap->ldpc_coding);
1089 WMI_HECAP_PHY_LTFGIFORHE_SET(phy_cap, he_cap->he_1x_ltf_800_gi_ppdu);
1090 WMI_HECAP_PHY_MIDAMBLETXRXMAXNSTS_SET(phy_cap,
1091 he_cap->midamble_tx_rx_max_nsts);
1092 WMI_HECAP_PHY_LTFGIFORNDP_SET(phy_cap, he_cap->he_4x_ltf_3200_gi_ndp);
1093
1094 WMI_HECAP_PHY_RXSTBC_SET(phy_cap, he_cap->rx_stbc_lt_80mhz);
1095 WMI_HECAP_PHY_TXSTBC_SET(phy_cap, he_cap->tb_ppdu_tx_stbc_lt_80mhz);
1096
1097 temp = he_cap->doppler & 0x1;
1098 WMI_HECAP_PHY_RXDOPPLER_SET(phy_cap, temp);
1099 temp = he_cap->doppler >> 0x1;
1100 WMI_HECAP_PHY_TXDOPPLER_SET(phy_cap, temp);
1101
1102 temp = he_cap->ul_mu & 0x1;
1103 WMI_HECAP_PHY_UL_MU_MIMO_SET(phy_cap, temp);
1104 temp = he_cap->ul_mu >> 0x1;
1105 WMI_HECAP_PHY_ULMUMIMOOFDMA_SET(phy_cap, temp);
1106
1107 WMI_HECAP_PHY_DCMTX_SET(phy_cap, he_cap->dcm_enc_tx);
1108 WMI_HECAP_PHY_DCMRX_SET(phy_cap, he_cap->dcm_enc_rx);
1109 WMI_HECAP_PHY_ULHEMU_SET(phy_cap, he_cap->ul_he_mu);
1110 WMI_HECAP_PHY_SUBFMR_SET(phy_cap, he_cap->su_beamformer);
1111 WMI_HECAP_PHY_SUBFME_SET(phy_cap, he_cap->su_beamformee);
1112 WMI_HECAP_PHY_MUBFMR_SET(phy_cap, he_cap->mu_beamformer);
1113 WMI_HECAP_PHY_BFMESTSLT80MHZ_SET(phy_cap, he_cap->bfee_sts_lt_80);
1114 WMI_HECAP_PHY_BFMESTSGT80MHZ_SET(phy_cap, he_cap->bfee_sts_gt_80);
1115 WMI_HECAP_PHY_NUMSOUNDLT80MHZ_SET(phy_cap, he_cap->num_sounding_lt_80);
1116 WMI_HECAP_PHY_NUMSOUNDGT80MHZ_SET(phy_cap, he_cap->num_sounding_gt_80);
1117 WMI_HECAP_PHY_NG16SUFEEDBACKLT80_SET(phy_cap,
1118 he_cap->su_feedback_tone16);
1119 WMI_HECAP_PHY_NG16MUFEEDBACKGT80_SET(phy_cap,
1120 he_cap->mu_feedback_tone16);
1121 WMI_HECAP_PHY_CODBK42SU_SET(phy_cap, he_cap->codebook_su);
1122 WMI_HECAP_PHY_CODBK75MU_SET(phy_cap, he_cap->codebook_mu);
1123 WMI_HECAP_PHY_BFFEEDBACKTRIG_SET(phy_cap, he_cap->beamforming_feedback);
1124 WMI_HECAP_PHY_HEERSU_SET(phy_cap, he_cap->he_er_su_ppdu);
1125 WMI_HECAP_PHY_DLMUMIMOPARTIALBW_SET(phy_cap,
1126 he_cap->dl_mu_mimo_part_bw);
1127 WMI_HECAP_PHY_PETHRESPRESENT_SET(phy_cap, he_cap->ppet_present);
1128 WMI_HECAP_PHY_SRPPRESENT_SET(phy_cap, he_cap->srp);
1129 WMI_HECAP_PHY_PWRBOOSTAR_SET(phy_cap, he_cap->power_boost);
1130 WMI_HECAP_PHY_4XLTFAND800NSECSGI_SET(phy_cap, he_cap->he_ltf_800_gi_4x);
1131
1132 WMI_HECAP_PHY_MAXNC_SET(phy_cap, he_cap->max_nc);
1133
1134 WMI_HECAP_PHY_STBCRXGT80_SET(phy_cap, he_cap->rx_stbc_gt_80mhz);
1135 WMI_HECAP_PHY_STBCTXGT80_SET(phy_cap, he_cap->tb_ppdu_tx_stbc_gt_80mhz);
1136
1137 WMI_HECAP_PHY_ERSU4X800NSECGI_SET(phy_cap, he_cap->er_he_ltf_800_gi_4x);
1138 WMI_HECAP_PHY_HEPPDU20IN40MHZ2G_SET(phy_cap,
1139 he_cap->he_ppdu_20_in_40Mhz_2G);
1140 WMI_HECAP_PHY_HEPPDU20IN160OR80P80MHZ_SET(phy_cap,
1141 he_cap->he_ppdu_20_in_160_80p80Mhz);
1142 WMI_HECAP_PHY_HEPPDU80IN160OR80P80MHZ_SET(phy_cap,
1143 he_cap->he_ppdu_80_in_160_80p80Mhz);
1144 WMI_HECAP_PHY_ERSU1X800NSECGI_SET(phy_cap, he_cap->er_1x_he_ltf_gi);
1145 WMI_HECAP_PHY_MIDAMBLETXRX2XAND1XHELTF_SET(phy_cap,
1146 he_cap->
1147 midamble_tx_rx_1x_he_ltf);
1148 WMI_HECAP_PHY_DCMMAXBW_SET(phy_cap, he_cap->dcm_max_bw);
1149 WMI_HECAP_PHY_LNG16SIGBSYMBSUPRT_SET(phy_cap,
1150 he_cap->
1151 longer_than_16_he_sigb_ofdm_sym);
1152 WMI_HECAP_PHY_NONTRIGCQIFEEDBK_SET(phy_cap,
1153 he_cap->non_trig_cqi_feedback);
1154 WMI_HECAP_PHY_TX1024QAM242RUSUPRT_SET(phy_cap,
1155 he_cap->
1156 tx_1024_qam_lt_242_tone_ru);
1157 WMI_HECAP_PHY_RX1024QAM242RUSUPRT_SET(phy_cap,
1158 he_cap->
1159 rx_1024_qam_lt_242_tone_ru);
1160 WMI_HECAP_PHY_RXFULBWSUWCMPRSSIGB_SET(phy_cap,
1161 he_cap->rx_full_bw_su_he_mu_compress_sigb);
1162 WMI_HECAP_PHY_RXFULBWSUWNONCMPRSSIGB_SET(phy_cap,
1163 he_cap->rx_full_bw_su_he_mu_non_cmpr_sigb);
1164
1165 /* as per 11ax draft 1.4 */
1166 peer->peer_he_mcs_count = 1;
1167 peer->peer_he_rx_mcs_set[0] =
1168 params->supportedRates.rx_he_mcs_map_lt_80;
1169 peer->peer_he_tx_mcs_set[0] =
1170 params->supportedRates.tx_he_mcs_map_lt_80;
1171 if (params->he_mcs_12_13_map) {
1172 peer->peer_he_tx_mcs_set[0] |=
1173 (params->he_mcs_12_13_map <<
1174 WMA_MCS_12_13_MAP_L80) & WMA_MCS_12_13_PEER_RATE_MAP;
1175 peer->peer_he_rx_mcs_set[0] |=
1176 (params->he_mcs_12_13_map <<
1177 WMA_MCS_12_13_MAP_L80) & WMA_MCS_12_13_PEER_RATE_MAP;
1178 }
1179
1180 if (params->ch_width > CH_WIDTH_80MHZ ||
1181 IS_TDLS_PEER(params->staType)) {
1182 peer->peer_he_mcs_count = WMI_HOST_MAX_HE_RATE_SET;
1183 peer->peer_he_rx_mcs_set[1] |=
1184 params->supportedRates.rx_he_mcs_map_160;
1185 peer->peer_he_tx_mcs_set[1] |=
1186 params->supportedRates.tx_he_mcs_map_160;
1187 peer->peer_he_rx_mcs_set[2] |=
1188 params->supportedRates.rx_he_mcs_map_80_80;
1189 peer->peer_he_tx_mcs_set[2] |=
1190 params->supportedRates.tx_he_mcs_map_80_80;
1191
1192 if (params->he_mcs_12_13_map) {
1193 peer->peer_he_tx_mcs_set[1] |=
1194 (params->he_mcs_12_13_map <<
1195 WMA_MCS_12_13_MAP_G80) &
1196 WMA_MCS_12_13_PEER_RATE_MAP;
1197 peer->peer_he_tx_mcs_set[2] |=
1198 (params->he_mcs_12_13_map <<
1199 WMA_MCS_12_13_MAP_G80) &
1200 WMA_MCS_12_13_PEER_RATE_MAP;
1201 peer->peer_he_rx_mcs_set[1] |=
1202 (params->he_mcs_12_13_map <<
1203 WMA_MCS_12_13_MAP_G80) &
1204 WMA_MCS_12_13_PEER_RATE_MAP;
1205 peer->peer_he_rx_mcs_set[2] |=
1206 (params->he_mcs_12_13_map <<
1207 WMA_MCS_12_13_MAP_G80) &
1208 WMA_MCS_12_13_PEER_RATE_MAP;
1209 }
1210 }
1211
1212 wma_debug("Sending TX/RX MCS set to FW: <=80: %x, 160: %x, 80+80: %x",
1213 peer->peer_he_rx_mcs_set[0], peer->peer_he_rx_mcs_set[1],
1214 peer->peer_he_rx_mcs_set[2]);
1215
1216 #define HE2x2MCSMASK 0xc
1217
1218 peer->peer_nss = ((params->supportedRates.rx_he_mcs_map_lt_80 &
1219 HE2x2MCSMASK) == HE2x2MCSMASK) ? 1 : 2;
1220 for (i = 0; i < peer->peer_he_mcs_count; i++)
1221 wma_debug("[HE - MCS Map: %d] rx_mcs: 0x%x, tx_mcs: 0x%x", i,
1222 peer->peer_he_rx_mcs_set[i],
1223 peer->peer_he_tx_mcs_set[i]);
1224
1225 WMI_HEOPS_COLOR_SET(he_ops, he_op->bss_color);
1226 WMI_HEOPS_DEFPE_SET(he_ops, he_op->default_pe);
1227 WMI_HEOPS_TWT_SET(he_ops, he_op->twt_required);
1228 WMI_HEOPS_RTSTHLD_SET(he_ops, he_op->txop_rts_threshold);
1229 WMI_HEOPS_ERSUDIS_SET(he_ops, he_op->er_su_disable);
1230 WMI_HEOPS_PARTBSSCOLOR_SET(he_ops, he_op->partial_bss_col);
1231 WMI_HEOPS_BSSCOLORDISABLE_SET(he_ops, he_op->bss_col_disabled);
1232 peer->peer_he_ops = he_ops;
1233
1234 wma_parse_he_ppet(he_cap->ppet.ppe_threshold.ppe_th, &peer->peer_ppet);
1235
1236 wma_print_he_cap(he_cap);
1237 wma_debug("Peer HE Caps:");
1238 wma_print_he_phy_cap(phy_cap);
1239 wma_print_he_mac_cap_w1(mac_cap[0]);
1240 wma_print_he_mac_cap_w2(mac_cap[1]);
1241 wma_print_he_ppet(&peer->peer_ppet);
1242
1243 if (params->he_6ghz_band_caps.present) {
1244 peer->peer_he_caps_6ghz =
1245 (params->he_6ghz_band_caps.min_mpdu_start_spacing <<
1246 HE_6G_MIN_MPDU_START_SAPCE_BIT_POS) |
1247 (params->he_6ghz_band_caps.max_ampdu_len_exp <<
1248 HE_6G_MAX_AMPDU_LEN_EXP_BIT_POS) |
1249 (params->he_6ghz_band_caps.max_mpdu_len <<
1250 HE_6G_MAX_MPDU_LEN_BIT_POS) |
1251 (params->he_6ghz_band_caps.sm_pow_save <<
1252 HE_6G_SMPS_BIT_POS) |
1253 (params->he_6ghz_band_caps.rd_responder <<
1254 HE_6G_RD_RESP_BIT_POS) |
1255 (params->he_6ghz_band_caps.rx_ant_pattern_consistency <<
1256 HE_6G_RX_ANT_PATTERN_BIT_POS) |
1257 (params->he_6ghz_band_caps.tx_ant_pattern_consistency <<
1258 HE_6G_TX_ANT_PATTERN_BIT_POS);
1259 wma_debug("HE 6GHz band caps: %0x", peer->peer_he_caps_6ghz);
1260 } else {
1261 peer->peer_he_caps_6ghz = 0;
1262 }
1263 }
1264
wma_update_vdev_he_ops(uint32_t * he_ops,tDot11fIEhe_op * he_op)1265 void wma_update_vdev_he_ops(uint32_t *he_ops, tDot11fIEhe_op *he_op)
1266 {
1267 WMI_HEOPS_COLOR_SET(*he_ops, he_op->bss_color);
1268 WMI_HEOPS_DEFPE_SET(*he_ops, he_op->default_pe);
1269 WMI_HEOPS_TWT_SET(*he_ops, he_op->twt_required);
1270 WMI_HEOPS_RTSTHLD_SET(*he_ops, he_op->txop_rts_threshold);
1271 WMI_HEOPS_PARTBSSCOLOR_SET(*he_ops, he_op->partial_bss_col);
1272 WMI_HEOPS_BSSCOLORDISABLE_SET(*he_ops, he_op->bss_col_disabled);
1273 }
1274
wma_vdev_set_he_bss_params(tp_wma_handle wma,uint8_t vdev_id,struct vdev_mlme_he_ops_info * he_info)1275 void wma_vdev_set_he_bss_params(tp_wma_handle wma, uint8_t vdev_id,
1276 struct vdev_mlme_he_ops_info *he_info)
1277 {
1278 QDF_STATUS ret;
1279
1280 if (!he_info->he_ops)
1281 return;
1282 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1283 wmi_vdev_param_set_heop, he_info->he_ops);
1284
1285 if (QDF_IS_STATUS_ERROR(ret))
1286 wma_err("Failed to set HE OPs");
1287 }
1288
wma_vdev_set_he_config(tp_wma_handle wma,uint8_t vdev_id,struct bss_params * add_bss)1289 void wma_vdev_set_he_config(tp_wma_handle wma, uint8_t vdev_id,
1290 struct bss_params *add_bss)
1291 {
1292 QDF_STATUS ret;
1293 int8_t pd_min, pd_max, sec_ch_ed, tx_pwr;
1294
1295 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1296 wmi_vdev_param_obsspd, add_bss->he_sta_obsspd);
1297 if (QDF_IS_STATUS_ERROR(ret))
1298 wma_err("Failed to set HE Config");
1299 pd_min = add_bss->he_sta_obsspd & 0xff,
1300 pd_max = (add_bss->he_sta_obsspd & 0xff00) >> 8,
1301 sec_ch_ed = (add_bss->he_sta_obsspd & 0xff0000) >> 16,
1302 tx_pwr = (add_bss->he_sta_obsspd & 0xff000000) >> 24;
1303 wma_debug("HE_STA_OBSSPD: PD_MIN: %d PD_MAX: %d SEC_CH_ED: %d TX_PWR: %d",
1304 pd_min, pd_max, sec_ch_ed, tx_pwr);
1305 }
1306
wma_update_he_ops_ie(tp_wma_handle wma,uint8_t vdev_id,tDot11fIEhe_op * he_op)1307 QDF_STATUS wma_update_he_ops_ie(tp_wma_handle wma, uint8_t vdev_id,
1308 tDot11fIEhe_op *he_op)
1309 {
1310 QDF_STATUS ret;
1311 uint32_t dword_he_op = 0;
1312
1313 if (wma_validate_handle(wma))
1314 return QDF_STATUS_E_FAILURE;
1315
1316 WMI_HEOPS_COLOR_SET(dword_he_op, he_op->bss_color);
1317 WMI_HEOPS_DEFPE_SET(dword_he_op, he_op->default_pe);
1318 WMI_HEOPS_TWT_SET(dword_he_op, he_op->twt_required);
1319 WMI_HEOPS_RTSTHLD_SET(dword_he_op, he_op->txop_rts_threshold);
1320 WMI_HEOPS_PARTBSSCOLOR_SET(dword_he_op, he_op->partial_bss_col);
1321 WMI_HEOPS_BSSCOLORDISABLE_SET(dword_he_op, he_op->bss_col_disabled);
1322
1323 wma_debug("vdev_id: %d HE_OPs: 0x%x", vdev_id, dword_he_op);
1324 ret = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1325 wmi_vdev_param_set_heop, dword_he_op);
1326
1327 if (QDF_IS_STATUS_ERROR(ret))
1328 wma_err("Failed to set HE OPs");
1329
1330 return ret;
1331 }
1332
wma_set_he_txbf_cfg(struct mac_context * mac,uint8_t vdev_id)1333 void wma_set_he_txbf_cfg(struct mac_context *mac, uint8_t vdev_id)
1334 {
1335 wma_set_he_txbf_params(vdev_id,
1336 mac->mlme_cfg->he_caps.dot11_he_cap.su_beamformer,
1337 mac->mlme_cfg->he_caps.dot11_he_cap.su_beamformee,
1338 mac->mlme_cfg->he_caps.dot11_he_cap.mu_beamformer);
1339 }
1340
wma_set_he_txbf_params(uint8_t vdev_id,bool su_bfer,bool su_bfee,bool mu_bfer)1341 void wma_set_he_txbf_params(uint8_t vdev_id, bool su_bfer,
1342 bool su_bfee, bool mu_bfer)
1343 {
1344 uint32_t hemu_mode;
1345 QDF_STATUS status;
1346 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
1347
1348 if (!wma)
1349 return;
1350
1351 hemu_mode = DOT11AX_HEMU_MODE;
1352 hemu_mode |= ((su_bfer << HE_SUBFER) | (su_bfee << HE_SUBFEE) |
1353 (mu_bfer << HE_MUBFER) | (su_bfee << HE_MUBFEE));
1354 /*
1355 * Enable / disable trigger access for a AP vdev's peers.
1356 * For a STA mode vdev this will enable/disable triggered
1357 * access and enable/disable Multi User mode of operation.
1358 * A value of 0 in a given bit disables corresponding mode.
1359 * bit | hemu mode
1360 * ---------------
1361 * 0 | HE SUBFEE
1362 * 1 | HE SUBFER
1363 * 2 | HE MUBFEE
1364 * 3 | HE MUBFER
1365 * 4 | DL OFDMA, for AP its DL Tx OFDMA for Sta its Rx OFDMA
1366 * 5 | UL OFDMA, for AP its Tx OFDMA trigger for Sta its
1367 * Rx OFDMA trigger receive & UL response
1368 * 6 | UL MUMIMO
1369 */
1370 status = wma_vdev_set_param(wma->wmi_handle, vdev_id,
1371 wmi_vdev_param_set_hemu_mode, hemu_mode);
1372 wma_debug("set HEMU_MODE (hemu_mode = 0x%x)", hemu_mode);
1373
1374 if (QDF_IS_STATUS_ERROR(status))
1375 wma_err("failed to set HEMU_MODE(status = %d)", status);
1376 }
1377
wma_get_he_capabilities(struct he_capability * he_cap)1378 QDF_STATUS wma_get_he_capabilities(struct he_capability *he_cap)
1379 {
1380 tp_wma_handle wma_handle;
1381
1382 wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
1383 if (!wma_handle)
1384 return QDF_STATUS_E_FAILURE;
1385
1386 qdf_mem_copy(he_cap->phy_cap,
1387 &wma_handle->he_cap.phy_cap,
1388 WMI_MAX_HECAP_PHY_SIZE);
1389 he_cap->mac_cap = wma_handle->he_cap.mac_cap;
1390 he_cap->mcs = wma_handle->he_cap.mcs;
1391
1392 he_cap->ppet.numss_m1 = wma_handle->he_cap.ppet.numss_m1;
1393 he_cap->ppet.ru_bit_mask = wma_handle->he_cap.ppet.ru_bit_mask;
1394 qdf_mem_copy(&he_cap->ppet.ppet16_ppet8_ru3_ru0,
1395 &wma_handle->he_cap.ppet.ppet16_ppet8_ru3_ru0,
1396 WMI_MAX_NUM_SS);
1397
1398 return QDF_STATUS_SUCCESS;
1399 }
1400
wma_set_he_vdev_param(struct wma_txrx_node * intr,wmi_conv_vdev_param_id param_id,uint32_t value)1401 void wma_set_he_vdev_param(struct wma_txrx_node *intr,
1402 wmi_conv_vdev_param_id param_id,
1403 uint32_t value)
1404 {
1405 switch (param_id) {
1406 case wmi_vdev_param_he_dcm_enable:
1407 intr->config.dcm = value;
1408 break;
1409 case wmi_vdev_param_he_range_ext:
1410 intr->config.range_ext = value;
1411 break;
1412 default:
1413 wma_err("Unhandled HE vdev param: %0x", param_id);
1414 break;
1415 }
1416 }
1417
wma_get_he_vdev_param(struct wma_txrx_node * intr,wmi_conv_vdev_param_id param_id)1418 uint32_t wma_get_he_vdev_param(struct wma_txrx_node *intr,
1419 wmi_conv_vdev_param_id param_id)
1420 {
1421 switch (param_id) {
1422 case wmi_vdev_param_he_dcm_enable:
1423 return intr->config.dcm;
1424 case wmi_vdev_param_he_range_ext:
1425 return intr->config.range_ext;
1426 default:
1427 wma_err("Unhandled HE vdev param: %0x", param_id);
1428 break;
1429 }
1430 return 0;
1431 }
1432
wma_get_hemu_mode(uint32_t * hemumode,struct mac_context * mac)1433 QDF_STATUS wma_get_hemu_mode(uint32_t *hemumode, struct mac_context *mac)
1434 {
1435 if (!hemumode || !mac)
1436 return QDF_STATUS_E_FAILURE;
1437
1438 *hemumode = DOT11AX_HEMU_MODE;
1439 *hemumode |= ((mac->mlme_cfg->he_caps.dot11_he_cap.su_beamformer << HE_SUBFER) |
1440 (mac->mlme_cfg->he_caps.dot11_he_cap.su_beamformee << HE_SUBFEE) |
1441 (mac->mlme_cfg->he_caps.dot11_he_cap.mu_beamformer << HE_MUBFER) |
1442 (mac->mlme_cfg->he_caps.dot11_he_cap.su_beamformee << HE_MUBFEE));
1443 /*
1444 * Enable / disable trigger access for a AP vdev's peers.
1445 * For a STA mode vdev this will enable/disable triggered
1446 * access and enable/disable Multi User mode of operation.
1447 * A value of 0 in a given bit disables corresponding mode.
1448 * bit | hemu mode
1449 * ---------------
1450 * 0 | HE SUBFEE
1451 * 1 | HE SUBFER
1452 * 2 | HE MUBFEE
1453 * 3 | HE MUBFER
1454 * 4 | DL OFDMA, for AP its DL Tx OFDMA for Sta its Rx OFDMA
1455 * 5 | UL OFDMA, for AP its Tx OFDMA trigger for Sta its
1456 * Rx OFDMA trigger receive & UL response
1457 * 6 | UL MUMIMO
1458 */
1459 return QDF_STATUS_SUCCESS;
1460 }
1461
wma_prevent_suspend_on_obss_color_collision(struct wlan_objmgr_vdev * vdev)1462 void wma_prevent_suspend_on_obss_color_collision(struct wlan_objmgr_vdev *vdev)
1463 {
1464 struct mlme_legacy_priv *mlme_priv;
1465
1466 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
1467 if (!mlme_priv)
1468 return;
1469
1470 qdf_wake_lock_timeout_acquire(&mlme_priv->bss_color_change_wakelock,
1471 MAX_WAKELOCK_FOR_BSS_COLOR_CHANGE);
1472 qdf_runtime_pm_prevent_suspend(
1473 &mlme_priv->bss_color_change_runtime_lock);
1474 }
1475
wma_allow_suspend_after_obss_color_change(struct wlan_objmgr_vdev * vdev)1476 void wma_allow_suspend_after_obss_color_change(struct wlan_objmgr_vdev *vdev)
1477 {
1478 struct mlme_legacy_priv *mlme_priv;
1479
1480 mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
1481 if (!mlme_priv)
1482 return;
1483
1484 qdf_runtime_pm_allow_suspend(
1485 &mlme_priv->bss_color_change_runtime_lock);
1486 qdf_wake_lock_release(&mlme_priv->bss_color_change_wakelock, 0);
1487 }
1488