drivers/wireless/ieee802.11: Add capabilility for Broadcom chips to get firmware and CLM data from a mounted file system vs. in-memory data structures.

This commit is contained in:
Ramtin Amin 2018-10-07 10:03:39 -06:00 committed by Gregory Nutt
parent 646cf35e54
commit b539d04cfb
6 changed files with 252 additions and 26 deletions

View File

@ -155,7 +155,7 @@
#define STM32_SPI5_BASE 0x40015000 /* 0x40015000-0x400153ff: SPI5 */
#define STM32_SAI1_BASE 0x40015800 /* 0x40015800-0x40015bff: SAI1 */
#define STM32_SAI2_BASE 0x40015c00 /* 0x40015c00-0x40015fff: SAI2 */
#define STM32_OTGPHY_BASE 0x40017c00 /* 0x40017C00-0x40017fff: OTG PHY HS */
#define STM32_USBPHYC_BASE 0x40017c00 /* 0x40017C00-0x40017fff: OTG PHY HS */
/* AHB1 Base Addresses **************************************************************/

View File

@ -488,8 +488,7 @@
#define GPIO_OTGHSFS_DM (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN14)
#define GPIO_OTGHSFS_DP (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTB|GPIO_PIN15)
#define GPIO_OTGHSFS_ID (GPIO_ALT|GPIO_PULLUP|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN12)
#define GPIO_OTGHS_SOF (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4)
#define GPIO_OTGHSFS_SOF (GPIO_ALT|GPIO_FLOAT|GPIO_AF12|GPIO_SPEED_100MHz|GPIO_PUSHPULL|GPIO_PORTA|GPIO_PIN4)
#define GPIO_OTGHS_ULPI_CK (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN5)
#define GPIO_OTGHS_ULPI_D0 (GPIO_ALT|GPIO_AF10|GPIO_PORTA|GPIO_PIN3)
@ -576,12 +575,7 @@
#define GPIO_SAI2_SD_B_3 (GPIO_ALT|GPIO_AF10|GPIO_PORTF|GPIO_PIN11)
#define GPIO_SAI2_SD_B_4 (GPIO_ALT|GPIO_AF10|GPIO_PORTG|GPIO_PIN10)
/* SD/MMC
*
* Note that the below configures GPIO_SPEED_50MHz I/O, that means for using
* the SDIO that you must enable I/O Compensation via the configuration option
* CONFIG_STM32F7_SYSCFG_IOCOMPENSATION=y.
*/
/* SD/MMC */
#define GPIO_SDMMC1_CK (GPIO_ALT|GPIO_AF12|GPIO_SPEED_50MHz|GPIO_PORTC|GPIO_PIN12)
#define GPIO_SDMMC1_CMD (GPIO_ALT|GPIO_AF12|GPIO_PULLUP|GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN2)

View File

@ -18,6 +18,33 @@ config IEEE80211_BROADCOM_BCM43438
depends on IEEE80211_BROADCOM_FULLMAC
default n
config IEEE80211_BROADCOM_FWFILES
bool "Firmware files"
default y
depends on IEEE80211_BROADCOM_BCM43438
---help---
By default, firmware files are provided in flash. This selection
enables an option to load the firmware files from a mounted file
system.
config IEEE80211_BROADCOM_FWFILENAME
string "Firmware file"
default "/mnt/sdcard/firmware.bin"
depends on IEEE80211_BROADCOM_FWFILES
---help---
If firmware files are provided on a file system, then this option
provides the full path to the file on a mounted file system where
the firmware can be found.
config IEEE80211_BROADCOM_FWCLMNAME
string "CLM file"
default "/mnt/sdcard/blob.bin"
depends on IEEE80211_BROADCOM_FWFILES
---help---
If firmware files are provided on a file system, then this option
provides the full path to the file on a mounted file system where
the CLM blob can be found.
config IEEE80211_BROADCOM_FULLMAC_SDIO
bool "Broadcom FullMAC driver on SDIO bus"
depends on ARCH_HAVE_SDIO

View File

