bcmf: add escan ioctls support + cleanup

This commit is contained in:
Simon Piriou 2017-04-28 19:28:29 +02:00
parent 6680eb0e0c
commit 0d1a79719a
15 changed files with 1096 additions and 236 deletions

View File

@ -1003,7 +1003,7 @@ CONFIG_NET_ETHERNET=y
#
# Network Device Operations
#
# CONFIG_NETDEV_IOCTL is not set
CONFIG_NETDEV_IOCTL=y
# CONFIG_NETDEV_PHY_IOCTL is not set
CONFIG_NETDEV_WIRELESS_IOCTL=y

View File

@ -43,6 +43,7 @@ ifeq ($(CONFIG_DRIVERS_IEEE80211),y)
ifeq ($(CONFIG_IEEE80211_BROADCOM_FULLMAC),y)
CSRCS += bcmf_driver.c
CSRCS += bcmf_cdc.c
CSRCS += bcmf_bdc.c
CSRCS += bcmf_utils.c
CSRCS += bcmf_netdev.c

View File

@ -0,0 +1,243 @@
/****************************************************************************
* drivers/wireless/ieee80211/bcmf_bdc.c
*
* Copyright (C) 2017 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <debug.h>
#include <errno.h>
#include <string.h>
#include <net/ethernet.h>
#include "bcmf_driver.h"
#include "bcmf_ioctl.h"
#include "bcmf_cdc.h"
#include "bcmf_bdc.h"
#include "bcmf_utils.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define BCMF_EVENT_ETHER_TYPE 0x6C88 /* Ether type of event frames */
/****************************************************************************
* Private Types
****************************************************************************/
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 */
};
struct __attribute__((packed)) bcmf_eth_header
{
uint16_t type; /* Vendor specific type */
uint16_t len; /* Event data length */
uint8_t version; /* Protocol version */
uint8_t oui[3]; /* Organizationally unique identifier */
uint16_t usr_type; /* User specific type */
};
struct __attribute__((packed)) bcmf_event_msg
{
struct ether_header eth;
struct bcmf_eth_header bcm_eth;
struct bcmf_event_s event;
uint8_t data[0];
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
static const uint8_t bcmf_broadcom_oui[] = {0x00, 0x10, 0x18};
/****************************************************************************
* Private Functions
****************************************************************************/
struct bcmf_frame_s* bcmf_bdc_allocate_frame(FAR struct bcmf_dev_s *priv,
uint32_t len, bool block)
{
if (len <= 0)
{
return NULL;
}
/* Allocate data frame */
return priv->bus->allocate_frame(priv,
sizeof(struct bcmf_bdc_header) + len,
false, block);
}
/****************************************************************************
* Public Functions
****************************************************************************/
int bcmf_bdc_process_data_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame)
{
wlinfo("Data message\n");
bcmf_hexdump(frame->base, frame->len, (unsigned long)frame->base);
return OK;
}
int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame)
{
int data_size;
struct bcmf_bdc_header *header;
struct bcmf_event_msg *event_msg;
uint32_t event_id;
event_handler_t handler;
/* Check frame header */
data_size = frame->len - (int)(frame->data - frame->base);
if (data_size < sizeof(struct bcmf_bdc_header))
{
goto exit_invalid_frame;
}
header = (struct bcmf_bdc_header*)frame->data;
data_size -= sizeof(struct bcmf_bdc_header) + header->data_offset;
if (data_size < sizeof(struct bcmf_event_msg))
{
goto exit_invalid_frame;
}
data_size -= sizeof(struct ether_header) + sizeof(struct bcmf_eth_header);
/* Check ethernet header */
event_msg = (struct bcmf_event_msg*)(frame->data +
sizeof(struct bcmf_bdc_header) +
header->data_offset);
if (event_msg->eth.ether_type != BCMF_EVENT_ETHER_TYPE ||
memcmp(event_msg->bcm_eth.oui, bcmf_broadcom_oui, 3))
{
goto exit_invalid_frame;
}
event_id = bcmf_getle32(&event_msg->event.type);
if (event_id >= BCMF_EVENT_COUNT)
{
wlinfo("Invalid event id %d\n", event_id);
return -EINVAL;
}
/* Dispatch event to registered handler */
handler = priv->event_handlers[event_id];
if (handler != NULL)
{
handler(priv, &event_msg->event, data_size);
}
return OK;
exit_invalid_frame:
wlerr("Invalid event frame\n");
bcmf_hexdump(frame->base, frame->len, (unsigned long)frame->base);
return -EINVAL;
}
int bcmf_event_register(FAR struct bcmf_dev_s *priv, event_handler_t handler,
unsigned int event_id)
{
if (event_id >= BCMF_EVENT_COUNT)
{
/* Invalid event id */
return -EINVAL;
}
priv->event_handlers[event_id] = handler;
return OK;
}
int bcmf_event_unregister(FAR struct bcmf_dev_s *priv,
unsigned int event_id)
{
return bcmf_event_register(priv, NULL, event_id);
}
int bcmf_event_push_config(FAR struct bcmf_dev_s *priv)
{
int i;
uint32_t out_len;
uint8_t event_mask[(BCMF_EVENT_COUNT+7)>>3];
memset(event_mask, 0, sizeof(event_mask));
for (i=0; i<BCMF_EVENT_COUNT; i++)
{
if (priv->event_handlers[i] != NULL)
{
event_mask[i>>3] |= 1 << (i & 0x7);
}
}
/* Send event mask to chip */
out_len = sizeof(event_mask);
if (bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, true,
IOVAR_STR_EVENT_MSGS, event_mask,
&out_len))
{
return -EIO;
}
return OK;
}

View File

@ -0,0 +1,86 @@
/****************************************************************************
* drivers/wireless/ieee80211/bcmf_bdc.h
*
* Copyright (C) 2017 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#ifndef __DRIVERS_WIRELESS_IEEE80211_BCMF_BDC_H
#define __DRIVERS_WIRELESS_IEEE80211_BCMF_BDC_H
#include "bcmf_driver.h"
#include "bcmf_ioctl.h"
/* Event frame content */
struct __attribute__((packed)) bcmf_event_s
{
uint16_t version; /* Vendor specific type */
uint16_t flags;
uint32_t type; /* Id of received event */
uint32_t status; /* Event status code */
uint32_t reason; /* Reason code */
uint32_t auth_type;
uint32_t len; /* Data size following this header */
struct ether_addr addr; /* AP MAC address */
char src_name[16]; /* Event source interface name */
uint8_t dst_id; /* Event destination interface id */
uint8_t bss_cfg_id;
};
/* Event callback handler */
typedef void (*event_handler_t)(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len);
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
int bcmf_bdc_process_data_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame);
int bcmf_bdc_process_event_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame);
int bcmf_event_register(FAR struct bcmf_dev_s *priv, event_handler_t handler,
unsigned int event_id);
int bcmf_event_unregister(FAR struct bcmf_dev_s *priv,
unsigned int event_id);
int bcmf_event_push_config(FAR struct bcmf_dev_s *priv);
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_BDC_H */

View File

