1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 /* 8 9 The purpose of rtw_io.c 10 11 a. provides the API 12 13 b. provides the protocol engine 14 15 c. provides the software interface between caller and the hardware interface 16 17 18 Compiler Flag Option: 19 20 1. CONFIG_SDIO_HCI: 21 a. USE_SYNC_IRP: Only sync operations are provided. 22 b. USE_ASYNC_IRP:Both sync/async operations are provided. 23 24 jackson@realtek.com.tw 25 26 */ 27 28 #define _RTW_IO_C_ 29 30 #include <drv_types.h> 31 #include <rtw_debug.h> 32 33 #define rtw_le16_to_cpu(val) val 34 #define rtw_le32_to_cpu(val) val 35 #define rtw_cpu_to_le16(val) val 36 #define rtw_cpu_to_le32(val) val 37 38 u8 _rtw_read8(struct adapter *adapter, u32 addr) 39 { 40 u8 r_val; 41 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 42 struct io_priv *pio_priv = &adapter->iopriv; 43 struct intf_hdl *pintfhdl = &(pio_priv->intf); 44 u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); 45 46 _read8 = pintfhdl->io_ops._read8; 47 48 r_val = _read8(pintfhdl, addr); 49 return r_val; 50 } 51 52 u16 _rtw_read16(struct adapter *adapter, u32 addr) 53 { 54 u16 r_val; 55 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 56 struct io_priv *pio_priv = &adapter->iopriv; 57 struct intf_hdl *pintfhdl = &(pio_priv->intf); 58 u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); 59 60 _read16 = pintfhdl->io_ops._read16; 61 62 r_val = _read16(pintfhdl, addr); 63 return rtw_le16_to_cpu(r_val); 64 } 65 66 u32 _rtw_read32(struct adapter *adapter, u32 addr) 67 { 68 u32 r_val; 69 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 70 struct io_priv *pio_priv = &adapter->iopriv; 71 struct intf_hdl *pintfhdl = &(pio_priv->intf); 72 u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); 73 74 _read32 = pintfhdl->io_ops._read32; 75 76 r_val = _read32(pintfhdl, addr); 77 return rtw_le32_to_cpu(r_val); 78 79 } 80 81 int _rtw_write8(struct adapter *adapter, u32 addr, u8 val) 82 { 83 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 84 struct io_priv *pio_priv = &adapter->iopriv; 85 struct intf_hdl *pintfhdl = &(pio_priv->intf); 86 int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); 87 int ret; 88 89 _write8 = pintfhdl->io_ops._write8; 90 91 ret = _write8(pintfhdl, addr, val); 92 93 return RTW_STATUS_CODE(ret); 94 } 95 int _rtw_write16(struct adapter *adapter, u32 addr, u16 val) 96 { 97 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 98 struct io_priv *pio_priv = &adapter->iopriv; 99 struct intf_hdl *pintfhdl = &(pio_priv->intf); 100 int (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); 101 int ret; 102 103 _write16 = pintfhdl->io_ops._write16; 104 105 ret = _write16(pintfhdl, addr, val); 106 return RTW_STATUS_CODE(ret); 107 } 108 int _rtw_write32(struct adapter *adapter, u32 addr, u32 val) 109 { 110 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 111 struct io_priv *pio_priv = &adapter->iopriv; 112 struct intf_hdl *pintfhdl = &(pio_priv->intf); 113 int (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); 114 int ret; 115 116 _write32 = pintfhdl->io_ops._write32; 117 118 ret = _write32(pintfhdl, addr, val); 119 120 return RTW_STATUS_CODE(ret); 121 } 122 123 u8 _rtw_sd_f0_read8(struct adapter *adapter, u32 addr) 124 { 125 u8 r_val = 0x00; 126 struct io_priv *pio_priv = &adapter->iopriv; 127 struct intf_hdl *pintfhdl = &(pio_priv->intf); 128 u8 (*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr); 129 130 _sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8; 131 132 if (_sd_f0_read8) 133 r_val = _sd_f0_read8(pintfhdl, addr); 134 else 135 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter)); 136 137 return r_val; 138 } 139 140 u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) 141 { 142 u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); 143 struct io_priv *pio_priv = &adapter->iopriv; 144 struct intf_hdl *pintfhdl = &(pio_priv->intf); 145 u32 ret = _SUCCESS; 146 147 _write_port = pintfhdl->io_ops._write_port; 148 149 ret = _write_port(pintfhdl, addr, cnt, pmem); 150 151 return ret; 152 } 153 154 int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct adapter *padapter, struct _io_ops *pops)) 155 { 156 struct io_priv *piopriv = &padapter->iopriv; 157 struct intf_hdl *pintf = &piopriv->intf; 158 159 if (set_intf_ops == NULL) 160 return _FAIL; 161 162 piopriv->padapter = padapter; 163 pintf->padapter = padapter; 164 pintf->pintf_dev = adapter_to_dvobj(padapter); 165 166 set_intf_ops(padapter, &pintf->io_ops); 167 168 return _SUCCESS; 169 } 170 171 /* 172 * Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR 173 * @return true: 174 * @return false: 175 */ 176 int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj) 177 { 178 int ret = false; 179 int value = atomic_inc_return(&dvobj->continual_io_error); 180 if (value > MAX_CONTINUAL_IO_ERR) { 181 DBG_871X("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR); 182 ret = true; 183 } else { 184 /* DBG_871X("[dvobj:%p] continual_io_error:%d\n", dvobj, value); */ 185 } 186 return ret; 187 } 188 189 /* 190 * Set the continual_io_error of this @param dvobjprive to 0 191 */ 192 void rtw_reset_continual_io_error(struct dvobj_priv *dvobj) 193 { 194 atomic_set(&dvobj->continual_io_error, 0); 195 } 196