forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmsdh.c
....@@ -1,16 +1,17 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /*
32 * BCMSDH interface glue
43 * implement bcmsdh API for SDIOH driver
54 *
6
- * Copyright (C) 1999-2019, Broadcom Corporation
7
- *
5
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
6
+ *
7
+ * Copyright (C) 1999-2017, Broadcom Corporation
8
+ *
89 * Unless you and Broadcom execute a separate written software license
910 * agreement governing use of this software, this software is licensed to you
1011 * under the terms of the GNU General Public License version 2 (the "GPL"),
1112 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1213 * following added to such license:
13
- *
14
+ *
1415 * As a special exception, the copyright holders of this software give you
1516 * permission to link this software with independent modules, and to copy and
1617 * distribute the resulting executable under terms of your choice, provided that
....@@ -18,7 +19,7 @@
1819 * the license of that module. An independent module is a module which is not
1920 * derived from this software. The special exception does not apply to any
2021 * modifications of the software.
21
- *
22
+ *
2223 * Notwithstanding the above, under no circumstances may you combine this
2324 * software in any way with any other Broadcom software provided under a license
2425 * other than the GPL, without Broadcom's express prior written consent.
....@@ -26,7 +27,7 @@
2627 *
2728 * <<Broadcom-WL-IPTag/Open:>>
2829 *
29
- * $Id: bcmsdh.c 572557 2015-07-20 07:12:29Z $
30
+ * $Id: bcmsdh.c 700323 2017-05-18 16:12:11Z $
3031 */
3132
3233 /**
....@@ -48,12 +49,22 @@
4849 #include <sbsdio.h> /* SDIO device core hardware definitions. */
4950 #include <sdio.h> /* SDIO Device and Protocol Specs */
5051
52
+#if defined(BT_OVER_SDIO)
53
+#include <dhd_bt_interface.h>
54
+#endif /* defined (BT_OVER_SDIO) */
55
+
5156 #define SDIOH_API_ACCESS_RETRY_LIMIT 2
5257 const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
5358
5459 /* local copy of bcm sd handler */
5560 bcmsdh_info_t * l_bcmsdh = NULL;
5661
62
+#if defined(BT_OVER_SDIO)
63
+struct sdio_func *func_f3 = NULL;
64
+static f3intr_handler processf3intr = NULL;
65
+static dhd_hang_notification process_dhd_hang_notification = NULL;
66
+static dhd_hang_state_t g_dhd_hang_state = NO_HANG_STATE;
67
+#endif /* defined (BT_OVER_SDIO) */
5768
5869 #if defined(OOB_INTR_ONLY) && defined(HW_OOB)
5970 extern int
....@@ -64,7 +75,87 @@
6475 {
6576 sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
6677 }
67
-#endif
78
+#endif // endif
79
+
80
+#if defined(BT_OVER_SDIO)
81
+void bcmsdh_btsdio_process_hang_state(dhd_hang_state_t new_state)
82
+{
83
+ bool state_change = false;
84
+
85
+ BCMSDH_ERROR(("%s: DHD hang state changed - [%d] -> [%d]\n",
86
+ __FUNCTION__, g_dhd_hang_state, new_state));
87
+
88
+ if (g_dhd_hang_state == new_state)
89
+ return;
90
+
91
+ switch (g_dhd_hang_state) {
92
+ case NO_HANG_STATE:
93
+ if (HANG_START_STATE == new_state)
94
+ state_change = true;
95
+ break;
96
+
97
+ case HANG_START_STATE:
98
+ if (HANG_RECOVERY_STATE == new_state ||
99
+ NO_HANG_STATE == new_state)
100
+ state_change = true;
101
+
102
+ break;
103
+
104
+ case HANG_RECOVERY_STATE:
105
+ if (NO_HANG_STATE == new_state)
106
+ state_change = true;
107
+ break;
108
+
109
+ default:
110
+ BCMSDH_ERROR(("%s: Unhandled Hang state\n", __FUNCTION__));
111
+ break;
112
+ }
113
+
114
+ if (!state_change) {
115
+ BCMSDH_ERROR(("%s: Hang state cannot be changed\n", __FUNCTION__));
116
+ return;
117
+ }
118
+
119
+ g_dhd_hang_state = new_state;
120
+}
121
+
122
+void bcmsdh_btsdio_process_f3_intr(void)
123
+{
124
+ if (processf3intr && (g_dhd_hang_state == NO_HANG_STATE))
125
+ processf3intr(func_f3);
126
+}
127
+
128
+void bcmsdh_btsdio_process_dhd_hang_notification(bool wifi_recovery_completed)
129
+{
130
+ bcmsdh_btsdio_process_hang_state(HANG_START_STATE);
131
+
132
+ if (process_dhd_hang_notification)
133
+ process_dhd_hang_notification(func_f3, wifi_recovery_completed);
134
+
135
+ /* WiFi was off, so HANG_RECOVERY_STATE is not needed */
136
+ if (wifi_recovery_completed)
137
+ bcmsdh_btsdio_process_hang_state(NO_HANG_STATE);
138
+ else {
139
+ bcmsdh_btsdio_process_hang_state(HANG_RECOVERY_STATE);
140
+ }
141
+}
142
+
143
+void bcmsdh_btsdio_interface_init(struct sdio_func *func,
144
+ f3intr_handler f3intr_fun, dhd_hang_notification hang_notification)
145
+{
146
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)l_bcmsdh;
147
+ BCMSDH_INFO(("%s: func %p \n", __FUNCTION__, func));
148
+ func_f3 = func;
149
+ processf3intr = f3intr_fun;
150
+#if defined(BCMLXSDMMC)
151
+ sdioh_sdmmc_card_enable_func_f3(bcmsdh->sdioh, func);
152
+#else
153
+ BCMSDH_ERROR(("bcmsdh_btsdio_interface_init: not support f3 enable on non-sdmmc build\n"));
154
+#endif /* defined(BCMLXSDMMC) */
155
+ process_dhd_hang_notification = hang_notification;
156
+
157
+} EXPORT_SYMBOL(bcmsdh_btsdio_interface_init);
158
+#endif /* defined (BT_OVER_SDIO) */
68159
69160 /* Attach BCMSDH layer to SDIO Host Controller Driver
70161 *
....@@ -88,12 +179,12 @@
88179 bcmsdh->sdioh = sdioh;
89180 bcmsdh->osh = osh;
90181 bcmsdh->init_success = TRUE;
91
- *regsva = SI_ENUM_BASE;
182
+ *regsva = si_enum_base(0);
92183
93184 bcmsdh_force_sbwad_calc(bcmsdh, FALSE);
94185
95186 /* Report the BAR, to fix if needed */
96
- bcmsdh->sbwad = SI_ENUM_BASE;
187
+ bcmsdh->sbwad = si_enum_base(0);
97188
98189 /* save the handler locally */
99190 l_bcmsdh = bcmsdh;
....@@ -117,7 +208,7 @@
117208
118209 int
119210 bcmsdh_iovar_op(void *sdh, const char *name,
120
- void *params, int plen, void *arg, int len, bool set)
211
+ void *params, uint plen, void *arg, uint len, bool set)
121212 {
122213 bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
123214 return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
....@@ -143,9 +234,17 @@
143234 {
144235 bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
145236 SDIOH_API_RC status;
237
+#ifdef BCMSPI_ANDROID
238
+ uint32 data;
239
+#endif /* BCMSPI_ANDROID */
146240 ASSERT(bcmsdh);
147241
148242 status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE);
243
+#ifdef BCMSPI_ANDROID
244
+ data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
245
+ data |= 0xE0E70000;
246
+ bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
247
+#endif /* BCMSPI_ANDROID */
149248 return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
150249 }
151250
....@@ -154,9 +253,17 @@
154253 {
155254 bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
156255 SDIOH_API_RC status;
256
+#ifdef BCMSPI_ANDROID
257
+ uint32 data;
258
+#endif /* BCMSPI_ANDROID */
157259 ASSERT(bcmsdh);
158260
159261 status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE);
262
+#ifdef BCMSPI_ANDROID
263
+ data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
264
+ data &= ~0xE0E70000;
265
+ bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
266
+#endif /* BCMSPI_ANDROID */
160267 return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
161268 }
162269
....@@ -165,6 +272,10 @@
165272 {
166273 bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
167274 SDIOH_API_RC status;
275
+
276
+ if (!bcmsdh)
277
+ bcmsdh = l_bcmsdh;
278
+
168279 ASSERT(bcmsdh);
169280
170281 status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
....@@ -176,6 +287,10 @@
176287 {
177288 bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
178289 SDIOH_API_RC status;
290
+
291
+ if (!bcmsdh)
292
+ bcmsdh = l_bcmsdh;
293
+
179294 ASSERT(bcmsdh);
180295
181296 status = sdioh_interrupt_deregister(bcmsdh->sdioh);
....@@ -191,8 +306,7 @@
191306 ASSERT(sdh);
192307 return sdioh_interrupt_pending(bcmsdh->sdioh);
193308 }
194
-#endif
195
-
309
+#endif // endif
196310
197311 int
198312 bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
....@@ -218,7 +332,7 @@
218332 SDIOH_API_RC status;
219333 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
220334 int32 retry = 0;
221
-#endif
335
+#endif // endif
222336 uint8 data = 0;
223337
224338 if (!bcmsdh)
....@@ -230,11 +344,11 @@
230344 do {
231345 if (retry) /* wait for 1 ms till bus get settled down */
232346 OSL_DELAY(1000);
233
-#endif
347
+#endif // endif
234348 status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
235349 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
236350 } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
237
-#endif
351
+#endif // endif
238352 if (err)
239353 *err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
240354
....@@ -242,7 +356,7 @@
242356 fnc_num, addr, data));
243357
244358 return data;
245
-}
359
+} EXPORT_SYMBOL(bcmsdh_cfg_read);
246360
247361 void
248362 bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err)
....@@ -251,7 +365,7 @@
251365 SDIOH_API_RC status;
252366 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
253367 int32 retry = 0;
254
-#endif
368
+#endif // endif
255369
256370 if (!bcmsdh)
257371 bcmsdh = l_bcmsdh;
....@@ -262,17 +376,17 @@
262376 do {
263377 if (retry) /* wait for 1 ms till bus get settled down */
264378 OSL_DELAY(1000);
265
-#endif
379
+#endif // endif
266380 status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
267381 #ifdef SDIOH_API_ACCESS_RETRY_LIMIT
268382 } while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
269
-#endif
383
+#endif // endif
270384 if (err)
271385 *err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
272386
273387 BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
274388 fnc_num, addr, data));
275
-}
389
+} EXPORT_SYMBOL(bcmsdh_cfg_write);
276390
277391 uint32
278392 bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err)
....@@ -319,7 +433,6 @@
319433 addr, data));
320434 }
321435
322
-
323436 int
324437 bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length)
325438 {
....@@ -359,7 +472,6 @@
359472 return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
360473 }
361474
362
-
363475 int
364476 bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set)
365477 {
....@@ -389,13 +501,14 @@
389501 }
390502
391503 uint32
392
-bcmsdh_reg_read(void *sdh, uint32 addr, uint size)
504
+bcmsdh_reg_read(void *sdh, uintptr addr, uint size)
393505 {
394506 bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
395507 SDIOH_API_RC status;
396508 uint32 word = 0;
397509
398
- BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr));
510
+ BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ",
511
+ __FUNCTION__, (unsigned int)addr));
399512
400513 if (!bcmsdh)
401514 bcmsdh = l_bcmsdh;
....@@ -432,19 +545,20 @@
432545 }
433546
434547 /* otherwise, bad sdio access or invalid size */
435
- BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __FUNCTION__, addr, size));
548
+ BCMSDH_ERROR(("%s: error reading addr 0x%x size %d\n",
549
+ __FUNCTION__, (unsigned int)addr, size));
436550 return 0xFFFFFFFF;
437551 }
438552
439553 uint32
440
-bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data)
554
+bcmsdh_reg_write(void *sdh, uintptr addr, uint size, uint32 data)
441555 {
442556 bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
443557 SDIOH_API_RC status;
444558 int err = 0;
445559
446560 BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
447
- __FUNCTION__, addr, size*8, data));
561
+ __FUNCTION__, (unsigned int)addr, size*8, data));
448562
449563 if (!bcmsdh)
450564 bcmsdh = l_bcmsdh;
....@@ -465,7 +579,7 @@
465579 return 0;
466580
467581 BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
468
- __FUNCTION__, data, addr, size));
582
+ __FUNCTION__, data, (unsigned int)addr, size));
469583 return 0xFFFFFFFF;
470584 }
471585
....@@ -504,7 +618,7 @@
504618
505619 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
506620 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
507
- if (width == 4)
621
+ if (fn != SDIO_FUNC_3 && width == 4)
508622 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
509623
510624 status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
....@@ -542,7 +656,7 @@
542656
543657 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
544658 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
545
- if (width == 4)
659
+ if (fn != SDIO_FUNC_3 && width == 4)
546660 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
547661
548662 status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
....@@ -603,7 +717,6 @@
603717 return sdioh_waitlockfree(bcmsdh->sdioh);
604718 }
605719
606
-
607720 int
608721 bcmsdh_query_device(void *sdh)
609722 {
....@@ -641,7 +754,13 @@
641754 uint32
642755 bcmsdh_get_dstatus(void *sdh)
643756 {
757
+#ifdef BCMSPI
758
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
759
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
760
+ return sdioh_get_dstatus(sd);
761
+#else
644762 return 0;
763
+#endif /* BCMSPI */
645764 }
646765 uint32
647766 bcmsdh_cur_sbwad(void *sdh)
....@@ -670,9 +789,25 @@
670789 void
671790 bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev)
672791 {
792
+#ifdef BCMSPI
793
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
794
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
795
+ sdioh_chipinfo(sd, chip, chiprev);
796
+#else
673797 return;
798
+#endif /* BCMSPI */
674799 }
675800
801
+#ifdef BCMSPI
802
+void
803
+bcmsdh_dwordmode(void *sdh, bool set)
804
+{
805
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
806
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
807
+ sdioh_dwordmode(sd, set);
808
+ return;
809
+}
810
+#endif /* BCMSPI */
676811
677812 int
678813 bcmsdh_sleep(void *sdh, bool enab)
....@@ -684,7 +819,7 @@
684819 return sdioh_sleep(sd, enab);
685820 #else
686821 return BCME_UNSUPPORTED;
687
-#endif
822
+#endif // endif
688823 }
689824
690825 int