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/bcmspibrcm.c |  189 +++++++++++++++++++++--------------------------
 1 files changed, 84 insertions(+), 105 deletions(-)

diff --git a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmspibrcm.c b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmspibrcm.c
index afe6780..c7ba27b 100644
--- a/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmspibrcm.c
+++ b/kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/bcmspibrcm.c
@@ -1,15 +1,16 @@
-/* SPDX-License-Identifier: GPL-2.0 */
 /*
  * Broadcom BCMSDH to gSPI Protocol Conversion Layer
  *
- * 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
@@ -17,7 +18,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.
@@ -25,7 +26,7 @@
  *
  * <<Broadcom-WL-IPTag/Open:>>
  *
- * $Id: bcmspibrcm.c 514727 2014-11-12 03:02:48Z $
+ * $Id: bcmspibrcm.c 700323 2017-05-18 16:12:11Z $
  */
 
 #define HSMODE
@@ -48,15 +49,17 @@
 
 #include <pcicfg.h>
 
-
 #include <bcmspibrcm.h>
+#ifdef BCMSPI_ANDROID
+extern void spi_sendrecv(sdioh_info_t *sd, uint8 *msg_out, uint8 *msg_in, int msglen);
+#else
 #include <bcmspi.h>
+#endif /* BCMSPI_ANDROID */
 
 /* these are for the older cores... for newer cores we have control for each of them */
 #define F0_RESPONSE_DELAY	16
 #define F1_RESPONSE_DELAY	16
 #define F2_RESPONSE_DELAY	F0_RESPONSE_DELAY
-
 
 #define GSPI_F0_RESP_DELAY		0
 #define GSPI_F1_RESP_DELAY		F1_RESPONSE_DELAY
@@ -65,21 +68,19 @@
 
 #define CMDLEN		4
 
-#define DWORDMODE_ON (sd->chip == BCM4329_CHIP_ID) && (sd->chiprev == 2) && (sd->dwordmode == TRUE)
-
 /* Globals */
 #if defined(DHD_DEBUG)
 uint sd_msglevel = SDH_ERROR_VAL;
 #else
 uint sd_msglevel = 0;
-#endif 
+#endif // endif
 
 uint sd_hiok = FALSE;		/* Use hi-speed mode if available? */
 uint sd_sdmode = SDIOH_MODE_SPI;		/* Use SD4 mode by default */
+uint sd_f1_blocksize = 64;		/* Default blocksize */
 uint sd_f2_blocksize = 64;		/* Default blocksize */
 
-
-uint sd_divisor = 2;
+uint sd_divisor = 1;
 uint sd_power = 1;		/* Default to SD Slot powered ON */
 uint sd_clock = 1;		/* Default to SD Clock turned ON */
 uint sd_crc = 0;		/* Default to SPI CRC Check turned OFF */
@@ -94,10 +95,18 @@
 #define BUF2_PKT_LEN	128
 uint8	spi_outbuf2[BUF2_PKT_LEN];
 uint8	spi_inbuf2[BUF2_PKT_LEN];
+#ifdef BCMSPI_ANDROID
+uint *dhd_spi_lockcount = NULL;
+#endif /* BCMSPI_ANDROID */
 
+#if !(defined(SPI_PIO_RW_BIGENDIAN) && defined(SPI_PIO_32BIT_RW))
 #define SPISWAP_WD4(x) bcmswap32(x);
 #define SPISWAP_WD2(x) (bcmswap16(x & 0xffff)) | \
 						(bcmswap16((x & 0xffff0000) >> 16) << 16);
+#else
+#define SPISWAP_WD4(x) x;
+#define SPISWAP_WD2(x) bcmswap32by16(x);
+#endif // endif
 
 /* Prototypes */
 static bool bcmspi_test_card(sdioh_info_t *sd);
@@ -140,11 +149,15 @@
 		return NULL;
 	}
 
+#ifndef BCMSPI_ANDROID
 	sd->bar0 = bar0;
+#endif /* !BCMSPI_ANDROID */
 	sd->irq = irq;
+#ifndef BCMSPI_ANDROID
 	sd->intr_handler = NULL;
 	sd->intr_handler_arg = NULL;
 	sd->intr_handler_valid = FALSE;
+#endif /* !BCMSPI_ANDROID */
 
 	/* Set defaults */
 	sd->use_client_ints = TRUE;
