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