@ -56,28 +56,24 @@
* Pre-processor Definitions
****************************************************************************/
/* CDC flag definitions */
#define CDC_DCMD_ERROR 0x01 /* 1=cmd failed */
#define CDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
#define CDC_DCMD_IF_MASK 0xF000 /* I/F index */
#define CDC_DCMD_IF_SHIFT 12
#define CDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
#define CDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
#define CDC_DCMD_ID(flags) \
(((flags) & CDC_DCMD_ID_MASK) >> CDC_DCMD_ID_SHIFT)
/* Control header flags */
#define CDC_CONTROL_TIMEOUT_MS 1000
#define BCMF_CONTROL_ERROR 0x01 /* Command failure flag */
#define BCMF_CONTROL_SET 0x02 /* Command type: SET = 1, GET = 0 */
#define BCMF_CONTROL_INTERFACE_SHIFT 12
#define BCMF_CONTROL_REQID_SHIFT 16
#define BCMF_CONTROL_TIMEOUT_MS 1000
/****************************************************************************
* Private Types
****************************************************************************/
struct bcmf_cdc_header {
uint32_t cmd; /* dongle command value */
uint32_t len; /* lower 16: output buflen;
* upper 16: input buflen (excludes header) */
uint32_t flags; /* flag defns given below */
uint32_t status; /* status code returned from the device */
struct __attribute__((packed)) bcmf_cdc_header {
uint32_t cmd; /* Command to be sent */
uint32_t len; /* Size of command data */
uint32_t flags; /* cdc request flags, see above */
uint32_t status; /* Returned status code from chip */
};
/****************************************************************************
@ -95,6 +91,10 @@ static int bcmf_cdc_control_request(FAR struct bcmf_dev_s *priv,
uint32_t ifidx, bool set, uint32_t cmd,
char *name, uint8_t *data, uint32_t *len);
static int bcmf_cdc_control_request_unsafe(FAR struct bcmf_dev_s *priv,
uint32_t ifidx, bool set, uint32_t cmd,
char *name, uint8_t *data, uint32_t *len);
/****************************************************************************
* Private Data
****************************************************************************/
@ -161,21 +161,21 @@ int bcmf_cdc_sendframe(FAR struct bcmf_dev_s *priv, uint32_t cmd,
struct bcmf_cdc_header* header =
(struct bcmf_cdc_header*)frame->data;
/* Setup cdc_dcmd header */
/* Setup control frame header */
uint32_t cdc_data_len = frame->len - (uint32_t)(frame->data-frame->base);
header->cmd = cmd;
header->len = cdc_data_len-sizeof(struct bcmf_cdc_header);
header->status = 0;
header->flags = ++priv->control_reqid << CDC_DCMD_ID_SHIFT;
header->flags |= ifidx << CDC_DCMD_IF_SHIFT;
header->flags = ++priv->control_reqid << BCMF_CONTROL_REQID_SHIFT;
header->flags |= ifidx << BCMF_CONTROL_INTERFACE_SHIFT;
if (set)
{
header->flags |= CDC_DCMD_SET;
header->flags |= BCMF_CONTROL_SET;
}
/* Queue frame */
/* Send frame */
return priv->bus->txframe(priv, frame);
}
@ -185,10 +185,6 @@ int bcmf_cdc_control_request(FAR struct bcmf_dev_s *priv,
char *name, uint8_t *data, uint32_t *len)
{
int ret;
struct bcmf_frame_s *frame;
uint32_t out_len = *len;
*len = 0;
/* Take device control mutex */
@ -197,14 +193,31 @@ int bcmf_cdc_control_request(FAR struct bcmf_dev_s *priv,
return ret;
}
ret = bcmf_cdc_control_request_unsafe(priv, ifidx, set, cmd,
name, data, len);
sem_post(&priv->control_mutex);
return ret;
}
int bcmf_cdc_control_request_unsafe(FAR struct bcmf_dev_s *priv,
uint32_t ifidx, bool set, uint32_t cmd,
char *name, uint8_t *data, uint32_t *len)
{
int ret;
struct bcmf_frame_s *frame;
uint32_t out_len = *len;
*len = 0;
/* Prepare control frame */
frame = bcmf_cdc_allocate_frame(priv, name, data, out_len);
if (!frame)
{
wlerr("Cannot allocate cdc frame\n");
ret = -ENOMEM;
goto exit_sem_post;
return -ENOMEM;
}
/* Setup buffer to store response */
@ -218,14 +231,14 @@ int bcmf_cdc_control_request(FAR struct bcmf_dev_s *priv,
if (ret != OK)
{
// TODO free allocated iovar buffer here
goto exit_sem_post;
return ret;
}
ret = bcmf_sem_wait(&priv->control_timeout, CDC_CONTROL_TIMEOUT_MS);
ret = bcmf_sem_wait(&priv->control_timeout, BCMF_CONTROL_TIMEOUT_MS);
if (ret != OK)
{
wlerr("Error while waiting for control response %d\n", ret);
goto exit_sem_post;
return ret;
}
*len = priv->control_rxdata_len;
@ -235,12 +248,10 @@ int bcmf_cdc_control_request(FAR struct bcmf_dev_s *priv,
if (priv->control_status != 0)
{
wlerr("Invalid cdc status 0x%x\n", priv->control_status);
ret = -EINVAL;
return -EINVAL;
}
exit_sem_post:
sem_post(&priv->control_mutex);
return ret;
return OK;
}
/****************************************************************************
@ -256,6 +267,15 @@ int bcmf_cdc_iovar_request(FAR struct bcmf_dev_s *priv,
data, len);
}
int bcmf_cdc_iovar_request_unsafe(FAR struct bcmf_dev_s *priv,
uint32_t ifidx, bool set, char *name,
uint8_t *data, uint32_t *len)
{
return bcmf_cdc_control_request_unsafe(priv, ifidx, set,
set ? WLC_SET_VAR : WLC_GET_VAR, name,
data, len);
}
int bcmf_cdc_ioctl(FAR struct bcmf_dev_s *priv,
uint32_t ifidx, bool set, uint32_t cmd,
uint8_t *data, uint32_t *len)
@ -290,7 +310,7 @@ int bcmf_cdc_process_control_frame(FAR struct bcmf_dev_s *priv,
// TODO check interface ?
if (cdc_header->flags >> CDC_DCMD_ID_SHIFT == priv->control_reqid)
if (cdc_header->flags >> BCMF_CONTROL_REQID_SHIFT == priv->control_reqid)
{
/* Expected frame received, send it back to user */
@ -314,20 +334,4 @@ int bcmf_cdc_process_control_frame(FAR struct bcmf_dev_s *priv,
wlinfo("Got unexpected control frame\n");
return -EINVAL;
}
int bcmf_cdc_process_event_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame)
{
wlinfo("Event message\n");
bcmf_hexdump(frame->base, frame->len, (unsigned long)frame->base);
return OK;
}
int bcmf_cdc_process_data_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame)
{
wlinfo("Data message\n");
bcmf_hexdump(frame->base, frame->len, (unsigned long)frame->base);
return OK;
}

View File

@ -48,19 +48,22 @@
* Public Function Prototypes
****************************************************************************/
/* Send safe cdc request */
int bcmf_cdc_iovar_request(FAR struct bcmf_dev_s *priv, uint32_t ifidx,
bool set, char *name, uint8_t *data, uint32_t *len);
int bcmf_cdc_ioctl(FAR struct bcmf_dev_s *priv, uint32_t ifidx, bool set,
uint32_t cmd, uint8_t *data, uint32_t *len);
/* Send cdc request without locking control_mutex */
int bcmf_cdc_iovar_request_unsafe(FAR struct bcmf_dev_s *priv, uint32_t ifidx,
bool set, char *name, uint8_t *data, uint32_t *len);
/* Callback used by bus layer to notify cdc response frame is available */
int bcmf_cdc_process_control_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame);
int bcmf_cdc_process_data_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame);
int bcmf_cdc_process_event_frame(FAR struct bcmf_dev_s *priv,
struct bcmf_frame_s *frame);
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_CDC_H */

View File