@@ -155,17 +168,24 @@
 	 */
 	sd->wordlen = 2;
 
+#ifdef BCMSPI_ANDROID
+	dhd_spi_lockcount = &sd->lockcount;
+#endif /* BCMSPI_ANDROID */
 
+#ifndef BCMSPI_ANDROID
 	if (!spi_hw_attach(sd)) {
 		sd_err(("%s: spi_hw_attach() failed\n", __FUNCTION__));
 		spi_osfree(sd);
 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 		return (NULL);
 	}
+#endif /* !BCMSPI_ANDROID */
 
 	if (bcmspi_driver_init(sd) != SUCCESS) {
 		sd_err(("%s: bcmspi_driver_init() failed()\n", __FUNCTION__));
+#ifndef BCMSPI_ANDROID
 		spi_hw_detach(sd);
+#endif /* !BCMSPI_ANDROID */
 		spi_osfree(sd);
 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 		return (NULL);
@@ -173,7 +193,9 @@
 
 	if (spi_register_irq(sd, irq) != SUCCESS) {
 		sd_err(("%s: spi_register_irq() failed for irq = %d\n", __FUNCTION__, irq));
+#ifndef BCMSPI_ANDROID
 		spi_hw_detach(sd);
+#endif /* !BCMSPI_ANDROID */
 		spi_osfree(sd);
 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 		return (NULL);
@@ -191,8 +213,13 @@
 	if (sd) {
 		sd_err(("%s: detaching from hardware\n", __FUNCTION__));
 		spi_free_irq(sd->irq, sd);
+#ifndef BCMSPI_ANDROID
 		spi_hw_detach(sd);
+#endif /* !BCMSPI_ANDROID */
 		spi_osfree(sd);
+#ifdef BCMSPI_ANDROID
+		dhd_spi_lockcount = NULL;
+#endif /* !BCMSPI_ANDROID */
 		MFREE(sd->osh, sd, sizeof(sdioh_info_t));
 	}
 	return SDIOH_API_RC_SUCCESS;
@@ -226,8 +253,10 @@
 extern SDIOH_API_RC
 sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
 {
+#ifndef BCMSPI_ANDROID
 	sd_trace(("%s: Entering\n", __FUNCTION__));
 	*onoff = sd->client_intr_enabled;
+#endif /* !BCMSPI_ANDROID */
 	return SDIOH_API_RC_SUCCESS;
 }
 
@@ -237,14 +266,7 @@
 {
 	return 0;
 }
-#endif
-
-extern SDIOH_API_RC
-sdioh_query_device(sdioh_info_t *sd)
-{
-	/* Return a BRCM ID appropriate to the dongle class */
-	return (sd->num_funcs > 1) ? BCM4329_D11N_ID : BCM4318_D11G_ID;
-}
+#endif // endif
 
 /* Provide dstatus bits of spi-transaction for dhd layers. */
 extern uint32
@@ -289,7 +311,6 @@
 	}
 }
 
