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