drivers/wiresless/ieee80211: Correct some initialization problems with BCM43362 chip. Adds BCM43428 support. arch/arm/src: Add support for SDIO card to SDIO driver.
Squashed commit of the following: Author: Gregory Nutt <gnutt@nuttx.org> include/nuttx/wireless/ieee80211: Cosmetic, coding standard changes from review of last merge. drivers/wireless/ieee80211: Cosmetic, coding standard changes from review of last merge. configs/photon: Cosmetic, coding standard changes from review of last merge. arch/arm/src/stm32: SDIO changes from last review: Fix a few long lines and other coding standard issues; Make additions for SDIO card support dependent on a configuration option. Author: hhuysqt <hyq9606@126.com> Return IEEE 802.11 MAC address just as ethernet does Modifyed bcmf_board_setup_oob_irq declaration Modified OOB ISR function types Add some logic according to WICED SDK Bug fixed: data_offset counts in 4-bytes Add BCM43438 logic for future developement Add tips on using telnet Use SDIO in-band interrupt instead of OOB interrupt, because Photon seems to unconnect the OOB interrupt line... add SDIO in-band interrupt logic
This commit is contained in:
parent
0c963449d6
commit
144e335b85
@ -7595,6 +7595,13 @@ endmenu
|
||||
menu "SDIO Configuration"
|
||||
depends on STM32_SDIO
|
||||
|
||||
config STM32_SDIO_CARD
|
||||
bool "SDIO Card support"
|
||||
default n
|
||||
---help---
|
||||
Build in additional support needed only for SDIO cards (vs. SD
|
||||
memory cards)
|
||||
|
||||
config STM32_SDIO_DMA
|
||||
bool "Support DMA data transfers"
|
||||
default y if STM32_DMA2
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32/stm32_sdio.c
|
||||
*
|
||||
* Copyright (C) 2009, 2011-2014, 2016-2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2009, 2011-2014, 2016-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -335,6 +335,14 @@ struct stm32_dev_s
|
||||
size_t remaining; /* Number of bytes remaining in the transfer */
|
||||
uint32_t xfrmask; /* Interrupt enables for data transfer */
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_CARD
|
||||
/* Interrupt at SDIO_D1 pin, only for SDIO cards */
|
||||
|
||||
uint32_t sdiointmask; /* STM32 SDIO register mask */
|
||||
int (*do_sdio_card)(void *); /* SDIO card ISR */
|
||||
void *do_sdio_arg; /* arg for SDIO card ISR */
|
||||
#endif
|
||||
|
||||
/* Fixed transfer block size support */
|
||||
|
||||
#ifdef CONFIG_SDIO_BLOCKSETUP
|
||||
@ -703,7 +711,14 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
|
||||
#ifdef CONFIG_STM32_SDIO_DMA
|
||||
priv->xfrflags = 0;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_CARD
|
||||
putreg32(priv->xfrmask | priv->waitmask | priv->sdiointmask,
|
||||
STM32_SDIO_MASK);
|
||||
#else
|
||||
putreg32(priv->xfrmask | priv->waitmask, STM32_SDIO_MASK);
|
||||
#endif
|
||||
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
@ -725,9 +740,15 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask,
|
||||
static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
priv->xfrmask = xfrmask;
|
||||
#ifdef CONFIG_STM32_SDIO_CARD
|
||||
putreg32(priv->xfrmask | priv->waitmask | priv->sdiointmask,
|
||||
STM32_SDIO_MASK);
|
||||
#else
|
||||
putreg32(priv->xfrmask | priv->waitmask, STM32_SDIO_MASK);
|
||||
#endif
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
@ -1534,6 +1555,23 @@ static int stm32_interrupt(int irq, void *context, FAR void *arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_CARD
|
||||
/* Handle SDIO card interrupt */
|
||||
|
||||
pending = enabled & priv->sdiointmask;
|
||||
if (pending != 0)
|
||||
{
|
||||
putreg32(SDIO_STA_SDIOIT, STM32_SDIO_ICR);
|
||||
|
||||
/* Perform callback */
|
||||
|
||||
if (priv->do_sdio_card)
|
||||
{
|
||||
priv->do_sdio_card(priv->do_sdio_arg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -1617,6 +1655,10 @@ static void stm32_reset(FAR struct sdio_dev_s *dev)
|
||||
priv->remaining = 0; /* Number of bytes remaining in the transfer */
|
||||
priv->xfrmask = 0; /* Interrupt enables for data transfer */
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_CARD
|
||||
priv->sdiointmask = 0; /* SDIO card in-band interrupt mask */
|
||||
#endif
|
||||
|
||||
/* DMA data transfer support */
|
||||
|
||||
priv->widebus = false; /* Required for DMA support */
|
||||
@ -3100,4 +3142,44 @@ void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect)
|
||||
mcinfo("cdstatus: %02x\n", priv->cdstatus);
|
||||
leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sdio_set_sdio_card_isr
|
||||
*
|
||||
* Description:
|
||||
* SDIO card generates interrupt via SDIO_DATA_1 pin.
|
||||
* Called by board-specific logic to register an ISR for SDIO card.
|
||||
*
|
||||
* Input Parameters:
|
||||
* func - callback function.
|
||||
* arg - arg to be passed to the function.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_CARD
|
||||
void sdio_set_sdio_card_isr(FAR struct sdio_dev_s *dev,
|
||||
int (*func)(void *), void *arg)
|
||||
{
|
||||
struct stm32_dev_s *priv = (struct stm32_dev_s *)dev;
|
||||
|
||||
priv->do_sdio_card = func;
|
||||
|
||||
if (func != NULL)
|
||||
{
|
||||
priv->sdiointmask = SDIO_STA_SDIOIT;
|
||||
priv->do_sdio_arg = arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->sdiointmask = 0;
|
||||
}
|
||||
|
||||
putreg32(priv->xfrmask | priv->waitmask | priv->sdiointmask,
|
||||
STM32_SDIO_MASK);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_STM32_SDIO */
|
||||
|
@ -118,6 +118,27 @@ void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot);
|
||||
|
||||
void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sdio_set_sdio_card_isr
|
||||
*
|
||||
* Description:
|
||||
* SDIO card generates interrupt via SDIO_DATA_1 pin.
|
||||
* Called by board-specific logic to register an ISR for SDIO card.
|
||||
*
|
||||
* Input Parameters:
|
||||
* func - callback function.
|
||||
* arg - arg to be passed to the function.
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_STM32_SDIO_CARD
|
||||
void sdio_set_sdio_card_isr(FAR struct sdio_dev_s *dev,
|
||||
int (*func)(void *), void *arg);
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -114,6 +114,29 @@ Flashing NuttX in the Photon board
|
||||
Download done.
|
||||
File downloaded successfully
|
||||
|
||||
3) Restore the original firmware
|
||||
|
||||
If you config to use the stock bootloader of Photon, you may
|
||||
reload the original firmware with dfu-utils as you like. Otherwize
|
||||
you must have backuped the whole image beforehand, and reload it
|
||||
via SWD debug port.
|
||||
|
||||
NSH via telnet
|
||||
==============
|
||||
|
||||
After you successfully downloaded nuttx.bin, reset the board and it
|
||||
automatically connects to the corresponding wifi AP. You may login
|
||||
your router to see its IP address. Assume that it's 192.168.1.111
|
||||
|
||||
Open a terminal on your computer and telnet your Photon:
|
||||
|
||||
$ telnet 192.168.1.111
|
||||
Trying 192.168.1.111...
|
||||
Connected to 192.168.1.111.
|
||||
Escape character is '^]'
|
||||
|
||||
NuttShell (NSH) NuttX-7.24
|
||||
nsh>
|
||||
|
||||
Serial console configuration
|
||||
============================
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* configs/photon/src/stm32_wlan.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -51,6 +51,12 @@
|
||||
|
||||
#include "photon.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct sdio_dev_s *g_sdio_dev;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -102,18 +108,19 @@ void bcmf_board_initialize(int minor)
|
||||
* Name: bcmf_board_setup_oob_irq
|
||||
****************************************************************************/
|
||||
|
||||
void bcmf_board_setup_oob_irq(int minor, xcpt_t func, void *arg)
|
||||
void bcmf_board_setup_oob_irq(int minor, int (*func)(void *), void *arg)
|
||||
{
|
||||
if (minor != SDIO_WLAN0_MINOR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Configure interrupt pin */
|
||||
/* Configure SDIO card in-band interrupt callback */
|
||||
|
||||
stm32_configgpio(GPIO_WLAN0_OOB_INT);
|
||||
|
||||
stm32_gpiosetevent(GPIO_WLAN0_OOB_INT, true, false, false, func, arg);
|
||||
if (g_sdio_dev != NULL)
|
||||
{
|
||||
sdio_set_sdio_card_isr(g_sdio_dev, func, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -123,15 +130,14 @@ void bcmf_board_setup_oob_irq(int minor, xcpt_t func, void *arg)
|
||||
int photon_wlan_initialize()
|
||||
{
|
||||
int ret;
|
||||
struct sdio_dev_s *sdio_dev;
|
||||
|
||||
/* Initialize sdio interface */
|
||||
|
||||
wlinfo("Initializing SDIO slot %d\n", SDIO_WLAN0_SLOTNO);
|
||||
|
||||
sdio_dev = sdio_initialize(SDIO_WLAN0_SLOTNO);
|
||||
g_sdio_dev = sdio_initialize(SDIO_WLAN0_SLOTNO);
|
||||
|
||||
if (!sdio_dev)
|
||||
if (!g_sdio_dev)
|
||||
{
|
||||
wlerr("ERROR: Failed to initialize SDIO with slot %d\n",
|
||||
SDIO_WLAN0_SLOTNO);
|
||||
@ -140,7 +146,7 @@ int photon_wlan_initialize()
|
||||
|
||||
/* Bind the SDIO interface to the bcmf driver */
|
||||
|
||||
ret = bcmf_sdio_initialize(SDIO_WLAN0_MINOR, sdio_dev);
|
||||
ret = bcmf_sdio_initialize(SDIO_WLAN0_MINOR, g_sdio_dev);
|
||||
|
||||
if (ret != OK)
|
||||
{
|
||||
|
@ -13,6 +13,11 @@ config IEEE80211_BROADCOM_BCM43362
|
||||
depends on IEEE80211_BROADCOM_FULLMAC
|
||||
default n
|
||||
|
||||
config IEEE80211_BROADCOM_BCM43438
|
||||
bool "Broadcom 43438 chip support"
|
||||
depends on IEEE80211_BROADCOM_FULLMAC
|
||||
default n
|
||||
|
||||
config IEEE80211_BROADCOM_FULLMAC_SDIO
|
||||
bool "Broadcom FullMAC driver on SDIO bus"
|
||||
depends on ARCH_HAVE_SDIO
|
||||
|
@ -58,6 +58,10 @@ ifeq ($(CONFIG_IEEE80211_BROADCOM_BCM43362),y)
|
||||
CSRCS += bcmf_chip_43362.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_IEEE80211_BROADCOM_BCM43438),y)
|
||||
CSRCS += bcmf_chip_43438.c
|
||||
endif
|
||||
|
||||
endif # CONFIG_IEEE80211_BROADCOM_FULLMAC
|
||||
|
||||
# Include IEEE 802.11 build support
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/ieee80211/bcmf_bdc.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -66,8 +66,8 @@ struct __attribute__((packed)) bcmf_bdc_header
|
||||
{
|
||||
uint8_t flags; /* bdc frame flags */
|
||||
uint8_t priority; /* bdc frame priority */
|
||||
uint8_t flags2; /* bdc frame additionnal flags */
|
||||
uint8_t data_offset; /* Offset from end of header to payload data */
|
||||
uint8_t flags2; /* bdc frame additional flags */
|
||||
uint8_t data_offset; /* Offset from end of header to payload data, in 4-bytes count */
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) bcmf_eth_header
|
||||
@ -138,7 +138,7 @@ int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
|
||||
|
||||
header = (struct bcmf_bdc_header *)frame->data;
|
||||
|
||||
data_size -= sizeof(struct bcmf_bdc_header) + header->data_offset;
|
||||
data_size -= sizeof(struct bcmf_bdc_header) + header->data_offset * 4;
|
||||
|
||||
if (data_size < sizeof(struct bcmf_event_msg))
|
||||
{
|
||||
@ -151,7 +151,7 @@ int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
|
||||
|
||||
event_msg = (struct bcmf_event_msg *)(frame->data +
|
||||
sizeof(struct bcmf_bdc_header) +
|
||||
header->data_offset);
|
||||
header->data_offset * 4);
|
||||
|
||||
if (event_msg->eth.ether_type != BCMF_EVENT_ETHER_TYPE ||
|
||||
memcmp(event_msg->bcm_eth.oui, bcmf_broadcom_oui, 3))
|
||||
@ -258,6 +258,7 @@ struct bcmf_frame_s *bcmf_bdc_rx_frame(FAR struct bcmf_dev_s *priv)
|
||||
{
|
||||
unsigned int frame_len;
|
||||
struct bcmf_frame_s *frame = priv->bus->rxframe(priv);
|
||||
struct bcmf_bdc_header *header;
|
||||
|
||||
/* Process bdc header */
|
||||
|
||||
@ -272,6 +273,7 @@ struct bcmf_frame_s *bcmf_bdc_rx_frame(FAR struct bcmf_dev_s *priv)
|
||||
|
||||
/* Transmit frame to upper layer */
|
||||
|
||||
frame->data += sizeof(struct bcmf_bdc_header);
|
||||
header = (struct bcmf_bdc_header*)frame->data;
|
||||
frame->data += sizeof(struct bcmf_bdc_header) + header->data_offset * 4;
|
||||
return frame;
|
||||
}
|
||||
|
@ -33,15 +33,19 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __DRIVERS_WIRELESS_IEEE80211_BCMF_BDC_H
|
||||
#define __DRIVERS_WIRELESS_IEEE80211_BCMF_BDC_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __DRIVERS_WIRELESS_IEEE80211_BCMF_BDC_H
|
||||
#define __DRIVERS_WIRELESS_IEEE80211_BCMF_BDC_H
|
||||
|
||||
#include "bcmf_driver.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Event frame content */
|
||||
|
||||
struct __attribute__((packed)) bcmf_event_s
|
||||
|
89
drivers/wireless/ieee80211/bcmf_chip_43438.c
Normal file
89
drivers/wireless/ieee80211/bcmf_chip_43438.c
Normal file
@ -0,0 +1,89 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/ieee80211/bcmf_chip_43438.c
|
||||
*
|
||||
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "bcmf_sdio.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define WRAPPER_REGISTER_OFFSET 0x100000
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
extern const char ap6212_nvram_image[];
|
||||
extern const unsigned int ap6212_nvram_image_len;
|
||||
|
||||
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;
|
||||
|
||||
const struct bcmf_sdio_chip bcmf_43438_config_sdio =
|
||||
{
|
||||
|
||||
/* General chip stats */
|
||||
|
||||
.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 */
|
||||
|
||||
.firmware_image = (uint8_t *)ap6212_firmware_image,
|
||||
.firmware_image_size = (unsigned int *)&ap6212_firmware_len,
|
||||
|
||||
.nvram_image = (uint8_t *)ap6212_nvram_image,
|
||||
.nvram_image_size = (unsigned int *)&ap6212_nvram_image_len,
|
||||
|
||||
.clm_blob_image = (uint8_t *)ap6212_clm_blob,
|
||||
.clm_blob_image_size = (unsigned int *)&ap6212_clm_blob_len,
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/ieee80211/bcmf_core.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -55,6 +55,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
/* Agent registers (common for every core) */
|
||||
|
||||
#define BCMA_IOCTL 0x0408 /* IO control */
|
||||
#define BCMA_IOST 0x0500 /* IO status */
|
||||
#define BCMA_RESET_CTL 0x0800 /* Reset control */
|
||||
@ -74,8 +75,14 @@
|
||||
|
||||
#define BCMA_RESET_CTL_RESET 0x0001
|
||||
|
||||
/* SOCSRAM core registers */
|
||||
|
||||
#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 BCMF_UPLOAD_TRANSFER_SIZE (64 * 256)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@ -87,11 +94,9 @@
|
||||
|
||||
static int bcmf_core_set_backplane_window(FAR struct bcmf_sdio_dev_s *sbus,
|
||||
uint32_t address);
|
||||
|
||||
static int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbusv,
|
||||
uint32_t address, uint8_t *buf,
|
||||
unsigned int len);
|
||||
|
||||
uint32_t address, uint8_t *buf,
|
||||
unsigned int len);
|
||||
static int bcmf_upload_nvram(FAR struct bcmf_sdio_dev_s *sbus);
|
||||
|
||||
/****************************************************************************
|
||||
@ -169,6 +174,7 @@ int bcmf_upload_binary(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
|
||||
address += size;
|
||||
buf += size;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -202,7 +208,8 @@ int bcmf_upload_nvram(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
|
||||
/* Write the length token to the last word */
|
||||
|
||||
ret = bcmf_write_sbreg(sbus, sbus->chip->ram_size - 4, (uint8_t *)&token, 4);
|
||||
ret = bcmf_write_sbreg(sbus, sbus->chip->ram_size - 4,
|
||||
(FAR uint8_t *)&token, 4);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
@ -220,7 +227,7 @@ int bcmf_upload_nvram(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
****************************************************************************/
|
||||
|
||||
int bcmf_read_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
|
||||
uint8_t *reg, unsigned int len)
|
||||
FAR uint8_t *reg, unsigned int len)
|
||||
{
|
||||
int ret = bcmf_core_set_backplane_window(sbus, address);
|
||||
if (ret != OK)
|
||||
@ -228,6 +235,13 @@ int bcmf_read_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Map to 32-bit access if len == 4 */
|
||||
|
||||
if (len == 4)
|
||||
{
|
||||
address |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
}
|
||||
|
||||
return bcmf_transfer_bytes(sbus, false, 1,
|
||||
address & SBSDIO_SB_OFT_ADDR_MASK, reg, len);
|
||||
}
|
||||
@ -237,7 +251,7 @@ int bcmf_read_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
|
||||
****************************************************************************/
|
||||
|
||||
int bcmf_write_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
|
||||
uint8_t *reg, unsigned int len)
|
||||
FAR uint8_t *reg, unsigned int len)
|
||||
{
|
||||
|
||||
int ret = bcmf_core_set_backplane_window(sbus, address);
|
||||
@ -246,6 +260,13 @@ int bcmf_write_sbreg(FAR struct bcmf_sdio_dev_s *sbus, uint32_t address,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Map to 32-bit access if len == 4 */
|
||||
|
||||
if (len == 4)
|
||||
{
|
||||
address |= SBSDIO_SB_ACCESS_2_4B_FLAG;
|
||||
}
|
||||
|
||||
return bcmf_transfer_bytes(sbus, true, 1, address & SBSDIO_SB_OFT_ADDR_MASK,
|
||||
reg, len);
|
||||
}
|
||||
@ -260,12 +281,23 @@ int bcmf_core_upload_firmware(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
|
||||
wlinfo("upload firmware\n");
|
||||
|
||||
/* Disable ARMCM3 core and reset SOCRAM core
|
||||
* to set device in firmware upload mode */
|
||||
/* Disable ARMCM3 core and reset SOCRAM core to set device in firmware
|
||||
* upload mode
|
||||
*/
|
||||
|
||||
bcmf_core_disable(sbus, WLAN_ARMCM3_CORE_ID);
|
||||
bcmf_core_reset(sbus, SOCSRAM_CORE_ID);
|
||||
|
||||
/* Do chip specific initialization */
|
||||
|
||||
if (sbus->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);
|
||||
}
|
||||
|
||||
up_mdelay(50);
|
||||
|
||||
/* Flash chip firmware */
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/ieee80211/bcmf_driver.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -69,15 +69,43 @@
|
||||
#define BCMF_AUTH_TIMEOUT_MS 10000
|
||||
#define BCMF_SCAN_RESULT_SIZE 1024
|
||||
|
||||
/* clm file is cut into pieces of MAX_CHUNK_LEN.
|
||||
* It is relatively small because dongles (FW) have a small maximum size input
|
||||
* payload restriction for ioctl's ... something like 1900'ish bytes. So chunk
|
||||
* len should not exceed 1400 bytes
|
||||
*/
|
||||
|
||||
#define MAX_CHUNK_LEN (CONFIG_NET_ETH_MTU > 1500 ? 1400 : CONFIG_NET_ETH_MTU - 100)
|
||||
|
||||
/* Helper to get iw_event size */
|
||||
|
||||
#define BCMF_IW_EVENT_SIZE(field) \
|
||||
(offsetof(struct iw_event, u)+sizeof(((union iwreq_data*)0)->field))
|
||||
|
||||
/* Clm blob marcos */
|
||||
|
||||
#define DLOAD_HANDLER_VER 1 /* Downloader version */
|
||||
#define DLOAD_FLAG_VER_MASK 0xf000 /* Downloader version mask */
|
||||
#define DLOAD_FLAG_VER_SHIFT 12 /* Downloader version shift */
|
||||
|
||||
#define DL_CRC_NOT_INUSE 0x0001
|
||||
#define DL_BEGIN 0x0002
|
||||
#define DL_END 0x0004
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* clm blob download head */
|
||||
|
||||
struct wl_dload_data
|
||||
{
|
||||
uint16_t flag;
|
||||
uint16_t dload_type;
|
||||
uint32_t len;
|
||||
uint32_t crc;
|
||||
};
|
||||
|
||||
/* AP scan state machine status */
|
||||
|
||||
enum
|
||||
@ -88,6 +116,14 @@ enum
|
||||
BCMF_SCAN_DONE
|
||||
};
|
||||
|
||||
/* Generic download types & flags */
|
||||
|
||||
enum
|
||||
{
|
||||
DL_TYPE_UCODE = 1,
|
||||
DL_TYPE_CLM = 2
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
@ -97,6 +133,8 @@ static void bcmf_free_device(FAR struct bcmf_dev_s *priv);
|
||||
|
||||
static int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv);
|
||||
|
||||
static int bcmf_driver_download_clm(FAR struct bcmf_dev_s *priv);
|
||||
|
||||
// FIXME only for debug purpose
|
||||
|
||||
static void bcmf_wl_default_event_handler(FAR struct bcmf_dev_s *priv,
|
||||
@ -213,6 +251,73 @@ int bcmf_wl_set_mac_address(FAR struct bcmf_dev_s *priv, struct ifreq *req)
|
||||
return OK;
|
||||
}
|
||||
|
||||
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 uint8_t *downloadbuff;
|
||||
unsigned int datalen = *sbus->chip->clm_blob_image_size;
|
||||
uint16_t dl_flag;
|
||||
int ret = 0;
|
||||
|
||||
if (srcbuff == NULL || datalen <= 0)
|
||||
{
|
||||
wlinfo("Skip clm blob...\n");
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wlinfo("Download %d bytes @ 0x%08x\n", datalen, srcbuff);
|
||||
}
|
||||
|
||||
/* Divide clm blob into chunks */
|
||||
|
||||
downloadbuff = kmm_malloc(sizeof(struct wl_dload_data) + MAX_CHUNK_LEN);
|
||||
if (!downloadbuff)
|
||||
{
|
||||
wlerr("No memory for clm data\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dl_flag = DL_BEGIN;
|
||||
do
|
||||
{
|
||||
FAR struct wl_dload_data *dlhead;
|
||||
unsigned int chunk_len = datalen >= MAX_CHUNK_LEN ? MAX_CHUNK_LEN : datalen;
|
||||
uint32_t out_len;
|
||||
|
||||
memcpy(downloadbuff + sizeof(struct wl_dload_data), srcbuff, chunk_len);
|
||||
datalen -= chunk_len;
|
||||
srcbuff += 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);
|
||||
|
||||
dl_flag &= (uint16_t)~DL_BEGIN;
|
||||
}
|
||||
while ((datalen > 0) && (ret == OK));
|
||||
|
||||
kmm_free(downloadbuff);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
|
||||
{
|
||||
int ret;
|
||||
@ -221,11 +326,19 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
|
||||
uint8_t tmp_buf[64];
|
||||
int interface = CHIP_STA_INTERFACE;
|
||||
|
||||
/* Download clm blob if needed */
|
||||
|
||||
ret = bcmf_driver_download_clm(priv);
|
||||
if (ret != OK)
|
||||
{
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* Disable TX Gloming feature */
|
||||
|
||||
out_len = 4;
|
||||
*(uint32_t *)tmp_buf = 0;
|
||||
ret = bcmf_cdc_iovar_request(priv, interface, false,
|
||||
*(FAR uint32_t *)tmp_buf = 0;
|
||||
ret = bcmf_cdc_iovar_request(priv, interface, true,
|
||||
IOVAR_STR_TX_GLOM, tmp_buf,
|
||||
&out_len);
|
||||
if (ret != OK)
|
||||
@ -236,9 +349,9 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
|
||||
/* FIXME disable power save mode */
|
||||
|
||||
out_len = 4;
|
||||
value = 0;
|
||||
ret = bcmf_cdc_ioctl(priv, interface, true, WLC_SET_PM,
|
||||
(uint8_t *)&value, &out_len);
|
||||
value = 0;
|
||||
ret = bcmf_cdc_ioctl(priv, interface, true, WLC_SET_PM,
|
||||
(uint8_t *)&value, &out_len);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
@ -258,16 +371,17 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
|
||||
/* TODO configure roaming if needed. Disable for now */
|
||||
|
||||
out_len = 4;
|
||||
value = 1;
|
||||
ret = bcmf_cdc_iovar_request(priv, interface, true, IOVAR_STR_ROAM_OFF,
|
||||
(uint8_t *)&value,
|
||||
&out_len);
|
||||
value = 1;
|
||||
ret = bcmf_cdc_iovar_request(priv, interface, true,
|
||||
IOVAR_STR_ROAM_OFF,
|
||||
(FAR uint8_t *)&value,
|
||||
&out_len);
|
||||
|
||||
/* TODO configure EAPOL version to default */
|
||||
|
||||
out_len = 8;
|
||||
((uint32_t *)tmp_buf)[0] = interface;
|
||||
((uint32_t *)tmp_buf)[1] = (uint32_t)-1;
|
||||
((FAR uint32_t *)tmp_buf)[0] = interface;
|
||||
((FAR uint32_t *)tmp_buf)[1] = (uint32_t)-1;
|
||||
|
||||
if (bcmf_cdc_iovar_request(priv, interface, true,
|
||||
"bsscfg:"IOVAR_STR_SUP_WPA2_EAPVER, tmp_buf,
|
||||
@ -279,9 +393,9 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
|
||||
/* Query firmware version string */
|
||||
|
||||
out_len = sizeof(tmp_buf);
|
||||
ret = bcmf_cdc_iovar_request(priv, interface, false,
|
||||
IOVAR_STR_VERSION, tmp_buf,
|
||||
&out_len);
|
||||
ret = bcmf_cdc_iovar_request(priv, interface, false,
|
||||
IOVAR_STR_VERSION, tmp_buf,
|
||||
&out_len);
|
||||
if (ret != OK)
|
||||
{
|
||||
return -EIO;
|
||||
|
@ -712,6 +712,7 @@ typedef struct wlc_iov_trx_s
|
||||
#define IOVAR_STR_AMPDU_MPDU "ampdu_mpdu"
|
||||
#define IOVAR_STR_AMPDU_RX_FACTOR "ampdu_rx_factor"
|
||||
#define IOVAR_STR_MIMO_BW_CAP "mimo_bw_cap"
|
||||
#define IOVAR_STR_CLMLOAD "clmload"
|
||||
|
||||
#define WLC_IOCTL_MAGIC ( 0x14e46c77 )
|
||||
#define WLC_IOCTL_VERSION ( 1 )
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/bcmf_netdev.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -110,22 +110,14 @@
|
||||
|
||||
#define BUF ((struct eth_hdr_s *)priv->bc_dev.d_buf)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Common TX logic */
|
||||
|
||||
static int bcmf_transmit(FAR struct bcmf_dev_s *priv,
|
||||
struct bcmf_frame_s *frame);
|
||||
static int bcmf_transmit(FAR struct bcmf_dev_s *priv,
|
||||
FAR struct bcmf_frame_s *frame);
|
||||
static void bcmf_receive(FAR struct bcmf_dev_s *priv);
|
||||
static int bcmf_txpoll(FAR struct net_driver_s *dev);
|
||||
static void bcmf_rxpoll(FAR void *arg);
|
||||
@ -145,10 +137,10 @@ static int bcmf_txavail(FAR struct net_driver_s *dev);
|
||||
|
||||
#if defined(CONFIG_NET_IGMP) || defined(CONFIG_NET_ICMPv6)
|
||||
static int bcmf_addmac(FAR struct net_driver_s *dev,
|
||||
FAR const uint8_t *mac);
|
||||
FAR const uint8_t *mac);
|
||||
#ifdef CONFIG_NET_IGMP
|
||||
static int bcmf_rmmac(FAR struct net_driver_s *dev,
|
||||
FAR const uint8_t *mac);
|
||||
FAR const uint8_t *mac);
|
||||
#endif
|
||||
#ifdef CONFIG_NET_ICMPv6
|
||||
static void bcmf_ipv6multicast(FAR struct bcmf_dev_s *priv);
|
||||
@ -156,7 +148,7 @@ static void bcmf_ipv6multicast(FAR struct bcmf_dev_s *priv);
|
||||
#endif
|
||||
#ifdef CONFIG_NETDEV_IOCTL
|
||||
static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
|
||||
unsigned long arg);
|
||||
unsigned long arg);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
@ -244,7 +236,7 @@ static int bcmf_transmit(FAR struct bcmf_dev_s *priv,
|
||||
static void bcmf_receive(FAR struct bcmf_dev_s *priv)
|
||||
{
|
||||
struct bcmf_frame_s *frame;
|
||||
// wlinfo("Entry\n");
|
||||
|
||||
do
|
||||
{
|
||||
/* Request frame buffer from bus interface */
|
||||
@ -254,12 +246,14 @@ static void bcmf_receive(FAR struct bcmf_dev_s *priv)
|
||||
if (frame == NULL)
|
||||
{
|
||||
/* No more frame to process */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!priv->bc_bifup)
|
||||
{
|
||||
/* Interface down, drop frame */
|
||||
|
||||
priv->bus->free_frame(priv, frame);
|
||||
continue;
|
||||
}
|
||||
@ -275,6 +269,24 @@ static void bcmf_receive(FAR struct bcmf_dev_s *priv)
|
||||
pkt_input(&priv->bc_dev);
|
||||
#endif
|
||||
|
||||
/* Check if this is an 802.1Q VLAN tagged packet */
|
||||
|
||||
if (BUF->type == HTONS(TPID_8021QVLAN))
|
||||
{
|
||||
/* Need to remove the 4 octet VLAN Tag, by moving src and dest
|
||||
* addresses 4 octets to the right, and then read the actual
|
||||
* ethertype. The VLAN ID and priority fields are currently
|
||||
* ignored.
|
||||
*/
|
||||
|
||||
uint8_t temp_buffer[12];
|
||||
memcpy( temp_buffer, frame->data, 12);
|
||||
memcpy( frame->data + 4, temp_buffer, 12);
|
||||
|
||||
priv->bc_dev.d_buf = frame->data = frame->data + 4;
|
||||
priv->bc_dev.d_len -= 4;
|
||||
}
|
||||
|
||||
/* We only accept IP packets of the configured type and ARP packets */
|
||||
|
||||
#ifdef CONFIG_NET_IPv4
|
||||
@ -392,7 +404,11 @@ static void bcmf_receive(FAR struct bcmf_dev_s *priv)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
wlerr("ERROR: RX dropped\n");
|
||||
/* On some routers, it may constantly receive mysterious packet...
|
||||
* https://www.wireshark.org/docs/wsar_html/epan/etypes_8h.html
|
||||
* for more etypes definitions.
|
||||
*/
|
||||
|
||||
NETDEV_RXDROPPED(&priv->bc_dev);
|
||||
priv->bus->free_frame(priv, frame);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/ieee80211/bcmf_sdio.c
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -67,9 +67,13 @@
|
||||
#include "bcmf_sdio_regs.h"
|
||||
|
||||
/* Supported chip configurations */
|
||||
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43362
|
||||
extern const struct bcmf_sdio_chip bcmf_43362_config_sdio;
|
||||
#endif
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43438
|
||||
extern const struct bcmf_sdio_chip bcmf_43438_config_sdio;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
@ -84,6 +88,12 @@
|
||||
|
||||
#define BCMF_WAITDOG_TIMEOUT_TICK (5*CLOCKS_PER_SEC)
|
||||
|
||||
/* Chipcommon registers */
|
||||
|
||||
#define CHIPCOMMON_GPIO_CONTROL ((uint32_t)(0x18000000 + 0x6C) )
|
||||
#define CHIPCOMMON_SR_CONTROL0 ((uint32_t)(0x18000000 + 0x504) )
|
||||
#define CHIPCOMMON_SR_CONTROL1 ((uint32_t)(0x18000000 + 0x508) )
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
@ -97,7 +107,7 @@ static int bcmf_hwinitialize(FAR struct bcmf_sdio_dev_s *sbus);
|
||||
static void bcmf_hwuninitialize(FAR struct bcmf_sdio_dev_s *sbus);
|
||||
static int bcmf_chipinitialize(FAR struct bcmf_sdio_dev_s *sbus);
|
||||
|
||||
static int bcmf_oob_irq(int irq, FAR void *context, FAR void *arg);
|
||||
static int bcmf_oob_irq(FAR void *arg);
|
||||
|
||||
static int bcmf_sdio_bus_sleep(FAR struct bcmf_sdio_dev_s *sbus, bool sleep);
|
||||
|
||||
@ -106,11 +116,15 @@ static int bcmf_sdio_thread(int argc, char **argv);
|
||||
|
||||
static int bcmf_sdio_find_block_size(unsigned int size);
|
||||
|
||||
static int bcmf_sdio_sr_init(FAR struct bcmf_sdio_dev_s *sbus);
|
||||
static bool brcm_chip_sr_capable(FAR struct bcmf_sdio_dev_s *sbus);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* FIXME remove */
|
||||
|
||||
FAR struct bcmf_dev_s *g_sdio_priv;
|
||||
|
||||
/* Buffer pool for SDIO bus interface
|
||||
@ -125,18 +139,18 @@ static struct bcmf_sdio_frame g_pktframes[BCMF_PKT_POOL_SIZE];
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
int bcmf_oob_irq(int irq, FAR void *context, FAR void *arg)
|
||||
int bcmf_oob_irq(FAR void *arg)
|
||||
{
|
||||
FAR struct bcmf_sdio_dev_s *sbus = (struct bcmf_sdio_dev_s *)arg;
|
||||
FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)arg;
|
||||
|
||||
if (sbus->ready)
|
||||
{
|
||||
/* Signal bmcf thread */
|
||||
/* Signal bmcf thread */
|
||||
|
||||
sbus->irq_pending = true;
|
||||
|
||||
nxsem_post(&sbus->thread_signal);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -158,22 +172,22 @@ int bcmf_sdio_bus_sleep(FAR struct bcmf_sdio_dev_s *sbus, bool sleep)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Request HT Avail */
|
||||
|
||||
ret = bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
SBSDIO_HT_AVAIL_REQ | SBSDIO_FORCE_HT);
|
||||
if (ret != OK)
|
||||
{
|
||||
wlerr("HT Avail request failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait for High Troughput clock */
|
||||
|
||||
loops = 20;
|
||||
loops = 200;
|
||||
while (--loops > 0)
|
||||
{
|
||||
up_mdelay(1);
|
||||
/* Request HT Avail */
|
||||
|
||||
ret = bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
SBSDIO_HT_AVAIL_REQ | SBSDIO_FORCE_HT);
|
||||
if (ret != OK)
|
||||
{
|
||||
wlerr("HT Avail request failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait for High Throughput clock */
|
||||
|
||||
up_mdelay(100);
|
||||
ret = bcmf_read_reg(sbus, 1, SBSDIO_FUNC1_CHIPCLKCSR, &value);
|
||||
|
||||
if (ret != OK)
|
||||
@ -184,6 +198,7 @@ int bcmf_sdio_bus_sleep(FAR struct bcmf_sdio_dev_s *sbus, bool sleep)
|
||||
if (value & SBSDIO_HT_AVAIL)
|
||||
{
|
||||
/* High Throughput clock is ready */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -246,7 +261,8 @@ int bcmf_probe(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
}
|
||||
|
||||
/* Default device clock speed is up to 25 Mhz
|
||||
* We could set EHS bit to operate at a clock rate up to 50 Mhz */
|
||||
* We could set EHS bit to operate at a clock rate up to 50 Mhz.
|
||||
*/
|
||||
|
||||
SDIO_CLOCK(sbus->sdio_dev, CLOCK_SD_TRANSFER_4BIT);
|
||||
up_mdelay(BCMF_CLOCK_SETUP_DELAY_MS);
|
||||
@ -280,9 +296,9 @@ int bcmf_businitialize(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
/* Send Active Low-Power clock request */
|
||||
|
||||
ret = bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_CHIPCLKCSR,
|
||||
SBSDIO_FORCE_HW_CLKREQ_OFF |
|
||||
SBSDIO_ALP_AVAIL_REQ |
|
||||
SBSDIO_FORCE_ALP);
|
||||
SBSDIO_FORCE_HW_CLKREQ_OFF |
|
||||
SBSDIO_ALP_AVAIL_REQ |
|
||||
SBSDIO_FORCE_ALP);
|
||||
|
||||
if (ret != OK)
|
||||
{
|
||||
@ -303,6 +319,7 @@ int bcmf_businitialize(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
if (value & SBSDIO_ALP_AVAIL)
|
||||
{
|
||||
/* Active Low-Power clock is ready */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -371,20 +388,24 @@ int bcmf_bus_setup_interrupts(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sdio_enable_interrupt(sbus->sdio_dev, 2);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_BCMFMAC_NO_OOB
|
||||
/* Redirect, configure and enable io for out-of-band interrupt signal */
|
||||
|
||||
ret = bcmf_write_reg(sbus, 0, SDIO_CCCR_BRCM_SEPINT,
|
||||
SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI);
|
||||
SDIO_SEPINT_MASK | SDIO_SEPINT_OE |
|
||||
SDIO_SEPINT_ACT_HI);
|
||||
if (ret != OK)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Wake up chip to be sure function 2 is running */
|
||||
|
||||
@ -404,8 +425,9 @@ int bcmf_bus_setup_interrupts(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
CORE_BUS_REG(sbus->chip->core_base[SDIOD_CORE_ID],
|
||||
funcintmask), 2);
|
||||
|
||||
bcmf_write_reg(sbus, 1, SBSDIO_WATERMARK, 8);
|
||||
/* Lower F2 Watermark to avoid DMA Hang in F2 when SD Clock is stopped. */
|
||||
|
||||
bcmf_write_reg(sbus, 1, SBSDIO_WATERMARK, 8);
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -457,6 +479,7 @@ int bcmf_sdio_find_block_size(unsigned int size)
|
||||
{
|
||||
int ret = 0;
|
||||
int size_copy = size;
|
||||
|
||||
while (size_copy)
|
||||
{
|
||||
size_copy >>= 1;
|
||||
@ -471,6 +494,65 @@ int bcmf_sdio_find_block_size(unsigned int size)
|
||||
return 1 << (ret - 1);
|
||||
}
|
||||
|
||||
/* Init save-restore if the firmware support it: */
|
||||
|
||||
static int bcmf_sdio_sr_init(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
if (brcm_chip_sr_capable(sbus))
|
||||
{
|
||||
/* Configure WakeupCtrl register to set HtAvail request bit in
|
||||
* chipClockCSR register after the sdiod core is powered on.
|
||||
*/
|
||||
|
||||
bcmf_read_reg(sbus, 1, SBSDIO_FUNC1_WAKEUPCTRL, &data);
|
||||
data |= SBSDIO_FUNC1_WCTRL_HTWAIT_MASK;
|
||||
bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_WAKEUPCTRL, data);
|
||||
|
||||
/* Set brcmCardCapability to noCmdDecode mode.
|
||||
* It makes sdiod_aos to wakeup host for any activity of cmd line,
|
||||
* even though module won't decode cmd or respond
|
||||
*/
|
||||
|
||||
bcmf_write_reg(sbus, 0, SDIO_CCCR_BRCM_CARDCAP, SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC);
|
||||
bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HT);
|
||||
|
||||
/* Enable KeepSdioOn (KSO) bit for normal operation */
|
||||
|
||||
bcmf_read_reg(sbus, 1, SBSDIO_FUNC1_SLEEPCSR, &data);
|
||||
if((data & SBSDIO_FUNC1_SLEEPCSR_KSO_MASK) == 0)
|
||||
{
|
||||
data |= SBSDIO_FUNC1_SLEEPCSR_KSO_MASK;
|
||||
bcmf_write_reg(sbus, 1, SBSDIO_FUNC1_SLEEPCSR, data);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Check if the firmware supports save restore feature.
|
||||
* TODO: Add more chip specific logic, and move it to a new bcmf_chip.c file.
|
||||
*/
|
||||
|
||||
static bool brcm_chip_sr_capable(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
{
|
||||
uint32_t srctrl = 0;
|
||||
int ret;
|
||||
|
||||
/* Check if fw initialized sr engine */
|
||||
|
||||
ret = bcmf_read_sbregw(sbus, CHIPCOMMON_SR_CONTROL1, &srctrl);
|
||||
if (ret != OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (srctrl != 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -500,6 +582,7 @@ int bcmf_transfer_bytes(FAR struct bcmf_sdio_dev_s *sbus, bool write,
|
||||
return sdio_io_rw_direct(sbus->sdio_dev, write,
|
||||
function, address, *buf, NULL);
|
||||
}
|
||||
|
||||
return sdio_io_rw_direct(sbus->sdio_dev, write,
|
||||
function, address, 0, buf);
|
||||
}
|
||||
@ -551,7 +634,7 @@ int bcmf_write_reg(FAR struct bcmf_sdio_dev_s *sbus, uint8_t function,
|
||||
****************************************************************************/
|
||||
|
||||
int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
int minor, FAR struct sdio_dev_s *dev)
|
||||
int minor, FAR struct sdio_dev_s *dev)
|
||||
{
|
||||
int ret;
|
||||
FAR struct bcmf_sdio_dev_s *sbus;
|
||||
@ -568,16 +651,16 @@ int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
/* Initialize sdio bus device structure */
|
||||
|
||||
memset(sbus, 0, sizeof(*sbus));
|
||||
sbus->sdio_dev = dev;
|
||||
sbus->minor = minor;
|
||||
sbus->ready = false;
|
||||
sbus->sleeping = true;
|
||||
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.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
|
||||
sbus->bus.free_frame = bcmf_sdpcm_free_frame;
|
||||
sbus->bus.stop = NULL; // TODO
|
||||
|
||||
/* Init transmit frames queue */
|
||||
|
||||
@ -591,8 +674,8 @@ int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
sq_init(&sbus->free_queue);
|
||||
|
||||
/* Setup free buffer list */
|
||||
|
||||
// FIXME this should be static to driver
|
||||
|
||||
for (ret = 0; ret < BCMF_PKT_POOL_SIZE; ret++)
|
||||
{
|
||||
bcmf_dqueue_push(&sbus->free_queue, &g_pktframes[ret].list_entry);
|
||||
@ -622,7 +705,6 @@ int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
/* Initialize device hardware */
|
||||
|
||||
ret = bcmf_hwinitialize(sbus);
|
||||
|
||||
if (ret != OK)
|
||||
{
|
||||
goto exit_free_waitdog;
|
||||
@ -631,7 +713,6 @@ int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
/* Probe device */
|
||||
|
||||
ret = bcmf_probe(sbus);
|
||||
|
||||
if (ret != OK)
|
||||
{
|
||||
goto exit_uninit_hw;
|
||||
@ -640,7 +721,6 @@ int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
/* Initialize device bus */
|
||||
|
||||
ret = bcmf_businitialize(sbus);
|
||||
|
||||
if (ret != OK)
|
||||
{
|
||||
goto exit_uninit_hw;
|
||||
@ -656,7 +736,14 @@ int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
goto exit_uninit_hw;
|
||||
}
|
||||
|
||||
ret = bcmf_sdio_sr_init(sbus);
|
||||
if (ret != OK)
|
||||
{
|
||||
goto exit_uninit_hw;
|
||||
}
|
||||
|
||||
/* FIXME global variable for now */
|
||||
|
||||
g_sdio_priv = priv;
|
||||
|
||||
/* Register sdio bus */
|
||||
@ -683,14 +770,16 @@ int bcmf_bus_sdio_initialize(FAR struct bcmf_dev_s *priv,
|
||||
|
||||
sbus->thread_id = ret;
|
||||
|
||||
/* sdio bus is up and running */
|
||||
/* SDIO bus is up and running */
|
||||
|
||||
return OK;
|
||||
|
||||
exit_uninit_hw:
|
||||
bcmf_hwuninitialize(sbus);
|
||||
|
||||
exit_free_waitdog:
|
||||
wd_delete(sbus->waitdog);
|
||||
|
||||
exit_free_bus:
|
||||
kmm_free(sbus);
|
||||
priv->bus = NULL;
|
||||
@ -699,8 +788,9 @@ exit_free_bus:
|
||||
|
||||
int bcmf_chipinitialize(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
{
|
||||
int ret;
|
||||
uint32_t value = 0;
|
||||
int chipid;
|
||||
int ret;
|
||||
|
||||
ret = bcmf_read_sbregw(sbus, SI_ENUM_BASE, &value);
|
||||
if (ret != OK)
|
||||
@ -708,7 +798,9 @@ int bcmf_chipinitialize(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int chipid = value & 0xffff;
|
||||
chipid = value & 0xffff;
|
||||
sbus->cur_chip_id = chipid;
|
||||
|
||||
switch (chipid)
|
||||
{
|
||||
#ifdef CONFIG_IEEE80211_BROADCOM_BCM43362
|
||||
@ -717,10 +809,19 @@ int bcmf_chipinitialize(FAR struct bcmf_sdio_dev_s *sbus)
|
||||
sbus->chip = (struct bcmf_sdio_chip *)&bcmf_43362_config_sdio;
|
||||
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;
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
wlerr("chip 0x%x is not supported\n", chipid);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
@ -741,7 +842,7 @@ int bcmf_sdio_thread(int argc, char **argv)
|
||||
FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
|
||||
int ret;
|
||||
|
||||
wlinfo("Enter\n");
|
||||
wlinfo(" Enter\n");
|
||||
|
||||
/* FIXME wait for the chip to be ready to receive commands */
|
||||
|
||||
@ -774,23 +875,20 @@ int bcmf_sdio_thread(int argc, char **argv)
|
||||
sbus->irq_pending = false;
|
||||
|
||||
bcmf_read_sbregw(sbus,
|
||||
CORE_BUS_REG(sbus->chip->core_base[SDIOD_CORE_ID],
|
||||
intstatus), &sbus->intstatus);
|
||||
CORE_BUS_REG(sbus->chip->core_base[SDIOD_CORE_ID],
|
||||
intstatus), &sbus->intstatus);
|
||||
|
||||
/* Clear interrupts */
|
||||
|
||||
bcmf_write_sbregw(sbus,
|
||||
CORE_BUS_REG(sbus->chip->core_base[SDIOD_CORE_ID],
|
||||
intstatus), sbus->intstatus);
|
||||
// wlinfo("intstatus %x\n", sbus->intstatus);
|
||||
CORE_BUS_REG(sbus->chip->core_base[SDIOD_CORE_ID],
|
||||
intstatus), sbus->intstatus);
|
||||
}
|
||||
|
||||
/* On frame indication, read available frames */
|
||||
|
||||
if (sbus->intstatus & I_HMB_FRAME_IND)
|
||||
{
|
||||
// wlinfo("Frames available\n");
|
||||
|
||||
do
|
||||
{
|
||||
ret = bcmf_sdpcm_readframe(priv);
|
||||
@ -830,7 +928,6 @@ int bcmf_sdio_thread(int argc, char **argv)
|
||||
}
|
||||
|
||||
wlinfo("Exit\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -843,7 +940,7 @@ struct bcmf_sdio_frame *bcmf_sdio_allocate_frame(FAR struct bcmf_dev_s *priv,
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (nxsem_wait(&sbus->queue_mutex < 0))
|
||||
if (nxsem_wait(&sbus->queue_mutex) < 0)
|
||||
{
|
||||
PANIC();
|
||||
}
|
||||
@ -867,27 +964,28 @@ struct bcmf_sdio_frame *bcmf_sdio_allocate_frame(FAR struct bcmf_dev_s *priv,
|
||||
if (block)
|
||||
{
|
||||
// TODO use signaling semaphore
|
||||
|
||||
wlinfo("alloc failed %d\n", tx);
|
||||
up_mdelay(100);
|
||||
continue;
|
||||
}
|
||||
|
||||
wlinfo("No avail buffer\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sframe = container_of(entry, struct bcmf_sdio_frame, list_entry);
|
||||
|
||||
sframe->header.len = HEADER_SIZE + MAX_NET_DEV_MTU;
|
||||
sframe->header.len = HEADER_SIZE + MAX_NET_DEV_MTU;
|
||||
sframe->header.base = sframe->data;
|
||||
sframe->header.data = sframe->data;
|
||||
sframe->tx = tx;
|
||||
sframe->tx = tx;
|
||||
return sframe;
|
||||
}
|
||||
|
||||
void bcmf_sdio_free_frame(FAR struct bcmf_dev_s *priv,
|
||||
struct bcmf_sdio_frame *sframe)
|
||||
{
|
||||
// wlinfo("free %p\n", sframe);
|
||||
FAR struct bcmf_sdio_dev_s *sbus = (FAR struct bcmf_sdio_dev_s *)priv->bus;
|
||||
|
||||
if (nxsem_wait(&sbus->queue_mutex) < 0)
|
||||
@ -901,5 +999,6 @@ void bcmf_sdio_free_frame(FAR struct bcmf_dev_s *priv,
|
||||
{
|
||||
sbus->tx_queue_count -= 1;
|
||||
}
|
||||
|
||||
nxsem_post(&sbus->queue_mutex);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* drivers/wireless/ieee80211/bcmf_sdio.h
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -69,6 +69,9 @@ struct bcmf_sdio_chip
|
||||
|
||||
uint8_t *nvram_image;
|
||||
unsigned int *nvram_image_size;
|
||||
|
||||
uint8_t *clm_blob_image;
|
||||
unsigned int *clm_blob_image_size;
|
||||
};
|
||||
|
||||
/* sdio bus structure extension */
|
||||
@ -79,6 +82,7 @@ struct bcmf_sdio_dev_s
|
||||
FAR struct sdio_dev_s *sdio_dev; /* The SDIO device bound to this instance */
|
||||
int minor; /* Device minor number */
|
||||
|
||||
int cur_chip_id; /* Chip ID read from the card */
|
||||
struct bcmf_sdio_chip *chip; /* Chip specific configuration */
|
||||
|
||||
volatile bool ready; /* Current device status */
|
||||
@ -144,4 +148,4 @@ struct bcmf_sdio_frame *bcmf_sdio_allocate_frame(FAR struct bcmf_dev_s *priv,
|
||||
void bcmf_sdio_free_frame(FAR struct bcmf_dev_s *priv,
|
||||
struct bcmf_sdio_frame *sframe);
|
||||
|
||||
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_SDIO_H */
|
||||
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_SDIO_H */
|
||||
|
@ -30,11 +30,12 @@
|
||||
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43143 43143
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
|
||||
#define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43362 43362
|
||||
#define SDIO_DEVICE_ID_BROADCOM_43430 43430
|
||||
|
||||
/* Core reg address translation.
|
||||
* Both macro's returns a 32 bits byte address on the backplane bus.
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* include/nuttx/wireless/ieee80211/bcmf_board.h
|
||||
*
|
||||
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
|
||||
* Author: Simon Piriou <spiriou31@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -69,6 +69,7 @@ extern "C"
|
||||
* Input Parameters:
|
||||
* minor - zero based minor device number which is unique
|
||||
* for each wlan device.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void bcmf_board_initialize(int minor);
|
||||
@ -84,6 +85,7 @@ void bcmf_board_initialize(int minor);
|
||||
* minor - zero based minor device number which is unique
|
||||
* for each wlan device.
|
||||
* power - true to power WLAN chip else false
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void bcmf_board_power(int minor, bool power);
|
||||
@ -99,6 +101,7 @@ void bcmf_board_power(int minor, bool power);
|
||||
* minor - zero based minor device number which is unique
|
||||
* for each wlan device.
|
||||
* reset - true to set WLAN chip in reset state else false
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void bcmf_board_reset(int minor, bool reset);
|
||||
@ -115,9 +118,10 @@ void bcmf_board_reset(int minor, bool reset);
|
||||
* for each wlan device.
|
||||
* func - WLAN chip callback function that must be called on gpio event
|
||||
* arg - WLAN chip internal structure that must be passed to callback
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void bcmf_board_setup_oob_irq(int minor, xcpt_t func, void *arg);
|
||||
void bcmf_board_setup_oob_irq(int minor, int (*func)(void *), void *arg);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
|
@ -958,7 +958,8 @@ static int netdev_ifr_ioctl(FAR struct socket *psock, int cmd,
|
||||
if (dev)
|
||||
{
|
||||
#ifdef CONFIG_NET_ETHERNET
|
||||
if (dev->d_lltype == NET_LL_ETHERNET)
|
||||
if (dev->d_lltype == NET_LL_ETHERNET ||
|
||||
dev->d_lltype == NET_LL_IEEE80211)
|
||||
{
|
||||
req->ifr_hwaddr.sa_family = AF_INETX;
|
||||
memcpy(req->ifr_hwaddr.sa_data,
|
||||
|
Loading…
Reference in New Issue
Block a user