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