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