1 /******************************************************************************
2 *
3 * Copyright(c) 2016 - 2017 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 /*@************************************************************
16 * Description:
17 *
18 * This file is for TXBF mechanism
19 *
20 ************************************************************/
21 #include "mp_precomp.h"
22 #include "../phydm_precomp.h"
23
24 #ifdef PHYDM_BEAMFORMING_SUPPORT
25 /*@Beamforming halcomtxbf API create by YuChen 2015/05*/
26
hal_com_txbf_beamform_init(void * dm_void)27 void hal_com_txbf_beamform_init(
28 void *dm_void)
29 {
30 struct dm_struct *dm = (struct dm_struct *)dm_void;
31 boolean is_iqgen_setting_ok = false;
32
33 if (dm->support_ic_type & ODM_RTL8814A) {
34 is_iqgen_setting_ok = phydm_beamforming_set_iqgen_8814A(dm);
35 PHYDM_DBG(dm, DBG_TXBF, "[%s] is_iqgen_setting_ok = %d\n",
36 __func__, is_iqgen_setting_ok);
37 }
38 }
39
40 /*Only used for MU BFer Entry when get GID management frame (self as MU STA)*/
hal_com_txbf_config_gtab(void * dm_void)41 void hal_com_txbf_config_gtab(
42 void *dm_void)
43 {
44 struct dm_struct *dm = (struct dm_struct *)dm_void;
45
46 if (dm->support_ic_type & ODM_RTL8822B)
47 hal_txbf_8822b_config_gtab(dm);
48 }
49
phydm_beamform_set_sounding_enter(void * dm_void)50 void phydm_beamform_set_sounding_enter(
51 void *dm_void)
52 {
53 struct dm_struct *dm = (struct dm_struct *)dm_void;
54 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
55 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
56
57 if (!odm_is_work_item_scheduled(&p_txbf_info->txbf_enter_work_item))
58 odm_schedule_work_item(&p_txbf_info->txbf_enter_work_item);
59 #else
60 hal_com_txbf_enter_work_item_callback(dm);
61 #endif
62 }
63
phydm_beamform_set_sounding_leave(void * dm_void)64 void phydm_beamform_set_sounding_leave(
65 void *dm_void)
66 {
67 struct dm_struct *dm = (struct dm_struct *)dm_void;
68 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
69 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
70
71 if (!odm_is_work_item_scheduled(&p_txbf_info->txbf_leave_work_item))
72 odm_schedule_work_item(&p_txbf_info->txbf_leave_work_item);
73 #else
74 hal_com_txbf_leave_work_item_callback(dm);
75 #endif
76 }
77
phydm_beamform_set_sounding_rate(void * dm_void)78 void phydm_beamform_set_sounding_rate(
79 void *dm_void)
80 {
81 struct dm_struct *dm = (struct dm_struct *)dm_void;
82 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
83 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
84
85 if (!odm_is_work_item_scheduled(&p_txbf_info->txbf_rate_work_item))
86 odm_schedule_work_item(&p_txbf_info->txbf_rate_work_item);
87 #else
88 hal_com_txbf_rate_work_item_callback(dm);
89 #endif
90 }
91
phydm_beamform_set_sounding_status(void * dm_void)92 void phydm_beamform_set_sounding_status(
93 void *dm_void)
94 {
95 struct dm_struct *dm = (struct dm_struct *)dm_void;
96 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
97 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
98
99 if (!odm_is_work_item_scheduled(&p_txbf_info->txbf_status_work_item))
100 odm_schedule_work_item(&p_txbf_info->txbf_status_work_item);
101 #else
102 hal_com_txbf_status_work_item_callback(dm);
103 #endif
104 }
105
phydm_beamform_set_sounding_fw_ndpa(void * dm_void)106 void phydm_beamform_set_sounding_fw_ndpa(
107 void *dm_void)
108 {
109 struct dm_struct *dm = (struct dm_struct *)dm_void;
110 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
111 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
112
113 if (*dm->is_fw_dw_rsvd_page_in_progress)
114 odm_set_timer(dm, &p_txbf_info->txbf_fw_ndpa_timer, 5);
115 else
116 odm_schedule_work_item(&p_txbf_info->txbf_fw_ndpa_work_item);
117 #else
118 hal_com_txbf_fw_ndpa_work_item_callback(dm);
119 #endif
120 }
121
phydm_beamform_set_sounding_clk(void * dm_void)122 void phydm_beamform_set_sounding_clk(
123 void *dm_void)
124 {
125 struct dm_struct *dm = (struct dm_struct *)dm_void;
126 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
127 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
128
129 if (!odm_is_work_item_scheduled(&p_txbf_info->txbf_clk_work_item))
130 odm_schedule_work_item(&p_txbf_info->txbf_clk_work_item);
131 #elif (DM_ODM_SUPPORT_TYPE == ODM_CE)
132 phydm_run_in_thread_cmd(dm, hal_com_txbf_clk_work_item_callback, dm);
133 #else
134 hal_com_txbf_clk_work_item_callback(dm);
135 #endif
136 }
137
phydm_beamform_set_reset_tx_path(void * dm_void)138 void phydm_beamform_set_reset_tx_path(
139 void *dm_void)
140 {
141 struct dm_struct *dm = (struct dm_struct *)dm_void;
142 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
143 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
144 struct _RT_WORK_ITEM *pwi = &p_txbf_info->txbf_reset_tx_path_work_item;
145
146 if (!odm_is_work_item_scheduled(pwi))
147 odm_schedule_work_item(pwi);
148 #else
149 hal_com_txbf_reset_tx_path_work_item_callback(dm);
150 #endif
151 }
152
phydm_beamform_set_get_tx_rate(void * dm_void)153 void phydm_beamform_set_get_tx_rate(
154 void *dm_void)
155 {
156 struct dm_struct *dm = (struct dm_struct *)dm_void;
157 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
158 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
159 struct _RT_WORK_ITEM *pwi = &p_txbf_info->txbf_get_tx_rate_work_item;
160
161 if (!odm_is_work_item_scheduled(pwi))
162 odm_schedule_work_item(pwi);
163 #else
164 hal_com_txbf_get_tx_rate_work_item_callback(dm);
165 #endif
166 }
167
hal_com_txbf_enter_work_item_callback(void * adapter)168 void hal_com_txbf_enter_work_item_callback(
169 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
170 void *adapter
171 #else
172 void *dm_void
173 #endif
174 )
175 {
176 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
177 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
178 struct dm_struct *dm = &hal_data->DM_OutSrc;
179 #else
180 struct dm_struct *dm = (struct dm_struct *)dm_void;
181 #endif
182 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
183 u8 idx = p_txbf_info->txbf_idx;
184
185 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
186
187 if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821))
188 hal_txbf_jaguar_enter(dm, idx);
189 else if (dm->support_ic_type & ODM_RTL8192E)
190 hal_txbf_8192e_enter(dm, idx);
191 else if (dm->support_ic_type & ODM_RTL8814A)
192 hal_txbf_8814a_enter(dm, idx);
193 else if (dm->support_ic_type & ODM_RTL8822B)
194 hal_txbf_8822b_enter(dm, idx);
195 }
196
hal_com_txbf_leave_work_item_callback(void * adapter)197 void hal_com_txbf_leave_work_item_callback(
198 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
199 void *adapter
200 #else
201 void *dm_void
202 #endif
203 )
204 {
205 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
206 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
207 struct dm_struct *dm = &hal_data->DM_OutSrc;
208 #else
209 struct dm_struct *dm = (struct dm_struct *)dm_void;
210 #endif
211 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
212
213 u8 idx = p_txbf_info->txbf_idx;
214
215 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
216
217 if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821))
218 hal_txbf_jaguar_leave(dm, idx);
219 else if (dm->support_ic_type & ODM_RTL8192E)
220 hal_txbf_8192e_leave(dm, idx);
221 else if (dm->support_ic_type & ODM_RTL8814A)
222 hal_txbf_8814a_leave(dm, idx);
223 else if (dm->support_ic_type & ODM_RTL8822B)
224 hal_txbf_8822b_leave(dm, idx);
225 }
226
hal_com_txbf_fw_ndpa_work_item_callback(void * adapter)227 void hal_com_txbf_fw_ndpa_work_item_callback(
228 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
229 void *adapter
230 #else
231 void *dm_void
232 #endif
233 )
234 {
235 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
236 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
237 struct dm_struct *dm = &hal_data->DM_OutSrc;
238 #else
239 struct dm_struct *dm = (struct dm_struct *)dm_void;
240 #endif
241 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
242 u8 idx = p_txbf_info->ndpa_idx;
243
244 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
245
246 if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821))
247 hal_txbf_jaguar_fw_txbf(dm, idx);
248 else if (dm->support_ic_type & ODM_RTL8192E)
249 hal_txbf_8192e_fw_tx_bf(dm, idx);
250 else if (dm->support_ic_type & ODM_RTL8814A)
251 hal_txbf_8814a_fw_txbf(dm, idx);
252 else if (dm->support_ic_type & ODM_RTL8822B)
253 hal_txbf_8822b_fw_txbf(dm, idx);
254 }
255
hal_com_txbf_clk_work_item_callback(void * adapter)256 void hal_com_txbf_clk_work_item_callback(
257 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
258 void *adapter
259 #else
260 void *dm_void
261 #endif
262 )
263 {
264 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
265 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
266 struct dm_struct *dm = &hal_data->DM_OutSrc;
267 #else
268 struct dm_struct *dm = (struct dm_struct *)dm_void;
269 #endif
270
271 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
272
273 if (dm->support_ic_type & ODM_RTL8812)
274 hal_txbf_jaguar_clk_8812a(dm);
275 }
276
hal_com_txbf_rate_work_item_callback(void * adapter)277 void hal_com_txbf_rate_work_item_callback(
278 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
279 void *adapter
280 #else
281 void *dm_void
282 #endif
283 )
284 {
285 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
286 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
287 struct dm_struct *dm = &hal_data->DM_OutSrc;
288 #else
289 struct dm_struct *dm = (struct dm_struct *)dm_void;
290 #endif
291 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
292 u8 BW = p_txbf_info->BW;
293 u8 rate = p_txbf_info->rate;
294
295 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
296
297 if (dm->support_ic_type & ODM_RTL8812)
298 hal_txbf_8812a_set_ndpa_rate(dm, BW, rate);
299 else if (dm->support_ic_type & ODM_RTL8192E)
300 hal_txbf_8192e_set_ndpa_rate(dm, BW, rate);
301 else if (dm->support_ic_type & ODM_RTL8814A)
302 hal_txbf_8814a_set_ndpa_rate(dm, BW, rate);
303 }
304
305 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
hal_com_txbf_fw_ndpa_timer_callback(struct phydm_timer_list * timer)306 void hal_com_txbf_fw_ndpa_timer_callback(
307 struct phydm_timer_list *timer)
308 {
309 void *adapter = (void *)timer->Adapter;
310 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
311 struct dm_struct *dm = &hal_data->DM_OutSrc;
312
313 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
314
315 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
316
317 if (*dm->is_fw_dw_rsvd_page_in_progress)
318 odm_set_timer(dm, &(p_txbf_info->txbf_fw_ndpa_timer), 5);
319 else
320 odm_schedule_work_item(&(p_txbf_info->txbf_fw_ndpa_work_item));
321 }
322 #endif
323
hal_com_txbf_status_work_item_callback(void * adapter)324 void hal_com_txbf_status_work_item_callback(
325 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
326 void *adapter
327 #else
328 void *dm_void
329 #endif
330 )
331 {
332 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
333 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
334 struct dm_struct *dm = &hal_data->DM_OutSrc;
335 #else
336 struct dm_struct *dm = (struct dm_struct *)dm_void;
337 #endif
338 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
339
340 u8 idx = p_txbf_info->txbf_idx;
341
342 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
343
344 if (dm->support_ic_type & (ODM_RTL8812 | ODM_RTL8821))
345 hal_txbf_jaguar_status(dm, idx);
346 else if (dm->support_ic_type & ODM_RTL8192E)
347 hal_txbf_8192e_status(dm, idx);
348 else if (dm->support_ic_type & ODM_RTL8814A)
349 hal_txbf_8814a_status(dm, idx);
350 else if (dm->support_ic_type & ODM_RTL8822B)
351 hal_txbf_8822b_status(dm, idx);
352 }
353
hal_com_txbf_reset_tx_path_work_item_callback(void * adapter)354 void hal_com_txbf_reset_tx_path_work_item_callback(
355 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
356 void *adapter
357 #else
358 void *dm_void
359 #endif
360 )
361 {
362 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
363 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
364 struct dm_struct *dm = &hal_data->DM_OutSrc;
365 #else
366 struct dm_struct *dm = (struct dm_struct *)dm_void;
367 #endif
368 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
369
370 u8 idx = p_txbf_info->txbf_idx;
371
372 if (dm->support_ic_type & ODM_RTL8814A)
373 hal_txbf_8814a_reset_tx_path(dm, idx);
374 }
375
hal_com_txbf_get_tx_rate_work_item_callback(void * adapter)376 void hal_com_txbf_get_tx_rate_work_item_callback(
377 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
378 void *adapter
379 #else
380 void *dm_void
381 #endif
382 )
383 {
384 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
385 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
386 struct dm_struct *dm = &hal_data->DM_OutSrc;
387 #else
388 struct dm_struct *dm = (struct dm_struct *)dm_void;
389 #endif
390
391 if (dm->support_ic_type & ODM_RTL8814A)
392 hal_txbf_8814a_get_tx_rate(dm);
393 }
394
395 boolean
hal_com_txbf_set(void * dm_void,u8 set_type,void * p_in_buf)396 hal_com_txbf_set(
397 void *dm_void,
398 u8 set_type,
399 void *p_in_buf)
400 {
401 struct dm_struct *dm = (struct dm_struct *)dm_void;
402 u8 *p_u1_tmp = (u8 *)p_in_buf;
403 struct _HAL_TXBF_INFO *p_txbf_info = &dm->beamforming_info.txbf_info;
404
405 PHYDM_DBG(dm, DBG_TXBF, "[%s] set_type = 0x%X\n", __func__, set_type);
406
407 switch (set_type) {
408 case TXBF_SET_SOUNDING_ENTER:
409 p_txbf_info->txbf_idx = *p_u1_tmp;
410 phydm_beamform_set_sounding_enter(dm);
411 break;
412
413 case TXBF_SET_SOUNDING_LEAVE:
414 p_txbf_info->txbf_idx = *p_u1_tmp;
415 phydm_beamform_set_sounding_leave(dm);
416 break;
417
418 case TXBF_SET_SOUNDING_RATE:
419 p_txbf_info->BW = p_u1_tmp[0];
420 p_txbf_info->rate = p_u1_tmp[1];
421 phydm_beamform_set_sounding_rate(dm);
422 break;
423
424 case TXBF_SET_SOUNDING_STATUS:
425 p_txbf_info->txbf_idx = *p_u1_tmp;
426 phydm_beamform_set_sounding_status(dm);
427 break;
428
429 case TXBF_SET_SOUNDING_FW_NDPA:
430 p_txbf_info->ndpa_idx = *p_u1_tmp;
431 phydm_beamform_set_sounding_fw_ndpa(dm);
432 break;
433
434 case TXBF_SET_SOUNDING_CLK:
435 phydm_beamform_set_sounding_clk(dm);
436 break;
437
438 case TXBF_SET_TX_PATH_RESET:
439 p_txbf_info->txbf_idx = *p_u1_tmp;
440 phydm_beamform_set_reset_tx_path(dm);
441 break;
442
443 case TXBF_SET_GET_TX_RATE:
444 phydm_beamform_set_get_tx_rate(dm);
445 break;
446 }
447
448 return true;
449 }
450
451 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)
452 boolean
hal_com_txbf_get(void * adapter,u8 get_type,void * p_out_buf)453 hal_com_txbf_get(
454 void *adapter,
455 u8 get_type,
456 void *p_out_buf)
457 {
458 PHAL_DATA_TYPE hal_data = GET_HAL_DATA(((PADAPTER)adapter));
459 struct dm_struct *dm = &hal_data->DM_OutSrc;
460 boolean *p_boolean = (boolean *)p_out_buf;
461
462 PHYDM_DBG(dm, DBG_TXBF, "[%s] Start!\n", __func__);
463
464 if (get_type == TXBF_GET_EXPLICIT_BEAMFORMEE) {
465 if (IS_HARDWARE_TYPE_OLDER_THAN_8812A(adapter))
466 *p_boolean = false;
467 else if (/*@IS_HARDWARE_TYPE_8822B(adapter) ||*/
468 IS_HARDWARE_TYPE_8821B(adapter) ||
469 IS_HARDWARE_TYPE_8192E(adapter) ||
470 IS_HARDWARE_TYPE_8192F(adapter) ||
471 IS_HARDWARE_TYPE_JAGUAR(adapter) ||
472 IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter) ||
473 IS_HARDWARE_TYPE_JAGUAR3(adapter))
474 *p_boolean = true;
475 else
476 *p_boolean = false;
477 } else if (get_type == TXBF_GET_EXPLICIT_BEAMFORMER) {
478 if (IS_HARDWARE_TYPE_OLDER_THAN_8812A(adapter))
479 *p_boolean = false;
480 else if (/*@IS_HARDWARE_TYPE_8822B(adapter) ||*/
481 IS_HARDWARE_TYPE_8821B(adapter) ||
482 IS_HARDWARE_TYPE_8192E(adapter) ||
483 IS_HARDWARE_TYPE_8192F(adapter) ||
484 IS_HARDWARE_TYPE_JAGUAR(adapter) ||
485 IS_HARDWARE_TYPE_JAGUAR_AND_JAGUAR2(adapter) ||
486 IS_HARDWARE_TYPE_JAGUAR3(adapter)) {
487 if (hal_data->RF_Type == RF_2T2R ||
488 hal_data->RF_Type == RF_3T3R ||
489 hal_data->RF_Type == RF_4T4R)
490 *p_boolean = true;
491 else
492 *p_boolean = false;
493 } else
494 *p_boolean = false;
495 } else if (get_type == TXBF_GET_MU_MIMO_STA) {
496 #if ((RTL8822B_SUPPORT == 1) || (RTL8821C_SUPPORT == 1) ||\
497 (RTL8822C_SUPPORT == 1))
498 if (IS_HARDWARE_TYPE_8822B(adapter) ||
499 IS_HARDWARE_TYPE_8821C(adapter) ||
500 IS_HARDWARE_TYPE_JAGUAR3(adapter))
501 *p_boolean = true;
502 else
503 #endif
504 *p_boolean = false;
505
506 } else if (get_type == TXBF_GET_MU_MIMO_AP) {
507 #if ((RTL8822B_SUPPORT == 1) || (RTL8822C_SUPPORT == 1))
508 if (IS_HARDWARE_TYPE_8822B(adapter) ||
509 IS_HARDWARE_TYPE_JAGUAR3(adapter))
510 *p_boolean = true;
511 else
512 #endif
513 *p_boolean = false;
514 }
515
516 return true;
517 }
518 #endif
519
520 #endif
521