xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8821cs/core/rtw_sdio.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2015 - 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 #define _RTW_SDIO_C_
16 
17 #include <drv_types.h>		/* struct dvobj_priv and etc. */
18 #include <drv_types_sdio.h>	/* RTW_SDIO_ADDR_CMD52_GEN */
19 
20 /*
21  * Description:
22  *	Use SDIO cmd52 or cmd53 to read/write data
23  *
24  * Parameters:
25  *	d	pointer of device object(struct dvobj_priv)
26  *	addr	SDIO address, 17 bits
27  *	buf	buffer for I/O
28  *	len	length
29  *	write	0:read, 1:write
30  *	cmd52	0:cmd52, 1:cmd53
31  *
32  * Return:
33  *	_SUCCESS	I/O ok.
34  *	_FAIL		I/O fail.
35  */
sdio_io(struct dvobj_priv * d,u32 addr,void * buf,size_t len,u8 write,u8 cmd52)36 static u8 sdio_io(struct dvobj_priv *d, u32 addr, void *buf, size_t len, u8 write, u8 cmd52)
37 {
38 #ifdef DBG_SDIO
39 #if (DBG_SDIO >= 3)
40 	struct sdio_data *sdio;
41 #endif /* DBG_SDIO >= 3 */
42 #endif /* DBG_SDIO */
43 	u32 addr_drv;	/* address with driver defined bit */
44 	int err;
45 	u8 retry = 0;
46 	u8 stop_retry = _FALSE;	/* flag for stopping retry or not */
47 
48 
49 #ifdef DBG_SDIO
50 #if (DBG_SDIO >= 3)
51 	sdio = &d->intf_data;
52 #endif /* DBG_SDIO >= 3 */
53 #endif /* DBG_SDIO */
54 
55 	if (rtw_is_surprise_removed(dvobj_get_primary_adapter(d))) {
56 		RTW_ERR("%s: bSurpriseRemoved, skip %s 0x%05x, %zu bytes\n",
57 			__FUNCTION__, write?"write":"read", addr, len);
58 		return _FAIL;
59 	}
60 
61 	addr_drv = addr;
62 	if (cmd52)
63 		addr_drv = RTW_SDIO_ADDR_CMD52_GEN(addr_drv);
64 
65 	do {
66 		if (write)
67 			err = d->intf_ops->write(d, addr_drv, buf, len, 0);
68 		else
69 			err = d->intf_ops->read(d, addr_drv, buf, len, 0);
70 		if (!err) {
71 			if (retry) {
72 				RTW_INFO("%s: Retry %s OK! addr=0x%05x %zu bytes, retry=%u,%u\n",
73 					 __FUNCTION__, write?"write":"read",
74 					 addr, len, retry, ATOMIC_READ(&d->continual_io_error));
75 				RTW_INFO_DUMP("Data: ", buf, len);
76 			}
77 			rtw_reset_continual_io_error(d);
78 			break;
79 		}
80 		RTW_ERR("%s: %s FAIL! error(%d) addr=0x%05x %zu bytes, retry=%u,%u\n",
81 			__FUNCTION__, write?"write":"read", err, addr, len,
82 			retry, ATOMIC_READ(&d->continual_io_error));
83 
84 #ifdef DBG_SDIO
85 #if (DBG_SDIO >= 3)
86 		if (sdio->dbg_enable) {
87 			if (sdio->err_test && sdio->err_test_triggered)
88 				sdio->err_test = 0;
89 
90 			if (sdio->err_stop) {
91 				RTW_ERR("%s: I/O error! Set surprise remove flag ON!\n",
92 					__FUNCTION__);
93 				rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
94 				return _FAIL;
95 			}
96 		}
97 #endif /* DBG_SDIO >= 3 */
98 #endif /* DBG_SDIO */
99 
100 		retry++;
101 		stop_retry = rtw_inc_and_chk_continual_io_error(d);
102 		if ((err == -1) || (stop_retry == _TRUE) || (retry > SD_IO_TRY_CNT)) {
103 			/* critical error, unrecoverable */
104 			RTW_ERR("%s: Fatal error! Set surprise remove flag ON! (retry=%u,%u)\n",
105 				__FUNCTION__, retry, ATOMIC_READ(&d->continual_io_error));
106 			rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
107 			return _FAIL;
108 		}
109 
110 		/* WLAN IOREG or SDIO Local */
111 		if ((addr & 0x10000) || !(addr & 0xE000)) {
112 			RTW_WARN("%s: Retry %s addr=0x%05x %zu bytes, retry=%u,%u\n",
113 				 __FUNCTION__, write?"write":"read", addr, len,
114 				 retry, ATOMIC_READ(&d->continual_io_error));
115 			continue;
116 		}
117 		return _FAIL;
118 	} while (1);
119 
120 	return _SUCCESS;
121 }
122 
rtw_sdio_read_cmd52(struct dvobj_priv * d,u32 addr,void * buf,size_t len)123 u8 rtw_sdio_read_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
124 {
125 	return sdio_io(d, addr, buf, len, 0, 1);
126 }
127 
rtw_sdio_read_cmd53(struct dvobj_priv * d,u32 addr,void * buf,size_t len)128 u8 rtw_sdio_read_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
129 {
130 	return sdio_io(d, addr, buf, len, 0, 0);
131 }
132 
rtw_sdio_write_cmd52(struct dvobj_priv * d,u32 addr,void * buf,size_t len)133 u8 rtw_sdio_write_cmd52(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
134 {
135 	return sdio_io(d, addr, buf, len, 1, 1);
136 }
137 
rtw_sdio_write_cmd53(struct dvobj_priv * d,u32 addr,void * buf,size_t len)138 u8 rtw_sdio_write_cmd53(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
139 {
140 	return sdio_io(d, addr, buf, len, 1, 0);
141 }
142 
rtw_sdio_f0_read(struct dvobj_priv * d,u32 addr,void * buf,size_t len)143 u8 rtw_sdio_f0_read(struct dvobj_priv *d, u32 addr, void *buf, size_t len)
144 {
145 	int err;
146 	u8 ret;
147 
148 
149 	ret = _SUCCESS;
150 	addr = RTW_SDIO_ADDR_F0_GEN(addr);
151 
152 	err = d->intf_ops->read(d, addr, buf, len, 0);
153 	if (err)
154 		ret = _FAIL;
155 
156 	return ret;
157 }
158