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