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