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:
parent
646cf35e54
commit
b539d04cfb
@ -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 **************************************************************/
|
||||
|
||||
|
@ -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)
|
||||
|
@ -9,15 +9,42 @@ config IEEE80211_BROADCOM_FULLMAC
|
||||
bool
|
||||
|
||||
config IEEE80211_BROADCOM_BCM43362
|
||||
bool "Broadcom 43362 chip support"
|
||||
depends on IEEE80211_BROADCOM_FULLMAC
|
||||
bool "Broadcom 43362 chip support"
|
||||
depends on IEEE80211_BROADCOM_FULLMAC
|
||||
default n
|
||||
|
||||
config IEEE80211_BROADCOM_BCM43438
|
||||
bool "Broadcom 43438 chip support"
|
||||
depends on IEEE80211_BROADCOM_FULLMAC
|
||||
bool "Broadcom 43438 chip support"
|
||||
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
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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,24 +394,29 @@ 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");
|
||||
return ret;
|
||||
wlerr("ERROR: Failed to upload firmware\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Flash NVRAM configuration file */
|
||||
|
||||
wlinfo("upload nvram configuration\n");
|
||||
ret = bcmf_upload_nvram(sbus);
|
||||
if (ret != OK)
|
||||
if (ret < 0)
|
||||
{
|
||||
wlerr("Failed to upload nvram\n");
|
||||
return ret;
|
||||
wlerr("ERROR: Failed to upload NVRAM\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Firmware upload done, restart ARMCM3 core */
|
||||
|
@ -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,19 +377,20 @@ 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;
|
||||
datalen -= chunk_len;
|
||||
srcbuff += chunk_len;
|
||||
|
||||
if (datalen <= 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user