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