wireless/ieee802154: Simplifies TX completion interface. Documents and cleans up some functions
This commit is contained in:
parent
c071cde220
commit
b1c8f008d6
@ -1520,7 +1520,7 @@ static void mrf24j40_irqwork_txnorm(FAR struct mrf24j40_radio_s *dev)
|
|||||||
|
|
||||||
/* Inform the next layer of the transmission success/failure */
|
/* 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 */
|
/* 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 */
|
/* 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 */
|
/* 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);
|
FAR struct ieee802154_txdesc_s *tx_desc, FAR uint8_t *buf);
|
||||||
CODE int (*poll_gts) (FAR struct ieee802154_radiocb_s *radiocb,
|
CODE int (*poll_gts) (FAR struct ieee802154_radiocb_s *radiocb,
|
||||||
FAR struct ieee802154_txdesc_s *tx_desc, FAR uint8_t *buf);
|
FAR struct ieee802154_txdesc_s *tx_desc, FAR uint8_t *buf);
|
||||||
CODE int (*txdone_csma) (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 (*txdone_gts) (FAR struct ieee802154_radiocb_s *radiocb,
|
|
||||||
FAR const struct ieee802154_txdesc_s *tx_desc);
|
FAR const struct ieee802154_txdesc_s *tx_desc);
|
||||||
CODE int (*rx_frame) (FAR struct ieee802154_radiocb_s *radiocb,
|
CODE int (*rx_frame) (FAR struct ieee802154_radiocb_s *radiocb,
|
||||||
FAR const struct ieee8021254_rxdesc_s *rx_desc,
|
FAR const struct ieee8021254_rxdesc_s *rx_desc,
|
||||||
|
@ -105,6 +105,9 @@ struct ieee802154_privmac_s
|
|||||||
|
|
||||||
sem_t exclsem; /* Support exclusive access */
|
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
|
/* 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
|
* CSMA algorithm. On a non-beacon enabled PAN, these transactions will be
|
||||||
* sent whenever. On a beacon-enabled PAN, these transactions will be sent
|
* 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_head;
|
||||||
FAR struct mac802154_trans_s *indirect_tail;
|
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 */
|
/* MAC PIB attributes, grouped to save memory */
|
||||||
|
|
||||||
/* Holds all address information (Extended, Short, and PAN ID) for the MAC. */
|
/* 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 struct ieee802154_txdesc_s *tx_desc,
|
||||||
FAR uint8_t *buf);
|
FAR uint8_t *buf);
|
||||||
|
|
||||||
|
static int mac802154_txdone(FAR struct ieee802154_radiocb_s *radiocb,
|
||||||
|
FAR struct ieee802154_txdesc_s *tx_desc);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -325,6 +335,258 @@ static int mac802154_applymib(FAR struct ieee802154_privmac_s *priv)
|
|||||||
return OK;
|
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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -382,6 +644,7 @@ MACHANDLE mac802154_create(FAR struct ieee802154_radio_s *radiodev)
|
|||||||
radiocb = &mac->radiocb.cb;
|
radiocb = &mac->radiocb.cb;
|
||||||
radiocb->poll_csma = mac802154_poll_csma;
|
radiocb->poll_csma = mac802154_poll_csma;
|
||||||
radiocb->poll_gts = mac802154_poll_gts;
|
radiocb->poll_gts = mac802154_poll_gts;
|
||||||
|
radiocb->txdone = mac802154_txdone;
|
||||||
|
|
||||||
/* Bind our callback structure */
|
/* Bind our callback structure */
|
||||||
|
|
||||||
@ -710,87 +973,6 @@ int mac802154_req_data(MACHANDLE mac, FAR struct ieee802154_data_req_s *req)
|
|||||||
return OK;
|
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
|
* Name: mac802154_req_purge
|
||||||
|
Loading…
Reference in New Issue
Block a user