Add gSPI mode support for Infineon CYW43539

This commit is contained in:
curuvar 2022-08-14 15:04:18 -04:00 committed by Xiang Xiao
parent 0892c895fc
commit e247eaf3e8
31 changed files with 3324 additions and 558 deletions

View file

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

View file

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

View file

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

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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);
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43438
if (sbus->cur_chip_id == SDIO_DEVICE_ID_BROADCOM_43430)
#if defined(CONFIG_IEEE80211_BROADCOM_BCM43438) \
|| defined(CONFIG_IEEE80211_INFINEON_CYW43439)
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);
}

View file

@ -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, &reg, 1);
return bcmf_write_sbreg(ibus, address, &reg, 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 *)&reg, 4);
return bcmf_write_sbreg(ibus, address, (uint8_t *)&reg, 4);
}
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_CORE_H */

View file

@ -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 */
return bcmf_driver_initialize(priv);
exit_free_device:
bcmf_free_device(priv);
return ret;
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;
}
/****************************************************************************
* 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,

View file

@ -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);

View file

@ -0,0 +1,86 @@
/****************************************************************************
* 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
* 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 <stdbool.h>
#include <nuttx/wireless/ieee80211/bcmf_gpio.h>
#include "bcmf_cdc.h"
#include "bcmf_interface.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bcmf_set_gpio
****************************************************************************/
int bcmf_set_gpio(FAR struct bcmf_dev_s *priv, int pin, bool value)
{
struct
{
uint32_t mask;
uint32_t value;
} buffer;
uint32_t buf_len = sizeof(buffer);
if (!(((FAR bcmf_interface_dev_t *)priv->bus)->ready)) return -EIO;
buffer.mask = 1 << pin;
buffer.value = value ? (1 << pin) : 0;
return bcmf_cdc_iovar_request(priv,
CHIP_STA_INTERFACE,
true,
IOVAR_STR_GPIOOUT,
(uint8_t *)&buffer,
&buf_len);
}
/****************************************************************************
* Name: bcmf_get_gpio
****************************************************************************/
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;
if (!(((FAR bcmf_interface_dev_t *)priv->bus)->ready)) return -EIO;
ret = bcmf_cdc_iovar_request(priv,
CHIP_STA_INTERFACE,
false,
IOVAR_STR_CCGPIOIN,
(uint8_t *)&buffer,
&buf_len);
if (ret != OK) return ret;
*value = (buffer & (1 << pin)) != 0;
return OK;
}

File diff suppressed because it is too large Load diff

View file

@ -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 */

View file

@ -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;
}

View file

@ -0,0 +1,66 @@
/****************************************************************************
* 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
* 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_F2_FRAME_H
#define __DRIVERS_WIRELESS_IEEE80211_BCM43XXX_BCMF_GSPI_F2_FRAME_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "bcmf_driver.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* 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);
/****************************************************************************
* 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 */

View file

@ -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;
}

View file

@ -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 */

View file

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

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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 */

View file

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

View file

@ -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,7 +246,7 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
goto exit_free_frame;
}
ret = bcmf_transfer_bytes(sbus, false, 2, 0,
ret = bcmf_transfer_bytes(ibus, false, 2, 0,
(uint8_t *)header + FIRST_WORD_SIZE,
len - FIRST_WORD_SIZE);
if (ret != OK)
@ -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;
}

View file

@ -0,0 +1,91 @@
/****************************************************************************
* 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
* 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 <stdint.h>
#include "bcmf_interface.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define WRAPPER_REGISTER_OFFSET 0x100000
/****************************************************************************
* Public Data
****************************************************************************/
extern const char cyw43439_nvram_image[];
extern const unsigned int cyw43439_nvram_image_len;
#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
extern const uint8_t cyw43439_firmware_image[];
extern const unsigned int cyw43439_firmware_len;
extern const uint8_t cyw43439_clm_blob_image[];
extern const unsigned int cyw43439_clm_blob_len;
#endif
const struct bcmf_chip_data cyw43439_config_data =
{
/* General chip stats */
.ram_base = 0,
.ram_size = 512 * 1024,
/* 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 *)cyw43439_nvram_image,
.nvram_image_size = (FAR unsigned int *)&cyw43439_nvram_image_len,
#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
.firmware_image = (FAR uint8_t *)cyw43439_firmware_image,
.firmware_image_size = (FAR unsigned int *)&cyw43439_firmware_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
};
/****************************************************************************
* Public Functions
****************************************************************************/

View file

@ -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 */

View file

@ -0,0 +1,52 @@
/****************************************************************************
* 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
* 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_GPIO_H
#define __INCLUDE_NUTTX_WIRELESS_IEEE80211_BCMF_GPIO_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
/****************************************************************************
* Private Type Definitions
****************************************************************************/
typedef struct bcmf_dev_s;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: bcmf_set_gpio
****************************************************************************/
int bcmf_set_gpio(FAR struct bcmf_dev_s *priv, int pin, bool value);
/****************************************************************************
* 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 */

View file

@ -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 */