Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_io.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14/*1516The purpose of rtw_io.c1718a. provides the API1920b. provides the protocol engine2122c. provides the software interface between caller and the hardware interface232425Compiler Flag Option:26271. CONFIG_SDIO_HCI:28a. USE_SYNC_IRP: Only sync operations are provided.29b. USE_ASYNC_IRP:Both sync/async operations are provided.30312. CONFIG_USB_HCI:32a. USE_ASYNC_IRP: Both sync/async operations are provided.33343. CONFIG_CFIO_HCI:35b. USE_SYNC_IRP: Only sync operations are provided.363738Only sync read/rtw_write_mem operations are provided.3940[email protected]4142*/4344#define _RTW_IO_C_4546#include <drv_types.h>47#include <hal_data.h>4849#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_PLATFORM_RTL8197D)50#define rtw_le16_to_cpu(val) val51#define rtw_le32_to_cpu(val) val52#define rtw_cpu_to_le16(val) val53#define rtw_cpu_to_le32(val) val54#else55#define rtw_le16_to_cpu(val) le16_to_cpu(val)56#define rtw_le32_to_cpu(val) le32_to_cpu(val)57#define rtw_cpu_to_le16(val) cpu_to_le16(val)58#define rtw_cpu_to_le32(val) cpu_to_le32(val)59#endif606162u8 _rtw_read8(_adapter *adapter, u32 addr)63{64u8 r_val;65/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */66struct io_priv *pio_priv = &adapter->iopriv;67struct intf_hdl *pintfhdl = &(pio_priv->intf);68u8(*_read8)(struct intf_hdl *pintfhdl, u32 addr);69_read8 = pintfhdl->io_ops._read8;7071r_val = _read8(pintfhdl, addr);72return r_val;73}7475u16 _rtw_read16(_adapter *adapter, u32 addr)76{77u16 r_val;78/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */79struct io_priv *pio_priv = &adapter->iopriv;80struct intf_hdl *pintfhdl = &(pio_priv->intf);81u16(*_read16)(struct intf_hdl *pintfhdl, u32 addr);82_read16 = pintfhdl->io_ops._read16;8384r_val = _read16(pintfhdl, addr);85return rtw_le16_to_cpu(r_val);86}8788u32 _rtw_read32(_adapter *adapter, u32 addr)89{90u32 r_val;91/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */92struct io_priv *pio_priv = &adapter->iopriv;93struct intf_hdl *pintfhdl = &(pio_priv->intf);94u32(*_read32)(struct intf_hdl *pintfhdl, u32 addr);95_read32 = pintfhdl->io_ops._read32;9697r_val = _read32(pintfhdl, addr);98return rtw_le32_to_cpu(r_val);99100}101102int _rtw_write8(_adapter *adapter, u32 addr, u8 val)103{104/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */105struct io_priv *pio_priv = &adapter->iopriv;106struct intf_hdl *pintfhdl = &(pio_priv->intf);107int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);108int ret;109_write8 = pintfhdl->io_ops._write8;110111ret = _write8(pintfhdl, addr, val);112113return RTW_STATUS_CODE(ret);114}115int _rtw_write16(_adapter *adapter, u32 addr, u16 val)116{117/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */118struct io_priv *pio_priv = &adapter->iopriv;119struct intf_hdl *pintfhdl = &(pio_priv->intf);120int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);121int ret;122_write16 = pintfhdl->io_ops._write16;123124val = rtw_cpu_to_le16(val);125ret = _write16(pintfhdl, addr, val);126127return RTW_STATUS_CODE(ret);128}129int _rtw_write32(_adapter *adapter, u32 addr, u32 val)130{131/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */132struct io_priv *pio_priv = &adapter->iopriv;133struct intf_hdl *pintfhdl = &(pio_priv->intf);134int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);135int ret;136_write32 = pintfhdl->io_ops._write32;137138val = rtw_cpu_to_le32(val);139ret = _write32(pintfhdl, addr, val);140141return RTW_STATUS_CODE(ret);142}143144int _rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *pdata)145{146/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */147struct io_priv *pio_priv = &adapter->iopriv;148struct intf_hdl *pintfhdl = (struct intf_hdl *)(&(pio_priv->intf));149int (*_writeN)(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata);150int ret;151_writeN = pintfhdl->io_ops._writeN;152153ret = _writeN(pintfhdl, addr, length, pdata);154155return RTW_STATUS_CODE(ret);156}157158#ifdef CONFIG_SDIO_HCI159u8 _rtw_sd_f0_read8(_adapter *adapter, u32 addr)160{161u8 r_val = 0x00;162struct io_priv *pio_priv = &adapter->iopriv;163struct intf_hdl *pintfhdl = &(pio_priv->intf);164u8(*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr);165166_sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8;167168if (_sd_f0_read8)169r_val = _sd_f0_read8(pintfhdl, addr);170else171RTW_WARN(FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter));172173return r_val;174}175176#ifdef CONFIG_SDIO_INDIRECT_ACCESS177u8 _rtw_sd_iread8(_adapter *adapter, u32 addr)178{179u8 r_val = 0x00;180struct io_priv *pio_priv = &adapter->iopriv;181struct intf_hdl *pintfhdl = &(pio_priv->intf);182u8(*_sd_iread8)(struct intf_hdl *pintfhdl, u32 addr);183184_sd_iread8 = pintfhdl->io_ops._sd_iread8;185186if (_sd_iread8)187r_val = _sd_iread8(pintfhdl, addr);188else189RTW_ERR(FUNC_ADPT_FMT" _sd_iread8 callback is NULL\n", FUNC_ADPT_ARG(adapter));190191return r_val;192}193194u16 _rtw_sd_iread16(_adapter *adapter, u32 addr)195{196u16 r_val = 0x00;197struct io_priv *pio_priv = &adapter->iopriv;198struct intf_hdl *pintfhdl = &(pio_priv->intf);199u16(*_sd_iread16)(struct intf_hdl *pintfhdl, u32 addr);200201_sd_iread16 = pintfhdl->io_ops._sd_iread16;202203if (_sd_iread16)204r_val = _sd_iread16(pintfhdl, addr);205else206RTW_ERR(FUNC_ADPT_FMT" _sd_iread16 callback is NULL\n", FUNC_ADPT_ARG(adapter));207208return r_val;209}210211u32 _rtw_sd_iread32(_adapter *adapter, u32 addr)212{213u32 r_val = 0x00;214struct io_priv *pio_priv = &adapter->iopriv;215struct intf_hdl *pintfhdl = &(pio_priv->intf);216u32(*_sd_iread32)(struct intf_hdl *pintfhdl, u32 addr);217218_sd_iread32 = pintfhdl->io_ops._sd_iread32;219220if (_sd_iread32)221r_val = _sd_iread32(pintfhdl, addr);222else223RTW_ERR(FUNC_ADPT_FMT" _sd_iread32 callback is NULL\n", FUNC_ADPT_ARG(adapter));224225return r_val;226}227228int _rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val)229{230struct io_priv *pio_priv = &adapter->iopriv;231struct intf_hdl *pintfhdl = &(pio_priv->intf);232int (*_sd_iwrite8)(struct intf_hdl *pintfhdl, u32 addr, u8 val);233int ret = -1;234235_sd_iwrite8 = pintfhdl->io_ops._sd_iwrite8;236237if (_sd_iwrite8)238ret = _sd_iwrite8(pintfhdl, addr, val);239else240RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite8 callback is NULL\n", FUNC_ADPT_ARG(adapter));241242return RTW_STATUS_CODE(ret);243}244245int _rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val)246{247struct io_priv *pio_priv = &adapter->iopriv;248struct intf_hdl *pintfhdl = &(pio_priv->intf);249int (*_sd_iwrite16)(struct intf_hdl *pintfhdl, u32 addr, u16 val);250int ret = -1;251252_sd_iwrite16 = pintfhdl->io_ops._sd_iwrite16;253254if (_sd_iwrite16)255ret = _sd_iwrite16(pintfhdl, addr, val);256else257RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite16 callback is NULL\n", FUNC_ADPT_ARG(adapter));258259return RTW_STATUS_CODE(ret);260}261int _rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val)262{263struct io_priv *pio_priv = &adapter->iopriv;264struct intf_hdl *pintfhdl = &(pio_priv->intf);265int (*_sd_iwrite32)(struct intf_hdl *pintfhdl, u32 addr, u32 val);266int ret = -1;267268_sd_iwrite32 = pintfhdl->io_ops._sd_iwrite32;269270if (_sd_iwrite32)271ret = _sd_iwrite32(pintfhdl, addr, val);272else273RTW_ERR(FUNC_ADPT_FMT" _sd_iwrite32 callback is NULL\n", FUNC_ADPT_ARG(adapter));274275return RTW_STATUS_CODE(ret);276}277278#endif /* CONFIG_SDIO_INDIRECT_ACCESS */279280#endif /* CONFIG_SDIO_HCI */281282int _rtw_write8_async(_adapter *adapter, u32 addr, u8 val)283{284/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */285struct io_priv *pio_priv = &adapter->iopriv;286struct intf_hdl *pintfhdl = &(pio_priv->intf);287int (*_write8_async)(struct intf_hdl *pintfhdl, u32 addr, u8 val);288int ret;289_write8_async = pintfhdl->io_ops._write8_async;290291ret = _write8_async(pintfhdl, addr, val);292293return RTW_STATUS_CODE(ret);294}295int _rtw_write16_async(_adapter *adapter, u32 addr, u16 val)296{297/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */298struct io_priv *pio_priv = &adapter->iopriv;299struct intf_hdl *pintfhdl = &(pio_priv->intf);300int (*_write16_async)(struct intf_hdl *pintfhdl, u32 addr, u16 val);301int ret;302_write16_async = pintfhdl->io_ops._write16_async;303val = rtw_cpu_to_le16(val);304ret = _write16_async(pintfhdl, addr, val);305306return RTW_STATUS_CODE(ret);307}308int _rtw_write32_async(_adapter *adapter, u32 addr, u32 val)309{310/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */311struct io_priv *pio_priv = &adapter->iopriv;312struct intf_hdl *pintfhdl = &(pio_priv->intf);313int (*_write32_async)(struct intf_hdl *pintfhdl, u32 addr, u32 val);314int ret;315_write32_async = pintfhdl->io_ops._write32_async;316val = rtw_cpu_to_le32(val);317ret = _write32_async(pintfhdl, addr, val);318319return RTW_STATUS_CODE(ret);320}321322void _rtw_read_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)323{324void (*_read_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);325/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */326struct io_priv *pio_priv = &adapter->iopriv;327struct intf_hdl *pintfhdl = &(pio_priv->intf);328329330if (RTW_CANNOT_RUN(adapter)) {331return;332}333334_read_mem = pintfhdl->io_ops._read_mem;335336_read_mem(pintfhdl, addr, cnt, pmem);337338339}340341void _rtw_write_mem(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)342{343void (*_write_mem)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);344/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */345struct io_priv *pio_priv = &adapter->iopriv;346struct intf_hdl *pintfhdl = &(pio_priv->intf);347348349_write_mem = pintfhdl->io_ops._write_mem;350351_write_mem(pintfhdl, addr, cnt, pmem);352353354}355356void _rtw_read_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)357{358u32(*_read_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);359/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */360struct io_priv *pio_priv = &adapter->iopriv;361struct intf_hdl *pintfhdl = &(pio_priv->intf);362363364if (RTW_CANNOT_RUN(adapter)) {365return;366}367368_read_port = pintfhdl->io_ops._read_port;369370_read_port(pintfhdl, addr, cnt, pmem);371372373}374375void _rtw_read_port_cancel(_adapter *adapter)376{377void (*_read_port_cancel)(struct intf_hdl *pintfhdl);378struct io_priv *pio_priv = &adapter->iopriv;379struct intf_hdl *pintfhdl = &(pio_priv->intf);380381_read_port_cancel = pintfhdl->io_ops._read_port_cancel;382383RTW_DISABLE_FUNC(adapter, DF_RX_BIT);384385if (_read_port_cancel)386_read_port_cancel(pintfhdl);387}388389u32 _rtw_write_port(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem)390{391u32(*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem);392/* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */393struct io_priv *pio_priv = &adapter->iopriv;394struct intf_hdl *pintfhdl = &(pio_priv->intf);395u32 ret = _SUCCESS;396397398_write_port = pintfhdl->io_ops._write_port;399400ret = _write_port(pintfhdl, addr, cnt, pmem);401402403return ret;404}405406u32 _rtw_write_port_and_wait(_adapter *adapter, u32 addr, u32 cnt, u8 *pmem, int timeout_ms)407{408int ret = _SUCCESS;409struct xmit_buf *pxmitbuf = (struct xmit_buf *)pmem;410struct submit_ctx sctx;411412rtw_sctx_init(&sctx, timeout_ms);413pxmitbuf->sctx = &sctx;414415ret = _rtw_write_port(adapter, addr, cnt, pmem);416417if (ret == _SUCCESS) {418ret = rtw_sctx_wait(&sctx, __func__);419420if (ret != _SUCCESS)421pxmitbuf->sctx = NULL;422}423424return ret;425}426427void _rtw_write_port_cancel(_adapter *adapter)428{429void (*_write_port_cancel)(struct intf_hdl *pintfhdl);430struct io_priv *pio_priv = &adapter->iopriv;431struct intf_hdl *pintfhdl = &(pio_priv->intf);432433_write_port_cancel = pintfhdl->io_ops._write_port_cancel;434435RTW_DISABLE_FUNC(adapter, DF_TX_BIT);436437if (_write_port_cancel)438_write_port_cancel(pintfhdl);439}440int rtw_init_io_priv(_adapter *padapter, void (*set_intf_ops)(_adapter *padapter, struct _io_ops *pops))441{442struct io_priv *piopriv = &padapter->iopriv;443struct intf_hdl *pintf = &piopriv->intf;444445if (set_intf_ops == NULL)446return _FAIL;447448piopriv->padapter = padapter;449pintf->padapter = padapter;450pintf->pintf_dev = adapter_to_dvobj(padapter);451452set_intf_ops(padapter, &pintf->io_ops);453454return _SUCCESS;455}456457/*458* Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR459* @return _TRUE:460* @return _FALSE:461*/462int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj)463{464int ret = _FALSE;465int value;466467value = ATOMIC_INC_RETURN(&dvobj->continual_io_error);468if (value > MAX_CONTINUAL_IO_ERR) {469RTW_INFO("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR);470ret = _TRUE;471} else {472/* RTW_INFO("[dvobj:%p] continual_io_error:%d\n", dvobj, value); */473}474return ret;475}476477/*478* Set the continual_io_error of this @param dvobjprive to 0479*/480void rtw_reset_continual_io_error(struct dvobj_priv *dvobj)481{482ATOMIC_SET(&dvobj->continual_io_error, 0);483}484485#ifdef DBG_IO486#define RTW_IO_SNIFF_TYPE_RANGE 0 /* specific address range is accessed */487#define RTW_IO_SNIFF_TYPE_VALUE 1 /* value match for sniffed range */488489struct rtw_io_sniff_ent {490u8 chip;491u8 hci;492u32 addr;493u8 type;494union {495u32 end_addr;496struct {497u32 mask;498u32 val;499bool equal;500} vm; /* value match */501} u;502bool trace;503char *tag;504bool (*assert_protsel)(_adapter *adapter, u32 addr, u8 len);505};506507#define RTW_IO_SNIFF_RANGE_ENT(_chip, _hci, _addr, _end_addr, _trace, _tag) \508{.chip = _chip, .hci = _hci, .addr = _addr, .u.end_addr = _end_addr, .trace = _trace, .tag = _tag, .type = RTW_IO_SNIFF_TYPE_RANGE,}509510#define RTW_IO_SNIFF_RANGE_PROT_ENT(_chip, _hci, _addr, _end_addr, _assert_protsel, _tag) \511{.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,}512513#define RTW_IO_SNIFF_VALUE_ENT(_chip, _hci, _addr, _mask, _val, _equal, _trace, _tag) \514{.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,}515516/* part or all sniffed range is enabled (not all 0) */517#define RTW_IO_SNIFF_EN_ENT(_chip, _hci, _addr, _mask, _trace, _tag) \518{.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,}519520/* part or all sniffed range is disabled (not all 1) */521#define RTW_IO_SNIFF_DIS_ENT(_chip, _hci, _addr, _mask, _trace, _tag) \522{.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,}523524const struct rtw_io_sniff_ent read_sniff[] = {525#ifdef DBG_IO_HCI_EN_CHK526RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_SDIO, 0x02, 0x1FC, 1, "SDIO 0x02[8:2] not all 0"),527RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_USB, 0x02, 0x1E0, 1, "USB 0x02[8:5] not all 0"),528RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_PCIE, 0x02, 0x01C, 1, "PCI 0x02[4:2] not all 0"),529#endif530#ifdef DBG_IO_SNIFF_EXAMPLE531RTW_IO_SNIFF_RANGE_ENT(MAX_CHIP_TYPE, 0, 0x522, 0x522, 0, "read TXPAUSE"),532RTW_IO_SNIFF_DIS_ENT(MAX_CHIP_TYPE, 0, 0x02, 0x3, 0, "0x02[1:0] not all 1"),533#endif534#ifdef DBG_IO_PROT_SEL535RTW_IO_SNIFF_RANGE_PROT_ENT(MAX_CHIP_TYPE, 0, 0x1501, 0x1513, rtw_assert_protsel_port, "protsel port"),536RTW_IO_SNIFF_RANGE_PROT_ENT(MAX_CHIP_TYPE, 0, 0x153a, 0x153b, rtw_assert_protsel_atimdtim, "protsel atimdtim"),537#endif538};539540const int read_sniff_num = sizeof(read_sniff) / sizeof(struct rtw_io_sniff_ent);541542const struct rtw_io_sniff_ent write_sniff[] = {543#ifdef DBG_IO_HCI_EN_CHK544RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_SDIO, 0x02, 0x1FC, 1, "SDIO 0x02[8:2] not all 0"),545RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_USB, 0x02, 0x1E0, 1, "USB 0x02[8:5] not all 0"),546RTW_IO_SNIFF_EN_ENT(MAX_CHIP_TYPE, RTW_PCIE, 0x02, 0x01C, 1, "PCI 0x02[4:2] not all 0"),547#endif548#ifdef DBG_IO_8822C_1TX_PATH_EN549RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x1a04, 0xc0000000, 0x02, 1, 0, "write tx_path_en_cck A enabled"),550RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x1a04, 0xc0000000, 0x01, 1, 0, "write tx_path_en_cck B enabled"),551RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x1a04, 0xc0000000, 0x03, 1, 1, "write tx_path_en_cck AB enabled"),552RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x03, 0x01, 1, 0, "write tx_path_en_ofdm_1sts A enabled"),553RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x03, 0x02, 1, 0, "write tx_path_en_ofdm_1sts B enabled"),554RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x03, 0x03, 1, 1, "write tx_path_en_ofdm_1sts AB enabled"),555RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x30, 0x01, 1, 0, "write tx_path_en_ofdm_2sts A enabled"),556RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x30, 0x02, 1, 0, "write tx_path_en_ofdm_2sts B enabled"),557RTW_IO_SNIFF_VALUE_ENT(RTL8822C, 0, 0x820, 0x30, 0x03, 1, 1, "write tx_path_en_ofdm_2sts AB enabled"),558#endif559#ifdef DBG_IO_SNIFF_EXAMPLE560RTW_IO_SNIFF_RANGE_ENT(MAX_CHIP_TYPE, 0, 0x522, 0x522, 0, "write TXPAUSE"),561RTW_IO_SNIFF_DIS_ENT(MAX_CHIP_TYPE, 0, 0x02, 0x3, 0, "0x02[1:0] not all 1"),562#endif563};564565const int write_sniff_num = sizeof(write_sniff) / sizeof(struct rtw_io_sniff_ent);566567static bool match_io_sniff_ranges(_adapter *adapter568, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u16 len)569{570571/* check if IO range after sniff end address */572if (addr > sniff->u.end_addr)573return 0;574575if (sniff->assert_protsel &&576sniff->assert_protsel(adapter, addr, len))577return 0;578579return 1;580}581582static bool match_io_sniff_value(_adapter *adapter583, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)584{585u8 sniff_len;586s8 mask_shift;587u32 mask;588s8 value_shift;589u32 value;590bool ret = 0;591592/* check if IO range after sniff end address */593sniff_len = 4;594while (!(sniff->u.vm.mask & (0xFF << ((sniff_len - 1) * 8)))) {595sniff_len--;596if (sniff_len == 0)597goto exit;598}599if (sniff->addr + sniff_len <= addr)600goto exit;601602/* align to IO addr */603mask_shift = (sniff->addr - addr) * 8;604value_shift = mask_shift + bitshift(sniff->u.vm.mask);605if (mask_shift > 0)606mask = sniff->u.vm.mask << mask_shift;607else if (mask_shift < 0)608mask = sniff->u.vm.mask >> -mask_shift;609else610mask = sniff->u.vm.mask;611612if (value_shift > 0)613value = sniff->u.vm.val << value_shift;614else if (mask_shift < 0)615value = sniff->u.vm.val >> -value_shift;616else617value = sniff->u.vm.val;618619if ((sniff->u.vm.equal && (mask & val) == (mask & value))620|| (!sniff->u.vm.equal && (mask & val) != (mask & value))621) {622ret = 1;623if (0)624RTW_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"625, FUNC_ADPT_ARG(adapter), addr, len, val, i, sniff_len, mask_shift, mask, value_shift, value, sniff->u.vm.equal);626}627628exit:629return ret;630}631632static bool match_io_sniff(_adapter *adapter633, const struct rtw_io_sniff_ent *sniff, int i, u32 addr, u8 len, u32 val)634{635bool ret = 0;636637if (sniff->chip != MAX_CHIP_TYPE638&& sniff->chip != rtw_get_chip_type(adapter))639goto exit;640if (sniff->hci641&& !(sniff->hci & rtw_get_intf_type(adapter)))642goto exit;643if (sniff->addr >= addr + len) /* IO range below sniff start address */644goto exit;645646switch (sniff->type) {647case RTW_IO_SNIFF_TYPE_RANGE:648ret = match_io_sniff_ranges(adapter, sniff, i, addr, len);649break;650case RTW_IO_SNIFF_TYPE_VALUE:651if (len == 1 || len == 2 || len == 4)652ret = match_io_sniff_value(adapter, sniff, i, addr, len, val);653break;654default:655rtw_warn_on(1);656break;657}658659exit:660return ret;661}662663u32 match_read_sniff(_adapter *adapter, u32 addr, u16 len, u32 val)664{665int i;666bool trace = 0;667u32 match = 0;668669for (i = 0; i < read_sniff_num; i++) {670if (match_io_sniff(adapter, &read_sniff[i], i, addr, len, val)) {671match++;672trace |= read_sniff[i].trace;673if (read_sniff[i].tag)674RTW_INFO("DBG_IO TAG %s\n", read_sniff[i].tag);675}676}677678rtw_warn_on(trace);679680return match;681}682683u32 match_write_sniff(_adapter *adapter, u32 addr, u16 len, u32 val)684{685int i;686bool trace = 0;687u32 match = 0;688689for (i = 0; i < write_sniff_num; i++) {690if (match_io_sniff(adapter, &write_sniff[i], i, addr, len, val)) {691match++;692trace |= write_sniff[i].trace;693if (write_sniff[i].tag)694RTW_INFO("DBG_IO TAG %s\n", write_sniff[i].tag);695}696}697698rtw_warn_on(trace);699700return match;701}702703struct rf_sniff_ent {704u8 path;705u16 reg;706u32 mask;707};708709struct rf_sniff_ent rf_read_sniff_ranges[] = {710/* example for all path addr 0x55 with all RF Reg mask */711/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */712};713714struct rf_sniff_ent rf_write_sniff_ranges[] = {715/* example for all path addr 0x55 with all RF Reg mask */716/* {MAX_RF_PATH, 0x55, bRFRegOffsetMask}, */717};718719int rf_read_sniff_num = sizeof(rf_read_sniff_ranges) / sizeof(struct rf_sniff_ent);720int rf_write_sniff_num = sizeof(rf_write_sniff_ranges) / sizeof(struct rf_sniff_ent);721722bool match_rf_read_sniff_ranges(_adapter *adapter, u8 path, u32 addr, u32 mask)723{724int i;725726for (i = 0; i < rf_read_sniff_num; i++) {727if (rf_read_sniff_ranges[i].path == MAX_RF_PATH || rf_read_sniff_ranges[i].path == path)728if (addr == rf_read_sniff_ranges[i].reg && (mask & rf_read_sniff_ranges[i].mask))729return _TRUE;730}731732return _FALSE;733}734735bool match_rf_write_sniff_ranges(_adapter *adapter, u8 path, u32 addr, u32 mask)736{737int i;738739for (i = 0; i < rf_write_sniff_num; i++) {740if (rf_write_sniff_ranges[i].path == MAX_RF_PATH || rf_write_sniff_ranges[i].path == path)741if (addr == rf_write_sniff_ranges[i].reg && (mask & rf_write_sniff_ranges[i].mask))742return _TRUE;743}744745return _FALSE;746}747748void dbg_rtw_reg_read_monitor(_adapter *adapter, u32 addr, u32 len, u32 val, const char *caller, const int line)749{750if (match_read_sniff(adapter, addr, len, val)) {751switch (len) {752case 1:753RTW_INFO("DBG_IO %s:%d read8(0x%04x) return 0x%02x\n"754, caller, line, addr, val);755break;756case 2:757RTW_INFO("DBG_IO %s:%d read16(0x%04x) return 0x%04x\n"758, caller, line, addr, val);759break;760case 4:761RTW_INFO("DBG_IO %s:%d read32(0x%04x) return 0x%08x\n"762, caller, line, addr, val);763break;764default:765RTW_INFO("DBG_IO %s:%d readN(0x%04x, %u)\n"766, caller, line, addr, len);767}768}769}770771void dbg_rtw_reg_write_monitor(_adapter *adapter, u32 addr, u32 len, u32 val, const char *caller, const int line)772{773if (match_write_sniff(adapter, addr, len, val)) {774switch (len) {775case 1:776RTW_INFO("DBG_IO %s:%d write8(0x%04x, 0x%02x)\n"777, caller, line, addr, val);778break;779case 2:780RTW_INFO("DBG_IO %s:%d write16(0x%04x, 0x%04x)\n"781, caller, line, addr, val);782break;783case 4:784RTW_INFO("DBG_IO %s:%d write32(0x%04x, 0x%08x)\n"785, caller, line, addr, val);786break;787default:788RTW_INFO("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n"789, caller, line, addr, len);790}791}792}793794u8 dbg_rtw_read8(_adapter *adapter, u32 addr, const char *caller, const int line)795{796u8 val = _rtw_read8(adapter, addr);797798if (match_read_sniff(adapter, addr, 1, val)) {799RTW_INFO("DBG_IO %s:%d rtw_read8(0x%04x) return 0x%02x\n"800, caller, line, addr, val);801}802803return val;804}805806u16 dbg_rtw_read16(_adapter *adapter, u32 addr, const char *caller, const int line)807{808u16 val = _rtw_read16(adapter, addr);809810if (match_read_sniff(adapter, addr, 2, val)) {811RTW_INFO("DBG_IO %s:%d rtw_read16(0x%04x) return 0x%04x\n"812, caller, line, addr, val);813}814815return val;816}817818u32 dbg_rtw_read32(_adapter *adapter, u32 addr, const char *caller, const int line)819{820u32 val = _rtw_read32(adapter, addr);821822if (match_read_sniff(adapter, addr, 4, val)) {823RTW_INFO("DBG_IO %s:%d rtw_read32(0x%04x) return 0x%08x\n"824, caller, line, addr, val);825}826827return val;828}829830int dbg_rtw_write8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)831{832if (match_write_sniff(adapter, addr, 1, val)) {833RTW_INFO("DBG_IO %s:%d rtw_write8(0x%04x, 0x%02x)\n"834, caller, line, addr, val);835}836837return _rtw_write8(adapter, addr, val);838}839int dbg_rtw_write16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)840{841if (match_write_sniff(adapter, addr, 2, val)) {842RTW_INFO("DBG_IO %s:%d rtw_write16(0x%04x, 0x%04x)\n"843, caller, line, addr, val);844}845846return _rtw_write16(adapter, addr, val);847}848int dbg_rtw_write32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)849{850if (match_write_sniff(adapter, addr, 4, val)) {851RTW_INFO("DBG_IO %s:%d rtw_write32(0x%04x, 0x%08x)\n"852, caller, line, addr, val);853}854855return _rtw_write32(adapter, addr, val);856}857int dbg_rtw_writeN(_adapter *adapter, u32 addr , u32 length , u8 *data, const char *caller, const int line)858{859if (match_write_sniff(adapter, addr, length, 0)) {860RTW_INFO("DBG_IO %s:%d rtw_writeN(0x%04x, %u)\n"861, caller, line, addr, length);862}863864return _rtw_writeN(adapter, addr, length, data);865}866867#ifdef CONFIG_SDIO_HCI868u8 dbg_rtw_sd_f0_read8(_adapter *adapter, u32 addr, const char *caller, const int line)869{870u8 val = _rtw_sd_f0_read8(adapter, addr);871872#if 0873if (match_read_sniff(adapter, addr, 1, val)) {874RTW_INFO("DBG_IO %s:%d rtw_sd_f0_read8(0x%04x) return 0x%02x\n"875, caller, line, addr, val);876}877#endif878879return val;880}881882#ifdef CONFIG_SDIO_INDIRECT_ACCESS883u8 dbg_rtw_sd_iread8(_adapter *adapter, u32 addr, const char *caller, const int line)884{885u8 val = rtw_sd_iread8(adapter, addr);886887if (match_read_sniff(adapter, addr, 1, val)) {888RTW_INFO("DBG_IO %s:%d rtw_sd_iread8(0x%04x) return 0x%02x\n"889, caller, line, addr, val);890}891892return val;893}894895u16 dbg_rtw_sd_iread16(_adapter *adapter, u32 addr, const char *caller, const int line)896{897u16 val = _rtw_sd_iread16(adapter, addr);898899if (match_read_sniff(adapter, addr, 2, val)) {900RTW_INFO("DBG_IO %s:%d rtw_sd_iread16(0x%04x) return 0x%04x\n"901, caller, line, addr, val);902}903904return val;905}906907u32 dbg_rtw_sd_iread32(_adapter *adapter, u32 addr, const char *caller, const int line)908{909u32 val = _rtw_sd_iread32(adapter, addr);910911if (match_read_sniff(adapter, addr, 4, val)) {912RTW_INFO("DBG_IO %s:%d rtw_sd_iread32(0x%04x) return 0x%08x\n"913, caller, line, addr, val);914}915916return val;917}918919int dbg_rtw_sd_iwrite8(_adapter *adapter, u32 addr, u8 val, const char *caller, const int line)920{921if (match_write_sniff(adapter, addr, 1, val)) {922RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite8(0x%04x, 0x%02x)\n"923, caller, line, addr, val);924}925926return _rtw_sd_iwrite8(adapter, addr, val);927}928int dbg_rtw_sd_iwrite16(_adapter *adapter, u32 addr, u16 val, const char *caller, const int line)929{930if (match_write_sniff(adapter, addr, 2, val)) {931RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite16(0x%04x, 0x%04x)\n"932, caller, line, addr, val);933}934935return _rtw_sd_iwrite16(adapter, addr, val);936}937int dbg_rtw_sd_iwrite32(_adapter *adapter, u32 addr, u32 val, const char *caller, const int line)938{939if (match_write_sniff(adapter, addr, 4, val)) {940RTW_INFO("DBG_IO %s:%d rtw_sd_iwrite32(0x%04x, 0x%08x)\n"941, caller, line, addr, val);942}943944return _rtw_sd_iwrite32(adapter, addr, val);945}946947#endif /* CONFIG_SDIO_INDIRECT_ACCESS */948949#endif /* CONFIG_SDIO_HCI */950951#endif952953954