wifi: renew patch drivers/net/wireless
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / 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         if(_read_port_cancel)
320                 _read_port_cancel(pintfhdl);
321
322 }
323
324 u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
325 {
326         u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
327         //struct        io_queue        *pio_queue = (struct io_queue *)adapter->pio_queue;
328         struct io_priv *pio_priv = &adapter->iopriv;
329         struct  intf_hdl                *pintfhdl = &(pio_priv->intf);
330         u32 ret = _SUCCESS;
331
332         _func_enter_;
333
334         _write_port = pintfhdl->io_ops._write_port;
335         
336         ret = _write_port(pintfhdl, addr, cnt, pmem);
337
338          _func_exit_;
339
340         return ret;
341 }
342
343 u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
344 {
345         int ret = _SUCCESS;
346         struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
347         struct submit_ctx sctx;
348
349         rtw_sctx_init(&sctx, timeout_ms);
350         pxmitbuf->sctx = &sctx;
351
352         ret = _rtw_write_port(adapter, addr, cnt, pmem);
353
354         if (ret == _SUCCESS)
355                 ret = rtw_sctx_wait(&sctx, __func__);
356
357          return ret;
358 }
359
360 void _rtw_write_port_cancel(_adapter *adapter)
361 {
362         void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
363         struct io_priv *pio_priv = &adapter->iopriv;
364         struct intf_hdl *pintfhdl = &(pio_priv->intf);
365
366         _write_port_cancel = pintfhdl->io_ops._write_port_cancel;
367
368         if(_write_port_cancel)
369                 _write_port_cancel(pintfhdl);
370
371 }
372 int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter,struct _io_ops *pops))
373 {
374         struct io_priv  *piopriv = &padapter->iopriv;
375         struct intf_hdl *pintf = &piopriv->intf;
376
377         if (set_intf_ops == NULL)
378                 return _FAIL;
379
380         piopriv->padapter = padapter;
381         pintf->padapter = padapter;
382         pintf->pintf_dev = adapter_to_dvobj(padapter);
383                 
384         set_intf_ops(padapter,&pintf->io_ops);  
385
386         return _SUCCESS;
387 }
388
389 /*
390 * Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
391 * @return _TRUE:
392 * @return _FALSE:
393 */
394 int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
395 {
396         int ret = _FALSE;
397         int value;
398         if( (value=ATOMIC_INC_RETURN(&dvobj->continual_io_error)) > MAX_CONTINUAL_IO_ERR) {
399                 DBG_871X("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR);
400                 ret = _TRUE;
401         } else {
402                 //DBG_871X("[dvobj:%p] continual_io_error:%d\n", dvobj, value);
403         }
404         return ret;
405 }
406
407 /*
408 * Set the continual_io_error of this @param dvobjprive to 0
409 */
410 void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
411 {
412         ATOMIC_SET(&dvobj->continual_io_error, 0);      
413 }
414
415 #ifdef DBG_IO
416
417 u16 read_sniff_ranges[][2] = {
418         //{0x520, 0x523},
419 }; 
420
421 u16 write_sniff_ranges[][2] = {
422         //{0x520, 0x523},
423         //{0x4c, 0x4c},
424 }; 
425
426 int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u16)/2;
427 int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u16)/2;
428
429 bool match_read_sniff_ranges(u16 addr, u16 len)
430 {
431         int i;
432         for (i = 0; i<read_sniff_num; i++) {
433                 if (addr + len > read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1])
434                         return _TRUE;
435         }
436         
437         return _FALSE;
438 }
439
440 bool match_write_sniff_ranges(u16 addr, u16 len)
441 {
442         int i;
443         for (i = 0; i<write_sniff_num; i++) {
444                 if (addr + len > write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1])
445                         return _TRUE;
446         }
447         
448         return _FALSE;
449 }
450
451 u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
452 {
453         u8 val = _rtw_read8(adapter, addr);
454
455         if (match_read_sniff_ranges(addr, 1))
456                 DBG_871X("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val);
457
458         return val;
459 }
460
461 u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
462 {
463         u16 val = _rtw_read16(adapter, addr);
464         
465         if (match_read_sniff_ranges(addr, 2))
466                 DBG_871X("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val);
467
468         return val;
469 }
470
471 u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
472 {
473         u32 val = _rtw_read32(adapter, addr);
474         
475         if (match_read_sniff_ranges(addr, 4))
476                 DBG_871X("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val);
477
478         return val;
479 }
480
481 int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
482 {
483         if (match_write_sniff_ranges(addr, 1))
484                 DBG_871X("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val);
485         
486         return _rtw_write8(adapter, addr, val);
487 }
488 int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
489 {
490         if (match_write_sniff_ranges(addr, 2))
491                 DBG_871X("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val);
492         
493         return _rtw_write16(adapter, addr, val);
494 }
495 int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
496 {
497         if (match_write_sniff_ranges(addr, 4))
498                 DBG_871X("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val);
499         
500         return _rtw_write32(adapter, addr, val);
501 }
502 int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line)
503 {
504         if (match_write_sniff_ranges(addr, length))
505                 DBG_871X("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length);
506
507         return _rtw_writeN(adapter, addr, length, data);
508 }
509 #endif
510
511