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 ******************************************************************************/
21 #include <drv_types.h>
24 struct xmit_frame *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter)
26 struct xmit_frame *xmit_frame;
27 struct xmit_buf *xmitbuf;
28 struct pkt_attrib *pattrib;
29 struct xmit_priv *pxmitpriv = &(adapter->xmitpriv);
32 xmit_frame = rtw_alloc_xmitframe(pxmitpriv);
33 if (xmit_frame == NULL) {
34 RTW_INFO("%s rtw_alloc_xmitframe return null\n", __FUNCTION__);
38 xmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
39 if (xmitbuf == NULL) {
40 RTW_INFO("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__);
41 rtw_free_xmitframe(pxmitpriv, xmit_frame);
46 xmit_frame->frame_tag = MGNT_FRAMETAG;
47 xmit_frame->pxmitbuf = xmitbuf;
48 xmit_frame->buf_addr = xmitbuf->pbuf;
49 xmitbuf->priv_data = xmit_frame;
51 pattrib = &xmit_frame->attrib;
52 update_mgntframe_attrib(adapter, pattrib);
53 pattrib->qsel = QSLT_BEACON;/* Beacon */
54 pattrib->subtype = WIFI_BEACON;
55 pattrib->pktlen = pattrib->last_txcmdsz = 0;
58 xmit_frame = alloc_mgtxmitframe(pxmitpriv);
59 if (xmit_frame == NULL)
60 RTW_INFO("%s alloc_mgtxmitframe return null\n", __FUNCTION__);
62 pattrib = &xmit_frame->attrib;
63 update_mgntframe_attrib(adapter, pattrib);
64 pattrib->qsel = QSLT_BEACON;
65 pattrib->pktlen = pattrib->last_txcmdsz = 0;
74 int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
76 struct pkt_attrib *pattrib = &xmit_frame->attrib;
80 buf_offset = TXDESC_OFFSET;
81 ori_len = buf_offset + pattrib->pktlen;
83 /* check if the io_buf can accommodate new cmds */
84 if (ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
85 RTW_INFO("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
86 , ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
90 _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
91 pattrib->pktlen += cmd_len;
92 pattrib->last_txcmdsz += cmd_len;
94 /* RTW_INFO("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen); */
99 bool rtw_IOL_applied(ADAPTER *adapter)
101 if (1 == adapter->registrypriv.fw_iol)
104 #ifdef CONFIG_USB_HCI
105 if ((2 == adapter->registrypriv.fw_iol) && (IS_FULL_SPEED_USB(adapter)))
112 int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
114 return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms, bndy_cnt);
117 #ifdef CONFIG_IOL_NEW_GENERATION
118 int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
122 int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
124 struct ioreg_cfg cmd = {8, IOREG_CMD_WB_REG, 0x0, 0x0, 0x0};
126 /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
127 /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
128 cmd.address = cpu_to_le16(addr);
129 cmd.data = cpu_to_le32(value);
133 /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
134 cmd.mask = cpu_to_le32(mask);
137 /* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
139 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
142 int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
144 struct ioreg_cfg cmd = {8, IOREG_CMD_WW_REG, 0x0, 0x0, 0x0};
146 /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
147 /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
148 cmd.address = cpu_to_le16(addr);
149 cmd.data = cpu_to_le32(value);
151 if (mask != 0xFFFF) {
153 /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
154 cmd.mask = cpu_to_le32(mask);
157 /* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask); */
159 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
162 int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
164 struct ioreg_cfg cmd = {8, IOREG_CMD_WD_REG, 0x0, 0x0, 0x0};
166 /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
167 /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
168 cmd.address = cpu_to_le16(addr);
169 cmd.data = cpu_to_le32(value);
171 if (mask != 0xFFFFFFFF) {
173 /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
174 cmd.mask = cpu_to_le32(mask);
177 /* RTW_INFO("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__, addr,value,mask); */
179 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
183 int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
185 struct ioreg_cfg cmd = {8, IOREG_CMD_W_RF, 0x0, 0x0, 0x0};
187 /* RTW_PUT_LE16((u8*)&cmd.address, addr); */
188 /* RTW_PUT_LE32((u8*)&cmd.value, (u32)value); */
189 cmd.address = (rf_path << 8) | ((addr) & 0xFF);
190 cmd.data = cpu_to_le32(value);
192 if (mask != 0x000FFFFF) {
194 /* RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask); */
195 cmd.mask = cpu_to_le32(mask);
198 /* RTW_INFO("%s rf_path:0x%02x addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__,rf_path, addr,value,mask); */
200 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, cmd.length);
206 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
208 struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
209 /* RTW_PUT_LE16((u8*)&cmd.address, us); */
210 cmd.address = cpu_to_le16(us);
212 /* RTW_INFO("%s %u\n", __FUNCTION__, us); */
213 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
216 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
218 struct ioreg_cfg cmd = {4, IOREG_CMD_DELAY_US, 0x0, 0x0, 0x0};
220 /* RTW_PUT_LE16((u8*)&cmd.address, ms); */
221 cmd.address = cpu_to_le16(ms);
223 /* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
224 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
226 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
228 struct ioreg_cfg cmd = {4, IOREG_CMD_END, 0xFFFF, 0xFF, 0x0};
229 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 4);
233 u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
235 u8 is_cmd_bndy = _FALSE;
236 if (((pxmit_frame->attrib.pktlen + 32) % 256) + 8 >= 256) {
237 rtw_IOL_append_END_cmd(pxmit_frame);
238 pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen + 32) / 256) + 1) * 256);
240 /* printk("==> %s, pktlen(%d)\n",__FUNCTION__,pxmit_frame->attrib.pktlen); */
241 pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
247 void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter, int buf_len, u8 *pbuf)
252 printk("###### %s ######\n", __FUNCTION__);
253 for (i = 0; i < buf_len; i++) {
254 printk("%02x-", *(pbuf + i));
261 printk("============= ioreg_cmd len = %d ===============\n", buf_len);
265 #else /* CONFIG_IOL_NEW_GENERATION */
266 int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
268 IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};
270 RTW_PUT_BE32((u8 *)&cmd.value, (u32)page_boundary);
272 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
275 int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)
277 IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};
279 RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
280 RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
282 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
285 int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)
287 IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};
289 RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
290 RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
292 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
295 int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)
297 IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};
298 u8 *pos = (u8 *)&cmd;
300 RTW_PUT_BE16((u8 *)&cmd.address, (u16)addr);
301 RTW_PUT_BE32((u8 *)&cmd.value, (u32)value);
303 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
307 int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)
309 if (match_write_sniff_ranges(addr, 1))
310 RTW_INFO("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value);
312 return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);
315 int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)
317 if (match_write_sniff_ranges(addr, 2))
318 RTW_INFO("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value);
320 return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);
323 int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)
325 if (match_write_sniff_ranges(addr, 4))
326 RTW_INFO("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value);
328 return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);
332 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
334 IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};
336 RTW_PUT_BE32((u8 *)&cmd.value, (u32)us);
338 /* RTW_INFO("%s %u\n", __FUNCTION__, us); */
340 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
343 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
345 IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};
347 RTW_PUT_BE32((u8 *)&cmd.value, (u32)ms);
349 /* RTW_INFO("%s %u\n", __FUNCTION__, ms); */
351 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&cmd, 8);
354 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
356 IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
359 return rtw_IOL_append_cmds(xmit_frame, (u8 *)&end_cmd, 8);
363 int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)
365 struct xmit_frame *xmit_frame;
367 xmit_frame = rtw_IOL_accquire_xmit_frame(adapter);
368 if (xmit_frame == NULL)
371 if (rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num << 3) == _FAIL)
374 return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms, 0);
377 int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)
379 IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
380 return rtw_IOL_exec_cmd_array_sync(adapter, (u8 *)&end_cmd, 1, max_wating_ms);
382 #endif /* CONFIG_IOL_NEW_GENERATION */
387 #endif /* CONFIG_IOL */