rtw_iol.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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. #include <drv_types.h>
  21. #ifdef CONFIG_IOL
  22. struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter)
  23. {
  24. struct xmit_frame *xmit_frame;
  25. struct xmit_buf *xmitbuf;
  26. struct pkt_attrib *pattrib;
  27. struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);
  28. #if 1
  29. xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
  30. if (xmit_frame == NULL) {
  31. RTW_INFO("%s rtw_alloc_xmitframe return null\n", __FUNCTION__);
  32. goto exit;
  33. }
  34. xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
  35. if (xmitbuf == NULL) {
  36. RTW_INFO("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__);
  37. rtw_free_xmitframe(pxmitpriv, xmit_frame);
  38. xmit_frame = NULL;
  39. goto exit;
  40. }
  41. xmit_frame->frame_tag = MGNT_FRAMETAG;
  42. xmit_frame->pxmitbuf = xmitbuf;
  43. xmit_frame->buf_addr = xmitbuf->pbuf;
  44. xmitbuf->priv_data = xmit_frame;
  45. pattrib = &xmit_frame->attrib;
  46. update_mgntframe_attrib(adapter, pattrib);
  47. pattrib->qsel = QSLT_BEACON;/* Beacon */
  48. pattrib->subtype = WIFI_BEACON;
  49. pattrib->pktlen = pattrib->last_txcmdsz = 0;
  50. #else
  51. xmit_frame = alloc_mgtxmitframe(pxmitpriv);
  52. if (xmit_frame == NULL)
  53. RTW_INFO("%s alloc_mgtxmitframe return null\n", __FUNCTION__);
  54. else {
  55. pattrib = &xmit_frame->attrib;
  56. update_mgntframe_attrib(adapter, pattrib);
  57. pattrib->qsel = QSLT_BEACON;
  58. pattrib->pktlen = pattrib->last_txcmdsz = 0;
  59. }
  60. #endif
  61. exit:
  62. return xmit_frame;
  63. }
  64. int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
  65. {
  66. struct pkt_attrib *pattrib = &xmit_frame->attrib;
  67. u16 buf_offset;
  68. u32 ori_len;
  69. buf_offset = TXDESC_OFFSET;
  70. ori_len = buf_offset + pattrib->pktlen;
  71. /* check if the io_buf can accommodate new cmds */
  72. if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
  73. RTW_INFO("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
  74. , ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
  75. return _FAIL;
  76. }
  77. _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
  78. pattrib->pktlen += cmd_len;
  79. pattrib->last_txcmdsz += cmd_len;
  80. /* RTW_INFO("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen); */
  81. return _SUCCESS;
  82. }
  83. bool rtw_IOL_applied(ADAPTER *adapter)
  84. {
  85. if (1 == adapter->registrypriv.fw_iol)
  86. return _TRUE;
  87. #ifdef CONFIG_USB_HCI
  88. if ((2 == adapter->registrypriv.fw_iol) && (IS_FULL_SPEED_USB(adapter)))
  89. return _TRUE;
  90. #endif
  91. return _FALSE;
  92. }
  93. int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
  94. {
  95. return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);
  96. }
  97. #ifdef CONFIG_IOL_NEW_GENERATION
  98. int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
  99. {
  100. return _SUCCESS;
  101. }
  102. int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
  103. {
  104. struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
  105. /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
  106. /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
  107. cmd.address = cpu_to_le16(addr);
  108. cmd.data = cpu_to_le32(value);
  109. if (mask != 0xFF) {
  110. cmd.length = 12;
  111. /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
  112. cmd.mask = cpu_to_le32(mask);
  113. }
  114. /* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
  115. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
  116. }
  117. int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
  118. {
  119. struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
  120. /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
  121. /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
  122. cmd.address = cpu_to_le16(addr);
  123. cmd.data = cpu_to_le32(value);
  124. if (mask != 0xFFFF) {
  125. cmd.length = 12;
  126. /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
  127. cmd.mask = cpu_to_le32(mask);
  128. }
  129. /* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
  130. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
  131. }
  132. int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
  133. {
  134. struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
  135. /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
  136. /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
  137. cmd.address = cpu_to_le16(addr);
  138. cmd.data = cpu_to_le32(value);
  139. if (mask != 0xFFFFFFFF) {
  140. cmd.length = 12;
  141. /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
  142. cmd.mask = cpu_to_le32(mask);
  143. }
  144. /* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__, addr,value,mask); */
  145. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
  146. }
  147. int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
  148. {
  149. struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
  150. /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
  151. /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
  152. cmd.address = (rf_path << 8) | ((addr) & 0xFF);
  153. cmd.data = cpu_to_le32(value);
  154. if (mask != 0x000FFFFF) {
  155. cmd.length = 12;
  156. /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
  157. cmd.mask = cpu_to_le32(mask);
  158. }
  159. /* RTW_INFO("%s rf_path:0x%02x addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__,rf_path, addr,value,mask); */
  160. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
  161. }
  162. int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
  163. {
  164. struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
  165. /* RTW_PUT_LE16((u8*)&cmd.address, us); */
  166. cmd.address = cpu_to_le16(us);
  167. /* RTW_INFO("%s %u\n", __FUNCTION__, us); */
  168. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
  169. }
  170. int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
  171. {
  172. struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
  173. /* RTW_PUT_LE16((u8*)&cmd.address, ms); */
  174. cmd.address = cpu_to_le16(ms);
  175. /* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
  176. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
  177. }
  178. int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
  179. {
  180. struct ioreg_cfg cmd = {4, IOREG_CMD_END, 0xFFFF, 0xFF, 0x0};
  181. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
  182. }
  183. u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
  184. {
  185. u8 is_cmd_bndy = _FALSE;
  186. if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
  187. rtw_IOL_append_END_cmd(pxmit_frame);
  188. pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
  189. /* printk("==> %s, pktlen(%d)\n",__FUNCTION__,pxmit_frame->attrib.pktlen); */
  190. pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
  191. is_cmd_bndy = _TRUE;
  192. }
  193. return is_cmd_bndy;
  194. }
  195. void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter, int buf_len, u8 *pbuf)
  196. {
  197. int i;
  198. int j = 1;
  199. printk("###### %s ######\n", __FUNCTION__);
  200. for (i = 0; i < buf_len; i++) {
  201. printk("%02x-", *(pbuf + i));
  202. if (j % 32 == 0)
  203. printk("\n");
  204. j++;
  205. }
  206. printk("\n");
  207. printk("============= ioreg_cmd len = %d ===============\n", buf_len);
  208. }
  209. #else /* CONFIG_IOL_NEW_GENERATION */
  210. int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
  211. {
  212. IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};
  213. RTW_PUT_BE32((u8 *)&cmd.value, (u32)page_boundary);
  214. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
  215. }
  216. int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)
  217. {
  218. IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};
  219. RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
  220. RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
  221. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
  222. }
  223. int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)
  224. {
  225. IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};
  226. RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
  227. RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
  228. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
  229. }
  230. int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)
  231. {
  232. IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};
  233. u8 *pos = (u8 *)&cmd;
  234. RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
  235. RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
  236. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
  237. }
  238. #ifdef DBG_IO
  239. int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)
  240. {
  241. if (match_write_sniff_ranges(addr, 1))
  242. RTW_INFO("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value);
  243. return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);
  244. }
  245. int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)
  246. {
  247. if (match_write_sniff_ranges(addr, 2))
  248. RTW_INFO("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value);
  249. return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);
  250. }
  251. int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)
  252. {
  253. if (match_write_sniff_ranges(addr, 4))
  254. RTW_INFO("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value);
  255. return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);
  256. }
  257. #endif
  258. int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
  259. {
  260. IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};
  261. RTW_PUT_BE32((u8 *)&cmd.value, (u32)us);
  262. /* RTW_INFO("%s %u\n", __FUNCTION__, us); */
  263. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
  264. }
  265. int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
  266. {
  267. IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};
  268. RTW_PUT_BE32((u8 *)&cmd.value, (u32)ms);
  269. /* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
  270. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
  271. }
  272. int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
  273. {
  274. IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
  275. return rtw_IOL_append_cmds(xmit_frame, (u8 *)&end_cmd, 8);
  276. }
  277. int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)
  278. {
  279. struct xmit_frame *xmit_frame;
  280. xmit_frame = rtw_IOL_accquire_xmit_frame(adapter);
  281. if (xmit_frame == NULL)
  282. return _FAIL;
  283. if (rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num << 3) == _FAIL)
  284. return _FAIL;
  285. return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms, 0);
  286. }
  287. int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)
  288. {
  289. IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
  290. return rtw_IOL_exec_cmd_array_sync(adapter, (u8 *)&end_cmd, 1, max_wating_ms);
  291. }
  292. #endif /* CONFIG_IOL_NEW_GENERATION */
  293. #endif /* CONFIG_IOL */