1 /****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. 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 jackson@realtek.com.tw 33 34 */ 35 36 #define _RTW_IO_C_ 37 38 #include <drv_types.h> 39 #include <rtw_debug.h> 40 41 #define rtw_le16_to_cpu(val) val 42 #define rtw_le32_to_cpu(val) val 43 #define rtw_cpu_to_le16(val) val 44 #define rtw_cpu_to_le32(val) val 45 46 u8 _rtw_read8(struct adapter *adapter, u32 addr) 47 { 48 u8 r_val; 49 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 50 struct io_priv *pio_priv = &adapter->iopriv; 51 struct intf_hdl *pintfhdl = &(pio_priv->intf); 52 u8 (*_read8)(struct intf_hdl *pintfhdl, u32 addr); 53 54 _read8 = pintfhdl->io_ops._read8; 55 56 r_val = _read8(pintfhdl, addr); 57 return r_val; 58 } 59 60 u16 _rtw_read16(struct adapter *adapter, u32 addr) 61 { 62 u16 r_val; 63 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 64 struct io_priv *pio_priv = &adapter->iopriv; 65 struct intf_hdl *pintfhdl = &(pio_priv->intf); 66 u16 (*_read16)(struct intf_hdl *pintfhdl, u32 addr); 67 68 _read16 = pintfhdl->io_ops._read16; 69 70 r_val = _read16(pintfhdl, addr); 71 return rtw_le16_to_cpu(r_val); 72 } 73 74 u32 _rtw_read32(struct adapter *adapter, u32 addr) 75 { 76 u32 r_val; 77 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 78 struct io_priv *pio_priv = &adapter->iopriv; 79 struct intf_hdl *pintfhdl = &(pio_priv->intf); 80 u32 (*_read32)(struct intf_hdl *pintfhdl, u32 addr); 81 82 _read32 = pintfhdl->io_ops._read32; 83 84 r_val = _read32(pintfhdl, addr); 85 return rtw_le32_to_cpu(r_val); 86 87 } 88 89 int _rtw_write8(struct adapter *adapter, u32 addr, u8 val) 90 { 91 /* struct io_queue *pio_queue = (struct io_queue *)adapter->pio_queue; */ 92 struct io_priv *pio_priv = &adapter->iopriv; 93 struct intf_hdl *pintfhdl = &(pio_priv->intf); 94 int (*_write8)(struct intf_hdl *pintfhdl, u32 addr, u8 val); 95 int ret; 96 97 _write8 = pintfhdl->io_ops._write8; 98 99 ret = _write8(pintfhdl, addr, val); 100 101 return RTW_STATUS_CODE(ret); 102 } 103 int _rtw_write16(struct adapter *adapter, u32 addr, u16 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 (*_write16)(struct intf_hdl *pintfhdl, u32 addr, u16 val); 109 int ret; 110 111 _write16 = pintfhdl->io_ops._write16; 112 113 ret = _write16(pintfhdl, addr, val); 114 return RTW_STATUS_CODE(ret); 115 } 116 int _rtw_write32(struct adapter *adapter, u32 addr, u32 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 (*_write32)(struct intf_hdl *pintfhdl, u32 addr, u32 val); 122 int ret; 123 124 _write32 = pintfhdl->io_ops._write32; 125 126 ret = _write32(pintfhdl, addr, val); 127 128 return RTW_STATUS_CODE(ret); 129 } 130 131 u8 _rtw_sd_f0_read8(struct adapter *adapter, u32 addr) 132 { 133 u8 r_val = 0x00; 134 struct io_priv *pio_priv = &adapter->iopriv; 135 struct intf_hdl *pintfhdl = &(pio_priv->intf); 136 u8 (*_sd_f0_read8)(struct intf_hdl *pintfhdl, u32 addr); 137 138 _sd_f0_read8 = pintfhdl->io_ops._sd_f0_read8; 139 140 if (_sd_f0_read8) 141 r_val = _sd_f0_read8(pintfhdl, addr); 142 else 143 DBG_871X_LEVEL(_drv_warning_, FUNC_ADPT_FMT" _sd_f0_read8 callback is NULL\n", FUNC_ADPT_ARG(adapter)); 144 145 return r_val; 146 } 147 148 u32 _rtw_write_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) 149 { 150 u32 (*_write_port)(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pmem); 151 struct io_priv *pio_priv = &adapter->iopriv; 152 struct intf_hdl *pintfhdl = &(pio_priv->intf); 153 u32 ret = _SUCCESS; 154 155 _write_port = pintfhdl->io_ops._write_port; 156 157 ret = _write_port(pintfhdl, addr, cnt, pmem); 158 159 return ret; 160 } 161 162 int rtw_init_io_priv(struct adapter *padapter, void (*set_intf_ops)(struct adapter *padapter, struct _io_ops *pops)) 163 { 164 struct io_priv *piopriv = &padapter->iopriv; 165 struct intf_hdl *pintf = &piopriv->intf; 166 167 if (set_intf_ops == NULL) 168 return _FAIL; 169 170 piopriv->padapter = padapter; 171 pintf->padapter = padapter; 172 pintf->pintf_dev = adapter_to_dvobj(padapter); 173 174 set_intf_ops(padapter, &pintf->io_ops); 175 176 return _SUCCESS; 177 } 178 179 /* 180 * Increase and check if the continual_io_error of this @param dvobjprive is larger than MAX_CONTINUAL_IO_ERR 181 * @return true: 182 * @return false: 183 */ 184 int rtw_inc_and_chk_continual_io_error(struct dvobj_priv *dvobj) 185 { 186 int ret = false; 187 int value = atomic_inc_return(&dvobj->continual_io_error); 188 if (value > MAX_CONTINUAL_IO_ERR) { 189 DBG_871X("[dvobj:%p][ERROR] continual_io_error:%d > %d\n", dvobj, value, MAX_CONTINUAL_IO_ERR); 190 ret = true; 191 } else { 192 /* DBG_871X("[dvobj:%p] continual_io_error:%d\n", dvobj, value); */ 193 } 194 return ret; 195 } 196 197 /* 198 * Set the continual_io_error of this @param dvobjprive to 0 199 */ 200 void rtw_reset_continual_io_error(struct dvobj_priv *dvobj) 201 { 202 atomic_set(&dvobj->continual_io_error, 0); 203 } 204