xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/hal_g6/hal_beamform.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 
16 #include "hal_headers.h"
17 
18 /**
19  * rtw_hal_bf_dbg_dump_entry
20  * @entry: hal_bf_entry for dump content
21  **/
rtw_hal_bf_dbg_dump_entry(void * entry)22 void rtw_hal_bf_dbg_dump_entry(void *entry)
23 {
24 	struct hal_bf_entry *bf_entry = (struct hal_bf_entry *)entry;
25 	if (bf_entry == NULL) {
26 		return;
27 	}
28 
29 	PHL_INFO("-----DUMP BF ENTRY-----\n");
30 	PHL_INFO("bf_entry->bf_idx 0x%x \n", bf_entry->bf_idx);
31 	PHL_INFO("bf_entry->macid 0x%x \n", bf_entry->macid);
32 	PHL_INFO("bf_entry->aid12 0x%x \n", bf_entry->aid12);
33 	PHL_INFO("bf_entry->band 0x%x \n", bf_entry->band);
34 	PHL_INFO("bf_entry->en_swap 0x%x \n", bf_entry->en_swap ? 1 : 0);
35 	PHL_INFO("bf_entry->counter 0x%x \n", bf_entry->couter);
36 	PHL_INFO("bf_entry->csi_buf 0x%x \n", bf_entry->csi_buf);
37 	PHL_INFO("bf_entry->csi_buf_swap 0x%x \n", bf_entry->csi_buf_swap);
38 	if (bf_entry->bfee != NULL) {
39 		PHL_INFO("bf_entry->bfee->type 0x%x \n", bf_entry->bfee->type);
40 	}
41 }
42 /**
43  * rtw_hal_bf_dbg_dump_entry_all
44  * @hal: hal_info_t
45  **/
rtw_hal_bf_dbg_dump_entry_all(void * hal)46 void rtw_hal_bf_dbg_dump_entry_all(void *hal)
47 {
48 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
49 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
50 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
51 	struct hal_bf_entry *bf_entry;
52 	_os_list *busy_list = &bf_obj->bf_busy_list;
53 	_os_list *idle_list = &bf_obj->bf_idle_list;
54 
55 	PHL_INFO("-----DUMP BF BUSY LIST-----\n");
56 	if(list_empty(busy_list)) {
57 		PHL_INFO("BF Entry BUSY LIST is Empty\n");
58 	} else {
59 		phl_list_for_loop(bf_entry, struct hal_bf_entry, busy_list,
60 					list) {
61 			PHL_INFO("bf_entry->bf_idx 0x%x \n", bf_entry->bf_idx);
62 			PHL_INFO("bf_entry->macid 0x%x \n", bf_entry->macid);
63 			PHL_INFO("bf_entry->aid12 0x%x \n", bf_entry->aid12);
64 			PHL_INFO("bf_entry->band 0x%x \n", bf_entry->band);
65 			PHL_INFO("bf_entry->en_swap 0x%x \n", bf_entry->en_swap ? 1 : 0);
66 			PHL_INFO("bf_entry->counter 0x%x \n", bf_entry->couter);
67 			PHL_INFO("bf_entry->csi_buf 0x%x \n",
68 					bf_entry->csi_buf);
69 			PHL_INFO("bf_entry->csi_buf_swap 0x%x \n",
70 					bf_entry->csi_buf_swap);
71 			if (NULL!=bf_entry->bfee) {
72 				PHL_INFO("bfee->idx 0x%x \n",
73 					bf_entry->bfee->idx);
74 				PHL_INFO("bfee->type 0x%x \n",
75 					bf_entry->bfee->type);
76 			}
77 		}
78 	}
79 	PHL_INFO("-----DUMP BF IDLE LIST-----\n");
80 	if(list_empty(idle_list)) {
81 		PHL_INFO("BF Entry IDLE LIST is Empty\n");
82 	} else {
83 		phl_list_for_loop(bf_entry, struct hal_bf_entry, idle_list,
84 					list) {
85 			PHL_INFO("bf_entry->bf_idx 0x%x \n", bf_entry->bf_idx);
86 			PHL_INFO("bf_entry->macid 0x%x \n", bf_entry->macid);
87 			PHL_INFO("bf_entry->aid12 0x%x \n", bf_entry->aid12);
88 			PHL_INFO("bf_entry->band 0x%x \n", bf_entry->band);
89 			PHL_INFO("bf_entry->csi_buf 0x%x \n",
90 					bf_entry->csi_buf);
91 		}
92 	}
93 }
94 
_reset_bf_entry(struct hal_bf_entry * bf_entry)95 void _reset_bf_entry(struct hal_bf_entry *bf_entry)
96 {
97 	bf_entry->macid = 0;
98 	bf_entry->aid12 = 0;
99 	bf_entry->csi_buf = 0;
100 	bf_entry->bfee = NULL;
101 	bf_entry->csi_buf_swap = 0;
102 	bf_entry->couter = 0;
103 }
104 
_reset_sumu_entry(struct hal_sumu_entry * entry)105 void _reset_sumu_entry(struct hal_sumu_entry *entry)
106 {
107 	entry->snd_sts = 0;
108 	return;
109 }
110 
111 /* START of tx bf entry */
_query_idle_bf_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj)112 static struct hal_bf_entry *_query_idle_bf_entry(struct hal_info_t *hal_info,
113 				struct hal_bf_obj *bf_obj)
114 {
115 	void *drv_priv = hal_to_drvpriv(hal_info);
116 	_os_list *idle_list = &bf_obj->bf_idle_list;
117 	struct hal_bf_entry *bf_entry = NULL;
118 
119 	_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
120 	if (true == list_empty(idle_list)) {
121 		bf_entry = NULL;
122 	} else {
123 		bf_entry = list_first_entry(idle_list, struct hal_bf_entry,
124 					list);
125 		bf_obj->num_idle_bf_entry--;
126 		list_del(&bf_entry->list);
127 	}
128 	_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
129 
130 	return bf_entry;
131 }
132 
_enqueue_idle_bf_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj,struct hal_bf_entry * bf_entry)133 static enum rtw_hal_status _enqueue_idle_bf_entry(
134 				struct hal_info_t *hal_info,
135 				struct hal_bf_obj *bf_obj,
136 				struct hal_bf_entry *bf_entry)
137 {
138 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
139 	void *drv_priv = hal_to_drvpriv(hal_info);
140 	_os_list *list = &bf_obj->bf_idle_list;
141 
142 	if (bf_entry != NULL) {
143 		_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
144 		list_add(&bf_entry->list, list);
145 		bf_obj->num_idle_bf_entry++;
146 		_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
147 		status = RTW_HAL_STATUS_SUCCESS;
148 	}
149 
150 	return status;
151 }
152 
_enqueue_busy_bf_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj,struct hal_bf_entry * bf_entry)153 static enum rtw_hal_status _enqueue_busy_bf_entry(
154 				struct hal_info_t *hal_info,
155 				struct hal_bf_obj *bf_obj,
156 				struct hal_bf_entry *bf_entry)
157 {
158 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
159 	void *drv_priv = hal_to_drvpriv(hal_info);
160 	_os_list *list = &bf_obj->bf_busy_list;
161 
162 	if (bf_entry != NULL) {
163 		_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
164 		list_add_tail(&bf_entry->list, list);
165 		_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
166 		status = RTW_HAL_STATUS_SUCCESS;
167 	}
168 
169 	return status;
170 }
171 /*su entry*/
_query_idle_su_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj)172 static struct hal_sumu_entry *_query_idle_su_entry(struct hal_info_t *hal_info,
173 				struct hal_bf_obj *bf_obj)
174 {
175 	void *drv_priv = hal_to_drvpriv(hal_info);
176 	_os_list *idle_list = &bf_obj->su_idle_list;
177 	struct hal_sumu_entry *su_entry = NULL;
178 
179 	_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
180 	if (true == list_empty(idle_list)) {
181 		su_entry = NULL;
182 	} else {
183 		su_entry = list_first_entry(idle_list, struct hal_sumu_entry,
184 					list);
185 		bf_obj->num_idle_su_entry--;
186 		list_del(&su_entry->list);
187 	}
188 	_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
189 
190 	return su_entry;
191 }
192 
_enqueue_idle_su_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj,struct hal_sumu_entry * su_entry)193 static enum rtw_hal_status _enqueue_idle_su_entry(
194 				struct hal_info_t *hal_info,
195 				struct hal_bf_obj *bf_obj,
196 				struct hal_sumu_entry *su_entry)
197 {
198 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
199 	void *drv_priv = hal_to_drvpriv(hal_info);
200 	_os_list *list = &bf_obj->su_idle_list;
201 
202 	if (su_entry != NULL) {
203 		_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
204 		list_add(&su_entry->list, list);
205 		bf_obj->num_idle_su_entry++;
206 		_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
207 		status = RTW_HAL_STATUS_SUCCESS;
208 	}
209 
210 	return status;
211 }
212 
_enqueue_busy_su_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj,struct hal_sumu_entry * su_entry)213 static enum rtw_hal_status _enqueue_busy_su_entry(
214 				struct hal_info_t *hal_info,
215 				struct hal_bf_obj *bf_obj,
216 				struct hal_sumu_entry *su_entry)
217 {
218 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
219 	void *drv_priv = hal_to_drvpriv(hal_info);
220 	_os_list *list = &bf_obj->su_busy_list;
221 
222 	if (su_entry != NULL) {
223 		_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
224 		list_add_tail(&su_entry->list, list);
225 		_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
226 		status = RTW_HAL_STATUS_SUCCESS;
227 	}
228 
229 	return status;
230 }
231 
232 
233 /*mu entry*/
_query_idle_mu_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj)234 static struct hal_sumu_entry *_query_idle_mu_entry(struct hal_info_t *hal_info,
235 				struct hal_bf_obj *bf_obj)
236 {
237 	void *drv_priv = hal_to_drvpriv(hal_info);
238 	_os_list *idle_list = &bf_obj->mu_idle_list;
239 	struct hal_sumu_entry *mu_entry = NULL;
240 
241 	_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
242 	if (true == list_empty(idle_list)) {
243 		mu_entry = NULL;
244 	} else {
245 		mu_entry = list_first_entry(idle_list, struct hal_sumu_entry,
246 					list);
247 		bf_obj->num_idle_mu_entry--;
248 		list_del(&mu_entry->list);
249 	}
250 	_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
251 
252 	return mu_entry;
253 }
254 
_enqueue_idle_mu_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj,struct hal_sumu_entry * mu_entry)255 static enum rtw_hal_status _enqueue_idle_mu_entry(
256 				struct hal_info_t *hal_info,
257 				struct hal_bf_obj *bf_obj,
258 				struct hal_sumu_entry *mu_entry)
259 {
260 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
261 	void *drv_priv = hal_to_drvpriv(hal_info);
262 	_os_list *list = &bf_obj->mu_idle_list;
263 
264 	if (mu_entry != NULL) {
265 		_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
266 		list_add(&mu_entry->list, list);
267 		bf_obj->num_idle_mu_entry++;
268 		_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
269 		status = RTW_HAL_STATUS_SUCCESS;
270 	}
271 
272 	return status;
273 }
274 
_enqueue_busy_mu_entry(struct hal_info_t * hal_info,struct hal_bf_obj * bf_obj,struct hal_sumu_entry * mu_entry)275 static enum rtw_hal_status _enqueue_busy_mu_entry(
276 				struct hal_info_t *hal_info,
277 				struct hal_bf_obj *bf_obj,
278 				struct hal_sumu_entry *mu_entry)
279 {
280 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
281 	void *drv_priv = hal_to_drvpriv(hal_info);
282 	_os_list *list = &bf_obj->mu_busy_list;
283 
284 	if (mu_entry != NULL) {
285 		_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
286 		list_add_tail(&mu_entry->list, list);
287 		_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
288 		status = RTW_HAL_STATUS_SUCCESS;
289 	}
290 
291 	return status;
292 }
293 
294 /* hal bf init */
_hal_bf_init_su_entry(struct hal_info_t * hal_info,u8 num)295 enum rtw_hal_status _hal_bf_init_su_entry(
296 				struct hal_info_t *hal_info,
297 				u8 num)
298 {
299 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
300 	void *drv_priv = hal_to_drvpriv(hal_info);
301 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
302 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
303 	struct hal_sumu_entry *su_entry = NULL;
304 	u8 i;
305 
306 	do {
307 		bf_obj->su_entry = _os_mem_alloc(drv_priv,
308 					sizeof(*su_entry) * num);
309 
310 		if (NULL == bf_obj->su_entry) {
311 			status = RTW_HAL_STATUS_RESOURCE;
312 			break;
313 		}
314 		_os_mem_set(drv_priv, bf_obj->su_entry, 0,
315 					sizeof(*su_entry) * num);
316 
317 		su_entry = bf_obj->su_entry;
318 
319 		for ( i = 0 ; i < num; i++) {
320 			su_entry[i].idx = i;
321 			su_entry[i].type = HAL_BFEE_SU;
322 			_reset_sumu_entry(&su_entry[i]);
323 			INIT_LIST_HEAD(&su_entry[i].list);
324 			list_add_tail(&su_entry[i].list, &bf_obj->su_idle_list);
325 			bf_obj->num_idle_su_entry++;
326 		}
327 
328 	} while (0);
329 	return status;
330 }
331 
332 
_hal_bf_init_mu_entry(struct hal_info_t * hal_info,u8 num)333 enum rtw_hal_status _hal_bf_init_mu_entry(
334 	struct hal_info_t *hal_info,
335 	u8 num)
336 {
337 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
338 	void *drv_priv = hal_to_drvpriv(hal_info);
339 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
340 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
341 	struct hal_sumu_entry *mu_entry = NULL;
342 	u8 i;
343 
344 	do {
345 		bf_obj->mu_entry = _os_mem_alloc(drv_priv,
346 					sizeof(*mu_entry) * num);
347 
348 		if (NULL == bf_obj->mu_entry) {
349 			status = RTW_HAL_STATUS_RESOURCE;
350 			break;
351 		}
352 		_os_mem_set(drv_priv, bf_obj->mu_entry, 0,
353 					sizeof(*mu_entry) * num);
354 
355 		mu_entry = bf_obj->mu_entry;
356 
357 		for ( i = 0 ; i < num; i++) {
358 			mu_entry[i].idx = i;
359 			mu_entry[i].type = HAL_BFEE_MU;
360 			_reset_sumu_entry(&mu_entry[i]);
361 			INIT_LIST_HEAD(&mu_entry[i].list);
362 			list_add_tail(&mu_entry[i].list, &bf_obj->mu_idle_list);
363 			bf_obj->num_idle_mu_entry++;
364 		}
365 
366 	} while (0);
367 	return status;
368 }
369 
370 
_hal_bf_init_bf_entry(struct hal_info_t * hal_info,u8 num)371 enum rtw_hal_status _hal_bf_init_bf_entry(
372 	struct hal_info_t *hal_info,
373 	u8 num)
374 {
375 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
376 	void *drv_priv = hal_to_drvpriv(hal_info);
377 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
378 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
379 	struct hal_bf_entry *bf_entry = NULL;
380 	u8 i;
381 
382 	do {
383 		bf_obj->bf_entry = _os_mem_alloc(drv_priv,
384 						sizeof(*bf_entry) * num);
385 		if (NULL == bf_obj->bf_entry) {
386 			status = RTW_HAL_STATUS_RESOURCE;
387 			break;
388 		}
389 		_os_mem_set(drv_priv, bf_obj->bf_entry, 0,
390 					sizeof(*bf_entry) * num);
391 
392 		bf_entry = bf_obj->bf_entry;
393 
394 		for ( i = 0 ; i < num; i++) {
395 			bf_entry[i].bf_idx = i;
396 			_reset_bf_entry(&bf_entry[i]);
397 			INIT_LIST_HEAD(&bf_entry[i].list);
398 			list_add_tail(&bf_entry[i].list,
399 					&bf_obj->bf_idle_list);
400 			bf_obj->num_idle_bf_entry++;
401 		}
402 
403 	} while (0);
404 	return status;
405 }
406 
407 
408 /* Start of HAL API for other HAL modules */
409 /**
410  * hal_bf_init:
411  * 	initialize of beamform resource mgnt module
412  * input :
413  * @hal_info: (struct hal_info_t *)
414  * @bf_entry_nr:  Number of HW support TxBF Entry
415  * @su_entry_nr: Number of HW support BFee-SU Entry
416  * @mu_entry_nr: Number of HW support BFee-MU Entry
417  **/
hal_bf_init(struct hal_info_t * hal_info,u8 bf_entry_nr,u8 su_entry_nr,u8 mu_entry_nr)418 enum rtw_hal_status hal_bf_init(
419 	struct hal_info_t *hal_info,
420 	u8 bf_entry_nr,
421 	u8 su_entry_nr,
422 	u8 mu_entry_nr)
423 {
424 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
425 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
426 	struct hal_bf_obj *bf_obj = NULL;
427 	void *drv_priv = hal_to_drvpriv(hal_info);
428 
429 	FUNCIN();
430 	do {
431 		bf_obj = _os_mem_alloc(drv_priv, sizeof(*bf_obj));
432 
433 		if (bf_obj == NULL) {
434 			status = RTW_HAL_STATUS_RESOURCE;
435 			break;
436 		}
437 		hal_com->bf_obj = bf_obj;
438 
439 		_os_spinlock_init(drv_priv, &bf_obj->bf_lock);
440 
441 		INIT_LIST_HEAD(&bf_obj->bf_idle_list);
442 		INIT_LIST_HEAD(&bf_obj->bf_busy_list);
443 
444 		INIT_LIST_HEAD(&bf_obj->su_idle_list);
445 		INIT_LIST_HEAD(&bf_obj->su_busy_list);
446 
447 		INIT_LIST_HEAD(&bf_obj->mu_idle_list);
448 		INIT_LIST_HEAD(&bf_obj->mu_busy_list);
449 
450 		if (RTW_HAL_STATUS_SUCCESS !=
451 			_hal_bf_init_bf_entry(hal_info, bf_entry_nr)) {
452 			status = RTW_HAL_STATUS_RESOURCE;
453 			break;
454 		}
455 		bf_obj->max_bf_entry_nr =  bf_entry_nr;
456 
457 		if (RTW_HAL_STATUS_SUCCESS !=
458 			_hal_bf_init_su_entry(hal_info, su_entry_nr)) {
459 			status = RTW_HAL_STATUS_RESOURCE;
460 			break;
461 		}
462 		bf_obj->max_su_bfee_nr = su_entry_nr;
463 
464 		if (RTW_HAL_STATUS_SUCCESS !=
465 			_hal_bf_init_mu_entry(hal_info, mu_entry_nr)) {
466 			status = RTW_HAL_STATUS_RESOURCE;
467 			break;
468 		}
469 		bf_obj->max_mu_bfee_nr =  mu_entry_nr;
470 
471 		bf_obj->self_bf_cap[0] = 0;
472 		bf_obj->self_bf_cap[1] = 0;
473 
474 	} while (0);
475 
476 	if (RTW_HAL_STATUS_SUCCESS != status) {
477 		hal_bf_deinit(hal_info);
478 	}
479 	FUNCOUT();
480 
481 	return status;
482 }
483 
484 /**
485  * hal_bf_deinit
486  * 	deinitialize of beamform resource mgnt module
487  * input :
488  * @hal_info: (struct hal_info_t *)
489  **/
hal_bf_deinit(struct hal_info_t * hal_info)490 void hal_bf_deinit(struct hal_info_t *hal_info)
491 {
492 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
493 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
494 	void *drv_priv = hal_to_drvpriv(hal_info);
495 	struct hal_bf_entry *bf_entry = bf_obj->bf_entry;
496 	struct hal_sumu_entry *mu_entry = bf_obj->mu_entry;
497 	struct hal_sumu_entry *su_entry = bf_obj->su_entry;
498 
499 	if (bf_obj != NULL) {
500 		if (bf_entry != NULL) {
501 			_os_mem_free(hal_to_drvpriv(hal_info), bf_entry,
502 				sizeof(*bf_entry) * bf_obj->max_bf_entry_nr);
503 			bf_obj->bf_entry = NULL;
504 		}
505 		if (su_entry != NULL) {
506 			_os_mem_free(hal_to_drvpriv(hal_info), su_entry,
507 				sizeof(*su_entry) * bf_obj->max_su_bfee_nr);
508 			bf_obj->su_entry = NULL;
509 		}
510 
511 		if (mu_entry != NULL) {
512 			_os_mem_free(hal_to_drvpriv(hal_info), mu_entry,
513 				sizeof(*mu_entry) * bf_obj->max_mu_bfee_nr);
514 			bf_obj->mu_entry = NULL;
515 		}
516 
517 		_os_spinlock_free(drv_priv, &bf_obj->bf_lock);
518 
519 		/* bf obj need free as last */
520 		_os_mem_free(hal_to_drvpriv(hal_info), bf_obj,
521 					sizeof(struct hal_bf_obj));
522 		hal_com->bf_obj = NULL;
523 	}
524 }
525 /**
526  * hal_bf_release_target_bf_entry
527  * 	Release the bf entry resource
528  * input
529  * @hal_info: (struct hal_info_t *)
530  * @entry:  hal_bf_entry to be released
531  **/
hal_bf_release_target_bf_entry(struct hal_info_t * hal_info,void * entry)532 enum rtw_hal_status hal_bf_release_target_bf_entry(
533 				struct hal_info_t *hal_info,
534 				void *entry)
535 {
536 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
537 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
538 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
539 	struct hal_bf_entry *bf_entry = (struct hal_bf_entry *)entry;
540 	void *drv_priv = hal_to_drvpriv(hal_info);
541 	u8 bfee_idx = 0;
542 	u16 macid_rsvd = 0;
543 	FUNCIN();
544 	if (bf_obj != NULL && bf_entry != NULL) {
545 		if (bf_entry->bfee != NULL) {
546 
547 			bfee_idx = bf_entry->bfee->idx +
548 				((bf_entry->bfee->type == HAL_BFEE_MU) ?
549 				  bf_obj->max_su_bfee_nr : 0);
550 			/* Clear HW CR to avoid TxBF when sounding is abort */
551 			rtw_hal_mac_ax_set_bf_entry(hal_info->mac,
552 					bf_entry->band, (u8)macid_rsvd,
553 					bfee_idx, bf_entry->bf_idx, 0);
554 
555 			_reset_sumu_entry(bf_entry->bfee);
556 			_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
557 			list_del(&bf_entry->bfee->list);
558 			_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
559 			if (bf_entry->bfee->type == HAL_BFEE_MU) {
560 				_enqueue_idle_mu_entry(
561 					hal_info, bf_obj, bf_entry->bfee);
562 			} else {
563 				_enqueue_idle_su_entry(
564 					hal_info, bf_obj, bf_entry->bfee);
565 			}
566 		}
567 		_reset_bf_entry(bf_entry);
568 		_os_spinlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
569 		list_del(&bf_entry->list);
570 		_os_spinunlock(drv_priv, &bf_obj->bf_lock, _ps, NULL);
571 		_enqueue_idle_bf_entry(hal_info, bf_obj, bf_entry);
572 		status = RTW_HAL_STATUS_SUCCESS;
573 	}
574 	FUNCOUT();
575 	return status;
576 }
577 
578 /**
579  * hal_bf_query_idle_bf_entry
580  * 	Get available beamformee entry
581  * @hal_info: (struct hal_info_t *)
582  * @mu:  Is MU BFee ? 1 = MU / 0 = SU
583  * return :
584  * @hal_bf_entry:  hal_bf_entry pointer
585  **/
586 struct hal_bf_entry *
hal_bf_query_idle_bf_entry(struct hal_info_t * hal_info,bool mu)587 hal_bf_query_idle_bf_entry(
588 	struct hal_info_t *hal_info,
589 	bool mu)
590 {
591 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
592 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
593 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
594 	struct hal_bf_entry *bf_entry = NULL;
595 	struct hal_sumu_entry *sumu_entry;
596 
597 	FUNCIN();
598 
599 	do {
600 		if (bf_obj == NULL)
601 			break;
602 
603 		bf_entry = _query_idle_bf_entry(hal_info, bf_obj);
604 
605 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
606 			  "_query_idle_bf_entry bf_entry %p \n", bf_entry);
607 
608 		if (NULL == bf_entry)
609 			break;
610 
611 		if (true == mu)
612 			bf_entry->bfee = _query_idle_mu_entry(hal_info, bf_obj);
613 		else
614 			bf_entry->bfee = _query_idle_su_entry(hal_info, bf_obj);
615 
616 		if (NULL == bf_entry->bfee)
617 			break;
618 
619 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
620 			  "_query_idle_bf_entry sumu_entry %p \n", bf_entry->bfee);
621 		sumu_entry = bf_entry->bfee;
622 
623 		status = _enqueue_busy_bf_entry(hal_info, bf_obj, bf_entry);
624 		if (RTW_HAL_STATUS_SUCCESS != status) {
625 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "warring :hal_bf_entry add busy queue fail !!!\n");
626 			break;
627 		}
628 
629 		if (true == mu)
630 			status = _enqueue_busy_mu_entry(
631 					hal_info, bf_obj, sumu_entry);
632 		else
633 			status = _enqueue_busy_su_entry(
634 					hal_info, bf_obj, sumu_entry);
635 		if (RTW_HAL_STATUS_SUCCESS != status) {
636 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "warring :sumu_entry add busy queue fail !!!\n");
637 			break;
638 		}
639 	} while (0);
640 
641 	if((status != RTW_HAL_STATUS_SUCCESS) && (bf_entry != NULL)) {
642 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "Get BF Entry Fail !!!\n");
643 		hal_bf_release_target_bf_entry(hal_info, (void *)bf_entry);
644 	}
645 	FUNCOUT();
646 	return bf_entry;
647 }
648 /**
649  * hal_bf_cfg_swbf_entry
650  * 	Fill BF Entry SW Content
651  * input:
652  * @sta: rtw_phl_stainfo_t
653  **/
654 enum rtw_hal_status
hal_bf_cfg_swbf_entry(struct rtw_phl_stainfo_t * sta,bool swap)655 hal_bf_cfg_swbf_entry(struct rtw_phl_stainfo_t *sta, bool swap)
656 {
657 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
658 	struct hal_bf_entry *bf_entry =
659 		(struct hal_bf_entry *)sta->hal_sta->bf_entry;
660 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "hal_bf_cfg_swbf_entry bf_entry->idx = 0x%x\n",
661 		bf_entry->bf_idx);
662 
663 	bf_entry->macid = sta->macid;
664 	bf_entry->aid12 = sta->aid;
665 	bf_entry->band = sta->wrole->hw_band; //TODO: :BSOD in snd_test whole = NULL
666 	bf_entry->csi_buf = sta->hal_sta->bf_csi_buf;
667 	if (swap) {
668 		bf_entry->en_swap = true;
669 		bf_entry->csi_buf_swap = sta->hal_sta->bf_csi_buf_swap;
670 	}
671 
672 	return status;
673 }
674 
675 /**
676  * hal_bf_set_entry_hwcfg
677  * 	Configure BF Entry HW Setting
678  * input
679  * @hal_info: (struct hal_info_t *)
680  * @entry: struct hal_bf_entry
681  **/
hal_bf_set_entry_hwcfg(struct hal_info_t * hal_info,void * entry)682 enum rtw_hal_status hal_bf_set_entry_hwcfg(
683 	struct hal_info_t *hal_info,
684 	void *entry)
685 {
686 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
687 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
688 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
689 	struct hal_bf_entry *bf_entry = (struct hal_bf_entry *)entry;
690 	u8 bfee_idx = 0;
691 	u16 csi_buf = 0;
692 
693 	/*TODO: 8852A : SU : 0 ~ N-1;  MU : N ~ M*/
694 	bfee_idx = bf_entry->bfee->idx +
695 		((bf_entry->bfee->type == HAL_BFEE_MU) ?
696 			bf_obj->max_su_bfee_nr : 0);
697 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
698 		  "hal_bf_set_entry_hwcfg set bf sts idx = 0x%x \n", bfee_idx);
699 
700 	/*1. HALMAC Settings*/
701 	if ((bf_entry->bfee->type == HAL_BFEE_MU) && bf_entry->en_swap) {
702 		/*swap mode*/
703 		if(0 == (bf_entry->couter % 2))
704 			csi_buf = bf_entry->csi_buf&CSI_BUF_IDX_HW_MSK;
705 		else
706 			csi_buf = bf_entry->csi_buf_swap&CSI_BUF_IDX_HW_MSK;
707 
708 		rtw_hal_mac_ax_set_bf_entry(
709 				hal_info->mac, bf_entry->band,
710 				(u8)(bf_entry->macid&0xFF), bfee_idx,
711 				bf_entry->bf_idx, csi_buf);
712 
713 		bf_entry->couter++;
714 	} else {
715 		rtw_hal_mac_ax_set_bf_entry(
716 				hal_info->mac, bf_entry->band,
717 				(u8)(bf_entry->macid&0xFF), bfee_idx,
718 				bf_entry->bf_idx,
719 				bf_entry->csi_buf&CSI_BUF_IDX_HW_MSK);
720 	}
721 	/*2.TODO: HALBB Settings if needed*/
722 
723 	return status;
724 }
725 
726 /**
727  * hal_bf_update_entry_snd_sts
728  * 	Update BF Entry Sounding Status
729  * input
730  * @hal_info: (struct hal_info_t *)
731  * @entry: struct hal_bf_entry
732  **/
hal_bf_update_entry_snd_sts(struct hal_info_t * hal_info,void * entry)733 void hal_bf_update_entry_snd_sts(struct hal_info_t *hal_info, void *entry)
734 {
735 	enum rtw_hal_status status = RTW_HAL_STATUS_FAILURE;
736 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
737 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
738 	struct hal_bf_entry *bf_entry = (struct hal_bf_entry *)entry;
739 	u8 bfee_idx = 0;
740 	/*TODO: 8852A : SU : 0 ~ N-1;  MU : N ~ M*/
741 	if (NULL == bf_entry) {
742 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "[ERROR] hal_bf_update_entry_snd_sts BF_Entry = NULL\n");
743 		return;
744 	}
745 	if (NULL == bf_entry->bfee) {
746 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
747 			  "[ERROR] rtw_hal_bf_get_entry_snd_sts bf_entry->macid = 0x%x\n", bf_entry->macid);
748 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
749 			  "[ERROR] rtw_hal_bf_get_entry_snd_sts bf_entry->bfee = NULL\n");
750 		return;
751 	}
752 	bfee_idx = bf_entry->bfee->idx +
753 			((bf_entry->bfee->type == HAL_BFEE_MU) ?
754 			bf_obj->max_su_bfee_nr : 0);
755 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "hal_bf_update_entry_snd_sts idx = 0x%x \n", bfee_idx);
756 
757 	status = rtw_hal_mac_ax_get_snd_sts(hal_info->mac,
758 							bf_entry->band, bfee_idx);
759 
760 	bf_entry->bfee->snd_sts = (status == RTW_HAL_STATUS_SUCCESS) ? 1 : 0;
761 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "hal_bf_update_entry_snd_sts bf_entry->bfee->snd_sts = 0x%x \n",
762 		  bf_entry->bfee->snd_sts);
763 
764 }
765 
766 enum rtw_hal_status
hal_bf_hw_mac_deinit_bfee(struct hal_info_t * hal_info,u8 band)767 hal_bf_hw_mac_deinit_bfee(struct hal_info_t *hal_info, u8 band)
768 {
769 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
770 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
771 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
772 
773 	do {
774 		if (band >= 2) {
775 			status = RTW_HAL_STATUS_FAILURE;
776 			break;
777 		}
778 		if ((0 == (bf_obj->self_bf_cap[band]&BF_CAP_HE_BFEE)) &&
779 		    (0 == (bf_obj->self_bf_cap[band]&BF_CAP_VHT_BFEE))) {
780 			/* already disable */
781 			break;
782 		}
783 		status = rtw_hal_mac_ax_deinit_bfee(hal_info->hal_com, band);
784 
785 		if (status != RTW_HAL_STATUS_SUCCESS)
786 			break;
787 
788 		bf_obj->self_bf_cap[band] &= ~(BF_CAP_HE_BFEE|BF_CAP_VHT_BFEE);
789 	} while (0);
790 
791 	return status;
792 }
793 
794 /**
795  * rtw_hal_bf_get_entry_snd_sts
796  * 	Get BF Entry Sounding Status
797  * input
798  * @hal_info: (struct hal_info_t *)
799  * @entry: struct hal_bf_entry
800  * return
801  * 	rtw_hal_status : RTW_HAL_STATUS_FAILURE or RTW_HAL_STATUS_SUCCESS
802  **/
803 enum rtw_hal_status
rtw_hal_bf_get_entry_snd_sts(void * entry)804 rtw_hal_bf_get_entry_snd_sts(void *entry)
805 {
806 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
807 	struct hal_bf_entry *bf_entry = (struct hal_bf_entry *)entry;
808 	if (NULL == bf_entry) {
809 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "[ERROR] rtw_hal_bf_get_entry_snd_sts BF_Entry = NULL\n");
810 		return hstatus;
811 	}
812 	if (NULL == bf_entry->bfee) {
813 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
814 			  "[ERROR] rtw_hal_bf_get_entry_snd_sts bf_entry->macid = 0x%x\n", bf_entry->macid);
815 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
816 			  "[ERROR] rtw_hal_bf_get_entry_snd_sts bf_entry->bfee = NULL\n");
817 		return hstatus;
818 	}
819 
820 	if (1 == bf_entry->bfee->snd_sts)
821 		hstatus = RTW_HAL_STATUS_SUCCESS;
822 
823 	return hstatus;
824 }
825 
826 /**
827  * hal_bf_hw_mac_init_bfee
828  * 	Initialize BFee HW Settings
829  * input
830  * @hal_info: struct hal_info_t
831  * @band: Band 0 / Band 1
832  **/
hal_bf_hw_mac_init_bfee(struct hal_info_t * hal_info,u8 band)833 enum rtw_hal_status hal_bf_hw_mac_init_bfee(
834 	struct hal_info_t *hal_info,
835 	u8 band)
836 {
837 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
838 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
839 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
840 
841 	do {
842 		if (band >= 2) {
843 			status = RTW_HAL_STATUS_FAILURE;
844 			break;
845 		}
846 		status = rtw_hal_mac_ax_init_bf_role(
847 				hal_info->hal_com, HAL_BF_ROLE_BFEE, band);
848 
849 		if(status != RTW_HAL_STATUS_SUCCESS)
850 			break;
851 
852 		/*TODO: Check Wireless Mode*/
853 		bf_obj->self_bf_cap[band] |= BF_CAP_HE_BFEE|BF_CAP_VHT_BFEE;
854 
855 	} while (0);
856 
857 	return status;
858 }
859 #ifdef RTW_WKARD_DYNAMIC_BFEE_CAP
860 enum rtw_hal_status
rtw_hal_bf_bfee_ctrl(void * hal,u8 band,bool ctrl)861 rtw_hal_bf_bfee_ctrl(void *hal, u8 band, bool ctrl)
862 {
863 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
864 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
865 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
866 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
867 	bool cur_bfee_cap = false;
868 
869 	if ((bf_obj->self_bf_cap[band] & BF_CAP_HE_BFEE) ||
870 	    (bf_obj->self_bf_cap[band] & BF_CAP_VHT_BFEE)) {
871 		    cur_bfee_cap = true;
872 	}
873 
874 	/* BB Workaround */
875 	if ((ctrl != cur_bfee_cap) && (true == ctrl)) {
876 		/* From Tx to Rx (need Enable BFee) */
877 		rtw_hal_bb_dcr_en(hal_info, true);
878 	} else if ((ctrl != cur_bfee_cap) && (false == ctrl)) {
879 		rtw_hal_bb_dcr_en(hal_info, false);
880 	}
881 
882 	if ((ctrl == true) &&
883 	    (false == rtw_hal_bb_csi_rsp(hal_info))) {
884 		ctrl = false;
885 	}
886 
887 	if (ctrl != cur_bfee_cap) {
888 		status = ((true == ctrl) ?
889 			   hal_bf_hw_mac_init_bfee(hal_info, band) :
890 			   hal_bf_hw_mac_deinit_bfee(hal_info, band));
891 	}
892 
893 	return status;
894 }
895 #endif
896 
897 /**
898  * hal_bf_set_bfee_csi_para
899  * 	Set self bfee hw capability.
900  * input:
901  * @hal_info: struct hal_info_t *
902  * @cr_cctl: set bfee capabiliy method
903  * 		true = by register  (only support 2 sets, Port 0 / Port 1-4 )
904  * 		false = by cmac control table
905  * @sta: struct rtw_phl_stainfo_t * (self)
906  */
hal_bf_set_bfee_csi_para(struct hal_info_t * hal_info,bool cr_cctl,struct rtw_phl_stainfo_t * sta)907 enum rtw_hal_status hal_bf_set_bfee_csi_para(struct hal_info_t *hal_info,
908 	bool cr_cctl, struct rtw_phl_stainfo_t *sta)
909 {
910 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
911 	u32 rrsc = BIT(HAL_BF_RRSC_6M) | BIT(HAL_BF_RRSC_24M);
912 
913 	if (false == cr_cctl) {
914 		status = rtw_hal_mac_ax_bfee_para_reg(hal_info->mac, sta);
915 	} else {
916 		status = rtw_hal_mac_ax_bfee_para_cctl(hal_info->mac, sta);
917 	}
918 	/* mac/bb csi rate settings initialize */
919 	if (RTW_HAL_STATUS_SUCCESS == status) {
920 		/* Initialize CSI rate RA parameters */
921 		sta->hal_sta->ra_info.fixed_csi_rate_en = false;
922 		sta->hal_sta->ra_info.ra_csi_rate_en = true;
923 		sta->hal_sta->ra_info.band_num = sta->wrole->hw_band;
924 		if (sta->chandef.bw >= CHANNEL_WIDTH_80)
925 			sta->hal_sta->ra_info.csi_rate.bw = HAL_RATE_BW_80;
926 		else if (sta->chandef.bw == CHANNEL_WIDTH_40)
927 			sta->hal_sta->ra_info.csi_rate.bw = HAL_RATE_BW_40;
928 		else
929 			sta->hal_sta->ra_info.csi_rate.bw = HAL_RATE_BW_20;
930 		sta->hal_sta->ra_info.csi_rate.gi_ltf = RTW_GILTF_LGI_4XHE32;
931 		sta->hal_sta->ra_info.csi_rate.mcs_ss_idx = 5;
932 		if (sta->wmode & WLAN_MD_11N) {
933 			rrsc |= (BIT(HAL_BF_RRSC_HT_MSC0) |
934 				 BIT(HAL_BF_RRSC_HT_MSC3) |
935 				 BIT(HAL_BF_RRSC_HT_MSC5));
936 			sta->hal_sta->ra_info.csi_rate.mode = HAL_HT_MODE;
937 		}
938 		if (sta->wmode & WLAN_MD_11AC) {
939 			rrsc |= (BIT(HAL_BF_RRSC_VHT_MSC0) |
940 				 BIT(HAL_BF_RRSC_VHT_MSC3) |
941 				 BIT(HAL_BF_RRSC_VHT_MSC5));
942 			sta->hal_sta->ra_info.csi_rate.mode = HAL_VHT_MODE;
943 		}
944 		if (sta->wmode & WLAN_MD_11AX) {
945 			rrsc |= (BIT(HAL_BF_RRSC_HE_MSC0) |
946 				 BIT(HAL_BF_RRSC_HE_MSC3) |
947 				 BIT(HAL_BF_RRSC_HE_MSC5));
948 			sta->hal_sta->ra_info.csi_rate.mode = HAL_HE_MODE;
949 		}
950 		/* Initialize mac rrsc function */
951 		rtw_hal_mac_ax_bfee_set_csi_rrsc(hal_info->mac,
952 			sta->wrole->hw_band, rrsc);
953 		PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, " set bfee csi rrsc =  0x%x\n", rrsc);
954 	}
955 
956 	return status;
957 }
958 
959 
960 
961 /**
962  * hal_bf_hw_mac_init_bfer
963  * 	Initialize BFer HW Settings
964  * @hal_info: struct hal_info_t
965  * @band: Band 0 / Band 1
966  **/
hal_bf_hw_mac_init_bfer(struct hal_info_t * hal_info,u8 band)967 enum rtw_hal_status hal_bf_hw_mac_init_bfer(
968 	struct hal_info_t *hal_info,
969 	u8 band)
970 {
971 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
972 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
973 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
974 
975 	do {
976 		if (band >= 2) {
977 			status = RTW_HAL_STATUS_FAILURE;
978 			break;
979 		}
980 		status = rtw_hal_mac_ax_init_bf_role(hal_info->hal_com,
981 						     HAL_BF_ROLE_BFER, band);
982 		if(status != RTW_HAL_STATUS_SUCCESS)
983 			break;
984 		/*TODO: Check Wireless Mode*/
985 		bf_obj->self_bf_cap[band] |= BF_CAP_HE_BFER|BF_CAP_VHT_BFER;
986 
987 	} while (0);
988 
989 	return status;
990 }
991 
992 /**
993  * rtw_hal_bf_chk_bf_type
994  * 	Check the STA's BF Entry Type
995  * @hal_info: struct hal_info_t
996  * @sta: rtw_phl_stainfo_t *
997  * @mu: check condition MU or SU?
998  * return :
999  * @ret: true : bf entry type is same to flag(mu)
1000  *		false : bf entry is not same to flag(mu) or bf entry is NULL
1001  **/
rtw_hal_bf_chk_bf_type(void * hal_info,struct rtw_phl_stainfo_t * sta,bool mu)1002 bool rtw_hal_bf_chk_bf_type(
1003 	void *hal_info,
1004 	struct rtw_phl_stainfo_t *sta,
1005 	bool mu)
1006 {
1007 	struct hal_bf_entry *bf_entry =
1008 		(struct hal_bf_entry *)sta->hal_sta->bf_entry;
1009 	bool ret = false;
1010 	do {
1011 		if (NULL == bf_entry)
1012 			break;
1013 
1014 		if (bf_entry->bfee == NULL)
1015 			break;
1016 
1017 		if (true == mu) {
1018 			if (HAL_BFEE_MU != bf_entry->bfee->type)
1019 				break;
1020 		} else {
1021 			if (HAL_BFEE_SU != bf_entry->bfee->type)
1022 				break;
1023 		}
1024 
1025 		ret = true;
1026 	} while(0);
1027 
1028 	return ret;
1029 }
1030 
rtw_hal_bf_get_sumu_idx(void * hal,void * entry)1031 u8 rtw_hal_bf_get_sumu_idx(void *hal, void *entry)
1032 {
1033 	struct hal_bf_entry *bf_entry = (struct hal_bf_entry *)entry;
1034 	u8 ret = 0xFF;
1035 	if (bf_entry->bfee != NULL)
1036 		ret = bf_entry->bfee->idx;
1037 
1038 	return ret;
1039 }
1040 
1041 
1042 void
rtw_hal_bf_preset_mu_ba_info(void * hal,struct rtw_phl_stainfo_t * psta,void * hal_ba_info)1043 rtw_hal_bf_preset_mu_ba_info(
1044 	void *hal,
1045 	struct rtw_phl_stainfo_t *psta,
1046 	void *hal_ba_info)
1047 {
1048 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
1049 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
1050 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
1051 	void *drv_priv = hal_to_drvpriv(hal_info);
1052 	struct rtw_hal_muba_info *ba_info =
1053 		(struct rtw_hal_muba_info *)hal_ba_info;
1054 
1055 	if (1 == bf_obj->fixed_para.fix_ba_info.fix_ba) {
1056 		/*Fixed BA info*/
1057 		_os_mem_cpy(drv_priv, ba_info, &bf_obj->fixed_para.fix_ba_info, sizeof(*ba_info));
1058 	} else {
1059 		/* TODO:  Config BA by STA Capabiliy or default value*/
1060 		ba_info->fix_ba = 0;
1061 		ba_info->ru_psd = 0;
1062 		ba_info->tf_rate = RTW_DATA_RATE_OFDM24;
1063 		ba_info->rf_gain_fix = 0;
1064 		ba_info->rf_gain_idx = 0;
1065 		ba_info->tb_ppdu_bw = (psta->chandef.bw == CHANNEL_WIDTH_80) ? 2 : 0;
1066 		ba_info->dcm = 0;
1067 		ba_info->ss = 0;
1068 		ba_info->mcs = 3;
1069 		ba_info->gi_ltf = 2;
1070 		ba_info->doppler = 0;
1071 		ba_info->stbc = 0;
1072 		ba_info->sta_coding = 0;
1073 		ba_info->tb_t_pe_nom = 0;
1074 		ba_info->pr20_bw_en = 0;
1075 		ba_info->ma_type = 0;
1076 	}
1077 }
1078 
1079 void
rtw_hal_bf_set_txmu_para(void * hal,u8 gid,u8 en,enum rtw_hal_protection_type rts_type,enum rtw_hal_ack_resp_type ack_type)1080 rtw_hal_bf_set_txmu_para(void *hal, u8 gid , u8 en,
1081 	enum rtw_hal_protection_type rts_type,
1082 	enum rtw_hal_ack_resp_type ack_type)
1083 {
1084 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
1085 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
1086 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
1087 	struct hal_bf_fixed_m_para *para = &bf_obj->fixed_para;
1088 
1089 	para->fix_m = (1 == en) ? HAL_BF_FIX_M_MU : HAL_BF_FIX_M_DISABLE;
1090 	para->gid = gid;
1091 	para->fix_resp = en;
1092 	para->fix_prot = en;
1093 	if (en) {
1094 		para->prot_type = rts_type;
1095 		para->resp_type = ack_type;
1096 	}
1097 }
1098 
1099 enum rtw_hal_status
rtw_hal_bf_set_fix_mode(void * hal,bool mu,bool he)1100 rtw_hal_bf_set_fix_mode(void *hal, bool mu, bool he)
1101 {
1102 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
1103 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
1104 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
1105 	struct hal_bf_obj *bf_obj = (struct hal_bf_obj *)hal_com->bf_obj;
1106 	struct hal_bf_fixed_m_para *para = &bf_obj->fixed_para;
1107 
1108 
1109 	if (mu) {
1110 		status = rtw_hal_mac_ax_set_mu_fix_mode(
1111 			hal_info->mac,
1112 			para->gid,
1113 			para->prot_type,
1114 			para->resp_type,
1115 			(para->fix_m == HAL_BF_FIX_M_MU) ? true : false,
1116 			he,
1117 			para->fix_resp,
1118 			para->fix_prot);
1119 	} else {
1120 		/*TODO: Force SU*/
1121 	}
1122 	return status;
1123 }
1124 
1125 enum rtw_hal_status
hal_bf_set_mu_sta_fw(void * hal,struct rtw_phl_stainfo_t * sta)1126 hal_bf_set_mu_sta_fw(void *hal, struct rtw_phl_stainfo_t *sta)
1127 {
1128 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
1129 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
1130 	struct hal_bf_entry *bf_entry =
1131 			(struct hal_bf_entry *)sta->hal_sta->bf_entry;
1132 	struct hal_sumu_entry *mu_entry = NULL;
1133 
1134 	do {
1135 		if (NULL == bf_entry)
1136 			break;
1137 
1138 		if (NULL == bf_entry->bfee)
1139 			break;
1140 
1141 		mu_entry = bf_entry->bfee;
1142 
1143 		if (HAL_BFEE_MU != mu_entry->type)
1144 			break;
1145 
1146 		status = rtw_hal_mac_ax_mu_sta_upd(
1147 				hal_info->mac,
1148 				(u8)(sta->macid&0xFF),
1149 				mu_entry->idx,
1150 				sta->hal_sta->prot_type,
1151 				sta->hal_sta->resp_type,
1152 				sta->hal_sta->mugrp_bmp);
1153 
1154 	} while (0);
1155 
1156 	return status;
1157 }
1158 
rtw_hal_beamform_set_vht_gid(void * hal,u8 band,struct rtw_phl_gid_pos_tbl * tbl)1159 void rtw_hal_beamform_set_vht_gid(void *hal, u8 band,
1160 				  struct rtw_phl_gid_pos_tbl *tbl)
1161 {
1162 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "--> %s()\n", __func__);
1163 	if (RTW_HAL_STATUS_SUCCESS !=
1164 		rtw_hal_mac_bfee_set_vht_gid(hal, band, tbl)) {
1165 		PHL_INFO("%s : Error to set VHT GID Position to MAC !!! \n",
1166 			 __func__);
1167 	}
1168 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "<-- %s()\n", __func__);
1169 }
1170 
rtw_hal_beamform_set_aid(void * hal,struct rtw_phl_stainfo_t * sta,u16 aid)1171 enum rtw_hal_status rtw_hal_beamform_set_aid(void *hal, struct rtw_phl_stainfo_t *sta, u16 aid)
1172 {
1173 	enum rtw_hal_status status = RTW_HAL_STATUS_SUCCESS;
1174 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
1175 
1176 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "--> %s() : set aid = %d\n", __func__, aid);
1177 
1178 	/*TODO: halmac need provide api that only change AID */
1179 	status = rtw_hal_mac_addr_cam_set_aid(hal_info, sta, aid);
1180 
1181 	if (status != RTW_HAL_STATUS_SUCCESS) {
1182 		PHL_ERR("rtw_hal_mac_addr_cam_change_entry failed\n");
1183 	}
1184 
1185 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "<-- %s()\n", __func__);
1186 
1187 	return status;
1188 }