From cde9070d9970eef1f7ec2360586c802a16230ad8 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Fri, 10 May 2024 07:43:50 +0000
Subject: [PATCH] rtl88x2CE_WiFi_linux driver

---
 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