Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

sys: net: introduce low-level ethernet driver API #2766

Merged
merged 4 commits into from
May 26, 2015

Conversation

kaspar030
Copy link
Contributor

While implementing the ethernet driver for encx24j600, I realized that ng_netdev is too fat for some applications, so I tried to create an interface just for ethernet drivers.

The actual tap device handling is taken from #2558.

edit
Let me rephrase the "too fat" statement, as it is totally inaccurate.

IMHO the currently developed network stack might not be the only one we might have in RIOT.
So when I started developing an ethernet driver for RIOT, I didn't want to tie it to netdev and friends.
netdev does make some assumptions on how a driver has to be implemented, and also implies a lot of dependencies.

This PR introduces a fairly thin interface with no dependencies, which can easily be used with netdev (see #2776), but doesn't depend on it.

I've implemented two drivers using it (the tap driver in this PR and a driver for encx24j600 chips, which I'll PR soon). As always with interfaces designed by yourself, I'm quite happy with the result.

The only disadvantage of using this interface instead of directly writing a driver for netdev is that pktsnips have to be converted to a flat buffer before sending to the device. This could be added to the interface if deemed necessary.

@kaspar030 kaspar030 added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Platform: native Platform: This PR/issue effects the native platform 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 labels Apr 8, 2015
err(EXIT_FAILURE, "dev_eth_tap: read");
}
}
else {
Copy link
Member

Choose a reason for hiding this comment

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

Please have a look at #2686 and #2664 (for the case nread == 0)

@kaspar030
Copy link
Contributor Author

@cgundogan integrated.

thread_wakeup(handler_pid);
}

void dev_eth_rx_handler(dev_eth_t *dev) {
Copy link
Contributor

Choose a reason for hiding this comment

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

this is never being called?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is supposed to be called from a drivers _isr implementation. Does the test app work (e.g., print something if you sent a packet to the node / broadcast one)?

@kaspar030
Copy link
Contributor Author

  • updated
  • rebased

@haukepetersen
Copy link
Contributor

I might have an idea to prevent having to copy the data to send into one continuous chunk before you send it: how about splitting the send function in three parts: prepare, load, and execute. This way you could call the load function with an data offset parameter multiple times and then call exec once all the data is loaded into the device buffer... The original send function could stay for convenience reasons, it would just call the three 'lower-level' functions.

@haukepetersen
Copy link
Contributor

Also I am not quite sure about the global functions you defined outside the eth_driver_t struct. I have the impression that they do not scale very well if you have multiple ethernet devices?!

@kaspar030
Copy link
Contributor Author

... splitting the send function in three parts ...
I came to the same conclusion. Will change the interface accordingly.

Also I am not quite sure about the global functions you defined outside the eth_driver_t struct. I have the impression that they do not scale very well if you have multiple ethernet devices?!

Why not? Those functions are called with the device handle as parameter. Should be easy to dispatch to whatever the network stack needs.

@kaspar030
Copy link
Contributor Author

load function with an data offset parameter

Do you think we can omit that parameter? The two drivers I have don't need it.

@OlegHahm
Copy link
Member

I didn't really follow the latest discussions on netdev and this stuff, but looking at the proposed interface that looks exactly how I remember netdev to look like. Now, that I look at driver/include/netdev again, I see that it became a little bit bigger over time, but still I don't really get the purpose/advantage of your interface. What dependencies are pulled in by netdev?

@kaspar030
Copy link
Contributor Author

@OlegHahm ng_netdev pulls at least ng_pkt, ng_pktbuf, ng_netconf. All of them are not needed for a low-level driver. pktbuf alone disqualifies the interface for class-0 devices. And as you realized, the interface is nearly the same, just without those dependencies. That is exactly the purpose / advantage of it.

@OlegHahm
Copy link
Member

ng_netdev pulls at least ng_pkt, ng_pktbuf, ng_netconf.

Maybe I'm starring at the wrong files. Can you point me to these dependencies?

And as you realized, the interface is nearly the same, just without those dependencies. That is exactly the purpose / advantage of it.

Sounds completely reasonable to me. But this sounds to me as we should use this interface as a base and put additional features as a kind of add-on on top of it if necessary.

(Sorry if I discuss about this from a rather abstract level, but I don't have time to dig into the actual code too much.)

@kaspar030
Copy link
Contributor Author

ng_netdev pulls at least ng_pkt, ng_pktbuf, ng_netconf.

Maybe I'm starring at the wrong files. Can you point me to these dependencies?

From ng_netdev.h:

#include "net/ng_pkt.h"
#include "net/ng_netconf.h"

Actually pktbuf is not a direct dependency, but ng_pkt.h states:
@note This type has no initializer on purpose. Please use @ref net_ng_pktbuf as factory.

Also the pktsnip_t is more complex than neccessary, forcing this additional complexity into every triver that uses ng_netdev.

Sounds completely reasonable to me. But this sounds to me as we should use this interface as a base and put additional features as a kind of add-on on top of it if necessary.

Which interface is "this" in that sentence? :)

@OlegHahm
Copy link
Member

Ah, I was indeed looking at the wrong file. Why is device driver interface specified in sys? Hm, ng_netconf.h is just header including some enums, so this dependency is bearable.

For the the other depencies, I agree that this is a bit unfortunate. Can we find a way to abstract from this?

I agree, that it may make sense to have different network stacks with different focuses (class 0 devices or class 1+ devices, for instance), but on the device driver level, I would have assumed that it is possible to define a basic set of functions that can (almost) always be satisfied.

Which interface is "this" in that sentence? :)

