Merged in merlin17/nuttx/ieee802154 (pull request #331)
wireless/ieee802154: Simplifies TX completion interface. Documents and cleans up some functions Approved-by: Gregory Nutt <gnutt@nuttx.org>
This commit is contained in:
commit
a31b555b72
@ -1520,7 +1520,7 @@ static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev)
|
||||
|
||||
/* Inform the next layer of the transmission success/failure */
|
||||
|
||||
dev->radiocb->txdone_csma(dev->radiocb, &dev->csma_desc.pub);
|
||||
dev->radiocb->txdone(dev->radiocb, &dev->csma_desc.pub);
|
||||
|
||||
/* We are now done with the transaction */
|
||||
|
||||
@ -1566,7 +1566,7 @@ static void mrf24j40_irqwork_txgts(FAR struct mrf24j40_radio_s *dev,
|
||||
|
||||
/* Inform the next layer of the transmission success/failure */
|
||||
|
||||
dev->radiocb->txdone_gts(dev->radiocb, &dev->gts_desc[gts].pub);
|
||||
dev->radiocb->txdone(dev->radiocb, &dev->gts_desc[gts].pub);
|
||||
|
||||
/* We are now done with the transaction */
|
||||
|
||||
|
@ -180,9 +180,7 @@ struct ieee802154_radiocb_s
|
||||
FAR struct ieee802154_txdesc_s *tx_desc, FAR uint8_t *buf);
|
||||
CODE int (*poll_gts) (FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc, FAR uint8_t *buf);
|
||||
CODE int (*txdone_csma) (FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR const struct ieee802154_txdesc_s *tx_desc);
|
||||
CODE int (*txdone_gts) (FAR struct ieee802154_radiocb_s *radiocb,
|
||||
CODE int (*txdone) (FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR const struct ieee802154_txdesc_s *tx_desc);
|
||||
CODE int (*rx_frame) (FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR const struct ieee8021254_rxdesc_s *rx_desc,
|
||||
|
@ -105,6 +105,9 @@ struct ieee802154_privmac_s
|
||||
|
||||
sem_t exclsem; /* Support exclusive access */
|
||||
|
||||
struct work_s tx_work;
|
||||
struct work_s rx_work;
|
||||
|
||||
/* Support a singly linked list of transactions that will be sent using the
|
||||
* CSMA algorithm. On a non-beacon enabled PAN, these transactions will be
|
||||
* sent whenever. On a beacon-enabled PAN, these transactions will be sent
|
||||
@ -125,6 +128,10 @@ struct ieee802154_privmac_s
|
||||
FAR struct mac802154_trans_s *indirect_head;
|
||||
FAR struct mac802154_trans_s *indirect_tail;
|
||||
|
||||
FAR struct ieee802154_txdesc_s *txhead; /* Next TX descriptor to handle */
|
||||
FAR struct ieee802154_txdesc_s *txtail; /* Location to push TX descriptor */
|
||||
struct ieee802154_txdesc_s txtable[CONFIG_IEEE802154_NTXDESC];
|
||||
|
||||
/* MAC PIB attributes, grouped to save memory */
|
||||
|
||||
/* Holds all address information (Extended, Short, and PAN ID) for the MAC. */
|
||||
@ -262,6 +269,9 @@ static int mac802154_poll_gts(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc,
|
||||
FAR uint8_t *buf);
|
||||
|
||||
static int mac802154_txdone(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@ -325,6 +335,258 @@ static int mac802154_applymib(FAR struct ieee802154_privmac_s *priv)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_poll_csma
|
||||
*
|
||||
* Description:
|
||||
* Called from the radio driver through the callback struct. This function is
|
||||
* called when the radio has room for another CSMA transaction. If the MAC
|
||||
* layer has a CSMA transaction, it copies it into the supplied buffer and
|
||||
* returns the length. A descriptor is also populated with the transaction.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mac802154_poll_csma(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc,
|
||||
FAR uint8_t *buf)
|
||||
{
|
||||
FAR struct mac802154_radiocb_s *cb =
|
||||
(FAR struct mac802154_radiocb_s *)radiocb;
|
||||
FAR struct ieee802154_privmac_s *priv;
|
||||
FAR struct mac802154_trans_s *trans;
|
||||
|
||||
DEBUGASSERT(cb != NULL && cb->priv != NULL);
|
||||
priv = cb->priv;
|
||||
|
||||
/* Get exclusive access to the driver structure. We don't care about any
|
||||
* signals so if we see one, just go back to trying to get access again.
|
||||
*/
|
||||
|
||||
while (mac802154_takesem(&priv->exclsem) != 0);
|
||||
|
||||
/* Check to see if there are any CSMA transactions waiting */
|
||||
|
||||
if (priv->csma_head)
|
||||
{
|
||||
/* Pop a CSMA transaction off the list */
|
||||
|
||||
trans = priv->csma_head;
|
||||
priv->csma_head = priv->csma_head->flink;
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
/* Setup the transmit descriptor */
|
||||
|
||||
tx_desc->psdu_handle = trans->msdu_handle;
|
||||
tx_desc->psdu_length = trans->mhr_len + trans->d_len;
|
||||
|
||||
/* Copy the frame into the buffer */
|
||||
|
||||
memcpy(&buf[0], trans->mhr_buf, trans->mhr_len);
|
||||
memcpy(&buf[trans->mhr_len], trans->d_buf, trans->d_len);
|
||||
|
||||
/* Now that we've passed off the data, notify the waiting thread.
|
||||
* NOTE: The transaction was allocated on the waiting thread's stack so
|
||||
* it will be automatically deallocated when that thread awakens and
|
||||
* returns.
|
||||
*/
|
||||
|
||||
sem_post(&trans->sem);
|
||||
return tx_desc->psdu_length;
|
||||
}
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_poll_gts
|
||||
*
|
||||
* Description:
|
||||
* Called from the radio driver through the callback struct. This function is
|
||||
* called when the radio has room for another GTS transaction. If the MAC
|
||||
* layer has a GTS transaction, it copies it into the supplied buffer and
|
||||
* returns the length. A descriptor is also populated with the transaction.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mac802154_poll_gts(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc,
|
||||
FAR uint8_t *buf)
|
||||
{
|
||||
FAR struct mac802154_radiocb_s *cb =
|
||||
(FAR struct mac802154_radiocb_s *)radiocb;
|
||||
FAR struct ieee802154_privmac_s *priv;
|
||||
FAR struct mac802154_trans_s *trans;
|
||||
int ret = 0;
|
||||
|
||||
DEBUGASSERT(cb != NULL && cb->priv != NULL);
|
||||
priv = cb->priv;
|
||||
|
||||
/* Get exclusive access to the driver structure. We don't care about any
|
||||
* signals so if we see one, just go back to trying to get access again.
|
||||
*/
|
||||
|
||||
while (mac802154_takesem(&priv->exclsem) != 0);
|
||||
|
||||
#warning Missing logic.
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_txdone
|
||||
*
|
||||
* Description:
|
||||
* Called from the radio driver through the callback struct. This function is
|
||||
* called when the radio has completed a transaction. The txdesc passed gives
|
||||
* provides information about the completed transaction including the original
|
||||
* handle provided when the transaction was created and the status of the
|
||||
* transaction. This function copies the descriptor and schedules work to
|
||||
* handle the transaction without blocking the radio.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int mac802154_txdone(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR const struct ieee802154_txdesc_s *tx_desc)
|
||||
{
|
||||
FAR struct mac802154_radiocb_s *cb =
|
||||
(FAR struct mac802154_radiocb_s *)radiocb;
|
||||
FAR struct ieee802154_privmac_s *priv;
|
||||
FAR struct ieee802154_txdesc_s *desc;
|
||||
int ret = 0;
|
||||
|
||||
DEBUGASSERT(cb != NULL && cb->priv != NULL);
|
||||
priv = cb->priv;
|
||||
|
||||
/* Get exclusive access to the driver structure. We don't care about any
|
||||
* signals so if we see one, just go back to trying to get access again.
|
||||
*/
|
||||
|
||||
while (mac802154_takesem(&priv->exclsem) != 0);
|
||||
|
||||
/* Allocate a tx_desc */
|
||||
|
||||
desc = kmm_zalloc(sizeof(struct ieee802154_txdesc_s));
|
||||
if (desc == NULL)
|
||||
{
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Copy the txdesc over and link it into our list */
|
||||
|
||||
memcpy(desc, tx_desc, sizeof(ieee802154_txdesc_s));
|
||||
|
||||
/* Link the descriptor */
|
||||
|
||||
#warning Missing Logic!
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
/* Schedule work with the work queue to process the completion further */
|
||||
|
||||
if (work_available(&priv->tx_work))
|
||||
{
|
||||
work_queue(MAC802154_WORK, &priv->tx_work, mac802154_txdone_worker,
|
||||
(FAR void *)dev, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_txdone_worker
|
||||
*
|
||||
* Description:
|
||||
* Worker function scheduled from mac802154_txdone. This function pops any
|
||||
* TX descriptors off of the list and calls the next highest layers callback
|
||||
* to inform the layer of the completed transaction and the status of it.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mac802154_txdone_worker(FAR void *arg)
|
||||
{
|
||||
FAR struct ieee802154_privmanc_s *priv =
|
||||
(FAR struct ieee802154_privmanc_s *)arg;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_rxframe
|
||||
*
|
||||
* Description:
|
||||
* Called from the radio driver through the callback struct. This function is
|
||||
* called when the radio has received a frame. The frame is passed in an iob,
|
||||
* so that we can free it when we are done processing. A pointer to the RX
|
||||
* descriptor is passed along with the iob, but it must be copied here as it
|
||||
* is allocated directly on the caller's stack. We simply link the frame,
|
||||
* copy the RX descriptor, and schedule a worker to process the frame later so
|
||||
* that we do not hold up the radio.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mac802154_rxframe(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_rxdesc_s *rx_desc,
|
||||
FAR struct iob_s *frame)
|
||||
{
|
||||
FAR struct mac802154_radiocb_s *cb =
|
||||
(FAR struct mac802154_radiocb_s *)radiocb;
|
||||
FAR struct ieee802154_privmac_s *priv;
|
||||
FAR struct ieee802154_txdesc_s *desc;
|
||||
int ret = 0;
|
||||
|
||||
DEBUGASSERT(cb != NULL && cb->priv != NULL);
|
||||
priv = cb->priv;
|
||||
|
||||
/* Get exclusive access to the driver structure. We don't care about any
|
||||
* signals so if we see one, just go back to trying to get access again.
|
||||
*/
|
||||
|
||||
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 = iob;
|
||||
priv->rxframes_tail = iob;
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
/* Schedule work with the work queue to process the completion further */
|
||||
|
||||
if (work_available(&priv->rx_work))
|
||||
{
|
||||
work_queue(MAC802154_WORK, &priv->rx_work, mac802154_rxframe_worker,
|
||||
(FAR void *)priv, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_rxframe_worker
|
||||
*
|
||||
* Description:
|
||||
* Worker function scheduled from mac802154_rxframe. This function processes
|
||||
* any frames in the list. Frames intended to be consumed by the MAC layer
|
||||
* will not produce any callbacks to the next highest layer. Frames intended
|
||||
* for the application layer will be forwarded to them.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mac802154_rxframe_worker(FAR void *arg)
|
||||
{
|
||||
FAR struct ieee802154_privmac_s *priv =
|
||||
(FAR struct ieee802154_privmac_s *)arg;
|
||||
|
||||
/* The radio layer is responsible for handling all ACKs and retries. If for
|
||||
* some reason an ACK gets here, just throw it out */
|
||||
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -379,9 +641,10 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
||||
|
||||
mac->radiocb.priv = mac;
|
||||
|
||||
radiocb = &mac->radiocb.cb;
|
||||
radiocb->poll_csma = mac802154_poll_csma;
|
||||
radiocb->poll_gts = mac802154_poll_gts;
|
||||
radiocb = &mac->radiocb.cb;
|
||||
radiocb->poll_csma = mac802154_poll_csma;
|
||||
radiocb->poll_gts = mac802154_poll_gts;
|
||||
radiocb->txdone = mac802154_txdone;
|
||||
|
||||
/* Bind our callback structure */
|
||||
|
||||
@ -710,87 +973,6 @@ int mac802154_req_data(MACHANDLE mac, FAR struct ieee802154_data_req_s *req)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Called from interrupt level or worker thread with interrupts disabled */
|
||||
|
||||
static int mac802154_poll_csma(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc,
|
||||
FAR uint8_t *buf)
|
||||
{
|
||||
FAR struct mac802154_radiocb_s *cb =
|
||||
(FAR struct mac802154_radiocb_s *)radiocb;
|
||||
FAR struct ieee802154_privmac_s *priv;
|
||||
FAR struct mac802154_trans_s *trans;
|
||||
int ret = 0;
|
||||
|
||||
DEBUGASSERT(cb != NULL && cb->priv != NULL);
|
||||
priv = cb->priv;
|
||||
|
||||
/* Get exclusive access to the driver structure. We don't care about any
|
||||
* signals so if we see one, just go back to trying to get access again.
|
||||
*/
|
||||
|
||||
while (mac802154_takesem(&priv->exclsem) != 0);
|
||||
|
||||
/* Check to see if there are any CSMA transactions waiting */
|
||||
|
||||
if (priv->csma_head)
|
||||
{
|
||||
/* Pop a CSMA transaction off the list */
|
||||
|
||||
trans = priv->csma_head;
|
||||
priv->csma_head = priv->csma_head->flink;
|
||||
|
||||
/* Setup the transmit descriptor */
|
||||
|
||||
tx_desc->psdu_handle = trans->msdu_handle;
|
||||
tx_desc->psdu_length = trans->mhr_len + trans->d_len;
|
||||
|
||||
/* Copy the frame into the buffer */
|
||||
|
||||
memcpy(&buf[0], trans->mhr_buf, trans->mhr_len);
|
||||
memcpy(&buf[trans->mhr_len], trans->d_buf, trans->d_len);
|
||||
|
||||
/* Now that we've passed off the data, notify the waiting thread.
|
||||
* NOTE: The transaction was allocated on the waiting thread's stack so
|
||||
* it will be automatically deallocated when that thread awakens and
|
||||
* returns.
|
||||
*/
|
||||
|
||||
sem_post(&trans->sem);
|
||||
|
||||
ret = tx_desc->psdu_length;
|
||||
}
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mac802154_poll_gts(FAR struct ieee802154_radiocb_s *radiocb,
|
||||
FAR struct ieee802154_txdesc_s *tx_desc,
|
||||
FAR uint8_t *buf)
|
||||
{
|
||||
FAR struct mac802154_radiocb_s *cb =
|
||||
(FAR struct mac802154_radiocb_s *)radiocb;
|
||||
FAR struct ieee802154_privmac_s *priv;
|
||||
FAR struct mac802154_trans_s *trans;
|
||||
int ret = 0;
|
||||
|
||||
DEBUGASSERT(cb != NULL && cb->priv != NULL);
|
||||
priv = cb->priv;
|
||||
|
||||
/* Get exclusive access to the driver structure. We don't care about any
|
||||
* signals so if we see one, just go back to trying to get access again.
|
||||
*/
|
||||
|
||||
while (mac802154_takesem(&priv->exclsem) != 0);
|
||||
|
||||
#warning Missing logic.
|
||||
|
||||
mac802154_givesem(&priv->exclsem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mac802154_req_purge
|
||||
|
Loading…
Reference in New Issue
Block a user