@ -48,10 +48,12 @@
#include <net/ethernet.h>
#include <nuttx/kmalloc.h>
#include <nuttx/wdog.h>
#include "bcmf_driver.h"
#include "bcmf_cdc.h"
#include "bcmf_ioctl.h"
#include "bcmf_utils.h"
#include <nuttx/sdio.h>
#include "bcmf_sdio.h"
@ -62,14 +64,23 @@
// TODO move elsewhere
#define DOT11_BSSTYPE_ANY 2
#define WL_SCAN_CHANNEL_TIME 40
#define WL_SCAN_UNASSOC_TIME 40
#define WL_SCAN_PASSIVE_TIME 120
#define BCMF_SCAN_TIMEOUT_TICK (5*CLOCKS_PER_SEC)
/****************************************************************************
* Private Types
****************************************************************************/
/* AP scan state machine status */
enum
{
BCMF_SCAN_TIMEOUT = 0,
BCMF_SCAN_DISABLED,
BCMF_SCAN_RUN,
BCMF_SCAN_DONE
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
@ -82,6 +93,16 @@ static int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv);
// FIXME add bcmf_netdev.h file
int bcmf_netdev_register(FAR struct bcmf_dev_s *priv);
// FIXME only for debug purpose
static void bcmf_wl_default_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len);
static void bcmf_wl_radio_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len);
static void bcmf_wl_scan_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len);
#if 0
static int bcmf_run_escan(FAR struct bcmf_dev_s *priv);
#endif
@ -128,6 +149,16 @@ FAR struct bcmf_dev_s* bcmf_allocate_device(void)
goto exit_free_priv;
}
/* Init scan timeout timer */
priv->scan_status = BCMF_SCAN_DISABLED;
priv->scan_timeout = wd_create();
if (!priv->scan_timeout)
{
ret = -ENOMEM;
goto exit_free_priv;
}
return priv;
exit_free_priv:
@ -163,127 +194,6 @@ int bcmf_wl_set_mac_address(FAR struct bcmf_dev_s *priv, uint8_t *addr)
return OK;
}
int bcmf_dongle_scantime(FAR struct bcmf_dev_s *priv, int32_t scan_assoc_time,
int32_t scan_unassoc_time, int32_t scan_passive_time)
{
int ret;
uint32_t out_len;
uint32_t value;
out_len = 4;
value = scan_assoc_time;
ret = bcmf_cdc_ioctl(priv, CHIP_STA_INTERFACE, true,
WLC_SET_SCAN_CHANNEL_TIME, (uint8_t*)&value,
&out_len);
if (ret != OK)
{
return -EIO;
}
out_len = 4;
value = scan_unassoc_time;
ret = bcmf_cdc_ioctl(priv, CHIP_STA_INTERFACE, true,
WLC_SET_SCAN_UNASSOC_TIME, (uint8_t*)&value,
&out_len);
if (ret != OK)
{
return -EIO;
}
out_len = 4;
value = scan_passive_time;
ret = bcmf_cdc_ioctl(priv, CHIP_STA_INTERFACE, true,
WLC_SET_SCAN_PASSIVE_TIME, (uint8_t*)&value,
&out_len);
if (ret != OK)
{
return -EIO;
}
return OK;
}
int bcmf_dongle_initialize(FAR struct bcmf_dev_s *priv)
{
int ret;
ret = bcmf_wl_enable(priv, true);
if (ret)
{
return ret;
}
ret = bcmf_dongle_scantime(priv, WL_SCAN_CHANNEL_TIME,
WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
if (ret)
{
return ret;
}
// FIXME remove
#if 0
/* Try scan */
value = 0;
out_len = 4;
ret = bcmf_cdc_ioctl(priv, CHIP_STA_INTERFACE, true,
WLC_SET_PASSIVE_SCAN, (uint8_t*)&value, &out_len);
bcmf_run_escan(priv);
#endif
return ret;
}
#if 0
int bcmf_run_escan(FAR struct bcmf_dev_s *priv)
{
int ret;
uint32_t out_len;
/* Default request structure */
struct wl_escan_params *params =
(struct wl_escan_params*)kmm_malloc(sizeof(*params));
if (!params)
{
return -ENOMEM;
}
memset(params, 0, sizeof(*params));
params->version = ESCAN_REQ_VERSION;
params->action = WL_SCAN_ACTION_START;
params->sync_id = 0x1234;
memset(&params->params.bssid, 0xFF, sizeof(params->params.bssid));
params->params.bss_type = DOT11_BSSTYPE_ANY;
params->params.scan_type = 0; /* Active scan */
params->params.nprobes = -1;
params->params.active_time = -1;
params->params.passive_time = -1;
params->params.home_time = -1;
params->params.channel_num = 0;
wlinfo("start scan\n");
out_len = sizeof(*params);
ret = bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, true,
IOVAR_STR_ESCAN, (uint8_t*)params,
&out_len);
free(params);
if (ret != OK)
{
return -EIO;
}
return OK;
}
#endif
int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
{
int ret;
@ -344,6 +254,8 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
return -EIO;
}
tmp_buf[sizeof(tmp_buf)-1] = 0;
/* Remove line feed */
out_len = strlen((char*)tmp_buf);
@ -356,14 +268,20 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
/* FIXME Configure event mask to enable all asynchronous events */
uint8_t event_mask[16];
memset(event_mask, 0xff, sizeof(event_mask));
for (ret = 0; ret < BCMF_EVENT_COUNT; ret++)
{
bcmf_event_register(priv, bcmf_wl_default_event_handler, ret);
}
out_len = sizeof(event_mask);
ret = bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, true,
IOVAR_STR_EVENT_MSGS, event_mask,
&out_len);
if (ret != OK)
/* Register radio event */
bcmf_event_register(priv, bcmf_wl_radio_event_handler, WLC_E_RADIO);
/* Register AP scan event */
bcmf_event_register(priv, bcmf_wl_scan_event_handler, WLC_E_ESCAN_RESULT);
if (bcmf_event_push_config(priv))
{
return -EIO;
}
@ -373,6 +291,161 @@ int bcmf_driver_initialize(FAR struct bcmf_dev_s *priv)
return bcmf_netdev_register(priv);
}
void bcmf_wl_default_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len)
{
wlinfo("Got event %d from <%s>\n", bcmf_getle32(&event->type),
event->src_name);
}
void bcmf_wl_radio_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len)
{
wlinfo("Got radio event %d from <%s>\n", bcmf_getle32(&event->type),
event->src_name);
}
void bcmf_wl_scan_event_handler(FAR struct bcmf_dev_s *priv,
struct bcmf_event_s *event, unsigned int len)
{
uint32_t status;
uint32_t reason;
uint32_t event_len;
struct wl_escan_result *result;
struct wl_bss_info *bss;
unsigned int bss_info_len;
unsigned int escan_result_len;
unsigned int bss_count = 0;
event_len = len;
if (priv->scan_status < BCMF_SCAN_RUN)
{
wlinfo("Got Unexpected scan event\n");
goto exit_invalid_frame;
}
status = bcmf_getle32(&event->status);
reason = bcmf_getle32(&event->reason);
escan_result_len = bcmf_getle32(&event->len);
len -= sizeof(struct bcmf_event_s);
if (len > escan_result_len)
{
len = escan_result_len;
}
if (len == sizeof(struct wl_escan_result) - sizeof(struct wl_bss_info))
{
/* Nothing to process, may be scan done event */
goto wl_escan_result_processed;
}
if (len < sizeof(struct wl_escan_result))
{
goto exit_invalid_frame;
}
/* Process escan result payload */
result = (struct wl_escan_result*)&event[1];
if (len < result->buflen || result->buflen < sizeof(struct wl_escan_result))
{
goto exit_invalid_frame;
}
/* wl_escan_result already cointains a wl_bss_info field */
len = result->buflen - sizeof(struct wl_escan_result)
+ sizeof(struct wl_bss_info);
/* Process bss_infos */
bss = result->bss_info;
do
{
bss_info_len = bss->length;
if (len < bss_info_len)
{
wlerr("bss_len error %d %d\n", len, bss_info_len);
goto exit_invalid_frame;
}
wlinfo("Scan result: <%.32s> %02x:%02x:%02x:%02x:%02x:%02x\n",
bss->SSID, bss->BSSID.octet[0], bss->BSSID.octet[1],
bss->BSSID.octet[2], bss->BSSID.octet[3],
bss->BSSID.octet[4], bss->BSSID.octet[5]);
/* Process next bss_info */
len -= bss_info_len;
bss = (struct wl_bss_info*)((uint8_t*)bss + bss_info_len);
bss_count += 1;
}
while (len > 0 && bss_count < result->bss_count);
wl_escan_result_processed:
if (status == WLC_E_STATUS_PARTIAL)
{
/* More frames to come */
return;
}
if (status != WLC_E_STATUS_SUCCESS)
{
wlerr("Invalid event status %d\n", status);
return;
}
/* Scan done */
wlinfo("escan done event %d %d\n", status, reason);
wd_cancel(priv->scan_timeout);
if (!priv->scan_params)
{
/* Scan has already timedout */
return;
}
free(priv->scan_params);
priv->scan_params = NULL;
priv->scan_status = BCMF_SCAN_DONE;
sem_post(&priv->control_mutex);
return;
exit_invalid_frame:
wlerr("Invalid scan result event\n");
bcmf_hexdump((uint8_t*)event, event_len, (unsigned long)event);
}
void bcmf_wl_scan_timeout(int argc, wdparm_t arg1, ...)
{
FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s*)arg1;
if (priv->scan_status < BCMF_SCAN_RUN)
{
/* Fatal error, invalid scan status */
wlerr("Unexpected scan timeout\n");
return;
}
wlerr("Scan timeout detected\n");
priv->scan_status = BCMF_SCAN_TIMEOUT;
free(priv->scan_params);
priv->scan_params = NULL;
sem_post(&priv->control_mutex);
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -419,10 +492,107 @@ int bcmf_wl_enable(FAR struct bcmf_dev_s *priv, bool enable)
ret = bcmf_cdc_ioctl(priv, CHIP_STA_INTERFACE, true,
enable ? WLC_UP : WLC_DOWN, NULL, &out_len);
/* TODO wait for WLC_E_RADIO event */
if (ret == OK)
{
/* TODO update device state */
}
return ret;
}
int bcmf_wl_start_scan(FAR struct bcmf_dev_s *priv)
{
int ret;
uint32_t out_len;
uint32_t value;
wlinfo("Enter\n");
/* Set active scan mode */
value = 0;
out_len = 4;
if (bcmf_cdc_ioctl(priv, CHIP_STA_INTERFACE, true,
WLC_SET_PASSIVE_SCAN, (uint8_t*)&value, &out_len))
{
return -EIO;
}
/* Lock control_mutex semaphore */
if ((ret = sem_wait(&priv->control_mutex)) != OK)
{
return ret;
}
/* Default request structure */
priv->scan_params = (struct wl_escan_params*)
kmm_malloc(sizeof(*priv->scan_params));
if (!priv->scan_params)
{
ret = -ENOMEM;
goto exit_sem_post;
}
memset(priv->scan_params, 0, sizeof(*priv->scan_params));
priv->scan_params->version = ESCAN_REQ_VERSION;
priv->scan_params->action = WL_SCAN_ACTION_START;
priv->scan_params->sync_id = 0xabcd; /* Not used for now */
memset(&priv->scan_params->params.bssid, 0xFF,
sizeof(priv->scan_params->params.bssid));
priv->scan_params->params.bss_type = DOT11_BSSTYPE_ANY;
priv->scan_params->params.scan_type = 0; /* Active scan */
priv->scan_params->params.nprobes = -1;
priv->scan_params->params.active_time = -1;
priv->scan_params->params.passive_time = -1;
priv->scan_params->params.home_time = -1;
priv->scan_params->params.channel_num = 0;
wlinfo("start scan\n");
priv->scan_status = BCMF_SCAN_RUN;
out_len = sizeof(*priv->scan_params);
if (bcmf_cdc_iovar_request_unsafe(priv, CHIP_STA_INTERFACE, true,
IOVAR_STR_ESCAN, (uint8_t*)priv->scan_params,
&out_len))
{
ret = -EIO;
goto exit_free_params;
}
/* Start scan_timeout timer */
wd_start(priv->scan_timeout, BCMF_SCAN_TIMEOUT_TICK,
bcmf_wl_scan_timeout, (wdparm_t)priv);
return OK;
exit_free_params:
free(priv->scan_params);
priv->scan_params = NULL;
exit_sem_post:
sem_post(&priv->control_mutex);
priv->scan_status = BCMF_SCAN_DISABLED;
return ret;
}
int bcmf_wl_is_scan_done(FAR struct bcmf_dev_s *priv)
{
if (priv->scan_status == BCMF_SCAN_RUN)
{
return -EAGAIN;
}
if (priv->scan_status == BCMF_SCAN_DONE)
{
return OK;
}
return -EINVAL;
}

