diff --git a/drivers/include/net/netdev.h b/drivers/include/net/netdev.h index 202dc8402a..929b00ed50 100644 --- a/drivers/include/net/netdev.h +++ b/drivers/include/net/netdev.h @@ -237,9 +237,29 @@ typedef enum { NETDEV_EVENT_RX_COMPLETE, /**< finished receiving a frame */ NETDEV_EVENT_TX_STARTED, /**< started to transfer a frame */ NETDEV_EVENT_TX_COMPLETE, /**< transfer frame complete */ - NETDEV_EVENT_TX_COMPLETE_DATA_PENDING, /**< transfer frame complete and data pending flag */ - NETDEV_EVENT_TX_NOACK, /**< ACK requested but not received */ - NETDEV_EVENT_TX_MEDIUM_BUSY, /**< couldn't transfer frame */ + /** + * @brief transfer frame complete and data pending flag + * + * @deprecated Issue an NETDEV_EVENT_TX_COMPLETE event instead and pass + * the data pending info in netdev_driver_t::confirm_send + * via the `info` parameter + */ + NETDEV_EVENT_TX_COMPLETE_DATA_PENDING, + /** + * @brief ACK requested but not received + * + * @deprecated Issue an NETDEV_EVENT_TX_COMPLETE event instead and return + * `-ECOMM` in netdev_driver_t::confirm_send. Via the `info` + * parameter additional details about the error can be passed + */ + NETDEV_EVENT_TX_NOACK, + /** + * @brief couldn't transfer frame + * + * @deprecated Issue an NETDEV_EVENT_TX_COMPLETE event instead and return + * `-EBUSY` in netdev_driver_t::confirm_send. + */ + NETDEV_EVENT_TX_MEDIUM_BUSY, NETDEV_EVENT_LINK_UP, /**< link established */ NETDEV_EVENT_LINK_DOWN, /**< link gone */ NETDEV_EVENT_TX_TIMEOUT, /**< timeout when sending */ @@ -357,22 +377,66 @@ static inline void netdev_register(struct netdev *dev, netdev_type_t type, uint8 */ typedef struct netdev_driver { /** - * @brief Send frame + * @brief Start transmission of the given frame and return directly * * @pre `(dev != NULL) && (iolist != NULL)` * * @param[in] dev Network device descriptor. Must not be NULL. * @param[in] iolist IO vector list to send. Elements of this list may - * have iolist_t::iol_data == NULL or - * iolist_t::iol_size == 0. However, unless otherwise - * specified by the device, the *first* element - * must contain data. + * have iolist_t::iol_size == 0 and (in this case only) + * iolist_t::iol_data == 0. * - * @return negative errno on error - * @return number of bytes sent + * @retval -EBUSY Driver is temporarily unable to send, e.g. because + * an incoming frame on a half-duplex medium is + * received + * @retval -ENETDOWN Device is powered down + * @retval <0 Other error + * @retval 0 Transmission successfully started + * @retval >0 Number of bytes transmitted (deprecated!) + * + * This function will cause the driver to start the transmission in an + * async fashion. The driver will "own" the `iolist` until a subsequent + * call to @ref netdev_driver_t::confirm_send returns something different + * than `-EAGAIN`. The driver must signal completion using the + * NETDEV_EVENT_TX_COMPLETE event, regardless of success or failure. + * + * 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 + * will return the number of bytes transmitted on success (instead of `0`) + * and will likely block until completion. */ int (*send)(netdev_t *dev, const iolist_t *iolist); + /** + * @brief Fetch the status of a transmission and perform any potential + * cleanup + * + * @param[in] dev Network device descriptor. Must not be NULL. + * @param[out] info Device class specific type to fetch transmission + * info. May be `NULL` if not needed by upper layer. + * May be ignored by driver. + * + * @return Number of bytes transmitted. (The size of the transmitted + * frame including all overhead, such as frame check sequence, + * bit stuffing, escaping, headers, trailers, preambles, start of + * frame delimiters, etc. May be an estimate for performance + * reasons.) + * @retval -EAGAIN Transmission still ongoing. (Call later again!) + * @retval -ECOMM Any kind of transmission error, such as collision + * detected, layer 2 ACK timeout, etc. + * Use @p info for more details + * @retval -EBUSY Medium is busy. (E.g. Auto-CCA failed / timed out) + * @retval <0 Other error. (Please use a negative errno code.) + * + * @warning After netdev_driver_t::send was called and returned zero, this + * function must be called until it returns anything other than + * `-EAGAIN`. + * @note The driver will signal completion using the + * NETDEV_EVENT_TX_COMPLETE event. This function must not return + * `-EAGAIN` after that event was received. + */ + int (*confirm_send)(netdev_t *dev, void *info); + /** * @brief Drop a received frame, **OR** get the length of a received * frame, **OR** get a received frame.