1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * Copyright(c) 2019 - 2020 Realtek Corporation.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify it
6*4882a593Smuzhiyun * under the terms of version 2 of the GNU General Public License as
7*4882a593Smuzhiyun * published by the Free Software Foundation.
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful, but WITHOUT
10*4882a593Smuzhiyun * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12*4882a593Smuzhiyun * more details.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun *****************************************************************************/
15*4882a593Smuzhiyun #include "phl_headers.h"
16*4882a593Smuzhiyun
__reset_snd_grp(struct phl_snd_grp * grp)17*4882a593Smuzhiyun void __reset_snd_grp(struct phl_snd_grp *grp)
18*4882a593Smuzhiyun {
19*4882a593Smuzhiyun u8 i = 0;
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun grp->snd_type = PHL_SND_TYPE_INVALID;
22*4882a593Smuzhiyun grp->band = 0;
23*4882a593Smuzhiyun grp->num_sta = 0;
24*4882a593Smuzhiyun grp->wrole_idx = 0;
25*4882a593Smuzhiyun grp->grp_tier = PHL_SND_GRP_TIER_1;
26*4882a593Smuzhiyun grp->snd_sts = PHL_SND_STS_PENDING;
27*4882a593Smuzhiyun for (i = 0; i < MAX_NUM_STA_SND_GRP; i++) {
28*4882a593Smuzhiyun grp->sta[i].valid = false;
29*4882a593Smuzhiyun grp->sta[i].macid = 0;
30*4882a593Smuzhiyun grp->sta[i].bw = CHANNEL_WIDTH_20;
31*4882a593Smuzhiyun grp->sta[i].snd_fb_t = PHL_SND_FB_TYPE_SU;
32*4882a593Smuzhiyun grp->sta[i].npda_sta_info = 0;
33*4882a593Smuzhiyun grp->sta[i].bf_entry = NULL;
34*4882a593Smuzhiyun grp->sta[i].snd_sts = PHL_SND_STS_PENDING;
35*4882a593Smuzhiyun }
36*4882a593Smuzhiyun }
37*4882a593Smuzhiyun
_phl_snd_init_snd_grp(struct phl_info_t * phl_info)38*4882a593Smuzhiyun enum rtw_phl_status _phl_snd_init_snd_grp(
39*4882a593Smuzhiyun struct phl_info_t *phl_info)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun enum rtw_phl_status status = RTW_PHL_STATUS_SUCCESS;
42*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
43*4882a593Smuzhiyun struct phl_sound_param *param = &snd->snd_param;
44*4882a593Smuzhiyun u8 i = 0;
45*4882a593Smuzhiyun do {
46*4882a593Smuzhiyun if (param->snd_grp == NULL) {
47*4882a593Smuzhiyun status = RTW_PHL_STATUS_FAILURE;
48*4882a593Smuzhiyun break;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun for (i = 0; i < MAX_SND_GRP_NUM; i++) {
51*4882a593Smuzhiyun __reset_snd_grp(¶m->snd_grp[i]);
52*4882a593Smuzhiyun param->snd_grp[i].gidx = i;
53*4882a593Smuzhiyun }
54*4882a593Smuzhiyun } while (0);
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun return status;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun #ifdef CONFIG_FSM
59*4882a593Smuzhiyun /* For EXTERNAL application to create Sound object */
60*4882a593Smuzhiyun /* @fsm: FSM main structure which created by phl_snd_new_fsm()
61*4882a593Smuzhiyun * @phl_info: private data structure to invoke hal/phl function
62*4882a593Smuzhiyun *
63*4882a593Smuzhiyun * return
64*4882a593Smuzhiyun */
phl_snd_new_obj(struct fsm_main * fsm,struct phl_info_t * phl_info)65*4882a593Smuzhiyun enum rtw_phl_status phl_snd_new_obj(
66*4882a593Smuzhiyun struct fsm_main *fsm,
67*4882a593Smuzhiyun struct phl_info_t *phl_info)
68*4882a593Smuzhiyun {
69*4882a593Smuzhiyun enum rtw_phl_status status = RTW_PHL_STATUS_SUCCESS;
70*4882a593Smuzhiyun struct phl_sound_obj *snd_obj = NULL;
71*4882a593Smuzhiyun struct fsm_obj *obj = NULL;
72*4882a593Smuzhiyun void *drv_priv = phl_to_drvpriv(phl_info);
73*4882a593Smuzhiyun FUNCIN();
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun do {
76*4882a593Smuzhiyun snd_obj = phl_fsm_new_obj(
77*4882a593Smuzhiyun fsm, (void **)&obj, sizeof(*snd_obj));
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun if (snd_obj == NULL) {
80*4882a593Smuzhiyun status = RTW_PHL_STATUS_RESOURCE;
81*4882a593Smuzhiyun break;
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun phl_info->snd_obj = snd_obj;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun snd_obj->fsm = fsm;
86*4882a593Smuzhiyun snd_obj->fsm_obj = obj;
87*4882a593Smuzhiyun snd_obj->phl_info = phl_info;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun /*Init the snd group static resources here*/
90*4882a593Smuzhiyun status = _phl_snd_init_snd_grp(phl_info);
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun /* init obj local use variable */
93*4882a593Smuzhiyun PHL_INFO("snd_fsm_func_init_st_hdl : PHL SND FSM Module Start Work\n");
94*4882a593Smuzhiyun _os_spinlock_init(drv_priv, &snd_obj->snd_lock);
95*4882a593Smuzhiyun _os_spinlock_init(drv_priv, &snd_obj->cmd_lock);
96*4882a593Smuzhiyun phl_snd_func_snd_init(snd_obj->phl_info);
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun } while (0);
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun if (RTW_PHL_STATUS_SUCCESS != status) {
101*4882a593Smuzhiyun PHL_ERR("phl_snd_init_obj FAIL\n");
102*4882a593Smuzhiyun /* phl fsm module will handle to free the phl fsm related object*/
103*4882a593Smuzhiyun /* phl_snd_deinit_obj(phl_info); */
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun FUNCOUT();
107*4882a593Smuzhiyun return status;
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun #endif
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* PHL SOUND EXTERNAL APIs */
112*4882a593Smuzhiyun /* get sounding in progress */
rtw_phl_snd_chk_in_progress(void * phl)113*4882a593Smuzhiyun u8 rtw_phl_snd_chk_in_progress(void *phl)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun u8 ret = 0;
116*4882a593Smuzhiyun struct phl_info_t *phl_info = (struct phl_info_t *)phl;
117*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
118*4882a593Smuzhiyun void *d = phl_to_drvpriv(phl_info);
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun _os_spinlock(d, &snd->snd_lock, _bh, NULL);
121*4882a593Smuzhiyun ret = snd->snd_in_progress;
122*4882a593Smuzhiyun _os_spinunlock(d, &snd->snd_lock, _bh, NULL);
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun return ret;
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun /**
128*4882a593Smuzhiyun * rtw_phl_sound_start
129*4882a593Smuzhiyun * @phl:(struct phl_info_t *)
130*4882a593Smuzhiyun * @st_dlg_tkn: start dialog token value, if 0, it will use previous sounding dialog token;
131*4882a593Smuzhiyun * @period: sounding process period (group--> next group)
132*4882a593Smuzhiyun * @test_flag: test mode flags
133*4882a593Smuzhiyun **/
134*4882a593Smuzhiyun enum rtw_phl_status
rtw_phl_sound_start(void * phl,u8 wrole_idx,u8 st_dlg_tkn,u8 period,u8 test_flag)135*4882a593Smuzhiyun rtw_phl_sound_start(void *phl, u8 wrole_idx, u8 st_dlg_tkn, u8 period, u8 test_flag)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun #ifdef CONFIG_FSM
138*4882a593Smuzhiyun struct phl_info_t *phl_info = (struct phl_info_t *)phl;
139*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
140*4882a593Smuzhiyun struct phl_snd_start_req snd_req;
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun snd_req.wrole = (void *)rtw_phl_get_wrole_by_ridx(phl_info->phl_com, wrole_idx);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun snd_req.dialog_token = (st_dlg_tkn == 0) ?
145*4882a593Smuzhiyun snd->snd_param.snd_dialog_token : st_dlg_tkn;
146*4882a593Smuzhiyun snd_req.proc_timeout_ms = SND_PROC_DEFAULT_TIMEOUT; /* Default Value */
147*4882a593Smuzhiyun snd_req.proc_period = (period > SND_PROC_DEFAULT_PERIOD) ?
148*4882a593Smuzhiyun SND_PROC_DEFAULT_PERIOD : period; /*MAX = Default Value */
149*4882a593Smuzhiyun snd_req.test_flag = test_flag;
150*4882a593Smuzhiyun if (test_flag&PHL_SND_TEST_F_PASS_STS_CHK)
151*4882a593Smuzhiyun snd_req.bypass_sts_chk = true;
152*4882a593Smuzhiyun else
153*4882a593Smuzhiyun snd_req.bypass_sts_chk = false; /* Default False */
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun return phl_snd_fsm_ev_start_func(phl, &snd_req);
156*4882a593Smuzhiyun #else
157*4882a593Smuzhiyun return RTW_PHL_STATUS_FAILURE;
158*4882a593Smuzhiyun #endif
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun enum rtw_phl_status
rtw_phl_sound_down_ev(void * phl)162*4882a593Smuzhiyun rtw_phl_sound_down_ev(void *phl)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun enum rtw_phl_status status = RTW_PHL_STATUS_SUCCESS;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun #ifdef CONFIG_FSM
167*4882a593Smuzhiyun status = phl_snd_fsm_ev_c2h_snd_down(phl);
168*4882a593Smuzhiyun #else
169*4882a593Smuzhiyun status = RTW_PHL_STATUS_FAILURE;
170*4882a593Smuzhiyun #endif
171*4882a593Smuzhiyun return status;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun enum rtw_phl_status
rtw_phl_sound_abort(void * phl)176*4882a593Smuzhiyun rtw_phl_sound_abort(void *phl)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun #ifdef CONFIG_FSM
179*4882a593Smuzhiyun return phl_snd_fsm_ev_abort(phl);
180*4882a593Smuzhiyun #else
181*4882a593Smuzhiyun return RTW_PHL_STATUS_FAILURE;
182*4882a593Smuzhiyun #endif
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /* set fixed mode parameters APIs*/
rtw_phl_snd_dump_fix_para(struct phl_info_t * phl_info)186*4882a593Smuzhiyun void rtw_phl_snd_dump_fix_para(struct phl_info_t *phl_info)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
189*4882a593Smuzhiyun struct phl_snd_fix_param *para = NULL;
190*4882a593Smuzhiyun u8 i = 0;
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun para = &snd->snd_param.fix_param;
193*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "===> rtw_phl_snd_fix_dump_para \n");
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "test_flag = 0x%x \n", snd->snd_param.test_flag);
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "en_fix_gidx = %d \n", para->en_fix_gidx ? 1 : 0);
198*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "en_fix_fb_type = %d \n", para->en_fix_fb_type ? 1 : 0);
199*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "en_fix_sta = %d \n", para->en_fix_sta ? 1 : 0);
200*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "en_fix_snd_bw = %d \n", para->en_fix_snd_bw ? 1 : 0);
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "grp_idx = %d \n", para->grp_idx);
203*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "snd_fb_type = %d \n", para->snd_fb_type);
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun for (i = 0; i < MAX_NUM_STA_SND_GRP; i++) {
206*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "sta_macid[i] = 0x%x \n", para->sta_macid[i]);
207*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "bw[i] = %d \n",para->bw[i]);
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "<=== rtw_phl_snd_fix_dump_para \n");
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun /* fixed group idx */
rtw_phl_snd_fix_gidx(struct phl_info_t * phl_info,bool en,u8 gidx)213*4882a593Smuzhiyun void rtw_phl_snd_fix_gidx(struct phl_info_t *phl_info, bool en, u8 gidx)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
216*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "rtw_phl_snd_fix_gidx() set sounding gidx = 0x%x\n", gidx);
217*4882a593Smuzhiyun if (en) {
218*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_gidx = 1;
219*4882a593Smuzhiyun snd->snd_param.fix_param.grp_idx = gidx;
220*4882a593Smuzhiyun } else {
221*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_gidx = 0;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun /* fixed snd feedback type */
rtw_phl_snd_fix_snd_fb_type(struct phl_info_t * phl_info,bool en,enum snd_fb_type fb_type)225*4882a593Smuzhiyun void rtw_phl_snd_fix_snd_fb_type(struct phl_info_t *phl_info,
226*4882a593Smuzhiyun bool en, enum snd_fb_type fb_type)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
229*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "rtw_phl_snd_fix_gidx() set sounding fb_type = 0x%x\n",
230*4882a593Smuzhiyun fb_type);
231*4882a593Smuzhiyun if (en) {
232*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_fb_type = 1;
233*4882a593Smuzhiyun snd->snd_param.fix_param.snd_fb_type = fb_type;
234*4882a593Smuzhiyun } else {
235*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_fb_type = 0;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun /* fixed sounding sta macids */
rtw_phl_snd_fix_set_sta(struct phl_info_t * phl_info,bool en,u8 sidx,u16 macid)240*4882a593Smuzhiyun void rtw_phl_snd_fix_set_sta(struct phl_info_t *phl_info,
241*4882a593Smuzhiyun bool en, u8 sidx, u16 macid)
242*4882a593Smuzhiyun {
243*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
244*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "rtw_phl_snd_fix_set_sta() set sta[%d] macid = 0x%x\n",
245*4882a593Smuzhiyun sidx, macid);
246*4882a593Smuzhiyun if (en) {
247*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_sta = 1;
248*4882a593Smuzhiyun if (sidx < MAX_NUM_STA_SND_GRP)
249*4882a593Smuzhiyun snd->snd_param.fix_param.sta_macid[sidx] = macid;
250*4882a593Smuzhiyun else
251*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "ERROR, sidx >= 4\n");
252*4882a593Smuzhiyun } else {
253*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_sta = 0;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun }
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun /* fixed sounding sta bw */
rtw_phl_snd_fix_set_bw(struct phl_info_t * phl_info,bool en,u8 sidx,enum channel_width bw)258*4882a593Smuzhiyun void rtw_phl_snd_fix_set_bw(struct phl_info_t *phl_info,
259*4882a593Smuzhiyun bool en, u8 sidx, enum channel_width bw)
260*4882a593Smuzhiyun {
261*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
262*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "rtw_phl_snd_fix_set_bw() set sta[%d] bw = 0x%x\n", sidx, bw);
263*4882a593Smuzhiyun if (en) {
264*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_snd_bw = 1;
265*4882a593Smuzhiyun if (sidx < MAX_NUM_STA_SND_GRP)
266*4882a593Smuzhiyun snd->snd_param.fix_param.bw[sidx] = bw;
267*4882a593Smuzhiyun else
268*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "ERROR, sidx >= 4\n");
269*4882a593Smuzhiyun } else {
270*4882a593Smuzhiyun snd->snd_param.fix_param.en_fix_snd_bw = 0;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun /* set forced fw tx mu-mimo (forced fw tx decision) */
rtw_phl_snd_fix_tx_he_mu(struct phl_info_t * phl_info,u8 gid,bool en)275*4882a593Smuzhiyun void rtw_phl_snd_fix_tx_he_mu(struct phl_info_t *phl_info, u8 gid, bool en)
276*4882a593Smuzhiyun {
277*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "rtw_phl_snd_fix_tx_mu_para()\n");
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun rtw_hal_bf_set_txmu_para(phl_info->hal, gid, en,
280*4882a593Smuzhiyun HAL_PROT_NO_PROETCT, HAL_ACK_N_USER_BA);
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun rtw_hal_bf_set_fix_mode(phl_info->hal, gid, en);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun /* PHL SOUND INTERNAL APIs */
287*4882a593Smuzhiyun /* SND FUNC */
288*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_func_snd_init(struct phl_info_t * phl_info)289*4882a593Smuzhiyun phl_snd_func_snd_init(struct phl_info_t *phl_info)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
292*4882a593Smuzhiyun void *d = phl_to_drvpriv(phl_info);
293*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
294*4882a593Smuzhiyun u8 f_ru_tbl_80m[MAX_SND_HE_BFRP_USER_NUM][MAX_SND_HE_BFRP_USER_NUM] = {
295*4882a593Smuzhiyun {RTW_HE_RU996_1, RTW_HE_RU996_1, RTW_HE_RU996_1 ,RTW_HE_RU996_1},
296*4882a593Smuzhiyun {RTW_HE_RU484_1, RTW_HE_RU484_2, RTW_HE_RU996_1 ,RTW_HE_RU996_1},
297*4882a593Smuzhiyun {RTW_HE_RU484_1, RTW_HE_RU242_3, RTW_HE_RU242_4 ,RTW_HE_RU996_1},
298*4882a593Smuzhiyun {RTW_HE_RU242_1, RTW_HE_RU242_2, RTW_HE_RU242_3 ,RTW_HE_RU242_4}
299*4882a593Smuzhiyun };
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun u8 f_ru_tbl_20m[MAX_SND_HE_BFRP_USER_NUM][MAX_SND_HE_BFRP_USER_NUM] = {
302*4882a593Smuzhiyun {RTW_HE_RU242_1, RTW_HE_RU242_1, RTW_HE_RU242_1, RTW_HE_RU242_1},
303*4882a593Smuzhiyun {RTW_HE_RU106_1, RTW_HE_RU106_1, RTW_HE_RU242_1, RTW_HE_RU242_1},
304*4882a593Smuzhiyun {RTW_HE_RU106_1, RTW_HE_RU52_3, RTW_HE_RU52_4, RTW_HE_RU242_1},
305*4882a593Smuzhiyun {RTW_HE_RU52_1, RTW_HE_RU52_2, RTW_HE_RU52_3, RTW_HE_RU52_4}
306*4882a593Smuzhiyun };
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun /* Add Other Sounding FUNC/PRCO Initialization Here */
309*4882a593Smuzhiyun snd->snd_param.snd_proc_timeout_ms = SND_PROC_DEFAULT_TIMEOUT;/* ms */
310*4882a593Smuzhiyun snd->snd_param.cur_proc_grp_idx = 0;
311*4882a593Smuzhiyun snd->snd_param.pre_proc_grp_idx = 0;
312*4882a593Smuzhiyun snd->snd_param.snd_dialog_token = 1;
313*4882a593Smuzhiyun snd->snd_param.snd_func_grp_num = 0;
314*4882a593Smuzhiyun snd->snd_param.grp_used_map = 0;
315*4882a593Smuzhiyun snd->snd_param.snd_proc_period = SND_PROC_DEFAULT_PERIOD;
316*4882a593Smuzhiyun snd->snd_param.snd_fail_counter = 0;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /*fixed_ru_tbl*/
319*4882a593Smuzhiyun _os_mem_cpy(d, snd->snd_param.fix_param.f_ru_tbl_20, f_ru_tbl_20m,
320*4882a593Smuzhiyun MAX_SND_HE_BFRP_USER_NUM * MAX_SND_HE_BFRP_USER_NUM);
321*4882a593Smuzhiyun _os_mem_cpy(d, snd->snd_param.fix_param.f_ru_tbl_80, f_ru_tbl_80m,
322*4882a593Smuzhiyun MAX_SND_HE_BFRP_USER_NUM * MAX_SND_HE_BFRP_USER_NUM);
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun return pstatus;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_func_pre_config(struct phl_info_t * phl_info)328*4882a593Smuzhiyun phl_snd_func_pre_config(struct phl_info_t *phl_info)
329*4882a593Smuzhiyun {
330*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
331*4882a593Smuzhiyun struct phl_sound_param *snd_param = &snd->snd_param;
332*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
333*4882a593Smuzhiyun void *d = phl_to_drvpriv(phl_info);
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun snd_param->proc_start_time = _os_get_cur_time_ms();
336*4882a593Smuzhiyun snd_param->cur_proc_grp_idx = 0; /* default start from group idx 0 */
337*4882a593Smuzhiyun snd_param->pre_proc_grp_idx = 0;
338*4882a593Smuzhiyun _os_spinlock(d, &snd->snd_lock, _bh, NULL);
339*4882a593Smuzhiyun snd->is_terminated = 0;
340*4882a593Smuzhiyun snd->snd_in_progress = 1;
341*4882a593Smuzhiyun _os_spinunlock(d, &snd->snd_lock, _bh, NULL);
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "PHL SND FUNC Start with SND Dialog Token = 0x%x\n",
344*4882a593Smuzhiyun snd_param->snd_dialog_token);
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun return pstatus;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun /* SND_FUNC : GROUP related */
352*4882a593Smuzhiyun /**
353*4882a593Smuzhiyun * phl_snd_proc_get_grp()
354*4882a593Smuzhiyun * get the grp(struct phl_sound_grp *) with group index.
355*4882a593Smuzhiyun * input:
356*4882a593Smuzhiyun * @gidx: group idx.
357*4882a593Smuzhiyun * return:
358*4882a593Smuzhiyun * @grp: (struct phl_snd_grp *grp), NULL = FAIL;
359*4882a593Smuzhiyun */
360*4882a593Smuzhiyun struct phl_snd_grp *
phl_snd_get_grp_byidx(struct phl_info_t * phl_info,u8 gidx)361*4882a593Smuzhiyun phl_snd_get_grp_byidx(struct phl_info_t *phl_info, u8 gidx)
362*4882a593Smuzhiyun {
363*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
364*4882a593Smuzhiyun struct phl_sound_param *snd_param = &snd->snd_param;
365*4882a593Smuzhiyun struct phl_snd_grp *grp = NULL;
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun do {
368*4882a593Smuzhiyun if (gidx >= MAX_SND_GRP_NUM)
369*4882a593Smuzhiyun break;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun if (!(snd_param->grp_used_map & BIT(gidx)))
372*4882a593Smuzhiyun break;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun if (0 == snd_param->snd_grp[gidx].num_sta)
375*4882a593Smuzhiyun break;
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun if (PHL_SND_TYPE_INVALID == snd_param->snd_grp[gidx].snd_type)
378*4882a593Smuzhiyun break;
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun grp = &snd_param->snd_grp[gidx];
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun } while (0);
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun return grp;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun /**
388*4882a593Smuzhiyun * phl_snd_func_remove_grp()
389*4882a593Smuzhiyun * remove the target sounding grp from sound process;
390*4882a593Smuzhiyun * input:
391*4882a593Smuzhiyun * @grp: (struct phl_snd_grp *) target sounding grp,
392*4882a593Smuzhiyun */
393*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_func_remove_grp(struct phl_info_t * phl_info,struct phl_snd_grp * grp)394*4882a593Smuzhiyun phl_snd_func_remove_grp(struct phl_info_t *phl_info, struct phl_snd_grp *grp)
395*4882a593Smuzhiyun {
396*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
397*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
398*4882a593Smuzhiyun struct phl_sound_param *snd_param = &snd->snd_param;
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun if (grp == NULL) {
401*4882a593Smuzhiyun return pstatus;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun if (snd_param->grp_used_map & BIT(grp->gidx)) {
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun /* Check and Release all the BF resource */
406*4882a593Smuzhiyun pstatus = phl_snd_proc_release_res(phl_info, grp);
407*4882a593Smuzhiyun if (pstatus != RTW_PHL_STATUS_SUCCESS) {
408*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "PHL SND Remove Grp : release BF resouce fail\n");
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun /* Reset group content to default value */
412*4882a593Smuzhiyun __reset_snd_grp(grp);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun /* Clear Group BIT */
415*4882a593Smuzhiyun snd_param->grp_used_map &= ~BIT(grp->gidx);
416*4882a593Smuzhiyun snd_param->snd_func_grp_num--;
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun } else {
419*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "PHL SND Remove Grp : Group is not in used!!!\n");
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun return pstatus;
423*4882a593Smuzhiyun }
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun /**
426*4882a593Smuzhiyun * phl_snd_func_remove_grp_all()
427*4882a593Smuzhiyun * remove the all of the sounding grp from sound process;
428*4882a593Smuzhiyun */
429*4882a593Smuzhiyun void
phl_snd_func_remove_grp_all(struct phl_info_t * phl_info)430*4882a593Smuzhiyun phl_snd_func_remove_grp_all(struct phl_info_t *phl_info)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
433*4882a593Smuzhiyun struct phl_snd_grp *grp = NULL;
434*4882a593Smuzhiyun u8 idx = 0;
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun for(idx = 0; idx < MAX_SND_GRP_NUM; idx++) {
437*4882a593Smuzhiyun grp = phl_snd_get_grp_byidx(phl_info, idx);
438*4882a593Smuzhiyun if (grp != NULL) {
439*4882a593Smuzhiyun pstatus = phl_snd_func_remove_grp(phl_info, grp);
440*4882a593Smuzhiyun if (pstatus != RTW_PHL_STATUS_SUCCESS) {
441*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "Remove SND GRP[%d] Fail\n", idx);
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun /**
448*4882a593Smuzhiyun * _phl_snd_get_available_gidx()
449*4882a593Smuzhiyun * Get available group resource.
450*4882a593Smuzhiyun * return:
451*4882a593Smuzhiyun * @gidx: u8, the group idx in snd_param->grp[n]
452*4882a593Smuzhiyun */
_phl_snd_get_available_gidx(struct phl_sound_obj * snd)453*4882a593Smuzhiyun u8 _phl_snd_get_available_gidx(struct phl_sound_obj *snd)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun struct phl_sound_param *param = &snd->snd_param;
456*4882a593Smuzhiyun u8 gidx = MAX_SND_GRP_NUM;
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun for (gidx = 0; gidx < MAX_SND_GRP_NUM; gidx++) {
459*4882a593Smuzhiyun if (!(param->grp_used_map & BIT(gidx))) {
460*4882a593Smuzhiyun param->grp_used_map |= BIT(gidx);
461*4882a593Smuzhiyun break;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun return gidx;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun /**
469*4882a593Smuzhiyun * _phl_snd_func_grp_add_sta()
470*4882a593Smuzhiyun * Add the STA into sounding group.
471*4882a593Smuzhiyun * input:
472*4882a593Smuzhiyun * @sta: (struct rtw_phl_stainfo_t *) the target sta to be added.
473*4882a593Smuzhiyun * the function will use the macid / bw information in sta_info;
474*4882a593Smuzhiyun * @gidx: the group idx to add
475*4882a593Smuzhiyun */
476*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_func_grp_add_sta(struct phl_info_t * phl_info,struct rtw_phl_stainfo_t * sta,u8 gidx)477*4882a593Smuzhiyun _phl_snd_func_grp_add_sta(
478*4882a593Smuzhiyun struct phl_info_t *phl_info, struct rtw_phl_stainfo_t *sta, u8 gidx)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
481*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
482*4882a593Smuzhiyun struct phl_sound_param *snd_param = &snd->snd_param;
483*4882a593Smuzhiyun struct phl_snd_grp *grp = NULL;
484*4882a593Smuzhiyun u8 i = 0;
485*4882a593Smuzhiyun bool chk = false;
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun do {
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun if (NULL == sta) {
490*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "STA == NULL !!!!\n");
491*4882a593Smuzhiyun break;
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun if (gidx >= MAX_SND_GRP_NUM) {
495*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "Get SND Grp Resource Fail : gidx >= MAX_SND_GRP_NUM\n");
496*4882a593Smuzhiyun break;
497*4882a593Smuzhiyun }
498*4882a593Smuzhiyun
499*4882a593Smuzhiyun grp = &snd_param->snd_grp[gidx];
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun /* check grp->sta[i].macid with sta->macid, skip it if same.*/
502*4882a593Smuzhiyun for (i = 0; i < grp->num_sta; i++) {
503*4882a593Smuzhiyun if(grp->sta[i].macid == sta->macid) {
504*4882a593Smuzhiyun chk = true;
505*4882a593Smuzhiyun break;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun }
508*4882a593Smuzhiyun if (true == chk)
509*4882a593Smuzhiyun break;
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun if (grp->num_sta >= MAX_NUM_STA_SND_GRP) {
512*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "The SND Grp is already has 4 STAs\n");
513*4882a593Smuzhiyun break;
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun grp->sta[grp->num_sta].macid = sta->macid;
517*4882a593Smuzhiyun grp->sta[grp->num_sta].snd_sts = PHL_SND_STS_PENDING;
518*4882a593Smuzhiyun grp->sta[grp->num_sta].bw = sta->chandef.bw;
519*4882a593Smuzhiyun grp->sta[grp->num_sta].valid = true;
520*4882a593Smuzhiyun grp->num_sta++;
521*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "sta bw = %d\n", sta->chandef.bw);
522*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "grp->num_sta = %d\n", grp->num_sta);
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_SUCCESS;
525*4882a593Smuzhiyun } while (0);
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun return pstatus;
528*4882a593Smuzhiyun }
529*4882a593Smuzhiyun
530*4882a593Smuzhiyun /**
531*4882a593Smuzhiyun * phl_snd_func_add_snd_grp :
532*4882a593Smuzhiyun * Add a Sounding Group with Primary STA for FW Sounding
533*4882a593Smuzhiyun * @phl_info: struct phl_info_t *
534*4882a593Smuzhiyun * @he_snd: 1 = HE , 0 =VHT
535*4882a593Smuzhiyun * @gidx: return value, snd group idxx in group list
536*4882a593Smuzhiyun * @psta: (struct rtw_phl_stainfo_t *)Primary Sounding STA,
537*4882a593Smuzhiyun * if pSTA is unavailable , SND PROC for this group will be terminated.
538*4882a593Smuzhiyun **/
539*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_func_add_snd_grp(struct phl_info_t * phl_info,bool he_snd,u8 wrole_idx,struct rtw_phl_stainfo_t * psta,u8 * gidx)540*4882a593Smuzhiyun phl_snd_func_add_snd_grp(
541*4882a593Smuzhiyun struct phl_info_t *phl_info, bool he_snd,
542*4882a593Smuzhiyun u8 wrole_idx, struct rtw_phl_stainfo_t *psta, u8 *gidx)
543*4882a593Smuzhiyun {
544*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
545*4882a593Smuzhiyun struct phl_sound_param *snd_param = &snd->snd_param;
546*4882a593Smuzhiyun struct phl_snd_grp *grp = NULL;
547*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun do {
550*4882a593Smuzhiyun /* Check Primary STA Available*/
551*4882a593Smuzhiyun if (psta == NULL) {
552*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "psta == NULL\n");
553*4882a593Smuzhiyun break;
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun /* Get available sounding group resource */
557*4882a593Smuzhiyun *gidx = _phl_snd_get_available_gidx(snd);
558*4882a593Smuzhiyun if (*gidx >= MAX_SND_GRP_NUM) {
559*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "Get SND Grp Resource Fail : gidx >= MAX_SND_GRP_NUM\n");
560*4882a593Smuzhiyun break;
561*4882a593Smuzhiyun }
562*4882a593Smuzhiyun
563*4882a593Smuzhiyun grp = &(snd_param->snd_grp[*gidx]);
564*4882a593Smuzhiyun grp->band = psta->wrole->hw_band;
565*4882a593Smuzhiyun grp->snd_type = he_snd ? PHL_SND_TYPE_HE_SW :
566*4882a593Smuzhiyun PHL_SND_TYPE_VHT_SW;
567*4882a593Smuzhiyun grp->wrole_idx = wrole_idx;
568*4882a593Smuzhiyun grp->snd_sts = PHL_SND_STS_PENDING;
569*4882a593Smuzhiyun grp->num_sta = 0;
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun /* Primary STA use idx-0 */
572*4882a593Smuzhiyun _phl_snd_func_grp_add_sta(phl_info, psta, *gidx);
573*4882a593Smuzhiyun
574*4882a593Smuzhiyun snd_param->snd_func_grp_num++;
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_SUCCESS;
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "phl_snd_func_add_snd_grp : Add group[%d] Success\n",
579*4882a593Smuzhiyun *gidx);
580*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "phl_snd_func_add_snd_grp : grp->snd_type 0x%x\n",
581*4882a593Smuzhiyun grp->snd_type);
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun } while (0);
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun return pstatus;
586*4882a593Smuzhiyun }
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun /**
589*4882a593Smuzhiyun * _phl_snd_func_set_grp_fb_mu()
590*4882a593Smuzhiyun * Set the whole sounding grp's feedback type = MU
591*4882a593Smuzhiyun * input:
592*4882a593Smuzhiyun * @grp: (struct phl_snd_grp *) the target group.
593*4882a593Smuzhiyun */
_phl_snd_func_set_grp_fb_mu(struct phl_snd_grp * grp)594*4882a593Smuzhiyun void _phl_snd_func_set_grp_fb_mu(struct phl_snd_grp *grp)
595*4882a593Smuzhiyun {
596*4882a593Smuzhiyun u8 i = 0;
597*4882a593Smuzhiyun if (grp == NULL)
598*4882a593Smuzhiyun return;
599*4882a593Smuzhiyun for (i = 0; i < grp->num_sta; i++) {
600*4882a593Smuzhiyun grp->sta[i].snd_fb_t = PHL_SND_FB_TYPE_MU;
601*4882a593Smuzhiyun }
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun /**
605*4882a593Smuzhiyun * phl_snd_func_grouping()
606*4882a593Smuzhiyun * function for soundind fsm state : SND_FUNC_READY
607*4882a593Smuzhiyun * input:
608*4882a593Smuzhiyun * @wroleidx: the index of wrole which the sounding proc run under with.
609*4882a593Smuzhiyun */
610*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_func_grouping(struct phl_info_t * phl_info,u8 wroleidx)611*4882a593Smuzhiyun phl_snd_func_grouping(struct phl_info_t *phl_info, u8 wroleidx)
612*4882a593Smuzhiyun {
613*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
614*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
615*4882a593Smuzhiyun struct phl_sound_param *snd_param = &snd->snd_param;
616*4882a593Smuzhiyun struct phl_snd_fix_param *fix_para = &snd->snd_param.fix_param;
617*4882a593Smuzhiyun struct rtw_wifi_role_t *wrole = NULL;
618*4882a593Smuzhiyun struct rtw_phl_stainfo_t *self = NULL, *sta;
619*4882a593Smuzhiyun struct phl_snd_grp *grp = NULL;
620*4882a593Smuzhiyun void *drv = phl_to_drvpriv(phl_info);
621*4882a593Smuzhiyun struct phl_queue *sta_queue;
622*4882a593Smuzhiyun u8 gidx = 0;
623*4882a593Smuzhiyun u8 cnt = 0;
624*4882a593Smuzhiyun
625*4882a593Smuzhiyun wrole = rtw_phl_get_wrole_by_ridx(phl_info->phl_com, wroleidx);
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun /* if wrole(STA) is linked, seft = AP */
628*4882a593Smuzhiyun /* if wrole is AP, self = ???? */
629*4882a593Smuzhiyun self = rtw_phl_get_stainfo_self(phl_info, wrole);
630*4882a593Smuzhiyun if (self == NULL) {
631*4882a593Smuzhiyun PHL_ERR("Cannot get self's phl_sta\n");
632*4882a593Smuzhiyun return pstatus;
633*4882a593Smuzhiyun }
634*4882a593Smuzhiyun sta_queue = &wrole->assoc_sta_queue;
635*4882a593Smuzhiyun if (PHL_RTYPE_STATION == wrole->type) {
636*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, " PHL_RTYPE_STATION == wrole->type \n");
637*4882a593Smuzhiyun /* STA Mode : Only SU TxBF with AP */
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "self->macid = 0x%x \n", self->macid);
640*4882a593Smuzhiyun debug_dump_mac_address(self->mac_addr);
641*4882a593Smuzhiyun
642*4882a593Smuzhiyun pstatus = phl_snd_func_add_snd_grp(
643*4882a593Smuzhiyun phl_info,
644*4882a593Smuzhiyun (self->wmode & WLAN_MD_11AX) ? true :
645*4882a593Smuzhiyun false,
646*4882a593Smuzhiyun wrole->id, self, &gidx);
647*4882a593Smuzhiyun grp = &snd_param->snd_grp[gidx];
648*4882a593Smuzhiyun grp->grp_tier = PHL_SND_GRP_TIER_0;
649*4882a593Smuzhiyun grp->sta[0].snd_fb_t = PHL_SND_FB_TYPE_SU;
650*4882a593Smuzhiyun grp->snd_type = (self->wmode & WLAN_MD_11AX) ?
651*4882a593Smuzhiyun PHL_SND_TYPE_HE_HW : PHL_SND_TYPE_VHT_HW;
652*4882a593Smuzhiyun } else {
653*4882a593Smuzhiyun #if 1
654*4882a593Smuzhiyun /* Test Code: Group-1 :Forced MU Sounding with first 1~4 STAs */
655*4882a593Smuzhiyun /* the mu sounding list shall get from mu grouping module */
656*4882a593Smuzhiyun cnt = 0;
657*4882a593Smuzhiyun _os_spinlock(drv, &sta_queue->lock, _bh, NULL);
658*4882a593Smuzhiyun phl_list_for_loop(sta, struct rtw_phl_stainfo_t,
659*4882a593Smuzhiyun &wrole->assoc_sta_queue.queue, list) {
660*4882a593Smuzhiyun if (is_broadcast_mac_addr(sta->mac_addr))
661*4882a593Smuzhiyun continue;
662*4882a593Smuzhiyun if (sta == self)
663*4882a593Smuzhiyun continue;
664*4882a593Smuzhiyun /* First STA */
665*4882a593Smuzhiyun if (cnt == 0) {
666*4882a593Smuzhiyun pstatus = phl_snd_func_add_snd_grp(
667*4882a593Smuzhiyun phl_info,
668*4882a593Smuzhiyun (sta->wmode & WLAN_MD_11AX) ?
669*4882a593Smuzhiyun true : false,
670*4882a593Smuzhiyun wrole->id, sta, &gidx);
671*4882a593Smuzhiyun if (pstatus != RTW_PHL_STATUS_SUCCESS)
672*4882a593Smuzhiyun break;
673*4882a593Smuzhiyun } else {
674*4882a593Smuzhiyun /* get next associated sta and add to group */
675*4882a593Smuzhiyun _phl_snd_func_grp_add_sta(phl_info, sta, gidx);
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun cnt++;
678*4882a593Smuzhiyun if (cnt >= 4)
679*4882a593Smuzhiyun break;
680*4882a593Smuzhiyun }
681*4882a593Smuzhiyun _os_spinunlock(drv, &sta_queue->lock, _bh, NULL);
682*4882a593Smuzhiyun if(pstatus != RTW_PHL_STATUS_SUCCESS)
683*4882a593Smuzhiyun return RTW_PHL_STATUS_FAILURE;
684*4882a593Smuzhiyun grp = &snd_param->snd_grp[gidx];
685*4882a593Smuzhiyun grp->grp_tier = PHL_SND_GRP_TIER_0;
686*4882a593Smuzhiyun /* Test : forced MU */
687*4882a593Smuzhiyun _phl_snd_func_set_grp_fb_mu(&snd_param->snd_grp[gidx]);
688*4882a593Smuzhiyun #endif
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun
691*4882a593Smuzhiyun /*TODO: fixed paramters gidx when multi-group */
692*4882a593Smuzhiyun if (snd_param->test_flag&PHL_SND_TEST_F_GRP_SND_PARA) {
693*4882a593Smuzhiyun /*Test Mode force set the group fb type = MU */
694*4882a593Smuzhiyun if (fix_para->en_fix_fb_type) {
695*4882a593Smuzhiyun if (PHL_SND_FB_TYPE_MU == fix_para->snd_fb_type) {
696*4882a593Smuzhiyun _phl_snd_func_set_grp_fb_mu(
697*4882a593Smuzhiyun &snd_param->snd_grp[gidx]);
698*4882a593Smuzhiyun }
699*4882a593Smuzhiyun /**
700*4882a593Smuzhiyun * Note : 8852A only support two CSI Buffer for SU,
701*4882a593Smuzhiyun * take care that num of STA in SU sounding of a group shall < 2.
702*4882a593Smuzhiyun **/
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun if(fix_para->en_fix_snd_bw) {
706*4882a593Smuzhiyun grp = &snd_param->snd_grp[gidx];
707*4882a593Smuzhiyun for (cnt = 0; cnt < MAX_NUM_STA_SND_GRP; cnt++) {
708*4882a593Smuzhiyun if (grp->sta[cnt].valid)
709*4882a593Smuzhiyun grp->sta[cnt].bw = fix_para->bw[cnt];
710*4882a593Smuzhiyun }
711*4882a593Smuzhiyun }
712*4882a593Smuzhiyun } else {
713*4882a593Smuzhiyun grp = &snd_param->snd_grp[gidx];
714*4882a593Smuzhiyun if (grp->num_sta > 2) {
715*4882a593Smuzhiyun /* forced using MU feedback because of SU CSI buffer number */
716*4882a593Smuzhiyun _phl_snd_func_set_grp_fb_mu(&snd_param->snd_grp[gidx]);
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun
720*4882a593Smuzhiyun if (snd_param->test_flag & PHL_SND_TEST_F_GRP_EN_BF_FIX) {
721*4882a593Smuzhiyun snd_param->snd_grp[gidx].en_fix_mode = 1; /* post confg forced mode setting */
722*4882a593Smuzhiyun }
723*4882a593Smuzhiyun return pstatus;
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun }
726*4882a593Smuzhiyun
727*4882a593Smuzhiyun /* SND PROC */
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun /* Free BF/CQI resource */
730*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_proc_release_res_cqi(struct phl_info_t * phl_info,struct phl_snd_grp * grp)731*4882a593Smuzhiyun _phl_snd_proc_release_res_cqi(
732*4882a593Smuzhiyun struct phl_info_t *phl_info, struct phl_snd_grp *grp)
733*4882a593Smuzhiyun {
734*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
735*4882a593Smuzhiyun
736*4882a593Smuzhiyun /*CQI Fb doesn't query any resource*/
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun return pstatus;
739*4882a593Smuzhiyun }
740*4882a593Smuzhiyun
741*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_proc_release_res_bf(struct phl_info_t * phl_info,struct phl_snd_grp * grp)742*4882a593Smuzhiyun _phl_snd_proc_release_res_bf(
743*4882a593Smuzhiyun struct phl_info_t *phl_info, struct phl_snd_grp *grp)
744*4882a593Smuzhiyun {
745*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
746*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
747*4882a593Smuzhiyun struct phl_snd_sta *snd_sta;
748*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta = NULL;
749*4882a593Smuzhiyun u8 idx = 0;
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun for (idx = 0; idx < grp->num_sta; idx++) {
752*4882a593Smuzhiyun snd_sta = &grp->sta[idx];
753*4882a593Smuzhiyun if(0 == snd_sta->valid)
754*4882a593Smuzhiyun continue;
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun sta = rtw_phl_get_stainfo_by_macid(
757*4882a593Smuzhiyun phl_info, snd_sta->macid);
758*4882a593Smuzhiyun if (NULL == sta) {
759*4882a593Smuzhiyun PHL_ERR("_phl_snd_proc_release_res_bf: Cannot find STA macid 0x%x in PHL STA Info List \n",
760*4882a593Smuzhiyun snd_sta->macid);
761*4882a593Smuzhiyun continue;
762*4882a593Smuzhiyun }
763*4882a593Smuzhiyun if (NULL == sta->hal_sta->bf_entry)
764*4882a593Smuzhiyun continue;
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun hstatus = rtw_hal_snd_release_proc_sta_res(phl_info->hal, sta);
767*4882a593Smuzhiyun if(hstatus != RTW_HAL_STATUS_SUCCESS) {
768*4882a593Smuzhiyun PHL_ERR("_phl_snd_proc_release_res_bf: macid 0x%x Free Sounding Resource FAIL \n",
769*4882a593Smuzhiyun snd_sta->macid);
770*4882a593Smuzhiyun continue;
771*4882a593Smuzhiyun }
772*4882a593Smuzhiyun /* un link the bf entry to STA info */
773*4882a593Smuzhiyun sta->hal_sta->bf_entry = NULL;
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun return pstatus;
776*4882a593Smuzhiyun }
777*4882a593Smuzhiyun /**
778*4882a593Smuzhiyun * phl_snd_proc_release_res:
779*4882a593Smuzhiyun * Release the sounding resource for the group
780*4882a593Smuzhiyun * @phl_info: phl_info_t
781*4882a593Smuzhiyun * @grp: (struct phl_snd_grp *) sounding gorup for release resource
782*4882a593Smuzhiyun **/
783*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_proc_release_res(struct phl_info_t * phl_info,struct phl_snd_grp * grp)784*4882a593Smuzhiyun phl_snd_proc_release_res(struct phl_info_t *phl_info, struct phl_snd_grp *grp)
785*4882a593Smuzhiyun {
786*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
787*4882a593Smuzhiyun struct phl_snd_sta *snd_sta;
788*4882a593Smuzhiyun snd_sta = &grp->sta[0];
789*4882a593Smuzhiyun if (snd_sta->snd_fb_t == PHL_SND_FB_TYPE_CQI)
790*4882a593Smuzhiyun pstatus = _phl_snd_proc_release_res_cqi(phl_info, grp);
791*4882a593Smuzhiyun else
792*4882a593Smuzhiyun pstatus = _phl_snd_proc_release_res_bf(phl_info, grp);
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun return pstatus;
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun
797*4882a593Smuzhiyun /**
798*4882a593Smuzhiyun * _phl_snd_proc_get_bf_res_cqi_fb:
799*4882a593Smuzhiyun * CQI Sounding doesn't need BF Reresource
800*4882a593Smuzhiyun * @phl_info: phl_info_t
801*4882a593Smuzhiyun * @grp: (struct phl_sound_grp *) sounding gorup
802*4882a593Smuzhiyun * @nsta: return value : how many sta query resource success
803*4882a593Smuzhiyun **/
804*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_proc_get_res_cqi_fb(struct phl_info_t * phl_info,struct phl_snd_grp * grp,u8 * nsta)805*4882a593Smuzhiyun _phl_snd_proc_get_res_cqi_fb(
806*4882a593Smuzhiyun struct phl_info_t *phl_info, struct phl_snd_grp *grp, u8 *nsta)
807*4882a593Smuzhiyun {
808*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
809*4882a593Smuzhiyun struct phl_snd_sta *snd_sta;
810*4882a593Smuzhiyun u8 idx = 0;
811*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta = NULL;
812*4882a593Smuzhiyun
813*4882a593Smuzhiyun *nsta = 0;
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun for (idx = 0; idx < grp->num_sta; idx++) {
816*4882a593Smuzhiyun snd_sta = &grp->sta[idx];
817*4882a593Smuzhiyun sta = rtw_phl_get_stainfo_by_macid(phl_info, snd_sta->macid);
818*4882a593Smuzhiyun if (NULL == sta) {
819*4882a593Smuzhiyun PHL_ERR("phl_snd_proc_get_bf_res: Cannot find STA macid 0x%x in PHL STA Info List \n",
820*4882a593Smuzhiyun snd_sta->macid);
821*4882a593Smuzhiyun continue;
822*4882a593Smuzhiyun }
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun rtw_hal_snd_ndpa_sta_info_he(
825*4882a593Smuzhiyun sta,
826*4882a593Smuzhiyun &snd_sta->npda_sta_info,
827*4882a593Smuzhiyun snd_sta->bw,
828*4882a593Smuzhiyun PHL_SND_FB_TYPE_CQI);
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun (*nsta)++;
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun if (*nsta == 0) {
833*4882a593Smuzhiyun grp->snd_sts = PHL_SND_STS_FAILURE;
834*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
835*4882a593Smuzhiyun }
836*4882a593Smuzhiyun if (*nsta != grp->num_sta) {
837*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, " Sounding STAs is fewer than group sta because of resource!");
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun return pstatus;
841*4882a593Smuzhiyun }
842*4882a593Smuzhiyun
843*4882a593Smuzhiyun /**
844*4882a593Smuzhiyun * _phl_snd_proc_get_res_bf:
845*4882a593Smuzhiyun * Get BF Resource for SU/MU Sounding
846*4882a593Smuzhiyun * @phl_info: phl_info_t
847*4882a593Smuzhiyun * @grp: (struct phl_sound_grp *) sounding gorup
848*4882a593Smuzhiyun * @nsta: return value : how many sta query bf resource success
849*4882a593Smuzhiyun **/
850*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_proc_get_res_bf(struct phl_info_t * phl_info,struct phl_snd_grp * grp,u8 * nsta)851*4882a593Smuzhiyun _phl_snd_proc_get_res_bf(
852*4882a593Smuzhiyun struct phl_info_t *phl_info, struct phl_snd_grp *grp, u8 *nsta)
853*4882a593Smuzhiyun {
854*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
855*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
856*4882a593Smuzhiyun struct phl_snd_sta *snd_sta;
857*4882a593Smuzhiyun u8 idx = 0;
858*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta = NULL;
859*4882a593Smuzhiyun bool mu, qry_bf;
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun *nsta = 0;
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun for (idx = 0; idx < grp->num_sta; idx++) {
864*4882a593Smuzhiyun snd_sta = &grp->sta[idx];
865*4882a593Smuzhiyun sta = rtw_phl_get_stainfo_by_macid(phl_info, snd_sta->macid);
866*4882a593Smuzhiyun if (NULL == sta) {
867*4882a593Smuzhiyun PHL_ERR("phl_snd_proc_get_bf_res: Cannot find STA macid 0x%x in PHL STA Info List \n",
868*4882a593Smuzhiyun snd_sta->macid);
869*4882a593Smuzhiyun continue;
870*4882a593Smuzhiyun }
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun mu = (snd_sta->snd_fb_t == PHL_SND_FB_TYPE_MU) ? true:false;
873*4882a593Smuzhiyun qry_bf = false;
874*4882a593Smuzhiyun if (sta->hal_sta->bf_entry != NULL) {
875*4882a593Smuzhiyun /* The sta already have BF reource */
876*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, " sta->bf_entry != NULL\n");
877*4882a593Smuzhiyun /* Check the BF resource */
878*4882a593Smuzhiyun hstatus = rtw_hal_snd_chk_bf_res(phl_info->hal,
879*4882a593Smuzhiyun sta, mu, sta->chandef.bw);
880*4882a593Smuzhiyun if (RTW_HAL_STATUS_FAILURE == hstatus) {
881*4882a593Smuzhiyun rtw_hal_snd_release_proc_sta_res(phl_info->hal,
882*4882a593Smuzhiyun sta);
883*4882a593Smuzhiyun qry_bf = true;
884*4882a593Smuzhiyun
885*4882a593Smuzhiyun } else {
886*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "Use Original BF Resource \n");
887*4882a593Smuzhiyun qry_bf = false;
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun } else {
890*4882a593Smuzhiyun qry_bf = true;
891*4882a593Smuzhiyun }
892*4882a593Smuzhiyun
893*4882a593Smuzhiyun if (true == qry_bf) {
894*4882a593Smuzhiyun hstatus = rtw_hal_snd_query_proc_sta_res(
895*4882a593Smuzhiyun phl_info->hal, sta, mu, sta->chandef.bw,
896*4882a593Smuzhiyun grp->en_swap_mode);
897*4882a593Smuzhiyun if (hstatus != RTW_HAL_STATUS_SUCCESS) {
898*4882a593Smuzhiyun PHL_ERR("phl_snd_proc_get_bf_res: macid 0x%x query sounding resource FAIL \n",
899*4882a593Smuzhiyun snd_sta->macid);
900*4882a593Smuzhiyun if (grp->en_swap_mode) {
901*4882a593Smuzhiyun break;/* break in swap mode if one of sta query bf res fail */
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun continue;
904*4882a593Smuzhiyun }
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun if (grp->snd_type >= PHL_SND_TYPE_HE_HW) {
907*4882a593Smuzhiyun rtw_hal_snd_ndpa_sta_info_he(
908*4882a593Smuzhiyun sta,
909*4882a593Smuzhiyun &snd_sta->npda_sta_info,
910*4882a593Smuzhiyun snd_sta->bw,
911*4882a593Smuzhiyun snd_sta->snd_fb_t);
912*4882a593Smuzhiyun } else {
913*4882a593Smuzhiyun rtw_hal_snd_ndpa_sta_info_vht(sta,
914*4882a593Smuzhiyun &snd_sta->npda_sta_info, mu);
915*4882a593Smuzhiyun }
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun /* Link STA information to Group Information */
918*4882a593Smuzhiyun snd_sta->bf_entry = sta->hal_sta->bf_entry;
919*4882a593Smuzhiyun
920*4882a593Smuzhiyun (*nsta)++;
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun if (*nsta == 0) {
924*4882a593Smuzhiyun grp->snd_sts = PHL_SND_STS_FAILURE;
925*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
926*4882a593Smuzhiyun }
927*4882a593Smuzhiyun if (*nsta != grp->num_sta) {
928*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "FAIL : Sounding STAs is fewer than group sta because of resource!\n");
929*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
930*4882a593Smuzhiyun }
931*4882a593Smuzhiyun
932*4882a593Smuzhiyun return pstatus;
933*4882a593Smuzhiyun }
934*4882a593Smuzhiyun /* snd proc get BF/CSI resource */
935*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_proc_get_res(struct phl_info_t * phl_info,struct phl_snd_grp * grp,u8 * nsta)936*4882a593Smuzhiyun phl_snd_proc_get_res(
937*4882a593Smuzhiyun struct phl_info_t *phl_info, struct phl_snd_grp *grp, u8 *nsta)
938*4882a593Smuzhiyun {
939*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
940*4882a593Smuzhiyun struct phl_snd_sta *snd_sta;
941*4882a593Smuzhiyun FUNCIN_WSTS(pstatus);
942*4882a593Smuzhiyun
943*4882a593Smuzhiyun snd_sta = &grp->sta[0];
944*4882a593Smuzhiyun /* CQI Fb cannot mixed with SU/MU feedback type*/
945*4882a593Smuzhiyun if(snd_sta->snd_fb_t == PHL_SND_FB_TYPE_CQI)
946*4882a593Smuzhiyun pstatus = _phl_snd_proc_get_res_cqi_fb(phl_info, grp, nsta);
947*4882a593Smuzhiyun else
948*4882a593Smuzhiyun pstatus = _phl_snd_proc_get_res_bf(phl_info, grp, nsta);
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun if(pstatus != RTW_PHL_STATUS_SUCCESS)
951*4882a593Smuzhiyun grp->snd_sts = PHL_SND_STS_FAILURE;
952*4882a593Smuzhiyun
953*4882a593Smuzhiyun FUNCOUT_WSTS(pstatus);
954*4882a593Smuzhiyun return pstatus;
955*4882a593Smuzhiyun }
956*4882a593Smuzhiyun
957*4882a593Smuzhiyun /* 2. SND Preconfiguration */
958*4882a593Smuzhiyun
959*4882a593Smuzhiyun /**
960*4882a593Smuzhiyun * _get_mu_mimo_gid_2sta()
961*4882a593Smuzhiyun * hard code for 8852A, gid relattion-ship
962*4882a593Smuzhiyun **/
_get_mu_mimo_gid_2sta(u8 primary,u8 secondary)963*4882a593Smuzhiyun static u8 _get_mu_mimo_gid_2sta(u8 primary, u8 secondary)
964*4882a593Smuzhiyun {
965*4882a593Smuzhiyun u8 gid_tbl[6][6] = { {0xFF, 1, 2, 3, 4, 5},
966*4882a593Smuzhiyun {16, 0xFF, 6, 7, 8, 9},
967*4882a593Smuzhiyun {17, 21, 0xFF, 10, 11, 12},
968*4882a593Smuzhiyun {18, 22, 25, 0xFF, 13, 14},
969*4882a593Smuzhiyun {19, 23, 26, 28, 0xFF, 15},
970*4882a593Smuzhiyun {20, 24, 27, 29, 30, 0xFF} };
971*4882a593Smuzhiyun u8 ret = 0xFF;
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun if ((primary < 6) && (secondary < 6))
974*4882a593Smuzhiyun ret = gid_tbl[primary][secondary];
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun return ret;
977*4882a593Smuzhiyun }
978*4882a593Smuzhiyun /* pre calculate mu-gid */
979*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_cal_mu_grp_bitmap(struct phl_info_t * phl_info,struct phl_snd_grp * grp)980*4882a593Smuzhiyun phl_snd_cal_mu_grp_bitmap(struct phl_info_t *phl_info, struct phl_snd_grp *grp)
981*4882a593Smuzhiyun {
982*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
983*4882a593Smuzhiyun struct rtw_phl_stainfo_t *psta_info = NULL;
984*4882a593Smuzhiyun struct rtw_phl_stainfo_t *tmp_psta_info = NULL;
985*4882a593Smuzhiyun struct phl_snd_sta *sta = NULL;
986*4882a593Smuzhiyun struct phl_snd_sta *tmp_sta = NULL;
987*4882a593Smuzhiyun u8 bfmu_idx , bfmu_idx_tmp;
988*4882a593Smuzhiyun u8 i = 0, j = 0;
989*4882a593Smuzhiyun
990*4882a593Smuzhiyun for (i = 0; i < MAX_NUM_STA_SND_GRP; i++) {
991*4882a593Smuzhiyun sta = &grp->sta[i];
992*4882a593Smuzhiyun if (false == sta->valid)
993*4882a593Smuzhiyun continue;
994*4882a593Smuzhiyun /* primary STA */
995*4882a593Smuzhiyun psta_info = rtw_phl_get_stainfo_by_macid(
996*4882a593Smuzhiyun phl_info, sta->macid);
997*4882a593Smuzhiyun
998*4882a593Smuzhiyun if (NULL == sta->bf_entry)
999*4882a593Smuzhiyun continue;
1000*4882a593Smuzhiyun if (false == rtw_hal_bf_chk_bf_type(phl_info->hal,
1001*4882a593Smuzhiyun psta_info, true)) {
1002*4882a593Smuzhiyun continue; /*BF SU Entry*/
1003*4882a593Smuzhiyun }
1004*4882a593Smuzhiyun /* primary STA MU Entry Idx */
1005*4882a593Smuzhiyun bfmu_idx = rtw_hal_bf_get_sumu_idx(phl_info->hal,
1006*4882a593Smuzhiyun sta->bf_entry);
1007*4882a593Smuzhiyun
1008*4882a593Smuzhiyun psta_info->hal_sta->mugrp_bmp = 0; /* clear first */
1009*4882a593Smuzhiyun
1010*4882a593Smuzhiyun for (j = 0; j < MAX_NUM_STA_SND_GRP; j++) {
1011*4882a593Smuzhiyun if (j == i) /* self */
1012*4882a593Smuzhiyun continue;
1013*4882a593Smuzhiyun /* secondary sta */
1014*4882a593Smuzhiyun tmp_sta = &grp->sta[j];
1015*4882a593Smuzhiyun
1016*4882a593Smuzhiyun if (NULL == tmp_sta->bf_entry)
1017*4882a593Smuzhiyun continue;
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun tmp_psta_info = rtw_phl_get_stainfo_by_macid(
1020*4882a593Smuzhiyun phl_info, tmp_sta->macid);
1021*4882a593Smuzhiyun
1022*4882a593Smuzhiyun if (false == rtw_hal_bf_chk_bf_type(phl_info->hal,
1023*4882a593Smuzhiyun tmp_psta_info, true)) {
1024*4882a593Smuzhiyun continue; /* BF SU Entry */
1025*4882a593Smuzhiyun }
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun /* secondary sta MU Entry Idx */
1028*4882a593Smuzhiyun bfmu_idx_tmp = rtw_hal_bf_get_sumu_idx(phl_info->hal,
1029*4882a593Smuzhiyun tmp_sta->bf_entry);
1030*4882a593Smuzhiyun
1031*4882a593Smuzhiyun /* Default set group bit enable = 1 */
1032*4882a593Smuzhiyun /* grp bitmap doesn't include self */
1033*4882a593Smuzhiyun /** BIT 0 1 2 3 4
1034*4882a593Smuzhiyun * MU_0 : MU_1 MU_2 MU_3 MU_4 MU_5
1035*4882a593Smuzhiyun * MU_1 : MU_0 MU_2 MU_3 MU_4 MU_5
1036*4882a593Smuzhiyun * MU_2 : MU_0 MU_1 MU_3 MU_4 MU_5
1037*4882a593Smuzhiyun * ...
1038*4882a593Smuzhiyun * MU_5 : MU_0 MU_1 MU_2 MU_3 MU_4
1039*4882a593Smuzhiyun **/
1040*4882a593Smuzhiyun
1041*4882a593Smuzhiyun if (bfmu_idx_tmp > bfmu_idx) {
1042*4882a593Smuzhiyun psta_info->hal_sta->mugrp_bmp |=
1043*4882a593Smuzhiyun BIT(bfmu_idx_tmp - 1);
1044*4882a593Smuzhiyun } else {
1045*4882a593Smuzhiyun psta_info->hal_sta->mugrp_bmp |=
1046*4882a593Smuzhiyun BIT(bfmu_idx_tmp);
1047*4882a593Smuzhiyun }
1048*4882a593Smuzhiyun }
1049*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "sta(macid = 0x%x) mugrp_bmp = 0x%x \n",
1050*4882a593Smuzhiyun psta_info->macid, psta_info->hal_sta->mugrp_bmp);
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun
1053*4882a593Smuzhiyun return pstatus;
1054*4882a593Smuzhiyun }
1055*4882a593Smuzhiyun
1056*4882a593Smuzhiyun /* Preconfiguration before souding */
1057*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_proc_precfg(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1058*4882a593Smuzhiyun phl_snd_proc_precfg(struct phl_info_t *phl_info, struct phl_snd_grp *grp)
1059*4882a593Smuzhiyun {
1060*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1061*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1062*4882a593Smuzhiyun struct phl_snd_sta *sta = NULL;
1063*4882a593Smuzhiyun u8 idx = 0;
1064*4882a593Smuzhiyun struct rtw_phl_stainfo_t *psta_info = NULL;
1065*4882a593Smuzhiyun FUNCIN_WSTS(pstatus);
1066*4882a593Smuzhiyun do {
1067*4882a593Smuzhiyun if (grp == NULL) {
1068*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1069*4882a593Smuzhiyun break;
1070*4882a593Smuzhiyun }
1071*4882a593Smuzhiyun if (PHL_SND_TYPE_INVALID == grp->snd_type) {
1072*4882a593Smuzhiyun /* both SW/HW mode need to set call halmac api to set bf entry */
1073*4882a593Smuzhiyun break;
1074*4882a593Smuzhiyun }
1075*4882a593Smuzhiyun for (idx = 0; idx < MAX_NUM_STA_SND_GRP; idx++) {
1076*4882a593Smuzhiyun sta = &grp->sta[idx];
1077*4882a593Smuzhiyun if (false == sta->valid)
1078*4882a593Smuzhiyun continue;
1079*4882a593Smuzhiyun psta_info = rtw_phl_get_stainfo_by_macid(
1080*4882a593Smuzhiyun phl_info, sta->macid);
1081*4882a593Smuzhiyun
1082*4882a593Smuzhiyun /*check bf entry available and snd_fb_type = SU/MU */
1083*4882a593Smuzhiyun if ((NULL != psta_info->hal_sta->bf_entry) &&
1084*4882a593Smuzhiyun (PHL_SND_FB_TYPE_CQI != sta->snd_fb_t)) {
1085*4882a593Smuzhiyun
1086*4882a593Smuzhiyun hstatus = rtw_hal_snd_proc_pre_cfg_sta(
1087*4882a593Smuzhiyun phl_info->hal, psta_info);
1088*4882a593Smuzhiyun
1089*4882a593Smuzhiyun if (hstatus != RTW_HAL_STATUS_SUCCESS) {
1090*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1091*4882a593Smuzhiyun }
1092*4882a593Smuzhiyun }
1093*4882a593Smuzhiyun }
1094*4882a593Smuzhiyun /* Prepare Group bitmap for Tx MU-MIMO */
1095*4882a593Smuzhiyun if (PHL_SND_FB_TYPE_MU == grp->sta[0].snd_fb_t)
1096*4882a593Smuzhiyun pstatus = phl_snd_cal_mu_grp_bitmap(phl_info, grp);
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun } while (0);
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun
1101*4882a593Smuzhiyun if(pstatus != RTW_PHL_STATUS_SUCCESS)
1102*4882a593Smuzhiyun grp->snd_sts = PHL_SND_STS_FAILURE;
1103*4882a593Smuzhiyun FUNCOUT_WSTS(pstatus);
1104*4882a593Smuzhiyun return pstatus;
1105*4882a593Smuzhiyun }
1106*4882a593Smuzhiyun /* 3. Send Sounding Command to HAL/FW */
1107*4882a593Smuzhiyun /*TODO: RU Allocation is now hard code value */
1108*4882a593Smuzhiyun /* HE TB Sounding : 2 sta in a grp */
1109*4882a593Smuzhiyun void
_phl_snd_proc_fw_cmd_he_tb_2sta(struct phl_info_t * phl_info,struct phl_snd_grp * grp,u8 * cmd,u8 bfrp_num)1110*4882a593Smuzhiyun _phl_snd_proc_fw_cmd_he_tb_2sta(struct phl_info_t *phl_info,
1111*4882a593Smuzhiyun struct phl_snd_grp *grp,
1112*4882a593Smuzhiyun u8 *cmd, u8 bfrp_num)
1113*4882a593Smuzhiyun {
1114*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
1115*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta_info = NULL;
1116*4882a593Smuzhiyun u8 *f_ru_tbl = NULL;
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun if (grp->num_sta != 2)
1119*4882a593Smuzhiyun return;
1120*4882a593Smuzhiyun /* get first sta */
1121*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[0].macid);
1122*4882a593Smuzhiyun
1123*4882a593Smuzhiyun if (bfrp_num == 1) {
1124*4882a593Smuzhiyun if (CHANNEL_WIDTH_20 == grp->sta[0].bw)
1125*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_20[1][0];/* Fixed 20MHz RU Table of 2 STA */
1126*4882a593Smuzhiyun else
1127*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_80[1][0];/* Fixed 80MHz RU Table of 2 STA */
1128*4882a593Smuzhiyun } else {
1129*4882a593Smuzhiyun if (CHANNEL_WIDTH_20 == grp->sta[0].bw)
1130*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_20[0][0];/* Fixed 20MHz RU Table of 1 STA */
1131*4882a593Smuzhiyun else
1132*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_80[0][0];/* Fixed 80MHz RU Table of 1 STA */
1133*4882a593Smuzhiyun }
1134*4882a593Smuzhiyun
1135*4882a593Smuzhiyun /* fill commmand */
1136*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_pri(phl_info->hal, cmd, grp->sta[0].bw,
1137*4882a593Smuzhiyun sta_info, grp->num_sta, 0);
1138*4882a593Smuzhiyun /* Always use BFRP#0 for primary user */
1139*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1140*4882a593Smuzhiyun phl_info->hal, cmd,
1141*4882a593Smuzhiyun &grp->sta[0].npda_sta_info,
1142*4882a593Smuzhiyun sta_info,
1143*4882a593Smuzhiyun f_ru_tbl[0],
1144*4882a593Smuzhiyun 0,
1145*4882a593Smuzhiyun 0,
1146*4882a593Smuzhiyun 0);
1147*4882a593Smuzhiyun
1148*4882a593Smuzhiyun /*get second sta*/
1149*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[1].macid);
1150*4882a593Smuzhiyun
1151*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1152*4882a593Smuzhiyun phl_info->hal, cmd,
1153*4882a593Smuzhiyun &grp->sta[1].npda_sta_info,
1154*4882a593Smuzhiyun sta_info,
1155*4882a593Smuzhiyun f_ru_tbl[1],
1156*4882a593Smuzhiyun 1,
1157*4882a593Smuzhiyun (bfrp_num == 1) ? 0 : 1,
1158*4882a593Smuzhiyun (bfrp_num == 1) ? 1 : 0);
1159*4882a593Smuzhiyun
1160*4882a593Smuzhiyun }
1161*4882a593Smuzhiyun
1162*4882a593Smuzhiyun /* HE TB Sounding : 3 sta in a grp */
1163*4882a593Smuzhiyun void
_phl_snd_proc_fw_cmd_he_tb_3sta(struct phl_info_t * phl_info,struct phl_snd_grp * grp,u8 * cmd,u8 bfrp_num)1164*4882a593Smuzhiyun _phl_snd_proc_fw_cmd_he_tb_3sta(struct phl_info_t *phl_info,
1165*4882a593Smuzhiyun struct phl_snd_grp *grp,
1166*4882a593Smuzhiyun u8 *cmd, u8 bfrp_num)
1167*4882a593Smuzhiyun {
1168*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
1169*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta_info = NULL;
1170*4882a593Smuzhiyun u8 *f_ru_tbl = NULL;
1171*4882a593Smuzhiyun
1172*4882a593Smuzhiyun if(grp->num_sta != 3)
1173*4882a593Smuzhiyun return;
1174*4882a593Smuzhiyun /* get first sta */
1175*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[0].macid);
1176*4882a593Smuzhiyun
1177*4882a593Smuzhiyun if (bfrp_num == 1) {
1178*4882a593Smuzhiyun if (CHANNEL_WIDTH_20 == grp->sta[0].bw)
1179*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_20[2][0];/* Fixed 20MHz RU Table of 3 STA */
1180*4882a593Smuzhiyun else
1181*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_80[2][0];/* Fixed 80MHz RU Table of 3 STA */
1182*4882a593Smuzhiyun } else {
1183*4882a593Smuzhiyun if (CHANNEL_WIDTH_20 == grp->sta[0].bw)
1184*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_20[1][0];/* Fixed 20MHz RU Table of 2 STA */
1185*4882a593Smuzhiyun else
1186*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_80[1][0];/* Fixed 80MHz RU Table of 2 STA */
1187*4882a593Smuzhiyun }
1188*4882a593Smuzhiyun
1189*4882a593Smuzhiyun /* fill commmand */
1190*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_pri(phl_info->hal, cmd, grp->sta[0].bw,
1191*4882a593Smuzhiyun sta_info, grp->num_sta, 0);
1192*4882a593Smuzhiyun /* Always use BFRP#0 for primary user */
1193*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1194*4882a593Smuzhiyun phl_info->hal, cmd,
1195*4882a593Smuzhiyun &grp->sta[0].npda_sta_info,
1196*4882a593Smuzhiyun sta_info,
1197*4882a593Smuzhiyun f_ru_tbl[0],
1198*4882a593Smuzhiyun 0,
1199*4882a593Smuzhiyun 0,
1200*4882a593Smuzhiyun 0);
1201*4882a593Smuzhiyun
1202*4882a593Smuzhiyun /*get second sta*/
1203*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[1].macid);
1204*4882a593Smuzhiyun
1205*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1206*4882a593Smuzhiyun phl_info->hal, cmd,
1207*4882a593Smuzhiyun &grp->sta[1].npda_sta_info,
1208*4882a593Smuzhiyun sta_info,
1209*4882a593Smuzhiyun f_ru_tbl[1],
1210*4882a593Smuzhiyun 1,
1211*4882a593Smuzhiyun 0,
1212*4882a593Smuzhiyun 1);
1213*4882a593Smuzhiyun /*get third sta*/
1214*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[2].macid);
1215*4882a593Smuzhiyun
1216*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1217*4882a593Smuzhiyun phl_info->hal, cmd,
1218*4882a593Smuzhiyun &grp->sta[2].npda_sta_info,
1219*4882a593Smuzhiyun sta_info,
1220*4882a593Smuzhiyun f_ru_tbl[2],
1221*4882a593Smuzhiyun 2,
1222*4882a593Smuzhiyun (bfrp_num == 1) ? 0 : 1,
1223*4882a593Smuzhiyun (bfrp_num == 1) ? 2 : 0);
1224*4882a593Smuzhiyun
1225*4882a593Smuzhiyun }
1226*4882a593Smuzhiyun
1227*4882a593Smuzhiyun /* HE TB Sounding : 4 sta in a grp */
1228*4882a593Smuzhiyun void
_phl_snd_proc_fw_cmd_he_tb_4sta(struct phl_info_t * phl_info,struct phl_snd_grp * grp,u8 * cmd,u8 bfrp_num)1229*4882a593Smuzhiyun _phl_snd_proc_fw_cmd_he_tb_4sta(struct phl_info_t *phl_info,
1230*4882a593Smuzhiyun struct phl_snd_grp *grp,
1231*4882a593Smuzhiyun u8 *cmd, u8 bfrp_num)
1232*4882a593Smuzhiyun {
1233*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
1234*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta_info = NULL;
1235*4882a593Smuzhiyun u8 *f_ru_tbl = NULL;
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun if(grp->num_sta != 4)
1238*4882a593Smuzhiyun return;
1239*4882a593Smuzhiyun /* get first sta */
1240*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[0].macid);
1241*4882a593Smuzhiyun
1242*4882a593Smuzhiyun if (bfrp_num == 1) {
1243*4882a593Smuzhiyun if (CHANNEL_WIDTH_20 == grp->sta[0].bw)
1244*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_20[3][0];/* Fixed 20MHz RU Table of 4 STA */
1245*4882a593Smuzhiyun else
1246*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_80[3][0];/* Fixed 80MHz RU Table of 4 STA */
1247*4882a593Smuzhiyun } else {
1248*4882a593Smuzhiyun if (CHANNEL_WIDTH_20 == grp->sta[0].bw)
1249*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_20[1][0];/* Fixed 20MHz RU Table of 2 STA */
1250*4882a593Smuzhiyun else
1251*4882a593Smuzhiyun f_ru_tbl = &snd->snd_param.fix_param.f_ru_tbl_80[1][0];/* Fixed 80MHz RU Table of 2 STA */
1252*4882a593Smuzhiyun }
1253*4882a593Smuzhiyun
1254*4882a593Smuzhiyun /* fill commmand */
1255*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_pri(phl_info->hal, cmd, grp->sta[0].bw,
1256*4882a593Smuzhiyun sta_info, grp->num_sta, 0);
1257*4882a593Smuzhiyun /* Always use BFRP#0 for primary user */
1258*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1259*4882a593Smuzhiyun phl_info->hal, cmd,
1260*4882a593Smuzhiyun &grp->sta[0].npda_sta_info,
1261*4882a593Smuzhiyun sta_info,
1262*4882a593Smuzhiyun f_ru_tbl[0],
1263*4882a593Smuzhiyun 0,
1264*4882a593Smuzhiyun 0,
1265*4882a593Smuzhiyun 0);
1266*4882a593Smuzhiyun
1267*4882a593Smuzhiyun /*get second sta*/
1268*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[1].macid);
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1271*4882a593Smuzhiyun phl_info->hal, cmd,
1272*4882a593Smuzhiyun &grp->sta[1].npda_sta_info,
1273*4882a593Smuzhiyun sta_info,
1274*4882a593Smuzhiyun f_ru_tbl[1],
1275*4882a593Smuzhiyun 1,
1276*4882a593Smuzhiyun (bfrp_num == 1) ? 0 : 0,
1277*4882a593Smuzhiyun (bfrp_num == 1) ? 1 : 1);
1278*4882a593Smuzhiyun /*get third sta*/
1279*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[2].macid);
1280*4882a593Smuzhiyun
1281*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1282*4882a593Smuzhiyun phl_info->hal, cmd,
1283*4882a593Smuzhiyun &grp->sta[2].npda_sta_info,
1284*4882a593Smuzhiyun sta_info,
1285*4882a593Smuzhiyun f_ru_tbl[2],
1286*4882a593Smuzhiyun 2,
1287*4882a593Smuzhiyun (bfrp_num == 1) ? 0 : 1,
1288*4882a593Smuzhiyun (bfrp_num == 1) ? 2 : 0);
1289*4882a593Smuzhiyun
1290*4882a593Smuzhiyun /*get 4th sta*/
1291*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[3].macid);
1292*4882a593Smuzhiyun
1293*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_tb_add_sta(
1294*4882a593Smuzhiyun phl_info->hal, cmd,
1295*4882a593Smuzhiyun &grp->sta[3].npda_sta_info,
1296*4882a593Smuzhiyun sta_info,
1297*4882a593Smuzhiyun f_ru_tbl[3],
1298*4882a593Smuzhiyun 3,
1299*4882a593Smuzhiyun (bfrp_num == 1) ? 0 : 1,
1300*4882a593Smuzhiyun (bfrp_num == 1) ? 3 : 1);
1301*4882a593Smuzhiyun
1302*4882a593Smuzhiyun }
1303*4882a593Smuzhiyun
1304*4882a593Smuzhiyun
1305*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_proc_start_sounding_fw(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1306*4882a593Smuzhiyun phl_snd_proc_start_sounding_fw(struct phl_info_t *phl_info,
1307*4882a593Smuzhiyun struct phl_snd_grp *grp)
1308*4882a593Smuzhiyun {
1309*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1310*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_FAILURE;
1311*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
1312*4882a593Smuzhiyun struct phl_sound_param *snd_param = &snd->snd_param;
1313*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta_info = NULL;
1314*4882a593Smuzhiyun u8 *cmd = NULL;
1315*4882a593Smuzhiyun u8 i = 0;
1316*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "==> phl_snd_proc_start_sounding_fw \n");
1317*4882a593Smuzhiyun do {
1318*4882a593Smuzhiyun if (NULL == grp)
1319*4882a593Smuzhiyun break;
1320*4882a593Smuzhiyun if(grp->sta[0].valid == 0)
1321*4882a593Smuzhiyun break;
1322*4882a593Smuzhiyun
1323*4882a593Smuzhiyun /*get first sta*/
1324*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(
1325*4882a593Smuzhiyun phl_info, grp->sta[0].macid);
1326*4882a593Smuzhiyun
1327*4882a593Smuzhiyun switch (grp->snd_type) {
1328*4882a593Smuzhiyun case PHL_SND_TYPE_VHT_SW:
1329*4882a593Smuzhiyun {
1330*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "--> PHL_SND_TYPE_VHT_SW\n");
1331*4882a593Smuzhiyun cmd = rtw_hal_snd_prepare_snd_cmd(phl_info->hal);
1332*4882a593Smuzhiyun if (cmd == NULL)
1333*4882a593Smuzhiyun break;
1334*4882a593Smuzhiyun if (grp->num_sta == 1) {
1335*4882a593Smuzhiyun rtw_hal_snd_vht_fwcmd_su(
1336*4882a593Smuzhiyun phl_info->hal, cmd,
1337*4882a593Smuzhiyun grp->sta[0].bw,
1338*4882a593Smuzhiyun sta_info,
1339*4882a593Smuzhiyun &grp->sta[0].npda_sta_info);
1340*4882a593Smuzhiyun
1341*4882a593Smuzhiyun } else {
1342*4882a593Smuzhiyun rtw_hal_snd_vht_fwcmd_mu_pri(
1343*4882a593Smuzhiyun phl_info->hal, cmd,
1344*4882a593Smuzhiyun grp->sta[0].bw,
1345*4882a593Smuzhiyun sta_info,
1346*4882a593Smuzhiyun grp->num_sta,
1347*4882a593Smuzhiyun &grp->sta[0].npda_sta_info);
1348*4882a593Smuzhiyun
1349*4882a593Smuzhiyun for (i = 1; i < grp->num_sta; i++) {
1350*4882a593Smuzhiyun if(grp->sta[i].valid == 0)
1351*4882a593Smuzhiyun break;
1352*4882a593Smuzhiyun sta_info = rtw_phl_get_stainfo_by_macid(
1353*4882a593Smuzhiyun phl_info, grp->sta[i].macid);
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun rtw_hal_snd_vht_fwcmd_mu_add_sta(
1356*4882a593Smuzhiyun phl_info->hal, cmd,
1357*4882a593Smuzhiyun &grp->sta[i].npda_sta_info,
1358*4882a593Smuzhiyun sta_info,
1359*4882a593Smuzhiyun i,
1360*4882a593Smuzhiyun (i==(grp->num_sta-1)) ? 1 : 0
1361*4882a593Smuzhiyun );
1362*4882a593Smuzhiyun }
1363*4882a593Smuzhiyun }
1364*4882a593Smuzhiyun rtw_hal_snd_set_fw_cmd_dialogtkn(
1365*4882a593Smuzhiyun phl_info->hal, cmd,
1366*4882a593Smuzhiyun 0,
1367*4882a593Smuzhiyun snd_param->snd_dialog_token);
1368*4882a593Smuzhiyun hstatus = rtw_hal_snd_send_fw_cmd(phl_info->hal, cmd);
1369*4882a593Smuzhiyun if (hstatus != RTW_HAL_STATUS_SUCCESS) {
1370*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
1371*4882a593Smuzhiyun "ERROR: rtw_hal_snd_send_fw_cmd Fail!!!!\n");
1372*4882a593Smuzhiyun }
1373*4882a593Smuzhiyun /* free cmd buf at last !!! */
1374*4882a593Smuzhiyun hstatus = rtw_hal_snd_release_snd_cmd(phl_info->hal, cmd);
1375*4882a593Smuzhiyun }
1376*4882a593Smuzhiyun break;
1377*4882a593Smuzhiyun case PHL_SND_TYPE_HE_SW:
1378*4882a593Smuzhiyun {
1379*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "--> PHL_SND_TYPE_HE_SW\n");
1380*4882a593Smuzhiyun cmd = rtw_hal_snd_prepare_snd_cmd(phl_info->hal);
1381*4882a593Smuzhiyun if (cmd == NULL)
1382*4882a593Smuzhiyun break;
1383*4882a593Smuzhiyun if (grp->num_sta == 1) {
1384*4882a593Smuzhiyun rtw_hal_snd_ax_fwcmd_nontb(
1385*4882a593Smuzhiyun phl_info->hal, cmd,
1386*4882a593Smuzhiyun grp->sta[0].bw,
1387*4882a593Smuzhiyun sta_info,
1388*4882a593Smuzhiyun &grp->sta[0].npda_sta_info);
1389*4882a593Smuzhiyun } else {
1390*4882a593Smuzhiyun /* Default use only 1 BFRP */
1391*4882a593Smuzhiyun /* TODO: Fixed mode or when to use 2 BFRP */
1392*4882a593Smuzhiyun if (grp->num_sta == 4)
1393*4882a593Smuzhiyun _phl_snd_proc_fw_cmd_he_tb_4sta(
1394*4882a593Smuzhiyun phl_info, grp, cmd, 1);
1395*4882a593Smuzhiyun else if (grp->num_sta == 3)
1396*4882a593Smuzhiyun _phl_snd_proc_fw_cmd_he_tb_3sta(
1397*4882a593Smuzhiyun phl_info, grp, cmd, 1);
1398*4882a593Smuzhiyun else if (grp->num_sta == 2)
1399*4882a593Smuzhiyun _phl_snd_proc_fw_cmd_he_tb_2sta(
1400*4882a593Smuzhiyun phl_info, grp, cmd, 1);
1401*4882a593Smuzhiyun else
1402*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "phl sounding : 1 sta with HE-TB case is NOT Ready ; need add fake sta into NDPA\n");
1403*4882a593Smuzhiyun }
1404*4882a593Smuzhiyun rtw_hal_snd_set_fw_cmd_dialogtkn(
1405*4882a593Smuzhiyun phl_info->hal, cmd,
1406*4882a593Smuzhiyun 1,
1407*4882a593Smuzhiyun snd_param->snd_dialog_token);
1408*4882a593Smuzhiyun
1409*4882a593Smuzhiyun hstatus = rtw_hal_snd_send_fw_cmd(phl_info->hal, cmd);
1410*4882a593Smuzhiyun if (hstatus != RTW_HAL_STATUS_SUCCESS) {
1411*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
1412*4882a593Smuzhiyun "ERROR: rtw_hal_snd_send_fw_cmd Fail!!!!\n");
1413*4882a593Smuzhiyun }
1414*4882a593Smuzhiyun /* free cmd buf at last !!! */
1415*4882a593Smuzhiyun hstatus = rtw_hal_snd_release_snd_cmd(phl_info->hal, cmd);
1416*4882a593Smuzhiyun }
1417*4882a593Smuzhiyun break;
1418*4882a593Smuzhiyun case PHL_SND_TYPE_VHT_HW:
1419*4882a593Smuzhiyun {
1420*4882a593Smuzhiyun u8 dialog_tkn = (snd->snd_param.snd_dialog_token << 2);
1421*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
1422*4882a593Smuzhiyun "PHL_SND_TYPE_VHT_HW:\n");
1423*4882a593Smuzhiyun if(NULL == snd->ops.snd_send_ndpa)
1424*4882a593Smuzhiyun break;
1425*4882a593Smuzhiyun rtw_hal_snd_mac_ctrl(phl_info->hal, sta_info->wrole->hw_band, 0);
1426*4882a593Smuzhiyun pstatus = snd->ops.snd_send_ndpa(
1427*4882a593Smuzhiyun phl_to_drvpriv(phl_info),
1428*4882a593Smuzhiyun sta_info->wrole,
1429*4882a593Smuzhiyun &dialog_tkn,
1430*4882a593Smuzhiyun &grp->sta[0].npda_sta_info,
1431*4882a593Smuzhiyun grp->sta[0].bw);
1432*4882a593Smuzhiyun }
1433*4882a593Smuzhiyun break;
1434*4882a593Smuzhiyun case PHL_SND_TYPE_HE_HW:
1435*4882a593Smuzhiyun {
1436*4882a593Smuzhiyun u8 dialog_tkn = (snd->snd_param.snd_dialog_token << 2) | BIT(1);
1437*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
1438*4882a593Smuzhiyun "PHL_SND_TYPE_HE_HW:\n");
1439*4882a593Smuzhiyun if(NULL == snd->ops.snd_send_ndpa)
1440*4882a593Smuzhiyun break;
1441*4882a593Smuzhiyun rtw_hal_snd_mac_ctrl(phl_info->hal, sta_info->wrole->hw_band, 0);
1442*4882a593Smuzhiyun pstatus = snd->ops.snd_send_ndpa(
1443*4882a593Smuzhiyun phl_to_drvpriv(phl_info),
1444*4882a593Smuzhiyun sta_info->wrole,
1445*4882a593Smuzhiyun &dialog_tkn,
1446*4882a593Smuzhiyun &grp->sta[0].npda_sta_info,
1447*4882a593Smuzhiyun grp->sta[0].bw);
1448*4882a593Smuzhiyun }
1449*4882a593Smuzhiyun break;
1450*4882a593Smuzhiyun case PHL_SND_TYPE_INVALID:
1451*4882a593Smuzhiyun default:
1452*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "ERROR: grp->snd_type invalid\n");
1453*4882a593Smuzhiyun break;
1454*4882a593Smuzhiyun }
1455*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_SUCCESS;
1456*4882a593Smuzhiyun } while (0);
1457*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "<== phl_snd_proc_start_sounding_fw \n");
1458*4882a593Smuzhiyun return pstatus;
1459*4882a593Smuzhiyun }
1460*4882a593Smuzhiyun
1461*4882a593Smuzhiyun /* 4. Post Configruation */
1462*4882a593Smuzhiyun
1463*4882a593Smuzhiyun /* BY MU_GID if MU Sounding */
1464*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_proc_postcfg_mu_gid(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1465*4882a593Smuzhiyun _phl_snd_proc_postcfg_mu_gid(struct phl_info_t *phl_info,
1466*4882a593Smuzhiyun struct phl_snd_grp *grp)
1467*4882a593Smuzhiyun {
1468*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1469*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1470*4882a593Smuzhiyun struct rtw_phl_stainfo_t *psta_info = NULL;
1471*4882a593Smuzhiyun struct phl_snd_sta *sta = NULL;
1472*4882a593Smuzhiyun struct rtw_hal_muba_info ba_info;
1473*4882a593Smuzhiyun u8 i = 0, j = 0;
1474*4882a593Smuzhiyun u8 bfmu_idx;
1475*4882a593Smuzhiyun u8 mugrp_bmp = 0;
1476*4882a593Smuzhiyun u8 gid = 0xFF;
1477*4882a593Smuzhiyun
1478*4882a593Smuzhiyun
1479*4882a593Smuzhiyun for (i = 0; i < MAX_NUM_STA_SND_GRP; i++) {
1480*4882a593Smuzhiyun sta = &grp->sta[i];
1481*4882a593Smuzhiyun if((false == sta->valid) || (NULL == sta->bf_entry))
1482*4882a593Smuzhiyun continue;
1483*4882a593Smuzhiyun
1484*4882a593Smuzhiyun bfmu_idx = rtw_hal_bf_get_sumu_idx(phl_info->hal,
1485*4882a593Smuzhiyun sta->bf_entry);
1486*4882a593Smuzhiyun
1487*4882a593Smuzhiyun psta_info = rtw_phl_get_stainfo_by_macid(
1488*4882a593Smuzhiyun phl_info, sta->macid);
1489*4882a593Smuzhiyun
1490*4882a593Smuzhiyun mugrp_bmp = psta_info->hal_sta->mugrp_bmp;
1491*4882a593Smuzhiyun
1492*4882a593Smuzhiyun /* GID(X + Y)'s setting is same as GID(Y + X)*/
1493*4882a593Smuzhiyun for (j = bfmu_idx; j < 5; j++) {
1494*4882a593Smuzhiyun if (mugrp_bmp & BIT(j)) {
1495*4882a593Smuzhiyun gid = _get_mu_mimo_gid_2sta(bfmu_idx, j + 1);
1496*4882a593Smuzhiyun /*Prepare MU BAR Info*/
1497*4882a593Smuzhiyun rtw_hal_bf_preset_mu_ba_info(phl_info->hal,
1498*4882a593Smuzhiyun psta_info, &ba_info);
1499*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "snd_post_cfg : gid = 0x%x \n", gid);
1500*4882a593Smuzhiyun hstatus = rtw_hal_snd_proc_post_cfg_gid(
1501*4882a593Smuzhiyun phl_info->hal,
1502*4882a593Smuzhiyun gid,
1503*4882a593Smuzhiyun (void *)&ba_info);
1504*4882a593Smuzhiyun
1505*4882a593Smuzhiyun if (RTW_HAL_STATUS_SUCCESS != hstatus) {
1506*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1507*4882a593Smuzhiyun }
1508*4882a593Smuzhiyun }
1509*4882a593Smuzhiyun }
1510*4882a593Smuzhiyun }
1511*4882a593Smuzhiyun
1512*4882a593Smuzhiyun return pstatus;
1513*4882a593Smuzhiyun }
1514*4882a593Smuzhiyun /* Per STA setting */
1515*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_proc_postcfg_sta(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1516*4882a593Smuzhiyun _phl_snd_proc_postcfg_sta(struct phl_info_t *phl_info,
1517*4882a593Smuzhiyun struct phl_snd_grp *grp)
1518*4882a593Smuzhiyun {
1519*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1520*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1521*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
1522*4882a593Smuzhiyun struct rtw_phl_stainfo_t *psta_info = NULL;
1523*4882a593Smuzhiyun struct phl_snd_sta *sta = NULL;
1524*4882a593Smuzhiyun u8 idx = 0;
1525*4882a593Smuzhiyun bool mu = false;
1526*4882a593Smuzhiyun
1527*4882a593Smuzhiyun /*post config for a single sta*/
1528*4882a593Smuzhiyun for (idx = 0; idx < MAX_NUM_STA_SND_GRP; idx++) {
1529*4882a593Smuzhiyun sta = &grp->sta[idx];
1530*4882a593Smuzhiyun mu = (sta->snd_fb_t == PHL_SND_FB_TYPE_MU) ? true : false;
1531*4882a593Smuzhiyun if (false == sta->valid)
1532*4882a593Smuzhiyun continue;
1533*4882a593Smuzhiyun
1534*4882a593Smuzhiyun psta_info = rtw_phl_get_stainfo_by_macid(phl_info, sta->macid);
1535*4882a593Smuzhiyun if (NULL == psta_info)
1536*4882a593Smuzhiyun continue;
1537*4882a593Smuzhiyun
1538*4882a593Smuzhiyun rtw_hal_snd_polling_snd_sts(phl_info->hal, psta_info);
1539*4882a593Smuzhiyun if (RTW_HAL_STATUS_SUCCESS ==
1540*4882a593Smuzhiyun rtw_hal_bf_get_entry_snd_sts(psta_info->hal_sta->bf_entry)) {
1541*4882a593Smuzhiyun sta->snd_sts = PHL_SND_STS_SUCCESS;
1542*4882a593Smuzhiyun } else {
1543*4882a593Smuzhiyun sta->snd_sts = PHL_SND_STS_FAILURE;
1544*4882a593Smuzhiyun }
1545*4882a593Smuzhiyun
1546*4882a593Smuzhiyun if ((PHL_SND_STS_SUCCESS != sta->snd_sts) &&
1547*4882a593Smuzhiyun (false == snd->snd_param.bypass_snd_sts_chk)) {
1548*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "SKIP STA Post Config because of sounding fail\n");
1549*4882a593Smuzhiyun continue; /*Sounding Fail, Next STA */
1550*4882a593Smuzhiyun }
1551*4882a593Smuzhiyun
1552*4882a593Smuzhiyun hstatus = rtw_hal_snd_proc_post_cfg_sta(phl_info->hal,
1553*4882a593Smuzhiyun psta_info, mu);
1554*4882a593Smuzhiyun
1555*4882a593Smuzhiyun if (hstatus != RTW_HAL_STATUS_SUCCESS) {
1556*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1557*4882a593Smuzhiyun }
1558*4882a593Smuzhiyun }
1559*4882a593Smuzhiyun
1560*4882a593Smuzhiyun return pstatus;
1561*4882a593Smuzhiyun }
1562*4882a593Smuzhiyun /* SND PROC Post Config API for FSM */
1563*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_proc_postcfg(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1564*4882a593Smuzhiyun phl_snd_proc_postcfg(struct phl_info_t *phl_info, struct phl_snd_grp *grp)
1565*4882a593Smuzhiyun {
1566*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1567*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1568*4882a593Smuzhiyun bool mu = false, he = true;
1569*4882a593Smuzhiyun
1570*4882a593Smuzhiyun FUNCIN();
1571*4882a593Smuzhiyun
1572*4882a593Smuzhiyun do {
1573*4882a593Smuzhiyun if (grp == NULL) {
1574*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1575*4882a593Smuzhiyun break;
1576*4882a593Smuzhiyun }
1577*4882a593Smuzhiyun he = (grp->snd_type >= PHL_SND_TYPE_HE_HW) ? true : false;
1578*4882a593Smuzhiyun mu = (grp->sta[0].snd_fb_t == PHL_SND_FB_TYPE_MU) ? true :
1579*4882a593Smuzhiyun false;
1580*4882a593Smuzhiyun
1581*4882a593Smuzhiyun /* 1. post config for whole sounding group */
1582*4882a593Smuzhiyun if (grp->skip_post_cfg & BIT(1)) {
1583*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "SKIP SND PROC POST CFG - Group \n");
1584*4882a593Smuzhiyun } else {
1585*4882a593Smuzhiyun hstatus = rtw_hal_snd_proc_post_cfg(
1586*4882a593Smuzhiyun phl_info->hal,
1587*4882a593Smuzhiyun he,
1588*4882a593Smuzhiyun mu,
1589*4882a593Smuzhiyun grp->en_fix_mode);
1590*4882a593Smuzhiyun if (hstatus != RTW_HAL_STATUS_SUCCESS) {
1591*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1592*4882a593Smuzhiyun }
1593*4882a593Smuzhiyun }
1594*4882a593Smuzhiyun
1595*4882a593Smuzhiyun /* 2. post config for gid (STA + STA) */
1596*4882a593Smuzhiyun if (grp->skip_post_cfg & BIT(2)) {
1597*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "SKIP SND PROC POST CFG - GID \n");
1598*4882a593Smuzhiyun } else {
1599*4882a593Smuzhiyun if (true == mu) {
1600*4882a593Smuzhiyun /* only mu sounding has gid related config */
1601*4882a593Smuzhiyun _phl_snd_proc_postcfg_mu_gid(phl_info, grp);
1602*4882a593Smuzhiyun }
1603*4882a593Smuzhiyun }
1604*4882a593Smuzhiyun
1605*4882a593Smuzhiyun /* 3. (Shall always at last) post config for each STA in group */
1606*4882a593Smuzhiyun if (grp->skip_post_cfg & BIT(3)) {
1607*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "SKIP SND PROC POST CFG - STA \n");
1608*4882a593Smuzhiyun } else {
1609*4882a593Smuzhiyun _phl_snd_proc_postcfg_sta(phl_info, grp);
1610*4882a593Smuzhiyun }
1611*4882a593Smuzhiyun
1612*4882a593Smuzhiyun } while (0);
1613*4882a593Smuzhiyun
1614*4882a593Smuzhiyun FUNCOUT();
1615*4882a593Smuzhiyun return pstatus;
1616*4882a593Smuzhiyun }
1617*4882a593Smuzhiyun
1618*4882a593Smuzhiyun /* SND_PROC_DOWN --> Next Sounding : Check sounding module status */
1619*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_proc_chk_condition(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1620*4882a593Smuzhiyun phl_snd_proc_chk_condition(struct phl_info_t *phl_info, struct phl_snd_grp *grp)
1621*4882a593Smuzhiyun {
1622*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1623*4882a593Smuzhiyun struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
1624*4882a593Smuzhiyun struct rtw_wifi_role_t *role =
1625*4882a593Smuzhiyun (struct rtw_wifi_role_t *)snd->snd_param.m_wrole;
1626*4882a593Smuzhiyun struct phl_snd_sta *sta = NULL;
1627*4882a593Smuzhiyun struct rtw_phl_stainfo_t *psta = NULL;
1628*4882a593Smuzhiyun struct phl_sound_param *para = &snd->snd_param;
1629*4882a593Smuzhiyun u8 i = 0;
1630*4882a593Smuzhiyun u8 terminate = 0;
1631*4882a593Smuzhiyun /* TODO: Add any conditions to stop the sounding fsm here */
1632*4882a593Smuzhiyun do {
1633*4882a593Smuzhiyun if (true == snd->is_terminated)
1634*4882a593Smuzhiyun break;
1635*4882a593Smuzhiyun
1636*4882a593Smuzhiyun if (NULL != role) {
1637*4882a593Smuzhiyun if (PHL_RTYPE_STATION == role->type) {
1638*4882a593Smuzhiyun if (MLME_NO_LINK == role->mstate)
1639*4882a593Smuzhiyun break;
1640*4882a593Smuzhiyun psta = rtw_phl_get_stainfo_self(phl_info, role);
1641*4882a593Smuzhiyun if (rtw_hal_bf_get_entry_snd_sts(
1642*4882a593Smuzhiyun psta->hal_sta->bf_entry)) {
1643*4882a593Smuzhiyun para->snd_fail_counter++;
1644*4882a593Smuzhiyun if (para->snd_fail_counter > 10) {
1645*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_ ,
1646*4882a593Smuzhiyun "Sounding Fail Count > 10, break sounding !!!!\n");
1647*4882a593Smuzhiyun break;
1648*4882a593Smuzhiyun }
1649*4882a593Smuzhiyun } else {
1650*4882a593Smuzhiyun para->snd_fail_counter = 0;
1651*4882a593Smuzhiyun }
1652*4882a593Smuzhiyun } else if (PHL_RTYPE_AP == role->type) {
1653*4882a593Smuzhiyun if (false == role->active)
1654*4882a593Smuzhiyun break;
1655*4882a593Smuzhiyun if (grp->sta[0].bw > role->chandef.bw)
1656*4882a593Smuzhiyun break;
1657*4882a593Smuzhiyun if (0 == grp->num_sta)
1658*4882a593Smuzhiyun break;
1659*4882a593Smuzhiyun for (i = 0; i < grp->num_sta; i++) {
1660*4882a593Smuzhiyun sta = &grp->sta[i];
1661*4882a593Smuzhiyun psta = rtw_phl_get_stainfo_by_macid(phl_info, sta->macid);
1662*4882a593Smuzhiyun if (NULL == psta) {
1663*4882a593Smuzhiyun terminate = 1;
1664*4882a593Smuzhiyun break;
1665*4882a593Smuzhiyun }
1666*4882a593Smuzhiyun if (false == psta->active) {
1667*4882a593Smuzhiyun terminate = 1;
1668*4882a593Smuzhiyun break;
1669*4882a593Smuzhiyun }
1670*4882a593Smuzhiyun if (sta->bw != psta->chandef.bw) {
1671*4882a593Smuzhiyun terminate = 1;
1672*4882a593Smuzhiyun break;
1673*4882a593Smuzhiyun }
1674*4882a593Smuzhiyun }
1675*4882a593Smuzhiyun if(terminate)
1676*4882a593Smuzhiyun break;
1677*4882a593Smuzhiyun }
1678*4882a593Smuzhiyun }
1679*4882a593Smuzhiyun
1680*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_SUCCESS;
1681*4882a593Smuzhiyun } while (0);
1682*4882a593Smuzhiyun
1683*4882a593Smuzhiyun return pstatus;
1684*4882a593Smuzhiyun }
1685*4882a593Smuzhiyun
1686*4882a593Smuzhiyun
1687*4882a593Smuzhiyun
1688*4882a593Smuzhiyun /**
1689*4882a593Smuzhiyun * Check the previous sounding group sounding status and free the resource.
1690*4882a593Smuzhiyun * if grp is TIER0 grp, skip release BF/CQI resource.
1691*4882a593Smuzhiyun **/
1692*4882a593Smuzhiyun void
phl_snd_proc_chk_prev_grp(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1693*4882a593Smuzhiyun phl_snd_proc_chk_prev_grp(struct phl_info_t *phl_info,
1694*4882a593Smuzhiyun struct phl_snd_grp *grp)
1695*4882a593Smuzhiyun {
1696*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1697*4882a593Smuzhiyun bool free_res = false;
1698*4882a593Smuzhiyun
1699*4882a593Smuzhiyun if (PHL_SND_STS_FAILURE == grp->snd_sts) {
1700*4882a593Smuzhiyun /* Sounding Fail */
1701*4882a593Smuzhiyun free_res = true;
1702*4882a593Smuzhiyun } else if ((PHL_SND_GRP_TIER_1 == grp->grp_tier) && (PHL_SND_STS_PENDING != grp->snd_sts)) {
1703*4882a593Smuzhiyun /* Sounding Success and Group is TIER_1 */
1704*4882a593Smuzhiyun free_res = true;
1705*4882a593Smuzhiyun }
1706*4882a593Smuzhiyun
1707*4882a593Smuzhiyun if (free_res) {
1708*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_, "Free Previous SND Group's Resource\n");
1709*4882a593Smuzhiyun pstatus = phl_snd_proc_release_res(phl_info, grp);
1710*4882a593Smuzhiyun }
1711*4882a593Smuzhiyun
1712*4882a593Smuzhiyun return;
1713*4882a593Smuzhiyun }
1714*4882a593Smuzhiyun
1715*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_polling_pri_sta_sts(struct phl_info_t * phl_info,struct phl_snd_grp * grp)1716*4882a593Smuzhiyun phl_snd_polling_pri_sta_sts(struct phl_info_t *phl_info,
1717*4882a593Smuzhiyun struct phl_snd_grp *grp)
1718*4882a593Smuzhiyun {
1719*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
1720*4882a593Smuzhiyun struct rtw_phl_stainfo_t *sta = NULL;
1721*4882a593Smuzhiyun
1722*4882a593Smuzhiyun PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
1723*4882a593Smuzhiyun "phl_snd_polling_stutus : polling primay sta sounding status\n");
1724*4882a593Smuzhiyun sta = rtw_phl_get_stainfo_by_macid(phl_info, grp->sta[0].macid);
1725*4882a593Smuzhiyun if (sta != NULL) {
1726*4882a593Smuzhiyun if (sta->active == true)
1727*4882a593Smuzhiyun rtw_hal_snd_polling_snd_sts(phl_info->hal, sta);
1728*4882a593Smuzhiyun else
1729*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1730*4882a593Smuzhiyun } else {
1731*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_FAILURE;
1732*4882a593Smuzhiyun }
1733*4882a593Smuzhiyun
1734*4882a593Smuzhiyun return pstatus;
1735*4882a593Smuzhiyun }
1736*4882a593Smuzhiyun
1737*4882a593Smuzhiyun void
phl_snd_mac_ctrl(struct phl_info_t * phl_info,struct rtw_wifi_role_t * wrole,u8 ctrl)1738*4882a593Smuzhiyun phl_snd_mac_ctrl(struct phl_info_t *phl_info,
1739*4882a593Smuzhiyun struct rtw_wifi_role_t *wrole, u8 ctrl)
1740*4882a593Smuzhiyun {
1741*4882a593Smuzhiyun enum rtw_hal_status hstatus = RTW_HAL_STATUS_SUCCESS;
1742*4882a593Smuzhiyun hstatus = rtw_hal_snd_mac_ctrl(phl_info->hal, wrole->hw_band, ctrl);
1743*4882a593Smuzhiyun }
1744*4882a593Smuzhiyun
1745*4882a593Smuzhiyun enum rtw_phl_status
rtw_phl_snd_init_ops_send_ndpa(void * phl,enum rtw_phl_status (* snd_send_ndpa)(void *,struct rtw_wifi_role_t *,u8 *,u32 *,enum channel_width))1746*4882a593Smuzhiyun rtw_phl_snd_init_ops_send_ndpa(void *phl,
1747*4882a593Smuzhiyun enum rtw_phl_status (*snd_send_ndpa)(void *,
1748*4882a593Smuzhiyun struct rtw_wifi_role_t *,
1749*4882a593Smuzhiyun u8 *,
1750*4882a593Smuzhiyun u32 *,
1751*4882a593Smuzhiyun enum channel_width))
1752*4882a593Smuzhiyun {
1753*4882a593Smuzhiyun enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
1754*4882a593Smuzhiyun struct phl_info_t *phl_info = (struct phl_info_t *)phl;
1755*4882a593Smuzhiyun struct phl_sound_obj *snd = NULL;
1756*4882a593Smuzhiyun if((phl_info != NULL) && (snd_send_ndpa != NULL)) {
1757*4882a593Smuzhiyun if (phl_info->snd_obj != NULL) {
1758*4882a593Smuzhiyun snd = (struct phl_sound_obj *)phl_info->snd_obj;
1759*4882a593Smuzhiyun snd->ops.snd_send_ndpa = snd_send_ndpa;
1760*4882a593Smuzhiyun pstatus = RTW_PHL_STATUS_SUCCESS;
1761*4882a593Smuzhiyun }
1762*4882a593Smuzhiyun }
1763*4882a593Smuzhiyun return pstatus;
1764*4882a593Smuzhiyun }