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