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