OSDN Git Service

0df2de2bd13a6c1e44fb19bd762341b72383bc7f
[android-x86/external-kernel-drivers.git] / rtl8723bu / core / rtw_iol.c
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 #include <drv_types.h>
22
23 #ifdef CONFIG_IOL
24 struct xmit_frame       *rtw_IOL_accquire_xmit_frame(ADAPTER *adapter)
25 {
26         struct xmit_frame       *xmit_frame;
27         struct xmit_buf *xmitbuf;
28         struct pkt_attrib       *pattrib;
29         struct xmit_priv        *pxmitpriv = &(adapter->xmitpriv);
30
31 #if 1
32         if ((xmit_frame = rtw_alloc_xmitframe(pxmitpriv)) == NULL)
33         {
34                 DBG_871X("%s rtw_alloc_xmitframe return null\n", __FUNCTION__);
35                 goto exit;
36         }
37
38         if ((xmitbuf = rtw_alloc_xmitbuf(pxmitpriv)) == NULL)
39         {
40                 DBG_871X("%s rtw_alloc_xmitbuf return null\n", __FUNCTION__);
41                 rtw_free_xmitframe(pxmitpriv, xmit_frame);
42                 xmit_frame=NULL;
43                 goto exit;
44         }
45
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;
50
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;
56
57 #else
58         if ((xmit_frame = alloc_mgtxmitframe(pxmitpriv)) == NULL)
59         {
60                 DBG_871X("%s alloc_mgtxmitframe return null\n", __FUNCTION__);
61         }
62         else {
63                 pattrib = &xmit_frame->attrib;
64                 update_mgntframe_attrib(adapter, pattrib);
65                 pattrib->qsel = QSLT_BEACON;
66                 pattrib->pktlen = pattrib->last_txcmdsz = 0;
67         }
68 #endif
69
70 exit:
71         return xmit_frame;
72 }
73
74
75 int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
76 {
77         struct pkt_attrib       *pattrib = &xmit_frame->attrib;
78         u16 buf_offset;
79         u32 ori_len;
80
81         buf_offset = TXDESC_OFFSET;
82         ori_len = buf_offset+pattrib->pktlen;
83
84         //check if the io_buf can accommodate new cmds
85         if(ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
86                 DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
87                         , ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
88                 return _FAIL;
89         }
90
91         _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
92         pattrib->pktlen += cmd_len;
93         pattrib->last_txcmdsz += cmd_len;
94
95         //DBG_871X("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen);
96
97         return _SUCCESS;
98 }
99
100 bool rtw_IOL_applied(ADAPTER *adapter)
101 {
102         if(1 == adapter->registrypriv.fw_iol)
103                 return _TRUE;
104
105 #ifdef CONFIG_USB_HCI
106         if((2 == adapter->registrypriv.fw_iol) && (IS_FULL_SPEED_USB(adapter)))
107                 return _TRUE;
108 #endif
109
110         return _FALSE;
111 }
112
113 int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms, u32 bndy_cnt)
114 {
115         return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms,bndy_cnt);
116 }
117
118 #ifdef CONFIG_IOL_NEW_GENERATION
119 int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
120 {
121         return _SUCCESS;
122 }
123 int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, u8 mask)
124 {
125         struct ioreg_cfg cmd = {8,IOREG_CMD_WB_REG,0x0, 0x0,0x0};
126
127         //RTW_PUT_LE16((u8*)&cmd.address, addr);
128         //RTW_PUT_LE32((u8*)&cmd.value, (u32)value);
129         cmd.address = cpu_to_le16(addr);
130         cmd.data = cpu_to_le32(value);
131
132         if(mask!=0xFF)
133         {
134                 cmd.length = 12;
135                 //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask);
136                 cmd.mask = cpu_to_le32(mask);
137         }
138
139         //DBG_871X("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask);
140
141         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length);
142
143 }
144 int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, u16 mask)
145 {
146         struct ioreg_cfg cmd = {8,IOREG_CMD_WW_REG,0x0, 0x0,0x0};
147
148         //RTW_PUT_LE16((u8*)&cmd.address, addr);
149         //RTW_PUT_LE32((u8*)&cmd.value, (u32)value);
150         cmd.address = cpu_to_le16(addr);
151         cmd.data = cpu_to_le32(value);
152
153         if(mask!=0xFFFF)
154         {
155                 cmd.length = 12;
156                 //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask);
157                 cmd.mask =  cpu_to_le32(mask);
158         }
159
160         //DBG_871X("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FUNCTION__, addr,value,mask);
161
162         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length);
163
164 }
165 int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, u32 mask)
166 {
167         struct ioreg_cfg cmd = {8,IOREG_CMD_WD_REG,0x0, 0x0,0x0};
168
169         //RTW_PUT_LE16((u8*)&cmd.address, addr);
170         //RTW_PUT_LE32((u8*)&cmd.value, (u32)value);
171         cmd.address = cpu_to_le16(addr);
172         cmd.data = cpu_to_le32(value);
173
174         if(mask!=0xFFFFFFFF)
175         {
176                 cmd.length = 12;
177                 //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask);
178                 cmd.mask =  cpu_to_le32(mask);
179         }
180
181         //DBG_871X("%s addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__, addr,value,mask);
182
183         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length);
184
185 }
186
187 int _rtw_IOL_append_WRF_cmd(struct xmit_frame *xmit_frame, u8 rf_path, u16 addr, u32 value, u32 mask)
188 {
189         struct ioreg_cfg cmd = {8,IOREG_CMD_W_RF,0x0, 0x0,0x0};
190
191         //RTW_PUT_LE16((u8*)&cmd.address, addr);
192         //RTW_PUT_LE32((u8*)&cmd.value, (u32)value);
193         cmd.address = (rf_path<<8) |((addr) &0xFF);
194         cmd.data = cpu_to_le32(value);
195
196         if(mask!=0x000FFFFF)
197         {
198                 cmd.length = 12;
199                 //RTW_PUT_LE32((u8*)&cmd.mask, (u32)mask);
200                 cmd.mask =  cpu_to_le32(mask);
201         }
202
203         //DBG_871X("%s rf_path:0x%02x addr:0x%04x,value:0x%08x,mask:0x%08x\n", __FU2NCTION__,rf_path, addr,value,mask);
204
205         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, cmd.length);
206
207 }
208
209
210
211 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
212 {
213         struct ioreg_cfg cmd = {4,IOREG_CMD_DELAY_US,0x0, 0x0,0x0};
214         //RTW_PUT_LE16((u8*)&cmd.address, us);
215         cmd.address = cpu_to_le16(us);
216
217         //DBG_871X("%s %u\n", __FUNCTION__, us);
218         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 4);
219 }
220
221 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
222 {
223         struct ioreg_cfg cmd = {4,IOREG_CMD_DELAY_US,0x0, 0x0,0x0};
224
225         //RTW_PUT_LE16((u8*)&cmd.address, ms);
226         cmd.address = cpu_to_le16(ms);
227
228         //DBG_871X("%s %u\n", __FUNCTION__, ms);
229         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 4);
230 }
231 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
232 {
233         struct ioreg_cfg cmd = {4,IOREG_CMD_END,0xFFFF, 0xFF,0x0};
234         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 4);
235
236 }
237
238 u8 rtw_IOL_cmd_boundary_handle(struct xmit_frame *pxmit_frame)
239 {
240         u8 is_cmd_bndy = _FALSE;
241         if(((pxmit_frame->attrib.pktlen+32)%256) + 8 >= 256){
242                 rtw_IOL_append_END_cmd(pxmit_frame);
243                 pxmit_frame->attrib.pktlen = ((((pxmit_frame->attrib.pktlen+32)/256)+1)*256 );
244
245                 //printk("==> %s, pktlen(%d)\n",__FUNCTION__,pxmit_frame->attrib.pktlen);
246                 pxmit_frame->attrib.last_txcmdsz = pxmit_frame->attrib.pktlen;
247                 is_cmd_bndy = _TRUE;
248         }
249         return is_cmd_bndy;
250 }
251
252 void rtw_IOL_cmd_buf_dump(ADAPTER *Adapter,int buf_len,u8 *pbuf)
253 {
254         int i;
255         int j=1;
256
257         printk("###### %s ######\n",__FUNCTION__);
258         for(i=0;i< buf_len;i++){
259                 printk("%02x-",*(pbuf+i));
260
261                 if(j%32 ==0) printk("\n");j++;
262         }
263         printk("\n");
264         printk("============= ioreg_cmd len = %d =============== \n",buf_len);
265 }
266
267
268 #else //CONFIG_IOL_NEW_GENERATION
269 int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
270 {
271         IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};
272
273         RTW_PUT_BE32((u8*)&cmd.value, (u32)page_boundary);
274
275         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
276 }
277
278 int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)
279 {
280         IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};
281
282         RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
283         RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
284
285         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
286 }
287
288 int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)
289 {
290         IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};
291
292         RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
293         RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
294
295         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
296 }
297
298 int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)
299 {
300         IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};
301         u8* pos = (u8 *)&cmd;
302
303         RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
304         RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
305
306         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
307 }
308
309 #ifdef DBG_IO
310 int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)
311 {
312         if (match_write_sniff_ranges(addr, 1))
313                 DBG_871X("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value);
314
315         return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);
316 }
317
318 int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)
319 {
320         if (match_write_sniff_ranges(addr, 2))
321                 DBG_871X("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value);
322
323         return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);
324 }
325
326 int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)
327 {
328         if (match_write_sniff_ranges(addr, 4))
329                 DBG_871X("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value);
330
331         return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);
332 }
333 #endif
334
335 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
336 {
337         IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};
338
339         RTW_PUT_BE32((u8*)&cmd.value, (u32)us);
340
341         //DBG_871X("%s %u\n", __FUNCTION__, us);
342
343         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
344 }
345
346 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
347 {
348         IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};
349
350         RTW_PUT_BE32((u8*)&cmd.value, (u32)ms);
351
352         //DBG_871X("%s %u\n", __FUNCTION__, ms);
353
354         return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
355 }
356
357 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
358 {
359         IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
360
361
362         return rtw_IOL_append_cmds(xmit_frame, (u8*)&end_cmd, 8);
363
364 }
365
366 int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)
367 {
368         struct xmit_frame       *xmit_frame;
369
370         if((xmit_frame=rtw_IOL_accquire_xmit_frame(adapter)) == NULL)
371                 return _FAIL;
372
373         if(rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num<<3) == _FAIL)
374                 return _FAIL;
375
376         return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms,0);
377 }
378
379 int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)
380 {
381         IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
382         return rtw_IOL_exec_cmd_array_sync(adapter, (u8*)&end_cmd, 1, max_wating_ms);
383 }
384 #endif //CONFIG_IOL_NEW_GENERATION
385
386
387
388
389 #endif //CONFIG_IOL