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