mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/netdev: allow .send() to return > 0 to signal synchronos send
This commit is contained in:
parent
387f970b50
commit
a86411b81e
@ -440,7 +440,7 @@ typedef struct netdev_driver {
|
|||||||
* @retval -ENETDOWN Device is powered down
|
* @retval -ENETDOWN Device is powered down
|
||||||
* @retval <0 Other error
|
* @retval <0 Other error
|
||||||
* @retval 0 Transmission successfully started
|
* @retval 0 Transmission successfully started
|
||||||
* @retval >0 Number of bytes transmitted (deprecated!)
|
* @retval >0 Number of bytes transmitted (transmission already complete)
|
||||||
*
|
*
|
||||||
* This function will cause the driver to start the transmission in an
|
* This function will cause the driver to start the transmission in an
|
||||||
* async fashion. The driver will "own" the `iolist` until a subsequent
|
* async fashion. The driver will "own" the `iolist` until a subsequent
|
||||||
@ -448,6 +448,12 @@ typedef struct netdev_driver {
|
|||||||
* than `-EAGAIN`. The driver must signal completion using the
|
* than `-EAGAIN`. The driver must signal completion using the
|
||||||
* NETDEV_EVENT_TX_COMPLETE event, regardless of success or failure.
|
* NETDEV_EVENT_TX_COMPLETE event, regardless of success or failure.
|
||||||
*
|
*
|
||||||
|
* If the driver implements blocking send (e.g. because it writes out the
|
||||||
|
* frame byte-by-byte over a serial line) it can also return the number of bytes
|
||||||
|
* transmitted here directly. In this case it MUST NOT emit a NETDEV_EVENT_TX_COMPLETE
|
||||||
|
* event, netdev_driver_t::confirm_send will never be called but should still be
|
||||||
|
* implemented to signal conformance to the new API.
|
||||||
|
*
|
||||||
* Old drivers might not be ported to the new API and have
|
* Old drivers might not be ported to the new API and have
|
||||||
* netdev_driver_t::confirm_send set to `NULL`. In that case the driver
|
* netdev_driver_t::confirm_send set to `NULL`. In that case the driver
|
||||||
* will return the number of bytes transmitted on success (instead of `0`)
|
* will return the number of bytes transmitted on success (instead of `0`)
|
||||||
|
@ -275,8 +275,9 @@ static err_t _common_link_output(struct netif *netif, netdev_t *netdev, iolist_t
|
|||||||
{
|
{
|
||||||
lwip_netif_dev_acquire(netif);
|
lwip_netif_dev_acquire(netif);
|
||||||
|
|
||||||
|
err_t res;
|
||||||
if (is_netdev_legacy_api(netdev)) {
|
if (is_netdev_legacy_api(netdev)) {
|
||||||
err_t res = (netdev->driver->send(netdev, iolist) > 0) ? ERR_OK : ERR_BUF;
|
res = (netdev->driver->send(netdev, iolist) > 0) ? ERR_OK : ERR_BUF;
|
||||||
lwip_netif_dev_release(netif);
|
lwip_netif_dev_release(netif);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -288,7 +289,8 @@ static err_t _common_link_output(struct netif *netif, netdev_t *netdev, iolist_t
|
|||||||
compat_netif->thread_doing_tx = thread_get_active();
|
compat_netif->thread_doing_tx = thread_get_active();
|
||||||
irq_restore(irq_state);
|
irq_restore(irq_state);
|
||||||
|
|
||||||
if (netdev->driver->send(netdev, iolist) < 0) {
|
res = netdev->driver->send(netdev, iolist);
|
||||||
|
if (res < 0) {
|
||||||
lwip_netif_dev_release(netif);
|
lwip_netif_dev_release(netif);
|
||||||
irq_state = irq_disable();
|
irq_state = irq_disable();
|
||||||
compat_netif->thread_doing_tx = NULL;
|
compat_netif->thread_doing_tx = NULL;
|
||||||
@ -303,17 +305,19 @@ static err_t _common_link_output(struct netif *netif, netdev_t *netdev, iolist_t
|
|||||||
compat_netif->thread_doing_tx = NULL;
|
compat_netif->thread_doing_tx = NULL;
|
||||||
irq_restore(irq_state);
|
irq_restore(irq_state);
|
||||||
|
|
||||||
int retval;
|
if (res == 0) {
|
||||||
while (-EAGAIN == (retval = netdev->driver->confirm_send(netdev, NULL))) {
|
/* async send */
|
||||||
/* this should not happen, as the driver really only should emit the
|
while (-EAGAIN == (res = netdev->driver->confirm_send(netdev, NULL))) {
|
||||||
* TX done event when it is actually done. But better be safe than
|
/* this should not happen, as the driver really only should emit the
|
||||||
* sorry */
|
* TX done event when it is actually done. But better be safe than
|
||||||
DEBUG_PUTS("[lwip_netdev] confirm_send() returned -EAGAIN\n");
|
* sorry */
|
||||||
|
DEBUG_PUTS("[lwip_netdev] confirm_send() returned -EAGAIN\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lwip_netif_dev_release(netif);
|
lwip_netif_dev_release(netif);
|
||||||
|
|
||||||
if (retval < 0) {
|
if (res < 0) {
|
||||||
return ERR_IF;
|
return ERR_IF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1915,7 +1915,7 @@ static void _send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, bool push_back)
|
|||||||
* completed. For new netdevs (with confirm_send), TX is async. It is only
|
* completed. For new netdevs (with confirm_send), TX is async. It is only
|
||||||
* done if TX failed right away (res < 0).
|
* done if TX failed right away (res < 0).
|
||||||
*/
|
*/
|
||||||
if (gnrc_netif_netdev_legacy_api(netif) || (res < 0)) {
|
if (gnrc_netif_netdev_legacy_api(netif) || (res != 0)) {
|
||||||
_tx_done(netif, pkt, tx_sync, res, push_back);
|
_tx_done(netif, pkt, tx_sync, res, push_back);
|
||||||
}
|
}
|
||||||
#if IS_USED(MODULE_NETDEV_NEW_API)
|
#if IS_USED(MODULE_NETDEV_NEW_API)
|
||||||
|
Loading…
Reference in New Issue
Block a user