@ -49,15 +49,16 @@
extern const char ap6212_nvram_image[];
extern const unsigned int ap6212_nvram_image_len;
#ifndef CONFIG_IEEE80211_BROADCOM_FWFILES
extern const uint8_t ap6212_firmware_image[];
extern const unsigned int ap6212_firmware_len;
extern const uint8_t ap6212_clm_blob[];
extern const unsigned int ap6212_clm_blob_len;
#endif
const struct bcmf_sdio_chip bcmf_43438_config_sdio =
{
/* General chip stats */
.ram_size = 512*1024,
@ -78,12 +79,22 @@ const struct bcmf_sdio_chip bcmf_43438_config_sdio =
/* Firmware images */
/* TODO find something smarter than using image_len references */
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
.firmware_image = (uint8_t *)NULL,
.firmware_image_size = (unsigned int *)NULL,
#else
.firmware_image = (uint8_t *)ap6212_firmware_image,
.firmware_image_size = (unsigned int *)&ap6212_firmware_len,
#endif
.nvram_image = (uint8_t *)ap6212_nvram_image,
.nvram_image_size = (unsigned int *)&ap6212_nvram_image_len,
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
.clm_blob_image = (uint8_t *)NULL,
.clm_blob_image_size = (unsigned int *)NULL,
#else
.clm_blob_image = (uint8_t *)ap6212_clm_blob,
.clm_blob_image_size = (unsigned int *)&ap6212_clm_blob_len,
#endif
};

View File

@ -39,9 +39,11 @@
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <nuttx/kmalloc.h>
#include <debug.h>
#include <errno.h>
#include <fcntl.h>
#include <nuttx/arch.h>
@ -178,6 +180,96 @@ int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
return OK;
}
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
int bcmf_upload_file(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
FAR const char *path)
{
struct file finfo;
FAR uint8_t *buf;
size_t total_read;
ssize_t nread;
int ret;
/* Open the file in the detached state */
ret = file_open(&finfo, path, O_RDONLY | O_BINARY);
if (ret <0)
{
wlerr("ERROR: Failed to open the FILE MTD file %s: %d\n", path, ret);
return ret;
}
/* Allocate an I/O buffer */
buf = (FAR uint8_t *)kmm_malloc(BCMF_UPLOAD_TRANSFER_SIZE);
if (buf == NULL)
{
wlerr("ERROR: Failed allocate an I/O buffer\n");
ret = -ENOMEM;
goto errout_with_file;
}
/* Loop until the firmware has been loaded */
do
{
/* Set the backplane window to include the start address */
nread = file_read(&finfo, buf, BCMF_UPLOAD_TRANSFER_SIZE);
if (nread < 0)
{
ret = (int)nread;
wlerr("ERROR: Failed to read file: %d\n", ret);
goto errout_with_buf;
}
if (nread == 0)
{
break;
}
wlinfo("Read %ld bytes\n", (long)nread);
ret = bcmf_core_set_backplane_window(sbus, address);
if (ret < 0)
{
wlerr("ERROR: bcmf_core_set_backplane_window() failed: %d\n", ret);
goto errout_with_buf;
}
total_read = nread;
/* Transfer firmware data */
ret = bcmf_transfer_bytes(sbus, true, 1,
address & SBSDIO_SB_OFT_ADDR_MASK, buf,
total_read);
if (ret < 0)
{
wlerr("ERROR: Transfer failed address=%lx total_read=%lu: %d\n",
(unsigned long)address, (unsigned long)total_read, ret);
goto errout_with_buf;
}
address += total_read;
}
while (nread == BCMF_UPLOAD_TRANSFER_SIZE);
file_close_detached(&finfo);
kmm_free(buf);
wlinfo("Upload complete\n");
return OK;
errout_with_buf:
kmm_free(buf);
errout_with_file:
file_close_detached(&finfo);
return ret;
}
#endif
int bcmf_upload_nvram(FAR struct bcmf_sdio_dev_s *sbus)
{
int ret;
@ -302,13 +394,18 @@ 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, 0, CONFIG_IEEE80211_BROADCOM_FWFILENAME);
#else
wlinfo("firmware size is %d bytes\n", *sbus->chip->firmware_image_size);
ret = bcmf_upload_binary(sbus, 0, sbus->chip->firmware_image,
*sbus->chip->firmware_image_size);
#endif
if (ret != OK)
if (ret < 0)
{
wlerr("Failed to upload firmware\n");
wlerr("ERROR: Failed to upload firmware\n");
return ret;
}
@ -316,9 +413,9 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
wlinfo("upload nvram configuration\n");
ret = bcmf_upload_nvram(sbus);
if (ret != OK)
if (ret < 0)
{
wlerr("Failed to upload nvram\n");
wlerr("ERROR: Failed to upload NVRAM\n");
return ret;
}

View File