View File

@ -44,15 +44,19 @@
#include <nuttx/wdog.h>
#include <nuttx/wqueue.h>
struct bcmf_dev_s;
struct bcmf_frame_s;
#include "bcmf_bdc.h"
struct bcmf_bus_dev_s;
/* Chip interfaces */
#define CHIP_STA_INTERFACE 0
#define CHIP_AP_INTERFACE 1
#define CHIP_P2P_INTERFACE 2
struct bcmf_bus_dev_s;
struct bcmf_frame_s;
/* This structure contains the unique state of the Broadcom FullMAC driver */
struct bcmf_dev_s
@ -69,6 +73,9 @@ struct bcmf_dev_s
struct net_driver_s bc_dev; /* Network interface structure */
/* Event registration array */
event_handler_t event_handlers[BCMF_EVENT_COUNT];
// FIXME use mutex instead of semaphore
sem_t control_mutex; /* Cannot handle multiple control requests */
@ -77,6 +84,13 @@ struct bcmf_dev_s
uint16_t control_rxdata_len; /* Received control frame out buffer length */
uint8_t *control_rxdata; /* Received control frame out buffer */
uint32_t control_status; /* Last received frame status */
/* AP Scan state machine.
* During scan, control_mutex is locked to prevent control requests */
int scan_status; /* Current scan status */
WDOG_ID scan_timeout; /* Scan timeout timer */
struct wl_escan_params *scan_params; /* Current scan parameters */
};
/* Default bus interface structure */
@ -104,4 +118,8 @@ struct bcmf_frame_s {
int bcmf_wl_enable(FAR struct bcmf_dev_s *priv, bool enable);
int bcmf_wl_start_scan(FAR struct bcmf_dev_s *priv);
int bcmf_wl_is_scan_done(FAR struct bcmf_dev_s *priv);
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_DRIVER_H */

View File

@ -106,7 +106,7 @@ typedef struct cnt_rx
#define WL_BSS_INFO_VERSION 108
#define MCSSET_LEN 16
typedef struct {
typedef struct wl_bss_info {
uint32_t version; /* version field */
uint32_t length; /* byte length of data in this record, */
/* starting at version and including IEs */
@ -2761,6 +2761,311 @@ typedef struct edcf_acparam edcf_acparam_t;
/* Stop packing structures */
#pragma pack()
/**
* Enumerated list of event types
*/
typedef enum
{
WLC_E_NONE = -1,
WLC_E_SET_SSID = 0 /** indicates status of set SSID */,
WLC_E_JOIN = 1, /** differentiates join IBSS from found (WLC_E_START) IBSS */
WLC_E_START = 2, /** STA founded an IBSS or AP started a BSS */
WLC_E_AUTH = 3, /** 802.11 AUTH request */
WLC_E_AUTH_IND = 4, /** 802.11 AUTH indication */
WLC_E_DEAUTH = 5, /** 802.11 DEAUTH request */
WLC_E_DEAUTH_IND = 6, /** 802.11 DEAUTH indication */
WLC_E_ASSOC = 7, /** 802.11 ASSOC request */
WLC_E_ASSOC_IND = 8, /** 802.11 ASSOC indication */
WLC_E_REASSOC = 9, /** 802.11 REASSOC request */
WLC_E_REASSOC_IND = 10, /** 802.11 REASSOC indication */
WLC_E_DISASSOC = 11, /** 802.11 DISASSOC request */
WLC_E_DISASSOC_IND = 12, /** 802.11 DISASSOC indication */
WLC_E_QUIET_START = 13, /** 802.11h Quiet period started */
WLC_E_QUIET_END = 14, /** 802.11h Quiet period ended */
WLC_E_BEACON_RX = 15, /** BEACONS received/lost indication */
WLC_E_LINK = 16, /** generic link indication */
WLC_E_MIC_ERROR = 17, /** TKIP MIC error occurred */
WLC_E_NDIS_LINK = 18, /** NDIS style link indication */
WLC_E_ROAM = 19, /** roam attempt occurred: indicate status & reason */
WLC_E_TXFAIL = 20, /** change in dot11FailedCount (txfail) */
WLC_E_PMKID_CACHE = 21, /** WPA2 pmkid cache indication */
WLC_E_RETROGRADE_TSF = 22, /** current AP's TSF value went backward */
WLC_E_PRUNE = 23, /** AP was pruned from join list for reason */
WLC_E_AUTOAUTH = 24, /** report AutoAuth table entry match for join attempt */
WLC_E_EAPOL_MSG = 25, /** Event encapsulating an EAPOL message */
WLC_E_SCAN_COMPLETE = 26, /** Scan results are ready or scan was aborted */
WLC_E_ADDTS_IND = 27, /** indicate to host addts fail/success */
WLC_E_DELTS_IND = 28, /** indicate to host delts fail/success */
WLC_E_BCNSENT_IND = 29, /** indicate to host of beacon transmit */
WLC_E_BCNRX_MSG = 30, /** Send the received beacon up to the host */
WLC_E_BCNLOST_MSG = 31, /** indicate to host loss of beacon */
WLC_E_ROAM_PREP = 32, /** before attempting to roam */
WLC_E_PFN_NET_FOUND = 33, /** PFN network found event */
WLC_E_PFN_NET_LOST = 34, /** PFN network lost event */
WLC_E_RESET_COMPLETE = 35,
WLC_E_JOIN_START = 36,
WLC_E_ROAM_START = 37,
WLC_E_ASSOC_START = 38,
WLC_E_IBSS_ASSOC = 39,
WLC_E_RADIO = 40,
WLC_E_PSM_WATCHDOG = 41, /** PSM microcode watchdog fired */
WLC_E_CCX_ASSOC_START = 42, /** CCX association start */
WLC_E_CCX_ASSOC_ABORT = 43, /** CCX association abort */
WLC_E_PROBREQ_MSG = 44, /** probe request received */
WLC_E_SCAN_CONFIRM_IND = 45,
WLC_E_PSK_SUP = 46, /** WPA Handshake */
WLC_E_COUNTRY_CODE_CHANGED = 47,
WLC_E_EXCEEDED_MEDIUM_TIME = 48, /** WMMAC excedded medium time */
WLC_E_ICV_ERROR = 49, /** WEP ICV error occurred */
WLC_E_UNICAST_DECODE_ERROR = 50, /** Unsupported unicast encrypted frame */
WLC_E_MULTICAST_DECODE_ERROR = 51, /** Unsupported multicast encrypted frame */
WLC_E_TRACE = 52,
WLC_E_BTA_HCI_EVENT = 53, /** BT-AMP HCI event */
WLC_E_IF = 54, /** I/F change (for wlan host notification) */
WLC_E_P2P_DISC_LISTEN_COMPLETE = 55, /** P2P Discovery listen state expires */
WLC_E_RSSI = 56, /** indicate RSSI change based on configured levels */
WLC_E_PFN_SCAN_COMPLETE = 57, /** PFN completed scan of network list */
WLC_E_EXTLOG_MSG = 58,
WLC_E_ACTION_FRAME = 59, /** Action frame reception */
WLC_E_ACTION_FRAME_COMPLETE = 60, /** Action frame Tx complete */
WLC_E_PRE_ASSOC_IND = 61, /** assoc request received */
WLC_E_PRE_REASSOC_IND = 62, /** re-assoc request received */
WLC_E_CHANNEL_ADOPTED = 63, /** channel adopted (xxx: obsoleted) */
WLC_E_AP_STARTED = 64, /** AP started */
WLC_E_DFS_AP_STOP = 65, /** AP stopped due to DFS */
WLC_E_DFS_AP_RESUME = 66, /** AP resumed due to DFS */
WLC_E_WAI_STA_EVENT = 67, /** WAI stations event */
WLC_E_WAI_MSG = 68, /** event encapsulating an WAI message */
WLC_E_ESCAN_RESULT = 69, /** escan result event */
WLC_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70, /** action frame off channel complete */ /* NOTE - This used to be WLC_E_WAKE_EVENT */
WLC_E_PROBRESP_MSG = 71, /** probe response received */
WLC_E_P2P_PROBREQ_MSG = 72, /** P2P Probe request received */
WLC_E_DCS_REQUEST = 73,
WLC_E_FIFO_CREDIT_MAP = 74, /** credits for D11 FIFOs. [AC0,AC1,AC2,AC3,BC_MC,ATIM] */
WLC_E_ACTION_FRAME_RX = 75, /** Received action frame event WITH wl_event_rx_frame_data_t header */
WLC_E_WAKE_EVENT = 76, /** Wake Event timer fired, used for wake WLAN test mode */
WLC_E_RM_COMPLETE = 77, /** Radio measurement complete */
WLC_E_HTSFSYNC = 78, /** Synchronize TSF with the host */
WLC_E_OVERLAY_REQ = 79, /** request an overlay IOCTL/iovar from the host */
WLC_E_CSA_COMPLETE_IND = 80,
WLC_E_EXCESS_PM_WAKE_EVENT = 81, /** excess PM Wake Event to inform host */
WLC_E_PFN_SCAN_NONE = 82, /** no PFN networks around */
WLC_E_PFN_SCAN_ALLGONE = 83, /** last found PFN network gets lost */
WLC_E_GTK_PLUMBED = 84,
WLC_E_ASSOC_IND_NDIS = 85, /** 802.11 ASSOC indication for NDIS only */
WLC_E_REASSOC_IND_NDIS = 86, /** 802.11 REASSOC indication for NDIS only */
WLC_E_ASSOC_REQ_IE = 87,
WLC_E_ASSOC_RESP_IE = 88,
WLC_E_ASSOC_RECREATED = 89, /** association recreated on resume */
WLC_E_ACTION_FRAME_RX_NDIS = 90, /** rx action frame event for NDIS only */
WLC_E_AUTH_REQ = 91, /** authentication request received */
WLC_E_TDLS_PEER_EVENT = 92, /** discovered peer, connected/disconnected peer */
WLC_E_SPEEDY_RECREATE_FAIL = 93, /** fast assoc recreation failed */
WLC_E_NATIVE = 94, /** port-specific event and payload (e.g. NDIS) */
WLC_E_PKTDELAY_IND = 95, /** event for tx pkt delay suddently jump */
WLC_E_AWDL_AW = 96, /** AWDL AW period starts */
WLC_E_AWDL_ROLE = 97, /** AWDL Master/Slave/NE master role event */
WLC_E_AWDL_EVENT = 98, /** Generic AWDL event */
WLC_E_NIC_AF_TXS = 99, /** NIC AF txstatus */
WLC_E_NIC_NIC_REPORT = 100, /** NIC period report */
WLC_E_BEACON_FRAME_RX = 101,
WLC_E_SERVICE_FOUND = 102, /** desired service found */
WLC_E_GAS_FRAGMENT_RX = 103, /** GAS fragment received */
WLC_E_GAS_COMPLETE = 104, /** GAS sessions all complete */
WLC_E_P2PO_ADD_DEVICE = 105, /** New device found by p2p offload */
WLC_E_P2PO_DEL_DEVICE = 106, /** device has been removed by p2p offload */
WLC_E_WNM_STA_SLEEP = 107, /** WNM event to notify STA enter sleep mode */
WLC_E_TXFAIL_THRESH = 108, /** Indication of MAC tx failures (exhaustion of 802.11 retries) exceeding threshold(s) */
WLC_E_PROXD = 109, /** Proximity Detection event */
WLC_E_IBSS_COALESCE = 110, /** IBSS Coalescing */
WLC_E_AWDL_RX_PRB_RESP = 111, /** AWDL RX Probe response */
WLC_E_AWDL_RX_ACT_FRAME = 112, /** AWDL RX Action Frames */
WLC_E_AWDL_WOWL_NULLPKT = 113, /** AWDL Wowl nulls */
WLC_E_AWDL_PHYCAL_STATUS = 114, /** AWDL Phycal status */
WLC_E_AWDL_OOB_AF_STATUS = 115, /** AWDL OOB AF status */
WLC_E_AWDL_SCAN_STATUS = 116, /** Interleaved Scan status */
WLC_E_AWDL_AW_START = 117, /** AWDL AW Start */
WLC_E_AWDL_AW_END = 118, /** AWDL AW End */
WLC_E_AWDL_AW_EXT = 119, /** AWDL AW Extensions */
WLC_E_AWDL_PEER_CACHE_CONTROL = 120,
WLC_E_CSA_START_IND = 121,
WLC_E_CSA_DONE_IND = 122,
WLC_E_CSA_FAILURE_IND = 123,
WLC_E_CCA_CHAN_QUAL = 124, /** CCA based channel quality report */
WLC_E_BSSID = 125, /** to report change in BSSID while roaming */
WLC_E_TX_STAT_ERROR = 126, /** tx error indication */
WLC_E_BCMC_CREDIT_SUPPORT = 127, /** credit check for BCMC supported */
WLC_E_PSTA_PRIMARY_INTF_IND = 128, /** psta primary interface indication */
WLC_E_LAST = 129, /** highest val + 1 for range checking */
WLC_E_FORCE_32_BIT = 0x7FFFFFFE /** Force enum to be stored in 32 bit variable */
} wwd_event_num_t;
#define BCMF_EVENT_COUNT WLC_E_LAST
#define WLC_SUP_STATUS_OFFSET (256)
#define WLC_DOT11_SC_STATUS_OFFSET (512)
/**
* Enumerated list of event status codes
* @note : WLC_SUP values overlap other values, so it is necessary
* to check the event type
*/
typedef enum
{
WLC_E_STATUS_SUCCESS = 0, /** operation was successful */
WLC_E_STATUS_FAIL = 1, /** operation failed */
WLC_E_STATUS_TIMEOUT = 2, /** operation timed out */
WLC_E_STATUS_NO_NETWORKS = 3, /** failed due to no matching network found */
WLC_E_STATUS_ABORT = 4, /** operation was aborted */
WLC_E_STATUS_NO_ACK = 5, /** protocol failure: packet not ack'd */
WLC_E_STATUS_UNSOLICITED = 6, /** AUTH or ASSOC packet was unsolicited */
WLC_E_STATUS_ATTEMPT = 7, /** attempt to assoc to an auto auth configuration */
WLC_E_STATUS_PARTIAL = 8, /** scan results are incomplete */
WLC_E_STATUS_NEWSCAN = 9, /** scan aborted by another scan */
WLC_E_STATUS_NEWASSOC = 10, /** scan aborted due to assoc in progress */
WLC_E_STATUS_11HQUIET = 11, /** 802.11h quiet period started */
WLC_E_STATUS_SUPPRESS = 12, /** user disabled scanning (WLC_SET_SCANSUPPRESS) */
WLC_E_STATUS_NOCHANS = 13, /** no allowable channels to scan */
WLC_E_STATUS_CCXFASTRM = 14, /** scan aborted due to CCX fast roam */
WLC_E_STATUS_CS_ABORT = 15, /** abort channel select */
/* for WLC_SUP messages */
WLC_SUP_DISCONNECTED = 0 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_CONNECTING = 1 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_IDREQUIRED = 2 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_AUTHENTICATING = 3 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_AUTHENTICATED = 4 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_KEYXCHANGE = 5 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_KEYED = 6 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_TIMEOUT = 7 + WLC_SUP_STATUS_OFFSET,
WLC_SUP_LAST_BASIC_STATE = 8 + WLC_SUP_STATUS_OFFSET,
/* Extended supplicant authentication states */
WLC_SUP_KEYXCHANGE_WAIT_M1 = (int) WLC_SUP_AUTHENTICATED + WLC_SUP_STATUS_OFFSET, /** Waiting to receive handshake msg M1 */
WLC_SUP_KEYXCHANGE_PREP_M2 = (int) WLC_SUP_KEYXCHANGE + WLC_SUP_STATUS_OFFSET, /** Preparing to send handshake msg M2 */
WLC_SUP_KEYXCHANGE_WAIT_M3 = (int) WLC_SUP_LAST_BASIC_STATE + WLC_SUP_STATUS_OFFSET, /** Waiting to receive handshake msg M3 */
WLC_SUP_KEYXCHANGE_PREP_M4 = 9 + WLC_SUP_STATUS_OFFSET, /** Preparing to send handshake msg M4 */
WLC_SUP_KEYXCHANGE_WAIT_G1 = 10 + WLC_SUP_STATUS_OFFSET, /** Waiting to receive handshake msg G1 */
WLC_SUP_KEYXCHANGE_PREP_G2 = 11 + WLC_SUP_STATUS_OFFSET, /** Preparing to send handshake msg G2 */
WLC_DOT11_SC_SUCCESS = 0 + WLC_DOT11_SC_STATUS_OFFSET, /* Successful */
WLC_DOT11_SC_FAILURE = 1 + WLC_DOT11_SC_STATUS_OFFSET, /* Unspecified failure */
WLC_DOT11_SC_CAP_MISMATCH = 10 + WLC_DOT11_SC_STATUS_OFFSET, /* Cannot support all requested capabilities in the Capability Information field */
WLC_DOT11_SC_REASSOC_FAIL = 11 + WLC_DOT11_SC_STATUS_OFFSET, /* Reassociation denied due to inability to confirm that association exists */
WLC_DOT11_SC_ASSOC_FAIL = 12 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to reason outside the scope of this standard */
WLC_DOT11_SC_AUTH_MISMATCH = 13 + WLC_DOT11_SC_STATUS_OFFSET, /* Responding station does not support the specified authentication algorithm */
WLC_DOT11_SC_AUTH_SEQ = 14 + WLC_DOT11_SC_STATUS_OFFSET, /* Received an Authentication frame with authentication transaction sequence number out of expected sequence */
WLC_DOT11_SC_AUTH_CHALLENGE_FAIL = 15 + WLC_DOT11_SC_STATUS_OFFSET, /* Authentication rejected because of challenge failure */
WLC_DOT11_SC_AUTH_TIMEOUT = 16 + WLC_DOT11_SC_STATUS_OFFSET, /* Authentication rejected due to timeout waiting for next frame in sequence */
WLC_DOT11_SC_ASSOC_BUSY_FAIL = 17 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because AP is unable to handle additional associated stations */
WLC_DOT11_SC_ASSOC_RATE_MISMATCH = 18 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter */
WLC_DOT11_SC_ASSOC_SHORT_REQUIRED = 19 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Short Preamble option */
WLC_DOT11_SC_ASSOC_PBCC_REQUIRED = 20 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the PBCC Modulation option */
WLC_DOT11_SC_ASSOC_AGILITY_REQUIRED = 21 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Channel Agility option */
WLC_DOT11_SC_ASSOC_SPECTRUM_REQUIRED = 22 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because Spectrum Management capability is required. */
WLC_DOT11_SC_ASSOC_BAD_POWER_CAP = 23 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because the info in the Power Cap element is unacceptable. */
WLC_DOT11_SC_ASSOC_BAD_SUP_CHANNELS = 24 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied because the info in the Supported Channel element is unacceptable */
WLC_DOT11_SC_ASSOC_SHORTSLOT_REQUIRED = 25 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the Short Slot Time option */
WLC_DOT11_SC_ASSOC_ERPBCC_REQUIRED = 26 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the ER-PBCC Modulation option */
WLC_DOT11_SC_ASSOC_DSSOFDM_REQUIRED = 27 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to requesting station not supporting the DSS-OFDM option */
WLC_DOT11_SC_DECLINED = 37 + WLC_DOT11_SC_STATUS_OFFSET, /* request declined */
WLC_DOT11_SC_INVALID_PARAMS = 38 + WLC_DOT11_SC_STATUS_OFFSET, /* One or more params have invalid values */
WLC_DOT11_SC_INVALID_AKMP = 43 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid AKMP */
WLC_DOT11_SC_INVALID_MDID = 54 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid MDID */
WLC_DOT11_SC_INVALID_FTIE = 55 + WLC_DOT11_SC_STATUS_OFFSET, /* Association denied due to invalid FTIE */
WLC_E_STATUS_FORCE_32_BIT = 0x7FFFFFFE /** Force enum to be stored in 32 bit variable */
} wwd_event_status_t;
#define WLC_E_PRUNE_REASON_OFFSET (256)
#define WLC_E_SUP_REASON_OFFSET (512)
#define WLC_E_DOT11_RC_REASON_OFFSET (768)
/**
* Enumerated list of event reason codes
* @note : Several values overlap other values, so it is necessary
* to check the event type
*/
typedef enum
{
/* roam reason codes */
WLC_E_REASON_INITIAL_ASSOC = 0, /** initial assoc */
WLC_E_REASON_LOW_RSSI = 1, /** roamed due to low RSSI */
WLC_E_REASON_DEAUTH = 2, /** roamed due to DEAUTH indication */
WLC_E_REASON_DISASSOC = 3, /** roamed due to DISASSOC indication */
WLC_E_REASON_BCNS_LOST = 4, /** roamed due to lost beacons */
WLC_E_REASON_FAST_ROAM_FAILED = 5, /** roamed due to fast roam failure */
WLC_E_REASON_DIRECTED_ROAM = 6, /** roamed due to request by AP */
WLC_E_REASON_TSPEC_REJECTED = 7, /** roamed due to TSPEC rejection */
WLC_E_REASON_BETTER_AP = 8, /** roamed due to finding better AP */
/* prune reason codes */
WLC_E_PRUNE_ENCR_MISMATCH = 1 + WLC_E_PRUNE_REASON_OFFSET, /** encryption mismatch */
WLC_E_PRUNE_BCAST_BSSID = 2 + WLC_E_PRUNE_REASON_OFFSET, /** AP uses a broadcast BSSID */
WLC_E_PRUNE_MAC_DENY = 3 + WLC_E_PRUNE_REASON_OFFSET, /** STA's MAC addr is in AP's MAC deny list */
WLC_E_PRUNE_MAC_NA = 4 + WLC_E_PRUNE_REASON_OFFSET, /** STA's MAC addr is not in AP's MAC allow list */
WLC_E_PRUNE_REG_PASSV = 5 + WLC_E_PRUNE_REASON_OFFSET, /** AP not allowed due to regulatory restriction */
WLC_E_PRUNE_SPCT_MGMT = 6 + WLC_E_PRUNE_REASON_OFFSET, /** AP does not support STA locale spectrum mgmt */
WLC_E_PRUNE_RADAR = 7 + WLC_E_PRUNE_REASON_OFFSET, /** AP is on a radar channel of STA locale */
WLC_E_RSN_MISMATCH = 8 + WLC_E_PRUNE_REASON_OFFSET, /** STA does not support AP's RSN */
WLC_E_PRUNE_NO_COMMON_RATES = 9 + WLC_E_PRUNE_REASON_OFFSET, /** No rates in common with AP */
WLC_E_PRUNE_BASIC_RATES = 10 + WLC_E_PRUNE_REASON_OFFSET, /** STA does not support all basic rates of BSS */
WLC_E_PRUNE_CCXFAST_PREVAP = 11 + WLC_E_PRUNE_REASON_OFFSET, /** CCX FAST ROAM: prune previous AP */
WLC_E_PRUNE_CIPHER_NA = 12 + WLC_E_PRUNE_REASON_OFFSET, /** BSS's cipher not supported */
WLC_E_PRUNE_KNOWN_STA = 13 + WLC_E_PRUNE_REASON_OFFSET, /** AP is already known to us as a STA */
WLC_E_PRUNE_CCXFAST_DROAM = 14 + WLC_E_PRUNE_REASON_OFFSET, /** CCX FAST ROAM: prune unqualified AP */
WLC_E_PRUNE_WDS_PEER = 15 + WLC_E_PRUNE_REASON_OFFSET, /** AP is already known to us as a WDS peer */
WLC_E_PRUNE_QBSS_LOAD = 16 + WLC_E_PRUNE_REASON_OFFSET, /** QBSS LOAD - AAC is too low */
WLC_E_PRUNE_HOME_AP = 17 + WLC_E_PRUNE_REASON_OFFSET, /** prune home AP */
WLC_E_PRUNE_AP_BLOCKED = 18 + WLC_E_PRUNE_REASON_OFFSET, /** prune blocked AP */
WLC_E_PRUNE_NO_DIAG_SUPPORT = 19 + WLC_E_PRUNE_REASON_OFFSET, /** prune due to diagnostic mode not supported */
/* WPA failure reason codes carried in the WLC_E_PSK_SUP event */
WLC_E_SUP_OTHER = 0 + WLC_E_SUP_REASON_OFFSET, /** Other reason */
WLC_E_SUP_DECRYPT_KEY_DATA = 1 + WLC_E_SUP_REASON_OFFSET, /** Decryption of key data failed */
WLC_E_SUP_BAD_UCAST_WEP128 = 2 + WLC_E_SUP_REASON_OFFSET, /** Illegal use of ucast WEP128 */
WLC_E_SUP_BAD_UCAST_WEP40 = 3 + WLC_E_SUP_REASON_OFFSET, /** Illegal use of ucast WEP40 */
WLC_E_SUP_UNSUP_KEY_LEN = 4 + WLC_E_SUP_REASON_OFFSET, /** Unsupported key length */
WLC_E_SUP_PW_KEY_CIPHER = 5 + WLC_E_SUP_REASON_OFFSET, /** Unicast cipher mismatch in pairwise key */
WLC_E_SUP_MSG3_TOO_MANY_IE = 6 + WLC_E_SUP_REASON_OFFSET, /** WPA IE contains > 1 RSN IE in key msg 3 */
WLC_E_SUP_MSG3_IE_MISMATCH = 7 + WLC_E_SUP_REASON_OFFSET, /** WPA IE mismatch in key message 3 */
WLC_E_SUP_NO_INSTALL_FLAG = 8 + WLC_E_SUP_REASON_OFFSET, /** INSTALL flag unset in 4-way msg */
WLC_E_SUP_MSG3_NO_GTK = 9 + WLC_E_SUP_REASON_OFFSET, /** encapsulated GTK missing from msg 3 */
WLC_E_SUP_GRP_KEY_CIPHER = 10 + WLC_E_SUP_REASON_OFFSET, /** Multicast cipher mismatch in group key */
WLC_E_SUP_GRP_MSG1_NO_GTK = 11 + WLC_E_SUP_REASON_OFFSET, /** encapsulated GTK missing from group msg 1 */
WLC_E_SUP_GTK_DECRYPT_FAIL = 12 + WLC_E_SUP_REASON_OFFSET, /** GTK decrypt failure */
WLC_E_SUP_SEND_FAIL = 13 + WLC_E_SUP_REASON_OFFSET, /** message send failure */
WLC_E_SUP_DEAUTH = 14 + WLC_E_SUP_REASON_OFFSET, /** received FC_DEAUTH */
WLC_E_SUP_WPA_PSK_TMO = 15 + WLC_E_SUP_REASON_OFFSET, /** WPA PSK 4-way handshake timeout */
DOT11_RC_RESERVED = 0 + WLC_E_DOT11_RC_REASON_OFFSET, /* d11 RC reserved */
DOT11_RC_UNSPECIFIED = 1 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unspecified reason */
DOT11_RC_AUTH_INVAL = 2 + WLC_E_DOT11_RC_REASON_OFFSET, /* Previous authentication no longer valid */
DOT11_RC_DEAUTH_LEAVING = 3 + WLC_E_DOT11_RC_REASON_OFFSET, /* Deauthenticated because sending station is leaving (or has left) IBSS or ESS */
DOT11_RC_INACTIVITY = 4 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated due to inactivity */
DOT11_RC_BUSY = 5 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated because AP is unable to handle all currently associated stations */
DOT11_RC_INVAL_CLASS_2 = 6 + WLC_E_DOT11_RC_REASON_OFFSET, /* Class 2 frame received from nonauthenticated station */
DOT11_RC_INVAL_CLASS_3 = 7 + WLC_E_DOT11_RC_REASON_OFFSET, /* Class 3 frame received from nonassociated station */
DOT11_RC_DISASSOC_LEAVING = 8 + WLC_E_DOT11_RC_REASON_OFFSET, /* Disassociated because sending station is leaving (or has left) BSS */
DOT11_RC_NOT_AUTH = 9 + WLC_E_DOT11_RC_REASON_OFFSET, /* Station requesting (re)association is not * authenticated with responding station */
DOT11_RC_BAD_PC = 10 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unacceptable power capability element */
DOT11_RC_BAD_CHANNELS = 11 + WLC_E_DOT11_RC_REASON_OFFSET, /* Unacceptable supported channels element */
/* 12 is unused */
/* XXX 13-23 are WPA/802.11i reason codes defined in proto/wpa.h */
/* 32-39 are QSTA specific reasons added in 11e */
DOT11_RC_UNSPECIFIED_QOS = 32 + WLC_E_DOT11_RC_REASON_OFFSET, /* unspecified QoS-related reason */
DOT11_RC_INSUFFCIENT_BW = 33 + WLC_E_DOT11_RC_REASON_OFFSET, /* QAP lacks sufficient bandwidth */
DOT11_RC_EXCESSIVE_FRAMES = 34 + WLC_E_DOT11_RC_REASON_OFFSET, /* excessive number of frames need ack */
DOT11_RC_TX_OUTSIDE_TXOP = 35 + WLC_E_DOT11_RC_REASON_OFFSET, /* transmitting outside the limits of txop */
DOT11_RC_LEAVING_QBSS = 36 + WLC_E_DOT11_RC_REASON_OFFSET, /* QSTA is leaving the QBSS (or restting) */
DOT11_RC_BAD_MECHANISM = 37 + WLC_E_DOT11_RC_REASON_OFFSET, /* does not want to use the mechanism */
DOT11_RC_SETUP_NEEDED = 38 + WLC_E_DOT11_RC_REASON_OFFSET, /* mechanism needs a setup */
DOT11_RC_TIMEOUT = 39 + WLC_E_DOT11_RC_REASON_OFFSET, /* timeout */
DOT11_RC_MAX = 23 + WLC_E_DOT11_RC_REASON_OFFSET, /* Reason codes > 23 are reserved */
WLC_E_REASON_FORCE_32_BIT = 0x7FFFFFFE /** Force enum to be stored in 32 bit variable */
} wwd_event_reason_t;
#ifdef __cplusplus

View File

@ -801,6 +801,12 @@ static int bcmf_ifup(FAR struct net_driver_s *dev)
priv->bc_bifup = true;
#warning Missing logic
if (bcmf_wl_enable(priv, true) != OK)
{
return -EIO;
}
return OK;
}
@ -825,6 +831,8 @@ static int bcmf_ifdown(FAR struct net_driver_s *dev)
FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s *)dev->d_private;
irqstate_t flags;
bcmf_wl_enable(priv, false);
/* Disable the hardware interrupt */
flags = enter_critical_section();
@ -1082,13 +1090,21 @@ static void bcmf_ipv6multicast(FAR struct bcmf_dev_s *priv)
static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
unsigned long arg)
{
FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s *)dev->d_private;
int ret;
FAR struct bcmf_dev_s *priv = (FAR struct bcmf_dev_s *)dev->d_private;
/* Decode and dispatch the driver-specific IOCTL command */
switch (cmd)
{
case SIOCSIWSCAN:
ret = bcmf_wl_start_scan(priv);
break;
case SIOCGIWSCAN:
ret = bcmf_wl_is_scan_done(priv);
break;
case SIOCSIWFREQ: /* Set channel/frequency (Hz) */
wlwarn("WARNING: SIOCSIWFREQ not implemented\n");
ret = -ENOSYS;
@ -1150,7 +1166,7 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
break;
default:
nerr("ERROR: Unrecognized IOCTL command: %d\n", command);
nerr("ERROR: Unrecognized IOCTL command: %d\n", cmd);
ret = -ENOTTY; /* Special return value for this case */
break;
}
@ -1181,7 +1197,6 @@ static int bcmf_ioctl(FAR struct net_driver_s *dev, int cmd,
int bcmf_netdev_register(FAR struct bcmf_dev_s *priv)
{
int ret;
uint32_t out_len;
/* Initialize network driver structure */
@ -1211,8 +1226,7 @@ int bcmf_netdev_register(FAR struct bcmf_dev_s *priv)
* the device and/or calling bcmf_ifdown().
*/
ret = bcmf_wl_enable(priv, false);
if (ret != OK)
if (bcmf_wl_enable(priv, false) != OK)
{
return -EIO;
}
@ -1220,23 +1234,14 @@ int bcmf_netdev_register(FAR struct bcmf_dev_s *priv)
/* Query MAC address */
out_len = ETHER_ADDR_LEN;
ret = bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, false,
if (bcmf_cdc_iovar_request(priv, CHIP_STA_INTERFACE, false,
IOVAR_STR_CUR_ETHERADDR,
priv->bc_dev.d_mac.ether.ether_addr_octet,
&out_len);
if (ret != OK)
&out_len) != OK)
{
return -EIO;
}
wlinfo("MAC address is %02X:%02X:%02X:%02X:%02X:%02X\n",
priv->bc_dev.d_mac.ether.ether_addr_octet[0],
priv->bc_dev.d_mac.ether.ether_addr_octet[1],
priv->bc_dev.d_mac.ether.ether_addr_octet[2],
priv->bc_dev.d_mac.ether.ether_addr_octet[3],
priv->bc_dev.d_mac.ether.ether_addr_octet[4],
priv->bc_dev.d_mac.ether.ether_addr_octet[5]);
/* Register the device with the OS so that socket IOCTLs can be performed */
(void)netdev_register(&priv->bc_dev, NET_LL_IEEE80211);

View File

@ -51,6 +51,7 @@
#include <nuttx/kmalloc.h>
#include <nuttx/arch.h>
#include <nuttx/kthread.h>
#include <nuttx/wdog.h>
#include <nuttx/wireless/ieee80211/mmc_sdio.h>
#include <nuttx/wireless/ieee80211/bcmf_sdio.h>

View File

@ -61,6 +61,13 @@
#define I_HMB_SW_MASK ( (uint32_t) 0x000000F0 )
#define I_HMB_FRAME_IND ( 1<<6 )
/* tosbmailbox bits corresponding to intstatus bits */
#define SMB_NAK (1 << 0) /* Frame NAK */
#define SMB_INT_ACK (1 << 1) /* Host Interrupt ACK */
#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */
#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */
enum {
CHIPCOMMON_CORE_ID = 0,
DOT11MAC_CORE_ID,

View File

@ -80,7 +80,6 @@
#define SBSDIO_WATERMARK 0x10008
/* control busy signal generation */
#define SBSDIO_DEVICE_CTL 0x10009
/* SB Address Window Low (b15) */
#define SBSDIO_FUNC1_SBADDRLOW 0x1000A
/* SB Address Window Mid (b23:b16) */
@ -89,24 +88,34 @@
#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C
/* Frame Control (frame term/abort) */
#define SBSDIO_FUNC1_FRAMECTRL 0x1000D
/* Read Frame Terminate */
#define SFC_RF_TERM (1 << 0)
/* Write Frame Terminate */
#define SFC_WF_TERM (1 << 1)
/* CRC error for write out of sync */
#define SFC_CRC4WOOS (1 << 2)
/* Abort all in-progress frames */
#define SFC_ABORTALL (1 << 3)
/* ChipClockCSR (ALP/HT ctl/status) */
#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E
/* Force ALP request to backplane */
#define SBSDIO_FORCE_ALP 0x01
#define SBSDIO_FORCE_ALP 0x01
/* Force HT request to backplane */
#define SBSDIO_FORCE_HT 0x02
#define SBSDIO_FORCE_HT 0x02
/* Force ILP request to backplane */
#define SBSDIO_FORCE_ILP 0x04
#define SBSDIO_FORCE_ILP 0x04
/* Make ALP ready (power up xtal) */
#define SBSDIO_ALP_AVAIL_REQ 0x08
/* Make HT ready (power up PLL) */
#define SBSDIO_HT_AVAIL_REQ 0x10
#define SBSDIO_HT_AVAIL_REQ 0x10
/* Squelch clock requests from HW */
#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20
/* Status: ALP is ready */
#define SBSDIO_ALP_AVAIL 0x40
#define SBSDIO_ALP_AVAIL 0x40
/* Status: HT is ready */
#define SBSDIO_HT_AVAIL 0x80
#define SBSDIO_HT_AVAIL 0x80
/* SdioPullUp (on cmd, d0-d2) */
#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F
/* Write Frame Byte Count Low */

View File

@ -53,6 +53,7 @@
#include "bcmf_core.h"
#include "bcmf_sdpcm.h"
#include "bcmf_cdc.h"
#include "bcmf_bdc.h"
#include "bcmf_utils.h"
#include "bcmf_sdio_regs.h"
@ -61,23 +62,9 @@
* Pre-processor Definitions
****************************************************************************/
/* SDA_FRAMECTRL */
#define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */
#define SFC_WF_TERM (1 << 1) /* Write Frame Terminate */
#define SFC_CRC4WOOS (1 << 2) /* CRC error for write out of sync */
#define SFC_ABORTALL (1 << 3) /* Abort all in-progress frames */
/* tosbmailbox bits corresponding to intstatus bits */
#define SMB_NAK (1 << 0) /* Frame NAK */
#define SMB_INT_ACK (1 << 1) /* Host Interrupt ACK */
#define SMB_USE_OOB (1 << 2) /* Use OOB Wakeup */
#define SMB_DEV_INT (1 << 3) /* Miscellaneous Interrupt */
#define SDPCM_CONTROL_CHANNEL 0 /* Control */
#define SDPCM_EVENT_CHANNEL 1 /* Asyc Event Indication */
#define SDPCM_DATA_CHANNEL 2 /* Data Xmit/Recv */
#define SDPCM_GLOM_CHANNEL 3 /* Coalesced packets */
#define SDPCM_TEST_CHANNEL 15 /* Test/debug packets */
#define SDPCM_CONTROL_CHANNEL 0 /* Control frame id */
#define SDPCM_EVENT_CHANNEL 1 /* Asynchronous event frame id */
#define SDPCM_DATA_CHANNEL 2 /* Data frame id */
#define container_of(ptr, type, member) \
(type *)( (uint8_t *)(ptr) - offsetof(type,member) )
@ -86,7 +73,7 @@
* Private Types
****************************************************************************/
struct bcmf_sdpcm_header {
struct __attribute__((packed)) bcmf_sdpcm_header {
uint16_t size;
uint16_t checksum;
uint8_t sequence;
@ -262,11 +249,20 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv)
break;
case SDPCM_EVENT_CHANNEL:
ret = bcmf_cdc_process_event_frame(priv, &sframe->frame_header);
if (header->data_offset == header->size)
{
/* Empty event, ignore */
ret = OK;
}
else
{
ret = bcmf_bdc_process_event_frame(priv, &sframe->frame_header);
}
break;
case SDPCM_DATA_CHANNEL:
ret = bcmf_cdc_process_data_frame(priv, &sframe->frame_header);
ret = bcmf_bdc_process_data_frame(priv, &sframe->frame_header);
break;
default:

View File

@ -51,4 +51,16 @@ void bcmf_hexdump(uint8_t *data, unsigned int len, unsigned long offset);
int bcmf_sem_wait(sem_t *sem, unsigned int timeout_ms);
static inline uint16_t bcmf_getle16(uint16_t *val)
{
uint8_t *valb = (uint8_t*)val;
return (uint16_t)valb[0] << 8 | (uint16_t)valb[1];
}
static inline uint16_t bcmf_getle32(uint32_t *val)
{
uint16_t *valw = (uint16_t*)val;
return (uint32_t)bcmf_getle16(valw)<<16 | bcmf_getle16(valw+1);
}
#endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_UTILS_H */