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 
rtw_sdio_claim_host_needed(struct sdio_func * func)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 
rtw_sdio_set_irq_thd(struct dvobj_priv * dvobj,void * thd_hdl)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 
sd_f0_read8(struct intf_hdl * pintfhdl,u32 addr,s32 * err)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  */
_sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)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  */
sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)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  */
_sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)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__,
160 				 err, addr + i, pdata[i]);
161 			break;
162 		}
163 	}
164 	return err;
165 }
166 
167 /*
168  * Return:
169  *0		Success
170  *others	Fail
171  */
sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)172 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
173 {
174 	struct adapter *padapter;
175 	struct dvobj_priv *psdiodev;
176 	struct sdio_data *psdio;
177 
178 	int err = 0;
179 	struct sdio_func *func;
180 	bool claim_needed;
181 
182 	padapter = pintfhdl->padapter;
183 	psdiodev = pintfhdl->pintf_dev;
184 	psdio = &psdiodev->intf_data;
185 
186 	if (padapter->bSurpriseRemoved) {
187 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
188 		return err;
189 	}
190 
191 	func = psdio->func;
192 	claim_needed = rtw_sdio_claim_host_needed(func);
193 
194 	if (claim_needed)
195 		sdio_claim_host(func);
196 	err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
197 	if (claim_needed)
198 		sdio_release_host(func);
199 	return err;
200 }
201 
sd_read8(struct intf_hdl * pintfhdl,u32 addr,s32 * err)202 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
203 {
204 	struct adapter *padapter;
205 	struct dvobj_priv *psdiodev;
206 	struct sdio_data *psdio;
207 
208 	u8 v = 0;
209 	struct sdio_func *func;
210 	bool claim_needed;
211 
212 	padapter = pintfhdl->padapter;
213 	psdiodev = pintfhdl->pintf_dev;
214 	psdio = &psdiodev->intf_data;
215 
216 	if (padapter->bSurpriseRemoved) {
217 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
218 		return v;
219 	}
220 
221 	func = psdio->func;
222 	claim_needed = rtw_sdio_claim_host_needed(func);
223 
224 	if (claim_needed)
225 		sdio_claim_host(func);
226 	v = sdio_readb(func, addr, err);
227 	if (claim_needed)
228 		sdio_release_host(func);
229 	if (err && *err)
230 		DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, *err, addr);
231 	return v;
232 }
233 
sd_read32(struct intf_hdl * pintfhdl,u32 addr,s32 * err)234 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
235 {
236 	struct adapter *padapter;
237 	struct dvobj_priv *psdiodev;
238 	struct sdio_data *psdio;
239 	u32 v = 0;
240 	struct sdio_func *func;
241 	bool claim_needed;
242 
243 	padapter = pintfhdl->padapter;
244 	psdiodev = pintfhdl->pintf_dev;
245 	psdio = &psdiodev->intf_data;
246 
247 	if (padapter->bSurpriseRemoved) {
248 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
249 		return v;
250 	}
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 	v = sdio_readl(func, addr, err);
258 	if (claim_needed)
259 		sdio_release_host(func);
260 
261 	if (err && *err) {
262 		int i;
263 
264 		DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x\n", __func__, *err, addr, v);
265 
266 		*err = 0;
267 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
268 			if (claim_needed)
269 				sdio_claim_host(func);
270 			v = sdio_readl(func, addr, err);
271 			if (claim_needed)
272 				sdio_release_host(func);
273 
274 			if (*err == 0) {
275 				rtw_reset_continual_io_error(psdiodev);
276 				break;
277 			} else {
278 				DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
279 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
280 					padapter->bSurpriseRemoved = true;
281 
282 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
283 					padapter->bSurpriseRemoved = true;
284 					break;
285 				}
286 			}
287 		}
288 
289 		if (i == SD_IO_TRY_CNT)
290 			DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
291 		else
292 			DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
293 
294 	}
295 	return  v;
296 }
297 
sd_write8(struct intf_hdl * pintfhdl,u32 addr,u8 v,s32 * err)298 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
299 {
300 	struct adapter *padapter;
301 	struct dvobj_priv *psdiodev;
302 	struct sdio_data *psdio;
303 	struct sdio_func *func;
304 	bool claim_needed;
305 
306 	padapter = pintfhdl->padapter;
307 	psdiodev = pintfhdl->pintf_dev;
308 	psdio = &psdiodev->intf_data;
309 
310 	if (padapter->bSurpriseRemoved) {
311 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
312 		return;
313 	}
314 
315 	func = psdio->func;
316 	claim_needed = rtw_sdio_claim_host_needed(func);
317 
318 	if (claim_needed)
319 		sdio_claim_host(func);
320 	sdio_writeb(func, v, addr, err);
321 	if (claim_needed)
322 		sdio_release_host(func);
323 	if (err && *err)
324 		DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n", __func__, *err, addr, v);
325 }
326 
sd_write32(struct intf_hdl * pintfhdl,u32 addr,u32 v,s32 * err)327 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
328 {
329 	struct adapter *padapter;
330 	struct dvobj_priv *psdiodev;
331 	struct sdio_data *psdio;
332 	struct sdio_func *func;
333 	bool claim_needed;
334 
335 	padapter = pintfhdl->padapter;
336 	psdiodev = pintfhdl->pintf_dev;
337 	psdio = &psdiodev->intf_data;
338 
339 	if (padapter->bSurpriseRemoved) {
340 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
341 		return;
342 	}
343 
344 	func = psdio->func;
345 	claim_needed = rtw_sdio_claim_host_needed(func);
346 
347 	if (claim_needed)
348 		sdio_claim_host(func);
349 	sdio_writel(func, v, addr, err);
350 	if (claim_needed)
351 		sdio_release_host(func);
352 
353 	if (err && *err) {
354 		int i;
355 
356 		DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x\n", __func__, *err, addr, v);
357 
358 		*err = 0;
359 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
360 			if (claim_needed)
361 				sdio_claim_host(func);
362 			sdio_writel(func, v, addr, err);
363 			if (claim_needed)
364 				sdio_release_host(func);
365 			if (*err == 0) {
366 				rtw_reset_continual_io_error(psdiodev);
367 				break;
368 			} else {
369 				DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x, val = 0x%x, try_cnt =%d\n", __func__, *err, addr, v, i);
370 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
371 					padapter->bSurpriseRemoved = true;
372 
373 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == true) {
374 					padapter->bSurpriseRemoved = true;
375 					break;
376 				}
377 			}
378 		}
379 
380 		if (i == SD_IO_TRY_CNT)
381 			DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
382 		else
383 			DBG_871X(KERN_ERR "%s: (%d) addr = 0x%05x val = 0x%08x, try_cnt =%d\n", __func__, *err, addr, v, i);
384 	}
385 }
386 
387 /*
388  * Use CMD53 to read data from SDIO device.
389  * This function MUST be called after sdio_claim_host() or
390  * in SDIO ISR(host had been claimed).
391  *
392  * Parameters:
393  *psdio	pointer of SDIO_DATA
394  *addr	address to read
395  *cnt		amount to read
396  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
397  *
398  * Return:
399  *0		Success
400  *others	Fail
401  */
_sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)402 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
403 {
404 	struct adapter *padapter;
405 	struct dvobj_priv *psdiodev;
406 	struct sdio_data *psdio;
407 
408 	int err = -EPERM;
409 	struct sdio_func *func;
410 
411 	padapter = pintfhdl->padapter;
412 	psdiodev = pintfhdl->pintf_dev;
413 	psdio = &psdiodev->intf_data;
414 
415 	if (padapter->bSurpriseRemoved) {
416 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
417 		return err;
418 	}
419 
420 	func = psdio->func;
421 
422 	if (unlikely((cnt == 1) || (cnt == 2))) {
423 		int i;
424 		u8 *pbuf = pdata;
425 
426 		for (i = 0; i < cnt; i++) {
427 			*(pbuf + i) = sdio_readb(func, addr + i, &err);
428 
429 			if (err) {
430 				DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x\n", __func__, err, addr);
431 				break;
432 			}
433 		}
434 		return err;
435 	}
436 
437 	err = sdio_memcpy_fromio(func, pdata, addr, cnt);
438 	if (err)
439 		DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d\n", __func__, err, addr, cnt);
440 
441 	return err;
442 }
443 
444 /*
445  * Use CMD53 to read data from SDIO device.
446  *
447  * Parameters:
448  *psdio	pointer of SDIO_DATA
449  *addr	address to read
450  *cnt		amount to read
451  *pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
452  *
453  * Return:
454  *0		Success
455  *others	Fail
456  */
sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)457 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
458 {
459 	struct adapter *padapter;
460 	struct dvobj_priv *psdiodev;
461 	struct sdio_data *psdio;
462 
463 	struct sdio_func *func;
464 	bool claim_needed;
465 	s32 err = -EPERM;
466 
467 	padapter = pintfhdl->padapter;
468 	psdiodev = pintfhdl->pintf_dev;
469 	psdio = &psdiodev->intf_data;
470 
471 	if (padapter->bSurpriseRemoved) {
472 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
473 		return err;
474 	}
475 	func = psdio->func;
476 	claim_needed = rtw_sdio_claim_host_needed(func);
477 
478 	if (claim_needed)
479 		sdio_claim_host(func);
480 	err = _sd_read(pintfhdl, addr, cnt, pdata);
481 	if (claim_needed)
482 		sdio_release_host(func);
483 	return err;
484 }
485 
486 /*
487  * Use CMD53 to write data to SDIO device.
488  * This function MUST be called after sdio_claim_host() or
489  * in SDIO ISR(host had been claimed).
490  *
491  * Parameters:
492  *psdio	pointer of SDIO_DATA
493  *addr	address to write
494  *cnt		amount to write
495  *pdata	data pointer, this should be a "DMA:able scratch buffer"!
496  *
497  * Return:
498  *0		Success
499  *others	Fail
500  */
_sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)501 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
502 {
503 	struct adapter *padapter;
504 	struct dvobj_priv *psdiodev;
505 	struct sdio_data *psdio;
506 
507 	struct sdio_func *func;
508 	u32 size;
509 	s32 err =  -EPERM;
510 
511 	padapter = pintfhdl->padapter;
512 	psdiodev = pintfhdl->pintf_dev;
513 	psdio = &psdiodev->intf_data;
514 
515 	if (padapter->bSurpriseRemoved) {
516 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
517 		return err;
518 	}
519 
520 	func = psdio->func;
521 /*	size = sdio_align_size(func, cnt); */
522 
523 	if (unlikely((cnt == 1) || (cnt == 2))) {
524 		int i;
525 		u8 *pbuf = pdata;
526 
527 		for (i = 0; i < cnt; i++) {
528 			sdio_writeb(func, *(pbuf + i), addr + i, &err);
529 			if (err) {
530 				DBG_871X(KERN_ERR "%s: FAIL!(%d) addr = 0x%05x val = 0x%02x\n",
531 					 __func__, err, addr, *(pbuf + i));
532 				break;
533 			}
534 		}
535 
536 		return err;
537 	}
538 
539 	size = cnt;
540 	err = sdio_memcpy_toio(func, addr, pdata, size);
541 	if (err)
542 		DBG_871X(KERN_ERR "%s: FAIL(%d)! ADDR =%#x Size =%d(%d)\n", __func__, err, addr, cnt, size);
543 
544 	return err;
545 }
546 
547 /*
548  * Use CMD53 to write data to SDIO device.
549  *
550  * Parameters:
551  *  psdio	pointer of SDIO_DATA
552  *  addr	address to write
553  *  cnt		amount to write
554  *  pdata	data pointer, this should be a "DMA:able scratch buffer"!
555  *
556  * Return:
557  *  0		Success
558  *  others	Fail
559  */
sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)560 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
561 {
562 	struct adapter *padapter;
563 	struct dvobj_priv *psdiodev;
564 	struct sdio_data *psdio;
565 	struct sdio_func *func;
566 	bool claim_needed;
567 	s32 err =  -EPERM;
568 
569 	padapter = pintfhdl->padapter;
570 	psdiodev = pintfhdl->pintf_dev;
571 	psdio = &psdiodev->intf_data;
572 
573 	if (padapter->bSurpriseRemoved) {
574 		/* DBG_871X(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__); */
575 		return err;
576 	}
577 
578 	func = psdio->func;
579 	claim_needed = rtw_sdio_claim_host_needed(func);
580 
581 	if (claim_needed)
582 		sdio_claim_host(func);
583 	err = _sd_write(pintfhdl, addr, cnt, pdata);
584 	if (claim_needed)
585 		sdio_release_host(func);
586 	return err;
587 }
588