Skip to content

Commit f8b4a04

Browse files
robhancockseddanieldegrasse
authored andcommitted
drivers: mdio: mdio_xilinx_axienet: Add access timeouts
Previously if the MDIO access failed to complete, the driver could enter an infinite busy loop. Add timeouts to fail the operation if the hardware fails to respond within a reasonable time. Signed-off-by: Robert Hancock <robert.hancock@calian.com>
1 parent e673f18 commit f8b4a04

File tree

1 file changed

+20
-2
lines changed

1 file changed

+20
-2
lines changed

drivers/mdio/mdio_xilinx_axienet.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ static void enable_mdio_bus(const struct mdio_xilinx_axienet_config *config,
9393
if ((xilinx_axienet_read_mdio_register(config, XILINX_AXIENET_MDIO_SETUP_REG_OFFSET) &
9494
XILINX_AXIENET_MDIO_SETUP_REG_MDIO_ENABLE_MASK) == 0) {
9595
int err;
96+
int count = 0;
9697

9798
xilinx_axienet_mdio_write_register(config, XILINX_AXIENET_MDIO_SETUP_REG_OFFSET,
9899
XILINX_AXIENET_MDIO_SETUP_REG_MDIO_ENABLE_MASK |
@@ -103,7 +104,7 @@ static void enable_mdio_bus(const struct mdio_xilinx_axienet_config *config,
103104
XILINX_AXIENET_MDIO_INTERRUPT_MASK);
104105

105106
if (config->have_irq) {
106-
LOG_DBG("Waiting for bus enable!");
107+
LOG_DBG("Waiting for bus enable IRQ");
107108
err = k_sem_take(&data->irq_sema,
108109
K_MSEC(XILINX_AXIENET_MDIO_INTERRUPT_TIMEOUT_MS));
109110

@@ -115,7 +116,12 @@ static void enable_mdio_bus(const struct mdio_xilinx_axienet_config *config,
115116
while ((xilinx_axienet_read_mdio_register(config,
116117
XILINX_AXIENET_MDIO_SETUP_REG_OFFSET) &
117118
XILINX_AXIENET_MDIO_SETUP_REG_MDIO_ENABLE_MASK) == 0) {
118-
LOG_DBG("Waiting for bus enable!");
119+
LOG_DBG("Waiting for bus enable flag");
120+
k_busy_wait(1);
121+
if (count++ > 1000) {
122+
LOG_ERR("MDIO bus enable timeout");
123+
return;
124+
}
119125
}
120126

121127
} else {
@@ -164,6 +170,7 @@ static int mdio_xilinx_axienet_read(const struct device *dev, uint8_t prtad, uin
164170
const struct mdio_xilinx_axienet_config *config = dev->config;
165171
struct mdio_xilinx_axienet_data *dev_data = dev->data;
166172
int err;
173+
int count = 0;
167174

168175
if (k_is_in_isr()) {
169176
LOG_ERR("Called MDIO read in ISR!");
@@ -201,6 +208,11 @@ static int mdio_xilinx_axienet_read(const struct device *dev, uint8_t prtad, uin
201208
while ((xilinx_axienet_read_mdio_register(config, XILINX_AXIENET_MDIO_CONTROL_REG_OFFSET) &
202209
XILINX_AXIENET_MDIO_CONTROL_REG_MASK_READY) == 0x0) {
203210
LOG_DBG("Transfer is not yet ready!");
211+
k_busy_wait(1);
212+
if (count++ > 1000) {
213+
LOG_ERR("MDIO read timeout");
214+
return -ETIMEDOUT;
215+
}
204216
}
205217

206218
LOG_DBG("IRQ from MDIO received - read complete!");
@@ -220,6 +232,7 @@ static int mdio_xilinx_axienet_write(const struct device *dev, uint8_t prtad, ui
220232
const struct mdio_xilinx_axienet_config *config = dev->config;
221233
struct mdio_xilinx_axienet_data *dev_data = dev->data;
222234
int err;
235+
int count = 0;
223236

224237
if (k_is_in_isr()) {
225238
LOG_ERR("Called MDIO write in ISR!");
@@ -257,6 +270,11 @@ static int mdio_xilinx_axienet_write(const struct device *dev, uint8_t prtad, ui
257270
while ((xilinx_axienet_read_mdio_register(config, XILINX_AXIENET_MDIO_CONTROL_REG_OFFSET) &
258271
XILINX_AXIENET_MDIO_CONTROL_REG_MASK_READY) == 0x0) {
259272
LOG_DBG("IRQ from MDIO received but transfer is not yet ready!");
273+
k_busy_wait(1);
274+
if (count++ > 1000) {
275+
LOG_ERR("MDIO write timeout");
276+
return -ETIMEDOUT;
277+
}
260278
}
261279

262280
LOG_DBG("IRQ from MDIO received - write complete!");

0 commit comments

Comments
 (0)