e4c0245769797f3073ee85c848a2e3ee0d659bd9
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bs / 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
31 Compiler Flag Option:
32
33 1. CONFIG_SDIO_HCI:
34     a. USE_SYNC_IRP:  Only sync operations are provided.
35     b. USE_ASYNC_IRP:Both sync/async operations are provided.
36
37 2. CONFIG_USB_HCI:
38    a. USE_ASYNC_IRP: Both sync/async operations are provided.
39
40 3. CONFIG_CFIO_HCI:
41    b. USE_SYNC_IRP: Only sync operations are provided.
42
43
44 Only sync read/rtw_write_mem operations are provided.
45
46 jackson@realtek.com.tw
47
48 */
49
50 #define _RTW_IO_C_
51
52 #include <drv_types.h>
53
54 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
55 #error "Shall be Linux or Windows, but not both!\n"
56 #endif
57
58 #ifdef CONFIG_SDIO_HCI
59 #define rtw_le16_to_cpu(val)            val
60 #define rtw_le32_to_cpu(val)            val
61 #define rtw_cpu_to_le16(val)            val
62 #define rtw_cpu_to_le32(val)            val
63 #else
64 #define rtw_le16_to_cpu(val)            le16_to_cpu(val)
65 #define rtw_le32_to_cpu(val)            le32_to_cpu(val)
66 #define rtw_cpu_to_le16(val)            cpu_to_le16(val)
67 #define rtw_cpu_to_le32(val)            cpu_to_le32(val)
68 #endif
69
70
71 u8 _rtw_read8(_adapter *adapter, u32 addr)
72 {
73         u8 r_val;
74         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
75         struct io_priv *pio_priv = &adapter->iopriv;
76         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
77         u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
78         _func_enter_;
79         _read8 = pintfhdl->io_ops._read8;
80
81         r_val = _read8(pintfhdl, addr);
82         _func_exit_;
83         return r_val;
84 }
85
86 u16 _rtw_read16(_adapter *adapter, u32 addr)
87 {
88         u16 r_val;
89         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
90         struct io_priv *pio_priv = &adapter->iopriv;
91         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
92         u16     (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
93         _func_enter_;
94         _read16 = pintfhdl->io_ops._read16;
95
96         r_val = _read16(pintfhdl, addr);
97         _func_exit_;
98         return rtw_le16_to_cpu(r_val);
99 }
100
101 u32 _rtw_read32(_adapter *adapter, u32 addr)
102 {
103         u32 r_val;
104         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
105         struct io_priv *pio_priv = &adapter->iopriv;
106         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
107         u32     (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
108         _func_enter_;
109         _read32 = pintfhdl->io_ops._read32;
110
111         r_val = _read32(pintfhdl, addr);
112         _func_exit_;
113         return rtw_le32_to_cpu(r_val);
114
115 }
116
117 int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
118 {
119         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
120         struct io_priv *pio_priv = &adapter->iopriv;
121         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
122         int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
123         int ret;
124         _func_enter_;
125         _write8 = pintfhdl->io_ops._write8;
126
127         ret = _write8(pintfhdl, addr, val);
128         _func_exit_;
129         
130         return RTW_STATUS_CODE(ret);
131 }
132 int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
133 {
134         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
135         struct io_priv *pio_priv = &adapter->iopriv;
136         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
137         int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
138         int ret;
139         _func_enter_;
140         _write16 = pintfhdl->io_ops._write16;
141
142         val = rtw_cpu_to_le16(val);
143         ret = _write16(pintfhdl, addr, val);
144         _func_exit_;
145
146         return RTW_STATUS_CODE(ret);
147 }
148 int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
149 {
150         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
151         struct io_priv *pio_priv = &adapter->iopriv;
152         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
153         int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
154         int ret;
155         _func_enter_;
156         _write32 = pintfhdl->io_ops._write32;
157         
158         val = rtw_cpu_to_le32(val);
159         ret = _write32(pintfhdl, addr, val);
160         _func_exit_;
161
162         return RTW_STATUS_CODE(ret);
163 }
164
165 int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata)
166 {
167         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
168         struct io_priv *pio_priv = &adapter->iopriv;
169         struct  intf_hdl        *pintfhdl = (struct intf_hdl*)(&(pio_priv->intf));
170         int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata);
171         int ret;
172         _func_enter_;
173         _writeN = pintfhdl->io_ops._writeN;
174
175         ret = _writeN(pintfhdl, addr,length,pdata);
176         _func_exit_;
177
178         return RTW_STATUS_CODE(ret);
179 }
180
181 #ifdef CONFIG_SDIO_HCI
182 u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr)
183 {
184         u8 r_val = 0x00;
185         struct io_priv *pio_priv = &adapter->iopriv;
186         struct intf_hdl *pintfhdl = &(pio_priv->intf);
187         u8 (*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr);
188
189         _func_enter_;
190         _sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8;
191
192         if (_sd_f0_read8)
193                 r_val = _sd_f0_read8(pintfhdl, addr);
194         else
195                 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
196
197         _func_exit_;
198         return r_val;
199 }
200 #endif /* CONFIG_SDIO_HCI */
201
202 int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
203 {
204         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
205         struct io_priv *pio_priv = &adapter->iopriv;
206         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
207         int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
208         int ret;
209         _func_enter_;
210         _write8_async = pintfhdl->io_ops._write8_async;
211
212         ret = _write8_async(pintfhdl, addr, val);
213         _func_exit_;
214
215         return RTW_STATUS_CODE(ret);
216 }
217 int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
218 {
219         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
220         struct io_priv *pio_priv = &adapter->iopriv;
221         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
222         int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
223         int ret;
224         _func_enter_;
225         _write16_async = pintfhdl->io_ops._write16_async;
226         val = rtw_cpu_to_le16(val);
227         ret = _write16_async(pintfhdl, addr, val);
228         _func_exit_;
229
230         return RTW_STATUS_CODE(ret);
231 }
232 int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
233 {
234         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
235         struct io_priv *pio_priv = &adapter->iopriv;
236         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
237         int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
238         int ret;
239         _func_enter_;
240         _write32_async = pintfhdl->io_ops._write32_async;
241         val = rtw_cpu_to_le32(val);
242         ret = _write32_async(pintfhdl, addr, val);
243         _func_exit_;
244
245         return RTW_STATUS_CODE(ret);
246 }
247
248 void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
249 {
250         void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
251         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
252         struct io_priv *pio_priv = &adapter->iopriv;
253         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
254
255         _func_enter_;
256
257         if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
258         {
259              RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));          
260              return;
261         }
262
263         _read_mem = pintfhdl->io_ops._read_mem;
264
265         _read_mem(pintfhdl, addr, cnt, pmem);
266
267         _func_exit_;
268
269 }
270
271 void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
272 {
273         void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
274         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
275         struct io_priv *pio_priv = &adapter->iopriv;
276         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
277
278         _func_enter_;
279
280         _write_mem = pintfhdl->io_ops._write_mem;
281
282         _write_mem(pintfhdl, addr, cnt, pmem);
283
284         _func_exit_;
285
286 }
287
288 void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
289 {
290         u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
291         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
292         struct io_priv *pio_priv = &adapter->iopriv;
293         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
294
295         _func_enter_;
296
297         if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
298         {
299              RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));         
300              return;
301         }
302
303         _read_port = pintfhdl->io_ops._read_port;
304
305         _read_port(pintfhdl, addr, cnt, pmem);
306
307         _func_exit_;
308
309 }
310
311 void _rtw_read_port_cancel(_adapter *adapter)
312 {
313         void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
314         struct io_priv *pio_priv = &adapter->iopriv;
315         struct intf_hdl *pintfhdl = &(pio_priv->intf);
316
317         _read_port_cancel = pintfhdl->io_ops._read_port_cancel;
318
319         RTW_DISABLE_FUNC(adapter, DF_RX_BIT);
320
321         if(_read_port_cancel)
322                 _read_port_cancel(pintfhdl);
323 }
324
325 u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
326 {
327         u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
328         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
329         struct io_priv *pio_priv = &adapter->iopriv;
330         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
331         u32 ret = _SUCCESS;
332
333         _func_enter_;
334
335         _write_port = pintfhdl->io_ops._write_port;
336         
337         ret = _write_port(pintfhdl, addr, cnt, pmem);
338
339          _func_exit_;
340
341         return ret;
342 }
343
344 u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
345 {
346         int ret = _SUCCESS;
347         struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
348         struct submit_ctx sctx;
349
350         rtw_sctx_init(&sctx, timeout_ms);
351         pxmitbuf->sctx = &sctx;
352
353         ret = _rtw_write_port(adapter, addr, cnt, pmem);
354
355         if (ret == _SUCCESS)
356                 ret = rtw_sctx_wait(&sctx, __func__);
357
358          return ret;
359 }
360
361 void _rtw_write_port_cancel(_adapter *adapter)
362 {
363         void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
364         struct io_priv *pio_priv = &adapter->iopriv;
365         struct intf_hdl *pintfhdl = &(pio_priv->intf);
366
367         _write_port_cancel = pintfhdl->io_ops._write_port_cancel;
368
369         RTW_DISABLE_FUNC(adapter, DF_TX_BIT);
370
371         if(_write_port_cancel)
372                 _write_port_cancel(pintfhdl);
373 }
374 int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter,struct _io_ops *pops))
375 {
376         struct io_priv  *piopriv = &padapter->iopriv;
377         struct intf_hdl *pintf = &piopriv->intf;
378
379         if (set_intf_ops == NULL)
380                 return _FAIL;
381
382         piopriv->padapter = padapter;
383         pintf->padapter = padapter;
384         pintf->pintf_dev = adapter_to_dvobj(padapter);
385                 
386         set_intf_ops(padapter,&pintf->io_ops);  
387
388         return _SUCCESS;
389 }
390
391 /*
392 * Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
393 * @return _TRUE:
394 * @return _FALSE:
395 */
396 int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
397 {
398         int ret = _FALSE;
399         int value;
400         if( (value=ATOMIC_INC_RETURN(&dvobj->continual_io_error)) > MAX_CONTINUAL_IO_ERR) {
401                 DBG_871X("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR);
402                 ret = _TRUE;
403         } else {
404                 //DBG_871X("[dvobj:%p] continual_io_error:%d\n", dvobj, value);
405         }
406         return ret;
407 }
408
409 /*
410 * Set the continual_io_error of this @param dvobjprive to 0
411 */
412 void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
413 {
414         ATOMIC_SET(&dvobj->continual_io_error, 0);      
415 }
416
417 #ifdef DBG_IO
418
419 u16 read_sniff_ranges[][2] = {
420         //{0x520, 0x523},
421 }; 
422
423 u16 write_sniff_ranges[][2] = {
424         //{0x520, 0x523},
425         //{0x4c, 0x4c},
426 }; 
427
428 int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u16)/2;
429 int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u16)/2;
430
431 bool match_read_sniff_ranges(u16 addr, u16 len)
432 {
433         int i;
434         for (i = 0; i<read_sniff_num; i++) {
435                 if (addr + len > read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1])
436                         return _TRUE;
437         }
438         
439         return _FALSE;
440 }
441
442 bool match_write_sniff_ranges(u16 addr, u16 len)
443 {
444         int i;
445         for (i = 0; i<write_sniff_num; i++) {
446                 if (addr + len > write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1])
447                         return _TRUE;
448         }
449         
450         return _FALSE;
451 }
452
453 u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
454 {
455         u8 val = _rtw_read8(adapter, addr);
456
457         if (match_read_sniff_ranges(addr, 1))
458                 DBG_871X("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val);
459
460         return val;
461 }
462
463 u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
464 {
465         u16 val = _rtw_read16(adapter, addr);
466         
467         if (match_read_sniff_ranges(addr, 2))
468                 DBG_871X("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val);
469
470         return val;
471 }
472
473 u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
474 {
475         u32 val = _rtw_read32(adapter, addr);
476         
477         if (match_read_sniff_ranges(addr, 4))
478                 DBG_871X("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val);
479
480         return val;
481 }
482
483 int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
484 {
485         if (match_write_sniff_ranges(addr, 1))
486                 DBG_871X("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val);
487         
488         return _rtw_write8(adapter, addr, val);
489 }
490 int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
491 {
492         if (match_write_sniff_ranges(addr, 2))
493                 DBG_871X("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val);
494         
495         return _rtw_write16(adapter, addr, val);
496 }
497 int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
498 {
499         if (match_write_sniff_ranges(addr, 4))
500                 DBG_871X("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val);
501         
502         return _rtw_write32(adapter, addr, val);
503 }
504 int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line)
505 {
506         if (match_write_sniff_ranges(addr, length))
507                 DBG_871X("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length);
508
509         return _rtw_writeN(adapter, addr, length, data);
510 }
511 #endif
512
513