wireless/ieee802154: Reworks data_ind allocation to include IOB allocation/deallocation. Hides private data.

This commit is contained in:
Anthony Merlino 2017-05-05 17:12:26 -04:00
parent e072069e2d
commit 1490599b69
7 changed files with 172 additions and 137 deletions

View File

@ -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).
*/

View File

@ -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

View File

@ -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 */

View File

@ -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.

View File

@ -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);

View File

@ -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
}

View File

@ -43,6 +43,9 @@
#include <string.h>
#include <nuttx/kmalloc.h>
#include <nuttx/drivers/iob.h>
#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
#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
}