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