@ -44,6 +44,8 @@
#include <string.h>
#include <debug.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <net/ethernet.h>
@ -66,7 +68,7 @@
#define DOT11_BSSTYPE_ANY 2
#define BCMF_SCAN_TIMEOUT_TICK (5*CLOCKS_PER_SEC)
#define BCMF_AUTH_TIMEOUT_MS 10000
#define BCMF_AUTH_TIMEOUT_MS 20000 /* was 10000 */
#define BCMF_SCAN_RESULT_SIZE 1024
/* clm file is cut into pieces of MAX_CHUNK_LEN.
@ -75,7 +77,11 @@
* len should not exceed 1400 bytes
*/
#define MAX_CHUNK_LEN (CONFIG_NET_ETH_PKTSIZE > 1500 ? 1400 : CONFIG_NET_ETH_PKTSIZE - 100)
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES /* REVISIT */
# define MAX_CHUNK_LEN (100)
#else
# define MAX_CHUNK_LEN (CONFIG_NET_ETH_MTU > 1500 ? 1400 : CONFIG_NET_ETH_MTU - 100)
#endif
/* Helper to get iw_event size */
@ -251,6 +257,94 @@ int bcmf_wl_set_mac_address(FAR struct bcmf_dev_s *priv, struct ifreq *req)
return OK;
}
#ifdef CONFIG_IEEE80211_BROADCOM_FWFILES
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 *downloadbuff;
struct file finfo;
ssize_t nread;
uint16_t dl_flag;
unsigned int datalen = 7222;
int ret;
wlinfo("Download %d bytes\n", datalen);
ret = file_open(&tmp, CONFIG_IEEE80211_BROADCOM_FWCLMNAME,
O_RDONLY | O_BINARY);
if (ret < 0)
{
wlerr("ERROR: Failed to open the FILE MTD file \n", ret);
return ret
}
/* Divide clm blob into chunks */
downloadbuff = kmm_malloc(sizeof(struct wl_dload_data) + MAX_CHUNK_LEN);
if (downloadbuff == NULL)
{
wlerr("ERROR: Failed allocate memory for CLM data\n");
ret = -ENOMEM;
goto errout_with_file;
}
dl_flag = DL_BEGIN;
do
{
FAR struct wl_dload_data *dlhead;
unsigned int chunk_len;
uint32_t out_len;
chunk_len = datalen >= MAX_CHUNK_LEN ? MAX_CHUNK_LEN : datalen;
nread = file_read(&finfo, downloadbuff + sizeof(struct wl_dload_data),
chunk_len);
if (nread < 0)
{
ret = (int)nread;
wlerr("ERROR: Failed to read CLM data: %d\n", ret);
goto errout_with_buffer;
}
wlinfo("Read blob %d bytes on %d\n", nread, chunk_len);
datalen -= chunk_len;
if (datalen <= 0)
{
dl_flag |= DL_END;
}
/* CLM header */
dlhead = (struct wl_dload_data *)downloadbuff;
dlhead->flag = (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT) | dl_flag;
dlhead->dload_type = DL_TYPE_CLM;
dlhead->len = chunk_len;
dlhead->crc = 0;
out_len = chunk_len + sizeof(struct wl_dload_data);
out_len = (out_len + 7) & ~0x7U;
ret = bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, true,
IOVAR_STR_CLMLOAD, downloadbuff,
&out_len);
wlinfo("datalen=%d, ret=%d\n", datalen, ret);
dl_flag &= (uint16_t)~DL_BEGIN;
}
while ((datalen > 0) && (ret == OK));
wlinfo("Done writing blob");
errout_with_buffer:
kmm_free(downloadbuff);
errout_with_file:
file_close_detached(&finfo);
return ret;
}
#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;
@ -283,9 +377,10 @@ int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
do
{
FAR struct wl_dload_data *dlhead;
unsigned int chunk_len = datalen >= MAX_CHUNK_LEN ? MAX_CHUNK_LEN : datalen;
unsigned int chunk_len = datalen;
uint32_t out_len;
chunk_len = datalen >= MAX_CHUNK_LEN ? MAX_CHUNK_LEN : datalen;
memcpy(downloadbuff + sizeof(struct wl_dload_data), srcbuff, chunk_len);
datalen -= chunk_len;
srcbuff += chunk_len;
@ -295,7 +390,7 @@ int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
dl_flag |= DL_END;
}
/* clm header */
/* CLM header */
dlhead = (struct wl_dload_data *)downloadbuff;
dlhead->flag = (DLOAD_HANDLER_VER << DLOAD_FLAG_VER_SHIFT) | dl_flag;
@ -317,6 +412,7 @@ int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv)
kmm_free(downloadbuff);
return ret;
}
#endif
int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
{
@ -489,6 +585,7 @@ void bcmf_wl_auth_event_handler(FAR struct bcmf_dev_s *priv,
/* bcmf_wl_scan_event_handler must run at high priority else
* race condition may occur on priv->scan_result field
*/
void bcmf_wl_scan_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len)
{