GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / staging / rtl8723bs / hal / sdio_ops.c
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 /*  */
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
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
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
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
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
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
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
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
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
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
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
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
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  */
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  */
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
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  */
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  */
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  */
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
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
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
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
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
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
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 /*  */
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 /*  */
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 /*  */
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 /*  */
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 /*  */
780 u8 CheckIPSStatus(struct adapter *adapter)
781 {
782         if (rtw_read8(adapter, 0x100) == 0xEA)
783                 return true;
784         else
785                 return false;
786 }
787
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
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
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
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 /*  */
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 /*  */
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