1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
22 The purpose of rtw_io.c
26 b. provides the protocol engine
28 c. provides the software interface between caller and the hardware interface
34 a. USE_SYNC_IRP: Only sync operations are provided.
35 b. USE_ASYNC_IRP:Both sync/async operations are provided.
38 a. USE_ASYNC_IRP: Both sync/async operations are provided.
41 b. USE_SYNC_IRP: Only sync operations are provided.
44 Only sync read/rtw_write_mem operations are provided.
46 jackson@realtek.com.tw
52 #include <drv_types.h>
54 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
55 #error "Shall be Linux or Windows, but not both!\n"
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
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)
71 u8 _rtw_read8(_adapter *adapter, u32 addr)
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);
79 _read8 = pintfhdl->io_ops._read8;
81 r_val = _read8(pintfhdl, addr);
86 u16 _rtw_read16(_adapter *adapter, u32 addr)
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);
94 _read16 = pintfhdl->io_ops._read16;
96 r_val = _read16(pintfhdl, addr);
98 return rtw_le16_to_cpu(r_val);
101 u32 _rtw_read32(_adapter *adapter, u32 addr)
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);
109 _read32 = pintfhdl->io_ops._read32;
111 r_val = _read32(pintfhdl, addr);
113 return rtw_le32_to_cpu(r_val);
117 int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
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);
125 _write8 = pintfhdl->io_ops._write8;
127 ret = _write8(pintfhdl, addr, val);
130 return RTW_STATUS_CODE(ret);
132 int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
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);
140 _write16 = pintfhdl->io_ops._write16;
142 val = rtw_cpu_to_le16(val);
143 ret = _write16(pintfhdl, addr, val);
146 return RTW_STATUS_CODE(ret);
148 int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
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);
156 _write32 = pintfhdl->io_ops._write32;
158 val = rtw_cpu_to_le32(val);
159 ret = _write32(pintfhdl, addr, val);
162 return RTW_STATUS_CODE(ret);
165 int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata)
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);
173 _writeN = pintfhdl->io_ops._writeN;
175 ret = _writeN(pintfhdl, addr,length,pdata);
178 return RTW_STATUS_CODE(ret);
181 #ifdef CONFIG_SDIO_HCI
182 u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr)
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);
190 _sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8;
193 r_val = _sd_f0_read8(pintfhdl, addr);
195 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
200 #endif /* CONFIG_SDIO_HCI */
202 int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
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);
210 _write8_async = pintfhdl->io_ops._write8_async;
212 ret = _write8_async(pintfhdl, addr, val);
215 return RTW_STATUS_CODE(ret);
217 int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
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);
225 _write16_async = pintfhdl->io_ops._write16_async;
226 val = rtw_cpu_to_le16(val);
227 ret = _write16_async(pintfhdl, addr, val);
230 return RTW_STATUS_CODE(ret);
232 int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
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);
240 _write32_async = pintfhdl->io_ops._write32_async;
241 val = rtw_cpu_to_le32(val);
242 ret = _write32_async(pintfhdl, addr, val);
245 return RTW_STATUS_CODE(ret);
248 void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
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);
257 if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
259 RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
263 _read_mem = pintfhdl->io_ops._read_mem;
265 _read_mem(pintfhdl, addr, cnt, pmem);
271 void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
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);
280 _write_mem = pintfhdl->io_ops._write_mem;
282 _write_mem(pintfhdl, addr, cnt, pmem);
288 void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
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);
297 if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
299 RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
303 _read_port = pintfhdl->io_ops._read_port;
305 _read_port(pintfhdl, addr, cnt, pmem);
311 void _rtw_read_port_cancel(_adapter *adapter)
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);
317 _read_port_cancel = pintfhdl->io_ops._read_port_cancel;
319 RTW_DISABLE_FUNC(adapter, DF_RX_BIT);
321 if(_read_port_cancel)
322 _read_port_cancel(pintfhdl);
325 u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
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);
335 _write_port = pintfhdl->io_ops._write_port;
337 ret = _write_port(pintfhdl, addr, cnt, pmem);
344 u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
347 struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
348 struct submit_ctx sctx;
350 rtw_sctx_init(&sctx, timeout_ms);
351 pxmitbuf->sctx = &sctx;
353 ret = _rtw_write_port(adapter, addr, cnt, pmem);
356 ret = rtw_sctx_wait(&sctx, __func__);
361 void _rtw_write_port_cancel(_adapter *adapter)
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);
367 _write_port_cancel = pintfhdl->io_ops._write_port_cancel;
369 RTW_DISABLE_FUNC(adapter, DF_TX_BIT);
371 if(_write_port_cancel)
372 _write_port_cancel(pintfhdl);
374 int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter,struct _io_ops *pops))
376 struct io_priv *piopriv = &padapter->iopriv;
377 struct intf_hdl *pintf = &piopriv->intf;
379 if (set_intf_ops == NULL)
382 piopriv->padapter = padapter;
383 pintf->padapter = padapter;
384 pintf->pintf_dev = adapter_to_dvobj(padapter);
386 set_intf_ops(padapter,&pintf->io_ops);
392 * Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
396 int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
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);
404 //DBG_871X("[dvobj:%p] continual_io_error:%d\n", dvobj, value);
410 * Set the continual_io_error of this @param dvobjprive to 0
412 void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
414 ATOMIC_SET(&dvobj->continual_io_error, 0);
419 u16 read_sniff_ranges[][2] = {
423 u16 write_sniff_ranges[][2] = {
428 int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u16)/2;
429 int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u16)/2;
431 bool match_read_sniff_ranges(u16 addr, u16 len)
434 for (i = 0; i<read_sniff_num; i++) {
435 if (addr + len > read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1])
442 bool match_write_sniff_ranges(u16 addr, u16 len)
445 for (i = 0; i<write_sniff_num; i++) {
446 if (addr + len > write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1])
453 u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
455 u8 val = _rtw_read8(adapter, addr);
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);
463 u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
465 u16 val = _rtw_read16(adapter, addr);
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);
473 u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
475 u32 val = _rtw_read32(adapter, addr);
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);
483 int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
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);
488 return _rtw_write8(adapter, addr, val);
490 int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
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);
495 return _rtw_write16(adapter, addr, val);
497 int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
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);
502 return _rtw_write32(adapter, addr, val);
504 int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line)
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);
509 return _rtw_writeN(adapter, addr, length, data);