Skip to content

Conversation

maribu
Copy link
Member

@maribu maribu commented Jul 28, 2020

Contribution description

Extend netdev_driver_t::send() to take an additional void *info parameter to allow passing info on the transmission in the same fashion netdev_driver_t::recv() passes info about the received frame.

Testing procedure

  1. Murdock
  2. Network operation should still work as usual

Issues/PRs references

@maribu maribu added Area: network Area: Networking State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Process: API change Integration Process: PR contains or issue proposes an API change. Should be handled with care. Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Process: needs >1 ACK Integration Process: This PR requires more than one ACK labels Jul 28, 2020
@maribu maribu requested review from miri64, benpicco and bergzand July 28, 2020 07:16
Comment on lines 304 to +320
*
* @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
* @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.
* @param[out] info Status information of the transmission. Might
* be of different type for different netdev devices.
* May be NULL if not needed or applicable.
*
* @return negative errno on error
* @return number of bytes sent
*/
int (*send)(netdev_t *dev, const iolist_t *iolist);
int (*send)(netdev_t *dev, const iolist_t *iolist, void *info);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actual change of this PR; The remaining stuff is just porting the code to this API change.

@maribu
Copy link
Member Author

maribu commented Jul 28, 2020

Note: Please wait with the in-depth review until Murdock is happy. I intent to fix all compilation issues up front.

@maribu maribu force-pushed the netdev_tx_info branch 2 times, most recently from 547bcbb to c5d5fac Compare July 28, 2020 07:54
@miri64
Copy link
Member

miri64 commented Jul 28, 2020

As this was originally not introduced since there was no use case, the question is obvious: what is your use case?

@maribu
Copy link
Member Author

maribu commented Jul 28, 2020

what is your use case?

Specifically, I would like to implement PTP. For that, I need to have the exact time stamp when a frame was send (the start of frame delimiter specifically).

Other use cases would be:

  • Number of retransmissions (if driver does so automagically)
  • Auto-CCA info
  • ...

Extend `netdev_driver_t::send()` to take an additional `void *info` parameter
to allow passing info on the transmission in the same fashion
`netdev_driver_t::recv()` passes info about the received frame.
@jia200x
Copy link
Member

jia200x commented Jul 28, 2020

We had an offline conversation once with @miri64 about such a feature and I think it's nice to have. My only concern is about putting this in the send function and not associated to the transmission events (TX_START, TX_END, etc).

The use cases you descirbe there would require to block the send function (as opposed to a handler in TX_START or TX_END).
Have you considered maybe using a dedicated NETOPT and a wrapper on top? (e.g netdev_get_tx_info). I'm doing something similar in the Radio HAL (but with a dedicated confirm function).

@maribu
Copy link
Member Author

maribu commented Jul 28, 2020

Have you considered maybe using a dedicated NETOPT and a wrapper on top?

I indeed have, but I decided against this for two reasons:

  1. If netdev_driver_t::send() is indeed implemented non-blocking, some care has to be taken to fetch the TX info at the right time. Otherwise we might fetch TX info of a different frame instead.
  2. I believe that TX has to block in netdev_driver_t for reliable operation anyway, as the upper layer otherwise will start to send e.g. the next 6LoWPAN fragment while the first isn't out. (E.g. the AT86RF233 will block on the second call to send() to solve this. But I have a branch lying around where the driver just blocks in send() in any case using a mutex, which reduced lines of code, ROM, and allows the CPU to attend to other threads while TX is ongoing.)

With the new Radio HAL and an explicit confirm() this is indeed solved much better. I see this as a short term solution and hope that the Radio HAL will become a role model for the network driver interfaces in general.

@jia200x
Copy link
Member

jia200x commented Jul 28, 2020

I believe that TX has to block in netdev_driver_t for reliable operation anyway, as the upper layer otherwise will start to send e.g. the next 6LoWPAN fragment while the first isn't out. (E.g. the AT86RF233 will block on the second call to send() to solve this. But I have a branch lying around where the driver just blocks in send() in any case using a mutex, which reduced lines of code, ROM, and allows the CPU to attend to other threads while TX is ongoing.)

Hmmm, but that would mean all drivers should be implemented as blocking. I'm not against the concept, but IMO it should be at least consistent with all implementations (or at least classes of device drivers). Otherwise getting TX info might not be feasible for several devices (e.g AT86RF2xx writes TX information on TX_DONE event, and the current implementation is non-blocking)

@maribu
Copy link
Member Author

maribu commented Jul 29, 2020

Hmmm, but that would mean all drivers should be implemented as blocking.

I agree.

I'm not against the concept, but IMO it should be at least consistent with all implementations (or at least classes of device drivers).

I also agree. But I'm not sure if it is worth the effort to touch all the netdev_driver_t code, if we indeed want to move to a new interface similar to the 802.15.4 Radio HAL.

If have two options in mind:

  1. Just add the txinfo to send() as is proposed here. Drivers need to implement this feature for the new API to become useful anyway. And if someone implements this feature, this person will also adapt the send() function to block, if this is not yet the case.

  2. Extend the netdev_driver_t to also contain a confirm_transmit() providing the TX info. That would only be called if the function pointer is not NULL, so that drivers can be migrated one at a time. Changing the netdev_driver_t interface in a sequence of smaller steps towards the concepts of the Radio HAL might not be such as bad thing, as this would play well with the async development model. And it would likely make life easier when the actual transition to the new Radio HAL is done.

@jia200x
Copy link
Member

jia200x commented Jul 29, 2020

  1. Extend the netdev_driver_t to also contain a confirm_transmit() providing the TX info. That would only be called if the function pointer is not NULL, so that drivers can be migrated one at a time. Changing the netdev_driver_t interface in a sequence of smaller steps towards the concepts of the Radio HAL might not be such as bad thing, as this would play well with the async development model. And it would likely make life easier when the actual transition to the new Radio HAL is done.

I agree and this would be my preferred option.

The problem with 1. is the fact that is hard to implement upper layers if the function can be blocking or non-blocking depending of the implementation.

For instance, if all IEEE802.15.4 drivers are blocking, one could think of a retransmission procedure like:

while (retrans-- > 0) {
    int res = dev->driver->send(...);
    if (res == 0) {
        break;
    }
}

If the send function is non-blocking, this pattern is not possible as it is. The other way around is also true, since some design decision can be made assuming a send function is non-blocking.

@maribu
Copy link
Member Author

maribu commented Jul 29, 2020

I agree and this would be my preferred option.

I'll open a new PR for this and keep this as reference. I should be able to open the PR some time today.

@maribu
Copy link
Member Author

maribu commented Jan 14, 2021

Alternative proposal got merged, this is not needed anymore

@maribu maribu closed this Jan 14, 2021
@maribu maribu deleted the netdev_tx_info branch January 14, 2021 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Process: API change Integration Process: PR contains or issue proposes an API change. Should be handled with care. Process: needs >1 ACK Integration Process: This PR requires more than one ACK State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants