• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 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 _SDIO_OPS_LINUX_C_
16 
17 #include <drv_types.h>
18 
rtw_is_sdio30(_adapter * adapter)19 inline bool rtw_is_sdio30(_adapter *adapter)
20 {
21 	struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
22 	PSDIO_DATA psdio_data = &dvobj->intf_data;
23 
24 	return (psdio_data->sd3_bus_mode) ? _TRUE : _FALSE;
25 }
26 
rtw_sdio_claim_host_needed(struct sdio_func * func)27 static bool rtw_sdio_claim_host_needed(struct sdio_func *func)
28 {
29 	struct dvobj_priv *dvobj = sdio_get_drvdata(func);
30 	PSDIO_DATA sdio_data = &dvobj->intf_data;
31 
32 	if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current)
33 		return _FALSE;
34 	return _TRUE;
35 }
36 
rtw_sdio_set_irq_thd(struct dvobj_priv * dvobj,_thread_hdl_ thd_hdl)37 inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, _thread_hdl_ thd_hdl)
38 {
39 	PSDIO_DATA sdio_data = &dvobj->intf_data;
40 
41 	sdio_data->sys_sdio_irq_thd = thd_hdl;
42 }
43 #ifndef RTW_HALMAC
sd_f0_read8(struct intf_hdl * pintfhdl,u32 addr,s32 * err)44 u8 sd_f0_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
45 {
46 	PADAPTER padapter;
47 	struct dvobj_priv *psdiodev;
48 	PSDIO_DATA psdio;
49 
50 	u8 v = 0;
51 	struct sdio_func *func;
52 	bool claim_needed;
53 
54 
55 	padapter = pintfhdl->padapter;
56 	psdiodev = pintfhdl->pintf_dev;
57 	psdio = &psdiodev->intf_data;
58 
59 	if (rtw_is_surprise_removed(padapter)) {
60 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
61 		return v;
62 	}
63 
64 	func = psdio->func;
65 	claim_needed = rtw_sdio_claim_host_needed(func);
66 
67 	if (claim_needed)
68 		sdio_claim_host(func);
69 	v = sdio_f0_readb(func, addr, err);
70 	if (claim_needed)
71 		sdio_release_host(func);
72 	if (err && *err)
73 		RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
74 
75 
76 	return v;
77 }
78 
sd_f0_write8(struct intf_hdl * pintfhdl,u32 addr,u8 v,s32 * err)79 void sd_f0_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
80 {
81 	PADAPTER padapter;
82 	struct dvobj_priv *psdiodev;
83 	PSDIO_DATA psdio;
84 
85 	struct sdio_func *func;
86 	bool claim_needed;
87 
88 	padapter = pintfhdl->padapter;
89 	psdiodev = pintfhdl->pintf_dev;
90 	psdio = &psdiodev->intf_data;
91 
92 	if (rtw_is_surprise_removed(padapter)) {
93 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
94 		return;
95 	}
96 
97 	func = psdio->func;
98 	claim_needed = rtw_sdio_claim_host_needed(func);
99 
100 	if (claim_needed)
101 		sdio_claim_host(func);
102 	sdio_f0_writeb(func, v, addr, err);
103 	if (claim_needed)
104 		sdio_release_host(func);
105 	if (err && *err)
106 		RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v);
107 
108 }
109 
110 /*
111  * Return:
112  *	0		Success
113  *	others	Fail
114  */
_sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)115 s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
116 {
117 	PADAPTER padapter;
118 	struct dvobj_priv *psdiodev;
119 	PSDIO_DATA psdio;
120 
121 	int err = 0, i;
122 	struct sdio_func *func;
123 
124 	padapter = pintfhdl->padapter;
125 	psdiodev = pintfhdl->pintf_dev;
126 	psdio = &psdiodev->intf_data;
127 
128 	if (rtw_is_surprise_removed(padapter)) {
129 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
130 		return err;
131 	}
132 
133 	func = psdio->func;
134 
135 	for (i = 0; i < cnt; i++) {
136 		pdata[i] = sdio_readb(func, addr + i, &err);
137 		if (err) {
138 			RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr + i);
139 			break;
140 		}
141 	}
142 
143 
144 	return err;
145 }
146 
147 /*
148  * Return:
149  *	0		Success
150  *	others	Fail
151  */
sd_cmd52_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)152 s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
153 {
154 	PADAPTER padapter;
155 	struct dvobj_priv *psdiodev;
156 	PSDIO_DATA psdio;
157 
158 	int err = 0, i;
159 	struct sdio_func *func;
160 	bool claim_needed;
161 
162 	padapter = pintfhdl->padapter;
163 	psdiodev = pintfhdl->pintf_dev;
164 	psdio = &psdiodev->intf_data;
165 
166 	if (rtw_is_surprise_removed(padapter)) {
167 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
168 		return err;
169 	}
170 
171 	func = psdio->func;
172 	claim_needed = rtw_sdio_claim_host_needed(func);
173 
174 	if (claim_needed)
175 		sdio_claim_host(func);
176 	err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata);
177 	if (claim_needed)
178 		sdio_release_host(func);
179 
180 
181 	return err;
182 }
183 
184 /*
185  * Return:
186  *	0		Success
187  *	others	Fail
188  */
_sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)189 s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
190 {
191 	PADAPTER padapter;
192 	struct dvobj_priv *psdiodev;
193 	PSDIO_DATA psdio;
194 
195 	int err = 0, i;
196 	struct sdio_func *func;
197 
198 	padapter = pintfhdl->padapter;
199 	psdiodev = pintfhdl->pintf_dev;
200 	psdio = &psdiodev->intf_data;
201 
202 	if (rtw_is_surprise_removed(padapter)) {
203 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
204 		return err;
205 	}
206 
207 	func = psdio->func;
208 
209 	for (i = 0; i < cnt; i++) {
210 		sdio_writeb(func, pdata[i], addr + i, &err);
211 		if (err) {
212 			RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr + i, pdata[i]);
213 			break;
214 		}
215 	}
216 
217 
218 	return err;
219 }
220 
221 /*
222  * Return:
223  *	0		Success
224  *	others	Fail
225  */
sd_cmd52_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pdata)226 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
227 {
228 	PADAPTER padapter;
229 	struct dvobj_priv *psdiodev;
230 	PSDIO_DATA psdio;
231 
232 	int err = 0, i;
233 	struct sdio_func *func;
234 	bool claim_needed;
235 
236 	padapter = pintfhdl->padapter;
237 	psdiodev = pintfhdl->pintf_dev;
238 	psdio = &psdiodev->intf_data;
239 
240 	if (rtw_is_surprise_removed(padapter)) {
241 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
242 		return err;
243 	}
244 
245 	func = psdio->func;
246 	claim_needed = rtw_sdio_claim_host_needed(func);
247 
248 	if (claim_needed)
249 		sdio_claim_host(func);
250 	err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
251 	if (claim_needed)
252 		sdio_release_host(func);
253 
254 
255 	return err;
256 }
257 
_sd_read8(struct intf_hdl * pintfhdl,u32 addr,s32 * err)258 u8 _sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
259 {
260 	PADAPTER padapter;
261 	struct dvobj_priv *psdiodev;
262 	PSDIO_DATA psdio;
263 
264 	u8 v = 0;
265 	struct sdio_func *func;
266 
267 	padapter = pintfhdl->padapter;
268 	psdiodev = pintfhdl->pintf_dev;
269 	psdio = &psdiodev->intf_data;
270 
271 	if (rtw_is_surprise_removed(padapter)) {
272 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
273 		return v;
274 	}
275 
276 	func = psdio->func;
277 
278 	v = sdio_readb(func, addr, err);
279 
280 	if (err && *err)
281 		RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
282 
283 
284 	return v;
285 }
286 
sd_read8(struct intf_hdl * pintfhdl,u32 addr,s32 * err)287 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
288 {
289 	PADAPTER padapter;
290 	struct dvobj_priv *psdiodev;
291 	PSDIO_DATA psdio;
292 
293 	u8 v = 0;
294 	struct sdio_func *func;
295 	bool claim_needed;
296 
297 	padapter = pintfhdl->padapter;
298 	psdiodev = pintfhdl->pintf_dev;
299 	psdio = &psdiodev->intf_data;
300 
301 	if (rtw_is_surprise_removed(padapter)) {
302 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
303 		return v;
304 	}
305 
306 	func = psdio->func;
307 	claim_needed = rtw_sdio_claim_host_needed(func);
308 
309 	if (claim_needed)
310 		sdio_claim_host(func);
311 	v = sdio_readb(func, addr, err);
312 	if (claim_needed)
313 		sdio_release_host(func);
314 	if (err && *err)
315 		RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
316 
317 
318 	return v;
319 }
320 
sd_read16(struct intf_hdl * pintfhdl,u32 addr,s32 * err)321 u16 sd_read16(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
322 {
323 	PADAPTER padapter;
324 	struct dvobj_priv *psdiodev;
325 	PSDIO_DATA psdio;
326 
327 	u16 v = 0;
328 	struct sdio_func *func;
329 	bool claim_needed;
330 
331 	padapter = pintfhdl->padapter;
332 	psdiodev = pintfhdl->pintf_dev;
333 	psdio = &psdiodev->intf_data;
334 
335 	if (rtw_is_surprise_removed(padapter)) {
336 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
337 		return v;
338 	}
339 
340 	func = psdio->func;
341 	claim_needed = rtw_sdio_claim_host_needed(func);
342 
343 	if (claim_needed)
344 		sdio_claim_host(func);
345 	v = sdio_readw(func, addr, err);
346 	if (claim_needed)
347 		sdio_release_host(func);
348 	if (err && *err)
349 		RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
350 
351 
352 	return  v;
353 }
354 
_sd_read32(struct intf_hdl * pintfhdl,u32 addr,s32 * err)355 u32 _sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
356 {
357 	PADAPTER padapter;
358 	struct dvobj_priv *psdiodev;
359 	PSDIO_DATA psdio;
360 
361 	u32 v = 0;
362 	struct sdio_func *func;
363 
364 	padapter = pintfhdl->padapter;
365 	psdiodev = pintfhdl->pintf_dev;
366 	psdio = &psdiodev->intf_data;
367 
368 	if (rtw_is_surprise_removed(padapter)) {
369 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
370 		return v;
371 	}
372 
373 	func = psdio->func;
374 
375 	v = sdio_readl(func, addr, err);
376 
377 	if (err && *err) {
378 		int i;
379 
380 		RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x\n", __func__, *err, addr, v);
381 
382 		*err = 0;
383 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
384 			/* sdio_claim_host(func); */
385 			v = sdio_readl(func, addr, err);
386 			/* sdio_release_host(func); */
387 			if (*err == 0) {
388 				rtw_reset_continual_io_error(psdiodev);
389 				break;
390 			} else {
391 				RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
392 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
393 					rtw_set_surprise_removed(padapter);
394 
395 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
396 					rtw_set_surprise_removed(padapter);
397 					break;
398 				}
399 
400 			}
401 		}
402 
403 		if (i == SD_IO_TRY_CNT)
404 			RTW_ERR("%s: FAIL!(%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
405 		else
406 			RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
407 
408 	}
409 
410 
411 	return  v;
412 }
413 
sd_read32(struct intf_hdl * pintfhdl,u32 addr,s32 * err)414 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
415 {
416 	PADAPTER padapter;
417 	struct dvobj_priv *psdiodev;
418 	PSDIO_DATA psdio;
419 
420 	u32 v = 0;
421 	struct sdio_func *func;
422 	bool claim_needed;
423 
424 	padapter = pintfhdl->padapter;
425 	psdiodev = pintfhdl->pintf_dev;
426 	psdio = &psdiodev->intf_data;
427 
428 	if (rtw_is_surprise_removed(padapter)) {
429 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
430 		return v;
431 	}
432 
433 	func = psdio->func;
434 	claim_needed = rtw_sdio_claim_host_needed(func);
435 
436 	if (claim_needed)
437 		sdio_claim_host(func);
438 	v = sdio_readl(func, addr, err);
439 	if (claim_needed)
440 		sdio_release_host(func);
441 
442 	if (err && *err) {
443 		int i;
444 
445 		RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x\n", __func__, *err, addr, v);
446 
447 		*err = 0;
448 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
449 			if (claim_needed)
450 				sdio_claim_host(func);
451 			v = sdio_readl(func, addr, err);
452 			if (claim_needed)
453 				sdio_release_host(func);
454 
455 			if (*err == 0) {
456 				rtw_reset_continual_io_error(psdiodev);
457 				break;
458 			} else {
459 				RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
460 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
461 					rtw_set_surprise_removed(padapter);
462 
463 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
464 					rtw_set_surprise_removed(padapter);
465 					break;
466 				}
467 			}
468 		}
469 
470 		if (i == SD_IO_TRY_CNT)
471 			RTW_ERR("%s: FAIL!(%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
472 		else
473 			RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
474 
475 	}
476 
477 
478 	return  v;
479 }
480 
sd_write8(struct intf_hdl * pintfhdl,u32 addr,u8 v,s32 * err)481 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
482 {
483 	PADAPTER padapter;
484 	struct dvobj_priv *psdiodev;
485 	PSDIO_DATA psdio;
486 
487 	struct sdio_func *func;
488 	bool claim_needed;
489 
490 
491 	padapter = pintfhdl->padapter;
492 	psdiodev = pintfhdl->pintf_dev;
493 	psdio = &psdiodev->intf_data;
494 
495 	if (rtw_is_surprise_removed(padapter)) {
496 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
497 		return ;
498 	}
499 
500 	func = psdio->func;
501 	claim_needed = rtw_sdio_claim_host_needed(func);
502 
503 	if (claim_needed)
504 		sdio_claim_host(func);
505 	sdio_writeb(func, v, addr, err);
506 	if (claim_needed)
507 		sdio_release_host(func);
508 	if (err && *err)
509 		RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v);
510 
511 }
512 
sd_write16(struct intf_hdl * pintfhdl,u32 addr,u16 v,s32 * err)513 void sd_write16(struct intf_hdl *pintfhdl, u32 addr, u16 v, s32 *err)
514 {
515 	PADAPTER padapter;
516 	struct dvobj_priv *psdiodev;
517 	PSDIO_DATA psdio;
518 
519 	struct sdio_func *func;
520 	bool claim_needed;
521 
522 	padapter = pintfhdl->padapter;
523 	psdiodev = pintfhdl->pintf_dev;
524 	psdio = &psdiodev->intf_data;
525 
526 	if (rtw_is_surprise_removed(padapter)) {
527 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
528 		return ;
529 	}
530 
531 	func = psdio->func;
532 	claim_needed = rtw_sdio_claim_host_needed(func);
533 
534 	if (claim_needed)
535 		sdio_claim_host(func);
536 	sdio_writew(func, v, addr, err);
537 	if (claim_needed)
538 		sdio_release_host(func);
539 	if (err && *err)
540 		RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%04x\n", __func__, *err, addr, v);
541 
542 }
543 
_sd_write32(struct intf_hdl * pintfhdl,u32 addr,u32 v,s32 * err)544 void _sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
545 {
546 	PADAPTER padapter;
547 	struct dvobj_priv *psdiodev;
548 	PSDIO_DATA psdio;
549 
550 	struct sdio_func *func;
551 
552 	padapter = pintfhdl->padapter;
553 	psdiodev = pintfhdl->pintf_dev;
554 	psdio = &psdiodev->intf_data;
555 
556 	if (rtw_is_surprise_removed(padapter)) {
557 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
558 		return ;
559 	}
560 
561 	func = psdio->func;
562 
563 	sdio_writel(func, v, addr, err);
564 
565 	if (err && *err) {
566 		int i;
567 
568 		RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v);
569 
570 		*err = 0;
571 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
572 			sdio_writel(func, v, addr, err);
573 			if (*err == 0) {
574 				rtw_reset_continual_io_error(psdiodev);
575 				break;
576 			} else {
577 				RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
578 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
579 					rtw_set_surprise_removed(padapter);
580 
581 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
582 					rtw_set_surprise_removed(padapter);
583 					break;
584 				}
585 			}
586 		}
587 
588 		if (i == SD_IO_TRY_CNT)
589 			RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
590 		else
591 			RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
592 
593 	}
594 
595 }
596 
sd_write32(struct intf_hdl * pintfhdl,u32 addr,u32 v,s32 * err)597 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
598 {
599 	PADAPTER padapter;
600 	struct dvobj_priv *psdiodev;
601 	PSDIO_DATA psdio;
602 	struct sdio_func *func;
603 	bool claim_needed;
604 
605 	padapter = pintfhdl->padapter;
606 	psdiodev = pintfhdl->pintf_dev;
607 	psdio = &psdiodev->intf_data;
608 
609 	if (rtw_is_surprise_removed(padapter)) {
610 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
611 		return ;
612 	}
613 
614 	func = psdio->func;
615 	claim_needed = rtw_sdio_claim_host_needed(func);
616 
617 	if (claim_needed)
618 		sdio_claim_host(func);
619 	sdio_writel(func, v, addr, err);
620 	if (claim_needed)
621 		sdio_release_host(func);
622 
623 	if (err && *err) {
624 		int i;
625 
626 		RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v);
627 
628 		*err = 0;
629 		for (i = 0; i < SD_IO_TRY_CNT; i++) {
630 			if (claim_needed)
631 				sdio_claim_host(func);
632 			sdio_writel(func, v, addr, err);
633 			if (claim_needed)
634 				sdio_release_host(func);
635 			if (*err == 0) {
636 				rtw_reset_continual_io_error(psdiodev);
637 				break;
638 			} else {
639 				RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
640 				if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
641 					rtw_set_surprise_removed(padapter);
642 
643 				if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
644 					rtw_set_surprise_removed(padapter);
645 					break;
646 				}
647 			}
648 		}
649 
650 		if (i == SD_IO_TRY_CNT)
651 			RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
652 		else
653 			RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
654 	}
655 
656 }
657 #endif /* !RTW_HALMAC */
658 
659 /*
660  * Use CMD53 to read data from SDIO device.
661  * This function MUST be called after sdio_claim_host() or
662  * in SDIO ISR(host had been claimed).
663  *
664  * Parameters:
665  *	psdio	pointer of SDIO_DATA
666  *	addr	address to read
667  *	cnt		amount to read
668  *	pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
669  *
670  * Return:
671  *	0		Success
672  *	others	Fail
673  */
_sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)674 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
675 {
676 	PADAPTER padapter;
677 	struct dvobj_priv *psdiodev;
678 	PSDIO_DATA psdio;
679 
680 	int err = -EPERM;
681 	struct sdio_func *func;
682 
683 	padapter = pintfhdl->padapter;
684 	psdiodev = pintfhdl->pintf_dev;
685 	psdio = &psdiodev->intf_data;
686 
687 	if (rtw_is_surprise_removed(padapter)) {
688 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
689 		return err;
690 	}
691 
692 	func = psdio->func;
693 
694 	if (unlikely((cnt == 1) || (cnt == 2))) {
695 		int i;
696 		u8 *pbuf = (u8 *)pdata;
697 
698 		for (i = 0; i < cnt; i++) {
699 			*(pbuf + i) = sdio_readb(func, addr + i, &err);
700 
701 			if (err) {
702 				RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr);
703 				break;
704 			}
705 		}
706 		return err;
707 	}
708 
709 	err = sdio_memcpy_fromio(func, pdata, addr, cnt);
710 	if (err)
711 		RTW_ERR("%s: FAIL(%d)! ADDR=%#x Size=%d\n", __func__, err, addr, cnt);
712 
713 	if (err == (-ESHUTDOWN) || err == (-ENODEV) || err == (-ENOMEDIUM) || err == (-ETIMEDOUT))
714 		rtw_set_surprise_removed(padapter);
715 
716 
717 	return err;
718 }
719 
720 /*
721  * Use CMD53 to read data from SDIO device.
722  *
723  * Parameters:
724  *	psdio	pointer of SDIO_DATA
725  *	addr	address to read
726  *	cnt		amount to read
727  *	pdata	pointer to put data, this should be a "DMA:able scratch buffer"!
728  *
729  * Return:
730  *	0		Success
731  *	others	Fail
732  */
sd_read(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)733 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
734 {
735 	PADAPTER padapter;
736 	struct dvobj_priv *psdiodev;
737 	PSDIO_DATA psdio;
738 
739 	struct sdio_func *func;
740 	bool claim_needed;
741 	s32 err = -EPERM;
742 
743 	padapter = pintfhdl->padapter;
744 	psdiodev = pintfhdl->pintf_dev;
745 	psdio = &psdiodev->intf_data;
746 
747 	if (rtw_is_surprise_removed(padapter)) {
748 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
749 		return err;
750 	}
751 	func = psdio->func;
752 	claim_needed = rtw_sdio_claim_host_needed(func);
753 
754 	if (claim_needed)
755 		sdio_claim_host(func);
756 	err = _sd_read(pintfhdl, addr, cnt, pdata);
757 	if (claim_needed)
758 		sdio_release_host(func);
759 	return err;
760 }
761 
762 /*
763  * Use CMD53 to write data to SDIO device.
764  * This function MUST be called after sdio_claim_host() or
765  * in SDIO ISR(host had been claimed).
766  *
767  * Parameters:
768  *	psdio	pointer of SDIO_DATA
769  *	addr	address to write
770  *	cnt		amount to write
771  *	pdata	data pointer, this should be a "DMA:able scratch buffer"!
772  *
773  * Return:
774  *	0		Success
775  *	others	Fail
776  */
_sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)777 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
778 {
779 	PADAPTER padapter;
780 	struct dvobj_priv *psdiodev;
781 	PSDIO_DATA psdio;
782 
783 	struct sdio_func *func;
784 	u32 size;
785 	s32 err = -EPERM;
786 
787 	padapter = pintfhdl->padapter;
788 	psdiodev = pintfhdl->pintf_dev;
789 	psdio = &psdiodev->intf_data;
790 
791 	if (rtw_is_surprise_removed(padapter)) {
792 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
793 		return err;
794 	}
795 
796 	func = psdio->func;
797 	/*	size = sdio_align_size(func, cnt); */
798 
799 	if (unlikely((cnt == 1) || (cnt == 2))) {
800 		int i;
801 		u8 *pbuf = (u8 *)pdata;
802 
803 		for (i = 0; i < cnt; i++) {
804 			sdio_writeb(func, *(pbuf + i), addr + i, &err);
805 			if (err) {
806 				RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, *(pbuf + i));
807 				break;
808 			}
809 		}
810 
811 		return err;
812 	}
813 
814 	size = cnt;
815 	err = sdio_memcpy_toio(func, addr, pdata, size);
816 	if (err)
817 		RTW_ERR("%s: FAIL(%d)! ADDR=%#x Size=%d(%d)\n", __func__, err, addr, cnt, size);
818 
819 
820 	return err;
821 }
822 
823 /*
824  * Use CMD53 to write data to SDIO device.
825  *
826  * Parameters:
827  *  psdio	pointer of SDIO_DATA
828  *  addr	address to write
829  *  cnt		amount to write
830  *  pdata	data pointer, this should be a "DMA:able scratch buffer"!
831  *
832  * Return:
833  *  0		Success
834  *  others	Fail
835  */
sd_write(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,void * pdata)836 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
837 {
838 	PADAPTER padapter;
839 	struct dvobj_priv *psdiodev;
840 	PSDIO_DATA psdio;
841 
842 	struct sdio_func *func;
843 	bool claim_needed;
844 	s32 err = -EPERM;
845 	padapter = pintfhdl->padapter;
846 	psdiodev = pintfhdl->pintf_dev;
847 	psdio = &psdiodev->intf_data;
848 
849 	if (rtw_is_surprise_removed(padapter)) {
850 		/* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
851 		return err;
852 	}
853 
854 	func = psdio->func;
855 	claim_needed = rtw_sdio_claim_host_needed(func);
856 
857 	if (claim_needed)
858 		sdio_claim_host(func);
859 	err = _sd_write(pintfhdl, addr, cnt, pdata);
860 	if (claim_needed)
861 		sdio_release_host(func);
862 	return err;
863 }
864 
865 #if 1
866 /*#define RTW_SDIO_DUMP*/
867 #ifdef RTW_SDIO_DUMP
868 #define DUMP_LEN_LMT	0	/* buffer dump size limit */
869 				/* unit: byte, 0 for no limit */
870 #else
871 #define DUMP_LEN_LMT	32
872 #endif
873 #define GET_DUMP_LEN(len)	(DUMP_LEN_LMT ? rtw_min(len, DUMP_LEN_LMT) : len)
874 
875 #ifdef DBG_SDIO
876 #if (DBG_SDIO >= 1)
sdio_dump_reg_by_cmd52(struct dvobj_priv * d,u32 addr,size_t len,u8 * buf)877 static void sdio_dump_reg_by_cmd52(struct dvobj_priv *d,
878 				   u32 addr, size_t len, u8 *buf)
879 {
880 	struct sdio_func *func;
881 	size_t i;
882 	u8 val;
883 	u8 str[80], used = 0;
884 	u8 read_twice = 0;
885 	int error;
886 
887 
888 	if (buf)
889 		_rtw_memset(buf, 0xAE, len);
890 	func = dvobj_to_sdio_func(d);
891 	/*
892 	 * When register is WLAN IOREG,
893 	 * read twice to guarantee the result is correct.
894 	 */
895 	if (addr & 0x10000)
896 		read_twice = 1;
897 
898 	_rtw_memset(str, 0, 80);
899 	used = 0;
900 	if (addr & 0xF) {
901 		used += snprintf(str+used, (80-used), "0x%02x:\t", addr&~0xF);
902 		used += snprintf(str+used, (80-used), "%*s", (addr&0xF)*5, "");
903 	}
904 	for (i = 0; i < len; i++, addr++) {
905 		val = sdio_readb(func, addr, &error);
906 		if (read_twice)
907 			val = sdio_readb(func, addr, &error);
908 		if (error)
909 			break;
910 
911 		if (buf)
912 			buf[i] = val;
913 
914 		if (!(addr & 0xF))
915 			used += snprintf(str+used, (80-used), "0x%02x:\t", addr&~0xF);
916 		used += snprintf(str+used, (80-used), "%02x ", val);
917 		if (((i + 1) < len) && ((addr + 1) & 0xF) == 0) {
918 			dev_err(&func->dev, "%s", str);
919 			_rtw_memset(str, 0, 80);
920 			used = 0;
921 		}
922 	}
923 
924 	if (used) {
925 		dev_err(&func->dev, "%s", str);
926 		_rtw_memset(str, 0, 80);
927 		used = 0;
928 	}
929 
930 	if (error)
931 		dev_err(&func->dev, "rtw_sdio_dbg: READ 0x%02x FAIL!", addr);
932 }
933 
sdio_dump_cia(struct dvobj_priv * d,u32 addr,size_t len,u8 * buf)934 static void sdio_dump_cia(struct dvobj_priv *d, u32 addr, size_t len, u8 *buf)
935 {
936 	struct sdio_func *func;
937 	size_t i;
938 	u8 val;
939 	u8 str[80], used = 0;
940 	int error;
941 
942 
943 	if (buf)
944 		_rtw_memset(buf, 0xAE, len);
945 	func = dvobj_to_sdio_func(d);
946 
947 	_rtw_memset(str, 0, 80);
948 	used = 0;
949 	if (addr & 0xF) {
950 		used += snprintf(str+used, (80-used), "0x%02x:\t", addr&~0xF);
951 		used += snprintf(str+used, (80-used), "%*s", (addr&0xF)*5, "");
952 	}
953 	for (i = 0; i < len; i++, addr++) {
954 		val = sdio_f0_readb(func, addr, &error);
955 		if (error)
956 			break;
957 
958 		if (buf)
959 			buf[i] = val;
960 
961 		if (!(addr & 0xF))
962 			used += snprintf(str+used, (80-used), "0x%02x:\t", addr&~0xF);
963 		used += snprintf(str+used, (80-used), "%02x ", val);
964 		if (((i + 1) < len) && ((addr + 1) & 0xF) == 0) {
965 			dev_err(&func->dev, "%s", str);
966 			_rtw_memset(str, 0, 80);
967 			used = 0;
968 		}
969 	}
970 
971 	if (used) {
972 		dev_err(&func->dev, "%s", str);
973 		_rtw_memset(str, 0, 80);
974 		used = 0;
975 	}
976 
977 	if (error)
978 		dev_err(&func->dev, "rtw_sdio_dbg: READ CIA 0x%02x FAIL!",
979 			addr);
980 }
981 
982 #if (DBG_SDIO >= 2)
983 void rtw_sdio_dbg_reg_alloc(struct dvobj_priv *d);
984 #endif /* DBG_SDIO >= 2 */
985 
986 /*
987  * Dump register when CMD53 fail
988  */
sdio_dump_dbg_reg(struct dvobj_priv * d,u8 write,unsigned int addr,size_t len)989 static void sdio_dump_dbg_reg(struct dvobj_priv *d, u8 write,
990 			      unsigned int addr, size_t len)
991 {
992 	struct sdio_data *sdio;
993 	struct sdio_func *func;
994 	u8 *buf = NULL;
995 #if (DBG_SDIO >= 2)
996 	u8 *msg;
997 #endif /* DBG_SDIO >= 2 */
998 
999 
1000 	sdio = &d->intf_data;
1001 	if (sdio->reg_dump_mark)
1002 		return;
1003 	func = dvobj_to_sdio_func(d);
1004 
1005 	sdio->reg_dump_mark = sdio->cmd53_err_cnt;
1006 
1007 #if (DBG_SDIO >= 2)
1008 	if (!sdio->dbg_msg) {
1009 		msg = rtw_zmalloc(80);
1010 		if (msg) {
1011 			sdio->dbg_msg = msg;
1012 			sdio->dbg_msg_size = 80;
1013 		}
1014 	}
1015 	if (sdio->dbg_msg_size) {
1016 		snprintf(sdio->dbg_msg, sdio->dbg_msg_size,
1017 			 "CMD53 %s 0x%05x, %zu bytes FAIL "
1018 			 "at err_cnt=%d",
1019 			 write?"WRITE":"READ",
1020 			 addr, len, sdio->reg_dump_mark);
1021 	}
1022 
1023 	rtw_sdio_dbg_reg_alloc(d);
1024 #endif /* DBG_SDIO >= 2 */
1025 
1026 	/* MAC register */
1027 	dev_err(&func->dev, "MAC register:");
1028 #if (DBG_SDIO >= 2)
1029 	buf = sdio->reg_mac;
1030 #endif /* DBG_SDIO >= 2 */
1031 	sdio_dump_reg_by_cmd52(d, 0x10000, 0x800, buf);
1032 	dev_err(&func->dev, "MAC Extend register:");
1033 #if (DBG_SDIO >= 2)
1034 	buf = sdio->reg_mac_ext;
1035 #endif /* DBG_SDIO >= 2 */
1036 	sdio_dump_reg_by_cmd52(d, 0x11000, 0x800, buf);
1037 
1038 	/* SDIO local register */
1039 	dev_err(&func->dev, "SDIO Local register:");
1040 #if (DBG_SDIO >= 2)
1041 	buf = sdio->reg_local;
1042 #endif /* DBG_SDIO >= 2 */
1043 	sdio_dump_reg_by_cmd52(d, 0x0, 0x100, buf);
1044 
1045 	/* F0 */
1046 	dev_err(&func->dev, "f0 register:");
1047 #if (DBG_SDIO >= 2)
1048 	buf = sdio->reg_cia;
1049 #endif /* DBG_SDIO >= 2 */
1050 	sdio_dump_cia(d, 0x0, 0x200, buf);
1051 }
1052 #endif /* DBG_SDIO >= 1 */
1053 #endif /* DBG_SDIO */
1054 
1055 /**
1056  *	Returns driver error code,
1057  *	0	no error
1058  *	-1	Level 1 error, critical error and can't be recovered
1059  *	-2	Level 2 error, normal error, retry to recover is possible
1060  */
linux_io_err_to_drv_err(int err)1061 static int linux_io_err_to_drv_err(int err)
1062 {
1063 	if (!err)
1064 		return 0;
1065 
1066 	/* critical error */
1067 	if ((err == -ESHUTDOWN) ||
1068 	    (err == -ENODEV) ||
1069 	    (err == -ENOMEDIUM))
1070 		return -1;
1071 
1072 	/* other error */
1073 	return -2;
1074 }
1075 
1076 /**
1077  *	rtw_sdio_raw_read - Read from SDIO device
1078  *	@d: driver object private data
1079  *	@addr: address to read
1080  *	@buf: buffer to store the data
1081  *	@len: number of bytes to read
1082  *	@fixed:
1083  *
1084  *	Reads from the address space of a SDIO device.
1085  *	Return value indicates if the transfer succeeded or not.
1086  */
rtw_sdio_raw_read(struct dvobj_priv * d,unsigned int addr,void * buf,size_t len,bool fixed)1087 int __must_check rtw_sdio_raw_read(struct dvobj_priv *d, unsigned int addr,
1088 				   void *buf, size_t len, bool fixed)
1089 {
1090 	int error = -EPERM;
1091 	bool f0, cmd52;
1092 	struct sdio_func *func;
1093 	bool claim_needed;
1094 	u32 offset, i;
1095 
1096 
1097 	func = dvobj_to_sdio_func(d);
1098 	claim_needed = rtw_sdio_claim_host_needed(func);
1099 	f0 = RTW_SDIO_ADDR_F0_CHK(addr);
1100 	cmd52 = RTW_SDIO_ADDR_CMD52_CHK(addr);
1101 
1102 	/*
1103 	 * Mask addr to remove driver defined bit and
1104 	 * make sure addr is in valid range
1105 	 */
1106 	if (f0)
1107 		addr &= 0xFFF;
1108 	else
1109 		addr &= 0x1FFFF;
1110 
1111 #ifdef RTW_SDIO_DUMP
1112 	if (f0)
1113 		dev_dbg(&func->dev, "rtw_sdio: READ F0\n");
1114 	else if (cmd52)
1115 		dev_dbg(&func->dev, "rtw_sdio: READ use CMD52\n");
1116 	else
1117 		dev_dbg(&func->dev, "rtw_sdio: READ use CMD53\n");
1118 
1119 	dev_dbg(&func->dev, "rtw_sdio: READ from 0x%05x\n", addr);
1120 #endif /* RTW_SDIO_DUMP */
1121 
1122 	if (claim_needed)
1123 		sdio_claim_host(func);
1124 
1125 	if (f0) {
1126 		offset = addr;
1127 		for (i = 0; i < len; i++, offset++) {
1128 			((u8 *)buf)[i] = sdio_f0_readb(func, offset, &error);
1129 			if (error)
1130 				break;
1131 #if 0
1132 			dev_info(&func->dev, "%s: sdio f0 read 52 addr 0x%x, byte 0x%02x\n",
1133 				 __func__, offset, ((u8 *)buf)[i]);
1134 #endif
1135 		}
1136 	} else {
1137 		if (cmd52) {
1138 #ifdef RTW_SDIO_IO_DBG
1139 			dev_info(&func->dev, "%s: sdio read 52 addr 0x%x, %zu bytes\n",
1140 				 __func__, addr, len);
1141 #endif
1142 			offset = addr;
1143 			for (i = 0; i < len; i++) {
1144 				((u8 *)buf)[i] = sdio_readb(func, offset, &error);
1145 				if (error)
1146 					break;
1147 #if 0
1148 				dev_info(&func->dev, "%s: sdio read 52 addr 0x%x, byte 0x%02x\n",
1149 					 __func__, offset, ((u8 *)buf)[i]);
1150 #endif
1151 				if (!fixed)
1152 					offset++;
1153 			}
1154 		} else {
1155 #ifdef RTW_SDIO_IO_DBG
1156 			dev_info(&func->dev, "%s: sdio read 53 addr 0x%x, %zu bytes\n",
1157 				 __func__, addr, len);
1158 #endif
1159 			if (fixed)
1160 				error = sdio_readsb(func, buf, addr, len);
1161 			else
1162 				error = sdio_memcpy_fromio(func, buf, addr, len);
1163 		}
1164 	}
1165 
1166 #ifdef DBG_SDIO
1167 #if (DBG_SDIO >= 3)
1168 	if (!error && !f0 && !cmd52
1169 	    && (d->intf_data.dbg_enable
1170 		&& d->intf_data.err_test && !d->intf_data.err_test_triggered
1171 		&& ((addr & 0x10000)
1172 		    || (!(addr & 0xE000)
1173 			&& !((addr >= 0x40) && (addr < 0x48)))))) {
1174 		d->intf_data.err_test_triggered = 1;
1175 		error = -ETIMEDOUT;
1176 		dev_warn(&func->dev, "Simulate error(%d) READ addr=0x%05x %zu bytes",
1177 			 error, addr, len);
1178 	}
1179 #endif /* DBG_SDIO >= 3 */
1180 
1181 	if (error) {
1182 		if (f0 || cmd52) {
1183 			d->intf_data.cmd52_err_cnt++;
1184 		} else {
1185 			d->intf_data.cmd53_err_cnt++;
1186 #if (DBG_SDIO >= 1)
1187 			sdio_dump_dbg_reg(d, 0, addr, len);
1188 #endif /* DBG_SDIO >= 1 */
1189 		}
1190 	}
1191 #endif /* DBG_SDIO */
1192 
1193 	if (claim_needed)
1194 		sdio_release_host(func);
1195 
1196 #ifdef RTW_SDIO_DUMP
1197 	print_hex_dump(KERN_DEBUG, "rtw_sdio: READ ",
1198 		       DUMP_PREFIX_OFFSET, 16, 1,
1199 		       buf, GET_DUMP_LEN(len), false);
1200 #endif /* RTW_SDIO_DUMP */
1201 
1202 	if (WARN_ON(error)) {
1203 		dev_err(&func->dev, "%s: sdio read failed (%d)\n", __func__, error);
1204 #ifndef RTW_SDIO_DUMP
1205 		if (f0)
1206 			dev_err(&func->dev, "rtw_sdio: READ F0\n");
1207 		if (cmd52)
1208 			dev_err(&func->dev, "rtw_sdio: READ use CMD52\n");
1209 		else
1210 			dev_err(&func->dev, "rtw_sdio: READ use CMD53\n");
1211 		dev_err(&func->dev, "rtw_sdio: READ from 0x%05x, %zu bytes\n", addr, len);
1212 		print_hex_dump(KERN_ERR, "rtw_sdio: READ ",
1213 			       DUMP_PREFIX_OFFSET, 16, 1,
1214 			       buf, GET_DUMP_LEN(len), false);
1215 #endif /* !RTW_SDIO_DUMP */
1216 	}
1217 
1218 	return linux_io_err_to_drv_err(error);
1219 }
1220 
1221 /**
1222  *	rtw_sdio_raw_write - Write to SDIO device
1223  *	@d: driver object private data
1224  *	@addr: address to write
1225  *	@buf: buffer that contains the data to write
1226  *	@len: number of bytes to write
1227  *	@fixed: address is fixed(FIFO) or incremented
1228  *
1229  *	Writes to the address space of a SDIO device.
1230  *	Return value indicates if the transfer succeeded or not.
1231  */
rtw_sdio_raw_write(struct dvobj_priv * d,unsigned int addr,void * buf,size_t len,bool fixed)1232 int __must_check rtw_sdio_raw_write(struct dvobj_priv *d, unsigned int addr,
1233 				    void *buf, size_t len, bool fixed)
1234 {
1235 	int error = -EPERM;
1236 	bool f0, cmd52;
1237 	struct sdio_func *func;
1238 	bool claim_needed;
1239 	u32 offset, i;
1240 
1241 
1242 	func = dvobj_to_sdio_func(d);
1243 	claim_needed = rtw_sdio_claim_host_needed(func);
1244 	f0 = RTW_SDIO_ADDR_F0_CHK(addr);
1245 	cmd52 = RTW_SDIO_ADDR_CMD52_CHK(addr);
1246 
1247 	/*
1248 	 * Mask addr to remove driver defined bit and
1249 	 * make sure addr is in valid range
1250 	 */
1251 	if (f0)
1252 		addr &= 0xFFF;
1253 	else
1254 		addr &= 0x1FFFF;
1255 
1256 #ifdef RTW_SDIO_DUMP
1257 	if (f0)
1258 		dev_dbg(&func->dev, "rtw_sdio: WRITE F0\n");
1259 	else if (cmd52)
1260 		dev_dbg(&func->dev, "rtw_sdio: WRITE use CMD52\n");
1261 	else
1262 		dev_dbg(&func->dev, "rtw_sdio: WRITE use CMD53\n");
1263 	dev_dbg(&func->dev, "rtw_sdio: WRITE to 0x%05x\n", addr);
1264 	print_hex_dump(KERN_DEBUG, "rtw_sdio: WRITE ",
1265 		       DUMP_PREFIX_OFFSET, 16, 1,
1266 		       buf, GET_DUMP_LEN(len), false);
1267 #endif /* RTW_SDIO_DUMP */
1268 
1269 	if (claim_needed)
1270 		sdio_claim_host(func);
1271 
1272 	if (f0) {
1273 		offset = addr;
1274 		for (i = 0; i < len; i++, offset++) {
1275 			sdio_f0_writeb(func, ((u8 *)buf)[i], offset, &error);
1276 			if (error)
1277 				break;
1278 #if 0
1279 			dev_info(&func->dev, "%s: sdio f0 write 52 addr 0x%x, byte 0x%02x\n",
1280 				 __func__, offset, ((u8 *)buf)[i]);
1281 #endif
1282 		}
1283 	} else {
1284 		if (cmd52) {
1285 #ifdef RTW_SDIO_IO_DBG
1286 			dev_info(&func->dev, "%s: sdio write 52 addr 0x%x, %zu bytes\n",
1287 				 __func__, addr, len);
1288 #endif
1289 			offset = addr;
1290 			for (i = 0; i < len; i++) {
1291 				sdio_writeb(func, ((u8 *)buf)[i], offset, &error);
1292 				if (error)
1293 					break;
1294 #if 0
1295 				dev_info(&func->dev, "%s: sdio write 52 addr 0x%x, byte 0x%02x\n",
1296 					 __func__, offset, ((u8 *)buf)[i]);
1297 #endif
1298 				if (!fixed)
1299 					offset++;
1300 			}
1301 		} else {
1302 #ifdef RTW_SDIO_IO_DBG
1303 			dev_info(&func->dev, "%s: sdio write 53 addr 0x%x, %zu bytes\n",
1304 				 __func__, addr, len);
1305 #endif
1306 			if (fixed)
1307 				error = sdio_writesb(func, addr, buf, len);
1308 			else
1309 				error = sdio_memcpy_toio(func, addr, buf, len);
1310 		}
1311 	}
1312 
1313 #ifdef DBG_SDIO
1314 	if (error) {
1315 		if (f0 || cmd52) {
1316 			d->intf_data.cmd52_err_cnt++;
1317 		} else {
1318 			d->intf_data.cmd53_err_cnt++;
1319 #if (DBG_SDIO >= 1)
1320 			sdio_dump_dbg_reg(d, 1, addr, len);
1321 #endif /* DBG_SDIO >= 1 */
1322 		}
1323 	}
1324 #endif /* DBG_SDIO */
1325 
1326 	if (claim_needed)
1327 		sdio_release_host(func);
1328 
1329 	if (WARN_ON(error)) {
1330 		dev_err(&func->dev, "%s: sdio write failed (%d)\n", __func__, error);
1331 #ifndef RTW_SDIO_DUMP
1332 		if (f0)
1333 			dev_err(&func->dev, "rtw_sdio: WRITE F0\n");
1334 		if (cmd52)
1335 			dev_err(&func->dev, "rtw_sdio: WRITE use CMD52\n");
1336 		else
1337 			dev_err(&func->dev, "rtw_sdio: WRITE use CMD53\n");
1338 		dev_err(&func->dev, "rtw_sdio: WRITE to 0x%05x, %zu bytes\n", addr, len);
1339 		print_hex_dump(KERN_ERR, "rtw_sdio: WRITE ",
1340 			       DUMP_PREFIX_OFFSET, 16, 1,
1341 			       buf, GET_DUMP_LEN(len), false);
1342 #endif /* !RTW_SDIO_DUMP */
1343 	}
1344 
1345 	return linux_io_err_to_drv_err(error);
1346 }
1347 #endif
1348