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