-
Notifications
You must be signed in to change notification settings - Fork 2.1k
drivers/stm32_eth: add 'NETDEV_EVENT_LINK_UP' event #14688
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This periodic polling seems odd. |
It seems there's no way to do it :(. How does it sound? |
Seems like there is only a sense pin that can generate an interrupt if you plug the cable, I guess that's not what you want. But looks like Zephyr does this too (zephyrproject-rtos/zephyr#19163) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there is only a sense pin that can generate an interrupt if you plug the cable, I guess that's not what you want.
But looks like Zephyr does this too (zephyrproject-rtos/zephyr#19163)
@benpicco I don't understand what you're saying. In zephyr, they have a polling based checkup routing (in the driver!) as well. I don't like this solution either, but there is just no interrupt pin connected. One thing that I'm wondering is whether we should provide such feature within the driver and not just inside the lwip
adaptation.
+1 for having this in the driver. Ideally as (pseudo)module, as not every use might be willing to pay the overhead for this feature. |
Btw: The link status timer could be reset in the driver after processing an RX event; the link must be if frames come in. That way the link polling won't add much additional load if the link is very busy. |
That's exactly what I'm saying 😉 |
Like @maribu I would prefer an implementation of this in the driver as optional pseudo-module. At one point or another we will need this in other network stacks. |
Can |
+1 Implementation-wise, if possible I would prefer a That way we don't have to pull the xtimer/ztimer every time we use the driver. |
Actually #14391 would be ideal IMO |
4188e26
to
3a69968
Compare
239e128
to
79afa99
Compare
I have now moved the implementation into the driver. I tried to solve it with a Unfortunately I am not very familiar with the timers, so I have not found the source of the error yet. |
You have to use a different hardware timer than then one used by xtimer, otherwise you will meddle with that. |
@benpicco I removed the old file and moved everything to |
makefiles/pseudomodules.inc.mk
Outdated
@@ -74,6 +74,7 @@ PSEUDOMODULES += mpu_noexec_ram | |||
PSEUDOMODULES += nanocoap_% | |||
PSEUDOMODULES += netdev_default | |||
PSEUDOMODULES += netdev_ieee802154_% | |||
PSEUDOMODULES += netdev_link_up |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be removed ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is now removed.
netdev_t *dev = (netdev_t *)arg; | ||
if (stm32_eth_get(dev, NETOPT_LINK, NULL, 0)) { | ||
_link_status = 1; | ||
dev->event_callback(dev, NETDEV_EVENT_ISR); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this causes stm32_eth_isr
to be called, it will also generate a NETDEV_EVENT_RX_COMPLETE
event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m not quite sure how to handle this right now. In the old eth.c
implementation there was this function stm32_eth_get_rx_status_owned
, which was used to check whether a frame reception was completed or not.
What is the best way to check for that in the current implementation?
cpu/stm32/periph/eth.c
Outdated
@@ -437,6 +511,11 @@ void stm32_eth_isr_eth_wkup(void) | |||
|
|||
static void stm32_eth_isr(netdev_t *netdev) { | |||
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now this is wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added the function stm32_eth_get_rx_status_owned
again to be able to distinguish between the link up and a message reception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pseudomodule stm32_eth_link_up
should include xtimer
as a dependency somewhere here.
I've tested this PR in two ways:
1.
printf
onNETDEV_EVENT_RX_COMPLETE
andNETDEV_EVENT_LINK_UP
.- examples/default on one nucleo-f207zg.
- Connect ethernet cable to an other nucleo-f207zg.
NETDEV_EVENT_LINK_UP
is reported once.
2.
printf
onNETDEV_EVENT_RX_COMPLETE
andNETDEV_EVENT_LINK_UP
.- tests/lwip compiled with
LWIP_IPV4=1
on one nucleo-f207zg. - Connect ethernet cable to local network (DHCP server running).
NETDEV_EVENT_LINK_UP
is reported once and various packets (that are not filtered by hardware) are received.- Board is assigned an IPv4 address.
cpu/stm32/periph/eth.c
Outdated
if (stm32_eth_get_rx_status_owned()) { | ||
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); | ||
} | ||
if (_link_status && _first_call) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please address this comment
cpu/stm32/periph/eth.c
Outdated
@@ -435,8 +512,19 @@ void stm32_eth_isr_eth_wkup(void) | |||
cortexm_isr_end(); | |||
} | |||
|
|||
int stm32_eth_get_rx_status_owned(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be static
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is not needed (see comment below). Please drop it again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See inline comments
cpu/stm32/periph/eth.c
Outdated
@@ -435,8 +512,19 @@ void stm32_eth_isr_eth_wkup(void) | |||
cortexm_isr_end(); | |||
} | |||
|
|||
int stm32_eth_get_rx_status_owned(void) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is not needed (see comment below). Please drop it again.
cpu/stm32/periph/eth.c
Outdated
/* Internal flags for the DMA descriptors */ | ||
#define DESC_OWN (0x80000000) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please drop this and use the existing macros
cpu/stm32/periph/eth.c
Outdated
static uint8_t _link_status = 0; | ||
static uint8_t _first_call = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to have two variables for this. It is a simple state machine with theses states:
+------------------+ 1 +---------------+ 2 +-------------+
| Link down (init) | --> | Link up | --> | Notified Up |
+------------------+ +---------------+ +-------------+
^ |
| 1 | 3
| v
+---------------+ 4 +-------------+
| Notified Down | <-- | Link Down |
+---------------+ +-------------+
And these events triggering the transitions:
- Link goes up
- Upper layer gets informed that link is up
- link goes down
- Upper layer gets informed that link is down
Tracking the current state fits nicely into a single byte.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to distinguish between the initial link down state and the notified down state
cpu/stm32/periph/eth.c
Outdated
if (stm32_eth_get_rx_status_owned()) { | ||
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE); | ||
} | ||
if (_link_status && _first_call) { | ||
netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP); | ||
_first_call = 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to call stm32_eth_get_rx_status_owned()
here. If there is no notification for link state changes pending, the ISR can only be caused by an RX event. And if the pseudo module for link status polling is not used, it will always be an RX event.
You could go as simple as:
#ifdef MODULE_STM32_ETH_LINK_UP
switch (link_state) {
case LINK_STATE_UP:
netdev->event_callback(netdev, NETDEV_EVENT_LINK_UP);
link_state = LINK_STATE_NOTIFIED_UP;
return;
case LINK_STATE_DOWN:
netdev->event_callback(netdev, NETDEV_EVENT_LINK_DOWN);
link_state = LINK_STATE_NOTIFIED_DOWN;
return;
}
#endif /* MODULE_STM32_ETH_LINK_UP */
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
2a5db3d
to
2d13318
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -86,6 +98,9 @@ static char rx_buffer[ETH_RX_DESCRIPTOR_COUNT][ETH_RX_BUFFER_SIZE]; | |||
/* Netdev used in RIOT's API to upper layer */ | |||
netdev_t *_netdev; | |||
|
|||
/* Used for checking the link status */ | |||
static uint8_t _link_state = LINK_STATE_DOWN; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compiler complains now about unused variable when module is not not enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable is now only defined if the module is used.
2d13318
to
627e906
Compare
Yep, looks good to me. @JannesVolkens thanks for adding it, this is going to be very useful. From my point of view only squashing is needed. (Note: You might find squashing easier if you commit fixes for previous commits using |
627e906
to
f3e9349
Compare
@maribu Squashed. |
Contribution description
This PR offers the possibility to check the link status of stm32 devices to issue the
NETDEV_EVENT_LINK_UP
event. To achieve this the link status is periodically checked with the initialization of the netdev and as soon as a link is detected the eventNETDEV_EVENT_LINK_UP
is triggered.Testing procedure
Try running the test under /tests/lwip/ for IPv4 and typing in
ifconfig
with an ethernet cable connected. The device should have a valid IPv4 address.This PR was testing using a Nucleo-F207ZG board.
Issues/PRs references
#14150