diff --git a/wireless/ieee802154/mac802154.c b/wireless/ieee802154/mac802154.c index af5e4523f7e..072e439d1d8 100644 --- a/wireless/ieee802154/mac802154.c +++ b/wireless/ieee802154/mac802154.c @@ -636,8 +636,8 @@ static void mac802154_purge_worker(FAR void *arg) /* Free the IOB, the notification, and the tx descriptor */ iob_free(txdesc->frame); - ((FAR struct mac802154_notif_s *)txdesc->conf)->flink = priv->notif_free; - priv->notif_free = ((FAR struct mac802154_notif_s *)txdesc->conf); + mac802154_notif_free_locked(priv, + (FAR struct ieee802154_notif_s *)txdesc->conf); mac802154_txdesc_free(priv, txdesc); priv->beaconupdate = true; @@ -760,7 +760,6 @@ static void mac802154_txdone_worker(FAR void *arg) (FAR struct ieee802154_privmac_s *)arg; FAR struct ieee802154_txdesc_s *txdesc; FAR struct ieee802154_notif_s *notif; - FAR struct mac802154_notif_s *privnotif; /* Get exclusive access to the driver structure. We don't care about any * signals so don't allow interruptions @@ -781,8 +780,7 @@ static void mac802154_txdone_worker(FAR void *arg) * notification structure to make it easier to use. */ - privnotif = (FAR struct mac802154_notif_s *)txdesc->conf; - notif = &privnotif->pub; + notif =(FAR struct ieee802154_notif_s *)txdesc->conf; switch(txdesc->frametype) { @@ -857,14 +855,7 @@ static void mac802154_txdone_worker(FAR void *arg) break; default: - /* We can deallocate the data conf notification as it is no - * longer needed. We can't use the public function here - * since we already have the MAC locked. - */ - - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; - priv->nnotif = 0; + mac802154_notif_free_locked(priv, notif); break; } } @@ -872,13 +863,7 @@ static void mac802154_txdone_worker(FAR void *arg) default: { - /* We can deallocate the data conf notification as it is no longer - * needed. We can't use the public function here since we already - * have the MAC locked. - */ - - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; + mac802154_notif_free_locked(priv, notif); } break; } diff --git a/wireless/ieee802154/mac802154.h b/wireless/ieee802154/mac802154.h index 90ff021952d..01762b2c5f0 100644 --- a/wireless/ieee802154/mac802154.h +++ b/wireless/ieee802154/mac802154.h @@ -368,7 +368,7 @@ int mac802154_resp_orphan(MACHANDLE mac, * ****************************************************************************/ -int mac802154_notif_free(MACHANDLE mac, +void mac802154_notif_free(MACHANDLE mac, FAR struct ieee802154_notif_s *notif); #undef EXTERN diff --git a/wireless/ieee802154/mac802154_assoc.c b/wireless/ieee802154/mac802154_assoc.c index 2027013b7ab..1df36a60ee0 100644 --- a/wireless/ieee802154/mac802154_assoc.c +++ b/wireless/ieee802154/mac802154_assoc.c @@ -402,10 +402,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_txdesc_s *txdesc) { enum ieee802154_status_e status; - FAR struct mac802154_notif_s *privnotif = - (FAR struct mac802154_notif_s *)txdesc->conf; - FAR struct ieee802154_notif_s *notif = &privnotif->pub; FAR struct ieee802154_txdesc_s *respdesc; + FAR struct ieee802154_notif_s *notif = + (FAR struct ieee802154_notif_s *)txdesc->conf; if(txdesc->conf->status != IEEE802154_STATUS_SUCCESS) { @@ -497,13 +496,9 @@ void mac802154_txdone_assocreq(FAR struct ieee802154_privmac_s *priv, (priv->resp_waittime*IEEE802154_BASE_SUPERFRAME_DURATION)); } - /* We can deallocate the data conf notification as it is no longer - * needed. We can't use the public function here since we already - * have the MAC locked. - */ + /* Deallocate the data conf notification as it is no longer needed. */ - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; + mac802154_notif_free_locked(priv, notif); } } @@ -524,9 +519,8 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_txdesc_s *txdesc) { enum ieee802154_status_e status; - FAR struct mac802154_notif_s *privnotif = - (FAR struct mac802154_notif_s *)txdesc->conf; - FAR struct ieee802154_notif_s *notif = &privnotif->pub; + FAR struct ieee802154_notif_s *notif = + (FAR struct ieee802154_notif_s *)txdesc->conf; /* If the data request failed to be sent, notify the next layer * that the association has failed. @@ -595,14 +589,9 @@ void mac802154_txdone_datareq_assoc(FAR struct ieee802154_privmac_s *priv, mac802154_timerstart(priv, priv->max_frame_waittime, mac802154_assoctimeout); - /* We can deallocate the data conf notification as it is no longer - * needed. We can't use the public function here since we already - * have the MAC locked. - */ + /* Deallocate the data conf notification as it is no longer needed. */ - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; - mac802154_givesem(&priv->notif_sem); + mac802154_notif_free_locked(priv, notif); } } diff --git a/wireless/ieee802154/mac802154_notif.c b/wireless/ieee802154/mac802154_notif.c index bce299c139c..059d95624cd 100644 --- a/wireless/ieee802154/mac802154_notif.c +++ b/wireless/ieee802154/mac802154_notif.c @@ -69,44 +69,22 @@ * ****************************************************************************/ -int mac802154_notif_free(MACHANDLE mac, - FAR struct ieee802154_notif_s *notif) +void mac802154_notif_free(MACHANDLE mac, FAR struct ieee802154_notif_s *notif) { FAR struct ieee802154_privmac_s *priv = (FAR struct ieee802154_privmac_s *)mac; - FAR struct mac802154_notif_s *privnotif = - (FAR struct mac802154_notif_s *)notif; - /* Get exclusive access to the MAC */ + /* Lock the MAC */ mac802154_takesem(&priv->exclsem, false); - /* We know how many clients have registered for notifications. Each must - * call mac802154_notif_free() before we can release the notification - * resource. - */ + /* Call the internal helper function to free the notification */ - if (priv->nnotif < 2) - { - /* This is the free from the last notification */ + mac802154_notif_free_locked(priv, notif); - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; - priv->nnotif = 0; - - mac802154_givesem(&priv->notif_sem); - } - else - { - /* More calls are expected. Decrement the count of expected calls - * and preserve the notification resources. - */ - - priv->nnotif--; - } + /* Unlock the MAC */ mac802154_givesem(&priv->exclsem); - return -ENOTTY; } /**************************************************************************** @@ -184,9 +162,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, if (ret == OK) { - privnotif = priv->notif_free; - priv->notif_free = privnotif->flink; - priv->nnotif = 0; + privnotif = priv->notif_free; + priv->notif_free = privnotif->flink; + privnotif->nclients = 0; } else { @@ -220,9 +198,9 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, /* We can now safely unlink the next free structure from the free list */ - privnotif = priv->notif_free; - priv->notif_free = privnotif->flink; - priv->nnotif = 0; + privnotif = priv->notif_free; + priv->notif_free = privnotif->flink; + privnotif->nclients = 0; } *notif = (FAR struct ieee802154_notif_s *)privnotif; @@ -230,6 +208,49 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, return OK; } +/**************************************************************************** + * Name: mac802154_notif_free_locked + * + * Description: + * When the MAC calls the registered callback, it passes a reference + * to a mac802154_notify_s structure. This structure needs to be freed + * after the callback handler is done using it. + * + * Internal version that already has MAC locked + * + ****************************************************************************/ + +void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv, + FAR struct ieee802154_notif_s *notif) +{ + FAR struct mac802154_notif_s *privnotif = + (FAR struct mac802154_notif_s *)notif; + + /* We know how many clients have registered for notifications. Each must + * call mac802154_notif_free() before we can release the notification + * resource. + */ + + if (privnotif->nclients < 2) + { + /* This is the free from the last notification */ + + privnotif->flink = priv->notif_free; + priv->notif_free = privnotif; + privnotif->nclients = 0; + + mac802154_givesem(&priv->notif_sem); + } + else + { + /* More calls are expected. Decrement the count of expected calls + * and preserve the notification resources. + */ + + privnotif->nclients--; + } +} + /**************************************************************************** * Name: mac802154_notify * @@ -242,12 +263,13 @@ void mac802154_notify(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_notif_s *notif) { FAR struct mac802154_maccb_s *cb; + FAR struct mac802154_notif_s *privnotif = (FAR struct mac802154_notif_s *)notif; /* Set the notification count so that the notification resources will be * preserved until the final notification. */ - priv->nnotif = priv->nclients; + privnotif->nclients = priv->nclients; /* Try to notify every registered MAC client */ diff --git a/wireless/ieee802154/mac802154_notif.h b/wireless/ieee802154/mac802154_notif.h index 3c6bdd35230..886d786c6b6 100644 --- a/wireless/ieee802154/mac802154_notif.h +++ b/wireless/ieee802154/mac802154_notif.h @@ -65,6 +65,7 @@ struct mac802154_notif_s { struct ieee802154_notif_s pub; /* Publically visible structure */ FAR struct mac802154_notif_s *flink; /* Supports a singly linked list */ + uint8_t nclients; }; /**************************************************************************** @@ -82,4 +83,7 @@ int mac802154_notif_alloc(FAR struct ieee802154_privmac_s *priv, void mac802154_notify(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_notif_s *notif); +void mac802154_notif_free_locked(FAR struct ieee802154_privmac_s * priv, + FAR struct ieee802154_notif_s *notif); + #endif /* __WIRELESS_IEEE802154__MAC802154_NOTIF_H */ \ No newline at end of file diff --git a/wireless/ieee802154/mac802154_poll.c b/wireless/ieee802154/mac802154_poll.c index e2881a397a9..368f8baac23 100644 --- a/wireless/ieee802154/mac802154_poll.c +++ b/wireless/ieee802154/mac802154_poll.c @@ -188,9 +188,8 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, FAR struct ieee802154_txdesc_s *txdesc) { enum ieee802154_status_e status; - FAR struct mac802154_notif_s *privnotif = - (FAR struct mac802154_notif_s *)txdesc->conf; - FAR struct ieee802154_notif_s *notif = &privnotif->pub; + FAR struct ieee802154_notif_s *notif = + (FAR struct ieee802154_notif_s *)txdesc->conf; /* If the data request failed to be sent, notify the next layer * that the poll has failed. @@ -245,13 +244,9 @@ void mac802154_txdone_datareq_poll(FAR struct ieee802154_privmac_s *priv, mac802154_timerstart(priv, priv->max_frame_waittime, mac802154_polltimeout); - /* We can deallocate the data conf notification as it is no longer - * needed. We can't use the public function here since we already - * have the MAC locked. - */ + /* Deallocate the data conf notification as it is no longer needed. */ - privnotif->flink = priv->notif_free; - priv->notif_free = privnotif; + mac802154_notif_free_locked(priv, notif); } }