rtw_iol.c 11 KB

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