xref: /wlan-driver/qcacld-3.0/core/wma/src/wma_he.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
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 = &params->he_config;
1021 	tDot11fIEhe_op *he_op = &params->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