xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852be/phl/hal_g6/hal_io.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2019 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 The purpose of hal_io.c
17 
18 a. provides the API
19 b. provides the protocol engine
20 c. provides the software interface between caller and the hardware interface
21 
22 Compiler Flag Option:
23 1. CONFIG_SDIO_HCI:
24     a. USE_SYNC_IRP:  Only sync operations are provided.
25     b. USE_ASYNC_IRP:Both sync/async operations are provided.
26 
27 2. CONFIG_USB_HCI:
28    a. USE_ASYNC_IRP: Both sync/async operations are provided.
29 
30 3. CONFIG_CFIO_HCI:
31    b. USE_SYNC_IRP: Only sync operations are provided.
32 
33 Only sync read/rtw_write_mem operations are provided.
34 */
35 
36 #define _HAL_IO_C_
37 #include "hal_headers.h"
38 
_hal_read8(struct rtw_hal_com_t * hal,u32 addr)39 u8 _hal_read8(struct rtw_hal_com_t *hal, u32 addr)
40 {
41 	u8 r_val;
42 	struct hal_io_priv *io_priv = &hal->iopriv;
43 	u8(*_read8)(struct rtw_hal_com_t *hal, u32 addr);
44 
45 	#ifdef DBG_PHL_MAC_REG_RW
46 	if (rtw_hal_mac_reg_chk(hal, addr) == false) {
47 		r_val = 0xEA;
48 		return r_val;
49 	}
50 	#endif
51 
52 	_read8 = io_priv->io_ops._read8;
53 	r_val = _read8(hal, addr);
54 	return r_val;
55 }
56 
_hal_read16(struct rtw_hal_com_t * hal,u32 addr)57 u16 _hal_read16(struct rtw_hal_com_t *hal, u32 addr)
58 {
59 	u16 r_val;
60 	struct hal_io_priv *io_priv = &hal->iopriv;
61 	u16(*_read16)(struct rtw_hal_com_t *hal, u32 addr);
62 
63 	#ifdef DBG_PHL_MAC_REG_RW
64 	if (rtw_hal_mac_reg_chk(hal, addr) == false) {
65 		r_val = 0xEAEA;
66 		return r_val;
67 	}
68 	#endif
69 
70 	_read16 = io_priv->io_ops._read16;
71 	r_val = _read16(hal, addr);
72 	return r_val;
73 }
74 
_hal_read32(struct rtw_hal_com_t * hal,u32 addr)75 u32 _hal_read32(struct rtw_hal_com_t *hal, u32 addr)
76 {
77 	u32 r_val;
78 	struct hal_io_priv *io_priv = &hal->iopriv;
79 	u32(*_read32)(struct rtw_hal_com_t *hal, u32 addr);
80 
81 	#ifdef DBG_PHL_MAC_REG_RW
82 	if (rtw_hal_mac_reg_chk(hal, addr) == false) {
83 		r_val = 0xEAEAEAEA;
84 		return r_val;
85 	}
86 	#endif
87 
88 	_read32 = io_priv->io_ops._read32;
89 	r_val = _read32(hal, addr);
90 	return r_val;
91 }
92 
_hal_write8(struct rtw_hal_com_t * hal,u32 addr,u8 val)93 int _hal_write8(struct rtw_hal_com_t *hal, u32 addr, u8 val)
94 {
95 	struct hal_io_priv *io_priv = &hal->iopriv;
96 	int (*_write8)(struct rtw_hal_com_t *hal, u32 addr, u8 val);
97 	#ifdef RTW_WKARD_BUS_WRITE
98 	int (*_write_post_cfg)(struct rtw_hal_com_t *hal, u32 addr,
99 						   u32 value) = NULL;
100 	#endif
101 	int ret;
102 
103 	#ifdef DBG_PHL_MAC_REG_RW
104 	if (rtw_hal_mac_reg_chk(hal, addr) == false)
105 		return 0;
106 	#endif
107 
108 	_write8 = io_priv->io_ops._write8;
109 	ret = _write8(hal, addr, val);
110 
111 	#ifdef RTW_WKARD_BUS_WRITE
112 	_write_post_cfg = io_priv->io_ops._write_post_cfg;
113 	if(NULL != _write_post_cfg) {
114 		ret = _write_post_cfg(hal, addr, val);
115 	}
116 	#endif
117 	return ret;
118 }
_hal_write16(struct rtw_hal_com_t * hal,u32 addr,u16 val)119 int _hal_write16(struct rtw_hal_com_t *hal, u32 addr, u16 val)
120 {
121 	struct hal_io_priv *io_priv = &hal->iopriv;
122 	int (*_write16)(struct rtw_hal_com_t *hal, u32 addr, u16 val);
123 	#ifdef RTW_WKARD_BUS_WRITE
124 	int (*_write_post_cfg)(struct rtw_hal_com_t *hal, u32 addr,
125 						   u32 value) = NULL;
126 	#endif
127 	int ret;
128 
129 	#ifdef DBG_PHL_MAC_REG_RW
130 	if (rtw_hal_mac_reg_chk(hal, addr) == false)
131 		return 0;
132 	#endif
133 
134 	_write16 = io_priv->io_ops._write16;
135 	ret = _write16(hal, addr, val);
136 
137 	#ifdef RTW_WKARD_BUS_WRITE
138 	_write_post_cfg = io_priv->io_ops._write_post_cfg;
139 	if(NULL != _write_post_cfg) {
140 		ret = _write_post_cfg(hal, addr, val);
141 	}
142 	#endif
143 	return ret;
144 }
_hal_write32(struct rtw_hal_com_t * hal,u32 addr,u32 val)145 int _hal_write32(struct rtw_hal_com_t *hal, u32 addr, u32 val)
146 {
147 	struct hal_io_priv *io_priv = &hal->iopriv;
148 	int (*_write32)(struct rtw_hal_com_t *hal, u32 addr, u32 val);
149 	#ifdef RTW_WKARD_BUS_WRITE
150 	int (*_write_post_cfg)(struct rtw_hal_com_t *hal, u32 addr,
151 						   u32 value) = NULL;
152 	#endif
153 	int ret;
154 
155 	#ifdef DBG_PHL_MAC_REG_RW
156 	if (rtw_hal_mac_reg_chk(hal, addr) == false)
157 		return 0;
158 	#endif
159 
160 	_write32 = io_priv->io_ops._write32;
161 	ret = _write32(hal, addr, val);
162 
163 	#ifdef RTW_WKARD_BUS_WRITE
164 	_write_post_cfg = io_priv->io_ops._write_post_cfg;
165 	if(NULL != _write_post_cfg) {
166 		ret = _write_post_cfg(hal, addr, val);
167 	}
168 	#endif
169 	return ret;
170 }
171 
172 #ifdef CONFIG_SDIO_HCI
_hal_sd_f0_read8(struct rtw_hal_com_t * hal,u32 addr)173 u8 _hal_sd_f0_read8(struct rtw_hal_com_t *hal, u32 addr)
174 {
175 	u8 r_val = 0x00;
176 	struct hal_io_priv *io_priv = &hal->iopriv;
177 	u8(*_sd_f0_read8)(struct rtw_hal_com_t *hal, u32 addr);
178 
179 	_sd_f0_read8 = io_priv->io_ops._sd_f0_read8;
180 
181 	if (_sd_f0_read8)
182 		r_val = _sd_f0_read8(hal, addr);
183 
184 	return r_val;
185 }
186 
187 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
_hal_sd_iread8(struct rtw_hal_com_t * hal,u32 addr)188 u8 _hal_sd_iread8(struct rtw_hal_com_t *hal, u32 addr)
189 {
190 	u8 r_val = 0x00;
191 	struct hal_io_priv *io_priv = &hal->iopriv;
192 	u8(*_sd_iread8)(struct rtw_hal_com_t *hal, u32 addr);
193 
194 	_sd_iread8 = io_priv->io_ops._sd_iread8;
195 
196 	if (_sd_iread8)
197 		r_val = _sd_iread8(hal, addr);
198 	return r_val;
199 }
200 
_hal_sd_iread16(struct rtw_hal_com_t * hal,u32 addr)201 u16 _hal_sd_iread16(struct rtw_hal_com_t *hal, u32 addr)
202 {
203 	u16 r_val = 0x00;
204 	struct hal_io_priv *io_priv = &hal->iopriv;
205 	u16(*_sd_iread16)(struct rtw_hal_com_t *hal, u32 addr);
206 
207 	_sd_iread16 = io_priv->io_ops._sd_iread16;
208 
209 	if (_sd_iread16)
210 		r_val = _sd_iread16(hal, addr);
211 	return r_val;
212 }
213 
_hal_sd_iread32(struct rtw_hal_com_t * hal,u32 addr)214 u32 _hal_sd_iread32(struct rtw_hal_com_t *hal, u32 addr)
215 {
216 	u32 r_val = 0x00;
217 	struct hal_io_priv *io_priv = &hal->iopriv;
218 	u32(*_sd_iread32)(struct rtw_hal_com_t *hal, u32 addr);
219 
220 	_sd_iread32 = io_priv->io_ops._sd_iread32;
221 
222 	if (_sd_iread32)
223 		r_val = _sd_iread32(hal, addr);
224 	return r_val;
225 }
226 
_hal_sd_iwrite8(struct rtw_hal_com_t * hal,u32 addr,u8 val)227 int _hal_sd_iwrite8(struct rtw_hal_com_t *hal, u32 addr, u8 val)
228 {
229 	struct hal_io_priv *io_priv = &hal->iopriv;
230 	int (*_sd_iwrite8)(struct rtw_hal_com_t *hal, u32 addr, u8 val);
231 	int ret = -1;
232 
233 	_sd_iwrite8 = io_priv->io_ops._sd_iwrite8;
234 
235 	if (_sd_iwrite8)
236 		ret = _sd_iwrite8(hal, addr, val);
237 
238 	return ret;
239 }
240 
_hal_sd_iwrite16(struct rtw_hal_com_t * hal,u32 addr,u16 val)241 int _hal_sd_iwrite16(struct rtw_hal_com_t *hal, u32 addr, u16 val)
242 {
243 	struct hal_io_priv *io_priv = &hal->iopriv;
244 	int (*_sd_iwrite16)(struct rtw_hal_com_t *hal, u32 addr, u16 val);
245 	int ret = -1;
246 
247 	_sd_iwrite16 = io_priv->io_ops._sd_iwrite16;
248 
249 	if (_sd_iwrite16)
250 		ret = _sd_iwrite16(hal, addr, val);
251 	return ret;
252 }
_hal_sd_iwrite32(struct rtw_hal_com_t * hal,u32 addr,u32 val)253 int _hal_sd_iwrite32(struct rtw_hal_com_t *hal, u32 addr, u32 val)
254 {
255 	struct hal_io_priv *io_priv = &hal->iopriv;
256 	int (*_sd_iwrite32)(struct rtw_hal_com_t *hal, u32 addr, u32 val);
257 	int ret = -1;
258 
259 	_sd_iwrite32 = io_priv->io_ops._sd_iwrite32;
260 
261 	if (_sd_iwrite32)
262 		ret = _sd_iwrite32(hal, addr, val);
263 
264 	return ret;
265 }
266 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
267 #endif /* CONFIG_SDIO_HCI */
268 
hal_init_io_priv(struct rtw_hal_com_t * hal,void (* set_intf_ops)(struct rtw_hal_com_t * hal,struct hal_io_ops * ops))269 u32 hal_init_io_priv(struct rtw_hal_com_t *hal,
270 	void (*set_intf_ops)(struct rtw_hal_com_t *hal, struct hal_io_ops *ops))
271 {
272 	struct hal_io_priv *iopriv = &hal->iopriv;
273 
274 	if (set_intf_ops == NULL)
275 		return RTW_HAL_STATUS_IO_INIT_FAILURE;
276 
277 	#ifdef CONFIG_SDIO_INDIRECT_ACCESS
278 	_os_mutex_init(hal->drv_priv, &iopriv->sd_indirect_access_mutex);
279 	#endif
280 	set_intf_ops(hal, &iopriv->io_ops);
281 
282 	return RTW_HAL_STATUS_SUCCESS;
283 }
hal_deinit_io_priv(struct rtw_hal_com_t * hal)284 u32 hal_deinit_io_priv(struct rtw_hal_com_t *hal)
285 {
286 	#ifdef CONFIG_SDIO_INDIRECT_ACCESS
287 	struct hal_io_priv *iopriv = &hal->iopriv;
288 
289 	_os_mutex_init(hal->drv_priv, &iopriv->sd_indirect_access_mutex);
290 	#endif
291 
292 	return RTW_HAL_STATUS_SUCCESS;
293 }
294 
295 /*******************common IO  APIs *******************/
_bit_shift(u32 mask)296 static inline u32 _bit_shift(u32 mask)
297 {
298 	u32 i;
299 
300 	for (i = 0; i <= 31; i++)
301 		if (mask & BIT(i))
302 			break;
303 
304 	return i;
305 }
306 
hal_read_macreg(struct hal_info_t * hal,u32 offset,u32 bit_mask)307 u32 hal_read_macreg(struct hal_info_t *hal,
308 		u32 offset, u32 bit_mask)
309 {
310 	u32 val = 0, val32, shift;
311 
312 	val32 = hal_read32(hal->hal_com, offset);
313 	if (bit_mask != 0xFFFFFFFF) {
314 		shift = _bit_shift(bit_mask);
315 		val = (val32 & bit_mask) >> shift;
316 		return val;
317 	}
318 	else {
319 		return val32;
320 	}
321 }
hal_write_macreg(struct hal_info_t * hal,u32 offset,u32 bit_mask,u32 data)322 void hal_write_macreg(struct hal_info_t *hal,
323 		u32 offset, u32 bit_mask, u32 data)
324 {
325 	u32 val32, shift;
326 
327 	if (bit_mask != 0xFFFFFFFF) {
328 		val32 = hal_read32(hal->hal_com, offset);
329 		shift = _bit_shift(bit_mask);
330 		data = ((val32 & (~bit_mask)) | ((data << shift) & bit_mask));
331 	}
332 
333 	hal_write32(hal->hal_com, offset, data);
334 }
335 
hal_read_bbreg(struct hal_info_t * hal,u32 offset,u32 bit_mask)336 u32 hal_read_bbreg(struct hal_info_t *hal,
337 		u32 offset, u32 bit_mask)
338 {
339 	u32 val32 = 0;
340 	val32 = rtw_hal_read_bb_reg(hal->hal_com, offset, bit_mask);
341 
342 	return val32;
343 }
344 
hal_write_bbreg(struct hal_info_t * hal,u32 offset,u32 bit_mask,u32 data)345 void hal_write_bbreg(struct hal_info_t *hal,
346 		u32 offset, u32 bit_mask, u32 data)
347 {
348 	rtw_hal_write_bb_reg(hal->hal_com, offset, bit_mask, data);
349 }
350 
hal_read_rfreg(struct hal_info_t * hal,enum rf_path path,u32 offset,u32 bit_mask)351 u32 hal_read_rfreg(struct hal_info_t *hal,
352 		enum rf_path path, u32 offset, u32 bit_mask)
353 {
354 	u32 val32 = 0;
355 	val32 = rtw_hal_read_rf_reg(hal->hal_com, path, offset, bit_mask);
356 #ifdef DBG_IO
357 	if (match_rf_read_sniff_ranges(hal->hal_com, path, offset, bit_mask)) {
358 		PHL_INFO("DBG_IO hal_read_rfreg(%u, 0x%04x, 0x%08x) read:0x%08x(0x%08x)\n"
359 			, path, offset, bit_mask, (val32 << _bit_shift(bit_mask)), val32);
360 	}
361 #endif
362 
363 	return val32;
364 }
hal_write_rfreg(struct hal_info_t * hal,enum rf_path path,u32 offset,u32 bit_mask,u32 data)365 void hal_write_rfreg(struct hal_info_t *hal,
366 		enum rf_path path, u32 offset, u32 bit_mask, u32 data)
367 {
368 	rtw_hal_write_rf_reg(hal->hal_com, path, offset, bit_mask, data);
369 #ifdef DBG_IO
370 	if (match_rf_write_sniff_ranges(hal->hal_com, path, offset, bit_mask)) {
371 		PHL_INFO("DBG_IO hal_write_rfreg(%u, 0x%04x, 0x%08x) write:0x%08x(0x%08x)\n"
372 			, path, offset, bit_mask, (data << _bit_shift(bit_mask)), data);
373 	}
374 #endif
375 }
376 
_cal_bit_shift(u32 bit_mask)377 static u32 _cal_bit_shift(u32 bit_mask)
378 {
379 	u32 i;
380 
381 	for (i = 0; i <= 31; i++) {
382 		if (((bit_mask >> i) &	0x1) == 1)
383 			break;
384 	}
385 
386 	return (i);
387 }
388 
hal_write32_mask(struct rtw_hal_com_t * hal,u16 addr,u32 mask,u32 val)389 void hal_write32_mask(struct rtw_hal_com_t *hal, u16 addr, u32 mask, u32 val)
390 {
391 	u32 original_value, new_value;
392 	u32 bit_shift;
393 
394 	if (mask == 0xFFFFFFFF) {
395 		hal_write32(hal, addr, val);
396 	} else {
397 		original_value = hal_read32(hal, addr);
398 		bit_shift = _cal_bit_shift(mask);
399 		new_value = (((original_value) & (~mask)) | ((val << bit_shift) & mask));
400 		hal_write32(hal, addr, new_value);
401 	}
402 }
403 
404 
405 #ifdef DBG_IO
406 #define RTW_IO_SNIFF_TYPE_RANGE	0 /* specific address range is accessed */
407 #define RTW_IO_SNIFF_TYPE_VALUE	1 /* value match for sniffed range */
408 
409 struct rtw_io_sniff_ent {
410 	u8 chip;
411 	u8 hci;
412 	u32 addr;
413 	u8 type;
414 	union {
415 		u32 end_addr;
416 		struct {
417 			u32 mask;
418 			u32 val;
419 			bool equal;
420 		} vm; /* value match */
421 	} u;
422 	bool trace;
423 	char *tag;
424 };
425 
426 #define RTW_IO_SNIFF_RANGE_ENT(_chip, _hci, _addr, _end_addr, _trace, _tag) \
427 	{.chip = _chip, .hci = _hci, .addr = _addr, .u.end_addr = _end_addr, .trace = _trace, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_RANGE,}
428 
429 #define RTW_IO_SNIFF_VALUE_ENT(_chip, _hci, _addr, _mask, _val, _equal, _trace, _tag) \
430 	{.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,}
431 
432 /* part or all sniffed range is enabled (not all 0) */
433 #define RTW_IO_SNIFF_EN_ENT(_chip, _hci, _addr, _mask, _trace, _tag) \
434 	{.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,}
435 
436 /* part or all sniffed range is disabled (not all 1) */
437 #define RTW_IO_SNIFF_DIS_ENT(_chip, _hci, _addr, _mask, _trace, _tag) \
438 	{.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,}
439 
440 const struct rtw_io_sniff_ent read_sniff[] = {
441 #ifdef DBG_IO_HCI_EN_CHK
442 	RTW_IO_SNIFF_EN_ENT(CHIP_WIFI6_MAX, RTW_HCI_SDIO, 0x02, 0x1FC, 1, "SDIO 0x02[8:2] not all 0"),
443 	RTW_IO_SNIFF_EN_ENT(CHIP_WIFI6_MAX, RTW_HCI_USB, 0x02, 0x1E0, 1, "USB 0x02[8:5] not all 0"),
444 	RTW_IO_SNIFF_EN_ENT(CHIP_WIFI6_MAX, RTW_HCI_PCIE, 0x02, 0x01C, 1, "PCI 0x02[4:2] not all 0"),
445 #endif
446 #ifdef DBG_IO_SNIFF_EXAMPLE
447 	RTW_IO_SNIFF_RANGE_ENT(CHIP_WIFI6_MAX, 0, 0x522, 0x522, 0, "read TXPAUSE"),
448 	RTW_IO_SNIFF_DIS_ENT(CHIP_WIFI6_MAX, 0, 0x02, 0x3, 0, "0x02[1:0] not all 1"),
449 #endif
450 };
451 
452 const int read_sniff_num = sizeof(read_sniff) / sizeof(struct rtw_io_sniff_ent);
453 
454 const struct rtw_io_sniff_ent write_sniff[] = {
455 #ifdef DBG_IO_HCI_EN_CHK
456 	RTW_IO_SNIFF_EN_ENT(CHIP_WIFI6_MAX, RTW_HCI_SDIO, 0x02, 0x1FC, 1, "SDIO 0x02[8:2] not all 0"),
457 	RTW_IO_SNIFF_EN_ENT(CHIP_WIFI6_MAX, RTW_HCI_SDIO, 0x02, 0x1E0, 1, "USB 0x02[8:5] not all 0"),
458 	RTW_IO_SNIFF_EN_ENT(CHIP_WIFI6_MAX, RTW_HCI_SDIO, 0x02, 0x01C, 1, "PCI 0x02[4:2] not all 0"),
459 #endif
460 #ifdef DBG_IO_SNIFF_EXAMPLE
461 	RTW_IO_SNIFF_RANGE_ENT(CHIP_WIFI6_MAX, 0, 0x522, 0x522, 0, "write TXPAUSE"),
462 	RTW_IO_SNIFF_DIS_ENT(CHIP_WIFI6_MAX, 0, 0x02, 0x3, 0, "0x02[1:0] not all 1"),
463 #endif
464 };
465 
466 const int write_sniff_num = sizeof(write_sniff) / sizeof(struct rtw_io_sniff_ent);
467 
match_io_sniff_ranges(struct rtw_hal_com_t * hal,const struct rtw_io_sniff_ent * sniff,int i,u32 addr,u16 len)468 static bool match_io_sniff_ranges(struct rtw_hal_com_t *hal
469 	, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u16 len)
470 {
471 
472 	/* check if IO range after sniff end address */
473 	if (addr > sniff->u.end_addr)
474 		return 0;
475 
476 	return 1;
477 }
478 
match_io_sniff_value(struct rtw_hal_com_t * hal,const struct rtw_io_sniff_ent * sniff,int i,u32 addr,u8 len,u32 val)479 static bool match_io_sniff_value(struct rtw_hal_com_t *hal
480 	, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)
481 {
482 	u8 sniff_len;
483 	s8 mask_shift;
484 	u32 mask;
485 	s8 value_shift;
486 	u32 value;
487 	bool ret = 0;
488 
489 	/* check if IO range after sniff end address */
490 	sniff_len = 4;
491 	while (!(sniff->u.vm.mask & (0xFF << ((sniff_len - 1) * 8)))) {
492 		sniff_len--;
493 		if (sniff_len == 0)
494 			goto exit;
495 	}
496 	if (sniff->addr + sniff_len <= addr)
497 		goto exit;
498 
499 	/* align to IO addr */
500 	mask_shift = (sniff->addr - addr) * 8;
501 	value_shift = mask_shift + bitshift(sniff->u.vm.mask);
502 	if (mask_shift > 0)
503 		mask = sniff->u.vm.mask << mask_shift;
504 	else if (mask_shift < 0)
505 		mask = sniff->u.vm.mask >> -mask_shift;
506 	else
507 		mask = sniff->u.vm.mask;
508 
509 	if (value_shift > 0)
510 		value = sniff->u.vm.val << value_shift;
511 	else if (mask_shift < 0)
512 		value = sniff->u.vm.val >> -value_shift;
513 	else
514 		value = sniff->u.vm.val;
515 
516 	if ((sniff->u.vm.equal && (mask & val) == (mask & value))
517 		|| (!sniff->u.vm.equal && (mask & val) != (mask & value))
518 	) {
519 		ret = 1;
520 		if (0)
521 			PHL_INFO(" 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"
522 				, addr, len, val, i, sniff_len, mask_shift, mask, value_shift, value, sniff->u.vm.equal);
523 	}
524 
525 exit:
526 	return ret;
527 }
528 
match_io_sniff(struct rtw_hal_com_t * hal,const struct rtw_io_sniff_ent * sniff,int i,u32 addr,u8 len,u32 val)529 static bool match_io_sniff(struct rtw_hal_com_t *hal
530 	, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)
531 {
532 	bool ret = 0;
533 
534 	if (sniff->chip != CHIP_WIFI6_MAX
535 		&& sniff->chip != hal_get_chip_id(hal))
536 		goto exit;
537 	/*
538 	if (sniff->hci
539 		&& !(sniff->hci & hal_get_hci_type(hal)))
540 		goto exit;
541 	*/
542 	if (sniff->addr >= addr + len) /* IO range below sniff start address */
543 		goto exit;
544 
545 	switch (sniff->type) {
546 	case RTW_IO_SNIFF_TYPE_RANGE:
547 		ret = match_io_sniff_ranges(hal, sniff, i, addr, len);
548 		break;
549 	case RTW_IO_SNIFF_TYPE_VALUE:
550 		if (len == 1 || len == 2 || len == 4)
551 			ret = match_io_sniff_value(hal, sniff, i, addr, len, val);
552 		break;
553 	default:
554 		/*_os_warn_on(1);*/
555 		break;
556 	}
557 
558 exit:
559 	return ret;
560 }
561 
match_read_sniff(struct rtw_hal_com_t * hal,u32 addr,u16 len,u32 val)562 u32 match_read_sniff(struct rtw_hal_com_t *hal, u32 addr, u16 len, u32 val)
563 {
564 	int i;
565 	bool trace = 0;
566 	u32 match = 0;
567 
568 	for (i = 0; i < read_sniff_num; i++) {
569 		if (match_io_sniff(hal, &read_sniff[i], i, addr, len, val)) {
570 			match++;
571 			trace |= read_sniff[i].trace;
572 			if (read_sniff[i].tag)
573 				PHL_INFO("DBG_IO TAG %s\n", read_sniff[i].tag);
574 		}
575 	}
576 
577 	/*_os_warn_on(trace);*/
578 
579 	return match;
580 }
581 
match_write_sniff(struct rtw_hal_com_t * hal,u32 addr,u16 len,u32 val)582 u32 match_write_sniff(struct rtw_hal_com_t *hal, u32 addr, u16 len, u32 val)
583 {
584 	int i;
585 	bool trace = 0;
586 	u32 match = 0;
587 
588 	for (i = 0; i < write_sniff_num; i++) {
589 		if (match_io_sniff(hal, &write_sniff[i], i, addr, len, val)) {
590 			match++;
591 			trace |= write_sniff[i].trace;
592 			if (write_sniff[i].tag)
593 				PHL_INFO("DBG_IO TAG %s\n", write_sniff[i].tag);
594 		}
595 	}
596 
597 	/*_os_warn_on(trace);*/
598 
599 	return match;
600 }
601 
602 struct rf_sniff_ent {
603 	u8 path;
604 	u16 reg;
605 	u32 mask;
606 };
607 
608 struct rf_sniff_ent rf_read_sniff_ranges[] = {
609 	/* example for all path addr 0x55 with all RF Reg mask */
610 	/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
611 };
612 
613 struct rf_sniff_ent rf_write_sniff_ranges[] = {
614 	/* example for all path addr 0x55 with all RF Reg mask */
615 	/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */
616 };
617 
618 int rf_read_sniff_num = sizeof(rf_read_sniff_ranges) / sizeof(struct rf_sniff_ent);
619 int rf_write_sniff_num = sizeof(rf_write_sniff_ranges) / sizeof(struct rf_sniff_ent);
620 
match_rf_read_sniff_ranges(struct rtw_hal_com_t * hal,u8 path,u32 addr,u32 mask)621 bool match_rf_read_sniff_ranges(struct rtw_hal_com_t *hal, u8 path, u32 addr, u32 mask)
622 {
623 	int i;
624 
625 	for (i = 0; i < rf_read_sniff_num; i++) {
626 		if (rf_read_sniff_ranges[i].path == MAX_RF_PATH ||
627 			rf_read_sniff_ranges[i].path == path)
628 			if ((addr == rf_read_sniff_ranges[i].reg) &&
629 				(mask & rf_read_sniff_ranges[i].mask))
630 				return true;
631 	}
632 
633 	return false;
634 }
635 
match_rf_write_sniff_ranges(struct rtw_hal_com_t * hal,u8 path,u32 addr,u32 mask)636 bool match_rf_write_sniff_ranges(struct rtw_hal_com_t *hal,
637 					u8 path, u32 addr, u32 mask)
638 {
639 	int i;
640 
641 	for (i = 0; i < rf_write_sniff_num; i++) {
642 		if (rf_write_sniff_ranges[i].path == MAX_RF_PATH ||
643 			rf_write_sniff_ranges[i].path == path)
644 			if ((addr == rf_write_sniff_ranges[i].reg) &&
645 				(mask & rf_write_sniff_ranges[i].mask))
646 				return true;
647 	}
648 
649 	return false;
650 }
651 
dbg_hal_read8(struct rtw_hal_com_t * hal,u32 addr,const char * caller,const int line)652 u8 dbg_hal_read8(struct rtw_hal_com_t *hal, u32 addr, const char *caller, const int line)
653 {
654 	u8 val = _hal_read8(hal, addr);
655 
656 	if (match_read_sniff(hal, addr, 1, val)) {
657 		PHL_INFO("DBG_IO %s:%d hal_read8(0x%04x) return 0x%02x\n"
658 			, caller, line, addr, val);
659 	}
660 
661 	return val;
662 }
663 
dbg_hal_read16(struct rtw_hal_com_t * hal,u32 addr,const char * caller,const int line)664 u16 dbg_hal_read16(struct rtw_hal_com_t *hal, u32 addr, const char *caller, const int line)
665 {
666 	u16 val = _hal_read16(hal, addr);
667 
668 	if (match_read_sniff(hal, addr, 2, val)) {
669 		PHL_INFO("DBG_IO %s:%d hal_read16(0x%04x) return 0x%04x\n"
670 			, caller, line, addr, val);
671 	}
672 
673 	return val;
674 }
675 
dbg_hal_read32(struct rtw_hal_com_t * hal,u32 addr,const char * caller,const int line)676 u32 dbg_hal_read32(struct rtw_hal_com_t *hal, u32 addr, const char *caller, const int line)
677 {
678 	u32 val = _hal_read32(hal, addr);
679 
680 	if (match_read_sniff(hal, addr, 4, val)) {
681 		PHL_INFO("DBG_IO %s:%d hal_read32(0x%04x) return 0x%08x\n"
682 			, caller, line, addr, val);
683 	}
684 
685 	return val;
686 }
687 
dbg_hal_write8(struct rtw_hal_com_t * hal,u32 addr,u8 val,const char * caller,const int line)688 int dbg_hal_write8(struct rtw_hal_com_t *hal, u32 addr, u8 val, const char *caller, const int line)
689 {
690 	if (match_write_sniff(hal, addr, 1, val)) {
691 		PHL_INFO("DBG_IO %s:%d hal_write8(0x%04x, 0x%02x)\n"
692 			, caller, line, addr, val);
693 	}
694 
695 	return _hal_write8(hal, addr, val);
696 }
dbg_hal_write16(struct rtw_hal_com_t * hal,u32 addr,u16 val,const char * caller,const int line)697 int dbg_hal_write16(struct rtw_hal_com_t *hal, u32 addr, u16 val, const char *caller, const int line)
698 {
699 	if (match_write_sniff(hal, addr, 2, val)) {
700 		PHL_INFO("DBG_IO %s:%d hal_write16(0x%04x, 0x%04x)\n"
701 			, caller, line, addr, val);
702 	}
703 
704 	return _hal_write16(hal, addr, val);
705 }
dbg_hal_write32(struct rtw_hal_com_t * hal,u32 addr,u32 val,const char * caller,const int line)706 int dbg_hal_write32(struct rtw_hal_com_t *hal, u32 addr, u32 val, const char *caller, const int line)
707 {
708 	if (match_write_sniff(hal, addr, 4, val)) {
709 		PHL_INFO("DBG_IO %s:%d hal_write32(0x%04x, 0x%08x)\n"
710 			, caller, line, addr, val);
711 	}
712 
713 	return _hal_write32(hal, addr, val);
714 }
715 
716 #ifdef CONFIG_SDIO_HCI
dbg_hal_sd_f0_read8(struct rtw_hal_com_t * hal,u32 addr,const char * caller,const int line)717 u8 dbg_hal_sd_f0_read8(struct rtw_hal_com_t *hal, u32 addr, const char *caller, const int line)
718 {
719 	u8 val = _hal_sd_f0_read8(hal, addr);
720 
721 #if 0
722 	if (match_read_sniff(adapter, addr, 1, val)) {
723 		PHL_INFO("DBG_IO %s:%d hal_sd_f0_read8(0x%04x) return 0x%02x\n"
724 			, caller, line, addr, val);
725 	}
726 #endif
727 
728 	return val;
729 }
730 
731 #ifdef CONFIG_SDIO_INDIRECT_ACCESS
dbg_hal_sd_iread8(struct rtw_hal_com_t * hal,u32 addr,const char * caller,const int line)732 u8 dbg_hal_sd_iread8(struct rtw_hal_com_t *hal, u32 addr, const char *caller, const int line)
733 {
734 	u8 val = hal_sd_iread8(hal, addr);
735 
736 	if (match_read_sniff(hal, addr, 1, val)) {
737 		PHL_INFO("DBG_IO %s:%d hal_sd_iread8(0x%04x) return 0x%02x\n"
738 			, caller, line, addr, val);
739 	}
740 
741 	return val;
742 }
743 
dbg_hal_sd_iread16(struct rtw_hal_com_t * hal,u32 addr,const char * caller,const int line)744 u16 dbg_hal_sd_iread16(struct rtw_hal_com_t *hal, u32 addr, const char *caller, const int line)
745 {
746 	u16 val = _hal_sd_iread16(hal, addr);
747 
748 	if (match_read_sniff(hal, addr, 2, val)) {
749 		PHL_INFO("DBG_IO %s:%d hal_sd_iread16(0x%04x) return 0x%04x\n"
750 			, caller, line, addr, val);
751 	}
752 
753 	return val;
754 }
755 
dbg_hal_sd_iread32(struct rtw_hal_com_t * hal,u32 addr,const char * caller,const int line)756 u32 dbg_hal_sd_iread32(struct rtw_hal_com_t *hal, u32 addr, const char *caller, const int line)
757 {
758 	u32 val = _hal_sd_iread32(hal, addr);
759 
760 	if (match_read_sniff(hal, addr, 4, val)) {
761 		PHL_INFO("DBG_IO %s:%d hal_sd_iread32(0x%04x) return 0x%08x\n"
762 			, caller, line, addr, val);
763 	}
764 
765 	return val;
766 }
767 
dbg_hal_sd_iwrite8(struct rtw_hal_com_t * hal,u32 addr,u8 val,const char * caller,const int line)768 int dbg_hal_sd_iwrite8(struct rtw_hal_com_t *hal, u32 addr, u8 val, const char *caller, const int line)
769 {
770 	if (match_write_sniff(hal, addr, 1, val)) {
771 		PHL_INFO("DBG_IO %s:%d hal_sd_iwrite8(0x%04x, 0x%02x)\n"
772 			, caller, line, addr, val);
773 	}
774 
775 	return _hal_sd_iwrite8(hal, addr, val);
776 }
dbg_hal_sd_iwrite16(struct rtw_hal_com_t * hal,u32 addr,u16 val,const char * caller,const int line)777 int dbg_hal_sd_iwrite16(struct rtw_hal_com_t *hal, u32 addr, u16 val, const char *caller, const int line)
778 {
779 	if (match_write_sniff(hal, addr, 2, val)) {
780 		PHL_INFO("DBG_IO %s:%d hal_sd_iwrite16(0x%04x, 0x%04x)\n"
781 			, caller, line, addr, val);
782 	}
783 
784 	return _hal_sd_iwrite16(hal, addr, val);
785 }
dbg_hal_sd_iwrite32(struct rtw_hal_com_t * hal,u32 addr,u32 val,const char * caller,const int line)786 int dbg_hal_sd_iwrite32(struct rtw_hal_com_t *hal, u32 addr, u32 val, const char *caller, const int line)
787 {
788 	if (match_write_sniff(hal, addr, 4, val)) {
789 		PHL_INFO("DBG_IO %s:%d hal_sd_iwrite32(0x%04x, 0x%08x)\n"
790 			, caller, line, addr, val);
791 	}
792 
793 	return _hal_sd_iwrite32(hal, addr, val);
794 }
795 
796 #endif /* CONFIG_SDIO_INDIRECT_ACCESS */
797 
798 #endif /* CONFIG_SDIO_HCI */
799 #endif
800