1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2017 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_C_
16
17 #include <rtl8723d_hal.h>
18
19 /* #define SDIO_DEBUG_IO 1 */
20
21
22 /*
23 * Description:
24 * The following mapping is for SDIO host local register space.
25 *
26 * Creadted by Roger, 2011.01.31.
27 * */
HalSdioGetCmdAddr8723DSdio(PADAPTER padapter,u8 DeviceID,u32 Addr,u32 * pCmdAddr)28 static void HalSdioGetCmdAddr8723DSdio(
29 PADAPTER padapter,
30 u8 DeviceID,
31 u32 Addr,
32 u32 *pCmdAddr
33 )
34 {
35 switch (DeviceID) {
36 case SDIO_LOCAL_DEVICE_ID:
37 *pCmdAddr = ((SDIO_LOCAL_DEVICE_ID << 13) | (Addr & SDIO_LOCAL_MSK));
38 break;
39
40 case WLAN_IOREG_DEVICE_ID:
41 *pCmdAddr = ((WLAN_IOREG_DEVICE_ID << 13) | (Addr & WLAN_IOREG_MSK));
42 break;
43
44 case WLAN_TX_HIQ_DEVICE_ID:
45 *pCmdAddr = ((WLAN_TX_HIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
46 break;
47
48 case WLAN_TX_MIQ_DEVICE_ID:
49 *pCmdAddr = ((WLAN_TX_MIQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
50 break;
51
52 case WLAN_TX_LOQ_DEVICE_ID:
53 *pCmdAddr = ((WLAN_TX_LOQ_DEVICE_ID << 13) | (Addr & WLAN_FIFO_MSK));
54 break;
55
56 case WLAN_RX0FF_DEVICE_ID:
57 *pCmdAddr = ((WLAN_RX0FF_DEVICE_ID << 13) | (Addr & WLAN_RX0FF_MSK));
58 break;
59
60 default:
61 break;
62 }
63 }
64
get_deviceid(u32 addr)65 static u8 get_deviceid(u32 addr)
66 {
67 u8 devideId;
68 u16 pseudoId;
69
70
71 pseudoId = (u16)(addr >> 16);
72 switch (pseudoId) {
73 case 0x1025:
74 devideId = SDIO_LOCAL_DEVICE_ID;
75 break;
76
77 case 0x1026:
78 devideId = WLAN_IOREG_DEVICE_ID;
79 break;
80
81 /* case 0x1027:
82 * devideId = SDIO_FIRMWARE_FIFO;
83 * break; */
84
85 case 0x1031:
86 devideId = WLAN_TX_HIQ_DEVICE_ID;
87 break;
88
89 case 0x1032:
90 devideId = WLAN_TX_MIQ_DEVICE_ID;
91 break;
92
93 case 0x1033:
94 devideId = WLAN_TX_LOQ_DEVICE_ID;
95 break;
96
97 case 0x1034:
98 devideId = WLAN_RX0FF_DEVICE_ID;
99 break;
100
101 default:
102 /* devideId = (u8)((addr >> 13) & 0xF); */
103 devideId = WLAN_IOREG_DEVICE_ID;
104 break;
105 }
106
107 return devideId;
108 }
109
110 /*
111 * Ref:
112 * HalSdioGetCmdAddr8723DSdio()
113 */
_cvrt2ftaddr(const u32 addr,u8 * pdeviceId,u16 * poffset)114 static u32 _cvrt2ftaddr(const u32 addr, u8 *pdeviceId, u16 *poffset)
115 {
116 u8 deviceId;
117 u16 offset;
118 u32 ftaddr;
119
120
121 deviceId = get_deviceid(addr);
122 offset = 0;
123
124 switch (deviceId) {
125 case SDIO_LOCAL_DEVICE_ID:
126 offset = addr & SDIO_LOCAL_MSK;
127 break;
128
129 case WLAN_TX_HIQ_DEVICE_ID:
130 case WLAN_TX_MIQ_DEVICE_ID:
131 case WLAN_TX_LOQ_DEVICE_ID:
132 offset = addr & WLAN_FIFO_MSK;
133 break;
134
135 case WLAN_RX0FF_DEVICE_ID:
136 offset = addr & WLAN_RX0FF_MSK;
137 break;
138
139 case WLAN_IOREG_DEVICE_ID:
140 default:
141 deviceId = WLAN_IOREG_DEVICE_ID;
142 offset = addr & WLAN_IOREG_MSK;
143 break;
144 }
145 ftaddr = (deviceId << 13) | offset;
146
147 if (pdeviceId)
148 *pdeviceId = deviceId;
149 if (poffset)
150 *poffset = offset;
151
152 return ftaddr;
153 }
154
sdio_read8(struct intf_hdl * pintfhdl,u32 addr)155 u8 sdio_read8(struct intf_hdl *pintfhdl, u32 addr)
156 {
157 u32 ftaddr;
158 u8 val;
159
160 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
161 val = sd_read8(pintfhdl, ftaddr, NULL);
162
163
164 return val;
165 }
166
sdio_read16(struct intf_hdl * pintfhdl,u32 addr)167 u16 sdio_read16(struct intf_hdl *pintfhdl, u32 addr)
168 {
169 u32 ftaddr;
170 u16 val;
171
172 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
173 val = 0;
174 sd_cmd52_read(pintfhdl, ftaddr, 2, (u8 *)&val);
175 val = le16_to_cpu(val);
176
177
178 return val;
179 }
180
sdio_read32(struct intf_hdl * pintfhdl,u32 addr)181 u32 sdio_read32(struct intf_hdl *pintfhdl, u32 addr)
182 {
183 PADAPTER padapter;
184 u8 bMacPwrCtrlOn;
185 u8 deviceId;
186 u16 offset;
187 u32 ftaddr;
188 u8 shift;
189 u32 val;
190 s32 err;
191
192
193 padapter = pintfhdl->padapter;
194 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
195
196 bMacPwrCtrlOn = _FALSE;
197 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
198 if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
199 || (_FALSE == bMacPwrCtrlOn)
200 #ifdef CONFIG_LPS_LCLK
201 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
202 #endif
203 ) {
204 val = 0;
205 err = sd_cmd52_read(pintfhdl, ftaddr, 4, (u8 *)&val);
206 #ifdef SDIO_DEBUG_IO
207 if (!err) {
208 #endif
209 val = le32_to_cpu(val);
210 return val;
211 #ifdef SDIO_DEBUG_IO
212 }
213
214 RTW_ERR("%s: Mac Power off, Read FAIL(%d)! addr=0x%x\n",
215 __func__, err, addr);
216
217 return SDIO_ERR_VAL32;
218 #endif
219 }
220
221 /* 4 bytes alignment */
222 shift = ftaddr & 0x3;
223 if (shift == 0)
224 val = sd_read32(pintfhdl, ftaddr, NULL);
225 else {
226 u8 *ptmpbuf;
227
228 ptmpbuf = (u8 *)rtw_malloc(8);
229 if (NULL == ptmpbuf) {
230 RTW_ERR("%s: Allocate memory FAIL!(size=8) addr=0x%x\n",
231 __func__, addr);
232 return SDIO_ERR_VAL32;
233 }
234
235 ftaddr &= ~(u16)0x3;
236 sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
237 _rtw_memcpy(&val, ptmpbuf + shift, 4);
238 val = le32_to_cpu(val);
239
240 rtw_mfree(ptmpbuf, 8);
241 }
242
243
244 return val;
245 }
246
sdio_readN(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pbuf)247 s32 sdio_readN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
248 {
249 PADAPTER padapter;
250 u8 bMacPwrCtrlOn;
251 u8 deviceId;
252 u16 offset;
253 u32 ftaddr;
254 u8 shift;
255 s32 err;
256
257
258 padapter = pintfhdl->padapter;
259 err = 0;
260
261 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
262
263 bMacPwrCtrlOn = _FALSE;
264 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
265 if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
266 || (_FALSE == bMacPwrCtrlOn)
267 #ifdef CONFIG_LPS_LCLK
268 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
269 #endif
270 ) {
271 err = sd_cmd52_read(pintfhdl, ftaddr, cnt, pbuf);
272 return err;
273 }
274
275 /* 4 bytes alignment */
276 shift = ftaddr & 0x3;
277 if (shift == 0)
278 err = sd_read(pintfhdl, ftaddr, cnt, pbuf);
279 else {
280 u8 *ptmpbuf;
281 u32 n;
282
283 ftaddr &= ~(u16)0x3;
284 n = cnt + shift;
285 ptmpbuf = rtw_malloc(n);
286 if (NULL == ptmpbuf)
287 return -1;
288 err = sd_read(pintfhdl, ftaddr, n, ptmpbuf);
289 if (!err)
290 _rtw_memcpy(pbuf, ptmpbuf + shift, cnt);
291 rtw_mfree(ptmpbuf, n);
292 }
293
294
295 return err;
296 }
297
sdio_write8(struct intf_hdl * pintfhdl,u32 addr,u8 val)298 s32 sdio_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
299 {
300 u32 ftaddr;
301 s32 err;
302
303 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
304 err = 0;
305 sd_write8(pintfhdl, ftaddr, val, &err);
306
307
308 return err;
309 }
310
sdio_write16(struct intf_hdl * pintfhdl,u32 addr,u16 val)311 s32 sdio_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
312 {
313 u32 ftaddr;
314 u8 shift;
315 s32 err;
316
317 ftaddr = _cvrt2ftaddr(addr, NULL, NULL);
318 val = cpu_to_le16(val);
319 err = sd_cmd52_write(pintfhdl, ftaddr, 2, (u8 *)&val);
320
321
322 return err;
323 }
324
sdio_write32(struct intf_hdl * pintfhdl,u32 addr,u32 val)325 s32 sdio_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
326 {
327 PADAPTER padapter;
328 u8 bMacPwrCtrlOn;
329 u8 deviceId;
330 u16 offset;
331 u32 ftaddr;
332 u8 shift;
333 s32 err;
334
335
336 padapter = pintfhdl->padapter;
337 err = 0;
338
339 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
340
341 bMacPwrCtrlOn = _FALSE;
342 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
343 if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
344 || (_FALSE == bMacPwrCtrlOn)
345 #ifdef CONFIG_LPS_LCLK
346 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
347 #endif
348 ) {
349 val = cpu_to_le32(val);
350 err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&val);
351 return err;
352 }
353
354 /* 4 bytes alignment */
355 shift = ftaddr & 0x3;
356 #if 1
357 if (shift == 0)
358 sd_write32(pintfhdl, ftaddr, val, &err);
359 else {
360 val = cpu_to_le32(val);
361 err = sd_cmd52_write(pintfhdl, ftaddr, 4, (u8 *)&val);
362 }
363 #else
364 if (shift == 0)
365 sd_write32(pintfhdl, ftaddr, val, &err);
366 else {
367 u8 *ptmpbuf;
368
369 ptmpbuf = (u8 *)rtw_malloc(8);
370 if (NULL == ptmpbuf)
371 return -1;
372
373 ftaddr &= ~(u16)0x3;
374 err = sd_read(pintfhdl, ftaddr, 8, ptmpbuf);
375 if (err) {
376 rtw_mfree(ptmpbuf, 8);
377 return err;
378 }
379 val = cpu_to_le32(val);
380 _rtw_memcpy(ptmpbuf + shift, &val, 4);
381 err = sd_write(pintfhdl, ftaddr, 8, ptmpbuf);
382
383 rtw_mfree(ptmpbuf, 8);
384 }
385 #endif
386
387
388 return err;
389 }
390
sdio_writeN(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * pbuf)391 s32 sdio_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *pbuf)
392 {
393 PADAPTER padapter;
394 u8 bMacPwrCtrlOn;
395 u8 deviceId;
396 u16 offset;
397 u32 ftaddr;
398 u8 shift;
399 s32 err;
400
401
402 padapter = pintfhdl->padapter;
403 err = 0;
404
405 ftaddr = _cvrt2ftaddr(addr, &deviceId, &offset);
406
407 bMacPwrCtrlOn = _FALSE;
408 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
409 if (((deviceId == WLAN_IOREG_DEVICE_ID) && (offset < 0x100))
410 || (_FALSE == bMacPwrCtrlOn)
411 #ifdef CONFIG_LPS_LCLK
412 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
413 #endif
414 ) {
415 err = sd_cmd52_write(pintfhdl, ftaddr, cnt, pbuf);
416 return err;
417 }
418
419 shift = ftaddr & 0x3;
420 if (shift == 0)
421 err = sd_write(pintfhdl, ftaddr, cnt, pbuf);
422 else {
423 u8 *ptmpbuf;
424 u32 n;
425
426 ftaddr &= ~(u16)0x3;
427 n = cnt + shift;
428 ptmpbuf = rtw_malloc(n);
429 if (NULL == ptmpbuf)
430 return -1;
431 err = sd_read(pintfhdl, ftaddr, 4, ptmpbuf);
432 if (err) {
433 rtw_mfree(ptmpbuf, n);
434 return err;
435 }
436 _rtw_memcpy(ptmpbuf + shift, pbuf, cnt);
437 err = sd_write(pintfhdl, ftaddr, n, ptmpbuf);
438 rtw_mfree(ptmpbuf, n);
439 }
440
441
442 return err;
443 }
444
sdio_f0_read8(struct intf_hdl * pintfhdl,u32 addr)445 u8 sdio_f0_read8(struct intf_hdl *pintfhdl, u32 addr)
446 {
447 u32 ftaddr;
448 u8 val;
449
450 val = sd_f0_read8(pintfhdl, addr, NULL);
451
452
453 return val;
454 }
455
sdio_read_mem(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * rmem)456 void sdio_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
457 {
458 s32 err;
459
460
461 err = sdio_readN(pintfhdl, addr, cnt, rmem);
462
463 }
464
sdio_write_mem(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * wmem)465 void sdio_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
466 {
467
468 sdio_writeN(pintfhdl, addr, cnt, wmem);
469
470 }
471
472 /*
473 * Description:
474 * Read from RX FIFO
475 * Round read size to block size,
476 * and make sure data transfer will be done in one command.
477 *
478 * Parameters:
479 * pintfhdl a pointer of intf_hdl
480 * addr port ID
481 * cnt size to read
482 * rmem address to put data
483 *
484 * Return:
485 * _SUCCESS(1) Success
486 * _FAIL(0) Fail
487 */
sdio_read_port(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * mem)488 static u32 sdio_read_port(
489 struct intf_hdl *pintfhdl,
490 u32 addr,
491 u32 cnt,
492 u8 *mem)
493 {
494 PADAPTER padapter;
495 PHAL_DATA_TYPE phal;
496 u32 oldcnt;
497 #ifdef SDIO_DYNAMIC_ALLOC_MEM
498 u8 *oldmem;
499 #endif
500 s32 err;
501
502
503 padapter = pintfhdl->padapter;
504 phal = GET_HAL_DATA(padapter);
505
506 HalSdioGetCmdAddr8723DSdio(padapter, addr, phal->SdioRxFIFOCnt++, &addr);
507
508 oldcnt = cnt;
509 cnt = rtw_sdio_cmd53_align_size(adapter_to_dvobj(padapter), cnt);
510
511 if (oldcnt != cnt) {
512 #ifdef SDIO_DYNAMIC_ALLOC_MEM
513 oldmem = mem;
514 mem = rtw_malloc(cnt);
515 if (mem == NULL) {
516 RTW_WARN("%s: allocate memory %d bytes fail!\n",
517 __func__, cnt);
518 mem = oldmem;
519 oldmem == NULL;
520 }
521 #else
522 /* in this case, caller should gurante the buffer is big enough */
523 /* to receive data after alignment */
524 #endif
525 }
526
527 err = _sd_read(pintfhdl, addr, cnt, mem);
528
529 #ifdef SDIO_DYNAMIC_ALLOC_MEM
530 if ((oldcnt != cnt) && (oldmem)) {
531 _rtw_memcpy(oldmem, mem, oldcnt);
532 rtw_mfree(mem, cnt);
533 }
534 #endif
535
536 if (err)
537 return _FAIL;
538 return _SUCCESS;
539 }
540
541 /*
542 * Description:
543 * Write to TX FIFO
544 * Align write size block size,
545 * and make sure data could be written in one command.
546 *
547 * Parameters:
548 * pintfhdl a pointer of intf_hdl
549 * addr port ID
550 * cnt size to write
551 * wmem data pointer to write
552 *
553 * Return:
554 * _SUCCESS(1) Success
555 * _FAIL(0) Fail
556 */
sdio_write_port(struct intf_hdl * pintfhdl,u32 addr,u32 cnt,u8 * mem)557 static u32 sdio_write_port(
558 struct intf_hdl *pintfhdl,
559 u32 addr,
560 u32 cnt,
561 u8 *mem)
562 {
563 PADAPTER padapter;
564 s32 err;
565 struct xmit_buf *xmitbuf = (struct xmit_buf *)mem;
566
567 padapter = pintfhdl->padapter;
568
569 #ifndef CONFIG_DLFW_TXPKT
570 if (!rtw_is_hw_init_completed(padapter)) {
571 RTW_INFO("%s [addr=0x%x cnt=%d] hw_init_completed is FALSE\n",
572 __func__, addr, cnt);
573 return _FAIL;
574 }
575 #endif
576
577 cnt = _RND4(cnt);
578 HalSdioGetCmdAddr8723DSdio(padapter, addr, cnt >> 2, &addr);
579
580 cnt = rtw_sdio_cmd53_align_size(adapter_to_dvobj(padapter), cnt);
581
582 err = sd_write(pintfhdl, addr, cnt, xmitbuf->pdata);
583
584 rtw_sctx_done_err(&xmitbuf->sctx,
585 err ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
586
587 if (err)
588 return _FAIL;
589 return _SUCCESS;
590 }
591
sdio_set_intf_ops(_adapter * padapter,struct _io_ops * pops)592 void sdio_set_intf_ops(_adapter *padapter, struct _io_ops *pops)
593 {
594
595 pops->_read8 = &sdio_read8;
596 pops->_read16 = &sdio_read16;
597 pops->_read32 = &sdio_read32;
598 pops->_read_mem = &sdio_read_mem;
599 pops->_read_port = &sdio_read_port;
600
601 pops->_write8 = &sdio_write8;
602 pops->_write16 = &sdio_write16;
603 pops->_write32 = &sdio_write32;
604 pops->_writeN = &sdio_writeN;
605 pops->_write_mem = &sdio_write_mem;
606 pops->_write_port = &sdio_write_port;
607
608 pops->_sd_f0_read8 = sdio_f0_read8;
609
610 }
611
612 /*
613 * Todo: align address to 4 bytes.
614 */
_sdio_local_read(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)615 s32 _sdio_local_read(
616 PADAPTER padapter,
617 u32 addr,
618 u32 cnt,
619 u8 *pbuf)
620 {
621 struct intf_hdl *pintfhdl;
622 u8 bMacPwrCtrlOn;
623 s32 err;
624 u8 *ptmpbuf;
625 u32 n;
626
627
628 pintfhdl = &padapter->iopriv.intf;
629
630 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
631
632 bMacPwrCtrlOn = _FALSE;
633 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
634 if (_FALSE == bMacPwrCtrlOn) {
635 err = _sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
636 return err;
637 }
638
639 n = RND4(cnt);
640 ptmpbuf = (u8 *)rtw_malloc(n);
641 if (!ptmpbuf)
642 return -1;
643
644 err = _sd_read(pintfhdl, addr, n, ptmpbuf);
645 if (!err)
646 _rtw_memcpy(pbuf, ptmpbuf, cnt);
647
648 if (ptmpbuf)
649 rtw_mfree(ptmpbuf, n);
650
651 return err;
652 }
653
654 /*
655 * Todo: align address to 4 bytes.
656 */
sdio_local_read(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)657 s32 sdio_local_read(
658 PADAPTER padapter,
659 u32 addr,
660 u32 cnt,
661 u8 *pbuf)
662 {
663 struct intf_hdl *pintfhdl;
664 u8 bMacPwrCtrlOn;
665 s32 err;
666 u8 *ptmpbuf;
667 u32 n;
668
669 pintfhdl = &padapter->iopriv.intf;
670
671 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
672
673 bMacPwrCtrlOn = _FALSE;
674 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
675 if ((_FALSE == bMacPwrCtrlOn)
676 #ifdef CONFIG_LPS_LCLK
677 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
678 #endif
679 ) {
680 err = sd_cmd52_read(pintfhdl, addr, cnt, pbuf);
681 return err;
682 }
683
684 n = RND4(cnt);
685 ptmpbuf = (u8 *)rtw_malloc(n);
686 if (!ptmpbuf)
687 return -1;
688
689 err = sd_read(pintfhdl, addr, n, ptmpbuf);
690 if (!err)
691 _rtw_memcpy(pbuf, ptmpbuf, cnt);
692
693 if (ptmpbuf)
694 rtw_mfree(ptmpbuf, n);
695
696 return err;
697 }
698
699 /*
700 * Todo: align address to 4 bytes.
701 */
_sdio_local_write(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)702 s32 _sdio_local_write(
703 PADAPTER padapter,
704 u32 addr,
705 u32 cnt,
706 u8 *pbuf)
707 {
708 struct intf_hdl *pintfhdl;
709 u8 bMacPwrCtrlOn;
710 s32 err;
711 u8 *ptmpbuf;
712
713 if (addr & 0x3)
714 RTW_INFO("%s, address must be 4 bytes alignment\n", __func__);
715
716 if (cnt & 0x3)
717 RTW_INFO("%s, size must be the multiple of 4\n", __func__);
718
719 pintfhdl = &padapter->iopriv.intf;
720
721 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
722
723 bMacPwrCtrlOn = _FALSE;
724 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
725 if ((_FALSE == bMacPwrCtrlOn)
726 #ifdef CONFIG_LPS_LCLK
727 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
728 #endif
729 ) {
730 err = _sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
731 return err;
732 }
733
734 ptmpbuf = (u8 *)rtw_malloc(cnt);
735 if (!ptmpbuf)
736 return -1;
737
738 _rtw_memcpy(ptmpbuf, pbuf, cnt);
739
740 err = _sd_write(pintfhdl, addr, cnt, ptmpbuf);
741
742 if (ptmpbuf)
743 rtw_mfree(ptmpbuf, cnt);
744
745 return err;
746 }
747
748 /*
749 * Todo: align address to 4 bytes.
750 */
sdio_local_write(PADAPTER padapter,u32 addr,u32 cnt,u8 * pbuf)751 s32 sdio_local_write(
752 PADAPTER padapter,
753 u32 addr,
754 u32 cnt,
755 u8 *pbuf)
756 {
757 struct intf_hdl *pintfhdl;
758 u8 bMacPwrCtrlOn;
759 s32 err;
760 u8 *ptmpbuf;
761
762 if (addr & 0x3)
763 RTW_INFO("%s, address must be 4 bytes alignment\n", __func__);
764
765 if (cnt & 0x3)
766 RTW_INFO("%s, size must be the multiple of 4\n", __func__);
767
768 pintfhdl = &padapter->iopriv.intf;
769
770 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
771
772 bMacPwrCtrlOn = _FALSE;
773 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
774 if ((_FALSE == bMacPwrCtrlOn)
775 #ifdef CONFIG_LPS_LCLK
776 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
777 #endif
778 ) {
779 err = sd_cmd52_write(pintfhdl, addr, cnt, pbuf);
780 return err;
781 }
782
783 ptmpbuf = (u8 *)rtw_malloc(cnt);
784 if (!ptmpbuf)
785 return -1;
786
787 _rtw_memcpy(ptmpbuf, pbuf, cnt);
788
789 err = sd_write(pintfhdl, addr, cnt, ptmpbuf);
790
791 if (ptmpbuf)
792 rtw_mfree(ptmpbuf, cnt);
793
794 return err;
795 }
796
SdioLocalCmd52Read1Byte(PADAPTER padapter,u32 addr)797 u8 SdioLocalCmd52Read1Byte(PADAPTER padapter, u32 addr)
798 {
799 u8 val = 0;
800 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
801
802 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
803 sd_cmd52_read(pintfhdl, addr, 1, &val);
804
805 return val;
806 }
807
SdioLocalCmd52Read2Byte(PADAPTER padapter,u32 addr)808 u16 SdioLocalCmd52Read2Byte(PADAPTER padapter, u32 addr)
809 {
810 u16 val = 0;
811 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
812
813 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
814 sd_cmd52_read(pintfhdl, addr, 2, (u8 *)&val);
815
816 val = le16_to_cpu(val);
817
818 return val;
819 }
820
SdioLocalCmd52Read4Byte(PADAPTER padapter,u32 addr)821 u32 SdioLocalCmd52Read4Byte(PADAPTER padapter, u32 addr)
822 {
823 u32 val = 0;
824 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
825
826 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
827 sd_cmd52_read(pintfhdl, addr, 4, (u8 *)&val);
828
829 val = le32_to_cpu(val);
830
831 return val;
832 }
833
SdioLocalCmd53Read4Byte(PADAPTER padapter,u32 addr)834 u32 SdioLocalCmd53Read4Byte(PADAPTER padapter, u32 addr)
835 {
836
837 u8 bMacPwrCtrlOn;
838 u32 val = 0;
839 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
840
841 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
842 bMacPwrCtrlOn = _FALSE;
843 rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);
844 if ((_FALSE == bMacPwrCtrlOn)
845 #ifdef CONFIG_LPS_LCLK
846 || (_TRUE == adapter_to_pwrctl(padapter)->bFwCurrentInPSMode)
847 #endif
848 ) {
849 sd_cmd52_read(pintfhdl, addr, 4, (u8 *)&val);
850 val = le32_to_cpu(val);
851 } else
852 val = sd_read32(pintfhdl, addr, NULL);
853
854 return val;
855 }
856
SdioLocalCmd52Write1Byte(PADAPTER padapter,u32 addr,u8 v)857 void SdioLocalCmd52Write1Byte(PADAPTER padapter, u32 addr, u8 v)
858 {
859 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
860
861 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
862 sd_cmd52_write(pintfhdl, addr, 1, &v);
863 }
864
SdioLocalCmd52Write2Byte(PADAPTER padapter,u32 addr,u16 v)865 void SdioLocalCmd52Write2Byte(PADAPTER padapter, u32 addr, u16 v)
866 {
867 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
868
869 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
870 v = cpu_to_le16(v);
871 sd_cmd52_write(pintfhdl, addr, 2, (u8 *)&v);
872 }
873
SdioLocalCmd52Write4Byte(PADAPTER padapter,u32 addr,u32 v)874 void SdioLocalCmd52Write4Byte(PADAPTER padapter, u32 addr, u32 v)
875 {
876 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
877
878 HalSdioGetCmdAddr8723DSdio(padapter, SDIO_LOCAL_DEVICE_ID, addr, &addr);
879 v = cpu_to_le32(v);
880 sd_cmd52_write(pintfhdl, addr, 4, (u8 *)&v);
881 }
882
883 #if 0
884 void
885 DumpLoggedInterruptHistory8723Sdio(
886 PADAPTER padapter
887 )
888 {
889 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
890 u32 DebugLevel = DBG_LOUD;
891
892 if (DBG_Var.DbgPrintIsr == 0)
893 return;
894
895 DBG_ChkDrvResource(padapter);
896
897
898
899 }
900
901 void
902 LogInterruptHistory8723Sdio(
903 PADAPTER padapter,
904 PRT_ISR_CONTENT pIsrContent
905 )
906 {
907 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
908
909 if ((pHalData->IntrMask[0] & SDIO_HIMR_RX_REQUEST_MSK) &&
910 (pIsrContent->IntArray[0] & SDIO_HISR_RX_REQUEST))
911 pHalData->InterruptLog.nISR_RX_REQUEST++;
912 if ((pHalData->IntrMask[0] & SDIO_HIMR_AVAL_MSK) &&
913 (pIsrContent->IntArray[0] & SDIO_HISR_AVAL))
914 pHalData->InterruptLog.nISR_AVAL++;
915 if ((pHalData->IntrMask[0] & SDIO_HIMR_TXERR_MSK) &&
916 (pIsrContent->IntArray[0] & SDIO_HISR_TXERR))
917 pHalData->InterruptLog.nISR_TXERR++;
918 if ((pHalData->IntrMask[0] & SDIO_HIMR_RXERR_MSK) &&
919 (pIsrContent->IntArray[0] & SDIO_HISR_RXERR))
920 pHalData->InterruptLog.nISR_RXERR++;
921 if ((pHalData->IntrMask[0] & SDIO_HIMR_TXFOVW_MSK) &&
922 (pIsrContent->IntArray[0] & SDIO_HISR_TXFOVW))
923 pHalData->InterruptLog.nISR_TXFOVW++;
924 if ((pHalData->IntrMask[0] & SDIO_HIMR_RXFOVW_MSK) &&
925 (pIsrContent->IntArray[0] & SDIO_HISR_RXFOVW))
926 pHalData->InterruptLog.nISR_RXFOVW++;
927 if ((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNOK_MSK) &&
928 (pIsrContent->IntArray[0] & SDIO_HISR_TXBCNOK))
929 pHalData->InterruptLog.nISR_TXBCNOK++;
930 if ((pHalData->IntrMask[0] & SDIO_HIMR_TXBCNERR_MSK) &&
931 (pIsrContent->IntArray[0] & SDIO_HISR_TXBCNERR))
932 pHalData->InterruptLog.nISR_TXBCNERR++;
933 if ((pHalData->IntrMask[0] & SDIO_HIMR_BCNERLY_INT_MSK) &&
934 (pIsrContent->IntArray[0] & SDIO_HISR_BCNERLY_INT))
935 pHalData->InterruptLog.nISR_BCNERLY_INT++;
936 if ((pHalData->IntrMask[0] & SDIO_HIMR_C2HCMD_MSK) &&
937 (pIsrContent->IntArray[0] & SDIO_HISR_C2HCMD))
938 pHalData->InterruptLog.nISR_C2HCMD++;
939 if ((pHalData->IntrMask[0] & SDIO_HIMR_CPWM1_MSK) &&
940 (pIsrContent->IntArray[0] & SDIO_HISR_CPWM1))
941 pHalData->InterruptLog.nISR_CPWM1++;
942 if ((pHalData->IntrMask[0] & SDIO_HIMR_CPWM2_MSK) &&
943 (pIsrContent->IntArray[0] & SDIO_HISR_CPWM2))
944 pHalData->InterruptLog.nISR_CPWM2++;
945 if ((pHalData->IntrMask[0] & SDIO_HIMR_HSISR_IND_MSK) &&
946 (pIsrContent->IntArray[0] & SDIO_HISR_HSISR_IND))
947 pHalData->InterruptLog.nISR_HSISR_IND++;
948 if ((pHalData->IntrMask[0] & SDIO_HIMR_GTINT3_IND_MSK) &&
949 (pIsrContent->IntArray[0] & SDIO_HISR_GTINT3_IND))
950 pHalData->InterruptLog.nISR_GTINT3_IND++;
951 if ((pHalData->IntrMask[0] & SDIO_HIMR_GTINT4_IND_MSK) &&
952 (pIsrContent->IntArray[0] & SDIO_HISR_GTINT4_IND))
953 pHalData->InterruptLog.nISR_GTINT4_IND++;
954 if ((pHalData->IntrMask[0] & SDIO_HIMR_PSTIMEOUT_MSK) &&
955 (pIsrContent->IntArray[0] & SDIO_HISR_PSTIMEOUT))
956 pHalData->InterruptLog.nISR_PSTIMEOUT++;
957 if ((pHalData->IntrMask[0] & SDIO_HIMR_OCPINT_MSK) &&
958 (pIsrContent->IntArray[0] & SDIO_HISR_OCPINT))
959 pHalData->InterruptLog.nISR_OCPINT++;
960 if ((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_MSK) &&
961 (pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND))
962 pHalData->InterruptLog.nISR_ATIMEND++;
963 if ((pHalData->IntrMask[0] & SDIO_HIMR_ATIMEND_E_MSK) &&
964 (pIsrContent->IntArray[0] & SDIO_HISR_ATIMEND_E))
965 pHalData->InterruptLog.nISR_ATIMEND_E++;
966 if ((pHalData->IntrMask[0] & SDIO_HIMR_CTWEND_MSK) &&
967 (pIsrContent->IntArray[0] & SDIO_HISR_CTWEND))
968 pHalData->InterruptLog.nISR_CTWEND++;
969
970 }
971
972 void
973 DumpHardwareProfile8723Sdio(
974 PADAPTER padapter
975 )
976 {
977 DumpLoggedInterruptHistory8723Sdio(padapter);
978 }
979 #endif
980
981 #ifndef CMD52_ACCESS_HISR_RX_REQ_LEN
982 #define CMD52_ACCESS_HISR_RX_REQ_LEN 0
983 #endif
984
985 #if CMD52_ACCESS_HISR_RX_REQ_LEN
ReadInterrupt8723DSdio(PADAPTER padapter,u32 * phisr)986 static s32 ReadInterrupt8723DSdio(PADAPTER padapter, u32 *phisr)
987 {
988 u32 hisr, himr;
989 u8 val8, hisr_len;
990
991
992 if (phisr == NULL)
993 return _FALSE;
994
995 himr = GET_HAL_DATA(padapter)->sdio_himr;
996
997 /* decide how many bytes need to be read */
998 hisr_len = 0;
999 while (himr) {
1000 hisr_len++;
1001 himr >>= 8;
1002 }
1003
1004 hisr = 0;
1005 while (hisr_len != 0) {
1006 hisr_len--;
1007 val8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR + hisr_len);
1008 hisr |= (val8 << (8 * hisr_len));
1009 }
1010
1011 *phisr = hisr;
1012
1013 return _TRUE;
1014 }
1015 #endif /*#if CMD52_ACCESS_HISR_RX_REQ_LEN*/
1016 /*
1017 * Description:
1018 * Initialize SDIO Host Interrupt Mask configuration variables for future use.
1019 *
1020 * Assumption:
1021 * Using SDIO Local register ONLY for configuration.
1022 *
1023 * Created by Roger, 2011.02.11.
1024 * */
InitInterrupt8723DSdio(PADAPTER padapter)1025 void InitInterrupt8723DSdio(PADAPTER padapter)
1026 {
1027 PHAL_DATA_TYPE pHalData;
1028
1029
1030 pHalData = GET_HAL_DATA(padapter);
1031 pHalData->sdio_himr = (u32)(
1032 SDIO_HIMR_RX_REQUEST_MSK |
1033 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
1034 SDIO_HIMR_AVAL_MSK |
1035 #endif
1036 /* SDIO_HIMR_TXERR_MSK |
1037 * SDIO_HIMR_RXERR_MSK |
1038 * SDIO_HIMR_TXFOVW_MSK |
1039 * SDIO_HIMR_RXFOVW_MSK |
1040 * SDIO_HIMR_TXBCNOK_MSK |
1041 * SDIO_HIMR_TXBCNERR_MSK |
1042 * SDIO_HIMR_BCNERLY_INT_MSK |
1043 * SDIO_HIMR_C2HCMD_MSK | */
1044 #if defined(CONFIG_LPS_LCLK) && !defined(CONFIG_DETECT_CPWM_BY_POLLING)
1045 SDIO_HIMR_CPWM1_MSK |
1046 /* SDIO_HIMR_CPWM2_MSK | */
1047 #endif /* CONFIG_LPS_LCLK && !CONFIG_DETECT_CPWM_BY_POLLING
1048 * SDIO_HIMR_HSISR_IND_MSK |
1049 * SDIO_HIMR_GTINT3_IND_MSK |
1050 * SDIO_HIMR_GTINT4_IND_MSK |
1051 * SDIO_HIMR_PSTIMEOUT_MSK |
1052 * SDIO_HIMR_OCPINT_MSK |
1053 * SDIO_HIMR_ATIMEND_MSK |
1054 * SDIO_HIMR_ATIMEND_E_MSK |
1055 * SDIO_HIMR_CTWEND_MSK | */
1056 0);
1057 }
1058
1059 /*
1060 * Description:
1061 * Initialize System Host Interrupt Mask configuration variables for future use.
1062 *
1063 * Created by Roger, 2011.08.03.
1064 * */
InitSysInterrupt8723DSdio(PADAPTER padapter)1065 void InitSysInterrupt8723DSdio(PADAPTER padapter)
1066 {
1067 PHAL_DATA_TYPE pHalData;
1068
1069
1070 pHalData = GET_HAL_DATA(padapter);
1071
1072 pHalData->SysIntrMask = (
1073 /* HSIMR_GPIO12_0_INT_EN |
1074 * HSIMR_SPS_OCP_INT_EN |
1075 * HSIMR_RON_INT_EN |
1076 * HSIMR_PDNINT_EN |
1077 * HSIMR_GPIO9_INT_EN | */
1078 0);
1079 }
1080
1081 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1082 /*
1083 * Description:
1084 * Clear corresponding SDIO Host ISR interrupt service.
1085 *
1086 * Assumption:
1087 * Using SDIO Local register ONLY for configuration.
1088 *
1089 * Created by Roger, 2011.02.11.
1090 * */
ClearInterrupt8723DSdio(PADAPTER padapter)1091 void ClearInterrupt8723DSdio(PADAPTER padapter)
1092 {
1093 PHAL_DATA_TYPE pHalData;
1094 u8 *clear;
1095 u8 val_8 = 0;
1096 u32 val_32 = 0;
1097
1098 if (rtw_is_surprise_removed(padapter))
1099 return;
1100
1101 pHalData = GET_HAL_DATA(padapter);
1102 clear = rtw_zmalloc(4);
1103
1104 /* Clear corresponding HISR Content if needed */
1105 val_8 = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HISR + 2);
1106
1107 val_32 = pHalData->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1108
1109 if (val_8 && BIT3)
1110 *(u32 *)clear = cpu_to_le32(val_32 | SDIO_HISR_CPWM2);
1111 else
1112 *(u32 *)clear = cpu_to_le32(val_32);
1113
1114 if (*(u32 *)clear) {
1115 /* Perform write one clear operation */
1116 sdio_local_write(padapter, SDIO_REG_HISR, 4, clear);
1117 }
1118
1119 rtw_mfree(clear, 4);
1120 }
1121 #endif
1122
1123 /*
1124 * Description:
1125 * Clear corresponding system Host ISR interrupt service.
1126 *
1127 *
1128 * Created by Roger, 2011.02.11.
1129 * */
ClearSysInterrupt8723DSdio(PADAPTER padapter)1130 void ClearSysInterrupt8723DSdio(PADAPTER padapter)
1131 {
1132 PHAL_DATA_TYPE pHalData;
1133 u32 clear;
1134
1135
1136 if (rtw_is_surprise_removed(padapter))
1137 return;
1138
1139 pHalData = GET_HAL_DATA(padapter);
1140
1141 /* Clear corresponding HISR Content if needed */
1142 clear = pHalData->SysIntrStatus & MASK_HSISR_CLEAR;
1143 if (clear) {
1144 /* Perform write one clear operation */
1145 rtw_write32(padapter, REG_HSISR, clear);
1146 }
1147 }
1148
1149 /*
1150 * Description:
1151 * Enalbe SDIO Host Interrupt Mask configuration on SDIO local domain.
1152 *
1153 * Assumption:
1154 * 1. Using SDIO Local register ONLY for configuration.
1155 * 2. PASSIVE LEVEL
1156 *
1157 * Created by Roger, 2011.02.11.
1158 * */
EnableInterrupt8723DSdio(PADAPTER padapter)1159 void EnableInterrupt8723DSdio(PADAPTER padapter)
1160 {
1161 PHAL_DATA_TYPE pHalData;
1162 u32 himr;
1163
1164 pHalData = GET_HAL_DATA(padapter);
1165
1166 himr = cpu_to_le32(pHalData->sdio_himr);
1167 sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1168
1169
1170 /* Update current system IMR settings */
1171 himr = rtw_read32(padapter, REG_HSIMR);
1172 rtw_write32(padapter, REG_HSIMR, himr | pHalData->SysIntrMask);
1173
1174
1175 /* */
1176 /* <Roger_Notes> There are some C2H CMDs have been sent before system interrupt is enabled, e.g., C2H, CPWM. */
1177 /* So we need to clear all C2H events that FW has notified, otherwise FW won't schedule any commands anymore. */
1178 /* 2011.10.19. */
1179 /* */
1180 rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
1181 }
1182
1183 /*
1184 * Description:
1185 * Disable SDIO Host IMR configuration to mask unnecessary interrupt service.
1186 *
1187 * Assumption:
1188 * Using SDIO Local register ONLY for configuration.
1189 *
1190 * Created by Roger, 2011.02.11.
1191 * */
DisableInterrupt8723DSdio(PADAPTER padapter)1192 void DisableInterrupt8723DSdio(PADAPTER padapter)
1193 {
1194 u32 himr;
1195
1196 himr = cpu_to_le32(SDIO_HIMR_DISABLED);
1197 sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1198
1199 }
1200
1201 /*
1202 * Description:
1203 * Using 0x100 to check the power status of FW.
1204 *
1205 * Assumption:
1206 * Using SDIO Local register ONLY for configuration.
1207 *
1208 * Created by Isaac, 2013.09.10.
1209 * */
CheckIPSStatus(PADAPTER padapter)1210 u8 CheckIPSStatus(PADAPTER padapter)
1211 {
1212 RTW_INFO("%s(): Read 0x100=0x%02x 0x86=0x%02x\n", __func__,
1213 rtw_read8(padapter, 0x100), rtw_read8(padapter, 0x86));
1214
1215 if (rtw_read8(padapter, 0x100) == 0xEA)
1216 return _TRUE;
1217 else
1218 return _FALSE;
1219 }
1220
1221 #ifdef CONFIG_WOWLAN
DisableInterruptButCpwm28723DSdio(PADAPTER padapter)1222 void DisableInterruptButCpwm28723DSdio(PADAPTER padapter)
1223 {
1224 u32 himr, tmp;
1225
1226 sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1227 RTW_INFO("DisableInterruptButCpwm28723DSdio(): Read SDIO_REG_HIMR: 0x%08x\n", tmp);
1228
1229 himr = cpu_to_le32(SDIO_HIMR_DISABLED) | SDIO_HIMR_CPWM2_MSK;
1230 sdio_local_write(padapter, SDIO_REG_HIMR, 4, (u8 *)&himr);
1231
1232 sdio_local_read(padapter, SDIO_REG_HIMR, 4, (u8 *)&tmp);
1233 RTW_INFO("DisableInterruptButCpwm28723DSdio(): Read again SDIO_REG_HIMR: 0x%08x\n", tmp);
1234 }
1235 #endif /* CONFIG_WOWLAN
1236 *
1237 * Description:
1238 * Update SDIO Host Interrupt Mask configuration on SDIO local domain.
1239 *
1240 * Assumption:
1241 * 1. Using SDIO Local register ONLY for configuration.
1242 * 2. PASSIVE LEVEL
1243 *
1244 * Created by Roger, 2011.02.11.
1245 * */
UpdateInterruptMask8723DSdio(PADAPTER padapter,u32 AddMSR,u32 RemoveMSR)1246 void UpdateInterruptMask8723DSdio(PADAPTER padapter, u32 AddMSR, u32 RemoveMSR)
1247 {
1248 HAL_DATA_TYPE *pHalData;
1249
1250 pHalData = GET_HAL_DATA(padapter);
1251
1252 if (AddMSR)
1253 pHalData->sdio_himr |= AddMSR;
1254
1255 if (RemoveMSR)
1256 pHalData->sdio_himr &= (~RemoveMSR);
1257
1258 DisableInterrupt8723DSdio(padapter);
1259 EnableInterrupt8723DSdio(padapter);
1260 }
1261
1262 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
sd_recv_loopback(PADAPTER padapter,u32 size)1263 static void sd_recv_loopback(PADAPTER padapter, u32 size)
1264 {
1265 PLOOPBACKDATA ploopback;
1266 u32 readsize, allocsize;
1267 u8 *preadbuf;
1268
1269
1270 readsize = size;
1271 RTW_INFO("%s: read size=%d\n", __func__, readsize);
1272 allocsize = _RND(readsize, rtw_sdio_get_block_size(adapter_to_dvobj(padapter)));
1273
1274 ploopback = padapter->ploopback;
1275 if (ploopback) {
1276 ploopback->rxsize = readsize;
1277 preadbuf = ploopback->rxbuf;
1278 } else {
1279 preadbuf = rtw_malloc(allocsize);
1280 if (preadbuf == NULL) {
1281 RTW_INFO("%s: malloc fail size=%d\n", __func__, allocsize);
1282 return;
1283 }
1284 }
1285
1286 /* rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); */
1287 sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1288
1289 if (ploopback)
1290 _rtw_up_sema(&ploopback->sema);
1291 else {
1292 u32 i;
1293
1294 RTW_INFO("%s: drop pkt\n", __func__);
1295 for (i = 0; i < readsize; i += 4) {
1296 RTW_INFO("%08X", *(u32 *)(preadbuf + i));
1297 if ((i + 4) & 0x1F)
1298 printk(KERN_ERR " ");
1299 else
1300 printk(KERN_ERR "\n");
1301 }
1302 printk(KERN_ERR "\n");
1303 rtw_mfree(preadbuf, allocsize);
1304 }
1305 }
1306 #endif /* CONFIG_MAC_LOOPBACK_DRIVER */
1307
1308 #ifdef CONFIG_SDIO_RX_COPY
sd_recv_rxfifo(PADAPTER padapter,u32 size,struct recv_buf ** recvbuf_ret)1309 static u32 sd_recv_rxfifo(PADAPTER padapter, u32 size,
1310 struct recv_buf **recvbuf_ret)
1311 {
1312 u32 readsize, ret;
1313 u8 *preadbuf;
1314 struct recv_priv *precvpriv;
1315 struct recv_buf *precvbuf;
1316
1317 *recvbuf_ret = NULL;
1318
1319 #if 0
1320 readsize = size;
1321 #else
1322 /* Patch for some SDIO Host 4 bytes issue */
1323 /* ex. RK3188 */
1324 readsize = RND4(size);
1325 #endif
1326
1327 /* 3 1. alloc recvbuf */
1328 precvpriv = &padapter->recvpriv;
1329 precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
1330 if (precvbuf == NULL) {
1331 RTW_INFO("%s: recvbuf unavailable\n", __func__);
1332 ret = RTW_RBUF_UNAVAIL;
1333 goto exit;
1334 }
1335
1336 /* 3 2. alloc skb */
1337 if (precvbuf->pskb == NULL) {
1338 SIZE_PTR tmpaddr = 0;
1339 SIZE_PTR alignment = 0;
1340
1341 precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
1342 if (precvbuf->pskb == NULL) {
1343 RTW_INFO("%s: alloc_skb fail! read=%d\n", __func__, readsize);
1344 rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
1345 ret = RTW_RBUF_PKT_UNAVAIL;
1346 goto exit;
1347 }
1348
1349 precvbuf->pskb->dev = padapter->pnetdev;
1350
1351 tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
1352 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
1353 skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
1354 }
1355
1356 /* 3 3. read data from rxfifo */
1357 preadbuf = precvbuf->pskb->data;
1358 /* rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); */
1359 ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1360 if (ret == _FAIL) {
1361 rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
1362 goto exit;
1363 }
1364
1365 /* 3 4. init recvbuf */
1366 precvbuf->len = size;
1367 precvbuf->phead = precvbuf->pskb->head;
1368 precvbuf->pdata = precvbuf->pskb->data;
1369 skb_set_tail_pointer(precvbuf->pskb, size);
1370 precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1371 precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1372
1373 *recvbuf_ret = precvbuf;
1374 exit:
1375 return ret;
1376 }
1377 #else /* !CONFIG_SDIO_RX_COPY */
sd_recv_rxfifo(PADAPTER padapter,u32 size)1378 static struct recv_buf *sd_recv_rxfifo(PADAPTER padapter, u32 size)
1379 {
1380 u32 readsize, allocsize, ret;
1381 u8 *preadbuf;
1382 _pkt *ppkt;
1383 struct recv_priv *precvpriv;
1384 struct recv_buf *precvbuf;
1385
1386
1387 #if 0
1388 readsize = size;
1389 #else
1390 /* Patch for some SDIO Host 4 bytes issue */
1391 /* ex. RK3188 */
1392 readsize = RND4(size);
1393 #endif
1394
1395 /* 3 1. alloc skb */
1396 /* align to block size */
1397 allocsize = rtw_sdio_cmd53_align_size(adapter_to_dvobj(padapter), readsize);
1398
1399 ppkt = rtw_skb_alloc(allocsize);
1400
1401 if (ppkt == NULL) {
1402 return NULL;
1403 }
1404
1405 /* 3 2. read data from rxfifo */
1406 preadbuf = skb_put(ppkt, size);
1407 /* rtw_read_port(padapter, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf); */
1408 ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, readsize, preadbuf);
1409 if (ret == _FAIL) {
1410 rtw_skb_free(ppkt);
1411 return NULL;
1412 }
1413
1414 /* 3 3. alloc recvbuf */
1415 precvpriv = &padapter->recvpriv;
1416 precvbuf = rtw_dequeue_recvbuf(&precvpriv->free_recv_buf_queue);
1417 if (precvbuf == NULL) {
1418 rtw_skb_free(ppkt);
1419 RTW_ERR("%s: alloc recvbuf FAIL!\n", __func__);
1420 return NULL;
1421 }
1422
1423 /* 3 4. init recvbuf */
1424 precvbuf->pskb = ppkt;
1425
1426 precvbuf->len = ppkt->len;
1427
1428 precvbuf->phead = ppkt->head;
1429 precvbuf->pdata = ppkt->data;
1430 precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1431 precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1432
1433 return precvbuf;
1434 }
1435 #endif /* !CONFIG_SDIO_RX_COPY */
1436
sd_rxhandler(PADAPTER padapter,struct recv_buf * precvbuf)1437 static void sd_rxhandler(PADAPTER padapter, struct recv_buf *precvbuf)
1438 {
1439 struct recv_priv *precvpriv;
1440 _queue *ppending_queue;
1441
1442
1443 precvpriv = &padapter->recvpriv;
1444 ppending_queue = &precvpriv->recv_buf_pending_queue;
1445
1446 /* 3 1. enqueue recvbuf */
1447 rtw_enqueue_recvbuf(precvbuf, ppending_queue);
1448
1449 /* 3 2. trigger recv hdl */
1450 #ifdef CONFIG_RECV_THREAD_MODE
1451 _rtw_up_sema(&precvpriv->recv_sema);
1452 #else
1453 #ifdef PLATFORM_LINUX
1454 tasklet_schedule(&precvpriv->recv_tasklet);
1455 #endif /* PLATFORM_LINUX */
1456 #endif /* CONFIG_RECV_THREAD_MODE */
1457 }
1458
1459
1460 #ifndef SD_INT_HDL_DIS_HIMR_RX_REQ
1461 #define SD_INT_HDL_DIS_HIMR_RX_REQ 1
1462 #endif
1463
1464 #if SD_INT_HDL_DIS_HIMR_RX_REQ
disable_himr_rx_req_8723d_sdio(_adapter * adapter)1465 static void disable_himr_rx_req_8723d_sdio(_adapter *adapter)
1466 {
1467 HAL_DATA_TYPE *hal = GET_HAL_DATA(adapter);
1468 u32 himr = cpu_to_le32(hal->sdio_himr & ~SDIO_HISR_RX_REQUEST);
1469
1470 SdioLocalCmd52Write1Byte(adapter, SDIO_REG_HIMR, *((u8 *)&himr));
1471 }
restore_himr_8723d_sdio(_adapter * adapter)1472 static void restore_himr_8723d_sdio(_adapter *adapter)
1473 {
1474 HAL_DATA_TYPE *hal = GET_HAL_DATA(adapter);
1475 u32 himr = cpu_to_le32(hal->sdio_himr);
1476
1477 SdioLocalCmd52Write1Byte(adapter, SDIO_REG_HIMR, *((u8 *)&himr));
1478 }
1479 #endif
1480 #ifdef CONFIG_RECV_THREAD_MODE
sdio_recv_and_drop(PADAPTER padapter,u32 size)1481 static u32 sdio_recv_and_drop(PADAPTER padapter, u32 size)
1482 {
1483 u32 readsz, blksz, bufsz;
1484 u8 *rbuf;
1485 s32 ret = _SUCCESS;
1486
1487 /*
1488 * Patch for some SDIO Host 4 bytes issue
1489 * ex. RK3188
1490 */
1491 readsz = RND4(size);
1492
1493 /* round to block size */
1494 blksz = adapter_to_dvobj(padapter)->intf_data.block_transfer_len;
1495 if (readsz > blksz)
1496 bufsz = _RND(readsz, blksz);
1497 else
1498 bufsz = readsz;
1499
1500 rbuf = rtw_zmalloc(bufsz);
1501 if (NULL == rbuf) {
1502 RTW_ERR("%s: NULL == rbuf!\n", __FUNCTION__);
1503 ret = _FAIL;
1504 goto _exit;
1505 }
1506
1507 ret = sdio_read_port(&padapter->iopriv.intf, WLAN_RX0FF_DEVICE_ID, bufsz, rbuf);
1508 if (_FAIL == ret)
1509 RTW_ERR("%s: read port FAIL!\n", __FUNCTION__);
1510
1511 if (NULL != rbuf)
1512 rtw_mfree(rbuf, bufsz);
1513
1514 _exit:
1515 return ret;
1516 }
1517 #endif
sd_recv(PADAPTER padapter)1518 void sd_recv(PADAPTER padapter)
1519 {
1520 PHAL_DATA_TYPE phal = GET_HAL_DATA(padapter);
1521 struct recv_buf *precvbuf;
1522 int alloc_fail_time = 0;
1523 u32 rx_cnt = 0;
1524
1525 do {
1526 if (phal->SdioRxFIFOSize == 0) {
1527 #if CMD52_ACCESS_HISR_RX_REQ_LEN
1528 u16 rx_req_len;
1529
1530 rx_req_len = SdioLocalCmd52Read2Byte(padapter, SDIO_REG_RX0_REQ_LEN);
1531 if (rx_req_len) {
1532 if (rx_req_len % 256 == 0)
1533 rx_req_len += SdioLocalCmd52Read1Byte(padapter, SDIO_REG_RX0_REQ_LEN);
1534 phal->SdioRxFIFOSize = rx_req_len;
1535 }
1536 #else
1537 u8 data[4];
1538
1539 _sdio_local_read(padapter, SDIO_REG_RX0_REQ_LEN, 4, data);
1540 phal->SdioRxFIFOSize = le16_to_cpu(*(u16 *)data);
1541 #endif
1542 }
1543
1544 if (phal->SdioRxFIFOSize != 0) {
1545 u32 ret;
1546
1547 #ifdef CONFIG_MAC_LOOPBACK_DRIVER
1548 sd_recv_loopback(padapter, phal->SdioRxFIFOSize);
1549 #else
1550 ret = sd_recv_rxfifo(padapter, phal->SdioRxFIFOSize, &precvbuf);
1551 if (precvbuf) {
1552 sd_rxhandler(padapter, precvbuf);
1553 phal->SdioRxFIFOSize = 0;
1554 rx_cnt++;
1555 } else {
1556 alloc_fail_time++;
1557 #ifdef CONFIG_RECV_THREAD_MODE
1558 if (alloc_fail_time >= 10) {
1559 if (_FAIL == sdio_recv_and_drop(padapter, phal->SdioRxFIFOSize))
1560 break;
1561
1562 alloc_fail_time = 0;
1563 phal->SdioRxFIFOSize = 0;
1564 rx_cnt = 0;
1565 RTW_INFO("%s RECV_THREAD_MODE drop pkt due to alloc_fail_time >= 10 \n",__func__);
1566 } else {
1567 rtw_msleep_os(1);
1568 continue;
1569 }
1570 #else /* !CONFIG_RECV_THREAD_MODE */
1571 if (ret == RTW_RBUF_UNAVAIL || ret == RTW_RBUF_PKT_UNAVAIL)
1572 rtw_msleep_os(10);
1573 else {
1574 RTW_INFO("%s: recv fail!(time=%d)\n", __func__, alloc_fail_time);
1575 phal->SdioRxFIFOSize = 0;
1576 }
1577 if (alloc_fail_time >= 10 && rx_cnt != 0)
1578 break;
1579 #endif /* !CONFIG_RECV_THREAD_MODE */
1580 }
1581 #endif
1582 } else
1583 break;
1584 } while (1);
1585
1586 if (alloc_fail_time >= 10)
1587 RTW_INFO("%s: exit because recv failed more than 10 times!, rx_cnt:%u\n", __func__, rx_cnt);
1588 }
sd_int_dpc(PADAPTER padapter)1589 void sd_int_dpc(PADAPTER padapter)
1590 {
1591 PHAL_DATA_TYPE phal;
1592 struct dvobj_priv *dvobj;
1593 struct intf_hdl *pintfhdl = &padapter->iopriv.intf;
1594 struct pwrctrl_priv *pwrctl;
1595
1596
1597 phal = GET_HAL_DATA(padapter);
1598 dvobj = adapter_to_dvobj(padapter);
1599 pwrctl = dvobj_to_pwrctl(dvobj);
1600
1601 #ifdef CONFIG_SDIO_TX_ENABLE_AVAL_INT
1602 if (phal->sdio_hisr & SDIO_HISR_AVAL) {
1603 /* _irqL irql; */
1604 u8 freepage[4];
1605
1606 _sdio_local_read(padapter, SDIO_REG_FREE_TXPG, 4, freepage);
1607 #ifdef DBG_TX_FREE_PAGE
1608 RTW_INFO("SDIO_HISR_AVAL, Tx Free Page = H:%u, M:%u, L:%u, P:%u\n",
1609 freepage[0], freepage[1], freepage[2], freepage[3]);
1610 #endif
1611
1612 _rtw_up_sema(&(padapter->xmitpriv.xmit_sema));
1613 }
1614 #endif
1615 if (phal->sdio_hisr & SDIO_HISR_CPWM1) {
1616 struct reportpwrstate_parm report;
1617
1618 #ifdef CONFIG_LPS_RPWM_TIMER
1619 _cancel_timer_ex(&(pwrctl->pwr_rpwm_timer));
1620 #endif /* CONFIG_LPS_RPWM_TIMER */
1621
1622 report.state = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_HCPWM1_8723D);
1623
1624 #ifdef CONFIG_LPS_LCLK
1625 /* cpwm_int_hdl(padapter, &report); */
1626 _set_workitem(&(pwrctl->cpwm_event));
1627 #endif
1628 }
1629
1630 if (phal->sdio_hisr & SDIO_HISR_TXERR) {
1631 u8 *status;
1632 u32 addr;
1633
1634 status = rtw_malloc(4);
1635 if (status) {
1636 addr = REG_TXDMA_STATUS;
1637 HalSdioGetCmdAddr8723DSdio(padapter, WLAN_IOREG_DEVICE_ID, addr, &addr);
1638 _sd_read(pintfhdl, addr, 4, status);
1639 _sd_write(pintfhdl, addr, 4, status);
1640 RTW_INFO("%s: SDIO_HISR_TXERR (0x%08x)\n", __func__, le32_to_cpu(*(u32 *)status));
1641 rtw_mfree(status, 4);
1642 } else
1643 RTW_INFO("%s: SDIO_HISR_TXERR, but can't allocate memory to read status!\n", __func__);
1644 }
1645
1646 if (phal->sdio_hisr & SDIO_HISR_TXBCNOK)
1647 RTW_INFO("%s: SDIO_HISR_TXBCNOK\n", __func__);
1648
1649 if (phal->sdio_hisr & SDIO_HISR_TXBCNERR)
1650 RTW_INFO("%s: SDIO_HISR_TXBCNERR\n", __func__);
1651
1652 #ifdef CONFIG_FW_C2H_REG
1653 if (phal->sdio_hisr & SDIO_HISR_C2HCMD) {
1654 RTW_INFO("%s: C2H Command\n", __func__);
1655 sd_c2h_hisr_hdl(padapter);
1656 }
1657 #endif
1658
1659 if (phal->sdio_hisr & SDIO_HISR_RXFOVW)
1660 RTW_INFO("%s: Rx Overflow\n", __func__);
1661 if (phal->sdio_hisr & SDIO_HISR_RXERR)
1662 RTW_INFO("%s: Rx Error\n", __func__);
1663
1664 if (phal->sdio_hisr & SDIO_HISR_RX_REQUEST) {
1665 phal->sdio_hisr ^= SDIO_HISR_RX_REQUEST;
1666 sd_recv(padapter);
1667 }
1668 }
1669 #ifndef DBG_SD_INT_HISR_HIMR
1670 #define DBG_SD_INT_HISR_HIMR 0
1671 #endif
sd_int_hdl(PADAPTER padapter)1672 void sd_int_hdl(PADAPTER padapter)
1673 {
1674 PHAL_DATA_TYPE phal;
1675 #if !CMD52_ACCESS_HISR_RX_REQ_LEN
1676 u8 data[6];
1677 #endif
1678
1679 if (RTW_CANNOT_RUN(padapter))
1680 return;
1681
1682 phal = GET_HAL_DATA(padapter);
1683
1684 #if SD_INT_HDL_DIS_HIMR_RX_REQ
1685 disable_himr_rx_req_8723d_sdio(padapter);
1686 #endif
1687
1688 #if CMD52_ACCESS_HISR_RX_REQ_LEN
1689 phal->sdio_hisr = 0;
1690 ReadInterrupt8723DSdio(padapter, &phal->sdio_hisr);
1691 #else
1692 _sdio_local_read(padapter, SDIO_REG_HISR, 6, data);
1693 phal->sdio_hisr = le32_to_cpu(*(u32 *)data);
1694 phal->SdioRxFIFOSize = le16_to_cpu(*(u16 *)&data[4]);
1695 #endif
1696
1697 if (phal->sdio_hisr & phal->sdio_himr) {
1698 u32 v32;
1699 #if DBG_SD_INT_HISR_HIMR
1700 static u32 match_cnt = 0;
1701
1702 if ((match_cnt++) % 1000 == 0)
1703 RTW_INFO("%s: HISR(0x%08x) and HIMR(0x%08x) match!\n"
1704 , __func__, phal->sdio_hisr, phal->sdio_himr);
1705 #endif
1706
1707 phal->sdio_hisr &= phal->sdio_himr;
1708
1709 /* clear HISR */
1710 v32 = phal->sdio_hisr & MASK_SDIO_HISR_CLEAR;
1711 if (v32) {
1712 #if CMD52_ACCESS_HISR_RX_REQ_LEN
1713 SdioLocalCmd52Write4Byte(padapter, SDIO_REG_HISR, v32);
1714 #else
1715 v32 = cpu_to_le32(v32);
1716 _sdio_local_write(padapter, SDIO_REG_HISR, 4, (u8 *)&v32);
1717 #endif
1718 }
1719
1720 sd_int_dpc(padapter);
1721 }
1722 #if DBG_SD_INT_HISR_HIMR
1723 else
1724 RTW_INFO("%s: HISR(0x%08x) and HIMR(0x%08x) not match!\n"
1725 , __func__, phal->sdio_hisr, phal->sdio_himr);
1726 #endif
1727
1728 #if SD_INT_HDL_DIS_HIMR_RX_REQ
1729 restore_himr_8723d_sdio(padapter);
1730 #endif
1731 }
1732
1733 /*
1734 * Description:
1735 * Query SDIO Local register to query current the number of Free TxPacketBuffer page.
1736 *
1737 * Assumption:
1738 * 1. Running at PASSIVE_LEVEL
1739 * 2. RT_TX_SPINLOCK is NOT acquired.
1740 *
1741 * Created by Roger, 2011.01.28.
1742 * */
HalQueryTxBufferStatus8723DSdio(PADAPTER padapter)1743 u8 HalQueryTxBufferStatus8723DSdio(PADAPTER padapter)
1744 {
1745 PHAL_DATA_TYPE phal;
1746 u32 NumOfFreePage;
1747 /* _irqL irql; */
1748
1749
1750 phal = GET_HAL_DATA(padapter);
1751
1752 NumOfFreePage = SdioLocalCmd53Read4Byte(padapter, SDIO_REG_FREE_TXPG);
1753
1754 /* _enter_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); */
1755 _rtw_memcpy(phal->SdioTxFIFOFreePage, &NumOfFreePage, 4);
1756 /* _exit_critical_bh(&phal->SdioTxFIFOFreePageLock, &irql); */
1757
1758 return _TRUE;
1759 }
1760
1761 /*
1762 * Description:
1763 * Query SDIO Local register to get the current number of TX OQT Free Space.
1764 * */
HalQueryTxOQTBufferStatus8723DSdio(PADAPTER padapter)1765 u8 HalQueryTxOQTBufferStatus8723DSdio(PADAPTER padapter)
1766 {
1767 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1768
1769 pHalData->SdioTxOQTFreeSpace = SdioLocalCmd52Read1Byte(padapter, SDIO_REG_OQT_FREE_PG);
1770 return _TRUE;
1771 }
1772
1773 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
RecvOnePkt(PADAPTER padapter)1774 u8 RecvOnePkt(PADAPTER padapter)
1775 {
1776 struct recv_buf *precvbuf;
1777 struct dvobj_priv *psddev;
1778 PSDIO_DATA psdio_data;
1779 struct sdio_func *func;
1780 u32 tmp = 0;
1781 u16 len = 0;
1782 u8 res = _FALSE;
1783
1784 if (padapter == NULL) {
1785 RTW_ERR("%s: padapter is NULL!\n", __func__);
1786 return _FALSE;
1787 }
1788
1789 psddev = adapter_to_dvobj(padapter);
1790 psdio_data = &psddev->intf_data;
1791 func = psdio_data->func;
1792
1793 /* If RX_DMA is not idle, receive one pkt from DMA */
1794 res = sdio_local_read(padapter,
1795 SDIO_REG_RX0_REQ_LEN, 4, (u8 *)&tmp);
1796 len = le16_to_cpu(tmp);
1797 RTW_INFO("+%s: size: %d+\n", __func__, len);
1798
1799 if (len) {
1800 sdio_claim_host(func);
1801 res = sd_recv_rxfifo(padapter, len, &precvbuf);
1802
1803 if (precvbuf) {
1804 /* printk("Completed Recv One Pkt.\n"); */
1805 sd_rxhandler(padapter, precvbuf);
1806 res = _TRUE;
1807 } else
1808 res = _FALSE;
1809 sdio_release_host(func);
1810 }
1811 RTW_INFO("-%s-\n", __func__);
1812 return res;
1813 }
1814 #endif /* CONFIG_WOWLAN */
1815
1816