diff --git a/arch/arm/src/stm32f7/chip/stm32f72xx73xx_memorymap.h b/arch/arm/src/stm32f7/chip/stm32f72xx73xx_memorymap.h index a0f348b10b..319b0e3526 100644 --- a/arch/arm/src/stm32f7/chip/stm32f72xx73xx_memorymap.h +++ b/arch/arm/src/stm32f7/chip/stm32f72xx73xx_memorymap.h @@ -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 **************************************************************/ diff --git a/arch/arm/src/stm32f7/chip/stm32f72xx73xx_pinmap.h b/arch/arm/src/stm32f7/chip/stm32f72xx73xx_pinmap.h index be428b4e3b..1bc2ffa5c2 100644 --- a/arch/arm/src/stm32f7/chip/stm32f72xx73xx_pinmap.h +++ b/arch/arm/src/stm32f7/chip/stm32f72xx73xx_pinmap.h @@ -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) diff --git a/drivers/wireless/ieee80211/Kconfig b/drivers/wireless/ieee80211/Kconfig index b34514326b..fbedd58609 100644 --- a/drivers/wireless/ieee80211/Kconfig +++ b/drivers/wireless/ieee80211/Kconfig @@ -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 diff --git a/drivers/wireless/ieee80211/bcmf_chip_43438.c b/drivers/wireless/ieee80211/bcmf_chip_43438.c index eab18dc555..3f613fb38b 100644 --- a/drivers/wireless/ieee80211/bcmf_chip_43438.c +++ b/drivers/wireless/ieee80211/bcmf_chip_43438.c @@ -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 }; diff --git a/drivers/wireless/ieee80211/bcmf_core.c b/drivers/wireless/ieee80211/bcmf_core.c index 170f1d9763..d0a55e2dd7 100644 --- a/drivers/wireless/ieee80211/bcmf_core.c +++ b/drivers/wireless/ieee80211/bcmf_core.c @@ -39,9 +39,11 @@ #include #include +#include #include #include +#include #include @@ -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 */ diff --git a/drivers/wireless/ieee80211/bcmf_driver.c b/drivers/wireless/ieee80211/bcmf_driver.c index d187d782e3..ae0a7d526b 100644 --- a/drivers/wireless/ieee80211/bcmf_driver.c +++ b/drivers/wireless/ieee80211/bcmf_driver.c @@ -44,6 +44,8 @@ #include #include #include +#include +#include #include @@ -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) {