From d646bde1f87d3aa2d70ebb355350248bc3c10c02 Mon Sep 17 00:00:00 2001 From: Simon Piriou Date: Sun, 16 Apr 2017 11:28:08 +0200 Subject: [PATCH] photon: add sdpcm tx basic support --- drivers/wireless/ieee80211/Make.defs | 1 + .../wireless/ieee80211/bcm43362_constants.h | 4 - drivers/wireless/ieee80211/bcmf_driver.h | 11 +- drivers/wireless/ieee80211/bcmf_hexdump.c | 36 ++ drivers/wireless/ieee80211/bcmf_sdio.c | 82 ++++- drivers/wireless/ieee80211/bcmf_sdio.h | 2 + drivers/wireless/ieee80211/bcmf_sdio_core.h | 4 + drivers/wireless/ieee80211/bcmf_sdpcm.c | 331 +++++++++++++++++- drivers/wireless/ieee80211/bcmf_sdpcm.h | 31 +- 9 files changed, 442 insertions(+), 60 deletions(-) create mode 100644 drivers/wireless/ieee80211/bcmf_hexdump.c diff --git a/drivers/wireless/ieee80211/Make.defs b/drivers/wireless/ieee80211/Make.defs index 440e5a9f23..1fa0d3b091 100644 --- a/drivers/wireless/ieee80211/Make.defs +++ b/drivers/wireless/ieee80211/Make.defs @@ -44,6 +44,7 @@ ifeq ($(CONFIG_IEEE80211_BROADCOM_FULLMAC_SDIO),y) CSRCS += bcmf_sdio.c CSRCS += bcmf_core.c CSRCS += bcmf_sdpcm.c + CSRCS += bcmf_hexdump.c CSRCS += mmc_sdio.c endif diff --git a/drivers/wireless/ieee80211/bcm43362_constants.h b/drivers/wireless/ieee80211/bcm43362_constants.h index 0911bdfbe8..4144c049b6 100644 --- a/drivers/wireless/ieee80211/bcm43362_constants.h +++ b/drivers/wireless/ieee80211/bcm43362_constants.h @@ -51,10 +51,6 @@ #define SOCSRAM_BASE_ADDRESS 0x18004000 /* SOCSRAM core register region */ #define BACKPLANE_ADDRESS_MASK 0x7FFF -#define CHIP_STA_INTERFACE 0 -#define CHIP_AP_INTERFACE 1 -#define CHIP_P2P_INTERFACE 2 - /* Maximum value of bus data credit difference */ #define CHIP_MAX_BUS_DATA_CREDIT_DIFF 7 diff --git a/drivers/wireless/ieee80211/bcmf_driver.h b/drivers/wireless/ieee80211/bcmf_driver.h index 6225f7396e..bf870bf9d6 100644 --- a/drivers/wireless/ieee80211/bcmf_driver.h +++ b/drivers/wireless/ieee80211/bcmf_driver.h @@ -51,7 +51,7 @@ struct bcmf_dev_s uint32_t (*get_core_base_address)(unsigned int core); /* Get chip specific base address for evey cores */ - sem_t sem; /* Semaphore for processing thread event */ + sem_t thread_signal; /* Semaphore for processing thread event */ struct wdog_s *waitdog; /* Processing thread waitdog */ bool ready; /* Current device status */ bool sleeping; /* Current sleep status */ @@ -61,6 +61,15 @@ struct bcmf_dev_s uint8_t max_seq; /* Maximum transmit sequence allowed */ uint8_t tx_seq; /* Transmit sequence number (next) */ uint8_t rx_seq; /* Receive sequence number (expected) */ + + // FIXME use mutex instead of semaphore + sem_t control_mutex; /* Cannot handle multiple control requests */ + sem_t control_timeout; /* Semaphore to wait for control frame rsp */ + uint16_t control_reqid; /* Current control request id */ + + // FIXME use mutex instead of semaphore + sem_t tx_queue_mutex; /* Lock for transmit queue */ + dq_queue_t tx_queue; /* Queue of frames to tramsmit */ }; #endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_DRIVER_H */ diff --git a/drivers/wireless/ieee80211/bcmf_hexdump.c b/drivers/wireless/ieee80211/bcmf_hexdump.c new file mode 100644 index 0000000000..d1f29b02ff --- /dev/null +++ b/drivers/wireless/ieee80211/bcmf_hexdump.c @@ -0,0 +1,36 @@ +#include +#include +#include + +#include + +#define LINE_LEN 16 + +void bcmf_hexdump(uint8_t *data, unsigned int len, unsigned long offset) +{ + unsigned int i; + unsigned int char_count = 0; + char char_line[20]; + char hex_line[64]; + + for(i = 0; i < len; i++) + { + if (char_count >= LINE_LEN) { + /* Flush line */ + _info("%08x: %s%s\n", offset+i-char_count, hex_line, char_line); + char_count = 0; + } + + sprintf(hex_line+3*char_count, "%02x ", data[i]); + sprintf(char_line+char_count, "%c", + data[i] < 0x20 || data[i] >= 0x7f? '.': data[i]); + char_count ++; + } + + if (char_count > 0) { + /* Flush last line */ + memset(hex_line+3*char_count, ' ', 3*(LINE_LEN-char_count)); + hex_line[3*LINE_LEN] = 0; + _info("%08x: %s%s\n", offset+i-char_count, hex_line, char_line); + } +} \ No newline at end of file diff --git a/drivers/wireless/ieee80211/bcmf_sdio.c b/drivers/wireless/ieee80211/bcmf_sdio.c index 9d5a26377c..96778a7d7c 100644 --- a/drivers/wireless/ieee80211/bcmf_sdio.c +++ b/drivers/wireless/ieee80211/bcmf_sdio.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,9 @@ #include "bcmf_core.h" #include "bcmf_sdpcm.h" +// TODO remove +#include "bcmf_ioctl.h" + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -114,7 +118,7 @@ int bcmf_oob_irq(int irq, FAR void *context, FAR void *arg) /* Signal bmcf thread */ priv->irq_pending = true; - sem_post(&priv->sem); + sem_post(&priv->thread_signal); } return OK; } @@ -362,8 +366,8 @@ int bcmf_bus_setup_interrupts(FAR struct bcmf_dev_s *priv) /* Redirect, configure and enable io for out-of-band interrupt signal */ - ret = sdio_io_rw_direct(priv->sdio_dev, true, 0, SDIO_CCCR_BRCM_SEPINT, - SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI, NULL); + ret = bcmf_write_reg(priv, 0, SDIO_CCCR_BRCM_SEPINT, + SDIO_SEPINT_MASK | SDIO_SEPINT_OE | SDIO_SEPINT_ACT_HI); if (ret != OK) { return ret; @@ -527,6 +531,29 @@ int bcmf_write_reg(FAR struct bcmf_dev_s *priv, uint8_t function, return bcmf_transfer_bytes(priv, true, function, address, ®, 1); } +/**************************************************************************** + * Name: bcmf_sem_wait + ****************************************************************************/ + +int bcmf_sem_wait(sem_t *sem, unsigned int timeout_ms) +{ + struct timespec abstime; + + /* Get the current time */ + + (void)clock_gettime(CLOCK_REALTIME, &abstime); + + abstime.tv_nsec += 1000 * 1000* timeout_ms; + + if (abstime.tv_nsec >= 1000 * 1000 * 1000) + { + abstime.tv_sec++; + abstime.tv_nsec -= 1000 * 1000 * 1000; + } + + return sem_timedwait(sem, &abstime); +} + /**************************************************************************** * Name: bcmf_sdio_initialize ****************************************************************************/ @@ -555,11 +582,11 @@ int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev) priv->ready = false; priv->sleeping = true; - if ((ret = sem_init(&priv->sem, 0, 0)) != OK) + if ((ret = sem_init(&priv->thread_signal, 0, 0)) != OK) { goto exit_free_priv; } - if ((ret = sem_setprotocol(&priv->sem, SEM_PRIO_NONE)) != OK) + if ((ret = sem_setprotocol(&priv->thread_signal, SEM_PRIO_NONE)) != OK) { goto exit_free_priv; } @@ -571,6 +598,27 @@ int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev) goto exit_free_priv; } + if ((ret = sem_init(&priv->control_mutex, 0, 1)) != OK) + { + goto exit_free_waitdog; + } + + if ((ret = sem_init(&priv->control_timeout, 0, 0)) != OK) + { + goto exit_free_waitdog; + } + if ((ret = sem_setprotocol(&priv->control_timeout, SEM_PRIO_NONE)) != OK) + { + goto exit_free_waitdog; + } + /* Init transmit frames queue */ + + if ((ret = sem_init(&priv->tx_queue_mutex, 0, 1)) != OK) + { + goto exit_free_waitdog; + } + sq_init(&priv->tx_queue); + /* Initialize device hardware */ ret = bcmf_hwinitialize(priv); @@ -632,6 +680,15 @@ int bcmf_sdio_initialize(int minor, FAR struct sdio_dev_s *dev) /* Device is up and running TODO Create a wlan device name and register network driver here */ + // TODO remove: basic iovar test + up_mdelay(2000); + char fw_version[64]; + ret = bcmf_sdpcm_iovar_request(priv, CHIP_STA_INTERFACE, false, + IOVAR_STR_VERSION, fw_version, + sizeof(fw_version)); + _info("fw version %d\n", ret); + + return OK; exit_uninit_hw: @@ -675,7 +732,8 @@ void bcmf_sdio_waitdog_timeout(int argc, wdparm_t arg1, ...) FAR struct bcmf_dev_s *priv = g_sdio_priv; /* Notify bcmf thread */ - sem_post(&priv->sem); + + sem_post(&priv->thread_signal); } int bcmf_sdio_thread(int argc, char **argv) @@ -693,7 +751,7 @@ int bcmf_sdio_thread(int argc, char **argv) { /* Wait for event (device interrupt, user request or waitdog timer) */ - ret = sem_wait(&priv->sem); + ret = sem_wait(&priv->thread_signal); if (ret != OK) { _err("Error while waiting for semaphore\n"); @@ -715,8 +773,6 @@ int bcmf_sdio_thread(int argc, char **argv) priv->irq_pending = false; - _info("process irq\n"); - bcmf_read_sbregw(priv, CORE_BUS_REG(priv->get_core_base_address(SDIOD_CORE_ID), intstatus), &priv->intstatus); @@ -748,10 +804,16 @@ int bcmf_sdio_thread(int argc, char **argv) } } - // TODO send all queued frames + /* Send all queued frames */ + + do + { + ret = bcmf_sdpcm_sendframe(priv); + } while (ret == OK); /* If we're done for now, turn off clock request. */ + // TODO add wakelock bcmf_sdio_bus_sleep(priv, true); } return 0; diff --git a/drivers/wireless/ieee80211/bcmf_sdio.h b/drivers/wireless/ieee80211/bcmf_sdio.h index bb66daca25..0645d23c92 100644 --- a/drivers/wireless/ieee80211/bcmf_sdio.h +++ b/drivers/wireless/ieee80211/bcmf_sdio.h @@ -24,4 +24,6 @@ int bcmf_read_reg(FAR struct bcmf_dev_s *priv, uint8_t function, int bcmf_write_reg(FAR struct bcmf_dev_s *priv, uint8_t function, uint32_t address, uint8_t reg); +int bcmf_sem_wait(sem_t *sem, unsigned int timeout_ms); + #endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_SDIO_H */ \ No newline at end of file diff --git a/drivers/wireless/ieee80211/bcmf_sdio_core.h b/drivers/wireless/ieee80211/bcmf_sdio_core.h index c6ad612c11..fa592adc9e 100644 --- a/drivers/wireless/ieee80211/bcmf_sdio_core.h +++ b/drivers/wireless/ieee80211/bcmf_sdio_core.h @@ -61,6 +61,10 @@ #define I_HMB_SW_MASK ( (uint32_t) 0x000000F0 ) #define I_HMB_FRAME_IND ( 1<<6 ) +#define CHIP_STA_INTERFACE 0 +#define CHIP_AP_INTERFACE 1 +#define CHIP_P2P_INTERFACE 2 + enum { CHIPCOMMON_CORE_ID, DOT11MAC_CORE_ID, diff --git a/drivers/wireless/ieee80211/bcmf_sdpcm.c b/drivers/wireless/ieee80211/bcmf_sdpcm.c index c7c3facc57..39d2f29e09 100644 --- a/drivers/wireless/ieee80211/bcmf_sdpcm.c +++ b/drivers/wireless/ieee80211/bcmf_sdpcm.c @@ -45,10 +45,18 @@ #include #include +#include +#include +#include #include "bcmf_sdio.h" #include "bcmf_core.h" #include "bcmf_sdpcm.h" +#include "bcmf_ioctl.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ /* SDA_FRAMECTRL */ #define SFC_RF_TERM (1 << 0) /* Read Frame Terminate */ @@ -57,25 +65,78 @@ #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_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 */ -/**************************************************************************** - * 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) + +#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_TIMEOUT_MS 1000 + +// TODO remove +void bcmf_hexdump(uint8_t *data, unsigned int len, unsigned long offset); /**************************************************************************** * Private Types ****************************************************************************/ +struct bcmf_sdpcm_header { + uint16_t size; + uint16_t checksum; + uint8_t sequence; + uint8_t channel; + uint8_t next_length; + uint8_t data_offset; + uint8_t flow_control; + uint8_t credit; + uint16_t padding; +}; + +struct bcmf_sdpcm_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 bcmf_sdpcm_frame { + dq_entry_t list_entry; + struct bcmf_sdpcm_header header; + uint8_t data[0]; +}; + +struct bcmf_sdpcm_cdc_dcmd { + dq_entry_t list_entry; + struct bcmf_sdpcm_header header; + struct bcmf_sdpcm_cdc_header cdc_header; + uint8_t data[0]; +}; + /**************************************************************************** * Private Function Prototypes ****************************************************************************/ static int bcmf_sdpcm_rxfail(FAR struct bcmf_dev_s *priv, bool retry); +static int bcmf_sdpcm_process_header(FAR struct bcmf_dev_s *priv, + struct bcmf_sdpcm_header *header); + /**************************************************************************** * Private Data ****************************************************************************/ @@ -105,19 +166,11 @@ int bcmf_sdpcm_rxfail(FAR struct bcmf_dev_s *priv, bool retry) return 0; } -/**************************************************************************** - * Public Functions - ****************************************************************************/ - int bcmf_sdpcm_process_header(FAR struct bcmf_dev_s *priv, struct bcmf_sdpcm_header *header) { - uint16_t len; - - len = header->frametag[0]; - if (header->data_offset < sizeof(struct bcmf_sdpcm_header) || - header->data_offset > len) + header->data_offset > header->size) { _err("Invalid data offset\n"); bcmf_sdpcm_rxfail(priv, false); @@ -142,6 +195,10 @@ int bcmf_sdpcm_process_header(FAR struct bcmf_dev_s *priv, return OK; } +/**************************************************************************** + * Public Functions + ****************************************************************************/ + // FIXME remove uint8_t tmp_buffer[512]; int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv) @@ -160,8 +217,8 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv) goto exit_abort; } - len = header->frametag[0]; - checksum = header->frametag[1]; + len = header->size; + checksum = header->checksum; /* All zero means no more to read */ @@ -194,6 +251,9 @@ int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv) goto exit_abort; } + _info("Receive frame\n"); + bcmf_hexdump((uint8_t*)header, len, (unsigned int)header); + /* Process and validate header */ ret = bcmf_sdpcm_process_header(priv, header); @@ -209,9 +269,242 @@ exit_abort: return ret; } -int bcmf_sdpcm_iovar_data_get(FAR struct bcmf_dev_s *priv, char *name, - void *data, unsigned int len) +int bcmf_sdpcm_sendframe(FAR struct bcmf_dev_s *priv) { - // TODO implement - return -EINVAL; + int ret; + struct bcmf_sdpcm_frame *frame; + + if (priv->tx_queue.tail == NULL) + { + /* No more frames to send */ + + return -ENODATA; + } + + if (priv->tx_seq == priv->max_seq) + { + // TODO handle this case + _err("No credit to send frame\n"); + return -EAGAIN; + } + + + if ((ret = sem_wait(&priv->tx_queue_mutex)) != OK) + { + return ret; + } + + frame = (struct bcmf_sdpcm_frame*)priv->tx_queue.tail; + + /* Set frame sequence id */ + + frame->header.sequence = priv->tx_seq++; + + _info("Send frame\n"); + bcmf_hexdump((uint8_t*)&frame->header, frame->header.size, + (unsigned int)&frame->header); + + ret = bcmf_transfer_bytes(priv, true, 2, 0, (uint8_t*)&frame->header, + frame->header.size); + if (ret != OK) + { + _info("fail send frame %d\n", ret); + ret = -EIO; + goto exit_abort; + // TODO handle retry count and remove frame from queue + abort TX + } + + /* Frame sent, remove it from queue */ + + if (priv->tx_queue.head == &frame->list_entry) + { + /* List is empty */ + + priv->tx_queue.head = NULL; + priv->tx_queue.tail = NULL; + } + else + { + priv->tx_queue.tail = frame->list_entry.blink; + frame->list_entry.blink->flink = priv->tx_queue.head; + } + + /* TODO free frame buffer */ + + goto exit_post_sem; + +exit_abort: + // bcmf_sdpcm_txfail(priv, false); +exit_post_sem: + sem_post(&priv->tx_queue_mutex); + return ret; } + +// FIXME remove +uint8_t tmp_buffer2[512]; +uint8_t* bcmf_sdpcm_allocate_iovar(FAR struct bcmf_dev_s *priv, char *name, + char *data, uint32_t *len) +{ + uint32_t data_len; + uint16_t name_len = strlen(name) + 1; + + if (!data) + { + data_len = 0; + } + else + { + data_len = *len; + } + + // FIXME allocate buffer and use max_size instead of 512 + if (data_len > 512-sizeof(struct bcmf_sdpcm_cdc_dcmd) || + (data_len + name_len) > 512-sizeof(struct bcmf_sdpcm_cdc_dcmd)) + { + *len = 0; + return NULL; + } + + // TODO allocate buffer + + /* Copy name string and data */ + + memcpy(tmp_buffer2+sizeof(struct bcmf_sdpcm_cdc_dcmd), name, name_len); + memcpy(tmp_buffer2+sizeof(struct bcmf_sdpcm_cdc_dcmd)+name_len, + data, data_len); + + *len = sizeof(struct bcmf_sdpcm_cdc_dcmd)+name_len+data_len; + return tmp_buffer2; +} + +int bcmf_sdpcm_queue_frame(FAR struct bcmf_dev_s *priv, uint8_t channel, + uint8_t *data, uint32_t len) +{ + int ret; + struct bcmf_sdpcm_frame *frame = (struct bcmf_sdpcm_frame*)data; + uint16_t frame_size = len - sizeof(frame->list_entry); + + /* Prepare sw header */ + + memset(&frame->header, 0, sizeof(struct bcmf_sdpcm_header)); + frame->header.size = frame_size; + frame->header.checksum = ~frame_size; + frame->header.channel = channel; + frame->header.data_offset = sizeof(struct bcmf_sdpcm_header); + + /* Add frame in tx queue */ + + if ((ret = sem_wait(&priv->tx_queue_mutex)) != OK) + { + return ret; + } + + if (priv->tx_queue.head == NULL) + { + /* List is empty */ + + priv->tx_queue.head = &frame->list_entry; + priv->tx_queue.tail = &frame->list_entry; + + frame->list_entry.flink = &frame->list_entry; + frame->list_entry.blink = &frame->list_entry; + } + else + { + /* Insert entry at list head */ + + frame->list_entry.flink = priv->tx_queue.head; + frame->list_entry.blink = priv->tx_queue.tail; + + priv->tx_queue.head->blink = &frame->list_entry; + priv->tx_queue.head = &frame->list_entry; + } + + sem_post(&priv->tx_queue_mutex); + + /* Notify bcmf thread tx frame is ready */ + + sem_post(&priv->thread_signal); + + return OK; +} + +int bcmf_sdpcm_send_dcmd(FAR struct bcmf_dev_s *priv, uint32_t cmd, + int ifidx, bool set, uint8_t *data, uint32_t len) +{ + struct bcmf_sdpcm_cdc_dcmd *msg = (struct bcmf_sdpcm_cdc_dcmd*)data; + + /* Setup cdc_dcmd header */ + + msg->cdc_header.cmd = cmd; + msg->cdc_header.len = len-sizeof(struct bcmf_sdpcm_cdc_dcmd); + msg->cdc_header.status = 0; + msg->cdc_header.flags = ++priv->control_reqid << CDC_DCMD_ID_SHIFT; + msg->cdc_header.flags |= ifidx << CDC_DCMD_IF_SHIFT; + + if (set) + { + msg->cdc_header.flags |= CDC_DCMD_SET; + } + + /* Queue frame */ + + return bcmf_sdpcm_queue_frame(priv, SDPCM_CONTROL_CHANNEL, data, len); +} + +int bcmf_sdpcm_iovar_request(FAR struct bcmf_dev_s *priv, + uint32_t ifidx, bool set, char *name, + char *data, uint32_t len) +{ + int ret; + uint8_t *iovar_buf; + uint32_t iovar_buf_len = len; + + /* Take device control mutex */ + + if ((ret = sem_wait(&priv->control_mutex)) !=OK) + { + return ret; + } + + /* Prepare control frame */ + + iovar_buf = bcmf_sdpcm_allocate_iovar(priv, name, data, &iovar_buf_len); + if (!iovar_buf) + { + _err("Cannot allocate iovar buf\n"); + ret = -ENOMEM; + goto exit_sem_post; + } + + /* Send control frame */ + + ret = bcmf_sdpcm_send_dcmd(priv, set ? WLC_SET_VAR : WLC_GET_VAR, + ifidx, set, iovar_buf, iovar_buf_len); + if (ret != OK) + { + goto exit_free_iovar; + } + + /* Wait for response */ + + ret = bcmf_sem_wait(&priv->control_timeout, SDPCM_CONTROL_TIMEOUT_MS); + if (ret != OK) + { + _err("Error while waiting for control response %d\n", ret); + goto exit_free_iovar; + } + + if (!set) + { + /* Request sent, copy received data back */ + + memcpy(data, iovar_buf+sizeof(struct bcmf_sdpcm_cdc_dcmd), len); + } + +exit_free_iovar: + // TODO free allocated buffer here +exit_sem_post: + sem_post(&priv->control_mutex); + return ret; +} \ No newline at end of file diff --git a/drivers/wireless/ieee80211/bcmf_sdpcm.h b/drivers/wireless/ieee80211/bcmf_sdpcm.h index 2f2844e651..537321e9fa 100644 --- a/drivers/wireless/ieee80211/bcmf_sdpcm.h +++ b/drivers/wireless/ieee80211/bcmf_sdpcm.h @@ -2,34 +2,13 @@ #define __DRIVERS_WIRELESS_IEEE80211_BCMF_SDPCM_H #include "bcmf_driver.h" -#include - -struct bcmf_sdpcm_header { - uint16_t frametag[2]; - uint8_t sequence; - uint8_t channel_flags; - uint8_t next_length; - uint8_t data_offset; - uint8_t flow_control; - uint8_t credit; - uint16_t padding; -}; - -struct bcmf_sdpcm_cdc_dcmd { - struct bcmf_sdpcm_header 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 */ -}; - -int bcmf_sdpcm_process_header(FAR struct bcmf_dev_s *priv, - struct bcmf_sdpcm_header *header); int bcmf_sdpcm_readframe(FAR struct bcmf_dev_s *priv); -int bcmf_sdpcm_iovar_data_get(FAR struct bcmf_dev_s *priv, char *name, - void *data, unsigned int len); +int bcmf_sdpcm_sendframe(FAR struct bcmf_dev_s *priv); + +int bcmf_sdpcm_iovar_request(FAR struct bcmf_dev_s *priv, + uint32_t ifidx, bool set, char *name, + char *data, uint32_t len); #endif /* __DRIVERS_WIRELESS_IEEE80211_BCMF_SDPCM_H */ \ No newline at end of file