-
 uint
 sdioh_query_iofnum(sdioh_info_t *sd)
 {
@@ -318,22 +339,22 @@
 };
 
 const bcm_iovar_t sdioh_iovars[] = {
-	{"sd_msglevel",	IOV_MSGLEVEL, 	0,	IOVT_UINT32,	0 },
-	{"sd_blocksize", IOV_BLOCKSIZE, 0,	IOVT_UINT32,	0 }, /* ((fn << 16) | size) */
-	{"sd_dma",	IOV_DMA,	0,	IOVT_BOOL,	0 },
-	{"sd_ints",	IOV_USEINTS,	0,	IOVT_BOOL,	0 },
-	{"sd_numints",	IOV_NUMINTS,	0,	IOVT_UINT32,	0 },
-	{"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32,	0 },
-	{"sd_hostreg",	IOV_HOSTREG,	0,	IOVT_BUFFER,	sizeof(sdreg_t) },
-	{"sd_devreg",	IOV_DEVREG,	0,	IOVT_BUFFER,	sizeof(sdreg_t)	},
-	{"sd_divisor",	IOV_DIVISOR,	0,	IOVT_UINT32,	0 },
-	{"sd_power",	IOV_POWER,	0,	IOVT_UINT32,	0 },
-	{"sd_clock",	IOV_CLOCK,	0,	IOVT_UINT32,	0 },
-	{"sd_mode",	IOV_SDMODE,	0,	IOVT_UINT32,	100},
-	{"sd_highspeed",	IOV_HISPEED,	0,	IOVT_UINT32,	0},
-	{"spi_errstats", IOV_SPIERRSTATS, 0, IOVT_BUFFER, sizeof(struct spierrstats_t) },
-	{"spi_respdelay",	IOV_RESP_DELAY_ALL,	0,	IOVT_BOOL,	0 },
-	{NULL, 0, 0, 0, 0 }
+	{"sd_msglevel",		IOV_MSGLEVEL,	0,	0,	IOVT_UINT32,	0 },
+	{"sd_blocksize",	IOV_BLOCKSIZE,	0,	0,	IOVT_UINT32,	0 },
+	{"sd_dma",		IOV_DMA,	0,	0,	IOVT_BOOL,	0 },
+	{"sd_ints",		IOV_USEINTS,	0,	0,	IOVT_BOOL,	0 },
+	{"sd_numints",		IOV_NUMINTS,	0,	0,	IOVT_UINT32,	0 },
+	{"sd_numlocalints",	IOV_NUMLOCALINTS,	0,	0,	IOVT_UINT32,	0 },
+	{"sd_hostreg",		IOV_HOSTREG,	0,	0,	IOVT_BUFFER,	sizeof(sdreg_t) },
+	{"sd_devreg",		IOV_DEVREG,	0,	0,	IOVT_BUFFER,	sizeof(sdreg_t)	},
+	{"sd_divisor",		IOV_DIVISOR,	0,	0,	IOVT_UINT32,	0 },
+	{"sd_power",		IOV_POWER,	0,	0,	IOVT_UINT32,	0 },
+	{"sd_clock",		IOV_CLOCK,	0,	0,	IOVT_UINT32,	0 },
+	{"sd_mode",		IOV_SDMODE,	0,	0,	IOVT_UINT32,	100},
+	{"sd_highspeed",	IOV_HISPEED,	0,	0,	IOVT_UINT32,	0},
+	{"spi_errstats",	IOV_SPIERRSTATS, 0, 0, IOVT_BUFFER, sizeof(struct spierrstats_t) },
+	{"spi_respdelay",	IOV_RESP_DELAY_ALL,	0,	0,	IOVT_BOOL,	0 },
+	{NULL, 0, 0, 0, 0, 0 }
 };
 
 int
@@ -344,7 +365,6 @@
 	int bcmerror = 0;
 	int val_size;
 	int32 int_val = 0;
-	bool bool_val;
 	uint32 actionid;
 /*
 	sdioh_regs_t *regs;
@@ -382,8 +402,6 @@
 
 	if (plen >= (int)sizeof(int_val))
 		bcopy(params, &int_val, sizeof(int_val));
-
-	bool_val = (int_val != 0) ? TRUE : FALSE;
 
 	actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
 	switch (actionid) {
@@ -427,6 +445,7 @@
 		bcopy(&int_val, arg, val_size);
 		break;
 
+#ifndef BCMSPI_ANDROID
 	case IOV_SVAL(IOV_DIVISOR):
 		sd_divisor = int_val;
 		if (!spi_start_clock(si, (uint16)sd_divisor)) {
@@ -434,6 +453,7 @@
 			bcmerror = BCME_ERROR;
 		}
 		break;
+#endif /* !BCMSPI_ANDROID */
 
 	case IOV_GVAL(IOV_POWER):
 		int_val = (uint32)sd_power;
@@ -513,7 +533,6 @@
 		}
 		break;
 	}
-
 
 	case IOV_GVAL(IOV_SPIERRSTATS):
 	{
@@ -598,7 +617,7 @@
 	int offset;
 	uint32 cis_byte;
 	uint16 *cis = (uint16 *)cisd;
-	uint bar0 = SI_ENUM_BASE;
+	uint bar0 = SI_ENUM_BASE_DEFAULT;
 	int status;
 	uint8 data;
 
@@ -762,7 +781,6 @@
 
 	sd_trace(("%s cmd_arg = 0x%x\n", __FUNCTION__, cmd_arg));
 
-
 	/* Set up and issue the SPI command.  MSByte goes out on bus first.  Increase datalen
 	 * according to the wordlen mode(16/32bit) the device is in.
 	 */
@@ -847,7 +865,6 @@
 bcmspi_resync_f1(sdioh_info_t *sd)
 {
 	uint32 cmd_arg = GSPI_RESYNC_PATTERN, data = 0, datalen = 0;
-
 
 	/* Set up and issue the SPI command.  MSByte goes out on bus first.  Increase datalen
 	 * according to the wordlen mode(16/32bit) the device is in.
@@ -978,7 +995,6 @@
 	return SUCCESS;
 }
 
-
 /*
  * Private/Static work routines
  */
@@ -1032,6 +1048,7 @@
 	uint32	status_en_reg = 0;
 	sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot));
 
