rtw_io.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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. The purpose of rtw_io.c
  22. a. provides the API
  23. b. provides the protocol engine
  24. c. provides the software interface between caller and the hardware interface
  25. Compiler Flag Option:
  26. 1. CONFIG_SDIO_HCI:
  27. a. USE_SYNC_IRP: Only sync operations are provided.
  28. b. USE_ASYNC_IRP:Both sync/async operations are provided.
  29. 2. CONFIG_USB_HCI:
  30. a. USE_ASYNC_IRP: Both sync/async operations are provided.
  31. 3. CONFIG_CFIO_HCI:
  32. b. USE_SYNC_IRP: Only sync operations are provided.
  33. Only sync read/rtw_write_mem operations are provided.
  34. jackson@realtek.com.tw
  35. */
  36. #define _RTW_IO_C_
  37. #include <drv_types.h>
  38. #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
  39. #error "Shall be Linux or Windows, but not both!\n"
  40. #endif
  41. #ifdef CONFIG_SDIO_HCI
  42. #define rtw_le16_to_cpu(val) val
  43. #define rtw_le32_to_cpu(val) val
  44. #define rtw_cpu_to_le16(val) val
  45. #define rtw_cpu_to_le32(val) val
  46. #else
  47. #define rtw_le16_to_cpu(val) le16_to_cpu(val)
  48. #define rtw_le32_to_cpu(val) le32_to_cpu(val)
  49. #define rtw_cpu_to_le16(val) cpu_to_le16(val)
  50. #define rtw_cpu_to_le32(val) cpu_to_le32(val)
  51. #endif
  52. u8 _rtw_read8(_adapter *adapter, u32 addr)
  53. {
  54. u8 r_val;
  55. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  56. struct io_priv *pio_priv = &adapter->iopriv;
  57. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  58. u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr);
  59. _func_enter_;
  60. _read8 = pintfhdl->io_ops._read8;
  61. r_val = _read8(pintfhdl, addr);
  62. _func_exit_;
  63. return r_val;
  64. }
  65. u16 _rtw_read16(_adapter *adapter, u32 addr)
  66. {
  67. u16 r_val;
  68. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  69. struct io_priv *pio_priv = &adapter->iopriv;
  70. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  71. u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr);
  72. _func_enter_;
  73. _read16 = pintfhdl->io_ops._read16;
  74. r_val = _read16(pintfhdl, addr);
  75. _func_exit_;
  76. return rtw_le16_to_cpu(r_val);
  77. }
  78. u32 _rtw_read32(_adapter *adapter, u32 addr)
  79. {
  80. u32 r_val;
  81. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  82. struct io_priv *pio_priv = &adapter->iopriv;
  83. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  84. u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr);
  85. _func_enter_;
  86. _read32 = pintfhdl->io_ops._read32;
  87. r_val = _read32(pintfhdl, addr);
  88. _func_exit_;
  89. return rtw_le32_to_cpu(r_val);
  90. }
  91. int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
  92. {
  93. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  94. struct io_priv *pio_priv = &adapter->iopriv;
  95. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  96. int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
  97. int ret;
  98. _func_enter_;
  99. _write8 = pintfhdl->io_ops._write8;
  100. ret = _write8(pintfhdl, addr, val);
  101. _func_exit_;
  102. return RTW_STATUS_CODE(ret);
  103. }
  104. int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
  105. {
  106. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  107. struct io_priv *pio_priv = &adapter->iopriv;
  108. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  109. int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
  110. int ret;
  111. _func_enter_;
  112. _write16 = pintfhdl->io_ops._write16;
  113. val = rtw_cpu_to_le16(val);
  114. ret = _write16(pintfhdl, addr, val);
  115. _func_exit_;
  116. return RTW_STATUS_CODE(ret);
  117. }
  118. int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
  119. {
  120. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  121. struct io_priv *pio_priv = &adapter->iopriv;
  122. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  123. int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
  124. int ret;
  125. _func_enter_;
  126. _write32 = pintfhdl->io_ops._write32;
  127. val = rtw_cpu_to_le32(val);
  128. ret = _write32(pintfhdl, addr, val);
  129. _func_exit_;
  130. return RTW_STATUS_CODE(ret);
  131. }
  132. int _rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *pdata)
  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 = (struct intf_hdl*)(&(pio_priv->intf));
  137. int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr,u32 length, u8 *pdata);
  138. int ret;
  139. _func_enter_;
  140. _writeN = pintfhdl->io_ops._writeN;
  141. ret = _writeN(pintfhdl, addr,length,pdata);
  142. _func_exit_;
  143. return RTW_STATUS_CODE(ret);
  144. }
  145. int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
  146. {
  147. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  148. struct io_priv *pio_priv = &adapter->iopriv;
  149. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  150. int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
  151. int ret;
  152. _func_enter_;
  153. _write8_async = pintfhdl->io_ops._write8_async;
  154. ret = _write8_async(pintfhdl, addr, val);
  155. _func_exit_;
  156. return RTW_STATUS_CODE(ret);
  157. }
  158. int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
  159. {
  160. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  161. struct io_priv *pio_priv = &adapter->iopriv;
  162. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  163. int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
  164. int ret;
  165. _func_enter_;
  166. _write16_async = pintfhdl->io_ops._write16_async;
  167. val = rtw_cpu_to_le16(val);
  168. ret = _write16_async(pintfhdl, addr, val);
  169. _func_exit_;
  170. return RTW_STATUS_CODE(ret);
  171. }
  172. int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
  173. {
  174. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  175. struct io_priv *pio_priv = &adapter->iopriv;
  176. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  177. int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
  178. int ret;
  179. _func_enter_;
  180. _write32_async = pintfhdl->io_ops._write32_async;
  181. val = rtw_cpu_to_le32(val);
  182. ret = _write32_async(pintfhdl, addr, val);
  183. _func_exit_;
  184. return RTW_STATUS_CODE(ret);
  185. }
  186. void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
  187. {
  188. void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
  189. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  190. struct io_priv *pio_priv = &adapter->iopriv;
  191. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  192. _func_enter_;
  193. if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
  194. {
  195. RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
  196. return;
  197. }
  198. _read_mem = pintfhdl->io_ops._read_mem;
  199. _read_mem(pintfhdl, addr, cnt, pmem);
  200. _func_exit_;
  201. }
  202. void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
  203. {
  204. void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
  205. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  206. struct io_priv *pio_priv = &adapter->iopriv;
  207. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  208. _func_enter_;
  209. _write_mem = pintfhdl->io_ops._write_mem;
  210. _write_mem(pintfhdl, addr, cnt, pmem);
  211. _func_exit_;
  212. }
  213. void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
  214. {
  215. u32 (*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
  216. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  217. struct io_priv *pio_priv = &adapter->iopriv;
  218. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  219. _func_enter_;
  220. if( (adapter->bDriverStopped ==_TRUE) || (adapter->bSurpriseRemoved == _TRUE))
  221. {
  222. RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved));
  223. return;
  224. }
  225. _read_port = pintfhdl->io_ops._read_port;
  226. _read_port(pintfhdl, addr, cnt, pmem);
  227. _func_exit_;
  228. }
  229. void _rtw_read_port_cancel(_adapter *adapter)
  230. {
  231. void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
  232. struct io_priv *pio_priv = &adapter->iopriv;
  233. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  234. _read_port_cancel = pintfhdl->io_ops._read_port_cancel;
  235. if(_read_port_cancel)
  236. _read_port_cancel(pintfhdl);
  237. }
  238. u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
  239. {
  240. u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
  241. //struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue;
  242. struct io_priv *pio_priv = &adapter->iopriv;
  243. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  244. u32 ret = _SUCCESS;
  245. _func_enter_;
  246. _write_port = pintfhdl->io_ops._write_port;
  247. ret = _write_port(pintfhdl, addr, cnt, pmem);
  248. _func_exit_;
  249. return ret;
  250. }
  251. u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
  252. {
  253. int ret = _SUCCESS;
  254. struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
  255. struct submit_ctx sctx;
  256. rtw_sctx_init(&sctx, timeout_ms);
  257. pxmitbuf->sctx = &sctx;
  258. ret = _rtw_write_port(adapter, addr, cnt, pmem);
  259. if (ret == _SUCCESS)
  260. ret = rtw_sctx_wait(&sctx);
  261. return ret;
  262. }
  263. void _rtw_write_port_cancel(_adapter *adapter)
  264. {
  265. void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
  266. struct io_priv *pio_priv = &adapter->iopriv;
  267. struct intf_hdl *pintfhdl = &(pio_priv->intf);
  268. _write_port_cancel = pintfhdl->io_ops._write_port_cancel;
  269. if(_write_port_cancel)
  270. _write_port_cancel(pintfhdl);
  271. }
  272. int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter,struct _io_ops *pops))
  273. {
  274. struct io_priv *piopriv = &padapter->iopriv;
  275. struct intf_hdl *pintf = &piopriv->intf;
  276. if (set_intf_ops == NULL)
  277. return _FAIL;
  278. piopriv->padapter = padapter;
  279. pintf->padapter = padapter;
  280. pintf->pintf_dev = adapter_to_dvobj(padapter);
  281. set_intf_ops(padapter,&pintf->io_ops);
  282. return _SUCCESS;
  283. }
  284. #ifdef DBG_IO
  285. u16 read_sniff_ranges[][2] = {
  286. //{0x550, 0x551},
  287. };
  288. u16 write_sniff_ranges[][2] = {
  289. //{0x550, 0x551},
  290. //{0x4c, 0x4c},
  291. };
  292. int read_sniff_num = sizeof(read_sniff_ranges)/sizeof(u16)/2;
  293. int write_sniff_num = sizeof(write_sniff_ranges)/sizeof(u16)/2;
  294. bool match_read_sniff_ranges(u16 addr, u16 len)
  295. {
  296. int i;
  297. for (i = 0; i<read_sniff_num; i++) {
  298. if (addr + len > read_sniff_ranges[i][0] && addr <= read_sniff_ranges[i][1])
  299. return _TRUE;
  300. }
  301. return _FALSE;
  302. }
  303. bool match_write_sniff_ranges(u16 addr, u16 len)
  304. {
  305. int i;
  306. for (i = 0; i<write_sniff_num; i++) {
  307. if (addr + len > write_sniff_ranges[i][0] && addr <= write_sniff_ranges[i][1])
  308. return _TRUE;
  309. }
  310. return _FALSE;
  311. }
  312. u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
  313. {
  314. u8 val = _rtw_read8(adapter, addr);
  315. if (match_read_sniff_ranges(addr, 1))
  316. DBG_871X("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n", caller, line, addr, val);
  317. return val;
  318. }
  319. u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
  320. {
  321. u16 val = _rtw_read16(adapter, addr);
  322. if (match_read_sniff_ranges(addr, 2))
  323. DBG_871X("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n", caller, line, addr, val);
  324. return val;
  325. }
  326. u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
  327. {
  328. u32 val = _rtw_read32(adapter, addr);
  329. if (match_read_sniff_ranges(addr, 4))
  330. DBG_871X("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n", caller, line, addr, val);
  331. return val;
  332. }
  333. int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
  334. {
  335. if (match_write_sniff_ranges(addr, 1))
  336. DBG_871X("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n", caller, line, addr, val);
  337. return _rtw_write8(adapter, addr, val);
  338. }
  339. int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
  340. {
  341. if (match_write_sniff_ranges(addr, 2))
  342. DBG_871X("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n", caller, line, addr, val);
  343. return _rtw_write16(adapter, addr, val);
  344. }
  345. int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
  346. {
  347. if (match_write_sniff_ranges(addr, 4))
  348. DBG_871X("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n", caller, line, addr, val);
  349. return _rtw_write32(adapter, addr, val);
  350. }
  351. int dbg_rtw_writeN(_adapter *adapter, u32 addr ,u32 length , u8 *data, const char *caller, const int line)
  352. {
  353. if (match_write_sniff_ranges(addr, length))
  354. DBG_871X("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n", caller, line, addr, length);
  355. return _rtw_writeN(adapter, addr, length, data);
  356. }
  357. #endif