lwip: Fix issue on Rx path in hadling packets with Xilkernel

This patch fixes rx packet handling issue with Xilkernel. The issue
was processing a single packet from the input queue everytime the
semaphore is released in the ISR. Now, we iterate till the queue
is completely emptied. After the ISR releases the semaphore and before
the queue is read, there could be new packets in the queue and hence can
lead to situations where there could be considerable delay in processing
a particular packet.
This patch also ensures that the ISR releases the semaphore once for
an entry into Rx ISR instead of each received packet. This enhances
performance.

Signed-off-by: Anirudha Sarangi <anirudh@xilinx.com>
This commit is contained in:
Anirudha Sarangi 2015-02-09 17:11:43 +05:30 committed by Nava kishore Manne
parent 46d7b155eb
commit 10bb0f7661
2 changed files with 35 additions and 32 deletions

View file

@ -242,45 +242,49 @@ int xaxiemacif_input(struct netif *netif)
struct pbuf *p;
SYS_ARCH_DECL_PROTECT(lev);
/* move received packet into a new pbuf */
SYS_ARCH_PROTECT(lev);
p = low_level_input(netif);
SYS_ARCH_UNPROTECT(lev);
#if !NO_SYS
while (1)
#endif
{
/* move received packet into a new pbuf */
SYS_ARCH_PROTECT(lev);
p = low_level_input(netif);
SYS_ARCH_UNPROTECT(lev);
/* no packet could be read, silently ignore this */
if (p == NULL)
return 0;
/* no packet could be read, silently ignore this */
if (p == NULL)
return 0;
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
/* points to packet payload, which starts with an Ethernet header */
ethhdr = p->payload;
#if LINK_STATS
lwip_stats.link.recv++;
lwip_stats.link.recv++;
#endif /* LINK_STATS */
switch (htons(ethhdr->type)) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
switch (htons(ethhdr->type)) {
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
#if PPPOE_SUPPORT
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
/* PPPoE packet? */
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("xaxiemacif_input: IP input error\r\n"));
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("xaxiemacif_input: IP input error\r\n"));
pbuf_free(p);
p = NULL;
}
break;
default:
pbuf_free(p);
p = NULL;
}
break;
default:
pbuf_free(p);
p = NULL;
break;
break;
}
}
return 1;
}

View file

@ -418,10 +418,6 @@ static void axidma_recv_handler(void *arg)
lwip_stats.link.drop++;
#endif
pbuf_free(p);
} else {
#if !NO_SYS
sys_sem_signal(&xemac->sem_rx_data_available);
#endif
}
rxbd = XAxiDma_BdRingNext(rxring, rxbd);
}
@ -430,6 +426,9 @@ static void axidma_recv_handler(void *arg)
/* return all the processed bd's back to the stack */
/* setup_rx_bds -> use XAxiDma_BdRingGetFreeCnt */
setup_rx_bds(rxring);
#if !NO_SYS
sys_sem_signal(&xemac->sem_rx_data_available);
#endif
}
XAxiDma_BdRingIntEnable(rxring, XAXIDMA_IRQ_ALL_MASK);
}