Sorry, I meant the interface you propose in this PR.

@kaspar030
Copy link
Contributor Author

Why is device driver interface specified in sys?

You're saying it should move to drivers/include?

Hm, ng_netconf.h is just header including some enums, so this dependency is bearable.

Agreed. Still personally I always prefer not to dictate implementation through interface, just for the flexibility.

I agree, that it may make sense to have different network stacks with different focuses (class 0 devices or class 1+ devices, for instance), but on the device driver level, I would have assumed that it is possible to define a basic set of functions that can (almost) always be satisfied.

Totally. That's what I tried with this interface. Should be simple to extend it so it also works for radio devices. And it can already be used with the ng network stack.

@OlegHahm
Copy link
Member

You're saying it should move to drivers/include?

That seems the natural place for me to look for a device driver interface - and that's the place where I searched for it.

Totally. That's what I tried with this interface. Should be simple to extend it so it also works for radio devices. And it can already be used with the ng network stack.

@haukepetersen, @authmillenon, do you have any opinion on this?

@miri64
Copy link
Member

miri64 commented Apr 15, 2015

@OlegHahm I'm also of the opinion to put it into drivers (as the legacy version of netdev you found there indicates). @haukepetersen however put it into sys/include/net since he feels it more belonging to the network architecture than the device architecture. The arguments for and against drivers/include or sys/include/net weigh each other pretty much out, I guess.

His argument was more or less, that yes, it's device related and it presents an API for a driver (that can in theory be directly connected to the hardware), but things like this PR and previous discussions not to enforce ng_netdev on devices, mainly because its strong dependency to ng_pktbuf, show that it is more an API for the network stack to speak with a device.

Does this reflect your argument @haukepetersen?

@OlegHahm
Copy link
Member

Why is it that dependent on ng_pktbuf? In the end the device just needs a pointer to some data (for sending) or a pointer to some buffer where to copy data (for receiving).

IMO we should have network device interface (i.e. netdev) in drivers/include that can be used as a basis for all network stacks. Otherwise (being dependent on RIOT specific structures) we would have to implement a device driver for each network stack like OpenWSN.

@miri64
Copy link
Member

miri64 commented Apr 15, 2015

@OlegHahm because a network device is required to at least release a sending packet from packet buffer, because it is the last one touching it. Apart from it sure, you can just use arbitrary ng_pktsnip_t pointers, but in practice it makes most sense to put them into the packet buffer directly to reduce overhead.

@haukepetersen
Copy link
Contributor

I spend some more thoughts about these driver interfaces the last days, but I have not come up with a clear opinion, yet. I understand @kaspar030s thoughts about netdev being too complicated/having too many implications on the actual implementation, but I don't see them necessarily as too bad...

I guess creating true low-level driver interfaces for ethernet, ieee802.15.4 etc and mapping the netdev interface on top of these would be an option. This is in my opinion however only valid, if we do not introduce addional copying of data and/or addiontial depth in function call hierarchy... Otherwise we would take efficiency away from the netdev interface.

@miri64
Copy link
Member

miri64 commented Apr 15, 2015

My question about your opinion was more about the directory of ng_netdev.h.

/*
* @ingroup net_dev_eth
* @{
* @file dev_eth_tap.c
Copy link
Member

Choose a reason for hiding this comment

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

remove the filename

@kaspar030
Copy link
Contributor Author

@OlegHahm I think this is squashable?

@OlegHahm
Copy link
Member

sure, go ahead

@kaspar030 kaspar030 force-pushed the add_dev_eth branch 2 times, most recently from f0a2b82 to 6c579c6 Compare May 19, 2015 07:56
@kaspar030
Copy link
Contributor Author

  • squashed
  • rebased

@OlegHahm OlegHahm removed the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label May 19, 2015
}
else if (nread == -1) {
if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
}
Copy link
Member

Choose a reason for hiding this comment

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

?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

empty if case. :) you made me remove the warning.

Copy link
Member

Choose a reason for hiding this comment

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

pffff

@OlegHahm
Copy link
Member

The last two comments are no stoppers. I leave it to you, @kaspar030, if you want to address them. Otherwise go ahead with merging.

* @defgroup sys_net_dev_eth dev_eth auto setup
* @ingroup sys_net_eth
* @brief Automatically setup available ethernet devices
* @{
Copy link
Member

Choose a reason for hiding this comment

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

@file is missing

@kaspar030
Copy link
Contributor Author

-rebased
-addressed @OlegHahm's doxygen comments

@kaspar030 kaspar030 added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label May 26, 2015
@kaspar030
Copy link
Contributor Author

go, travis, go!

@miri64
Copy link
Member

miri64 commented May 26, 2015

driver_nrfmin is failing, but this is unrelated to this PR. Go as soon as it goes … red

@kaspar030
Copy link
Contributor Author

GO.

kaspar030 added a commit that referenced this pull request May 26, 2015
sys: net: introduce low-level ethernet driver API
@kaspar030 kaspar030 merged commit cfd9a59 into RIOT-OS:master May 26, 2015
@kaspar030 kaspar030 deleted the add_dev_eth branch May 26, 2015 17:28
@OlegHahm
Copy link
Member

🎉 🍻

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Area: network Area: Networking CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: native Platform: This PR/issue effects the native platform Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants