xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/phl_sound_cmd.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
17*4882a593Smuzhiyun #ifdef CONFIG_CMD_DISP
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun /* START of sounding / beamform cmd_disp module */
20*4882a593Smuzhiyun void
_phl_snd_cmd_set_eng_busy(struct phl_info_t * phl_info,enum snd_cmd_disp_ctrl ctrl)21*4882a593Smuzhiyun _phl_snd_cmd_set_eng_busy(struct phl_info_t *phl_info, enum snd_cmd_disp_ctrl ctrl)
22*4882a593Smuzhiyun {
23*4882a593Smuzhiyun 	struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun 	if (snd != NULL) {
26*4882a593Smuzhiyun 		snd->msg_busy |= BIT(ctrl);
27*4882a593Smuzhiyun 	}
28*4882a593Smuzhiyun }
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun void
_phl_snd_cmd_set_eng_idle(struct phl_info_t * phl_info,enum snd_cmd_disp_ctrl ctrl)31*4882a593Smuzhiyun _phl_snd_cmd_set_eng_idle(struct phl_info_t *phl_info, enum snd_cmd_disp_ctrl ctrl)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun 	struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	if (snd != NULL) {
36*4882a593Smuzhiyun 		snd->msg_busy &= ~(BIT(ctrl));
37*4882a593Smuzhiyun 	}
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_cmd_get_eng_status(struct phl_info_t * phl_info,enum snd_cmd_disp_ctrl ctrl)41*4882a593Smuzhiyun _phl_snd_cmd_get_eng_status(struct phl_info_t *phl_info, enum snd_cmd_disp_ctrl ctrl)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
44*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_FAILURE;
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun 	if (snd != NULL) {
47*4882a593Smuzhiyun 		if (0 != (snd->msg_busy & BIT(ctrl))) {
48*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_PENDING;
49*4882a593Smuzhiyun 		} else {
50*4882a593Smuzhiyun 			pstatus = RTW_PHL_STATUS_SUCCESS;
51*4882a593Smuzhiyun 		}
52*4882a593Smuzhiyun 	} else {
53*4882a593Smuzhiyun 		pstatus = RTW_PHL_STATUS_RESOURCE;
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun 	return pstatus;
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_aquire_eng(struct phl_info_t * phl_info,enum snd_cmd_disp_ctrl ctrl)58*4882a593Smuzhiyun _phl_snd_aquire_eng(struct phl_info_t *phl_info, enum snd_cmd_disp_ctrl ctrl)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
61*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
62*4882a593Smuzhiyun 	enum rtw_phl_status pstatus = RTW_PHL_STATUS_SUCCESS;
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	if (snd == NULL)
65*4882a593Smuzhiyun 		return RTW_PHL_STATUS_FAILURE;
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun 	/* acuired cmd_disp_eng control */
68*4882a593Smuzhiyun 	_os_spinlock(d, &snd->cmd_lock, _bh, NULL);
69*4882a593Smuzhiyun 	pstatus = _phl_snd_cmd_get_eng_status(phl_info, ctrl);
70*4882a593Smuzhiyun 	if (pstatus != RTW_PHL_STATUS_SUCCESS) {
71*4882a593Smuzhiyun 		_os_spinunlock(d, &snd->cmd_lock, _bh, NULL);
72*4882a593Smuzhiyun 		return pstatus;
73*4882a593Smuzhiyun 	}
74*4882a593Smuzhiyun 	_phl_snd_cmd_set_eng_busy(phl_info, SND_CMD_DISP_CTRL_BFEE);
75*4882a593Smuzhiyun 	_os_spinunlock(d, &snd->cmd_lock, _bh, NULL);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	return pstatus;
78*4882a593Smuzhiyun }
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun void
_phl_snd_free_eng(struct phl_info_t * phl_info,enum snd_cmd_disp_ctrl ctrl)81*4882a593Smuzhiyun _phl_snd_free_eng(struct phl_info_t *phl_info, enum snd_cmd_disp_ctrl ctrl)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	struct phl_sound_obj *snd = (struct phl_sound_obj *)phl_info->snd_obj;
84*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	if (snd != NULL) {
87*4882a593Smuzhiyun 		_os_spinlock(d, &snd->cmd_lock, _bh, NULL);
88*4882a593Smuzhiyun 		_phl_snd_cmd_set_eng_idle(phl_info, ctrl);
89*4882a593Smuzhiyun 		_os_spinunlock(d, &snd->cmd_lock, _bh, NULL);
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun static enum phl_mdl_ret_code
_phl_snd_cmd_module_init(void * phl,void * dispr,void ** priv)94*4882a593Smuzhiyun _phl_snd_cmd_module_init(void *phl, void *dispr, void **priv)
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun 	enum phl_mdl_ret_code ret = MDL_RET_SUCCESS;
97*4882a593Smuzhiyun #ifdef CONFIG_SND_CMD
98*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
99*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
100*4882a593Smuzhiyun 	struct phl_sound_obj *snd_obj = NULL;
101*4882a593Smuzhiyun 
102*4882a593Smuzhiyun 	PHL_INFO("--> %s\n", __func__);
103*4882a593Smuzhiyun 	if (NULL == phl_info->snd_obj) {
104*4882a593Smuzhiyun 		phl_info->snd_obj = _os_kmem_alloc(d, sizeof(struct phl_sound_obj));
105*4882a593Smuzhiyun 	}
106*4882a593Smuzhiyun 	snd_obj = phl_info->snd_obj;
107*4882a593Smuzhiyun 	if (snd_obj == NULL) {
108*4882a593Smuzhiyun 		ret = MDL_RET_FAIL;
109*4882a593Smuzhiyun 	} else {
110*4882a593Smuzhiyun 		/* Init the snd static resources here */
111*4882a593Smuzhiyun 		snd_obj->phl_info = (struct phl_info_t *)phl;
112*4882a593Smuzhiyun 		_os_spinlock_init(d, &snd_obj->snd_lock);
113*4882a593Smuzhiyun 		_os_spinlock_init(d, &snd_obj->cmd_lock);
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun #endif
116*4882a593Smuzhiyun 	*priv = (void *)phl;
117*4882a593Smuzhiyun 	return ret;
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun 
_phl_snd_cmd_module_deinit(void * dispr,void * priv)120*4882a593Smuzhiyun static void _phl_snd_cmd_module_deinit(void *dispr, void *priv)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun #ifdef CONFIG_SND_CMD
123*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)priv;
124*4882a593Smuzhiyun 	struct phl_sound_obj *snd_obj = (struct phl_sound_obj *)phl_info->snd_obj;
125*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	PHL_INFO("--> %s\n", __func__);
128*4882a593Smuzhiyun 	if (NULL != snd_obj) {
129*4882a593Smuzhiyun 		_os_spinlock_free(d, &snd_obj->snd_lock);
130*4882a593Smuzhiyun 		_os_spinlock_free(d, &snd_obj->cmd_lock);
131*4882a593Smuzhiyun 		_os_kmem_free(d, snd_obj, sizeof(struct phl_sound_obj));
132*4882a593Smuzhiyun 	}
133*4882a593Smuzhiyun 	phl_info->snd_obj = NULL;
134*4882a593Smuzhiyun #endif
135*4882a593Smuzhiyun 	return;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
_phl_snd_cmd_module_start(void * dispr,void * priv)138*4882a593Smuzhiyun static enum phl_mdl_ret_code _phl_snd_cmd_module_start(void *dispr, void *priv)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	return MDL_RET_SUCCESS;
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
_phl_snd_cmd_module_stop(void * dispr,void * priv)143*4882a593Smuzhiyun static enum phl_mdl_ret_code _phl_snd_cmd_module_stop(void *dispr, void *priv)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	return MDL_RET_SUCCESS;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun static enum phl_mdl_ret_code
_phl_snd_cmd_module_set_info(void * dispr,void * priv,struct phl_module_op_info * info)149*4882a593Smuzhiyun _phl_snd_cmd_module_set_info(void *dispr, void *priv,
150*4882a593Smuzhiyun 			     struct phl_module_op_info *info)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	enum phl_mdl_ret_code mstatus = MDL_RET_IGNORE;
153*4882a593Smuzhiyun 	struct phl_info_t *phl = (struct phl_info_t *)priv;
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	PHL_INFO("[SND_CMD], %s(): opcode %d.\n", __func__, info->op_code);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	switch (info->op_code) {
158*4882a593Smuzhiyun 		case SND_CMD_OP_SET_AID:
159*4882a593Smuzhiyun 		{
160*4882a593Smuzhiyun 			struct snd_cmd_set_aid *cmdbuf = (struct snd_cmd_set_aid *)info->inbuf;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 			if (NULL == cmdbuf) {
163*4882a593Smuzhiyun 				mstatus = MDL_RET_FAIL;
164*4882a593Smuzhiyun 				break;
165*4882a593Smuzhiyun 			}
166*4882a593Smuzhiyun 			if (NULL == cmdbuf->sta_info) {
167*4882a593Smuzhiyun 				mstatus = MDL_RET_FAIL;
168*4882a593Smuzhiyun 				cmdbuf->cmd_sts = MDL_RET_FAIL;
169*4882a593Smuzhiyun 				break;
170*4882a593Smuzhiyun 			}
171*4882a593Smuzhiyun 			if (RTW_HAL_STATUS_SUCCESS != rtw_hal_beamform_set_aid(
172*4882a593Smuzhiyun 						phl->hal, cmdbuf->sta_info, cmdbuf->aid)) {
173*4882a593Smuzhiyun 				mstatus = MDL_RET_FAIL;
174*4882a593Smuzhiyun 				cmdbuf->cmd_sts = MDL_RET_FAIL;
175*4882a593Smuzhiyun 				break;
176*4882a593Smuzhiyun 			}
177*4882a593Smuzhiyun #ifdef RTW_WKARD_BFEE_SET_AID
178*4882a593Smuzhiyun 			cmdbuf->sta_info->wrole->last_set_aid = cmdbuf->aid;
179*4882a593Smuzhiyun #endif
180*4882a593Smuzhiyun 			cmdbuf->cmd_sts = MDL_RET_SUCCESS;
181*4882a593Smuzhiyun 			mstatus = MDL_RET_SUCCESS;
182*4882a593Smuzhiyun 		}
183*4882a593Smuzhiyun 		break;
184*4882a593Smuzhiyun 		case SND_CMD_OP_NONE:
185*4882a593Smuzhiyun 		case SND_CMD_OP_MAX:
186*4882a593Smuzhiyun 		default:
187*4882a593Smuzhiyun 		break;
188*4882a593Smuzhiyun 	}
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	return mstatus;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun static enum phl_mdl_ret_code
_phl_snd_cmd_module_query_info(void * dispr,void * priv,struct phl_module_op_info * info)194*4882a593Smuzhiyun _phl_snd_cmd_module_query_info(void *dispr, void *priv,
195*4882a593Smuzhiyun 			       struct phl_module_op_info *info)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	return MDL_RET_IGNORE;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun static enum phl_mdl_ret_code
_phl_snd_cmd_module_msg_msg_hdlr_pre(struct phl_info_t * phl,struct phl_msg * msg)201*4882a593Smuzhiyun _phl_snd_cmd_module_msg_msg_hdlr_pre(struct phl_info_t *phl,
202*4882a593Smuzhiyun 				     struct phl_msg *msg)
203*4882a593Smuzhiyun {
204*4882a593Smuzhiyun 	enum phl_mdl_ret_code mstatus = MDL_RET_IGNORE;
205*4882a593Smuzhiyun 	switch (MSG_EVT_ID_FIELD(msg->msg_id)) {
206*4882a593Smuzhiyun 	case MSG_EVT_SET_VHT_GID:
207*4882a593Smuzhiyun 		/* do nothing in pre phase */
208*4882a593Smuzhiyun 	break;
209*4882a593Smuzhiyun 	case MSG_EVT_SET_BFEE_AID:
210*4882a593Smuzhiyun 		/* do nothing in pre phase */
211*4882a593Smuzhiyun 	break;
212*4882a593Smuzhiyun 	default:
213*4882a593Smuzhiyun 		break;
214*4882a593Smuzhiyun 	}
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	return mstatus;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun static enum phl_mdl_ret_code
_phl_snd_cmd_module_msg_msg_hdlr_post(struct phl_info_t * phl,struct phl_msg * msg)220*4882a593Smuzhiyun _phl_snd_cmd_module_msg_msg_hdlr_post(struct phl_info_t *phl,
221*4882a593Smuzhiyun 				      struct phl_msg *msg)
222*4882a593Smuzhiyun {
223*4882a593Smuzhiyun 	enum phl_mdl_ret_code mstatus = MDL_RET_IGNORE;
224*4882a593Smuzhiyun 	switch (MSG_EVT_ID_FIELD(msg->msg_id)) {
225*4882a593Smuzhiyun 	case MSG_EVT_SET_VHT_GID:
226*4882a593Smuzhiyun 	{
227*4882a593Smuzhiyun 		struct rtw_phl_gid_pos_tbl *gid_tbl = (struct rtw_phl_gid_pos_tbl *)msg->inbuf;
228*4882a593Smuzhiyun 		if (msg->inlen != sizeof(struct rtw_phl_gid_pos_tbl)) {
229*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
230*4882a593Smuzhiyun 				  "%s() VHT-BFEE : Error, size mis-match \n", __func__);
231*4882a593Smuzhiyun 			mstatus = MDL_RET_FAIL;
232*4882a593Smuzhiyun 			break;
233*4882a593Smuzhiyun 		}
234*4882a593Smuzhiyun 		rtw_hal_beamform_set_vht_gid(phl->hal, msg->band_idx, gid_tbl);
235*4882a593Smuzhiyun 		mstatus = MDL_RET_SUCCESS;
236*4882a593Smuzhiyun 	}
237*4882a593Smuzhiyun 	break;
238*4882a593Smuzhiyun 	case MSG_EVT_SET_BFEE_AID:
239*4882a593Smuzhiyun 	{
240*4882a593Smuzhiyun 		struct snd_cmd_set_aid *cmdbuf = (struct snd_cmd_set_aid *)msg->inbuf;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 		if (NULL == cmdbuf) {
243*4882a593Smuzhiyun 			mstatus = MDL_RET_FAIL;
244*4882a593Smuzhiyun 			break;
245*4882a593Smuzhiyun 		}
246*4882a593Smuzhiyun 		if (NULL == cmdbuf->sta_info) {
247*4882a593Smuzhiyun 			mstatus = MDL_RET_FAIL;
248*4882a593Smuzhiyun 			cmdbuf->cmd_sts = MDL_RET_FAIL;
249*4882a593Smuzhiyun 			break;
250*4882a593Smuzhiyun 		}
251*4882a593Smuzhiyun 		if (RTW_HAL_STATUS_SUCCESS != rtw_hal_beamform_set_aid(
252*4882a593Smuzhiyun 					phl->hal, cmdbuf->sta_info, cmdbuf->aid)) {
253*4882a593Smuzhiyun 			mstatus = MDL_RET_FAIL;
254*4882a593Smuzhiyun 			cmdbuf->cmd_sts = MDL_RET_FAIL;
255*4882a593Smuzhiyun 			break;
256*4882a593Smuzhiyun 		}
257*4882a593Smuzhiyun 		cmdbuf->cmd_sts = MDL_RET_SUCCESS;
258*4882a593Smuzhiyun 		mstatus = MDL_RET_SUCCESS;
259*4882a593Smuzhiyun 	}
260*4882a593Smuzhiyun 	break;
261*4882a593Smuzhiyun 	default:
262*4882a593Smuzhiyun 		break;
263*4882a593Smuzhiyun 	}
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	return mstatus;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun 
268*4882a593Smuzhiyun static enum phl_mdl_ret_code
_phl_snd_cmd_module_msg_hdlr(void * dispr,void * priv,struct phl_msg * msg)269*4882a593Smuzhiyun _phl_snd_cmd_module_msg_hdlr(void *dispr, void *priv,
270*4882a593Smuzhiyun 			     struct phl_msg *msg)
271*4882a593Smuzhiyun {
272*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)priv;
273*4882a593Smuzhiyun 	enum phl_mdl_ret_code mstatus = MDL_RET_IGNORE;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_SOUND, _PHL_INFO_,
276*4882a593Smuzhiyun 		  "===> %s() event id : 0x%x \n", __func__, MSG_EVT_ID_FIELD(msg->msg_id));
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	if (IS_MSG_FAIL(msg->msg_id)) {
279*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_DBG, _PHL_WARNING_,
280*4882a593Smuzhiyun 			  "%s: cmd dispatcher notify cmd failure: 0x%x.\n",
281*4882a593Smuzhiyun 			  __FUNCTION__, msg->msg_id);
282*4882a593Smuzhiyun 		mstatus = MDL_RET_FAIL;
283*4882a593Smuzhiyun 		return mstatus;
284*4882a593Smuzhiyun 	}
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	if (IS_MSG_IN_PRE_PHASE(msg->msg_id)) {
287*4882a593Smuzhiyun 		mstatus = _phl_snd_cmd_module_msg_msg_hdlr_pre(phl_info, msg);
288*4882a593Smuzhiyun 	} else {
289*4882a593Smuzhiyun 		mstatus = _phl_snd_cmd_module_msg_msg_hdlr_post(phl_info, msg);
290*4882a593Smuzhiyun 	}
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun 	return mstatus;
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun 
phl_snd_cmd_register_module(struct phl_info_t * phl_info)295*4882a593Smuzhiyun enum rtw_phl_status phl_snd_cmd_register_module(struct phl_info_t *phl_info)
296*4882a593Smuzhiyun {
297*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
298*4882a593Smuzhiyun 	struct phl_bk_module_ops bk_ops;
299*4882a593Smuzhiyun 	struct phl_cmd_dispatch_engine *disp_eng = &(phl_info->disp_eng);
300*4882a593Smuzhiyun 	u8 i = 0;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	bk_ops.init = _phl_snd_cmd_module_init;
303*4882a593Smuzhiyun 	bk_ops.deinit = _phl_snd_cmd_module_deinit;
304*4882a593Smuzhiyun 	bk_ops.start = _phl_snd_cmd_module_start;
305*4882a593Smuzhiyun 	bk_ops.stop = _phl_snd_cmd_module_stop;
306*4882a593Smuzhiyun 	bk_ops.msg_hdlr = _phl_snd_cmd_module_msg_hdlr;
307*4882a593Smuzhiyun 	bk_ops.set_info = _phl_snd_cmd_module_set_info;
308*4882a593Smuzhiyun 	bk_ops.query_info = _phl_snd_cmd_module_query_info;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	for (i = 0; i < disp_eng->phy_num; i++) {
312*4882a593Smuzhiyun 		phl_status = phl_disp_eng_register_module(phl_info, i,
313*4882a593Smuzhiyun 						PHL_MDL_SOUND, &bk_ops);
314*4882a593Smuzhiyun 		if (phl_status != RTW_PHL_STATUS_SUCCESS) {
315*4882a593Smuzhiyun 			PHL_ERR("%s register SOUND module in cmd disp band[%d] failed\n",
316*4882a593Smuzhiyun 				__func__, i);
317*4882a593Smuzhiyun 			phl_status = RTW_PHL_STATUS_FAILURE;
318*4882a593Smuzhiyun 			break;
319*4882a593Smuzhiyun 		}
320*4882a593Smuzhiyun 	}
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 	return phl_status;
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun /* Start of APIs for Core/OtherModule */
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun /* sub-functions */
329*4882a593Smuzhiyun /**
330*4882a593Smuzhiyun  * _phl_snd_cmd_post_set_vht_gid(...)
331*4882a593Smuzhiyun  * 	used by rtw_phl_snd_cmd_set_vht_gid(..)
332*4882a593Smuzhiyun  **/
_phl_snd_cmd_post_set_vht_gid(void * priv,struct phl_msg * msg)333*4882a593Smuzhiyun void _phl_snd_cmd_post_set_vht_gid(void* priv, struct phl_msg* msg)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)priv;
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "--> %s : release memeory \n", __func__);
338*4882a593Smuzhiyun 	if (msg->inbuf && msg->inlen){
339*4882a593Smuzhiyun 		_os_kmem_free(phl_to_drvpriv(phl_info), msg->inbuf, msg->inlen);
340*4882a593Smuzhiyun 	}
341*4882a593Smuzhiyun 	/* release cmd_disp_eng control */
342*4882a593Smuzhiyun 	_phl_snd_free_eng(phl_info, SND_CMD_DISP_CTRL_BFEE);
343*4882a593Smuzhiyun }
344*4882a593Smuzhiyun /* main-functions */
345*4882a593Smuzhiyun /**
346*4882a593Smuzhiyun  * rtw_phl_snd_cmd_set_vht_gid (...)
347*4882a593Smuzhiyun  * input : struct rtw_phl_gid_pos_tbl *tbl
348*4882a593Smuzhiyun  * 		the received VHT GID management frame's GID / Position informaion.
349*4882a593Smuzhiyun  **/
350*4882a593Smuzhiyun enum rtw_phl_status
rtw_phl_snd_cmd_set_vht_gid(void * phl,struct rtw_wifi_role_t * wrole,struct rtw_phl_gid_pos_tbl * tbl)351*4882a593Smuzhiyun rtw_phl_snd_cmd_set_vht_gid(void *phl,
352*4882a593Smuzhiyun 			    struct rtw_wifi_role_t *wrole,
353*4882a593Smuzhiyun 			    struct rtw_phl_gid_pos_tbl *tbl)
354*4882a593Smuzhiyun {
355*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
356*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
357*4882a593Smuzhiyun 	struct phl_msg msg = {0};
358*4882a593Smuzhiyun 	struct phl_msg_attribute attr = {0};
359*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
360*4882a593Smuzhiyun 	struct rtw_phl_gid_pos_tbl *gid_tbl;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 	/* acuired cmd_disp_eng control */
363*4882a593Smuzhiyun 	if (RTW_PHL_STATUS_SUCCESS !=
364*4882a593Smuzhiyun 		_phl_snd_aquire_eng(phl_info, SND_CMD_DISP_CTRL_BFEE)) {
365*4882a593Smuzhiyun 			return RTW_PHL_STATUS_FAILURE;
366*4882a593Smuzhiyun 	}
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun 	SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_SOUND);
369*4882a593Smuzhiyun 	SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_SET_VHT_GID);
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	msg.band_idx = wrole->hw_band;
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	attr.completion.completion = _phl_snd_cmd_post_set_vht_gid;
374*4882a593Smuzhiyun 	attr.completion.priv = phl_info;
375*4882a593Smuzhiyun 	gid_tbl = (struct rtw_phl_gid_pos_tbl *)_os_kmem_alloc(d, sizeof(struct rtw_phl_gid_pos_tbl));
376*4882a593Smuzhiyun 	_os_mem_cpy(d, gid_tbl, tbl, sizeof(struct rtw_phl_gid_pos_tbl));
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	msg.inbuf = (u8 *)gid_tbl;
379*4882a593Smuzhiyun 	msg.inlen = sizeof(struct rtw_phl_gid_pos_tbl);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	phl_status = phl_disp_eng_send_msg(phl_info, &msg, &attr, NULL);
382*4882a593Smuzhiyun 	if (phl_status != RTW_PHL_STATUS_SUCCESS) {
383*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_, "%s: Dispr send msg fail!\n",
384*4882a593Smuzhiyun 			  __func__);
385*4882a593Smuzhiyun 		goto exit;
386*4882a593Smuzhiyun 	}
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 	return phl_status;
389*4882a593Smuzhiyun 
390*4882a593Smuzhiyun exit:
391*4882a593Smuzhiyun 	_os_kmem_free(d, gid_tbl,
392*4882a593Smuzhiyun 		      sizeof(struct rtw_phl_gid_pos_tbl));
393*4882a593Smuzhiyun 	/* release cmd_disp_eng control */
394*4882a593Smuzhiyun 	_phl_snd_free_eng(phl_info, SND_CMD_DISP_CTRL_BFEE);
395*4882a593Smuzhiyun 	return phl_status;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun 
_phl_snd_cmd_post_set_aid(void * priv,struct phl_msg * msg)399*4882a593Smuzhiyun void _phl_snd_cmd_post_set_aid(void* priv, struct phl_msg* msg)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)priv;
402*4882a593Smuzhiyun #ifdef RTW_WKARD_BFEE_SET_AID
403*4882a593Smuzhiyun 	struct snd_cmd_set_aid *cmdbuf = NULL;
404*4882a593Smuzhiyun #endif
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	if (msg->inbuf && msg->inlen){
407*4882a593Smuzhiyun #ifdef RTW_WKARD_BFEE_SET_AID
408*4882a593Smuzhiyun 		cmdbuf = (struct snd_cmd_set_aid *)msg->inbuf;
409*4882a593Smuzhiyun 		/* backup aid */
410*4882a593Smuzhiyun 		if (MDL_RET_SUCCESS == cmdbuf->cmd_sts) {
411*4882a593Smuzhiyun 			cmdbuf->sta_info->wrole->last_set_aid = cmdbuf->aid;
412*4882a593Smuzhiyun 			PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_,
413*4882a593Smuzhiyun 				"%s : set aid (%d)\n",
414*4882a593Smuzhiyun 				__func__, cmdbuf->sta_info->wrole->last_set_aid);
415*4882a593Smuzhiyun 		}
416*4882a593Smuzhiyun #endif
417*4882a593Smuzhiyun 		_os_kmem_free(phl_to_drvpriv(phl_info), msg->inbuf, msg->inlen);
418*4882a593Smuzhiyun 	}
419*4882a593Smuzhiyun 	/* release cmd_disp_eng control */
420*4882a593Smuzhiyun 	_phl_snd_free_eng(phl_info, SND_CMD_DISP_CTRL_BFEE);
421*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "%s : set aid complete\n", __func__);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun 
424*4882a593Smuzhiyun enum rtw_phl_status
rtw_phl_snd_cmd_set_aid(void * phl,struct rtw_wifi_role_t * wrole,struct rtw_phl_stainfo_t * sta,u16 aid)425*4882a593Smuzhiyun rtw_phl_snd_cmd_set_aid(void *phl,
426*4882a593Smuzhiyun 			struct rtw_wifi_role_t *wrole,
427*4882a593Smuzhiyun 			struct rtw_phl_stainfo_t *sta,
428*4882a593Smuzhiyun 			u16 aid)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
431*4882a593Smuzhiyun 	struct phl_info_t *phl_info = (struct phl_info_t *)phl;
432*4882a593Smuzhiyun 	struct phl_msg msg = {0};
433*4882a593Smuzhiyun 	struct phl_msg_attribute attr = {0};
434*4882a593Smuzhiyun 	void *d = phl_to_drvpriv(phl_info);
435*4882a593Smuzhiyun 	struct snd_cmd_set_aid *cmdbuf = NULL;
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	/* acuired cmd_disp_eng control */
438*4882a593Smuzhiyun 	if (RTW_PHL_STATUS_SUCCESS !=
439*4882a593Smuzhiyun 		_phl_snd_aquire_eng(phl_info, SND_CMD_DISP_CTRL_BFEE)) {
440*4882a593Smuzhiyun 			return RTW_PHL_STATUS_FAILURE;
441*4882a593Smuzhiyun 	}
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun 	SET_MSG_MDL_ID_FIELD(msg.msg_id, PHL_MDL_SOUND);
444*4882a593Smuzhiyun 	SET_MSG_EVT_ID_FIELD(msg.msg_id, MSG_EVT_SET_BFEE_AID);
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	msg.band_idx = wrole->hw_band;
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	attr.completion.completion = _phl_snd_cmd_post_set_aid;
449*4882a593Smuzhiyun 	attr.completion.priv = phl_info;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	cmdbuf = (struct snd_cmd_set_aid *)_os_kmem_alloc(d, sizeof(struct snd_cmd_set_aid));
452*4882a593Smuzhiyun 	cmdbuf->aid = aid;
453*4882a593Smuzhiyun 	cmdbuf->sta_info = sta;
454*4882a593Smuzhiyun 
455*4882a593Smuzhiyun 	msg.inbuf = (u8 *)cmdbuf;
456*4882a593Smuzhiyun 	msg.inlen = sizeof(struct snd_cmd_set_aid);
457*4882a593Smuzhiyun 
458*4882a593Smuzhiyun 	phl_status = phl_disp_eng_send_msg(phl_info, &msg, &attr, NULL);
459*4882a593Smuzhiyun 
460*4882a593Smuzhiyun 	if (phl_status != RTW_PHL_STATUS_SUCCESS) {
461*4882a593Smuzhiyun 		PHL_TRACE(COMP_PHL_DBG, _PHL_ERR_, "%s: Dispr send msg fail!\n",
462*4882a593Smuzhiyun 			  __func__);
463*4882a593Smuzhiyun 		goto exit;
464*4882a593Smuzhiyun 	}
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun 	return phl_status;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun exit:
469*4882a593Smuzhiyun 	_os_kmem_free(d, cmdbuf, sizeof(struct snd_cmd_set_aid));
470*4882a593Smuzhiyun 	/* release cmd_disp_eng control */
471*4882a593Smuzhiyun 	_phl_snd_free_eng(phl_info, SND_CMD_DISP_CTRL_BFEE);
472*4882a593Smuzhiyun 	return phl_status;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun 
476*4882a593Smuzhiyun /**
477*4882a593Smuzhiyun  * For other module, such as LPS, direct set aid.
478*4882a593Smuzhiyun  **/
479*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_cmd_set_aid_info(struct phl_info_t * phl,struct rtw_wifi_role_t * wrole,struct rtw_phl_stainfo_t * sta,u16 aid)480*4882a593Smuzhiyun phl_snd_cmd_set_aid_info(struct phl_info_t *phl,
481*4882a593Smuzhiyun 			 struct rtw_wifi_role_t *wrole,
482*4882a593Smuzhiyun 			 struct rtw_phl_stainfo_t *sta,
483*4882a593Smuzhiyun 			 u16 aid)
484*4882a593Smuzhiyun {
485*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_FAILURE;
486*4882a593Smuzhiyun 	struct phl_module_op_info op_info = {0};
487*4882a593Smuzhiyun 	struct snd_cmd_set_aid cmdbuf = {0};
488*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "--> %s\n", __func__);
489*4882a593Smuzhiyun 
490*4882a593Smuzhiyun 	cmdbuf.aid = aid;
491*4882a593Smuzhiyun 	cmdbuf.sta_info = sta;
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 	op_info.op_code = SND_CMD_OP_SET_AID;
494*4882a593Smuzhiyun 	op_info.inbuf = (u8 *)&cmdbuf;
495*4882a593Smuzhiyun 	op_info.inlen = sizeof(struct snd_cmd_set_aid);
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun 	phl_status = phl_disp_eng_set_bk_module_info(phl, wrole->hw_band,
498*4882a593Smuzhiyun 						     PHL_MDL_SOUND, &op_info);
499*4882a593Smuzhiyun 
500*4882a593Smuzhiyun 	PHL_TRACE(COMP_PHL_DBG, _PHL_INFO_, "<-- %s\n", __func__);
501*4882a593Smuzhiyun 	return phl_status;
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun #ifdef RTW_WKARD_BFEE_SET_AID
505*4882a593Smuzhiyun enum rtw_phl_status
_phl_cmd_snd_restore_aid(struct phl_info_t * phl,struct rtw_wifi_role_t * wrole)506*4882a593Smuzhiyun _phl_cmd_snd_restore_aid(struct phl_info_t *phl,
507*4882a593Smuzhiyun 			 struct rtw_wifi_role_t *wrole)
508*4882a593Smuzhiyun {
509*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
510*4882a593Smuzhiyun 	struct rtw_phl_stainfo_t *sta = NULL;
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 	do {
513*4882a593Smuzhiyun 		if (MLME_NO_LINK == wrole->mstate)
514*4882a593Smuzhiyun 			break;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 		sta = rtw_phl_get_stainfo_self(phl, wrole);
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun 		if (NULL == sta)
519*4882a593Smuzhiyun 			break;
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 		if (wrole->last_set_aid == sta->aid)
522*4882a593Smuzhiyun 			break;
523*4882a593Smuzhiyun 
524*4882a593Smuzhiyun 		phl_status = phl_snd_cmd_set_aid_info(phl, wrole, sta, sta->aid);
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	} while (0);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	return phl_status;
529*4882a593Smuzhiyun }
530*4882a593Smuzhiyun #endif
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_cmd_ntfy_ps_enter(struct phl_info_t * phl,struct rtw_wifi_role_t * wrole)534*4882a593Smuzhiyun _phl_snd_cmd_ntfy_ps_enter(struct phl_info_t *phl,
535*4882a593Smuzhiyun 			   struct rtw_wifi_role_t *wrole)
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun #ifdef RTW_WKARD_BFEE_SET_AID
540*4882a593Smuzhiyun 	phl->phl_com->is_in_lps = 1;
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	if (PHL_RTYPE_STATION == wrole->type) {
543*4882a593Smuzhiyun 		phl_status= _phl_cmd_snd_restore_aid(phl, wrole);
544*4882a593Smuzhiyun 	}
545*4882a593Smuzhiyun #endif
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	/* TODO: stop BFer period sounding if in progress */
548*4882a593Smuzhiyun 	return phl_status;
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun enum rtw_phl_status
_phl_snd_cmd_ntfy_ps_leave(struct phl_info_t * phl,struct rtw_wifi_role_t * wrole)552*4882a593Smuzhiyun _phl_snd_cmd_ntfy_ps_leave(struct phl_info_t *phl,
553*4882a593Smuzhiyun 			   struct rtw_wifi_role_t *wrole)
554*4882a593Smuzhiyun {
555*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun #ifdef RTW_WKARD_BFEE_SET_AID
558*4882a593Smuzhiyun 	phl->phl_com->is_in_lps = 0;
559*4882a593Smuzhiyun #endif
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	/* TODO: restart BFer period sounding if sounding needed */
562*4882a593Smuzhiyun 	return phl_status;
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun 
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun enum rtw_phl_status
phl_snd_cmd_ntfy_ps(struct phl_info_t * phl,struct rtw_wifi_role_t * wrole,bool enter)567*4882a593Smuzhiyun phl_snd_cmd_ntfy_ps(struct phl_info_t *phl,
568*4882a593Smuzhiyun 		    struct rtw_wifi_role_t *wrole,
569*4882a593Smuzhiyun 		    bool enter)
570*4882a593Smuzhiyun {
571*4882a593Smuzhiyun 	enum rtw_phl_status phl_status = RTW_PHL_STATUS_SUCCESS;
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	if (true == enter)
574*4882a593Smuzhiyun 		phl_status = _phl_snd_cmd_ntfy_ps_enter(phl, wrole);
575*4882a593Smuzhiyun 	else
576*4882a593Smuzhiyun 		phl_status = _phl_snd_cmd_ntfy_ps_leave(phl, wrole);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	return phl_status;
579*4882a593Smuzhiyun }
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun #endif