diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index fb1127db..7562a1ac 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -38,6 +38,7 @@ #define RX_BUF_LEN 8192 #define TX_BUF_LEN 4096 +#define MIN(a, b) (a) < (b) ? (a) : (b) board_t board_tbl[] = { @@ -131,15 +132,18 @@ static void rtl8139if_input(struct netif* netif, struct pbuf* p) case ETHTYPE_PPPOEDISC: case ETHTYPE_PPPOE: #endif /* PPPOE_SUPPORT */ - /* full packet send to tcpip_thread to process */ - err = mynetif->input(p, mynetif); + /* + * This function is called in the context of the tcpip thread. + * Therefore, we are able to call directly the input functions + */ + err = ethernet_input(p, netif); if (err != ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_input: IP input error %d\n", (int32_t) err)); - pbuf_free_callback(p); + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_input: ethernet_input failed %d\n", err)); } break; default: - pbuf_free_callback(p); + LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139_input: invalid ethernet header 0x%x\n", htons(ethhdr->type))); + pbuf_free(p); break; } } @@ -170,11 +174,13 @@ static void rtl_rx_inthandler(struct netif* netif) #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif - for (q=p, i=0; q!=NULL; q=q->next) { - memcpy((uint8_t*) q->payload + i, rtl8139if->rx_buffer + rtl8139if->rx_pos + i, q->len); - i += q->len; - } - rtl8139if->rx_pos = (rtl8139if->rx_pos + p->tot_len) % RX_BUF_LEN; + for (q=p; q!=NULL; q=q->next) { + i = MIN(q->len, RX_BUF_LEN - rtl8139if->rx_pos); + memcpy((uint8_t*) q->payload, rtl8139if->rx_buffer + rtl8139if->rx_pos, i); + if (i < q->len) // wrap around to end of RxBuffer + memcpy((uint8_t*) q->payload + i, rtl8139if->rx_buffer, q->len - i); + rtl8139if->rx_pos = (rtl8139if->rx_pos + q->len) % RX_BUF_LEN; + } #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif @@ -235,6 +241,14 @@ static void rtl_tx_inthandler(struct netif* netif) } } +/* this function is called in the context of the tcpip thread */ +static void rtl8139if_poll(void* ctx) +{ + //uint32_t flag = irq_nested_disable(); + rtl_rx_inthandler(mynetif); + //irq_nested_enable(flag); +} + static void rtl8139if_handler(struct state* s) { rtl1839if_t* rtl8139if = mynetif->state; @@ -246,7 +260,9 @@ static void rtl8139if_handler(struct state* s) break; if (isr_contents & ISR_ROK) { - rtl_rx_inthandler(mynetif); + if (tcpip_callback_with_block(rtl8139if_poll, NULL, 0) != ERR_OK) { + //LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: unable to send a poll request to the tcpip thread\n")); + } outportw(rtl8139if->iobase + ISR, ISR_ROK); } @@ -291,7 +307,7 @@ err_t rtl8139if_init(struct netif* netif) memset(rtl8139if, 0, sizeof(rtl1839if_t)); /* allocate the receive buffer */ - rtl8139if->rx_buffer = mem_allocation(RX_BUF_LEN + 1500 /* MTU */ + 16 /* header size */, MAP_KERNEL_SPACE|MAP_NO_CACHE); + rtl8139if->rx_buffer = mem_allocation(RX_BUF_LEN + 16 /* header size */, 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)); @@ -389,7 +405,7 @@ err_t rtl8139if_init(struct netif* netif) * APM - Accept Physical Match: Accept packets send to NIC's MAC address. * AAP - Accept All Packets. Accept all packets (run in promiscuous mode). */ - outportl(rtl8139if->iobase + RCR, RCR_MXDMA2|RCR_MXDMA1|RCR_WRAP|RCR_MXDMA0|RCR_AB|RCR_AM|RCR_APM|RCR_AAP); // The WRAP bit is set! + outportl(rtl8139if->iobase + RCR, RCR_MXDMA2|RCR_MXDMA1|RCR_MXDMA0|RCR_AB|RCR_AM|RCR_APM|RCR_AAP); // The WRAP bit isn't set! // set the transmit config register to // be the normal interframe gap time