From 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Tue, 22 Oct 2024 10:36:11 +0000
Subject: [PATCH] 修改4g拨号为QMI,需要在系统里后台执行quectel-CM
---
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmsdh.c | 199 +++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 167 insertions(+), 32 deletions(-)
diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmsdh.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmsdh.c
index 1ebf527..2fbbcf5 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmsdh.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmsdh.c
@@ -1,16 +1,17 @@
-/* SPDX-License-Identifier: GPL-2.0 */
/*
* BCMSDH interface glue
* implement bcmsdh API for SDIOH driver
*
- * Copyright (C) 1999-2019, Broadcom Corporation
- *
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
+ *
+ * Copyright (C) 1999-2017, Broadcom Corporation
+ *
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -18,7 +19,7 @@
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
- *
+ *
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
@@ -26,7 +27,7 @@
*
* <<Broadcom-WL-IPTag/Open:>>
*
- * $Id: bcmsdh.c 572557 2015-07-20 07:12:29Z $
+ * $Id: bcmsdh.c 700323 2017-05-18 16:12:11Z $
*/
/**
@@ -48,12 +49,22 @@
#include <sbsdio.h> /* SDIO device core hardware definitions. */
#include <sdio.h> /* SDIO Device and Protocol Specs */
+#if defined(BT_OVER_SDIO)
+#include <dhd_bt_interface.h>
+#endif /* defined (BT_OVER_SDIO) */
+
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
/* local copy of bcm sd handler */
bcmsdh_info_t * l_bcmsdh = NULL;
+#if defined(BT_OVER_SDIO)
+struct sdio_func *func_f3 = NULL;
+static f3intr_handler processf3intr = NULL;
+static dhd_hang_notification process_dhd_hang_notification = NULL;
+static dhd_hang_state_t g_dhd_hang_state = NO_HANG_STATE;
+#endif /* defined (BT_OVER_SDIO) */
#if defined(OOB_INTR_ONLY) && defined(HW_OOB)
extern int
@@ -64,7 +75,87 @@
{
sdioh_enable_hw_oob_intr(sdh->sdioh, enable);
}
-#endif
+#endif // endif
+
+#if defined(BT_OVER_SDIO)
+void bcmsdh_btsdio_process_hang_state(dhd_hang_state_t new_state)
+{
+ bool state_change = false;
+
+ BCMSDH_ERROR(("%s: DHD hang state changed - [%d] -> [%d]\n",
+ __FUNCTION__, g_dhd_hang_state, new_state));
+
+ if (g_dhd_hang_state == new_state)
+ return;
+
+ switch (g_dhd_hang_state) {
+ case NO_HANG_STATE:
+ if (HANG_START_STATE == new_state)
+ state_change = true;
+ break;
+
+ case HANG_START_STATE:
+ if (HANG_RECOVERY_STATE == new_state ||
+ NO_HANG_STATE == new_state)
+ state_change = true;
+
+ break;
+
+ case HANG_RECOVERY_STATE:
+ if (NO_HANG_STATE == new_state)
+ state_change = true;
+ break;
+
+ default:
+ BCMSDH_ERROR(("%s: Unhandled Hang state\n", __FUNCTION__));
+ break;
+ }
+
+ if (!state_change) {
+ BCMSDH_ERROR(("%s: Hang state cannot be changed\n", __FUNCTION__));
+ return;
+ }
+
+ g_dhd_hang_state = new_state;
+}
+
+void bcmsdh_btsdio_process_f3_intr(void)
+{
+ if (processf3intr && (g_dhd_hang_state == NO_HANG_STATE))
+ processf3intr(func_f3);
+}
+
+void bcmsdh_btsdio_process_dhd_hang_notification(bool wifi_recovery_completed)
+{
+ bcmsdh_btsdio_process_hang_state(HANG_START_STATE);
+
+ if (process_dhd_hang_notification)
+ process_dhd_hang_notification(func_f3, wifi_recovery_completed);
+
+ /* WiFi was off, so HANG_RECOVERY_STATE is not needed */
+ if (wifi_recovery_completed)
+ bcmsdh_btsdio_process_hang_state(NO_HANG_STATE);
+ else {
+ bcmsdh_btsdio_process_hang_state(HANG_RECOVERY_STATE);
+ }
+}
+
+void bcmsdh_btsdio_interface_init(struct sdio_func *func,
+ f3intr_handler f3intr_fun, dhd_hang_notification hang_notification)
+{
+ bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)l_bcmsdh;
+ BCMSDH_INFO(("%s: func %p \n", __FUNCTION__, func));
+ func_f3 = func;
+ processf3intr = f3intr_fun;
+#if defined(BCMLXSDMMC)
+ sdioh_sdmmc_card_enable_func_f3(bcmsdh->sdioh, func);
+#else
+ BCMSDH_ERROR(("bcmsdh_btsdio_interface_init: not support f3 enable on non-sdmmc build\n"));
+#endif /* defined(BCMLXSDMMC) */
+ process_dhd_hang_notification = hang_notification;
+
+} EXPORT_SYMBOL(bcmsdh_btsdio_interface_init);
+#endif /* defined (BT_OVER_SDIO) */
/* Attach BCMSDH layer to SDIO Host Controller Driver
*
@@ -88,12 +179,12 @@
bcmsdh->sdioh = sdioh;
bcmsdh->osh = osh;
bcmsdh->init_success = TRUE;
- *regsva = SI_ENUM_BASE;
+ *regsva = si_enum_base(0);
bcmsdh_force_sbwad_calc(bcmsdh, FALSE);
/* Report the BAR, to fix if needed */
- bcmsdh->sbwad = SI_ENUM_BASE;
+ bcmsdh->sbwad = si_enum_base(0);
/* save the handler locally */
l_bcmsdh = bcmsdh;
@@ -117,7 +208,7 @@
int
bcmsdh_iovar_op(void *sdh, const char *name,
- void *params, int plen, void *arg, int len, bool set)
+ void *params, uint plen, void *arg, uint len, bool set)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
return sdioh_iovar_op(bcmsdh->sdioh, name, params, plen, arg, len, set);
@@ -143,9 +234,17 @@
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
SDIOH_API_RC status;
+#ifdef BCMSPI_ANDROID
+ uint32 data;
+#endif /* BCMSPI_ANDROID */
ASSERT(bcmsdh);
status = sdioh_interrupt_set(bcmsdh->sdioh, TRUE);
+#ifdef BCMSPI_ANDROID
+ data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
+ data |= 0xE0E70000;
+ bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
+#endif /* BCMSPI_ANDROID */
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
}
@@ -154,9 +253,17 @@
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
SDIOH_API_RC status;
+#ifdef BCMSPI_ANDROID
+ uint32 data;
+#endif /* BCMSPI_ANDROID */
ASSERT(bcmsdh);
status = sdioh_interrupt_set(bcmsdh->sdioh, FALSE);
+#ifdef BCMSPI_ANDROID
+ data = bcmsdh_cfg_read_word(sdh, 0, 4, NULL);
+ data &= ~0xE0E70000;
+ bcmsdh_cfg_write_word(sdh, 0, 4, data, NULL);
+#endif /* BCMSPI_ANDROID */
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
}
@@ -165,6 +272,10 @@
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
SDIOH_API_RC status;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
ASSERT(bcmsdh);
status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
@@ -176,6 +287,10 @@
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
SDIOH_API_RC status;
+
+ if (!bcmsdh)
+ bcmsdh = l_bcmsdh;
+
ASSERT(bcmsdh);
status = sdioh_interrupt_deregister(bcmsdh->sdioh);
@@ -191,8 +306,7 @@
ASSERT(sdh);
return sdioh_interrupt_pending(bcmsdh->sdioh);
}
-#endif
-
+#endif // endif
int
bcmsdh_devremove_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
@@ -218,7 +332,7 @@
SDIOH_API_RC status;
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
int32 retry = 0;
-#endif
+#endif // endif
uint8 data = 0;
if (!bcmsdh)
@@ -230,11 +344,11 @@
do {
if (retry) /* wait for 1 ms till bus get settled down */
OSL_DELAY(1000);
-#endif
+#endif // endif
status = sdioh_cfg_read(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
} while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
-#endif
+#endif // endif
if (err)
*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
@@ -242,7 +356,7 @@
fnc_num, addr, data));
return data;
-}
+} EXPORT_SYMBOL(bcmsdh_cfg_read);
void
bcmsdh_cfg_write(void *sdh, uint fnc_num, uint32 addr, uint8 data, int *err)
@@ -251,7 +365,7 @@
SDIOH_API_RC status;
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
int32 retry = 0;
-#endif
+#endif // endif
if (!bcmsdh)
bcmsdh = l_bcmsdh;
@@ -262,17 +376,17 @@
do {
if (retry) /* wait for 1 ms till bus get settled down */
OSL_DELAY(1000);
-#endif
+#endif // endif
status = sdioh_cfg_write(bcmsdh->sdioh, fnc_num, addr, (uint8 *)&data);
#ifdef SDIOH_API_ACCESS_RETRY_LIMIT
} while (!SDIOH_API_SUCCESS(status) && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
-#endif
+#endif // endif
if (err)
*err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, uint8data = 0x%x\n", __FUNCTION__,
fnc_num, addr, data));
-}
+} EXPORT_SYMBOL(bcmsdh_cfg_write);
uint32
bcmsdh_cfg_read_word(void *sdh, uint fnc_num, uint32 addr, int *err)
@@ -319,7 +433,6 @@
addr, data));
}
-
int
bcmsdh_cis_read(void *sdh, uint func, uint8 *cis, uint length)
{
@@ -359,7 +472,6 @@
return (SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR);
}
-
int
bcmsdhsdio_set_sbaddr_window(void *sdh, uint32 address, bool force_set)
{
@@ -389,13 +501,14 @@
}
uint32
-bcmsdh_reg_read(void *sdh, uint32 addr, uint size)
+bcmsdh_reg_read(void *sdh, uintptr addr, uint size)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
SDIOH_API_RC status;
uint32 word = 0;
- BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ", __FUNCTION__, addr));
+ BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, ",
+ __FUNCTION__, (unsigned int)addr));
if (!bcmsdh)
bcmsdh = l_bcmsdh;
@@ -432,19 +545,20 @@
}
/* otherwise, bad sdio access or invalid size */
- BCMSDH_ERROR(("%s: error reading addr 0x%04x size %d\n", __FUNCTION__, addr, size));
+ BCMSDH_ERROR(("%s: error reading addr 0x%x size %d\n",
+ __FUNCTION__, (unsigned int)addr, size));
return 0xFFFFFFFF;
}
uint32
-bcmsdh_reg_write(void *sdh, uint32 addr, uint size, uint32 data)
+bcmsdh_reg_write(void *sdh, uintptr addr, uint size, uint32 data)
{
bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *)sdh;
SDIOH_API_RC status;
int err = 0;
BCMSDH_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n",
- __FUNCTION__, addr, size*8, data));
+ __FUNCTION__, (unsigned int)addr, size*8, data));
if (!bcmsdh)
bcmsdh = l_bcmsdh;
@@ -465,7 +579,7 @@
return 0;
BCMSDH_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n",
- __FUNCTION__, data, addr, size));
+ __FUNCTION__, data, (unsigned int)addr, size));
return 0xFFFFFFFF;
}
@@ -504,7 +618,7 @@
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- if (width == 4)
+ if (fn != SDIO_FUNC_3 && width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
@@ -542,7 +656,7 @@
incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- if (width == 4)
+ if (fn != SDIO_FUNC_3 && width == 4)
addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
status = sdioh_request_buffer(bcmsdh->sdioh, SDIOH_DATA_PIO, incr_fix,
@@ -603,7 +717,6 @@
return sdioh_waitlockfree(bcmsdh->sdioh);
}
-
int
bcmsdh_query_device(void *sdh)
{
@@ -641,7 +754,13 @@
uint32
bcmsdh_get_dstatus(void *sdh)
{
+#ifdef BCMSPI
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+ return sdioh_get_dstatus(sd);
+#else
return 0;
+#endif /* BCMSPI */
}
uint32
bcmsdh_cur_sbwad(void *sdh)
@@ -670,9 +789,25 @@
void
bcmsdh_chipinfo(void *sdh, uint32 chip, uint32 chiprev)
{
+#ifdef BCMSPI
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+ sdioh_chipinfo(sd, chip, chiprev);
+#else
return;
+#endif /* BCMSPI */
}
+#ifdef BCMSPI
+void
+bcmsdh_dwordmode(void *sdh, bool set)
+{
+ bcmsdh_info_t *p = (bcmsdh_info_t *)sdh;
+ sdioh_info_t *sd = (sdioh_info_t *)(p->sdioh);
+ sdioh_dwordmode(sd, set);
+ return;
+}
+#endif /* BCMSPI */
int
bcmsdh_sleep(void *sdh, bool enab)
@@ -684,7 +819,7 @@
return sdioh_sleep(sd, enab);
#else
return BCME_UNSUPPORTED;
-#endif
+#endif // endif
}
int
--
Gitblit v1.6.2