xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8188fu/hal/hal_halmac.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /******************************************************************************
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright(c) 2015 - 2019 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 #define _HAL_HALMAC_C_
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #include <drv_types.h>		/* PADAPTER, struct dvobj_priv, SDIO_ERR_VAL8 and etc. */
18*4882a593Smuzhiyun #include <hal_data.h>		/* efuse, PHAL_DATA_TYPE and etc. */
19*4882a593Smuzhiyun #include "hal_halmac.h"		/* dvobj_to_halmac() and ect. */
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun /*
22*4882a593Smuzhiyun  * HALMAC take return value 0 for fail and 1 for success to replace
23*4882a593Smuzhiyun  * _FALSE/_TRUE after V1_04_09
24*4882a593Smuzhiyun  */
25*4882a593Smuzhiyun #define RTW_HALMAC_FAIL			0
26*4882a593Smuzhiyun #define RTW_HALMAC_SUCCESS		1
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #define DEFAULT_INDICATOR_TIMELMT	1000	/* ms */
29*4882a593Smuzhiyun #define MSG_PREFIX			"[HALMAC]"
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun #define RTW_HALMAC_DLFW_MEM_NO_STOP_TX
32*4882a593Smuzhiyun #define RTW_HALMAC_FILTER_DRV_C2H	/* Block C2H owner=driver */
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /*
35*4882a593Smuzhiyun  * Driver API for HALMAC operations
36*4882a593Smuzhiyun  */
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
39*4882a593Smuzhiyun #include <rtw_sdio.h>
40*4882a593Smuzhiyun 
_halmac_mac_reg_page0_chk(const char * func,struct dvobj_priv * dvobj,u32 offset)41*4882a593Smuzhiyun static u8 _halmac_mac_reg_page0_chk(const char *func, struct dvobj_priv *dvobj, u32 offset)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun #if defined(CONFIG_IO_CHECK_IN_ANA_LOW_CLK) && defined(CONFIG_LPS_LCLK)
44*4882a593Smuzhiyun 	struct pwrctrl_priv *pwrpriv = &dvobj->pwrctl_priv;
45*4882a593Smuzhiyun 	u32 mac_reg_offset = 0;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun 	if (pwrpriv->pwr_mode == PS_MODE_ACTIVE)
48*4882a593Smuzhiyun 		return _TRUE;
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun 	if (pwrpriv->lps_level == LPS_NORMAL)
51*4882a593Smuzhiyun 		return _TRUE;
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	if (pwrpriv->rpwm >= PS_STATE_S2)
54*4882a593Smuzhiyun 		return _TRUE;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	if (offset & (WLAN_IOREG_DEVICE_ID << 13))  { /*WLAN_IOREG_OFFSET*/
57*4882a593Smuzhiyun 		mac_reg_offset = offset & HALMAC_WLAN_MAC_REG_MSK;
58*4882a593Smuzhiyun 		if (mac_reg_offset < 0x100) {
59*4882a593Smuzhiyun 			RTW_ERR(FUNC_ADPT_FMT
60*4882a593Smuzhiyun 				"access MAC REG -0x%04x in PS-mode:0x%02x (rpwm:0x%02x, lps_level:0x%02x)\n",
61*4882a593Smuzhiyun 				FUNC_ADPT_ARG(dvobj_get_primary_adapter(dvobj)), mac_reg_offset,
62*4882a593Smuzhiyun 				pwrpriv->pwr_mode, pwrpriv->rpwm, pwrpriv->lps_level);
63*4882a593Smuzhiyun 			rtw_warn_on(1);
64*4882a593Smuzhiyun 			return _FALSE;
65*4882a593Smuzhiyun 		}
66*4882a593Smuzhiyun 	}
67*4882a593Smuzhiyun #endif
68*4882a593Smuzhiyun 	return _TRUE;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
_halmac_sdio_cmd52_read(void * p,u32 offset)71*4882a593Smuzhiyun static u8 _halmac_sdio_cmd52_read(void *p, u32 offset)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	struct dvobj_priv *d;
74*4882a593Smuzhiyun 	u8 val;
75*4882a593Smuzhiyun 	u8 ret;
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
79*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
80*4882a593Smuzhiyun 	ret = rtw_sdio_read_cmd52(d, offset, &val, 1);
81*4882a593Smuzhiyun 	if (_FAIL == ret) {
82*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
83*4882a593Smuzhiyun 		return SDIO_ERR_VAL8;
84*4882a593Smuzhiyun 	}
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	return val;
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
_halmac_sdio_cmd52_write(void * p,u32 offset,u8 val)89*4882a593Smuzhiyun static void _halmac_sdio_cmd52_write(void *p, u32 offset, u8 val)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	struct dvobj_priv *d;
92*4882a593Smuzhiyun 	u8 ret;
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
96*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
97*4882a593Smuzhiyun 	ret = rtw_sdio_write_cmd52(d, offset, &val, 1);
98*4882a593Smuzhiyun 	if (_FAIL == ret)
99*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
_halmac_sdio_reg_read_8(void * p,u32 offset)102*4882a593Smuzhiyun static u8 _halmac_sdio_reg_read_8(void *p, u32 offset)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun 	struct dvobj_priv *d;
105*4882a593Smuzhiyun 	u8 *pbuf;
106*4882a593Smuzhiyun 	u8 val;
107*4882a593Smuzhiyun 	u8 ret;
108*4882a593Smuzhiyun 
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
111*4882a593Smuzhiyun 	val = SDIO_ERR_VAL8;
112*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
113*4882a593Smuzhiyun 	pbuf = rtw_zmalloc(1);
114*4882a593Smuzhiyun 	if (!pbuf)
115*4882a593Smuzhiyun 		return val;
116*4882a593Smuzhiyun 
117*4882a593Smuzhiyun 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 1);
118*4882a593Smuzhiyun 	if (ret == _FAIL) {
119*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
120*4882a593Smuzhiyun 		goto exit;
121*4882a593Smuzhiyun 	}
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun 	val = *pbuf;
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun exit:
126*4882a593Smuzhiyun 	rtw_mfree(pbuf, 1);
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun 	return val;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
_halmac_sdio_reg_read_16(void * p,u32 offset)131*4882a593Smuzhiyun static u16 _halmac_sdio_reg_read_16(void *p, u32 offset)
132*4882a593Smuzhiyun {
133*4882a593Smuzhiyun 	struct dvobj_priv *d;
134*4882a593Smuzhiyun 	u8 *pbuf;
135*4882a593Smuzhiyun 	u16 val;
136*4882a593Smuzhiyun 	u8 ret;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
140*4882a593Smuzhiyun 	val = SDIO_ERR_VAL16;
141*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
142*4882a593Smuzhiyun 	pbuf = rtw_zmalloc(2);
143*4882a593Smuzhiyun 	if (!pbuf)
144*4882a593Smuzhiyun 		return val;
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 2);
147*4882a593Smuzhiyun 	if (ret == _FAIL) {
148*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
149*4882a593Smuzhiyun 		goto exit;
150*4882a593Smuzhiyun 	}
151*4882a593Smuzhiyun 
152*4882a593Smuzhiyun 	val = le16_to_cpu(*(u16 *)pbuf);
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun exit:
155*4882a593Smuzhiyun 	rtw_mfree(pbuf, 2);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	return val;
158*4882a593Smuzhiyun }
159*4882a593Smuzhiyun 
_halmac_sdio_reg_read_32(void * p,u32 offset)160*4882a593Smuzhiyun static u32 _halmac_sdio_reg_read_32(void *p, u32 offset)
161*4882a593Smuzhiyun {
162*4882a593Smuzhiyun 	struct dvobj_priv *d;
163*4882a593Smuzhiyun 	u8 *pbuf;
164*4882a593Smuzhiyun 	u32 val;
165*4882a593Smuzhiyun 	u8 ret;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 
168*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
169*4882a593Smuzhiyun 	val = SDIO_ERR_VAL32;
170*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
171*4882a593Smuzhiyun 	pbuf = rtw_zmalloc(4);
172*4882a593Smuzhiyun 	if (!pbuf)
173*4882a593Smuzhiyun 		return val;
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, 4);
176*4882a593Smuzhiyun 	if (ret == _FAIL) {
177*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
178*4882a593Smuzhiyun 		goto exit;
179*4882a593Smuzhiyun 	}
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	val = le32_to_cpu(*(u32 *)pbuf);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun exit:
184*4882a593Smuzhiyun 	rtw_mfree(pbuf, 4);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun 	return val;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun 
_halmac_sdio_reg_read_n(void * p,u32 offset,u32 size,u8 * data)189*4882a593Smuzhiyun static u8 _halmac_sdio_reg_read_n(void *p, u32 offset, u32 size, u8 *data)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	struct dvobj_priv *d = (struct dvobj_priv *)p;
192*4882a593Smuzhiyun 	u8 *pbuf;
193*4882a593Smuzhiyun 	u8 ret;
194*4882a593Smuzhiyun 	u8 rst = RTW_HALMAC_FAIL;
195*4882a593Smuzhiyun 	u32 sdio_read_size;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	if (!data)
199*4882a593Smuzhiyun 		return rst;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	sdio_read_size = RND4(size);
202*4882a593Smuzhiyun 	sdio_read_size = rtw_sdio_cmd53_align_size(d, sdio_read_size);
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	pbuf = rtw_zmalloc(sdio_read_size);
205*4882a593Smuzhiyun 	if (!pbuf)
206*4882a593Smuzhiyun 		return rst;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun 	ret = rtw_sdio_read_cmd53(d, offset, pbuf, sdio_read_size);
209*4882a593Smuzhiyun 	if (ret == _FAIL) {
210*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
211*4882a593Smuzhiyun 		goto exit;
212*4882a593Smuzhiyun 	}
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	_rtw_memcpy(data, pbuf, size);
215*4882a593Smuzhiyun 	rst = RTW_HALMAC_SUCCESS;
216*4882a593Smuzhiyun exit:
217*4882a593Smuzhiyun 	rtw_mfree(pbuf, sdio_read_size);
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	return rst;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun 
_halmac_sdio_reg_write_8(void * p,u32 offset,u8 val)222*4882a593Smuzhiyun static void _halmac_sdio_reg_write_8(void *p, u32 offset, u8 val)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun 	struct dvobj_priv *d;
225*4882a593Smuzhiyun 	u8 *pbuf;
226*4882a593Smuzhiyun 	u8 ret;
227*4882a593Smuzhiyun 
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
230*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
231*4882a593Smuzhiyun 	pbuf = rtw_zmalloc(1);
232*4882a593Smuzhiyun 	if (!pbuf)
233*4882a593Smuzhiyun 		return;
234*4882a593Smuzhiyun 	_rtw_memcpy(pbuf, &val, 1);
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 1);
237*4882a593Smuzhiyun 	if (ret == _FAIL)
238*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	rtw_mfree(pbuf, 1);
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
_halmac_sdio_reg_write_16(void * p,u32 offset,u16 val)243*4882a593Smuzhiyun static void _halmac_sdio_reg_write_16(void *p, u32 offset, u16 val)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun 	struct dvobj_priv *d;
246*4882a593Smuzhiyun 	u8 *pbuf;
247*4882a593Smuzhiyun 	u8 ret;
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
251*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
252*4882a593Smuzhiyun 	val = cpu_to_le16(val);
253*4882a593Smuzhiyun 	pbuf = rtw_zmalloc(2);
254*4882a593Smuzhiyun 	if (!pbuf)
255*4882a593Smuzhiyun 		return;
256*4882a593Smuzhiyun 	_rtw_memcpy(pbuf, &val, 2);
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 2);
259*4882a593Smuzhiyun 	if (ret == _FAIL)
260*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun 	rtw_mfree(pbuf, 2);
263*4882a593Smuzhiyun }
264*4882a593Smuzhiyun 
_halmac_sdio_reg_write_32(void * p,u32 offset,u32 val)265*4882a593Smuzhiyun static void _halmac_sdio_reg_write_32(void *p, u32 offset, u32 val)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	struct dvobj_priv *d;
268*4882a593Smuzhiyun 	u8 *pbuf;
269*4882a593Smuzhiyun 	u8 ret;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
273*4882a593Smuzhiyun 	_halmac_mac_reg_page0_chk(__func__, d, offset);
274*4882a593Smuzhiyun 	val = cpu_to_le32(val);
275*4882a593Smuzhiyun 	pbuf = rtw_zmalloc(4);
276*4882a593Smuzhiyun 	if (!pbuf)
277*4882a593Smuzhiyun 		return;
278*4882a593Smuzhiyun 	_rtw_memcpy(pbuf, &val, 4);
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	ret = rtw_sdio_write_cmd53(d, offset, pbuf, 4);
281*4882a593Smuzhiyun 	if (ret == _FAIL)
282*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	rtw_mfree(pbuf, 4);
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun 
_halmac_sdio_read_cia(void * p,u32 offset)287*4882a593Smuzhiyun static u8 _halmac_sdio_read_cia(void *p, u32 offset)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun 	struct dvobj_priv *d;
290*4882a593Smuzhiyun 	u8 data = 0;
291*4882a593Smuzhiyun 	u8 ret;
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
295*4882a593Smuzhiyun 
296*4882a593Smuzhiyun 	ret = rtw_sdio_f0_read(d, offset, &data, 1);
297*4882a593Smuzhiyun 	if (ret == _FAIL)
298*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	return data;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
303*4882a593Smuzhiyun #else /* !CONFIG_SDIO_HCI */
304*4882a593Smuzhiyun 
_halmac_reg_read_8(void * p,u32 offset)305*4882a593Smuzhiyun static u8 _halmac_reg_read_8(void *p, u32 offset)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun 	struct dvobj_priv *d;
308*4882a593Smuzhiyun 	PADAPTER adapter;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
312*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun 	return _rtw_read8(adapter, offset);
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
_halmac_reg_read_16(void * p,u32 offset)317*4882a593Smuzhiyun static u16 _halmac_reg_read_16(void *p, u32 offset)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	struct dvobj_priv *d;
320*4882a593Smuzhiyun 	PADAPTER adapter;
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 
323*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
324*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 	return _rtw_read16(adapter, offset);
327*4882a593Smuzhiyun }
328*4882a593Smuzhiyun 
_halmac_reg_read_32(void * p,u32 offset)329*4882a593Smuzhiyun static u32 _halmac_reg_read_32(void *p, u32 offset)
330*4882a593Smuzhiyun {
331*4882a593Smuzhiyun 	struct dvobj_priv *d;
332*4882a593Smuzhiyun 	PADAPTER adapter;
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
336*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun 	return _rtw_read32(adapter, offset);
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun 
_halmac_reg_write_8(void * p,u32 offset,u8 val)341*4882a593Smuzhiyun static void _halmac_reg_write_8(void *p, u32 offset, u8 val)
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun 	struct dvobj_priv *d;
344*4882a593Smuzhiyun 	PADAPTER adapter;
345*4882a593Smuzhiyun 	int err;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
349*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
350*4882a593Smuzhiyun 
351*4882a593Smuzhiyun 	err = _rtw_write8(adapter, offset, val);
352*4882a593Smuzhiyun 	if (err == _FAIL)
353*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
_halmac_reg_write_16(void * p,u32 offset,u16 val)356*4882a593Smuzhiyun static void _halmac_reg_write_16(void *p, u32 offset, u16 val)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun 	struct dvobj_priv *d;
359*4882a593Smuzhiyun 	PADAPTER adapter;
360*4882a593Smuzhiyun 	int err;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
364*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun 	err = _rtw_write16(adapter, offset, val);
367*4882a593Smuzhiyun 	if (err == _FAIL)
368*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun 
_halmac_reg_write_32(void * p,u32 offset,u32 val)371*4882a593Smuzhiyun static void _halmac_reg_write_32(void *p, u32 offset, u32 val)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	struct dvobj_priv *d;
374*4882a593Smuzhiyun 	PADAPTER adapter;
375*4882a593Smuzhiyun 	int err;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
379*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 	err = _rtw_write32(adapter, offset, val);
382*4882a593Smuzhiyun 	if (err == _FAIL)
383*4882a593Smuzhiyun 		RTW_ERR("%s: I/O FAIL!\n", __FUNCTION__);
384*4882a593Smuzhiyun }
385*4882a593Smuzhiyun #endif /* !CONFIG_SDIO_HCI */
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun #ifdef DBG_IO
_halmac_reg_read_monitor(void * p,u32 addr,u32 len,u32 val,const char * caller,const u32 line)388*4882a593Smuzhiyun static void _halmac_reg_read_monitor(void *p, u32 addr, u32 len, u32 val
389*4882a593Smuzhiyun 	, const char *caller, const u32 line)
390*4882a593Smuzhiyun {
391*4882a593Smuzhiyun 	struct dvobj_priv *d = (struct dvobj_priv *)p;
392*4882a593Smuzhiyun 	_adapter *adapter = dvobj_get_primary_adapter(d);
393*4882a593Smuzhiyun 
394*4882a593Smuzhiyun 	dbg_rtw_reg_read_monitor(adapter, addr, len, val, caller, line);
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun 
_halmac_reg_write_monitor(void * p,u32 addr,u32 len,u32 val,const char * caller,const u32 line)397*4882a593Smuzhiyun static void _halmac_reg_write_monitor(void *p, u32 addr, u32 len, u32 val
398*4882a593Smuzhiyun 	, const char *caller, const u32 line)
399*4882a593Smuzhiyun {
400*4882a593Smuzhiyun 	struct dvobj_priv *d = (struct dvobj_priv *)p;
401*4882a593Smuzhiyun 	_adapter *adapter = dvobj_get_primary_adapter(d);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	dbg_rtw_reg_write_monitor(adapter, addr, len, val, caller, line);
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun #endif
406*4882a593Smuzhiyun 
_halmac_mfree(void * p,void * buffer,u32 size)407*4882a593Smuzhiyun static u8 _halmac_mfree(void *p, void *buffer, u32 size)
408*4882a593Smuzhiyun {
409*4882a593Smuzhiyun 	rtw_mfree(buffer, size);
410*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun 
_halmac_malloc(void * p,u32 size)413*4882a593Smuzhiyun static void *_halmac_malloc(void *p, u32 size)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun 	return rtw_zmalloc(size);
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun 
_halmac_memcpy(void * p,void * dest,void * src,u32 size)418*4882a593Smuzhiyun static u8 _halmac_memcpy(void *p, void *dest, void *src, u32 size)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun 	_rtw_memcpy(dest, src, size);
421*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun 
_halmac_memset(void * p,void * addr,u8 value,u32 size)424*4882a593Smuzhiyun static u8 _halmac_memset(void *p, void *addr, u8 value, u32 size)
425*4882a593Smuzhiyun {
426*4882a593Smuzhiyun 	_rtw_memset(addr, value, size);
427*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun 
_halmac_udelay(void * p,u32 us)430*4882a593Smuzhiyun static void _halmac_udelay(void *p, u32 us)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun 	/* Most hardware polling wait time < 50us) */
433*4882a593Smuzhiyun 	if (us <= 50)
434*4882a593Smuzhiyun 		rtw_udelay_os(us);
435*4882a593Smuzhiyun 	else if (us <= 1000)
436*4882a593Smuzhiyun 		rtw_usleep_os(us);
437*4882a593Smuzhiyun 	else
438*4882a593Smuzhiyun 		rtw_msleep_os(RTW_DIV_ROUND_UP(us, 1000));
439*4882a593Smuzhiyun }
440*4882a593Smuzhiyun 
_halmac_mutex_init(void * p,HALMAC_MUTEX * pMutex)441*4882a593Smuzhiyun static u8 _halmac_mutex_init(void *p, HALMAC_MUTEX *pMutex)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	_rtw_mutex_init(pMutex);
444*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun 
_halmac_mutex_deinit(void * p,HALMAC_MUTEX * pMutex)447*4882a593Smuzhiyun static u8 _halmac_mutex_deinit(void *p, HALMAC_MUTEX *pMutex)
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun 	_rtw_mutex_free(pMutex);
450*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun 
_halmac_mutex_lock(void * p,HALMAC_MUTEX * pMutex)453*4882a593Smuzhiyun static u8 _halmac_mutex_lock(void *p, HALMAC_MUTEX *pMutex)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun 	int err;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	err = _enter_critical_mutex(pMutex, NULL);
458*4882a593Smuzhiyun 	if (err)
459*4882a593Smuzhiyun 		return RTW_HALMAC_FAIL;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun 
_halmac_mutex_unlock(void * p,HALMAC_MUTEX * pMutex)464*4882a593Smuzhiyun static u8 _halmac_mutex_unlock(void *p, HALMAC_MUTEX *pMutex)
465*4882a593Smuzhiyun {
466*4882a593Smuzhiyun 	_exit_critical_mutex(pMutex, NULL);
467*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
468*4882a593Smuzhiyun }
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun #ifndef CONFIG_SDIO_HCI
471*4882a593Smuzhiyun #define DBG_MSG_FILTER
472*4882a593Smuzhiyun #endif
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun #ifdef DBG_MSG_FILTER
is_msg_allowed(uint drv_lv,u8 msg_lv)475*4882a593Smuzhiyun static u8 is_msg_allowed(uint drv_lv, u8 msg_lv)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun 	switch (drv_lv) {
478*4882a593Smuzhiyun 	case _DRV_NONE_:
479*4882a593Smuzhiyun 		return _FALSE;
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	case _DRV_ALWAYS_:
482*4882a593Smuzhiyun 		if (msg_lv > HALMAC_DBG_ALWAYS)
483*4882a593Smuzhiyun 			return _FALSE;
484*4882a593Smuzhiyun 		break;
485*4882a593Smuzhiyun 	case _DRV_ERR_:
486*4882a593Smuzhiyun 		if (msg_lv > HALMAC_DBG_ERR)
487*4882a593Smuzhiyun 			return _FALSE;
488*4882a593Smuzhiyun 		break;
489*4882a593Smuzhiyun 	case _DRV_WARNING_:
490*4882a593Smuzhiyun 		if (msg_lv > HALMAC_DBG_WARN)
491*4882a593Smuzhiyun 			return _FALSE;
492*4882a593Smuzhiyun 		break;
493*4882a593Smuzhiyun 	case _DRV_INFO_:
494*4882a593Smuzhiyun 		if (msg_lv >= HALMAC_DBG_TRACE)
495*4882a593Smuzhiyun 			return _FALSE;
496*4882a593Smuzhiyun 		break;
497*4882a593Smuzhiyun 	}
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	return _TRUE;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun #endif /* DBG_MSG_FILTER */
502*4882a593Smuzhiyun 
_halmac_msg_print(void * p,u32 msg_type,u8 msg_level,s8 * fmt,...)503*4882a593Smuzhiyun static u8 _halmac_msg_print(void *p, u32 msg_type, u8 msg_level, s8 *fmt, ...)
504*4882a593Smuzhiyun {
505*4882a593Smuzhiyun #define MSG_LEN		100
506*4882a593Smuzhiyun 	va_list args;
507*4882a593Smuzhiyun 	u8 str[MSG_LEN] = {0};
508*4882a593Smuzhiyun #ifdef DBG_MSG_FILTER
509*4882a593Smuzhiyun 	uint drv_level = _DRV_NONE_;
510*4882a593Smuzhiyun #endif
511*4882a593Smuzhiyun 	int err;
512*4882a593Smuzhiyun 	u8 ret = RTW_HALMAC_SUCCESS;
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun #ifdef DBG_MSG_FILTER
516*4882a593Smuzhiyun #ifdef CONFIG_RTW_DEBUG
517*4882a593Smuzhiyun 	drv_level = rtw_drv_log_level;
518*4882a593Smuzhiyun #endif
519*4882a593Smuzhiyun 	if (is_msg_allowed(drv_level, msg_level) == _FALSE)
520*4882a593Smuzhiyun 		return ret;
521*4882a593Smuzhiyun #endif
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun 	str[0] = '\n';
524*4882a593Smuzhiyun 	va_start(args, fmt);
525*4882a593Smuzhiyun 	err = vsnprintf(str, MSG_LEN, fmt, args);
526*4882a593Smuzhiyun 	va_end(args);
527*4882a593Smuzhiyun 
528*4882a593Smuzhiyun 	/* An output error is encountered */
529*4882a593Smuzhiyun 	if (err < 0)
530*4882a593Smuzhiyun 		return RTW_HALMAC_FAIL;
531*4882a593Smuzhiyun 	/* Output may be truncated due to size limit */
532*4882a593Smuzhiyun 	if ((err == (MSG_LEN - 1)) && (str[MSG_LEN - 2] != '\n'))
533*4882a593Smuzhiyun 		ret = RTW_HALMAC_FAIL;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	if (msg_level == HALMAC_DBG_ALWAYS)
536*4882a593Smuzhiyun 		RTW_PRINT(MSG_PREFIX "%s", str);
537*4882a593Smuzhiyun 	else if (msg_level <= HALMAC_DBG_ERR)
538*4882a593Smuzhiyun 		RTW_ERR(MSG_PREFIX "%s", str);
539*4882a593Smuzhiyun 	else if (msg_level <= HALMAC_DBG_WARN)
540*4882a593Smuzhiyun 		RTW_WARN(MSG_PREFIX "%s", str);
541*4882a593Smuzhiyun 	else
542*4882a593Smuzhiyun 		RTW_DBG(MSG_PREFIX "%s", str);
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	return ret;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
_halmac_buff_print(void * p,u32 msg_type,u8 msg_level,s8 * buf,u32 size)547*4882a593Smuzhiyun static u8 _halmac_buff_print(void *p, u32 msg_type, u8 msg_level, s8 *buf, u32 size)
548*4882a593Smuzhiyun {
549*4882a593Smuzhiyun 	if (msg_level <= HALMAC_DBG_WARN)
550*4882a593Smuzhiyun 		RTW_INFO_DUMP(MSG_PREFIX, buf, size);
551*4882a593Smuzhiyun 	else
552*4882a593Smuzhiyun 		RTW_DBG_DUMP(MSG_PREFIX, buf, size);
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun const char *const RTW_HALMAC_FEATURE_NAME[] = {
559*4882a593Smuzhiyun 	"HALMAC_FEATURE_CFG_PARA",
560*4882a593Smuzhiyun 	"HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE",
561*4882a593Smuzhiyun 	"HALMAC_FEATURE_DUMP_LOGICAL_EFUSE",
562*4882a593Smuzhiyun 	"HALMAC_FEATURE_DUMP_LOGICAL_EFUSE_MASK",
563*4882a593Smuzhiyun 	"HALMAC_FEATURE_UPDATE_PACKET",
564*4882a593Smuzhiyun 	"HALMAC_FEATURE_SEND_SCAN_PACKET",
565*4882a593Smuzhiyun 	"HALMAC_FEATURE_DROP_SCAN_PACKET",
566*4882a593Smuzhiyun 	"HALMAC_FEATURE_UPDATE_DATAPACK",
567*4882a593Smuzhiyun 	"HALMAC_FEATURE_RUN_DATAPACK",
568*4882a593Smuzhiyun 	"HALMAC_FEATURE_CHANNEL_SWITCH",
569*4882a593Smuzhiyun 	"HALMAC_FEATURE_IQK",
570*4882a593Smuzhiyun 	"HALMAC_FEATURE_POWER_TRACKING",
571*4882a593Smuzhiyun 	"HALMAC_FEATURE_PSD",
572*4882a593Smuzhiyun 	"HALMAC_FEATURE_FW_SNDING",
573*4882a593Smuzhiyun 	"HALMAC_FEATURE_DPK",
574*4882a593Smuzhiyun 	"HALMAC_FEATURE_ALL"
575*4882a593Smuzhiyun };
576*4882a593Smuzhiyun 
is_valid_id_status(enum halmac_feature_id id,enum halmac_cmd_process_status status)577*4882a593Smuzhiyun static inline u8 is_valid_id_status(enum halmac_feature_id id, enum halmac_cmd_process_status status)
578*4882a593Smuzhiyun {
579*4882a593Smuzhiyun 	switch (id) {
580*4882a593Smuzhiyun 	case HALMAC_FEATURE_CFG_PARA:
581*4882a593Smuzhiyun 		RTW_DBG("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
582*4882a593Smuzhiyun 		break;
583*4882a593Smuzhiyun 	case HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE:
584*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
585*4882a593Smuzhiyun 		if (HALMAC_CMD_PROCESS_DONE != status)
586*4882a593Smuzhiyun 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
587*4882a593Smuzhiyun 				 __FUNCTION__, id, status);
588*4882a593Smuzhiyun 		break;
589*4882a593Smuzhiyun 	case HALMAC_FEATURE_DUMP_LOGICAL_EFUSE:
590*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
591*4882a593Smuzhiyun 		if (HALMAC_CMD_PROCESS_DONE != status)
592*4882a593Smuzhiyun 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
593*4882a593Smuzhiyun 				 __FUNCTION__, id, status);
594*4882a593Smuzhiyun 		break;
595*4882a593Smuzhiyun 	case HALMAC_FEATURE_UPDATE_PACKET:
596*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
597*4882a593Smuzhiyun 		if (status != HALMAC_CMD_PROCESS_DONE)
598*4882a593Smuzhiyun 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
599*4882a593Smuzhiyun 				 __FUNCTION__, id, status);
600*4882a593Smuzhiyun 		break;
601*4882a593Smuzhiyun 	case HALMAC_FEATURE_UPDATE_DATAPACK:
602*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
603*4882a593Smuzhiyun 		break;
604*4882a593Smuzhiyun 	case HALMAC_FEATURE_RUN_DATAPACK:
605*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
606*4882a593Smuzhiyun 		break;
607*4882a593Smuzhiyun 	case HALMAC_FEATURE_CHANNEL_SWITCH:
608*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
609*4882a593Smuzhiyun 		if ((status != HALMAC_CMD_PROCESS_DONE) && (status != HALMAC_CMD_PROCESS_RCVD))
610*4882a593Smuzhiyun 			RTW_INFO("%s: id(%d) unspecified status(%d)!\n",
611*4882a593Smuzhiyun 				 __FUNCTION__, id, status);
612*4882a593Smuzhiyun 		if (status == HALMAC_CMD_PROCESS_DONE)
613*4882a593Smuzhiyun 			return _FALSE;
614*4882a593Smuzhiyun 		break;
615*4882a593Smuzhiyun 	case HALMAC_FEATURE_IQK:
616*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
617*4882a593Smuzhiyun 		break;
618*4882a593Smuzhiyun 	case HALMAC_FEATURE_POWER_TRACKING:
619*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
620*4882a593Smuzhiyun 		break;
621*4882a593Smuzhiyun 	case HALMAC_FEATURE_PSD:
622*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
623*4882a593Smuzhiyun 		break;
624*4882a593Smuzhiyun 	case HALMAC_FEATURE_FW_SNDING:
625*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
626*4882a593Smuzhiyun 		break;
627*4882a593Smuzhiyun 	case HALMAC_FEATURE_DPK:
628*4882a593Smuzhiyun 		if (status == HALMAC_CMD_PROCESS_RCVD)
629*4882a593Smuzhiyun 			return _FALSE;
630*4882a593Smuzhiyun 		if ((status != HALMAC_CMD_PROCESS_DONE)
631*4882a593Smuzhiyun 		    || (status != HALMAC_CMD_PROCESS_ERROR))
632*4882a593Smuzhiyun 			RTW_WARN("%s: %s unexpected status(0x%x)!\n",
633*4882a593Smuzhiyun 				 __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id],
634*4882a593Smuzhiyun 				 status);
635*4882a593Smuzhiyun 		break;
636*4882a593Smuzhiyun 	case HALMAC_FEATURE_ALL:
637*4882a593Smuzhiyun 		RTW_INFO("%s: %s\n", __FUNCTION__, RTW_HALMAC_FEATURE_NAME[id]);
638*4882a593Smuzhiyun 		break;
639*4882a593Smuzhiyun 	default:
640*4882a593Smuzhiyun 		RTW_ERR("%s: unknown feature id(%d)\n", __FUNCTION__, id);
641*4882a593Smuzhiyun 		return _FALSE;
642*4882a593Smuzhiyun 	}
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	return _TRUE;
645*4882a593Smuzhiyun }
646*4882a593Smuzhiyun 
init_halmac_event_with_waittime(struct dvobj_priv * d,enum halmac_feature_id id,u8 * buf,u32 size,u32 time)647*4882a593Smuzhiyun static int init_halmac_event_with_waittime(struct dvobj_priv *d, enum halmac_feature_id id, u8 *buf, u32 size, u32 time)
648*4882a593Smuzhiyun {
649*4882a593Smuzhiyun 	struct submit_ctx *sctx;
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 	if (!d->hmpriv.indicator[id].sctx) {
653*4882a593Smuzhiyun 		sctx = (struct submit_ctx *)rtw_zmalloc(sizeof(*sctx));
654*4882a593Smuzhiyun 		if (!sctx)
655*4882a593Smuzhiyun 			return -1;
656*4882a593Smuzhiyun 	} else {
657*4882a593Smuzhiyun 		RTW_WARN("%s: id(%d) sctx is not NULL!!\n", __FUNCTION__, id);
658*4882a593Smuzhiyun 		sctx = d->hmpriv.indicator[id].sctx;
659*4882a593Smuzhiyun 		d->hmpriv.indicator[id].sctx = NULL;
660*4882a593Smuzhiyun 	}
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	rtw_sctx_init(sctx, time);
663*4882a593Smuzhiyun 	d->hmpriv.indicator[id].buffer = buf;
664*4882a593Smuzhiyun 	d->hmpriv.indicator[id].buf_size = size;
665*4882a593Smuzhiyun 	d->hmpriv.indicator[id].ret_size = 0;
666*4882a593Smuzhiyun 	d->hmpriv.indicator[id].status = 0;
667*4882a593Smuzhiyun 	/* fill sctx at least to sure other variables are all ready! */
668*4882a593Smuzhiyun 	d->hmpriv.indicator[id].sctx = sctx;
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	return 0;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun 
init_halmac_event(struct dvobj_priv * d,enum halmac_feature_id id,u8 * buf,u32 size)673*4882a593Smuzhiyun static inline int init_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id, u8 *buf, u32 size)
674*4882a593Smuzhiyun {
675*4882a593Smuzhiyun 	return init_halmac_event_with_waittime(d, id, buf, size, DEFAULT_INDICATOR_TIMELMT);
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun 
free_halmac_event(struct dvobj_priv * d,enum halmac_feature_id id)678*4882a593Smuzhiyun static void free_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun 	struct submit_ctx *sctx;
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 
683*4882a593Smuzhiyun 	if (!d->hmpriv.indicator[id].sctx)
684*4882a593Smuzhiyun 		return;
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun 	sctx = d->hmpriv.indicator[id].sctx;
687*4882a593Smuzhiyun 	d->hmpriv.indicator[id].sctx = NULL;
688*4882a593Smuzhiyun 	rtw_mfree((u8 *)sctx, sizeof(*sctx));
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun 
wait_halmac_event(struct dvobj_priv * d,enum halmac_feature_id id)691*4882a593Smuzhiyun static int wait_halmac_event(struct dvobj_priv *d, enum halmac_feature_id id)
692*4882a593Smuzhiyun {
693*4882a593Smuzhiyun 	struct halmac_adapter *mac;
694*4882a593Smuzhiyun 	struct halmac_api *api;
695*4882a593Smuzhiyun 	struct submit_ctx *sctx;
696*4882a593Smuzhiyun 	int status;
697*4882a593Smuzhiyun 	int ret;
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun 
700*4882a593Smuzhiyun 	sctx = d->hmpriv.indicator[id].sctx;
701*4882a593Smuzhiyun 	if (!sctx)
702*4882a593Smuzhiyun 		return -1;
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun 	ret = rtw_sctx_wait(sctx, RTW_HALMAC_FEATURE_NAME[id]);
705*4882a593Smuzhiyun 	status = sctx->status;
706*4882a593Smuzhiyun 	free_halmac_event(d, id);
707*4882a593Smuzhiyun 	if (_SUCCESS == ret)
708*4882a593Smuzhiyun 		return 0;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	/* If no one change sctx->status, it is timeout case */
711*4882a593Smuzhiyun 	if (status == 0)
712*4882a593Smuzhiyun 		status = RTW_SCTX_DONE_TIMEOUT;
713*4882a593Smuzhiyun 	RTW_ERR("%s: id(%d, %s) status=0x%x ! Reset HALMAC state!\n",
714*4882a593Smuzhiyun 		__FUNCTION__, id, RTW_HALMAC_FEATURE_NAME[id], status);
715*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
716*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
717*4882a593Smuzhiyun 	api->halmac_reset_feature(mac, id);
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	return -1;
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun 
722*4882a593Smuzhiyun /*
723*4882a593Smuzhiyun  * Return:
724*4882a593Smuzhiyun  *	Always return RTW_HALMAC_SUCCESS, HALMAC don't care the return value.
725*4882a593Smuzhiyun  */
_halmac_event_indication(void * p,enum halmac_feature_id feature_id,enum halmac_cmd_process_status process_status,u8 * buf,u32 size)726*4882a593Smuzhiyun static u8 _halmac_event_indication(void *p, enum halmac_feature_id feature_id,
727*4882a593Smuzhiyun 				enum halmac_cmd_process_status process_status,
728*4882a593Smuzhiyun 				u8 *buf, u32 size)
729*4882a593Smuzhiyun {
730*4882a593Smuzhiyun 	struct dvobj_priv *d;
731*4882a593Smuzhiyun 	PADAPTER adapter;
732*4882a593Smuzhiyun 	PHAL_DATA_TYPE hal;
733*4882a593Smuzhiyun 	struct halmac_indicator *tbl, *indicator;
734*4882a593Smuzhiyun 	struct submit_ctx *sctx;
735*4882a593Smuzhiyun 	u32 cpsz;
736*4882a593Smuzhiyun 	u8 ret;
737*4882a593Smuzhiyun 
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun 	d = (struct dvobj_priv *)p;
740*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
741*4882a593Smuzhiyun 	hal = GET_HAL_DATA(adapter);
742*4882a593Smuzhiyun 	tbl = d->hmpriv.indicator;
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun 	/* Filter(Skip) middle status indication */
745*4882a593Smuzhiyun 	ret = is_valid_id_status(feature_id, process_status);
746*4882a593Smuzhiyun 	if (_FALSE == ret)
747*4882a593Smuzhiyun 		goto exit;
748*4882a593Smuzhiyun 
749*4882a593Smuzhiyun 	indicator = &tbl[feature_id];
750*4882a593Smuzhiyun 	indicator->status = process_status;
751*4882a593Smuzhiyun 	indicator->ret_size = size;
752*4882a593Smuzhiyun 	if (!indicator->sctx) {
753*4882a593Smuzhiyun 		RTW_WARN("%s: id(%d, %s) is not waiting!!\n", __FUNCTION__,
754*4882a593Smuzhiyun 			 feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
755*4882a593Smuzhiyun 		goto exit;
756*4882a593Smuzhiyun 	}
757*4882a593Smuzhiyun 	sctx = indicator->sctx;
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	if (HALMAC_CMD_PROCESS_ERROR == process_status) {
760*4882a593Smuzhiyun 		RTW_ERR("%s: id(%d, %s) Something wrong!!\n", __FUNCTION__,
761*4882a593Smuzhiyun 			feature_id, RTW_HALMAC_FEATURE_NAME[feature_id]);
762*4882a593Smuzhiyun 		if ((size == 1) && buf)
763*4882a593Smuzhiyun 			RTW_ERR("%s: error code=0x%x\n", __FUNCTION__, *buf);
764*4882a593Smuzhiyun 		rtw_sctx_done_err(&sctx, RTW_SCTX_DONE_UNKNOWN);
765*4882a593Smuzhiyun 		goto exit;
766*4882a593Smuzhiyun 	}
767*4882a593Smuzhiyun 
768*4882a593Smuzhiyun 	if (size > indicator->buf_size) {
769*4882a593Smuzhiyun 		RTW_WARN("%s: id(%d, %s) buffer is not enough(%d<%d), "
770*4882a593Smuzhiyun 			 "and data will be truncated!\n",
771*4882a593Smuzhiyun 			 __FUNCTION__,
772*4882a593Smuzhiyun 			 feature_id, RTW_HALMAC_FEATURE_NAME[feature_id],
773*4882a593Smuzhiyun 			 indicator->buf_size, size);
774*4882a593Smuzhiyun 		cpsz = indicator->buf_size;
775*4882a593Smuzhiyun 	} else {
776*4882a593Smuzhiyun 		cpsz = size;
777*4882a593Smuzhiyun 	}
778*4882a593Smuzhiyun 	if (cpsz && indicator->buffer)
779*4882a593Smuzhiyun 		_rtw_memcpy(indicator->buffer, buf, cpsz);
780*4882a593Smuzhiyun 
781*4882a593Smuzhiyun 	rtw_sctx_done(&sctx);
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun exit:
784*4882a593Smuzhiyun 	return RTW_HALMAC_SUCCESS;
785*4882a593Smuzhiyun }
786*4882a593Smuzhiyun 
787*4882a593Smuzhiyun struct halmac_platform_api rtw_halmac_platform_api = {
788*4882a593Smuzhiyun 	/* R/W register */
789*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
790*4882a593Smuzhiyun 	.SDIO_CMD52_READ = _halmac_sdio_cmd52_read,
791*4882a593Smuzhiyun 	.SDIO_CMD53_READ_8 = _halmac_sdio_reg_read_8,
792*4882a593Smuzhiyun 	.SDIO_CMD53_READ_16 = _halmac_sdio_reg_read_16,
793*4882a593Smuzhiyun 	.SDIO_CMD53_READ_32 = _halmac_sdio_reg_read_32,
794*4882a593Smuzhiyun 	.SDIO_CMD53_READ_N = _halmac_sdio_reg_read_n,
795*4882a593Smuzhiyun 	.SDIO_CMD52_WRITE = _halmac_sdio_cmd52_write,
796*4882a593Smuzhiyun 	.SDIO_CMD53_WRITE_8 = _halmac_sdio_reg_write_8,
797*4882a593Smuzhiyun 	.SDIO_CMD53_WRITE_16 = _halmac_sdio_reg_write_16,
798*4882a593Smuzhiyun 	.SDIO_CMD53_WRITE_32 = _halmac_sdio_reg_write_32,
799*4882a593Smuzhiyun 	.SDIO_CMD52_CIA_READ = _halmac_sdio_read_cia,
800*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
801*4882a593Smuzhiyun #if defined(CONFIG_USB_HCI) || defined(CONFIG_PCI_HCI)
802*4882a593Smuzhiyun 	.REG_READ_8 = _halmac_reg_read_8,
803*4882a593Smuzhiyun 	.REG_READ_16 = _halmac_reg_read_16,
804*4882a593Smuzhiyun 	.REG_READ_32 = _halmac_reg_read_32,
805*4882a593Smuzhiyun 	.REG_WRITE_8 = _halmac_reg_write_8,
806*4882a593Smuzhiyun 	.REG_WRITE_16 = _halmac_reg_write_16,
807*4882a593Smuzhiyun 	.REG_WRITE_32 = _halmac_reg_write_32,
808*4882a593Smuzhiyun #endif /* CONFIG_USB_HCI || CONFIG_PCI_HCI */
809*4882a593Smuzhiyun 
810*4882a593Smuzhiyun #ifdef DBG_IO
811*4882a593Smuzhiyun 	.READ_MONITOR = _halmac_reg_read_monitor,
812*4882a593Smuzhiyun 	.WRITE_MONITOR = _halmac_reg_write_monitor,
813*4882a593Smuzhiyun #endif
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 	/* Write data */
816*4882a593Smuzhiyun #if 0
817*4882a593Smuzhiyun 	/* impletement in HAL-IC level */
818*4882a593Smuzhiyun 	.SEND_RSVD_PAGE = sdio_write_data_rsvd_page,
819*4882a593Smuzhiyun 	.SEND_H2C_PKT = sdio_write_data_h2c,
820*4882a593Smuzhiyun #endif
821*4882a593Smuzhiyun 	/* Memory allocate */
822*4882a593Smuzhiyun 	.RTL_FREE = _halmac_mfree,
823*4882a593Smuzhiyun 	.RTL_MALLOC = _halmac_malloc,
824*4882a593Smuzhiyun 	.RTL_MEMCPY = _halmac_memcpy,
825*4882a593Smuzhiyun 	.RTL_MEMSET = _halmac_memset,
826*4882a593Smuzhiyun 
827*4882a593Smuzhiyun 	/* Sleep */
828*4882a593Smuzhiyun 	.RTL_DELAY_US = _halmac_udelay,
829*4882a593Smuzhiyun 
830*4882a593Smuzhiyun 	/* Process Synchronization */
831*4882a593Smuzhiyun 	.MUTEX_INIT = _halmac_mutex_init,
832*4882a593Smuzhiyun 	.MUTEX_DEINIT = _halmac_mutex_deinit,
833*4882a593Smuzhiyun 	.MUTEX_LOCK = _halmac_mutex_lock,
834*4882a593Smuzhiyun 	.MUTEX_UNLOCK = _halmac_mutex_unlock,
835*4882a593Smuzhiyun 
836*4882a593Smuzhiyun 	.MSG_PRINT = _halmac_msg_print,
837*4882a593Smuzhiyun 	.BUFF_PRINT = _halmac_buff_print,
838*4882a593Smuzhiyun 	.EVENT_INDICATION = _halmac_event_indication,
839*4882a593Smuzhiyun };
840*4882a593Smuzhiyun 
rtw_halmac_read8(struct intf_hdl * pintfhdl,u32 addr)841*4882a593Smuzhiyun u8 rtw_halmac_read8(struct intf_hdl *pintfhdl, u32 addr)
842*4882a593Smuzhiyun {
843*4882a593Smuzhiyun 	struct halmac_adapter *mac;
844*4882a593Smuzhiyun 	struct halmac_api *api;
845*4882a593Smuzhiyun 
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
848*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
849*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
850*4882a593Smuzhiyun 
851*4882a593Smuzhiyun 	return api->halmac_reg_read_8(mac, addr);
852*4882a593Smuzhiyun }
853*4882a593Smuzhiyun 
rtw_halmac_read16(struct intf_hdl * pintfhdl,u32 addr)854*4882a593Smuzhiyun u16 rtw_halmac_read16(struct intf_hdl *pintfhdl, u32 addr)
855*4882a593Smuzhiyun {
856*4882a593Smuzhiyun 	struct halmac_adapter *mac;
857*4882a593Smuzhiyun 	struct halmac_api *api;
858*4882a593Smuzhiyun 
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
861*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
862*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
863*4882a593Smuzhiyun 
864*4882a593Smuzhiyun 	return api->halmac_reg_read_16(mac, addr);
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun 
rtw_halmac_read32(struct intf_hdl * pintfhdl,u32 addr)867*4882a593Smuzhiyun u32 rtw_halmac_read32(struct intf_hdl *pintfhdl, u32 addr)
868*4882a593Smuzhiyun {
869*4882a593Smuzhiyun 	struct halmac_adapter *mac;
870*4882a593Smuzhiyun 	struct halmac_api *api;
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun 
873*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
874*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
875*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
876*4882a593Smuzhiyun 
877*4882a593Smuzhiyun 	return api->halmac_reg_read_32(mac, addr);
878*4882a593Smuzhiyun }
879*4882a593Smuzhiyun 
_read_register(struct dvobj_priv * d,u32 addr,u32 cnt,u8 * buf)880*4882a593Smuzhiyun static void _read_register(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
881*4882a593Smuzhiyun {
882*4882a593Smuzhiyun #if 1
883*4882a593Smuzhiyun 	struct _ADAPTER *a;
884*4882a593Smuzhiyun 	u32 i, n;
885*4882a593Smuzhiyun 	u16 val16;
886*4882a593Smuzhiyun 	u32 val32;
887*4882a593Smuzhiyun 
888*4882a593Smuzhiyun 
889*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 	i = addr & 0x3;
892*4882a593Smuzhiyun 	/* Handle address not start from 4 bytes alignment case */
893*4882a593Smuzhiyun 	if (i) {
894*4882a593Smuzhiyun 		val32 = cpu_to_le32(rtw_read32(a, addr & ~0x3));
895*4882a593Smuzhiyun 		n = 4 - i;
896*4882a593Smuzhiyun 		_rtw_memcpy(buf, ((u8 *)&val32) + i, n);
897*4882a593Smuzhiyun 		i = n;
898*4882a593Smuzhiyun 		cnt -= n;
899*4882a593Smuzhiyun 	}
900*4882a593Smuzhiyun 
901*4882a593Smuzhiyun 	while (cnt) {
902*4882a593Smuzhiyun 		if (cnt >= 4)
903*4882a593Smuzhiyun 			n = 4;
904*4882a593Smuzhiyun 		else if (cnt >= 2)
905*4882a593Smuzhiyun 			n = 2;
906*4882a593Smuzhiyun 		else
907*4882a593Smuzhiyun 			n = 1;
908*4882a593Smuzhiyun 		cnt -= n;
909*4882a593Smuzhiyun 
910*4882a593Smuzhiyun 		switch (n) {
911*4882a593Smuzhiyun 		case 1:
912*4882a593Smuzhiyun 			buf[i] = rtw_read8(a, addr+i);
913*4882a593Smuzhiyun 			i++;
914*4882a593Smuzhiyun 			break;
915*4882a593Smuzhiyun 		case 2:
916*4882a593Smuzhiyun 			val16 = cpu_to_le16(rtw_read16(a, addr+i));
917*4882a593Smuzhiyun 			_rtw_memcpy(&buf[i], &val16, 2);
918*4882a593Smuzhiyun 			i += 2;
919*4882a593Smuzhiyun 			break;
920*4882a593Smuzhiyun 		case 4:
921*4882a593Smuzhiyun 			val32 = cpu_to_le32(rtw_read32(a, addr+i));
922*4882a593Smuzhiyun 			_rtw_memcpy(&buf[i], &val32, 4);
923*4882a593Smuzhiyun 			i += 4;
924*4882a593Smuzhiyun 			break;
925*4882a593Smuzhiyun 		}
926*4882a593Smuzhiyun 	}
927*4882a593Smuzhiyun #else
928*4882a593Smuzhiyun 	struct _ADAPTER *a;
929*4882a593Smuzhiyun 	u32 i;
930*4882a593Smuzhiyun 
931*4882a593Smuzhiyun 
932*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
933*4882a593Smuzhiyun 	for (i = 0; i < cnt; i++)
934*4882a593Smuzhiyun 		buf[i] = rtw_read8(a, addr + i);
935*4882a593Smuzhiyun #endif
936*4882a593Smuzhiyun }
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
_sdio_read_local(struct dvobj_priv * d,u32 addr,u32 cnt,u8 * buf)939*4882a593Smuzhiyun static int _sdio_read_local(struct dvobj_priv *d, u32 addr, u32 cnt, u8 *buf)
940*4882a593Smuzhiyun {
941*4882a593Smuzhiyun 	struct halmac_adapter *mac;
942*4882a593Smuzhiyun 	struct halmac_api *api;
943*4882a593Smuzhiyun 	enum halmac_ret_status status;
944*4882a593Smuzhiyun 
945*4882a593Smuzhiyun 
946*4882a593Smuzhiyun 	if (buf == NULL)
947*4882a593Smuzhiyun 		return -1;
948*4882a593Smuzhiyun 
949*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
950*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
951*4882a593Smuzhiyun 
952*4882a593Smuzhiyun 	status = api->halmac_reg_sdio_cmd53_read_n(mac, addr, cnt, buf);
953*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
954*4882a593Smuzhiyun 		RTW_ERR("%s: addr=0x%08x cnt=%d err=%d\n",
955*4882a593Smuzhiyun 			__FUNCTION__, addr, cnt, status);
956*4882a593Smuzhiyun 		return -1;
957*4882a593Smuzhiyun 	}
958*4882a593Smuzhiyun 
959*4882a593Smuzhiyun 	return 0;
960*4882a593Smuzhiyun }
961*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
962*4882a593Smuzhiyun 
rtw_halmac_read_mem(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pmem)963*4882a593Smuzhiyun void rtw_halmac_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem)
964*4882a593Smuzhiyun {
965*4882a593Smuzhiyun 	struct dvobj_priv *d;
966*4882a593Smuzhiyun 
967*4882a593Smuzhiyun 
968*4882a593Smuzhiyun 	if (pmem == NULL) {
969*4882a593Smuzhiyun 		RTW_ERR("pmem is NULL\n");
970*4882a593Smuzhiyun 		return;
971*4882a593Smuzhiyun 	}
972*4882a593Smuzhiyun 
973*4882a593Smuzhiyun 	d = pintfhdl->pintf_dev;
974*4882a593Smuzhiyun 
975*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
976*4882a593Smuzhiyun 	if (addr & 0xFFFF0000) {
977*4882a593Smuzhiyun 		int err = 0;
978*4882a593Smuzhiyun 
979*4882a593Smuzhiyun 		err = _sdio_read_local(d, addr, cnt, pmem);
980*4882a593Smuzhiyun 		if (!err)
981*4882a593Smuzhiyun 			return;
982*4882a593Smuzhiyun 	}
983*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
984*4882a593Smuzhiyun 
985*4882a593Smuzhiyun 	_read_register(d, addr, cnt, pmem);
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun #ifdef CONFIG_SDIO_INDIRECT_ACCESS
rtw_halmac_iread8(struct intf_hdl * pintfhdl,u32 addr)989*4882a593Smuzhiyun u8 rtw_halmac_iread8(struct intf_hdl *pintfhdl, u32 addr)
990*4882a593Smuzhiyun {
991*4882a593Smuzhiyun 	struct halmac_adapter *mac;
992*4882a593Smuzhiyun 	struct halmac_api *api;
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
995*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
996*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
997*4882a593Smuzhiyun 
998*4882a593Smuzhiyun 	/*return api->halmac_reg_read_indirect_8(mac, addr);*/
999*4882a593Smuzhiyun 	return api->halmac_reg_read_8(mac, addr);
1000*4882a593Smuzhiyun }
1001*4882a593Smuzhiyun 
rtw_halmac_iread16(struct intf_hdl * pintfhdl,u32 addr)1002*4882a593Smuzhiyun u16 rtw_halmac_iread16(struct intf_hdl *pintfhdl, u32 addr)
1003*4882a593Smuzhiyun {
1004*4882a593Smuzhiyun 	struct halmac_adapter *mac;
1005*4882a593Smuzhiyun 	struct halmac_api *api;
1006*4882a593Smuzhiyun 	u16 val16 = 0;
1007*4882a593Smuzhiyun 
1008*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
1009*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1010*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
1011*4882a593Smuzhiyun 
1012*4882a593Smuzhiyun 	/*return api->halmac_reg_read_indirect_16(mac, addr);*/
1013*4882a593Smuzhiyun 	return api->halmac_reg_read_16(mac, addr);
1014*4882a593Smuzhiyun }
1015*4882a593Smuzhiyun 
rtw_halmac_iread32(struct intf_hdl * pintfhdl,u32 addr)1016*4882a593Smuzhiyun u32 rtw_halmac_iread32(struct intf_hdl *pintfhdl, u32 addr)
1017*4882a593Smuzhiyun {
1018*4882a593Smuzhiyun 	struct halmac_adapter *mac;
1019*4882a593Smuzhiyun 	struct halmac_api *api;
1020*4882a593Smuzhiyun 
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
1023*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1024*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 	return api->halmac_reg_read_indirect_32(mac, addr);
1027*4882a593Smuzhiyun }
1028*4882a593Smuzhiyun #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
1029*4882a593Smuzhiyun 
rtw_halmac_write8(struct intf_hdl * pintfhdl,u32 addr,u8 value)1030*4882a593Smuzhiyun int rtw_halmac_write8(struct intf_hdl *pintfhdl, u32 addr, u8 value)
1031*4882a593Smuzhiyun {
1032*4882a593Smuzhiyun 	struct halmac_adapter *mac;
1033*4882a593Smuzhiyun 	struct halmac_api *api;
1034*4882a593Smuzhiyun 	enum halmac_ret_status status;
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 
1037*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
1038*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1039*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
1040*4882a593Smuzhiyun 
1041*4882a593Smuzhiyun 	status = api->halmac_reg_write_8(mac, addr, value);
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun 	if (status == HALMAC_RET_SUCCESS)
1044*4882a593Smuzhiyun 		return 0;
1045*4882a593Smuzhiyun 
1046*4882a593Smuzhiyun 	return -1;
1047*4882a593Smuzhiyun }
1048*4882a593Smuzhiyun 
rtw_halmac_write16(struct intf_hdl * pintfhdl,u32 addr,u16 value)1049*4882a593Smuzhiyun int rtw_halmac_write16(struct intf_hdl *pintfhdl, u32 addr, u16 value)
1050*4882a593Smuzhiyun {
1051*4882a593Smuzhiyun 	struct halmac_adapter *mac;
1052*4882a593Smuzhiyun 	struct halmac_api *api;
1053*4882a593Smuzhiyun 	enum halmac_ret_status status;
1054*4882a593Smuzhiyun 
1055*4882a593Smuzhiyun 
1056*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
1057*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1058*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
1059*4882a593Smuzhiyun 
1060*4882a593Smuzhiyun 	status = api->halmac_reg_write_16(mac, addr, value);
1061*4882a593Smuzhiyun 
1062*4882a593Smuzhiyun 	if (status == HALMAC_RET_SUCCESS)
1063*4882a593Smuzhiyun 		return 0;
1064*4882a593Smuzhiyun 
1065*4882a593Smuzhiyun 	return -1;
1066*4882a593Smuzhiyun }
1067*4882a593Smuzhiyun 
rtw_halmac_write32(struct intf_hdl * pintfhdl,u32 addr,u32 value)1068*4882a593Smuzhiyun int rtw_halmac_write32(struct intf_hdl *pintfhdl, u32 addr, u32 value)
1069*4882a593Smuzhiyun {
1070*4882a593Smuzhiyun 	struct halmac_adapter *mac;
1071*4882a593Smuzhiyun 	struct halmac_api *api;
1072*4882a593Smuzhiyun 	enum halmac_ret_status status;
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun 	/* WARNING: pintf_dev should not be null! */
1076*4882a593Smuzhiyun 	mac = dvobj_to_halmac(pintfhdl->pintf_dev);
1077*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
1078*4882a593Smuzhiyun 
1079*4882a593Smuzhiyun 	status = api->halmac_reg_write_32(mac, addr, value);
1080*4882a593Smuzhiyun 
1081*4882a593Smuzhiyun 	if (status == HALMAC_RET_SUCCESS)
1082*4882a593Smuzhiyun 		return 0;
1083*4882a593Smuzhiyun 
1084*4882a593Smuzhiyun 	return -1;
1085*4882a593Smuzhiyun }
1086*4882a593Smuzhiyun 
init_write_rsvd_page_size(struct dvobj_priv * d)1087*4882a593Smuzhiyun static int init_write_rsvd_page_size(struct dvobj_priv *d)
1088*4882a593Smuzhiyun {
1089*4882a593Smuzhiyun 	struct halmac_adapter *mac;
1090*4882a593Smuzhiyun 	struct halmac_api *api;
1091*4882a593Smuzhiyun 	u32 size = 0;
1092*4882a593Smuzhiyun 	struct halmac_ofld_func_info ofld_info;
1093*4882a593Smuzhiyun 	enum halmac_ret_status status;
1094*4882a593Smuzhiyun 	int err = 0;
1095*4882a593Smuzhiyun 
1096*4882a593Smuzhiyun 
1097*4882a593Smuzhiyun #ifdef CONFIG_USB_HCI
1098*4882a593Smuzhiyun 	/* for USB do not exceed MAX_CMDBUF_SZ */
1099*4882a593Smuzhiyun 	size = 0x1000;
1100*4882a593Smuzhiyun #elif defined(CONFIG_PCI_HCI)
1101*4882a593Smuzhiyun 	size = MAX_CMDBUF_SZ - TXDESC_OFFSET;
1102*4882a593Smuzhiyun #elif defined(CONFIG_SDIO_HCI)
1103*4882a593Smuzhiyun 	size = 0x7000; /* 28KB */
1104*4882a593Smuzhiyun #else
1105*4882a593Smuzhiyun 	/* Use HALMAC default setting and don't call any function */
1106*4882a593Smuzhiyun 	return 0;
1107*4882a593Smuzhiyun #endif
1108*4882a593Smuzhiyun #if 0	/* Fail to pass coverity DEADCODE check */
1109*4882a593Smuzhiyun 	/* If size==0, use HALMAC default setting and don't call any function */
1110*4882a593Smuzhiyun 	if (!size)
1111*4882a593Smuzhiyun 		return 0;
1112*4882a593Smuzhiyun #endif
1113*4882a593Smuzhiyun 	err = rtw_halmac_set_max_dl_fw_size(d, size);
1114*4882a593Smuzhiyun 	if (err) {
1115*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to set max download fw size!\n", __FUNCTION__);
1116*4882a593Smuzhiyun 		return -1;
1117*4882a593Smuzhiyun 	}
1118*4882a593Smuzhiyun 
1119*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
1120*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
1121*4882a593Smuzhiyun 
1122*4882a593Smuzhiyun 	_rtw_memset(&ofld_info, 0, sizeof(ofld_info));
1123*4882a593Smuzhiyun 	ofld_info.halmac_malloc_max_sz = 0xFFFFFFFF;
1124*4882a593Smuzhiyun 	ofld_info.rsvd_pg_drv_buf_max_sz = size;
1125*4882a593Smuzhiyun 	status = api->halmac_ofld_func_cfg(mac, &ofld_info);
1126*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
1127*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to config offload parameters!\n", __FUNCTION__);
1128*4882a593Smuzhiyun 		return -1;
1129*4882a593Smuzhiyun 	}
1130*4882a593Smuzhiyun 
1131*4882a593Smuzhiyun 	return 0;
1132*4882a593Smuzhiyun }
1133*4882a593Smuzhiyun 
init_priv(struct halmacpriv * priv)1134*4882a593Smuzhiyun static int init_priv(struct halmacpriv *priv)
1135*4882a593Smuzhiyun {
1136*4882a593Smuzhiyun 	struct halmac_indicator *indicator;
1137*4882a593Smuzhiyun 	u32 count, size;
1138*4882a593Smuzhiyun 
1139*4882a593Smuzhiyun 
1140*4882a593Smuzhiyun 	if (priv->indicator)
1141*4882a593Smuzhiyun 		RTW_WARN("%s: HALMAC private data is not CLEAR!\n", __FUNCTION__);
1142*4882a593Smuzhiyun 	count = HALMAC_FEATURE_ALL + 1;
1143*4882a593Smuzhiyun 	size = sizeof(*indicator) * count;
1144*4882a593Smuzhiyun 	indicator = (struct halmac_indicator *)rtw_zmalloc(size);
1145*4882a593Smuzhiyun 	if (!indicator)
1146*4882a593Smuzhiyun 		return -1;
1147*4882a593Smuzhiyun 	priv->indicator = indicator;
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun 	return 0;
1150*4882a593Smuzhiyun }
1151*4882a593Smuzhiyun 
deinit_priv(struct halmacpriv * priv)1152*4882a593Smuzhiyun static void deinit_priv(struct halmacpriv *priv)
1153*4882a593Smuzhiyun {
1154*4882a593Smuzhiyun 	struct halmac_indicator *indicator;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	indicator = priv->indicator;
1158*4882a593Smuzhiyun 	priv->indicator = NULL;
1159*4882a593Smuzhiyun 	if (indicator) {
1160*4882a593Smuzhiyun 		u32 count, size;
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 		count = HALMAC_FEATURE_ALL + 1;
1163*4882a593Smuzhiyun #ifdef CONFIG_RTW_DEBUG
1164*4882a593Smuzhiyun 		{
1165*4882a593Smuzhiyun 			struct submit_ctx *sctx;
1166*4882a593Smuzhiyun 			u32 i;
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun 			for (i = 0; i < count; i++) {
1169*4882a593Smuzhiyun 				if (!indicator[i].sctx)
1170*4882a593Smuzhiyun 					continue;
1171*4882a593Smuzhiyun 
1172*4882a593Smuzhiyun 				RTW_WARN("%s: %s id(%d) sctx still exist!!\n",
1173*4882a593Smuzhiyun 					__FUNCTION__, RTW_HALMAC_FEATURE_NAME[i], i);
1174*4882a593Smuzhiyun 				sctx = indicator[i].sctx;
1175*4882a593Smuzhiyun 				indicator[i].sctx = NULL;
1176*4882a593Smuzhiyun 				rtw_mfree((u8 *)sctx, sizeof(*sctx));
1177*4882a593Smuzhiyun 			}
1178*4882a593Smuzhiyun 		}
1179*4882a593Smuzhiyun #endif /* !CONFIG_RTW_DEBUG */
1180*4882a593Smuzhiyun 		size = sizeof(*indicator) * count;
1181*4882a593Smuzhiyun 		rtw_mfree((u8 *)indicator, size);
1182*4882a593Smuzhiyun 	}
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
_sdio_ver_drv2halmac(struct dvobj_priv * d)1186*4882a593Smuzhiyun static enum halmac_sdio_spec_ver _sdio_ver_drv2halmac(struct dvobj_priv *d)
1187*4882a593Smuzhiyun {
1188*4882a593Smuzhiyun 	bool v3;
1189*4882a593Smuzhiyun 	enum halmac_sdio_spec_ver ver;
1190*4882a593Smuzhiyun 
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 	v3 = rtw_is_sdio30(dvobj_get_primary_adapter(d));
1193*4882a593Smuzhiyun 	if (v3)
1194*4882a593Smuzhiyun 		ver = HALMAC_SDIO_SPEC_VER_3_00;
1195*4882a593Smuzhiyun 	else
1196*4882a593Smuzhiyun 		ver = HALMAC_SDIO_SPEC_VER_2_00;
1197*4882a593Smuzhiyun 
1198*4882a593Smuzhiyun 	return ver;
1199*4882a593Smuzhiyun }
1200*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
1201*4882a593Smuzhiyun 
rtw_halmac_get_version(char * str,u32 len)1202*4882a593Smuzhiyun void rtw_halmac_get_version(char *str, u32 len)
1203*4882a593Smuzhiyun {
1204*4882a593Smuzhiyun 	enum halmac_ret_status status;
1205*4882a593Smuzhiyun 	struct halmac_ver ver;
1206*4882a593Smuzhiyun 
1207*4882a593Smuzhiyun 
1208*4882a593Smuzhiyun 	status = halmac_get_version(&ver);
1209*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1210*4882a593Smuzhiyun 		return;
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 	rtw_sprintf(str, len, "V%d_%02d_%02d",
1213*4882a593Smuzhiyun 		    ver.major_ver, ver.prototype_ver, ver.minor_ver);
1214*4882a593Smuzhiyun }
1215*4882a593Smuzhiyun 
rtw_halmac_init_adapter(struct dvobj_priv * d,struct halmac_platform_api * pf_api)1216*4882a593Smuzhiyun int rtw_halmac_init_adapter(struct dvobj_priv *d, struct halmac_platform_api *pf_api)
1217*4882a593Smuzhiyun {
1218*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1219*4882a593Smuzhiyun 	struct halmac_api *api;
1220*4882a593Smuzhiyun 	enum halmac_interface intf;
1221*4882a593Smuzhiyun 	enum halmac_intf_phy_platform pltfm = HALMAC_INTF_PHY_PLATFORM_ALL;
1222*4882a593Smuzhiyun 	enum halmac_ret_status status;
1223*4882a593Smuzhiyun 	int err = 0;
1224*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
1225*4882a593Smuzhiyun 	struct halmac_sdio_hw_info info;
1226*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
1227*4882a593Smuzhiyun 
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1230*4882a593Smuzhiyun 	if (halmac) {
1231*4882a593Smuzhiyun 		RTW_WARN("%s: initialize already completed!\n", __FUNCTION__);
1232*4882a593Smuzhiyun 		goto error;
1233*4882a593Smuzhiyun 	}
1234*4882a593Smuzhiyun 
1235*4882a593Smuzhiyun 	err = init_priv(&d->hmpriv);
1236*4882a593Smuzhiyun 	if (err)
1237*4882a593Smuzhiyun 		goto error;
1238*4882a593Smuzhiyun 
1239*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
1240*4882a593Smuzhiyun 	intf = HALMAC_INTERFACE_SDIO;
1241*4882a593Smuzhiyun #elif defined(CONFIG_USB_HCI)
1242*4882a593Smuzhiyun 	intf = HALMAC_INTERFACE_USB;
1243*4882a593Smuzhiyun #elif defined(CONFIG_PCI_HCI)
1244*4882a593Smuzhiyun 	intf = HALMAC_INTERFACE_PCIE;
1245*4882a593Smuzhiyun #else
1246*4882a593Smuzhiyun #warning "INTERFACE(CONFIG_XXX_HCI) not be defined!!"
1247*4882a593Smuzhiyun 	intf = HALMAC_INTERFACE_UNDEFINE;
1248*4882a593Smuzhiyun #endif
1249*4882a593Smuzhiyun 	status = halmac_init_adapter(d, pf_api, intf, &halmac, &api);
1250*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status) {
1251*4882a593Smuzhiyun 		RTW_ERR("%s: halmac_init_adapter fail!(status=%d)\n", __FUNCTION__, status);
1252*4882a593Smuzhiyun 		err = -1;
1253*4882a593Smuzhiyun 		if (halmac)
1254*4882a593Smuzhiyun 			goto deinit;
1255*4882a593Smuzhiyun 		goto free;
1256*4882a593Smuzhiyun 	}
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun 	dvobj_set_halmac(d, halmac);
1259*4882a593Smuzhiyun 
1260*4882a593Smuzhiyun 	status = api->halmac_interface_integration_tuning(halmac);
1261*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
1262*4882a593Smuzhiyun 		RTW_ERR("%s: halmac_interface_integration_tuning fail!(status=%d)\n", __FUNCTION__, status);
1263*4882a593Smuzhiyun 		err = -1;
1264*4882a593Smuzhiyun 		goto deinit;
1265*4882a593Smuzhiyun 	}
1266*4882a593Smuzhiyun 
1267*4882a593Smuzhiyun #ifdef CONFIG_PLATFORM_RTK1319
1268*4882a593Smuzhiyun 	pltfm = HALMAC_INTF_PHY_PLATFORM_DHC;
1269*4882a593Smuzhiyun #endif /* CONFIG_PLATFORM_RTK1319 */
1270*4882a593Smuzhiyun 	status = api->halmac_phy_cfg(halmac, pltfm);
1271*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
1272*4882a593Smuzhiyun 		RTW_ERR("%s: halmac_phy_cfg fail! (platform=%d, status=%d)\n",
1273*4882a593Smuzhiyun 			__FUNCTION__, pltfm, status);
1274*4882a593Smuzhiyun 		err = -1;
1275*4882a593Smuzhiyun 		goto deinit;
1276*4882a593Smuzhiyun 	}
1277*4882a593Smuzhiyun 
1278*4882a593Smuzhiyun 	init_write_rsvd_page_size(d);
1279*4882a593Smuzhiyun 
1280*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
1281*4882a593Smuzhiyun 	_rtw_memset(&info, 0, sizeof(info));
1282*4882a593Smuzhiyun 	info.spec_ver = _sdio_ver_drv2halmac(d);
1283*4882a593Smuzhiyun 	/* Convert clock speed unit to MHz from Hz */
1284*4882a593Smuzhiyun 	info.clock_speed = RTW_DIV_ROUND_UP(rtw_sdio_get_clock(d), 1000000);
1285*4882a593Smuzhiyun 	info.block_size = rtw_sdio_get_block_size(d);
1286*4882a593Smuzhiyun 	if (d->hmpriv.sdio_io_indir == 2)
1287*4882a593Smuzhiyun 		info.io_indir_flag = 0;
1288*4882a593Smuzhiyun 	else
1289*4882a593Smuzhiyun 		info.io_indir_flag = 1; /* Default enable indirect I/O */
1290*4882a593Smuzhiyun 	RTW_DBG("%s: SDIO ver=%u clock=%uMHz blk_size=%u bytes, io_indir=%u\n",
1291*4882a593Smuzhiyun 		__FUNCTION__, info.spec_ver+2, info.clock_speed,
1292*4882a593Smuzhiyun 		info.block_size, info.io_indir_flag);
1293*4882a593Smuzhiyun 	status = api->halmac_sdio_hw_info(halmac, &info);
1294*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
1295*4882a593Smuzhiyun 		RTW_ERR("%s: halmac_sdio_hw_info fail!(status=%d)\n",
1296*4882a593Smuzhiyun 			__FUNCTION__, status);
1297*4882a593Smuzhiyun 		err = -1;
1298*4882a593Smuzhiyun 		goto deinit;
1299*4882a593Smuzhiyun 	}
1300*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
1301*4882a593Smuzhiyun 
1302*4882a593Smuzhiyun 	return 0;
1303*4882a593Smuzhiyun 
1304*4882a593Smuzhiyun deinit:
1305*4882a593Smuzhiyun 	status = halmac_deinit_adapter(halmac);
1306*4882a593Smuzhiyun 	dvobj_set_halmac(d, NULL);
1307*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1308*4882a593Smuzhiyun 		RTW_ERR("%s: halmac_deinit_adapter fail!(status=%d)\n",
1309*4882a593Smuzhiyun 			__FUNCTION__, status);
1310*4882a593Smuzhiyun 
1311*4882a593Smuzhiyun free:
1312*4882a593Smuzhiyun 	deinit_priv(&d->hmpriv);
1313*4882a593Smuzhiyun 
1314*4882a593Smuzhiyun error:
1315*4882a593Smuzhiyun 	return err;
1316*4882a593Smuzhiyun }
1317*4882a593Smuzhiyun 
rtw_halmac_deinit_adapter(struct dvobj_priv * d)1318*4882a593Smuzhiyun int rtw_halmac_deinit_adapter(struct dvobj_priv *d)
1319*4882a593Smuzhiyun {
1320*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1321*4882a593Smuzhiyun 	enum halmac_ret_status status;
1322*4882a593Smuzhiyun 	int err = 0;
1323*4882a593Smuzhiyun 
1324*4882a593Smuzhiyun 
1325*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1326*4882a593Smuzhiyun 	if (halmac) {
1327*4882a593Smuzhiyun 		status = halmac_deinit_adapter(halmac);
1328*4882a593Smuzhiyun 		dvobj_set_halmac(d, NULL);
1329*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS)
1330*4882a593Smuzhiyun 			err = -1;
1331*4882a593Smuzhiyun 	}
1332*4882a593Smuzhiyun 
1333*4882a593Smuzhiyun 	deinit_priv(&d->hmpriv);
1334*4882a593Smuzhiyun 
1335*4882a593Smuzhiyun 	return err;
1336*4882a593Smuzhiyun }
1337*4882a593Smuzhiyun 
_hw_port_drv2halmac(enum _hw_port hwport)1338*4882a593Smuzhiyun static inline enum halmac_portid _hw_port_drv2halmac(enum _hw_port hwport)
1339*4882a593Smuzhiyun {
1340*4882a593Smuzhiyun 	enum halmac_portid port = HALMAC_PORTID_NUM;
1341*4882a593Smuzhiyun 
1342*4882a593Smuzhiyun 
1343*4882a593Smuzhiyun 	switch (hwport) {
1344*4882a593Smuzhiyun 	case HW_PORT0:
1345*4882a593Smuzhiyun 		port = HALMAC_PORTID0;
1346*4882a593Smuzhiyun 		break;
1347*4882a593Smuzhiyun 	case HW_PORT1:
1348*4882a593Smuzhiyun 		port = HALMAC_PORTID1;
1349*4882a593Smuzhiyun 		break;
1350*4882a593Smuzhiyun 	case HW_PORT2:
1351*4882a593Smuzhiyun 		port = HALMAC_PORTID2;
1352*4882a593Smuzhiyun 		break;
1353*4882a593Smuzhiyun 	case HW_PORT3:
1354*4882a593Smuzhiyun 		port = HALMAC_PORTID3;
1355*4882a593Smuzhiyun 		break;
1356*4882a593Smuzhiyun 	case HW_PORT4:
1357*4882a593Smuzhiyun 		port = HALMAC_PORTID4;
1358*4882a593Smuzhiyun 		break;
1359*4882a593Smuzhiyun 	default:
1360*4882a593Smuzhiyun 		break;
1361*4882a593Smuzhiyun 	}
1362*4882a593Smuzhiyun 
1363*4882a593Smuzhiyun 	return port;
1364*4882a593Smuzhiyun }
1365*4882a593Smuzhiyun 
_network_type_drv2halmac(u8 type)1366*4882a593Smuzhiyun static enum halmac_network_type_select _network_type_drv2halmac(u8 type)
1367*4882a593Smuzhiyun {
1368*4882a593Smuzhiyun 	enum halmac_network_type_select network = HALMAC_NETWORK_UNDEFINE;
1369*4882a593Smuzhiyun 
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 	switch (type) {
1372*4882a593Smuzhiyun 	case _HW_STATE_NOLINK_:
1373*4882a593Smuzhiyun 	case _HW_STATE_MONITOR_:
1374*4882a593Smuzhiyun 		network = HALMAC_NETWORK_NO_LINK;
1375*4882a593Smuzhiyun 		break;
1376*4882a593Smuzhiyun 
1377*4882a593Smuzhiyun 	case _HW_STATE_ADHOC_:
1378*4882a593Smuzhiyun 		network = HALMAC_NETWORK_ADHOC;
1379*4882a593Smuzhiyun 		break;
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun 	case _HW_STATE_STATION_:
1382*4882a593Smuzhiyun 		network = HALMAC_NETWORK_INFRASTRUCTURE;
1383*4882a593Smuzhiyun 		break;
1384*4882a593Smuzhiyun 
1385*4882a593Smuzhiyun 	case _HW_STATE_AP_:
1386*4882a593Smuzhiyun 		network = HALMAC_NETWORK_AP;
1387*4882a593Smuzhiyun 		break;
1388*4882a593Smuzhiyun 	}
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 	return network;
1391*4882a593Smuzhiyun }
1392*4882a593Smuzhiyun 
_network_type_halmac2drv(enum halmac_network_type_select network)1393*4882a593Smuzhiyun static u8 _network_type_halmac2drv(enum halmac_network_type_select network)
1394*4882a593Smuzhiyun {
1395*4882a593Smuzhiyun 	u8 type = _HW_STATE_NOLINK_;
1396*4882a593Smuzhiyun 
1397*4882a593Smuzhiyun 
1398*4882a593Smuzhiyun 	switch (network) {
1399*4882a593Smuzhiyun 	case HALMAC_NETWORK_NO_LINK:
1400*4882a593Smuzhiyun 	case HALMAC_NETWORK_UNDEFINE:
1401*4882a593Smuzhiyun 		type = _HW_STATE_NOLINK_;
1402*4882a593Smuzhiyun 		break;
1403*4882a593Smuzhiyun 
1404*4882a593Smuzhiyun 	case HALMAC_NETWORK_ADHOC:
1405*4882a593Smuzhiyun 		type = _HW_STATE_ADHOC_;
1406*4882a593Smuzhiyun 		break;
1407*4882a593Smuzhiyun 
1408*4882a593Smuzhiyun 	case HALMAC_NETWORK_INFRASTRUCTURE:
1409*4882a593Smuzhiyun 		type = _HW_STATE_STATION_;
1410*4882a593Smuzhiyun 		break;
1411*4882a593Smuzhiyun 
1412*4882a593Smuzhiyun 	case HALMAC_NETWORK_AP:
1413*4882a593Smuzhiyun 		type = _HW_STATE_AP_;
1414*4882a593Smuzhiyun 		break;
1415*4882a593Smuzhiyun 	}
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun 	return type;
1418*4882a593Smuzhiyun }
1419*4882a593Smuzhiyun 
_beacon_ctrl_halmac2drv(struct halmac_bcn_ctrl * ctrl,struct rtw_halmac_bcn_ctrl * drv_ctrl)1420*4882a593Smuzhiyun static void _beacon_ctrl_halmac2drv(struct halmac_bcn_ctrl *ctrl,
1421*4882a593Smuzhiyun 				struct rtw_halmac_bcn_ctrl *drv_ctrl)
1422*4882a593Smuzhiyun {
1423*4882a593Smuzhiyun 	drv_ctrl->rx_bssid_fit = ctrl->dis_rx_bssid_fit ? 0 : 1;
1424*4882a593Smuzhiyun 	drv_ctrl->txbcn_rpt = ctrl->en_txbcn_rpt ? 1 : 0;
1425*4882a593Smuzhiyun 	drv_ctrl->tsf_update = ctrl->dis_tsf_udt ? 0 : 1;
1426*4882a593Smuzhiyun 	drv_ctrl->enable_bcn = ctrl->en_bcn ? 1 : 0;
1427*4882a593Smuzhiyun 	drv_ctrl->rxbcn_rpt = ctrl->en_rxbcn_rpt ? 1 : 0;
1428*4882a593Smuzhiyun 	drv_ctrl->p2p_ctwin = ctrl->en_p2p_ctwin ? 1 : 0;
1429*4882a593Smuzhiyun 	drv_ctrl->p2p_bcn_area = ctrl->en_p2p_bcn_area ? 1 : 0;
1430*4882a593Smuzhiyun }
1431*4882a593Smuzhiyun 
_beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl * drv_ctrl,struct halmac_bcn_ctrl * ctrl)1432*4882a593Smuzhiyun static void _beacon_ctrl_drv2halmac(struct rtw_halmac_bcn_ctrl *drv_ctrl,
1433*4882a593Smuzhiyun 				struct halmac_bcn_ctrl *ctrl)
1434*4882a593Smuzhiyun {
1435*4882a593Smuzhiyun 	ctrl->dis_rx_bssid_fit = drv_ctrl->rx_bssid_fit ? 0 : 1;
1436*4882a593Smuzhiyun 	ctrl->en_txbcn_rpt = drv_ctrl->txbcn_rpt ? 1 : 0;
1437*4882a593Smuzhiyun 	ctrl->dis_tsf_udt = drv_ctrl->tsf_update ? 0 : 1;
1438*4882a593Smuzhiyun 	ctrl->en_bcn = drv_ctrl->enable_bcn ? 1 : 0;
1439*4882a593Smuzhiyun 	ctrl->en_rxbcn_rpt = drv_ctrl->rxbcn_rpt ? 1 : 0;
1440*4882a593Smuzhiyun 	ctrl->en_p2p_ctwin = drv_ctrl->p2p_ctwin ? 1 : 0;
1441*4882a593Smuzhiyun 	ctrl->en_p2p_bcn_area = drv_ctrl->p2p_bcn_area ? 1 : 0;
1442*4882a593Smuzhiyun }
1443*4882a593Smuzhiyun 
rtw_halmac_get_hw_value(struct dvobj_priv * d,enum halmac_hw_id hw_id,void * pvalue)1444*4882a593Smuzhiyun int rtw_halmac_get_hw_value(struct dvobj_priv *d, enum halmac_hw_id hw_id, void *pvalue)
1445*4882a593Smuzhiyun {
1446*4882a593Smuzhiyun 	struct halmac_adapter *mac;
1447*4882a593Smuzhiyun 	struct halmac_api *api;
1448*4882a593Smuzhiyun 	enum halmac_ret_status status;
1449*4882a593Smuzhiyun 
1450*4882a593Smuzhiyun 
1451*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
1452*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
1453*4882a593Smuzhiyun 
1454*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(mac, hw_id, pvalue);
1455*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
1456*4882a593Smuzhiyun 		return -1;
1457*4882a593Smuzhiyun 
1458*4882a593Smuzhiyun 	return 0;
1459*4882a593Smuzhiyun }
1460*4882a593Smuzhiyun 
1461*4882a593Smuzhiyun /**
1462*4882a593Smuzhiyun  * rtw_halmac_get_tx_fifo_size() - TX FIFO size
1463*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1464*4882a593Smuzhiyun  * @size:	TX FIFO size, unit is byte.
1465*4882a593Smuzhiyun  *
1466*4882a593Smuzhiyun  * Get TX FIFO size(byte) from HALMAC.
1467*4882a593Smuzhiyun  *
1468*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1469*4882a593Smuzhiyun  */
rtw_halmac_get_tx_fifo_size(struct dvobj_priv * d,u32 * size)1470*4882a593Smuzhiyun int rtw_halmac_get_tx_fifo_size(struct dvobj_priv *d, u32 *size)
1471*4882a593Smuzhiyun {
1472*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1473*4882a593Smuzhiyun 	struct halmac_api *api;
1474*4882a593Smuzhiyun 	enum halmac_ret_status status;
1475*4882a593Smuzhiyun 	u32 val = 0;
1476*4882a593Smuzhiyun 
1477*4882a593Smuzhiyun 
1478*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1479*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1480*4882a593Smuzhiyun 
1481*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFIFO_SIZE, &val);
1482*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1483*4882a593Smuzhiyun 		return -1;
1484*4882a593Smuzhiyun 
1485*4882a593Smuzhiyun 	*size = val;
1486*4882a593Smuzhiyun 
1487*4882a593Smuzhiyun 	return 0;
1488*4882a593Smuzhiyun }
1489*4882a593Smuzhiyun 
1490*4882a593Smuzhiyun /**
1491*4882a593Smuzhiyun  * rtw_halmac_get_rx_fifo_size() - RX FIFO size
1492*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1493*4882a593Smuzhiyun  * @size:	RX FIFO size, unit is byte
1494*4882a593Smuzhiyun  *
1495*4882a593Smuzhiyun  * Get RX FIFO size(byte) from HALMAC.
1496*4882a593Smuzhiyun  *
1497*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1498*4882a593Smuzhiyun  */
rtw_halmac_get_rx_fifo_size(struct dvobj_priv * d,u32 * size)1499*4882a593Smuzhiyun int rtw_halmac_get_rx_fifo_size(struct dvobj_priv *d, u32 *size)
1500*4882a593Smuzhiyun {
1501*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1502*4882a593Smuzhiyun 	struct halmac_api *api;
1503*4882a593Smuzhiyun 	enum halmac_ret_status status;
1504*4882a593Smuzhiyun 	u32 val = 0;
1505*4882a593Smuzhiyun 
1506*4882a593Smuzhiyun 
1507*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1508*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1509*4882a593Smuzhiyun 
1510*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RXFIFO_SIZE, &val);
1511*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1512*4882a593Smuzhiyun 		return -1;
1513*4882a593Smuzhiyun 
1514*4882a593Smuzhiyun 	*size = val;
1515*4882a593Smuzhiyun 
1516*4882a593Smuzhiyun 	return 0;
1517*4882a593Smuzhiyun }
1518*4882a593Smuzhiyun 
1519*4882a593Smuzhiyun /**
1520*4882a593Smuzhiyun  * rtw_halmac_get_rsvd_drv_pg_bndy() - Reserve page boundary of driver
1521*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1522*4882a593Smuzhiyun  * @size:	Page size, unit is byte
1523*4882a593Smuzhiyun  *
1524*4882a593Smuzhiyun  * Get reserve page boundary of driver from HALMAC.
1525*4882a593Smuzhiyun  *
1526*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1527*4882a593Smuzhiyun  */
rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv * d,u16 * bndy)1528*4882a593Smuzhiyun int rtw_halmac_get_rsvd_drv_pg_bndy(struct dvobj_priv *d, u16 *bndy)
1529*4882a593Smuzhiyun {
1530*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1531*4882a593Smuzhiyun 	struct halmac_api *api;
1532*4882a593Smuzhiyun 	enum halmac_ret_status status;
1533*4882a593Smuzhiyun 	u16 val = 0;
1534*4882a593Smuzhiyun 
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1537*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1538*4882a593Smuzhiyun 
1539*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RSVD_PG_BNDY, &val);
1540*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1541*4882a593Smuzhiyun 		return -1;
1542*4882a593Smuzhiyun 
1543*4882a593Smuzhiyun 	*bndy = val;
1544*4882a593Smuzhiyun 
1545*4882a593Smuzhiyun 	return 0;
1546*4882a593Smuzhiyun }
1547*4882a593Smuzhiyun 
1548*4882a593Smuzhiyun /**
1549*4882a593Smuzhiyun  * rtw_halmac_get_page_size() - Page size
1550*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1551*4882a593Smuzhiyun  * @size:	Page size, unit is byte
1552*4882a593Smuzhiyun  *
1553*4882a593Smuzhiyun  * Get TX/RX page size(byte) from HALMAC.
1554*4882a593Smuzhiyun  *
1555*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1556*4882a593Smuzhiyun  */
rtw_halmac_get_page_size(struct dvobj_priv * d,u32 * size)1557*4882a593Smuzhiyun int rtw_halmac_get_page_size(struct dvobj_priv *d, u32 *size)
1558*4882a593Smuzhiyun {
1559*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1560*4882a593Smuzhiyun 	struct halmac_api *api;
1561*4882a593Smuzhiyun 	enum halmac_ret_status status;
1562*4882a593Smuzhiyun 	u32 val = 0;
1563*4882a593Smuzhiyun 
1564*4882a593Smuzhiyun 
1565*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1566*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1567*4882a593Smuzhiyun 
1568*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_PAGE_SIZE, &val);
1569*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1570*4882a593Smuzhiyun 		return -1;
1571*4882a593Smuzhiyun 
1572*4882a593Smuzhiyun 	*size = val;
1573*4882a593Smuzhiyun 
1574*4882a593Smuzhiyun 	return 0;
1575*4882a593Smuzhiyun }
1576*4882a593Smuzhiyun 
1577*4882a593Smuzhiyun /**
1578*4882a593Smuzhiyun  * rtw_halmac_get_tx_agg_align_size() - TX aggregation align size
1579*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1580*4882a593Smuzhiyun  * @size:	TX aggregation align size, unit is byte
1581*4882a593Smuzhiyun  *
1582*4882a593Smuzhiyun  * Get TX aggregation align size(byte) from HALMAC.
1583*4882a593Smuzhiyun  *
1584*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1585*4882a593Smuzhiyun  */
rtw_halmac_get_tx_agg_align_size(struct dvobj_priv * d,u16 * size)1586*4882a593Smuzhiyun int rtw_halmac_get_tx_agg_align_size(struct dvobj_priv *d, u16 *size)
1587*4882a593Smuzhiyun {
1588*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1589*4882a593Smuzhiyun 	struct halmac_api *api;
1590*4882a593Smuzhiyun 	enum halmac_ret_status status;
1591*4882a593Smuzhiyun 	u16 val = 0;
1592*4882a593Smuzhiyun 
1593*4882a593Smuzhiyun 
1594*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1595*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1596*4882a593Smuzhiyun 
1597*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_AGG_ALIGN_SIZE, &val);
1598*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1599*4882a593Smuzhiyun 		return -1;
1600*4882a593Smuzhiyun 
1601*4882a593Smuzhiyun 	*size = val;
1602*4882a593Smuzhiyun 
1603*4882a593Smuzhiyun 	return 0;
1604*4882a593Smuzhiyun }
1605*4882a593Smuzhiyun 
1606*4882a593Smuzhiyun /**
1607*4882a593Smuzhiyun  * rtw_halmac_get_rx_agg_align_size() - RX aggregation align size
1608*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1609*4882a593Smuzhiyun  * @size:	RX aggregation align size, unit is byte
1610*4882a593Smuzhiyun  *
1611*4882a593Smuzhiyun  * Get RX aggregation align size(byte) from HALMAC.
1612*4882a593Smuzhiyun  *
1613*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1614*4882a593Smuzhiyun  */
rtw_halmac_get_rx_agg_align_size(struct dvobj_priv * d,u8 * size)1615*4882a593Smuzhiyun int rtw_halmac_get_rx_agg_align_size(struct dvobj_priv *d, u8 *size)
1616*4882a593Smuzhiyun {
1617*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1618*4882a593Smuzhiyun 	struct halmac_api *api;
1619*4882a593Smuzhiyun 	enum halmac_ret_status status;
1620*4882a593Smuzhiyun 	u8 val = 0;
1621*4882a593Smuzhiyun 
1622*4882a593Smuzhiyun 
1623*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1624*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1625*4882a593Smuzhiyun 
1626*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_AGG_ALIGN_SIZE, &val);
1627*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1628*4882a593Smuzhiyun 		return -1;
1629*4882a593Smuzhiyun 
1630*4882a593Smuzhiyun 	*size = val;
1631*4882a593Smuzhiyun 
1632*4882a593Smuzhiyun 	return 0;
1633*4882a593Smuzhiyun }
1634*4882a593Smuzhiyun 
1635*4882a593Smuzhiyun /*
1636*4882a593Smuzhiyun  * Description:
1637*4882a593Smuzhiyun  *	Get RX driver info size. RX driver info is a small memory space between
1638*4882a593Smuzhiyun  *	scriptor and RX payload.
1639*4882a593Smuzhiyun  *
1640*4882a593Smuzhiyun  *	+-------------------------+
1641*4882a593Smuzhiyun  *	| RX descriptor           |
1642*4882a593Smuzhiyun  *	| usually 24 bytes        |
1643*4882a593Smuzhiyun  *	+-------------------------+
1644*4882a593Smuzhiyun  *	| RX driver info          |
1645*4882a593Smuzhiyun  *	| depends on driver cfg   |
1646*4882a593Smuzhiyun  *	+-------------------------+
1647*4882a593Smuzhiyun  *	| RX paylad               |
1648*4882a593Smuzhiyun  *	|                         |
1649*4882a593Smuzhiyun  *	+-------------------------+
1650*4882a593Smuzhiyun  *
1651*4882a593Smuzhiyun  * Parameter:
1652*4882a593Smuzhiyun  *	d	pointer to struct dvobj_priv of driver
1653*4882a593Smuzhiyun  *	sz	rx driver info size in bytes.
1654*4882a593Smuzhiyun  *
1655*4882a593Smuzhiyun  * Return:
1656*4882a593Smuzhiyun  *	0	Success
1657*4882a593Smuzhiyun  *	other	Fail
1658*4882a593Smuzhiyun  */
rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv * d,u8 * sz)1659*4882a593Smuzhiyun int rtw_halmac_get_rx_drv_info_sz(struct dvobj_priv *d, u8 *sz)
1660*4882a593Smuzhiyun {
1661*4882a593Smuzhiyun 	enum halmac_ret_status status;
1662*4882a593Smuzhiyun 	struct halmac_adapter *halmac = dvobj_to_halmac(d);
1663*4882a593Smuzhiyun 	struct halmac_api *api = HALMAC_GET_API(halmac);
1664*4882a593Smuzhiyun 	u8 dw = 0;
1665*4882a593Smuzhiyun 
1666*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_DRV_INFO_SIZE, &dw);
1667*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1668*4882a593Smuzhiyun 		return -1;
1669*4882a593Smuzhiyun 
1670*4882a593Smuzhiyun 	*sz = dw * 8;
1671*4882a593Smuzhiyun 	return 0;
1672*4882a593Smuzhiyun }
1673*4882a593Smuzhiyun 
1674*4882a593Smuzhiyun /**
1675*4882a593Smuzhiyun  * rtw_halmac_get_tx_desc_size() - TX descriptor size
1676*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1677*4882a593Smuzhiyun  * @size:	TX descriptor size, unit is byte.
1678*4882a593Smuzhiyun  *
1679*4882a593Smuzhiyun  * Get TX descriptor size(byte) from HALMAC.
1680*4882a593Smuzhiyun  *
1681*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1682*4882a593Smuzhiyun  */
rtw_halmac_get_tx_desc_size(struct dvobj_priv * d,u32 * size)1683*4882a593Smuzhiyun int rtw_halmac_get_tx_desc_size(struct dvobj_priv *d, u32 *size)
1684*4882a593Smuzhiyun {
1685*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1686*4882a593Smuzhiyun 	struct halmac_api *api;
1687*4882a593Smuzhiyun 	enum halmac_ret_status status;
1688*4882a593Smuzhiyun 	u32 val = 0;
1689*4882a593Smuzhiyun 
1690*4882a593Smuzhiyun 
1691*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1692*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1693*4882a593Smuzhiyun 
1694*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TX_DESC_SIZE, &val);
1695*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1696*4882a593Smuzhiyun 		return -1;
1697*4882a593Smuzhiyun 
1698*4882a593Smuzhiyun 	*size = val;
1699*4882a593Smuzhiyun 
1700*4882a593Smuzhiyun 	return 0;
1701*4882a593Smuzhiyun }
1702*4882a593Smuzhiyun 
1703*4882a593Smuzhiyun /**
1704*4882a593Smuzhiyun  * rtw_halmac_get_rx_desc_size() - RX descriptor size
1705*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1706*4882a593Smuzhiyun  * @size:	RX descriptor size, unit is byte.
1707*4882a593Smuzhiyun  *
1708*4882a593Smuzhiyun  * Get RX descriptor size(byte) from HALMAC.
1709*4882a593Smuzhiyun  *
1710*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1711*4882a593Smuzhiyun  */
rtw_halmac_get_rx_desc_size(struct dvobj_priv * d,u32 * size)1712*4882a593Smuzhiyun int rtw_halmac_get_rx_desc_size(struct dvobj_priv *d, u32 *size)
1713*4882a593Smuzhiyun {
1714*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1715*4882a593Smuzhiyun 	struct halmac_api *api;
1716*4882a593Smuzhiyun 	enum halmac_ret_status status;
1717*4882a593Smuzhiyun 	u32 val = 0;
1718*4882a593Smuzhiyun 
1719*4882a593Smuzhiyun 
1720*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1721*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1722*4882a593Smuzhiyun 
1723*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RX_DESC_SIZE, &val);
1724*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1725*4882a593Smuzhiyun 		return -1;
1726*4882a593Smuzhiyun 
1727*4882a593Smuzhiyun 	*size = val;
1728*4882a593Smuzhiyun 
1729*4882a593Smuzhiyun 	return 0;
1730*4882a593Smuzhiyun }
1731*4882a593Smuzhiyun 
1732*4882a593Smuzhiyun /**
1733*4882a593Smuzhiyun  * rtw_halmac_get_tx_dma_ch_map() - Get TX DMA channel Map for tx desc
1734*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1735*4882a593Smuzhiyun  * @dma_ch_map:	return map of QSEL to DMA channel
1736*4882a593Smuzhiyun  * @map_size:	size of dma_ch_map
1737*4882a593Smuzhiyun  *		Suggest size to be last valid QSEL(QSLT_CMD)+1 or full QSLT
1738*4882a593Smuzhiyun  *		size(0x20)
1739*4882a593Smuzhiyun  *
1740*4882a593Smuzhiyun  * 8814B would need this to get mapping of QSEL to DMA channel for TX desc.
1741*4882a593Smuzhiyun  *
1742*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1743*4882a593Smuzhiyun  */
rtw_halmac_get_tx_dma_ch_map(struct dvobj_priv * d,u8 * dma_ch_map,u8 map_size)1744*4882a593Smuzhiyun int rtw_halmac_get_tx_dma_ch_map(struct dvobj_priv *d, u8 *dma_ch_map, u8 map_size)
1745*4882a593Smuzhiyun {
1746*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1747*4882a593Smuzhiyun 	struct halmac_api *api;
1748*4882a593Smuzhiyun 	enum halmac_ret_status status;
1749*4882a593Smuzhiyun 	struct halmac_rqpn_ch_map map;
1750*4882a593Smuzhiyun 	enum halmac_dma_ch channel = HALMAC_DMA_CH_UNDEFINE;
1751*4882a593Smuzhiyun 	u8 qsel;
1752*4882a593Smuzhiyun 
1753*4882a593Smuzhiyun 
1754*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1755*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1756*4882a593Smuzhiyun 
1757*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_CH_MAPPING, &map);
1758*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1759*4882a593Smuzhiyun 		return -1;
1760*4882a593Smuzhiyun 
1761*4882a593Smuzhiyun 	for (qsel = 0; qsel < map_size; qsel++) {
1762*4882a593Smuzhiyun 		switch (qsel) {
1763*4882a593Smuzhiyun 		/*case QSLT_VO:*/
1764*4882a593Smuzhiyun 		case 0x06:
1765*4882a593Smuzhiyun 		case 0x07:
1766*4882a593Smuzhiyun 			channel = map.dma_map_vo;
1767*4882a593Smuzhiyun 			break;
1768*4882a593Smuzhiyun 		/*case QSLT_VI:*/
1769*4882a593Smuzhiyun 		case 0x04:
1770*4882a593Smuzhiyun 		case 0x05:
1771*4882a593Smuzhiyun 			channel = map.dma_map_vi;
1772*4882a593Smuzhiyun 			break;
1773*4882a593Smuzhiyun 		/*case QSLT_BE:*/
1774*4882a593Smuzhiyun 		case 0x00:
1775*4882a593Smuzhiyun 		case 0x03:
1776*4882a593Smuzhiyun 			channel = map.dma_map_be;
1777*4882a593Smuzhiyun 			break;
1778*4882a593Smuzhiyun 		/*case QSLT_BK:*/
1779*4882a593Smuzhiyun 		case 0x01:
1780*4882a593Smuzhiyun 		case 0x02:
1781*4882a593Smuzhiyun 			channel = map.dma_map_bk;
1782*4882a593Smuzhiyun 			break;
1783*4882a593Smuzhiyun 		/*case QSLT_BEACON:*/
1784*4882a593Smuzhiyun 		case 0x10:
1785*4882a593Smuzhiyun 			channel = HALMAC_DMA_CH_BCN;
1786*4882a593Smuzhiyun 			break;
1787*4882a593Smuzhiyun 		/*case QSLT_HIGH:*/
1788*4882a593Smuzhiyun 		case 0x11:
1789*4882a593Smuzhiyun 			channel = map.dma_map_hi;
1790*4882a593Smuzhiyun 			break;
1791*4882a593Smuzhiyun 		/*case QSLT_MGNT:*/
1792*4882a593Smuzhiyun 		case 0x12:
1793*4882a593Smuzhiyun 			channel = map.dma_map_mg;
1794*4882a593Smuzhiyun 			break;
1795*4882a593Smuzhiyun 		/*case QSLT_CMD:*/
1796*4882a593Smuzhiyun 		case 0x13:
1797*4882a593Smuzhiyun 			channel = HALMAC_DMA_CH_H2C;
1798*4882a593Smuzhiyun 			break;
1799*4882a593Smuzhiyun 		default:
1800*4882a593Smuzhiyun 			/*RTW_ERR("%s: invalid qsel=0x%x\n", __FUNCTION__, qsel);*/
1801*4882a593Smuzhiyun 			channel = HALMAC_DMA_CH_UNDEFINE;
1802*4882a593Smuzhiyun 			break;
1803*4882a593Smuzhiyun 		}
1804*4882a593Smuzhiyun 		dma_ch_map[qsel] = (u8)channel;
1805*4882a593Smuzhiyun 	}
1806*4882a593Smuzhiyun 
1807*4882a593Smuzhiyun 	return 0;
1808*4882a593Smuzhiyun }
1809*4882a593Smuzhiyun 
1810*4882a593Smuzhiyun /**
1811*4882a593Smuzhiyun  * rtw_halmac_get_fw_max_size() - Firmware MAX size
1812*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1813*4882a593Smuzhiyun  * @size:	MAX Firmware size, unit is byte.
1814*4882a593Smuzhiyun  *
1815*4882a593Smuzhiyun  * Get Firmware MAX size(byte) from HALMAC.
1816*4882a593Smuzhiyun  *
1817*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1818*4882a593Smuzhiyun  */
rtw_halmac_get_fw_max_size(struct dvobj_priv * d,u32 * size)1819*4882a593Smuzhiyun static int rtw_halmac_get_fw_max_size(struct dvobj_priv *d, u32 *size)
1820*4882a593Smuzhiyun {
1821*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1822*4882a593Smuzhiyun 	struct halmac_api *api;
1823*4882a593Smuzhiyun 	enum halmac_ret_status status;
1824*4882a593Smuzhiyun 	u32 val = 0;
1825*4882a593Smuzhiyun 
1826*4882a593Smuzhiyun 
1827*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1828*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1829*4882a593Smuzhiyun 
1830*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_FW_MAX_SIZE, &val);
1831*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1832*4882a593Smuzhiyun 		return -1;
1833*4882a593Smuzhiyun 
1834*4882a593Smuzhiyun 	*size = val;
1835*4882a593Smuzhiyun 
1836*4882a593Smuzhiyun 	return 0;
1837*4882a593Smuzhiyun }
1838*4882a593Smuzhiyun 
1839*4882a593Smuzhiyun /**
1840*4882a593Smuzhiyun  * rtw_halmac_get_ori_h2c_size() - Original H2C MAX size
1841*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1842*4882a593Smuzhiyun  * @size:	H2C MAX size, unit is byte.
1843*4882a593Smuzhiyun  *
1844*4882a593Smuzhiyun  * Get original H2C MAX size(byte) from HALMAC.
1845*4882a593Smuzhiyun  *
1846*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1847*4882a593Smuzhiyun  */
rtw_halmac_get_ori_h2c_size(struct dvobj_priv * d,u32 * size)1848*4882a593Smuzhiyun int rtw_halmac_get_ori_h2c_size(struct dvobj_priv *d, u32 *size)
1849*4882a593Smuzhiyun {
1850*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1851*4882a593Smuzhiyun 	struct halmac_api *api;
1852*4882a593Smuzhiyun 	enum halmac_ret_status status;
1853*4882a593Smuzhiyun 	u32 val = 0;
1854*4882a593Smuzhiyun 
1855*4882a593Smuzhiyun 
1856*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1857*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1858*4882a593Smuzhiyun 
1859*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_ORI_H2C_SIZE, &val);
1860*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1861*4882a593Smuzhiyun 		return -1;
1862*4882a593Smuzhiyun 
1863*4882a593Smuzhiyun 	*size = val;
1864*4882a593Smuzhiyun 
1865*4882a593Smuzhiyun 	return 0;
1866*4882a593Smuzhiyun }
1867*4882a593Smuzhiyun 
rtw_halmac_get_oqt_size(struct dvobj_priv * d,u8 * size)1868*4882a593Smuzhiyun int rtw_halmac_get_oqt_size(struct dvobj_priv *d, u8 *size)
1869*4882a593Smuzhiyun {
1870*4882a593Smuzhiyun 	enum halmac_ret_status status;
1871*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1872*4882a593Smuzhiyun 	struct halmac_api *api;
1873*4882a593Smuzhiyun 	u8 val;
1874*4882a593Smuzhiyun 
1875*4882a593Smuzhiyun 
1876*4882a593Smuzhiyun 	if (!size)
1877*4882a593Smuzhiyun 		return -1;
1878*4882a593Smuzhiyun 
1879*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1880*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1881*4882a593Smuzhiyun 
1882*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_OQT_SIZE, &val);
1883*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1884*4882a593Smuzhiyun 		return -1;
1885*4882a593Smuzhiyun 
1886*4882a593Smuzhiyun 	*size = val;
1887*4882a593Smuzhiyun 	return 0;
1888*4882a593Smuzhiyun }
1889*4882a593Smuzhiyun 
rtw_halmac_get_ac_queue_number(struct dvobj_priv * d,u8 * num)1890*4882a593Smuzhiyun int rtw_halmac_get_ac_queue_number(struct dvobj_priv *d, u8 *num)
1891*4882a593Smuzhiyun {
1892*4882a593Smuzhiyun 	enum halmac_ret_status status;
1893*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1894*4882a593Smuzhiyun 	struct halmac_api *api;
1895*4882a593Smuzhiyun 	u8 val;
1896*4882a593Smuzhiyun 
1897*4882a593Smuzhiyun 
1898*4882a593Smuzhiyun 	if (!num)
1899*4882a593Smuzhiyun 		return -1;
1900*4882a593Smuzhiyun 
1901*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1902*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1903*4882a593Smuzhiyun 
1904*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_AC_QUEUE_NUM, &val);
1905*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1906*4882a593Smuzhiyun 		return -1;
1907*4882a593Smuzhiyun 
1908*4882a593Smuzhiyun 	*num = val;
1909*4882a593Smuzhiyun 	return 0;
1910*4882a593Smuzhiyun }
1911*4882a593Smuzhiyun 
1912*4882a593Smuzhiyun /**
1913*4882a593Smuzhiyun  * rtw_halmac_get_mac_address() - Get MAC address of specific port
1914*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1915*4882a593Smuzhiyun  * @hwport:	port
1916*4882a593Smuzhiyun  * @addr:	buffer for storing MAC address
1917*4882a593Smuzhiyun  *
1918*4882a593Smuzhiyun  * Get MAC address of specific port from HALMAC.
1919*4882a593Smuzhiyun  *
1920*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1921*4882a593Smuzhiyun  */
rtw_halmac_get_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)1922*4882a593Smuzhiyun int rtw_halmac_get_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
1923*4882a593Smuzhiyun {
1924*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1925*4882a593Smuzhiyun 	struct halmac_api *api;
1926*4882a593Smuzhiyun 	enum halmac_portid port;
1927*4882a593Smuzhiyun 	union halmac_wlan_addr hwa;
1928*4882a593Smuzhiyun 	enum halmac_ret_status status;
1929*4882a593Smuzhiyun 	int err = -1;
1930*4882a593Smuzhiyun 
1931*4882a593Smuzhiyun 
1932*4882a593Smuzhiyun 	if (!addr)
1933*4882a593Smuzhiyun 		goto out;
1934*4882a593Smuzhiyun 
1935*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1936*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1937*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
1938*4882a593Smuzhiyun 	_rtw_memset(&hwa, 0, sizeof(hwa));
1939*4882a593Smuzhiyun 
1940*4882a593Smuzhiyun 	status = api->halmac_get_mac_addr(halmac, port, &hwa);
1941*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1942*4882a593Smuzhiyun 		goto out;
1943*4882a593Smuzhiyun 
1944*4882a593Smuzhiyun 	_rtw_memcpy(addr, hwa.addr, 6);
1945*4882a593Smuzhiyun 
1946*4882a593Smuzhiyun 	err = 0;
1947*4882a593Smuzhiyun out:
1948*4882a593Smuzhiyun 	return err;
1949*4882a593Smuzhiyun }
1950*4882a593Smuzhiyun 
1951*4882a593Smuzhiyun /**
1952*4882a593Smuzhiyun  * rtw_halmac_get_network_type() - Get network type of specific port
1953*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
1954*4882a593Smuzhiyun  * @hwport:	port
1955*4882a593Smuzhiyun  * @type:	buffer to put network type (_HW_STATE_*)
1956*4882a593Smuzhiyun  *
1957*4882a593Smuzhiyun  * Get network type of specific port from HALMAC.
1958*4882a593Smuzhiyun  *
1959*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
1960*4882a593Smuzhiyun  */
rtw_halmac_get_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 * type)1961*4882a593Smuzhiyun int rtw_halmac_get_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 *type)
1962*4882a593Smuzhiyun {
1963*4882a593Smuzhiyun #if 0
1964*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
1965*4882a593Smuzhiyun 	struct halmac_api *api;
1966*4882a593Smuzhiyun 	enum halmac_portid port;
1967*4882a593Smuzhiyun 	enum halmac_network_type_select network;
1968*4882a593Smuzhiyun 	enum halmac_ret_status status;
1969*4882a593Smuzhiyun 	int err = -1;
1970*4882a593Smuzhiyun 
1971*4882a593Smuzhiyun 
1972*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
1973*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
1974*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
1975*4882a593Smuzhiyun 	network = HALMAC_NETWORK_UNDEFINE;
1976*4882a593Smuzhiyun 
1977*4882a593Smuzhiyun 	status = api->halmac_get_net_type(halmac, port, &network);
1978*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
1979*4882a593Smuzhiyun 		goto out;
1980*4882a593Smuzhiyun 
1981*4882a593Smuzhiyun 	*type = _network_type_halmac2drv(network);
1982*4882a593Smuzhiyun 
1983*4882a593Smuzhiyun 	err = 0;
1984*4882a593Smuzhiyun out:
1985*4882a593Smuzhiyun 	return err;
1986*4882a593Smuzhiyun #else
1987*4882a593Smuzhiyun 	struct _ADAPTER *a;
1988*4882a593Smuzhiyun 	enum halmac_portid port;
1989*4882a593Smuzhiyun 	enum halmac_network_type_select network;
1990*4882a593Smuzhiyun 	u32 val;
1991*4882a593Smuzhiyun 	int err = -1;
1992*4882a593Smuzhiyun 
1993*4882a593Smuzhiyun 
1994*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
1995*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
1996*4882a593Smuzhiyun 	network = HALMAC_NETWORK_UNDEFINE;
1997*4882a593Smuzhiyun 
1998*4882a593Smuzhiyun 	switch (port) {
1999*4882a593Smuzhiyun 	case HALMAC_PORTID0:
2000*4882a593Smuzhiyun 		val = rtw_read32(a, REG_CR);
2001*4882a593Smuzhiyun 		network = BIT_GET_NETYPE0(val);
2002*4882a593Smuzhiyun 		break;
2003*4882a593Smuzhiyun 
2004*4882a593Smuzhiyun 	case HALMAC_PORTID1:
2005*4882a593Smuzhiyun 		val = rtw_read32(a, REG_CR);
2006*4882a593Smuzhiyun 		network = BIT_GET_NETYPE1(val);
2007*4882a593Smuzhiyun 		break;
2008*4882a593Smuzhiyun 
2009*4882a593Smuzhiyun 	case HALMAC_PORTID2:
2010*4882a593Smuzhiyun 		val = rtw_read32(a, REG_CR_EXT);
2011*4882a593Smuzhiyun 		network = BIT_GET_NETYPE2(val);
2012*4882a593Smuzhiyun 		break;
2013*4882a593Smuzhiyun 
2014*4882a593Smuzhiyun 	case HALMAC_PORTID3:
2015*4882a593Smuzhiyun 		val = rtw_read32(a, REG_CR_EXT);
2016*4882a593Smuzhiyun 		network = BIT_GET_NETYPE3(val);
2017*4882a593Smuzhiyun 		break;
2018*4882a593Smuzhiyun 
2019*4882a593Smuzhiyun 	case HALMAC_PORTID4:
2020*4882a593Smuzhiyun 		val = rtw_read32(a, REG_CR_EXT);
2021*4882a593Smuzhiyun 		network = BIT_GET_NETYPE4(val);
2022*4882a593Smuzhiyun 		break;
2023*4882a593Smuzhiyun 
2024*4882a593Smuzhiyun 	default:
2025*4882a593Smuzhiyun 		goto out;
2026*4882a593Smuzhiyun 	}
2027*4882a593Smuzhiyun 
2028*4882a593Smuzhiyun 	*type = _network_type_halmac2drv(network);
2029*4882a593Smuzhiyun 
2030*4882a593Smuzhiyun 	err = 0;
2031*4882a593Smuzhiyun out:
2032*4882a593Smuzhiyun 	return err;
2033*4882a593Smuzhiyun #endif
2034*4882a593Smuzhiyun }
2035*4882a593Smuzhiyun 
2036*4882a593Smuzhiyun /**
2037*4882a593Smuzhiyun  * rtw_halmac_get_bcn_ctrl() - Get beacon control setting of specific port
2038*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2039*4882a593Smuzhiyun  * @hwport:	port
2040*4882a593Smuzhiyun  * @bcn_ctrl:	setting of beacon control
2041*4882a593Smuzhiyun  *
2042*4882a593Smuzhiyun  * Get beacon control setting of specific port from HALMAC.
2043*4882a593Smuzhiyun  *
2044*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2045*4882a593Smuzhiyun  */
rtw_halmac_get_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)2046*4882a593Smuzhiyun int rtw_halmac_get_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2047*4882a593Smuzhiyun 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2048*4882a593Smuzhiyun {
2049*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2050*4882a593Smuzhiyun 	struct halmac_api *api;
2051*4882a593Smuzhiyun 	enum halmac_portid port;
2052*4882a593Smuzhiyun 	struct halmac_bcn_ctrl ctrl;
2053*4882a593Smuzhiyun 	enum halmac_ret_status status;
2054*4882a593Smuzhiyun 	int err = -1;
2055*4882a593Smuzhiyun 
2056*4882a593Smuzhiyun 
2057*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2058*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2059*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2060*4882a593Smuzhiyun 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
2061*4882a593Smuzhiyun 
2062*4882a593Smuzhiyun 	status = api->halmac_rw_bcn_ctrl(halmac, port, 0, &ctrl);
2063*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2064*4882a593Smuzhiyun 		goto out;
2065*4882a593Smuzhiyun 	_beacon_ctrl_halmac2drv(&ctrl, bcn_ctrl);
2066*4882a593Smuzhiyun 
2067*4882a593Smuzhiyun 	err = 0;
2068*4882a593Smuzhiyun out:
2069*4882a593Smuzhiyun 	return err;
2070*4882a593Smuzhiyun }
2071*4882a593Smuzhiyun 
2072*4882a593Smuzhiyun /*
2073*4882a593Smuzhiyun  * Note:
2074*4882a593Smuzhiyun  *	When this function return, the register REG_RCR may be changed.
2075*4882a593Smuzhiyun  */
rtw_halmac_config_rx_info(struct dvobj_priv * d,enum halmac_drv_info info)2076*4882a593Smuzhiyun int rtw_halmac_config_rx_info(struct dvobj_priv *d, enum halmac_drv_info info)
2077*4882a593Smuzhiyun {
2078*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2079*4882a593Smuzhiyun 	struct halmac_api *api;
2080*4882a593Smuzhiyun 	enum halmac_ret_status status;
2081*4882a593Smuzhiyun 	int err = -1;
2082*4882a593Smuzhiyun 
2083*4882a593Smuzhiyun 
2084*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2085*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2086*4882a593Smuzhiyun 
2087*4882a593Smuzhiyun 	status = api->halmac_cfg_drv_info(halmac, info);
2088*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2089*4882a593Smuzhiyun 		goto out;
2090*4882a593Smuzhiyun 
2091*4882a593Smuzhiyun 	err = 0;
2092*4882a593Smuzhiyun out:
2093*4882a593Smuzhiyun 	/* Sync driver RCR cache with register setting */
2094*4882a593Smuzhiyun 	rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL);
2095*4882a593Smuzhiyun 
2096*4882a593Smuzhiyun 	return err;
2097*4882a593Smuzhiyun }
2098*4882a593Smuzhiyun 
2099*4882a593Smuzhiyun /**
2100*4882a593Smuzhiyun  * rtw_halmac_set_max_dl_fw_size() - Set the MAX download firmware size
2101*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2102*4882a593Smuzhiyun  * @size:	the max download firmware size in one I/O
2103*4882a593Smuzhiyun  *
2104*4882a593Smuzhiyun  * Set the max download firmware size in one I/O.
2105*4882a593Smuzhiyun  * Please also consider the max size of the callback function "SEND_RSVD_PAGE"
2106*4882a593Smuzhiyun  * could accept, because download firmware would call "SEND_RSVD_PAGE" to send
2107*4882a593Smuzhiyun  * firmware to IC.
2108*4882a593Smuzhiyun  *
2109*4882a593Smuzhiyun  * If the value of "size" is not even, it would be rounded down to nearest
2110*4882a593Smuzhiyun  * even, and 0 and 1 are both invalid value.
2111*4882a593Smuzhiyun  *
2112*4882a593Smuzhiyun  * Return 0 for setting OK, otherwise fail.
2113*4882a593Smuzhiyun  */
rtw_halmac_set_max_dl_fw_size(struct dvobj_priv * d,u32 size)2114*4882a593Smuzhiyun int rtw_halmac_set_max_dl_fw_size(struct dvobj_priv *d, u32 size)
2115*4882a593Smuzhiyun {
2116*4882a593Smuzhiyun 	struct halmac_adapter *mac;
2117*4882a593Smuzhiyun 	struct halmac_api *api;
2118*4882a593Smuzhiyun 	enum halmac_ret_status status;
2119*4882a593Smuzhiyun 
2120*4882a593Smuzhiyun 
2121*4882a593Smuzhiyun 	if (!size || (size == 1))
2122*4882a593Smuzhiyun 		return -1;
2123*4882a593Smuzhiyun 
2124*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
2125*4882a593Smuzhiyun 	if (!mac) {
2126*4882a593Smuzhiyun 		RTW_ERR("%s: HALMAC is not ready!!\n", __FUNCTION__);
2127*4882a593Smuzhiyun 		return -1;
2128*4882a593Smuzhiyun 	}
2129*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
2130*4882a593Smuzhiyun 
2131*4882a593Smuzhiyun 	size &= ~1; /* round down to even */
2132*4882a593Smuzhiyun 	status = api->halmac_cfg_max_dl_size(mac, size);
2133*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
2134*4882a593Smuzhiyun 		RTW_WARN("%s: Fail to cfg_max_dl_size(%d), err=%d!!\n",
2135*4882a593Smuzhiyun 			 __FUNCTION__, size, status);
2136*4882a593Smuzhiyun 		return -1;
2137*4882a593Smuzhiyun 	}
2138*4882a593Smuzhiyun 
2139*4882a593Smuzhiyun 	return 0;
2140*4882a593Smuzhiyun }
2141*4882a593Smuzhiyun 
2142*4882a593Smuzhiyun /**
2143*4882a593Smuzhiyun  * rtw_halmac_set_mac_address() - Set mac address of specific port
2144*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2145*4882a593Smuzhiyun  * @hwport:	port
2146*4882a593Smuzhiyun  * @addr:	mac address
2147*4882a593Smuzhiyun  *
2148*4882a593Smuzhiyun  * Set self mac address of specific port to HALMAC.
2149*4882a593Smuzhiyun  *
2150*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2151*4882a593Smuzhiyun  */
rtw_halmac_set_mac_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2152*4882a593Smuzhiyun int rtw_halmac_set_mac_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2153*4882a593Smuzhiyun {
2154*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2155*4882a593Smuzhiyun 	struct halmac_api *api;
2156*4882a593Smuzhiyun 	enum halmac_portid port;
2157*4882a593Smuzhiyun 	union halmac_wlan_addr hwa;
2158*4882a593Smuzhiyun 	enum halmac_ret_status status;
2159*4882a593Smuzhiyun 	int err = -1;
2160*4882a593Smuzhiyun 
2161*4882a593Smuzhiyun 
2162*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2163*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2164*4882a593Smuzhiyun 
2165*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2166*4882a593Smuzhiyun 	_rtw_memset(&hwa, 0, sizeof(hwa));
2167*4882a593Smuzhiyun 	_rtw_memcpy(hwa.addr, addr, 6);
2168*4882a593Smuzhiyun 
2169*4882a593Smuzhiyun 	status = api->halmac_cfg_mac_addr(halmac, port, &hwa);
2170*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2171*4882a593Smuzhiyun 		goto out;
2172*4882a593Smuzhiyun 
2173*4882a593Smuzhiyun 	err = 0;
2174*4882a593Smuzhiyun out:
2175*4882a593Smuzhiyun 	return err;
2176*4882a593Smuzhiyun }
2177*4882a593Smuzhiyun 
2178*4882a593Smuzhiyun /**
2179*4882a593Smuzhiyun  * rtw_halmac_set_bssid() - Set BSSID of specific port
2180*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2181*4882a593Smuzhiyun  * @hwport:	port
2182*4882a593Smuzhiyun  * @addr:	BSSID, mac address of AP
2183*4882a593Smuzhiyun  *
2184*4882a593Smuzhiyun  * Set BSSID of specific port to HALMAC.
2185*4882a593Smuzhiyun  *
2186*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2187*4882a593Smuzhiyun  */
rtw_halmac_set_bssid(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2188*4882a593Smuzhiyun int rtw_halmac_set_bssid(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2189*4882a593Smuzhiyun {
2190*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2191*4882a593Smuzhiyun 	struct halmac_api *api;
2192*4882a593Smuzhiyun 	enum halmac_portid port;
2193*4882a593Smuzhiyun 	union halmac_wlan_addr hwa;
2194*4882a593Smuzhiyun 	enum halmac_ret_status status;
2195*4882a593Smuzhiyun 	int err = -1;
2196*4882a593Smuzhiyun 
2197*4882a593Smuzhiyun 
2198*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2199*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2200*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2201*4882a593Smuzhiyun 
2202*4882a593Smuzhiyun 	_rtw_memset(&hwa, 0, sizeof(hwa));
2203*4882a593Smuzhiyun 	_rtw_memcpy(hwa.addr, addr, 6);
2204*4882a593Smuzhiyun 	status = api->halmac_cfg_bssid(halmac, port, &hwa);
2205*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2206*4882a593Smuzhiyun 		goto out;
2207*4882a593Smuzhiyun 
2208*4882a593Smuzhiyun 	err = 0;
2209*4882a593Smuzhiyun out:
2210*4882a593Smuzhiyun 	return err;
2211*4882a593Smuzhiyun }
2212*4882a593Smuzhiyun 
2213*4882a593Smuzhiyun /**
2214*4882a593Smuzhiyun  * rtw_halmac_set_tx_address() - Set transmitter address of specific port
2215*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2216*4882a593Smuzhiyun  * @hwport:	port
2217*4882a593Smuzhiyun  * @addr:	transmitter address
2218*4882a593Smuzhiyun  *
2219*4882a593Smuzhiyun  * Set transmitter address of specific port to HALMAC.
2220*4882a593Smuzhiyun  *
2221*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2222*4882a593Smuzhiyun  */
rtw_halmac_set_tx_address(struct dvobj_priv * d,enum _hw_port hwport,u8 * addr)2223*4882a593Smuzhiyun int rtw_halmac_set_tx_address(struct dvobj_priv *d, enum _hw_port hwport, u8 *addr)
2224*4882a593Smuzhiyun {
2225*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2226*4882a593Smuzhiyun 	struct halmac_api *api;
2227*4882a593Smuzhiyun 	enum halmac_portid port;
2228*4882a593Smuzhiyun 	union halmac_wlan_addr hwa;
2229*4882a593Smuzhiyun 	enum halmac_ret_status status;
2230*4882a593Smuzhiyun 	int err = -1;
2231*4882a593Smuzhiyun 
2232*4882a593Smuzhiyun 
2233*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2234*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2235*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2236*4882a593Smuzhiyun 	_rtw_memset(&hwa, 0, sizeof(hwa));
2237*4882a593Smuzhiyun 	_rtw_memcpy(hwa.addr, addr, 6);
2238*4882a593Smuzhiyun 
2239*4882a593Smuzhiyun 	status = api->halmac_cfg_transmitter_addr(halmac, port, &hwa);
2240*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2241*4882a593Smuzhiyun 		goto out;
2242*4882a593Smuzhiyun 
2243*4882a593Smuzhiyun 	err = 0;
2244*4882a593Smuzhiyun out:
2245*4882a593Smuzhiyun 	return err;
2246*4882a593Smuzhiyun }
2247*4882a593Smuzhiyun 
2248*4882a593Smuzhiyun /**
2249*4882a593Smuzhiyun  * rtw_halmac_set_network_type() - Set network type of specific port
2250*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2251*4882a593Smuzhiyun  * @hwport:	port
2252*4882a593Smuzhiyun  * @type:	network type (_HW_STATE_*)
2253*4882a593Smuzhiyun  *
2254*4882a593Smuzhiyun  * Set network type of specific port to HALMAC.
2255*4882a593Smuzhiyun  *
2256*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2257*4882a593Smuzhiyun  */
rtw_halmac_set_network_type(struct dvobj_priv * d,enum _hw_port hwport,u8 type)2258*4882a593Smuzhiyun int rtw_halmac_set_network_type(struct dvobj_priv *d, enum _hw_port hwport, u8 type)
2259*4882a593Smuzhiyun {
2260*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2261*4882a593Smuzhiyun 	struct halmac_api *api;
2262*4882a593Smuzhiyun 	enum halmac_portid port;
2263*4882a593Smuzhiyun 	enum halmac_network_type_select network;
2264*4882a593Smuzhiyun 	enum halmac_ret_status status;
2265*4882a593Smuzhiyun 	int err = -1;
2266*4882a593Smuzhiyun 
2267*4882a593Smuzhiyun 
2268*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2269*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2270*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2271*4882a593Smuzhiyun 	network = _network_type_drv2halmac(type);
2272*4882a593Smuzhiyun 
2273*4882a593Smuzhiyun 	status = api->halmac_cfg_net_type(halmac, port, network);
2274*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2275*4882a593Smuzhiyun 		goto out;
2276*4882a593Smuzhiyun 
2277*4882a593Smuzhiyun 	err = 0;
2278*4882a593Smuzhiyun out:
2279*4882a593Smuzhiyun 	return err;
2280*4882a593Smuzhiyun }
2281*4882a593Smuzhiyun 
2282*4882a593Smuzhiyun /**
2283*4882a593Smuzhiyun  * rtw_halmac_reset_tsf() - Reset TSF timer of specific port
2284*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2285*4882a593Smuzhiyun  * @hwport:	port
2286*4882a593Smuzhiyun  *
2287*4882a593Smuzhiyun  * Notice HALMAC to reset timing synchronization function(TSF) timer of
2288*4882a593Smuzhiyun  * specific port.
2289*4882a593Smuzhiyun  *
2290*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2291*4882a593Smuzhiyun  */
rtw_halmac_reset_tsf(struct dvobj_priv * d,enum _hw_port hwport)2292*4882a593Smuzhiyun int rtw_halmac_reset_tsf(struct dvobj_priv *d, enum _hw_port hwport)
2293*4882a593Smuzhiyun {
2294*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2295*4882a593Smuzhiyun 	struct halmac_api *api;
2296*4882a593Smuzhiyun 	enum halmac_portid port;
2297*4882a593Smuzhiyun 	enum halmac_ret_status status;
2298*4882a593Smuzhiyun 	int err = -1;
2299*4882a593Smuzhiyun 
2300*4882a593Smuzhiyun 
2301*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2302*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2303*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2304*4882a593Smuzhiyun 
2305*4882a593Smuzhiyun 	status = api->halmac_cfg_tsf_rst(halmac, port);
2306*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2307*4882a593Smuzhiyun 		goto out;
2308*4882a593Smuzhiyun 
2309*4882a593Smuzhiyun 	err = 0;
2310*4882a593Smuzhiyun out:
2311*4882a593Smuzhiyun 	return err;
2312*4882a593Smuzhiyun }
2313*4882a593Smuzhiyun 
2314*4882a593Smuzhiyun /**
2315*4882a593Smuzhiyun  * rtw_halmac_set_bcn_interval() - Set beacon interval of each port
2316*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2317*4882a593Smuzhiyun  * @hwport:	port
2318*4882a593Smuzhiyun  * @space:	beacon interval, unit is ms
2319*4882a593Smuzhiyun  *
2320*4882a593Smuzhiyun  * Set beacon interval of specific port to HALMAC.
2321*4882a593Smuzhiyun  *
2322*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2323*4882a593Smuzhiyun  */
rtw_halmac_set_bcn_interval(struct dvobj_priv * d,enum _hw_port hwport,u32 interval)2324*4882a593Smuzhiyun int rtw_halmac_set_bcn_interval(struct dvobj_priv *d, enum _hw_port hwport,
2325*4882a593Smuzhiyun 				u32 interval)
2326*4882a593Smuzhiyun {
2327*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2328*4882a593Smuzhiyun 	struct halmac_api *api;
2329*4882a593Smuzhiyun 	enum halmac_portid port;
2330*4882a593Smuzhiyun 	enum halmac_ret_status status;
2331*4882a593Smuzhiyun 	int err = -1;
2332*4882a593Smuzhiyun 
2333*4882a593Smuzhiyun 
2334*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2335*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2336*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2337*4882a593Smuzhiyun 
2338*4882a593Smuzhiyun 	status = api->halmac_cfg_bcn_space(halmac, port, interval);
2339*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2340*4882a593Smuzhiyun 		goto out;
2341*4882a593Smuzhiyun 
2342*4882a593Smuzhiyun 	err = 0;
2343*4882a593Smuzhiyun out:
2344*4882a593Smuzhiyun 	return err;
2345*4882a593Smuzhiyun }
2346*4882a593Smuzhiyun 
2347*4882a593Smuzhiyun /**
2348*4882a593Smuzhiyun  * rtw_halmac_set_bcn_ctrl() - Set beacon control setting of each port
2349*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2350*4882a593Smuzhiyun  * @hwport:	port
2351*4882a593Smuzhiyun  * @bcn_ctrl:	setting of beacon control
2352*4882a593Smuzhiyun  *
2353*4882a593Smuzhiyun  * Set beacon control setting of specific port to HALMAC.
2354*4882a593Smuzhiyun  *
2355*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2356*4882a593Smuzhiyun  */
rtw_halmac_set_bcn_ctrl(struct dvobj_priv * d,enum _hw_port hwport,struct rtw_halmac_bcn_ctrl * bcn_ctrl)2357*4882a593Smuzhiyun int rtw_halmac_set_bcn_ctrl(struct dvobj_priv *d, enum _hw_port hwport,
2358*4882a593Smuzhiyun 			struct rtw_halmac_bcn_ctrl *bcn_ctrl)
2359*4882a593Smuzhiyun {
2360*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2361*4882a593Smuzhiyun 	struct halmac_api *api;
2362*4882a593Smuzhiyun 	enum halmac_portid port;
2363*4882a593Smuzhiyun 	struct halmac_bcn_ctrl ctrl;
2364*4882a593Smuzhiyun 	enum halmac_ret_status status;
2365*4882a593Smuzhiyun 	int err = -1;
2366*4882a593Smuzhiyun 
2367*4882a593Smuzhiyun 
2368*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2369*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2370*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2371*4882a593Smuzhiyun 	_rtw_memset(&ctrl, 0, sizeof(ctrl));
2372*4882a593Smuzhiyun 	_beacon_ctrl_drv2halmac(bcn_ctrl, &ctrl);
2373*4882a593Smuzhiyun 
2374*4882a593Smuzhiyun 	status = api->halmac_rw_bcn_ctrl(halmac, port, 1, &ctrl);
2375*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2376*4882a593Smuzhiyun 		goto out;
2377*4882a593Smuzhiyun 
2378*4882a593Smuzhiyun 	err = 0;
2379*4882a593Smuzhiyun out:
2380*4882a593Smuzhiyun 	return err;
2381*4882a593Smuzhiyun }
2382*4882a593Smuzhiyun 
2383*4882a593Smuzhiyun /**
2384*4882a593Smuzhiyun  * rtw_halmac_set_aid() - Set association identifier(AID) of specific port
2385*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2386*4882a593Smuzhiyun  * @hwport:	port
2387*4882a593Smuzhiyun  * @aid:	Association identifier
2388*4882a593Smuzhiyun  *
2389*4882a593Smuzhiyun  * Set association identifier(AID) of specific port to HALMAC.
2390*4882a593Smuzhiyun  *
2391*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
2392*4882a593Smuzhiyun  */
rtw_halmac_set_aid(struct dvobj_priv * d,enum _hw_port hwport,u16 aid)2393*4882a593Smuzhiyun int rtw_halmac_set_aid(struct dvobj_priv *d, enum _hw_port hwport, u16 aid)
2394*4882a593Smuzhiyun {
2395*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2396*4882a593Smuzhiyun 	struct halmac_api *api;
2397*4882a593Smuzhiyun 	enum halmac_portid port;
2398*4882a593Smuzhiyun 	enum halmac_ret_status status;
2399*4882a593Smuzhiyun 	int err = -1;
2400*4882a593Smuzhiyun 
2401*4882a593Smuzhiyun 
2402*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2403*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2404*4882a593Smuzhiyun 	port = _hw_port_drv2halmac(hwport);
2405*4882a593Smuzhiyun 
2406*4882a593Smuzhiyun #if 0
2407*4882a593Smuzhiyun 	status = api->halmac_cfg_aid(halmac, port, aid);
2408*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2409*4882a593Smuzhiyun 		goto out;
2410*4882a593Smuzhiyun #else
2411*4882a593Smuzhiyun {
2412*4882a593Smuzhiyun 	struct _ADAPTER *a;
2413*4882a593Smuzhiyun 	u32 addr;
2414*4882a593Smuzhiyun 	u16 val;
2415*4882a593Smuzhiyun 
2416*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
2417*4882a593Smuzhiyun 
2418*4882a593Smuzhiyun 	switch (port) {
2419*4882a593Smuzhiyun 	case 0:
2420*4882a593Smuzhiyun 		addr = REG_BCN_PSR_RPT;
2421*4882a593Smuzhiyun 		val = rtw_read16(a, addr);
2422*4882a593Smuzhiyun 		val = BIT_SET_PS_AID_0(val, aid);
2423*4882a593Smuzhiyun 		rtw_write16(a, addr, val);
2424*4882a593Smuzhiyun 		break;
2425*4882a593Smuzhiyun 
2426*4882a593Smuzhiyun 	case 1:
2427*4882a593Smuzhiyun 		addr = REG_BCN_PSR_RPT1;
2428*4882a593Smuzhiyun 		val = rtw_read16(a, addr);
2429*4882a593Smuzhiyun 		val = BIT_SET_PS_AID_1(val, aid);
2430*4882a593Smuzhiyun 		rtw_write16(a, addr, val);
2431*4882a593Smuzhiyun 		break;
2432*4882a593Smuzhiyun 
2433*4882a593Smuzhiyun 	case 2:
2434*4882a593Smuzhiyun 		addr = REG_BCN_PSR_RPT2;
2435*4882a593Smuzhiyun 		val = rtw_read16(a, addr);
2436*4882a593Smuzhiyun 		val = BIT_SET_PS_AID_2(val, aid);
2437*4882a593Smuzhiyun 		rtw_write16(a, addr, val);
2438*4882a593Smuzhiyun 		break;
2439*4882a593Smuzhiyun 
2440*4882a593Smuzhiyun 	case 3:
2441*4882a593Smuzhiyun 		addr = REG_BCN_PSR_RPT3;
2442*4882a593Smuzhiyun 		val = rtw_read16(a, addr);
2443*4882a593Smuzhiyun 		val = BIT_SET_PS_AID_3(val, aid);
2444*4882a593Smuzhiyun 		rtw_write16(a, addr, val);
2445*4882a593Smuzhiyun 		break;
2446*4882a593Smuzhiyun 
2447*4882a593Smuzhiyun 	case 4:
2448*4882a593Smuzhiyun 		addr = REG_BCN_PSR_RPT4;
2449*4882a593Smuzhiyun 		val = rtw_read16(a, addr);
2450*4882a593Smuzhiyun 		val = BIT_SET_PS_AID_4(val, aid);
2451*4882a593Smuzhiyun 		rtw_write16(a, addr, val);
2452*4882a593Smuzhiyun 		break;
2453*4882a593Smuzhiyun 
2454*4882a593Smuzhiyun 	default:
2455*4882a593Smuzhiyun 		goto out;
2456*4882a593Smuzhiyun 	}
2457*4882a593Smuzhiyun }
2458*4882a593Smuzhiyun #endif
2459*4882a593Smuzhiyun 
2460*4882a593Smuzhiyun 	err = 0;
2461*4882a593Smuzhiyun out:
2462*4882a593Smuzhiyun 	return err;
2463*4882a593Smuzhiyun }
2464*4882a593Smuzhiyun 
rtw_halmac_set_bandwidth(struct dvobj_priv * d,u8 channel,u8 pri_ch_idx,u8 bw)2465*4882a593Smuzhiyun int rtw_halmac_set_bandwidth(struct dvobj_priv *d, u8 channel, u8 pri_ch_idx, u8 bw)
2466*4882a593Smuzhiyun {
2467*4882a593Smuzhiyun 	struct halmac_adapter *mac;
2468*4882a593Smuzhiyun 	struct halmac_api *api;
2469*4882a593Smuzhiyun 	enum halmac_ret_status status;
2470*4882a593Smuzhiyun 
2471*4882a593Smuzhiyun 
2472*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
2473*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
2474*4882a593Smuzhiyun 
2475*4882a593Smuzhiyun 	status = api->halmac_cfg_ch_bw(mac, channel, pri_ch_idx, bw);
2476*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
2477*4882a593Smuzhiyun 		return -1;
2478*4882a593Smuzhiyun 
2479*4882a593Smuzhiyun 	return 0;
2480*4882a593Smuzhiyun }
2481*4882a593Smuzhiyun 
2482*4882a593Smuzhiyun /**
2483*4882a593Smuzhiyun  * rtw_halmac_set_edca() - config edca parameter
2484*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2485*4882a593Smuzhiyun  * @queue:	XMIT_[VO/VI/BE/BK]_QUEUE
2486*4882a593Smuzhiyun  * @aifs:	Arbitration inter-frame space(AIFS)
2487*4882a593Smuzhiyun  * @cw:		Contention window(CW)
2488*4882a593Smuzhiyun  * @txop:	MAX Transmit Opportunity(TXOP)
2489*4882a593Smuzhiyun  *
2490*4882a593Smuzhiyun  * Return: 0 if process OK, otherwise -1.
2491*4882a593Smuzhiyun  */
rtw_halmac_set_edca(struct dvobj_priv * d,u8 queue,u8 aifs,u8 cw,u16 txop)2492*4882a593Smuzhiyun int rtw_halmac_set_edca(struct dvobj_priv *d, u8 queue, u8 aifs, u8 cw, u16 txop)
2493*4882a593Smuzhiyun {
2494*4882a593Smuzhiyun 	struct halmac_adapter *mac;
2495*4882a593Smuzhiyun 	struct halmac_api *api;
2496*4882a593Smuzhiyun 	enum halmac_acq_id ac;
2497*4882a593Smuzhiyun 	struct halmac_edca_para edca;
2498*4882a593Smuzhiyun 	enum halmac_ret_status status;
2499*4882a593Smuzhiyun 
2500*4882a593Smuzhiyun 
2501*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
2502*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
2503*4882a593Smuzhiyun 
2504*4882a593Smuzhiyun 	switch (queue) {
2505*4882a593Smuzhiyun 	case XMIT_VO_QUEUE:
2506*4882a593Smuzhiyun 		ac = HALMAC_ACQ_ID_VO;
2507*4882a593Smuzhiyun 		break;
2508*4882a593Smuzhiyun 	case XMIT_VI_QUEUE:
2509*4882a593Smuzhiyun 		ac = HALMAC_ACQ_ID_VI;
2510*4882a593Smuzhiyun 		break;
2511*4882a593Smuzhiyun 	case XMIT_BE_QUEUE:
2512*4882a593Smuzhiyun 		ac = HALMAC_ACQ_ID_BE;
2513*4882a593Smuzhiyun 		break;
2514*4882a593Smuzhiyun 	case XMIT_BK_QUEUE:
2515*4882a593Smuzhiyun 		ac = HALMAC_ACQ_ID_BK;
2516*4882a593Smuzhiyun 		break;
2517*4882a593Smuzhiyun 	default:
2518*4882a593Smuzhiyun 		return -1;
2519*4882a593Smuzhiyun 	}
2520*4882a593Smuzhiyun 
2521*4882a593Smuzhiyun 	edca.aifs = aifs;
2522*4882a593Smuzhiyun 	edca.cw = cw;
2523*4882a593Smuzhiyun 	edca.txop_limit = txop;
2524*4882a593Smuzhiyun 
2525*4882a593Smuzhiyun 	status = api->halmac_cfg_edca_para(mac, ac, &edca);
2526*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2527*4882a593Smuzhiyun 		return -1;
2528*4882a593Smuzhiyun 
2529*4882a593Smuzhiyun 	return 0;
2530*4882a593Smuzhiyun }
2531*4882a593Smuzhiyun 
2532*4882a593Smuzhiyun /**
2533*4882a593Smuzhiyun  * rtw_halmac_set_rts_full_bw() - Send RTS to all covered channels
2534*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
2535*4882a593Smuzhiyun  * @enable:	_TRUE(enable), _FALSE(disable)
2536*4882a593Smuzhiyun  *
2537*4882a593Smuzhiyun  * Hradware will duplicate RTS packet to all channels which are covered in used
2538*4882a593Smuzhiyun  * bandwidth.
2539*4882a593Smuzhiyun  *
2540*4882a593Smuzhiyun  * Return 0 if process OK, otherwise -1.
2541*4882a593Smuzhiyun  */
rtw_halmac_set_rts_full_bw(struct dvobj_priv * d,u8 enable)2542*4882a593Smuzhiyun int rtw_halmac_set_rts_full_bw(struct dvobj_priv *d, u8 enable)
2543*4882a593Smuzhiyun {
2544*4882a593Smuzhiyun 	struct halmac_adapter *mac;
2545*4882a593Smuzhiyun 	struct halmac_api *api;
2546*4882a593Smuzhiyun 	enum halmac_ret_status status;
2547*4882a593Smuzhiyun 	u8 full;
2548*4882a593Smuzhiyun 
2549*4882a593Smuzhiyun 
2550*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
2551*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
2552*4882a593Smuzhiyun 	full = (enable == _TRUE) ? 1 : 0;
2553*4882a593Smuzhiyun 
2554*4882a593Smuzhiyun 	status = api->halmac_set_hw_value(mac, HALMAC_HW_RTS_FULL_BW, &full);
2555*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
2556*4882a593Smuzhiyun 		return -1;
2557*4882a593Smuzhiyun 
2558*4882a593Smuzhiyun 	return 0;
2559*4882a593Smuzhiyun }
2560*4882a593Smuzhiyun 
2561*4882a593Smuzhiyun #ifdef RTW_HALMAC_DBG_POWER_SWITCH
_dump_mac_reg(struct dvobj_priv * d,u32 start,u32 end)2562*4882a593Smuzhiyun static void _dump_mac_reg(struct dvobj_priv *d, u32 start, u32 end)
2563*4882a593Smuzhiyun {
2564*4882a593Smuzhiyun 	struct _ADAPTER *adapter;
2565*4882a593Smuzhiyun 	int i, j = 1;
2566*4882a593Smuzhiyun 
2567*4882a593Smuzhiyun 
2568*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
2569*4882a593Smuzhiyun 	for (i = start; i < end; i += 4) {
2570*4882a593Smuzhiyun 		if (j % 4 == 1)
2571*4882a593Smuzhiyun 			RTW_PRINT("0x%04x", i);
2572*4882a593Smuzhiyun 		_RTW_PRINT(" 0x%08x ", rtw_read32(adapter, i));
2573*4882a593Smuzhiyun 		if ((j++) % 4 == 0)
2574*4882a593Smuzhiyun 			_RTW_PRINT("\n");
2575*4882a593Smuzhiyun 	}
2576*4882a593Smuzhiyun }
2577*4882a593Smuzhiyun 
dump_dbg_val(struct _ADAPTER * a,u32 reg)2578*4882a593Smuzhiyun void dump_dbg_val(struct _ADAPTER *a, u32 reg)
2579*4882a593Smuzhiyun {
2580*4882a593Smuzhiyun 	u32 v32;
2581*4882a593Smuzhiyun 
2582*4882a593Smuzhiyun 
2583*4882a593Smuzhiyun 	rtw_write8(a, 0x3A, reg);
2584*4882a593Smuzhiyun 	v32 = rtw_read32(a, 0xC0);
2585*4882a593Smuzhiyun 	RTW_PRINT("0x3A = %02x, 0xC0 = 0x%08x\n",reg, v32);
2586*4882a593Smuzhiyun }
2587*4882a593Smuzhiyun 
2588*4882a593Smuzhiyun #ifdef CONFIG_PCI_HCI
_dump_pcie_cfg_space(struct dvobj_priv * d)2589*4882a593Smuzhiyun static void _dump_pcie_cfg_space(struct dvobj_priv *d)
2590*4882a593Smuzhiyun {
2591*4882a593Smuzhiyun 	struct _ADAPTER *padapter = dvobj_get_primary_adapter(d);
2592*4882a593Smuzhiyun 	struct dvobj_priv       *pdvobjpriv = adapter_to_dvobj(padapter);
2593*4882a593Smuzhiyun 	struct pci_dev  *pdev = pdvobjpriv->ppcidev;
2594*4882a593Smuzhiyun 	struct pci_dev  *bridge_pdev = pdev->bus->self;
2595*4882a593Smuzhiyun 
2596*4882a593Smuzhiyun         u32 tmp[4] = { 0 };
2597*4882a593Smuzhiyun         u32 i, j;
2598*4882a593Smuzhiyun 
2599*4882a593Smuzhiyun 	RTW_PRINT("\n*****  PCI Device Configuration Space *****\n\n");
2600*4882a593Smuzhiyun 
2601*4882a593Smuzhiyun         for(i = 0; i < 0x100; i += 0x10)
2602*4882a593Smuzhiyun         {
2603*4882a593Smuzhiyun                 for (j = 0 ; j < 4 ; j++)
2604*4882a593Smuzhiyun                         pci_read_config_dword(pdev, i + j * 4, tmp+j);
2605*4882a593Smuzhiyun 
2606*4882a593Smuzhiyun         	RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2607*4882a593Smuzhiyun                         i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2608*4882a593Smuzhiyun                         tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2609*4882a593Smuzhiyun                         tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2610*4882a593Smuzhiyun                         tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2611*4882a593Smuzhiyun         }
2612*4882a593Smuzhiyun 
2613*4882a593Smuzhiyun 	RTW_PRINT("\n*****  PCI Host Device Configuration Space*****\n\n");
2614*4882a593Smuzhiyun 
2615*4882a593Smuzhiyun         for(i = 0; i < 0x100; i += 0x10)
2616*4882a593Smuzhiyun         {
2617*4882a593Smuzhiyun                 for (j = 0 ; j < 4 ; j++)
2618*4882a593Smuzhiyun                         pci_read_config_dword(bridge_pdev, i + j * 4, tmp+j);
2619*4882a593Smuzhiyun 
2620*4882a593Smuzhiyun         	RTW_PRINT("%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
2621*4882a593Smuzhiyun                         i, tmp[0] & 0xFF, (tmp[0] >> 8) & 0xFF, (tmp[0] >> 16) & 0xFF, (tmp[0] >> 24) & 0xFF,
2622*4882a593Smuzhiyun                         tmp[1] & 0xFF, (tmp[1] >> 8) & 0xFF, (tmp[1] >> 16) & 0xFF, (tmp[1] >> 24) & 0xFF,
2623*4882a593Smuzhiyun                         tmp[2] & 0xFF, (tmp[2] >> 8) & 0xFF, (tmp[2] >> 16) & 0xFF, (tmp[2] >> 24) & 0xFF,
2624*4882a593Smuzhiyun                         tmp[3] & 0xFF, (tmp[3] >> 8) & 0xFF, (tmp[3] >> 16) & 0xFF, (tmp[3] >> 24) & 0xFF);
2625*4882a593Smuzhiyun         }
2626*4882a593Smuzhiyun }
2627*4882a593Smuzhiyun #endif
2628*4882a593Smuzhiyun 
_dump_mac_reg_for_power_switch(struct dvobj_priv * d,const char * caller,char * desc)2629*4882a593Smuzhiyun static void _dump_mac_reg_for_power_switch(struct dvobj_priv *d,
2630*4882a593Smuzhiyun 					   const char* caller, char* desc)
2631*4882a593Smuzhiyun {
2632*4882a593Smuzhiyun 	struct _ADAPTER *a;
2633*4882a593Smuzhiyun 	u8 v8;
2634*4882a593Smuzhiyun 
2635*4882a593Smuzhiyun 
2636*4882a593Smuzhiyun 	RTW_PRINT("%s: %s\n", caller, desc);
2637*4882a593Smuzhiyun 	RTW_PRINT("======= MAC REG =======\n");
2638*4882a593Smuzhiyun 	/* page 0/1 */
2639*4882a593Smuzhiyun 	_dump_mac_reg(d, 0x0, 0x200);
2640*4882a593Smuzhiyun 	_dump_mac_reg(d, 0x300, 0x400); /* also dump page 3 */
2641*4882a593Smuzhiyun 
2642*4882a593Smuzhiyun 	/* dump debug register */
2643*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
2644*4882a593Smuzhiyun 
2645*4882a593Smuzhiyun #ifdef CONFIG_PCI_HCI
2646*4882a593Smuzhiyun 	_dump_pcie_cfg_space(d);
2647*4882a593Smuzhiyun 
2648*4882a593Smuzhiyun 	v8 = rtw_read8(a, 0xF6) | 0x01;
2649*4882a593Smuzhiyun 	rtw_write8(a, 0xF6, v8);
2650*4882a593Smuzhiyun 	RTW_PRINT("0xF6 = %02x\n", v8);
2651*4882a593Smuzhiyun 
2652*4882a593Smuzhiyun 	dump_dbg_val(a, 0x63);
2653*4882a593Smuzhiyun 	dump_dbg_val(a, 0x64);
2654*4882a593Smuzhiyun 	dump_dbg_val(a, 0x68);
2655*4882a593Smuzhiyun 	dump_dbg_val(a, 0x69);
2656*4882a593Smuzhiyun 	dump_dbg_val(a, 0x6a);
2657*4882a593Smuzhiyun 	dump_dbg_val(a, 0x6b);
2658*4882a593Smuzhiyun 	dump_dbg_val(a, 0x71);
2659*4882a593Smuzhiyun 	dump_dbg_val(a, 0x72);
2660*4882a593Smuzhiyun #endif
2661*4882a593Smuzhiyun }
2662*4882a593Smuzhiyun 
_power_switch(struct halmac_adapter * halmac,struct halmac_api * api,enum halmac_mac_power pwr)2663*4882a593Smuzhiyun static enum halmac_ret_status _power_switch(struct halmac_adapter *halmac,
2664*4882a593Smuzhiyun 					    struct halmac_api *api,
2665*4882a593Smuzhiyun 					    enum halmac_mac_power pwr)
2666*4882a593Smuzhiyun {
2667*4882a593Smuzhiyun 	enum halmac_ret_status status;
2668*4882a593Smuzhiyun 	char desc[80] = {0};
2669*4882a593Smuzhiyun 
2670*4882a593Smuzhiyun 
2671*4882a593Smuzhiyun 	rtw_sprintf(desc, 80, "before calling power %s",
2672*4882a593Smuzhiyun 				(pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2673*4882a593Smuzhiyun 	_dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2674*4882a593Smuzhiyun 			__FUNCTION__, desc);
2675*4882a593Smuzhiyun 
2676*4882a593Smuzhiyun 	status = api->halmac_mac_power_switch(halmac, pwr);
2677*4882a593Smuzhiyun 	RTW_PRINT("%s: status=%d\n", __FUNCTION__, status);
2678*4882a593Smuzhiyun 
2679*4882a593Smuzhiyun 	rtw_sprintf(desc, 80, "after calling power %s",
2680*4882a593Smuzhiyun 				(pwr==HALMAC_MAC_POWER_ON)?"on":"off");
2681*4882a593Smuzhiyun 	_dump_mac_reg_for_power_switch((struct dvobj_priv *)halmac->drv_adapter,
2682*4882a593Smuzhiyun 			__FUNCTION__, desc);
2683*4882a593Smuzhiyun 
2684*4882a593Smuzhiyun 	return status;
2685*4882a593Smuzhiyun }
2686*4882a593Smuzhiyun #else /* !RTW_HALMAC_DBG_POWER_SWITCH */
2687*4882a593Smuzhiyun #define _power_switch(mac, api, pwr)	(api)->halmac_mac_power_switch(mac, pwr)
2688*4882a593Smuzhiyun #endif /* !RTW_HALMAC_DBG_POWER_SWITCH */
2689*4882a593Smuzhiyun 
2690*4882a593Smuzhiyun /*
2691*4882a593Smuzhiyun  * Description:
2692*4882a593Smuzhiyun  *	Power on device hardware.
2693*4882a593Smuzhiyun  *	[Notice!] If device's power state is on before,
2694*4882a593Smuzhiyun  *	it would be power off first and turn on power again.
2695*4882a593Smuzhiyun  *
2696*4882a593Smuzhiyun  * Return:
2697*4882a593Smuzhiyun  *	0	power on success
2698*4882a593Smuzhiyun  *	-1	power on fail
2699*4882a593Smuzhiyun  *	-2	power state unchange
2700*4882a593Smuzhiyun  */
rtw_halmac_poweron(struct dvobj_priv * d)2701*4882a593Smuzhiyun int rtw_halmac_poweron(struct dvobj_priv *d)
2702*4882a593Smuzhiyun {
2703*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2704*4882a593Smuzhiyun 	struct halmac_api *api;
2705*4882a593Smuzhiyun 	enum halmac_ret_status status;
2706*4882a593Smuzhiyun 	int err = -1;
2707*4882a593Smuzhiyun #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2708*4882a593Smuzhiyun 	struct _ADAPTER *a;
2709*4882a593Smuzhiyun 	u8 v8;
2710*4882a593Smuzhiyun 	u32 addr;
2711*4882a593Smuzhiyun 
2712*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
2713*4882a593Smuzhiyun #endif
2714*4882a593Smuzhiyun 
2715*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2716*4882a593Smuzhiyun 	if (!halmac)
2717*4882a593Smuzhiyun 		goto out;
2718*4882a593Smuzhiyun 
2719*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2720*4882a593Smuzhiyun 
2721*4882a593Smuzhiyun 	status = api->halmac_pre_init_system_cfg(halmac);
2722*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2723*4882a593Smuzhiyun 		goto out;
2724*4882a593Smuzhiyun 
2725*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
2726*4882a593Smuzhiyun 	status = api->halmac_sdio_cmd53_4byte(halmac, HALMAC_SDIO_CMD53_4BYTE_MODE_RW);
2727*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2728*4882a593Smuzhiyun 		goto out;
2729*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
2730*4882a593Smuzhiyun 
2731*4882a593Smuzhiyun #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2732*4882a593Smuzhiyun 	addr = 0x3F3;
2733*4882a593Smuzhiyun 	v8 = rtw_read8(a, addr);
2734*4882a593Smuzhiyun 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2735*4882a593Smuzhiyun 	/* are we in pcie debug mode? */
2736*4882a593Smuzhiyun 	if (!(v8 & BIT(2))) {
2737*4882a593Smuzhiyun 		RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2738*4882a593Smuzhiyun 		v8 |= BIT(2);
2739*4882a593Smuzhiyun 		v8 = rtw_write8(a, addr, v8);
2740*4882a593Smuzhiyun 	}
2741*4882a593Smuzhiyun #endif
2742*4882a593Smuzhiyun 
2743*4882a593Smuzhiyun 	status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2744*4882a593Smuzhiyun 	if (HALMAC_RET_PWR_UNCHANGE == status) {
2745*4882a593Smuzhiyun 
2746*4882a593Smuzhiyun #if defined(CONFIG_PCI_HCI) && defined(CONFIG_RTL8822B)
2747*4882a593Smuzhiyun 		addr = 0x3F3;
2748*4882a593Smuzhiyun 		v8 = rtw_read8(a, addr);
2749*4882a593Smuzhiyun 		RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2750*4882a593Smuzhiyun 
2751*4882a593Smuzhiyun 		/* are we in pcie debug mode? */
2752*4882a593Smuzhiyun 		if (!(v8 & BIT(2))) {
2753*4882a593Smuzhiyun 			RTW_PRINT("%s: Enable pcie debug mode\n", __FUNCTION__);
2754*4882a593Smuzhiyun 			v8 |= BIT(2);
2755*4882a593Smuzhiyun 			v8 = rtw_write8(a, addr, v8);
2756*4882a593Smuzhiyun 		} else if (v8 & BIT(0)) {
2757*4882a593Smuzhiyun 			/* DMA stuck */
2758*4882a593Smuzhiyun 			addr = 0x1350;
2759*4882a593Smuzhiyun 			v8 = rtw_read8(a, addr);
2760*4882a593Smuzhiyun 			RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2761*4882a593Smuzhiyun 			RTW_PRINT("%s: recover DMA stuck\n", __FUNCTION__);
2762*4882a593Smuzhiyun 			v8 |= BIT(6);
2763*4882a593Smuzhiyun 			v8 = rtw_write8(a, addr, v8);
2764*4882a593Smuzhiyun 			RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v8);
2765*4882a593Smuzhiyun 		}
2766*4882a593Smuzhiyun #endif
2767*4882a593Smuzhiyun 		/*
2768*4882a593Smuzhiyun 		 * Work around for warm reboot but device not power off,
2769*4882a593Smuzhiyun 		 * but it would also fall into this case when auto power on is enabled.
2770*4882a593Smuzhiyun 		 */
2771*4882a593Smuzhiyun 		_power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2772*4882a593Smuzhiyun 		status = _power_switch(halmac, api, HALMAC_MAC_POWER_ON);
2773*4882a593Smuzhiyun 		RTW_WARN("%s: Power state abnormal, try to recover...%s\n",
2774*4882a593Smuzhiyun 			 __FUNCTION__, (HALMAC_RET_SUCCESS == status)?"OK":"FAIL!");
2775*4882a593Smuzhiyun 	}
2776*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status) {
2777*4882a593Smuzhiyun 		if (HALMAC_RET_PWR_UNCHANGE == status)
2778*4882a593Smuzhiyun 			err = -2;
2779*4882a593Smuzhiyun 		goto out;
2780*4882a593Smuzhiyun 	}
2781*4882a593Smuzhiyun 
2782*4882a593Smuzhiyun 	status = api->halmac_init_system_cfg(halmac);
2783*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
2784*4882a593Smuzhiyun 		goto out;
2785*4882a593Smuzhiyun 
2786*4882a593Smuzhiyun 	err = 0;
2787*4882a593Smuzhiyun out:
2788*4882a593Smuzhiyun 	return err;
2789*4882a593Smuzhiyun }
2790*4882a593Smuzhiyun 
2791*4882a593Smuzhiyun /*
2792*4882a593Smuzhiyun  * Description:
2793*4882a593Smuzhiyun  *	Power off device hardware.
2794*4882a593Smuzhiyun  *
2795*4882a593Smuzhiyun  * Return:
2796*4882a593Smuzhiyun  *	0	Power off success
2797*4882a593Smuzhiyun  *	-1	Power off fail
2798*4882a593Smuzhiyun  */
rtw_halmac_poweroff(struct dvobj_priv * d)2799*4882a593Smuzhiyun int rtw_halmac_poweroff(struct dvobj_priv *d)
2800*4882a593Smuzhiyun {
2801*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
2802*4882a593Smuzhiyun 	struct halmac_api *api;
2803*4882a593Smuzhiyun 	enum halmac_ret_status status;
2804*4882a593Smuzhiyun 	int err = -1;
2805*4882a593Smuzhiyun 
2806*4882a593Smuzhiyun 
2807*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
2808*4882a593Smuzhiyun 	if (!halmac)
2809*4882a593Smuzhiyun 		goto out;
2810*4882a593Smuzhiyun 
2811*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
2812*4882a593Smuzhiyun 
2813*4882a593Smuzhiyun 	status = _power_switch(halmac, api, HALMAC_MAC_POWER_OFF);
2814*4882a593Smuzhiyun 	if ((HALMAC_RET_SUCCESS != status)
2815*4882a593Smuzhiyun 	    && (HALMAC_RET_PWR_UNCHANGE != status))
2816*4882a593Smuzhiyun 		goto out;
2817*4882a593Smuzhiyun 
2818*4882a593Smuzhiyun 	err = 0;
2819*4882a593Smuzhiyun out:
2820*4882a593Smuzhiyun 	return err;
2821*4882a593Smuzhiyun }
2822*4882a593Smuzhiyun 
2823*4882a593Smuzhiyun #ifdef CONFIG_SUPPORT_TRX_SHARED
_trx_share_mode_drv2halmac(u8 trx_share_mode)2824*4882a593Smuzhiyun static inline enum halmac_rx_fifo_expanding_mode _trx_share_mode_drv2halmac(u8 trx_share_mode)
2825*4882a593Smuzhiyun {
2826*4882a593Smuzhiyun 	if (0 == trx_share_mode)
2827*4882a593Smuzhiyun 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2828*4882a593Smuzhiyun 	else if (1 == trx_share_mode)
2829*4882a593Smuzhiyun 		return HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK;
2830*4882a593Smuzhiyun 	else if (2 == trx_share_mode)
2831*4882a593Smuzhiyun 		return HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK;
2832*4882a593Smuzhiyun 	else if (3 == trx_share_mode)
2833*4882a593Smuzhiyun 		return HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK;
2834*4882a593Smuzhiyun 	else
2835*4882a593Smuzhiyun 		return HALMAC_RX_FIFO_EXPANDING_MODE_DISABLE;
2836*4882a593Smuzhiyun }
2837*4882a593Smuzhiyun 
_rtw_get_trx_share_mode(struct _ADAPTER * adapter)2838*4882a593Smuzhiyun static enum halmac_rx_fifo_expanding_mode _rtw_get_trx_share_mode(struct _ADAPTER *adapter)
2839*4882a593Smuzhiyun {
2840*4882a593Smuzhiyun 	struct registry_priv *registry_par = &adapter->registrypriv;
2841*4882a593Smuzhiyun 
2842*4882a593Smuzhiyun 	return _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2843*4882a593Smuzhiyun }
2844*4882a593Smuzhiyun 
dump_trx_share_mode(void * sel,struct _ADAPTER * adapter)2845*4882a593Smuzhiyun void dump_trx_share_mode(void *sel, struct _ADAPTER *adapter)
2846*4882a593Smuzhiyun {
2847*4882a593Smuzhiyun 	struct registry_priv  *registry_par = &adapter->registrypriv;
2848*4882a593Smuzhiyun 	u8 mode = _trx_share_mode_drv2halmac(registry_par->trx_share_mode);
2849*4882a593Smuzhiyun 
2850*4882a593Smuzhiyun 	if (HALMAC_RX_FIFO_EXPANDING_MODE_1_BLOCK == mode)
2851*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_1");
2852*4882a593Smuzhiyun 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_2_BLOCK == mode)
2853*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_2");
2854*4882a593Smuzhiyun 	else if (HALMAC_RX_FIFO_EXPANDING_MODE_3_BLOCK == mode)
2855*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "RX_FIFO_EXPANDING_MODE_3");
2856*4882a593Smuzhiyun 	else
2857*4882a593Smuzhiyun 		RTW_PRINT_SEL(sel, "TRx share mode : %s\n", "DISABLE");
2858*4882a593Smuzhiyun }
2859*4882a593Smuzhiyun #endif
2860*4882a593Smuzhiyun 
_rsvd_page_num_drv2halmac(u16 num)2861*4882a593Smuzhiyun static enum halmac_drv_rsvd_pg_num _rsvd_page_num_drv2halmac(u16 num)
2862*4882a593Smuzhiyun {
2863*4882a593Smuzhiyun 	if (num <= 8)
2864*4882a593Smuzhiyun 		return HALMAC_RSVD_PG_NUM8;
2865*4882a593Smuzhiyun 	if (num <= 16)
2866*4882a593Smuzhiyun 		return HALMAC_RSVD_PG_NUM16;
2867*4882a593Smuzhiyun 	if (num <= 24)
2868*4882a593Smuzhiyun 		return HALMAC_RSVD_PG_NUM24;
2869*4882a593Smuzhiyun 	if (num <= 32)
2870*4882a593Smuzhiyun 		return HALMAC_RSVD_PG_NUM32;
2871*4882a593Smuzhiyun 	if (num <= 64)
2872*4882a593Smuzhiyun 		return HALMAC_RSVD_PG_NUM64;
2873*4882a593Smuzhiyun 	if (num <= 128)
2874*4882a593Smuzhiyun 		return HALMAC_RSVD_PG_NUM128;
2875*4882a593Smuzhiyun 
2876*4882a593Smuzhiyun 	if (num > 256)
2877*4882a593Smuzhiyun 		RTW_WARN("%s: Fail to allocate RSVD page(%d)!!"
2878*4882a593Smuzhiyun 			 " The MAX RSVD page number is 256...\n",
2879*4882a593Smuzhiyun 			 __FUNCTION__, num);
2880*4882a593Smuzhiyun 
2881*4882a593Smuzhiyun 	return HALMAC_RSVD_PG_NUM256;
2882*4882a593Smuzhiyun }
2883*4882a593Smuzhiyun 
_rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)2884*4882a593Smuzhiyun static u16 _rsvd_page_num_halmac2drv(enum halmac_drv_rsvd_pg_num rsvd_page_number)
2885*4882a593Smuzhiyun {
2886*4882a593Smuzhiyun 	u16 num = 0;
2887*4882a593Smuzhiyun 
2888*4882a593Smuzhiyun 
2889*4882a593Smuzhiyun 	switch (rsvd_page_number) {
2890*4882a593Smuzhiyun 	case HALMAC_RSVD_PG_NUM8:
2891*4882a593Smuzhiyun 		num = 8;
2892*4882a593Smuzhiyun 		break;
2893*4882a593Smuzhiyun 
2894*4882a593Smuzhiyun 	case HALMAC_RSVD_PG_NUM16:
2895*4882a593Smuzhiyun 		num = 16;
2896*4882a593Smuzhiyun 		break;
2897*4882a593Smuzhiyun 
2898*4882a593Smuzhiyun 	case HALMAC_RSVD_PG_NUM24:
2899*4882a593Smuzhiyun 		num = 24;
2900*4882a593Smuzhiyun 		break;
2901*4882a593Smuzhiyun 
2902*4882a593Smuzhiyun 	case HALMAC_RSVD_PG_NUM32:
2903*4882a593Smuzhiyun 		num = 32;
2904*4882a593Smuzhiyun 		break;
2905*4882a593Smuzhiyun 
2906*4882a593Smuzhiyun 	case HALMAC_RSVD_PG_NUM64:
2907*4882a593Smuzhiyun 		num = 64;
2908*4882a593Smuzhiyun 		break;
2909*4882a593Smuzhiyun 
2910*4882a593Smuzhiyun 	case HALMAC_RSVD_PG_NUM128:
2911*4882a593Smuzhiyun 		num = 128;
2912*4882a593Smuzhiyun 		break;
2913*4882a593Smuzhiyun 
2914*4882a593Smuzhiyun 	case HALMAC_RSVD_PG_NUM256:
2915*4882a593Smuzhiyun 		num = 256;
2916*4882a593Smuzhiyun 		break;
2917*4882a593Smuzhiyun 	}
2918*4882a593Smuzhiyun 
2919*4882a593Smuzhiyun 	return num;
2920*4882a593Smuzhiyun }
2921*4882a593Smuzhiyun 
_choose_trx_mode(struct dvobj_priv * d)2922*4882a593Smuzhiyun static enum halmac_trx_mode _choose_trx_mode(struct dvobj_priv *d)
2923*4882a593Smuzhiyun {
2924*4882a593Smuzhiyun 	PADAPTER p;
2925*4882a593Smuzhiyun 
2926*4882a593Smuzhiyun 
2927*4882a593Smuzhiyun 	p = dvobj_get_primary_adapter(d);
2928*4882a593Smuzhiyun 
2929*4882a593Smuzhiyun 	if (p->registrypriv.wifi_spec)
2930*4882a593Smuzhiyun 		return HALMAC_TRX_MODE_WMM;
2931*4882a593Smuzhiyun 
2932*4882a593Smuzhiyun #ifdef CONFIG_SUPPORT_TRX_SHARED
2933*4882a593Smuzhiyun 	if (_rtw_get_trx_share_mode(p))
2934*4882a593Smuzhiyun 		return HALMAC_TRX_MODE_TRXSHARE;
2935*4882a593Smuzhiyun #endif
2936*4882a593Smuzhiyun 
2937*4882a593Smuzhiyun 	return HALMAC_TRX_MODE_NORMAL;
2938*4882a593Smuzhiyun }
2939*4882a593Smuzhiyun 
_rf_type_drv2halmac(enum rf_type rf_drv)2940*4882a593Smuzhiyun static inline enum halmac_rf_type _rf_type_drv2halmac(enum rf_type rf_drv)
2941*4882a593Smuzhiyun {
2942*4882a593Smuzhiyun 	enum halmac_rf_type rf_mac;
2943*4882a593Smuzhiyun 
2944*4882a593Smuzhiyun 
2945*4882a593Smuzhiyun 	switch (rf_drv) {
2946*4882a593Smuzhiyun 	case RF_1T1R:
2947*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_1T1R;
2948*4882a593Smuzhiyun 		break;
2949*4882a593Smuzhiyun 	case RF_1T2R:
2950*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_1T2R;
2951*4882a593Smuzhiyun 		break;
2952*4882a593Smuzhiyun 	case RF_2T2R:
2953*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_2T2R;
2954*4882a593Smuzhiyun 		break;
2955*4882a593Smuzhiyun 	case RF_2T3R:
2956*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_2T3R;
2957*4882a593Smuzhiyun 		break;
2958*4882a593Smuzhiyun 	case RF_2T4R:
2959*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_2T4R;
2960*4882a593Smuzhiyun 		break;
2961*4882a593Smuzhiyun 	case RF_3T3R:
2962*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_3T3R;
2963*4882a593Smuzhiyun 		break;
2964*4882a593Smuzhiyun 	case RF_3T4R:
2965*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_3T4R;
2966*4882a593Smuzhiyun 		break;
2967*4882a593Smuzhiyun 	case RF_4T4R:
2968*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_4T4R;
2969*4882a593Smuzhiyun 		break;
2970*4882a593Smuzhiyun 	default:
2971*4882a593Smuzhiyun 		rf_mac = HALMAC_RF_MAX_TYPE;
2972*4882a593Smuzhiyun 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_drv);
2973*4882a593Smuzhiyun 		break;
2974*4882a593Smuzhiyun 	}
2975*4882a593Smuzhiyun 
2976*4882a593Smuzhiyun 	return rf_mac;
2977*4882a593Smuzhiyun }
2978*4882a593Smuzhiyun 
_rf_type_halmac2drv(enum halmac_rf_type rf_mac)2979*4882a593Smuzhiyun static inline enum rf_type _rf_type_halmac2drv(enum halmac_rf_type rf_mac)
2980*4882a593Smuzhiyun {
2981*4882a593Smuzhiyun 	enum rf_type rf_drv;
2982*4882a593Smuzhiyun 
2983*4882a593Smuzhiyun 
2984*4882a593Smuzhiyun 	switch (rf_mac) {
2985*4882a593Smuzhiyun 	case HALMAC_RF_1T2R:
2986*4882a593Smuzhiyun 		rf_drv = RF_1T2R;
2987*4882a593Smuzhiyun 		break;
2988*4882a593Smuzhiyun 	case HALMAC_RF_2T4R:
2989*4882a593Smuzhiyun 		rf_drv = RF_2T4R;
2990*4882a593Smuzhiyun 		break;
2991*4882a593Smuzhiyun 	case HALMAC_RF_2T2R:
2992*4882a593Smuzhiyun 	case HALMAC_RF_2T2R_GREEN:
2993*4882a593Smuzhiyun 		rf_drv = RF_2T2R;
2994*4882a593Smuzhiyun 		break;
2995*4882a593Smuzhiyun 	case HALMAC_RF_2T3R:
2996*4882a593Smuzhiyun 		rf_drv = RF_2T3R;
2997*4882a593Smuzhiyun 		break;
2998*4882a593Smuzhiyun 	case HALMAC_RF_1T1R:
2999*4882a593Smuzhiyun 		rf_drv = RF_1T1R;
3000*4882a593Smuzhiyun 		break;
3001*4882a593Smuzhiyun 	case HALMAC_RF_3T3R:
3002*4882a593Smuzhiyun 		rf_drv = RF_3T3R;
3003*4882a593Smuzhiyun 		break;
3004*4882a593Smuzhiyun 	case HALMAC_RF_3T4R:
3005*4882a593Smuzhiyun 		rf_drv = RF_3T4R;
3006*4882a593Smuzhiyun 		break;
3007*4882a593Smuzhiyun 	case HALMAC_RF_4T4R:
3008*4882a593Smuzhiyun 		rf_drv = RF_4T4R;
3009*4882a593Smuzhiyun 		break;
3010*4882a593Smuzhiyun 	default:
3011*4882a593Smuzhiyun 		rf_drv = RF_TYPE_MAX;
3012*4882a593Smuzhiyun 		RTW_ERR("%s: Invalid RF type(0x%x)!\n", __FUNCTION__, rf_mac);
3013*4882a593Smuzhiyun 		break;
3014*4882a593Smuzhiyun 	}
3015*4882a593Smuzhiyun 
3016*4882a593Smuzhiyun 	return rf_drv;
3017*4882a593Smuzhiyun }
3018*4882a593Smuzhiyun 
_cut_version_drv2phydm(enum tag_HAL_Cut_Version_Definition cut_drv)3019*4882a593Smuzhiyun static enum odm_cut_version _cut_version_drv2phydm(
3020*4882a593Smuzhiyun 				enum tag_HAL_Cut_Version_Definition cut_drv)
3021*4882a593Smuzhiyun {
3022*4882a593Smuzhiyun 	enum odm_cut_version cut_phydm = ODM_CUT_A;
3023*4882a593Smuzhiyun 	u32 diff;
3024*4882a593Smuzhiyun 
3025*4882a593Smuzhiyun 
3026*4882a593Smuzhiyun 	if (cut_drv > K_CUT_VERSION)
3027*4882a593Smuzhiyun 		RTW_WARN("%s: unknown cut_ver=%d !!\n", __FUNCTION__, cut_drv);
3028*4882a593Smuzhiyun 
3029*4882a593Smuzhiyun 	diff = cut_drv - A_CUT_VERSION;
3030*4882a593Smuzhiyun 	cut_phydm += diff;
3031*4882a593Smuzhiyun 
3032*4882a593Smuzhiyun 	return cut_phydm;
3033*4882a593Smuzhiyun }
3034*4882a593Smuzhiyun 
_send_general_info_by_reg(struct dvobj_priv * d,struct halmac_general_info * info)3035*4882a593Smuzhiyun static int _send_general_info_by_reg(struct dvobj_priv *d,
3036*4882a593Smuzhiyun 				     struct halmac_general_info *info)
3037*4882a593Smuzhiyun {
3038*4882a593Smuzhiyun 	struct _ADAPTER *a;
3039*4882a593Smuzhiyun 	struct hal_com_data *hal;
3040*4882a593Smuzhiyun 	enum tag_HAL_Cut_Version_Definition cut_drv;
3041*4882a593Smuzhiyun 	enum rf_type rftype;
3042*4882a593Smuzhiyun 	enum odm_cut_version cut_phydm;
3043*4882a593Smuzhiyun 	u8 h2c[RTW_HALMAC_H2C_MAX_SIZE] = {0};
3044*4882a593Smuzhiyun 
3045*4882a593Smuzhiyun 
3046*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
3047*4882a593Smuzhiyun 	hal = GET_HAL_DATA(a);
3048*4882a593Smuzhiyun 	rftype = _rf_type_halmac2drv(info->rf_type);
3049*4882a593Smuzhiyun 	cut_drv = GET_CVID_CUT_VERSION(hal->version_id);
3050*4882a593Smuzhiyun 	cut_phydm = _cut_version_drv2phydm(cut_drv);
3051*4882a593Smuzhiyun 
3052*4882a593Smuzhiyun #define CLASS_GENERAL_INFO_REG				0x02
3053*4882a593Smuzhiyun #define CMD_ID_GENERAL_INFO_REG				0x0C
3054*4882a593Smuzhiyun #define GENERAL_INFO_REG_SET_CMD_ID(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 0, 5, v)
3055*4882a593Smuzhiyun #define GENERAL_INFO_REG_SET_CLASS(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 5, 3, v)
3056*4882a593Smuzhiyun #define GENERAL_INFO_REG_SET_RFE_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 8, 8, v)
3057*4882a593Smuzhiyun #define GENERAL_INFO_REG_SET_RF_TYPE(buf, v)		SET_BITS_TO_LE_4BYTE(buf, 16, 8, v)
3058*4882a593Smuzhiyun #define GENERAL_INFO_REG_SET_CUT_VERSION(buf, v)	SET_BITS_TO_LE_4BYTE(buf, 24, 8, v)
3059*4882a593Smuzhiyun #define GENERAL_INFO_REG_SET_RX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 0, 4, v)
3060*4882a593Smuzhiyun #define GENERAL_INFO_REG_SET_TX_ANT_STATUS(buf, v)	SET_BITS_TO_LE_1BYTE(buf+4, 4, 4, v)
3061*4882a593Smuzhiyun 
3062*4882a593Smuzhiyun 	GENERAL_INFO_REG_SET_CMD_ID(h2c, CMD_ID_GENERAL_INFO_REG);
3063*4882a593Smuzhiyun 	GENERAL_INFO_REG_SET_CLASS(h2c, CLASS_GENERAL_INFO_REG);
3064*4882a593Smuzhiyun 	GENERAL_INFO_REG_SET_RFE_TYPE(h2c, info->rfe_type);
3065*4882a593Smuzhiyun 	GENERAL_INFO_REG_SET_RF_TYPE(h2c, rftype);
3066*4882a593Smuzhiyun 	GENERAL_INFO_REG_SET_CUT_VERSION(h2c, cut_phydm);
3067*4882a593Smuzhiyun 	GENERAL_INFO_REG_SET_RX_ANT_STATUS(h2c, info->rx_ant_status);
3068*4882a593Smuzhiyun 	GENERAL_INFO_REG_SET_TX_ANT_STATUS(h2c, info->tx_ant_status);
3069*4882a593Smuzhiyun 
3070*4882a593Smuzhiyun 	return rtw_halmac_send_h2c(d, h2c);
3071*4882a593Smuzhiyun }
3072*4882a593Smuzhiyun 
_send_general_info(struct dvobj_priv * d)3073*4882a593Smuzhiyun static int _send_general_info(struct dvobj_priv *d)
3074*4882a593Smuzhiyun {
3075*4882a593Smuzhiyun 	struct _ADAPTER *adapter;
3076*4882a593Smuzhiyun 	struct hal_com_data *hal;
3077*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
3078*4882a593Smuzhiyun 	struct halmac_api *api;
3079*4882a593Smuzhiyun 	struct halmac_general_info info;
3080*4882a593Smuzhiyun 	enum halmac_ret_status status;
3081*4882a593Smuzhiyun 	enum rf_type rf = RF_1T1R;
3082*4882a593Smuzhiyun 	enum bb_path txpath = BB_PATH_A;
3083*4882a593Smuzhiyun 	enum bb_path rxpath = BB_PATH_A;
3084*4882a593Smuzhiyun 	int err;
3085*4882a593Smuzhiyun 
3086*4882a593Smuzhiyun 
3087*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
3088*4882a593Smuzhiyun 	hal = GET_HAL_DATA(adapter);
3089*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
3090*4882a593Smuzhiyun 	if (!halmac)
3091*4882a593Smuzhiyun 		return -1;
3092*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
3093*4882a593Smuzhiyun 
3094*4882a593Smuzhiyun 	_rtw_memset(&info, 0, sizeof(info));
3095*4882a593Smuzhiyun 	info.rfe_type = (u8)hal->rfe_type;
3096*4882a593Smuzhiyun 	rtw_hal_get_trx_path(d, &rf, &txpath, &rxpath);
3097*4882a593Smuzhiyun 	info.rf_type = _rf_type_drv2halmac(rf);
3098*4882a593Smuzhiyun 	info.tx_ant_status = (u8)txpath;
3099*4882a593Smuzhiyun 	info.rx_ant_status = (u8)rxpath;
3100*4882a593Smuzhiyun 	info.ext_pa = 0;	/* 2.4G or 5G? format not known */
3101*4882a593Smuzhiyun 	info.package_type = hal->PackageType;
3102*4882a593Smuzhiyun 	info.mp_mode = adapter->registrypriv.mp_mode;
3103*4882a593Smuzhiyun 
3104*4882a593Smuzhiyun 	status = api->halmac_send_general_info(halmac, &info);
3105*4882a593Smuzhiyun 	switch (status) {
3106*4882a593Smuzhiyun 	case HALMAC_RET_SUCCESS:
3107*4882a593Smuzhiyun 		break;
3108*4882a593Smuzhiyun 	case HALMAC_RET_NO_DLFW:
3109*4882a593Smuzhiyun 		RTW_WARN("%s: halmac_send_general_info() fail because fw not dl!\n",
3110*4882a593Smuzhiyun 			 __FUNCTION__);
3111*4882a593Smuzhiyun 		/* fall through */
3112*4882a593Smuzhiyun 	default:
3113*4882a593Smuzhiyun 		return -1;
3114*4882a593Smuzhiyun 	}
3115*4882a593Smuzhiyun 
3116*4882a593Smuzhiyun 	err = _send_general_info_by_reg(d, &info);
3117*4882a593Smuzhiyun 	if (err) {
3118*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to send general info by register!\n",
3119*4882a593Smuzhiyun 			 __FUNCTION__);
3120*4882a593Smuzhiyun 		return -1;
3121*4882a593Smuzhiyun 	}
3122*4882a593Smuzhiyun 
3123*4882a593Smuzhiyun 	return 0;
3124*4882a593Smuzhiyun }
3125*4882a593Smuzhiyun 
_cfg_drv_rsvd_pg_num(struct dvobj_priv * d)3126*4882a593Smuzhiyun static int _cfg_drv_rsvd_pg_num(struct dvobj_priv *d)
3127*4882a593Smuzhiyun {
3128*4882a593Smuzhiyun 	struct _ADAPTER *a;
3129*4882a593Smuzhiyun 	struct hal_com_data *hal;
3130*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
3131*4882a593Smuzhiyun 	struct halmac_api *api;
3132*4882a593Smuzhiyun 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3133*4882a593Smuzhiyun 	enum halmac_ret_status status;
3134*4882a593Smuzhiyun 	u16 drv_rsvd_num;
3135*4882a593Smuzhiyun 	int ret = 0;
3136*4882a593Smuzhiyun 
3137*4882a593Smuzhiyun 
3138*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
3139*4882a593Smuzhiyun 	hal = GET_HAL_DATA(a);
3140*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
3141*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
3142*4882a593Smuzhiyun 
3143*4882a593Smuzhiyun 	drv_rsvd_num = rtw_hal_get_rsvd_page_num(a);
3144*4882a593Smuzhiyun 	rsvd_page_number = _rsvd_page_num_drv2halmac(drv_rsvd_num);
3145*4882a593Smuzhiyun 	status = api->halmac_cfg_drv_rsvd_pg_num(halmac, rsvd_page_number);
3146*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
3147*4882a593Smuzhiyun 		ret = -1;
3148*4882a593Smuzhiyun 		goto exit;
3149*4882a593Smuzhiyun 	}
3150*4882a593Smuzhiyun 	hal->drv_rsvd_page_number = _rsvd_page_num_halmac2drv(rsvd_page_number);
3151*4882a593Smuzhiyun 
3152*4882a593Smuzhiyun exit:
3153*4882a593Smuzhiyun #ifndef DBG_RSVD_PAGE_CFG
3154*4882a593Smuzhiyun 	if (drv_rsvd_num != _rsvd_page_num_halmac2drv(rsvd_page_number))
3155*4882a593Smuzhiyun #endif
3156*4882a593Smuzhiyun 		RTW_INFO("%s: request %d pages => halmac %d pages %s\n"
3157*4882a593Smuzhiyun 			, __FUNCTION__, drv_rsvd_num, _rsvd_page_num_halmac2drv(rsvd_page_number)
3158*4882a593Smuzhiyun 			, ret ? "fail" : "success");
3159*4882a593Smuzhiyun 
3160*4882a593Smuzhiyun 	return ret;
3161*4882a593Smuzhiyun }
3162*4882a593Smuzhiyun 
_debug_dlfw_fail(struct dvobj_priv * d)3163*4882a593Smuzhiyun static void _debug_dlfw_fail(struct dvobj_priv *d)
3164*4882a593Smuzhiyun {
3165*4882a593Smuzhiyun 	struct _ADAPTER *a;
3166*4882a593Smuzhiyun 	u32 addr;
3167*4882a593Smuzhiyun 	u32 v32, i, n;
3168*4882a593Smuzhiyun 
3169*4882a593Smuzhiyun 
3170*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
3171*4882a593Smuzhiyun 
3172*4882a593Smuzhiyun 	/* read 0x80[15:0], 0x10F8[31:0] once */
3173*4882a593Smuzhiyun 	addr = 0x80;
3174*4882a593Smuzhiyun 	v32 = rtw_read16(a, addr);
3175*4882a593Smuzhiyun 	RTW_PRINT("%s: 0x%X = 0x%04x\n", __FUNCTION__, addr, v32);
3176*4882a593Smuzhiyun 
3177*4882a593Smuzhiyun 	addr = 0x10F8;
3178*4882a593Smuzhiyun 	v32 = rtw_read32(a, addr);
3179*4882a593Smuzhiyun 	RTW_PRINT("%s: 0x%X = 0x%08x\n", __FUNCTION__, addr, v32);
3180*4882a593Smuzhiyun 
3181*4882a593Smuzhiyun 	/* read 0x10FC[31:0], 5 times */
3182*4882a593Smuzhiyun 	addr = 0x10FC;
3183*4882a593Smuzhiyun 	n = 5;
3184*4882a593Smuzhiyun 	for (i = 0; i < n; i++) {
3185*4882a593Smuzhiyun 		v32 = rtw_read32(a, addr);
3186*4882a593Smuzhiyun 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3187*4882a593Smuzhiyun 			  __FUNCTION__, addr, v32, i, n);
3188*4882a593Smuzhiyun 	}
3189*4882a593Smuzhiyun 
3190*4882a593Smuzhiyun 	/*
3191*4882a593Smuzhiyun 	 * write 0x3A[7:0]=0x28 and 0xF6[7:0]=0x01
3192*4882a593Smuzhiyun 	 * and then read 0xC0[31:0] 5 times
3193*4882a593Smuzhiyun 	 */
3194*4882a593Smuzhiyun 	addr = 0x3A;
3195*4882a593Smuzhiyun 	v32 = 0x28;
3196*4882a593Smuzhiyun 	rtw_write8(a, addr, (u8)v32);
3197*4882a593Smuzhiyun 	v32 = rtw_read8(a, addr);
3198*4882a593Smuzhiyun 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3199*4882a593Smuzhiyun 
3200*4882a593Smuzhiyun 	addr = 0xF6;
3201*4882a593Smuzhiyun 	v32 = 0x1;
3202*4882a593Smuzhiyun 	rtw_write8(a, addr, (u8)v32);
3203*4882a593Smuzhiyun 	v32 = rtw_read8(a, addr);
3204*4882a593Smuzhiyun 	RTW_PRINT("%s: 0x%X = 0x%02x\n", __FUNCTION__, addr, v32);
3205*4882a593Smuzhiyun 
3206*4882a593Smuzhiyun 	addr = 0xC0;
3207*4882a593Smuzhiyun 	n = 5;
3208*4882a593Smuzhiyun 	for (i = 0; i < n; i++) {
3209*4882a593Smuzhiyun 		v32 = rtw_read32(a, addr);
3210*4882a593Smuzhiyun 		RTW_PRINT("%s: 0x%X = 0x%08x (%u/%u)\n",
3211*4882a593Smuzhiyun 			  __FUNCTION__, addr, v32, i, n);
3212*4882a593Smuzhiyun 	}
3213*4882a593Smuzhiyun 
3214*4882a593Smuzhiyun 	mac_reg_dump(NULL, a);
3215*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
3216*4882a593Smuzhiyun 	RTW_PRINT("======= SDIO Local REG =======\n");
3217*4882a593Smuzhiyun 	sdio_local_reg_dump(NULL, a);
3218*4882a593Smuzhiyun 	RTW_PRINT("======= SDIO CCCR REG =======\n");
3219*4882a593Smuzhiyun 	sd_f0_reg_dump(NULL, a);
3220*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
3221*4882a593Smuzhiyun 
3222*4882a593Smuzhiyun 	/* read 0x80 after 10 secs */
3223*4882a593Smuzhiyun 	rtw_msleep_os(10000);
3224*4882a593Smuzhiyun 	addr = 0x80;
3225*4882a593Smuzhiyun 	v32 = rtw_read16(a, addr);
3226*4882a593Smuzhiyun 	RTW_PRINT("%s: 0x%X = 0x%04x (after 10 secs)\n",
3227*4882a593Smuzhiyun 		  __FUNCTION__, addr, v32);
3228*4882a593Smuzhiyun }
3229*4882a593Smuzhiyun 
_enter_cpu_sleep_mode(struct dvobj_priv * d)3230*4882a593Smuzhiyun static enum halmac_ret_status _enter_cpu_sleep_mode(struct dvobj_priv *d)
3231*4882a593Smuzhiyun {
3232*4882a593Smuzhiyun 	struct hal_com_data *hal;
3233*4882a593Smuzhiyun 	struct halmac_adapter *mac;
3234*4882a593Smuzhiyun 	struct halmac_api *api;
3235*4882a593Smuzhiyun 
3236*4882a593Smuzhiyun 
3237*4882a593Smuzhiyun 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3238*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
3239*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
3240*4882a593Smuzhiyun 
3241*4882a593Smuzhiyun #ifdef CONFIG_RTL8822B
3242*4882a593Smuzhiyun 	/* Support after firmware version 21 */
3243*4882a593Smuzhiyun 	if (hal->firmware_version < 21)
3244*4882a593Smuzhiyun 		return HALMAC_RET_NOT_SUPPORT;
3245*4882a593Smuzhiyun #elif defined(CONFIG_RTL8821C)
3246*4882a593Smuzhiyun 	/* Support after firmware version 13.6 or 16 */
3247*4882a593Smuzhiyun 	if (hal->firmware_version == 13) {
3248*4882a593Smuzhiyun 		if (hal->firmware_sub_version < 6)
3249*4882a593Smuzhiyun 			return HALMAC_RET_NOT_SUPPORT;
3250*4882a593Smuzhiyun 	} else if (hal->firmware_version < 16) {
3251*4882a593Smuzhiyun 		return HALMAC_RET_NOT_SUPPORT;
3252*4882a593Smuzhiyun 	}
3253*4882a593Smuzhiyun #endif
3254*4882a593Smuzhiyun 
3255*4882a593Smuzhiyun 	return api->halmac_enter_cpu_sleep_mode(mac);
3256*4882a593Smuzhiyun }
3257*4882a593Smuzhiyun 
3258*4882a593Smuzhiyun /*
3259*4882a593Smuzhiyun  * _cpu_sleep() - Let IC CPU enter sleep mode
3260*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
3261*4882a593Smuzhiyun  * @timeout:	time limit of wait, unit is ms
3262*4882a593Smuzhiyun  *		0 for no limit
3263*4882a593Smuzhiyun  *
3264*4882a593Smuzhiyun  * Return 0 for CPU in sleep mode, otherwise fail to enter sleep mode.
3265*4882a593Smuzhiyun  * Error codes definition are as follow:
3266*4882a593Smuzhiyun  * 	-1	HALMAC enter sleep return fail
3267*4882a593Smuzhiyun  *	-2	HALMAC get CPU mode return fail
3268*4882a593Smuzhiyun  *	-110	timeout
3269*4882a593Smuzhiyun  */
_cpu_sleep(struct dvobj_priv * d,u32 timeout)3270*4882a593Smuzhiyun static int _cpu_sleep(struct dvobj_priv *d, u32 timeout)
3271*4882a593Smuzhiyun {
3272*4882a593Smuzhiyun 	struct halmac_adapter *mac;
3273*4882a593Smuzhiyun 	struct halmac_api *api;
3274*4882a593Smuzhiyun 	enum halmac_ret_status status;
3275*4882a593Smuzhiyun 	enum halmac_wlcpu_mode mode = HALMAC_WLCPU_UNDEFINE;
3276*4882a593Smuzhiyun 	systime start_t;
3277*4882a593Smuzhiyun 	s32 period = 0;
3278*4882a593Smuzhiyun 	u32 cnt = 0;
3279*4882a593Smuzhiyun 	int err = 0;
3280*4882a593Smuzhiyun 
3281*4882a593Smuzhiyun 
3282*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
3283*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
3284*4882a593Smuzhiyun 
3285*4882a593Smuzhiyun 	start_t = rtw_get_current_time();
3286*4882a593Smuzhiyun 
3287*4882a593Smuzhiyun 	status = _enter_cpu_sleep_mode(d);
3288*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
3289*4882a593Smuzhiyun 		if (status != HALMAC_RET_NOT_SUPPORT)
3290*4882a593Smuzhiyun 			err = -1;
3291*4882a593Smuzhiyun 		goto exit;
3292*4882a593Smuzhiyun 	}
3293*4882a593Smuzhiyun 
3294*4882a593Smuzhiyun 	do {
3295*4882a593Smuzhiyun 		cnt++;
3296*4882a593Smuzhiyun 
3297*4882a593Smuzhiyun 		mode = HALMAC_WLCPU_UNDEFINE;
3298*4882a593Smuzhiyun 		status = api->halmac_get_cpu_mode(mac, &mode);
3299*4882a593Smuzhiyun 
3300*4882a593Smuzhiyun 		period = rtw_get_passing_time_ms(start_t);
3301*4882a593Smuzhiyun 
3302*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
3303*4882a593Smuzhiyun 			err = -2;
3304*4882a593Smuzhiyun 			break;
3305*4882a593Smuzhiyun 		}
3306*4882a593Smuzhiyun 		if (mode == HALMAC_WLCPU_SLEEP)
3307*4882a593Smuzhiyun 			break;
3308*4882a593Smuzhiyun 		if (period > timeout) {
3309*4882a593Smuzhiyun 			err = -110;
3310*4882a593Smuzhiyun 			break;
3311*4882a593Smuzhiyun 		}
3312*4882a593Smuzhiyun 
3313*4882a593Smuzhiyun 		rtw_msleep_os(1);
3314*4882a593Smuzhiyun 	} while (1);
3315*4882a593Smuzhiyun 
3316*4882a593Smuzhiyun exit:
3317*4882a593Smuzhiyun 	if (err)
3318*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to enter sleep mode! (%d, %d)\n",
3319*4882a593Smuzhiyun 			__FUNCTION__, status, mode);
3320*4882a593Smuzhiyun 
3321*4882a593Smuzhiyun 	RTW_INFO("%s: Cost %dms to polling %u times. (err=%d)\n",
3322*4882a593Smuzhiyun 		__FUNCTION__, period, cnt, err);
3323*4882a593Smuzhiyun 
3324*4882a593Smuzhiyun 	return err;
3325*4882a593Smuzhiyun }
3326*4882a593Smuzhiyun 
_init_trx_cfg_drv(struct dvobj_priv * d)3327*4882a593Smuzhiyun static void _init_trx_cfg_drv(struct dvobj_priv *d)
3328*4882a593Smuzhiyun {
3329*4882a593Smuzhiyun #ifdef CONFIG_PCI_HCI
3330*4882a593Smuzhiyun 	rtw_hal_irp_reset(dvobj_get_primary_adapter(d));
3331*4882a593Smuzhiyun #endif
3332*4882a593Smuzhiyun }
3333*4882a593Smuzhiyun 
3334*4882a593Smuzhiyun /*
3335*4882a593Smuzhiyun  * Description:
3336*4882a593Smuzhiyun  *	Downlaod Firmware Flow
3337*4882a593Smuzhiyun  *
3338*4882a593Smuzhiyun  * Parameters:
3339*4882a593Smuzhiyun  *	d	pointer of struct dvobj_priv
3340*4882a593Smuzhiyun  *	fw	firmware array
3341*4882a593Smuzhiyun  *	fwsize	firmware size
3342*4882a593Smuzhiyun  *	re_dl	re-download firmware or not
3343*4882a593Smuzhiyun  *		0: run in init hal flow, not re-download
3344*4882a593Smuzhiyun  *		1: it is a stand alone operation, not in init hal flow
3345*4882a593Smuzhiyun  *
3346*4882a593Smuzhiyun  * Return:
3347*4882a593Smuzhiyun  *	0	Success
3348*4882a593Smuzhiyun  *	others	Fail
3349*4882a593Smuzhiyun  */
download_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize,u8 re_dl)3350*4882a593Smuzhiyun static int download_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize, u8 re_dl)
3351*4882a593Smuzhiyun {
3352*4882a593Smuzhiyun 	PHAL_DATA_TYPE hal;
3353*4882a593Smuzhiyun 	struct halmac_adapter *mac;
3354*4882a593Smuzhiyun 	struct halmac_api *api;
3355*4882a593Smuzhiyun 	struct halmac_fw_version fw_vesion;
3356*4882a593Smuzhiyun 	enum halmac_ret_status status;
3357*4882a593Smuzhiyun 	int err = 0;
3358*4882a593Smuzhiyun 
3359*4882a593Smuzhiyun 
3360*4882a593Smuzhiyun 	hal = GET_HAL_DATA(dvobj_get_primary_adapter(d));
3361*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
3362*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
3363*4882a593Smuzhiyun 
3364*4882a593Smuzhiyun 	if ((!fw) || (!fwsize))
3365*4882a593Smuzhiyun 		return -1;
3366*4882a593Smuzhiyun 
3367*4882a593Smuzhiyun 	/* 1. Driver Stop Tx */
3368*4882a593Smuzhiyun 	/* ToDo */
3369*4882a593Smuzhiyun 
3370*4882a593Smuzhiyun 	/* 2. Driver Check Tx FIFO is empty */
3371*4882a593Smuzhiyun 	err = rtw_halmac_txfifo_wait_empty(d, 2000); /* wait 2s */
3372*4882a593Smuzhiyun 	if (err) {
3373*4882a593Smuzhiyun 		err = -1;
3374*4882a593Smuzhiyun 		goto resume_tx;
3375*4882a593Smuzhiyun 	}
3376*4882a593Smuzhiyun 
3377*4882a593Smuzhiyun 	/* 3. Config MAX download size */
3378*4882a593Smuzhiyun 	/*
3379*4882a593Smuzhiyun 	 * Already done in rtw_halmac_init_adapter() or
3380*4882a593Smuzhiyun 	 * somewhere calling rtw_halmac_set_max_dl_fw_size().
3381*4882a593Smuzhiyun 	 */
3382*4882a593Smuzhiyun 
3383*4882a593Smuzhiyun 	if (re_dl) {
3384*4882a593Smuzhiyun 		/* 4. Enter IC CPU sleep mode */
3385*4882a593Smuzhiyun 		err = _cpu_sleep(d, 2000);
3386*4882a593Smuzhiyun 		if (err) {
3387*4882a593Smuzhiyun 			RTW_ERR("%s: IC CPU fail to enter sleep mode!(%d)\n",
3388*4882a593Smuzhiyun 				__FUNCTION__, err);
3389*4882a593Smuzhiyun 			/* skip this error */
3390*4882a593Smuzhiyun 			err = 0;
3391*4882a593Smuzhiyun 		}
3392*4882a593Smuzhiyun 	}
3393*4882a593Smuzhiyun 
3394*4882a593Smuzhiyun 	/* 5. Download Firmware */
3395*4882a593Smuzhiyun 	status = api->halmac_download_firmware(mac, fw, fwsize);
3396*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
3397*4882a593Smuzhiyun 		RTW_ERR("%s: download firmware FAIL! status=0x%02x\n",
3398*4882a593Smuzhiyun 			__FUNCTION__, status);
3399*4882a593Smuzhiyun 		_debug_dlfw_fail(d);
3400*4882a593Smuzhiyun 		err = -1;
3401*4882a593Smuzhiyun 		goto resume_tx;
3402*4882a593Smuzhiyun 	}
3403*4882a593Smuzhiyun 
3404*4882a593Smuzhiyun 	/* 5.1. (Driver) Reset driver variables if needed */
3405*4882a593Smuzhiyun 	hal->LastHMEBoxNum = 0;
3406*4882a593Smuzhiyun 
3407*4882a593Smuzhiyun 	/* 5.2. (Driver) Get FW version */
3408*4882a593Smuzhiyun 	status = api->halmac_get_fw_version(mac, &fw_vesion);
3409*4882a593Smuzhiyun 	if (status == HALMAC_RET_SUCCESS) {
3410*4882a593Smuzhiyun 		hal->firmware_version = fw_vesion.version;
3411*4882a593Smuzhiyun 		hal->firmware_sub_version = fw_vesion.sub_version;
3412*4882a593Smuzhiyun 		hal->firmware_size = fwsize;
3413*4882a593Smuzhiyun 	}
3414*4882a593Smuzhiyun 
3415*4882a593Smuzhiyun resume_tx:
3416*4882a593Smuzhiyun 	/* 6. Driver resume TX if needed */
3417*4882a593Smuzhiyun 	/* ToDo */
3418*4882a593Smuzhiyun 
3419*4882a593Smuzhiyun 	if (err)
3420*4882a593Smuzhiyun 		goto exit;
3421*4882a593Smuzhiyun 
3422*4882a593Smuzhiyun 	if (re_dl) {
3423*4882a593Smuzhiyun 		enum halmac_trx_mode mode;
3424*4882a593Smuzhiyun 
3425*4882a593Smuzhiyun 		/* 7. Change reserved page size */
3426*4882a593Smuzhiyun 		err = _cfg_drv_rsvd_pg_num(d);
3427*4882a593Smuzhiyun 		if (err)
3428*4882a593Smuzhiyun 			return -1;
3429*4882a593Smuzhiyun 
3430*4882a593Smuzhiyun 		/* 8. Init TRX Configuration */
3431*4882a593Smuzhiyun 		mode = _choose_trx_mode(d);
3432*4882a593Smuzhiyun 		status = api->halmac_init_trx_cfg(mac, mode);
3433*4882a593Smuzhiyun 		if (HALMAC_RET_SUCCESS != status)
3434*4882a593Smuzhiyun 			return -1;
3435*4882a593Smuzhiyun 		_init_trx_cfg_drv(d);
3436*4882a593Smuzhiyun 
3437*4882a593Smuzhiyun 		/* 9. Config RX Aggregation */
3438*4882a593Smuzhiyun 		err = rtw_halmac_rx_agg_switch(d, _TRUE);
3439*4882a593Smuzhiyun 		if (err)
3440*4882a593Smuzhiyun 			return -1;
3441*4882a593Smuzhiyun 
3442*4882a593Smuzhiyun 		/* 10. Send General Info */
3443*4882a593Smuzhiyun 		err = _send_general_info(d);
3444*4882a593Smuzhiyun 		if (err)
3445*4882a593Smuzhiyun 			return -1;
3446*4882a593Smuzhiyun 	}
3447*4882a593Smuzhiyun 
3448*4882a593Smuzhiyun exit:
3449*4882a593Smuzhiyun 	return err;
3450*4882a593Smuzhiyun }
3451*4882a593Smuzhiyun 
init_mac_flow(struct dvobj_priv * d)3452*4882a593Smuzhiyun static int init_mac_flow(struct dvobj_priv *d)
3453*4882a593Smuzhiyun {
3454*4882a593Smuzhiyun 	PADAPTER p;
3455*4882a593Smuzhiyun 	struct hal_com_data *hal;
3456*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
3457*4882a593Smuzhiyun 	struct halmac_api *api;
3458*4882a593Smuzhiyun 	enum halmac_drv_rsvd_pg_num rsvd_page_number;
3459*4882a593Smuzhiyun 	union halmac_wlan_addr hwa;
3460*4882a593Smuzhiyun 	enum halmac_trx_mode trx_mode;
3461*4882a593Smuzhiyun 	enum halmac_ret_status status;
3462*4882a593Smuzhiyun 	u8 drv_rsvd_num;
3463*4882a593Smuzhiyun 	u8 nettype;
3464*4882a593Smuzhiyun 	int err, err_ret = -1;
3465*4882a593Smuzhiyun 
3466*4882a593Smuzhiyun 
3467*4882a593Smuzhiyun 	p = dvobj_get_primary_adapter(d);
3468*4882a593Smuzhiyun 	hal = GET_HAL_DATA(p);
3469*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
3470*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
3471*4882a593Smuzhiyun 
3472*4882a593Smuzhiyun #ifdef CONFIG_SUPPORT_TRX_SHARED
3473*4882a593Smuzhiyun 	status = api->halmac_cfg_rxff_expand_mode(halmac,
3474*4882a593Smuzhiyun 						  _rtw_get_trx_share_mode(p));
3475*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3476*4882a593Smuzhiyun 		goto out;
3477*4882a593Smuzhiyun #endif
3478*4882a593Smuzhiyun 
3479*4882a593Smuzhiyun #ifdef DBG_LA_MODE
3480*4882a593Smuzhiyun 	if (dvobj_to_regsty(d)->la_mode_en) {
3481*4882a593Smuzhiyun 		status = api->halmac_cfg_la_mode(halmac, HALMAC_LA_MODE_PARTIAL);
3482*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
3483*4882a593Smuzhiyun 			RTW_ERR("%s: Fail to enable LA mode!\n", __FUNCTION__);
3484*4882a593Smuzhiyun 			goto out;
3485*4882a593Smuzhiyun 		}
3486*4882a593Smuzhiyun 		RTW_PRINT("%s: Enable LA mode OK.\n", __FUNCTION__);
3487*4882a593Smuzhiyun 	}
3488*4882a593Smuzhiyun #endif
3489*4882a593Smuzhiyun 
3490*4882a593Smuzhiyun 	err = _cfg_drv_rsvd_pg_num(d);
3491*4882a593Smuzhiyun 	if (err)
3492*4882a593Smuzhiyun 		goto out;
3493*4882a593Smuzhiyun 
3494*4882a593Smuzhiyun #ifdef CONFIG_USB_HCI
3495*4882a593Smuzhiyun 	status = api->halmac_set_bulkout_num(halmac, d->RtNumOutPipes);
3496*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3497*4882a593Smuzhiyun 		goto out;
3498*4882a593Smuzhiyun #endif /* CONFIG_USB_HCI */
3499*4882a593Smuzhiyun 
3500*4882a593Smuzhiyun 	trx_mode = _choose_trx_mode(d);
3501*4882a593Smuzhiyun 	status = api->halmac_init_mac_cfg(halmac, trx_mode);
3502*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3503*4882a593Smuzhiyun 		goto out;
3504*4882a593Smuzhiyun 
3505*4882a593Smuzhiyun 	/* Driver insert flow: Sync driver setting with register */
3506*4882a593Smuzhiyun 	/* Sync driver RCR cache with register setting */
3507*4882a593Smuzhiyun 	rtw_hal_get_hwreg(dvobj_get_primary_adapter(d), HW_VAR_RCR, NULL);
3508*4882a593Smuzhiyun 
3509*4882a593Smuzhiyun #ifdef CONFIG_RTS_FULL_BW
3510*4882a593Smuzhiyun 	err = rtw_halmac_set_rts_full_bw(d, _TRUE);
3511*4882a593Smuzhiyun 	if (err)
3512*4882a593Smuzhiyun 		RTW_WARN("%s: Fail to set RTS FULL BW mode\n", __FUNCTION__);
3513*4882a593Smuzhiyun #else
3514*4882a593Smuzhiyun 	err = rtw_halmac_set_rts_full_bw(d, _FALSE);
3515*4882a593Smuzhiyun 	if (err)
3516*4882a593Smuzhiyun 		RTW_WARN("%s: Fail to disable RTS FULL BW mode\n", __FUNCTION__);
3517*4882a593Smuzhiyun #endif /* CONFIG_RTS_FULL_BW */
3518*4882a593Smuzhiyun 
3519*4882a593Smuzhiyun 	_init_trx_cfg_drv(d);
3520*4882a593Smuzhiyun 	/* Driver inser flow end */
3521*4882a593Smuzhiyun 
3522*4882a593Smuzhiyun 	err = rtw_halmac_rx_agg_switch(d, _TRUE);
3523*4882a593Smuzhiyun 	if (err)
3524*4882a593Smuzhiyun 		goto out;
3525*4882a593Smuzhiyun 
3526*4882a593Smuzhiyun 	nettype = dvobj_to_regsty(d)->wireless_mode;
3527*4882a593Smuzhiyun 	if (is_supported_vht(nettype) == _TRUE)
3528*4882a593Smuzhiyun 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_AC);
3529*4882a593Smuzhiyun 	else if (is_supported_ht(nettype) == _TRUE)
3530*4882a593Smuzhiyun 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_N);
3531*4882a593Smuzhiyun 	else if (IsSupportedTxOFDM(nettype) == _TRUE)
3532*4882a593Smuzhiyun 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_G);
3533*4882a593Smuzhiyun 	else
3534*4882a593Smuzhiyun 		status = api->halmac_cfg_operation_mode(halmac, HALMAC_WIRELESS_MODE_B);
3535*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3536*4882a593Smuzhiyun 		goto out;
3537*4882a593Smuzhiyun 
3538*4882a593Smuzhiyun 	err_ret = 0;
3539*4882a593Smuzhiyun out:
3540*4882a593Smuzhiyun 	return err_ret;
3541*4882a593Smuzhiyun }
3542*4882a593Smuzhiyun 
_drv_enable_trx(struct dvobj_priv * d)3543*4882a593Smuzhiyun static int _drv_enable_trx(struct dvobj_priv *d)
3544*4882a593Smuzhiyun {
3545*4882a593Smuzhiyun 	struct _ADAPTER *adapter;
3546*4882a593Smuzhiyun 	u32 status;
3547*4882a593Smuzhiyun 
3548*4882a593Smuzhiyun 
3549*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
3550*4882a593Smuzhiyun 	if (adapter->bup == _FALSE) {
3551*4882a593Smuzhiyun #ifdef CONFIG_NEW_NETDEV_HDL
3552*4882a593Smuzhiyun 		status = rtw_mi_start_drv_threads(adapter);
3553*4882a593Smuzhiyun #else
3554*4882a593Smuzhiyun 		status = rtw_start_drv_threads(adapter);
3555*4882a593Smuzhiyun #endif
3556*4882a593Smuzhiyun 		if (status == _FAIL) {
3557*4882a593Smuzhiyun 			RTW_ERR("%s: Start threads Failed!\n", __FUNCTION__);
3558*4882a593Smuzhiyun 			return -1;
3559*4882a593Smuzhiyun 		}
3560*4882a593Smuzhiyun 	}
3561*4882a593Smuzhiyun 
3562*4882a593Smuzhiyun 	rtw_intf_start(adapter);
3563*4882a593Smuzhiyun 
3564*4882a593Smuzhiyun 	return 0;
3565*4882a593Smuzhiyun }
3566*4882a593Smuzhiyun 
3567*4882a593Smuzhiyun /*
3568*4882a593Smuzhiyun  * Notices:
3569*4882a593Smuzhiyun  *	Make sure following information
3570*4882a593Smuzhiyun  *	1. GET_HAL_RFPATH
3571*4882a593Smuzhiyun  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3572*4882a593Smuzhiyun  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3573*4882a593Smuzhiyun  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3574*4882a593Smuzhiyun  *	are all ready before calling this function.
3575*4882a593Smuzhiyun  */
_halmac_init_hal(struct dvobj_priv * d,u8 * fw,u32 fwsize)3576*4882a593Smuzhiyun static int _halmac_init_hal(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3577*4882a593Smuzhiyun {
3578*4882a593Smuzhiyun 	PADAPTER adapter;
3579*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
3580*4882a593Smuzhiyun 	struct halmac_api *api;
3581*4882a593Smuzhiyun 	enum halmac_ret_status status;
3582*4882a593Smuzhiyun 	u32 ok;
3583*4882a593Smuzhiyun 	u8 fw_ok = _FALSE;
3584*4882a593Smuzhiyun 	int err, err_ret = -1;
3585*4882a593Smuzhiyun 
3586*4882a593Smuzhiyun 
3587*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
3588*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
3589*4882a593Smuzhiyun 	if (!halmac)
3590*4882a593Smuzhiyun 		goto out;
3591*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
3592*4882a593Smuzhiyun 
3593*4882a593Smuzhiyun 	/* StatePowerOff */
3594*4882a593Smuzhiyun 
3595*4882a593Smuzhiyun 	/* SKIP: halmac_init_adapter (Already done before) */
3596*4882a593Smuzhiyun 
3597*4882a593Smuzhiyun 	/* halmac_pre_Init_system_cfg */
3598*4882a593Smuzhiyun 	/* halmac_mac_power_switch(on) */
3599*4882a593Smuzhiyun 	/* halmac_Init_system_cfg */
3600*4882a593Smuzhiyun 	ok = rtw_hal_power_on(adapter);
3601*4882a593Smuzhiyun 	if (_FAIL == ok)
3602*4882a593Smuzhiyun 		goto out;
3603*4882a593Smuzhiyun 
3604*4882a593Smuzhiyun 	/* StatePowerOn */
3605*4882a593Smuzhiyun 
3606*4882a593Smuzhiyun 	/* DownloadFW */
3607*4882a593Smuzhiyun 	if (fw && fwsize) {
3608*4882a593Smuzhiyun 		err = download_fw(d, fw, fwsize, 0);
3609*4882a593Smuzhiyun 		if (err)
3610*4882a593Smuzhiyun 			goto out;
3611*4882a593Smuzhiyun 		fw_ok = _TRUE;
3612*4882a593Smuzhiyun 	}
3613*4882a593Smuzhiyun 
3614*4882a593Smuzhiyun 	/* InitMACFlow */
3615*4882a593Smuzhiyun 	err = init_mac_flow(d);
3616*4882a593Smuzhiyun 	if (err)
3617*4882a593Smuzhiyun 		goto out;
3618*4882a593Smuzhiyun 
3619*4882a593Smuzhiyun 	/* Driver insert flow: Enable TR/RX */
3620*4882a593Smuzhiyun 	err = _drv_enable_trx(d);
3621*4882a593Smuzhiyun 	if (err)
3622*4882a593Smuzhiyun 		goto out;
3623*4882a593Smuzhiyun 
3624*4882a593Smuzhiyun 	/* halmac_send_general_info */
3625*4882a593Smuzhiyun 	if (_TRUE == fw_ok) {
3626*4882a593Smuzhiyun 		err = _send_general_info(d);
3627*4882a593Smuzhiyun 		if (err)
3628*4882a593Smuzhiyun 			goto out;
3629*4882a593Smuzhiyun 	}
3630*4882a593Smuzhiyun 
3631*4882a593Smuzhiyun 	/* Init Phy parameter-MAC */
3632*4882a593Smuzhiyun 	ok = rtw_hal_init_mac_register(adapter);
3633*4882a593Smuzhiyun 	if (_FALSE == ok)
3634*4882a593Smuzhiyun 		goto out;
3635*4882a593Smuzhiyun 
3636*4882a593Smuzhiyun 	/* StateMacInitialized */
3637*4882a593Smuzhiyun 
3638*4882a593Smuzhiyun 	/* halmac_cfg_drv_info */
3639*4882a593Smuzhiyun 	err = rtw_halmac_config_rx_info(d, HALMAC_DRV_INFO_PHY_STATUS);
3640*4882a593Smuzhiyun 	if (err)
3641*4882a593Smuzhiyun 		goto out;
3642*4882a593Smuzhiyun 
3643*4882a593Smuzhiyun 	/* halmac_set_hw_value(HALMAC_HW_EN_BB_RF) */
3644*4882a593Smuzhiyun 	/* Init BB, RF */
3645*4882a593Smuzhiyun 	ok = rtw_hal_init_phy(adapter);
3646*4882a593Smuzhiyun 	if (_FALSE == ok)
3647*4882a593Smuzhiyun 		goto out;
3648*4882a593Smuzhiyun 
3649*4882a593Smuzhiyun 	status = api->halmac_init_interface_cfg(halmac);
3650*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3651*4882a593Smuzhiyun 		goto out;
3652*4882a593Smuzhiyun 
3653*4882a593Smuzhiyun 	/* SKIP: halmac_verify_platform_api */
3654*4882a593Smuzhiyun 	/* SKIP: halmac_h2c_lb */
3655*4882a593Smuzhiyun 
3656*4882a593Smuzhiyun 	/* StateRxIdle */
3657*4882a593Smuzhiyun 
3658*4882a593Smuzhiyun 	err_ret = 0;
3659*4882a593Smuzhiyun out:
3660*4882a593Smuzhiyun 	return err_ret;
3661*4882a593Smuzhiyun }
3662*4882a593Smuzhiyun 
rtw_halmac_init_hal(struct dvobj_priv * d)3663*4882a593Smuzhiyun int rtw_halmac_init_hal(struct dvobj_priv *d)
3664*4882a593Smuzhiyun {
3665*4882a593Smuzhiyun 	return _halmac_init_hal(d, NULL, 0);
3666*4882a593Smuzhiyun }
3667*4882a593Smuzhiyun 
3668*4882a593Smuzhiyun /*
3669*4882a593Smuzhiyun  * Notices:
3670*4882a593Smuzhiyun  *	Make sure following information
3671*4882a593Smuzhiyun  *	1. GET_HAL_RFPATH
3672*4882a593Smuzhiyun  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3673*4882a593Smuzhiyun  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3674*4882a593Smuzhiyun  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3675*4882a593Smuzhiyun  *	are all ready before calling this function.
3676*4882a593Smuzhiyun  */
rtw_halmac_init_hal_fw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3677*4882a593Smuzhiyun int rtw_halmac_init_hal_fw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3678*4882a593Smuzhiyun {
3679*4882a593Smuzhiyun 	return _halmac_init_hal(d, fw, fwsize);
3680*4882a593Smuzhiyun }
3681*4882a593Smuzhiyun 
3682*4882a593Smuzhiyun /*
3683*4882a593Smuzhiyun  * Notices:
3684*4882a593Smuzhiyun  *	Make sure following information
3685*4882a593Smuzhiyun  *	1. GET_HAL_RFPATH
3686*4882a593Smuzhiyun  *	2. GET_HAL_DATA(dvobj_get_primary_adapter(d))->rfe_type
3687*4882a593Smuzhiyun  *	3. GET_HAL_DATA(dvobj_get_primary_adapter(d))->PackageType
3688*4882a593Smuzhiyun  *	4. dvobj_get_primary_adapter(d)->registrypriv.mp_mode
3689*4882a593Smuzhiyun  *	are all ready before calling this function.
3690*4882a593Smuzhiyun  */
rtw_halmac_init_hal_fw_file(struct dvobj_priv * d,u8 * fwpath)3691*4882a593Smuzhiyun int rtw_halmac_init_hal_fw_file(struct dvobj_priv *d, u8 *fwpath)
3692*4882a593Smuzhiyun {
3693*4882a593Smuzhiyun 	u8 *fw = NULL;
3694*4882a593Smuzhiyun 	u32 fwmaxsize = 0, size = 0;
3695*4882a593Smuzhiyun 	int err = 0;
3696*4882a593Smuzhiyun 
3697*4882a593Smuzhiyun 
3698*4882a593Smuzhiyun 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3699*4882a593Smuzhiyun 	if (err) {
3700*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3701*4882a593Smuzhiyun 		return -1;
3702*4882a593Smuzhiyun 	}
3703*4882a593Smuzhiyun 
3704*4882a593Smuzhiyun 	fw = rtw_zmalloc(fwmaxsize);
3705*4882a593Smuzhiyun 	if (!fw)
3706*4882a593Smuzhiyun 		return -1;
3707*4882a593Smuzhiyun 
3708*4882a593Smuzhiyun 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3709*4882a593Smuzhiyun 	if (!size) {
3710*4882a593Smuzhiyun 		err = -1;
3711*4882a593Smuzhiyun 		goto exit;
3712*4882a593Smuzhiyun 	}
3713*4882a593Smuzhiyun 
3714*4882a593Smuzhiyun 	err = _halmac_init_hal(d, fw, size);
3715*4882a593Smuzhiyun 
3716*4882a593Smuzhiyun exit:
3717*4882a593Smuzhiyun 	rtw_mfree(fw, fwmaxsize);
3718*4882a593Smuzhiyun 	/*fw = NULL;*/
3719*4882a593Smuzhiyun 
3720*4882a593Smuzhiyun 	return err;
3721*4882a593Smuzhiyun }
3722*4882a593Smuzhiyun 
rtw_halmac_deinit_hal(struct dvobj_priv * d)3723*4882a593Smuzhiyun int rtw_halmac_deinit_hal(struct dvobj_priv *d)
3724*4882a593Smuzhiyun {
3725*4882a593Smuzhiyun 	PADAPTER adapter;
3726*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
3727*4882a593Smuzhiyun 	struct halmac_api *api;
3728*4882a593Smuzhiyun 	enum halmac_ret_status status;
3729*4882a593Smuzhiyun 	int err = -1;
3730*4882a593Smuzhiyun 
3731*4882a593Smuzhiyun 
3732*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
3733*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
3734*4882a593Smuzhiyun 	if (!halmac)
3735*4882a593Smuzhiyun 		goto out;
3736*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
3737*4882a593Smuzhiyun 
3738*4882a593Smuzhiyun 	status = api->halmac_deinit_interface_cfg(halmac);
3739*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3740*4882a593Smuzhiyun 		goto out;
3741*4882a593Smuzhiyun 
3742*4882a593Smuzhiyun 	rtw_hal_power_off(adapter);
3743*4882a593Smuzhiyun 
3744*4882a593Smuzhiyun 	err = 0;
3745*4882a593Smuzhiyun out:
3746*4882a593Smuzhiyun 	return err;
3747*4882a593Smuzhiyun }
3748*4882a593Smuzhiyun 
rtw_halmac_self_verify(struct dvobj_priv * d)3749*4882a593Smuzhiyun int rtw_halmac_self_verify(struct dvobj_priv *d)
3750*4882a593Smuzhiyun {
3751*4882a593Smuzhiyun 	struct halmac_adapter *mac;
3752*4882a593Smuzhiyun 	struct halmac_api *api;
3753*4882a593Smuzhiyun 	enum halmac_ret_status status;
3754*4882a593Smuzhiyun 	int err = -1;
3755*4882a593Smuzhiyun 
3756*4882a593Smuzhiyun 
3757*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
3758*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
3759*4882a593Smuzhiyun 
3760*4882a593Smuzhiyun 	status = api->halmac_verify_platform_api(mac);
3761*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3762*4882a593Smuzhiyun 		goto out;
3763*4882a593Smuzhiyun 
3764*4882a593Smuzhiyun 	status = api->halmac_h2c_lb(mac);
3765*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
3766*4882a593Smuzhiyun 		goto out;
3767*4882a593Smuzhiyun 
3768*4882a593Smuzhiyun 	err = 0;
3769*4882a593Smuzhiyun out:
3770*4882a593Smuzhiyun 	return err;
3771*4882a593Smuzhiyun }
3772*4882a593Smuzhiyun 
rtw_halmac_txfifo_is_empty(struct dvobj_priv * d)3773*4882a593Smuzhiyun static u8 rtw_halmac_txfifo_is_empty(struct dvobj_priv *d)
3774*4882a593Smuzhiyun {
3775*4882a593Smuzhiyun 	struct halmac_adapter *mac;
3776*4882a593Smuzhiyun 	struct halmac_api *api;
3777*4882a593Smuzhiyun 	enum halmac_ret_status status;
3778*4882a593Smuzhiyun 	u32 chk_num = 10;
3779*4882a593Smuzhiyun 	u8 rst = _FALSE;
3780*4882a593Smuzhiyun 
3781*4882a593Smuzhiyun 
3782*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
3783*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
3784*4882a593Smuzhiyun 
3785*4882a593Smuzhiyun 	status = api->halmac_txfifo_is_empty(mac, chk_num);
3786*4882a593Smuzhiyun 	if (status == HALMAC_RET_SUCCESS)
3787*4882a593Smuzhiyun 		rst = _TRUE;
3788*4882a593Smuzhiyun 
3789*4882a593Smuzhiyun 	return rst;
3790*4882a593Smuzhiyun }
3791*4882a593Smuzhiyun 
3792*4882a593Smuzhiyun /**
3793*4882a593Smuzhiyun  * rtw_halmac_txfifo_wait_empty() - Wait TX FIFO to be emtpy
3794*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
3795*4882a593Smuzhiyun  * @timeout:	time limit of wait, unit is ms
3796*4882a593Smuzhiyun  *		0 for no limit
3797*4882a593Smuzhiyun  *
3798*4882a593Smuzhiyun  * Wait TX FIFO to be emtpy.
3799*4882a593Smuzhiyun  *
3800*4882a593Smuzhiyun  * Return 0 for TX FIFO is empty, otherwise not empty.
3801*4882a593Smuzhiyun  */
rtw_halmac_txfifo_wait_empty(struct dvobj_priv * d,u32 timeout)3802*4882a593Smuzhiyun int rtw_halmac_txfifo_wait_empty(struct dvobj_priv *d, u32 timeout)
3803*4882a593Smuzhiyun {
3804*4882a593Smuzhiyun 	struct _ADAPTER *a;
3805*4882a593Smuzhiyun 	u8 empty = _FALSE;
3806*4882a593Smuzhiyun 	u32 cnt = 0;
3807*4882a593Smuzhiyun 	systime start_time = 0;
3808*4882a593Smuzhiyun 	u32 pass_time; /* ms */
3809*4882a593Smuzhiyun 
3810*4882a593Smuzhiyun 
3811*4882a593Smuzhiyun 	a = dvobj_get_primary_adapter(d);
3812*4882a593Smuzhiyun 	start_time = rtw_get_current_time();
3813*4882a593Smuzhiyun 
3814*4882a593Smuzhiyun 	do {
3815*4882a593Smuzhiyun 		cnt++;
3816*4882a593Smuzhiyun 		empty = rtw_halmac_txfifo_is_empty(d);
3817*4882a593Smuzhiyun 		if (empty == _TRUE)
3818*4882a593Smuzhiyun 			break;
3819*4882a593Smuzhiyun 
3820*4882a593Smuzhiyun 		if (timeout) {
3821*4882a593Smuzhiyun 			pass_time = rtw_get_passing_time_ms(start_time);
3822*4882a593Smuzhiyun 			if (pass_time > timeout)
3823*4882a593Smuzhiyun 				break;
3824*4882a593Smuzhiyun 		}
3825*4882a593Smuzhiyun 		if (RTW_CANNOT_IO(a)) {
3826*4882a593Smuzhiyun 			RTW_WARN("%s: Interrupted by I/O forbiden!\n", __FUNCTION__);
3827*4882a593Smuzhiyun 			break;
3828*4882a593Smuzhiyun 		}
3829*4882a593Smuzhiyun 
3830*4882a593Smuzhiyun 		rtw_msleep_os(2);
3831*4882a593Smuzhiyun 	} while (1);
3832*4882a593Smuzhiyun 
3833*4882a593Smuzhiyun 	if (empty == _FALSE) {
3834*4882a593Smuzhiyun #ifdef CONFIG_RTW_DEBUG
3835*4882a593Smuzhiyun 		u16 dbg_reg[] = {0x210, 0x230, 0x234, 0x238, 0x23C, 0x240,
3836*4882a593Smuzhiyun 				 0x418, 0x10FC, 0x10F8, 0x11F4, 0x11F8};
3837*4882a593Smuzhiyun 		u8 i;
3838*4882a593Smuzhiyun 		u32 val;
3839*4882a593Smuzhiyun 
3840*4882a593Smuzhiyun 		if (!RTW_CANNOT_IO(a)) {
3841*4882a593Smuzhiyun 			for (i = 0; i < ARRAY_SIZE(dbg_reg); i++) {
3842*4882a593Smuzhiyun 				val = rtw_read32(a, dbg_reg[i]);
3843*4882a593Smuzhiyun 				RTW_ERR("REG_%X:0x%08x\n", dbg_reg[i], val);
3844*4882a593Smuzhiyun 			}
3845*4882a593Smuzhiyun 		}
3846*4882a593Smuzhiyun #endif /* CONFIG_RTW_DEBUG */
3847*4882a593Smuzhiyun 
3848*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to wait txfifo empty!(cnt=%d)\n",
3849*4882a593Smuzhiyun 			__FUNCTION__, cnt);
3850*4882a593Smuzhiyun 		return -1;
3851*4882a593Smuzhiyun 	}
3852*4882a593Smuzhiyun 
3853*4882a593Smuzhiyun 	return 0;
3854*4882a593Smuzhiyun }
3855*4882a593Smuzhiyun 
_fw_mem_drv2halmac(enum fw_mem mem,u8 tx_stop)3856*4882a593Smuzhiyun static enum halmac_dlfw_mem _fw_mem_drv2halmac(enum fw_mem mem, u8 tx_stop)
3857*4882a593Smuzhiyun {
3858*4882a593Smuzhiyun 	enum halmac_dlfw_mem mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3859*4882a593Smuzhiyun 
3860*4882a593Smuzhiyun 
3861*4882a593Smuzhiyun 	switch (mem) {
3862*4882a593Smuzhiyun 	case FW_EMEM:
3863*4882a593Smuzhiyun 		if (tx_stop == _FALSE)
3864*4882a593Smuzhiyun 			mem_halmac = HALMAC_DLFW_MEM_EMEM_RSVD_PG;
3865*4882a593Smuzhiyun 		else
3866*4882a593Smuzhiyun 			mem_halmac = HALMAC_DLFW_MEM_EMEM;
3867*4882a593Smuzhiyun 		break;
3868*4882a593Smuzhiyun 
3869*4882a593Smuzhiyun 	case FW_IMEM:
3870*4882a593Smuzhiyun 	case FW_DMEM:
3871*4882a593Smuzhiyun 		mem_halmac = HALMAC_DLFW_MEM_UNDEFINE;
3872*4882a593Smuzhiyun 		break;
3873*4882a593Smuzhiyun 	}
3874*4882a593Smuzhiyun 
3875*4882a593Smuzhiyun 	return mem_halmac;
3876*4882a593Smuzhiyun }
3877*4882a593Smuzhiyun 
rtw_halmac_dlfw_mem(struct dvobj_priv * d,u8 * fw,u32 fwsize,enum fw_mem mem)3878*4882a593Smuzhiyun int rtw_halmac_dlfw_mem(struct dvobj_priv *d, u8 *fw, u32 fwsize, enum fw_mem mem)
3879*4882a593Smuzhiyun {
3880*4882a593Smuzhiyun 	struct halmac_adapter *mac;
3881*4882a593Smuzhiyun 	struct halmac_api *api;
3882*4882a593Smuzhiyun 	enum halmac_ret_status status;
3883*4882a593Smuzhiyun 	enum halmac_dlfw_mem dlfw_mem;
3884*4882a593Smuzhiyun 	u8 tx_stop = _FALSE;
3885*4882a593Smuzhiyun 	u32 chk_timeout = 2000; /* unit: ms */
3886*4882a593Smuzhiyun 	int err = 0;
3887*4882a593Smuzhiyun 
3888*4882a593Smuzhiyun 
3889*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
3890*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
3891*4882a593Smuzhiyun 
3892*4882a593Smuzhiyun 	if ((!fw) || (!fwsize))
3893*4882a593Smuzhiyun 		return -1;
3894*4882a593Smuzhiyun 
3895*4882a593Smuzhiyun #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3896*4882a593Smuzhiyun 	/* 1. Driver Stop Tx */
3897*4882a593Smuzhiyun 	/* ToDo */
3898*4882a593Smuzhiyun 
3899*4882a593Smuzhiyun 	/* 2. Driver Check Tx FIFO is empty */
3900*4882a593Smuzhiyun 	err = rtw_halmac_txfifo_wait_empty(d, chk_timeout);
3901*4882a593Smuzhiyun 	if (err)
3902*4882a593Smuzhiyun 		tx_stop = _FALSE;
3903*4882a593Smuzhiyun 	else
3904*4882a593Smuzhiyun 		tx_stop = _TRUE;
3905*4882a593Smuzhiyun #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3906*4882a593Smuzhiyun 
3907*4882a593Smuzhiyun 	/* 3. Download Firmware MEM */
3908*4882a593Smuzhiyun 	dlfw_mem = _fw_mem_drv2halmac(mem, tx_stop);
3909*4882a593Smuzhiyun 	if (dlfw_mem == HALMAC_DLFW_MEM_UNDEFINE) {
3910*4882a593Smuzhiyun 		err = -1;
3911*4882a593Smuzhiyun 		goto resume_tx;
3912*4882a593Smuzhiyun 	}
3913*4882a593Smuzhiyun 	status = api->halmac_free_download_firmware(mac, dlfw_mem, fw, fwsize);
3914*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
3915*4882a593Smuzhiyun 		RTW_ERR("%s: halmac_free_download_firmware fail(err=0x%x)\n",
3916*4882a593Smuzhiyun 			__FUNCTION__, status);
3917*4882a593Smuzhiyun 		err = -1;
3918*4882a593Smuzhiyun 		goto resume_tx;
3919*4882a593Smuzhiyun 	}
3920*4882a593Smuzhiyun 
3921*4882a593Smuzhiyun resume_tx:
3922*4882a593Smuzhiyun #ifndef RTW_HALMAC_DLFW_MEM_NO_STOP_TX
3923*4882a593Smuzhiyun 	/* 4. Driver resume TX if needed */
3924*4882a593Smuzhiyun 	/* ToDo */
3925*4882a593Smuzhiyun #endif /* !RTW_HALMAC_DLFW_MEM_NO_STOP_TX */
3926*4882a593Smuzhiyun 
3927*4882a593Smuzhiyun 	return err;
3928*4882a593Smuzhiyun }
3929*4882a593Smuzhiyun 
rtw_halmac_dlfw_mem_from_file(struct dvobj_priv * d,u8 * fwpath,enum fw_mem mem)3930*4882a593Smuzhiyun int rtw_halmac_dlfw_mem_from_file(struct dvobj_priv *d, u8 *fwpath, enum fw_mem mem)
3931*4882a593Smuzhiyun {
3932*4882a593Smuzhiyun 	u8 *fw = NULL;
3933*4882a593Smuzhiyun 	u32 fwmaxsize = 0, size = 0;
3934*4882a593Smuzhiyun 	int err = 0;
3935*4882a593Smuzhiyun 
3936*4882a593Smuzhiyun 
3937*4882a593Smuzhiyun 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
3938*4882a593Smuzhiyun 	if (err) {
3939*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
3940*4882a593Smuzhiyun 		return -1;
3941*4882a593Smuzhiyun 	}
3942*4882a593Smuzhiyun 
3943*4882a593Smuzhiyun 	fw = rtw_zmalloc(fwmaxsize);
3944*4882a593Smuzhiyun 	if (!fw)
3945*4882a593Smuzhiyun 		return -1;
3946*4882a593Smuzhiyun 
3947*4882a593Smuzhiyun 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
3948*4882a593Smuzhiyun 	if (size)
3949*4882a593Smuzhiyun 		err = rtw_halmac_dlfw_mem(d, fw, size, mem);
3950*4882a593Smuzhiyun 	else
3951*4882a593Smuzhiyun 		err = -1;
3952*4882a593Smuzhiyun 
3953*4882a593Smuzhiyun 	rtw_mfree(fw, fwmaxsize);
3954*4882a593Smuzhiyun 	/*fw = NULL;*/
3955*4882a593Smuzhiyun 
3956*4882a593Smuzhiyun 	return err;
3957*4882a593Smuzhiyun }
3958*4882a593Smuzhiyun 
3959*4882a593Smuzhiyun /*
3960*4882a593Smuzhiyun  * Return:
3961*4882a593Smuzhiyun  *	0	Success
3962*4882a593Smuzhiyun  *	-22	Invalid arguemnt
3963*4882a593Smuzhiyun  */
rtw_halmac_dlfw(struct dvobj_priv * d,u8 * fw,u32 fwsize)3964*4882a593Smuzhiyun int rtw_halmac_dlfw(struct dvobj_priv *d, u8 *fw, u32 fwsize)
3965*4882a593Smuzhiyun {
3966*4882a593Smuzhiyun 	PADAPTER adapter;
3967*4882a593Smuzhiyun 	enum halmac_ret_status status;
3968*4882a593Smuzhiyun 	u32 ok;
3969*4882a593Smuzhiyun 	int err, err_ret = -1;
3970*4882a593Smuzhiyun 
3971*4882a593Smuzhiyun 
3972*4882a593Smuzhiyun 	if (!fw || !fwsize)
3973*4882a593Smuzhiyun 		return -22;
3974*4882a593Smuzhiyun 
3975*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
3976*4882a593Smuzhiyun 
3977*4882a593Smuzhiyun 	/* re-download firmware */
3978*4882a593Smuzhiyun 	if (rtw_is_hw_init_completed(adapter))
3979*4882a593Smuzhiyun 		return download_fw(d, fw, fwsize, 1);
3980*4882a593Smuzhiyun 
3981*4882a593Smuzhiyun 	/* Download firmware before hal init */
3982*4882a593Smuzhiyun 	/* Power on, download firmware and init mac */
3983*4882a593Smuzhiyun 	ok = rtw_hal_power_on(adapter);
3984*4882a593Smuzhiyun 	if (_FAIL == ok)
3985*4882a593Smuzhiyun 		goto out;
3986*4882a593Smuzhiyun 
3987*4882a593Smuzhiyun 	err = download_fw(d, fw, fwsize, 0);
3988*4882a593Smuzhiyun 	if (err) {
3989*4882a593Smuzhiyun 		err_ret = err;
3990*4882a593Smuzhiyun 		goto out;
3991*4882a593Smuzhiyun 	}
3992*4882a593Smuzhiyun 
3993*4882a593Smuzhiyun 	err = init_mac_flow(d);
3994*4882a593Smuzhiyun 	if (err)
3995*4882a593Smuzhiyun 		goto out;
3996*4882a593Smuzhiyun 
3997*4882a593Smuzhiyun 	err = _send_general_info(d);
3998*4882a593Smuzhiyun 	if (err)
3999*4882a593Smuzhiyun 		goto out;
4000*4882a593Smuzhiyun 
4001*4882a593Smuzhiyun 	err_ret = 0;
4002*4882a593Smuzhiyun 
4003*4882a593Smuzhiyun out:
4004*4882a593Smuzhiyun 	return err_ret;
4005*4882a593Smuzhiyun }
4006*4882a593Smuzhiyun 
rtw_halmac_dlfw_from_file(struct dvobj_priv * d,u8 * fwpath)4007*4882a593Smuzhiyun int rtw_halmac_dlfw_from_file(struct dvobj_priv *d, u8 *fwpath)
4008*4882a593Smuzhiyun {
4009*4882a593Smuzhiyun 	u8 *fw = NULL;
4010*4882a593Smuzhiyun 	u32 fwmaxsize = 0, size = 0;
4011*4882a593Smuzhiyun 	int err = 0;
4012*4882a593Smuzhiyun 
4013*4882a593Smuzhiyun 
4014*4882a593Smuzhiyun 	err = rtw_halmac_get_fw_max_size(d, &fwmaxsize);
4015*4882a593Smuzhiyun 	if (err) {
4016*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to get Firmware MAX size(err=%d)\n", __FUNCTION__, err);
4017*4882a593Smuzhiyun 		return -1;
4018*4882a593Smuzhiyun 	}
4019*4882a593Smuzhiyun 
4020*4882a593Smuzhiyun 	fw = rtw_zmalloc(fwmaxsize);
4021*4882a593Smuzhiyun 	if (!fw)
4022*4882a593Smuzhiyun 		return -1;
4023*4882a593Smuzhiyun 
4024*4882a593Smuzhiyun 	size = rtw_retrieve_from_file(fwpath, fw, fwmaxsize);
4025*4882a593Smuzhiyun 	if (size)
4026*4882a593Smuzhiyun 		err = rtw_halmac_dlfw(d, fw, size);
4027*4882a593Smuzhiyun 	else
4028*4882a593Smuzhiyun 		err = -1;
4029*4882a593Smuzhiyun 
4030*4882a593Smuzhiyun 	rtw_mfree(fw, fwmaxsize);
4031*4882a593Smuzhiyun 	/*fw = NULL;*/
4032*4882a593Smuzhiyun 
4033*4882a593Smuzhiyun 	return err;
4034*4882a593Smuzhiyun }
4035*4882a593Smuzhiyun 
4036*4882a593Smuzhiyun /*
4037*4882a593Smuzhiyun  * Description:
4038*4882a593Smuzhiyun  *	Power on/off BB/RF domain.
4039*4882a593Smuzhiyun  *
4040*4882a593Smuzhiyun  * Parameters:
4041*4882a593Smuzhiyun  *	enable	_TRUE/_FALSE for power on/off
4042*4882a593Smuzhiyun  *
4043*4882a593Smuzhiyun  * Return:
4044*4882a593Smuzhiyun  *	0	Success
4045*4882a593Smuzhiyun  *	others	Fail
4046*4882a593Smuzhiyun  */
rtw_halmac_phy_power_switch(struct dvobj_priv * d,u8 enable)4047*4882a593Smuzhiyun int rtw_halmac_phy_power_switch(struct dvobj_priv *d, u8 enable)
4048*4882a593Smuzhiyun {
4049*4882a593Smuzhiyun 	PADAPTER adapter;
4050*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
4051*4882a593Smuzhiyun 	struct halmac_api *api;
4052*4882a593Smuzhiyun 	enum halmac_ret_status status;
4053*4882a593Smuzhiyun 	u8 on;
4054*4882a593Smuzhiyun 
4055*4882a593Smuzhiyun 
4056*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
4057*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
4058*4882a593Smuzhiyun 	if (!halmac)
4059*4882a593Smuzhiyun 		return -1;
4060*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
4061*4882a593Smuzhiyun 	on = (enable == _TRUE) ? 1 : 0;
4062*4882a593Smuzhiyun 
4063*4882a593Smuzhiyun 	status = api->halmac_set_hw_value(halmac, HALMAC_HW_EN_BB_RF, &on);
4064*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
4065*4882a593Smuzhiyun 		return -1;
4066*4882a593Smuzhiyun 
4067*4882a593Smuzhiyun 	return 0;
4068*4882a593Smuzhiyun }
4069*4882a593Smuzhiyun 
_is_fw_read_cmd_down(PADAPTER adapter,u8 msgbox_num)4070*4882a593Smuzhiyun static u8 _is_fw_read_cmd_down(PADAPTER adapter, u8 msgbox_num)
4071*4882a593Smuzhiyun {
4072*4882a593Smuzhiyun 	u8 read_down = _FALSE;
4073*4882a593Smuzhiyun 	int retry_cnts = 100;
4074*4882a593Smuzhiyun 	u8 valid;
4075*4882a593Smuzhiyun 
4076*4882a593Smuzhiyun 	do {
4077*4882a593Smuzhiyun 		valid = rtw_read8(adapter, REG_HMETFR) & BIT(msgbox_num);
4078*4882a593Smuzhiyun 		if (0 == valid)
4079*4882a593Smuzhiyun 			read_down = _TRUE;
4080*4882a593Smuzhiyun 		else
4081*4882a593Smuzhiyun 			rtw_msleep_os(1);
4082*4882a593Smuzhiyun 	} while ((!read_down) && (retry_cnts--));
4083*4882a593Smuzhiyun 
4084*4882a593Smuzhiyun 	if (_FALSE == read_down)
4085*4882a593Smuzhiyun 		RTW_WARN("%s, reg_1cc(%x), msg_box(%d)...\n", __func__, rtw_read8(adapter, REG_HMETFR), msgbox_num);
4086*4882a593Smuzhiyun 
4087*4882a593Smuzhiyun 	return read_down;
4088*4882a593Smuzhiyun }
4089*4882a593Smuzhiyun 
4090*4882a593Smuzhiyun /**
4091*4882a593Smuzhiyun  * rtw_halmac_send_h2c() - Send H2C to firmware
4092*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
4093*4882a593Smuzhiyun  * @h2c:	H2C data buffer, suppose to be 8 bytes
4094*4882a593Smuzhiyun  *
4095*4882a593Smuzhiyun  * Send H2C to firmware by message box register(0x1D0~0x1D3 & 0x1F0~0x1F3).
4096*4882a593Smuzhiyun  *
4097*4882a593Smuzhiyun  * Assume firmware be ready to accept H2C here, please check
4098*4882a593Smuzhiyun  * (hal->bFWReady == _TRUE) before call this function or make sure firmware is
4099*4882a593Smuzhiyun  * ready.
4100*4882a593Smuzhiyun  *
4101*4882a593Smuzhiyun  * Return: 0 if process OK, otherwise fail to send this H2C.
4102*4882a593Smuzhiyun  */
rtw_halmac_send_h2c(struct dvobj_priv * d,u8 * h2c)4103*4882a593Smuzhiyun int rtw_halmac_send_h2c(struct dvobj_priv *d, u8 *h2c)
4104*4882a593Smuzhiyun {
4105*4882a593Smuzhiyun 	PADAPTER adapter = dvobj_get_primary_adapter(d);
4106*4882a593Smuzhiyun 	PHAL_DATA_TYPE hal = GET_HAL_DATA(adapter);
4107*4882a593Smuzhiyun 	u8 h2c_box_num = 0;
4108*4882a593Smuzhiyun 	u32 msgbox_addr = 0;
4109*4882a593Smuzhiyun 	u32 msgbox_ex_addr = 0;
4110*4882a593Smuzhiyun 	u32 h2c_cmd = 0;
4111*4882a593Smuzhiyun 	u32 h2c_cmd_ex = 0;
4112*4882a593Smuzhiyun 	int err = -1;
4113*4882a593Smuzhiyun 
4114*4882a593Smuzhiyun 
4115*4882a593Smuzhiyun 	if (!h2c) {
4116*4882a593Smuzhiyun 		RTW_WARN("%s: pbuf is NULL\n", __FUNCTION__);
4117*4882a593Smuzhiyun 		return err;
4118*4882a593Smuzhiyun 	}
4119*4882a593Smuzhiyun 
4120*4882a593Smuzhiyun 	if (rtw_is_surprise_removed(adapter)) {
4121*4882a593Smuzhiyun 		RTW_WARN("%s: surprise removed\n", __FUNCTION__);
4122*4882a593Smuzhiyun 		return err;
4123*4882a593Smuzhiyun 	}
4124*4882a593Smuzhiyun 
4125*4882a593Smuzhiyun 	_enter_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4126*4882a593Smuzhiyun 
4127*4882a593Smuzhiyun 	/* pay attention to if race condition happened in H2C cmd setting */
4128*4882a593Smuzhiyun 	h2c_box_num = hal->LastHMEBoxNum;
4129*4882a593Smuzhiyun 
4130*4882a593Smuzhiyun 	if (!_is_fw_read_cmd_down(adapter, h2c_box_num)) {
4131*4882a593Smuzhiyun 		RTW_WARN(" fw read cmd failed...\n");
4132*4882a593Smuzhiyun #ifdef DBG_CONFIG_ERROR_DETECT
4133*4882a593Smuzhiyun 		hal->srestpriv.self_dect_fw = _TRUE;
4134*4882a593Smuzhiyun 		hal->srestpriv.self_dect_fw_cnt++;
4135*4882a593Smuzhiyun #endif /* DBG_CONFIG_ERROR_DETECT */
4136*4882a593Smuzhiyun 		goto exit;
4137*4882a593Smuzhiyun 	}
4138*4882a593Smuzhiyun 
4139*4882a593Smuzhiyun 	/* Write Ext command (byte 4~7) */
4140*4882a593Smuzhiyun 	msgbox_ex_addr = REG_HMEBOX_E0 + (h2c_box_num * EX_MESSAGE_BOX_SIZE);
4141*4882a593Smuzhiyun 	_rtw_memcpy((u8 *)(&h2c_cmd_ex), h2c + 4, EX_MESSAGE_BOX_SIZE);
4142*4882a593Smuzhiyun 	h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);
4143*4882a593Smuzhiyun 	rtw_write32(adapter, msgbox_ex_addr, h2c_cmd_ex);
4144*4882a593Smuzhiyun 
4145*4882a593Smuzhiyun 	/* Write command (byte 0~3) */
4146*4882a593Smuzhiyun 	msgbox_addr = REG_HMEBOX0 + (h2c_box_num * MESSAGE_BOX_SIZE);
4147*4882a593Smuzhiyun 	_rtw_memcpy((u8 *)(&h2c_cmd), h2c, 4);
4148*4882a593Smuzhiyun 	h2c_cmd = le32_to_cpu(h2c_cmd);
4149*4882a593Smuzhiyun 	rtw_write32(adapter, msgbox_addr, h2c_cmd);
4150*4882a593Smuzhiyun 
4151*4882a593Smuzhiyun 	/* update last msg box number */
4152*4882a593Smuzhiyun 	hal->LastHMEBoxNum = (h2c_box_num + 1) % MAX_H2C_BOX_NUMS;
4153*4882a593Smuzhiyun 	err = 0;
4154*4882a593Smuzhiyun 
4155*4882a593Smuzhiyun #ifdef DBG_H2C_CONTENT
4156*4882a593Smuzhiyun 	RTW_INFO_DUMP("[H2C] - ", h2c, RTW_HALMAC_H2C_MAX_SIZE);
4157*4882a593Smuzhiyun #endif
4158*4882a593Smuzhiyun exit:
4159*4882a593Smuzhiyun 	_exit_critical_mutex(&d->h2c_fwcmd_mutex, NULL);
4160*4882a593Smuzhiyun 	return err;
4161*4882a593Smuzhiyun }
4162*4882a593Smuzhiyun 
4163*4882a593Smuzhiyun /**
4164*4882a593Smuzhiyun  * rtw_halmac_c2h_handle() - Handle C2H for HALMAC
4165*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
4166*4882a593Smuzhiyun  * @c2h:	Full C2H packet, including RX description and payload
4167*4882a593Smuzhiyun  * @size:	Size(byte) of c2h
4168*4882a593Smuzhiyun  *
4169*4882a593Smuzhiyun  * Send C2H packet to HALMAC to process C2H packets, and the expected C2H ID is
4170*4882a593Smuzhiyun  * 0xFF. This function won't have any I/O, so caller doesn't have to call it in
4171*4882a593Smuzhiyun  * I/O safe place(ex. command thread).
4172*4882a593Smuzhiyun  *
4173*4882a593Smuzhiyun  * Please sure doesn't call this function in the same thread as someone is
4174*4882a593Smuzhiyun  * waiting HALMAC C2H ack, otherwise there is a deadlock happen.
4175*4882a593Smuzhiyun  *
4176*4882a593Smuzhiyun  * Return: 0 if process OK, otherwise no action for this C2H.
4177*4882a593Smuzhiyun  */
rtw_halmac_c2h_handle(struct dvobj_priv * d,u8 * c2h,u32 size)4178*4882a593Smuzhiyun int rtw_halmac_c2h_handle(struct dvobj_priv *d, u8 *c2h, u32 size)
4179*4882a593Smuzhiyun {
4180*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4181*4882a593Smuzhiyun 	struct halmac_api *api;
4182*4882a593Smuzhiyun 	enum halmac_ret_status status;
4183*4882a593Smuzhiyun #ifdef RTW_HALMAC_FILTER_DRV_C2H
4184*4882a593Smuzhiyun 	u32 desc_size = 0;
4185*4882a593Smuzhiyun 	u8 *c2h_data;
4186*4882a593Smuzhiyun 	u8 sub;
4187*4882a593Smuzhiyun #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4188*4882a593Smuzhiyun 
4189*4882a593Smuzhiyun 
4190*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4191*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4192*4882a593Smuzhiyun 
4193*4882a593Smuzhiyun #ifdef RTW_HALMAC_FILTER_DRV_C2H
4194*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(mac, HALMAC_HW_RX_DESC_SIZE,
4195*4882a593Smuzhiyun 					  &desc_size);
4196*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
4197*4882a593Smuzhiyun 		RTW_ERR("%s: fail to get rx desc size!\n", __FUNCTION__);
4198*4882a593Smuzhiyun 		goto skip_filter;
4199*4882a593Smuzhiyun 	}
4200*4882a593Smuzhiyun 
4201*4882a593Smuzhiyun 	c2h_data = c2h + desc_size;
4202*4882a593Smuzhiyun 	sub = C2H_HDR_GET_C2H_SUB_CMD_ID(c2h_data);
4203*4882a593Smuzhiyun 	switch (sub) {
4204*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_DBG:
4205*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_2_DBG:
4206*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_3_DBG:
4207*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_4_DBG:
4208*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_FTMACKRPT_HDL_DBG:
4209*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_FTMC2H_RPT:
4210*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_DRVFTMC2H_RPT:
4211*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_FTM_5_DBG:
4212*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_CCX_RPT:
4213*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_NAN_RPT:
4214*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_ATM_RPT:
4215*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_SCC_CSA_RPT:
4216*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_FW_STATUS_NOTIFY:
4217*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_FTMSESSION_END:
4218*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_C2H_PKT_DETECT_THERMAL:
4219*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_FW_FWCTRL_RPT:
4220*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_SCAN_CH_NOTIFY:
4221*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_FW_TBTT_RPT:
4222*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_BCN_OFFLOAD:
4223*4882a593Smuzhiyun 	case C2H_SUB_CMD_ID_FW_DBG_MSG:
4224*4882a593Smuzhiyun 		RTW_PRINT("%s: unhandled C2H, id=0xFF subid=0x%x len=%u\n",
4225*4882a593Smuzhiyun 			  __FUNCTION__, sub, C2H_HDR_GET_LEN(c2h_data));
4226*4882a593Smuzhiyun 		RTW_PRINT_DUMP("C2H: ", c2h_data, size - desc_size);
4227*4882a593Smuzhiyun 		return 0;
4228*4882a593Smuzhiyun 	}
4229*4882a593Smuzhiyun 
4230*4882a593Smuzhiyun skip_filter:
4231*4882a593Smuzhiyun #endif /* RTW_HALMAC_FILTER_DRV_C2H */
4232*4882a593Smuzhiyun 
4233*4882a593Smuzhiyun 	status = api->halmac_get_c2h_info(mac, c2h, size);
4234*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
4235*4882a593Smuzhiyun 		return -1;
4236*4882a593Smuzhiyun 
4237*4882a593Smuzhiyun 	return 0;
4238*4882a593Smuzhiyun }
4239*4882a593Smuzhiyun 
rtw_halmac_get_available_efuse_size(struct dvobj_priv * d,u32 * size)4240*4882a593Smuzhiyun int rtw_halmac_get_available_efuse_size(struct dvobj_priv *d, u32 *size)
4241*4882a593Smuzhiyun {
4242*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4243*4882a593Smuzhiyun 	struct halmac_api *api;
4244*4882a593Smuzhiyun 	enum halmac_ret_status status;
4245*4882a593Smuzhiyun 	u32 val;
4246*4882a593Smuzhiyun 
4247*4882a593Smuzhiyun 
4248*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4249*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4250*4882a593Smuzhiyun 
4251*4882a593Smuzhiyun 	status = api->halmac_get_efuse_available_size(mac, &val);
4252*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
4253*4882a593Smuzhiyun 		return -1;
4254*4882a593Smuzhiyun 
4255*4882a593Smuzhiyun 	*size = val;
4256*4882a593Smuzhiyun 	return 0;
4257*4882a593Smuzhiyun }
4258*4882a593Smuzhiyun 
rtw_halmac_get_physical_efuse_size(struct dvobj_priv * d,u32 * size)4259*4882a593Smuzhiyun int rtw_halmac_get_physical_efuse_size(struct dvobj_priv *d, u32 *size)
4260*4882a593Smuzhiyun {
4261*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4262*4882a593Smuzhiyun 	struct halmac_api *api;
4263*4882a593Smuzhiyun 	enum halmac_ret_status status;
4264*4882a593Smuzhiyun 	u32 val;
4265*4882a593Smuzhiyun 
4266*4882a593Smuzhiyun 
4267*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4268*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4269*4882a593Smuzhiyun 
4270*4882a593Smuzhiyun 	status = api->halmac_get_efuse_size(mac, &val);
4271*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
4272*4882a593Smuzhiyun 		return -1;
4273*4882a593Smuzhiyun 
4274*4882a593Smuzhiyun 	*size = val;
4275*4882a593Smuzhiyun 	return 0;
4276*4882a593Smuzhiyun }
4277*4882a593Smuzhiyun 
rtw_halmac_read_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4278*4882a593Smuzhiyun int rtw_halmac_read_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4279*4882a593Smuzhiyun {
4280*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4281*4882a593Smuzhiyun 	struct halmac_api *api;
4282*4882a593Smuzhiyun 	enum halmac_ret_status status;
4283*4882a593Smuzhiyun 	enum halmac_feature_id id;
4284*4882a593Smuzhiyun 	int ret;
4285*4882a593Smuzhiyun 
4286*4882a593Smuzhiyun 
4287*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4288*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4289*4882a593Smuzhiyun 	id = HALMAC_FEATURE_DUMP_PHYSICAL_EFUSE;
4290*4882a593Smuzhiyun 
4291*4882a593Smuzhiyun 	ret = init_halmac_event(d, id, map, size);
4292*4882a593Smuzhiyun 	if (ret)
4293*4882a593Smuzhiyun 		return -1;
4294*4882a593Smuzhiyun 
4295*4882a593Smuzhiyun 	status = api->halmac_dump_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4296*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status) {
4297*4882a593Smuzhiyun 		free_halmac_event(d, id);
4298*4882a593Smuzhiyun 		return -1;
4299*4882a593Smuzhiyun 	}
4300*4882a593Smuzhiyun 
4301*4882a593Smuzhiyun 	ret = wait_halmac_event(d, id);
4302*4882a593Smuzhiyun 	if (ret)
4303*4882a593Smuzhiyun 		return -1;
4304*4882a593Smuzhiyun 
4305*4882a593Smuzhiyun 	return 0;
4306*4882a593Smuzhiyun }
4307*4882a593Smuzhiyun 
rtw_halmac_read_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4308*4882a593Smuzhiyun int rtw_halmac_read_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4309*4882a593Smuzhiyun {
4310*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4311*4882a593Smuzhiyun 	struct halmac_api *api;
4312*4882a593Smuzhiyun 	enum halmac_ret_status status;
4313*4882a593Smuzhiyun 	u8 v;
4314*4882a593Smuzhiyun 	u32 i;
4315*4882a593Smuzhiyun 	u8 *efuse = NULL;
4316*4882a593Smuzhiyun 	u32 size = 0;
4317*4882a593Smuzhiyun 	int err = 0;
4318*4882a593Smuzhiyun 
4319*4882a593Smuzhiyun 
4320*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4321*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4322*4882a593Smuzhiyun 
4323*4882a593Smuzhiyun 	if (api->halmac_read_efuse) {
4324*4882a593Smuzhiyun 		for (i = 0; i < cnt; i++) {
4325*4882a593Smuzhiyun 			status = api->halmac_read_efuse(mac, offset + i, &v);
4326*4882a593Smuzhiyun 			if (HALMAC_RET_SUCCESS != status)
4327*4882a593Smuzhiyun 				return -1;
4328*4882a593Smuzhiyun 			data[i] = v;
4329*4882a593Smuzhiyun 		}
4330*4882a593Smuzhiyun 	} else {
4331*4882a593Smuzhiyun 		err = rtw_halmac_get_physical_efuse_size(d, &size);
4332*4882a593Smuzhiyun 		if (err)
4333*4882a593Smuzhiyun 			return -1;
4334*4882a593Smuzhiyun 
4335*4882a593Smuzhiyun 		efuse = rtw_zmalloc(size);
4336*4882a593Smuzhiyun 		if (!efuse)
4337*4882a593Smuzhiyun 			return -1;
4338*4882a593Smuzhiyun 
4339*4882a593Smuzhiyun 		err = rtw_halmac_read_physical_efuse_map(d, efuse, size);
4340*4882a593Smuzhiyun 		if (err)
4341*4882a593Smuzhiyun 			err = -1;
4342*4882a593Smuzhiyun 		else
4343*4882a593Smuzhiyun 			_rtw_memcpy(data, efuse + offset, cnt);
4344*4882a593Smuzhiyun 
4345*4882a593Smuzhiyun 		rtw_mfree(efuse, size);
4346*4882a593Smuzhiyun 	}
4347*4882a593Smuzhiyun 
4348*4882a593Smuzhiyun 	return err;
4349*4882a593Smuzhiyun }
4350*4882a593Smuzhiyun 
rtw_halmac_write_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4351*4882a593Smuzhiyun int rtw_halmac_write_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4352*4882a593Smuzhiyun {
4353*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4354*4882a593Smuzhiyun 	struct halmac_api *api;
4355*4882a593Smuzhiyun 	enum halmac_ret_status status;
4356*4882a593Smuzhiyun 	u32 i;
4357*4882a593Smuzhiyun 
4358*4882a593Smuzhiyun 
4359*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4360*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4361*4882a593Smuzhiyun 
4362*4882a593Smuzhiyun 	if (api->halmac_write_efuse == NULL)
4363*4882a593Smuzhiyun 		return -1;
4364*4882a593Smuzhiyun 
4365*4882a593Smuzhiyun 	for (i = 0; i < cnt; i++) {
4366*4882a593Smuzhiyun 		status = api->halmac_write_efuse(mac, offset + i, data[i]);
4367*4882a593Smuzhiyun 		if (HALMAC_RET_SUCCESS != status)
4368*4882a593Smuzhiyun 			return -1;
4369*4882a593Smuzhiyun 	}
4370*4882a593Smuzhiyun 
4371*4882a593Smuzhiyun 	return 0;
4372*4882a593Smuzhiyun }
4373*4882a593Smuzhiyun 
rtw_halmac_get_logical_efuse_size(struct dvobj_priv * d,u32 * size)4374*4882a593Smuzhiyun int rtw_halmac_get_logical_efuse_size(struct dvobj_priv *d, u32 *size)
4375*4882a593Smuzhiyun {
4376*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4377*4882a593Smuzhiyun 	struct halmac_api *api;
4378*4882a593Smuzhiyun 	enum halmac_ret_status status;
4379*4882a593Smuzhiyun 	u32 val;
4380*4882a593Smuzhiyun 
4381*4882a593Smuzhiyun 
4382*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4383*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4384*4882a593Smuzhiyun 
4385*4882a593Smuzhiyun 	status = api->halmac_get_logical_efuse_size(mac, &val);
4386*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
4387*4882a593Smuzhiyun 		return -1;
4388*4882a593Smuzhiyun 
4389*4882a593Smuzhiyun 	*size = val;
4390*4882a593Smuzhiyun 	return 0;
4391*4882a593Smuzhiyun }
4392*4882a593Smuzhiyun 
rtw_halmac_read_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4393*4882a593Smuzhiyun int rtw_halmac_read_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4394*4882a593Smuzhiyun {
4395*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4396*4882a593Smuzhiyun 	struct halmac_api *api;
4397*4882a593Smuzhiyun 	enum halmac_ret_status status;
4398*4882a593Smuzhiyun 	enum halmac_feature_id id;
4399*4882a593Smuzhiyun 	int ret;
4400*4882a593Smuzhiyun 
4401*4882a593Smuzhiyun 
4402*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4403*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4404*4882a593Smuzhiyun 	id = HALMAC_FEATURE_DUMP_LOGICAL_EFUSE;
4405*4882a593Smuzhiyun 
4406*4882a593Smuzhiyun 	ret = init_halmac_event(d, id, map, size);
4407*4882a593Smuzhiyun 	if (ret)
4408*4882a593Smuzhiyun 		return -1;
4409*4882a593Smuzhiyun 
4410*4882a593Smuzhiyun 	status = api->halmac_dump_logical_efuse_map(mac, HALMAC_EFUSE_R_DRV);
4411*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status) {
4412*4882a593Smuzhiyun 		free_halmac_event(d, id);
4413*4882a593Smuzhiyun 		return -1;
4414*4882a593Smuzhiyun 	}
4415*4882a593Smuzhiyun 
4416*4882a593Smuzhiyun 	ret = wait_halmac_event(d, id);
4417*4882a593Smuzhiyun 	if (ret)
4418*4882a593Smuzhiyun 		return -1;
4419*4882a593Smuzhiyun 
4420*4882a593Smuzhiyun 	if (maskmap && masksize) {
4421*4882a593Smuzhiyun 		struct halmac_pg_efuse_info pginfo;
4422*4882a593Smuzhiyun 
4423*4882a593Smuzhiyun 		pginfo.efuse_map = map;
4424*4882a593Smuzhiyun 		pginfo.efuse_map_size = size;
4425*4882a593Smuzhiyun 		pginfo.efuse_mask = maskmap;
4426*4882a593Smuzhiyun 		pginfo.efuse_mask_size = masksize;
4427*4882a593Smuzhiyun 
4428*4882a593Smuzhiyun 		status = api->halmac_mask_logical_efuse(mac, &pginfo);
4429*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS)
4430*4882a593Smuzhiyun 			RTW_WARN("%s: mask logical efuse FAIL!\n", __FUNCTION__);
4431*4882a593Smuzhiyun 	}
4432*4882a593Smuzhiyun 
4433*4882a593Smuzhiyun 	return 0;
4434*4882a593Smuzhiyun }
4435*4882a593Smuzhiyun 
rtw_halmac_write_logical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size,u8 * maskmap,u32 masksize)4436*4882a593Smuzhiyun int rtw_halmac_write_logical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size, u8 *maskmap, u32 masksize)
4437*4882a593Smuzhiyun {
4438*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4439*4882a593Smuzhiyun 	struct halmac_api *api;
4440*4882a593Smuzhiyun 	struct halmac_pg_efuse_info pginfo;
4441*4882a593Smuzhiyun 	enum halmac_ret_status status;
4442*4882a593Smuzhiyun 
4443*4882a593Smuzhiyun 
4444*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4445*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4446*4882a593Smuzhiyun 
4447*4882a593Smuzhiyun 	pginfo.efuse_map = map;
4448*4882a593Smuzhiyun 	pginfo.efuse_map_size = size;
4449*4882a593Smuzhiyun 	pginfo.efuse_mask = maskmap;
4450*4882a593Smuzhiyun 	pginfo.efuse_mask_size = masksize;
4451*4882a593Smuzhiyun 
4452*4882a593Smuzhiyun 	status = api->halmac_pg_efuse_by_map(mac, &pginfo, HALMAC_EFUSE_R_AUTO);
4453*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
4454*4882a593Smuzhiyun 		return -1;
4455*4882a593Smuzhiyun 
4456*4882a593Smuzhiyun 	return 0;
4457*4882a593Smuzhiyun }
4458*4882a593Smuzhiyun 
rtw_halmac_read_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4459*4882a593Smuzhiyun int rtw_halmac_read_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4460*4882a593Smuzhiyun {
4461*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4462*4882a593Smuzhiyun 	struct halmac_api *api;
4463*4882a593Smuzhiyun 	enum halmac_ret_status status;
4464*4882a593Smuzhiyun 	u8 v;
4465*4882a593Smuzhiyun 	u32 i;
4466*4882a593Smuzhiyun 
4467*4882a593Smuzhiyun 
4468*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4469*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4470*4882a593Smuzhiyun 
4471*4882a593Smuzhiyun 	for (i = 0; i < cnt; i++) {
4472*4882a593Smuzhiyun 		status = api->halmac_read_logical_efuse(mac, offset + i, &v);
4473*4882a593Smuzhiyun 		if (HALMAC_RET_SUCCESS != status)
4474*4882a593Smuzhiyun 			return -1;
4475*4882a593Smuzhiyun 		data[i] = v;
4476*4882a593Smuzhiyun 	}
4477*4882a593Smuzhiyun 
4478*4882a593Smuzhiyun 	return 0;
4479*4882a593Smuzhiyun }
4480*4882a593Smuzhiyun 
rtw_halmac_write_logical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4481*4882a593Smuzhiyun int rtw_halmac_write_logical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4482*4882a593Smuzhiyun {
4483*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4484*4882a593Smuzhiyun 	struct halmac_api *api;
4485*4882a593Smuzhiyun 	enum halmac_ret_status status;
4486*4882a593Smuzhiyun 	u32 i;
4487*4882a593Smuzhiyun 
4488*4882a593Smuzhiyun 
4489*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4490*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4491*4882a593Smuzhiyun 
4492*4882a593Smuzhiyun 	for (i = 0; i < cnt; i++) {
4493*4882a593Smuzhiyun 		status = api->halmac_write_logical_efuse(mac, offset + i, data[i]);
4494*4882a593Smuzhiyun 		if (HALMAC_RET_SUCCESS != status)
4495*4882a593Smuzhiyun 			return -1;
4496*4882a593Smuzhiyun 	}
4497*4882a593Smuzhiyun 
4498*4882a593Smuzhiyun 	return 0;
4499*4882a593Smuzhiyun }
4500*4882a593Smuzhiyun 
rtw_halmac_write_bt_physical_efuse(struct dvobj_priv * d,u32 offset,u32 cnt,u8 * data)4501*4882a593Smuzhiyun int rtw_halmac_write_bt_physical_efuse(struct dvobj_priv *d, u32 offset, u32 cnt, u8 *data)
4502*4882a593Smuzhiyun {
4503*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4504*4882a593Smuzhiyun 	struct halmac_api *api;
4505*4882a593Smuzhiyun 	enum halmac_ret_status status;
4506*4882a593Smuzhiyun 	u32 i;
4507*4882a593Smuzhiyun 	u8 bank = 1;
4508*4882a593Smuzhiyun 
4509*4882a593Smuzhiyun 
4510*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4511*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4512*4882a593Smuzhiyun 
4513*4882a593Smuzhiyun 	for (i = 0; i < cnt; i++) {
4514*4882a593Smuzhiyun 		status = api->halmac_write_efuse_bt(mac, offset + i, data[i], bank);
4515*4882a593Smuzhiyun 		if (HALMAC_RET_SUCCESS != status) {
4516*4882a593Smuzhiyun 			printk("%s: halmac_write_efuse_bt status = %d\n", __FUNCTION__, status);
4517*4882a593Smuzhiyun 			return -1;
4518*4882a593Smuzhiyun 		}
4519*4882a593Smuzhiyun 	}
4520*4882a593Smuzhiyun 	printk("%s: halmac_write_efuse_bt status = HALMAC_RET_SUCCESS %d\n", __FUNCTION__, status);
4521*4882a593Smuzhiyun 	return 0;
4522*4882a593Smuzhiyun }
4523*4882a593Smuzhiyun 
4524*4882a593Smuzhiyun 
rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv * d,u8 * map,u32 size)4525*4882a593Smuzhiyun int rtw_halmac_read_bt_physical_efuse_map(struct dvobj_priv *d, u8 *map, u32 size)
4526*4882a593Smuzhiyun {
4527*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4528*4882a593Smuzhiyun 	struct halmac_api *api;
4529*4882a593Smuzhiyun 	enum halmac_ret_status status;
4530*4882a593Smuzhiyun 	int bank = 1;
4531*4882a593Smuzhiyun 
4532*4882a593Smuzhiyun 
4533*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4534*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4535*4882a593Smuzhiyun 
4536*4882a593Smuzhiyun 	status = api->halmac_dump_efuse_map_bt(mac, bank, size, map);
4537*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status) {
4538*4882a593Smuzhiyun 		printk("%s: halmac_dump_efuse_map_bt fail!\n", __FUNCTION__);
4539*4882a593Smuzhiyun 		return -1;
4540*4882a593Smuzhiyun 	}
4541*4882a593Smuzhiyun 
4542*4882a593Smuzhiyun 	printk("%s: OK!\n", __FUNCTION__);
4543*4882a593Smuzhiyun 
4544*4882a593Smuzhiyun 	return 0;
4545*4882a593Smuzhiyun }
4546*4882a593Smuzhiyun 
_fifo_sel_drv2halmac(u8 fifo_sel)4547*4882a593Smuzhiyun static enum hal_fifo_sel _fifo_sel_drv2halmac(u8 fifo_sel)
4548*4882a593Smuzhiyun {
4549*4882a593Smuzhiyun 	switch (fifo_sel) {
4550*4882a593Smuzhiyun 	case 0:
4551*4882a593Smuzhiyun 		return HAL_FIFO_SEL_TX;
4552*4882a593Smuzhiyun 	case 1:
4553*4882a593Smuzhiyun 		return HAL_FIFO_SEL_RX;
4554*4882a593Smuzhiyun 	case 2:
4555*4882a593Smuzhiyun 		return HAL_FIFO_SEL_RSVD_PAGE;
4556*4882a593Smuzhiyun 	case 3:
4557*4882a593Smuzhiyun 		return HAL_FIFO_SEL_REPORT;
4558*4882a593Smuzhiyun 	case 4:
4559*4882a593Smuzhiyun 		return HAL_FIFO_SEL_LLT;
4560*4882a593Smuzhiyun 	case 5:
4561*4882a593Smuzhiyun 		return HAL_FIFO_SEL_RXBUF_FW;
4562*4882a593Smuzhiyun 	}
4563*4882a593Smuzhiyun 
4564*4882a593Smuzhiyun 	return HAL_FIFO_SEL_RSVD_PAGE;
4565*4882a593Smuzhiyun }
4566*4882a593Smuzhiyun 
4567*4882a593Smuzhiyun /*#define CONFIG_HALMAC_FIFO_DUMP*/
rtw_halmac_dump_fifo(struct dvobj_priv * d,u8 fifo_sel,u32 addr,u32 size,u8 * buffer)4568*4882a593Smuzhiyun int rtw_halmac_dump_fifo(struct dvobj_priv *d, u8 fifo_sel, u32 addr, u32 size, u8 *buffer)
4569*4882a593Smuzhiyun {
4570*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4571*4882a593Smuzhiyun 	struct halmac_api *api;
4572*4882a593Smuzhiyun 	enum hal_fifo_sel halmac_fifo_sel;
4573*4882a593Smuzhiyun 	enum halmac_ret_status status;
4574*4882a593Smuzhiyun 	u8 *pfifo_map = NULL;
4575*4882a593Smuzhiyun 	u32 fifo_size = 0;
4576*4882a593Smuzhiyun 	s8 ret = 0;/* 0:success, -1:error */
4577*4882a593Smuzhiyun 	u8 mem_created = _FALSE;
4578*4882a593Smuzhiyun 
4579*4882a593Smuzhiyun 
4580*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4581*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4582*4882a593Smuzhiyun 
4583*4882a593Smuzhiyun 	if ((size != 0) && (buffer == NULL))
4584*4882a593Smuzhiyun 		return -1;
4585*4882a593Smuzhiyun 
4586*4882a593Smuzhiyun 	halmac_fifo_sel = _fifo_sel_drv2halmac(fifo_sel);
4587*4882a593Smuzhiyun 
4588*4882a593Smuzhiyun 	if ((size) && (buffer)) {
4589*4882a593Smuzhiyun 		pfifo_map = buffer;
4590*4882a593Smuzhiyun 		fifo_size = size;
4591*4882a593Smuzhiyun 	} else {
4592*4882a593Smuzhiyun 		fifo_size = api->halmac_get_fifo_size(mac, halmac_fifo_sel);
4593*4882a593Smuzhiyun 
4594*4882a593Smuzhiyun 		if (fifo_size)
4595*4882a593Smuzhiyun 			pfifo_map = rtw_zvmalloc(fifo_size);
4596*4882a593Smuzhiyun 		if (pfifo_map == NULL)
4597*4882a593Smuzhiyun 			return -1;
4598*4882a593Smuzhiyun 		mem_created = _TRUE;
4599*4882a593Smuzhiyun 	}
4600*4882a593Smuzhiyun 
4601*4882a593Smuzhiyun 	status = api->halmac_dump_fifo(mac, halmac_fifo_sel, addr, fifo_size, pfifo_map);
4602*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status) {
4603*4882a593Smuzhiyun 		ret = -1;
4604*4882a593Smuzhiyun 		goto _exit;
4605*4882a593Smuzhiyun 	}
4606*4882a593Smuzhiyun 
4607*4882a593Smuzhiyun #ifdef CONFIG_HALMAC_FIFO_DUMP
4608*4882a593Smuzhiyun 	{
4609*4882a593Smuzhiyun 		static const char * const fifo_sel_str[] = {
4610*4882a593Smuzhiyun 			"TX", "RX", "RSVD_PAGE", "REPORT", "LLT", "RXBUF_FW"
4611*4882a593Smuzhiyun 		};
4612*4882a593Smuzhiyun 
4613*4882a593Smuzhiyun 		RTW_INFO("%s FIFO DUMP [start_addr:0x%04x , size:%d]\n", fifo_sel_str[halmac_fifo_sel], addr, fifo_size);
4614*4882a593Smuzhiyun 		RTW_INFO_DUMP("\n", pfifo_map, fifo_size);
4615*4882a593Smuzhiyun 		RTW_INFO(" ==================================================\n");
4616*4882a593Smuzhiyun 	}
4617*4882a593Smuzhiyun #endif /* CONFIG_HALMAC_FIFO_DUMP */
4618*4882a593Smuzhiyun 
4619*4882a593Smuzhiyun _exit:
4620*4882a593Smuzhiyun 	if ((mem_created == _TRUE) && pfifo_map)
4621*4882a593Smuzhiyun 		rtw_vmfree(pfifo_map, fifo_size);
4622*4882a593Smuzhiyun 
4623*4882a593Smuzhiyun 	return ret;
4624*4882a593Smuzhiyun }
4625*4882a593Smuzhiyun 
4626*4882a593Smuzhiyun /*
4627*4882a593Smuzhiyun  * rtw_halmac_rx_agg_switch() - Switch RX aggregation function and setting
4628*4882a593Smuzhiyun  * @d		struct dvobj_priv *
4629*4882a593Smuzhiyun  * @enable	_FALSE/_TRUE for disable/enable RX aggregation function
4630*4882a593Smuzhiyun  *
4631*4882a593Smuzhiyun  * This function could help to on/off bus RX aggregation function, and is only
4632*4882a593Smuzhiyun  * useful for SDIO and USB interface. Although only "enable" flag is brough in,
4633*4882a593Smuzhiyun  * some setting would be taken from other places, and they are from:
4634*4882a593Smuzhiyun  * [DMA aggregation]
4635*4882a593Smuzhiyun  *	struct hal_com_data.rxagg_dma_size
4636*4882a593Smuzhiyun  *	struct hal_com_data.rxagg_dma_timeout
4637*4882a593Smuzhiyun  * [USB aggregation] (only use for USB interface)
4638*4882a593Smuzhiyun  *	struct hal_com_data.rxagg_usb_size
4639*4882a593Smuzhiyun  *	struct hal_com_data.rxagg_usb_timeout
4640*4882a593Smuzhiyun  * If above values of size and timeout are both 0 means driver would not
4641*4882a593Smuzhiyun  * control the threshold setting and leave it to HALMAC handle.
4642*4882a593Smuzhiyun  *
4643*4882a593Smuzhiyun  * From HALMAC V1_04_04, driver force the size threshold be hard limit, and the
4644*4882a593Smuzhiyun  * rx size can not exceed the setting.
4645*4882a593Smuzhiyun  *
4646*4882a593Smuzhiyun  * Return 0 for success, otherwise fail.
4647*4882a593Smuzhiyun  */
rtw_halmac_rx_agg_switch(struct dvobj_priv * d,u8 enable)4648*4882a593Smuzhiyun int rtw_halmac_rx_agg_switch(struct dvobj_priv *d, u8 enable)
4649*4882a593Smuzhiyun {
4650*4882a593Smuzhiyun 	struct _ADAPTER *adapter;
4651*4882a593Smuzhiyun 	struct hal_com_data *hal;
4652*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
4653*4882a593Smuzhiyun 	struct halmac_api *api;
4654*4882a593Smuzhiyun 	struct halmac_rxagg_cfg rxaggcfg;
4655*4882a593Smuzhiyun 	enum halmac_ret_status status;
4656*4882a593Smuzhiyun 
4657*4882a593Smuzhiyun 
4658*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
4659*4882a593Smuzhiyun 	hal = GET_HAL_DATA(adapter);
4660*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
4661*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
4662*4882a593Smuzhiyun 	_rtw_memset((void *)&rxaggcfg, 0, sizeof(rxaggcfg));
4663*4882a593Smuzhiyun 	rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4664*4882a593Smuzhiyun 	/*
4665*4882a593Smuzhiyun 	 * Always enable size limit to avoid rx size exceed
4666*4882a593Smuzhiyun 	 * driver defined size.
4667*4882a593Smuzhiyun 	 */
4668*4882a593Smuzhiyun 	rxaggcfg.threshold.size_limit_en = 1;
4669*4882a593Smuzhiyun 
4670*4882a593Smuzhiyun #ifdef RTW_RX_AGGREGATION
4671*4882a593Smuzhiyun 	if (_TRUE == enable) {
4672*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
4673*4882a593Smuzhiyun 		rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4674*4882a593Smuzhiyun 		rxaggcfg.threshold.drv_define = 0;
4675*4882a593Smuzhiyun 		if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4676*4882a593Smuzhiyun 			rxaggcfg.threshold.drv_define = 1;
4677*4882a593Smuzhiyun 			rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4678*4882a593Smuzhiyun 			rxaggcfg.threshold.size = hal->rxagg_dma_size;
4679*4882a593Smuzhiyun 			RTW_INFO("%s: RX aggregation threshold: "
4680*4882a593Smuzhiyun 				 "timeout=%u size=%u\n",
4681*4882a593Smuzhiyun 				 __FUNCTION__,
4682*4882a593Smuzhiyun 				 hal->rxagg_dma_timeout,
4683*4882a593Smuzhiyun 				 hal->rxagg_dma_size);
4684*4882a593Smuzhiyun 		}
4685*4882a593Smuzhiyun #elif defined(CONFIG_USB_HCI)
4686*4882a593Smuzhiyun 		switch (hal->rxagg_mode) {
4687*4882a593Smuzhiyun 		case RX_AGG_DISABLE:
4688*4882a593Smuzhiyun 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_NONE;
4689*4882a593Smuzhiyun 			break;
4690*4882a593Smuzhiyun 
4691*4882a593Smuzhiyun 		case RX_AGG_DMA:
4692*4882a593Smuzhiyun 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_DMA;
4693*4882a593Smuzhiyun 			if (hal->rxagg_dma_size || hal->rxagg_dma_timeout) {
4694*4882a593Smuzhiyun 				rxaggcfg.threshold.drv_define = 1;
4695*4882a593Smuzhiyun 				rxaggcfg.threshold.timeout = hal->rxagg_dma_timeout;
4696*4882a593Smuzhiyun 				rxaggcfg.threshold.size = hal->rxagg_dma_size;
4697*4882a593Smuzhiyun 			}
4698*4882a593Smuzhiyun 			break;
4699*4882a593Smuzhiyun 
4700*4882a593Smuzhiyun 		case RX_AGG_USB:
4701*4882a593Smuzhiyun 		case RX_AGG_MIX:
4702*4882a593Smuzhiyun 			rxaggcfg.mode = HALMAC_RX_AGG_MODE_USB;
4703*4882a593Smuzhiyun 			if (hal->rxagg_usb_size || hal->rxagg_usb_timeout) {
4704*4882a593Smuzhiyun 				rxaggcfg.threshold.drv_define = 1;
4705*4882a593Smuzhiyun 				rxaggcfg.threshold.timeout = hal->rxagg_usb_timeout;
4706*4882a593Smuzhiyun 				rxaggcfg.threshold.size = hal->rxagg_usb_size;
4707*4882a593Smuzhiyun 			}
4708*4882a593Smuzhiyun 			break;
4709*4882a593Smuzhiyun 		}
4710*4882a593Smuzhiyun #endif /* CONFIG_USB_HCI */
4711*4882a593Smuzhiyun 	}
4712*4882a593Smuzhiyun #endif /* RTW_RX_AGGREGATION */
4713*4882a593Smuzhiyun 
4714*4882a593Smuzhiyun 	status = api->halmac_cfg_rx_aggregation(halmac, &rxaggcfg);
4715*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
4716*4882a593Smuzhiyun 		return -1;
4717*4882a593Smuzhiyun 
4718*4882a593Smuzhiyun 	return 0;
4719*4882a593Smuzhiyun }
4720*4882a593Smuzhiyun 
rtw_halmac_download_rsvd_page(struct dvobj_priv * dvobj,u8 pg_offset,u8 * pbuf,u32 size)4721*4882a593Smuzhiyun int rtw_halmac_download_rsvd_page(struct dvobj_priv *dvobj, u8 pg_offset, u8 *pbuf, u32 size)
4722*4882a593Smuzhiyun {
4723*4882a593Smuzhiyun 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4724*4882a593Smuzhiyun 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4725*4882a593Smuzhiyun 	struct halmac_api *api = HALMAC_GET_API(halmac);
4726*4882a593Smuzhiyun 
4727*4882a593Smuzhiyun 	status = api->halmac_dl_drv_rsvd_page(halmac, pg_offset, pbuf, size);
4728*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
4729*4882a593Smuzhiyun 		return -1;
4730*4882a593Smuzhiyun 
4731*4882a593Smuzhiyun 	return 0;
4732*4882a593Smuzhiyun }
4733*4882a593Smuzhiyun 
4734*4882a593Smuzhiyun /*
4735*4882a593Smuzhiyun  * Description
4736*4882a593Smuzhiyun  *	Fill following spec info from HALMAC API:
4737*4882a593Smuzhiyun  *	sec_cam_ent_num
4738*4882a593Smuzhiyun  *
4739*4882a593Smuzhiyun  * Return
4740*4882a593Smuzhiyun  *	0	Success
4741*4882a593Smuzhiyun  *	others	Fail
4742*4882a593Smuzhiyun  */
rtw_halmac_fill_hal_spec(struct dvobj_priv * dvobj,struct hal_spec_t * spec)4743*4882a593Smuzhiyun int rtw_halmac_fill_hal_spec(struct dvobj_priv *dvobj, struct hal_spec_t *spec)
4744*4882a593Smuzhiyun {
4745*4882a593Smuzhiyun 	enum halmac_ret_status status;
4746*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
4747*4882a593Smuzhiyun 	struct halmac_api *api;
4748*4882a593Smuzhiyun 	u8 cam = 0;	/* Security Cam Entry Number */
4749*4882a593Smuzhiyun 
4750*4882a593Smuzhiyun 
4751*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(dvobj);
4752*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
4753*4882a593Smuzhiyun 
4754*4882a593Smuzhiyun 	/* Prepare data from HALMAC */
4755*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_CAM_ENTRY_NUM, &cam);
4756*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
4757*4882a593Smuzhiyun 		return -1;
4758*4882a593Smuzhiyun 
4759*4882a593Smuzhiyun 	/* Fill data to hal_spec_t */
4760*4882a593Smuzhiyun 	spec->sec_cam_ent_num = cam;
4761*4882a593Smuzhiyun 
4762*4882a593Smuzhiyun 	return 0;
4763*4882a593Smuzhiyun }
4764*4882a593Smuzhiyun 
rtw_halmac_p2pps(struct dvobj_priv * dvobj,struct hal_p2p_ps_para * pp2p_ps_para)4765*4882a593Smuzhiyun int rtw_halmac_p2pps(struct dvobj_priv *dvobj, struct hal_p2p_ps_para *pp2p_ps_para)
4766*4882a593Smuzhiyun {
4767*4882a593Smuzhiyun 	enum halmac_ret_status status = HALMAC_RET_SUCCESS;
4768*4882a593Smuzhiyun 	struct halmac_adapter *halmac = dvobj_to_halmac(dvobj);
4769*4882a593Smuzhiyun 	struct halmac_api *api = HALMAC_GET_API(halmac);
4770*4882a593Smuzhiyun 	struct halmac_p2pps halmac_p2p_ps;
4771*4882a593Smuzhiyun 
4772*4882a593Smuzhiyun 	(&halmac_p2p_ps)->offload_en = pp2p_ps_para->offload_en;
4773*4882a593Smuzhiyun 	(&halmac_p2p_ps)->role = pp2p_ps_para->role;
4774*4882a593Smuzhiyun 	(&halmac_p2p_ps)->ctwindow_en = pp2p_ps_para->ctwindow_en;
4775*4882a593Smuzhiyun 	(&halmac_p2p_ps)->noa_en = pp2p_ps_para->noa_en;
4776*4882a593Smuzhiyun 	(&halmac_p2p_ps)->noa_sel = pp2p_ps_para->noa_sel;
4777*4882a593Smuzhiyun 	(&halmac_p2p_ps)->all_sta_sleep = pp2p_ps_para->all_sta_sleep;
4778*4882a593Smuzhiyun 	(&halmac_p2p_ps)->discovery = pp2p_ps_para->discovery;
4779*4882a593Smuzhiyun 	(&halmac_p2p_ps)->disable_close_rf = pp2p_ps_para->disable_close_rf;
4780*4882a593Smuzhiyun 	(&halmac_p2p_ps)->p2p_port_id = _hw_port_drv2halmac(pp2p_ps_para->p2p_port_id);
4781*4882a593Smuzhiyun 	(&halmac_p2p_ps)->p2p_group = pp2p_ps_para->p2p_group;
4782*4882a593Smuzhiyun 	(&halmac_p2p_ps)->p2p_macid = pp2p_ps_para->p2p_macid;
4783*4882a593Smuzhiyun 	(&halmac_p2p_ps)->ctwindow_length = pp2p_ps_para->ctwindow_length;
4784*4882a593Smuzhiyun 	(&halmac_p2p_ps)->noa_duration_para = pp2p_ps_para->noa_duration_para;
4785*4882a593Smuzhiyun 	(&halmac_p2p_ps)->noa_interval_para = pp2p_ps_para->noa_interval_para;
4786*4882a593Smuzhiyun 	(&halmac_p2p_ps)->noa_start_time_para = pp2p_ps_para->noa_start_time_para;
4787*4882a593Smuzhiyun 	(&halmac_p2p_ps)->noa_count_para = pp2p_ps_para->noa_count_para;
4788*4882a593Smuzhiyun 
4789*4882a593Smuzhiyun 	status = api->halmac_p2pps(halmac, (&halmac_p2p_ps));
4790*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
4791*4882a593Smuzhiyun 		return -1;
4792*4882a593Smuzhiyun 
4793*4882a593Smuzhiyun 	return 0;
4794*4882a593Smuzhiyun 
4795*4882a593Smuzhiyun }
4796*4882a593Smuzhiyun 
4797*4882a593Smuzhiyun /**
4798*4882a593Smuzhiyun  * rtw_halmac_iqk() - Run IQ Calibration
4799*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
4800*4882a593Smuzhiyun  * @clear:	IQK parameters
4801*4882a593Smuzhiyun  * @segment:	IQK parameters
4802*4882a593Smuzhiyun  *
4803*4882a593Smuzhiyun  * Process IQ Calibration(IQK).
4804*4882a593Smuzhiyun  *
4805*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
4806*4882a593Smuzhiyun  */
rtw_halmac_iqk(struct dvobj_priv * d,u8 clear,u8 segment)4807*4882a593Smuzhiyun int rtw_halmac_iqk(struct dvobj_priv *d, u8 clear, u8 segment)
4808*4882a593Smuzhiyun {
4809*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4810*4882a593Smuzhiyun 	struct halmac_api *api;
4811*4882a593Smuzhiyun 	enum halmac_ret_status status;
4812*4882a593Smuzhiyun 	enum halmac_feature_id id;
4813*4882a593Smuzhiyun 	struct halmac_iqk_para para;
4814*4882a593Smuzhiyun 	int ret;
4815*4882a593Smuzhiyun 	u8 retry = 3;
4816*4882a593Smuzhiyun 	u8 delay = 1; /* ms */
4817*4882a593Smuzhiyun 
4818*4882a593Smuzhiyun 
4819*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4820*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4821*4882a593Smuzhiyun 	id = HALMAC_FEATURE_IQK;
4822*4882a593Smuzhiyun 
4823*4882a593Smuzhiyun 	ret = init_halmac_event(d, id, NULL, 0);
4824*4882a593Smuzhiyun 	if (ret)
4825*4882a593Smuzhiyun 		return -1;
4826*4882a593Smuzhiyun 
4827*4882a593Smuzhiyun 	para.clear = clear;
4828*4882a593Smuzhiyun 	para.segment_iqk = segment;
4829*4882a593Smuzhiyun 
4830*4882a593Smuzhiyun 	do {
4831*4882a593Smuzhiyun 		status = api->halmac_start_iqk(mac, &para);
4832*4882a593Smuzhiyun 		if (status != HALMAC_RET_BUSY_STATE)
4833*4882a593Smuzhiyun 			break;
4834*4882a593Smuzhiyun 		RTW_WARN("%s: Fail to start IQK, status is BUSY! retry=%d\n", __FUNCTION__, retry);
4835*4882a593Smuzhiyun 		if (!retry)
4836*4882a593Smuzhiyun 			break;
4837*4882a593Smuzhiyun 		retry--;
4838*4882a593Smuzhiyun 		rtw_msleep_os(delay);
4839*4882a593Smuzhiyun 	} while (1);
4840*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
4841*4882a593Smuzhiyun 		free_halmac_event(d, id);
4842*4882a593Smuzhiyun 		return -1;
4843*4882a593Smuzhiyun 	}
4844*4882a593Smuzhiyun 
4845*4882a593Smuzhiyun 	ret = wait_halmac_event(d, id);
4846*4882a593Smuzhiyun 	if (ret)
4847*4882a593Smuzhiyun 		return -1;
4848*4882a593Smuzhiyun 
4849*4882a593Smuzhiyun 	return 0;
4850*4882a593Smuzhiyun }
4851*4882a593Smuzhiyun 
4852*4882a593Smuzhiyun /**
4853*4882a593Smuzhiyun  * rtw_halmac_dpk() - Run DP Calibration
4854*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
4855*4882a593Smuzhiyun  * @buf:	buffer for store return value
4856*4882a593Smuzhiyun  * @bufsz:	size of buffer
4857*4882a593Smuzhiyun  *
4858*4882a593Smuzhiyun  * Process DP Calibration(DPK).
4859*4882a593Smuzhiyun  *
4860*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
4861*4882a593Smuzhiyun  */
rtw_halmac_dpk(struct dvobj_priv * d,u8 * buf,u32 bufsz)4862*4882a593Smuzhiyun int rtw_halmac_dpk(struct dvobj_priv *d, u8 *buf, u32 bufsz)
4863*4882a593Smuzhiyun {
4864*4882a593Smuzhiyun 	struct halmac_adapter *mac;
4865*4882a593Smuzhiyun 	struct halmac_api *api;
4866*4882a593Smuzhiyun 	enum halmac_ret_status status;
4867*4882a593Smuzhiyun 	enum halmac_feature_id id;
4868*4882a593Smuzhiyun 	int ret;
4869*4882a593Smuzhiyun 
4870*4882a593Smuzhiyun 
4871*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
4872*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
4873*4882a593Smuzhiyun 	id = HALMAC_FEATURE_DPK;
4874*4882a593Smuzhiyun 
4875*4882a593Smuzhiyun 	ret = init_halmac_event(d, id, buf, bufsz);
4876*4882a593Smuzhiyun 	if (ret)
4877*4882a593Smuzhiyun 		return -1;
4878*4882a593Smuzhiyun 
4879*4882a593Smuzhiyun 	status = api->halmac_start_dpk(mac);
4880*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS) {
4881*4882a593Smuzhiyun 		free_halmac_event(d, id);
4882*4882a593Smuzhiyun 		RTW_ERR("%s: Fail to start DPK (0x%x)!\n",
4883*4882a593Smuzhiyun 			__FUNCTION__, status);
4884*4882a593Smuzhiyun 		return -1;
4885*4882a593Smuzhiyun 	}
4886*4882a593Smuzhiyun 
4887*4882a593Smuzhiyun 	ret = wait_halmac_event(d, id);
4888*4882a593Smuzhiyun 	if (ret)
4889*4882a593Smuzhiyun 		return -1;
4890*4882a593Smuzhiyun 
4891*4882a593Smuzhiyun 	return 0;
4892*4882a593Smuzhiyun }
4893*4882a593Smuzhiyun 
_phy_parameter_val_drv2halmac(u32 val,u8 msk_en,u32 msk)4894*4882a593Smuzhiyun static inline u32 _phy_parameter_val_drv2halmac(u32 val, u8 msk_en, u32 msk)
4895*4882a593Smuzhiyun {
4896*4882a593Smuzhiyun 	if (!msk_en)
4897*4882a593Smuzhiyun 		return val;
4898*4882a593Smuzhiyun 
4899*4882a593Smuzhiyun 	return (val << bitshift(msk));
4900*4882a593Smuzhiyun }
4901*4882a593Smuzhiyun 
_phy_parameter_drv2halmac(struct rtw_phy_parameter * para,struct halmac_phy_parameter_info * info)4902*4882a593Smuzhiyun static int _phy_parameter_drv2halmac(struct rtw_phy_parameter *para, struct halmac_phy_parameter_info *info)
4903*4882a593Smuzhiyun {
4904*4882a593Smuzhiyun 	if (!para || !info)
4905*4882a593Smuzhiyun 		return -1;
4906*4882a593Smuzhiyun 
4907*4882a593Smuzhiyun 	_rtw_memset(info, 0, sizeof(*info));
4908*4882a593Smuzhiyun 
4909*4882a593Smuzhiyun 	switch (para->cmd) {
4910*4882a593Smuzhiyun 	case 0:
4911*4882a593Smuzhiyun 		/* MAC register */
4912*4882a593Smuzhiyun 		switch (para->data.mac.size) {
4913*4882a593Smuzhiyun 		case 1:
4914*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W8;
4915*4882a593Smuzhiyun 			break;
4916*4882a593Smuzhiyun 		case 2:
4917*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W16;
4918*4882a593Smuzhiyun 			break;
4919*4882a593Smuzhiyun 		default:
4920*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_MAC_W32;
4921*4882a593Smuzhiyun 			break;
4922*4882a593Smuzhiyun 		}
4923*4882a593Smuzhiyun 		info->content.MAC_REG_W.value = _phy_parameter_val_drv2halmac(
4924*4882a593Smuzhiyun 							para->data.mac.value,
4925*4882a593Smuzhiyun 							para->data.mac.msk_en,
4926*4882a593Smuzhiyun 							para->data.mac.msk);
4927*4882a593Smuzhiyun 		info->content.MAC_REG_W.msk = para->data.mac.msk;
4928*4882a593Smuzhiyun 		info->content.MAC_REG_W.offset = para->data.mac.offset;
4929*4882a593Smuzhiyun 		info->content.MAC_REG_W.msk_en = para->data.mac.msk_en;
4930*4882a593Smuzhiyun 		break;
4931*4882a593Smuzhiyun 
4932*4882a593Smuzhiyun 	case 1:
4933*4882a593Smuzhiyun 		/* BB register */
4934*4882a593Smuzhiyun 		switch (para->data.bb.size) {
4935*4882a593Smuzhiyun 		case 1:
4936*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W8;
4937*4882a593Smuzhiyun 			break;
4938*4882a593Smuzhiyun 		case 2:
4939*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W16;
4940*4882a593Smuzhiyun 			break;
4941*4882a593Smuzhiyun 		default:
4942*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_BB_W32;
4943*4882a593Smuzhiyun 			break;
4944*4882a593Smuzhiyun 		}
4945*4882a593Smuzhiyun 		info->content.BB_REG_W.value = _phy_parameter_val_drv2halmac(
4946*4882a593Smuzhiyun 							para->data.bb.value,
4947*4882a593Smuzhiyun 							para->data.bb.msk_en,
4948*4882a593Smuzhiyun 							para->data.bb.msk);
4949*4882a593Smuzhiyun 		info->content.BB_REG_W.msk = para->data.bb.msk;
4950*4882a593Smuzhiyun 		info->content.BB_REG_W.offset = para->data.bb.offset;
4951*4882a593Smuzhiyun 		info->content.BB_REG_W.msk_en = para->data.bb.msk_en;
4952*4882a593Smuzhiyun 		break;
4953*4882a593Smuzhiyun 
4954*4882a593Smuzhiyun 	case 2:
4955*4882a593Smuzhiyun 		/* RF register */
4956*4882a593Smuzhiyun 		info->cmd_id = HALMAC_PARAMETER_CMD_RF_W;
4957*4882a593Smuzhiyun 		info->content.RF_REG_W.value = _phy_parameter_val_drv2halmac(
4958*4882a593Smuzhiyun 							para->data.rf.value,
4959*4882a593Smuzhiyun 							para->data.rf.msk_en,
4960*4882a593Smuzhiyun 							para->data.rf.msk);
4961*4882a593Smuzhiyun 		info->content.RF_REG_W.msk = para->data.rf.msk;
4962*4882a593Smuzhiyun 		info->content.RF_REG_W.offset = para->data.rf.offset;
4963*4882a593Smuzhiyun 		info->content.RF_REG_W.msk_en = para->data.rf.msk_en;
4964*4882a593Smuzhiyun 		info->content.RF_REG_W.rf_path = para->data.rf.path;
4965*4882a593Smuzhiyun 		break;
4966*4882a593Smuzhiyun 
4967*4882a593Smuzhiyun 	case 3:
4968*4882a593Smuzhiyun 		/* Delay register */
4969*4882a593Smuzhiyun 		if (para->data.delay.unit == 0)
4970*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_US;
4971*4882a593Smuzhiyun 		else
4972*4882a593Smuzhiyun 			info->cmd_id = HALMAC_PARAMETER_CMD_DELAY_MS;
4973*4882a593Smuzhiyun 		info->content.DELAY_TIME.delay_time = para->data.delay.value;
4974*4882a593Smuzhiyun 		break;
4975*4882a593Smuzhiyun 
4976*4882a593Smuzhiyun 	case 0xFF:
4977*4882a593Smuzhiyun 		/* Latest(End) command */
4978*4882a593Smuzhiyun 		info->cmd_id = HALMAC_PARAMETER_CMD_END;
4979*4882a593Smuzhiyun 		break;
4980*4882a593Smuzhiyun 
4981*4882a593Smuzhiyun 	default:
4982*4882a593Smuzhiyun 		return -1;
4983*4882a593Smuzhiyun 	}
4984*4882a593Smuzhiyun 
4985*4882a593Smuzhiyun 	return 0;
4986*4882a593Smuzhiyun }
4987*4882a593Smuzhiyun 
4988*4882a593Smuzhiyun /**
4989*4882a593Smuzhiyun  * rtw_halmac_cfg_phy_para() - Register(Phy parameter) configuration
4990*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
4991*4882a593Smuzhiyun  * @para:	phy parameter
4992*4882a593Smuzhiyun  *
4993*4882a593Smuzhiyun  * Configure registers by firmware using H2C/C2H mechanism.
4994*4882a593Smuzhiyun  * The latest command should be para->cmd==0xFF(End command) to finish all
4995*4882a593Smuzhiyun  * processes.
4996*4882a593Smuzhiyun  *
4997*4882a593Smuzhiyun  * Return: 0 for OK, otherwise fail.
4998*4882a593Smuzhiyun  */
rtw_halmac_cfg_phy_para(struct dvobj_priv * d,struct rtw_phy_parameter * para)4999*4882a593Smuzhiyun int rtw_halmac_cfg_phy_para(struct dvobj_priv *d, struct rtw_phy_parameter *para)
5000*4882a593Smuzhiyun {
5001*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5002*4882a593Smuzhiyun 	struct halmac_api *api;
5003*4882a593Smuzhiyun 	enum halmac_ret_status status;
5004*4882a593Smuzhiyun 	enum halmac_feature_id id;
5005*4882a593Smuzhiyun 	struct halmac_phy_parameter_info info;
5006*4882a593Smuzhiyun 	u8 full_fifo;
5007*4882a593Smuzhiyun 	int err, ret;
5008*4882a593Smuzhiyun 
5009*4882a593Smuzhiyun 
5010*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5011*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5012*4882a593Smuzhiyun 	id = HALMAC_FEATURE_CFG_PARA;
5013*4882a593Smuzhiyun 	full_fifo = 1; /* ToDo: How to deciede? */
5014*4882a593Smuzhiyun 	ret = 0;
5015*4882a593Smuzhiyun 
5016*4882a593Smuzhiyun 	err = _phy_parameter_drv2halmac(para, &info);
5017*4882a593Smuzhiyun 	if (err)
5018*4882a593Smuzhiyun 		return -1;
5019*4882a593Smuzhiyun 
5020*4882a593Smuzhiyun 	err = init_halmac_event(d, id, NULL, 0);
5021*4882a593Smuzhiyun 	if (err)
5022*4882a593Smuzhiyun 		return -1;
5023*4882a593Smuzhiyun 
5024*4882a593Smuzhiyun 	status = api->halmac_cfg_parameter(mac, &info, full_fifo);
5025*4882a593Smuzhiyun 	if (info.cmd_id == HALMAC_PARAMETER_CMD_END) {
5026*4882a593Smuzhiyun 		if (status == HALMAC_RET_SUCCESS) {
5027*4882a593Smuzhiyun 			err = wait_halmac_event(d, id);
5028*4882a593Smuzhiyun 			if (err)
5029*4882a593Smuzhiyun 				ret = -1;
5030*4882a593Smuzhiyun 		} else {
5031*4882a593Smuzhiyun 			free_halmac_event(d, id);
5032*4882a593Smuzhiyun 			ret = -1;
5033*4882a593Smuzhiyun 			RTW_ERR("%s: Fail to send END of cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5034*4882a593Smuzhiyun 		}
5035*4882a593Smuzhiyun 	} else {
5036*4882a593Smuzhiyun 		if (status == HALMAC_RET_PARA_SENDING) {
5037*4882a593Smuzhiyun 			err = wait_halmac_event(d, id);
5038*4882a593Smuzhiyun 			if (err)
5039*4882a593Smuzhiyun 				ret = -1;
5040*4882a593Smuzhiyun 		} else {
5041*4882a593Smuzhiyun 			free_halmac_event(d, id);
5042*4882a593Smuzhiyun 			if (status != HALMAC_RET_SUCCESS) {
5043*4882a593Smuzhiyun 				ret = -1;
5044*4882a593Smuzhiyun 				RTW_ERR("%s: Fail to cfg parameter, status is 0x%x!\n", __FUNCTION__, status);
5045*4882a593Smuzhiyun 			}
5046*4882a593Smuzhiyun 		}
5047*4882a593Smuzhiyun 	}
5048*4882a593Smuzhiyun 
5049*4882a593Smuzhiyun 	return ret;
5050*4882a593Smuzhiyun }
5051*4882a593Smuzhiyun 
_led_mode_drv2halmac(u8 drv_mode)5052*4882a593Smuzhiyun static enum halmac_wlled_mode _led_mode_drv2halmac(u8 drv_mode)
5053*4882a593Smuzhiyun {
5054*4882a593Smuzhiyun 	enum halmac_wlled_mode halmac_mode;
5055*4882a593Smuzhiyun 
5056*4882a593Smuzhiyun 
5057*4882a593Smuzhiyun 	switch (drv_mode) {
5058*4882a593Smuzhiyun 	case 1:
5059*4882a593Smuzhiyun 		halmac_mode = HALMAC_WLLED_MODE_TX;
5060*4882a593Smuzhiyun 		break;
5061*4882a593Smuzhiyun 	case 2:
5062*4882a593Smuzhiyun 		halmac_mode = HALMAC_WLLED_MODE_RX;
5063*4882a593Smuzhiyun 		break;
5064*4882a593Smuzhiyun 	case 3:
5065*4882a593Smuzhiyun 		halmac_mode = HALMAC_WLLED_MODE_SW_CTRL;
5066*4882a593Smuzhiyun 		break;
5067*4882a593Smuzhiyun 	case 0:
5068*4882a593Smuzhiyun 	default:
5069*4882a593Smuzhiyun 		halmac_mode = HALMAC_WLLED_MODE_TRX;
5070*4882a593Smuzhiyun 		break;
5071*4882a593Smuzhiyun 	}
5072*4882a593Smuzhiyun 
5073*4882a593Smuzhiyun 	return halmac_mode;
5074*4882a593Smuzhiyun }
5075*4882a593Smuzhiyun 
5076*4882a593Smuzhiyun /**
5077*4882a593Smuzhiyun  * rtw_halmac_led_cfg() - Configure Hardware LED Mode
5078*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5079*4882a593Smuzhiyun  * @enable:	enable or disable LED function
5080*4882a593Smuzhiyun  *		0: disable
5081*4882a593Smuzhiyun  *		1: enable
5082*4882a593Smuzhiyun  * @mode:	WLan LED mode (valid when enable==1)
5083*4882a593Smuzhiyun  *		0: Blink when TX(transmit packet) and RX(receive packet)
5084*4882a593Smuzhiyun  *		1: Blink when TX only
5085*4882a593Smuzhiyun  *		2: Blink when RX only
5086*4882a593Smuzhiyun  *		3: Software control
5087*4882a593Smuzhiyun  *
5088*4882a593Smuzhiyun  * Configure hardware WLan LED mode.
5089*4882a593Smuzhiyun  * If want to change LED mode after enabled, need to disable LED first and
5090*4882a593Smuzhiyun  * enable again to set new mode.
5091*4882a593Smuzhiyun  *
5092*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5093*4882a593Smuzhiyun  */
rtw_halmac_led_cfg(struct dvobj_priv * d,u8 enable,u8 mode)5094*4882a593Smuzhiyun int rtw_halmac_led_cfg(struct dvobj_priv *d, u8 enable, u8 mode)
5095*4882a593Smuzhiyun {
5096*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
5097*4882a593Smuzhiyun 	struct halmac_api *api;
5098*4882a593Smuzhiyun 	enum halmac_wlled_mode led_mode;
5099*4882a593Smuzhiyun 	enum halmac_ret_status status;
5100*4882a593Smuzhiyun 
5101*4882a593Smuzhiyun 
5102*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
5103*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
5104*4882a593Smuzhiyun 
5105*4882a593Smuzhiyun 	if (enable) {
5106*4882a593Smuzhiyun 		status = api->halmac_pinmux_set_func(halmac,
5107*4882a593Smuzhiyun 						     HALMAC_GPIO_FUNC_WL_LED);
5108*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5109*4882a593Smuzhiyun 			RTW_ERR("%s: pinmux set fail!(0x%x)\n",
5110*4882a593Smuzhiyun 				__FUNCTION__, status);
5111*4882a593Smuzhiyun 			return -1;
5112*4882a593Smuzhiyun 		}
5113*4882a593Smuzhiyun 
5114*4882a593Smuzhiyun 		led_mode = _led_mode_drv2halmac(mode);
5115*4882a593Smuzhiyun 		status = api->halmac_pinmux_wl_led_mode(halmac, led_mode);
5116*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5117*4882a593Smuzhiyun 			RTW_ERR("%s: mode set fail!(0x%x)\n",
5118*4882a593Smuzhiyun 				__FUNCTION__, status);
5119*4882a593Smuzhiyun 			return -1;
5120*4882a593Smuzhiyun 		}
5121*4882a593Smuzhiyun 	} else {
5122*4882a593Smuzhiyun 		/* Change LED to software control and turn off */
5123*4882a593Smuzhiyun 		api->halmac_pinmux_wl_led_mode(halmac,
5124*4882a593Smuzhiyun 					       HALMAC_WLLED_MODE_SW_CTRL);
5125*4882a593Smuzhiyun 		api->halmac_pinmux_wl_led_sw_ctrl(halmac, 0);
5126*4882a593Smuzhiyun 
5127*4882a593Smuzhiyun 		status = api->halmac_pinmux_free_func(halmac,
5128*4882a593Smuzhiyun 						      HALMAC_GPIO_FUNC_WL_LED);
5129*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5130*4882a593Smuzhiyun 			RTW_ERR("%s: pinmux free fail!(0x%x)\n",
5131*4882a593Smuzhiyun 				__FUNCTION__, status);
5132*4882a593Smuzhiyun 			return -1;
5133*4882a593Smuzhiyun 		}
5134*4882a593Smuzhiyun 	}
5135*4882a593Smuzhiyun 
5136*4882a593Smuzhiyun 	return 0;
5137*4882a593Smuzhiyun }
5138*4882a593Smuzhiyun 
5139*4882a593Smuzhiyun /**
5140*4882a593Smuzhiyun  * rtw_halmac_led_switch() - Turn Hardware LED on/off
5141*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5142*4882a593Smuzhiyun  * @on:		LED light or not
5143*4882a593Smuzhiyun  *		0: Off
5144*4882a593Smuzhiyun  *		1: On(Light)
5145*4882a593Smuzhiyun  *
5146*4882a593Smuzhiyun  * Turn Hardware WLan LED On/Off.
5147*4882a593Smuzhiyun  * Before use this function, user should call rtw_halmac_led_ctrl() to switch
5148*4882a593Smuzhiyun  * mode to "software control(3)" first, otherwise control would fail.
5149*4882a593Smuzhiyun  * The interval between on and off must be longer than 1 ms, or the LED would
5150*4882a593Smuzhiyun  * keep light or dark only.
5151*4882a593Smuzhiyun  * Ex. Turn off LED at first, turn on after 0.5ms and turn off again after
5152*4882a593Smuzhiyun  * 0.5ms. The LED during this flow will only keep dark, and miss the turn on
5153*4882a593Smuzhiyun  * operation between two turn off operations.
5154*4882a593Smuzhiyun  */
rtw_halmac_led_switch(struct dvobj_priv * d,u8 on)5155*4882a593Smuzhiyun void rtw_halmac_led_switch(struct dvobj_priv *d, u8 on)
5156*4882a593Smuzhiyun {
5157*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
5158*4882a593Smuzhiyun 	struct halmac_api *api;
5159*4882a593Smuzhiyun 
5160*4882a593Smuzhiyun 
5161*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
5162*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
5163*4882a593Smuzhiyun 
5164*4882a593Smuzhiyun 	api->halmac_pinmux_wl_led_sw_ctrl(halmac, on);
5165*4882a593Smuzhiyun }
5166*4882a593Smuzhiyun 
_gpio_cfg(struct dvobj_priv * d,enum halmac_gpio_func gpio,u8 enable)5167*4882a593Smuzhiyun static int _gpio_cfg(struct dvobj_priv *d, enum halmac_gpio_func gpio, u8 enable)
5168*4882a593Smuzhiyun {
5169*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
5170*4882a593Smuzhiyun 	struct halmac_api *api;
5171*4882a593Smuzhiyun 	enum halmac_ret_status status;
5172*4882a593Smuzhiyun 
5173*4882a593Smuzhiyun 
5174*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
5175*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
5176*4882a593Smuzhiyun 
5177*4882a593Smuzhiyun 	if (enable) {
5178*4882a593Smuzhiyun 		status = api->halmac_pinmux_set_func(halmac, gpio);
5179*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5180*4882a593Smuzhiyun 			RTW_ERR("%s: pinmux set GPIO(%d) fail!(0x%x)\n",
5181*4882a593Smuzhiyun 				__FUNCTION__, gpio, status);
5182*4882a593Smuzhiyun 			return -1;
5183*4882a593Smuzhiyun 		}
5184*4882a593Smuzhiyun 	} else {
5185*4882a593Smuzhiyun  		status = api->halmac_pinmux_free_func(halmac, gpio);
5186*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5187*4882a593Smuzhiyun 			RTW_ERR("%s: pinmux free GPIO(%d) fail!(0x%x)\n",
5188*4882a593Smuzhiyun 				__FUNCTION__, gpio, status);
5189*4882a593Smuzhiyun 			return -1;
5190*4882a593Smuzhiyun 		}
5191*4882a593Smuzhiyun 	}
5192*4882a593Smuzhiyun 
5193*4882a593Smuzhiyun 	return 0;
5194*4882a593Smuzhiyun }
5195*4882a593Smuzhiyun 
5196*4882a593Smuzhiyun /**
5197*4882a593Smuzhiyun  * rtw_halmac_bt_wake_cfg() - Configure BT wake host function
5198*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5199*4882a593Smuzhiyun  * @enable:	enable or disable BT wake host function
5200*4882a593Smuzhiyun  *		0: disable
5201*4882a593Smuzhiyun  *		1: enable
5202*4882a593Smuzhiyun  *
5203*4882a593Smuzhiyun  * Configure pinmux to allow BT to control BT wake host pin.
5204*4882a593Smuzhiyun  *
5205*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5206*4882a593Smuzhiyun  */
rtw_halmac_bt_wake_cfg(struct dvobj_priv * d,u8 enable)5207*4882a593Smuzhiyun int rtw_halmac_bt_wake_cfg(struct dvobj_priv *d, u8 enable)
5208*4882a593Smuzhiyun {
5209*4882a593Smuzhiyun 	return _gpio_cfg(d, HALMAC_GPIO_FUNC_BT_HOST_WAKE1, enable);
5210*4882a593Smuzhiyun }
5211*4882a593Smuzhiyun 
_gpio_to_func_for_rfe_ctrl(u8 gpio)5212*4882a593Smuzhiyun static enum halmac_gpio_func _gpio_to_func_for_rfe_ctrl(u8 gpio)
5213*4882a593Smuzhiyun {
5214*4882a593Smuzhiyun 	enum halmac_gpio_func f = HALMAC_GPIO_FUNC_UNDEFINE;
5215*4882a593Smuzhiyun 
5216*4882a593Smuzhiyun 
5217*4882a593Smuzhiyun #ifdef CONFIG_RTL8822C
5218*4882a593Smuzhiyun 	switch (gpio) {
5219*4882a593Smuzhiyun 	case 1:
5220*4882a593Smuzhiyun 		f = HALMAC_GPIO_FUNC_ANTSWB;
5221*4882a593Smuzhiyun 		break;
5222*4882a593Smuzhiyun 	case 2:
5223*4882a593Smuzhiyun 		f = HALMAC_GPIO_FUNC_S1_TRSW;
5224*4882a593Smuzhiyun 		break;
5225*4882a593Smuzhiyun 	case 3:
5226*4882a593Smuzhiyun 		f = HALMAC_GPIO_FUNC_S0_TRSW;
5227*4882a593Smuzhiyun 		break;
5228*4882a593Smuzhiyun 	case 6:
5229*4882a593Smuzhiyun 		f = HALMAC_GPIO_FUNC_S0_PAPE;
5230*4882a593Smuzhiyun 		break;
5231*4882a593Smuzhiyun 	case 7:
5232*4882a593Smuzhiyun 		f = HALMAC_GPIO_FUNC_S0_TRSWB;
5233*4882a593Smuzhiyun 		break;
5234*4882a593Smuzhiyun 	case 13:
5235*4882a593Smuzhiyun 		f = HALMAC_GPIO_FUNC_ANTSW;
5236*4882a593Smuzhiyun 		break;
5237*4882a593Smuzhiyun 	}
5238*4882a593Smuzhiyun #endif /* CONFIG_RTL8822C */
5239*4882a593Smuzhiyun 
5240*4882a593Smuzhiyun 	return f;
5241*4882a593Smuzhiyun }
5242*4882a593Smuzhiyun 
5243*4882a593Smuzhiyun /**
5244*4882a593Smuzhiyun  * rtw_halmac_rfe_ctrl_cfg() - Configure RFE control GPIO
5245*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5246*4882a593Smuzhiyun  * @gpio:	gpio number
5247*4882a593Smuzhiyun  *
5248*4882a593Smuzhiyun  * Configure pinmux to enable RFE control GPIO.
5249*4882a593Smuzhiyun  *
5250*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5251*4882a593Smuzhiyun  */
rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv * d,u8 gpio)5252*4882a593Smuzhiyun int rtw_halmac_rfe_ctrl_cfg(struct dvobj_priv *d, u8 gpio)
5253*4882a593Smuzhiyun {
5254*4882a593Smuzhiyun 	enum halmac_gpio_func f;
5255*4882a593Smuzhiyun 
5256*4882a593Smuzhiyun 
5257*4882a593Smuzhiyun 	f = _gpio_to_func_for_rfe_ctrl(gpio);
5258*4882a593Smuzhiyun 	if (f == HALMAC_GPIO_FUNC_UNDEFINE)
5259*4882a593Smuzhiyun 		return -1;
5260*4882a593Smuzhiyun 	return _gpio_cfg(d, f, 1);
5261*4882a593Smuzhiyun }
5262*4882a593Smuzhiyun 
5263*4882a593Smuzhiyun #ifdef CONFIG_PNO_SUPPORT
5264*4882a593Smuzhiyun /**
5265*4882a593Smuzhiyun  * _halmac_scanoffload() - Switch channel by firmware during scanning
5266*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5267*4882a593Smuzhiyun  * @enable:	1: enable, 0: disable
5268*4882a593Smuzhiyun  * @nlo:	1: nlo mode (no c2h event), 0: normal mode
5269*4882a593Smuzhiyun  * @ssid:	ssid of probe request
5270*4882a593Smuzhiyun  * @ssid_len:	ssid length
5271*4882a593Smuzhiyun  *
5272*4882a593Smuzhiyun  * Switch Channel and Send Porbe Request Offloaded by FW
5273*4882a593Smuzhiyun  *
5274*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5275*4882a593Smuzhiyun  */
_halmac_scanoffload(struct dvobj_priv * d,u32 enable,u8 nlo,u8 * ssid,u8 ssid_len)5276*4882a593Smuzhiyun static int _halmac_scanoffload(struct dvobj_priv *d, u32 enable, u8 nlo,
5277*4882a593Smuzhiyun 			       u8 *ssid, u8 ssid_len)
5278*4882a593Smuzhiyun {
5279*4882a593Smuzhiyun 	struct _ADAPTER *adapter;
5280*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5281*4882a593Smuzhiyun 	struct halmac_api *api;
5282*4882a593Smuzhiyun 	enum halmac_ret_status status;
5283*4882a593Smuzhiyun 	struct halmac_ch_info ch_info;
5284*4882a593Smuzhiyun 	struct halmac_ch_switch_option cs_option;
5285*4882a593Smuzhiyun 	struct mlme_ext_priv *pmlmeext;
5286*4882a593Smuzhiyun 	enum halmac_feature_id id_update, id_ch_sw;
5287*4882a593Smuzhiyun 	struct halmac_indicator *indicator, *tbl;
5288*4882a593Smuzhiyun 
5289*4882a593Smuzhiyun 	int err = 0;
5290*4882a593Smuzhiyun 	u8 probereq[64];
5291*4882a593Smuzhiyun 	u32 len = 0;
5292*4882a593Smuzhiyun 	int i = 0;
5293*4882a593Smuzhiyun 	struct pno_ssid pnossid;
5294*4882a593Smuzhiyun 	struct rf_ctl_t *rfctl = NULL;
5295*4882a593Smuzhiyun 	struct _RT_CHANNEL_INFO *ch_set;
5296*4882a593Smuzhiyun 
5297*4882a593Smuzhiyun 
5298*4882a593Smuzhiyun 	tbl = d->hmpriv.indicator;
5299*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
5300*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5301*4882a593Smuzhiyun 	if (!mac)
5302*4882a593Smuzhiyun 		return -1;
5303*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5304*4882a593Smuzhiyun 	id_update = HALMAC_FEATURE_UPDATE_PACKET;
5305*4882a593Smuzhiyun 	id_ch_sw = HALMAC_FEATURE_CHANNEL_SWITCH;
5306*4882a593Smuzhiyun 	pmlmeext = &(adapter->mlmeextpriv);
5307*4882a593Smuzhiyun 	rfctl = adapter_to_rfctl(adapter);
5308*4882a593Smuzhiyun 	ch_set = rfctl->channel_set;
5309*4882a593Smuzhiyun 
5310*4882a593Smuzhiyun 	RTW_INFO("%s: %s scanoffload, mode: %s\n",
5311*4882a593Smuzhiyun 		 __FUNCTION__, enable?"Enable":"Disable",
5312*4882a593Smuzhiyun 		 nlo?"PNO/NLO":"Normal");
5313*4882a593Smuzhiyun 
5314*4882a593Smuzhiyun 	if (enable) {
5315*4882a593Smuzhiyun 		_rtw_memset(probereq, 0, sizeof(probereq));
5316*4882a593Smuzhiyun 
5317*4882a593Smuzhiyun 		_rtw_memset(&pnossid, 0, sizeof(pnossid));
5318*4882a593Smuzhiyun 		if (ssid) {
5319*4882a593Smuzhiyun 			if (ssid_len > sizeof(pnossid.SSID)) {
5320*4882a593Smuzhiyun 				RTW_ERR("%s: SSID length(%d) is too long(>%d)!!\n",
5321*4882a593Smuzhiyun 					__FUNCTION__, ssid_len, sizeof(pnossid.SSID));
5322*4882a593Smuzhiyun 				return -1;
5323*4882a593Smuzhiyun 			}
5324*4882a593Smuzhiyun 
5325*4882a593Smuzhiyun 			pnossid.SSID_len = ssid_len;
5326*4882a593Smuzhiyun 			_rtw_memcpy(pnossid.SSID, ssid, ssid_len);
5327*4882a593Smuzhiyun 		}
5328*4882a593Smuzhiyun 
5329*4882a593Smuzhiyun 		rtw_hal_construct_ProbeReq(adapter, probereq, &len, &pnossid);
5330*4882a593Smuzhiyun 
5331*4882a593Smuzhiyun 		if (!nlo) {
5332*4882a593Smuzhiyun 			err = init_halmac_event(d, id_update, NULL, 0);
5333*4882a593Smuzhiyun 			if (err)
5334*4882a593Smuzhiyun 				return -1;
5335*4882a593Smuzhiyun 		}
5336*4882a593Smuzhiyun 
5337*4882a593Smuzhiyun 		status = api->halmac_update_packet(mac, HALMAC_PACKET_PROBE_REQ,
5338*4882a593Smuzhiyun 						   probereq, len);
5339*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5340*4882a593Smuzhiyun 			if (!nlo)
5341*4882a593Smuzhiyun 				free_halmac_event(d, id_update);
5342*4882a593Smuzhiyun 			RTW_ERR("%s: halmac_update_packet FAIL(%d)!!\n",
5343*4882a593Smuzhiyun 				__FUNCTION__, status);
5344*4882a593Smuzhiyun 			return -1;
5345*4882a593Smuzhiyun 		}
5346*4882a593Smuzhiyun 
5347*4882a593Smuzhiyun 		if (!nlo) {
5348*4882a593Smuzhiyun 			err = wait_halmac_event(d, id_update);
5349*4882a593Smuzhiyun 			if (err)
5350*4882a593Smuzhiyun 				RTW_ERR("%s: wait update packet FAIL(%d)!!\n",
5351*4882a593Smuzhiyun 					__FUNCTION__, err);
5352*4882a593Smuzhiyun 		}
5353*4882a593Smuzhiyun 
5354*4882a593Smuzhiyun 		api->halmac_clear_ch_info(mac);
5355*4882a593Smuzhiyun 
5356*4882a593Smuzhiyun 		for (i = 0; i < rfctl->max_chan_nums && ch_set[i].ChannelNum != 0; i++) {
5357*4882a593Smuzhiyun 			_rtw_memset(&ch_info, 0, sizeof(ch_info));
5358*4882a593Smuzhiyun 			ch_info.extra_info = 0;
5359*4882a593Smuzhiyun 			ch_info.channel = ch_set[i].ChannelNum;
5360*4882a593Smuzhiyun 			ch_info.bw = HALMAC_BW_20;
5361*4882a593Smuzhiyun 			ch_info.pri_ch_idx = HALMAC_CH_IDX_1;
5362*4882a593Smuzhiyun 			ch_info.action_id = HALMAC_CS_ACTIVE_SCAN;
5363*4882a593Smuzhiyun 			ch_info.timeout = 1;
5364*4882a593Smuzhiyun 			status = api->halmac_add_ch_info(mac, &ch_info);
5365*4882a593Smuzhiyun 			if (status != HALMAC_RET_SUCCESS) {
5366*4882a593Smuzhiyun 				RTW_ERR("%s: add_ch_info FAIL(%d)!!\n",
5367*4882a593Smuzhiyun 					__FUNCTION__, status);
5368*4882a593Smuzhiyun 				return -1;
5369*4882a593Smuzhiyun 			}
5370*4882a593Smuzhiyun 		}
5371*4882a593Smuzhiyun 
5372*4882a593Smuzhiyun 		/* set channel switch option */
5373*4882a593Smuzhiyun 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5374*4882a593Smuzhiyun 		cs_option.dest_bw = HALMAC_BW_20;
5375*4882a593Smuzhiyun 		cs_option.periodic_option = HALMAC_CS_PERIODIC_2_PHASE;
5376*4882a593Smuzhiyun 		cs_option.dest_pri_ch_idx = HALMAC_CH_IDX_UNDEFINE;
5377*4882a593Smuzhiyun 		cs_option.tsf_low = 0;
5378*4882a593Smuzhiyun 		cs_option.switch_en = 1;
5379*4882a593Smuzhiyun 		cs_option.dest_ch_en = 1;
5380*4882a593Smuzhiyun 		cs_option.absolute_time_en = 0;
5381*4882a593Smuzhiyun 		cs_option.dest_ch = 1;
5382*4882a593Smuzhiyun 
5383*4882a593Smuzhiyun 		cs_option.normal_period = 5;
5384*4882a593Smuzhiyun 		cs_option.normal_period_sel = 0;
5385*4882a593Smuzhiyun 		cs_option.normal_cycle = 10;
5386*4882a593Smuzhiyun 
5387*4882a593Smuzhiyun 		cs_option.phase_2_period = 1;
5388*4882a593Smuzhiyun 		cs_option.phase_2_period_sel = 1;
5389*4882a593Smuzhiyun 
5390*4882a593Smuzhiyun 		/* nlo is for wow fw,  1: no c2h response */
5391*4882a593Smuzhiyun 		cs_option.nlo_en = nlo;
5392*4882a593Smuzhiyun 
5393*4882a593Smuzhiyun 		if (!nlo) {
5394*4882a593Smuzhiyun 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5395*4882a593Smuzhiyun 			if (err)
5396*4882a593Smuzhiyun 				return -1;
5397*4882a593Smuzhiyun 		}
5398*4882a593Smuzhiyun 
5399*4882a593Smuzhiyun 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5400*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5401*4882a593Smuzhiyun 			if (!nlo)
5402*4882a593Smuzhiyun 				free_halmac_event(d, id_ch_sw);
5403*4882a593Smuzhiyun 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5404*4882a593Smuzhiyun 				__FUNCTION__, status);
5405*4882a593Smuzhiyun 			return -1;
5406*4882a593Smuzhiyun 		}
5407*4882a593Smuzhiyun 
5408*4882a593Smuzhiyun 		if (!nlo) {
5409*4882a593Smuzhiyun 			err = wait_halmac_event(d, id_ch_sw);
5410*4882a593Smuzhiyun 			if (err)
5411*4882a593Smuzhiyun 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5412*4882a593Smuzhiyun 					__FUNCTION__, err);
5413*4882a593Smuzhiyun 		}
5414*4882a593Smuzhiyun 	} else {
5415*4882a593Smuzhiyun 		api->halmac_clear_ch_info(mac);
5416*4882a593Smuzhiyun 
5417*4882a593Smuzhiyun 		_rtw_memset(&cs_option, 0, sizeof(cs_option));
5418*4882a593Smuzhiyun 		cs_option.switch_en = 0;
5419*4882a593Smuzhiyun 
5420*4882a593Smuzhiyun 		if (!nlo) {
5421*4882a593Smuzhiyun 			err = init_halmac_event(d, id_ch_sw, NULL, 0);
5422*4882a593Smuzhiyun 			if (err)
5423*4882a593Smuzhiyun 				return -1;
5424*4882a593Smuzhiyun 		}
5425*4882a593Smuzhiyun 
5426*4882a593Smuzhiyun 		status = api->halmac_ctrl_ch_switch(mac, &cs_option);
5427*4882a593Smuzhiyun 		if (status != HALMAC_RET_SUCCESS) {
5428*4882a593Smuzhiyun 			if (!nlo)
5429*4882a593Smuzhiyun 				free_halmac_event(d, id_ch_sw);
5430*4882a593Smuzhiyun 			RTW_ERR("%s: halmac_ctrl_ch_switch FAIL(%d)!!\n",
5431*4882a593Smuzhiyun 				__FUNCTION__, status);
5432*4882a593Smuzhiyun 			return -1;
5433*4882a593Smuzhiyun 		}
5434*4882a593Smuzhiyun 
5435*4882a593Smuzhiyun 		if (!nlo) {
5436*4882a593Smuzhiyun 			err = wait_halmac_event(d, id_ch_sw);
5437*4882a593Smuzhiyun 			if (err)
5438*4882a593Smuzhiyun 				RTW_ERR("%s: wait ctrl_ch_switch FAIL(%d)!!\n",
5439*4882a593Smuzhiyun 					__FUNCTION__, err);
5440*4882a593Smuzhiyun 		}
5441*4882a593Smuzhiyun 	}
5442*4882a593Smuzhiyun 
5443*4882a593Smuzhiyun 	return 0;
5444*4882a593Smuzhiyun }
5445*4882a593Smuzhiyun 
5446*4882a593Smuzhiyun /**
5447*4882a593Smuzhiyun  * rtw_halmac_pno_scanoffload() - Control firmware scan AP function for PNO
5448*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5449*4882a593Smuzhiyun  * @enable:	1: enable, 0: disable
5450*4882a593Smuzhiyun  *
5451*4882a593Smuzhiyun  * Switch firmware scan AP function for PNO(prefer network offload) or
5452*4882a593Smuzhiyun  * NLO(network list offload).
5453*4882a593Smuzhiyun  *
5454*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5455*4882a593Smuzhiyun  */
rtw_halmac_pno_scanoffload(struct dvobj_priv * d,u32 enable)5456*4882a593Smuzhiyun int rtw_halmac_pno_scanoffload(struct dvobj_priv *d, u32 enable)
5457*4882a593Smuzhiyun {
5458*4882a593Smuzhiyun 	return _halmac_scanoffload(d, enable, 1, NULL, 0);
5459*4882a593Smuzhiyun }
5460*4882a593Smuzhiyun #endif /* CONFIG_PNO_SUPPORT */
5461*4882a593Smuzhiyun 
5462*4882a593Smuzhiyun #ifdef CONFIG_SDIO_HCI
5463*4882a593Smuzhiyun 
5464*4882a593Smuzhiyun /**
5465*4882a593Smuzhiyun  * rtw_halmac_preinit_sdio_io_indirect() - Enable indirect I/O or not
5466*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5467*4882a593Smuzhiyun  * @enable:	true: enable, false: disable
5468*4882a593Smuzhiyun  *
5469*4882a593Smuzhiyun  * Enable register access using direct I/O or indirect. This function should be
5470*4882a593Smuzhiyun  * called before rtw_halmac_init_adapter(), and the life cycle is the same as
5471*4882a593Smuzhiyun  * driver until removing driver.
5472*4882a593Smuzhiyun  *
5473*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5474*4882a593Smuzhiyun  */
rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv * d,bool enable)5475*4882a593Smuzhiyun int rtw_halmac_preinit_sdio_io_indirect(struct dvobj_priv *d, bool enable)
5476*4882a593Smuzhiyun {
5477*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
5478*4882a593Smuzhiyun 	struct halmacpriv *priv;
5479*4882a593Smuzhiyun 
5480*4882a593Smuzhiyun 
5481*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
5482*4882a593Smuzhiyun 	if (halmac) {
5483*4882a593Smuzhiyun 		RTW_WARN("%s: illegal operation! "
5484*4882a593Smuzhiyun 			 "preinit function only could be called before init!\n",
5485*4882a593Smuzhiyun 			 __FUNCTION__);
5486*4882a593Smuzhiyun 		return -1;
5487*4882a593Smuzhiyun 	}
5488*4882a593Smuzhiyun 
5489*4882a593Smuzhiyun 	priv = &d->hmpriv;
5490*4882a593Smuzhiyun 	priv->sdio_io_indir = (enable ? 1 : 2);
5491*4882a593Smuzhiyun 
5492*4882a593Smuzhiyun 	return 0;
5493*4882a593Smuzhiyun }
5494*4882a593Smuzhiyun 
5495*4882a593Smuzhiyun /*
5496*4882a593Smuzhiyun  * Description:
5497*4882a593Smuzhiyun  *	Update queue allocated page number to driver
5498*4882a593Smuzhiyun  *
5499*4882a593Smuzhiyun  * Parameter:
5500*4882a593Smuzhiyun  *	d	pointer to struct dvobj_priv of driver
5501*4882a593Smuzhiyun  *
5502*4882a593Smuzhiyun  * Return:
5503*4882a593Smuzhiyun  *	0	Success, "page" is valid.
5504*4882a593Smuzhiyun  *	others	Fail, "page" is invalid.
5505*4882a593Smuzhiyun  */
rtw_halmac_query_tx_page_num(struct dvobj_priv * d)5506*4882a593Smuzhiyun int rtw_halmac_query_tx_page_num(struct dvobj_priv *d)
5507*4882a593Smuzhiyun {
5508*4882a593Smuzhiyun 	PADAPTER adapter;
5509*4882a593Smuzhiyun 	struct halmacpriv *hmpriv;
5510*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
5511*4882a593Smuzhiyun 	struct halmac_api *api;
5512*4882a593Smuzhiyun 	struct halmac_rqpn_map rqpn;
5513*4882a593Smuzhiyun 	enum halmac_dma_mapping dmaqueue;
5514*4882a593Smuzhiyun 	struct halmac_txff_allocation fifosize;
5515*4882a593Smuzhiyun 	enum halmac_ret_status status;
5516*4882a593Smuzhiyun 	u8 i;
5517*4882a593Smuzhiyun 
5518*4882a593Smuzhiyun 
5519*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
5520*4882a593Smuzhiyun 	hmpriv = &d->hmpriv;
5521*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
5522*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
5523*4882a593Smuzhiyun 	_rtw_memset((void *)&rqpn, 0, sizeof(rqpn));
5524*4882a593Smuzhiyun 	_rtw_memset((void *)&fifosize, 0, sizeof(fifosize));
5525*4882a593Smuzhiyun 
5526*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_RQPN_MAPPING, &rqpn);
5527*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5528*4882a593Smuzhiyun 		return -1;
5529*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_TXFF_ALLOCATION, &fifosize);
5530*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5531*4882a593Smuzhiyun 		return -1;
5532*4882a593Smuzhiyun 
5533*4882a593Smuzhiyun 	for (i = 0; i < HW_QUEUE_ENTRY; i++) {
5534*4882a593Smuzhiyun 		hmpriv->txpage[i] = 0;
5535*4882a593Smuzhiyun 
5536*4882a593Smuzhiyun 		/* Driver index mapping to HALMAC DMA queue */
5537*4882a593Smuzhiyun 		dmaqueue = HALMAC_DMA_MAPPING_UNDEFINE;
5538*4882a593Smuzhiyun 		switch (i) {
5539*4882a593Smuzhiyun 		case VO_QUEUE_INX:
5540*4882a593Smuzhiyun 			dmaqueue = rqpn.dma_map_vo;
5541*4882a593Smuzhiyun 			break;
5542*4882a593Smuzhiyun 		case VI_QUEUE_INX:
5543*4882a593Smuzhiyun 			dmaqueue = rqpn.dma_map_vi;
5544*4882a593Smuzhiyun 			break;
5545*4882a593Smuzhiyun 		case BE_QUEUE_INX:
5546*4882a593Smuzhiyun 			dmaqueue = rqpn.dma_map_be;
5547*4882a593Smuzhiyun 			break;
5548*4882a593Smuzhiyun 		case BK_QUEUE_INX:
5549*4882a593Smuzhiyun 			dmaqueue = rqpn.dma_map_bk;
5550*4882a593Smuzhiyun 			break;
5551*4882a593Smuzhiyun 		case MGT_QUEUE_INX:
5552*4882a593Smuzhiyun 			dmaqueue = rqpn.dma_map_mg;
5553*4882a593Smuzhiyun 			break;
5554*4882a593Smuzhiyun 		case HIGH_QUEUE_INX:
5555*4882a593Smuzhiyun 			dmaqueue = rqpn.dma_map_hi;
5556*4882a593Smuzhiyun 			break;
5557*4882a593Smuzhiyun 		case BCN_QUEUE_INX:
5558*4882a593Smuzhiyun 		case TXCMD_QUEUE_INX:
5559*4882a593Smuzhiyun 			/* Unlimited */
5560*4882a593Smuzhiyun 			hmpriv->txpage[i] = 0xFFFF;
5561*4882a593Smuzhiyun 			continue;
5562*4882a593Smuzhiyun 		}
5563*4882a593Smuzhiyun 
5564*4882a593Smuzhiyun 		switch (dmaqueue) {
5565*4882a593Smuzhiyun 		case HALMAC_DMA_MAPPING_EXTRA:
5566*4882a593Smuzhiyun 			hmpriv->txpage[i] = fifosize.extra_queue_pg_num;
5567*4882a593Smuzhiyun 			break;
5568*4882a593Smuzhiyun 		case HALMAC_DMA_MAPPING_LOW:
5569*4882a593Smuzhiyun 			hmpriv->txpage[i] = fifosize.low_queue_pg_num;
5570*4882a593Smuzhiyun 			break;
5571*4882a593Smuzhiyun 		case HALMAC_DMA_MAPPING_NORMAL:
5572*4882a593Smuzhiyun 			hmpriv->txpage[i] = fifosize.normal_queue_pg_num;
5573*4882a593Smuzhiyun 			break;
5574*4882a593Smuzhiyun 		case HALMAC_DMA_MAPPING_HIGH:
5575*4882a593Smuzhiyun 			hmpriv->txpage[i] = fifosize.high_queue_pg_num;
5576*4882a593Smuzhiyun 			break;
5577*4882a593Smuzhiyun 		case HALMAC_DMA_MAPPING_UNDEFINE:
5578*4882a593Smuzhiyun 			break;
5579*4882a593Smuzhiyun 		}
5580*4882a593Smuzhiyun 		hmpriv->txpage[i] += fifosize.pub_queue_pg_num;
5581*4882a593Smuzhiyun 	}
5582*4882a593Smuzhiyun 
5583*4882a593Smuzhiyun 	return 0;
5584*4882a593Smuzhiyun }
5585*4882a593Smuzhiyun 
5586*4882a593Smuzhiyun /*
5587*4882a593Smuzhiyun  * Description:
5588*4882a593Smuzhiyun  *	Get specific queue allocated page number
5589*4882a593Smuzhiyun  *
5590*4882a593Smuzhiyun  * Parameter:
5591*4882a593Smuzhiyun  *	d	pointer to struct dvobj_priv of driver
5592*4882a593Smuzhiyun  *	queue	target queue to query, VO/VI/BE/BK/.../TXCMD_QUEUE_INX
5593*4882a593Smuzhiyun  *	page	return allocated page number
5594*4882a593Smuzhiyun  *
5595*4882a593Smuzhiyun  * Return:
5596*4882a593Smuzhiyun  *	0	Success, "page" is valid.
5597*4882a593Smuzhiyun  *	others	Fail, "page" is invalid.
5598*4882a593Smuzhiyun  */
rtw_halmac_get_tx_queue_page_num(struct dvobj_priv * d,u8 queue,u32 * page)5599*4882a593Smuzhiyun int rtw_halmac_get_tx_queue_page_num(struct dvobj_priv *d, u8 queue, u32 *page)
5600*4882a593Smuzhiyun {
5601*4882a593Smuzhiyun 	*page = 0;
5602*4882a593Smuzhiyun 	if (queue < HW_QUEUE_ENTRY)
5603*4882a593Smuzhiyun 		*page = d->hmpriv.txpage[queue];
5604*4882a593Smuzhiyun 
5605*4882a593Smuzhiyun 	return 0;
5606*4882a593Smuzhiyun }
5607*4882a593Smuzhiyun 
5608*4882a593Smuzhiyun /*
5609*4882a593Smuzhiyun  * Return:
5610*4882a593Smuzhiyun  *	address for SDIO command
5611*4882a593Smuzhiyun  */
rtw_halmac_sdio_get_tx_addr(struct dvobj_priv * d,u8 * desc,u32 size)5612*4882a593Smuzhiyun u32 rtw_halmac_sdio_get_tx_addr(struct dvobj_priv *d, u8 *desc, u32 size)
5613*4882a593Smuzhiyun {
5614*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5615*4882a593Smuzhiyun 	struct halmac_api *api;
5616*4882a593Smuzhiyun 	enum halmac_ret_status status;
5617*4882a593Smuzhiyun 	u32 addr;
5618*4882a593Smuzhiyun 
5619*4882a593Smuzhiyun 
5620*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5621*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5622*4882a593Smuzhiyun 
5623*4882a593Smuzhiyun 	status = api->halmac_get_sdio_tx_addr(mac, desc, size, &addr);
5624*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
5625*4882a593Smuzhiyun 		return 0;
5626*4882a593Smuzhiyun 
5627*4882a593Smuzhiyun 	return addr;
5628*4882a593Smuzhiyun }
5629*4882a593Smuzhiyun 
rtw_halmac_sdio_tx_allowed(struct dvobj_priv * d,u8 * buf,u32 size)5630*4882a593Smuzhiyun int rtw_halmac_sdio_tx_allowed(struct dvobj_priv *d, u8 *buf, u32 size)
5631*4882a593Smuzhiyun {
5632*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5633*4882a593Smuzhiyun 	struct halmac_api *api;
5634*4882a593Smuzhiyun 	enum halmac_ret_status status;
5635*4882a593Smuzhiyun 
5636*4882a593Smuzhiyun 
5637*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5638*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5639*4882a593Smuzhiyun 
5640*4882a593Smuzhiyun 	status = api->halmac_tx_allowed_sdio(mac, buf, size);
5641*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
5642*4882a593Smuzhiyun 		return -1;
5643*4882a593Smuzhiyun 
5644*4882a593Smuzhiyun 	return 0;
5645*4882a593Smuzhiyun }
5646*4882a593Smuzhiyun 
rtw_halmac_sdio_get_rx_addr(struct dvobj_priv * d,u8 * seq)5647*4882a593Smuzhiyun u32 rtw_halmac_sdio_get_rx_addr(struct dvobj_priv *d, u8 *seq)
5648*4882a593Smuzhiyun {
5649*4882a593Smuzhiyun 	u8 id;
5650*4882a593Smuzhiyun 
5651*4882a593Smuzhiyun #define RTW_SDIO_ADDR_RX_RX0FF_PRFIX	0x0E000
5652*4882a593Smuzhiyun #define RTW_SDIO_ADDR_RX_RX0FF_GEN(a)	(RTW_SDIO_ADDR_RX_RX0FF_PRFIX|(a&0x3))
5653*4882a593Smuzhiyun 
5654*4882a593Smuzhiyun 	id = *seq;
5655*4882a593Smuzhiyun 	(*seq)++;
5656*4882a593Smuzhiyun 	return RTW_SDIO_ADDR_RX_RX0FF_GEN(id);
5657*4882a593Smuzhiyun }
5658*4882a593Smuzhiyun 
rtw_halmac_sdio_set_tx_format(struct dvobj_priv * d,enum halmac_sdio_tx_format format)5659*4882a593Smuzhiyun int rtw_halmac_sdio_set_tx_format(struct dvobj_priv *d, enum halmac_sdio_tx_format format)
5660*4882a593Smuzhiyun {
5661*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5662*4882a593Smuzhiyun 	struct halmac_api *api;
5663*4882a593Smuzhiyun 	enum halmac_ret_status status;
5664*4882a593Smuzhiyun 
5665*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5666*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5667*4882a593Smuzhiyun 
5668*4882a593Smuzhiyun 	status = api->halmac_set_hw_value(mac, HALMAC_HW_SDIO_TX_FORMAT, &format);
5669*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
5670*4882a593Smuzhiyun 		return -1;
5671*4882a593Smuzhiyun 
5672*4882a593Smuzhiyun 	return 0;
5673*4882a593Smuzhiyun }
5674*4882a593Smuzhiyun #endif /* CONFIG_SDIO_HCI */
5675*4882a593Smuzhiyun 
5676*4882a593Smuzhiyun #ifdef CONFIG_USB_HCI
rtw_halmac_usb_get_bulkout_id(struct dvobj_priv * d,u8 * buf,u32 size)5677*4882a593Smuzhiyun u8 rtw_halmac_usb_get_bulkout_id(struct dvobj_priv *d, u8 *buf, u32 size)
5678*4882a593Smuzhiyun {
5679*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5680*4882a593Smuzhiyun 	struct halmac_api *api;
5681*4882a593Smuzhiyun 	enum halmac_ret_status status;
5682*4882a593Smuzhiyun 	u8 bulkout_id;
5683*4882a593Smuzhiyun 
5684*4882a593Smuzhiyun 
5685*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5686*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5687*4882a593Smuzhiyun 
5688*4882a593Smuzhiyun 	status = api->halmac_get_usb_bulkout_id(mac, buf, size, &bulkout_id);
5689*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
5690*4882a593Smuzhiyun 		return 0;
5691*4882a593Smuzhiyun 
5692*4882a593Smuzhiyun 	return bulkout_id;
5693*4882a593Smuzhiyun }
5694*4882a593Smuzhiyun 
5695*4882a593Smuzhiyun /**
5696*4882a593Smuzhiyun  * rtw_halmac_usb_get_txagg_desc_num() - MAX descriptor number in one bulk for TX
5697*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5698*4882a593Smuzhiyun  * @size:	TX FIFO size, unit is byte.
5699*4882a593Smuzhiyun  *
5700*4882a593Smuzhiyun  * Get MAX descriptor number in one bulk out from HALMAC.
5701*4882a593Smuzhiyun  *
5702*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5703*4882a593Smuzhiyun  */
rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv * d,u8 * num)5704*4882a593Smuzhiyun int rtw_halmac_usb_get_txagg_desc_num(struct dvobj_priv *d, u8 *num)
5705*4882a593Smuzhiyun {
5706*4882a593Smuzhiyun 	struct halmac_adapter *halmac;
5707*4882a593Smuzhiyun 	struct halmac_api *api;
5708*4882a593Smuzhiyun 	enum halmac_ret_status status;
5709*4882a593Smuzhiyun 	u8 val = 0;
5710*4882a593Smuzhiyun 
5711*4882a593Smuzhiyun 
5712*4882a593Smuzhiyun 	halmac = dvobj_to_halmac(d);
5713*4882a593Smuzhiyun 	api = HALMAC_GET_API(halmac);
5714*4882a593Smuzhiyun 
5715*4882a593Smuzhiyun 	status = api->halmac_get_hw_value(halmac, HALMAC_HW_USB_TXAGG_DESC_NUM, &val);
5716*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5717*4882a593Smuzhiyun 		return -1;
5718*4882a593Smuzhiyun 
5719*4882a593Smuzhiyun 	*num = val;
5720*4882a593Smuzhiyun 
5721*4882a593Smuzhiyun 	return 0;
5722*4882a593Smuzhiyun }
5723*4882a593Smuzhiyun 
_usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)5724*4882a593Smuzhiyun static inline enum halmac_usb_mode _usb_mode_drv2halmac(enum RTW_USB_SPEED usb_mode)
5725*4882a593Smuzhiyun {
5726*4882a593Smuzhiyun 	enum halmac_usb_mode halmac_usb_mode = HALMAC_USB_MODE_U2;
5727*4882a593Smuzhiyun 
5728*4882a593Smuzhiyun 	switch (usb_mode) {
5729*4882a593Smuzhiyun 	case RTW_USB_SPEED_2:
5730*4882a593Smuzhiyun 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5731*4882a593Smuzhiyun 		break;
5732*4882a593Smuzhiyun 	case RTW_USB_SPEED_3:
5733*4882a593Smuzhiyun 		halmac_usb_mode = HALMAC_USB_MODE_U3;
5734*4882a593Smuzhiyun 		break;
5735*4882a593Smuzhiyun 	default:
5736*4882a593Smuzhiyun 		halmac_usb_mode = HALMAC_USB_MODE_U2;
5737*4882a593Smuzhiyun 		break;
5738*4882a593Smuzhiyun 	}
5739*4882a593Smuzhiyun 
5740*4882a593Smuzhiyun 	return halmac_usb_mode;
5741*4882a593Smuzhiyun }
5742*4882a593Smuzhiyun 
rtw_halmac_switch_usb_mode(struct dvobj_priv * d,enum RTW_USB_SPEED usb_mode)5743*4882a593Smuzhiyun u8 rtw_halmac_switch_usb_mode(struct dvobj_priv *d, enum RTW_USB_SPEED usb_mode)
5744*4882a593Smuzhiyun {
5745*4882a593Smuzhiyun 	PADAPTER adapter;
5746*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5747*4882a593Smuzhiyun 	struct halmac_api *api;
5748*4882a593Smuzhiyun 	enum halmac_ret_status status;
5749*4882a593Smuzhiyun 	enum halmac_usb_mode halmac_usb_mode;
5750*4882a593Smuzhiyun 
5751*4882a593Smuzhiyun 	adapter = dvobj_get_primary_adapter(d);
5752*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5753*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5754*4882a593Smuzhiyun 	halmac_usb_mode = _usb_mode_drv2halmac(usb_mode);
5755*4882a593Smuzhiyun 	status = api->halmac_set_hw_value(mac, HALMAC_HW_USB_MODE, (void *)&halmac_usb_mode);
5756*4882a593Smuzhiyun 
5757*4882a593Smuzhiyun 	if (HALMAC_RET_SUCCESS != status)
5758*4882a593Smuzhiyun 		return _FAIL;
5759*4882a593Smuzhiyun 
5760*4882a593Smuzhiyun 	return _SUCCESS;
5761*4882a593Smuzhiyun }
5762*4882a593Smuzhiyun #endif /* CONFIG_USB_HCI */
5763*4882a593Smuzhiyun 
5764*4882a593Smuzhiyun #ifdef CONFIG_BEAMFORMING
5765*4882a593Smuzhiyun #ifdef RTW_BEAMFORMING_VERSION_2
rtw_halmac_bf_add_mu_bfer(struct dvobj_priv * d,u16 paid,u16 csi_para,u16 my_aid,enum halmac_csi_seg_len sel,u8 * addr)5766*4882a593Smuzhiyun int rtw_halmac_bf_add_mu_bfer(struct dvobj_priv *d, u16 paid, u16 csi_para,
5767*4882a593Smuzhiyun 		u16 my_aid, enum halmac_csi_seg_len sel, u8 *addr)
5768*4882a593Smuzhiyun {
5769*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5770*4882a593Smuzhiyun 	struct halmac_api *api;
5771*4882a593Smuzhiyun 	enum halmac_ret_status status;
5772*4882a593Smuzhiyun 	struct halmac_mu_bfer_init_para param;
5773*4882a593Smuzhiyun 
5774*4882a593Smuzhiyun 
5775*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5776*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5777*4882a593Smuzhiyun 
5778*4882a593Smuzhiyun 	_rtw_memset(&param, 0, sizeof(param));
5779*4882a593Smuzhiyun 	param.paid = paid;
5780*4882a593Smuzhiyun 	param.csi_para = csi_para;
5781*4882a593Smuzhiyun 	param.my_aid = my_aid;
5782*4882a593Smuzhiyun 	param.csi_length_sel = sel;
5783*4882a593Smuzhiyun 	_rtw_memcpy(param.bfer_address.addr, addr, 6);
5784*4882a593Smuzhiyun 
5785*4882a593Smuzhiyun 	status = api->halmac_mu_bfer_entry_init(mac, &param);
5786*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5787*4882a593Smuzhiyun 		return -1;
5788*4882a593Smuzhiyun 
5789*4882a593Smuzhiyun 	return 0;
5790*4882a593Smuzhiyun }
5791*4882a593Smuzhiyun 
rtw_halmac_bf_del_mu_bfer(struct dvobj_priv * d)5792*4882a593Smuzhiyun int rtw_halmac_bf_del_mu_bfer(struct dvobj_priv *d)
5793*4882a593Smuzhiyun {
5794*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5795*4882a593Smuzhiyun 	struct halmac_api *api;
5796*4882a593Smuzhiyun 	enum halmac_ret_status status;
5797*4882a593Smuzhiyun 
5798*4882a593Smuzhiyun 
5799*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5800*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5801*4882a593Smuzhiyun 
5802*4882a593Smuzhiyun 	status = api->halmac_mu_bfer_entry_del(mac);
5803*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5804*4882a593Smuzhiyun 		return -1;
5805*4882a593Smuzhiyun 
5806*4882a593Smuzhiyun 	return 0;
5807*4882a593Smuzhiyun }
5808*4882a593Smuzhiyun 
5809*4882a593Smuzhiyun 
rtw_halmac_bf_cfg_sounding(struct dvobj_priv * d,enum halmac_snd_role role,enum halmac_data_rate rate)5810*4882a593Smuzhiyun int rtw_halmac_bf_cfg_sounding(struct dvobj_priv *d,
5811*4882a593Smuzhiyun 		enum halmac_snd_role role, enum halmac_data_rate rate)
5812*4882a593Smuzhiyun {
5813*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5814*4882a593Smuzhiyun 	struct halmac_api *api;
5815*4882a593Smuzhiyun 	enum halmac_ret_status status;
5816*4882a593Smuzhiyun 
5817*4882a593Smuzhiyun 
5818*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5819*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5820*4882a593Smuzhiyun 
5821*4882a593Smuzhiyun 	status = api->halmac_cfg_sounding(mac, role, rate);
5822*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5823*4882a593Smuzhiyun 		return -1;
5824*4882a593Smuzhiyun 
5825*4882a593Smuzhiyun 	return 0;
5826*4882a593Smuzhiyun }
5827*4882a593Smuzhiyun 
rtw_halmac_bf_del_sounding(struct dvobj_priv * d,enum halmac_snd_role role)5828*4882a593Smuzhiyun int rtw_halmac_bf_del_sounding(struct dvobj_priv *d,
5829*4882a593Smuzhiyun 		enum halmac_snd_role role)
5830*4882a593Smuzhiyun {
5831*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5832*4882a593Smuzhiyun 	struct halmac_api *api;
5833*4882a593Smuzhiyun 	enum halmac_ret_status status;
5834*4882a593Smuzhiyun 
5835*4882a593Smuzhiyun 
5836*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5837*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5838*4882a593Smuzhiyun 
5839*4882a593Smuzhiyun 	status = api->halmac_del_sounding(mac, role);
5840*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5841*4882a593Smuzhiyun 		return -1;
5842*4882a593Smuzhiyun 
5843*4882a593Smuzhiyun 	return 0;
5844*4882a593Smuzhiyun }
5845*4882a593Smuzhiyun 
5846*4882a593Smuzhiyun /**
5847*4882a593Smuzhiyun  * rtw_halmac_bf_cfg_csi_rate() - Config data rate for CSI report frame by RSSI
5848*4882a593Smuzhiyun  * @d:		struct dvobj_priv*
5849*4882a593Smuzhiyun  * @rssi:	RSSI vlaue, unit is percentage (0~100).
5850*4882a593Smuzhiyun  * @current_rate:	Current CSI frame rate
5851*4882a593Smuzhiyun  *			Valid value example
5852*4882a593Smuzhiyun  *			0	CCK 1M
5853*4882a593Smuzhiyun  *			3	CCK 11M
5854*4882a593Smuzhiyun  *			4	OFDM 6M
5855*4882a593Smuzhiyun  *			and so on
5856*4882a593Smuzhiyun  * @fixrate_en:	Enable to fix CSI frame in VHT rate, otherwise legacy OFDM rate.
5857*4882a593Smuzhiyun  *		The value "0" for disable, otheriwse enable.
5858*4882a593Smuzhiyun  * @new_rate:	Return new data rate, and value range is the same as
5859*4882a593Smuzhiyun  *		current_rate
5860*4882a593Smuzhiyun  * @bmp_ofdm54: Return to suggest enabling OFDM 54M for CSI report frame or not,
5861*4882a593Smuzhiyun  *		The valid values and meanings are:
5862*4882a593Smuzhiyun  *		0x00	disable
5863*4882a593Smuzhiyun  *		0x01	enable
5864*4882a593Smuzhiyun  *		0xFF	Keep current setting
5865*4882a593Smuzhiyun  *
5866*4882a593Smuzhiyun  * According RSSI to config data rate for CSI report frame of Beamforming.
5867*4882a593Smuzhiyun  *
5868*4882a593Smuzhiyun  * Return 0 for OK, otherwise fail.
5869*4882a593Smuzhiyun  */
rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv * d,u8 rssi,u8 current_rate,u8 fixrate_en,u8 * new_rate,u8 * bmp_ofdm54)5870*4882a593Smuzhiyun int rtw_halmac_bf_cfg_csi_rate(struct dvobj_priv *d, u8 rssi,
5871*4882a593Smuzhiyun 			       u8 current_rate, u8 fixrate_en, u8 *new_rate,
5872*4882a593Smuzhiyun 			       u8 *bmp_ofdm54)
5873*4882a593Smuzhiyun {
5874*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5875*4882a593Smuzhiyun 	struct halmac_api *api;
5876*4882a593Smuzhiyun 	enum halmac_ret_status status;
5877*4882a593Smuzhiyun 
5878*4882a593Smuzhiyun 
5879*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5880*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5881*4882a593Smuzhiyun 
5882*4882a593Smuzhiyun 	status = api->halmac_cfg_csi_rate(mac,
5883*4882a593Smuzhiyun 			rssi, current_rate, fixrate_en, new_rate,
5884*4882a593Smuzhiyun 			bmp_ofdm54);
5885*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5886*4882a593Smuzhiyun 		return -1;
5887*4882a593Smuzhiyun 
5888*4882a593Smuzhiyun 	return 0;
5889*4882a593Smuzhiyun }
5890*4882a593Smuzhiyun 
rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv * d,enum halmac_snd_role role,u8 * sounding_sts,u16 grouping_bitmap,u8 mu_tx_en,u32 * given_gid_tab,u32 * given_user_pos)5891*4882a593Smuzhiyun int rtw_halmac_bf_cfg_mu_mimo(struct dvobj_priv *d, enum halmac_snd_role role,
5892*4882a593Smuzhiyun 		u8 *sounding_sts, u16 grouping_bitmap, u8 mu_tx_en,
5893*4882a593Smuzhiyun 		u32 *given_gid_tab, u32 *given_user_pos)
5894*4882a593Smuzhiyun {
5895*4882a593Smuzhiyun 	struct halmac_adapter *mac;
5896*4882a593Smuzhiyun 	struct halmac_api *api;
5897*4882a593Smuzhiyun 	enum halmac_ret_status status;
5898*4882a593Smuzhiyun 	struct halmac_cfg_mumimo_para param;
5899*4882a593Smuzhiyun 
5900*4882a593Smuzhiyun 
5901*4882a593Smuzhiyun 	mac = dvobj_to_halmac(d);
5902*4882a593Smuzhiyun 	api = HALMAC_GET_API(mac);
5903*4882a593Smuzhiyun 
5904*4882a593Smuzhiyun 	_rtw_memset(&param, 0, sizeof(param));
5905*4882a593Smuzhiyun 
5906*4882a593Smuzhiyun 	param.role = role;
5907*4882a593Smuzhiyun 	param.grouping_bitmap = grouping_bitmap;
5908*4882a593Smuzhiyun 	param.mu_tx_en = mu_tx_en;
5909*4882a593Smuzhiyun 
5910*4882a593Smuzhiyun 	if (sounding_sts)
5911*4882a593Smuzhiyun 		_rtw_memcpy(param.sounding_sts, sounding_sts, 6);
5912*4882a593Smuzhiyun 
5913*4882a593Smuzhiyun 	if (given_gid_tab)
5914*4882a593Smuzhiyun 		_rtw_memcpy(param.given_gid_tab, given_gid_tab, 8);
5915*4882a593Smuzhiyun 
5916*4882a593Smuzhiyun 	if (given_user_pos)
5917*4882a593Smuzhiyun 		_rtw_memcpy(param.given_user_pos, given_user_pos, 16);
5918*4882a593Smuzhiyun 
5919*4882a593Smuzhiyun 	status = api->halmac_cfg_mumimo(mac, &param);
5920*4882a593Smuzhiyun 	if (status != HALMAC_RET_SUCCESS)
5921*4882a593Smuzhiyun 		return -1;
5922*4882a593Smuzhiyun 
5923*4882a593Smuzhiyun 	return 0;
5924*4882a593Smuzhiyun }
5925*4882a593Smuzhiyun 
5926*4882a593Smuzhiyun #endif /* RTW_BEAMFORMING_VERSION_2 */
5927*4882a593Smuzhiyun #endif /* CONFIG_BEAMFORMING */
5928