You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/08/15 02:31:42 UTC
[incubator-nuttx] branch master updated: Add gSPI mode support for Infineon CYW43539
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new e247eaf3e8 Add gSPI mode support for Infineon CYW43539
e247eaf3e8 is described below
commit e247eaf3e894f2f3ff173b0732b8fc6712c5334d
Author: curuvar <58...@users.noreply.github.com>
AuthorDate: Sun Aug 14 15:04:18 2022 -0400
Add gSPI mode support for Infineon CYW43539
---
drivers/leds/Kconfig | 2 +-
drivers/wireless/ieee80211/bcm43xxx/Kconfig | 26 +
drivers/wireless/ieee80211/bcm43xxx/Make.defs | 14 +
drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c | 5 +-
drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c | 30 +-
.../wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c | 4 +-
.../wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c | 4 +-
.../wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c | 4 +-
.../wireless/ieee80211/bcm43xxx/bcmf_chip_43455.c | 4 +-
.../wireless/ieee80211/bcm43xxx/bcmf_chip_data.h | 82 ++
drivers/wireless/ieee80211/bcm43xxx/bcmf_core.c | 173 +--
drivers/wireless/ieee80211/bcm43xxx/bcmf_core.h | 36 +-
drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c | 343 ++++--
drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h | 5 +
.../bcm43xxx/{bcmf_chip_43362.c => bcmf_gpio.c} | 87 +-
drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.c | 1135 ++++++++++++++++++++
drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.h | 114 ++
.../ieee80211/bcm43xxx/bcmf_gspi_f2_frame.c | 394 +++++++
.../{bcmf_chip_4301x.c => bcmf_gspi_f2_frame.h} | 83 +-
.../wireless/ieee80211/bcm43xxx/bcmf_interface.c | 144 +++
.../wireless/ieee80211/bcm43xxx/bcmf_interface.h | 154 +++
drivers/wireless/ieee80211/bcm43xxx/bcmf_ioctl.h | 6 +
drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c | 6 +-
drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.c | 329 +++---
drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h | 65 +-
.../wireless/ieee80211/bcm43xxx/bcmf_sdio_core.h | 18 +-
drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c | 192 ++--
.../{bcmf_chip_43438.c => cyw_chip_43439.c} | 32 +-
drivers/wireless/ieee80211/bcm43xxx/cyw_reg_def.h | 165 +++
.../nuttx/wireless/ieee80211/bcmf_gpio.h | 63 +-
include/nuttx/wireless/ieee80211/bcmf_gspi.h | 133 +++
31 files changed, 3140 insertions(+), 712 deletions(-)
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index f2525a81ea..0c45a2623e 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -106,7 +106,7 @@ config WS2812
---help---
Enable support for the Worldsemi WS2812 LED driver which commonly
found in LED strips.
- NOTE: Depening on the board slected this device may require
+ NOTE: Depending on the board selected, this device may require
exclusive use of an SPI bus as ws2812 LEDs have no CS or
RESET line.
diff --git a/drivers/wireless/ieee80211/bcm43xxx/Kconfig b/drivers/wireless/ieee80211/bcm43xxx/Kconfig
index 9463b5e9bf..2929a67313 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/Kconfig
+++ b/drivers/wireless/ieee80211/bcm43xxx/Kconfig
@@ -34,6 +34,12 @@ config IEEE80211_BROADCOM_BCM43455
default n
select IEEE80211_BROADCOM_HAVE_CLM
+config IEEE80211_INFINEON_CYW43439
+ bool "Infineon 43439 chip support"
+ depends on IEEE80211_BROADCOM_FULLMAC
+ default n
+ select IEEE80211_BROADCOM_HAVE_CLM
+
config IEEE80211_BROADCOM_FWFILES
bool "Firmware files"
default y
@@ -118,8 +124,25 @@ config IEEE80211_BROADCOM_FULLMAC_SDIO
This selection enables support for broadcom
FullMAC-compliant devices using SDIO bus.
+config IEEE80211_BROADCOM_FULLMAC_GSPI
+ bool "Broadcom FullMAC driver on gSPI bus"
+ select IEEE80211_BROADCOM_FULLMAC
+ default n
+ ---help---
+ This selection enables support for broadcom
+ FullMAC-compliant devices using gSPI bus.
+
+config IEEE80211_BROADCOM_FULLMAC_GSPI_MAX_FRAME
+ int "Broadcom FullMAC driver on gSPI bus"
+ default 2048
+ depends on IEEE80211_BROADCOM_FULLMAC_GSPI
+ ---help---
+ This is the maximum frame size for data transfers
+ with the chip.
+
config IEEE80211_BROADCOM_SCHED_PRIORITY
int "Broadcom BCMF daemon thread schedule priority"
+ depends on IEEE80211_BROADCOM_FULLMAC
default SCHED_HPWORKPRIORITY if SCHED_HPWORK
default 255
---help---
@@ -128,18 +151,21 @@ config IEEE80211_BROADCOM_SCHED_PRIORITY
config IEEE80211_BROADCOM_SCAN_RESULT_ENTRIES
int "Broadcom BCMF escan result entries"
+ depends on IEEE80211_BROADCOM_FULLMAC
default 10
---help---
This parameter should be set the bcmf escan result buffer entries
config IEEE80211_BROADCOM_LOWPOWER
bool "Broadcom BCMF lower power"
+ depends on IEEE80211_BROADCOM_FULLMAC
default n
---help---
This parameter should be enable the bcmf lower power mode
config IEEE80211_BROADCOM_DEFAULT_COUNTRY
string "Broadcom BCMF default country code"
+ depends on IEEE80211_BROADCOM_FULLMAC
default ""
---help---
This parameter should be set the default country code
diff --git a/drivers/wireless/ieee80211/bcm43xxx/Make.defs b/drivers/wireless/ieee80211/bcm43xxx/Make.defs
index 42e345e912..0041d73e88 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/Make.defs
+++ b/drivers/wireless/ieee80211/bcm43xxx/Make.defs
@@ -26,9 +26,19 @@ ifeq ($(CONFIG_IEEE80211_BROADCOM_FULLMAC),y)
CSRCS += bcmf_bdc.c
CSRCS += bcmf_utils.c
CSRCS += bcmf_netdev.c
+ CSRCS += bcmf_gpio.c
ifeq ($(CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO),y)
CSRCS += bcmf_sdio.c
+ CSRCS += bcmf_interface.c
+ CSRCS += bcmf_core.c
+ CSRCS += bcmf_sdpcm.c
+endif
+
+ifeq ($(CONFIG_IEEE80211_BROADCOM_FULLMAC_GSPI),y)
+ CSRCS += bcmf_gspi.c
+ CSRCS += bcmf_gspi_f2_frame.c
+ CSRCS += bcmf_interface.c
CSRCS += bcmf_core.c
CSRCS += bcmf_sdpcm.c
endif
@@ -49,6 +59,10 @@ ifeq ($(CONFIG_IEEE80211_BROADCOM_BCM43455),y)
CSRCS += bcmf_chip_43455.c
endif
+ifeq ($(CONFIG_IEEE80211_INFINEON_CYW43439),y)
+CSRCS += cyw_chip_43439.c
+endif
+
# Include BCM43xxx build support
DEPPATH += --dep-path wireless$(DELIM)ieee80211$(DELIM)bcm43xxx
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c
index 458d8a1e50..de1f1b78ea 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_bdc.c
@@ -123,6 +123,7 @@ int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
if (data_size < sizeof(struct bcmf_bdc_header))
{
+ wlerr("invalid event frame -- way too small\n");
goto exit_invalid_frame;
}
@@ -132,6 +133,7 @@ int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
if (data_size < sizeof(struct bcmf_event_msg))
{
+ wlerr("invalid event frame -- too small\n");
goto exit_invalid_frame;
}
@@ -146,6 +148,8 @@ int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
if (event_msg->eth.ether_type != BCMF_EVENT_ETHER_TYPE ||
memcmp(event_msg->bcm_eth.oui, bcmf_broadcom_oui, 3))
{
+ wlerr("invalid event frame -- bad data\n");
+
goto exit_invalid_frame;
}
@@ -168,7 +172,6 @@ int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
return OK;
exit_invalid_frame:
- wlerr("Invalid event frame\n");
bcmf_hexdump(frame->base, frame->len, (unsigned long)frame->base);
return -EINVAL;
}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c
index 6e7bda541e..e0bb291785 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_cdc.c
@@ -48,7 +48,7 @@
#define BCMF_CONTROL_INTERFACE_SHIFT 12
#define BCMF_CONTROL_REQID_SHIFT 16
-#define BCMF_CONTROL_TIMEOUT_MS 1000
+#define BCMF_CONTROL_TIMEOUT_MS 2000
/****************************************************************************
* Private Types
@@ -198,6 +198,29 @@ int bcmf_cdc_control_request_unsafe(FAR struct bcmf_dev_s *priv,
return -ENOMEM;
}
+#ifdef CONFIG_DEBUG_WIRELESS_INFO
+ if (cmd == WLC_SET_VAR || cmd == WLC_GET_VAR)
+ {
+ wlinfo(">>> Sending control %d %d 0x%08lX [%d] %s %s \n",
+ ifidx,
+ set,
+ cmd,
+ out_len,
+ set ? "set" : "get",
+ name);
+ }
+ else
+ {
+ wlinfo(">>> Sending control %d %d 0x%08lX [%d] %s cmd: %d\n",
+ ifidx,
+ set,
+ cmd,
+ out_len,
+ set ? "set" : "get",
+ cmd);
+ }
+#endif
+
/* Setup buffer to store response */
priv->control_rxdata = set ? NULL : data;
@@ -210,6 +233,7 @@ int bcmf_cdc_control_request_unsafe(FAR struct bcmf_dev_s *priv,
{
/* Free allocated iovar buffer */
+ wlerr("cdc send frame failed: %d\n", ret);
priv->bus->free_frame(priv, frame);
return ret;
}
@@ -263,6 +287,10 @@ int bcmf_cdc_ioctl(FAR struct bcmf_dev_s *priv,
return bcmf_cdc_control_request(priv, ifidx, set, cmd, NULL, data, len);
}
+/****************************************************************************
+ * Name: bcmf_cdc_process_control_frame
+ ****************************************************************************/
+
int bcmf_cdc_process_control_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame)
{
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
index 7fdbea81ef..5d5f2bf180 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
@@ -25,7 +25,7 @@
#include <nuttx/config.h>
#include <stdint.h>
-#include "bcmf_sdio.h"
+#include "bcmf_interface.h"
/****************************************************************************
* Pre-processor Definitions
@@ -45,7 +45,7 @@ extern const uint8_t bcm4301x_firmware_image[];
extern const unsigned int bcm4301x_firmware_image_len;
#endif
-const struct bcmf_sdio_chip bcmf_4301x_config_sdio =
+const struct bcmf_chip_data bcmf_4301x_config_data =
{
/* General chip stats */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c
index ab77418f46..12e9f682aa 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c
@@ -25,7 +25,7 @@
#include <nuttx/config.h>
#include <stdint.h>
-#include "bcmf_sdio.h"
+#include "bcmf_interface.h"
/****************************************************************************
* Pre-processor Definitions
@@ -45,7 +45,7 @@ extern const uint8_t bcm43362_firmware_image[];
extern const unsigned int bcm43362_firmware_image_len;
#endif
-const struct bcmf_sdio_chip bcmf_43362_config_sdio =
+const struct bcmf_chip_data bcmf_43362_config_data =
{
/* General chip stats */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c
index 2592b92c23..281de11f04 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c
@@ -25,7 +25,7 @@
#include <nuttx/config.h>
#include <stdint.h>
-#include "bcmf_sdio.h"
+#include "bcmf_interface.h"
/****************************************************************************
* Pre-processor Definitions
@@ -48,7 +48,7 @@ extern const uint8_t ap6212_clm_blob[];
extern const unsigned int ap6212_clm_blob_len;
#endif
-const struct bcmf_sdio_chip bcmf_43438_config_sdio =
+const struct bcmf_chip_data bcmf_43438_config_data =
{
/* General chip stats */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43455.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43455.c
index 92adb03fce..449bf6a479 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43455.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43455.c
@@ -25,7 +25,7 @@
#include <nuttx/config.h>
#include <stdint.h>
-#include "bcmf_sdio.h"
+#include "bcmf_interface.h"
/****************************************************************************
* Pre-processor Definitions
@@ -48,7 +48,7 @@ extern const uint8_t bcm43455_clm_blob[];
extern const unsigned int bcm43455_clm_blob_len;
#endif
-const struct bcmf_sdio_chip bcmf_43455_config_sdio =
+const struct bcmf_chip_data bcmf_43455_config_data =
{
/* General chip stats */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_data.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_data.h
new file mode 100644
index 0000000000..703e7bbf27
--- /dev/null
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_data.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_data.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_CHIP_DATA_H
+#define __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_CHIP_DATA_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+enum
+{
+ CHIPCOMMON_CORE_ID = 0,
+ DOT11MAC_CORE_ID,
+ SDIOD_CORE_ID,
+#if defined(CONFIG_IEEE80211_BROADCOM_BCM4301X) || \
+ defined(CONFIG_IEEE80211_BROADCOM_BCM43362) || \
+ defined(CONFIG_IEEE80211_BROADCOM_BCM43438) || \
+ defined(CONFIG_IEEE80211_INFINEON_CYW43439)
+ WLAN_ARMCM3_CORE_ID,
+ SOCSRAM_CORE_ID,
+#endif
+#if defined(CONFIG_IEEE80211_BROADCOM_BCM43455)
+ WLAN_ARMCR4_CORE_ID,
+#endif
+ MAX_CORE_ID
+};
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* SDIO chip configuration structure */
+
+struct bcmf_chip_data
+{
+ uint32_t ram_base;
+ uint32_t ram_size;
+ uint32_t core_base[MAX_CORE_ID];
+
+ /* In-memory file images */
+
+ FAR uint8_t *nvram_image;
+ FAR unsigned int *nvram_image_size;
+
+#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
+ FAR uint8_t *firmware_image;
+ FAR unsigned int *firmware_image_size;
+
+#ifdef CONFIG_IEEE80211_BROADCOM_HAVE_CLM
+ FAR uint8_t *clm_blob_image;
+ FAR unsigned int *clm_blob_image_size;
+#endif
+#endif
+};
+
+#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_CHIP_DATA_H */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.c
index dc6da7f45d..cd32015550 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.c
@@ -40,8 +40,7 @@
#include <nuttx/signal.h>
#include "bcmf_core.h"
-#include "bcmf_sdio.h"
-
+#include "bcmf_interface.h"
#include "bcmf_sdio_regs.h"
/****************************************************************************
@@ -78,10 +77,6 @@
#define SOCSRAM_BANKX_INDEX ((uint32_t) (0x18004000 + 0x10) )
#define SOCSRAM_BANKX_PDA ((uint32_t) (0x18004000 + 0x44) )
-/* Transfer size properties */
-
-#define BCMF_UPLOAD_TRANSFER_SIZE (64 * 256)
-
/* Define this to validate uploaded materials */
/* #define DBG_VALIDATE_UPLOAD */
@@ -98,18 +93,18 @@ static uint8_t compare_buffer[BCMF_UPLOAD_TRANSFER_SIZE];
* Private Function Prototypes
****************************************************************************/
-static int bcmf_core_set_backplane_window(FAR struct bcmf_sdio_dev_s *sbus,
+static int bcmf_core_set_backplane_window(FAR bcmf_interface_dev_t *ibus,
uint32_t address);
-static int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbusv,
+static int bcmf_upload_binary(FAR bcmf_interface_dev_t *ibus,
uint32_t address, uint8_t *buf,
unsigned int len);
-static int bcmf_upload_nvram(FAR struct bcmf_sdio_dev_s *sbus);
+static int bcmf_upload_nvram(FAR bcmf_interface_dev_t *ibus);
/****************************************************************************
* Private Functions
****************************************************************************/
-int bcmf_core_set_backplane_window(FAR struct bcmf_sdio_dev_s *sbus,
+int bcmf_core_set_backplane_window(FAR bcmf_interface_dev_t *ibus,
uint32_t address)
{
int ret;
@@ -120,13 +115,13 @@ int bcmf_core_set_backplane_window(FAR struct bcmf_sdio_dev_s *sbus,
for (i = 1; i < 4; i++)
{
uint8_t addr_part = (address >> (8*i)) & 0xff;
- uint8_t cur_addr_part = (sbus->backplane_current_addr >> (8*i)) & 0xff;
+ uint8_t cur_addr_part = (ibus->backplane_current_addr >> (8*i)) & 0xff;
if (addr_part != cur_addr_part)
{
/* Update current backplane base address */
- ret = bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_SBADDRLOW + i - 1,
+ ret = bcmf_write_reg(ibus, 1, SBSDIO_FUNC1_SBADDRLOW + i - 1,
addr_part);
if (ret != OK)
@@ -134,15 +129,15 @@ int bcmf_core_set_backplane_window(FAR struct bcmf_sdio_dev_s *sbus,
return ret;
}
- sbus->backplane_current_addr &= ~(0xff << (8*i));
- sbus->backplane_current_addr |= addr_part << (8*i);
+ ibus->backplane_current_addr &= ~(0xff << (8*i));
+ ibus->backplane_current_addr |= addr_part << (8*i);
}
}
return OK;
}
-int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
+int bcmf_upload_binary(FAR bcmf_interface_dev_t *ibus, uint32_t address,
uint8_t *buf, unsigned int len)
{
unsigned int size;
@@ -157,7 +152,7 @@ int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
{
/* Set the backplane window to include the start address */
- int ret = bcmf_core_set_backplane_window(sbus, address);
+ int ret = bcmf_core_set_backplane_window(ibus, address);
if (ret != OK)
{
wlerr("Backplane setting failed at %08" PRIx32 "\n", address);
@@ -175,7 +170,7 @@ int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
/* Transfer firmware data */
- ret = bcmf_transfer_bytes(sbus, true, 1,
+ ret = bcmf_transfer_bytes(ibus, true, 1,
address & SBSDIO_SB_OFT_ADDR_MASK, buf,
size);
if (ret != OK)
@@ -195,7 +190,7 @@ int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
{
/* Set the backplane window to include the start address */
- int ret = bcmf_core_set_backplane_window(sbus, validate_address);
+ int ret = bcmf_core_set_backplane_window(ibus, validate_address);
if (ret != OK)
{
wlerr("Backplane setting failed at %08x\n", validate_address);
@@ -213,7 +208,7 @@ int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
/* Transfer firmware data */
- ret = bcmf_transfer_bytes(sbus, false, 1,
+ ret = bcmf_transfer_bytes(ibus, false, 1,
validate_address & SBSDIO_SB_OFT_ADDR_MASK,
compare_buffer, size);
if (ret != OK)
@@ -241,7 +236,7 @@ int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
}
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
-int bcmf_upload_file(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
+int bcmf_upload_file(FAR bcmf_interface_dev_t *ibus, uint32_t address,
FAR const char *path)
{
struct file finfo;
@@ -290,7 +285,7 @@ int bcmf_upload_file(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
wlinfo("Read %ld bytes\n", (long)nread);
- ret = bcmf_core_set_backplane_window(sbus, address);
+ ret = bcmf_core_set_backplane_window(ibus, address);
if (ret < 0)
{
wlerr("ERROR: bcmf_core_set_backplane_window() failed: %d\n", ret);
@@ -301,7 +296,7 @@ int bcmf_upload_file(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
/* Transfer firmware data */
- ret = bcmf_transfer_bytes(sbus, true, 1,
+ ret = bcmf_transfer_bytes(ibus, true, 1,
address & SBSDIO_SB_OFT_ADDR_MASK, buf,
total_read);
if (ret < 0)
@@ -330,10 +325,10 @@ errout_with_file:
}
#endif
-int bcmf_upload_nvram(FAR struct bcmf_sdio_dev_s *sbus)
+int bcmf_upload_nvram(FAR bcmf_interface_dev_t *ibus)
{
- FAR uint8_t *nvram_buf = sbus->chip->nvram_image;
- uint32_t nvram_sz = *sbus->chip->nvram_image_size;
+ FAR uint8_t *nvram_buf = ibus->chip->nvram_image;
+ uint32_t nvram_sz = *ibus->chip->nvram_image_size;
uint32_t token;
int ret;
@@ -421,13 +416,13 @@ out:
/* Write image */
- ret = bcmf_upload_binary(sbus,
- sbus->chip->ram_size - 4 - nvram_sz
- + sbus->chip->ram_base,
+ ret = bcmf_upload_binary(ibus,
+ ibus->chip->ram_size - 4 - nvram_sz
+ + ibus->chip->ram_base,
nvram_buf, nvram_sz);
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
- if (nvram_buf != sbus->chip->nvram_image)
+ if (nvram_buf != ibus->chip->nvram_image)
{
kmm_free(nvram_buf);
}
@@ -445,8 +440,8 @@ out:
/* Write the length token to the last word */
- return bcmf_write_sbreg(sbus,
- sbus->chip->ram_size - 4 + sbus->chip->ram_base,
+ return bcmf_write_sbreg(ibus,
+ ibus->chip->ram_size - 4 + ibus->chip->ram_base,
(FAR uint8_t *)&token, 4);
}
@@ -458,10 +453,10 @@ out:
* Name: bcmf_read_sbreg
****************************************************************************/
-int bcmf_read_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
+int bcmf_read_sbreg(FAR bcmf_interface_dev_t *ibus, uint32_t address,
FAR uint8_t *reg, unsigned int len)
{
- int ret = bcmf_core_set_backplane_window(sbus, address);
+ int ret = bcmf_core_set_backplane_window(ibus, address);
if (ret != OK)
{
return ret;
@@ -476,17 +471,17 @@ int bcmf_read_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
address |= SBSDIO_SB_ACCESS_2_4B_FLAG;
}
- return bcmf_transfer_bytes(sbus, false, 1, address, reg, len);
+ return bcmf_transfer_bytes(ibus, false, 1, address, reg, len);
}
/****************************************************************************
* Name: bcmf_write_sbreg
****************************************************************************/
-int bcmf_write_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
+int bcmf_write_sbreg(FAR bcmf_interface_dev_t *ibus, uint32_t address,
FAR uint8_t *reg, unsigned int len)
{
- int ret = bcmf_core_set_backplane_window(sbus, address);
+ int ret = bcmf_core_set_backplane_window(ibus, address);
if (ret != OK)
{
return ret;
@@ -501,14 +496,14 @@ int bcmf_write_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
address |= SBSDIO_SB_ACCESS_2_4B_FLAG;
}
- return bcmf_transfer_bytes(sbus, true, 1, address, reg, len);
+ return bcmf_transfer_bytes(ibus, true, 1, address, reg, len);
}
/****************************************************************************
* Name: bcmf_core_upload_firmware
****************************************************************************/
-int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
+int bcmf_core_upload_firmware(FAR bcmf_interface_dev_t *ibus)
{
int ret;
#if defined(CONFIG_IEEE80211_BROADCOM_BCM43455)
@@ -518,30 +513,34 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
wlinfo("upload firmware\n");
- switch (sbus->cur_chip_id)
+ switch (ibus->cur_chip_id)
{
#if defined(CONFIG_IEEE80211_BROADCOM_BCM4301X) || \
defined(CONFIG_IEEE80211_BROADCOM_BCM43362) || \
- defined(CONFIG_IEEE80211_BROADCOM_BCM43438)
+ defined(CONFIG_IEEE80211_BROADCOM_BCM43438) || \
+ defined(CONFIG_IEEE80211_INFINEON_CYW43439)
case SDIO_DEVICE_ID_BROADCOM_43012:
case SDIO_DEVICE_ID_BROADCOM_43013:
case SDIO_DEVICE_ID_BROADCOM_43362:
case SDIO_DEVICE_ID_BROADCOM_43430:
+ case SDIO_DEVICE_ID_INFINEON_CYW43439:
/* Disable ARMCM3 core and reset SOCRAM core to set device in
* firmware upload mode
*/
- bcmf_core_disable(sbus, WLAN_ARMCM3_CORE_ID, 0, 0);
- bcmf_core_reset(sbus, SOCSRAM_CORE_ID, 0, 0, 0);
+ bcmf_core_disable(ibus, WLAN_ARMCM3_CORE_ID, 0, 0);
+ bcmf_core_reset(ibus, SOCSRAM_CORE_ID, 0, 0, 0);
+
+#if defined(CONFIG_IEEE80211_BROADCOM_BCM43438) \
+ || defined(CONFIG_IEEE80211_INFINEON_CYW43439)
-#ifdef CONFIG_IEEE80211_BROADCOM_BCM43438
- if (sbus->cur_chip_id == SDIO_DEVICE_ID_BROADCOM_43430)
+ if (ibus->cur_chip_id == SDIO_DEVICE_ID_BROADCOM_43430)
{
/* Disable remap for SRAM_3. Only for 4343x */
- bcmf_write_sbregw(sbus, SOCSRAM_BANKX_INDEX, 0x3);
- bcmf_write_sbregw(sbus, SOCSRAM_BANKX_PDA, 0);
+ bcmf_write_sbregw(ibus, SOCSRAM_BANKX_INDEX, 0x3);
+ bcmf_write_sbregw(ibus, SOCSRAM_BANKX_PDA, 0);
}
#endif
break;
@@ -553,10 +552,10 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
/* Clear all IOCTL bits except HALT bit */
- base = sbus->chip->core_base[WLAN_ARMCR4_CORE_ID];
- bcmf_read_sbregw(sbus, base + BCMA_IOCTL, &value);
+ base = ibus->chip->core_base[WLAN_ARMCR4_CORE_ID];
+ bcmf_read_sbregw(ibus, base + BCMA_IOCTL, &value);
value &= ARMCR4_BCMA_IOCTL_CPUHALT;
- bcmf_core_reset(sbus,
+ bcmf_core_reset(ibus,
WLAN_ARMCR4_CORE_ID,
value,
ARMCR4_BCMA_IOCTL_CPUHALT,
@@ -573,16 +572,16 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
/* Flash chip firmware */
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
- ret = bcmf_upload_file(sbus,
- sbus->chip->ram_base,
+ ret = bcmf_upload_file(ibus,
+ ibus->chip->ram_base,
CONFIG_IEEE80211_BROADCOM_FWFILENAME);
#else
- wlinfo("firmware size is %d bytes\n", *sbus->chip->firmware_image_size);
+ wlinfo("firmware size is %d bytes\n", *ibus->chip->firmware_image_size);
- ret = bcmf_upload_binary(sbus,
- sbus->chip->ram_base,
- sbus->chip->firmware_image,
- *sbus->chip->firmware_image_size);
+ ret = bcmf_upload_binary(ibus,
+ ibus->chip->ram_base,
+ ibus->chip->firmware_image,
+ *ibus->chip->firmware_image_size);
#endif
if (ret < 0)
@@ -594,7 +593,7 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
/* Flash NVRAM configuration file */
wlinfo("upload nvram configuration\n");
- ret = bcmf_upload_nvram(sbus);
+ ret = bcmf_upload_nvram(ibus);
if (ret < 0)
{
wlerr("ERROR: Failed to upload NVRAM\n");
@@ -603,23 +602,25 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
/* Firmware upload done, restart ARM CM3/CR4 core */
- switch (sbus->cur_chip_id)
+ switch (ibus->cur_chip_id)
{
#if defined(CONFIG_IEEE80211_BROADCOM_BCM4301X) || \
defined(CONFIG_IEEE80211_BROADCOM_BCM43362) || \
- defined(CONFIG_IEEE80211_BROADCOM_BCM43438)
+ defined(CONFIG_IEEE80211_BROADCOM_BCM43438) || \
+ defined(CONFIG_IEEE80211_INFINEON_CYW43439)
case SDIO_DEVICE_ID_BROADCOM_43012:
case SDIO_DEVICE_ID_BROADCOM_43013:
case SDIO_DEVICE_ID_BROADCOM_43362:
case SDIO_DEVICE_ID_BROADCOM_43430:
+ case SDIO_DEVICE_ID_INFINEON_CYW43439:
nxsig_usleep(10 * 1000);
- bcmf_core_reset(sbus, WLAN_ARMCM3_CORE_ID, 0, 0, 0);
+ bcmf_core_reset(ibus, WLAN_ARMCM3_CORE_ID, 0, 0, 0);
/* Check ARMCM3 core is running */
nxsig_usleep(10 * 1000);
- if (!bcmf_core_isup(sbus, WLAN_ARMCM3_CORE_ID))
+ if (!bcmf_core_isup(ibus, WLAN_ARMCM3_CORE_ID))
{
wlerr("Cannot start ARMCM3 core\n");
return -ETIMEDOUT;
@@ -634,22 +635,22 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
/* Clear all interrupts */
bcmf_write_sbregw(
- sbus,
- CORE_BUS_REG(sbus->chip->core_base[SDIOD_CORE_ID], intstatus),
+ ibus,
+ CORE_BUS_REG(ibus->chip->core_base[SDIOD_CORE_ID], intstatus),
0xffffffff);
/* Write reset vector to address 0 */
- ret = bcmf_upload_binary(sbus,
+ ret = bcmf_upload_binary(ibus,
0,
- sbus->chip->firmware_image,
+ ibus->chip->firmware_image,
4);
if (ret < 0)
{
return ret;
}
- bcmf_core_reset(sbus,
+ bcmf_core_reset(ibus,
WLAN_ARMCR4_CORE_ID,
ARMCR4_BCMA_IOCTL_CPUHALT,
0,
@@ -658,7 +659,7 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
/* Check ARMCR4 core is running */
nxsig_usleep(10 * 1000);
- if (!bcmf_core_isup(sbus, WLAN_ARMCR4_CORE_ID))
+ if (!bcmf_core_isup(ibus, WLAN_ARMCR4_CORE_ID))
{
wlerr("Cannot start ARMCR4 core\n");
return -ETIMEDOUT;
@@ -674,7 +675,7 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
return OK;
}
-bool bcmf_core_isup(FAR struct bcmf_sdio_dev_s *sbus, unsigned int core)
+bool bcmf_core_isup(FAR bcmf_interface_dev_t *ibus, unsigned int core)
{
uint32_t value = 0;
uint32_t base;
@@ -685,21 +686,21 @@ bool bcmf_core_isup(FAR struct bcmf_sdio_dev_s *sbus, unsigned int core)
return false;
}
- base = sbus->chip->core_base[core];
+ base = ibus->chip->core_base[core];
- bcmf_read_sbregw(sbus, base + BCMA_IOCTL, &value);
+ bcmf_read_sbregw(ibus, base + BCMA_IOCTL, &value);
if ((value & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) != BCMA_IOCTL_CLK)
{
return false;
}
- bcmf_read_sbregw(sbus, base + BCMA_RESET_CTL, &value);
+ bcmf_read_sbregw(ibus, base + BCMA_RESET_CTL, &value);
return (value & BCMA_RESET_CTL_RESET) == 0;
}
-void bcmf_core_disable(FAR struct bcmf_sdio_dev_s *sbus,
+void bcmf_core_disable(FAR bcmf_interface_dev_t *ibus,
unsigned int core,
uint32_t prereset,
uint32_t reset)
@@ -712,13 +713,13 @@ void bcmf_core_disable(FAR struct bcmf_sdio_dev_s *sbus,
return;
}
- uint32_t base = sbus->chip->core_base[core];
+ uint32_t base = ibus->chip->core_base[core];
/* Check if core is already in reset state.
* If core is already in reset state, skip reset.
*/
- bcmf_read_sbregw(sbus, base + BCMA_RESET_CTL, &value);
+ bcmf_read_sbregw(ibus, base + BCMA_RESET_CTL, &value);
if ((value & BCMA_RESET_CTL_RESET) == 0)
{
@@ -728,25 +729,25 @@ void bcmf_core_disable(FAR struct bcmf_sdio_dev_s *sbus,
nxsig_usleep(10 * 1000);
- bcmf_write_sbregw(sbus,
+ bcmf_write_sbregw(ibus,
base + BCMA_IOCTL,
prereset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
- bcmf_read_sbregw(sbus, base + BCMA_IOCTL, &value);
+ bcmf_read_sbregw(ibus, base + BCMA_IOCTL, &value);
/* Set core in reset state */
- bcmf_write_sbregw(sbus, base + BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
+ bcmf_write_sbregw(ibus, base + BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
up_udelay(1);
}
- bcmf_write_sbregw(sbus,
+ bcmf_write_sbregw(ibus,
base + BCMA_IOCTL,
reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
- bcmf_read_sbregw(sbus, base + BCMA_IOCTL, &value);
+ bcmf_read_sbregw(ibus, base + BCMA_IOCTL, &value);
up_udelay(10);
}
-void bcmf_core_reset(FAR struct bcmf_sdio_dev_s *sbus,
+void bcmf_core_reset(FAR bcmf_interface_dev_t *ibus,
unsigned int core,
uint32_t prereset,
uint32_t reset,
@@ -761,21 +762,21 @@ void bcmf_core_reset(FAR struct bcmf_sdio_dev_s *sbus,
return;
}
- base = sbus->chip->core_base[core];
+ base = ibus->chip->core_base[core];
/* Put core in reset state */
- bcmf_core_disable(sbus, core, prereset, reset);
+ bcmf_core_disable(ibus, core, prereset, reset);
/* Run initialization sequence */
- bcmf_write_sbregw(sbus, base + BCMA_RESET_CTL, 0);
- bcmf_read_sbregw(sbus, base + BCMA_RESET_CTL, &value);
+ bcmf_write_sbregw(ibus, base + BCMA_RESET_CTL, 0);
+ bcmf_read_sbregw(ibus, base + BCMA_RESET_CTL, &value);
up_udelay(1);
- bcmf_write_sbregw(sbus, base + BCMA_IOCTL, postreset | BCMA_IOCTL_CLK);
- bcmf_read_sbregw(sbus, base + BCMA_IOCTL, &value);
+ bcmf_write_sbregw(ibus, base + BCMA_IOCTL, postreset | BCMA_IOCTL_CLK);
+ bcmf_read_sbregw(ibus, base + BCMA_IOCTL, &value);
up_udelay(1);
}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.h
index 3709f464ae..e891117dba 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.h
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_core.h
@@ -28,55 +28,57 @@
#include <stdint.h>
#include <stdbool.h>
-#include "bcmf_sdio.h"
+#include "bcmf_interface.h"
/****************************************************************************
* Public Functions Prototypes
****************************************************************************/
-int bcmf_read_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
+int bcmf_read_sbreg(FAR bcmf_interface_dev_t *ibus, uint32_t address,
uint8_t *reg, unsigned int len);
-int bcmf_write_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
+int bcmf_write_sbreg(FAR bcmf_interface_dev_t *ibus, uint32_t address,
uint8_t *reg, unsigned int len);
-bool bcmf_core_isup(FAR struct bcmf_sdio_dev_s *sbus, unsigned int core);
+bool bcmf_core_isup(FAR bcmf_interface_dev_t *ibus, unsigned int core);
-void bcmf_core_disable(FAR struct bcmf_sdio_dev_s *sbus,
+void bcmf_core_disable(FAR bcmf_interface_dev_t *ibus,
unsigned int core,
uint32_t prereset,
uint32_t reset);
-void bcmf_core_reset(FAR struct bcmf_sdio_dev_s *sbus,
+void bcmf_core_reset(FAR bcmf_interface_dev_t *ibus,
unsigned int core,
uint32_t prereset,
uint32_t reset,
uint32_t postreset);
-int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus);
+int bcmf_core_upload_firmware(FAR bcmf_interface_dev_t *ibus);
-static inline int bcmf_read_sbregb(FAR struct bcmf_sdio_dev_s *sbus,
- uint32_t address, uint8_t *reg)
+static inline int bcmf_read_sbregb(FAR bcmf_interface_dev_t *ibus,
+ uint32_t address,
+ uint8_t *value)
{
- return bcmf_read_sbreg(sbus, address, reg, 1);
+ return bcmf_read_sbreg(ibus, address, value, 1);
}
-static inline int bcmf_read_sbregw(FAR struct bcmf_sdio_dev_s *sbus,
- uint32_t address, uint32_t *reg)
+static inline int bcmf_read_sbregw(FAR bcmf_interface_dev_t *ibus,
+ uint32_t address,
+ void *value)
{
- return bcmf_read_sbreg(sbus, address, (uint8_t *)reg, 4);
+ return bcmf_read_sbreg(ibus, address, (uint8_t *)value, 4);
}
-static inline int bcmf_write_sbregb(FAR struct bcmf_sdio_dev_s *sbus,
+static inline int bcmf_write_sbregb(FAR bcmf_interface_dev_t *ibus,
uint32_t address, uint8_t reg)
{
- return bcmf_write_sbreg(sbus, address, ®, 1);
+ return bcmf_write_sbreg(ibus, address, ®, 1);
}
-static inline int bcmf_write_sbregw(FAR struct bcmf_sdio_dev_s *sbus,
+static inline int bcmf_write_sbregw(FAR bcmf_interface_dev_t *ibus,
uint32_t address, uint32_t reg)
{
- return bcmf_write_sbreg(sbus, address, (uint8_t *)®, 4);
+ return bcmf_write_sbreg(ibus, address, (uint8_t *)®, 4);
}
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_CORE_H */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c
index 40f08a44fd..ad93876780 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.c
@@ -47,7 +47,7 @@
#include "bcmf_ioctl.h"
#include "bcmf_utils.h"
#include "bcmf_netdev.h"
-#include "bcmf_sdio.h"
+#include "bcmf_core.h"
/****************************************************************************
* Pre-processor Definitions
@@ -118,11 +118,6 @@ enum
* Private Function Prototypes
****************************************************************************/
-static FAR struct bcmf_dev_s *bcmf_allocate_device(void);
-static void bcmf_free_device(FAR struct bcmf_dev_s *priv);
-
-static int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv);
-
#ifdef CONFIG_IEEE80211_BROADCOM_HAVE_CLM
static int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv);
#endif
@@ -148,6 +143,10 @@ static int bcmf_wl_get_interface(FAR struct bcmf_dev_s *priv,
* Private Functions
****************************************************************************/
+/****************************************************************************
+ * Name: bcmf_wl_channel_to_frequency
+ ****************************************************************************/
+
static int bcmf_wl_channel_to_frequency(int chan)
{
if (chan <= 0)
@@ -174,70 +173,9 @@ static int bcmf_wl_channel_to_frequency(int chan)
return 0; /* not supported */
}
-FAR struct bcmf_dev_s *bcmf_allocate_device(void)
-{
- int ret;
- FAR struct bcmf_dev_s *priv;
-
- /* Allocate a bcmf device structure */
-
- priv = (FAR struct bcmf_dev_s *)kmm_malloc(sizeof(*priv));
- if (!priv)
- {
- return NULL;
- }
-
- /* Initialize bcmf device structure */
-
- memset(priv, 0, sizeof(*priv));
-
- /* Init control frames mutex and timeout signal */
-
- if ((ret = nxsem_init(&priv->control_mutex, 0, 1)) != OK)
- {
- goto exit_free_priv;
- }
-
- if ((ret = nxsem_init(&priv->control_timeout, 0, 0)) != OK)
- {
- goto exit_free_priv;
- }
-
- if ((ret = nxsem_set_protocol(&priv->control_timeout, SEM_PRIO_NONE)) !=
- OK)
- {
- goto exit_free_priv;
- }
-
- /* Init authentication signal semaphore */
-
- if ((ret = nxsem_init(&priv->auth_signal, 0, 0)) != OK)
- {
- goto exit_free_priv;
- }
-
- if ((ret = nxsem_set_protocol(&priv->auth_signal, SEM_PRIO_NONE)) != OK)
- {
- goto exit_free_priv;
- }
-
- /* Init scan timeout timer */
-
- priv->scan_status = BCMF_SCAN_DISABLED;
-
- return priv;
-
-exit_free_priv:
- kmm_free(priv);
- return NULL;
-}
-
-void bcmf_free_device(FAR struct bcmf_dev_s *priv)
-{
- /* TODO deinitialize device structures */
-
- kmm_free(priv);
-}
+/****************************************************************************
+ * Name: bcmf_wl_set_mac_address
+ ****************************************************************************/
int bcmf_wl_set_mac_address(FAR struct bcmf_dev_s *priv, struct ifreq *req)
{
@@ -264,6 +202,10 @@ int bcmf_wl_set_mac_address(FAR struct bcmf_dev_s *priv, struct ifreq *req)
return OK;
}
+/****************************************************************************
+ * Name: bcmf_driver_download_clm
+ ****************************************************************************/
+
#ifdef CONFIG_IEEE80211_BROADCOM_HAVE_CLM
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
@@ -356,10 +298,10 @@ errout_with_file:
#else
int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
{
- FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
- FAR uint8_t *srcbuff = sbus->chip->clm_blob_image;
+ FAR bcmf_interface_dev_t *ibus = (FAR bcmf_interface_dev_t *)priv->bus;
+ FAR uint8_t *srcbuff = ibus->chip->clm_blob_image;
FAR uint8_t *downloadbuff;
- unsigned int datalen = *sbus->chip->clm_blob_image_size;
+ unsigned int datalen = *ibus->chip->clm_blob_image_size;
uint16_t dl_flag;
int ret = 0;
@@ -426,6 +368,10 @@ int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
#endif
#endif /* CONFIG_IEEE80211_BROADCOM_HAVE_CLM */
+/****************************************************************************
+ * Name: bcmf_wl_active
+ ****************************************************************************/
+
int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active)
{
int interface = CHIP_STA_INTERFACE;
@@ -434,12 +380,16 @@ int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active)
uint32_t value;
int ret;
- ret = bcmf_bus_sdio_active(priv, active);
+ ninfo("Entered\n");
+
+ ret = bcmf_bus_interface_active(priv, active);
if (ret != OK || !active)
{
return ret;
}
+ ninfo("Interface activated\n");
+
#ifdef CONFIG_IEEE80211_BROADCOM_HAVE_CLM
/* Download CLM blob if needed */
@@ -539,12 +489,16 @@ int bcmf_wl_active(FAR struct bcmf_dev_s *priv, bool active)
errout_in_sdio_active:
if (ret != OK)
{
- bcmf_bus_sdio_active(priv, false);
+ bcmf_bus_interface_active(priv, false);
}
return ret;
}
+/****************************************************************************
+ * Name: bcmf_driver_initialize
+ ****************************************************************************/
+
int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
{
int i;
@@ -592,21 +546,34 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
return bcmf_netdev_register(priv);
}
+/****************************************************************************
+ * Name: bcmf_wl_default_event_handler
+ ****************************************************************************/
+
void bcmf_wl_default_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event,
unsigned int len)
{
- wlinfo("Got event %" PRId32 " from <%s>\n",
+ wlinfo("Unhandled event %" PRId32 " from <%s>\n",
bcmf_getle32(&event->type),
event->src_name);
}
+/****************************************************************************
+ * Name: bcmf_wl_radio_event_handler
+ ****************************************************************************/
+
void bcmf_wl_radio_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event,
unsigned int len)
{
+ wlinfo("Unhandled radio event from <%s>\n", event->src_name);
}
+/****************************************************************************
+ * Name: bcmf_wl_auth_event_handler
+ ****************************************************************************/
+
void bcmf_wl_auth_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event,
unsigned int len)
@@ -642,6 +609,10 @@ void bcmf_wl_auth_event_handler(FAR struct bcmf_dev_s *priv,
}
}
+/****************************************************************************
+ * Name: bcmf_wl_scan_event_handler
+ ****************************************************************************/
+
/* bcmf_wl_scan_event_handler must run at high priority else
* race condition may occur on priv->scan_result field
*/
@@ -669,6 +640,8 @@ void bcmf_wl_scan_event_handler(FAR struct bcmf_dev_s *priv,
goto exit_invalid_frame;
}
+ wlinfo("Scan event from <%s>\n", event->src_name);
+
status = bcmf_getle32(&event->status);
escan_result_len = bcmf_getle32(&event->len);
@@ -809,6 +782,10 @@ exit_invalid_frame:
bcmf_hexdump((FAR uint8_t *)event, event_len, (unsigned long)event);
}
+/****************************************************************************
+ * Name: bcmf_wl_scan_format_results
+ ****************************************************************************/
+
static int bcmf_wl_scan_format_results(FAR struct bcmf_dev_s *priv,
FAR struct iwreq *iwr)
{
@@ -926,6 +903,10 @@ static int bcmf_wl_scan_format_results(FAR struct bcmf_dev_s *priv,
return OK;
}
+/****************************************************************************
+ * Name: bcmf_wl_scan_timeout
+ ****************************************************************************/
+
void bcmf_wl_scan_timeout(wdparm_t arg)
{
FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s *)arg;
@@ -944,6 +925,10 @@ void bcmf_wl_scan_timeout(wdparm_t arg)
nxsem_post(&priv->control_mutex);
}
+/****************************************************************************
+ * Name: bcmf_wl_get_interface
+ ****************************************************************************/
+
int bcmf_wl_get_interface(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
/* TODO resolve interface using iwr->ifr_name */
@@ -955,37 +940,83 @@ int bcmf_wl_get_interface(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
* Public Functions
****************************************************************************/
-int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev)
+/****************************************************************************
+ * Name: bcmf_allocate_device
+ ****************************************************************************/
+
+FAR struct bcmf_dev_s *bcmf_allocate_device(void)
{
int ret;
FAR struct bcmf_dev_s *priv;
- wlinfo("minor: %d\n", minor);
+ /* Allocate a bcmf device structure */
- priv = bcmf_allocate_device();
+ priv = (FAR struct bcmf_dev_s *)kmm_malloc(sizeof(*priv));
if (!priv)
{
- return -ENOMEM;
+ return NULL;
}
- /* Init sdio bus */
+ /* Initialize bcmf device structure */
- ret = bcmf_bus_sdio_initialize(priv, minor, dev);
- if (ret != OK)
+ memset(priv, 0, sizeof(*priv));
+
+ /* Init control frames mutex and timeout signal */
+
+ if ((ret = nxsem_init(&priv->control_mutex, 0, 1)) != OK)
{
- ret = -EIO;
- goto exit_free_device;
+ goto exit_free_priv;
}
- /* Bus initialized, register network driver */
+ if ((ret = nxsem_init(&priv->control_timeout, 0, 0)) != OK)
+ {
+ goto exit_free_priv;
+ }
- return bcmf_driver_initialize(priv);
+ if ((ret = nxsem_set_protocol(&priv->control_timeout, SEM_PRIO_NONE)) !=
+ OK)
+ {
+ goto exit_free_priv;
+ }
-exit_free_device:
- bcmf_free_device(priv);
- return ret;
+ /* Init authentication signal semaphore */
+
+ if ((ret = nxsem_init(&priv->auth_signal, 0, 0)) != OK)
+ {
+ goto exit_free_priv;
+ }
+
+ if ((ret = nxsem_set_protocol(&priv->auth_signal, SEM_PRIO_NONE)) != OK)
+ {
+ goto exit_free_priv;
+ }
+
+ /* Init scan timeout timer */
+
+ priv->scan_status = BCMF_SCAN_DISABLED;
+
+ return priv;
+
+exit_free_priv:
+ kmm_free(priv);
+ return NULL;
}
+/****************************************************************************
+ * Name: bcmf_free_device
+ ****************************************************************************/
+
+void bcmf_free_device(FAR struct bcmf_dev_s *priv)
+{
+ /* ## TODO ## deinitialize device structures */
+
+ kmm_free(priv);
+}
+
+/****************************************************************************
+ * Name: bcmf_wl_enable
+ ****************************************************************************/
+
int bcmf_wl_enable(FAR struct bcmf_dev_s *priv, bool enable)
{
int ret;
@@ -1009,6 +1040,13 @@ int bcmf_wl_enable(FAR struct bcmf_dev_s *priv, bool enable)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_start_scan
+ *
+ * Description:
+ * Start a WiFi scan.
+ ****************************************************************************/
+
int bcmf_wl_start_scan(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
int ret;
@@ -1130,11 +1168,20 @@ exit_sem_post:
priv->scan_status = BCMF_SCAN_DISABLED;
nxsem_post(&priv->control_mutex);
+ wlinfo("scan complete\n");
+
exit_failed:
wlinfo("Failed\n");
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_get_scan_results
+ *
+ * Description:
+ * Get the results of a WiFi scan.
+ ****************************************************************************/
+
int bcmf_wl_get_scan_results(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
int ret = OK;
@@ -1189,6 +1236,13 @@ exit_failed:
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_set_auth_param
+ *
+ * Description:
+ * Set the authorization parameters for the device
+ ****************************************************************************/
+
int bcmf_wl_set_auth_param(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
int ret = -ENOSYS;
@@ -1322,6 +1376,13 @@ int bcmf_wl_set_auth_param(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_set_mode
+ *
+ * Description:
+ * Set the mode for the device
+ ****************************************************************************/
+
int bcmf_wl_set_mode(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
uint32_t out_len;
@@ -1342,6 +1403,13 @@ int bcmf_wl_set_mode(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
WLC_SET_INFRA, (uint8_t *)&value, &out_len);
}
+/****************************************************************************
+ * Name: bcmf_wl_get_mode
+ *
+ * Description:
+ * Get the mode for the device
+ ****************************************************************************/
+
int bcmf_wl_get_mode(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
uint32_t out_len;
@@ -1386,6 +1454,13 @@ int bcmf_wl_get_mode(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_set_bssid
+ *
+ * Description:
+ * Set the bssid for the device
+ ****************************************************************************/
+
int bcmf_wl_set_bssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
uint32_t out_len;
@@ -1423,6 +1498,13 @@ int bcmf_wl_set_bssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_get_bssid
+ *
+ * Description:
+ * Get the bssid for the device
+ ****************************************************************************/
+
int bcmf_wl_get_bssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
uint32_t out_len;
@@ -1442,6 +1524,13 @@ int bcmf_wl_get_bssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
(uint8_t *)iwr->u.ap_addr.sa_data, &out_len);
}
+/****************************************************************************
+ * Name: bcmf_wl_get_channel
+ *
+ * Description:
+ * Get the channel for the device
+ ****************************************************************************/
+
int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
channel_info_t ci;
@@ -1467,6 +1556,13 @@ int bcmf_wl_get_channel(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_get_rate
+ *
+ * Description:
+ * Get the data rate for the device
+ ****************************************************************************/
+
int bcmf_wl_get_rate(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
uint32_t out_len;
@@ -1493,6 +1589,13 @@ int bcmf_wl_get_rate(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_get_txpower
+ *
+ * Description:
+ * Get the tranmit power for the device
+ ****************************************************************************/
+
int bcmf_wl_get_txpower(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
uint32_t out_len;
@@ -1531,6 +1634,13 @@ int bcmf_wl_get_txpower(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_get_iwrange
+ *
+ * Description:
+ * Get the iwrange for the device
+ ****************************************************************************/
+
int bcmf_wl_get_iwrange(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
struct iw_range *range;
@@ -1568,6 +1678,13 @@ int bcmf_wl_get_iwrange(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return OK;
}
+/****************************************************************************
+ * Name: bcmf_wl_get_rssi
+ *
+ * Description:
+ * Get the RSSI for the device
+ ****************************************************************************/
+
int bcmf_wl_get_rssi(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
wl_sta_rssi_t rssi;
@@ -1595,6 +1712,13 @@ int bcmf_wl_get_rssi(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_set_encode_ext
+ *
+ * Description:
+ * Set the encoding scheme for a device based on iwreq structure.
+ ****************************************************************************/
+
int bcmf_wl_set_encode_ext(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
int interface;
@@ -1634,6 +1758,13 @@ int bcmf_wl_set_encode_ext(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
WLC_SET_WSEC_PMK, (uint8_t *)&psk, &out_len);
}
+/****************************************************************************
+ * Name: bcmf_wl_set_ssid
+ *
+ * Description:
+ * Get the SSID for a device based on iwreq structure.
+ ****************************************************************************/
+
int bcmf_wl_set_ssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
int ret;
@@ -1698,6 +1829,13 @@ int bcmf_wl_set_ssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return OK;
}
+/****************************************************************************
+ * Name: bcmf_wl_get_ssid
+ *
+ * Description:
+ * Get the SSID for a device.
+ ****************************************************************************/
+
int bcmf_wl_get_ssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
{
uint32_t out_len;
@@ -1727,6 +1865,13 @@ int bcmf_wl_get_ssid(FAR struct bcmf_dev_s *priv, struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_set_country_code
+ *
+ * Description:
+ * Set a new country code.
+ ****************************************************************************/
+
int bcmf_wl_set_country_code(FAR struct bcmf_dev_s *priv,
int interface, FAR void *code)
{
@@ -1750,6 +1895,13 @@ int bcmf_wl_set_country_code(FAR struct bcmf_dev_s *priv,
&out_len);
}
+/****************************************************************************
+ * Name: bcmf_wl_set_country
+ *
+ * Description:
+ * Set a new country code based on data in an iwreq structure.
+ ****************************************************************************/
+
int bcmf_wl_set_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr)
{
int interface;
@@ -1764,6 +1916,13 @@ int bcmf_wl_set_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr)
return bcmf_wl_set_country_code(priv, interface, iwr->u.data.pointer);
}
+/****************************************************************************
+ * Name: bcmf_wl_get_country
+ *
+ * Description:
+ * Get the current country code.
+ ****************************************************************************/
+
int bcmf_wl_get_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr)
{
uint8_t country[4] =
@@ -1795,6 +1954,10 @@ int bcmf_wl_get_country(FAR struct bcmf_dev_s *priv, FAR struct iwreq *iwr)
return ret;
}
+/****************************************************************************
+ * Name: bcmf_wl_set_dtim
+ ****************************************************************************/
+
#ifdef CONFIG_IEEE80211_BROADCOM_LOWPOWER
int bcmf_wl_set_dtim(FAR struct bcmf_dev_s *priv,
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h
index 5433a0382e..ac1847304b 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_driver.h
@@ -139,6 +139,11 @@ struct bcmf_frame_s
* Public Function Prototypes
****************************************************************************/
+FAR struct bcmf_dev_s *bcmf_allocate_device(void);
+void bcmf_free_device(FAR struct bcmf_dev_s *priv);
+
+int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv);
+
/* IOCTLs network interface implementation */
int bcmf_wl_set_mac_address(FAR struct bcmf_dev_s *priv, struct ifreq *req);
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gpio.c
similarity index 51%
copy from drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c
copy to drivers/wireless/ieee80211/bcm43xxx/bcmf_gpio.c
index ab77418f46..7fdd0de542 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gpio.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43362.c
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_gpio.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -22,62 +22,65 @@
* Included Files
****************************************************************************/
-#include <nuttx/config.h>
-#include <stdint.h>
+#include <stdbool.h>
-#include "bcmf_sdio.h"
+#include <nuttx/wireless/ieee80211/bcmf_gpio.h>
+
+#include "bcmf_cdc.h"
+#include "bcmf_interface.h"
/****************************************************************************
- * Pre-processor Definitions
+ * Public Functions
****************************************************************************/
-#define WRAPPER_REGISTER_OFFSET 0x100000
-
/****************************************************************************
- * Public Data
+ * Name: bcmf_set_gpio
****************************************************************************/
-extern const char bcm43362_nvram_image[];
-extern const unsigned int bcm43362_nvram_image_len;
+int bcmf_set_gpio(FAR struct bcmf_dev_s *priv, int pin, bool value)
+{
+ struct
+ {
+ uint32_t mask;
+ uint32_t value;
+ } buffer;
-#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
-extern const uint8_t bcm43362_firmware_image[];
-extern const unsigned int bcm43362_firmware_image_len;
-#endif
+ uint32_t buf_len = sizeof(buffer);
-const struct bcmf_sdio_chip bcmf_43362_config_sdio =
-{
- /* General chip stats */
+ if (!(((FAR bcmf_interface_dev_t *)priv->bus)->ready)) return -EIO;
- .ram_base = 0,
- .ram_size = 0x3c000,
+ buffer.mask = 1 << pin;
+ buffer.value = value ? (1 << pin) : 0;
- /* Backplane architecture */
+ return bcmf_cdc_iovar_request(priv,
+ CHIP_STA_INTERFACE,
+ true,
+ IOVAR_STR_GPIOOUT,
+ (uint8_t *)&buffer,
+ &buf_len);
+}
- .core_base =
- {
- [CHIPCOMMON_CORE_ID] = 0x18000000, /* Chipcommon core register base */
- [DOT11MAC_CORE_ID] = 0x18001000, /* dot11mac core register base */
- [SDIOD_CORE_ID] = 0x18002000, /* SDIOD Device core register base */
- [WLAN_ARMCM3_CORE_ID] = 0x18003000 + /* ARMCM3 core register base */
- WRAPPER_REGISTER_OFFSET,
- [SOCSRAM_CORE_ID] = 0x18004000 + /* SOCSRAM core register base */
- WRAPPER_REGISTER_OFFSET
- },
+/****************************************************************************
+ * Name: bcmf_get_gpio
+ ****************************************************************************/
- /* Firmware images */
+int bcmf_get_gpio(FAR struct bcmf_dev_s *priv, int pin, bool *value)
+{
+ uint8_t buffer;
+ uint32_t buf_len = sizeof(buffer);
+ int ret;
- /* TODO find something smarter than using image_len references */
+ if (!(((FAR bcmf_interface_dev_t *)priv->bus)->ready)) return -EIO;
- .nvram_image = (FAR uint8_t *)bcm43362_nvram_image,
- .nvram_image_size = (FAR unsigned int *)&bcm43362_nvram_image_len,
+ ret = bcmf_cdc_iovar_request(priv,
+ CHIP_STA_INTERFACE,
+ false,
+ IOVAR_STR_CCGPIOIN,
+ (uint8_t *)&buffer,
+ &buf_len);
+ if (ret != OK) return ret;
-#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
- .firmware_image = (FAR uint8_t *)bcm43362_firmware_image,
- .firmware_image_size = (FAR unsigned int *)&bcm43362_firmware_image_len,
-#endif
-};
+ *value = (buffer & (1 << pin)) != 0;
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
+ return OK;
+}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.c
new file mode 100644
index 0000000000..8e64025874
--- /dev/null
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.c
@@ -0,0 +1,1135 @@
+/****************************************************************************
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <debug.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <nuttx/kmalloc.h>
+#include <nuttx/arch.h>
+#include <nuttx/kthread.h>
+#include <nuttx/wdog.h>
+#include <nuttx/signal.h>
+
+#include <nuttx/wireless/ieee80211/bcmf_board.h>
+
+#include "bcmf_gspi.h"
+#include "bcmf_gspi_f2_frame.h"
+#include "bcmf_core.h"
+#include "bcmf_sdpcm.h"
+#include "bcmf_utils.h"
+
+#include "bcmf_sdio_core.h"
+#include "bcmf_sdio_regs.h"
+#include "cyw_reg_def.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define BCMF_GSPI_READY_TRYS 10
+#define BCMF_GSPI_THREAD_NAME "bcmf-gspi-thread"
+#define BCMF_GSPI_THREAD_STACK_SIZE 2048
+#define BCMF_GSPI_LOWPOWER_TIMEOUT_TICK SEC2TICK(2)
+
+#ifdef CONFIG_IEEE80211_INFINEON_CYW43439
+extern const struct bcmf_chip_data cyw43439_config_data;
+#endif
+
+#define REV16(x) (((x & 0x000000ff) << 8) \
+ | ((x & 0x0000ff00) >> 8) \
+ | ((x & 0x00ff0000) << 8) \
+ | ((x & 0xff000000) >> 8))
+
+/* Chip-common registers */
+
+#define CHIPCOMMON_GPIO_CONTROL ((uint32_t)(0x18000000 + 0x06c) )
+#define CHIPCOMMON_SR_CONTROL0 ((uint32_t)(0x18000000 + 0x504) )
+#define CHIPCOMMON_SR_CONTROL1 ((uint32_t)(0x18000000 + 0x508) )
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcmf_gspi_read_reg_32
+ *
+ * Description:
+ * Read a 32-bit register
+ *
+ ****************************************************************************/
+
+static inline uint32_t bcmf_gspi_read_reg_32(FAR gspi_dev_t *gspi,
+ enum gspi_cmd_func_e function,
+ uint32_t address)
+{
+ uint32_t buffer;
+
+ gspi->read(gspi, true, function, address, 4, &buffer);
+
+ return buffer;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_read_reg_16
+ *
+ * Description:
+ * Read a 32-bit register
+ *
+ ****************************************************************************/
+
+static inline uint16_t bcmf_gspi_read_reg_16(FAR gspi_dev_t *gspi,
+ enum gspi_cmd_func_e function,
+ uint32_t address)
+{
+ uint32_t buffer;
+
+ gspi->read(gspi, true, function, address, 2, &buffer);
+
+ return buffer;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_read_reg_8
+ *
+ * Description:
+ * Read a 32-bit register
+ *
+ ****************************************************************************/
+
+static inline uint8_t bcmf_gspi_read_reg_8(FAR gspi_dev_t *gspi,
+ enum gspi_cmd_func_e function,
+ uint32_t address)
+{
+ uint32_t buffer;
+
+ gspi->read(gspi, true, function, address, 1, &buffer);
+
+ return buffer;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_write_reg_32
+ *
+ * Description:
+ * Write a 32-bit register
+ *
+ ****************************************************************************/
+
+static inline void bcmf_gspi_write_reg_32(FAR gspi_dev_t *gspi,
+ enum gspi_cmd_func_e function,
+ uint32_t address,
+ uint32_t value)
+{
+ gspi->write(gspi, true, function, address, 4, &value);
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_write_reg_16
+ *
+ * Description:
+ * Read a 32-bit register
+ *
+ ****************************************************************************/
+
+static inline void bcmf_gspi_write_reg_16(FAR gspi_dev_t *gspi,
+ enum gspi_cmd_func_e function,
+ uint32_t address,
+ uint32_t value)
+{
+ gspi->write(gspi, true, function, address, 2, &value);
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_write_reg_8
+ *
+ * Description:
+ * Write a 8-bit register
+ *
+ ****************************************************************************/
+
+static inline void bcmf_gspi_write_reg_8(FAR gspi_dev_t *gspi,
+ enum gspi_cmd_func_e function,
+ uint32_t address,
+ uint32_t value)
+{
+ gspi->write(gspi, true, function, address, 1, &value);
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_kso_enable
+ ****************************************************************************/
+
+static int bcmf_gspi_kso_enable(FAR bcmf_gspi_dev_t *gbus, bool enable)
+{
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ uint8_t value;
+ int loops;
+
+ if (!gbus->ready)
+ {
+ return -EPERM;
+ }
+
+ if (gbus->kso_enable == enable)
+ {
+ return OK;
+ }
+
+ if (enable)
+ {
+ wlinfo("enable\n");
+
+ loops = 200;
+ while (--loops > 0)
+ {
+ bcmf_gspi_write_reg_8(gspi,
+ gspi_f1_backplane,
+ SBSDIO_FUNC1_SLEEPCSR,
+ SBSDIO_FUNC1_SLEEPCSR_KSO_MASK
+ | SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK);
+
+ nxsig_usleep(100 * 1000);
+
+ value = bcmf_gspi_read_reg_8(gspi, 1, SBSDIO_FUNC1_SLEEPCSR);
+
+ if ((value & (SBSDIO_FUNC1_SLEEPCSR_KSO_MASK |
+ SBSDIO_FUNC1_SLEEPCSR_DEVON_MASK)) != 0)
+ {
+ break;
+ }
+ }
+
+ if (loops <= 0)
+ {
+ return -ETIMEDOUT;
+ }
+ }
+ else
+ {
+ wlinfo("disable\n");
+
+ bcmf_gspi_write_reg_8(gspi, 1, SBSDIO_FUNC1_SLEEPCSR, 0);
+ }
+
+ gbus->kso_enable = enable;
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_bus_sleep
+ ****************************************************************************/
+
+static int bcmf_gspi_bus_sleep(FAR bcmf_gspi_dev_t *gbus, bool sleep)
+{
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ uint8_t value;
+ int loops;
+
+ if (!gbus->ready)
+ {
+ return -EPERM;
+ }
+
+ if (gbus->sleeping == sleep)
+ {
+ return OK;
+ }
+
+ if (sleep)
+ {
+ wlinfo("enable\n");
+
+ gbus->sleeping = true;
+ bcmf_gspi_write_reg_8(gspi,
+ gspi_f1_backplane,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ 0);
+
+ wlinfo("exit\n");
+
+ return OK;
+ }
+ else
+ {
+ wlinfo("disable\n");
+
+ loops = 200;
+ while (--loops > 0)
+ {
+ /* Request HT Avail */
+
+ bcmf_gspi_write_reg_8(gspi,
+ gspi_f1_backplane,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ SBSDIO_HT_AVAIL_REQ
+ | SBSDIO_FORCE_HT);
+
+ /* Wait for High Throughput clock */
+
+ nxsig_usleep(100 * 1000);
+ value = bcmf_gspi_read_reg_8(gspi, 1, SBSDIO_FUNC1_CHIPCLKCSR);
+
+ if (value & SBSDIO_HT_AVAIL)
+ {
+ /* High Throughput clock is ready */
+
+ break;
+ }
+ }
+
+ if (loops <= 0)
+ {
+ wlerr("HT clock not ready\n");
+ return -ETIMEDOUT;
+ }
+
+ gbus->sleeping = false;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_bus_lowpower
+ ****************************************************************************/
+
+static int bcmf_gspi_bus_lowpower(FAR bcmf_gspi_dev_t *gbus, bool enable)
+{
+ return gbus->support_sr ? bcmf_gspi_kso_enable(gbus, !enable)
+ : bcmf_gspi_bus_sleep(gbus, enable);
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_thread_isr
+ ****************************************************************************/
+
+static int bcmf_gspi_thread_isr(int isr, void *context, void *arg)
+{
+ FAR bcmf_gspi_dev_t *gbus = (FAR bcmf_gspi_dev_t *) arg;
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ int semcount;
+
+ gbus->irq_pending = true;
+
+ nxsem_get_value(&gbus->thread_signal, &semcount);
+
+ if (semcount < 1)
+ {
+ nxsem_post(&gbus->thread_signal);
+ }
+
+ /* Disable interrupt until bcmf_gspi_thread runs */
+
+ gspi->interrupt_enable(gspi, false);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_thread
+ ****************************************************************************/
+
+static int bcmf_gspi_thread(int argc, char **argv)
+{
+ FAR struct bcmf_dev_s *priv;
+ FAR bcmf_gspi_dev_t *gbus;
+ FAR gspi_dev_t *gspi;
+ uint32_t status;
+ uint16_t intr_flags;
+ int ret;
+ int length;
+ int wait_count = 0;
+ bool wait_for_event;
+ bool enter_low_power = false;
+
+ priv = (FAR struct bcmf_dev_s *)((uintptr_t)strtoul(argv[1], NULL, 16));
+ gbus = (FAR bcmf_gspi_dev_t *)priv->bus;
+ gspi = gbus->gspi;
+
+ wlinfo(">>>> entered\n");
+
+ nxsig_usleep(50 * 1000);
+
+ gbus->thread_run = true;
+
+ bcmf_gspi_bus_lowpower(gbus, false);
+
+ while (gbus->thread_run)
+ {
+ /* Preset the wait for event flag in case we have nothing to do */
+
+ wait_for_event = true;
+
+ /* Get the device status */
+
+ status = bcmf_gspi_read_reg_32(gspi, gspi_f0_bus, CYW_REG_STATUS);
+
+#ifdef CONFIG_DEBUG_WIRELESS_ERROR
+ if (status & (1 << 2))
+ {
+ wlerr("CYW_REG_STATUS_FIFO_OVERFLOW\n");
+ }
+
+ if (status & (1 << 7))
+ {
+ wlerr("CYW_REG_STATUS_CMD_DATA_ERROR\n");
+ }
+#endif
+
+ /* If we were woken by an device interrupt clear the interrupt bits. */
+
+ if (gbus->irq_pending)
+ {
+ gbus->irq_pending = false;
+
+ /* These call also update the status in gspi->status */
+
+ intr_flags = bcmf_gspi_read_reg_16(gspi,
+ gspi_f0_bus,
+ CYW_REG_INTERRUPT);
+
+ if (intr_flags != 0)
+ {
+ bcmf_gspi_write_reg_16(gspi,
+ gspi_f0_bus,
+ CYW_REG_INTERRUPT,
+ intr_flags);
+ }
+ }
+
+ /* If we have a packet available to read -- read it */
+
+ if (status & CYW_REG_STATUS_F2_PKT_AVAIL)
+ {
+ length = status & CYW_REG_STATUS_F2_PKT_LEN_MASK;
+ length >>= CYW_REG_STATUS_F2_PKT_LEN_SHIFT;
+
+ /* If we don't have a frame leave the loop */
+
+ if (length == 0) break;
+
+ /* Read and process frame. This updates gspi->status */
+
+ ret = bcmf_gspi_read_f2_frame(priv, length);
+
+ if (ret == OK)
+ {
+ wait_for_event = false;
+ }
+ else
+ {
+ wlerr("error reading f2 frame: %d\n", ret);
+ }
+ }
+ else
+ {
+ /* If we don't have anything to read, try sending a packet */
+
+ while ((status & CYW_REG_STATUS_F2_RECEIVE_RDY) == 0)
+ {
+ /* Oops! no room for a packet. We'll wait a bit to see
+ * if room shows up.
+ */
+
+ wlinfo(">>>> not ready to receive\n");
+
+ if (++wait_count > 100)
+ {
+ wlerr("Chip cannot receive F2 frame\n");
+ break;
+ }
+
+ /* No room at the inn for an f2 frame -- wait a bit */
+
+ usleep(10000);
+
+ status = bcmf_gspi_read_reg_32(gspi,
+ gspi_f0_bus,
+ CYW_REG_STATUS);
+ }
+
+ /* reset the count for next time */
+
+ wait_count = 0;
+
+ /* We have space, send the frame */
+
+ ret = bcmf_gspi_send_f2_frame(priv);
+
+ if (ret == OK)
+ {
+ wait_for_event = false;
+ }
+ else
+ {
+#ifdef CONFIG_DEBUG_WIRELESS_ERROR
+ if (ret != -ENODATA)
+ {
+ wlerr("error sending f2 frame: %d\n", ret);
+ }
+#endif
+ }
+ }
+
+ /* No more transfer requests. Wait for something to happen. */
+
+ if (wait_for_event)
+ {
+ /* Wait for event (device interrupt or user request) */
+
+ gspi->interrupt_enable(gspi, true);
+
+ if (enter_low_power)
+ {
+ enter_low_power = false;
+
+ bcmf_gspi_bus_lowpower(gbus, true);
+ nxsem_wait_uninterruptible(&gbus->thread_signal);
+ bcmf_gspi_bus_lowpower(gbus, false);
+ }
+ else
+ {
+ ret = nxsem_tickwait_uninterruptible(
+ &gbus->thread_signal,
+ BCMF_GSPI_LOWPOWER_TIMEOUT_TICK);
+
+ if (ret == -ETIMEDOUT) enter_low_power = true;
+ }
+ }
+ }
+
+ wlinfo(">>>> exit\n");
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_init_device
+ *
+ * Description:
+ * Keeps checking the 43439's test register looking for the test pattern.
+ * When found puts the chip in 32-bit mode.
+ *
+ * Note:
+ * Some calls to the 43439 in this function uses the "magic" rev16 mode
+ * to account for the 16-bit mode's default byte ordering.
+ ****************************************************************************/
+
+static int bcmf_gspi_init_device(FAR bcmf_gspi_dev_t *gbus)
+{
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ uint32_t buffer[2];
+ uint32_t data;
+ int ret;
+ int i;
+
+ wlinfo("entered.\n");
+
+ /* Look for the chip ready pattern. */
+
+ for (i = 0; i < BCMF_GSPI_READY_TRYS; ++i)
+ {
+ ret = gspi->read(gspi,
+ true,
+ gspi_f0_bus_rev16,
+ CYW_REG_TEST_RO,
+ 4,
+ buffer);
+
+ if (ret != 0)
+ {
+ wlerr("Error looking for \"ready\" pattern: %d\n", ret);
+ return ret;
+ }
+
+ if (REV16(buffer[0]) == CYW_REG_TEST_RO_PATTERN) break;
+ }
+
+ if (i == BCMF_GSPI_READY_TRYS)
+ {
+ wlerr("Could not find cyw43439 \"ready\" pattern\n");
+ return -ENODEV;
+ }
+
+ data = CYW_REG_SETUP_WORD_LEN_32
+ | CYW_REG_SETUP_BIG_ENDIAN
+ | CYW_REG_SETUP_HIGH_SPEED
+ | CYW_REG_SETUP_INT_POLARITY
+ | CYW_REG_SETUP_WAKE_UP
+ | CYW_REG_STAT_ENA_INTR_STAT;
+
+ data = REV16(data);
+
+ gspi->write(gspi, true, gspi_f0_bus_rev16, CYW_REG_SETUP, 4, &data);
+
+ /* We are now in 32-bit bigendian mode -- we no longer do REV16s. */
+
+ /* Set a 4-byte response delay for F1 packets */
+
+ bcmf_gspi_write_reg_8(gspi, gspi_f0_bus, CYW_REG_RESP_DELAY_F1, 4);
+
+ wlinfo("complete\n");
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_probe_chip
+ ****************************************************************************/
+
+static int bcmf_gspi_probe_chip(FAR bcmf_gspi_dev_t *gbus)
+{
+ uint32_t value;
+ int chipid;
+ int ret;
+
+ wlinfo("entered\n");
+
+ ret = bcmf_read_sbregw(gbus, SI_ENUM_BASE, &value);
+ if (ret != OK)
+ {
+ wlerr("bcmf_read_sbregw failed\n");
+ return ret;
+ }
+
+ chipid = value & 0xffff;
+ gbus->cur_chip_id = chipid;
+
+ switch (chipid)
+ {
+#ifdef CONFIG_IEEE80211_INFINEON_CYW43439
+ case SDIO_DEVICE_ID_INFINEON_CYW43439:
+ wlinfo("cyw%d chip detected\n", chipid);
+ gbus->chip = (struct bcmf_chip_data *)&cyw43439_config_data;
+ break;
+#endif
+
+ default:
+ wlerr("chip 0x%08X is not supported\n", chipid);
+ return -ENODEV;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_setup_interrupts
+ ****************************************************************************/
+
+static int bcmf_gspi_setup_interrupts(FAR bcmf_gspi_dev_t *gbus)
+{
+ FAR gspi_dev_t *gspi = gbus->gspi;
+
+ wlinfo("entered\n");
+
+ /* Set up device interrupt preferences */
+
+ bcmf_gspi_write_reg_16(gspi,
+ gspi_f0_bus,
+ CYW_REG_INTERRUPT,
+ CYW_REG_INTERRUPT_DATA_NOT_AVAIL
+ | CYW_REG_INTERRUPT_COMMAND_ERROR
+ | CYW_REG_INTERRUPT_DATA_ERROR
+ | CYW_REG_INTERRUPT_F1_OVERFLOW);
+
+ /* We only want an interrupt if an F2 packet is available */
+
+ bcmf_gspi_write_reg_16(gspi,
+ gspi_f0_bus,
+ CYW_REG_INTR_ENA,
+ CYW_REG_INTR_ENA_F2_PKT_AVAIL);
+
+ wlinfo("interrupt set up complete\n");
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_init_alp_clock
+ ****************************************************************************/
+
+static int bcmf_gspi_init_alp_clock(FAR bcmf_gspi_dev_t *gbus)
+{
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ int loops;
+ uint8_t value;
+
+ wlinfo("entered\n");
+
+ /* Send Active Low-Power clock request */
+
+ bcmf_gspi_write_reg_8(gspi,
+ gspi_f1_backplane,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ SBSDIO_FORCE_HW_CLKREQ_OFF
+ | SBSDIO_ALP_AVAIL_REQ
+ | SBSDIO_FORCE_ALP);
+
+ loops = 10;
+ while (--loops > 0)
+ {
+ nxsig_usleep(10 * 1000);
+
+ value = bcmf_gspi_read_reg_8(gspi,
+ gspi_f1_backplane,
+ SBSDIO_FUNC1_CHIPCLKCSR);
+
+ if (value & SBSDIO_ALP_AVAIL)
+ {
+ /* Active Low-Power clock is ready */
+
+ break;
+ }
+ }
+
+ if (loops <= 0)
+ {
+ wlerr("failed to enable ALP\n");
+ return -ETIMEDOUT;
+ }
+
+ /* Clear Active Low-Power clock request */
+
+ bcmf_gspi_write_reg_8(gspi,
+ gspi_f1_backplane,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ 0);
+
+ wlinfo("ALP initialization complete\n");
+
+ nxsig_usleep(100 * 1000);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_init_save_restore
+ ****************************************************************************/
+
+static int bcmf_gspi_init_save_restore(FAR bcmf_gspi_dev_t *gbus)
+{
+ uint8_t data;
+ uint32_t srctrl = 0;
+ int ret;
+
+ wlinfo("entered\n");
+
+ ret = bcmf_read_sbregw(gbus, CHIPCOMMON_SR_CONTROL1, &srctrl);
+ if (ret != OK)
+ {
+ wlinfo("exit -- not SR capable.\n");
+
+ return OK; /* chip not sr capable */
+ }
+
+ if (srctrl != 0)
+ {
+ /* Configure WakeupCtrl register to set HtAvail request bit in
+ * chipClockCSR register after the sdiod core is powered on.
+ */
+
+ bcmf_read_reg(gbus, 1, SBSDIO_FUNC1_WAKEUPCTRL, &data);
+ data |= SBSDIO_FUNC1_WCTRL_HTWAIT_MASK;
+ bcmf_write_reg(gbus, 1, SBSDIO_FUNC1_WAKEUPCTRL, data);
+
+ /* Set brcmCardCapability to noCmdDecode mode.
+ * It makes sdiod_aos to wakeup host for any activity of cmd line,
+ * even though module won't decode cmd or respond
+ */
+
+ bcmf_write_reg(gbus, 0, SDIO_CCCR_BRCM_CARDCAP,
+ SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC);
+ bcmf_write_reg(gbus, 1, SBSDIO_FUNC1_CHIPCLKCSR,
+ SBSDIO_FORCE_HT);
+
+ /* Enable KeepSdioOn (KSO) bit for normal operation */
+
+ bcmf_gspi_kso_enable(gbus, true);
+
+ gbus->support_sr = true;
+ }
+
+ wlinfo("exit\n");
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_hw_uninitialize
+ ****************************************************************************/
+
+static int bcmf_gspi_hw_uninitialize(FAR bcmf_gspi_dev_t *gbus)
+{
+ FAR gspi_dev_t *gspi = gbus->gspi;
+
+ wlinfo("entered\n");
+
+ if (gbus->thread_id != 0)
+ {
+ gbus->thread_run = false;
+ nxsem_post(&gbus->thread_signal);
+ }
+
+ gspi->deinit(gspi);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_bus_gspi_initialize
+ *
+ * Description:
+ * Initialize a bcmf device connected via gSPI interface.
+ *
+ ****************************************************************************/
+
+static int bcmf_bus_gspi_initialize(FAR struct bcmf_dev_s *priv,
+ FAR struct gspi_dev_s *gspi)
+{
+ FAR bcmf_gspi_dev_t *gbus;
+ int ret;
+
+ wlinfo("entered.\n");
+
+ /* Allocate gSPI bus structure */
+
+ gbus = (FAR bcmf_gspi_dev_t *)kmm_zalloc(sizeof(*gbus));
+
+ if (!gspi)
+ {
+ return -ENOMEM;
+ }
+
+ /* Initialize sdio bus device structure */
+
+ gbus->gspi = gspi;
+ gbus->ready = false;
+ gbus->sleeping = true;
+
+ /* FIX ME -- The interface needs some room to send F2 packets
+ * to the device before we've read the first F2
+ * packet from the device, so we set the max_seq
+ * to something small;
+ */
+
+ gbus->max_seq = 4;
+
+ gbus->bus.txframe = bcmf_sdpcm_queue_frame;
+ gbus->bus.rxframe = bcmf_sdpcm_get_rx_frame;
+ gbus->bus.allocate_frame = bcmf_sdpcm_alloc_frame;
+ gbus->bus.free_frame = bcmf_sdpcm_free_frame;
+ gbus->bus.stop = NULL; /* TODO */
+
+ /* Init transmit frames queue */
+
+ if ((ret = nxsem_init(&gbus->queue_mutex, 0, 1)) != OK)
+ {
+ goto exit_free_bus;
+ }
+
+ list_initialize(&gbus->tx_queue);
+ list_initialize(&gbus->rx_queue);
+
+ /* Setup free buffer list */
+
+ bcmf_initialize_interface_frames();
+
+ /* Init thread semaphore */
+
+ if ((ret = nxsem_init(&gbus->thread_signal, 0, 0)) != OK)
+ {
+ goto exit_free_bus;
+ }
+
+ if ((ret = nxsem_set_protocol(&gbus->thread_signal, SEM_PRIO_NONE)) != OK)
+ {
+ goto exit_free_bus;
+ }
+
+ /* Register sdio bus */
+
+ priv->bus = &gbus->bus;
+
+ /* Save a back pointer so we can recover driver state */
+
+ gspi->priv = priv;
+
+ wlinfo("complete.\n");
+
+ return OK;
+
+exit_free_bus:
+
+ wlinfo("failed.\n");
+
+ kmm_free(gbus);
+ priv->bus = NULL;
+ return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcmf_gspi_initialize
+ *
+ * Description:
+ * Initialize the drive with a gSPI connection.
+ ****************************************************************************/
+
+int bcmf_gspi_initialize(FAR struct gspi_dev_s *gspi)
+{
+ int ret;
+ FAR struct bcmf_dev_s *priv;
+
+ ninfo("entered.\n");
+
+ priv = bcmf_allocate_device();
+ if (!priv)
+ {
+ return -ENOMEM;
+ }
+
+ /* Init sdio bus */
+
+ ret = bcmf_bus_gspi_initialize(priv, gspi);
+ if (ret != OK)
+ {
+ ret = -EIO;
+ goto exit_free_device;
+ }
+
+ /* Bus initialized, register network driver */
+
+ return bcmf_driver_initialize(priv);
+
+exit_free_device:
+ bcmf_free_device(priv);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcmf_bus_gspi_active
+ *
+ * Description:
+ * Activate (or deactivate) a bcmf device connected via gSPI interface.
+ ****************************************************************************/
+
+int bcmf_bus_gspi_active(FAR struct bcmf_dev_s *priv,
+ bool active)
+{
+ FAR bcmf_gspi_dev_t *gbus = (FAR bcmf_gspi_dev_t *)priv->bus;
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ int ret = OK;
+ FAR char *argv[2];
+ char arg1[32];
+
+ wlinfo("entered. active = %d\n", active);
+
+ if (!active)
+ {
+ goto exit_uninit_hw;
+ }
+
+ /* Initialize device hardware */
+
+ ret = gspi->init(gspi);
+
+ if (ret != OK)
+ {
+ return ret;
+ }
+
+ gbus->ready = active;
+
+ /* Probe device */
+
+ ret = bcmf_gspi_init_device(gbus);
+ if (ret != OK)
+ {
+ goto exit_uninit_hw;
+ }
+
+ /* Detect and configure for specific chip */
+
+ ret = bcmf_gspi_probe_chip(gbus);
+ if (ret != OK)
+ {
+ wlerr("bcmf_gspi_probe_chip failed\n");
+ goto exit_uninit_hw;
+ }
+
+ ret = bcmf_gspi_setup_interrupts(gbus);
+ if (ret != OK)
+ {
+ goto exit_uninit_hw;
+ }
+
+ /* Active the low power clock */
+
+ ret = bcmf_gspi_init_alp_clock(gbus);
+ if (ret != OK)
+ {
+ goto exit_uninit_hw;
+ }
+
+ /* Upload firmware */
+
+ ret = bcmf_core_upload_firmware(gbus);
+ if (ret != OK)
+ {
+ wlerr("bcmf_core_upload_firmware failed\n");
+ goto exit_uninit_hw;
+ }
+
+ /* Spawn bcmf daemon thread */
+
+ snprintf(arg1, sizeof(arg1), "%p", priv);
+ argv[0] = arg1;
+ argv[1] = NULL;
+ ret = kthread_create(BCMF_GSPI_THREAD_NAME,
+ CONFIG_IEEE80211_BROADCOM_SCHED_PRIORITY,
+ BCMF_GSPI_THREAD_STACK_SIZE,
+ bcmf_gspi_thread,
+ argv);
+ if (ret <= 0)
+ {
+ wlerr("Cannot spawn daemon thread\n");
+ ret = -EBADE;
+ goto exit_uninit_hw;
+ }
+
+ gbus->thread_id = (pid_t)ret;
+
+ ret = gspi->set_isr(gspi, bcmf_gspi_thread_isr, gbus);
+
+ if (ret != OK)
+ {
+ wlerr("set_isr failed\n");
+ goto exit_uninit_hw;
+ }
+
+ ret = bcmf_gspi_init_save_restore(gbus);
+ if (ret != OK)
+ {
+ goto exit_uninit_hw;
+ }
+
+ return OK;
+
+exit_uninit_hw:
+ gbus->ready = false;
+ bcmf_gspi_hw_uninitialize(gbus);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcmf_transfer_bytes
+ ****************************************************************************/
+
+/* FIXME: Low level bus data transfer function
+ * To avoid bus error, len will be aligned to:
+ * - upper power of 2 iflen is lesser than 64
+ * - upper 64 bytes block if len is greater than 64
+ */
+
+int bcmf_transfer_bytes(FAR bcmf_gspi_dev_t *gbus,
+ bool write,
+ uint8_t function,
+ uint32_t address,
+ uint8_t *buf,
+ unsigned int len)
+{
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ int ret;
+
+ DEBUGASSERT((((uintptr_t) buf) & 0x03) == 0); /* make sure buf is word aligned */
+
+ if (write)
+ {
+ ret = gspi->write(gspi,
+ true,
+ function,
+ address,
+ len,
+ (FAR uint32_t *) buf);
+
+ return ret;
+ }
+
+ /* -- read btytes -- */
+
+ ret = gspi->read(gspi,
+ true,
+ function,
+ address,
+ len,
+ (FAR uint32_t *) buf);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcmf_read_reg
+ ****************************************************************************/
+
+int bcmf_read_reg(FAR bcmf_gspi_dev_t *gbus,
+ uint8_t function,
+ uint32_t address,
+ uint8_t *reg)
+{
+ *reg = bcmf_gspi_read_reg_8(gbus->gspi, function, address);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: bcmf_write_reg
+ ****************************************************************************/
+
+int bcmf_write_reg(FAR bcmf_gspi_dev_t *gbus,
+ uint8_t function,
+ uint32_t address,
+ uint8_t reg)
+{
+ bcmf_gspi_write_reg_8(gbus->gspi, function, address, reg);
+
+ return OK;
+}
+
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.h
new file mode 100644
index 0000000000..58cd1d361e
--- /dev/null
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_GSPI_H
+#define __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_GSPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <nuttx/list.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/wireless/ieee80211/bcmf_gspi.h>
+
+#include "bcmf_chip_data.h"
+#include "bcmf_driver.h"
+#include "bcmf_sdio_core.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define HEADER_SIZE 0x12 /* Default sdpcm + bdc header size */
+#define FIRST_WORD_SIZE 4
+#define FC_UPDATE_PKT_LENGTH 12
+
+#define BCMF_UPLOAD_TRANSFER_SIZE 64
+
+/* gSPI bus structure extension */
+
+typedef struct bcmf_gspi_dev_s
+{
+ struct bcmf_bus_dev_s bus; /* Default bcmf bus structure */
+ FAR struct gspi_dev_s *gspi; /* The gSPI device bound to this instance */
+
+ int cur_chip_id; /* Chip ID read from the card */
+ struct bcmf_chip_data *chip; /* Chip specific configuration */
+
+ volatile bool ready; /* Current device status */
+ bool sleeping; /* Current sleep status */
+ bool kso_enable; /* Current Keep sdio on status */
+ bool support_sr; /* Firmware support save restore */
+
+ pid_t thread_id; /* Processing thread id */
+ sem_t thread_signal; /* Semaphore for processing thread event */
+ volatile bool thread_run; /* Set false to exit processing thread */
+ volatile bool irq_pending; /* True if interrupt is pending */
+
+ uint32_t backplane_current_addr; /* Current function 1 backplane base addr */
+
+ uint8_t max_seq; /* Maximum transmit sequence allowed */
+ uint8_t tx_seq; /* Transmit sequence number (next) */
+
+ sem_t queue_mutex; /* Lock for TX/RX/free queues */
+ struct list_node tx_queue; /* Queue of frames to transmit */
+ struct list_node rx_queue; /* Queue of frames used to receive */
+ volatile int tx_queue_count; /* Count of items in TX queue */
+} bcmf_gspi_dev_t;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int bcmf_gspi_initialize(FAR struct gspi_dev_s *gspi);
+
+int bcmf_bus_gspi_active(FAR struct bcmf_dev_s *priv,
+ bool active);
+
+/* FIXME: Low level bus data transfer function
+ * To avoid bus error, len will be aligned to:
+ * - upper power of 2 iflen is lesser than 64
+ * - upper 64 bytes block if len is greater than 64
+ */
+
+int bcmf_transfer_bytes(FAR bcmf_gspi_dev_t *gbus,
+ bool write,
+ uint8_t function,
+ uint32_t address,
+ uint8_t *buf,
+ unsigned int len);
+
+int bcmf_read_reg(FAR bcmf_gspi_dev_t *gbus,
+ uint8_t function,
+ uint32_t address,
+ uint8_t *reg);
+
+int bcmf_write_reg(FAR bcmf_gspi_dev_t *gbus,
+ uint8_t function,
+ uint32_t address,
+ uint8_t reg);
+
+#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_GSPI_H */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.c
new file mode 100644
index 0000000000..c534982baa
--- /dev/null
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.c
@@ -0,0 +1,394 @@
+/****************************************************************************
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/compiler.h>
+
+#include <debug.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <nuttx/arch.h>
+
+#include <stddef.h>
+#include <string.h>
+
+#include "bcmf_core.h"
+#include "bcmf_sdpcm.h"
+#include "bcmf_cdc.h"
+#include "bcmf_bdc.h"
+#include "bcmf_utils.h"
+
+ #include "bcmf_netdev.h"
+
+#include "bcmf_sdio_regs.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define F2_FRAME_CONTROL_CHANNEL 0 /* Control frame id */
+#define F2_FRAME_EVENT_CHANNEL 1 /* Asynchronous event frame id */
+#define F2_FRAME_DATA_CHANNEL 2 /* Data frame id */
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+begin_packed_struct struct f2_frame_header_s
+{
+ uint16_t size;
+ uint16_t checksum;
+ uint8_t sequence;
+ uint8_t channel;
+ uint8_t next_length;
+ uint8_t data_offset;
+ uint8_t flow_control;
+ uint8_t credit;
+ uint16_t padding;
+} end_packed_struct;
+
+typedef struct f2_frame_header_s f2_frame_header_t;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: f2_frame_rx_fail
+ ****************************************************************************/
+
+static int f2_frame_rx_fail(FAR bcmf_gspi_dev_t *gbus, bool retry)
+{
+ /* issue abort command for F2 through F0 */
+
+ bcmf_bus_io_abort(gbus);
+
+ bcmf_write_reg(gbus, 1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM);
+
+ /* TODO Wait until the packet has been flushed (device/FIFO stable) */
+
+ if (retry)
+ {
+ /* Send NAK to retry to read frame */
+
+ bcmf_write_sbregb(gbus,
+ CORE_BUS_REG(gbus->chip->core_base[SDIOD_CORE_ID],
+ tosbmailbox),
+ SMB_NAK);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: process_f2_frame_header
+ ****************************************************************************/
+
+int process_f2_frame_header(FAR bcmf_interface_dev_t *gbus,
+ f2_frame_header_t *header)
+{
+ if (header->data_offset < sizeof(f2_frame_header_t)
+ || header->data_offset > header->size)
+ {
+ wlerr("Invalid data offset\n");
+ f2_frame_rx_fail(gbus, false);
+ return -ENXIO;
+ }
+
+ /* Update tx credits */
+
+ gbus->max_seq = header->credit;
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: read_f2_frame
+ *
+ * Description:
+ * Read and process an F2 frame.
+ *
+ * Parameters:
+ * priv - the device structure
+ * frame_length - Length of frame we are to read. (From chip status)
+ *
+ * Returns:
+ * OK on success, negated error code on failure.
+ ****************************************************************************/
+
+int bcmf_gspi_read_f2_frame(FAR struct bcmf_dev_s *priv,
+ int frame_length)
+{
+ FAR bcmf_gspi_dev_t *gbus = (FAR bcmf_gspi_dev_t *)priv->bus;
+ FAR gspi_dev_t *gspi = gbus->gspi;
+
+ bcmf_interface_frame_t *iframe;
+ f2_frame_header_t *header;
+ int ret;
+ uint16_t checksum;
+
+ /* Request free frame buffer */
+
+ if (frame_length <= sizeof(f2_frame_header_t))
+ {
+ return -EINVAL;
+ }
+
+ iframe = bcmf_interface_allocate_frame(priv, false, false);
+
+ if (iframe == NULL)
+ {
+ wlinfo("fail alloc\n");
+ return -EAGAIN;
+ }
+
+ if (frame_length > iframe->header.len)
+ {
+ wlerr("Frame is too large, cancel %d > %d\n",
+ frame_length,
+ iframe->header.len);
+
+ ret = -ENOMEM;
+ goto exit_abort;
+ }
+
+ /* Read the frame data (the buffer is DMA aligned here) */
+
+ ret = gspi->read(gspi,
+ true,
+ gspi_f2_dma,
+ 0,
+ frame_length,
+ (uint32_t *) iframe->data);
+
+ if (ret != OK)
+ {
+ wlinfo("Failed to read frame data\n");
+ ret = -EIO;
+ goto exit_abort;
+ }
+
+ header = (f2_frame_header_t *)iframe->data;
+
+ if (header->size == 0)
+ {
+ ret = OK;
+ goto exit_free_frame;
+ }
+
+ checksum = header->size | header->checksum;
+
+ if (checksum != 0xffff || header->size < sizeof(f2_frame_header_t))
+ {
+ wlerr("Checksum failed: size:.0x%04X checksum: 0x%04X\n",
+ header->size,
+ header->checksum);
+
+ bcmf_hexdump((uint8_t *)header, MIN(header->size, 64), 0);
+
+ f2_frame_rx_fail(gbus, false);
+ return -EINVAL;
+ }
+
+ /* Process and validate header */
+
+ ret = process_f2_frame_header(gbus, header);
+ if (ret != OK)
+ {
+ wlerr("Error while processing header %d\n", ret);
+ ret = -EINVAL;
+ goto exit_free_frame;
+ }
+
+ if (header->size == FC_UPDATE_PKT_LENGTH)
+ {
+ /* Flow control update packet with no data */
+
+ return OK;
+ }
+
+ /* Update frame structure */
+
+ iframe->header.len = header->size;
+ iframe->header.data += header->data_offset;
+
+ /* Process received frame content */
+
+ switch (header->channel & 0x0f)
+ {
+ case F2_FRAME_CONTROL_CHANNEL:
+ ret = bcmf_cdc_process_control_frame(priv, &iframe->header);
+ goto exit_free_frame;
+
+ case F2_FRAME_EVENT_CHANNEL:
+ if (header->data_offset == header->size)
+ {
+ /* Empty event, ignore */
+
+ ret = OK;
+ }
+ else
+ {
+ ret = bcmf_bdc_process_event_frame(priv, &iframe->header);
+ }
+
+ goto exit_free_frame;
+
+ case F2_FRAME_DATA_CHANNEL:
+
+ /* Queue frame and notify network layer frame is available */
+
+ if (nxsem_wait_uninterruptible(&gbus->queue_mutex) < 0)
+ {
+ DEBUGPANIC();
+ }
+
+ list_add_tail(&gbus->rx_queue, &iframe->list_entry);
+ nxsem_post(&gbus->queue_mutex);
+
+ bcmf_netdev_notify_rx(priv);
+
+ /* Upper layer have to free all received frames */
+
+ ret = OK;
+ break;
+
+ default:
+ wlerr("Got unexpected message type %d\n", header->channel);
+ ret = -EINVAL;
+ goto exit_free_frame;
+ }
+
+ return ret;
+
+exit_abort:
+ f2_frame_rx_fail(gbus, false);
+exit_free_frame:
+ bcmf_interface_free_frame(priv, iframe);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: bcmf_gspi_send_f2_frame
+ *
+ * Description:
+ * De-queue and send an F2 frame.
+ *
+ * Parameters:
+ * priv - the device structure
+ *
+ * Returns:
+ * OK on success, negated error code on failure.
+ ****************************************************************************/
+
+int bcmf_gspi_send_f2_frame(FAR struct bcmf_dev_s *priv)
+{
+ FAR bcmf_gspi_dev_t *gbus = (FAR bcmf_gspi_dev_t *)priv->bus;
+ FAR gspi_dev_t *gspi = gbus->gspi;
+ f2_frame_header_t *header;
+ bcmf_interface_frame_t *iframe;
+ int ret;
+ bool is_txframe;
+
+ if (list_is_empty(&gbus->tx_queue))
+ {
+ /* No more frames to send */
+
+ return -ENODATA;
+ }
+
+ if (gbus->tx_seq == gbus->max_seq)
+ {
+ /* TODO handle this case */
+
+ wlerr("No credit to send frame\n");
+ return -EAGAIN;
+ }
+
+ if (nxsem_wait_uninterruptible(&gbus->queue_mutex) < 0)
+ {
+ DEBUGPANIC();
+ }
+
+ iframe = list_remove_head_type(&gbus->tx_queue,
+ bcmf_interface_frame_t,
+ list_entry);
+
+ nxsem_post(&gbus->queue_mutex);
+
+ is_txframe = iframe->tx;
+
+ header = (f2_frame_header_t *)iframe->header.base;
+
+ /* Set frame sequence id */
+
+ header->sequence = gbus->tx_seq++;
+
+#if 0
+ wlinfo("\n>>>---> Send frame %p %d\n", iframe, iframe->header.len);
+
+ wlinfo("size:%d seq: %d, channel: %d next len: %d\n",
+ header->size,
+ header->sequence,
+ header->channel,
+ header->next_length);
+
+ wlinfo("data offset:0x%02X flow: %d, credit: %d\n",
+ header->data_offset,
+ header->flow_control,
+ header->credit);
+#endif
+
+#if 0
+ bcmf_hexdump(iframe->header.base, iframe->header.len,
+ (unsigned long)iframe->header.base);
+#endif
+
+ /* Write the frame data (the buffer is DMA aligned here) */
+
+ ret = gspi->write(gspi,
+ true,
+ gspi_f2_dma,
+ 0,
+ iframe->header.len,
+ (FAR uint32_t *) iframe->header.base);
+
+ /* Free frame buffer */
+
+ bcmf_interface_free_frame(priv, iframe);
+
+ if (ret == OK && is_txframe)
+ {
+ /* Notify upper layer at least one TX buffer is available */
+
+ bcmf_netdev_notify_tx(priv);
+ }
+
+ return ret;
+}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.h
similarity index 50%
copy from drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
copy to drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.h
index 7fdbea81ef..bad14cba45 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_gspi_f2_frame.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -18,66 +18,49 @@
*
****************************************************************************/
+#ifndef __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_GSPI_F2_FRAME_H
+#define __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_GSPI_F2_FRAME_H
+
/****************************************************************************
* Included Files
****************************************************************************/
-#include <nuttx/config.h>
-#include <stdint.h>
-
-#include "bcmf_sdio.h"
+#include "bcmf_driver.h"
/****************************************************************************
- * Pre-processor Definitions
+ * Public Function Prototypes
****************************************************************************/
-#define WRAPPER_REGISTER_OFFSET 0x100000
-
/****************************************************************************
- * Public Data
+ * Name: read_f2_frame
+ *
+ * Description:
+ * Read and process an F2 frame.
+ *
+ * Parameters:
+ * priv - the device structure
+ * frame_length - Length of frame we are to read. (From chip status)
+ *
+ * Returns:
+ * OK on success, negated error code on failure.
****************************************************************************/
-extern const char bcm4301x_nvram_image[];
-extern const unsigned int bcm4301x_nvram_image_len;
-
-#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
-extern const uint8_t bcm4301x_firmware_image[];
-extern const unsigned int bcm4301x_firmware_image_len;
-#endif
-
-const struct bcmf_sdio_chip bcmf_4301x_config_sdio =
-{
- /* General chip stats */
-
- .ram_base = 0,
- .ram_size = 0xa0000,
-
- /* Backplane architecture */
-
- .core_base =
- {
- [CHIPCOMMON_CORE_ID] = 0x18000000, /* Chipcommon core register base */
- [DOT11MAC_CORE_ID] = 0x18001000, /* dot11mac core register base */
- [SDIOD_CORE_ID] = 0x18002000, /* SDIOD Device core register base */
- [WLAN_ARMCM3_CORE_ID] = 0x18003000 + /* ARMCM3 core register base */
- WRAPPER_REGISTER_OFFSET,
- [SOCSRAM_CORE_ID] = 0x18004000 + /* SOCSRAM core register base */
- WRAPPER_REGISTER_OFFSET
- },
-
- /* Firmware images */
-
- /* TODO find something smarter than using image_len references */
-
- .nvram_image = (FAR uint8_t *)bcm4301x_nvram_image,
- .nvram_image_size = (FAR unsigned int *)&bcm4301x_nvram_image_len,
-
-#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
- .firmware_image = (FAR uint8_t *)bcm4301x_firmware_image,
- .firmware_image_size = (FAR unsigned int *)&bcm4301x_firmware_image_len,
-#endif
-};
+int bcmf_gspi_read_f2_frame(FAR struct bcmf_dev_s *priv,
+ int frame_length);
/****************************************************************************
- * Public Functions
+ * Name: bcmf_gspi_send_f2_frame
+ *
+ * Description:
+ * De-queue and send an F2 frame.
+ *
+ * Parameters:
+ * priv - the device structure
+ *
+ * Returns:
+ * OK on success, negated error code on failure.
****************************************************************************/
+
+int bcmf_gspi_send_f2_frame(FAR struct bcmf_dev_s *priv);
+
+#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_GSPI_F2_FRAME_H */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.c
new file mode 100644
index 0000000000..a6aa74f245
--- /dev/null
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.c
@@ -0,0 +1,144 @@
+/****************************************************************************
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/signal.h>
+
+#include "bcmf_interface.h"
+#include "debug.h"
+#include "assert.h"
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static bcmf_interface_frame_t
+g_pktframes[CONFIG_IEEE80211_BROADCOM_FRAME_POOL_SIZE];
+
+static struct list_node free_interface_frames; /* Queue of available frames */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcmf_initialize_interface_frames
+ ****************************************************************************/
+
+void bcmf_initialize_interface_frames(void)
+{
+ int i;
+
+ list_initialize(&free_interface_frames);
+
+ for (i = 0; i < CONFIG_IEEE80211_BROADCOM_FRAME_POOL_SIZE; ++i)
+ {
+ list_add_tail(&free_interface_frames, &g_pktframes[i].list_entry);
+ }
+}
+
+/****************************************************************************
+ * Name: bcmf_interface_free_frame
+ ****************************************************************************/
+
+void bcmf_interface_free_frame(FAR struct bcmf_dev_s *priv,
+ bcmf_interface_frame_t *iframe)
+{
+ FAR bcmf_interface_dev_t *ibus = (FAR bcmf_interface_dev_t *) priv->bus;
+
+ if (nxsem_wait_uninterruptible(&ibus->queue_mutex) < 0)
+ {
+ DEBUGPANIC();
+ }
+
+ list_add_head(&free_interface_frames, &iframe->list_entry);
+
+ if (iframe->tx)
+ {
+ ibus->tx_queue_count--;
+ }
+
+ nxsem_post(&ibus->queue_mutex);
+}
+
+/****************************************************************************
+ * Name: bcmf_interface_allocate_frame
+ ****************************************************************************/
+
+bcmf_interface_frame_t
+*bcmf_interface_allocate_frame(FAR struct bcmf_dev_s *priv,
+ bool block,
+ bool tx)
+{
+ FAR bcmf_interface_dev_t *ibus = (FAR bcmf_interface_dev_t *) priv->bus;
+ bcmf_interface_frame_t *iframe;
+
+ while (1)
+ {
+ if (nxsem_wait_uninterruptible(&ibus->queue_mutex) < 0)
+ {
+ DEBUGPANIC();
+ }
+
+ if (!tx ||
+ ibus->tx_queue_count <
+ CONFIG_IEEE80211_BROADCOM_FRAME_POOL_SIZE / 2)
+ {
+ if ((iframe = list_remove_head_type(&free_interface_frames,
+ bcmf_interface_frame_t,
+ list_entry)) != NULL)
+ {
+ if (tx)
+ {
+ ibus->tx_queue_count++;
+ }
+
+ nxsem_post(&ibus->queue_mutex);
+ break;
+ }
+ }
+
+ nxsem_post(&ibus->queue_mutex);
+
+ if (!block)
+ {
+ wlinfo("No avail buffer\n");
+ return NULL;
+ }
+
+ nxsig_usleep(10 * 1000);
+ }
+
+#if defined(CONFIG_IEEE80211_BROADCOM_FULLMAC_GSPI)
+ iframe->header.len = CONFIG_IEEE80211_BROADCOM_FULLMAC_GSPI_MAX_FRAME;
+#else
+ iframe->header.len = HEADER_SIZE + MAX_NETDEV_PKTSIZE +
+ CONFIG_NET_GUARDSIZE;
+#endif
+ iframe->header.base = iframe->data;
+ iframe->header.data = iframe->data;
+ iframe->tx = tx;
+ return iframe;
+}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.h
new file mode 100644
index 0000000000..e617e880f2
--- /dev/null
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+ * drivers/wireless/ieee80211/bcm43xxx/bcmf_interface.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_INTERFACE_H
+#define __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_INTERFACE_H
+
+/* ==== This file contains dispatch between the SDIO & gSPI interface. ==== */
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#if defined(CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO)
+#include "bcmf_sdio.h"
+#elif defined(CONFIG_IEEE80211_BROADCOM_FULLMAC_GSPI)
+#include "bcmf_gspi.h"
+#else
+#error Must define IEEE80211_BROADCOM_FULLMAC_SDIO or IEEE80211_BROADCOM_FULLMAC_GSPI
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct bcmf_dev_s;
+
+#if defined(CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO)
+typedef struct bcmf_sdio_dev_s bcmf_interface_dev_t;
+#else
+typedef bcmf_gspi_dev_t bcmf_interface_dev_t;
+#endif
+
+/* Note:
+ * The structure referred to above must as its first item:
+ *
+ * struct bcmf_bus_dev_s bus; --- Default bcmf bus structure
+ *
+ * The structure must also contain the following items:
+ *
+ * int cur_chip_id; --- Chip ID read from the card
+ * struct bcmf_chip_data *chip; --- Chip specific configuration
+ *
+ * sem_t thread_signal; --- Thread event semaphore
+ *
+ * uint32_t backplane_current_addr; --- Current F1 backplane base addr
+ *
+ * uint8_t max_seq; --- Maximum TX sequence allowed
+ * uint8_t tx_seq; --- TX sequence number (next)
+ *
+ * sem_t queue_mutex; --- Lock for TX/RX/free queues
+ * struct list_node tx_queue; --- Queue of frames to transmit
+ * struct list_node rx_queue; --- Queue of frames for receiving
+ * volatile int tx_queue_count; --- Count of items in TX queue
+ */
+
+/* Structure used to manage interface frames */
+
+typedef struct bcmf_interface_frame_s
+{
+ struct bcmf_frame_s header;
+ bool tx;
+ struct list_node list_entry;
+ uint8_t pad[CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT -
+ FIRST_WORD_SIZE]
+ aligned_data(CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT);
+
+ /* pad[] array is used and aligned in order to make the following data[]
+ * buffer aligned beginning from the offset of 4 bytes to the address
+ * boundary for SDIO DMA transfers.
+ * The first 4 bytes of data[] buffer are not directly used in DMA
+ * transfers. Instead, they are used as the initial phase just to get
+ * the length of the remaining long data to be read. Thus only
+ * the remaining part of data[] buffer beginning from the offset of 4 bytes
+ * is required to be aligned to the address boundary set by
+ * CONFIG_IEEE80211_BROADCOM_SDIO_DMA_BUF_ALIGNMENT parameter.
+ */
+
+ uint8_t data[HEADER_SIZE + MAX_NETDEV_PKTSIZE +
+ CONFIG_NET_GUARDSIZE];
+} bcmf_interface_frame_t;
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcmf_bus_interface_active
+ ****************************************************************************/
+
+static inline int bcmf_bus_interface_active(FAR struct bcmf_dev_s *priv,
+ bool active)
+{
+#if defined(CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO)
+ return bcmf_bus_sdio_active(priv, active);
+#else
+ return bcmf_bus_gspi_active(priv, active);
+#endif
+}
+
+/****************************************************************************
+ * Name: bcmf_bus_io_abort
+ ****************************************************************************/
+
+static inline void bcmf_bus_io_abort(FAR bcmf_interface_dev_t *ibus)
+{
+#if defined(CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO)
+ bcmf_write_reg(ibus, 0, SDIO_CCCR_IOABORT, 2);
+#else
+ return;
+#endif
+}
+
+/****************************************************************************
+ * Name: bcmf_initialize_interface_frames
+ ****************************************************************************/
+
+void bcmf_initialize_interface_frames(void);
+
+/****************************************************************************
+ * Name: bcmf_interface_free_frame
+ ****************************************************************************/
+
+void bcmf_interface_free_frame(FAR struct bcmf_dev_s *priv,
+ bcmf_interface_frame_t *iframe);
+
+/****************************************************************************
+ * Name: bcmf_interface_allocate_frame
+ ****************************************************************************/
+
+bcmf_interface_frame_t
+*bcmf_interface_allocate_frame(FAR struct bcmf_dev_s *priv,
+ bool block,
+ bool tx);
+
+#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_INTERFACE_H */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_ioctl.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_ioctl.h
index ed0710fdc4..a4aa2d6d09 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_ioctl.h
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_ioctl.h
@@ -762,7 +762,13 @@ typedef struct wlc_iov_trx_s
#define IOVAR_STR_AMPDU_RX_FACTOR "ampdu_rx_factor"
#define IOVAR_STR_MIMO_BW_CAP "mimo_bw_cap"
#define IOVAR_STR_CLMLOAD "clmload"
+#define IOVAR_STR_CLVER "clmver"
#define IOVAR_STR_JOIN "join"
+#define IOVAR_STR_GPIOOUT "gpioout"
+#define IOVAR_STR_CCGPIOCTRL "ccgpioctrl"
+#define IOVAR_STR_CCGPIOIN "ccgpioin"
+#define IOVAR_STR_CCGPIOOUT "ccgpioout"
+#define IOVAR_STR_CCGPIOPUTEN "ccgpioputen"
#define WLC_IOCTL_MAGIC ( 0x14e46c77 )
#define WLC_IOCTL_VERSION ( 1 )
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c
index d9557f4c02..80ab2897f7 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_netdev.c
@@ -252,8 +252,6 @@ static void bcmf_receive(FAR struct bcmf_dev_s *priv)
priv->bc_dev.d_buf = frame->data;
priv->bc_dev.d_len = frame->len - (frame->data - frame->base);
- wlinfo("Got frame %p %d\n", frame, priv->bc_dev.d_len);
-
#ifdef CONFIG_NET_PKT
/* When packet sockets are enabled, feed the frame into the tap */
@@ -270,6 +268,8 @@ static void bcmf_receive(FAR struct bcmf_dev_s *priv)
* ignored.
*/
+ /* ### TODO ### Implement VLAN support */
+
uint8_t temp_buffer[12];
memcpy(temp_buffer, frame->data, 12);
memcpy(frame->data + 4, temp_buffer, 12);
@@ -733,6 +733,8 @@ errout_in_critical_section:
leave_critical_section(flags);
+ wlinfo("bcmf_ifup done: %d\n", ret);
+
return ret;
}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.c
index 53f78ed1d2..66b3259c7f 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.c
@@ -77,16 +77,16 @@
/* Supported chip configurations */
#ifdef CONFIG_IEEE80211_BROADCOM_BCM4301X
- extern const struct bcmf_sdio_chip bcmf_4301x_config_sdio;
+ extern const struct bcmf_chip_data bcmf_4301x_config_data;
#endif
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43362
- extern const struct bcmf_sdio_chip bcmf_43362_config_sdio;
+ extern const struct bcmf_chip_data bcmf_43362_config_data;
#endif
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43438
- extern const struct bcmf_sdio_chip bcmf_43438_config_sdio;
+ extern const struct bcmf_chip_data bcmf_43438_config_data;
#endif
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43455
- extern const struct bcmf_sdio_chip bcmf_43455_config_sdio;
+ extern const struct bcmf_chip_data bcmf_43455_config_data;
#endif
/****************************************************************************
@@ -114,15 +114,6 @@ static bool brcm_chip_sr_capable(FAR struct bcmf_sdio_dev_s *sbus);
* Private Data
****************************************************************************/
-/* Buffer pool for SDIO bus interface
- * This pool is shared between all driver devices
- */
-
-static struct bcmf_sdio_frame
- g_pktframes[CONFIG_IEEE80211_BROADCOM_FRAME_POOL_SIZE];
-
-/* TODO free_queue should be static */
-
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -647,10 +638,143 @@ static bool brcm_chip_sr_capable(FAR struct bcmf_sdio_dev_s *sbus)
}
}
+/****************************************************************************
+ * Name: bcmf_bus_sdio_initialize
+ ****************************************************************************/
+
+static int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
+ int minor, FAR struct sdio_dev_s *dev)
+{
+ FAR struct bcmf_sdio_dev_s *sbus;
+ FAR char *argv[2];
+ char arg1[32];
+ int ret;
+
+ /* Allocate sdio bus structure */
+
+ sbus = (FAR struct bcmf_sdio_dev_s *)kmm_malloc(sizeof(*sbus));
+
+ if (!sbus)
+ {
+ return -ENOMEM;
+ }
+
+ /* Initialize sdio bus device structure */
+
+ memset(sbus, 0, sizeof(*sbus));
+ sbus->sdio_dev = dev;
+ sbus->minor = minor;
+ sbus->ready = false;
+ sbus->sleeping = true;
+
+ sbus->bus.txframe = bcmf_sdpcm_queue_frame;
+ sbus->bus.rxframe = bcmf_sdpcm_get_rx_frame;
+ sbus->bus.allocate_frame = bcmf_sdpcm_alloc_frame;
+ sbus->bus.free_frame = bcmf_sdpcm_free_frame;
+ sbus->bus.stop = NULL; /* TODO */
+
+ /* Init transmit frames queue */
+
+ if ((ret = nxsem_init(&sbus->queue_mutex, 0, 1)) != OK)
+ {
+ goto exit_free_bus;
+ }
+
+ list_initialize(&sbus->tx_queue);
+ list_initialize(&sbus->rx_queue);
+
+ /* Setup free buffer list */
+
+ bcmf_initialize_interface_frames();
+
+ /* Init thread semaphore */
+
+ if ((ret = nxsem_init(&sbus->thread_signal, 0, 0)) != OK)
+ {
+ goto exit_free_bus;
+ }
+
+ if ((ret = nxsem_set_protocol(&sbus->thread_signal, SEM_PRIO_NONE)) != OK)
+ {
+ goto exit_free_bus;
+ }
+
+ /* Configure hardware */
+
+ bcmf_board_initialize(sbus->minor);
+
+ /* Register sdio bus */
+
+ priv->bus = &sbus->bus;
+
+ /* Spawn bcmf daemon thread */
+
+ snprintf(arg1, sizeof(arg1), "%p", priv);
+ argv[0] = arg1;
+ argv[1] = NULL;
+ ret = kthread_create(BCMF_THREAD_NAME,
+ CONFIG_IEEE80211_BROADCOM_SCHED_PRIORITY,
+ BCMF_THREAD_STACK_SIZE, bcmf_sdio_thread,
+ argv);
+ if (ret <= 0)
+ {
+ wlerr("Cannot spawn bcmf thread\n");
+ ret = -EBADE;
+ goto exit_free_bus;
+ }
+
+ sbus->thread_id = (pid_t)ret;
+
+ return OK;
+
+exit_free_bus:
+ kmm_free(sbus);
+ priv->bus = NULL;
+ return ret;
+}
+
/****************************************************************************
* Public Functions
****************************************************************************/
+/****************************************************************************
+ * Name: bcmf_sdio_initialize
+ *
+ * Description:
+ * Initialize the drive with a SDIO connection.
+ ****************************************************************************/
+
+int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev)
+{
+ int ret;
+ FAR struct bcmf_dev_s *priv;
+
+ wlinfo("minor: %d\n", minor);
+
+ priv = bcmf_allocate_device();
+ if (!priv)
+ {
+ return -ENOMEM;
+ }
+
+ /* Init sdio bus */
+
+ ret = bcmf_bus_sdio_initialize(priv, minor, dev);
+ if (ret != OK)
+ {
+ ret = -EIO;
+ goto exit_free_device;
+ }
+
+ /* Bus initialized, register network driver */
+
+ return bcmf_driver_initialize(priv);
+
+exit_free_device:
+ bcmf_free_device(priv);
+ return ret;
+}
+
/****************************************************************************
* Name: bcmf_transfer_bytes
****************************************************************************/
@@ -789,107 +913,6 @@ exit_uninit_hw:
return ret;
}
-/****************************************************************************
- * Name: bcmf_bus_sdio_initialize
- ****************************************************************************/
-
-int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
- int minor, FAR struct sdio_dev_s *dev)
-{
- FAR struct bcmf_sdio_dev_s *sbus;
- FAR char *argv[2];
- char arg1[32];
- int ret;
-
- /* Allocate sdio bus structure */
-
- sbus = (FAR struct bcmf_sdio_dev_s *)kmm_malloc(sizeof(*sbus));
-
- if (!sbus)
- {
- return -ENOMEM;
- }
-
- /* Initialize sdio bus device structure */
-
- memset(sbus, 0, sizeof(*sbus));
- sbus->sdio_dev = dev;
- sbus->minor = minor;
- sbus->ready = false;
- sbus->sleeping = true;
-
- sbus->bus.txframe = bcmf_sdpcm_queue_frame;
- sbus->bus.rxframe = bcmf_sdpcm_get_rx_frame;
- sbus->bus.allocate_frame = bcmf_sdpcm_alloc_frame;
- sbus->bus.free_frame = bcmf_sdpcm_free_frame;
- sbus->bus.stop = NULL; /* TODO */
-
- /* Init transmit frames queue */
-
- if ((ret = nxsem_init(&sbus->queue_mutex, 0, 1)) != OK)
- {
- goto exit_free_bus;
- }
-
- list_initialize(&sbus->tx_queue);
- list_initialize(&sbus->rx_queue);
- list_initialize(&sbus->free_queue);
-
- /* Setup free buffer list */
-
- /* FIXME this should be static to driver */
-
- for (ret = 0; ret < CONFIG_IEEE80211_BROADCOM_FRAME_POOL_SIZE; ret++)
- {
- list_add_tail(&sbus->free_queue, &g_pktframes[ret].list_entry);
- }
-
- /* Init thread semaphore */
-
- if ((ret = nxsem_init(&sbus->thread_signal, 0, 0)) != OK)
- {
- goto exit_free_bus;
- }
-
- if ((ret = nxsem_set_protocol(&sbus->thread_signal, SEM_PRIO_NONE)) != OK)
- {
- goto exit_free_bus;
- }
-
- /* Configure hardware */
-
- bcmf_board_initialize(sbus->minor);
-
- /* Register sdio bus */
-
- priv->bus = &sbus->bus;
-
- /* Spawn bcmf daemon thread */
-
- snprintf(arg1, sizeof(arg1), "%p", priv);
- argv[0] = arg1;
- argv[1] = NULL;
- ret = kthread_create(BCMF_THREAD_NAME,
- CONFIG_IEEE80211_BROADCOM_SCHED_PRIORITY,
- BCMF_THREAD_STACK_SIZE, bcmf_sdio_thread,
- argv);
- if (ret <= 0)
- {
- wlerr("Cannot spawn bcmf thread\n");
- ret = -EBADE;
- goto exit_free_bus;
- }
-
- sbus->thread_id = (pid_t)ret;
-
- return OK;
-
-exit_free_bus:
- kmm_free(sbus);
- priv->bus = NULL;
- return ret;
-}
-
int bcmf_chipinitialize(FAR struct bcmf_sdio_dev_s *sbus)
{
uint32_t value = 0;
@@ -911,28 +934,28 @@ int bcmf_chipinitialize(FAR struct bcmf_sdio_dev_s *sbus)
case SDIO_DEVICE_ID_BROADCOM_43012:
case SDIO_DEVICE_ID_BROADCOM_43013:
wlinfo("bcm%d chip detected\n", chipid);
- sbus->chip = (struct bcmf_sdio_chip *)&bcmf_4301x_config_sdio;
+ sbus->chip = (struct bcmf_chip_data *)&bcmf_4301x_config_data;
break;
#endif
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43362
case SDIO_DEVICE_ID_BROADCOM_43362:
wlinfo("bcm43362 chip detected\n");
- sbus->chip = (struct bcmf_sdio_chip *)&bcmf_43362_config_sdio;
+ sbus->chip = (struct bcmf_chip_data *)&bcmf_43362_config_data;
break;
#endif
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43438
case SDIO_DEVICE_ID_BROADCOM_43430:
wlinfo("bcm43438 chip detected\n");
- sbus->chip = (struct bcmf_sdio_chip *)&bcmf_43438_config_sdio;
+ sbus->chip = (struct bcmf_chip_data *)&bcmf_43438_config_data;
break;
#endif
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43455
case SDIO_DEVICE_ID_BROADCOM_43455:
wlinfo("bcm43455 chip detected\n");
- sbus->chip = (struct bcmf_sdio_chip *)&bcmf_43455_config_sdio;
+ sbus->chip = (struct bcmf_chip_data *)&bcmf_43455_config_data;
break;
#endif
@@ -1048,73 +1071,3 @@ int bcmf_sdio_thread(int argc, char **argv)
wlinfo("Exit\n");
return 0;
}
-
-struct bcmf_sdio_frame *bcmf_sdio_allocate_frame(FAR struct bcmf_dev_s *priv,
- bool block, bool tx)
-{
- FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
- struct bcmf_sdio_frame *sframe;
-
- while (1)
- {
- if (nxsem_wait_uninterruptible(&sbus->queue_mutex) < 0)
- {
- DEBUGPANIC();
- }
-
- if (!tx ||
- sbus->tx_queue_count <
- CONFIG_IEEE80211_BROADCOM_FRAME_POOL_SIZE / 2)
- {
- if ((sframe = list_remove_head_type(&sbus->free_queue,
- struct bcmf_sdio_frame,
- list_entry)) != NULL)
- {
- if (tx)
- {
- sbus->tx_queue_count++;
- }
-
- nxsem_post(&sbus->queue_mutex);
- break;
- }
- }
-
- nxsem_post(&sbus->queue_mutex);
-
- if (!block)
- {
- wlinfo("No avail buffer\n");
- return NULL;
- }
-
- nxsig_usleep(10 * 1000);
- }
-
- sframe->header.len = HEADER_SIZE + MAX_NETDEV_PKTSIZE +
- CONFIG_NET_GUARDSIZE;
- sframe->header.base = sframe->data;
- sframe->header.data = sframe->data;
- sframe->tx = tx;
- return sframe;
-}
-
-void bcmf_sdio_free_frame(FAR struct bcmf_dev_s *priv,
- struct bcmf_sdio_frame *sframe)
-{
- FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
-
- if (nxsem_wait_uninterruptible(&sbus->queue_mutex) < 0)
- {
- DEBUGPANIC();
- }
-
- list_add_head(&sbus->free_queue, &sframe->list_entry);
-
- if (sframe->tx)
- {
- sbus->tx_queue_count--;
- }
-
- nxsem_post(&sbus->queue_mutex);
-}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h
index 9fbb78f155..5ee7fee333 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio.h
@@ -34,6 +34,7 @@
#include <nuttx/sdio.h>
#include <nuttx/semaphore.h>
+#include "bcmf_chip_data.h"
#include "bcmf_driver.h"
#include "bcmf_sdio_core.h"
@@ -45,34 +46,12 @@
#define FIRST_WORD_SIZE 4
#define FC_UPDATE_PKT_LENGTH 12
+#define BCMF_UPLOAD_TRANSFER_SIZE (64 * 256)
+
/****************************************************************************
* Public Types
****************************************************************************/
-/* SDIO chip configuration structure */
-
-struct bcmf_sdio_chip
-{
- uint32_t ram_base;
- uint32_t ram_size;
- uint32_t core_base[MAX_CORE_ID];
-
- /* In-memory file images */
-
- FAR uint8_t *nvram_image;
- FAR unsigned int *nvram_image_size;
-
-#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
- FAR uint8_t *firmware_image;
- FAR unsigned int *firmware_image_size;
-
-#ifdef CONFIG_IEEE80211_BROADCOM_HAVE_CLM
- FAR uint8_t *clm_blob_image;
- FAR unsigned int *clm_blob_image_size;
-#endif
-#endif
-};
-
/* SDIO bus structure extension */
struct bcmf_sdio_dev_s
@@ -82,7 +61,7 @@ struct bcmf_sdio_dev_s
int minor; /* Device minor number */
int cur_chip_id; /* Chip ID read from the card */
- struct bcmf_sdio_chip *chip; /* Chip specific configuration */
+ struct bcmf_chip_data *chip; /* Chip specific configuration */
volatile bool ready; /* Current device status */
bool sleeping; /* Current sleep status */
@@ -103,44 +82,16 @@ struct bcmf_sdio_dev_s
bool flow_ctrl; /* Current flow control status */
sem_t queue_mutex; /* Lock for TX/RX/free queues */
- struct list_node free_queue; /* Queue of available frames */
struct list_node tx_queue; /* Queue of frames to transmit */
struct list_node rx_queue; /* Queue of frames used to receive */
volatile int tx_queue_count; /* Count of items in TX queue */
};
-/* Structure used to manage SDIO frames */
-
-struct bcmf_sdio_frame
-{
- struct bcmf_frame_s header;
- bool tx;
- struct list_node list_entry;
- uint8_t pad[CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT -
- FIRST_WORD_SIZE]
- aligned_data(CONFIG_IEEE80211_BROADCOM_DMABUF_ALIGNMENT);
-
- /* pad[] array is used and aligned in order to make the following data[]
- * buffer aligned beginning from the offset of 4 bytes to the address
- * boundary for SDIO DMA transfers.
- * The first 4 bytes of data[] buffer are not directly used in DMA
- * transfers. Instead, they are used as the initial phase just to get
- * the length of the remaining long data to be read. Thus only
- * the remaining part of data[] buffer beginning from the offset of 4 bytes
- * is required to be aligned to the address boundary set by
- * CONFIG_IEEE80211_BROADCOM_SDIO_DMA_BUF_ALIGNMENT parameter.
- */
-
- uint8_t data[HEADER_SIZE + MAX_NETDEV_PKTSIZE +
- CONFIG_NET_GUARDSIZE];
-};
-
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
-int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
- int minor, FAR struct sdio_dev_s *dev);
+int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev);
int bcmf_bus_sdio_active(FAR struct bcmf_dev_s *priv, bool active);
@@ -160,10 +111,4 @@ int bcmf_read_reg(FAR struct bcmf_sdio_dev_s *sbus, uint8_t function,
int bcmf_write_reg(FAR struct bcmf_sdio_dev_s *sbus, uint8_t function,
uint32_t address, uint8_t reg);
-struct bcmf_sdio_frame *bcmf_sdio_allocate_frame(FAR struct bcmf_dev_s *priv,
- bool block, bool tx);
-
-void bcmf_sdio_free_frame(FAR struct bcmf_dev_s *priv,
- struct bcmf_sdio_frame *sframe);
-
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_SDIO_H */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio_core.h b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio_core.h
index 936135d386..cd86afe873 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio_core.h
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdio_core.h
@@ -47,6 +47,7 @@
#define SDIO_DEVICE_ID_BROADCOM_43362 43362
#define SDIO_DEVICE_ID_BROADCOM_43430 43430
#define SDIO_DEVICE_ID_BROADCOM_43455 0x4345
+#define SDIO_DEVICE_ID_INFINEON_CYW43439 43439
/* Core reg address translation.
* Both macro's returns a 32 bits byte address on the backplane bus.
@@ -82,23 +83,6 @@
#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */
#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */
-enum
-{
- CHIPCOMMON_CORE_ID = 0,
- DOT11MAC_CORE_ID,
- SDIOD_CORE_ID,
-#if defined(CONFIG_IEEE80211_BROADCOM_BCM4301X) || \
- defined(CONFIG_IEEE80211_BROADCOM_BCM43362) || \
- defined(CONFIG_IEEE80211_BROADCOM_BCM43438)
- WLAN_ARMCM3_CORE_ID,
- SOCSRAM_CORE_ID,
-#endif
-#if defined(CONFIG_IEEE80211_BROADCOM_BCM43455)
- WLAN_ARMCR4_CORE_ID,
-#endif
- MAX_CORE_ID
-};
-
struct chip_core_info
{
uint16_t id;
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c
index 2c2f5fc0c2..eed19c26c0 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/bcmf_sdpcm.c
@@ -34,11 +34,11 @@
#include <stddef.h>
#include <string.h>
-#include "bcmf_sdio.h"
#include "bcmf_core.h"
#include "bcmf_sdpcm.h"
#include "bcmf_cdc.h"
#include "bcmf_bdc.h"
+#include "bcmf_interface.h"
#include "bcmf_utils.h"
#include "bcmf_netdev.h"
@@ -74,9 +74,9 @@ begin_packed_struct struct bcmf_sdpcm_header
* Private Function Prototypes
****************************************************************************/
-static int bcmf_sdpcm_rxfail(FAR struct bcmf_sdio_dev_s *sbus, bool retry);
+static int bcmf_sdpcm_rxfail(FAR bcmf_interface_dev_t *ibus, bool retry);
-static int bcmf_sdpcm_process_header(FAR struct bcmf_sdio_dev_s *sbus,
+static int bcmf_sdpcm_process_header(FAR bcmf_interface_dev_t *ibus,
struct bcmf_sdpcm_header *header);
/****************************************************************************
@@ -87,13 +87,13 @@ static int bcmf_sdpcm_process_header(FAR struct bcmf_sdio_dev_s *sbus,
* Private Functions
****************************************************************************/
-int bcmf_sdpcm_rxfail(FAR struct bcmf_sdio_dev_s *sbus, bool retry)
+int bcmf_sdpcm_rxfail(FAR bcmf_interface_dev_t *ibus, bool retry)
{
/* issue abort command for F2 through F0 */
- bcmf_write_reg(sbus, 0, SDIO_CCCR_IOABORT, 2);
+ bcmf_bus_io_abort(ibus);
- bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM);
+ bcmf_write_reg(ibus, 1, SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM);
/* TODO Wait until the packet has been flushed (device/FIFO stable) */
@@ -101,28 +101,28 @@ int bcmf_sdpcm_rxfail(FAR struct bcmf_sdio_dev_s *sbus, bool retry)
{
/* Send NAK to retry to read frame */
- bcmf_write_sbregb(sbus,
- CORE_BUS_REG(sbus->chip->core_base[SDIOD_CORE_ID],
+ bcmf_write_sbregb(ibus,
+ CORE_BUS_REG(ibus->chip->core_base[SDIOD_CORE_ID],
tosbmailbox), SMB_NAK);
}
return 0;
}
-int bcmf_sdpcm_process_header(FAR struct bcmf_sdio_dev_s *sbus,
+int bcmf_sdpcm_process_header(FAR bcmf_interface_dev_t *ibus,
struct bcmf_sdpcm_header *header)
{
if (header->data_offset < sizeof(struct bcmf_sdpcm_header) ||
header->data_offset > header->size)
{
wlerr("Invalid data offset\n");
- bcmf_sdpcm_rxfail(sbus, false);
+ bcmf_sdpcm_rxfail(ibus, false);
return -ENXIO;
}
/* Update tx credits */
- sbus->max_seq = header->credit;
+ ibus->max_seq = header->credit;
return OK;
}
@@ -138,20 +138,20 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
uint16_t checksum;
struct bcmf_sdpcm_header *header;
struct bcmf_sdpcm_header tmp_hdr;
- struct bcmf_sdio_frame *sframe;
- FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
+ bcmf_interface_frame_t *iframe;
+ FAR bcmf_interface_dev_t *ibus = (FAR bcmf_interface_dev_t *)priv->bus;
/* Read the first 4 bytes of sdpcm header
* to get the length of the following data to be read
*/
- ret = bcmf_transfer_bytes(sbus, false, 2, 0,
+ ret = bcmf_transfer_bytes(ibus, false, 2, 0,
(uint8_t *)&tmp_hdr,
FIRST_WORD_SIZE);
if (ret != OK)
{
wlinfo("Failed to read size\n");
- bcmf_sdpcm_rxfail(sbus, false);
+ bcmf_sdpcm_rxfail(ibus, false);
return -EIO;
}
@@ -160,15 +160,19 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
/* All zero means no more to read */
- if (!(len | checksum))
+ if (len == 0)
{
+ wlinfo("No data\n");
+
return -ENODATA;
}
+ wlinfo("len: %d Header checksum: 0x%04x\n", len, checksum);
+
if (((~len & 0xffff) ^ checksum) || len < sizeof(struct bcmf_sdpcm_header))
{
- wlerr("Invalid header checksum or len %x %x\n", len, checksum);
- bcmf_sdpcm_rxfail(sbus, false);
+ wlerr("Invalid header checksum or len %d 0x%04x\n", len, checksum);
+ bcmf_sdpcm_rxfail(ibus, false);
return -EINVAL;
}
@@ -176,17 +180,19 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
{
/* Flow control update packet with no data */
- ret = bcmf_transfer_bytes(sbus, false, 2, 0,
+ wlinfo("Flow control\n");
+
+ ret = bcmf_transfer_bytes(ibus, false, 2, 0,
(uint8_t *)&tmp_hdr + FIRST_WORD_SIZE,
FC_UPDATE_PKT_LENGTH - FIRST_WORD_SIZE);
if (ret != OK)
{
wlinfo("Failed to read the rest 8 bytes\n");
- bcmf_sdpcm_rxfail(sbus, false);
+ bcmf_sdpcm_rxfail(ibus, false);
return -EIO;
}
- ret = bcmf_sdpcm_process_header(sbus, &tmp_hdr);
+ ret = bcmf_sdpcm_process_header(ibus, &tmp_hdr);
if (ret != OK)
{
@@ -199,28 +205,27 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
/* Request free frame buffer */
- sframe = bcmf_sdio_allocate_frame(priv, false, false);
+ iframe = bcmf_interface_allocate_frame(priv, false, false);
- if (sframe == NULL)
+ if (iframe == NULL)
{
wlinfo("fail alloc\n");
/* Read out the rest of the header to get the bus credit information */
- ret = bcmf_transfer_bytes(sbus, false, 2, 0,
+ ret = bcmf_transfer_bytes(ibus, false, 2, 0,
(uint8_t *)&tmp_hdr + FIRST_WORD_SIZE,
FC_UPDATE_PKT_LENGTH - FIRST_WORD_SIZE);
-
if (ret != OK)
{
wlinfo("Failed to read the rest 8 bytes\n");
- bcmf_sdpcm_rxfail(sbus, false);
+ bcmf_sdpcm_rxfail(ibus, false);
return -EIO;
}
- bcmf_sdpcm_rxfail(sbus, false);
+ bcmf_sdpcm_rxfail(ibus, false);
- ret = bcmf_sdpcm_process_header(sbus, &tmp_hdr);
+ ret = bcmf_sdpcm_process_header(ibus, &tmp_hdr);
if (ret != OK)
{
@@ -231,7 +236,7 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
return -EAGAIN;
}
- header = (struct bcmf_sdpcm_header *)sframe->data;
+ header = (struct bcmf_sdpcm_header *)iframe->data;
/* Read the remaining frame data (the buffer is DMA aligned here) */
@@ -241,9 +246,9 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
goto exit_free_frame;
}
- ret = bcmf_transfer_bytes(sbus, false, 2, 0,
- (uint8_t *)header + FIRST_WORD_SIZE,
- len - FIRST_WORD_SIZE);
+ ret = bcmf_transfer_bytes(ibus, false, 2, 0,
+ (uint8_t *)header + FIRST_WORD_SIZE,
+ len - FIRST_WORD_SIZE);
if (ret != OK)
{
wlinfo("Failed to read remaining frame data\n");
@@ -253,22 +258,33 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
memcpy(header, &tmp_hdr, FIRST_WORD_SIZE);
- if (len > sframe->header.len)
+ if (len > iframe->header.len)
{
- wlerr("Frame is too large, cancel %d %d\n", len, sframe->header.len);
+ wlerr("Frame is too large, cancel %d %d\n", len, iframe->header.len);
ret = -ENOMEM;
goto exit_abort;
}
-#if 0
- wlinfo("Receive frame %p %d\n", sframe, len);
+#if 1
+ wlinfo("Receive frame %p %d\n", iframe, len);
+
+ wlinfo("size:%d seq: %d, channel: %d next len: %d\n",
+ header->size,
+ header->sequence,
+ header->channel,
+ header->next_length);
+
+ wlinfo("data offset:0x%02X flow: %d, credit: %d\n",
+ header->data_offset,
+ header->flow_control,
+ header->credit);
bcmf_hexdump((uint8_t *)header, header->size, (unsigned int)header);
#endif
/* Process and validate header */
- ret = bcmf_sdpcm_process_header(sbus, header);
+ ret = bcmf_sdpcm_process_header(ibus, header);
if (ret != OK)
{
wlerr("Error while processing header %d\n", ret);
@@ -278,15 +294,15 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
/* Update frame structure */
- sframe->header.len = header->size;
- sframe->header.data += header->data_offset;
+ iframe->header.len = header->size;
+ iframe->header.data += header->data_offset;
/* Process received frame content */
switch (header->channel & 0x0f)
{
case SDPCM_CONTROL_CHANNEL:
- ret = bcmf_cdc_process_control_frame(priv, &sframe->header);
+ ret = bcmf_cdc_process_control_frame(priv, &iframe->header);
goto exit_free_frame;
case SDPCM_EVENT_CHANNEL:
@@ -298,7 +314,7 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
}
else
{
- ret = bcmf_bdc_process_event_frame(priv, &sframe->header);
+ ret = bcmf_bdc_process_event_frame(priv, &iframe->header);
}
goto exit_free_frame;
@@ -307,13 +323,13 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
/* Queue frame and notify network layer frame is available */
- if (nxsem_wait_uninterruptible(&sbus->queue_mutex) < 0)
+ if (nxsem_wait_uninterruptible(&ibus->queue_mutex) < 0)
{
DEBUGPANIC();
}
- list_add_tail(&sbus->rx_queue, &sframe->list_entry);
- nxsem_post(&sbus->queue_mutex);
+ list_add_tail(&ibus->rx_queue, &iframe->list_entry);
+ nxsem_post(&ibus->queue_mutex);
bcmf_netdev_notify_rx(priv);
@@ -331,9 +347,9 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
return ret;
exit_abort:
- bcmf_sdpcm_rxfail(sbus, false);
+ bcmf_sdpcm_rxfail(ibus, false);
exit_free_frame:
- bcmf_sdio_free_frame(priv, sframe);
+ bcmf_interface_free_frame(priv, iframe);
return ret;
}
@@ -341,18 +357,18 @@ int bcmf_sdpcm_sendframe(FAR struct bcmf_dev_s *priv)
{
int ret;
bool is_txframe;
- struct bcmf_sdio_frame *sframe;
+ bcmf_interface_frame_t *iframe;
struct bcmf_sdpcm_header *header;
- FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
+ FAR bcmf_interface_dev_t *ibus = (FAR bcmf_interface_dev_t *)priv->bus;
- if (list_is_empty(&sbus->tx_queue))
+ if (list_is_empty(&ibus->tx_queue))
{
/* No more frames to send */
return -ENODATA;
}
- if (sbus->tx_seq == sbus->max_seq)
+ if (ibus->tx_seq == ibus->max_seq)
{
/* TODO handle this case */
@@ -360,38 +376,38 @@ int bcmf_sdpcm_sendframe(FAR struct bcmf_dev_s *priv)
return -EAGAIN;
}
- if (nxsem_wait_uninterruptible(&sbus->queue_mutex) < 0)
+ if (nxsem_wait_uninterruptible(&ibus->queue_mutex) < 0)
{
DEBUGPANIC();
}
- sframe = list_remove_head_type(&sbus->tx_queue, struct bcmf_sdio_frame,
+ iframe = list_remove_head_type(&ibus->tx_queue, bcmf_interface_frame_t,
list_entry);
- nxsem_post(&sbus->queue_mutex);
+ nxsem_post(&ibus->queue_mutex);
- header = (struct bcmf_sdpcm_header *)sframe->header.base;
+ header = (struct bcmf_sdpcm_header *)iframe->header.base;
/* Set frame sequence id */
- header->sequence = sbus->tx_seq++;
+ header->sequence = ibus->tx_seq++;
-#if 0
- wlinfo("Send frame %p\n", sframe);
+#if 1
+ wlinfo("Send frame %p\n", iframe);
- bcmf_hexdump(sframe->header.base, sframe->header.len,
- (unsigned long)sframe->header.base);
+ bcmf_hexdump(iframe->header.base, iframe->header.len,
+ (unsigned long)iframe->header.base);
#endif
/* Write the frame data (the buffer is DMA aligned here) */
- ret = bcmf_transfer_bytes(sbus, true, 2, 0,
- sframe->header.base,
- sframe->header.len);
- is_txframe = sframe->tx;
+ ret = bcmf_transfer_bytes(ibus, true, 2, 0,
+ iframe->header.base,
+ iframe->header.len);
+ is_txframe = iframe->tx;
/* Free frame buffer */
- bcmf_sdio_free_frame(priv, sframe);
+ bcmf_interface_free_frame(priv, iframe);
if (ret == OK && is_txframe)
{
@@ -400,16 +416,18 @@ int bcmf_sdpcm_sendframe(FAR struct bcmf_dev_s *priv)
bcmf_netdev_notify_tx(priv);
}
+ wlinfo("return %d\n", ret);
+
return ret;
}
int bcmf_sdpcm_queue_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame, bool control)
{
- FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
- struct bcmf_sdio_frame *sframe = (struct bcmf_sdio_frame *)frame;
+ FAR bcmf_interface_dev_t *ibus = (FAR bcmf_interface_dev_t *)priv->bus;
+ bcmf_interface_frame_t *iframe = (bcmf_interface_frame_t *)frame;
struct bcmf_sdpcm_header *header =
- (struct bcmf_sdpcm_header *)sframe->data;
+ (struct bcmf_sdpcm_header *)iframe->data;
int semcount;
/* Prepare sw header */
@@ -430,21 +448,21 @@ int bcmf_sdpcm_queue_frame(FAR struct bcmf_dev_s *priv,
/* Add frame in tx queue */
- if (nxsem_wait_uninterruptible(&sbus->queue_mutex) < 0)
+ if (nxsem_wait_uninterruptible(&ibus->queue_mutex) < 0)
{
DEBUGPANIC();
}
- list_add_tail(&sbus->tx_queue, &sframe->list_entry);
+ list_add_tail(&ibus->tx_queue, &iframe->list_entry);
- nxsem_post(&sbus->queue_mutex);
+ nxsem_post(&ibus->queue_mutex);
/* Notify bcmf thread tx frame is ready */
- nxsem_get_value(&sbus->thread_signal, &semcount);
+ nxsem_get_value(&ibus->thread_signal, &semcount);
if (semcount < 1)
{
- nxsem_post(&sbus->thread_signal);
+ nxsem_post(&ibus->thread_signal);
}
return OK;
@@ -454,7 +472,7 @@ struct bcmf_frame_s *bcmf_sdpcm_alloc_frame(FAR struct bcmf_dev_s *priv,
unsigned int len, bool block,
bool control)
{
- struct bcmf_sdio_frame *sframe;
+ bcmf_interface_frame_t *iframe;
unsigned int header_len = sizeof(struct bcmf_sdpcm_header);
if (!control)
@@ -470,44 +488,44 @@ struct bcmf_frame_s *bcmf_sdpcm_alloc_frame(FAR struct bcmf_dev_s *priv,
/* Allocate a frame for RX in case of control frame */
- sframe = bcmf_sdio_allocate_frame(priv, block, !control);
+ iframe = bcmf_interface_allocate_frame(priv, block, !control);
- if (sframe == NULL)
+ if (iframe == NULL)
{
return NULL;
}
- sframe->header.len = header_len + len;
- sframe->header.data += header_len;
- return &sframe->header;
+ iframe->header.len = header_len + len;
+ iframe->header.data += header_len;
+ return &iframe->header;
}
void bcmf_sdpcm_free_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame)
{
- bcmf_sdio_free_frame(priv, (struct bcmf_sdio_frame *)frame);
+ bcmf_interface_free_frame(priv, (bcmf_interface_frame_t *)frame);
}
struct bcmf_frame_s *bcmf_sdpcm_get_rx_frame(FAR struct bcmf_dev_s *priv)
{
- struct bcmf_sdio_frame *sframe;
- FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
+ bcmf_interface_frame_t *iframe;
+ FAR bcmf_interface_dev_t *ibus = (FAR bcmf_interface_dev_t *)priv->bus;
- if (nxsem_wait_uninterruptible(&sbus->queue_mutex) < 0)
+ if (nxsem_wait_uninterruptible(&ibus->queue_mutex) < 0)
{
DEBUGPANIC();
}
- sframe = list_remove_head_type(&sbus->rx_queue,
- struct bcmf_sdio_frame,
+ iframe = list_remove_head_type(&ibus->rx_queue,
+ bcmf_interface_frame_t,
list_entry);
- nxsem_post(&sbus->queue_mutex);
+ nxsem_post(&ibus->queue_mutex);
- if (sframe == NULL)
+ if (iframe == NULL)
{
return NULL;
}
- return &sframe->header;
+ return &iframe->header;
}
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c b/drivers/wireless/ieee80211/bcm43xxx/cyw_chip_43439.c
similarity index 74%
copy from drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c
copy to drivers/wireless/ieee80211/bcm43xxx/cyw_chip_43439.c
index 2592b92c23..529b5c5f96 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c
+++ b/drivers/wireless/ieee80211/bcm43xxx/cyw_chip_43439.c
@@ -1,5 +1,5 @@
/****************************************************************************
- * drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_43438.c
+ * drivers/wireless/ieee80211/bcm43xxx/cyw_chip_43439.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -25,7 +25,7 @@
#include <nuttx/config.h>
#include <stdint.h>
-#include "bcmf_sdio.h"
+#include "bcmf_interface.h"
/****************************************************************************
* Pre-processor Definitions
@@ -37,18 +37,18 @@
* Public Data
****************************************************************************/
-extern const char ap6212_nvram_image[];
-extern const unsigned int ap6212_nvram_image_len;
+extern const char cyw43439_nvram_image[];
+extern const unsigned int cyw43439_nvram_image_len;
#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
-extern const uint8_t ap6212_firmware_image[];
-extern const unsigned int ap6212_firmware_len;
+extern const uint8_t cyw43439_firmware_image[];
+extern const unsigned int cyw43439_firmware_len;
-extern const uint8_t ap6212_clm_blob[];
-extern const unsigned int ap6212_clm_blob_len;
+extern const uint8_t cyw43439_clm_blob_image[];
+extern const unsigned int cyw43439_clm_blob_len;
#endif
-const struct bcmf_sdio_chip bcmf_43438_config_sdio =
+const struct bcmf_chip_data cyw43439_config_data =
{
/* General chip stats */
@@ -72,15 +72,17 @@ const struct bcmf_sdio_chip bcmf_43438_config_sdio =
/* TODO find something smarter than using image_len references */
- .nvram_image = (FAR uint8_t *)ap6212_nvram_image,
- .nvram_image_size = (FAR unsigned int *)&ap6212_nvram_image_len,
+ .nvram_image = (FAR uint8_t *)cyw43439_nvram_image,
+ .nvram_image_size = (FAR unsigned int *)&cyw43439_nvram_image_len,
#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
- .firmware_image = (FAR uint8_t *)ap6212_firmware_image,
- .firmware_image_size = (FAR unsigned int *)&ap6212_firmware_len,
+ .firmware_image = (FAR uint8_t *)cyw43439_firmware_image,
+ .firmware_image_size = (FAR unsigned int *)&cyw43439_firmware_len,
- .clm_blob_image = (FAR uint8_t *)ap6212_clm_blob,
- .clm_blob_image_size = (FAR unsigned int *)&ap6212_clm_blob_len,
+#ifdef CONFIG_IEEE80211_BROADCOM_HAVE_CLM
+ .clm_blob_image = (FAR uint8_t *)cyw43439_clm_blob_image,
+ .clm_blob_image_size = (FAR unsigned int *)&cyw43439_clm_blob_len
+#endif
#endif
};
diff --git a/drivers/wireless/ieee80211/bcm43xxx/cyw_reg_def.h b/drivers/wireless/ieee80211/bcm43xxx/cyw_reg_def.h
new file mode 100644
index 0000000000..d309a1bf7a
--- /dev/null
+++ b/drivers/wireless/ieee80211/bcm43xxx/cyw_reg_def.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+ * drivers/wireless/ieee80211/bcm43xxx/cyw_reg_def.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_WIRELESS_CYW43439_CYW_REG_DEF_H
+#define __DRIVERS_WIRELESS_CYW43439_CYW_REG_DEF_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/spi/spi.h>
+#include <nuttx/irq.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "bcmf_sdio_regs.h"
+
+/****************************************************************************
+ * Pre-Processor Declarations
+ ****************************************************************************/
+
+/* --- gSPI Registers --- */
+
+#define CYW_REG_SETUP (0x0000) /* 32-bit register */
+#define CYW_REG_INTERRUPT (0x0004) /* 16-bit register */
+#define CYW_REG_INTR_ENA (0x0006) /* 16-bit register */
+#define CYW_REG_STATUS (0x0008) /* 32-bit register */
+#define CYW_REG_F1_INFO (0x000c) /* 16-bit register */
+#define CYW_REG_F2_INFO (0x000e) /* 16-bit register */
+#define CYW_REG_TEST_RO (0x0014) /* 32-bit register */
+#define CYW_REG_TEST_RW (0x0018) /* 32-bit register */
+#define CYW_REG_RESP_DELAY_F0 (0x001c) /* 8-bit register */
+#define CYW_REG_RESP_DELAY_F1 (0x001d) /* 8-bit register */
+#define CYW_REG_RESP_DELAY_F2 (0x001e) /* 8-bit register */
+#define CYW_REG_RESP_DELAY_F3 (0x001f) /* 8-bit register */
+
+/* --- Registers --- */
+
+#define CYW_REG_SETUP_WORD_LEN_32 (1<<0)
+#define CYW_REG_SETUP_BIG_ENDIAN (1<<1)
+#define CYW_REG_SETUP_HIGH_SPEED (1<<4)
+#define CYW_REG_SETUP_INT_POLARITY (1<<5)
+#define CYW_REG_SETUP_WAKE_UP (1<<7)
+#define CYW_REG_SETUP_RESP_DELAY_SHIFT (8)
+#define CYW_REG_SETUP_RESP_DELAY_MASK (0x00FF << CYW_REG_SETUP_RESP_DELAY_SHIFT)
+#define CYW_REG_STAT_ENA_STAT_ENA (1<<16)
+#define CYW_REG_STAT_ENA_INTR_STAT (1<<17)
+
+#define CYW_REG_INTERRUPT_DATA_NOT_AVAIL (1<<0)
+#define CYW_REG_INTERRUPT_FIFO_UNDERFLOW (1<<1)
+#define CYW_REG_INTERRUPT_FIFO_OVERFLOW (1<<2)
+#define CYW_REG_INTERRUPT_COMMAND_ERROR (1<<3)
+#define CYW_REG_INTERRUPT_DATA_ERROR (1<<4)
+#define CYW_REG_INTERRUPT_F2_PKT_AVAIL (1<<5)
+#define CYW_REG_INTERRUPT_F3_PKT_AVAIL (1<<6)
+#define CYW_REG_INTERRUPT_F1_OVERFLOW (1<<7)
+#define CYW_REG_INTERRUPT_F1_INTERRUPT (1<<13)
+#define CYW_REG_INTERRUPT_F2_INTERRUPT (1<<14)
+#define CYW_REG_INTERRUPT_F3_INTERRUPT (1<<15)
+
+#define CYW_REG_INTR_ENA_DATA_NOT_AVAIL (1<<0)
+#define CYW_REG_INTR_ENA_FIFO_UNDERFLOW (1<<1)
+#define CYW_REG_INTR_ENA_FIFO_OVERFLOW (1<<2)
+#define CYW_REG_INTR_ENA_COMMAND_ERROR (1<<3)
+#define CYW_REG_INTR_ENA_DATA_ERROR (1<<4)
+#define CYW_REG_INTR_ENA_F2_PKT_AVAIL (1<<5)
+#define CYW_REG_INTR_ENA_F3_PKT_AVAIL (1<<6)
+#define CYW_REG_INTR_ENA_F1_OVERFLOW (1<<7)
+#define CYW_REG_INTR_ENA_F1_INTERRUPT (1<<13)
+#define CYW_REG_INTR_ENA_F2_INTERRUPT (1<<14)
+#define CYW_REG_INTR_ENA_F3_INTERRUPT (1<<15)
+
+#define CYW_REG_STATUS_DATA_NOT_AVAIL (1<<0)
+#define CYW_REG_STATUS_FIFO_UNDERFLOW (1<<1)
+#define CYW_REG_STATUS_FIFO_OVERFLOW (1<<2)
+#define CYW_REG_STATUS_F2_INTERRUPT (1<<3)
+#define CYW_REG_STATUS_F3_INTERRUPT (1<<4)
+#define CYW_REG_STATUS_F2_RECEIVE_RDY (1<<5)
+#define CYW_REG_STATUS_F3_RECEIVE_RDY (1<<6)
+#define CYW_REG_STATUS_CMD_DATA_ERROR (1<<7)
+#define CYW_REG_STATUS_F2_PKT_AVAIL (1<<8)
+#define CYW_REG_STATUS_F2_PKT_LEN_SHIFT (9)
+#define CYW_REG_STATUS_F2_PKT_LEN_MASK (0x7FF << CYW_REG_STATUS_F2_PKT_LEN_SHIFT)
+#define CYW_REG_STATUS_F3_PKT_AVAIL (1<<20)
+#define CYW_REG_STATUS_F3_PKT_LEN_SHIFT (21)
+#define CYW_REG_STATUS_F3_PKT_LEN_MASK (0x7FF << CYW_REG_STATUS_F3_PKT_LEN_SHIFT)
+
+#define CYW_REG_F1_INFO_ENABLED (1<<0)
+#define CYW_REG_F1_INFO_READY (1<<1)
+#define CYW_REG_F1_INFO_MAX_SIZE_SHIFT (2)
+#define CYW_REG_F1_INFO_MAX_SIZE_MASK (0x0FFF << CYW_REG_F1_INFO_MAX_SIZE_SHIFT)
+
+#define CYW_REG_F2_INFO_ENABLED (1<<0)
+#define CYW_REG_F2_INFO_READY (1<<1)
+#define CYW_REG_F2_INFO_MAX_SIZE_SHIFT (2)
+#define CYW_REG_F2_INFO_MAX_SIZE_MASK (0x0FFF << CYW_REG_F2_INFO_MAX_SIZE_SHIFT)
+
+#define CYW_REG_RESP_DELAY_F0_SHIFT (0)
+#define CYW_REG_RESP_DELAY_F0_MASK (0x00FF << CYW_REG_RESP_DELAY_F0_SHIFT)
+#define CYW_REG_RESP_DELAY_F1_SHIFT (8)
+#define CYW_REG_RESP_DELAY_F1_MASK (0x00FF << CYW_REG_RESP_DELAY_F1_SHIFT)
+#define CYW_REG_RESP_DELAY_F2_SHIFT (16)
+#define CYW_REG_RESP_DELAY_F2_MASK (0x00FF << CYW_REG_RESP_DELAY_F2_SHIFT)
+#define CYW_REG_RESP_DELAY_F3_SHIFT (24)
+#define CYW_REG_RESP_DELAY_F3_MASK (0x00FF << CYW_REG_RESP_DELAY_F3_SHIFT)
+
+#define CYW_REG_TEST_RO_PATTERN (0xfeedbead)
+
+#define CYW_STATUS_DATA_NOT_AVAIL (1<<0) /* data not avail on read */
+#define CYW_STATUS_FIFO_UNDERFLOW (1<<1) /* read underflow (F2, F3) */
+#define CYW_STATUS_FIFO_OVERFLOW (1<<2) /* write overflow (F1, F2, F3) */
+#define CYW_STATUS_F2_INTERRUPT (1<<3) /* F2 channel interrupt */
+#define CYW_STATUS_F3_INTERRUPT (1<<4)
+#define CYW_STATUS_F2_RECEIVE_RDY (1<<5) /* F2 ready to receive data */
+#define CYW_STATUS_F3_RECEIVE_RDY (1<<6)
+#define CYW_STATUS_CMD_DATA_ERROR (1<<7)
+#define CYW_STATUS_F2_PKT_AVAIL (1<<8) /* F2 has data to read */
+#define CYW_STATUS_F2_PKT_LEN_SHIFT (9) /* Length of avail F2 data */
+#define CYW_STATUS_F2_PKT_LEN_MASK (0x7FF << CYW_REG_STATUS_F2_PKT_LEN_SHIFT)
+#define CYW_STATUS_F3_PKT_AVAIL (1<<20)
+#define CYW_STATUS_F3_PKT_LEN_SHIFT (21)
+#define CYW_STATUS_F3_PKT_LEN_MASK (0x7FF << CYW_REG_STATUS_F3_PKT_LEN_SHIFT)
+
+/****************************************************************************
+ * Public Data Types
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+# define EXTERN extern "C"
+extern "C"
+ {
+#else
+# define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Functions Prototypes
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __DRIVERS_WIRELESS_CYW43439_CYW_REG_DEF_H */
diff --git a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c b/include/nuttx/wireless/ieee80211/bcmf_gpio.h
similarity index 51%
copy from drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
copy to include/nuttx/wireless/ieee80211/bcmf_gpio.h
index 7fdbea81ef..d466a291a6 100644
--- a/drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
+++ b/include/nuttx/wireless/ieee80211/bcmf_gpio.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * drivers/wireless/ieee80211/bcm43xxx/bcmf_chip_4301x.c
+ * include/nuttx/wireless/ieee80211/bcmf_gpio.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -18,66 +18,35 @@
*
****************************************************************************/
+#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_GPIO_H
+#define __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_GPIO_H
+
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
-#include <stdint.h>
-
-#include "bcmf_sdio.h"
/****************************************************************************
- * Pre-processor Definitions
+ * Private Type Definitions
****************************************************************************/
-#define WRAPPER_REGISTER_OFFSET 0x100000
+typedef struct bcmf_dev_s;
/****************************************************************************
- * Public Data
+ * Public Function Prototypes
****************************************************************************/
-extern const char bcm4301x_nvram_image[];
-extern const unsigned int bcm4301x_nvram_image_len;
-
-#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
-extern const uint8_t bcm4301x_firmware_image[];
-extern const unsigned int bcm4301x_firmware_image_len;
-#endif
-
-const struct bcmf_sdio_chip bcmf_4301x_config_sdio =
-{
- /* General chip stats */
-
- .ram_base = 0,
- .ram_size = 0xa0000,
-
- /* Backplane architecture */
-
- .core_base =
- {
- [CHIPCOMMON_CORE_ID] = 0x18000000, /* Chipcommon core register base */
- [DOT11MAC_CORE_ID] = 0x18001000, /* dot11mac core register base */
- [SDIOD_CORE_ID] = 0x18002000, /* SDIOD Device core register base */
- [WLAN_ARMCM3_CORE_ID] = 0x18003000 + /* ARMCM3 core register base */
- WRAPPER_REGISTER_OFFSET,
- [SOCSRAM_CORE_ID] = 0x18004000 + /* SOCSRAM core register base */
- WRAPPER_REGISTER_OFFSET
- },
-
- /* Firmware images */
-
- /* TODO find something smarter than using image_len references */
-
- .nvram_image = (FAR uint8_t *)bcm4301x_nvram_image,
- .nvram_image_size = (FAR unsigned int *)&bcm4301x_nvram_image_len,
+/****************************************************************************
+ * Name: bcmf_set_gpio
+ ****************************************************************************/
-#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
- .firmware_image = (FAR uint8_t *)bcm4301x_firmware_image,
- .firmware_image_size = (FAR unsigned int *)&bcm4301x_firmware_image_len,
-#endif
-};
+int bcmf_set_gpio(FAR struct bcmf_dev_s *priv, int pin, bool value);
/****************************************************************************
- * Public Functions
+ * Name: bcmf_get_gpio
****************************************************************************/
+
+int bcmf_get_gpio(FAR struct bcmf_dev_s *priv, int pin, bool *value);
+
+#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_GPIO_H */
diff --git a/include/nuttx/wireless/ieee80211/bcmf_gspi.h b/include/nuttx/wireless/ieee80211/bcmf_gspi.h
new file mode 100644
index 0000000000..984d13ef80
--- /dev/null
+++ b/include/nuttx/wireless/ieee80211/bcmf_gspi.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+ * include/nuttx/wireless/ieee80211/bcmf_gspi.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_GSPI_H
+#define __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_GSPI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/irq.h>
+
+#include "nuttx/net/net.h"
+#include "nuttx/net/netdev.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+enum gspi_cmd_func_e
+ {
+ gspi_f0_bus = 0x0,
+ gspi_f1_backplane = 0x1,
+ gspi_f2_dma = 0x2,
+ gspi_f3_dma = 0x3,
+ gspi_f0_bus_rev16 = 0x4 /* variant of gspi_f0_bus that does REV16 */
+ };
+
+struct bcmf_dev_s;
+
+/* --- Our extension to struct net_driver_s --- */
+
+typedef struct gspi_dev_s
+{
+ /* --------------------------------------------------------
+ * Each board that implements CYW43439 must initialize the
+ * following fields before calling gspi_register.
+ */
+
+ FAR int (*init) (FAR struct gspi_dev_s *gspi);
+
+ FAR int (*deinit) (FAR struct gspi_dev_s *gspi);
+
+ FAR int (*set_isr) (FAR struct gspi_dev_s *gspi,
+ xcpt_t thread_isr,
+ FAR void *thread_isr_arg);
+
+ FAR int (*interrupt_enable)(FAR struct gspi_dev_s *gspi,
+ bool enable);
+
+ FAR int (*write) (FAR struct gspi_dev_s *gspi,
+ bool increment,
+ enum gspi_cmd_func_e function,
+ uint32_t address,
+ uint16_t length,
+ FAR const uint32_t *data);
+
+ FAR int (*read) (FAR struct gspi_dev_s *gspi,
+ bool increment,
+ enum gspi_cmd_func_e function,
+ uint32_t address,
+ uint16_t length,
+ FAR uint32_t *buffer);
+
+ sem_t exclsem;
+
+ /* --------------------------------------------------------
+ * Other fields must be set to zero.
+ */
+
+ void *io_dev; /* Private data for opened io device. */
+ FAR struct bcmf_dev_s *priv; /* Back pointer to bus. */
+} gspi_dev_t;
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: bcmf_gspi_initialize
+ *
+ * Description:
+ * Initialize the cyw43439 driver.
+ *
+ ****************************************************************************/
+
+int bcmf_gspi_initialize(FAR gspi_dev_t *gspi);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_GSPI_H */