]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/net/wireless/realtek/rtl8192cu/core/rtw_iol.c
net: Add non-mainline source for rtl8192cu wlan
[mirror_ubuntu-zesty-kernel.git] / drivers / net / wireless / realtek / rtl8192cu / 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<rtw_iol.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 = 0x10;
54 pattrib->pktlen = pattrib->last_txcmdsz = 0;
55
56 #else
57 if ((xmit_frame = alloc_mgtxmitframe(pxmitpriv)) == NULL)
58 {
59 DBG_871X("%s alloc_mgtxmitframe return null\n", __FUNCTION__);
60 }
61 else {
62 pattrib = &xmit_frame->attrib;
63 update_mgntframe_attrib(adapter, pattrib);
64 pattrib->qsel = 0x10;
65 pattrib->pktlen = pattrib->last_txcmdsz = 0;
66 }
67 #endif
68
69 exit:
70 return xmit_frame;
71 }
72
73
74 int rtw_IOL_append_cmds(struct xmit_frame *xmit_frame, u8 *IOL_cmds, u32 cmd_len)
75 {
76 struct pkt_attrib *pattrib = &xmit_frame->attrib;
77 u16 buf_offset;
78 u32 ori_len;
79
80 //Todo: bulkout without this offset
81 #ifdef CONFIG_USB_HCI
82 buf_offset = TXDESC_OFFSET;
83 #else
84 buf_offset = 0;
85 #endif
86
87 ori_len = buf_offset+pattrib->pktlen;
88
89 //check if the io_buf can accommodate new cmds
90 if(ori_len + cmd_len + 8 > MAX_XMITBUF_SZ) {
91 DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate new cmds\n", __FUNCTION__
92 , ori_len + cmd_len + 8, MAX_XMITBUF_SZ);
93 return _FAIL;
94 }
95
96 _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, IOL_cmds, cmd_len);
97 pattrib->pktlen += cmd_len;
98 pattrib->last_txcmdsz += cmd_len;
99
100 //DBG_871X("%s ori:%u + cmd_len:%u = %u\n", __FUNCTION__, ori_len, cmd_len, buf_offset+pattrib->pktlen);
101
102 return _SUCCESS;
103 }
104
105 int rtw_IOL_append_LLT_cmd(struct xmit_frame *xmit_frame, u8 page_boundary)
106 {
107 IOL_CMD cmd = {0x0, IOL_CMD_LLT, 0x0, 0x0};
108
109 RTW_PUT_BE32((u8*)&cmd.value, (u32)page_boundary);
110
111 return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
112 }
113
114 int _rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value)
115 {
116 IOL_CMD cmd = {0x0, IOL_CMD_WB_REG, 0x0, 0x0};
117
118 RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
119 RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
120
121 return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
122 }
123
124 int _rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value)
125 {
126 IOL_CMD cmd = {0x0, IOL_CMD_WW_REG, 0x0, 0x0};
127
128 RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
129 RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
130
131 return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
132 }
133
134 int _rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value)
135 {
136 IOL_CMD cmd = {0x0, IOL_CMD_WD_REG, 0x0, 0x0};
137 u8* pos = (u8 *)&cmd;
138
139 RTW_PUT_BE16((u8*)&cmd.address, (u16)addr);
140 RTW_PUT_BE32((u8*)&cmd.value, (u32)value);
141
142 return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
143 }
144
145 #ifdef DBG_IO
146 int dbg_rtw_IOL_append_WB_cmd(struct xmit_frame *xmit_frame, u16 addr, u8 value, const char *caller, const int line)
147 {
148 if (match_write_sniff_ranges(addr, 1))
149 DBG_871X("DBG_IO %s:%d IOL_WB(0x%04x, 0x%02x)\n", caller, line, addr, value);
150
151 return _rtw_IOL_append_WB_cmd(xmit_frame, addr, value);
152 }
153
154 int dbg_rtw_IOL_append_WW_cmd(struct xmit_frame *xmit_frame, u16 addr, u16 value, const char *caller, const int line)
155 {
156 if (match_write_sniff_ranges(addr, 2))
157 DBG_871X("DBG_IO %s:%d IOL_WW(0x%04x, 0x%04x)\n", caller, line, addr, value);
158
159 return _rtw_IOL_append_WW_cmd(xmit_frame, addr, value);
160 }
161
162 int dbg_rtw_IOL_append_WD_cmd(struct xmit_frame *xmit_frame, u16 addr, u32 value, const char *caller, const int line)
163 {
164 if (match_write_sniff_ranges(addr, 4))
165 DBG_871X("DBG_IO %s:%d IOL_WD(0x%04x, 0x%08x)\n", caller, line, addr, value);
166
167 return _rtw_IOL_append_WD_cmd(xmit_frame, addr, value);
168 }
169 #endif
170
171 int rtw_IOL_append_DELAY_US_cmd(struct xmit_frame *xmit_frame, u16 us)
172 {
173 IOL_CMD cmd = {0x0, IOL_CMD_DELAY_US, 0x0, 0x0};
174
175 RTW_PUT_BE32((u8*)&cmd.value, (u32)us);
176
177 //DBG_871X("%s %u\n", __FUNCTION__, us);
178
179 return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
180 }
181
182 int rtw_IOL_append_DELAY_MS_cmd(struct xmit_frame *xmit_frame, u16 ms)
183 {
184 IOL_CMD cmd = {0x0, IOL_CMD_DELAY_MS, 0x0, 0x0};
185
186 RTW_PUT_BE32((u8*)&cmd.value, (u32)ms);
187
188 //DBG_871X("%s %u\n", __FUNCTION__, ms);
189
190 return rtw_IOL_append_cmds(xmit_frame, (u8*)&cmd, 8);
191 }
192
193 int rtw_IOL_append_END_cmd(struct xmit_frame *xmit_frame)
194 {
195 struct pkt_attrib *pattrib = &xmit_frame->attrib;
196 u16 buf_offset;
197 u32 ori_len;
198 IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
199
200 //Todo: bulkout without this offset
201 #ifdef CONFIG_USB_HCI
202 buf_offset = TXDESC_OFFSET;
203 #else
204 buf_offset = 0;
205 #endif
206
207 ori_len = buf_offset+pattrib->pktlen;
208
209 //check if the io_buf can accommodate new cmds
210 if(ori_len + 8 > MAX_XMITBUF_SZ) {
211 DBG_871X("%s %u is large than MAX_XMITBUF_SZ:%u, can't accommodate end cmd\n", __FUNCTION__
212 , ori_len + 8, MAX_XMITBUF_SZ);
213 return _FAIL;
214 }
215
216 _rtw_memcpy(xmit_frame->buf_addr + buf_offset + pattrib->pktlen, (u8*)&end_cmd, 8);
217 pattrib->pktlen += 8;
218 pattrib->last_txcmdsz += 8;
219
220 //DBG_871X("%s ori:%u + 8 = %u\n", __FUNCTION__ , ori_len, buf_offset+pattrib->pktlen);
221
222 return _SUCCESS;
223 }
224
225 int rtw_IOL_exec_cmds_sync(ADAPTER *adapter, struct xmit_frame *xmit_frame, u32 max_wating_ms)
226 {
227 return rtw_hal_iol_cmd(adapter, xmit_frame, max_wating_ms);
228 }
229
230 int rtw_IOL_exec_cmd_array_sync(PADAPTER adapter, u8 *IOL_cmds, u32 cmd_num, u32 max_wating_ms)
231 {
232 struct xmit_frame *xmit_frame;
233
234 if((xmit_frame=rtw_IOL_accquire_xmit_frame(adapter)) == NULL)
235 return _FAIL;
236
237 if(rtw_IOL_append_cmds(xmit_frame, IOL_cmds, cmd_num<<3) == _FAIL)
238 return _FAIL;
239
240 return rtw_IOL_exec_cmds_sync(adapter, xmit_frame, max_wating_ms);
241 }
242
243 int rtw_IOL_exec_empty_cmds_sync(ADAPTER *adapter, u32 max_wating_ms)
244 {
245 IOL_CMD end_cmd = {0x0, IOL_CMD_END, 0x0, 0x0};
246 return rtw_IOL_exec_cmd_array_sync(adapter, (u8*)&end_cmd, 1, max_wating_ms);
247 }
248
249 bool rtw_IOL_applied(ADAPTER *adapter)
250 {
251 if(adapter->registrypriv.force_iol)
252 return _TRUE;
253
254 #ifdef CONFIG_USB_HCI
255 if(!adapter_to_dvobj(adapter)->ishighspeed)
256 return _TRUE;
257 #endif
258
259 return _FALSE;
260 }
261
262 #endif //CONFIG_IOL