OSDN Git Service

479d92b82498ec3af5d6179bbd5d921f48037a08
[android-x86/external-modules-rtl8723au.git] / core / rtw_io.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 /*
21
22 The purpose of rtw_io.c
23
24 a. provides the API
25
26 b. provides the protocol engine
27
28 c. provides the software interface between caller and the hardware interface
29
30 Compiler Flag Option:
31
32 2. CONFIG_USB_HCI:
33    a. USE_ASYNC_IRP: Both sync/async operations are provided.
34
35 3. CONFIG_CFIO_HCI:
36    b. USE_SYNC_IRP: Only sync operations are provided.
37
38 Only sync read/rtw_write_mem operations are provided.
39
40 jackson@realtek.com.tw
41
42 */
43
44 #define _RTW_IO_C_
45 #include <drv_conf.h>
46 #include <osdep_service.h>
47 #include <drv_types.h>
48 #include <rtw_io.h>
49 #include <osdep_intf.h>
50
51 #ifdef CONFIG_GSPI_HCI
52 #include <gspi_ops.h>
53 #endif
54
55 #ifdef CONFIG_USB_HCI
56 #include <usb_ops.h>
57 #endif
58
59 #define rtw_le16_to_cpu(val)            le16_to_cpu(val)
60 #define rtw_le32_to_cpu(val)            le32_to_cpu(val)
61 #define rtw_cpu_to_le16(val)            cpu_to_le16(val)
62 #define rtw_cpu_to_le32(val)            cpu_to_le32(val)
63 u8 _rtw_read8(_adapter *adapter, u32 addr)
64 {
65         u8 r_val;
66         struct io_priv *pio_priv = &adapter->iopriv;
67         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
68         u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
69         _func_enter_;
70         _read8 = pintfhdl->io_ops._read8;
71
72         r_val = _read8(pintfhdl, addr);
73         _func_exit_;
74         return r_val;
75 }
76
77 u16 _rtw_read16(_adapter *adapter, u32 addr)
78 {
79         u16 r_val;
80         struct io_priv *pio_priv = &adapter->iopriv;
81         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
82         u16     (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
83         _func_enter_;
84         _read16 = pintfhdl->io_ops._read16;
85
86         r_val = _read16(pintfhdl, addr);
87         _func_exit_;
88         return rtw_le16_to_cpu(r_val);
89 }
90
91 u32 _rtw_read32(_adapter *adapter, u32 addr)
92 {
93         u32 r_val;
94         struct io_priv *pio_priv = &adapter->iopriv;
95         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
96         u32     (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
97         _func_enter_;
98         _read32 = pintfhdl->io_ops._read32;
99
100         r_val = _read32(pintfhdl, addr);
101         _func_exit_;
102         return rtw_le32_to_cpu(r_val);
103 }
104
105 int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
106 {
107         struct io_priv *pio_priv = &adapter->iopriv;
108         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
109         int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
110         int ret;
111         _func_enter_;
112         _write8 = pintfhdl->io_ops._write8;
113
114         ret = _write8(pintfhdl, addr, val);
115         _func_exit_;
116
117         return RTW_STATUS_CODE(ret);
118 }
119 int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
120 {
121         struct io_priv *pio_priv = &adapter->iopriv;
122         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
123         int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
124         int ret;
125         _func_enter_;
126         _write16 = pintfhdl->io_ops._write16;
127
128         val = rtw_cpu_to_le16(val);
129         ret = _write16(pintfhdl, addr, val);
130         _func_exit_;
131
132         return RTW_STATUS_CODE(ret);
133 }
134 int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
135 {
136         struct io_priv *pio_priv = &adapter->iopriv;
137         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
138         int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
139         int ret;
140         _func_enter_;
141         _write32 = pintfhdl->io_ops._write32;
142
143         val = rtw_cpu_to_le32(val);
144         ret = _write32(pintfhdl, addr, val);
145         _func_exit_;
146
147         return RTW_STATUS_CODE(ret);
148 }
149
150 int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata)
151 {
152         struct io_priv *pio_priv = &adapter->iopriv;
153         struct  intf_hdl        *pintfhdl = (struct intf_hdl*)(&(pio_priv->intf));
154         int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata);
155         int ret;
156         _func_enter_;
157         _writeN = pintfhdl->io_ops._writeN;
158
159         ret = _writeN(pintfhdl, addr,length,pdata);
160         _func_exit_;
161
162         return RTW_STATUS_CODE(ret);
163 }
164 int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
165 {
166         struct io_priv *pio_priv = &adapter->iopriv;
167         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
168         int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
169         int ret;
170         _func_enter_;
171         _write8_async = pintfhdl->io_ops._write8_async;
172
173         ret = _write8_async(pintfhdl, addr, val);
174         _func_exit_;
175
176         return RTW_STATUS_CODE(ret);
177 }
178 int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
179 {
180         struct io_priv *pio_priv = &adapter->iopriv;
181         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
182         int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
183         int ret;
184         _func_enter_;
185         _write16_async = pintfhdl->io_ops._write16_async;
186         val = rtw_cpu_to_le16(val);
187         ret = _write16_async(pintfhdl, addr, val);
188         _func_exit_;
189
190         return RTW_STATUS_CODE(ret);
191 }
192 int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
193 {
194         struct io_priv *pio_priv = &adapter->iopriv;
195         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
196         int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
197         int ret;
198         _func_enter_;
199         _write32_async = pintfhdl->io_ops._write32_async;
200         val = rtw_cpu_to_le32(val);
201         ret = _write32_async(pintfhdl, addr, val);
202         _func_exit_;
203
204         return RTW_STATUS_CODE(ret);
205 }
206
207 void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
208 {
209         void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
210         struct io_priv *pio_priv = &adapter->iopriv;
211         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
212
213         _func_enter_;
214
215         if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
216         {
217              RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
218              return;
219         }
220
221         _read_mem = pintfhdl->io_ops._read_mem;
222
223         _read_mem(pintfhdl, addr, cnt, pmem);
224
225         _func_exit_;
226 }
227
228 void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
229 {
230         void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
231         struct io_priv *pio_priv = &adapter->iopriv;
232         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
233
234         _func_enter_;
235
236         _write_mem = pintfhdl->io_ops._write_mem;
237
238         _write_mem(pintfhdl, addr, cnt, pmem);
239
240         _func_exit_;
241 }
242
243 void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
244 {
245         u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
246         struct io_priv *pio_priv = &adapter->iopriv;
247         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
248
249         _func_enter_;
250
251         if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
252         {
253              RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
254              return;
255         }
256
257         _read_port = pintfhdl->io_ops._read_port;
258
259         _read_port(pintfhdl, addr, cnt, pmem);
260
261         _func_exit_;
262 }
263
264 void _rtw_read_port_cancel(_adapter *adapter)
265 {
266         void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
267         struct io_priv *pio_priv = &adapter->iopriv;
268         struct intf_hdl *pintfhdl = &(pio_priv->intf);
269
270         _read_port_cancel = pintfhdl->io_ops._read_port_cancel;
271
272         if(_read_port_cancel)
273                 _read_port_cancel(pintfhdl);
274 }
275
276 u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
277 {
278         u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
279         struct io_priv *pio_priv = &adapter->iopriv;
280         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
281         u32 ret = _SUCCESS;
282
283         _func_enter_;
284
285         _write_port = pintfhdl->io_ops._write_port;
286
287         ret = _write_port(pintfhdl, addr, cnt, pmem);
288
289          _func_exit_;
290
291         return ret;
292 }
293
294 u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
295 {
296         int ret = _SUCCESS;
297         struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
298         struct submit_ctx sctx;
299
300         rtw_sctx_init(&sctx, timeout_ms);
301         pxmitbuf->sctx = &sctx;
302
303         ret = _rtw_write_port(adapter, addr, cnt, pmem);
304
305         if (ret == _SUCCESS)
306                 ret = rtw_sctx_wait(&sctx);
307
308          return ret;
309 }
310
311 void _rtw_write_port_cancel(_adapter *adapter)
312 {
313         void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
314         struct io_priv *pio_priv = &adapter->iopriv;
315         struct intf_hdl *pintfhdl = &(pio_priv->intf);
316
317         _write_port_cancel = pintfhdl->io_ops._write_port_cancel;
318
319         if(_write_port_cancel)
320                 _write_port_cancel(pintfhdl);
321 }
322
323 int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(struct _io_ops *pops))
324 {
325         struct io_priv  *piopriv = &padapter->iopriv;
326         struct intf_hdl *pintf = &piopriv->intf;
327
328         if (set_intf_ops == NULL)
329                 return _FAIL;
330
331         piopriv->padapter = padapter;
332         pintf->padapter = padapter;
333         pintf->pintf_dev = adapter_to_dvobj(padapter);
334
335         set_intf_ops(&pintf->io_ops);
336
337         return _SUCCESS;
338 }
339
340 #ifdef DBG_IO
341
342 u16 read_sniff_ranges[][2] = {
343         /* 0x550, 0x551}, */
344 };
345
346 u16 write_sniff_ranges[][2] = {
347         /* 0x550, 0x551}, */
348         /* 0x4c, 0x4c}, */
349 };
350
351 int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u16)/2;
352 int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u16)/2;
353
354 bool match_read_sniff_ranges(u16 addr, u16 len)
355 {
356         int i;
357         for (i = 0; i<read_sniff_num; i++) {
358                 if (addr + len > read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1])
359                         return _TRUE;
360         }
361
362         return _FALSE;
363 }
364
365 bool match_write_sniff_ranges(u16 addr, u16 len)
366 {
367         int i;
368         for (i = 0; i<write_sniff_num; i++) {
369                 if (addr + len > write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1])
370                         return _TRUE;
371         }
372
373         return _FALSE;
374 }
375
376 u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
377 {
378         u8 val = _rtw_read8(adapter, addr);
379
380         if (match_read_sniff_ranges(addr, 1))
381                 DBG_8723A("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val);
382
383         return val;
384 }
385
386 u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
387 {
388         u16 val = _rtw_read16(adapter, addr);
389
390         if (match_read_sniff_ranges(addr, 2))
391                 DBG_8723A("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val);
392
393         return val;
394 }
395
396 u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
397 {
398         u32 val = _rtw_read32(adapter, addr);
399
400         if (match_read_sniff_ranges(addr, 4))
401                 DBG_8723A("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val);
402
403         return val;
404 }
405
406 int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
407 {
408         if (match_write_sniff_ranges(addr, 1))
409                 DBG_8723A("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val);
410
411         return _rtw_write8(adapter, addr, val);
412 }
413 int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
414 {
415         if (match_write_sniff_ranges(addr, 2))
416                 DBG_8723A("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val);
417
418         return _rtw_write16(adapter, addr, val);
419 }
420 int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
421 {
422         if (match_write_sniff_ranges(addr, 4))
423                 DBG_8723A("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val);
424
425         return _rtw_write32(adapter, addr, val);
426 }
427 int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line)
428 {
429         if (match_write_sniff_ranges(addr, length))
430                 DBG_8723A("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length);
431
432         return _rtw_writeN(adapter, addr, length, data);
433 }
434 #endif