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