xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8723ds/core/rtw_io.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
17 The purpose of rtw_io.c
18 
19 a. provides the API
20 
21 b. provides the protocol engine
22 
23 c. provides the software interface between caller and the hardware interface
24 
25 
26 Compiler Flag Option:
27 
28 1. CONFIG_SDIO_HCI:
29     a. USE_SYNC_IRP:  Only sync operations are provided.
30     b. USE_ASYNC_IRP:Both sync/async operations are provided.
31 
32 2. CONFIG_USB_HCI:
33    a. USE_ASYNC_IRP: Both sync/async operations are provided.
34 
35 3. CONFIG_CFIO_HCI:
36    b. USE_SYNC_IRP: Only sync operations are provided.
37 
38 
39 Only sync read/rtw_write_mem operations are provided.
40 
41 jackson@realtek.com.tw
42 
43 */
44 
45 #define _RTW_IO_C_
46 
47 #include <drv_types.h>
48 #include <hal_data.h>
49 
50 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_PLATFORM_RTL8197D)
51 	#define rtw_le16_to_cpu(val)		val
52 	#define rtw_le32_to_cpu(val)		val
53 	#define rtw_cpu_to_le16(val)		val
54 	#define rtw_cpu_to_le32(val)		val
55 #else
56 	#define rtw_le16_to_cpu(val)		le16_to_cpu(val)
57 	#define rtw_le32_to_cpu(val)		le32_to_cpu(val)
58 	#define rtw_cpu_to_le16(val)		cpu_to_le16(val)
59 	#define rtw_cpu_to_le32(val)		cpu_to_le32(val)
60 #endif
61 
62 
_rtw_read8(_adapter * adapter,u32 addr)63 u8 _rtw_read8(_adapter *adapter, u32 addr)
64 {
65 	u8 r_val;
66 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
67 	struct io_priv *pio_priv = &adapter->iopriv;
68 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
69 	u8(*_read8)(struct intf_hdl *pintfhdl, u32 addr);
70 	_read8 = pintfhdl->io_ops._read8;
71 
72 	r_val = _read8(pintfhdl, addr);
73 	return r_val;
74 }
75 
_rtw_read16(_adapter * adapter,u32 addr)76 u16 _rtw_read16(_adapter *adapter, u32 addr)
77 {
78 	u16 r_val;
79 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
80 	struct io_priv *pio_priv = &adapter->iopriv;
81 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
82 	u16(*_read16)(struct intf_hdl *pintfhdl, u32 addr);
83 	_read16 = pintfhdl->io_ops._read16;
84 
85 	r_val = _read16(pintfhdl, addr);
86 	return rtw_le16_to_cpu(r_val);
87 }
88 
_rtw_read32(_adapter * adapter,u32 addr)89 u32 _rtw_read32(_adapter *adapter, u32 addr)
90 {
91 	u32 r_val;
92 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
93 	struct io_priv *pio_priv = &adapter->iopriv;
94 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
95 	u32(*_read32)(struct intf_hdl *pintfhdl, u32 addr);
96 	_read32 = pintfhdl->io_ops._read32;
97 
98 	r_val = _read32(pintfhdl, addr);
99 	return rtw_le32_to_cpu(r_val);
100 
101 }
102 
_rtw_write8(_adapter * adapter,u32 addr,u8 val)103 int _rtw_write8(_adapter *adapter, u32 addr, u8 val)
104 {
105 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
106 	struct io_priv *pio_priv = &adapter->iopriv;
107 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
108 	int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
109 	int ret;
110 	_write8 = pintfhdl->io_ops._write8;
111 
112 	ret = _write8(pintfhdl, addr, val);
113 
114 	return RTW_STATUS_CODE(ret);
115 }
_rtw_write16(_adapter * adapter,u32 addr,u16 val)116 int _rtw_write16(_adapter *adapter, u32 addr, u16 val)
117 {
118 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
119 	struct io_priv *pio_priv = &adapter->iopriv;
120 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
121 	int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
122 	int ret;
123 	_write16 = pintfhdl->io_ops._write16;
124 
125 	val = rtw_cpu_to_le16(val);
126 	ret = _write16(pintfhdl, addr, val);
127 
128 	return RTW_STATUS_CODE(ret);
129 }
_rtw_write32(_adapter * adapter,u32 addr,u32 val)130 int _rtw_write32(_adapter *adapter, u32 addr, u32 val)
131 {
132 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
133 	struct io_priv *pio_priv = &adapter->iopriv;
134 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
135 	int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
136 	int ret;
137 	_write32 = pintfhdl->io_ops._write32;
138 
139 	val = rtw_cpu_to_le32(val);
140 	ret = _write32(pintfhdl, addr, val);
141 
142 	return RTW_STATUS_CODE(ret);
143 }
144 
_rtw_writeN(_adapter * adapter,u32 addr,u32 length,u8 * pdata)145 int _rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *pdata)
146 {
147 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
148 	struct io_priv *pio_priv = &adapter->iopriv;
149 	struct	intf_hdl	*pintfhdl = (struct intf_hdl *)(&(pio_priv->intf));
150 	int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata);
151 	int ret;
152 	_writeN = pintfhdl->io_ops._writeN;
153 
154 	ret = _writeN(pintfhdl, addr, length, pdata);
155 
156 	return RTW_STATUS_CODE(ret);
157 }
158 
159 #ifdef CONFIG_SDIO_HCI
_rtw_sd_f0_read8(_adapter * adapter,u32 addr)160 u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr)
161 {
162 	u8 r_val = 0x00;
163 	struct io_priv *pio_priv = &adapter->iopriv;
164 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
165 	u8(*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr);
166 
167 	_sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8;
168 
169 	if (_sd_f0_read8)
170 		r_val = _sd_f0_read8(pintfhdl, addr);
171 	else
172 		RTW_WARN(FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
173 
174 	return r_val;
175 }
176 
177 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
_rtw_sd_iread8(_adapter * adapter,u32 addr)178 u8 _rtw_sd_iread8(_adapter *adapter, u32 addr)
179 {
180 	u8 r_val = 0x00;
181 	struct io_priv *pio_priv = &adapter->iopriv;
182 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
183 	u8(*_sd_iread8)(struct intf_hdl *pintfhdl, u32 addr);
184 
185 	_sd_iread8 = pintfhdl->io_ops._sd_iread8;
186 
187 	if (_sd_iread8)
188 		r_val = _sd_iread8(pintfhdl, addr);
189 	else
190 		RTW_ERR(FUNC_ADPT_FMT" _sd_iread8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
191 
192 	return r_val;
193 }
194 
_rtw_sd_iread16(_adapter * adapter,u32 addr)195 u16 _rtw_sd_iread16(_adapter *adapter, u32 addr)
196 {
197 	u16 r_val = 0x00;
198 	struct io_priv *pio_priv = &adapter->iopriv;
199 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
200 	u16(*_sd_iread16)(struct intf_hdl *pintfhdl, u32 addr);
201 
202 	_sd_iread16 = pintfhdl->io_ops._sd_iread16;
203 
204 	if (_sd_iread16)
205 		r_val = _sd_iread16(pintfhdl, addr);
206 	else
207 		RTW_ERR(FUNC_ADPT_FMT" _sd_iread16 callback is NULL\n", FUNC_ADPT_ARG(adapter));
208 
209 	return r_val;
210 }
211 
_rtw_sd_iread32(_adapter * adapter,u32 addr)212 u32 _rtw_sd_iread32(_adapter *adapter, u32 addr)
213 {
214 	u32 r_val = 0x00;
215 	struct io_priv *pio_priv = &adapter->iopriv;
216 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
217 	u32(*_sd_iread32)(struct intf_hdl *pintfhdl, u32 addr);
218 
219 	_sd_iread32 = pintfhdl->io_ops._sd_iread32;
220 
221 	if (_sd_iread32)
222 		r_val = _sd_iread32(pintfhdl, addr);
223 	else
224 		RTW_ERR(FUNC_ADPT_FMT" _sd_iread32 callback is NULL\n", FUNC_ADPT_ARG(adapter));
225 
226 	return r_val;
227 }
228 
_rtw_sd_iwrite8(_adapter * adapter,u32 addr,u8 val)229 int _rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val)
230 {
231 	struct io_priv *pio_priv = &adapter->iopriv;
232 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
233 	int (*_sd_iwrite8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
234 	int ret = -1;
235 
236 	_sd_iwrite8 = pintfhdl->io_ops._sd_iwrite8;
237 
238 	if (_sd_iwrite8)
239 		ret = _sd_iwrite8(pintfhdl, addr, val);
240 	else
241 		RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite8 callback is NULL\n", FUNC_ADPT_ARG(adapter));
242 
243 	return RTW_STATUS_CODE(ret);
244 }
245 
_rtw_sd_iwrite16(_adapter * adapter,u32 addr,u16 val)246 int _rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val)
247 {
248 	struct io_priv *pio_priv = &adapter->iopriv;
249 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
250 	int (*_sd_iwrite16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
251 	int ret = -1;
252 
253 	_sd_iwrite16 = pintfhdl->io_ops._sd_iwrite16;
254 
255 	if (_sd_iwrite16)
256 		ret = _sd_iwrite16(pintfhdl, addr, val);
257 	else
258 		RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite16 callback is NULL\n", FUNC_ADPT_ARG(adapter));
259 
260 	return RTW_STATUS_CODE(ret);
261 }
_rtw_sd_iwrite32(_adapter * adapter,u32 addr,u32 val)262 int _rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val)
263 {
264 	struct io_priv *pio_priv = &adapter->iopriv;
265 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
266 	int (*_sd_iwrite32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
267 	int ret = -1;
268 
269 	_sd_iwrite32 = pintfhdl->io_ops._sd_iwrite32;
270 
271 	if (_sd_iwrite32)
272 		ret = _sd_iwrite32(pintfhdl, addr, val);
273 	else
274 		RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite32 callback is NULL\n", FUNC_ADPT_ARG(adapter));
275 
276 	return RTW_STATUS_CODE(ret);
277 }
278 
279 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
280 
281 #endif /* CONFIG_SDIO_HCI */
282 
_rtw_write8_async(_adapter * adapter,u32 addr,u8 val)283 int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)
284 {
285 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
286 	struct io_priv *pio_priv = &adapter->iopriv;
287 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
288 	int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);
289 	int ret;
290 	_write8_async = pintfhdl->io_ops._write8_async;
291 
292 	ret = _write8_async(pintfhdl, addr, val);
293 
294 	return RTW_STATUS_CODE(ret);
295 }
_rtw_write16_async(_adapter * adapter,u32 addr,u16 val)296 int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)
297 {
298 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
299 	struct io_priv *pio_priv = &adapter->iopriv;
300 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
301 	int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);
302 	int ret;
303 	_write16_async = pintfhdl->io_ops._write16_async;
304 	val = rtw_cpu_to_le16(val);
305 	ret = _write16_async(pintfhdl, addr, val);
306 
307 	return RTW_STATUS_CODE(ret);
308 }
_rtw_write32_async(_adapter * adapter,u32 addr,u32 val)309 int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)
310 {
311 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
312 	struct io_priv *pio_priv = &adapter->iopriv;
313 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
314 	int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);
315 	int ret;
316 	_write32_async = pintfhdl->io_ops._write32_async;
317 	val = rtw_cpu_to_le32(val);
318 	ret = _write32_async(pintfhdl, addr, val);
319 
320 	return RTW_STATUS_CODE(ret);
321 }
322 
_rtw_read_mem(_adapter * adapter,u32 addr,u32 cnt,u8 * pmem)323 void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
324 {
325 	void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
326 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
327 	struct io_priv *pio_priv = &adapter->iopriv;
328 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
329 
330 
331 	if (RTW_CANNOT_RUN(adapter)) {
332 		return;
333 	}
334 
335 	_read_mem = pintfhdl->io_ops._read_mem;
336 
337 	_read_mem(pintfhdl, addr, cnt, pmem);
338 
339 
340 }
341 
_rtw_write_mem(_adapter * adapter,u32 addr,u32 cnt,u8 * pmem)342 void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
343 {
344 	void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
345 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
346 	struct io_priv *pio_priv = &adapter->iopriv;
347 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
348 
349 
350 	_write_mem = pintfhdl->io_ops._write_mem;
351 
352 	_write_mem(pintfhdl, addr, cnt, pmem);
353 
354 
355 }
356 
_rtw_read_port(_adapter * adapter,u32 addr,u32 cnt,u8 * pmem)357 void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
358 {
359 	u32(*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
360 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
361 	struct io_priv *pio_priv = &adapter->iopriv;
362 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
363 
364 
365 	if (RTW_CANNOT_RUN(adapter)) {
366 		return;
367 	}
368 
369 	_read_port = pintfhdl->io_ops._read_port;
370 
371 	_read_port(pintfhdl, addr, cnt, pmem);
372 
373 
374 }
375 
_rtw_read_port_cancel(_adapter * adapter)376 void _rtw_read_port_cancel(_adapter *adapter)
377 {
378 	void (*_read_port_cancel)(struct intf_hdl *pintfhdl);
379 	struct io_priv *pio_priv = &adapter->iopriv;
380 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
381 
382 	_read_port_cancel = pintfhdl->io_ops._read_port_cancel;
383 
384 	RTW_DISABLE_FUNC(adapter, DF_RX_BIT);
385 
386 	if (_read_port_cancel)
387 		_read_port_cancel(pintfhdl);
388 }
389 
_rtw_write_port(_adapter * adapter,u32 addr,u32 cnt,u8 * pmem)390 u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)
391 {
392 	u32(*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);
393 	/* struct	io_queue  	*pio_queue = (struct io_queue *)adapter->pio_queue; */
394 	struct io_priv *pio_priv = &adapter->iopriv;
395 	struct	intf_hdl		*pintfhdl = &(pio_priv->intf);
396 	u32 ret = _SUCCESS;
397 
398 
399 	_write_port = pintfhdl->io_ops._write_port;
400 
401 	ret = _write_port(pintfhdl, addr, cnt, pmem);
402 
403 
404 	return ret;
405 }
406 
_rtw_write_port_and_wait(_adapter * adapter,u32 addr,u32 cnt,u8 * pmem,int timeout_ms)407 u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)
408 {
409 	int ret = _SUCCESS;
410 	struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;
411 	struct submit_ctx sctx;
412 
413 	rtw_sctx_init(&sctx, timeout_ms);
414 	pxmitbuf->sctx = &sctx;
415 
416 	ret = _rtw_write_port(adapter, addr, cnt, pmem);
417 
418 	if (ret == _SUCCESS) {
419 		ret = rtw_sctx_wait(&sctx, __func__);
420 
421 		if (ret != _SUCCESS)
422 			pxmitbuf->sctx = NULL;
423 	}
424 
425 	return ret;
426 }
427 
_rtw_write_port_cancel(_adapter * adapter)428 void _rtw_write_port_cancel(_adapter *adapter)
429 {
430 	void (*_write_port_cancel)(struct intf_hdl *pintfhdl);
431 	struct io_priv *pio_priv = &adapter->iopriv;
432 	struct intf_hdl *pintfhdl = &(pio_priv->intf);
433 
434 	_write_port_cancel = pintfhdl->io_ops._write_port_cancel;
435 
436 	RTW_DISABLE_FUNC(adapter, DF_TX_BIT);
437 
438 	if (_write_port_cancel)
439 		_write_port_cancel(pintfhdl);
440 }
rtw_init_io_priv(_adapter * padapter,void (* set_intf_ops)(_adapter * padapter,struct _io_ops * pops))441 int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter, struct _io_ops *pops))
442 {
443 	struct io_priv	*piopriv = &padapter->iopriv;
444 	struct intf_hdl *pintf = &piopriv->intf;
445 
446 	if (set_intf_ops == NULL)
447 		return _FAIL;
448 
449 	piopriv->padapter = padapter;
450 	pintf->padapter = padapter;
451 	pintf->pintf_dev = adapter_to_dvobj(padapter);
452 
453 	set_intf_ops(padapter, &pintf->io_ops);
454 
455 	return _SUCCESS;
456 }
457 
458 /*
459 * Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR
460 * @return _TRUE:
461 * @return _FALSE:
462 */
rtw_inc_and_chk_continual_io_error(struct dvobj_priv * dvobj)463 int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)
464 {
465 	int ret = _FALSE;
466 	int value;
467 
468 	value = ATOMIC_INC_RETURN(&dvobj->continual_io_error);
469 	if (value > MAX_CONTINUAL_IO_ERR) {
470 		RTW_INFO("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR);
471 		ret = _TRUE;
472 	} else {
473 		/* RTW_INFO("[dvobj:%p] continual_io_error:%d\n", dvobj, value); */
474 	}
475 	return ret;
476 }
477 
478 /*
479 * Set the continual_io_error of this @param dvobjprive to 0
480 */
rtw_reset_continual_io_error(struct dvobj_priv * dvobj)481 void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)
482 {
483 	ATOMIC_SET(&dvobj->continual_io_error, 0);
484 }
485 
486 #ifdef DBG_IO
487 #define RTW_IO_SNIFF_TYPE_RANGE	0 /* specific address range is accessed */
488 #define RTW_IO_SNIFF_TYPE_VALUE	1 /* value match for sniffed range */
489 
490 struct rtw_io_sniff_ent {
491 	u8 chip;
492 	u8 hci;
493 	u32 addr;
494 	u8 type;
495 	union {
496 		u32 end_addr;
497 		struct {
498 			u32 mask;
499 			u32 val;
500 			bool equal;
501 		} vm; /* value match */
502 	} u;
503 	bool trace;
504 	char *tag;
505 	bool (*assert_protsel)(_adapter *adapter, u32 addr, u8 len);
506 };
507 
508 #define RTW_IO_SNIFF_RANGE_ENT(_chip, _hci, _addr, _end_addr, _trace, _tag) \
509 	{.chip = _chip, .hci = _hci, .addr = _addr, .u.end_addr = _end_addr, .trace = _trace, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_RANGE,}
510 
511 #define RTW_IO_SNIFF_RANGE_PROT_ENT(_chip, _hci, _addr, _end_addr, _assert_protsel, _tag) \
512 	{.chip = _chip, .hci = _hci, .addr = _addr, .u.end_addr = _end_addr, .trace = 1, .assert_protsel = _assert_protsel, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_RANGE,}
513 
514 #define RTW_IO_SNIFF_VALUE_ENT(_chip, _hci, _addr, _mask, _val, _equal, _trace, _tag) \
515 	{.chip = _chip, .hci = _hci, .addr = _addr, .u.vm.mask = _mask, .u.vm.val = _val, .u.vm.equal = _equal, .trace = _trace, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_VALUE,}
516 
517 /* part or all sniffed range is enabled (not all 0) */
518 #define RTW_IO_SNIFF_EN_ENT(_chip, _hci, _addr, _mask, _trace, _tag) \
519 	{.chip = _chip, .hci = _hci, .addr = _addr, .u.vm.mask = _mask, .u.vm.val = 0, .u.vm.equal = 0, .trace = _trace, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_VALUE,}
520 
521 /* part or all sniffed range is disabled (not all 1) */
522 #define RTW_IO_SNIFF_DIS_ENT(_chip, _hci, _addr, _mask, _trace, _tag) \
523 	{.chip = _chip, .hci = _hci, .addr = _addr, .u.vm.mask = _mask, .u.vm.val = 0xFFFFFFFF, .u.vm.equal = 0, .trace = _trace, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_VALUE,}
524 
525 const struct rtw_io_sniff_ent read_sniff[] = {
526 #ifdef DBG_IO_HCI_EN_CHK
527 	RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_SDIO, 0x02, 0x1FC, 1, "SDIO 0x02[8:2] not all 0"),
528 	RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_USB, 0x02, 0x1E0, 1, "USB 0x02[8:5] not all 0"),
529 	RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_PCIE, 0x02, 0x01C, 1, "PCI 0x02[4:2] not all 0"),
530 #endif
531 #ifdef DBG_IO_SNIFF_EXAMPLE
532 	RTW_IO_SNIFF_RANGE_ENT(MAX_CHIP_TYPE, 0, 0x522, 0x522, 0, "read TXPAUSE"),
533 	RTW_IO_SNIFF_DIS_ENT(MAX_CHIP_TYPE, 0, 0x02, 0x3, 0, "0x02[1:0] not all 1"),
534 #endif
535 #ifdef DBG_IO_PROT_SEL
536 	RTW_IO_SNIFF_RANGE_PROT_ENT(MAX_CHIP_TYPE, 0, 0x1501, 0x1513, rtw_assert_protsel_port, "protsel port"),
537 	RTW_IO_SNIFF_RANGE_PROT_ENT(MAX_CHIP_TYPE, 0, 0x153a, 0x153b, rtw_assert_protsel_atimdtim, "protsel atimdtim"),
538 #endif
539 };
540 
541 const int read_sniff_num = sizeof(read_sniff) / sizeof(struct rtw_io_sniff_ent);
542 
543 const struct rtw_io_sniff_ent write_sniff[] = {
544 #ifdef DBG_IO_HCI_EN_CHK
545 	RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_SDIO, 0x02, 0x1FC, 1, "SDIO 0x02[8:2] not all 0"),
546 	RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_USB, 0x02, 0x1E0, 1, "USB 0x02[8:5] not all 0"),
547 	RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_PCIE, 0x02, 0x01C, 1, "PCI 0x02[4:2] not all 0"),
548 #endif
549 #ifdef DBG_IO_8822C_1TX_PATH_EN
550 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x1a04, 0xc0000000, 0x02, 1, 0, "write tx_path_en_cck A enabled"),
551 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x1a04, 0xc0000000, 0x01, 1, 0, "write tx_path_en_cck B enabled"),
552 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x1a04, 0xc0000000, 0x03, 1, 1, "write tx_path_en_cck AB enabled"),
553 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x03, 0x01, 1, 0, "write tx_path_en_ofdm_1sts A enabled"),
554 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x03, 0x02, 1, 0, "write tx_path_en_ofdm_1sts B enabled"),
555 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x03, 0x03, 1, 1, "write tx_path_en_ofdm_1sts AB enabled"),
556 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x30, 0x01, 1, 0, "write tx_path_en_ofdm_2sts A enabled"),
557 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x30, 0x02, 1, 0, "write tx_path_en_ofdm_2sts B enabled"),
558 	RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x30, 0x03, 1, 1, "write tx_path_en_ofdm_2sts AB enabled"),
559 #endif
560 #ifdef DBG_IO_SNIFF_EXAMPLE
561 	RTW_IO_SNIFF_RANGE_ENT(MAX_CHIP_TYPE, 0, 0x522, 0x522, 0, "write TXPAUSE"),
562 	RTW_IO_SNIFF_DIS_ENT(MAX_CHIP_TYPE, 0, 0x02, 0x3, 0, "0x02[1:0] not all 1"),
563 #endif
564 };
565 
566 const int write_sniff_num = sizeof(write_sniff) / sizeof(struct rtw_io_sniff_ent);
567 
match_io_sniff_ranges(_adapter * adapter,const struct rtw_io_sniff_ent * sniff,int i,u32 addr,u16 len)568 static bool match_io_sniff_ranges(_adapter *adapter
569 	, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u16 len)
570 {
571 
572 	/* check if IO range after sniff end address */
573 	if (addr > sniff->u.end_addr)
574 		return 0;
575 
576 	if (sniff->assert_protsel &&
577 	    sniff->assert_protsel(adapter, addr, len))
578 		return 0;
579 
580 	return 1;
581 }
582 
match_io_sniff_value(_adapter * adapter,const struct rtw_io_sniff_ent * sniff,int i,u32 addr,u8 len,u32 val)583 static bool match_io_sniff_value(_adapter *adapter
584 	, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)
585 {
586 	u8 sniff_len;
587 	s8 mask_shift;
588 	u32 mask;
589 	s8 value_shift;
590 	u32 value;
591 	bool ret = 0;
592 
593 	/* check if IO range after sniff end address */
594 	sniff_len = 4;
595 	while (!(sniff->u.vm.mask & (0xFF << ((sniff_len - 1) * 8)))) {
596 		sniff_len--;
597 		if (sniff_len == 0)
598 			goto exit;
599 	}
600 	if (sniff->addr + sniff_len <= addr)
601 		goto exit;
602 
603 	/* align to IO addr */
604 	mask_shift = (sniff->addr - addr) * 8;
605 	value_shift = mask_shift + bitshift(sniff->u.vm.mask);
606 	if (mask_shift > 0)
607 		mask = sniff->u.vm.mask << mask_shift;
608 	else if (mask_shift < 0)
609 		mask = sniff->u.vm.mask >> -mask_shift;
610 	else
611 		mask = sniff->u.vm.mask;
612 
613 	if (value_shift > 0)
614 		value = sniff->u.vm.val << value_shift;
615 	else if (mask_shift < 0)
616 		value = sniff->u.vm.val >> -value_shift;
617 	else
618 		value = sniff->u.vm.val;
619 
620 	if ((sniff->u.vm.equal && (mask & val) == (mask & value))
621 		|| (!sniff->u.vm.equal && (mask & val) != (mask & value))
622 	) {
623 		ret = 1;
624 		if (0)
625 			RTW_INFO(FUNC_ADPT_FMT" addr:0x%x len:%u val:0x%x (i:%d sniff_len:%u m_shift:%d mask:0x%x v_shifd:%d value:0x%x equal:%d)\n"
626 				, FUNC_ADPT_ARG(adapter), addr, len, val, i, sniff_len, mask_shift, mask, value_shift, value, sniff->u.vm.equal);
627 	}
628 
629 exit:
630 	return ret;
631 }
632 
match_io_sniff(_adapter * adapter,const struct rtw_io_sniff_ent * sniff,int i,u32 addr,u8 len,u32 val)633 static bool match_io_sniff(_adapter *adapter
634 	, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)
635 {
636 	bool ret = 0;
637 
638 	if (sniff->chip != MAX_CHIP_TYPE
639 		&& sniff->chip != rtw_get_chip_type(adapter))
640 		goto exit;
641 	if (sniff->hci
642 		&& !(sniff->hci & rtw_get_intf_type(adapter)))
643 		goto exit;
644 	if (sniff->addr >= addr + len) /* IO range below sniff start address */
645 		goto exit;
646 
647 	switch (sniff->type) {
648 	case RTW_IO_SNIFF_TYPE_RANGE:
649 		ret = match_io_sniff_ranges(adapter, sniff, i, addr, len);
650 		break;
651 	case RTW_IO_SNIFF_TYPE_VALUE:
652 		if (len == 1 || len == 2 || len == 4)
653 			ret = match_io_sniff_value(adapter, sniff, i, addr, len, val);
654 		break;
655 	default:
656 		rtw_warn_on(1);
657 		break;
658 	}
659 
660 exit:
661 	return ret;
662 }
663 
match_read_sniff(_adapter * adapter,u32 addr,u16 len,u32 val)664 u32 match_read_sniff(_adapter *adapter, u32 addr, u16 len, u32 val)
665 {
666 	int i;
667 	bool trace = 0;
668 	u32 match = 0;
669 
670 	for (i = 0; i < read_sniff_num; i++) {
671 		if (match_io_sniff(adapter, &read_sniff[i], i, addr, len, val)) {
672 			match++;
673 			trace |= read_sniff[i].trace;
674 			if (read_sniff[i].tag)
675 				RTW_INFO("DBG_IO TAG %s\n", read_sniff[i].tag);
676 		}
677 	}
678 
679 	rtw_warn_on(trace);
680 
681 	return match;
682 }
683 
match_write_sniff(_adapter * adapter,u32 addr,u16 len,u32 val)684 u32 match_write_sniff(_adapter *adapter, u32 addr, u16 len, u32 val)
685 {
686 	int i;
687 	bool trace = 0;
688 	u32 match = 0;
689 
690 	for (i = 0; i < write_sniff_num; i++) {
691 		if (match_io_sniff(adapter, &write_sniff[i], i, addr, len, val)) {
692 			match++;
693 			trace |= write_sniff[i].trace;
694 			if (write_sniff[i].tag)
695 				RTW_INFO("DBG_IO TAG %s\n", write_sniff[i].tag);
696 		}
697 	}
698 
699 	rtw_warn_on(trace);
700 
701 	return match;
702 }
703 
704 struct rf_sniff_ent {
705 	u8 path;
706 	u16 reg;
707 	u32 mask;
708 };
709 
710 struct rf_sniff_ent rf_read_sniff_ranges[] = {
711 	/* example for all path addr 0x55 with all RF Reg mask */
712 	/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
713 };
714 
715 struct rf_sniff_ent rf_write_sniff_ranges[] = {
716 	/* example for all path addr 0x55 with all RF Reg mask */
717 	/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
718 };
719 
720 int rf_read_sniff_num = sizeof(rf_read_sniff_ranges) / sizeof(struct rf_sniff_ent);
721 int rf_write_sniff_num = sizeof(rf_write_sniff_ranges) / sizeof(struct rf_sniff_ent);
722 
match_rf_read_sniff_ranges(_adapter * adapter,u8 path,u32 addr,u32 mask)723 bool match_rf_read_sniff_ranges(_adapter *adapter, u8 path, u32 addr, u32 mask)
724 {
725 	int i;
726 
727 	for (i = 0; i < rf_read_sniff_num; i++) {
728 		if (rf_read_sniff_ranges[i].path == MAX_RF_PATH || rf_read_sniff_ranges[i].path == path)
729 			if (addr == rf_read_sniff_ranges[i].reg && (mask & rf_read_sniff_ranges[i].mask))
730 				return _TRUE;
731 	}
732 
733 	return _FALSE;
734 }
735 
match_rf_write_sniff_ranges(_adapter * adapter,u8 path,u32 addr,u32 mask)736 bool match_rf_write_sniff_ranges(_adapter *adapter, u8 path, u32 addr, u32 mask)
737 {
738 	int i;
739 
740 	for (i = 0; i < rf_write_sniff_num; i++) {
741 		if (rf_write_sniff_ranges[i].path == MAX_RF_PATH || rf_write_sniff_ranges[i].path == path)
742 			if (addr == rf_write_sniff_ranges[i].reg && (mask & rf_write_sniff_ranges[i].mask))
743 				return _TRUE;
744 	}
745 
746 	return _FALSE;
747 }
748 
dbg_rtw_reg_read_monitor(_adapter * adapter,u32 addr,u32 len,u32 val,const char * caller,const int line)749 void dbg_rtw_reg_read_monitor(_adapter *adapter, u32 addr, u32 len, u32 val, const char *caller, const int line)
750 {
751 	if (match_read_sniff(adapter, addr, len, val)) {
752 		switch (len) {
753 		case 1:
754 			RTW_INFO("DBG_IO %s:%d read8(0x%04x) return 0x%02x\n"
755 				, caller, line, addr, val);
756 			break;
757 		case 2:
758 			RTW_INFO("DBG_IO %s:%d read16(0x%04x) return 0x%04x\n"
759 				, caller, line, addr, val);
760 			break;
761 		case 4:
762 			RTW_INFO("DBG_IO %s:%d read32(0x%04x) return 0x%08x\n"
763 				, caller, line, addr, val);
764 			break;
765 		default:
766 			RTW_INFO("DBG_IO %s:%d readN(0x%04x, %u)\n"
767 				, caller, line, addr, len);
768 		}
769 	}
770 }
771 
dbg_rtw_reg_write_monitor(_adapter * adapter,u32 addr,u32 len,u32 val,const char * caller,const int line)772 void dbg_rtw_reg_write_monitor(_adapter *adapter, u32 addr, u32 len, u32 val, const char *caller, const int line)
773 {
774 	if (match_write_sniff(adapter, addr, len, val)) {
775 		switch (len) {
776 		case 1:
777 			RTW_INFO("DBG_IO %s:%d write8(0x%04x, 0x%02x)\n"
778 				, caller, line, addr, val);
779 			break;
780 		case 2:
781 			RTW_INFO("DBG_IO %s:%d write16(0x%04x, 0x%04x)\n"
782 				, caller, line, addr, val);
783 			break;
784 		case 4:
785 			RTW_INFO("DBG_IO %s:%d write32(0x%04x, 0x%08x)\n"
786 				, caller, line, addr, val);
787 			break;
788 		default:
789 			RTW_INFO("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n"
790 				, caller, line, addr, len);
791 		}
792 	}
793 }
794 
dbg_rtw_read8(_adapter * adapter,u32 addr,const char * caller,const int line)795 u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
796 {
797 	u8 val = _rtw_read8(adapter, addr);
798 
799 	if (match_read_sniff(adapter, addr, 1, val)) {
800 		RTW_INFO("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n"
801 			, caller, line, addr, val);
802 	}
803 
804 	return val;
805 }
806 
dbg_rtw_read16(_adapter * adapter,u32 addr,const char * caller,const int line)807 u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)
808 {
809 	u16 val = _rtw_read16(adapter, addr);
810 
811 	if (match_read_sniff(adapter, addr, 2, val)) {
812 		RTW_INFO("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n"
813 			, caller, line, addr, val);
814 	}
815 
816 	return val;
817 }
818 
dbg_rtw_read32(_adapter * adapter,u32 addr,const char * caller,const int line)819 u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)
820 {
821 	u32 val = _rtw_read32(adapter, addr);
822 
823 	if (match_read_sniff(adapter, addr, 4, val)) {
824 		RTW_INFO("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n"
825 			, caller, line, addr, val);
826 	}
827 
828 	return val;
829 }
830 
dbg_rtw_write8(_adapter * adapter,u32 addr,u8 val,const char * caller,const int line)831 int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
832 {
833 	if (match_write_sniff(adapter, addr, 1, val)) {
834 		RTW_INFO("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n"
835 			, caller, line, addr, val);
836 	}
837 
838 	return _rtw_write8(adapter, addr, val);
839 }
dbg_rtw_write16(_adapter * adapter,u32 addr,u16 val,const char * caller,const int line)840 int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
841 {
842 	if (match_write_sniff(adapter, addr, 2, val)) {
843 		RTW_INFO("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n"
844 			, caller, line, addr, val);
845 	}
846 
847 	return _rtw_write16(adapter, addr, val);
848 }
dbg_rtw_write32(_adapter * adapter,u32 addr,u32 val,const char * caller,const int line)849 int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
850 {
851 	if (match_write_sniff(adapter, addr, 4, val)) {
852 		RTW_INFO("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n"
853 			, caller, line, addr, val);
854 	}
855 
856 	return _rtw_write32(adapter, addr, val);
857 }
dbg_rtw_writeN(_adapter * adapter,u32 addr,u32 length,u8 * data,const char * caller,const int line)858 int dbg_rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *data, const char *caller, const int line)
859 {
860 	if (match_write_sniff(adapter, addr, length, 0)) {
861 		RTW_INFO("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n"
862 			, caller, line, addr, length);
863 	}
864 
865 	return _rtw_writeN(adapter, addr, length, data);
866 }
867 
868 #ifdef CONFIG_SDIO_HCI
dbg_rtw_sd_f0_read8(_adapter * adapter,u32 addr,const char * caller,const int line)869 u8 dbg_rtw_sd_f0_read8(_adapter *adapter, u32 addr, const char *caller, const int line)
870 {
871 	u8 val = _rtw_sd_f0_read8(adapter, addr);
872 
873 #if 0
874 	if (match_read_sniff(adapter, addr, 1, val)) {
875 		RTW_INFO("DBG_IO %s:%d rtw_sd_f0_read8(0x%04x) return 0x%02x\n"
876 			, caller, line, addr, val);
877 	}
878 #endif
879 
880 	return val;
881 }
882 
883 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
dbg_rtw_sd_iread8(_adapter * adapter,u32 addr,const char * caller,const int line)884 u8 dbg_rtw_sd_iread8(_adapter *adapter, u32 addr, const char *caller, const int line)
885 {
886 	u8 val = rtw_sd_iread8(adapter, addr);
887 
888 	if (match_read_sniff(adapter, addr, 1, val)) {
889 		RTW_INFO("DBG_IO %s:%d rtw_sd_iread8(0x%04x) return 0x%02x\n"
890 			, caller, line, addr, val);
891 	}
892 
893 	return val;
894 }
895 
dbg_rtw_sd_iread16(_adapter * adapter,u32 addr,const char * caller,const int line)896 u16 dbg_rtw_sd_iread16(_adapter *adapter, u32 addr, const char *caller, const int line)
897 {
898 	u16 val = _rtw_sd_iread16(adapter, addr);
899 
900 	if (match_read_sniff(adapter, addr, 2, val)) {
901 		RTW_INFO("DBG_IO %s:%d rtw_sd_iread16(0x%04x) return 0x%04x\n"
902 			, caller, line, addr, val);
903 	}
904 
905 	return val;
906 }
907 
dbg_rtw_sd_iread32(_adapter * adapter,u32 addr,const char * caller,const int line)908 u32 dbg_rtw_sd_iread32(_adapter *adapter, u32 addr, const char *caller, const int line)
909 {
910 	u32 val = _rtw_sd_iread32(adapter, addr);
911 
912 	if (match_read_sniff(adapter, addr, 4, val)) {
913 		RTW_INFO("DBG_IO %s:%d rtw_sd_iread32(0x%04x) return 0x%08x\n"
914 			, caller, line, addr, val);
915 	}
916 
917 	return val;
918 }
919 
dbg_rtw_sd_iwrite8(_adapter * adapter,u32 addr,u8 val,const char * caller,const int line)920 int dbg_rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)
921 {
922 	if (match_write_sniff(adapter, addr, 1, val)) {
923 		RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite8(0x%04x, 0x%02x)\n"
924 			, caller, line, addr, val);
925 	}
926 
927 	return _rtw_sd_iwrite8(adapter, addr, val);
928 }
dbg_rtw_sd_iwrite16(_adapter * adapter,u32 addr,u16 val,const char * caller,const int line)929 int dbg_rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)
930 {
931 	if (match_write_sniff(adapter, addr, 2, val)) {
932 		RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite16(0x%04x, 0x%04x)\n"
933 			, caller, line, addr, val);
934 	}
935 
936 	return _rtw_sd_iwrite16(adapter, addr, val);
937 }
dbg_rtw_sd_iwrite32(_adapter * adapter,u32 addr,u32 val,const char * caller,const int line)938 int dbg_rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)
939 {
940 	if (match_write_sniff(adapter, addr, 4, val)) {
941 		RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite32(0x%04x, 0x%08x)\n"
942 			, caller, line, addr, val);
943 	}
944 
945 	return _rtw_sd_iwrite32(adapter, addr, val);
946 }
947 
948 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
949 
950 #endif /* CONFIG_SDIO_HCI */
951 
952 #endif
953