Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/enc28j60: fix ISR routine and bth #19461

Merged
merged 2 commits into from
Apr 12, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 34 additions & 12 deletions drivers/enc28j60/enc28j60.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,6 @@ static void mac_set(enc28j60_t *dev, uint8_t *mac)

static void on_int(void *arg)
{
/* disable global interrupt enable bit to avoid losing interrupts */
cmd_bfc((enc28j60_t *)arg, REG_EIE, -1, EIE_INTIE);

netdev_trigger_event_isr(arg);
}

Expand Down Expand Up @@ -450,13 +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;
uint8_t eir = cmd_rcr(dev, REG_EIR, -1);

while (eir != 0) {
/* disable global interrupt enable bit to avoid losing interrupts */
cmd_bfc(dev, REG_EIE, -1, EIE_INTIE);

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 @@ -469,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