diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c index 366471cd9c..14c9782777 100644 --- a/drivers/wireless/ieee802154/mrf24j40.c +++ b/drivers/wireless/ieee802154/mrf24j40.c @@ -1505,8 +1505,7 @@ static int mrf24j40_rxenable(FAR struct ieee802154_radio_s *radio, bool enable) static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev) { - FAR struct iob_s *iob; - struct ieee802154_rxdesc_s rxdesc; + FAR struct ieee802154_data_ind_s *ind; uint32_t addr; uint32_t index; uint8_t reg; @@ -1521,46 +1520,43 @@ static void mrf24j40_irqwork_rx(FAR struct mrf24j40_radio_s *dev) mrf24j40_setreg(dev->spi, MRF24J40_BBREG1, MRF24J40_BBREG1_RXDECINV); - /* Allocate an IOB to put the packet in */ + /* Allocate a data_ind to put the frame in */ - iob = iob_alloc(true); - DEBUGASSERT(iob != NULL); - - iob->io_flink = NULL; - iob->io_len = 0; - iob->io_offset = 0; - iob->io_pktlen = 0; + ind = ieee802154_ind_allocate(); + if (ind == NULL) + { + wlerr("ERROR: Unable to allocate data_ind. Discarding frame"); + goto done; + } /* Read packet */ addr = MRF24J40_RXBUF_BASE; - iob->io_len= mrf24j40_getreg(dev->spi, addr++); + ind->frame->io_len= mrf24j40_getreg(dev->spi, addr++); /* TODO: This needs to be changed. It is inefficient to do the SPI read byte * by byte */ - for (index = 0; index < iob->io_len; index++) + for (index = 0; index < ind->frame->io_len; index++) { - iob->io_data[index] = mrf24j40_getreg(dev->spi, addr++); + ind->frame->io_data[index] = mrf24j40_getreg(dev->spi, addr++); } - /* Copy meta-data into RX descriptor */ - - rxdesc.lqi = mrf24j40_getreg(dev->spi, addr++); - rxdesc.rssi = mrf24j40_getreg(dev->spi, addr++); + ind->lqi = mrf24j40_getreg(dev->spi, addr++); + ind->rssi = mrf24j40_getreg(dev->spi, addr++); /* Reduce len by 2, we only receive frames with correct crc, no check * required. */ - iob->io_len -= 2; + ind->frame->io_len -= 2; /* Callback the receiver in the next highest layer */ - dev->radiocb->rxframe(dev->radiocb, - (FAR const struct ieee802154_rxdesc_s *)&rxdesc, iob); + dev->radiocb->rxframe(dev->radiocb, ind); +done: /* Enable reception of next packet by flushing the fifo. * This is an MRF24J40 errata (no. 1). */ diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h b/include/nuttx/wireless/ieee802154/ieee802154_mac.h index b4583c2e3c..fc9818212e 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_mac.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h @@ -480,12 +480,6 @@ struct ieee802154_txdesc_s /* TODO: Add slotting information for GTS transactions */ }; -struct ieee802154_rxdesc_s -{ - uint8_t lqi; - uint8_t rssi; -}; - struct ieee802154_cca_s { uint8_t use_ed : 1; /* CCA using ED */ @@ -645,11 +639,13 @@ struct ieee802154_data_ind_s { FAR struct ieee802154_data_ind_s *flink; + FAR struct iob_s *frame; + struct ieee802154_addr_s src; /* Source addressing information */ struct ieee802154_addr_s dest; /* Destination addressing infromation */ uint8_t lqi; /* Link Quality Index */ + uint8_t rssi; /* Non-standard field */ uint8_t dsn; /* Data Sequence Number */ - uint8_t pool; /* Memory pool (Needed for deallocation) */ uint32_t timestamp; /* Time of received frame */ #ifdef CONFIG_IEEE802154_SECURITY diff --git a/include/nuttx/wireless/ieee802154/ieee802154_radio.h b/include/nuttx/wireless/ieee802154/ieee802154_radio.h index bfadc11023..fcbc7ec1b7 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_radio.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_radio.h @@ -71,8 +71,7 @@ struct ieee802154_radiocb_s CODE void (*txdone) (FAR const struct ieee802154_radiocb_s *radiocb, FAR const struct ieee802154_txdesc_s *tx_desc); CODE void (*rxframe) (FAR const struct ieee802154_radiocb_s *radiocb, - FAR const struct ieee802154_rxdesc_s *rx_desc, - FAR struct iob_s *frame); + FAR struct ieee802154_data_ind_s *ind); }; struct ieee802154_radio_s; /* Forward reference */ diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig index 77f194d6ef..ff64c06d84 100644 --- a/wireless/ieee802154/Kconfig +++ b/wireless/ieee802154/Kconfig @@ -79,13 +79,13 @@ config IEEE802154_IND_IRQRESERVE In that case, the allocation will fail if tasking logic has allocated them all. - Interrupt logic will first attempt to allocate fromt the general, + Interrupt logic will first attempt to allocate from the general, pre-allocated structure pool that will contain up to (size CONFIG_IEEE802154_IND_PREALLOC - CONFIG_IEEE802154_IND_IRQRESERVE) entries. If that fails, then it will try to take a structure from the reserve (size CONFIG_IEEE802154_IND_IRQRESERVE). - Non-interrupt logic will also first attempt to allocate fromt the + Non-interrupt logic will also first attempt to allocate from the general, pre-allocated structure pool. If that fails, it will dynamically allocate the meta data structure with an additional cost in performance. diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index f954fd9046..127eae9d4f 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -84,11 +84,11 @@ * Private Types ****************************************************************************/ -struct mac802154_trans_s +struct mac802154_txframe_s { /* Supports a singly linked list */ - FAR struct mac802154_trans_s *flink; + FAR struct mac802154_txframe_s *flink; FAR struct iob_s *frame; uint8_t msdu_handle; sem_t sem; @@ -132,8 +132,8 @@ struct ieee802154_privmac_s * during the CAP of the Coordinator's superframe. */ - FAR struct mac802154_trans_s *csma_head; - FAR struct mac802154_trans_s *csma_tail; + FAR struct mac802154_txframe_s *csma_head; + FAR struct mac802154_txframe_s *csma_tail; /* Support a singly linked list of transactions that will be sent indirectly. * This list should only be used by a MAC acting as a coordinator. These @@ -143,15 +143,15 @@ struct ieee802154_privmac_s * beacon frame. */ - FAR struct mac802154_trans_s *indirect_head; - FAR struct mac802154_trans_s *indirect_tail; + FAR struct mac802154_txframe_s *indirect_head; + FAR struct mac802154_txframe_s *indirect_tail; uint8_t txdesc_count; struct ieee802154_txdesc_s txdesc[CONFIG_IEEE802154_NTXDESC]; /* Support a singly linked list of frames received */ - FAR struct iob_s *rxframes_head; - FAR struct iob_s *rxframes_tail; + FAR struct ieee802154_data_ind_s *rxframes_head; + FAR struct ieee802154_data_ind_s *rxframes_tail; /* MAC PIB attributes, grouped to save memory */ @@ -297,8 +297,7 @@ static void mac802154_txdone(FAR const struct ieee802154_radiocb_s *radiocb, FAR const struct ieee802154_txdesc_s *tx_desc); static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb, - FAR const struct ieee802154_rxdesc_s *rx_desc, - FAR struct iob_s *frame); + FAR struct ieee802154_data_ind_s *ind); /**************************************************************************** * Private Data @@ -345,7 +344,7 @@ static inline int mac802154_takesem(sem_t *sem) ****************************************************************************/ static void mac802154_push_csma(FAR struct ieee802154_privmac_s *priv, - FAR struct mac802154_trans_s *trans) + FAR struct mac802154_txframe_s *trans) { /* Ensure the transactions forward link is NULL */ @@ -380,10 +379,10 @@ static void mac802154_push_csma(FAR struct ieee802154_privmac_s *priv, * ****************************************************************************/ -static FAR struct mac802154_trans_s * +static FAR struct mac802154_txframe_s * mac802154_pop_csma(FAR struct ieee802154_privmac_s *priv) { - FAR struct mac802154_trans_s *trans; + FAR struct mac802154_txframe_s *trans; if (priv->csma_head == NULL) { @@ -510,7 +509,7 @@ static int mac802154_poll_csma(FAR const struct ieee802154_radiocb_s *radiocb, FAR struct mac802154_radiocb_s *cb = (FAR struct mac802154_radiocb_s *)radiocb; FAR struct ieee802154_privmac_s *priv; - FAR struct mac802154_trans_s *trans; + FAR struct mac802154_txframe_s *trans; DEBUGASSERT(cb != NULL && cb->priv != NULL); priv = cb->priv; @@ -564,7 +563,7 @@ static int mac802154_poll_gts(FAR const struct ieee802154_radiocb_s *radiocb, FAR struct mac802154_radiocb_s *cb = (FAR struct mac802154_radiocb_s *)radiocb; FAR struct ieee802154_privmac_s *priv; - FAR struct mac802154_trans_s *trans; + FAR struct mac802154_txframe_s *trans; int ret = 0; DEBUGASSERT(cb != NULL && cb->priv != NULL); @@ -691,13 +690,11 @@ static void mac802154_txdone_worker(FAR void *arg) ****************************************************************************/ static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb, - FAR const struct ieee802154_rxdesc_s *rx_desc, - FAR struct iob_s *frame) + FAR struct ieee802154_data_ind_s *ind) { FAR struct mac802154_radiocb_s *cb = (FAR struct mac802154_radiocb_s *)radiocb; FAR struct ieee802154_privmac_s *priv; - FAR struct ieee802154_rxdesc_s *desc; DEBUGASSERT(cb != NULL && cb->priv != NULL); priv = cb->priv; @@ -708,12 +705,10 @@ static void mac802154_rxframe(FAR const struct ieee802154_radiocb_s *radiocb, while (mac802154_takesem(&priv->exclsem) != 0); - /* TODO: Copy the frame descriptor to some type of list */ - /* Push the iob onto the tail of the frame list for processing */ - priv->rxframes_tail->io_flink = frame; - priv->rxframes_tail = frame; + priv->rxframes_tail->flink = ind; + priv->rxframes_tail = ind; mac802154_givesem(&priv->exclsem); @@ -1050,7 +1045,7 @@ int mac802154_req_data(MACHANDLE mac, { FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; - FAR struct mac802154_trans_s trans; + FAR struct mac802154_txframe_s trans; uint16_t *frame_ctrl; uint8_t mhr_len = 3; /* Start assuming frame control and seq. num */ int ret; @@ -1606,67 +1601,3 @@ int mac802154_resp_orphan(MACHANDLE mac, return -ENOTTY; } -/**************************************************************************** - * Name: ieee802154_indpool_initialize - * - * Description: - * This function initializes the meta-data allocator. This function must - * be called early in the initialization sequence before any radios - * begin operation. - * - * Inputs: - * None - * - * Return Value: - * None - * - ****************************************************************************/ - -void ieee802154_indpool_initialize(void); - -/**************************************************************************** - * Name: ieee802154_ind_allocate - * - * Description: - * The ieee802154_ind_allocate function will get a free meta-data - * structure for use by the IEEE 802.15.4 MAC. - * - * Interrupt handling logic will first attempt to allocate from the - * g_indfree list. If that list is empty, it will attempt to allocate - * from its reserve, g_indfree_irq. If that list is empty, then the - * allocation fails (NULL is returned). - * - * Non-interrupt handler logic will attempt to allocate from g_indfree - * list. If that the list is empty, then the meta-data structure will be - * allocated from the dynamic memory pool. - * - * Inputs: - * None - * - * Return Value: - * A reference to the allocated msg structure. All user fields in this - * structure have been zeroed. On a failure to allocate, NULL is - * returned. - * - ****************************************************************************/ - -FAR struct ieee802154_data_ind_s *ieee802154_ind_allocate(void); - -/**************************************************************************** - * Name: ieee802154_ind_free - * - * Description: - * The ieee802154_ind_free function will return a meta-data structure to - * the free pool of messages if it was a pre-allocated meta-data - * structure. If the meta-data structure was allocated dynamically it will - * be deallocated. - * - * Inputs: - * ind - meta-data structure to free - * - * Return Value: - * None - * - ****************************************************************************/ - -void ieee802154_ind_free(FAR struct ieee802154_data_ind_s *ind); diff --git a/wireless/ieee802154/mac802154.h b/wireless/ieee802154/mac802154.h index 152046b61f..45f9c3a729 100644 --- a/wireless/ieee802154/mac802154.h +++ b/wireless/ieee802154/mac802154.h @@ -336,6 +336,71 @@ int mac802154_resp_associate(MACHANDLE mac, int mac802154_resp_orphan(MACHANDLE mac, FAR struct ieee802154_orphan_resp_s *resp); +/**************************************************************************** + * Name: ieee802154_indpool_initialize + * + * Description: + * This function initializes the meta-data allocator. This function must + * be called early in the initialization sequence before any radios + * begin operation. + * + * Inputs: + * None + * + * Return Value: + * None + * + ****************************************************************************/ + +void ieee802154_indpool_initialize(void); + +/**************************************************************************** + * Name: ieee802154_ind_allocate + * + * Description: + * The ieee802154_ind_allocate function will get a free meta-data + * structure for use by the IEEE 802.15.4 MAC. + * + * Interrupt handling logic will first attempt to allocate from the + * g_indfree list. If that list is empty, it will attempt to allocate + * from its reserve, g_indfree_irq. If that list is empty, then the + * allocation fails (NULL is returned). + * + * Non-interrupt handler logic will attempt to allocate from g_indfree + * list. If that the list is empty, then the meta-data structure will be + * allocated from the dynamic memory pool. + * + * Inputs: + * None + * + * Return Value: + * A reference to the allocated msg structure. All user fields in this + * structure have been zeroed. On a failure to allocate, NULL is + * returned. + * + ****************************************************************************/ + +FAR struct ieee802154_data_ind_s *ieee802154_ind_allocate(void); + +/**************************************************************************** + * Name: ieee802154_ind_free + * + * Description: + * The ieee802154_ind_free function will return a meta-data structure to + * the free pool of messages if it was a pre-allocated meta-data + * structure. If the meta-data structure was allocated dynamically it will + * be deallocated. + * + * Inputs: + * ind - meta-data structure to free + * + * Return Value: + * None + * + ****************************************************************************/ + +void ieee802154_ind_free(FAR struct ieee802154_data_ind_s *ind); + #undef EXTERN #ifdef __cplusplus } diff --git a/wireless/ieee802154/mac802154_indalloc.c b/wireless/ieee802154/mac802154_indalloc.c index 86d8dcd0ef..5e05c5c09e 100644 --- a/wireless/ieee802154/mac802154_indalloc.c +++ b/wireless/ieee802154/mac802154_indalloc.c @@ -43,6 +43,9 @@ #include #include + +#include + #include #include "mac802154.h" @@ -72,6 +75,21 @@ #define POOL_IND_IRQ 1 #define POOL_IND_DYNAMIC 2 +/**************************************************************************** + * Private Data Types + ****************************************************************************/ + +/* Private data type that extends the ieee802154_data_ind_s struct */ + +struct ieee802154_priv_ind_s +{ + /* Must be first member so we can cast to/from */ + + struct ieee802154_data_ind_s pub; + FAR struct ieee802154_priv_ind_s *flink; + uint8_t pool; +}; + /**************************************************************************** * Private Data ****************************************************************************/ @@ -83,7 +101,7 @@ * item. */ -static struct ieee802154_data_ind_s *g_indfree; +static struct ieee802154_priv_ind_s *g_indfree; #endif #if CONFIG_IEEE802154_IND_IRQRESERVE > 0 @@ -91,12 +109,12 @@ static struct ieee802154_data_ind_s *g_indfree; * use by only by interrupt handlers. */ -static struct ieee802154_data_ind_s *g_indfree_irq; +static struct ieee802154_priv_ind_s *g_indfree_irq; #endif /* Pool of pre-allocated meta-data stuctures */ -static struct ieee802154_data_ind_s g_indpool[CONFIG_IEEE802154_IND_PREALLOC]; +static struct ieee802154_priv_ind_s g_indpool[CONFIG_IEEE802154_IND_PREALLOC]; #endif /* CONFIG_IEEE802154_IND_PREALLOC > 0 */ /**************************************************************************** @@ -122,7 +140,7 @@ static struct ieee802154_data_ind_s g_indpool[CONFIG_IEEE802154_IND_PREALLOC]; void ieee802154_indpool_initialize(void) { #if CONFIG_IEEE802154_IND_PREALLOC > 0 - FAR struct ieee802154_data_ind_s *pool = g_indpool; + FAR struct ieee802154_priv_ind_s *pool = g_indpool; int remaining = CONFIG_IEEE802154_IND_PREALLOC; #if CONFIG_IEEE802154_IND_PREALLOC > CONFIG_IEEE802154_IND_IRQRESERVE @@ -133,7 +151,7 @@ void ieee802154_indpool_initialize(void) g_indfree = NULL; while (remaining > CONFIG_IEEE802154_IND_IRQRESERVE) { - FAR struct ieee802154_data_ind_s *ind = pool; + FAR struct ieee802154_priv_ind_s *ind = pool; /* Add the next meta data structure from the pool to the list of * general structures. @@ -157,7 +175,7 @@ void ieee802154_indpool_initialize(void) g_indfree_irq = NULL; while (remaining > 0) { - FAR struct ieee802154_data_ind_s *ind = pool; + FAR struct ieee802154_priv_ind_s *ind = pool; /* Add the next meta data structure from the pool to the list of * general structures. @@ -204,7 +222,7 @@ void ieee802154_indpool_initialize(void) FAR struct ieee802154_data_ind_s *ieee802154_ind_allocate(void) { #if CONFIG_IEEE802154_IND_PREALLOC > 0 - FAR struct ieee802154_data_ind_s *ind; + FAR struct ieee802154_priv_ind_s *ind; irqstate_t flags; uint8_t pool; @@ -271,8 +289,8 @@ FAR struct ieee802154_data_ind_s *ieee802154_ind_allocate(void) */ leave_critical_section(flags); - ind = (FAR struct ieee802154_data_ind_s *) - kmm_malloc((sizeof (struct ieee802154_data_ind_s))); + ind = (FAR struct ieee802154_priv_ind_s *) + kmm_malloc((sizeof (struct ieee802154_priv_ind_s))); /* Check if we allocated the meta-data structure */ @@ -289,9 +307,27 @@ FAR struct ieee802154_data_ind_s *ieee802154_ind_allocate(void) * Zero and tag the alloated meta-data structure. */ - memset(ind, 0, sizeof(struct ieee802154_data_ind_s)); ind->pool = pool; - return ind; + memset(&ind->pub, 0, sizeof(struct ieee802154_data_ind_s)); + + /* Allocate the IOB for the frame */ + + ind->pub.frame = iob_alloc(true); + if (ind->pub.frame == NULL) + { + /* Deallocate the ind */ + + ieee802154_ind_free(&ind->pub); + + return NULL; + } + + ind->pub.frame->io_flink = NULL; + ind->pub.frame->io_len = 0; + ind->pub.frame->io_offset = 0; + ind->pub.frame->io_pktlen = 0; + + return &ind->pub; #else return NULL; #endif @@ -318,21 +354,33 @@ void ieee802154_ind_free(FAR struct ieee802154_data_ind_s *ind) { #if CONFIG_IEEE802154_IND_PREALLOC > 0 irqstate_t flags; + FAR struct ieee802154_priv_ind_s *priv = + (FAR struct ieee802154_priv_ind_s *)ind; + + /* Check if the IOB is not NULL. The only time it should be NULL is if we + * allocated the data_ind, but the IOB allocation failed so we now have to + * free the data_ind but not the IOB. This really should happen rarely if at all. + */ + + if (ind->frame != NULL) + { + iob_free(ind->frame); + } #if CONFIG_IEEE802154_IND_PREALLOC > CONFIG_IEEE802154_IND_IRQRESERVE /* If this is a generally available pre-allocated meta-data structure, * then just put it back in the free list. */ - if (ind->pool == POOL_IND_GENERAL) + if (priv->pool == POOL_IND_GENERAL) { /* Make sure we avoid concurrent access to the free * list from interrupt handlers. */ flags = enter_critical_section(); - ind->flink = g_indfree; - g_indfree = ind; + priv->flink = g_indfree; + g_indfree = priv; leave_critical_section(flags); } else @@ -343,15 +391,15 @@ void ieee802154_ind_free(FAR struct ieee802154_data_ind_s *ind) * then put it back in the correct free list. */ - if (ind->pool == POOL_IND_IRQ) + if (priv->pool == POOL_IND_IRQ) { /* Make sure we avoid concurrent access to the free * list from interrupt handlers. */ flags = enter_critical_section(); - ind->flink = g_indfree_irq; - g_indfree_irq = ind; + priv->flink = g_indfree_irq; + g_indfree_irq = priv; leave_critical_section(flags); } else @@ -360,8 +408,8 @@ void ieee802154_ind_free(FAR struct ieee802154_data_ind_s *ind) { /* Otherwise, deallocate it. */ - DEBUGASSERT(ind->pool == POOL_IND_DYNAMIC); - sched_kfree(ind); + DEBUGASSERT(priv->pool == POOL_IND_DYNAMIC); + sched_kfree(priv); } #endif }