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