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_external_cap_limit(struct phl_info_t * phl_info,struct protocol_cap_t * proto_role_cap)333 static void _phl_external_cap_limit(struct phl_info_t *phl_info,
334 struct protocol_cap_t *proto_role_cap)
335 {
336 #ifdef RTW_WKARD_BTC_STBC_CAP
337 struct rtw_hal_com_t *hal_com = rtw_hal_get_halcom(phl_info->hal);
338
339 if ((proto_role_cap->cap_option & EXT_CAP_LIMIT_2G_RX_STBC) &&
340 hal_com->btc_ctrl.disable_rx_stbc) {
341 proto_role_cap->stbc_he_rx = 0;
342 proto_role_cap->stbc_vht_rx = 0;
343 proto_role_cap->stbc_ht_rx = 0;
344 PHL_INFO("%s Disable STBC RX cap for BTC request\n", __func__);
345 }
346 #endif
347 }
348
_phl_init_proto_stbc_cap(struct phl_info_t * phl_info,u8 hw_band,struct protocol_cap_t * proto_role_cap)349 static void _phl_init_proto_stbc_cap(struct phl_info_t *phl_info,
350 u8 hw_band, struct protocol_cap_t *proto_role_cap)
351 {
352 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
353 struct role_sw_cap_t *sw_role_cap = &phl_com->role_sw_cap;
354 struct protocol_cap_t proto_cap = {0};
355
356 /* First : compare and get the stbc sw_proto_cap and hw_proto_cap .*/
357 if (RTW_HAL_STATUS_SUCCESS != rtw_hal_get_stbc_proto_cap(phl_com,
358 phl_info->hal,
359 hw_band,
360 &proto_cap)) {
361 PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_,
362 "%s : Get SW/HW STBC proto_cap FAIL, disable all of the STBC functions.\n", __func__);
363 }
364
365 /* Final : Compare with sw_role_cap->stbc_cap to judge the final wrole's STBC CAP. */
366 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s : sw_role_cap->stbc_cap = 0x%x \n",
367 __func__, sw_role_cap->stbc_cap);
368
369 #ifdef RTW_WKARD_PHY_CAP
370
371 proto_role_cap->stbc_tx = 0; /* Removed later */
372
373 /* Check sw role cap, if it is not support, set proto_role_cap->xxx to 0 */
374 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HT_TX) &&
375 (proto_cap.stbc_ht_tx)) {
376 proto_role_cap->stbc_ht_tx = 0;
377 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HT STBC Tx by sw_role_cap.\n");
378 } else {
379 proto_role_cap->stbc_ht_tx = proto_cap.stbc_ht_tx;
380 }
381
382 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_VHT_TX) &&
383 (proto_cap.stbc_vht_tx)) {
384 proto_role_cap->stbc_vht_tx = 0;
385 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT STBC Tx by sw_role_cap.\n");
386 } else {
387 proto_role_cap->stbc_vht_tx = proto_cap.stbc_vht_tx;
388 }
389
390 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_TX) &&
391 (proto_cap.stbc_he_tx)) {
392 proto_role_cap->stbc_he_tx = 0;
393 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE STBC Tx by sw_role_cap.\n");
394 } else {
395 proto_role_cap->stbc_he_tx = proto_cap.stbc_he_tx;
396 }
397
398 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_TX_GT_80M) &&
399 (proto_cap.stbc_tx_greater_80mhz)) {
400 proto_role_cap->stbc_tx_greater_80mhz = 0;
401 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable STBC Tx (greater than 80M) by sw_role_cap.\n");
402 } else {
403 proto_role_cap->stbc_tx_greater_80mhz = proto_cap.stbc_tx_greater_80mhz;
404 }
405
406 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HT_RX) &&
407 (proto_cap.stbc_ht_rx)) {
408 proto_role_cap->stbc_ht_rx = 0;
409 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HT STBC Rx by sw_role_cap.\n");
410 } else {
411 proto_role_cap->stbc_ht_rx = proto_cap.stbc_ht_rx;
412 }
413
414 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_VHT_RX) &&
415 (proto_cap.stbc_vht_rx)) {
416 proto_role_cap->stbc_vht_rx = 0;
417 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable VHT STBC Rx by sw_role_cap.\n");
418 } else {
419 proto_role_cap->stbc_vht_rx = proto_cap.stbc_vht_rx;
420 }
421
422 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_RX) &&
423 (proto_cap.stbc_he_rx)) {
424 proto_role_cap->stbc_he_rx = 0;
425 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE STBC Rx by sw_role_cap.\n");
426 } else {
427 proto_role_cap->stbc_he_rx = proto_cap.stbc_he_rx;
428 }
429
430 if (!(sw_role_cap->stbc_cap & HW_CAP_STBC_HE_RX_GT_80M) &&
431 (proto_cap.stbc_rx_greater_80mhz)) {
432 proto_role_cap->stbc_rx_greater_80mhz = 0;
433 PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Disable HE STBC Rx (greater than 80M) by sw_role_cap.\n");
434 } else {
435 proto_role_cap->stbc_rx_greater_80mhz = proto_cap.stbc_rx_greater_80mhz;
436 }
437 #endif
438
439 _phl_external_cap_limit(phl_info, proto_role_cap);
440 }
441
442 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)443 _phl_init_protocol_cap(struct phl_info_t *phl_info,
444 u8 hw_band, enum role_type rtype,
445 struct protocol_cap_t *proto_role_cap)
446 {
447 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
448
449 /* TODO: Get protocol cap from sw and hw cap*/
450 if (rtype == PHL_RTYPE_AP) {
451 proto_role_cap->num_ampdu = 128;
452 proto_role_cap->ampdu_density = 0;
453 proto_role_cap->ampdu_len_exp = 0xff;
454 proto_role_cap->amsdu_in_ampdu = 1;
455 proto_role_cap->max_amsdu_len =
456 phl_com->proto_sw_cap[hw_band].max_amsdu_len;
457 proto_role_cap->htc_rx = 1;
458 proto_role_cap->sm_ps = 0;
459 proto_role_cap->trig_padding = 0;
460 #ifdef CONFIG_PHL_TWT
461 proto_role_cap->twt =
462 phl_com->dev_cap.twt_sup & RTW_PHL_TWT_RSP_SUP;
463 #else
464 proto_role_cap->twt = 0;
465 #endif /* CONFIG_PHL_TWT */
466 proto_role_cap->all_ack = 1;
467 proto_role_cap->a_ctrl = 0xe;
468 proto_role_cap->ops = 1;
469 proto_role_cap->ht_vht_trig_rx = 0;
470 proto_role_cap->bsscolor = 0x0E; /* Default BSS Color */
471 proto_role_cap->edca[RTW_AC_BE].ac = RTW_AC_BE;
472 proto_role_cap->edca[RTW_AC_BE].param = 0xA42B;
473 proto_role_cap->edca[RTW_AC_BK].ac = RTW_AC_BK;
474 proto_role_cap->edca[RTW_AC_BK].param = 0xA549;
475 proto_role_cap->edca[RTW_AC_VI].ac = RTW_AC_VI;
476 proto_role_cap->edca[RTW_AC_VI].param = 0x5E4326;
477 proto_role_cap->edca[RTW_AC_VO].ac = RTW_AC_VO;
478 proto_role_cap->edca[RTW_AC_VO].param = 0x2F3224;
479 proto_role_cap->ht_ldpc = 1;
480 proto_role_cap->vht_ldpc = 1;
481 proto_role_cap->he_ldpc = 1;
482 proto_role_cap->sgi_20 = 1;
483 proto_role_cap->sgi_40 = 1;
484 proto_role_cap->sgi_80 = 1;
485 proto_role_cap->sgi_160 = 0;
486 switch (phl_com->phy_cap[hw_band].rxss) {
487 default:
488 break;
489 case 1:
490 proto_role_cap->ht_rx_mcs[0] = 0xff;
491 proto_role_cap->vht_rx_mcs[0] = 0xfe;
492 proto_role_cap->vht_rx_mcs[1] = 0xff;
493 proto_role_cap->he_rx_mcs[0] = 0xfe;
494 proto_role_cap->he_rx_mcs[1] = 0xff;
495 break;
496 case 2:
497 proto_role_cap->ht_rx_mcs[0] = 0xff;
498 proto_role_cap->ht_rx_mcs[1] = 0xff;
499 proto_role_cap->vht_rx_mcs[0] = 0xfa;
500 proto_role_cap->vht_rx_mcs[1] = 0xff;
501 proto_role_cap->he_rx_mcs[0] = 0xfa;
502 proto_role_cap->he_rx_mcs[1] = 0xff;
503 break;
504 }
505 switch (phl_com->phy_cap[hw_band].txss) {
506 default:
507 break;
508 case 1:
509 proto_role_cap->ht_tx_mcs[0] = 0xff;
510 proto_role_cap->vht_tx_mcs[0] = 0xfe;
511 proto_role_cap->vht_tx_mcs[1] = 0xff;
512 proto_role_cap->he_tx_mcs[0] = 0xfe;
513 proto_role_cap->he_tx_mcs[1] = 0xff;
514 break;
515 case 2:
516 proto_role_cap->ht_tx_mcs[0] = 0xff;
517 proto_role_cap->ht_tx_mcs[1] = 0xff;
518 proto_role_cap->vht_tx_mcs[0] = 0xfa;
519 proto_role_cap->vht_tx_mcs[1] = 0xff;
520 proto_role_cap->he_tx_mcs[0] = 0xfa;
521 proto_role_cap->he_tx_mcs[1] = 0xff;
522 break;
523 }
524
525 proto_role_cap->ltf_gi = 0x3f; // bit-x
526 proto_role_cap->doppler_tx = 1;
527 proto_role_cap->doppler_rx = 0;
528 proto_role_cap->dcm_max_const_tx = 0;
529 proto_role_cap->dcm_max_nss_tx = 0;
530 proto_role_cap->dcm_max_const_rx = 3;
531 proto_role_cap->dcm_max_nss_rx = 0;
532 proto_role_cap->partial_bw_su_in_mu = 1;
533 _phl_init_proto_stbc_cap(phl_info, hw_band, proto_role_cap);
534 _phl_init_proto_bf_cap(phl_info, hw_band, rtype, proto_role_cap);
535
536 /* All of the HT/VHT/HE BFee */
537 if ((1 == proto_role_cap->ht_su_bfme) ||
538 (1 == proto_role_cap->vht_su_bfme) ||
539 (1 == proto_role_cap->vht_mu_bfme) ||
540 (1 == proto_role_cap->he_su_bfme) ||
541 (1 == proto_role_cap->he_mu_bfme) ||
542 (1 == proto_role_cap->non_trig_cqi_fb)||
543 (1 == proto_role_cap->trig_cqi_fb)) {
544 proto_role_cap->bfme_sts = 3;
545 proto_role_cap->bfme_sts_greater_80mhz = 0;
546 proto_role_cap->max_nc = 1;
547 } else {
548 proto_role_cap->bfme_sts = 0;
549 proto_role_cap->bfme_sts_greater_80mhz = 0;
550 proto_role_cap->max_nc = 0;
551 }
552 /* HE BFer */
553 if ((1 == proto_role_cap->he_su_bfmr) ||
554 (1 == proto_role_cap->he_mu_bfmr)) {
555 proto_role_cap->num_snd_dim = 1;
556 proto_role_cap->num_snd_dim_greater_80mhz = 0;
557 } else {
558 proto_role_cap->num_snd_dim = 0;
559 proto_role_cap->num_snd_dim_greater_80mhz = 0;
560 }
561 /* HE BFee */
562 if ((1 == proto_role_cap->he_su_bfme) ||
563 (1 == proto_role_cap->he_mu_bfme)) {
564 proto_role_cap->ng_16_su_fb = 1;
565 proto_role_cap->ng_16_mu_fb = 1;
566 proto_role_cap->cb_sz_su_fb = 1;
567 proto_role_cap->cb_sz_mu_fb = 1;
568 proto_role_cap->he_rx_ndp_4x32 = 1;
569 } else {
570 proto_role_cap->ng_16_su_fb = 0;
571 proto_role_cap->ng_16_mu_fb = 0;
572 proto_role_cap->cb_sz_su_fb = 0;
573 proto_role_cap->cb_sz_mu_fb = 0;
574 proto_role_cap->he_rx_ndp_4x32 = 0;
575 }
576
577 /*HE SU BFer or BFer*/
578 if ((1 == proto_role_cap->he_su_bfme) ||
579 (1 == proto_role_cap->he_su_bfmr)) {
580 proto_role_cap->trig_su_bfm_fb = 1;
581 } else {
582 proto_role_cap->trig_su_bfm_fb = 0;
583 }
584 /*HE MU BFer or BFer*/
585 if ((1 == proto_role_cap->he_mu_bfme) ||
586 (1 == proto_role_cap->he_mu_bfmr)) {
587 proto_role_cap->trig_mu_bfm_fb = 1;
588 } else {
589 proto_role_cap->trig_mu_bfm_fb = 0;
590 }
591 /* HT/VHT BFee */
592 if ((1 == proto_role_cap->vht_mu_bfme) ||
593 (1 == proto_role_cap->vht_su_bfme) ||
594 (1 == proto_role_cap->ht_su_bfme)) {
595 proto_role_cap->ht_vht_ng = 0; /* vht ng = 1 */
596 proto_role_cap->ht_vht_cb = 1; /* vht_mu{9,7}/vht_su{6,4}/ht{4,2} */
597 }
598
599 proto_role_cap->partial_bw_su_er = 1;
600 proto_role_cap->pkt_padding = 2;
601 proto_role_cap->pwr_bst_factor = 1;
602 proto_role_cap->dcm_max_ru = 2;
603 proto_role_cap->long_sigb_symbol = 1;
604 proto_role_cap->tx_1024q_ru = 0;
605 proto_role_cap->rx_1024q_ru = 1;
606 proto_role_cap->fbw_su_using_mu_cmprs_sigb = 1;
607 proto_role_cap->fbw_su_using_mu_non_cmprs_sigb = 1;
608 proto_role_cap->nss_tx =
609 phl_com->phy_cap[hw_band].txss;
610 proto_role_cap->nss_rx =
611 phl_com->phy_cap[hw_band].rxss;
612 } else if (rtype == PHL_RTYPE_STATION) {
613 proto_role_cap->num_ampdu = 128;
614 proto_role_cap->ampdu_density = 0;
615 proto_role_cap->ampdu_len_exp = 0xff;
616 proto_role_cap->amsdu_in_ampdu = 1;
617 proto_role_cap->max_amsdu_len =
618 phl_com->proto_sw_cap[hw_band].max_amsdu_len;
619 proto_role_cap->htc_rx = 1;
620 proto_role_cap->sm_ps = 3;
621 proto_role_cap->trig_padding = 2;
622 #ifdef CONFIG_PHL_TWT
623 proto_role_cap->twt =
624 phl_com->dev_cap.twt_sup & RTW_PHL_TWT_REQ_SUP;
625 #else
626 proto_role_cap->twt = 0;
627 #endif /* CONFIG_PHL_TWT */
628 proto_role_cap->all_ack = 1;
629 proto_role_cap->a_ctrl = 0x6;
630 proto_role_cap->ops = 1;
631 proto_role_cap->ht_vht_trig_rx = 1;
632 proto_role_cap->edca[RTW_AC_BE].ac = RTW_AC_BE;
633 proto_role_cap->edca[RTW_AC_BE].param = 0xA42B;
634 proto_role_cap->edca[RTW_AC_BK].ac = RTW_AC_BK;
635 proto_role_cap->edca[RTW_AC_BK].param = 0xA549;
636 proto_role_cap->edca[RTW_AC_VI].ac = RTW_AC_VI;
637 proto_role_cap->edca[RTW_AC_VI].param = 0x5E4326;
638 proto_role_cap->edca[RTW_AC_VO].ac = RTW_AC_VO;
639 proto_role_cap->edca[RTW_AC_VO].param = 0x2F3224;
640 proto_role_cap->ht_ldpc = 1;
641 proto_role_cap->vht_ldpc = 1;
642 proto_role_cap->he_ldpc = 1;
643 proto_role_cap->sgi_20 = 1;
644 proto_role_cap->sgi_40 = 1;
645 proto_role_cap->sgi_80 = 1;
646 proto_role_cap->sgi_160 = 0;
647
648 switch (phl_com->phy_cap[hw_band].rxss) {
649 default:
650 break;
651 case 1:
652 proto_role_cap->ht_rx_mcs[0] = 0xff;
653 proto_role_cap->vht_rx_mcs[0] = 0xfe;
654 proto_role_cap->vht_rx_mcs[1] = 0xff;
655 proto_role_cap->he_rx_mcs[0] = 0xfe;
656 proto_role_cap->he_rx_mcs[1] = 0xff;
657 break;
658 case 2:
659 proto_role_cap->ht_rx_mcs[0] = 0xff;
660 proto_role_cap->ht_rx_mcs[1] = 0xff;
661 proto_role_cap->vht_rx_mcs[0] = 0xfa;
662 proto_role_cap->vht_rx_mcs[1] = 0xff;
663 proto_role_cap->he_rx_mcs[0] = 0xfa;
664 proto_role_cap->he_rx_mcs[1] = 0xff;
665 break;
666 }
667 switch (phl_com->phy_cap[hw_band].txss) {
668 default:
669 break;
670 case 1:
671 proto_role_cap->ht_tx_mcs[0] = 0xff;
672 proto_role_cap->vht_tx_mcs[0] = 0xfe;
673 proto_role_cap->vht_tx_mcs[1] = 0xff;
674 proto_role_cap->he_tx_mcs[0] = 0xfe;
675 proto_role_cap->he_tx_mcs[1] = 0xff;
676 break;
677 case 2:
678 proto_role_cap->ht_tx_mcs[0] = 0xff;
679 proto_role_cap->ht_tx_mcs[1] = 0xff;
680 proto_role_cap->vht_tx_mcs[0] = 0xfa;
681 proto_role_cap->vht_tx_mcs[1] = 0xff;
682 proto_role_cap->he_tx_mcs[0] = 0xfa;
683 proto_role_cap->he_tx_mcs[1] = 0xff;
684 break;
685 }
686
687 proto_role_cap->ltf_gi = 0x3f; // bit-x
688 proto_role_cap->doppler_tx = 1;
689 proto_role_cap->doppler_rx = 0;
690 proto_role_cap->dcm_max_const_tx = 3;
691 proto_role_cap->dcm_max_nss_tx = 1;
692 proto_role_cap->dcm_max_const_rx = 3;
693 proto_role_cap->dcm_max_nss_rx = 0;
694
695 _phl_init_proto_stbc_cap(phl_info, hw_band, proto_role_cap);
696 _phl_init_proto_bf_cap(phl_info, hw_band, rtype, proto_role_cap);
697
698 /* All of the HT/VHT/HE BFee */
699 if ((1 == proto_role_cap->ht_su_bfme) ||
700 (1 == proto_role_cap->vht_su_bfme) ||
701 (1 == proto_role_cap->vht_mu_bfme) ||
702 (1 == proto_role_cap->he_su_bfme) ||
703 (1 == proto_role_cap->he_mu_bfme) ||
704 (1 == proto_role_cap->non_trig_cqi_fb) ||
705 (1 == proto_role_cap->trig_cqi_fb)) {
706 proto_role_cap->bfme_sts = 3;
707 proto_role_cap->bfme_sts_greater_80mhz = 0;
708 proto_role_cap->max_nc = 1;
709 } else {
710 proto_role_cap->bfme_sts = 0;
711 proto_role_cap->bfme_sts_greater_80mhz = 0;
712 proto_role_cap->max_nc = 0;
713 }
714
715 /* HE BFer */
716 if ((1 == proto_role_cap->he_su_bfmr) ||
717 (1 == proto_role_cap->he_mu_bfmr)) {
718 proto_role_cap->num_snd_dim = 1;
719 proto_role_cap->num_snd_dim_greater_80mhz = 0;
720 } else {
721 proto_role_cap->num_snd_dim = 0;
722 proto_role_cap->num_snd_dim_greater_80mhz = 0;
723 }
724 /* HE BFee */
725 if ((1 == proto_role_cap->he_su_bfme) ||
726 (1 == proto_role_cap->he_mu_bfme)) {
727 #ifdef RTW_WKARD_BFEE_DISABLE_NG16
728 proto_role_cap->ng_16_su_fb = 0;
729 proto_role_cap->ng_16_mu_fb = 0;
730 #else
731 proto_role_cap->ng_16_su_fb = 1;
732 proto_role_cap->ng_16_mu_fb = 1;
733 #endif
734 proto_role_cap->cb_sz_su_fb = 1;
735 proto_role_cap->cb_sz_mu_fb = 1;
736 proto_role_cap->he_rx_ndp_4x32 = 1;
737 } else {
738 proto_role_cap->ng_16_su_fb = 0;
739 proto_role_cap->ng_16_mu_fb = 0;
740 proto_role_cap->cb_sz_su_fb = 0;
741 proto_role_cap->cb_sz_mu_fb = 0;
742 proto_role_cap->he_rx_ndp_4x32 = 0;
743 }
744 /*HE SU BFer or BFer*/
745 if ((1 == proto_role_cap->he_su_bfme) ||
746 (1 == proto_role_cap->he_su_bfmr)) {
747 proto_role_cap->trig_su_bfm_fb = 1;
748 } else {
749 proto_role_cap->trig_su_bfm_fb = 0;
750 }
751 /*HE MU BFer or BFer*/
752 if ((1 == proto_role_cap->he_mu_bfme) ||
753 (1 == proto_role_cap->he_mu_bfmr)) {
754 proto_role_cap->trig_mu_bfm_fb = 1;
755 } else {
756 proto_role_cap->trig_mu_bfm_fb = 0;
757 }
758 /* HT/VHT BFee */
759 if ((1 == proto_role_cap->vht_mu_bfme) ||
760 (1 == proto_role_cap->vht_su_bfme) ||
761 (1 == proto_role_cap->ht_su_bfme)) {
762 proto_role_cap->ht_vht_ng = 0; /* vht ng = 1 */
763 proto_role_cap->ht_vht_cb = 1; /* vht_mu{9,7}/vht_su{6,4}/ht{4,2} */
764 }
765 proto_role_cap->partial_bw_su_in_mu = 0;
766 proto_role_cap->partial_bw_su_er = 1;
767 proto_role_cap->pkt_padding = 2;
768 proto_role_cap->pwr_bst_factor = 1;
769 proto_role_cap->dcm_max_ru = 2;
770 proto_role_cap->long_sigb_symbol = 1;
771 proto_role_cap->tx_1024q_ru = 1;
772 proto_role_cap->rx_1024q_ru = 1;
773 proto_role_cap->fbw_su_using_mu_cmprs_sigb = 1;
774 proto_role_cap->fbw_su_using_mu_non_cmprs_sigb = 1;
775 proto_role_cap->nss_tx =
776 phl_com->phy_cap[hw_band].txss;
777 proto_role_cap->nss_rx =
778 phl_com->phy_cap[hw_band].rxss;
779 }
780 return RTW_PHL_STATUS_SUCCESS;
781 }
782
783 enum rtw_phl_status
phl_init_protocol_cap(struct phl_info_t * phl_info,struct rtw_wifi_role_t * wifi_role)784 phl_init_protocol_cap(struct phl_info_t *phl_info,
785 struct rtw_wifi_role_t *wifi_role)
786 {
787
788 enum rtw_phl_status ret = RTW_PHL_STATUS_SUCCESS;
789 struct protocol_cap_t *role_proto_cap = &wifi_role->proto_role_cap;
790
791 _os_mem_set(phl_to_drvpriv(phl_info),
792 role_proto_cap, 0, sizeof(struct protocol_cap_t));
793
794 ret = _phl_init_protocol_cap(phl_info, wifi_role->hw_band, wifi_role->type,
795 role_proto_cap);
796
797 if (ret == RTW_PHL_STATUS_FAILURE)
798 PHL_ERR("wrole:%d - %s failed\n", wifi_role->id, __func__);
799
800 return ret;
801 }
802
803 static enum rtw_phl_status
_phl_init_role_cap(struct phl_info_t * phl_info,u8 hw_band,struct role_cap_t * role_cap)804 _phl_init_role_cap(struct phl_info_t *phl_info,
805 u8 hw_band, struct role_cap_t *role_cap)
806 {
807 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
808
809 #ifdef RTW_WKARD_PHY_CAP
810 role_cap->wmode = phl_com->phy_cap[hw_band].proto_sup;
811 role_cap->bw = _phl_sw_cap_get_hi_bw(&phl_com->phy_cap[hw_band]);
812 role_cap->rty_lmt = 0xFF; /* default follow CR */
813 role_cap->rty_lmt_rts = 0xFF; /* default follow CR */
814
815 role_cap->tx_htc = 1;
816 role_cap->tx_sgi = 1;
817 role_cap->tx_ht_ldpc = 1;
818 role_cap->tx_vht_ldpc = 1;
819 role_cap->tx_he_ldpc = 1;
820 role_cap->tx_ht_stbc = 1;
821 role_cap->tx_vht_stbc = 1;
822 role_cap->tx_he_stbc = 1;
823 #endif
824 return RTW_PHL_STATUS_SUCCESS;
825 }
826
827 enum rtw_phl_status
phl_init_role_cap(struct phl_info_t * phl_info,struct rtw_wifi_role_t * wifi_role)828 phl_init_role_cap(struct phl_info_t *phl_info,
829 struct rtw_wifi_role_t *wifi_role)
830 {
831 struct role_cap_t *role_cap = &wifi_role->cap;
832 enum rtw_phl_status ret = RTW_PHL_STATUS_SUCCESS;
833
834 _os_mem_set(phl_to_drvpriv(phl_info),
835 role_cap, 0, sizeof(struct role_cap_t));
836
837
838 ret = _phl_init_role_cap(phl_info, wifi_role->hw_band, role_cap);
839
840 ret = phl_custom_init_role_cap(phl_info, wifi_role->hw_band, role_cap);
841
842 return RTW_PHL_STATUS_SUCCESS;
843 }
844
845 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)846 rtw_phl_get_dft_proto_cap(void *phl, u8 hw_band, enum role_type rtype,
847 struct protocol_cap_t *role_proto_cap)
848 {
849 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
850
851 _os_mem_set(phl_to_drvpriv(phl_info),
852 role_proto_cap, 0, sizeof(struct protocol_cap_t));
853
854 return _phl_init_protocol_cap(phl_info, hw_band, rtype,
855 role_proto_cap);
856 }
857
858 enum rtw_phl_status
rtw_phl_get_dft_cap(void * phl,u8 hw_band,struct role_cap_t * role_cap)859 rtw_phl_get_dft_cap(void *phl, u8 hw_band, struct role_cap_t *role_cap)
860 {
861 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
862
863 _os_mem_set(phl_to_drvpriv(phl_info),
864 role_cap, 0, sizeof(struct role_cap_t));
865
866 return _phl_init_role_cap(phl_info, hw_band, role_cap);
867 }
868
869
rtw_phl_final_cap_decision(void * phl)870 void rtw_phl_final_cap_decision(void * phl)
871 {
872 struct phl_info_t *phl_info = (struct phl_info_t *)phl;
873 struct rtw_phl_com_t *phl_com = phl_info->phl_com;
874
875 #ifdef CONFIG_PHL_DFS
876 phl_com->dfs_info.region_domain = DFS_REGD_ETSI;
877 #endif
878
879 rtw_hal_final_cap_decision(phl_com, phl_info->hal);
880 }
881
phl_init_proto_stbc_cap(struct rtw_wifi_role_t * role,struct phl_info_t * phl_info,struct protocol_cap_t * proto_role_cap)882 void phl_init_proto_stbc_cap(struct rtw_wifi_role_t *role,
883 struct phl_info_t *phl_info,
884 struct protocol_cap_t *proto_role_cap)
885 {
886 if (role->chandef.band == BAND_ON_24G)
887 proto_role_cap->cap_option |= EXT_CAP_LIMIT_2G_RX_STBC;
888 else
889 proto_role_cap->cap_option &= ~(EXT_CAP_LIMIT_2G_RX_STBC);
890
891 _phl_init_proto_stbc_cap(phl_info, role->hw_band, proto_role_cap);
892 }
893