1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define _SDIO_OPS_C_
16
17#include <drv_types.h>
18#include <rtw_debug.h>
19#include <rtl8723b_hal.h>
20
21
22
23
24
25
26
27
28
29
30static void HalSdioGetCmdAddr8723BSdio(
31 struct adapter *adapter,
32 u8 device_id,
33 u32 addr,
34 u32 *cmdaddr
35)
36{
37 switch (device_id) {
38 case SDIO_LOCAL_DEVICE_ID:
39 *cmdaddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (addr & SDIO_LOCAL_MSK));
40 break;
41
42 case WLAN_IOREG_DEVICE_ID:
43 *cmdaddr = ((WLAN_IOREG_DEVICE_ID << 13) | (addr & WLAN_IOREG_MSK));
44 break;
45
46 case WLAN_TX_HIQ_DEVICE_ID:
47 *cmdaddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
48 break;
49
50 case WLAN_TX_MIQ_DEVICE_ID:
51 *cmdaddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
52 break;
53
54 case WLAN_TX_LOQ_DEVICE_ID:
55 *cmdaddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (addr & WLAN_FIFO_MSK));
56 break;
57
58 case WLAN_RX0FF_DEVICE_ID:
59 *cmdaddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (addr & WLAN_RX0FF_MSK));
60 break;
61
62 default:
63 break;
64 }
65}
66
67static u8 get_deviceid(u32 addr)
68{
69 u8 devide_id;
70 u16 pseudo_id;
71
72
73 pseudo_id = (u16)(addr >> 16);
74 switch (pseudo_id) {
75 case 0x1025:
76 devide_id = SDIO_LOCAL_DEVICE_ID;
77 break;
78
79 case 0x1026:
80 devide_id = WLAN_IOREG_DEVICE_ID;
81 break;
82
83
84
85
86
87 case 0x1031:
88 devide_id = WLAN_TX_HIQ_DEVICE_ID;
89 break;
90
91 case 0x1032:
92 devide_id = WLAN_TX_MIQ_DEVICE_ID;
93 break;
94
95 case 0x1033:
96 devide_id = WLAN_TX_LOQ_DEVICE_ID;
97 break;
98
99 case 0x1034:
100 devide_id = WLAN_RX0FF_DEVICE_ID;
101 break;
102
103 default:
104
105 devide_id = WLAN_IOREG_DEVICE_ID;
106 break;
107 }
108
109 return devide_id;
110}
111
112
113
114
115
116static u32 _cvrt2ftaddr(const u32 addr, u8 *pdevice_id, u16 *poffset)
117{
118 u8 device_id;
119 u16 offset;
120 u32 ftaddr;
121
122
123 device_id = get_deviceid(addr);
124 offset = 0;
125
126 switch (device_id) {
127 case SDIO_LOCAL_DEVICE_ID:
128 offset = addr & SDIO_LOCAL_MSK;
129 break;
130
131 case WLAN_TX_HIQ_DEVICE_ID:
132 case WLAN_TX_MIQ_DEVICE_ID:
133 case WLAN_TX_LOQ_DEVICE_ID:
134 offset = addr & WLAN_FIFO_MSK;
135 break;
136
137 case WLAN_RX0FF_DEVICE_ID:
138 offset = addr & WLAN_RX0FF_MSK;
139 break;
140
141 case WLAN_IOREG_DEVICE_ID:
142 default:
143 device_id = WLAN_IOREG_DEVICE_ID;
144 offset = addr & WLAN_IOREG_MSK;
145 break;
146 }
147 ftaddr = (device_id << 13) | offset;
148
149 if (pdevice_id)
150 *pdevice_id = device_id;
151 if (poffset)
152 *poffset = offset;
153
154 return ftaddr;
155}
156
157static u8 sdio_read8(struct intf_hdl *intfhdl, u32 addr)
158{
159 u32 ftaddr;
160 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
161
162 return sd_read8(intfhdl, ftaddr, NULL);
163}
164
165static u16 sdio_read16(struct intf_hdl *intfhdl, u32 addr)
166{
167 u32 ftaddr;
168 __le16 le_tmp;
169
170 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
171 sd_cmd52_read(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
172
173 return le16_to_cpu(le_tmp);
174}
175
176static u32 sdio_read32(struct intf_hdl *intfhdl, u32 addr)
177{
178 struct adapter *adapter;
179 u8 mac_pwr_ctrl_on;
180 u8 device_id;
181 u16 offset;
182 u32 ftaddr;
183 u8 shift;
184 u32 val;
185 s32 err;
186 __le32 le_tmp;
187
188 adapter = intfhdl->padapter;
189 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
190
191 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
192 if (
193 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
194 (!mac_pwr_ctrl_on) ||
195 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
196 ) {
197 err = sd_cmd52_read(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
198#ifdef SDIO_DEBUG_IO
199 if (!err) {
200#endif
201 return le32_to_cpu(le_tmp);
202#ifdef SDIO_DEBUG_IO
203 }
204
205 DBG_8192C(KERN_ERR "%s: Mac Power off, Read FAIL(%d)! addr = 0x%x\n", __func__, err, addr);
206 return SDIO_ERR_VAL32;
207#endif
208 }
209
210
211 shift = ftaddr & 0x3;
212 if (shift == 0) {
213 val = sd_read32(intfhdl, ftaddr, NULL);
214 } else {
215 u8 *tmpbuf;
216
217 tmpbuf = rtw_malloc(8);
218 if (!tmpbuf) {
219 DBG_8192C(KERN_ERR "%s: Allocate memory FAIL!(size =8) addr = 0x%x\n", __func__, addr);
220 return SDIO_ERR_VAL32;
221 }
222
223 ftaddr &= ~(u16)0x3;
224 sd_read(intfhdl, ftaddr, 8, tmpbuf);
225 memcpy(&le_tmp, tmpbuf+shift, 4);
226 val = le32_to_cpu(le_tmp);
227
228 kfree(tmpbuf);
229 }
230 return val;
231}
232
233static s32 sdio_readN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
234{
235 struct adapter *adapter;
236 u8 mac_pwr_ctrl_on;
237 u8 device_id;
238 u16 offset;
239 u32 ftaddr;
240 u8 shift;
241 s32 err;
242
243 adapter = intfhdl->padapter;
244 err = 0;
245
246 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
247
248 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
249 if (
250 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
251 (!mac_pwr_ctrl_on) ||
252 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
253 )
254 return sd_cmd52_read(intfhdl, ftaddr, cnt, buf);
255
256
257 shift = ftaddr & 0x3;
258 if (shift == 0) {
259 err = sd_read(intfhdl, ftaddr, cnt, buf);
260 } else {
261 u8 *tmpbuf;
262 u32 n;
263
264 ftaddr &= ~(u16)0x3;
265 n = cnt + shift;
266 tmpbuf = rtw_malloc(n);
267 if (!tmpbuf)
268 return -1;
269
270 err = sd_read(intfhdl, ftaddr, n, tmpbuf);
271 if (!err)
272 memcpy(buf, tmpbuf+shift, cnt);
273 kfree(tmpbuf);
274 }
275 return err;
276}
277
278static s32 sdio_write8(struct intf_hdl *intfhdl, u32 addr, u8 val)
279{
280 u32 ftaddr;
281 s32 err;
282
283 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
284 sd_write8(intfhdl, ftaddr, val, &err);
285
286 return err;
287}
288
289static s32 sdio_write16(struct intf_hdl *intfhdl, u32 addr, u16 val)
290{
291 u32 ftaddr;
292 __le16 le_tmp;
293
294 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
295 le_tmp = cpu_to_le16(val);
296 return sd_cmd52_write(intfhdl, ftaddr, 2, (u8 *)&le_tmp);
297}
298
299static s32 sdio_write32(struct intf_hdl *intfhdl, u32 addr, u32 val)
300{
301 struct adapter *adapter;
302 u8 mac_pwr_ctrl_on;
303 u8 device_id;
304 u16 offset;
305 u32 ftaddr;
306 u8 shift;
307 s32 err;
308 __le32 le_tmp;
309
310 adapter = intfhdl->padapter;
311 err = 0;
312
313 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
314
315 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
316 if (
317 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
318 (!mac_pwr_ctrl_on) ||
319 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
320 ) {
321 le_tmp = cpu_to_le32(val);
322
323 return sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
324 }
325
326
327 shift = ftaddr & 0x3;
328 if (shift == 0) {
329 sd_write32(intfhdl, ftaddr, val, &err);
330 } else {
331 le_tmp = cpu_to_le32(val);
332 err = sd_cmd52_write(intfhdl, ftaddr, 4, (u8 *)&le_tmp);
333 }
334 return err;
335}
336
337static s32 sdio_writeN(struct intf_hdl *intfhdl, u32 addr, u32 cnt, u8 *buf)
338{
339 struct adapter *adapter;
340 u8 mac_pwr_ctrl_on;
341 u8 device_id;
342 u16 offset;
343 u32 ftaddr;
344 u8 shift;
345 s32 err;
346
347 adapter = intfhdl->padapter;
348 err = 0;
349
350 ftaddr = _cvrt2ftaddr(addr, &device_id, &offset);
351
352 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
353 if (
354 ((device_id == WLAN_IOREG_DEVICE_ID) && (offset < 0x100)) ||
355 (!mac_pwr_ctrl_on) ||
356 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
357 )
358 return sd_cmd52_write(intfhdl, ftaddr, cnt, buf);
359
360 shift = ftaddr & 0x3;
361 if (shift == 0) {
362 err = sd_write(intfhdl, ftaddr, cnt, buf);
363 } else {
364 u8 *tmpbuf;
365 u32 n;
366
367 ftaddr &= ~(u16)0x3;
368 n = cnt + shift;
369 tmpbuf = rtw_malloc(n);
370 if (!tmpbuf)
371 return -1;
372 err = sd_read(intfhdl, ftaddr, 4, tmpbuf);
373 if (err) {
374 kfree(tmpbuf);
375 return err;
376 }
377 memcpy(tmpbuf+shift, buf, cnt);
378 err = sd_write(intfhdl, ftaddr, n, tmpbuf);
379 kfree(tmpbuf);
380 }
381 return err;
382}
383
384static u8 sdio_f0_read8(struct intf_hdl *intfhdl, u32 addr)
385{
386 return sd_f0_read8(intfhdl, addr, NULL);
387}
388
389static void sdio_read_mem(
390 struct intf_hdl *intfhdl,
391 u32 addr,
392 u32 cnt,
393 u8 *rmem
394)
395{
396 s32 err;
397
398 err = sdio_readN(intfhdl, addr, cnt, rmem);
399
400}
401
402static void sdio_write_mem(
403 struct intf_hdl *intfhdl,
404 u32 addr,
405 u32 cnt,
406 u8 *wmem
407)
408{
409 sdio_writeN(intfhdl, addr, cnt, wmem);
410}
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428static u32 sdio_read_port(
429 struct intf_hdl *intfhdl,
430 u32 addr,
431 u32 cnt,
432 u8 *mem
433)
434{
435 struct adapter *adapter;
436 PSDIO_DATA psdio;
437 struct hal_com_data *hal;
438 u32 oldcnt;
439#ifdef SDIO_DYNAMIC_ALLOC_MEM
440 u8 *oldmem;
441#endif
442 s32 err;
443
444
445 adapter = intfhdl->padapter;
446 psdio = &adapter_to_dvobj(adapter)->intf_data;
447 hal = GET_HAL_DATA(adapter);
448
449 HalSdioGetCmdAddr8723BSdio(adapter, addr, hal->SdioRxFIFOCnt++, &addr);
450
451 oldcnt = cnt;
452 if (cnt > psdio->block_transfer_len)
453 cnt = _RND(cnt, psdio->block_transfer_len);
454
455
456 err = _sd_read(intfhdl, addr, cnt, mem);
457
458#ifdef SDIO_DYNAMIC_ALLOC_MEM
459 if ((oldcnt != cnt) && (oldmem)) {
460 memcpy(oldmem, mem, oldcnt);
461 kfree(mem);
462 }
463#endif
464
465 if (err)
466 return _FAIL;
467 return _SUCCESS;
468}
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486static u32 sdio_write_port(
487 struct intf_hdl *intfhdl,
488 u32 addr,
489 u32 cnt,
490 u8 *mem
491)
492{
493 struct adapter *adapter;
494 PSDIO_DATA psdio;
495 s32 err;
496 struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
497
498 adapter = intfhdl->padapter;
499 psdio = &adapter_to_dvobj(adapter)->intf_data;
500
501 if (!adapter->hw_init_completed) {
502 DBG_871X("%s [addr = 0x%x cnt =%d] adapter->hw_init_completed == false\n", __func__, addr, cnt);
503 return _FAIL;
504 }
505
506 cnt = _RND4(cnt);
507 HalSdioGetCmdAddr8723BSdio(adapter, addr, cnt >> 2, &addr);
508
509 if (cnt > psdio->block_transfer_len)
510 cnt = _RND(cnt, psdio->block_transfer_len);
511
512
513 err = sd_write(intfhdl, addr, cnt, xmitbuf->pdata);
514
515 rtw_sctx_done_err(
516 &xmitbuf->sctx,
517 err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS
518 );
519
520 if (err)
521 return _FAIL;
522 return _SUCCESS;
523}
524
525void sdio_set_intf_ops(struct adapter *adapter, struct _io_ops *ops)
526{
527 ops->_read8 = &sdio_read8;
528 ops->_read16 = &sdio_read16;
529 ops->_read32 = &sdio_read32;
530 ops->_read_mem = &sdio_read_mem;
531 ops->_read_port = &sdio_read_port;
532
533 ops->_write8 = &sdio_write8;
534 ops->_write16 = &sdio_write16;
535 ops->_write32 = &sdio_write32;
536 ops->_writeN = &sdio_writeN;
537 ops->_write_mem = &sdio_write_mem;
538 ops->_write_port = &sdio_write_port;
539
540 ops->_sd_f0_read8 = sdio_f0_read8;
541}
542
543
544
545
546static s32 _sdio_local_read(
547 struct adapter *adapter,
548 u32 addr,
549 u32 cnt,
550 u8 *buf
551)
552{
553 struct intf_hdl *intfhdl;
554 u8 mac_pwr_ctrl_on;
555 s32 err;
556 u8 *tmpbuf;
557 u32 n;
558
559
560 intfhdl = &adapter->iopriv.intf;
561
562 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
563
564 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
565 if (!mac_pwr_ctrl_on)
566 return _sd_cmd52_read(intfhdl, addr, cnt, buf);
567
568 n = RND4(cnt);
569 tmpbuf = rtw_malloc(n);
570 if (!tmpbuf)
571 return (-1);
572
573 err = _sd_read(intfhdl, addr, n, tmpbuf);
574 if (!err)
575 memcpy(buf, tmpbuf, cnt);
576
577 kfree(tmpbuf);
578
579 return err;
580}
581
582
583
584
585s32 sdio_local_read(
586 struct adapter *adapter,
587 u32 addr,
588 u32 cnt,
589 u8 *buf
590)
591{
592 struct intf_hdl *intfhdl;
593 u8 mac_pwr_ctrl_on;
594 s32 err;
595 u8 *tmpbuf;
596 u32 n;
597
598 intfhdl = &adapter->iopriv.intf;
599
600 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
601
602 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
603 if (
604 (!mac_pwr_ctrl_on) ||
605 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
606 )
607 return sd_cmd52_read(intfhdl, addr, cnt, buf);
608
609 n = RND4(cnt);
610 tmpbuf = rtw_malloc(n);
611 if (!tmpbuf)
612 return (-1);
613
614 err = sd_read(intfhdl, addr, n, tmpbuf);
615 if (!err)
616 memcpy(buf, tmpbuf, cnt);
617
618 kfree(tmpbuf);
619
620 return err;
621}
622
623
624
625
626s32 sdio_local_write(
627 struct adapter *adapter,
628 u32 addr,
629 u32 cnt,
630 u8 *buf
631)
632{
633 struct intf_hdl *intfhdl;
634 u8 mac_pwr_ctrl_on;
635 s32 err;
636 u8 *tmpbuf;
637
638 if (addr & 0x3)
639 DBG_8192C("%s, address must be 4 bytes alignment\n", __func__);
640
641 if (cnt & 0x3)
642 DBG_8192C("%s, size must be the multiple of 4\n", __func__);
643
644 intfhdl = &adapter->iopriv.intf;
645
646 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
647
648 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
649 if (
650 (!mac_pwr_ctrl_on) ||
651 (adapter_to_pwrctl(adapter)->bFwCurrentInPSMode)
652 )
653 return sd_cmd52_write(intfhdl, addr, cnt, buf);
654
655 tmpbuf = rtw_malloc(cnt);
656 if (!tmpbuf)
657 return (-1);
658
659 memcpy(tmpbuf, buf, cnt);
660
661 err = sd_write(intfhdl, addr, cnt, tmpbuf);
662
663 kfree(tmpbuf);
664
665 return err;
666}
667
668u8 SdioLocalCmd52Read1Byte(struct adapter *adapter, u32 addr)
669{
670 u8 val = 0;
671 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
672
673 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
674 sd_cmd52_read(intfhdl, addr, 1, &val);
675
676 return val;
677}
678
679static u16 SdioLocalCmd52Read2Byte(struct adapter *adapter, u32 addr)
680{
681 __le16 val = 0;
682 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
683
684 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
685 sd_cmd52_read(intfhdl, addr, 2, (u8 *)&val);
686
687 return le16_to_cpu(val);
688}
689
690static u32 SdioLocalCmd53Read4Byte(struct adapter *adapter, u32 addr)
691{
692
693 u8 mac_pwr_ctrl_on;
694 u32 val = 0;
695 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
696 __le32 le_tmp;
697
698 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
699 rtw_hal_get_hwreg(adapter, HW_VAR_APFM_ON_MAC, &mac_pwr_ctrl_on);
700 if (!mac_pwr_ctrl_on || adapter_to_pwrctl(adapter)->bFwCurrentInPSMode) {
701 sd_cmd52_read(intfhdl, addr, 4, (u8 *)&le_tmp);
702 val = le32_to_cpu(le_tmp);
703 } else {
704 val = sd_read32(intfhdl, addr, NULL);
705 }
706 return val;
707}
708
709void SdioLocalCmd52Write1Byte(struct adapter *adapter, u32 addr, u8 v)
710{
711 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
712
713 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
714 sd_cmd52_write(intfhdl, addr, 1, &v);
715}
716
717static void SdioLocalCmd52Write4Byte(struct adapter *adapter, u32 addr, u32 v)
718{
719 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
720 __le32 le_tmp;
721
722 HalSdioGetCmdAddr8723BSdio(adapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
723 le_tmp = cpu_to_le32(v);
724 sd_cmd52_write(intfhdl, addr, 4, (u8 *)&le_tmp);
725}
726
727static s32 ReadInterrupt8723BSdio(struct adapter *adapter, u32 *phisr)
728{
729 u32 hisr, himr;
730 u8 val8, hisr_len;
731
732
733 if (!phisr)
734 return false;
735
736 himr = GET_HAL_DATA(adapter)->sdio_himr;
737
738
739 hisr_len = 0;
740 while (himr) {
741 hisr_len++;
742 himr >>= 8;
743 }
744
745 hisr = 0;
746 while (hisr_len != 0) {
747 hisr_len--;
748 val8 = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HISR+hisr_len);
749 hisr |= (val8 << (8*hisr_len));
750 }
751
752 *phisr = hisr;
753
754 return true;
755}
756
757
758
759
760
761
762
763
764
765
766void InitInterrupt8723BSdio(struct adapter *adapter)
767{
768 struct hal_com_data *haldata;
769
770
771 haldata = GET_HAL_DATA(adapter);
772 haldata->sdio_himr = (u32)( \
773 SDIO_HIMR_RX_REQUEST_MSK |
774 SDIO_HIMR_AVAL_MSK |
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791 0);
792}
793
794
795
796
797
798
799
800void InitSysInterrupt8723BSdio(struct adapter *adapter)
801{
802 struct hal_com_data *haldata;
803
804
805 haldata = GET_HAL_DATA(adapter);
806
807 haldata->SysIntrMask = ( \
808
809
810
811
812
813 0);
814}
815
816#ifdef CONFIG_WOWLAN
817
818
819
820
821
822
823
824
825
826void clearinterrupt8723bsdio(struct adapter *adapter)
827{
828 struct hal_com_data *haldata;
829 u8 *clear;
830
831 if (adapter->bSurpriseRemoved)
832 return;
833
834 haldata = GET_HAL_DATA(adapter);
835 clear = rtw_zmalloc(4);
836
837
838 *(__le32 *)clear = cpu_to_le32(haldata->sdio_hisr & MASK_SDIO_HISR_CLEAR);
839 if (*(__le32 *)clear) {
840
841 sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
842 }
843
844 kfree(clear);
845}
846#endif
847
848
849
850
851
852
853
854
855
856
857
858void EnableInterrupt8723BSdio(struct adapter *adapter)
859{
860 struct hal_com_data *haldata;
861 __le32 himr;
862 u32 tmp;
863
864 haldata = GET_HAL_DATA(adapter);
865
866 himr = cpu_to_le32(haldata->sdio_himr);
867 sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
868
869 RT_TRACE(
870 _module_hci_ops_c_,
871 _drv_notice_,
872 (
873 "%s: enable SDIO HIMR = 0x%08X\n",
874 __func__,
875 haldata->sdio_himr
876 )
877 );
878
879
880 tmp = rtw_read32(adapter, REG_HSIMR);
881 rtw_write32(adapter, REG_HSIMR, tmp | haldata->SysIntrMask);
882
883 RT_TRACE(
884 _module_hci_ops_c_,
885 _drv_notice_,
886 (
887 "%s: enable HSIMR = 0x%08X\n",
888 __func__,
889 haldata->SysIntrMask
890 )
891 );
892
893
894
895
896
897
898 rtw_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
899}
900
901
902
903
904
905
906
907
908
909
910void DisableInterrupt8723BSdio(struct adapter *adapter)
911{
912 __le32 himr;
913
914 himr = cpu_to_le32(SDIO_HIMR_DISABLED);
915 sdio_local_write(adapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
916}
917
918
919
920
921
922
923
924
925
926
927u8 CheckIPSStatus(struct adapter *adapter)
928{
929 DBG_871X(
930 "%s(): Read 0x100 = 0x%02x 0x86 = 0x%02x\n",
931 __func__,
932 rtw_read8(adapter, 0x100),
933 rtw_read8(adapter, 0x86)
934 );
935
936 if (rtw_read8(adapter, 0x100) == 0xEA)
937 return true;
938 else
939 return false;
940}
941
942static struct recv_buf *sd_recv_rxfifo(struct adapter *adapter, u32 size)
943{
944 u32 readsize, ret;
945 u8 *readbuf;
946 struct recv_priv *recv_priv;
947 struct recv_buf *recvbuf;
948
949
950
951
952 readsize = RND4(size);
953
954
955 recv_priv = &adapter->recvpriv;
956 recvbuf = rtw_dequeue_recvbuf(&recv_priv->free_recv_buf_queue);
957 if (!recvbuf) {
958 DBG_871X_LEVEL(_drv_err_, "%s: alloc recvbuf FAIL!\n", __func__);
959 return NULL;
960 }
961
962
963 if (!recvbuf->pskb) {
964 SIZE_PTR tmpaddr = 0;
965 SIZE_PTR alignment = 0;
966
967 recvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
968
969 if (recvbuf->pskb) {
970 recvbuf->pskb->dev = adapter->pnetdev;
971
972 tmpaddr = (SIZE_PTR)recvbuf->pskb->data;
973 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
974 skb_reserve(recvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
975 }
976
977 if (!recvbuf->pskb) {
978 DBG_871X("%s: alloc_skb fail! read =%d\n", __func__, readsize);
979 return NULL;
980 }
981 }
982
983
984 readbuf = recvbuf->pskb->data;
985 ret = sdio_read_port(&adapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, readbuf);
986 if (ret == _FAIL) {
987 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("%s: read port FAIL!\n", __func__));
988 return NULL;
989 }
990
991
992
993 recvbuf->len = size;
994 recvbuf->phead = recvbuf->pskb->head;
995 recvbuf->pdata = recvbuf->pskb->data;
996 skb_set_tail_pointer(recvbuf->pskb, size);
997 recvbuf->ptail = skb_tail_pointer(recvbuf->pskb);
998 recvbuf->pend = skb_end_pointer(recvbuf->pskb);
999
1000 return recvbuf;
1001}
1002
1003static void sd_rxhandler(struct adapter *adapter, struct recv_buf *recvbuf)
1004{
1005 struct recv_priv *recv_priv;
1006 struct __queue *pending_queue;
1007
1008 recv_priv = &adapter->recvpriv;
1009 pending_queue = &recv_priv->recv_buf_pending_queue;
1010
1011
1012 rtw_enqueue_recvbuf(recvbuf, pending_queue);
1013
1014
1015 tasklet_schedule(&recv_priv->recv_tasklet);
1016}
1017
1018void sd_int_dpc(struct adapter *adapter)
1019{
1020 struct hal_com_data *hal;
1021 struct dvobj_priv *dvobj;
1022 struct intf_hdl *intfhdl = &adapter->iopriv.intf;
1023 struct pwrctrl_priv *pwrctl;
1024
1025
1026 hal = GET_HAL_DATA(adapter);
1027 dvobj = adapter_to_dvobj(adapter);
1028 pwrctl = dvobj_to_pwrctl(dvobj);
1029
1030 if (hal->sdio_hisr & SDIO_HISR_AVAL) {
1031 u8 freepage[4];
1032
1033 _sdio_local_read(adapter, SDIO_REG_FREE_TXPG, 4, freepage);
1034 up(&(adapter->xmitpriv.xmit_sema));
1035 }
1036
1037 if (hal->sdio_hisr & SDIO_HISR_CPWM1) {
1038 struct reportpwrstate_parm report;
1039
1040 u8 bcancelled;
1041 _cancel_timer(&(pwrctl->pwr_rpwm_timer), &bcancelled);
1042
1043 report.state = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_HCPWM1_8723B);
1044
1045
1046 _set_workitem(&(pwrctl->cpwm_event));
1047 }
1048
1049 if (hal->sdio_hisr & SDIO_HISR_TXERR) {
1050 u8 *status;
1051 u32 addr;
1052
1053 status = rtw_malloc(4);
1054 if (status) {
1055 addr = REG_TXDMA_STATUS;
1056 HalSdioGetCmdAddr8723BSdio(adapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
1057 _sd_read(intfhdl, addr, 4, status);
1058 _sd_write(intfhdl, addr, 4, status);
1059 DBG_8192C("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
1060 kfree(status);
1061 } else {
1062 DBG_8192C("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1063 }
1064 }
1065
1066 if (hal->sdio_hisr & SDIO_HISR_TXBCNOK) {
1067 DBG_8192C("%s: SDIO_HISR_TXBCNOK\n", __func__);
1068 }
1069
1070 if (hal->sdio_hisr & SDIO_HISR_TXBCNERR) {
1071 DBG_8192C("%s: SDIO_HISR_TXBCNERR\n", __func__);
1072 }
1073#ifndef CONFIG_C2H_PACKET_EN
1074 if (hal->sdio_hisr & SDIO_HISR_C2HCMD) {
1075 struct c2h_evt_hdr_88xx *c2h_evt;
1076
1077 DBG_8192C("%s: C2H Command\n", __func__);
1078 c2h_evt = rtw_zmalloc(16);
1079 if (c2h_evt != NULL) {
1080 if (rtw_hal_c2h_evt_read(adapter, (u8 *)c2h_evt) == _SUCCESS) {
1081 if (c2h_id_filter_ccx_8723b((u8 *)c2h_evt)) {
1082
1083 rtw_hal_c2h_handler(adapter, (u8 *)c2h_evt);
1084 kfree((u8 *)c2h_evt);
1085 } else {
1086 rtw_c2h_wk_cmd(adapter, (u8 *)c2h_evt);
1087 }
1088 }
1089 } else {
1090
1091 if (rtw_cbuf_push(adapter->evtpriv.c2h_queue, NULL) != _SUCCESS)
1092 DBG_871X("%s rtw_cbuf_push fail\n", __func__);
1093 _set_workitem(&adapter->evtpriv.c2h_wk);
1094 }
1095 }
1096#endif
1097
1098 if (hal->sdio_hisr & SDIO_HISR_RXFOVW) {
1099 DBG_8192C("%s: Rx Overflow\n", __func__);
1100 }
1101
1102 if (hal->sdio_hisr & SDIO_HISR_RXERR) {
1103 DBG_8192C("%s: Rx Error\n", __func__);
1104 }
1105
1106 if (hal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
1107 struct recv_buf *recvbuf;
1108 int alloc_fail_time = 0;
1109 u32 hisr;
1110
1111
1112 hal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1113 do {
1114 hal->SdioRxFIFOSize = SdioLocalCmd52Read2Byte(adapter, SDIO_REG_RX0_REQ_LEN);
1115 if (hal->SdioRxFIFOSize != 0) {
1116 recvbuf = sd_recv_rxfifo(adapter, hal->SdioRxFIFOSize);
1117 if (recvbuf)
1118 sd_rxhandler(adapter, recvbuf);
1119 else {
1120 alloc_fail_time++;
1121 DBG_871X("recvbuf is Null for %d times because alloc memory failed\n", alloc_fail_time);
1122 if (alloc_fail_time >= 10)
1123 break;
1124 }
1125 hal->SdioRxFIFOSize = 0;
1126 } else
1127 break;
1128
1129 hisr = 0;
1130 ReadInterrupt8723BSdio(adapter, &hisr);
1131 hisr &= SDIO_HISR_RX_REQUEST;
1132 if (!hisr)
1133 break;
1134 } while (1);
1135
1136 if (alloc_fail_time == 10)
1137 DBG_871X("exit because alloc memory failed more than 10 times\n");
1138
1139 }
1140}
1141
1142void sd_int_hdl(struct adapter *adapter)
1143{
1144 struct hal_com_data *hal;
1145
1146
1147 if (
1148 (adapter->bDriverStopped) || (adapter->bSurpriseRemoved)
1149 )
1150 return;
1151
1152 hal = GET_HAL_DATA(adapter);
1153
1154 hal->sdio_hisr = 0;
1155 ReadInterrupt8723BSdio(adapter, &hal->sdio_hisr);
1156
1157 if (hal->sdio_hisr & hal->sdio_himr) {
1158 u32 v32;
1159
1160 hal->sdio_hisr &= hal->sdio_himr;
1161
1162
1163 v32 = hal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1164 if (v32) {
1165 SdioLocalCmd52Write4Byte(adapter, SDIO_REG_HISR, v32);
1166 }
1167
1168 sd_int_dpc(adapter);
1169 } else {
1170 RT_TRACE(_module_hci_ops_c_, _drv_err_,
1171 ("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n",
1172 __func__, hal->sdio_hisr, hal->sdio_himr));
1173 }
1174}
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186u8 HalQueryTxBufferStatus8723BSdio(struct adapter *adapter)
1187{
1188 struct hal_com_data *hal;
1189 u32 numof_free_page;
1190
1191
1192
1193 hal = GET_HAL_DATA(adapter);
1194
1195 numof_free_page = SdioLocalCmd53Read4Byte(adapter, SDIO_REG_FREE_TXPG);
1196
1197
1198 memcpy(hal->SdioTxFIFOFreePage, &numof_free_page, 4);
1199 RT_TRACE(_module_hci_ops_c_, _drv_notice_,
1200 ("%s: Free page for HIQ(%#x), MIDQ(%#x), LOWQ(%#x), PUBQ(%#x)\n",
1201 __func__,
1202 hal->SdioTxFIFOFreePage[HI_QUEUE_IDX],
1203 hal->SdioTxFIFOFreePage[MID_QUEUE_IDX],
1204 hal->SdioTxFIFOFreePage[LOW_QUEUE_IDX],
1205 hal->SdioTxFIFOFreePage[PUBLIC_QUEUE_IDX]));
1206
1207
1208 return true;
1209}
1210
1211
1212
1213
1214
1215u8 HalQueryTxOQTBufferStatus8723BSdio(struct adapter *adapter)
1216{
1217 struct hal_com_data *haldata = GET_HAL_DATA(adapter);
1218
1219 haldata->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(adapter, SDIO_REG_OQT_FREE_PG);
1220 return true;
1221}
1222
1223#if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1224u8 RecvOnePkt(struct adapter *adapter, u32 size)
1225{
1226 struct recv_buf *recvbuf;
1227 struct dvobj_priv *sddev;
1228 PSDIO_DATA psdio_data;
1229 struct sdio_func *func;
1230
1231 u8 res = false;
1232
1233 DBG_871X("+%s: size: %d+\n", __func__, size);
1234
1235 if (!adapter) {
1236 DBG_871X(KERN_ERR "%s: adapter is NULL!\n", __func__);
1237 return false;
1238 }
1239
1240 sddev = adapter_to_dvobj(adapter);
1241 psdio_data = &sddev->intf_data;
1242 func = psdio_data->func;
1243
1244 if (size) {
1245 sdio_claim_host(func);
1246 recvbuf = sd_recv_rxfifo(adapter, size);
1247
1248 if (recvbuf) {
1249
1250 sd_rxhandler(adapter, recvbuf);
1251 res = true;
1252 } else {
1253 res = false;
1254 }
1255 sdio_release_host(func);
1256 }
1257 DBG_871X("-%s-\n", __func__);
1258 return res;
1259}
1260#endif
1261