+#ifndef BCMSPI_ANDROID
 #ifdef HSMODE
 	if (!spi_start_clock(sd, (uint16)sd_divisor)) {
 		sd_err(("spi_start_clock failed\n"));
@@ -1044,6 +1061,7 @@
 		return ERROR;
 	}
 #endif /* HSMODE */
+#endif /* !BCMSPI_ANDROID */
 
 	if (!bcmspi_host_device_init_adapt(sd)) {
 		sd_err(("bcmspi_host_device_init_adapt failed\n"));
@@ -1076,11 +1094,13 @@
 	}
 
 #ifndef HSMODE
+#ifndef BCMSPI_ANDROID
 	/* After configuring for High-Speed mode, set the desired clock rate. */
 	if (!spi_start_clock(sd, 4)) {
 		sd_err(("spi_start_clock failed\n"));
 		return ERROR;
 	}
+#endif /* !BCMSPI_ANDROID */
 #endif /* HSMODE */
 
 	/* check to see if the response delay needs to be programmed properly */
@@ -1127,7 +1147,6 @@
 		}
 	}
 
-
 	sd->card_init_done = TRUE;
 
 	/* get the device rev to program the prop respdelays */
@@ -1146,7 +1165,6 @@
 		return status;
 
 	sd_trace(("In %s spih-ctrl = 0x%x \n", __FUNCTION__, regdata));
-
 
 	if (hsmode == TRUE) {
 		sd_trace(("Attempting to enable High-Speed mode.\n"));
@@ -1167,6 +1185,7 @@
 
 		if (regdata & HIGH_SPEED_MODE) {
 			regdata &= ~HIGH_SPEED_MODE;
+			regdata |= CLOCK_POLARITY;
 			sd_trace(("Writing %08x to device at %08x\n", regdata, SPID_CONFIG));
 			if ((status = bcmspi_card_regwrite(sd, 0, SPID_CONFIG,
 			                                  4, regdata)) != SUCCESS)
@@ -1177,7 +1196,9 @@
 			return status;
 		}
 	}
+#ifndef BCMSPI_ANDROID
 	spi_controller_highspeed_mode(sd, hsmode);
+#endif /* !BCMSPI_ANDROID */
 
 	return TRUE;
 }
@@ -1287,8 +1308,14 @@
 			OSL_DELAY(1000);
 		}
 
+#if defined(CHANGE_SPI_INTR_POLARITY_ACTIVE_HIGH)
+		/* Change to host controller intr-polarity of active-high */
+		wrregdata |= INTR_POLARITY;
+#else
 		/* Change to host controller intr-polarity of active-low */
 		wrregdata &= ~INTR_POLARITY;
+#endif /* CHANGE_SPI_INTR_POLARITY_ACTIVE_HIGH */
+
 		sd_trace(("(we are still in 16bit mode) 32bit Write LE reg-ctrl-data = 0x%x\n",
 		        wrregdata));
 		/* Change to 32bit mode */
@@ -1311,7 +1338,6 @@
 		}
 	}
 
-
 	return TRUE;
 }
 
@@ -1330,7 +1356,6 @@
 		sd_trace(("Incorrect 32bit LE regdata = 0x%x\n", regdata));
 		return FALSE;
 	}
-
 
 #define RW_PATTERN1	0xA0A1A2A3
 #define RW_PATTERN2	0x4B5B6B7B
@@ -1518,27 +1543,10 @@
 	uint8	resp_delay = 0;
 	int	err = SUCCESS;
 	uint32	hostlen;
-	uint32 spilen = 0;
 	uint32 dstatus_idx = 0;
-	uint16 templen, buslen, len, *ptr = NULL;
+//	uint16 templen, buslen, len;
 
 	sd_trace(("spi cmd = 0x%x\n", cmd_arg));
