Skip to content

Commit

Permalink
drivers/enc28j60: fix PKTIF issue.
Browse files Browse the repository at this point in the history
The PKTIF does not reliably report the status of pending packags.
Apply the proposed workaround [1].

[1] https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/Errata/80349c.pdf
  • Loading branch information
peteut committed Apr 10, 2023
1 parent 200c49d commit 4bf4c4a
Showing 1 changed file with 32 additions and 9 deletions.
41 changes: 32 additions & 9 deletions drivers/enc28j60/enc28j60.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,15 +447,38 @@ static int nd_init(netdev_t *netdev)
return 0;
}

/**
* PKTIF does not reliably report the status of pending packets.
* Checking EPKTCNT is the suggested workaround.
* Returns the number of pending packets.
*/
static int rx_interrupt(netdev_t *netdev)
{
enc28j60_t *dev = (enc28j60_t *)netdev;
int pkg_cnt = cmd_rcr(dev, REG_B1_EPKTCNT , 1);
int ret = pkg_cnt;
while (pkg_cnt-- > 0) {
DEBUG("[enc28j60] isr: packet received\n");
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
}
return ret;
}

static void nd_isr(netdev_t *netdev)
{
enc28j60_t *dev = (enc28j60_t *)netdev;

/* disable global interrupt enable bit to avoid losing interrupts */
cmd_bfc(dev, REG_EIE, -1, EIE_INTIE);
uint8_t eir = cmd_rcr(dev, REG_EIR, -1);

while (eir != 0) {
uint8_t eir;
int loop;
do {
loop = 0;
eir = cmd_rcr(dev, REG_EIR, -1);

if (eir & EIR_LINKIF) {
loop++;
/* clear link state interrupt flag */
cmd_r_phy(dev, REG_PHY_PHIR);
/* go and tell the new link layer state to upper layers */
Expand All @@ -468,27 +491,27 @@ static void nd_isr(netdev_t *netdev)
netdev->event_callback(netdev, NETDEV_EVENT_LINK_DOWN);
}
}
if (eir & EIR_PKTIF) {
do {
DEBUG("[enc28j60] isr: packet received\n");
netdev->event_callback(netdev, NETDEV_EVENT_RX_COMPLETE);
} while (cmd_rcr(dev, REG_B1_EPKTCNT, 1) > 0);
if (rx_interrupt(netdev)) {
loop++;
}
if (eir & EIR_RXERIF) {
loop++;
DEBUG("[enc28j60] isr: incoming packet dropped - RX buffer full\n");
cmd_bfc(dev, REG_EIR, -1, EIR_RXERIF);
}
if (eir & EIR_TXIF) {
loop++;
DEBUG("[enc28j60] isr: packet transmitted\n");
netdev->event_callback(netdev, NETDEV_EVENT_TX_COMPLETE);
cmd_bfc(dev, REG_EIR, -1, EIR_TXIF);
}
if (eir & EIR_TXERIF) {
loop++;
DEBUG("[enc28j60] isr: error during transmission - pkt dropped\n");
cmd_bfc(dev, REG_EIR, -1, EIR_TXERIF);
}
eir = cmd_rcr(dev, REG_EIR, -1);
}
} while (loop);

/* enable global interrupt enable bit again */
cmd_bfs(dev, REG_EIE, -1, EIE_INTIE);
}
Expand Down

0 comments on commit 4bf4c4a

Please sign in to comment.