xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/phl_sw_cap.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  *****************************************************************************/
15 #include "phl_headers.h"
16 
17 static void
_phl_sw_cap_para_init(struct rtw_phl_com_t * phl_com,struct rtw_para_info_t * para_info)18 _phl_sw_cap_para_init(
19 	struct rtw_phl_com_t* phl_com, struct rtw_para_info_t *para_info)
20 {
21 	para_info->para_src = RTW_PARA_SRC_INTNAL;
22 	para_info->para_data = NULL;
23 	para_info->para_data_len = 0;
24 	para_info->hal_phy_folder = NULL;
25 }
26 
27 static void
_phl_sw_cap_para_free(struct rtw_phl_com_t * phl_com,struct rtw_para_info_t * para_info)28 _phl_sw_cap_para_free(
29 	struct rtw_phl_com_t* phl_com, struct rtw_para_info_t *para_info)
30 {
31 	u32 buf_sz = MAX_HWCONFIG_FILE_CONTENT;
32 	void *drv = phl_com->drv_priv;
33 
34 	if(para_info->para_data)
35 		_os_mem_free(drv, para_info->para_data, buf_sz * sizeof(u32));
36 
37 	para_info->para_data = NULL;
38 	para_info->para_data_len = 0;
39 }
40 
41 static void
_phl_pwrlmt_para_init(struct rtw_phl_com_t * phl_com,struct rtw_para_pwrlmt_info_t * para_info)42 _phl_pwrlmt_para_init(
43 	struct rtw_phl_com_t* phl_com, struct rtw_para_pwrlmt_info_t *para_info)
44 {
45 	para_info->para_src = RTW_PARA_SRC_INTNAL;
46 	para_info->para_data = NULL;
47 	para_info->para_data_len = 0;
48 	para_info->ext_regd_arridx = 0;
49 	para_info->ext_reg_map_num = 0;
50 	para_info->hal_phy_folder = NULL;
51 }
52 
53 static void
_phl_pwrlmt_para_free(struct rtw_phl_com_t * phl_com,struct rtw_para_pwrlmt_info_t * para_info)54 _phl_pwrlmt_para_free(
55 	struct rtw_phl_com_t* phl_com, struct rtw_para_pwrlmt_info_t *para_info)
56 {
57 	u32 file_buf_sz = MAX_HWCONFIG_FILE_CONTENT;
58 	u32 buf_sz = MAX_LINES_HWCONFIG_TXT;
59 	void *drv = phl_com->drv_priv;
60 
61 	if(para_info->para_data)
62 		_os_mem_free(drv, para_info->para_data, file_buf_sz * sizeof(u32));
63 	para_info->para_data = NULL;
64 	para_info->para_data_len = 0;
65 
66 	if(para_info->ext_reg_codemap)
67 		_os_mem_free(drv, para_info->ext_reg_codemap, buf_sz * sizeof(u8));
68 	para_info->ext_reg_codemap = NULL;
69 	para_info->ext_reg_map_num = 0;
70 }
71 
_phl_sw_cap_get_hi_bw(struct phy_cap_t * phy_cap)72 enum channel_width _phl_sw_cap_get_hi_bw(struct phy_cap_t *phy_cap)
73 {
74 	enum channel_width bw = CHANNEL_WIDTH_20;
75 	do {
76 		if (phy_cap->bw_sup & BW_CAP_80_80M) {
77 			bw = CHANNEL_WIDTH_80_80;
78 			break;
79 		} else if (phy_cap->bw_sup & BW_CAP_160M) {
80 			bw = CHANNEL_WIDTH_160;
81 			break;
82 		} else if (phy_cap->bw_sup & BW_CAP_80M) {
83 			bw = CHANNEL_WIDTH_80;
84 			break;
85 		} else if (phy_cap->bw_sup & BW_CAP_40M) {
86 			bw = CHANNEL_WIDTH_40;
87 			break;
88 		} else if (phy_cap->bw_sup & BW_CAP_20M) {
89 			bw = CHANNEL_WIDTH_20;
90 			break;
91 		}
92 	} while (0);
93 
94 	return bw;
95 }
96 
97 enum rtw_phl_status
phl_sw_cap_init(struct rtw_phl_com_t * phl_com)98 phl_sw_cap_init(struct rtw_phl_com_t* phl_com)
99 {
100 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
101 	struct phy_sw_cap_t *phy_sw_cap = NULL;
102 	u8	idx=0;
103 
104 	for(idx=0; idx < 2 ; idx++)
105 	{
106 		phy_sw_cap = &phl_com->phy_sw_cap[idx];
107 
108 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->mac_reg_info);
109 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->bb_phy_reg_info);
110 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->bb_phy_reg_mp_info);
111 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->bb_phy_reg_gain_info);
112 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->rf_radio_a_info);
113 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->rf_radio_b_info);
114 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->rf_txpwr_byrate_info);
115 		_phl_sw_cap_para_init(phl_com, &phy_sw_cap->rf_txpwrtrack_info);
116 
117 		_phl_pwrlmt_para_init(phl_com, &phy_sw_cap->rf_txpwrlmt_info);
118 		_phl_pwrlmt_para_init(phl_com, &phy_sw_cap->rf_txpwrlmt_ru_info);
119 		phy_sw_cap->bfreed_para = false;
120 	}
121 	phl_com->dev_sw_cap.bfree_para_info = false; /* Default keep Phy file param info*/
122 #endif
123 	phl_com->dev_sw_cap.fw_cap.fw_src = RTW_FW_SRC_INTNAL;
124 	phl_com->dev_sw_cap.btc_mode = BTC_MODE_NORMAL;
125 	phl_com->dev_sw_cap.bypass_rfe_chk = false;
126 	phl_com->dev_sw_cap.rf_board_opt = PHL_UNDEFINED_SW_CAP;
127 
128 	return RTW_PHL_STATUS_SUCCESS;
129 }
130 
131 enum rtw_phl_status
phl_sw_cap_deinit(struct rtw_phl_com_t * phl_com)132 phl_sw_cap_deinit(struct rtw_phl_com_t* phl_com)
133 {
134 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
135 	struct phy_sw_cap_t *phy_sw_cap = NULL;
136 	u8	idx=0;
137 
138 	for (idx = 0; idx < 2; idx++) {
139 		phy_sw_cap = &phl_com->phy_sw_cap[idx];
140 		if (phy_sw_cap->bfreed_para == true) {
141 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "already bfreed para_info->para_data\n");
142 			return RTW_PHL_STATUS_SUCCESS;
143 		}
144 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "To free para_info->para_data phy %d\n", idx);
145 
146 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->mac_reg_info);
147 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->bb_phy_reg_info);
148 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->bb_phy_reg_mp_info);
149 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->bb_phy_reg_gain_info);
150 
151 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->rf_radio_a_info);
152 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->rf_radio_b_info);
153 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->rf_txpwr_byrate_info);
154 		_phl_sw_cap_para_free(phl_com, &phy_sw_cap->rf_txpwrtrack_info);
155 
156 		_phl_pwrlmt_para_free(phl_com, &phy_sw_cap->rf_txpwrlmt_info);
157 		_phl_pwrlmt_para_free(phl_com, &phy_sw_cap->rf_txpwrlmt_ru_info);
158 
159 		phy_sw_cap->bfreed_para = true;
160 	}
161 #endif
162 
163 	return RTW_PHL_STATUS_SUCCESS;
164 }
165 
rtw_phl_init_free_para_buf(struct rtw_phl_com_t * phl_com)166 void rtw_phl_init_free_para_buf(struct rtw_phl_com_t *phl_com)
167 {
168 
169 #ifdef CONFIG_LOAD_PHY_PARA_FROM_FILE
170 	if (phl_com->dev_sw_cap.bfree_para_info == true)
171 		phl_sw_cap_deinit(phl_com);
172 
173 #endif
174 }
175 
176 
_phl_sw_role_cap_bf(enum role_type rtype)177 u16 _phl_sw_role_cap_bf(enum role_type rtype)
178 {
179 	u16 def_bf_cap = 0;
180 
181 	if (PHL_RTYPE_AP == rtype) {
182 		/* AP mode : no MU BFee */
183 		def_bf_cap = (HW_CAP_BFEE_HT_SU | HW_CAP_BFER_HT_SU |
184 			      HW_CAP_BFEE_VHT_SU | HW_CAP_BFER_VHT_SU |
185 			      HW_CAP_BFER_VHT_MU |
186 			      HW_CAP_BFEE_HE_SU | HW_CAP_BFER_HE_SU |
187 			      HW_CAP_BFER_HE_MU |
188 			      HW_CAP_HE_NON_TB_CQI | HW_CAP_HE_TB_CQI);
189 	} else if (PHL_RTYPE_STATION == rtype) {
190 		/* STA mode : no MU BFer */
191 		def_bf_cap = (HW_CAP_BFEE_HT_SU | HW_CAP_BFER_HT_SU |
192 			      HW_CAP_BFEE_VHT_SU | HW_CAP_BFER_VHT_SU |
193 			      HW_CAP_BFEE_VHT_MU |
194 			      HW_CAP_BFEE_HE_SU | HW_CAP_BFER_HE_SU |
195 			      HW_CAP_BFEE_HE_MU |
196 			      HW_CAP_HE_NON_TB_CQI | HW_CAP_HE_TB_CQI);
197 	} else {
198 		def_bf_cap = (HW_CAP_BFEE_HT_SU | HW_CAP_BFER_HT_SU |
199 			      HW_CAP_BFEE_VHT_SU | HW_CAP_BFER_VHT_SU |
200 			      HW_CAP_BFEE_VHT_MU | HW_CAP_BFER_VHT_MU |
201 			      HW_CAP_BFEE_HE_SU | HW_CAP_BFER_HE_SU |
202 			      HW_CAP_BFEE_HE_MU | HW_CAP_BFER_HE_MU |
203 			      HW_CAP_HE_NON_TB_CQI | HW_CAP_HE_TB_CQI);
204 	}
205 
206 	return def_bf_cap;
207 }
208 
_phl_init_proto_bf_cap(struct phl_info_t * phl_info,u8 hw_band,enum role_type rtype,struct protocol_cap_t * role_cap)209 static void _phl_init_proto_bf_cap(struct phl_info_t *phl_info,
210 		u8 hw_band, enum role_type rtype, struct protocol_cap_t *role_cap)
211 {
212 #ifdef RTW_WKARD_PHY_CAP
213 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
214 	struct role_sw_cap_t *sw_role_cap = &phl_com->role_sw_cap;
215 	struct protocol_cap_t proto_cap = {0};
216 	u16 bfcap = sw_role_cap->bf_cap;
217 
218 	/* First : compare and get the bf sw_proto_cap and hw_proto_cap .*/
219 	if (RTW_HAL_STATUS_SUCCESS != rtw_hal_get_bf_proto_cap(
220 						phl_com,
221 						phl_info->hal,
222 			 			hw_band,
223 						&proto_cap)) {
224 		PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_,
225 			  "%s : Get SW/HW BF Cap FAIL, disable all of the BF functions.\n", __func__);
226 	}
227 
228 	/* Second : filter bf cap with 802.11 spec */
229 	bfcap &= _phl_sw_role_cap_bf(rtype);
230 
231 	/* Final : Compare with sw_role_cap->bf_cap to judge the final wrole's BF CAP. */
232 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s : sw_role_cap->bf_cap = 0x%x \n",
233 		  __func__, sw_role_cap->bf_cap);
234 	if (!(bfcap & HW_CAP_BFEE_HT_SU) &&
235 	    (proto_cap.ht_su_bfme)) {
236 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HT SU BFEE by sw_role_cap.\n");
237 		role_cap->ht_su_bfme = 0;
238 	} else {
239 		role_cap->ht_su_bfme = proto_cap.ht_su_bfme;
240 	}
241 
242 	if (!(bfcap & HW_CAP_BFER_HT_SU) &&
243 	    (proto_cap.ht_su_bfmr)) {
244 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HT SU BFER by sw_role_cap.\n");
245 		role_cap->ht_su_bfmr = 0;
246 	} else {
247 		role_cap->ht_su_bfmr = proto_cap.ht_su_bfmr;
248 	}
249 
250 	if (!(bfcap & HW_CAP_BFEE_VHT_SU) &&
251 	    (proto_cap.vht_su_bfme)) {
252 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT SU BFEE by sw_role_cap.\n");
253 		role_cap->vht_su_bfme = 0;
254 	} else {
255 		role_cap->vht_su_bfme = proto_cap.vht_su_bfme;
256 	}
257 
258 	if (!(bfcap & HW_CAP_BFER_VHT_SU) &&
259 	    (proto_cap.vht_su_bfmr)) {
260 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT SU BFER by sw_role_cap.\n");
261 		role_cap->vht_su_bfmr = 0;
262 	} else {
263 		role_cap->vht_su_bfmr = proto_cap.vht_su_bfmr;
264 	}
265 
266 	if (!(bfcap & HW_CAP_BFEE_VHT_MU) &&
267 	    (proto_cap.vht_mu_bfme)) {
268 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT MU BFEE by sw_role_cap.\n");
269 		role_cap->vht_mu_bfme = 0;
270 	} else {
271 		role_cap->vht_mu_bfme = proto_cap.vht_mu_bfme;
272 	}
273 
274 	if (!(bfcap & HW_CAP_BFER_VHT_MU) &&
275 	    (proto_cap.vht_mu_bfmr)) {
276 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT MU BFER by sw_role_cap.\n");
277 		role_cap->vht_mu_bfmr = 0;
278 	} else {
279 		role_cap->vht_mu_bfmr = proto_cap.vht_mu_bfmr;
280 	}
281 
282 	if (!(bfcap & HW_CAP_BFEE_HE_SU) &&
283 	    (proto_cap.he_su_bfme)) {
284 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE SU BFEE by sw_role_cap.\n");
285 		role_cap->he_su_bfme = 0;
286 	} else {
287 		role_cap->he_su_bfme = proto_cap.he_su_bfme;
288 	}
289 
290 	if (!(bfcap & HW_CAP_BFER_HE_SU) &&
291 	    (proto_cap.he_su_bfmr)) {
292 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE SU BFER by sw_role_cap.\n");
293 		role_cap->he_su_bfmr = 0;
294 	} else {
295 		role_cap->he_su_bfmr = proto_cap.he_su_bfmr;
296 	}
297 
298 	if (!(bfcap & HW_CAP_BFEE_HE_MU) &&
299 	    (proto_cap.he_mu_bfme)) {
300 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE MU BFEE by sw_role_cap.\n");
301 		role_cap->he_mu_bfme = 0;
302 	} else {
303 		role_cap->he_mu_bfme = proto_cap.he_mu_bfme;
304 	}
305 
306 	if (!(bfcap & HW_CAP_BFER_HE_MU) &&
307 	    (proto_cap.he_mu_bfmr)) {
308 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE MU BFER by sw_role_cap.\n");
309 		role_cap->he_mu_bfmr = 0;
310 	} else {
311 		role_cap->he_mu_bfmr = proto_cap.he_mu_bfmr;
312 	}
313 
314 	if (!(bfcap & HW_CAP_HE_NON_TB_CQI) &&
315 	    (proto_cap.non_trig_cqi_fb)) {
316 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE NON-TB CQI_FB by sw_role_cap.\n");
317 		role_cap->non_trig_cqi_fb = 0;
318 	} else {
319 		role_cap->non_trig_cqi_fb = proto_cap.non_trig_cqi_fb;
320 	}
321 
322 	if (!(bfcap & HW_CAP_HE_TB_CQI) &&
323 	    (proto_cap.trig_cqi_fb)) {
324 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE TB CQI_FB by sw_role_cap.\n");
325 		role_cap->trig_cqi_fb = 0;
326 	} else {
327 		role_cap->trig_cqi_fb = proto_cap.trig_cqi_fb;
328 	}
329 #endif
330 
331 }
332 
_phl_init_proto_stbc_cap(struct phl_info_t * phl_info,u8 hw_band,struct protocol_cap_t * proto_role_cap)333 static void _phl_init_proto_stbc_cap(struct phl_info_t *phl_info,
334 		u8 hw_band, struct protocol_cap_t *proto_role_cap)
335 {
336 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
337 	struct role_sw_cap_t *sw_role_cap = &phl_com->role_sw_cap;
338 	struct protocol_cap_t proto_cap = {0};
339 
340 	/* First : compare and get the stbc sw_proto_cap and hw_proto_cap .*/
341 	if (RTW_HAL_STATUS_SUCCESS != rtw_hal_get_stbc_proto_cap(phl_com,
342 								 phl_info->hal,
343 			 					 hw_band,
344 								 &proto_cap)) {
345 		PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_,
346 			  "%s : Get SW/HW STBC proto_cap FAIL, disable all of the STBC functions.\n", __func__);
347 	}
348 
349 	/* Final : Compare with sw_role_cap->stbc_cap to judge the final wrole's STBC CAP. */
350 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s : sw_role_cap->stbc_cap = 0x%x \n",
351 		__func__, sw_role_cap->stbc_cap);
352 
353 #ifdef RTW_WKARD_PHY_CAP
354 
355 	proto_role_cap->stbc_tx = 0; /* Removed later */
356 
357 	/* Check sw role cap, if it is not support, set proto_role_cap->xxx to 0 */
358 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HT_TX) &&
359 	    (proto_cap.stbc_ht_tx)) {
360 		proto_role_cap->stbc_ht_tx = 0;
361 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HT STBC Tx by sw_role_cap.\n");
362 	} else {
363 		proto_role_cap->stbc_ht_tx = proto_cap.stbc_ht_tx;
364 	}
365 
366 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_VHT_TX) &&
367 	    (proto_cap.stbc_vht_tx)) {
368 		proto_role_cap->stbc_vht_tx = 0;
369 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT STBC Tx by sw_role_cap.\n");
370 	} else {
371 		proto_role_cap->stbc_vht_tx = proto_cap.stbc_vht_tx;
372 	}
373 
374 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_TX) &&
375 	    (proto_cap.stbc_he_tx)) {
376 		proto_role_cap->stbc_he_tx = 0;
377 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE STBC Tx by sw_role_cap.\n");
378 	} else {
379 		proto_role_cap->stbc_he_tx = proto_cap.stbc_he_tx;
380 	}
381 
382 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_TX_GT_80M) &&
383 	    (proto_cap.stbc_tx_greater_80mhz)) {
384 		proto_role_cap->stbc_tx_greater_80mhz = 0;
385 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable STBC Tx (greater than 80M) by sw_role_cap.\n");
386 	} else {
387 		proto_role_cap->stbc_tx_greater_80mhz = proto_cap.stbc_tx_greater_80mhz;
388 	}
389 
390 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HT_RX) &&
391 	    (proto_cap.stbc_ht_rx)) {
392 		proto_role_cap->stbc_ht_rx = 0;
393 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HT STBC Rx by sw_role_cap.\n");
394 	} else {
395 		proto_role_cap->stbc_ht_rx = proto_cap.stbc_ht_rx;
396 	}
397 
398 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_VHT_RX) &&
399 	    (proto_cap.stbc_vht_rx)) {
400 		proto_role_cap->stbc_vht_rx = 0;
401 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT STBC Rx by sw_role_cap.\n");
402 	} else {
403 		proto_role_cap->stbc_vht_rx = proto_cap.stbc_vht_rx;
404 	}
405 
406 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_RX) &&
407 	    (proto_cap.stbc_he_rx)) {
408 		proto_role_cap->stbc_he_rx = 0;
409 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE STBC Rx by sw_role_cap.\n");
410 	} else {
411 		proto_role_cap->stbc_he_rx = proto_cap.stbc_he_rx;
412 	}
413 
414 	if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_RX_GT_80M) &&
415 	    (proto_cap.stbc_rx_greater_80mhz)) {
416 		proto_role_cap->stbc_rx_greater_80mhz = 0;
417 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE STBC Rx (greater than 80M) by sw_role_cap.\n");
418 	} else {
419 		proto_role_cap->stbc_rx_greater_80mhz = proto_cap.stbc_rx_greater_80mhz;
420 	}
421 #endif
422 }
423 
424 static enum rtw_phl_status
_phl_init_protocol_cap(struct phl_info_t * phl_info,u8 hw_band,enum role_type rtype,struct protocol_cap_t * proto_role_cap)425 _phl_init_protocol_cap(struct phl_info_t *phl_info,
426 				u8 hw_band, enum role_type rtype,
427 				struct protocol_cap_t *proto_role_cap)
428 {
429 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
430 
431 	/* TODO: Get protocol cap from sw and hw cap*/
432 	if (rtype == PHL_RTYPE_AP) {
433 		proto_role_cap->num_ampdu = 128;
434 		proto_role_cap->ampdu_density = 0;
435 		proto_role_cap->ampdu_len_exp = 0xff;
436 		proto_role_cap->amsdu_in_ampdu = 1;
437 		proto_role_cap->max_amsdu_len =
438 			phl_com->proto_sw_cap[hw_band].max_amsdu_len;
439 		proto_role_cap->htc_rx = 1;
440 		proto_role_cap->sm_ps = 0;
441 		proto_role_cap->trig_padding = 0;
442 #ifdef CONFIG_PHL_TWT
443 		proto_role_cap->twt =
444 				phl_com->dev_cap.twt_sup & RTW_PHL_TWT_RSP_SUP;
445 #else
446 		proto_role_cap->twt = 0;
447 #endif /* CONFIG_PHL_TWT */
448 		proto_role_cap->all_ack = 1;
449 		proto_role_cap->a_ctrl = 0xe;
450 		proto_role_cap->ops = 1;
451 		proto_role_cap->ht_vht_trig_rx = 0;
452 		proto_role_cap->bsscolor = 0x0E; /* Default BSS Color */
453 		proto_role_cap->edca[RTW_AC_BE].ac = RTW_AC_BE;
454 		proto_role_cap->edca[RTW_AC_BE].param = 0xA42B;
455 		proto_role_cap->edca[RTW_AC_BK].ac = RTW_AC_BK;
456 		proto_role_cap->edca[RTW_AC_BK].param = 0xA549;
457 		proto_role_cap->edca[RTW_AC_VI].ac = RTW_AC_VI;
458 		proto_role_cap->edca[RTW_AC_VI].param = 0x5E4326;
459 		proto_role_cap->edca[RTW_AC_VO].ac = RTW_AC_VO;
460 		proto_role_cap->edca[RTW_AC_VO].param = 0x2F3224;
461 		proto_role_cap->ht_ldpc = 1;
462 		proto_role_cap->vht_ldpc = 1;
463 		proto_role_cap->he_ldpc = 1;
464 		proto_role_cap->sgi_20 = 1;
465 		proto_role_cap->sgi_40 = 1;
466 		proto_role_cap->sgi_80 = 1;
467 		proto_role_cap->sgi_160 = 0;
468 		switch (phl_com->phy_cap[hw_band].rxss) {
469 			default:
470 				break;
471 			case 1:
472 				proto_role_cap->ht_rx_mcs[0] = 0xff;
473 				proto_role_cap->vht_rx_mcs[0] = 0xfe;
474 				proto_role_cap->vht_rx_mcs[1] = 0xff;
475 				proto_role_cap->he_rx_mcs[0] = 0xfe;
476 				proto_role_cap->he_rx_mcs[1] = 0xff;
477 				break;
478 			case 2:
479 				proto_role_cap->ht_rx_mcs[0] = 0xff;
480 				proto_role_cap->ht_rx_mcs[1] = 0xff;
481 				proto_role_cap->vht_rx_mcs[0] = 0xfa;
482 				proto_role_cap->vht_rx_mcs[1] = 0xff;
483 				proto_role_cap->he_rx_mcs[0] = 0xfa;
484 				proto_role_cap->he_rx_mcs[1] = 0xff;
485 				break;
486 		}
487 		switch (phl_com->phy_cap[hw_band].txss) {
488 			default:
489 				break;
490 			case 1:
491 				proto_role_cap->ht_tx_mcs[0] = 0xff;
492 				proto_role_cap->vht_tx_mcs[0] = 0xfe;
493 				proto_role_cap->vht_tx_mcs[1] = 0xff;
494 				proto_role_cap->he_tx_mcs[0] = 0xfe;
495 				proto_role_cap->he_tx_mcs[1] = 0xff;
496 				break;
497 			case 2:
498 				proto_role_cap->ht_tx_mcs[0] = 0xff;
499 				proto_role_cap->ht_tx_mcs[1] = 0xff;
500 				proto_role_cap->vht_tx_mcs[0] = 0xfa;
501 				proto_role_cap->vht_tx_mcs[1] = 0xff;
502 				proto_role_cap->he_tx_mcs[0] = 0xfa;
503 				proto_role_cap->he_tx_mcs[1] = 0xff;
504 				break;
505 		}
506 
507 		proto_role_cap->ltf_gi = 0x3f;	// bit-x
508 		proto_role_cap->doppler_tx = 1;
509 		proto_role_cap->doppler_rx = 0;
510 		proto_role_cap->dcm_max_const_tx = 0;
511 		proto_role_cap->dcm_max_nss_tx = 0;
512 		proto_role_cap->dcm_max_const_rx = 3;
513 		proto_role_cap->dcm_max_nss_rx = 0;
514 		proto_role_cap->partial_bw_su_in_mu = 1;
515 		_phl_init_proto_stbc_cap(phl_info, hw_band, proto_role_cap);
516 		_phl_init_proto_bf_cap(phl_info, hw_band, rtype, proto_role_cap);
517 
518 		/* All of the HT/VHT/HE BFee */
519 		if ((1 == proto_role_cap->ht_su_bfme) ||
520 		    (1 == proto_role_cap->vht_su_bfme) ||
521 		    (1 == proto_role_cap->vht_mu_bfme) ||
522 		    (1 == proto_role_cap->he_su_bfme) ||
523 		    (1 == proto_role_cap->he_mu_bfme) ||
524 		    (1 == proto_role_cap->non_trig_cqi_fb)||
525 		    (1 == proto_role_cap->trig_cqi_fb)) {
526 			proto_role_cap->bfme_sts = 3;
527 			proto_role_cap->bfme_sts_greater_80mhz = 0;
528 			proto_role_cap->max_nc = 1;
529 		} else {
530 			proto_role_cap->bfme_sts = 0;
531 			proto_role_cap->bfme_sts_greater_80mhz = 0;
532 			proto_role_cap->max_nc = 0;
533 		}
534 		/* HE BFer */
535 		if ((1 == proto_role_cap->he_su_bfmr) ||
536 		    (1 == proto_role_cap->he_mu_bfmr)) {
537 			proto_role_cap->num_snd_dim = 1;
538 			proto_role_cap->num_snd_dim_greater_80mhz = 0;
539 		} else {
540 			proto_role_cap->num_snd_dim = 0;
541 			proto_role_cap->num_snd_dim_greater_80mhz = 0;
542 		}
543 		/* HE BFee */
544 		if ((1 == proto_role_cap->he_su_bfme) ||
545 		    (1 == proto_role_cap->he_mu_bfme)) {
546 			proto_role_cap->ng_16_su_fb = 1;
547 			proto_role_cap->ng_16_mu_fb = 1;
548 			proto_role_cap->cb_sz_su_fb = 1;
549 			proto_role_cap->cb_sz_mu_fb = 1;
550 			proto_role_cap->he_rx_ndp_4x32 = 1;
551 		} else {
552 			proto_role_cap->ng_16_su_fb = 0;
553 			proto_role_cap->ng_16_mu_fb = 0;
554 			proto_role_cap->cb_sz_su_fb = 0;
555 			proto_role_cap->cb_sz_mu_fb = 0;
556 			proto_role_cap->he_rx_ndp_4x32 = 0;
557 		}
558 
559 		/*HE SU BFer or BFer*/
560 		if ((1 == proto_role_cap->he_su_bfme) ||
561 		    (1 == proto_role_cap->he_su_bfmr)) {
562 			proto_role_cap->trig_su_bfm_fb = 1;
563 		} else {
564 			proto_role_cap->trig_su_bfm_fb = 0;
565 		}
566 		/*HE MU BFer or BFer*/
567 		if ((1 == proto_role_cap->he_mu_bfme) ||
568 		    (1 == proto_role_cap->he_mu_bfmr)) {
569 			proto_role_cap->trig_mu_bfm_fb = 1;
570 		} else {
571 			proto_role_cap->trig_mu_bfm_fb = 0;
572 		}
573 		/* HT/VHT BFee */
574 		if ((1 == proto_role_cap->vht_mu_bfme) ||
575 		    (1 == proto_role_cap->vht_su_bfme) ||
576 		    (1 == proto_role_cap->ht_su_bfme)) {
577 			proto_role_cap->ht_vht_ng = 0; /* vht ng = 1 */
578 			proto_role_cap->ht_vht_cb = 1; /* vht_mu{9,7}/vht_su{6,4}/ht{4,2} */
579 		}
580 
581 		proto_role_cap->partial_bw_su_er = 1;
582 		proto_role_cap->pkt_padding = 2;
583 		proto_role_cap->pwr_bst_factor = 1;
584 		proto_role_cap->dcm_max_ru = 2;
585 		proto_role_cap->long_sigb_symbol = 1;
586 		proto_role_cap->tx_1024q_ru = 0;
587 		proto_role_cap->rx_1024q_ru = 1;
588 		proto_role_cap->fbw_su_using_mu_cmprs_sigb = 1;
589 		proto_role_cap->fbw_su_using_mu_non_cmprs_sigb = 1;
590 		proto_role_cap->nss_tx =
591 			phl_com->phy_cap[hw_band].txss;
592 		proto_role_cap->nss_rx =
593 			phl_com->phy_cap[hw_band].rxss;
594 	} else if (rtype == PHL_RTYPE_STATION) {
595 		proto_role_cap->num_ampdu = 128;
596 		proto_role_cap->ampdu_density = 0;
597 		proto_role_cap->ampdu_len_exp = 0xff;
598 		proto_role_cap->amsdu_in_ampdu = 1;
599 		proto_role_cap->max_amsdu_len =
600 			phl_com->proto_sw_cap[hw_band].max_amsdu_len;
601 		proto_role_cap->htc_rx = 1;
602 		proto_role_cap->sm_ps = 3;
603 		proto_role_cap->trig_padding = 2;
604 #ifdef CONFIG_PHL_TWT
605 		proto_role_cap->twt =
606 				phl_com->dev_cap.twt_sup & RTW_PHL_TWT_REQ_SUP;
607 #else
608 		proto_role_cap->twt = 0;
609 #endif /* CONFIG_PHL_TWT */
610 		proto_role_cap->all_ack = 1;
611 		proto_role_cap->a_ctrl = 0x6;
612 		proto_role_cap->ops = 1;
613 		proto_role_cap->ht_vht_trig_rx = 1;
614 		proto_role_cap->edca[RTW_AC_BE].ac = RTW_AC_BE;
615 		proto_role_cap->edca[RTW_AC_BE].param = 0xA42B;
616 		proto_role_cap->edca[RTW_AC_BK].ac = RTW_AC_BK;
617 		proto_role_cap->edca[RTW_AC_BK].param = 0xA549;
618 		proto_role_cap->edca[RTW_AC_VI].ac = RTW_AC_VI;
619 		proto_role_cap->edca[RTW_AC_VI].param = 0x5E4326;
620 		proto_role_cap->edca[RTW_AC_VO].ac = RTW_AC_VO;
621 		proto_role_cap->edca[RTW_AC_VO].param = 0x2F3224;
622 		proto_role_cap->ht_ldpc = 1;
623 		proto_role_cap->vht_ldpc = 1;
624 		proto_role_cap->he_ldpc = 1;
625 		proto_role_cap->sgi_20 = 1;
626 		proto_role_cap->sgi_40 = 1;
627 		proto_role_cap->sgi_80 = 1;
628 		proto_role_cap->sgi_160 = 0;
629 
630 		switch (phl_com->phy_cap[hw_band].rxss) {
631 			default:
632 				break;
633 			case 1:
634 				proto_role_cap->ht_rx_mcs[0] = 0xff;
635 				proto_role_cap->vht_rx_mcs[0] = 0xfe;
636 				proto_role_cap->vht_rx_mcs[1] = 0xff;
637 				proto_role_cap->he_rx_mcs[0] = 0xfe;
638 				proto_role_cap->he_rx_mcs[1] = 0xff;
639 				break;
640 			case 2:
641 				proto_role_cap->ht_rx_mcs[0] = 0xff;
642 				proto_role_cap->ht_rx_mcs[1] = 0xff;
643 				proto_role_cap->vht_rx_mcs[0] = 0xfa;
644 				proto_role_cap->vht_rx_mcs[1] = 0xff;
645 				proto_role_cap->he_rx_mcs[0] = 0xfa;
646 				proto_role_cap->he_rx_mcs[1] = 0xff;
647 				break;
648 		}
649 		switch (phl_com->phy_cap[hw_band].txss) {
650 			default:
651 				break;
652 			case 1:
653 				proto_role_cap->ht_tx_mcs[0] = 0xff;
654 				proto_role_cap->vht_tx_mcs[0] = 0xfe;
655 				proto_role_cap->vht_tx_mcs[1] = 0xff;
656 				proto_role_cap->he_tx_mcs[0] = 0xfe;
657 				proto_role_cap->he_tx_mcs[1] = 0xff;
658 				break;
659 			case 2:
660 				proto_role_cap->ht_tx_mcs[0] = 0xff;
661 				proto_role_cap->ht_tx_mcs[1] = 0xff;
662 				proto_role_cap->vht_tx_mcs[0] = 0xfa;
663 				proto_role_cap->vht_tx_mcs[1] = 0xff;
664 				proto_role_cap->he_tx_mcs[0] = 0xfa;
665 				proto_role_cap->he_tx_mcs[1] = 0xff;
666 				break;
667 		}
668 
669 		proto_role_cap->ltf_gi = 0x3f;	// bit-x
670 		proto_role_cap->doppler_tx = 1;
671 		proto_role_cap->doppler_rx = 0;
672 		proto_role_cap->dcm_max_const_tx = 3;
673 		proto_role_cap->dcm_max_nss_tx = 1;
674 		proto_role_cap->dcm_max_const_rx = 3;
675 		proto_role_cap->dcm_max_nss_rx = 0;
676 
677 		_phl_init_proto_stbc_cap(phl_info, hw_band, proto_role_cap);
678 		_phl_init_proto_bf_cap(phl_info, hw_band, rtype, proto_role_cap);
679 
680 		/* All of the HT/VHT/HE BFee */
681 		if ((1 == proto_role_cap->ht_su_bfme) ||
682 		    (1 == proto_role_cap->vht_su_bfme) ||
683 		    (1 == proto_role_cap->vht_mu_bfme) ||
684 		    (1 == proto_role_cap->he_su_bfme) ||
685 		    (1 == proto_role_cap->he_mu_bfme) ||
686 		    (1 == proto_role_cap->non_trig_cqi_fb) ||
687 		    (1 == proto_role_cap->trig_cqi_fb)) {
688 			proto_role_cap->bfme_sts = 3;
689 			proto_role_cap->bfme_sts_greater_80mhz = 0;
690 			proto_role_cap->max_nc = 1;
691 		} else {
692 			proto_role_cap->bfme_sts = 0;
693 			proto_role_cap->bfme_sts_greater_80mhz = 0;
694 			proto_role_cap->max_nc = 0;
695 		}
696 
697 		/* HE BFer */
698 		if ((1 == proto_role_cap->he_su_bfmr) ||
699 		    (1 == proto_role_cap->he_mu_bfmr)) {
700 			proto_role_cap->num_snd_dim = 1;
701 			proto_role_cap->num_snd_dim_greater_80mhz = 0;
702 		} else {
703 			proto_role_cap->num_snd_dim = 0;
704 			proto_role_cap->num_snd_dim_greater_80mhz = 0;
705 		}
706 		/* HE BFee */
707 		if ((1 == proto_role_cap->he_su_bfme) ||
708 		    (1 == proto_role_cap->he_mu_bfme)) {
709 #ifdef RTW_WKARD_BFEE_DISABLE_NG16
710 			proto_role_cap->ng_16_su_fb = 0;
711 			proto_role_cap->ng_16_mu_fb = 0;
712 #else
713 			proto_role_cap->ng_16_su_fb = 1;
714 			proto_role_cap->ng_16_mu_fb = 1;
715 #endif
716 			proto_role_cap->cb_sz_su_fb = 1;
717 			proto_role_cap->cb_sz_mu_fb = 1;
718 			proto_role_cap->he_rx_ndp_4x32 = 1;
719 		} else {
720 			proto_role_cap->ng_16_su_fb = 0;
721 			proto_role_cap->ng_16_mu_fb = 0;
722 			proto_role_cap->cb_sz_su_fb = 0;
723 			proto_role_cap->cb_sz_mu_fb = 0;
724 			proto_role_cap->he_rx_ndp_4x32 = 0;
725 		}
726 		/*HE SU BFer or BFer*/
727 		if ((1 == proto_role_cap->he_su_bfme) ||
728 		    (1 == proto_role_cap->he_su_bfmr)) {
729 			proto_role_cap->trig_su_bfm_fb = 1;
730 		} else {
731 			proto_role_cap->trig_su_bfm_fb = 0;
732 		}
733 		/*HE MU BFer or BFer*/
734 		if ((1 == proto_role_cap->he_mu_bfme) ||
735 		    (1 == proto_role_cap->he_mu_bfmr)) {
736 			proto_role_cap->trig_mu_bfm_fb = 1;
737 		} else {
738 			proto_role_cap->trig_mu_bfm_fb = 0;
739 		}
740 		/* HT/VHT BFee */
741 		if ((1 == proto_role_cap->vht_mu_bfme) ||
742 		    (1 == proto_role_cap->vht_su_bfme) ||
743 		    (1 == proto_role_cap->ht_su_bfme)) {
744 			proto_role_cap->ht_vht_ng = 0; /* vht ng = 1 */
745 			proto_role_cap->ht_vht_cb = 1; /* vht_mu{9,7}/vht_su{6,4}/ht{4,2} */
746 		}
747 		proto_role_cap->partial_bw_su_in_mu = 0;
748 		proto_role_cap->partial_bw_su_er = 1;
749 		proto_role_cap->pkt_padding = 2;
750 		proto_role_cap->pwr_bst_factor = 1;
751 		proto_role_cap->dcm_max_ru = 2;
752 		proto_role_cap->long_sigb_symbol = 1;
753 		proto_role_cap->tx_1024q_ru = 1;
754 		proto_role_cap->rx_1024q_ru = 1;
755 		proto_role_cap->fbw_su_using_mu_cmprs_sigb = 1;
756 		proto_role_cap->fbw_su_using_mu_non_cmprs_sigb = 1;
757 		proto_role_cap->nss_tx =
758 			phl_com->phy_cap[hw_band].txss;
759 		proto_role_cap->nss_rx =
760 			phl_com->phy_cap[hw_band].rxss;
761 	}
762 	return RTW_PHL_STATUS_SUCCESS;
763 }
764 
765 enum rtw_phl_status
phl_init_protocol_cap(struct phl_info_t * phl_info,struct rtw_wifi_role_t * wifi_role)766 phl_init_protocol_cap(struct phl_info_t *phl_info,
767 			    struct rtw_wifi_role_t *wifi_role)
768 {
769 
770 	enum rtw_phl_status ret = RTW_PHL_STATUS_SUCCESS;
771 	struct protocol_cap_t *role_proto_cap = &wifi_role->proto_role_cap;
772 
773 	_os_mem_set(phl_to_drvpriv(phl_info),
774 		role_proto_cap, 0, sizeof(struct protocol_cap_t));
775 
776 	ret = _phl_init_protocol_cap(phl_info, wifi_role->hw_band, wifi_role->type,
777 		role_proto_cap);
778 
779 	if (ret == RTW_PHL_STATUS_FAILURE)
780 		PHL_ERR("wrole:%d - %s failed\n", wifi_role->id, __func__);
781 
782 	return ret;
783 }
784 
785 static enum rtw_phl_status
_phl_init_role_cap(struct phl_info_t * phl_info,u8 hw_band,struct role_cap_t * role_cap)786 _phl_init_role_cap(struct phl_info_t *phl_info,
787 			u8 hw_band, struct role_cap_t *role_cap)
788 {
789 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
790 
791 #ifdef RTW_WKARD_PHY_CAP
792 	role_cap->wmode = phl_com->phy_cap[hw_band].proto_sup;
793 	role_cap->bw = _phl_sw_cap_get_hi_bw(&phl_com->phy_cap[hw_band]);
794 	role_cap->rty_lmt = 0xFF; /* default follow CR */
795 	role_cap->rty_lmt_rts = 0xFF; /* default follow CR */
796 
797 	role_cap->tx_htc = 1;
798 	role_cap->tx_sgi = 1;
799 	role_cap->tx_ht_ldpc = 1;
800 	role_cap->tx_vht_ldpc = 1;
801 	role_cap->tx_he_ldpc = 1;
802 	role_cap->tx_ht_stbc = 1;
803 	role_cap->tx_vht_stbc = 1;
804 	role_cap->tx_he_stbc = 1;
805 #endif
806 	return RTW_PHL_STATUS_SUCCESS;
807 }
808 
809 enum rtw_phl_status
phl_init_role_cap(struct phl_info_t * phl_info,struct rtw_wifi_role_t * wifi_role)810 phl_init_role_cap(struct phl_info_t *phl_info,
811 		  struct rtw_wifi_role_t *wifi_role)
812 {
813 	struct role_cap_t *role_cap = &wifi_role->cap;
814 	enum rtw_phl_status ret = RTW_PHL_STATUS_SUCCESS;
815 
816 	_os_mem_set(phl_to_drvpriv(phl_info),
817 		role_cap, 0, sizeof(struct role_cap_t));
818 
819 
820 	ret = _phl_init_role_cap(phl_info, wifi_role->hw_band, role_cap);
821 
822 	ret = phl_custom_init_role_cap(phl_info, wifi_role->hw_band, role_cap);
823 
824 	return RTW_PHL_STATUS_SUCCESS;
825 }
826 
827 enum rtw_phl_status
rtw_phl_get_dft_proto_cap(void * phl,u8 hw_band,enum role_type rtype,struct protocol_cap_t * role_proto_cap)828 rtw_phl_get_dft_proto_cap(void *phl, u8 hw_band, enum role_type rtype,
829 				struct protocol_cap_t *role_proto_cap)
830 {
831 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
832 
833 	_os_mem_set(phl_to_drvpriv(phl_info),
834 		role_proto_cap, 0, sizeof(struct protocol_cap_t));
835 
836 	return _phl_init_protocol_cap(phl_info, hw_band, rtype,
837 		role_proto_cap);
838 }
839 
840 enum rtw_phl_status
rtw_phl_get_dft_cap(void * phl,u8 hw_band,struct role_cap_t * role_cap)841 rtw_phl_get_dft_cap(void *phl, u8 hw_band, struct role_cap_t *role_cap)
842 {
843 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
844 
845 	_os_mem_set(phl_to_drvpriv(phl_info),
846 		role_cap, 0, sizeof(struct role_cap_t));
847 
848 	return _phl_init_role_cap(phl_info, hw_band, role_cap);
849 }
850 
851 
rtw_phl_final_cap_decision(void * phl)852 void rtw_phl_final_cap_decision(void * phl)
853 {
854 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
855 	struct rtw_phl_com_t *phl_com = phl_info->phl_com;
856 
857 #ifdef CONFIG_PHL_DFS
858 	phl_com->dfs_info.region_domain = DFS_REGD_ETSI;
859 #endif
860 
861 	rtw_hal_final_cap_decision(phl_com, phl_info->hal);
862 }
863 
864 
865