-
-	if (DWORDMODE_ON) {
-		spilen = GFIELD(cmd_arg, SPI_LEN);
-		if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_0) ||
-		    (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_1))
-			dstatus_idx = spilen * 3;
-
-		if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) &&
-		    (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) {
-			spilen = spilen << 2;
-			dstatus_idx = (spilen % 16) ? (16 - (spilen % 16)) : 0;
-			/* convert len to mod16 size */
-			spilen = ROUNDUP(spilen, 16);
-			cmd_arg = SFIELD(cmd_arg, SPI_LEN, (spilen >> 2));
-		}
-	}
 
 	/* Set up and issue the SPI command.  MSByte goes out on bus first.  Increase datalen
 	 * according to the wordlen mode(16/32bit) the device is in.
@@ -1562,17 +1570,6 @@
 	/* for Write, put the data into the output buffer */
 	if (GFIELD(cmd_arg, SPI_RW_FLAG) == 1) {
 		/* We send len field of hw-header always a mod16 size, both from host and dongle */
-		if (DWORDMODE_ON) {
-			if (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) {
-				ptr = (uint16 *)&data[0];
-				templen = *ptr;
-				/* ASSERT(*ptr == ~*(ptr + 1)); */
-				templen = ROUNDUP(templen, 16);
-				*ptr = templen;
-				sd_trace(("actual tx len = %d\n", (uint16)(~*(ptr+1))));
-			}
-		}
-
 		if (datalen != 0) {
 			for (i = 0; i < datalen/4; i++) {
 				if (sd->wordlen == 4) { /* 32bit spid */
@@ -1620,7 +1617,15 @@
 	/* +4 for cmd and +4 for dstatus */
 	hostlen = datalen + 8 + resp_delay;
 	hostlen += dstatus_idx;
+#ifdef BCMSPI_ANDROID
+	if (hostlen%4) {
+		sd_err(("Unaligned data len %d, hostlen %d\n",
+			datalen, hostlen));
+#endif /* BCMSPI_ANDROID */
 	hostlen += (4 - (hostlen & 0x3));
+#ifdef BCMSPI_ANDROID
+	}
+#endif /* BCMSPI_ANDROID */
 	spi_sendrecv(sd, spi_outbuf, spi_inbuf, hostlen);
 
 	/* for Read, get the data into the input buffer */
@@ -1635,25 +1640,6 @@
 					            CMDLEN + resp_delay]);
 				}
 			}
-
-			if ((DWORDMODE_ON) && (GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2)) {
-				ptr = (uint16 *)&data[0];
-				templen = *ptr;
-				buslen = len = ~(*(ptr + 1));
-				buslen = ROUNDUP(buslen, 16);
-				/* populate actual len in hw-header */
-				if (templen == buslen)
-					*ptr = len;
-			}
-		}
-	}
-
-	/* Restore back the len field of the hw header */
-	if (DWORDMODE_ON) {
-		if ((GFIELD(cmd_arg, SPI_FUNCTION) == SPI_FUNC_2) &&
-		    (GFIELD(cmd_arg, SPI_RW_FLAG) == 1)) {
-			ptr = (uint16 *)&data[0];
-			*ptr = (uint16)(~*(ptr+1));
 		}
 	}
 
@@ -1761,17 +1747,10 @@
 	         __FUNCTION__, write ? "Wd" : "Rd", func, "INCR",
 	         addr, nbytes, sd->r_cnt, sd->t_cnt));
 
-
 	if ((status = bcmspi_cmd_issue(sd, sd->sd_use_dma, cmd_arg, data, nbytes)) != SUCCESS) {
 		sd_err(("%s: cmd_issue failed for %s\n", __FUNCTION__,
 			(write ? "write" : "read")));
 		return status;
-	}
-
-	/* gSPI expects that hw-header-len is equal to spi-command-len */
-	if ((func == 2) && (rw == SDIOH_WRITE) && (sd->dwordmode == FALSE)) {
-		ASSERT((uint16)sd->data_xfer_count == (uint16)(*data & 0xffff));
-		ASSERT((uint16)sd->data_xfer_count == (uint16)(~((*data & 0xffff0000) >> 16)));
 	}
 
 	if ((nbytes > 2000) && !write) {

--
Gitblit v1.6.2