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