xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/phl/hal_g6/hal_sound.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 #define _HAL_SOUND_C_
16 
17 #include "hal_headers.h"
18 
19 struct csi_rpt_na {
20 	u8 nr;
21 	u8 nc;
22 	u8 na;
23 };
24 
25 #define CSI_NA_MATRIX_SIZE 35
26 static const struct csi_rpt_na csi_na[CSI_NA_MATRIX_SIZE] =
27 {
28 	{2, 1, 2}, {2, 2, 2},
29 	{3, 1, 4}, {3, 2, 6}, {3, 3, 6},
30 	{4, 1, 6}, {4, 2, 10}, {4, 3, 12}, {4, 4, 12},
31 	{5, 1, 8}, {5, 2, 14}, {5, 3, 18}, {5, 4, 20}, {5, 5, 20},
32 	{6, 1, 10}, {6, 2, 18}, {6, 3, 24}, {6, 4, 28}, {6, 5, 30},
33 	{6, 6, 30},
34 	{7, 1, 12}, {7, 2, 22}, {7, 3, 30}, {7, 4, 36},
35 	{7, 5, 40}, {7, 6, 42}, {7, 7, 42},
36 	{8, 1, 14}, {8, 2, 26}, {8, 3, 36}, {8, 4, 55},
37 	{8, 5, 50}, {8, 6, 54}, {8, 7, 56}, {8, 8, 56}
38 };
39 
40 
_cal_he_csi_size(u8 mu,enum channel_width bw,u8 nr,u8 nc,u8 ng,u8 cb)41 u32 _cal_he_csi_size(u8 mu, enum channel_width bw, u8 nr, u8 nc, u8 ng, u8 cb)
42 {
43 	u8 na = 0;
44 	u8 ns = 0;
45 	u8 i = 0;
46 	u32 csi_size = 0;
47 	u8 cb_s = 0;
48 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
49 		  "%s : mu(%d) ; bw(%d) ; nr(%d) ; nc(%d), ng(%d), cb(%d)\n",
50 		  __func__, mu, bw, nr, nc, ng ,cb);
51 	do {
52 		if (CHANNEL_WIDTH_80 == bw)
53 			ns = (ng == 4) ? 250 : 64;
54 		else if(CHANNEL_WIDTH_40 == bw)
55 			ns = (ng == 4) ? 122 : 32;
56 		else if(CHANNEL_WIDTH_20 == bw)
57 			ns = (ng == 4) ? 64 : 20;
58 		else
59 			break;
60 
61 		for (i = 0; i < CSI_NA_MATRIX_SIZE; i++) {
62 			if ((nr == csi_na[i].nr) && (nc ==csi_na[i].nc)) {
63 				na = csi_na[i].na;
64 				break;
65 			}
66 		}
67 		if (na == 0)
68 			break;
69 
70 		if (cb) {
71 			if(mu)
72 				cb_s = 8;
73 			else
74 				cb_s = 5;
75 		} else {
76 			if(mu)
77 				cb_s = 6;
78 			else
79 				cb_s = 3;
80 		}
81 	} while(0);
82 
83 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
84 		  "%s : na %d ; ns %d ; cb_s %d",__func__, na, ns, cb_s);
85 
86 	if ((0 != na) && (0 != ns) && (0 != cb_s)) {
87 		csi_size = ((8 * (u32)nc) +
88 			    ((u32)na * (u32)cb_s * (u32)ns)) / 8;
89 		if(mu)
90 			csi_size += (4 * (u32)nc * (u32)ns) / 8;
91 	}
92 
93 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
94 		  "%s : expected he csi report size = %d byte",
95 		  __func__, csi_size);
96 	return csi_size;
97 }
98 
_cal_he_cqi_only_rpt_size(enum channel_width bw,u8 nc)99 u32 _cal_he_cqi_only_rpt_size(enum channel_width bw, u8 nc)
100 {
101 	u32 ret = 0;
102 	if (CHANNEL_WIDTH_80 == bw)
103 		ret = (u32)nc * 37;
104 	else if(CHANNEL_WIDTH_40 == bw)
105 		ret = (u32)nc * 18;
106 	else if(CHANNEL_WIDTH_20 == bw)
107 		ret = (u32)nc * 9;
108 
109 	return ret;
110 }
111 
112 /*1. BF Resource Related*/
_get_bw_ru_end_idx(enum channel_width bw)113 u8 _get_bw_ru_end_idx(enum channel_width bw) {
114 	u8 ru_end_idx = 0;
115 
116 	switch (bw) {
117 	case CHANNEL_WIDTH_20:
118 		ru_end_idx = HAL_NPDA_RU_IDX_END_20MHZ;
119 	break;
120 	case CHANNEL_WIDTH_40:
121 		ru_end_idx = HAL_NPDA_RU_IDX_END_40MHZ;
122 	break;
123 	case CHANNEL_WIDTH_80:
124 		ru_end_idx = HAL_NPDA_RU_IDX_END_80MHZ;
125 	break;
126 	case CHANNEL_WIDTH_160:
127 	case CHANNEL_WIDTH_80_80:
128 		ru_end_idx = HAL_NPDA_RU_IDX_END_160MHZ;
129 	default:
130 	break;
131 	}
132 	return ru_end_idx;
133 }
134 
_hal_snd_set_default_var(struct hal_snd_obj * snd_obj)135 void _hal_snd_set_default_var(struct hal_snd_obj *snd_obj)
136 {
137 	snd_obj->ndpa_xpara.bw = CHANNEL_WIDTH_20;
138 	snd_obj->ndpa_xpara.rate = RTW_DATA_RATE_OFDM6;
139 	snd_obj->ndpa_xpara.gi_ltf = RTW_GILTF_LGI_4XHE32;
140 	snd_obj->ndpa_xpara.stbc = 0;
141 	snd_obj->ndpa_xpara.ldpc = 0;
142 
143 	snd_obj->bfrp_xpara.bw = CHANNEL_WIDTH_20;
144 	snd_obj->bfrp_xpara.rate = RTW_DATA_RATE_OFDM6;
145 	snd_obj->bfrp_xpara.gi_ltf = RTW_GILTF_LGI_4XHE32;
146 	snd_obj->bfrp_xpara.stbc = 0;
147 	snd_obj->bfrp_xpara.ldpc = 0;
148 }
149 
150 enum rtw_hal_status
hal_snd_obj_init(void * hal)151 hal_snd_obj_init(void *hal)
152 {
153 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
154 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
155 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
156 	struct hal_snd_obj *snd_obj = NULL;
157 
158 	do {
159 		hal_com->snd_obj = _os_mem_alloc(hal_to_drvpriv(hal_info),
160 				    sizeof(struct hal_snd_obj));
161 		if (NULL == hal_com->snd_obj) {
162 			break;
163 		}
164 		snd_obj = hal_com->snd_obj;
165 		/* preset hal sounding default values */
166  		_hal_snd_set_default_var(snd_obj);
167 
168 		hstatus = RTW_HAL_STATUS_SUCCESS;
169 	} while (0);
170 	return hstatus;
171 }
172 
173 
174 enum rtw_hal_status
hal_snd_obj_deinit(void * hal)175 hal_snd_obj_deinit(void *hal)
176 {
177 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
178 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
179 	struct rtw_hal_com_t *hal_com = hal_info->hal_com;
180 
181 	do {
182 		if (hal_com->snd_obj == NULL)
183 			break;
184 		_os_mem_free(hal_to_drvpriv(hal_info), hal_com->snd_obj,
185 			     sizeof(struct hal_snd_obj));
186 		hal_com->snd_obj = NULL;
187 	} while (0);
188 
189 	return hstatus;
190 }
191 
192 /**
193  * rtw_hal_snd_release_proc_sta_res
194  * 	free the resource for a STA used in sounding process
195  * input:
196  * @hal: (struct hal_info_t *)
197  * @sta: (struct rtw_phl_stainfo_t *)
198  **/
199 enum rtw_hal_status
rtw_hal_snd_release_proc_sta_res(void * hal,struct rtw_phl_stainfo_t * sta)200 rtw_hal_snd_release_proc_sta_res(void *hal, struct rtw_phl_stainfo_t *sta)
201 {
202 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
203 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
204 	struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
205 	do {
206 		if (hal_sta->bf_entry != NULL) {
207 			hal_status = hal_bf_release_target_bf_entry(
208 					hal_info, hal_sta->bf_entry);
209 		}
210 
211 		if (hal_is_csi_buf_valid(hal_info, &hal_sta->bf_csi_buf)) {
212 			hal_status = hal_csi_release_csi_buf(
213 					hal_info, &hal_sta->bf_csi_buf);
214 		}
215 		if (hal_is_csi_buf_valid(hal_info, &hal_sta->bf_csi_buf_swap)) {
216 			hal_status = hal_csi_release_csi_buf(
217 					hal_info, &hal_sta->bf_csi_buf_swap);
218 		}
219 	} while(0);
220 
221 	return hal_status;
222 }
223 
224 
225 /**
226  * rtw_hal_snd_query_proc_sta_res
227  * input:
228  * @hal: hal_info
229  * @sta: rtw_phl_stainfo_t
230  * @mu: is this MU-MIMO STA resource request
231  * @bw: enum channel_width sounding bandwidth
232  **/
233 enum rtw_hal_status
rtw_hal_snd_query_proc_sta_res(void * hal,struct rtw_phl_stainfo_t * sta,bool mu,enum channel_width bw,bool en_swap)234 rtw_hal_snd_query_proc_sta_res(
235 	void *hal,
236 	struct rtw_phl_stainfo_t *sta,
237 	bool mu,
238 	enum channel_width bw,
239 	bool en_swap)
240 {
241 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
242 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
243 	struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
244 
245 	do {
246 		if (hal_sta->bf_entry != NULL) {
247 			PHL_TRACE(COMP_PHL_SOUND,  _PHL_INFO_, "[WARNING] sta->bf_entry != NULL\n");
248 			/* TODO:Shall Release First ?*/
249 			/* rtw_hal_snd_release_proc_sta_res(hal, sta); */
250 		}
251 
252 		hal_sta->bf_entry =
253 			(void *)hal_bf_query_idle_bf_entry(hal_info, mu);
254 
255 		if (hal_sta->bf_entry == NULL)
256 			break;
257 
258 		hal_status = hal_csi_query_idle_csi_buf(
259 				hal_info, mu, bw, &hal_sta->bf_csi_buf);
260 
261 		if (hal_status != RTW_HAL_STATUS_SUCCESS)
262 			break;
263 
264 		if (mu && en_swap) {
265 			hal_status = hal_csi_query_idle_csi_buf(
266 				hal_info, mu, bw, &hal_sta->bf_csi_buf_swap);
267 		}
268 		if (hal_status == RTW_HAL_STATUS_FAILURE) {
269 			PHL_INFO("Cannot Enable Swap Mode! Because of the CSI resource is not enougth.\n");
270 			break;
271 		}
272 
273 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "sta->bf_csi_buf 0x%x \n",
274 				hal_sta->bf_csi_buf);
275 		PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "sta->bf_csi_buf_swap 0x%x \n",
276 				hal_sta->bf_csi_buf_swap);
277 
278 		/* Set STA-INFO info to BF Entry */
279 		hal_status = hal_bf_cfg_swbf_entry(sta, en_swap);
280 	} while (0);
281 
282 	if (hal_status != RTW_HAL_STATUS_SUCCESS) {
283 		PHL_INFO("rtw_hal_snd_query_proc_sta_res FAIL \n");
284 		rtw_hal_snd_release_proc_sta_res(hal, sta);
285 	}
286 
287 	return hal_status;
288 }
289 
290 /**
291  * rtw_hal_snd_proc_pre_cfg_sta
292  * 	hw preconfiguration for a sounding sta
293  * input:
294  * @hal: hal_info
295  * @sta: (struct rtw_phl_stainfo_t *)
296  **/
297 enum rtw_hal_status
rtw_hal_snd_proc_pre_cfg_sta(void * hal,struct rtw_phl_stainfo_t * sta)298 rtw_hal_snd_proc_pre_cfg_sta(
299 	void *hal,
300 	struct rtw_phl_stainfo_t *sta)
301 {
302 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_FAILURE;
303 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
304 	struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
305 
306 	/* 1. MAC HW BF Entry Settings */
307 	hal_status = hal_bf_set_entry_hwcfg(
308 				hal_info, hal_sta->bf_entry);
309 
310 	/* 2. Add other HAL setting here */
311 	/*TODO:*/
312 
313 	return hal_status;
314 }
315 
316 
317 /**
318  * rtw_hal_snd_proc_post_cfg
319  * 	hw/fw post configuration for a sounding event
320  * input:
321  * @hal: hal_info
322  **/
323 enum rtw_hal_status
rtw_hal_snd_proc_post_cfg(void * hal,bool he,bool mu,bool en_fixed_mode)324 rtw_hal_snd_proc_post_cfg(void *hal, bool he, bool mu, bool en_fixed_mode)
325 {
326 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
327 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
328 	struct hal_mu_score_tbl *hal_score_table = &hal_info->hal_com->bb_mu_score_tbl;
329 	if (mu) {
330 		/*1. MU Score Board */
331 		hal_status = rtw_hal_mac_ax_set_mu_table_whole(
332 				hal_info->mac, hal_score_table);
333 
334 		/*2. (optional) MU Fixed Mode */
335 		if (en_fixed_mode)
336 			hal_status = rtw_hal_bf_set_fix_mode(hal, mu, he);
337 	}
338 
339 	return hal_status;
340 }
341 
342 
343 /**
344  * rtw_hal_snd_proc_post_cfg_gid
345  * 	hw/fw post configuration for a vht/he gid
346  * input:
347  * @hal: hal_info
348  * @gid: wifi protolcol gid (PLCP) for configuration
349  * @ba_info: pointer of struct rtw_hal_muba_info
350  **/
351 enum rtw_hal_status
rtw_hal_snd_proc_post_cfg_gid(void * hal,u8 gid,void * ba_info)352 rtw_hal_snd_proc_post_cfg_gid(void *hal, u8 gid, void *ba_info)
353 {
354 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
355 	/*
356 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
357 	struct rtw_hal_muba_info *hal_ba_info = (struct rtw_hal_muba_info *)ba_info;
358 	*/
359 
360 	/*TODO:*/
361 	/*1. MU BAR Table : Table ID = GID, GID = STA-x + sSTA-y*/
362 	return hal_status;
363 }
364 
365 /**
366  * rtw_hal_snd_proc_post_cfg_sta
367  * 	hw/fw post configuration for a single sounding sta
368  * input:
369  * @hal: hal_info
370  * @sta: (struct rtw_phl_stainfo_t *)
371  **/
372 enum rtw_hal_status
rtw_hal_snd_proc_post_cfg_sta(void * hal,struct rtw_phl_stainfo_t * sta,bool mu)373 rtw_hal_snd_proc_post_cfg_sta(
374 	void *hal,
375 	struct rtw_phl_stainfo_t *sta,
376 	bool mu)
377 {
378 	enum rtw_hal_status hal_status = RTW_HAL_STATUS_SUCCESS;
379 	/* MAC/FW Settings */
380 	if (mu) {
381 		/*1. FW MU STA Update */
382 		hal_status = hal_bf_set_mu_sta_fw(hal, sta);
383 		/*2. MU Score Board */
384 		/* mac->mac_set_mu_table_single_sta */
385 	}
386 
387 	/* BB/FW Settings */
388 	/*TODO:*/
389 
390 	/* 2. Add other setting here */
391 	/*TODO:*/
392 
393 	return hal_status;
394 }
395 
396 /**
397  * rtw_hal_snd_mac_ctrl
398  * 	control sounding process : pause or start.
399  * @hal: hal_info
400  * @band: band0 / band1
401  * @ctrl: 0 = pause souning / 1 = start sounding
402  **/
403 enum rtw_hal_status
rtw_hal_snd_mac_ctrl(void * hal,u8 band,u8 ctrl)404 rtw_hal_snd_mac_ctrl(void *hal, u8 band, u8 ctrl)
405 {
406 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
407 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
408 
409 	hstatus = rtw_hal_mac_ax_hw_snd_control(hal_info->mac, band, ctrl);
410 
411 	return hstatus;
412 }
413 
414 /**
415  * rtw_hal_snd_chk_bf_res
416  * 	check the sta's sounding resource is enough for sounding
417  * input :
418  * @hal: hal_info
419  * @sta: (struct rtw_hal_stainfo_t *)
420  * @mu: true = mu / false = su
421  * @bw: enum channel_width
422  * return :
423  * @hstatus: RTW_HAL_STATUS_FAILURE = need release and query bf entry and CSI buffer
424  *  	     RTW_HAL_STATUS_SUCCESS = STA's BF Entry and CSI Buffer is same to condition.
425  **/
426 enum rtw_hal_status
rtw_hal_snd_chk_bf_res(void * hal,struct rtw_phl_stainfo_t * sta,bool mu,enum channel_width bw)427 rtw_hal_snd_chk_bf_res(void *hal, struct rtw_phl_stainfo_t *sta,
428 	bool mu, enum channel_width bw)
429 {
430 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
431 	struct rtw_hal_stainfo_t *hal_sta = sta->hal_sta;
432 	do {
433 		if (sta == NULL)
434 			break;
435 
436 		if (false == rtw_hal_bf_chk_bf_type(hal, sta, mu))
437 			break;
438 		if (mu != rtw_hal_get_csi_buf_type(&hal_sta->bf_csi_buf))
439 			break;
440 		if (bw != rtw_hal_get_csi_buf_bw(&hal_sta->bf_csi_buf))
441 			break;
442 
443 		hstatus = RTW_HAL_STATUS_SUCCESS;
444 	} while (0);
445 
446 	return hstatus;
447 }
448 
449 /**
450  * rtw_hal_snd_polling_snd_sts
451  * 	update the sta's sounding status into sta->hal_sta->bf_entry->bfee
452  * input :
453  * @hal: hal_info
454  * @sta: (struct rtw_hal_stainfo_t *)
455  **/
456 void
rtw_hal_snd_polling_snd_sts(void * hal,struct rtw_phl_stainfo_t * sta)457 rtw_hal_snd_polling_snd_sts(void *hal, struct rtw_phl_stainfo_t *sta)
458 {
459 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
460 	do {
461 		if (sta == NULL)
462 			break;
463 
464 		hal_bf_update_entry_snd_sts(hal_info, sta->hal_sta->bf_entry);
465 
466 	} while (0);
467 }
468 
469 /* SND H2C CMD related functions */
470 void
rtw_hal_snd_ndpa_sta_info_vht(struct rtw_phl_stainfo_t * psta_info,u32 * ndpa,u8 mu)471 rtw_hal_snd_ndpa_sta_info_vht(struct rtw_phl_stainfo_t *psta_info,
472 			      u32 *ndpa, u8 mu)
473 {
474 	struct hal_vht_ndpa_sta_info *ndpa_sta =
475 		(struct hal_vht_ndpa_sta_info *)ndpa;
476 	if (PHL_RTYPE_STATION == psta_info->wrole->type)
477 		ndpa_sta->aid12 = 0; /* Target is an AP, AID = 0 */
478 	else
479 		ndpa_sta->aid12 = psta_info->aid;
480 	ndpa_sta->feedback_type	= (mu == 0) ? HAL_NPDA_AC_SU : HAL_NPDA_AC_MU;
481 	/* Nc shall alwary <= Nr */
482 	if (psta_info->asoc_cap.max_nc >
483 		psta_info->wrole->proto_role_cap.num_snd_dim) {
484 		ndpa_sta->nc = psta_info->wrole->proto_role_cap.num_snd_dim;
485 	} else {
486 		ndpa_sta->nc = psta_info->asoc_cap.max_nc;
487 	}
488 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "vht ndpa_sta aid12 0x%x ; fb 0x%x ; nc 0x%x\n",
489 		  ndpa_sta->aid12, ndpa_sta->feedback_type, ndpa_sta->nc);
490 }
491 
492 void
rtw_hal_snd_ndpa_sta_info_he(struct rtw_phl_stainfo_t * psta_info,u32 * ndpa,enum channel_width bw,u8 fb_type)493 rtw_hal_snd_ndpa_sta_info_he(struct rtw_phl_stainfo_t *psta_info,
494 			     u32 *ndpa, enum channel_width bw, u8 fb_type)
495 {
496 
497 	struct hal_he_ndpa_sta_info *ndpa_sta =
498 		(struct hal_he_ndpa_sta_info *)ndpa;
499 	u16 ru_start = HAL_NPDA_RU_IDX_START;
500 	u16 ru_end = _get_bw_ru_end_idx(bw);
501 
502 	if (PHL_RTYPE_STATION == psta_info->wrole->type)
503 		ndpa_sta->aid = 0; /* Target is and AP, AID = 0 */
504 	else
505 		ndpa_sta->aid = (psta_info->aid&0x7FF);
506 	ndpa_sta->bw = ((ru_start&0x7F) << 0) | ((ru_end&0x7F) << 7);
507 	if (0 == fb_type) {
508 		ndpa_sta->fb_ng = psta_info->asoc_cap.ng_16_su_fb ?
509 			 HAL_NDPA_AX_FB_SU_NG_16 : HAL_NDPA_AX_FB_SU_NG_4;
510 		ndpa_sta->cb = psta_info->asoc_cap.cb_sz_su_fb ?
511 			HAL_NPDA_AX_CB_SU42_MU75 : HAL_NPDA_AX_CB_SU64_MU97;
512 	} else if (1 == fb_type) {
513 		ndpa_sta->fb_ng = psta_info->asoc_cap.ng_16_mu_fb ?
514 			HAL_NDPA_AX_FB_MU_NG_16 : HAL_NDPA_AX_FB_MU_NG_4;
515 		ndpa_sta->cb = psta_info->asoc_cap.cb_sz_mu_fb ?
516 			HAL_NPDA_AX_CB_SU42_MU75 : HAL_NPDA_AX_CB_SU64_MU97;
517 	} else {
518 		ndpa_sta->fb_ng = HAL_NDPA_AX_FB_CQI;
519 		ndpa_sta->cb = 1;
520 	}
521 	ndpa_sta->disambiguation = 1;
522 	/* Nc shall alwary <= Nr */
523 	if (psta_info->asoc_cap.max_nc >
524 		psta_info->wrole->proto_role_cap.num_snd_dim) {
525 		ndpa_sta->nc = psta_info->wrole->proto_role_cap.num_snd_dim;
526 	} else {
527 		ndpa_sta->nc = psta_info->asoc_cap.max_nc;
528 	}
529 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "HE NDPA : aid 0x%x fb_ng 0x%x cb 0x%x nc 0x%x \n",
530 		  ndpa_sta->aid, ndpa_sta->fb_ng, ndpa_sta->cb, ndpa_sta->nc);
531 }
532 
533 
534 /**
535  * rtw_hal_snd_set_fw_cmd_dialogtkn()
536  * 	Set cmd dialog token value in NDPA
537  * input
538  * @he: is NDPA HE or not(VHT).
539  * @token: dialog token value.
540  **/
rtw_hal_snd_set_fw_cmd_dialogtkn(void * hal,u8 * buf,u8 he,u8 token)541 void rtw_hal_snd_set_fw_cmd_dialogtkn(void *hal, u8 *buf, u8 he, u8 token)
542 {
543 	struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
544 
545 	cmd->ndpa.snd_dialog.he = he;
546 	cmd->ndpa.snd_dialog.token = token;
547 }
548 
549 /**
550  * rtw_hal_snd_vht_fwcmd_su()
551  * 	Prepared VHT SU Sounding Fw Cmd.
552  * @hal:
553  * @buf: (struct hal_ax_fwcmd_snd *) cmd buffer pointer.
554  * @psta:  (struct rtw_phl_stainfo_t *) STA to be sounding.
555  * @npda_sta: NPDA sta_info value
556  **/
rtw_hal_snd_vht_fwcmd_su(void * hal,u8 * buf,enum channel_width bw,struct rtw_phl_stainfo_t * psta,u32 * npda_sta)557 void rtw_hal_snd_vht_fwcmd_su(void *hal, u8 *buf, enum channel_width bw,
558 		    struct rtw_phl_stainfo_t *psta, u32 *npda_sta)
559 {
560 	struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
561 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
562 	struct hal_snd_obj *snd_obj =
563 		(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
564 	u8 i = 0;
565 
566 	cmd->frame_ex_type = HAL_FEXG_TYPE_AC_SU;
567 	cmd->macid[0] = psta->macid;
568 	cmd->ndpa.common.frame_ctl = HAL_SND_VHT_NDPA_FRM_CTRL; /*TODO*/
569 	for (i = 0; i < 6;i++) {
570 		cmd->ndpa.common.addr1[i] = psta->mac_addr[i]; /* NDPA-RA*/
571 		cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
572 	}
573 	cmd->ndpa.common.duration = 100;
574 	cmd->ndpa.ndpa_sta_info[0] = *npda_sta;
575 	/* NDPA WD */
576 	cmd->wd[0].txpktsize = 21;/* 2 + 2 + 6 + 6 + 1 + 4, NO FCS */
577 	cmd->wd[0].ndpa_duration = 100;
578 	cmd->wd[0].disdatafb = 1;
579 	cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
580 	cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
581 	cmd->wd[0].macid = psta->macid;
582 	cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
583 	cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
584 	cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
585 	cmd->wd[0].sifs_tx = 1;
586 	cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_UST_NDPA;/* unicast ndpa */
587 	cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_VHT;
588 	/* NDP WD */
589 	cmd->wd[1].disdatafb = 1;
590 	if (1 == psta->wrole->proto_role_cap.num_snd_dim)
591 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
592 	else if (2 ==psta->wrole->proto_role_cap.num_snd_dim)
593 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS3_MCS0;
594 	else if (3 == psta->wrole->proto_role_cap.num_snd_dim)
595 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS4_MCS0;
596 	else
597 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
598 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "psta->asoc_cap.nss_rx = 0x%x\n", psta->asoc_cap.nss_rx);
599 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "cmd->wd[1].datarate = 0x%x\n", cmd->wd[1].datarate);
600 	cmd->wd[1].data_bw = bw;
601 	cmd->wd[1].macid = psta->macid;
602 	cmd->wd[1].gi_ltf = RTW_GILTF_LGI_4XHE32;
603 	cmd->wd[1].sifs_tx = 0;
604 	cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_NDP;
605 	cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_VHT;
606 }
607 
rtw_hal_snd_vht_fwcmd_mu_add_sta(void * hal,u8 * buf,u32 * ndpa_sta,struct rtw_phl_stainfo_t * sta,u8 ndpa_idx,u8 last)608 void rtw_hal_snd_vht_fwcmd_mu_add_sta(void *hal, u8 *buf, u32 *ndpa_sta,
609 				      struct rtw_phl_stainfo_t *sta,
610 		  		      u8 ndpa_idx, u8 last)
611 {
612 	struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
613 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
614 	struct hal_snd_obj *snd_obj =
615 		(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
616 	u8 i = 0;
617 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "==> rtw_hal_snd_vht_fwcmd_mu_add_sta\n");
618 
619 	if (ndpa_idx >= HAL_MAX_VHT_SND_STA_NUM)
620 		return;
621 
622 	cmd->macid[ndpa_idx] = sta->macid;
623 	/* NDPA sta_info*/
624 	cmd->ndpa.ndpa_sta_info[ndpa_idx] = *ndpa_sta;
625 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "mac id 0x%x ; ndpa sta_info 0x%x\n",
626 		  cmd->macid[ndpa_idx], cmd->ndpa.ndpa_sta_info[ndpa_idx]);
627 
628 	/* VHT BFRP */
629 	cmd->bfrp.hdr[ndpa_idx - 1].frame_ctl = HAL_SND_VHT_BFRP_FRM_CTRL;
630 	cmd->bfrp.hdr[ndpa_idx - 1].duration = 100;
631 	for (i = 0; i < 6; i++) {
632 		cmd->bfrp.hdr[ndpa_idx - 1].addr1[i] = sta->mac_addr[i]; /* NDPA-RA = Broadcast*/
633 		cmd->bfrp.hdr[ndpa_idx - 1].addr2[i] = sta->wrole->mac_addr[i]; /* NDPA-TA*/
634 	}
635 	cmd->bfrp.vht_para[ndpa_idx - 1].rexmit_bmp = 0;
636 	/*BFRP WD*/
637 	cmd->wd[1 + ndpa_idx].txpktsize = 17;  /* 2 + 2 + 6 + 6 + 1 */
638 	cmd->wd[1 + ndpa_idx].ndpa_duration = 100;
639 	cmd->wd[1 + ndpa_idx].datarate = snd_obj->bfrp_xpara.rate;
640 	cmd->wd[1 + ndpa_idx].data_ldpc = snd_obj->bfrp_xpara.ldpc;
641 	cmd->wd[1 + ndpa_idx].data_stbc = snd_obj->bfrp_xpara.stbc;
642 	cmd->wd[1 + ndpa_idx].macid = sta->macid;
643 	cmd->wd[1 + ndpa_idx].data_bw = snd_obj->bfrp_xpara.bw;
644 	cmd->wd[1 + ndpa_idx].gi_ltf = snd_obj->bfrp_xpara.gi_ltf;
645 	cmd->wd[1 + ndpa_idx].disdatafb = 1;
646 	if(last) {
647 		cmd->wd[1 + ndpa_idx].sifs_tx = 0;
648 		cmd->wd[1 + ndpa_idx].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_BFRP;/* Final BFRP */
649 	} else {
650 		cmd->wd[1 + ndpa_idx].sifs_tx = 1;
651 		cmd->wd[1 + ndpa_idx].snd_pkt_sel = HAL_SND_PKT_SEL_MID_BFRP;
652 	}
653 	cmd->wd[1 + ndpa_idx].ndpa = HAL_SND_PKT_NDPA_VHT;
654 
655 }
656 
rtw_hal_snd_vht_fwcmd_mu_pri(void * hal,u8 * buf,enum channel_width bw,struct rtw_phl_stainfo_t * psta,u8 sta_nr,u32 * ndpa_sta)657 void rtw_hal_snd_vht_fwcmd_mu_pri(void *hal, u8 *buf, enum channel_width bw,
658 		    struct rtw_phl_stainfo_t *psta, u8 sta_nr, u32 *ndpa_sta)
659 {
660 	struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
661 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
662 	struct hal_snd_obj *snd_obj =
663 		(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
664 	u8 i = 0;
665 
666 	if (sta_nr == 4)
667 		cmd->frame_ex_type = HAL_FEXG_TYPE_AC_MU_3;
668 	else if(sta_nr == 3)
669 		cmd->frame_ex_type = HAL_FEXG_TYPE_AC_MU_2;
670 	else if(sta_nr == 2)
671 		cmd->frame_ex_type = HAL_FEXG_TYPE_AC_MU_1;
672 	else
673 		PHL_INFO("rtw_hal_snd_vht_fwcmd_mu_pri : ERROR!!!!!!!!!!!!!!!");
674 	cmd->macid[0] = psta->macid;
675 
676 	/* NDPA */
677 	cmd->ndpa.common.frame_ctl = HAL_SND_VHT_NDPA_FRM_CTRL;
678 	for (i = 0; i < 6;i++) {
679 		/**
680 		 * Addr1: In VHT Case, Fill User_0's MAC Address to match BF Entry,
681 		 * HW will auto re-fill to Broadcast Address
682 		 **/
683 		cmd->ndpa.common.addr1[i] = psta->mac_addr[i];
684 		cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
685 	}
686 	cmd->ndpa.common.duration = 150;/*TODO:*/
687 	/* primary sta ndpa sta_info*/
688 	cmd->ndpa.ndpa_sta_info[0] = *ndpa_sta;
689 
690 	/* VHT BFRP ==> by STA */
691 
692 	/* NDPA WD */
693 	cmd->wd[0].txpktsize = 17 + HAL_SND_VHT_NDPA_STA_SZ * sta_nr;/* 2 + 2 + 6 + 6 + 1 + 2, NO FCS */
694 	cmd->wd[0].ndpa_duration = 150;
695 	cmd->wd[0].disdatafb = 1;
696 	cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
697 	cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
698 	cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
699 	cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
700 	cmd->wd[0].macid = psta->macid;
701 	cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
702 	cmd->wd[0].sifs_tx = 1;
703 	cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_BST_NDPA;
704 	cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_VHT;
705 	/* NDP WD */
706 	cmd->wd[1].disdatafb = 1;
707 	if (1 == psta->wrole->proto_role_cap.num_snd_dim)
708 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
709 	else if (2 == psta->wrole->proto_role_cap.num_snd_dim)
710 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS3_MCS0;
711 	else if (3 == psta->wrole->proto_role_cap.num_snd_dim)
712 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS4_MCS0;
713 	else
714 		cmd->wd[1].datarate = RTW_DATA_RATE_VHT_NSS2_MCS0;
715 	cmd->wd[1].data_bw = bw;
716 	cmd->wd[1].macid = psta->macid;
717 	cmd->wd[1].gi_ltf = RTW_GILTF_LGI_4XHE32;
718 	cmd->wd[1].sifs_tx = 1;
719 	cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_MID_NDP;/*Last NDP*/
720 	cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_VHT;
721 }
722 
723 /* HE FW Command */
724 /**
725  * rtw_hal_snd_ax_fwcmd_su()
726  * 	fill the fw cmd for HE sounding type HE Non-TB : NDPA - NDP - CSI Report
727  *
728  **/
rtw_hal_snd_ax_fwcmd_nontb(void * hal,u8 * buf,enum channel_width bw,struct rtw_phl_stainfo_t * psta,u32 * npda_sta)729 void rtw_hal_snd_ax_fwcmd_nontb(void *hal, u8 *buf, enum channel_width bw,
730 		    struct rtw_phl_stainfo_t *psta, u32 *npda_sta)
731 {
732 	struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
733 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
734 	struct hal_snd_obj *snd_obj =
735 		(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
736 	u8 i = 0;
737 
738 	cmd->frame_ex_type = HAL_FEXG_TYPE_AX_SU;
739 	cmd->macid[0] = psta->macid;
740 	cmd->ndpa.common.frame_ctl = HAL_SND_HE_NDPA_FRM_CTRL;
741 	for (i = 0; i < 6;i++) {
742 		cmd->ndpa.common.addr1[i] = psta->mac_addr[i]; /* NDPA-RA*/
743 		cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
744 	}
745 	cmd->ndpa.common.duration = 100;
746 	cmd->ndpa.ndpa_sta_info[0] = *npda_sta;
747 	/* NDPA WD */
748 	cmd->wd[0].txpktsize = 21;/* 2 + 2 + 6 + 6 + 1 + 4, NO FCS */
749 	cmd->wd[0].ndpa_duration = 100;
750 	cmd->wd[0].disdatafb = 1;
751 	cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
752 	cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
753 	cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
754 	cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
755 	cmd->wd[0].macid = psta->macid;
756 	cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
757 	cmd->wd[0].sifs_tx = 1;
758 	cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_UST_NDPA;/*unicast ndpa*/
759 	cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_HE;
760 	/* NDP WD */
761 	cmd->wd[1].disdatafb = 1;
762 	if (1 == psta->wrole->proto_role_cap.num_snd_dim)
763 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
764 	else if (2 == psta->wrole->proto_role_cap.num_snd_dim)
765 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS3_MCS0;
766 	else if (3 == psta->wrole->proto_role_cap.num_snd_dim)
767 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS4_MCS0;
768 	else
769 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
770 	cmd->wd[1].data_bw = bw;
771 	cmd->wd[1].macid = psta->macid;
772 	cmd->wd[1].gi_ltf = RTW_GILTF_2XHE16; /* TODO: if psta->asoc_cap.ltf_gi support NDP 4XHE32;*/
773 	cmd->wd[1].sifs_tx = 0;
774 	cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_NDP;
775 	cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_HE;
776 }
777 
778 /**
779  * rtw_hal_snd_ax_fwcmd_tb_add_sta()
780  * 	fill fw cmd for HE sounding with TB case.
781  * 	shall call rtw_hal_snd_ax_fwcmd_tb_pri() first, and add STA by this api.
782  * 	Note that RU-Allocation shall dicide from phl caller,
783  * 	and shall avoid same with others
784  * function input:
785  * @hal:
786  * @buf: (struct hal_ax_fwcmd_snd *) command buf pointer.
787  * @ndpa_sta:
788  * @sta: (struct rtw_phl_stainfo_t *)
789  * @ru_idx: RU Allocation index;
790  * @ndpa_idx: 0-7 for 8852a
791  * @bfrp_idx: 0-1 for 8852a
792  * @bfrp_u_idx: 0-3 for 8852a
793  **/
rtw_hal_snd_ax_fwcmd_tb_add_sta(void * hal,u8 * buf,u32 * ndpa_sta,struct rtw_phl_stainfo_t * sta,u8 ru_idx,u8 ndpa_idx,u8 bfrp_idx,u8 bfrp_u_idx)794 void rtw_hal_snd_ax_fwcmd_tb_add_sta(void *hal, u8 *buf, u32 *ndpa_sta,
795 				     struct rtw_phl_stainfo_t *sta, u8 ru_idx,
796 		  		     u8 ndpa_idx, u8 bfrp_idx, u8 bfrp_u_idx)
797 {
798 	struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
799 	struct hal_he_ndpa_sta_info *ndpa =
800 		(struct hal_he_ndpa_sta_info *)ndpa_sta;
801 	u8 mu = 0, ng = 4;
802 	u32 rpt_size = 0;
803 
804 	if (ndpa_idx >= HAL_MAX_HE_SND_STA_NUM)
805 		return;
806 	if (bfrp_idx >= HAL_MAX_HE_BFRP_NUM)
807 		return;
808 	cmd->macid[ndpa_idx] = sta->macid;
809 	/* NDPA sta_info*/
810 	cmd->ndpa.ndpa_sta_info[ndpa_idx] = *ndpa_sta;
811 	/* BFRP user_info */
812 	cmd->bfrp.he_para[bfrp_idx].fbseg_rexmit_bmp[bfrp_u_idx] = 0;
813 	cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].aid12 = sta->aid;
814 	if (cmd->bfrp.he_para[bfrp_idx].common.ul_bw > CHANNEL_WIDTH_80) {
815 		ru_idx = (ru_idx << 1) | BIT(0);
816 	} else {
817 		ru_idx = (ru_idx << 1) &(~BIT(0));
818 	}
819 	cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ru_pos = ru_idx;
820 
821 	cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_fec_code = 0;
822 	cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_mcs = 3;/* HE-MCS3, TODO: Default value of golden */
823 	cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_dcm = 0 ;
824 	cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ss_alloc = 0;/* 1SS, TODO: Default value of golden */
825 	cmd->bfrp.he_para[bfrp_idx].user[bfrp_u_idx].ul_tgt_rssi =
826 			(u8)(sta->hal_sta->rssi_stat.rssi >> 1);/*TODO: From Rx ST SU RSSI */
827 	if (ndpa->fb_ng == HAL_NDPA_AX_FB_MU_NG_4) {
828 		mu = 1;
829 		ng = 4;
830 	} else if (ndpa->fb_ng == HAL_NDPA_AX_FB_MU_NG_16) {
831 		mu = 1;
832 		ng = 16;
833 	} else if (ndpa->fb_ng == HAL_NDPA_AX_FB_SU_NG_4) {
834 		mu = 0;
835 		ng = 4;
836 	} else if (ndpa->fb_ng == HAL_NDPA_AX_FB_SU_NG_16) {
837 		mu = 0;
838 		ng = 4;
839 	}
840 	rpt_size = _cal_he_csi_size(mu, sta->chandef.bw,
841 				    (sta->wrole->proto_role_cap.num_snd_dim + 1),
842 				    ((u8)ndpa->nc + 1), ng, (u8)ndpa->cb);
843 	if (cmd->bfrp.he_para[bfrp_idx].f2p_info.csi_len_bfrp < (rpt_size/64))
844 		cmd->bfrp.he_para[bfrp_idx].f2p_info.csi_len_bfrp =
845 			(u16)(rpt_size / 64); /*unit 64 byte*/
846 }
847 
rtw_hal_snd_ax_fwcmd_tb_pri(void * hal,u8 * buf,enum channel_width bw,struct rtw_phl_stainfo_t * psta,u8 sta_nr1,u8 sta_nr2)848 void rtw_hal_snd_ax_fwcmd_tb_pri(void *hal, u8 *buf, enum channel_width bw,
849 		    struct rtw_phl_stainfo_t *psta, u8 sta_nr1, u8 sta_nr2)
850 {
851 	struct hal_ax_fwcmd_snd *cmd = (struct hal_ax_fwcmd_snd *)buf;
852 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
853 	struct hal_snd_obj *snd_obj =
854 		(struct hal_snd_obj *)hal_info->hal_com->snd_obj;
855 	u8 i = 0;
856 	u8 sta_nr = sta_nr1 + sta_nr2;
857 
858 	if (sta_nr2 != 0)
859 		cmd->frame_ex_type = HAL_FEXG_TYPE_AX_MU_2;
860 	else
861 		cmd->frame_ex_type = HAL_FEXG_TYPE_AX_MU_1;
862 	cmd->bfrp0_sta_nr = sta_nr1;
863 	cmd->bfrp1_sta_nr = sta_nr2;
864 	cmd->macid[0] = psta->macid;
865 
866 	/* NDPA */
867 	cmd->ndpa.common.frame_ctl = HAL_SND_HE_NDPA_FRM_CTRL; /*TODO:*/
868 	for (i = 0; i < 6;i++) {
869 		cmd->ndpa.common.addr1[i] = 0xFF; /* NDPA-RA = Broadcast*/
870 		cmd->ndpa.common.addr2[i] = psta->wrole->mac_addr[i]; /* NDPA-TA*/
871 		/* BFRP - 1*/
872 		cmd->bfrp.hdr[0].addr1[i] = 0xFF;
873 		cmd->bfrp.hdr[0].addr2[i] = psta->wrole->mac_addr[i];
874 		if (sta_nr2 != 0) {
875 			/* BFRP - 2*/
876 			cmd->bfrp.hdr[1].addr1[i] = 0xFF;
877 			cmd->bfrp.hdr[1].addr2[i] =  psta->wrole->mac_addr[i];
878 		}
879 	}
880 	cmd->ndpa.common.duration = 150;/*TODO:*/
881 	/*TODO: ndpa user info in other api */
882 
883 	/* BFRP #1 */
884 	cmd->bfrp.hdr[0].frame_ctl = HAL_SND_HE_BFRP_FRM_CTRL; /* Trigger Frame */
885 	cmd->bfrp.hdr[0].duration = 100;
886 	cmd->bfrp.he_para[0].common.tgr_info = HAL_SND_TRIG_INFO_BFRP;/*BFRP*/
887 	cmd->bfrp.he_para[0].common.ul_len = 0xFFF;/*TODO: LSIG Length : sw provide or fw calculate */
888 	cmd->bfrp.he_para[0].common.more_tf = 0;
889 	cmd->bfrp.he_para[0].common.cs_rqd = 1;
890 	cmd->bfrp.he_para[0].common.ul_bw = bw;
891 	cmd->bfrp.he_para[0].common.gi_ltf = RTW_TB_GILTF_4XHE32;/* 8852A Limitation of UL OFDMA */
892 	cmd->bfrp.he_para[0].common.num_heltf = 0;/* TODO: Default value of golden */
893 	cmd->bfrp.he_para[0].common.ul_pktext = 0;/* TODO: fw? hw? */
894 	cmd->bfrp.he_para[0].common.ap_tx_pwr = 0x3C;/* TODO: Default value of golden */
895 
896 	/* F2P cmd parameters */
897 	cmd->bfrp.he_para[0].f2p_info.tb_t_pe_bfrp = 2;
898 	cmd->bfrp.he_para[0].f2p_info.tri_pad_bfrp = 2;
899 	cmd->bfrp.he_para[0].f2p_info.ul_cqi_rpt_tri_bfrp = 0;
900 	cmd->bfrp.he_para[0].f2p_info.rf_gain_idx_bfrp = 0;/* ?? */
901 	cmd->bfrp.he_para[0].f2p_info.fix_gain_en_bfrp = 0;/* ?? */
902 
903 	if (sta_nr2) {
904 		cmd->bfrp.hdr[1].frame_ctl = HAL_SND_HE_BFRP_FRM_CTRL; /* Trigger Frame */
905 		cmd->bfrp.hdr[1].duration = 100;
906 		cmd->bfrp.he_para[1].common.tgr_info = HAL_SND_TRIG_INFO_BFRP;/*BFRP*/
907 		cmd->bfrp.he_para[1].common.ul_len = 0xFFF;/*TODO: LSIG Length : sw provide or fw calculate */
908 		cmd->bfrp.he_para[1].common.more_tf = 0;
909 		cmd->bfrp.he_para[1].common.cs_rqd = 1;
910 		cmd->bfrp.he_para[1].common.ul_bw = bw;
911 		cmd->bfrp.he_para[1].common.gi_ltf = RTW_TB_GILTF_4XHE32;/* 8852A Limitation of UL OFDMA */
912 		cmd->bfrp.he_para[1].common.num_heltf = 0;/* TODO: Default value of golden */
913 		cmd->bfrp.he_para[1].common.ul_pktext = 0;/* TODO: fw? hw? */
914 		cmd->bfrp.he_para[1].common.ap_tx_pwr = 0x32;/* TODO: Default value of golden */
915 
916 		cmd->bfrp.he_para[1].f2p_info.tb_t_pe_bfrp = 2;
917 		cmd->bfrp.he_para[1].f2p_info.tri_pad_bfrp = 2;
918 		cmd->bfrp.he_para[1].f2p_info.ul_cqi_rpt_tri_bfrp = 0;
919 		cmd->bfrp.he_para[1].f2p_info.rf_gain_idx_bfrp = 0;
920 		cmd->bfrp.he_para[1].f2p_info.fix_gain_en_bfrp = 0;
921 	}
922 	/* NDPA WD */
923 	cmd->wd[0].txpktsize = 17 + HAL_SND_HE_NDPA_STA_SZ * sta_nr;/* 2 + 2 + 6 + 6 + 1 + 4, NO FCS */
924 	cmd->wd[0].ndpa_duration = 100;
925 	cmd->wd[0].disdatafb = 1;
926 	cmd->wd[0].datarate = snd_obj->ndpa_xpara.rate;
927 	cmd->wd[0].data_bw = snd_obj->ndpa_xpara.bw;
928 	cmd->wd[0].data_stbc = snd_obj->ndpa_xpara.stbc;
929 	cmd->wd[0].data_ldpc = snd_obj->ndpa_xpara.ldpc;
930 	cmd->wd[0].macid = psta->macid;
931 	cmd->wd[0].gi_ltf = snd_obj->ndpa_xpara.gi_ltf;
932 	cmd->wd[0].sifs_tx = 1;
933 	cmd->wd[0].snd_pkt_sel = HAL_SND_PKT_SEL_BST_NDPA;
934 	cmd->wd[0].ndpa = HAL_SND_PKT_NDPA_HE;
935 	/* NDP WD */
936 	cmd->wd[1].disdatafb = 1;
937 	if (1 == psta->wrole->proto_role_cap.num_snd_dim)
938 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
939 	else if (2 == psta->wrole->proto_role_cap.num_snd_dim)
940 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS3_MCS0;
941 	else if(3 == psta->wrole->proto_role_cap.num_snd_dim)
942 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS4_MCS0;
943 	else
944 		cmd->wd[1].datarate = RTW_DATA_RATE_HE_NSS2_MCS0;
945 	cmd->wd[1].data_bw = bw;
946 	cmd->wd[1].macid = psta->macid;
947 	cmd->wd[1].gi_ltf = RTW_GILTF_2XHE16; /* TODO: if support 4x32 NDP */
948 	cmd->wd[1].sifs_tx = 0;
949 	cmd->wd[1].snd_pkt_sel = HAL_SND_PKT_SEL_MID_NDP;
950 	cmd->wd[1].ndpa = HAL_SND_PKT_NDPA_HE;
951 	/* BFRP #1 WD */
952 	cmd->wd[2].txpktsize = 24 + HAL_SND_HE_BFRP_STA_SZ * sta_nr1;  /* 2 + 2 + 6 + 6 + 8 + 5*N */
953 	cmd->wd[2].ndpa_duration = 100;
954 	cmd->wd[2].datarate = snd_obj->bfrp_xpara.rate;
955 	//cmd->wd[2].macid
956 	cmd->wd[2].data_bw = snd_obj->bfrp_xpara.bw;
957 	cmd->wd[2].data_stbc = snd_obj->bfrp_xpara.stbc;
958 	cmd->wd[2].data_ldpc = snd_obj->bfrp_xpara.ldpc;
959 	cmd->wd[2].gi_ltf = snd_obj->bfrp_xpara.gi_ltf;
960 	cmd->wd[2].disdatafb = 1;
961 	if(sta_nr2) {
962 		cmd->wd[2].sifs_tx = 1;
963 		cmd->wd[2].snd_pkt_sel = HAL_SND_PKT_SEL_MID_BFRP;
964 	} else {
965 		cmd->wd[2].sifs_tx = 0;/* Final BFRP */
966 		cmd->wd[2].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_BFRP;
967 	}
968 	cmd->wd[2].ndpa = HAL_SND_PKT_NDPA_HE;
969 	if (sta_nr2) {
970 		cmd->wd[3].txpktsize = 24 + HAL_SND_HE_BFRP_STA_SZ * sta_nr2;  /* 2 + 2 + 6 + 6 + 8 + 5*N */
971 		cmd->wd[3].ndpa_duration = 100;
972 		cmd->wd[3].datarate = snd_obj->bfrp_xpara.rate;
973 		cmd->wd[3].data_bw = snd_obj->bfrp_xpara.bw;
974 		cmd->wd[3].data_stbc = snd_obj->bfrp_xpara.stbc;
975 		cmd->wd[3].data_ldpc = snd_obj->bfrp_xpara.ldpc;
976 		cmd->wd[3].gi_ltf = snd_obj->bfrp_xpara.gi_ltf;
977 		cmd->wd[3].disdatafb = 1;
978 		cmd->wd[3].sifs_tx = 0;/* Final BFRP */
979 		cmd->wd[3].snd_pkt_sel = HAL_SND_PKT_SEL_LAST_BFRP;
980 		cmd->wd[3].ndpa = HAL_SND_PKT_NDPA_HE;
981 	}
982 }
983 
984 u8 *
rtw_hal_snd_prepare_snd_cmd(void * hal)985 rtw_hal_snd_prepare_snd_cmd(void *hal)
986 {
987 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
988 	u8 *buf = NULL;
989 
990 	buf = _os_mem_alloc(hal_to_drvpriv(hal_info),
991 			    sizeof(struct hal_ax_fwcmd_snd));
992 
993 	return buf;
994 }
995 
996 
997 enum rtw_hal_status
rtw_hal_snd_release_snd_cmd(void * hal,u8 * buf)998 rtw_hal_snd_release_snd_cmd(void *hal, u8 *buf)
999 {
1000 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1001 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
1002 
1003 	do {
1004 		if (buf == NULL)
1005 			break;
1006 		_os_mem_free(hal_to_drvpriv(hal_info), buf,
1007 			     sizeof(struct hal_ax_fwcmd_snd));
1008 	} while (0);
1009 
1010 	return hstatus;
1011 }
1012 
1013 
1014 enum rtw_hal_status
rtw_hal_snd_send_fw_cmd(void * hal,u8 * cmd)1015 rtw_hal_snd_send_fw_cmd(void *hal, u8 *cmd)
1016 {
1017 	enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1018 	struct hal_info_t *hal_info = (struct hal_info_t *)hal;
1019 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "==> rtw_hal_snd_send_fw_cmd \n");
1020 	hstatus = hal_mac_ax_send_fw_snd(hal_info,
1021 			(struct hal_ax_fwcmd_snd *)cmd);
1022 	/*TODO: Dump CMD content */
1023 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "<== rtw_hal_snd_send_fw_cmd \n");
1024 	return hstatus;
1025 }
1026