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