xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8189es/hal/rtl8188e/sdio/sdio_ops.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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