drivers: ethernet: stm32: Add carrier state detection
This patch adds carrier state detection to the STM32 Ethernet driver. Fixes #16097 Signed-off-by: Markus Fuchs <markus.fuchs@de.sauter-bc.com>
This commit is contained in:
parent
1911a7599c
commit
f08caaf677
3 changed files with 46 additions and 10 deletions
|
@ -88,4 +88,12 @@ config ETH_STM32_HAL_MII
|
||||||
help
|
help
|
||||||
Use the MII physical interface instead of RMII.
|
Use the MII physical interface instead of RMII.
|
||||||
|
|
||||||
|
config ETH_STM32_CARRIER_CHECK_RX_IDLE_TIMEOUT_MS
|
||||||
|
int "Carrier check timeout period (ms)"
|
||||||
|
default 500
|
||||||
|
range 100 30000
|
||||||
|
help
|
||||||
|
Set the RX idle timeout period in milliseconds after which the
|
||||||
|
PHY's carrier status is re-evaluated.
|
||||||
|
|
||||||
endif # ETH_STM32_HAL
|
endif # ETH_STM32_HAL
|
||||||
|
|
|
@ -230,6 +230,7 @@ static void rx_thread(void *arg1, void *unused1, void *unused2)
|
||||||
struct eth_stm32_hal_dev_data *dev_data;
|
struct eth_stm32_hal_dev_data *dev_data;
|
||||||
struct net_pkt *pkt;
|
struct net_pkt *pkt;
|
||||||
int res;
|
int res;
|
||||||
|
u32_t status;
|
||||||
|
|
||||||
__ASSERT_NO_MSG(arg1 != NULL);
|
__ASSERT_NO_MSG(arg1 != NULL);
|
||||||
ARG_UNUSED(unused1);
|
ARG_UNUSED(unused1);
|
||||||
|
@ -241,16 +242,39 @@ static void rx_thread(void *arg1, void *unused1, void *unused2)
|
||||||
__ASSERT_NO_MSG(dev_data != NULL);
|
__ASSERT_NO_MSG(dev_data != NULL);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
k_sem_take(&dev_data->rx_int_sem, K_FOREVER);
|
res = k_sem_take(&dev_data->rx_int_sem,
|
||||||
|
K_MSEC(CONFIG_ETH_STM32_CARRIER_CHECK_RX_IDLE_TIMEOUT_MS));
|
||||||
while ((pkt = eth_rx(dev)) != NULL) {
|
if (res == 0) {
|
||||||
net_pkt_print_frags(pkt);
|
/* semaphore taken, update link status and receive packets */
|
||||||
res = net_recv_data(dev_data->iface, pkt);
|
if (dev_data->link_up != true) {
|
||||||
if (res < 0) {
|
dev_data->link_up = true;
|
||||||
eth_stats_update_errors_rx(dev_data->iface);
|
net_eth_carrier_on(dev_data->iface);
|
||||||
LOG_ERR("Failed to enqueue frame "
|
}
|
||||||
"into RX queue: %d", res);
|
while ((pkt = eth_rx(dev)) != NULL) {
|
||||||
net_pkt_unref(pkt);
|
net_pkt_print_frags(pkt);
|
||||||
|
res = net_recv_data(dev_data->iface, pkt);
|
||||||
|
if (res < 0) {
|
||||||
|
eth_stats_update_errors_rx(dev_data->iface);
|
||||||
|
LOG_ERR("Failed to enqueue frame "
|
||||||
|
"into RX queue: %d", res);
|
||||||
|
net_pkt_unref(pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (res == -EAGAIN) {
|
||||||
|
/* semaphore timeout period expired, check link status */
|
||||||
|
if (HAL_ETH_ReadPHYRegister(&dev_data->heth, PHY_BSR,
|
||||||
|
(uint32_t *) &status) == HAL_OK) {
|
||||||
|
if ((status & PHY_LINKED_STATUS) == PHY_LINKED_STATUS) {
|
||||||
|
if (dev_data->link_up != true) {
|
||||||
|
dev_data->link_up = true;
|
||||||
|
net_eth_carrier_on(dev_data->iface);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dev_data->link_up != false) {
|
||||||
|
dev_data->link_up = false;
|
||||||
|
net_eth_carrier_off(dev_data->iface);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,6 +406,8 @@ static void eth_iface_init(struct net_if *iface)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dev_data->link_up = false;
|
||||||
|
|
||||||
/* Initialize semaphores */
|
/* Initialize semaphores */
|
||||||
k_mutex_init(&dev_data->tx_mutex);
|
k_mutex_init(&dev_data->tx_mutex);
|
||||||
k_sem_init(&dev_data->rx_int_sem, 0, UINT_MAX);
|
k_sem_init(&dev_data->rx_int_sem, 0, UINT_MAX);
|
||||||
|
@ -417,6 +443,7 @@ static void eth_iface_init(struct net_if *iface)
|
||||||
NET_LINK_ETHERNET);
|
NET_LINK_ETHERNET);
|
||||||
|
|
||||||
ethernet_init(iface);
|
ethernet_init(iface);
|
||||||
|
net_if_flag_set(iface, NET_IF_NO_AUTO_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum ethernet_hw_caps eth_stm32_hal_get_capabilities(struct device *dev)
|
static enum ethernet_hw_caps eth_stm32_hal_get_capabilities(struct device *dev)
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct eth_stm32_hal_dev_data {
|
||||||
K_THREAD_STACK_MEMBER(rx_thread_stack,
|
K_THREAD_STACK_MEMBER(rx_thread_stack,
|
||||||
CONFIG_ETH_STM32_HAL_RX_THREAD_STACK_SIZE);
|
CONFIG_ETH_STM32_HAL_RX_THREAD_STACK_SIZE);
|
||||||
struct k_thread rx_thread;
|
struct k_thread rx_thread;
|
||||||
|
bool link_up;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DEV_CFG(dev) \
|
#define DEV_CFG(dev) \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue