drivers: ethernet: enc28j60: Prevent infinate loop on driver init

In the case that there is a situation where the controller
oscillator start-up timer doesn't expire, or the SPI can't
read the CLKRDY bit the driver would hang during init.
The config option ETH_ENC28J60_CLKRDY_INIT_WAIT_MS sets
the time that the driver will wait for OST before returning
an ETIMEDOUT error.

Signed-off-by: Dean Sellers <dsellers@evos.com.au>
This commit is contained in:
Dean Sellers 2023-05-01 14:05:58 +10:00 committed by Carles Cufí
commit ca7a66d787
2 changed files with 23 additions and 2 deletions

View file

@ -30,6 +30,16 @@ config ETH_ENC28J60_RX_THREAD_PRIO
Priority level for internal thread which is ran for incoming
packet processing.
config ETH_ENC28J60_CLKRDY_INIT_WAIT_MS
int "Time to wait for the CLKRDY bit on driver init"
depends on ETH_ENC28J60
default 2
help
Timeout in milliseconds. Maximum time the initialisation
of the driver will wait for the OST to expire, indicated
by the CLKRDY bit set. If timeout driver init will fail
with -ETIMEDOUT.
config ETH_ENC28J60_TIMEOUT
int "IP buffer timeout"
depends on ETH_ENC28J60

View file

@ -335,7 +335,7 @@ static void eth_enc28j60_gpio_callback(const struct device *dev,
k_sem_give(&context->int_sem);
}
static void eth_enc28j60_init_buffers(const struct device *dev)
static int eth_enc28j60_init_buffers(const struct device *dev)
{
uint8_t data_estat;
@ -375,11 +375,20 @@ static void eth_enc28j60_init_buffers(const struct device *dev)
ENC28J60_RECEIVE_FILTERS);
/* Waiting for OST */
/* 32 bits for this timer should be fine, rollover not an issue with initialisation */
uint32_t start_wait = (uint32_t) k_uptime_get();
do {
/* If the CLK isn't ready don't wait forever */
if ((k_uptime_get_32() - start_wait) > CONFIG_ETH_ENC28J60_CLKRDY_INIT_WAIT_MS) {
LOG_ERR("OST wait timed out");
return -ETIMEDOUT;
}
/* wait 10.24 useconds */
k_busy_wait(D10D24S);
eth_enc28j60_read_reg(dev, ENC28J60_REG_ESTAT, &data_estat);
} while (!(data_estat & ENC28J60_BIT_ESTAT_CLKRDY));
return 0;
}
static void eth_enc28j60_init_mac(const struct device *dev)
@ -821,7 +830,9 @@ static int eth_enc28j60_init(const struct device *dev)
context->mac_address[1] = MICROCHIP_OUI_B1;
context->mac_address[2] = MICROCHIP_OUI_B2;
eth_enc28j60_init_buffers(dev);
if (eth_enc28j60_init_buffers(dev)) {
return -ETIMEDOUT;
}
eth_enc28j60_init_mac(dev);
eth_enc28j60_init_phy(dev);