fix bug in ring buffer handling

This commit is contained in:
Stefan Lankes 2011-09-17 00:55:47 +02:00
parent 6ad28af6b9
commit ce4bfa61bd

View file

@ -36,6 +36,9 @@
#include <netif/etharp.h>
#include <net/rtl8139.h>
#define RX_BUF_LEN 8192
#define TX_BUF_LEN 4096
board_t board_tbl[] =
{
{"RealTek", "RealTek RTL8139", 0x10ec, 0x8139},
@ -153,11 +156,11 @@ static void rtl_rx_inthandler(struct netif* netif)
cmd = inportb(rtl8139if->iobase + CR);
while(!(cmd & CR_BUFE)) {
header = *((uint16_t*) (rtl8139if->rx_buffer+rtl8139if->rx_pos));
rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % (8192+16);
rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % RX_BUF_LEN;
if (header & ISR_ROK) {
length = *((uint16_t*) (rtl8139if->rx_buffer+rtl8139if->rx_pos)) - 4; // copy packet (but not the CRC)
rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % (8192+16);
rtl8139if->rx_pos = (rtl8139if->rx_pos + 2) % RX_BUF_LEN;
#if ETH_PAD_SIZE
length += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
@ -170,7 +173,7 @@ static void rtl_rx_inthandler(struct netif* netif)
for (q=p; q!=NULL; q=q->next) {
for(i=0; i<q->len; i++) {
((uint8_t*) q->payload)[i] = rtl8139if->rx_buffer[rtl8139if->rx_pos];
rtl8139if->rx_pos = (rtl8139if->rx_pos + 1) % (8192+16);
rtl8139if->rx_pos = (rtl8139if->rx_pos + 1) % RX_BUF_LEN;
}
}
#if ETH_PAD_SIZE
@ -180,16 +183,16 @@ static void rtl_rx_inthandler(struct netif* netif)
LINK_STATS_INC(link.recv);
} else {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: not enough memory!\n"));
rtl8139if->rx_pos += (rtl8139if->rx_pos + length) % (8192+16);
rtl8139if->rx_pos += (rtl8139if->rx_pos + length) % RX_BUF_LEN;
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
}
// packets are dword aligned
rtl8139if->rx_pos = ((rtl8139if->rx_pos + 4 + 3) & ~0x3) % (8192+16);
rtl8139if->rx_pos = ((rtl8139if->rx_pos + 4 + 3) & ~0x3) % RX_BUF_LEN;
outportw(rtl8139if->iobase + CAPR, rtl8139if->rx_pos - 0x10);
} else {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: invalid header!\n"));
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: invalid header 0x%x, rx_pos %d\n", (uint32_t) header, rtl8139if->rx_pos));
LINK_STATS_INC(link.memerr);
LINK_STATS_INC(link.drop);
break;
@ -287,26 +290,26 @@ err_t rtl8139if_init(struct netif* netif)
memset(rtl8139if, 0, sizeof(rtl1839if_t));
/* allocate the receive buffer */
rtl8139if->rx_buffer = mem_allocation(8192+16, MAP_KERNEL_SPACE|MAP_NO_CACHE);
rtl8139if->rx_buffer = mem_allocation(RX_BUF_LEN/*+16*/, MAP_KERNEL_SPACE|MAP_NO_CACHE);
if (!(rtl8139if->rx_buffer)) {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_init: out of memory\n"));
kfree(rtl8139if, sizeof(rtl1839if_t));
return ERR_MEM;
}
memset(rtl8139if->rx_buffer, 0, 8192+16);
memset(rtl8139if->rx_buffer, 0x00, RX_BUF_LEN);
/* allocate the send buffers */
rtl8139if->tx_buffer[0] = mem_allocation(4*4096, MAP_KERNEL_SPACE|MAP_NO_CACHE);
rtl8139if->tx_buffer[0] = mem_allocation(4*TX_BUF_LEN, MAP_KERNEL_SPACE|MAP_NO_CACHE);
if (!(rtl8139if->tx_buffer[0])) {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_init: out of memory\n"));
kfree(rtl8139if->rx_buffer, 8192+16);
kfree(rtl8139if->rx_buffer, RX_BUF_LEN);
kfree(rtl8139if, sizeof(rtl1839if_t));
return ERR_MEM;
}
memset(rtl8139if->tx_buffer[0], 0, 4*4096);
rtl8139if->tx_buffer[1] = rtl8139if->tx_buffer[0] + 4096;
rtl8139if->tx_buffer[2] = rtl8139if->tx_buffer[1] + 4096;
rtl8139if->tx_buffer[3] = rtl8139if->tx_buffer[2] + 4096;
memset(rtl8139if->tx_buffer[0], 0x00, 4*TX_BUF_LEN);
rtl8139if->tx_buffer[1] = rtl8139if->tx_buffer[0] + TX_BUF_LEN;
rtl8139if->tx_buffer[2] = rtl8139if->tx_buffer[1] + TX_BUF_LEN;
rtl8139if->tx_buffer[3] = rtl8139if->tx_buffer[2] + TX_BUF_LEN;
netif->state = rtl8139if;
mynetif = netif;