1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  *******************************************************************************/
7 
8 #include <drv_types.h>
9 #include <rtw_debug.h>
10 
11 static bool rtw_sdio_claim_host_needed(struct sdio_func *func)
12 {
13 	struct dvobj_priv *dvobj = sdio_get_drvdata(func);
14 	struct sdio_data *sdio_data = &dvobj->intf_data;
15 
16 	if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current)
17 		return false;
18 	return true;
19 }
20 
21 inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, void *thd_hdl)
22 {
23 	struct sdio_data *sdio_data = &dvobj->intf_data;
24 
25 	sdio_data->sys_sdio_irq_thd = thd_hdl;
26 }
27 
28 /*
29  * Return:
30  *0		Success
31  *others	Fail
32  */
33 s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
34 {
35 	struct adapter *padapter;
36 	struct dvobj_priv *psdiodev;
37 	struct sdio_data *psdio;
38 
39 	int err = 0, i;
40 	struct sdio_func *func;
41 
42 	padapter = pintfhdl->padapter;
43 	psdiodev = pintfhdl->pintf_dev;
44 	psdio = &psdiodev->intf_data;
45 
46 	if (padapter->bSurpriseRemoved)
47 		return err;
48 
49 	func = psdio->func;
50 
51 	for (i = 0; i < cnt; i++) {
52 		pdata[i] = sdio_readb(func, addr + i, &err);
53 		if (err)
54 			break;
55 	}
56 	return err;
57 }
58 
59 /*
60  * Return:
61  *0		Success
62  *others	Fail
63  */
64 s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
65 {
66 	struct adapter *padapter;
67 	struct dvobj_priv *psdiodev;
68 	struct sdio_data *psdio;
69 
70 	int err = 0;
71 	struct sdio_func *func;
72 	bool claim_needed;
73 
74 	padapter = pintfhdl->padapter;
75 	psdiodev = pintfhdl->pintf_dev;
76 	psdio = &psdiodev->intf_data;
77 
78 	if (padapter->bSurpriseRemoved)
79 		return err;
80 
81 	func = psdio->func;
82 	claim_needed = rtw_sdio_claim_host_needed(func);
83 
84 	if (claim_needed)
85 		sdio_claim_host(func);
86 	err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata);
87 	if (claim_needed)
88 		sdio_release_host(func);
89 	return err;
90 }
91 
92 /*
93  * Return:
94  *0		Success
95  *others	Fail
96  */
97 s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
98 {
99 	struct adapter *padapter;
100 	struct dvobj_priv *psdiodev;
101 	struct sdio_data *psdio;
102 
103 	int err = 0, i;
104 	struct sdio_func *func;
105 
106 	padapter = pintfhdl->padapter;
107 	psdiodev = pintfhdl->pintf_dev;
108 	psdio = &psdiodev->intf_data;
109 
110 	if (padapter->bSurpriseRemoved)
111 		return err;
112 
113 	func = psdio->func;
114 
115 	for (i = 0; i < cnt; i++) {
116 		sdio_writeb(func, pdata[i], addr + i, &err);
117 		if (err)
118 			break;
119 	}
120 	return err;
121 }
122 
123 /*
124  * Return:
125  *0		Success
126  *others	Fail
127  */
128 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
129 {
130 	struct adapter *padapter;
131 	struct dvobj_priv *psdiodev;
132 	struct sdio_data *psdio;
133 
134 	int err = 0;
135 	struct sdio_func *func;
136 	bool claim_needed;
137 
138 	padapter = pintfhdl->padapter;
139 	psdiodev = pintfhdl->pintf_dev;
140 	psdio = &psdiodev->intf_data;
141 
142 	if (padapter->bSurpriseRemoved)
143 		return err;
144 
145 	func = psdio->func;
146 	claim_needed = rtw_sdio_claim_host_needed(func);
147 
148 	if (claim_needed)
149 		sdio_claim_host(func);
150 	err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
151 	if (claim_needed)
152 		sdio_release_host(func);
153 	return err;
154 }
155 
156 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
157 {
158 	struct adapter *padapter;
159 	struct dvobj_priv *psdiodev;
160 	struct sdio_data *psdio;
161 
162 	u8 v = 0;
163 	struct sdio_func *func;
164 	bool claim_needed;
165 
166 	padapter = pintfhdl->padapter;
167 	psdiodev = pintfhdl->pintf_dev;
168 	psdio = &psdiodev->intf_data;
169 
170 	if (padapter->bSurpriseRemoved)
171 		return v;
172 
173 	func = psdio->func;
174 	claim_needed = rtw_sdio_claim_host_needed(func);
175 
176 	if (claim_needed)
177 		sdio_claim_host(func);
178 	v = sdio_readb(func, addr, err);
179 	if (claim_needed)
180 		sdio_release_host(func);
181 	return v;
182 }
183 
184 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
185 {
186 	struct adapter *padapter;
187 	struct dvobj_priv *psdiodev;
188 	struct sdio_data *psdio;
189 	u32 v = 0;
190 	struct sdio_func *func;
191 	bool claim_needed;
192 
193 	padapter = pintfhdl->padapter;
194 	psdiodev = pintfhdl->pintf_dev;
195 	psdio = &psdiodev->intf_data;
196 
197 	if (padapter->bSurpriseRemoved)
198 		return v;
199 
200 	func = psdio->func;
201 	claim_needed = rtw_sdio_claim_host_needed(func);
202 
203 	if (claim_needed)
204 		sdio_claim_host(func);
205 	v = sdio_readl(func, addr, err);
206 	if (claim_needed)
207 		sdio_release_host(func);
208 
209 	if (err && *err) {
210 		int i;
211 
212 		*err = 0;
213 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
214 			if (claim_needed)
215 				sdio_claim_host(func);
216 			v = sdio_readl(func, addr, err);
217 			if (claim_needed)
218 				sdio_release_host(func);
219 
220 			if (*err == 0) {
221 				rtw_reset_continual_io_error(psdiodev);
222 				break;
223 			} else {
224 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
225 					padapter->bSurpriseRemoved = true;
226 
227 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
228 					padapter->bSurpriseRemoved = true;
229 					break;
230 				}
231 			}
232 		}
233 	}
234 	return  v;
235 }
236 
237 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
238 {
239 	struct adapter *padapter;
240 	struct dvobj_priv *psdiodev;
241 	struct sdio_data *psdio;
242 	struct sdio_func *func;
243 	bool claim_needed;
244 
245 	padapter = pintfhdl->padapter;
246 	psdiodev = pintfhdl->pintf_dev;
247 	psdio = &psdiodev->intf_data;
248 
249 	if (padapter->bSurpriseRemoved)
250 		return;
251 
252 	func = psdio->func;
253 	claim_needed = rtw_sdio_claim_host_needed(func);
254 
255 	if (claim_needed)
256 		sdio_claim_host(func);
257 	sdio_writeb(func, v, addr, err);
258 	if (claim_needed)
259 		sdio_release_host(func);
260 }
261 
262 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
263 {
264 	struct adapter *padapter;
265 	struct dvobj_priv *psdiodev;
266 	struct sdio_data *psdio;
267 	struct sdio_func *func;
268 	bool claim_needed;
269 
270 	padapter = pintfhdl->padapter;
271 	psdiodev = pintfhdl->pintf_dev;
272 	psdio = &psdiodev->intf_data;
273 
274 	if (padapter->bSurpriseRemoved)
275 		return;
276 
277 	func = psdio->func;
278 	claim_needed = rtw_sdio_claim_host_needed(func);
279 
280 	if (claim_needed)
281 		sdio_claim_host(func);
282 	sdio_writel(func, v, addr, err);
283 	if (claim_needed)
284 		sdio_release_host(func);
285 
286 	if (err && *err) {
287 		int i;
288 
289 		*err = 0;
290 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
291 			if (claim_needed)
292 				sdio_claim_host(func);
293 			sdio_writel(func, v, addr, err);
294 			if (claim_needed)
295 				sdio_release_host(func);
296 			if (*err == 0) {
297 				rtw_reset_continual_io_error(psdiodev);
298 				break;
299 			} else {
300 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
301 					padapter->bSurpriseRemoved = true;
302 
303 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
304 					padapter->bSurpriseRemoved = true;
305 					break;
306 				}
307 			}
308 		}
309 
310 	}
311 }
312 
313 /*
314  * Use CMD53 to read data from SDIO device.
315  * This function MUST be called after sdio_claim_host() or
316  * in SDIO ISR(host had been claimed).
317  *
318  * Parameters:
319  *psdio	pointer of SDIO_DATA
320  *addr	address to read
321  *cnt		amount to read
322  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
323  *
324  * Return:
325  *0		Success
326  *others	Fail
327  */
328 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
329 {
330 	struct adapter *padapter;
331 	struct dvobj_priv *psdiodev;
332 	struct sdio_data *psdio;
333 
334 	int err = -EPERM;
335 	struct sdio_func *func;
336 
337 	padapter = pintfhdl->padapter;
338 	psdiodev = pintfhdl->pintf_dev;
339 	psdio = &psdiodev->intf_data;
340 
341 	if (padapter->bSurpriseRemoved)
342 		return err;
343 
344 	func = psdio->func;
345 
346 	if (unlikely((cnt == 1) || (cnt == 2))) {
347 		int i;
348 		u8 *pbuf = pdata;
349 
350 		for (i = 0; i < cnt; i++) {
351 			*(pbuf + i) = sdio_readb(func, addr + i, &err);
352 
353 			if (err)
354 				break;
355 		}
356 		return err;
357 	}
358 
359 	err = sdio_memcpy_fromio(func, pdata, addr, cnt);
360 
361 	return err;
362 }
363 
364 /*
365  * Use CMD53 to read data from SDIO device.
366  *
367  * Parameters:
368  *psdio	pointer of SDIO_DATA
369  *addr	address to read
370  *cnt		amount to read
371  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
372  *
373  * Return:
374  *0		Success
375  *others	Fail
376  */
377 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
378 {
379 	struct adapter *padapter;
380 	struct dvobj_priv *psdiodev;
381 	struct sdio_data *psdio;
382 
383 	struct sdio_func *func;
384 	bool claim_needed;
385 	s32 err = -EPERM;
386 
387 	padapter = pintfhdl->padapter;
388 	psdiodev = pintfhdl->pintf_dev;
389 	psdio = &psdiodev->intf_data;
390 
391 	if (padapter->bSurpriseRemoved)
392 		return err;
393 
394 	func = psdio->func;
395 	claim_needed = rtw_sdio_claim_host_needed(func);
396 
397 	if (claim_needed)
398 		sdio_claim_host(func);
399 	err = _sd_read(pintfhdl, addr, cnt, pdata);
400 	if (claim_needed)
401 		sdio_release_host(func);
402 	return err;
403 }
404 
405 /*
406  * Use CMD53 to write data to SDIO device.
407  * This function MUST be called after sdio_claim_host() or
408  * in SDIO ISR(host had been claimed).
409  *
410  * Parameters:
411  *psdio	pointer of SDIO_DATA
412  *addr	address to write
413  *cnt		amount to write
414  *pdata	data pointer, this should be a "DMA:able scratch buffer"!
415  *
416  * Return:
417  *0		Success
418  *others	Fail
419  */
420 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
421 {
422 	struct adapter *padapter;
423 	struct dvobj_priv *psdiodev;
424 	struct sdio_data *psdio;
425 
426 	struct sdio_func *func;
427 	u32 size;
428 	s32 err =  -EPERM;
429 
430 	padapter = pintfhdl->padapter;
431 	psdiodev = pintfhdl->pintf_dev;
432 	psdio = &psdiodev->intf_data;
433 
434 	if (padapter->bSurpriseRemoved)
435 		return err;
436 
437 	func = psdio->func;
438 /*	size = sdio_align_size(func, cnt); */
439 
440 	if (unlikely((cnt == 1) || (cnt == 2))) {
441 		int i;
442 		u8 *pbuf = pdata;
443 
444 		for (i = 0; i < cnt; i++) {
445 			sdio_writeb(func, *(pbuf + i), addr + i, &err);
446 			if (err)
447 				break;
448 		}
449 
450 		return err;
451 	}
452 
453 	size = cnt;
454 	err = sdio_memcpy_toio(func, addr, pdata, size);
455 
456 	return err;
457 }
458 
459 /*
460  * Use CMD53 to write data to SDIO device.
461  *
462  * Parameters:
463  *  psdio	pointer of SDIO_DATA
464  *  addr	address to write
465  *  cnt		amount to write
466  *  pdata	data pointer, this should be a "DMA:able scratch buffer"!
467  *
468  * Return:
469  *  0		Success
470  *  others	Fail
471  */
472 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
473 {
474 	struct adapter *padapter;
475 	struct dvobj_priv *psdiodev;
476 	struct sdio_data *psdio;
477 	struct sdio_func *func;
478 	bool claim_needed;
479 	s32 err =  -EPERM;
480 
481 	padapter = pintfhdl->padapter;
482 	psdiodev = pintfhdl->pintf_dev;
483 	psdio = &psdiodev->intf_data;
484 
485 	if (padapter->bSurpriseRemoved)
486 		return err;
487 
488 	func = psdio->func;
489 	claim_needed = rtw_sdio_claim_host_needed(func);
490 
491 	if (claim_needed)
492 		sdio_claim_host(func);
493 	err = _sd_write(pintfhdl, addr, cnt, pdata);
494 	if (claim_needed)
495 		sdio_release_host(func);
496 	return err;
497 }
498