net: wireless: rockchip_wlan: add rtl8723cs support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723cs / os_dep / linux / sdio_ops_linux.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *******************************************************************************/
19 #define _SDIO_OPS_LINUX_C_
20
21 #include <drv_types.h>
22
23 static bool rtw_sdio_claim_host_needed(struct sdio_func *func)
24 {
25         struct dvobj_priv *dvobj = sdio_get_drvdata(func);
26         PSDIO_DATA sdio_data = &dvobj->intf_data;
27
28         if (sdio_data->sys_sdio_irq_thd && sdio_data->sys_sdio_irq_thd == current)
29                 return _FALSE;
30         return _TRUE;
31 }
32
33 inline void rtw_sdio_set_irq_thd(struct dvobj_priv *dvobj, _thread_hdl_ thd_hdl)
34 {
35         PSDIO_DATA sdio_data = &dvobj->intf_data;
36
37         sdio_data->sys_sdio_irq_thd = thd_hdl;
38 }
39 #ifndef RTW_HALMAC
40 u8 sd_f0_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
41 {
42         PADAPTER padapter;
43         struct dvobj_priv *psdiodev;
44         PSDIO_DATA psdio;
45
46         u8 v = 0;
47         struct sdio_func *func;
48         bool claim_needed;
49
50
51         padapter = pintfhdl->padapter;
52         psdiodev = pintfhdl->pintf_dev;
53         psdio = &psdiodev->intf_data;
54
55         if (rtw_is_surprise_removed(padapter)) {
56                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
57                 return v;
58         }
59
60         func = psdio->func;
61         claim_needed = rtw_sdio_claim_host_needed(func);
62
63         if (claim_needed)
64                 sdio_claim_host(func);
65         v = sdio_f0_readb(func, addr, err);
66         if (claim_needed)
67                 sdio_release_host(func);
68         if (err && *err)
69                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
70
71
72         return v;
73 }
74
75 void sd_f0_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
76 {
77         PADAPTER padapter;
78         struct dvobj_priv *psdiodev;
79         PSDIO_DATA psdio;
80
81         struct sdio_func *func;
82         bool claim_needed;
83
84         padapter = pintfhdl->padapter;
85         psdiodev = pintfhdl->pintf_dev;
86         psdio = &psdiodev->intf_data;
87
88         if (rtw_is_surprise_removed(padapter)) {
89                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
90                 return;
91         }
92
93         func = psdio->func;
94         claim_needed = rtw_sdio_claim_host_needed(func);
95
96         if (claim_needed)
97                 sdio_claim_host(func);
98         sdio_f0_writeb(func, v, addr, err);
99         if (claim_needed)
100                 sdio_release_host(func);
101         if (err && *err)
102                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v);
103
104 }
105
106 /*
107  * Return:
108  *      0               Success
109  *      others  Fail
110  */
111 s32 _sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
112 {
113         PADAPTER padapter;
114         struct dvobj_priv *psdiodev;
115         PSDIO_DATA psdio;
116
117         int err = 0, i;
118         struct sdio_func *func;
119
120         padapter = pintfhdl->padapter;
121         psdiodev = pintfhdl->pintf_dev;
122         psdio = &psdiodev->intf_data;
123
124         if (rtw_is_surprise_removed(padapter)) {
125                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
126                 return err;
127         }
128
129         func = psdio->func;
130
131         for (i = 0; i < cnt; i++) {
132                 pdata[i] = sdio_readb(func, addr + i, &err);
133                 if (err) {
134                         RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr + i);
135                         break;
136                 }
137         }
138
139
140         return err;
141 }
142
143 /*
144  * Return:
145  *      0               Success
146  *      others  Fail
147  */
148 s32 sd_cmd52_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
149 {
150         PADAPTER padapter;
151         struct dvobj_priv *psdiodev;
152         PSDIO_DATA psdio;
153
154         int err = 0, i;
155         struct sdio_func *func;
156         bool claim_needed;
157
158         padapter = pintfhdl->padapter;
159         psdiodev = pintfhdl->pintf_dev;
160         psdio = &psdiodev->intf_data;
161
162         if (rtw_is_surprise_removed(padapter)) {
163                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
164                 return err;
165         }
166
167         func = psdio->func;
168         claim_needed = rtw_sdio_claim_host_needed(func);
169
170         if (claim_needed)
171                 sdio_claim_host(func);
172         err = _sd_cmd52_read(pintfhdl, addr, cnt, pdata);
173         if (claim_needed)
174                 sdio_release_host(func);
175
176
177         return err;
178 }
179
180 /*
181  * Return:
182  *      0               Success
183  *      others  Fail
184  */
185 s32 _sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
186 {
187         PADAPTER padapter;
188         struct dvobj_priv *psdiodev;
189         PSDIO_DATA psdio;
190
191         int err = 0, i;
192         struct sdio_func *func;
193
194         padapter = pintfhdl->padapter;
195         psdiodev = pintfhdl->pintf_dev;
196         psdio = &psdiodev->intf_data;
197
198         if (rtw_is_surprise_removed(padapter)) {
199                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
200                 return err;
201         }
202
203         func = psdio->func;
204
205         for (i = 0; i < cnt; i++) {
206                 sdio_writeb(func, pdata[i], addr + i, &err);
207                 if (err) {
208                         RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr + i, pdata[i]);
209                         break;
210                 }
211         }
212
213
214         return err;
215 }
216
217 /*
218  * Return:
219  *      0               Success
220  *      others  Fail
221  */
222 s32 sd_cmd52_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pdata)
223 {
224         PADAPTER padapter;
225         struct dvobj_priv *psdiodev;
226         PSDIO_DATA psdio;
227
228         int err = 0, i;
229         struct sdio_func *func;
230         bool claim_needed;
231
232         padapter = pintfhdl->padapter;
233         psdiodev = pintfhdl->pintf_dev;
234         psdio = &psdiodev->intf_data;
235
236         if (rtw_is_surprise_removed(padapter)) {
237                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
238                 return err;
239         }
240
241         func = psdio->func;
242         claim_needed = rtw_sdio_claim_host_needed(func);
243
244         if (claim_needed)
245                 sdio_claim_host(func);
246         err = _sd_cmd52_write(pintfhdl, addr, cnt, pdata);
247         if (claim_needed)
248                 sdio_release_host(func);
249
250
251         return err;
252 }
253
254 u8 _sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
255 {
256         PADAPTER padapter;
257         struct dvobj_priv *psdiodev;
258         PSDIO_DATA psdio;
259
260         u8 v = 0;
261         struct sdio_func *func;
262
263         padapter = pintfhdl->padapter;
264         psdiodev = pintfhdl->pintf_dev;
265         psdio = &psdiodev->intf_data;
266
267         if (rtw_is_surprise_removed(padapter)) {
268                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
269                 return v;
270         }
271
272         func = psdio->func;
273
274         v = sdio_readb(func, addr, err);
275
276         if (err && *err)
277                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
278
279
280         return v;
281 }
282
283 u8 sd_read8(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
284 {
285         PADAPTER padapter;
286         struct dvobj_priv *psdiodev;
287         PSDIO_DATA psdio;
288
289         u8 v = 0;
290         struct sdio_func *func;
291         bool claim_needed;
292
293         padapter = pintfhdl->padapter;
294         psdiodev = pintfhdl->pintf_dev;
295         psdio = &psdiodev->intf_data;
296
297         if (rtw_is_surprise_removed(padapter)) {
298                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
299                 return v;
300         }
301
302         func = psdio->func;
303         claim_needed = rtw_sdio_claim_host_needed(func);
304
305         if (claim_needed)
306                 sdio_claim_host(func);
307         v = sdio_readb(func, addr, err);
308         if (claim_needed)
309                 sdio_release_host(func);
310         if (err && *err)
311                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
312
313
314         return v;
315 }
316
317 u16 sd_read16(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
318 {
319         PADAPTER padapter;
320         struct dvobj_priv *psdiodev;
321         PSDIO_DATA psdio;
322
323         u16 v = 0;
324         struct sdio_func *func;
325         bool claim_needed;
326
327         padapter = pintfhdl->padapter;
328         psdiodev = pintfhdl->pintf_dev;
329         psdio = &psdiodev->intf_data;
330
331         if (rtw_is_surprise_removed(padapter)) {
332                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
333                 return v;
334         }
335
336         func = psdio->func;
337         claim_needed = rtw_sdio_claim_host_needed(func);
338
339         if (claim_needed)
340                 sdio_claim_host(func);
341         v = sdio_readw(func, addr, err);
342         if (claim_needed)
343                 sdio_release_host(func);
344         if (err && *err)
345                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, *err, addr);
346
347
348         return  v;
349 }
350
351 u32 _sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
352 {
353         PADAPTER padapter;
354         struct dvobj_priv *psdiodev;
355         PSDIO_DATA psdio;
356
357         u32 v = 0;
358         struct sdio_func *func;
359
360         padapter = pintfhdl->padapter;
361         psdiodev = pintfhdl->pintf_dev;
362         psdio = &psdiodev->intf_data;
363
364         if (rtw_is_surprise_removed(padapter)) {
365                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
366                 return v;
367         }
368
369         func = psdio->func;
370
371         v = sdio_readl(func, addr, err);
372
373         if (err && *err) {
374                 int i;
375
376                 RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x\n", __func__, *err, addr, v);
377
378                 *err = 0;
379                 for (i = 0; i < SD_IO_TRY_CNT; i++) {
380                         /* sdio_claim_host(func); */
381                         v = sdio_readl(func, addr, err);
382                         /* sdio_release_host(func); */
383                         if (*err == 0) {
384                                 rtw_reset_continual_io_error(psdiodev);
385                                 break;
386                         } else {
387                                 RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
388                                 if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
389                                         rtw_set_surprise_removed(padapter);
390
391                                 if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
392                                         rtw_set_surprise_removed(padapter);
393                                         break;
394                                 }
395
396                         }
397                 }
398
399                 if (i == SD_IO_TRY_CNT)
400                         RTW_ERR("%s: FAIL!(%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
401                 else
402                         RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
403
404         }
405
406
407         return  v;
408 }
409
410 u32 sd_read32(struct intf_hdl *pintfhdl, u32 addr, s32 *err)
411 {
412         PADAPTER padapter;
413         struct dvobj_priv *psdiodev;
414         PSDIO_DATA psdio;
415
416         u32 v = 0;
417         struct sdio_func *func;
418         bool claim_needed;
419
420         padapter = pintfhdl->padapter;
421         psdiodev = pintfhdl->pintf_dev;
422         psdio = &psdiodev->intf_data;
423
424         if (rtw_is_surprise_removed(padapter)) {
425                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
426                 return v;
427         }
428
429         func = psdio->func;
430         claim_needed = rtw_sdio_claim_host_needed(func);
431
432         if (claim_needed)
433                 sdio_claim_host(func);
434         v = sdio_readl(func, addr, err);
435         if (claim_needed)
436                 sdio_release_host(func);
437
438         if (err && *err) {
439                 int i;
440
441                 RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x\n", __func__, *err, addr, v);
442
443                 *err = 0;
444                 for (i = 0; i < SD_IO_TRY_CNT; i++) {
445                         if (claim_needed)
446                                 sdio_claim_host(func);
447                         v = sdio_readl(func, addr, err);
448                         if (claim_needed)
449                                 sdio_release_host(func);
450
451                         if (*err == 0) {
452                                 rtw_reset_continual_io_error(psdiodev);
453                                 break;
454                         } else {
455                                 RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
456                                 if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
457                                         rtw_set_surprise_removed(padapter);
458
459                                 if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
460                                         rtw_set_surprise_removed(padapter);
461                                         break;
462                                 }
463                         }
464                 }
465
466                 if (i == SD_IO_TRY_CNT)
467                         RTW_ERR("%s: FAIL!(%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
468                 else
469                         RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
470
471         }
472
473
474         return  v;
475 }
476
477 void sd_write8(struct intf_hdl *pintfhdl, u32 addr, u8 v, s32 *err)
478 {
479         PADAPTER padapter;
480         struct dvobj_priv *psdiodev;
481         PSDIO_DATA psdio;
482
483         struct sdio_func *func;
484         bool claim_needed;
485
486
487         padapter = pintfhdl->padapter;
488         psdiodev = pintfhdl->pintf_dev;
489         psdio = &psdiodev->intf_data;
490
491         if (rtw_is_surprise_removed(padapter)) {
492                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
493                 return ;
494         }
495
496         func = psdio->func;
497         claim_needed = rtw_sdio_claim_host_needed(func);
498
499         if (claim_needed)
500                 sdio_claim_host(func);
501         sdio_writeb(func, v, addr, err);
502         if (claim_needed)
503                 sdio_release_host(func);
504         if (err && *err)
505                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, *err, addr, v);
506
507 }
508
509 void sd_write16(struct intf_hdl *pintfhdl, u32 addr, u16 v, s32 *err)
510 {
511         PADAPTER padapter;
512         struct dvobj_priv *psdiodev;
513         PSDIO_DATA psdio;
514
515         struct sdio_func *func;
516         bool claim_needed;
517
518         padapter = pintfhdl->padapter;
519         psdiodev = pintfhdl->pintf_dev;
520         psdio = &psdiodev->intf_data;
521
522         if (rtw_is_surprise_removed(padapter)) {
523                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
524                 return ;
525         }
526
527         func = psdio->func;
528         claim_needed = rtw_sdio_claim_host_needed(func);
529
530         if (claim_needed)
531                 sdio_claim_host(func);
532         sdio_writew(func, v, addr, err);
533         if (claim_needed)
534                 sdio_release_host(func);
535         if (err && *err)
536                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%04x\n", __func__, *err, addr, v);
537
538 }
539
540 void _sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
541 {
542         PADAPTER padapter;
543         struct dvobj_priv *psdiodev;
544         PSDIO_DATA psdio;
545
546         struct sdio_func *func;
547
548         padapter = pintfhdl->padapter;
549         psdiodev = pintfhdl->pintf_dev;
550         psdio = &psdiodev->intf_data;
551
552         if (rtw_is_surprise_removed(padapter)) {
553                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
554                 return ;
555         }
556
557         func = psdio->func;
558
559         sdio_writel(func, v, addr, err);
560
561         if (err && *err) {
562                 int i;
563
564                 RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v);
565
566                 *err = 0;
567                 for (i = 0; i < SD_IO_TRY_CNT; i++) {
568                         sdio_writel(func, v, addr, err);
569                         if (*err == 0) {
570                                 rtw_reset_continual_io_error(psdiodev);
571                                 break;
572                         } else {
573                                 RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
574                                 if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
575                                         rtw_set_surprise_removed(padapter);
576
577                                 if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
578                                         rtw_set_surprise_removed(padapter);
579                                         break;
580                                 }
581                         }
582                 }
583
584                 if (i == SD_IO_TRY_CNT)
585                         RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
586                 else
587                         RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
588
589         }
590
591 }
592
593 void sd_write32(struct intf_hdl *pintfhdl, u32 addr, u32 v, s32 *err)
594 {
595         PADAPTER padapter;
596         struct dvobj_priv *psdiodev;
597         PSDIO_DATA psdio;
598         struct sdio_func *func;
599         bool claim_needed;
600
601         padapter = pintfhdl->padapter;
602         psdiodev = pintfhdl->pintf_dev;
603         psdio = &psdiodev->intf_data;
604
605         if (rtw_is_surprise_removed(padapter)) {
606                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
607                 return ;
608         }
609
610         func = psdio->func;
611         claim_needed = rtw_sdio_claim_host_needed(func);
612
613         if (claim_needed)
614                 sdio_claim_host(func);
615         sdio_writel(func, v, addr, err);
616         if (claim_needed)
617                 sdio_release_host(func);
618
619         if (err && *err) {
620                 int i;
621
622                 RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x\n", __func__, *err, addr, v);
623
624                 *err = 0;
625                 for (i = 0; i < SD_IO_TRY_CNT; i++) {
626                         if (claim_needed)
627                                 sdio_claim_host(func);
628                         sdio_writel(func, v, addr, err);
629                         if (claim_needed)
630                                 sdio_release_host(func);
631                         if (*err == 0) {
632                                 rtw_reset_continual_io_error(psdiodev);
633                                 break;
634                         } else {
635                                 RTW_ERR("%s: (%d) addr=0x%05x, val=0x%x, try_cnt=%d\n", __func__, *err, addr, v, i);
636                                 if ((-ESHUTDOWN == *err) || (-ENODEV == *err))
637                                         rtw_set_surprise_removed(padapter);
638
639                                 if (rtw_inc_and_chk_continual_io_error(psdiodev) == _TRUE) {
640                                         rtw_set_surprise_removed(padapter);
641                                         break;
642                                 }
643                         }
644                 }
645
646                 if (i == SD_IO_TRY_CNT)
647                         RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
648                 else
649                         RTW_ERR("%s: (%d) addr=0x%05x val=0x%08x, try_cnt=%d\n", __func__, *err, addr, v, i);
650         }
651
652 }
653 #endif /* !RTW_HALMAC */
654
655 /*
656  * Use CMD53 to read data from SDIO device.
657  * This function MUST be called after sdio_claim_host() or
658  * in SDIO ISR(host had been claimed).
659  *
660  * Parameters:
661  *      psdio   pointer of SDIO_DATA
662  *      addr    address to read
663  *      cnt             amount to read
664  *      pdata   pointer to put data, this should be a "DMA:able scratch buffer"!
665  *
666  * Return:
667  *      0               Success
668  *      others  Fail
669  */
670 s32 _sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
671 {
672         PADAPTER padapter;
673         struct dvobj_priv *psdiodev;
674         PSDIO_DATA psdio;
675
676         int err = -EPERM;
677         struct sdio_func *func;
678
679         padapter = pintfhdl->padapter;
680         psdiodev = pintfhdl->pintf_dev;
681         psdio = &psdiodev->intf_data;
682
683         if (rtw_is_surprise_removed(padapter)) {
684                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
685                 return err;
686         }
687
688         func = psdio->func;
689
690         if (unlikely((cnt == 1) || (cnt == 2))) {
691                 int i;
692                 u8 *pbuf = (u8 *)pdata;
693
694                 for (i = 0; i < cnt; i++) {
695                         *(pbuf + i) = sdio_readb(func, addr + i, &err);
696
697                         if (err) {
698                                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x\n", __func__, err, addr);
699                                 break;
700                         }
701                 }
702                 return err;
703         }
704
705         err = sdio_memcpy_fromio(func, pdata, addr, cnt);
706         if (err)
707                 RTW_ERR("%s: FAIL(%d)! ADDR=%#x Size=%d\n", __func__, err, addr, cnt);
708
709         if (err == (-ESHUTDOWN) || err == (-ENODEV) || err == (-ENOMEDIUM) || err == (-ETIMEDOUT))
710                 rtw_set_surprise_removed(padapter);
711
712
713         return err;
714 }
715
716 /*
717  * Use CMD53 to read data from SDIO device.
718  *
719  * Parameters:
720  *      psdio   pointer of SDIO_DATA
721  *      addr    address to read
722  *      cnt             amount to read
723  *      pdata   pointer to put data, this should be a "DMA:able scratch buffer"!
724  *
725  * Return:
726  *      0               Success
727  *      others  Fail
728  */
729 s32 sd_read(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
730 {
731         PADAPTER padapter;
732         struct dvobj_priv *psdiodev;
733         PSDIO_DATA psdio;
734
735         struct sdio_func *func;
736         bool claim_needed;
737         s32 err = -EPERM;
738
739         padapter = pintfhdl->padapter;
740         psdiodev = pintfhdl->pintf_dev;
741         psdio = &psdiodev->intf_data;
742
743         if (rtw_is_surprise_removed(padapter)) {
744                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
745                 return err;
746         }
747         func = psdio->func;
748         claim_needed = rtw_sdio_claim_host_needed(func);
749
750         if (claim_needed)
751                 sdio_claim_host(func);
752         err = _sd_read(pintfhdl, addr, cnt, pdata);
753         if (claim_needed)
754                 sdio_release_host(func);
755         return err;
756 }
757
758 /*
759  * Use CMD53 to write data to SDIO device.
760  * This function MUST be called after sdio_claim_host() or
761  * in SDIO ISR(host had been claimed).
762  *
763  * Parameters:
764  *      psdio   pointer of SDIO_DATA
765  *      addr    address to write
766  *      cnt             amount to write
767  *      pdata   data pointer, this should be a "DMA:able scratch buffer"!
768  *
769  * Return:
770  *      0               Success
771  *      others  Fail
772  */
773 s32 _sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
774 {
775         PADAPTER padapter;
776         struct dvobj_priv *psdiodev;
777         PSDIO_DATA psdio;
778
779         struct sdio_func *func;
780         u32 size;
781         s32 err = -EPERM;
782
783         padapter = pintfhdl->padapter;
784         psdiodev = pintfhdl->pintf_dev;
785         psdio = &psdiodev->intf_data;
786
787         if (rtw_is_surprise_removed(padapter)) {
788                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
789                 return err;
790         }
791
792         func = psdio->func;
793         /*      size = sdio_align_size(func, cnt); */
794
795         if (unlikely((cnt == 1) || (cnt == 2))) {
796                 int i;
797                 u8 *pbuf = (u8 *)pdata;
798
799                 for (i = 0; i < cnt; i++) {
800                         sdio_writeb(func, *(pbuf + i), addr + i, &err);
801                         if (err) {
802                                 RTW_ERR("%s: FAIL!(%d) addr=0x%05x val=0x%02x\n", __func__, err, addr, *(pbuf + i));
803                                 break;
804                         }
805                 }
806
807                 return err;
808         }
809
810         size = cnt;
811         err = sdio_memcpy_toio(func, addr, pdata, size);
812         if (err)
813                 RTW_ERR("%s: FAIL(%d)! ADDR=%#x Size=%d(%d)\n", __func__, err, addr, cnt, size);
814
815
816         return err;
817 }
818
819 /*
820  * Use CMD53 to write data to SDIO device.
821  *
822  * Parameters:
823  *  psdio       pointer of SDIO_DATA
824  *  addr        address to write
825  *  cnt         amount to write
826  *  pdata       data pointer, this should be a "DMA:able scratch buffer"!
827  *
828  * Return:
829  *  0           Success
830  *  others      Fail
831  */
832 s32 sd_write(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, void *pdata)
833 {
834         PADAPTER padapter;
835         struct dvobj_priv *psdiodev;
836         PSDIO_DATA psdio;
837
838         struct sdio_func *func;
839         bool claim_needed;
840         s32 err = -EPERM;
841         padapter = pintfhdl->padapter;
842         psdiodev = pintfhdl->pintf_dev;
843         psdio = &psdiodev->intf_data;
844
845         if (rtw_is_surprise_removed(padapter)) {
846                 /* RTW_INFO(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n",__FUNCTION__); */
847                 return err;
848         }
849
850         func = psdio->func;
851         claim_needed = rtw_sdio_claim_host_needed(func);
852
853         if (claim_needed)
854                 sdio_claim_host(func);
855         err = _sd_write(pintfhdl, addr, cnt, pdata);
856         if (claim_needed)
857                 sdio_release_host(func);
858         return err;
859 }
860
861 #if 1
862 /*#define RTW_SDIO_DUMP*/
863
864 int __must_check rtw_sdio_raw_read(struct dvobj_priv *d, int addr,
865                                    void *buf, size_t len, bool fixed)
866 {
867         int error = -EPERM;
868         bool f0, cmd52;
869         struct sdio_func *func;
870         bool claim_needed;
871
872         if (rtw_is_surprise_removed(dvobj_get_primary_adapter(d))) {
873                 /*RTW_ERR(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__);*/
874                 return error;
875         }
876
877         func = dvobj_to_sdio_func(d);
878         claim_needed = rtw_sdio_claim_host_needed(func);
879         f0 = RTW_SDIO_ADDR_F0_CHK(addr);
880         cmd52 = RTW_SDIO_ADDR_CMD52_CHK(addr);
881
882 #ifdef RTW_SDIO_DUMP
883         if (f0)
884                 dev_dbg(&func->dev, "rtw_sdio: READ F0\n");
885         if (cmd52)
886                 dev_dbg(&func->dev, "rtw_sdio: READ use CMD52\n");
887         else
888                 dev_dbg(&func->dev, "rtw_sdio: READ use CMD53\n");
889
890         dev_dbg(&func->dev, "rtw_sdio: READ from 0x%05x\n", addr);
891         print_hex_dump(KERN_DEBUG, "rtw_sdio: READ ",
892                        DUMP_PREFIX_OFFSET, 16, 1,
893                        buf, len, false);
894 #endif /* RTW_SDIO_DUMP */
895
896         if (claim_needed)
897                 sdio_claim_host(func);
898
899         if (f0) {
900                 int i;
901
902                 addr &= 0xFF;
903                 for (i = 0; i < len; i++, addr++) {
904                         ((u8 *)buf)[i] = sdio_f0_readb(func, addr, &error);
905                         if (error)
906                                 break;
907 #if 0
908                         dev_info(&func->dev, "%s: sdio f0 read 52 addr 0x%x, byte 0x%02x\n",
909                                  __func__, addr + i, ((u8 *)buf)[i]);
910 #endif
911                 }
912         } else {
913                 addr &= 0x1FFFF;
914                 if (cmd52) {
915                         int i;
916 #ifdef RTW_SDIO_IO_DBG
917                         dev_info(&func->dev, "%s: sdio read 52 addr 0x%x, %zu bytes\n",
918                                  __func__, addr, len);
919 #endif
920                         for (i = 0; i < len; i++) {
921                                 ((u8 *)buf)[i] = sdio_readb(func, addr, &error);
922                                 if (error)
923                                         break;
924 #if 0
925                                 dev_info(&func->dev, "%s: sdio read 52 addr 0x%x, byte 0x%02x\n",
926                                          __func__, addr + i, ((u8 *)buf)[i]);
927 #endif
928                                 if (!fixed)
929                                         addr++;
930                         }
931                 } else {
932 #ifdef RTW_SDIO_IO_DBG
933                         dev_info(&func->dev, "%s: sdio read 53 addr 0x%x, %zu bytes\n",
934                                  __func__, addr, len);
935 #endif
936                         if (fixed)
937                                 error = sdio_readsb(func, buf, addr, len);
938                         else
939                                 error = sdio_memcpy_fromio(func, buf, addr, len);
940                 }
941         }
942
943         if (claim_needed)
944                 sdio_release_host(func);
945
946         if (WARN_ON(error)) {
947                 dev_err(&func->dev, "%s: sdio read failed (%d)\n", __func__, error);
948 #ifndef RTW_SDIO_DUMP
949                 if (f0)
950                         dev_err(&func->dev, "rtw_sdio: READ F0\n");
951                 if (cmd52)
952                         dev_err(&func->dev, "rtw_sdio: READ use CMD52\n");
953                 else
954                         dev_err(&func->dev, "rtw_sdio: READ use CMD53\n");
955                 dev_err(&func->dev, "rtw_sdio: READ from 0x%04x\n", addr);
956                 print_hex_dump(KERN_ERR, "rtw_sdio: READ ",
957                                DUMP_PREFIX_OFFSET, 16, 1,
958                                buf, len, false);
959 #endif /* !RTW_SDIO_DUMP */
960         }
961
962         if (error == (-ESHUTDOWN) || error == (-ENODEV) || error == (-ENOMEDIUM) || error == (-ETIMEDOUT))
963                 rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
964
965         return error;
966 }
967
968 int __must_check rtw_sdio_raw_write(struct dvobj_priv *d, int addr,
969                                     void *buf, size_t len, bool fixed)
970 {
971         int error = -EPERM;
972         bool f0, cmd52;
973         struct sdio_func *func;
974         bool claim_needed;
975
976         if (rtw_is_surprise_removed(dvobj_get_primary_adapter(d))) {
977                 /*RTW_ERR(" %s (padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n", __func__);*/
978                 return error;
979         }
980
981         func = dvobj_to_sdio_func(d);
982         claim_needed = rtw_sdio_claim_host_needed(func);
983         f0 = RTW_SDIO_ADDR_F0_CHK(addr);
984         cmd52 = RTW_SDIO_ADDR_CMD52_CHK(addr);
985
986 #ifdef RTW_SDIO_DUMP
987         if (f0)
988                 dev_dbg(&func->dev, "rtw_sdio: WRITE F0\n");
989         if (cmd52)
990                 dev_dbg(&func->dev, "rtw_sdio: WRITE use CMD52\n");
991         else
992                 dev_dbg(&func->dev, "rtw_sdio: WRITE use CMD53\n");
993         dev_dbg(&func->dev, "rtw_sdio: WRITE to 0x%05x\n", addr);
994         print_hex_dump(KERN_DEBUG, "rtw_sdio: WRITE ",
995                        DUMP_PREFIX_OFFSET, 16, 1,
996                        buf, len, false);
997 #endif /* RTW_SDIO_DUMP */
998
999         if (claim_needed)
1000                 sdio_claim_host(func);
1001
1002         if (f0) {
1003                 int i;
1004
1005                 addr &= 0xFF;
1006                 for (i = 0; i < len; i++, addr++) {
1007                         sdio_f0_writeb(func, ((u8 *)buf)[i], addr, &error);
1008                         if (error)
1009                                 break;
1010 #if 0
1011                         dev_info(&func->dev, "%s: sdio f0 write 52 addr 0x%x, byte 0x%02x\n",
1012                                  __func__, addr, ((u8 *)buf)[i]);
1013 #endif
1014                 }
1015         } else {
1016                 addr &= 0x1FFFF;
1017                 if (cmd52) {
1018                         int i;
1019 #ifdef RTW_SDIO_IO_DBG
1020                         dev_info(&func->dev, "%s: sdio write 52 addr 0x%x, %zu bytes\n",
1021                                  __func__, addr, len);
1022 #endif
1023                         for (i = 0; i < len; i++) {
1024                                 sdio_writeb(func, ((u8 *)buf)[i], addr, &error);
1025                                 if (error)
1026                                         break;
1027 #if 0
1028                                 dev_info(&func->dev, "%s: sdio write 52 addr 0x%x, byte 0x%02x\n",
1029                                          __func__, addr + i, ((u8 *)buf)[i]);
1030 #endif
1031                                 if (!fixed)
1032                                         addr++;
1033                         }
1034                 } else {
1035 #ifdef RTW_SDIO_IO_DBG
1036                         dev_info(&func->dev, "%s: sdio write 53 addr 0x%x, %zu bytes\n",
1037                                  __func__, addr, len);
1038 #endif
1039                         if (fixed)
1040                                 error = sdio_writesb(func, addr, buf, len);
1041                         else
1042                                 error = sdio_memcpy_toio(func, addr, buf, len);
1043                 }
1044         }
1045
1046         if (claim_needed)
1047                 sdio_release_host(func);
1048
1049         if (WARN_ON(error)) {
1050                 dev_err(&func->dev, "%s: sdio write failed (%d)\n", __func__, error);
1051 #ifndef RTW_SDIO_DUMP
1052                 if (f0)
1053                         dev_err(&func->dev, "rtw_sdio: WRITE F0\n");
1054                 if (cmd52)
1055                         dev_err(&func->dev, "rtw_sdio: WRITE use CMD52\n");
1056                 else
1057                         dev_err(&func->dev, "rtw_sdio: WRITE use CMD53\n");
1058                 dev_err(&func->dev, "rtw_sdio: WRITE to 0x%05x\n", addr);
1059                 print_hex_dump(KERN_ERR, "rtw_sdio: WRITE ",
1060                                DUMP_PREFIX_OFFSET, 16, 1,
1061                                buf, len, false);
1062 #endif /* !RTW_SDIO_DUMP */
1063         }
1064
1065         if (error == (-ESHUTDOWN) || error == (-ENODEV) || error == (-ENOMEDIUM) || error == (-ETIMEDOUT))
1066                 rtw_set_surprise_removed(dvobj_get_primary_adapter(d));
1067
1068         return error;
1069 }
1070 #endif