drivers: ethernet: enc28j60: disable/enable interrupts to avoid races
Currently, there is a small race window where we can miss an interrupt. Right after we're done reading the RX buffer but just before decrementing the RX counter to zero, the ENC28J60 may receive a packet. The chip will raise an interrupt, but the line is still asserted. That means that the callback will not be invoked since it is edge-triggered. To avoid that, disable interrupts on the chip itself before processing the RX buffer. In fact, the ENC28J60 datasheet specifically says: "After an interrupt occurs, the host controller should clear the global enable bit for the interrupt pin before servicing the interrupt. Clearing the enable bit will cause the interrupt pin to return to the non-asserted state (high). Doing so will prevent the host controller from missing a falling edge should another interrupt occur while the immediate interrupt is being serviced. After the interrupt has been serviced, the global enable bit may be restored. If an interrupt event occurred while the previous interrupt was being processed, the act of resetting the global enable bit will cause a new falling edge on the interrupt pin to occur." This is also what is being done in the Linux driver [1]. [1] https://elixir.bootlin.com/linux/v6.11.2/source/drivers/net/ethernet/microchip/enc28j60.c#L1126 Signed-off-by:Xavier Ruppen <xruppen@gmail.com>
Loading
Please sign in to comment