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