Merge branch 'master' into smp

This commit is contained in:
Stefan Lankes 2011-09-20 22:34:50 +02:00
commit 6b2e1f16bc
6 changed files with 103 additions and 50 deletions

View file

@ -347,15 +347,18 @@ static void rckemacif_input(struct netif* netif, struct pbuf* p)
case ETHTYPE_PPPOEDISC:
case ETHTYPE_PPPOE:
#endif /* PPPOE_SUPPORT */
/* full packet send to tcpip_thread to process */
if ((err = mynetif->input(p, mynetif)) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_input: IP input error %d\n", (int32_t) err));
pbuf_free_callback(p);
/*
* 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, ("rckemacif_input: ethernet_input failed %d\n", err));
}
break;
default:
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_input: invalid ethernet header: 0x%x\n", htons(ethhdr->type)));
pbuf_free_callback(p);
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_input: invalid ethernet header 0x%x\n", htons(ethhdr->type)));
pbuf_free(p);
break;
}
}
@ -498,6 +501,19 @@ rxDone:
if (read_offset != write_offset)
goto again;
/* Enable eMAC interrupt */
int tmp = *((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
*((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4)) = tmp & ~(1 << rckemacif->num_emac);
rckemacif->polling = 0;
}
/* this function is called in the context of the tcpip thread */
static void rckemacif_poll(void* ctx)
{
unsigned int write_offset = (unsigned int) ctx;
rckemacif_rx_handler(mynetif, write_offset);
}
static void rckemacif_handler(struct state* s)
@ -514,13 +530,18 @@ static void rckemacif_handler(struct state* s)
return;
}
nexttry:
/* check for updated write offset */
write_offset = *((volatile unsigned int*) (rckemacif->rx_buffer)) & 0xFFFF;
//write_offset = read_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_WRITE_OFFSET, rckemacif->core);
if ((write_offset != 0) && (rckemacif->rx_read_offset != write_offset)) {
rckemacif_rx_handler(mynetif, write_offset);
goto nexttry;
if ((write_offset != 0) && (rckemacif->rx_read_offset != write_offset) && !rckemacif->polling) {
if (tcpip_callback_with_block(rckemacif_poll, (void*) write_offset, 0) == ERR_OK) {
/* Maks eMAC interrupt */
int tmp = *((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4));
*((volatile int*) (FPGA_BASE + IRQ_MASK + rckemacif->core * 2 * 4)) = tmp | (1 << rckemacif->num_emac);
rckemacif->polling = 1;
} else {
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_handler: unable to send a poll request to the tcpip thread\n"));
}
}
/* Set interrupt bit */
@ -561,7 +582,7 @@ err_t rckemacif_init(struct netif* netif)
LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: out of memory\n"));
return ERR_MEM;
}
memset(rckemacif, 0, sizeof(rckemacif_t));
memset(rckemacif, 0x00, sizeof(rckemacif_t));
rckemacif->core = core;
/* allocate the receive buffer */

View file

@ -39,6 +39,7 @@ typedef struct rckemacif {
void* irq_address;
uint32_t core;
uint32_t num_emac;
volatile uint8_t polling;
} rckemacif_t;
/*

View file

@ -38,6 +38,18 @@
#define RX_BUF_LEN 8192
#define TX_BUF_LEN 4096
#define MIN(a, b) (a) < (b) ? (a) : (b)
/*
* To set the RTL8139 to accept only the Transmit OK (TOK) and Receive OK (ROK)
* interrupts, we would have the TOK and ROK bits of the IMR high and leave the
* rest low. That way when a TOK or ROK IRQ happens, it actually will go through
* and fire up an IRQ.
*/
#define INT_MASK (ISR_ROK|ISR_TOK|ISR_RXOVW|ISR_TER|ISR_RER)
// Beside Receive OK (ROK) interrupt, this mask enable all other interrupts
#define INT_MASK_NO_ROK (ISR_TOK|ISR_RXOVW|ISR_TER|ISR_RER)
board_t board_tbl[] =
{
@ -131,15 +143,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 +185,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
@ -201,6 +218,10 @@ static void rtl_rx_inthandler(struct netif* netif)
cmd = inportb(rtl8139if->iobase + CR);
}
rtl8139if->polling = 0;
// enable all known interrupts
outportw(rtl8139if->iobase + IMR, INT_MASK);
}
static void rtl_tx_inthandler(struct netif* netif)
@ -235,41 +256,55 @@ 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)
{
rtl_rx_inthandler(mynetif);
}
static void rtl8139if_handler(struct state* s)
{
rtl1839if_t* rtl8139if = mynetif->state;
uint16_t isr_contents;
// disable all interrupts
outportw(rtl8139if->iobase + IMR, 0x00);
while (1) {
isr_contents = inportw(rtl8139if->iobase + ISR);
if (isr_contents == 0)
break;
if (isr_contents & ISR_ROK) {
rtl_rx_inthandler(mynetif);
outportw(rtl8139if->iobase + ISR, ISR_ROK);
if ((isr_contents & ISR_ROK) && !rtl8139if->polling) {
if (tcpip_callback_with_block(rtl8139if_poll, NULL, 0) == ERR_OK) {
rtl8139if->polling = 1;
} else {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: unable to send a poll request to the tcpip thread\n"));
}
}
if (isr_contents & ISR_TOK) {
if (isr_contents & ISR_TOK)
rtl_tx_inthandler(mynetif);
outportw(rtl8139if->iobase + ISR, ISR_TOK);
}
if (isr_contents & ISR_RER) {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: RX error detected!\n"));
outportw(rtl8139if->iobase + ISR, ISR_RER);
}
if (isr_contents & ISR_TER) {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: TX error detected!\n"));
outportw(rtl8139if->iobase + ISR, ISR_TER);
}
if (isr_contents & ISR_RXOVW) {
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_handler: RX overflow detected!\n"));
outportw(rtl8139if->iobase + ISR, ISR_RXOVW);
}
outportw(rtl8139if->iobase + ISR, isr_contents & (ISR_RXOVW|ISR_TER|ISR_RER|ISR_TOK|ISR_ROK));
}
if (rtl8139if->polling) // now, the tcpip thread will check for incoming messages
outportw(rtl8139if->iobase + IMR, INT_MASK_NO_ROK);
else
outportw(rtl8139if->iobase + IMR, INT_MASK); // enable interrupts
}
err_t rtl8139if_init(struct netif* netif)
@ -288,10 +323,10 @@ err_t rtl8139if_init(struct netif* netif)
LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_init: out of memory\n"));
return ERR_MEM;
}
memset(rtl8139if, 0, sizeof(rtl1839if_t));
memset(rtl8139if, 0x00, 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 +424,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
@ -405,13 +440,8 @@ err_t rtl8139if_init(struct netif* netif)
outportl(rtl8139if->iobase + TSAD2, virt_to_phys((size_t) rtl8139if->tx_buffer[2]));
outportl(rtl8139if->iobase + TSAD3, virt_to_phys((size_t) rtl8139if->tx_buffer[3]));
/*
* To set the RTL8139 to accept only the Transmit OK (TOK) and Receive OK (ROK)
* interrupts, we would have the TOK and ROK bits of the IMR high and leave the
* rest low. That way when a TOK or ROK IRQ happens, it actually will go through
* and fire up an IRQ.
*/
outportw(rtl8139if->iobase + IMR, ISR_ROK|ISR_TOK|ISR_RXOVW|ISR_TER|ISR_RER);
// Enable all known interrupts by setting the interrupt mask.
outportw(rtl8139if->iobase + IMR, INT_MASK);
outportw(rtl8139if->iobase + BMCR, BMCR_ANE);
tmp16 = inportw(rtl8139if->iobase + BMCR);

View file

@ -148,8 +148,8 @@
// Bits in ISR indicate the status of the card
#define ISR_SERR 0x8000 // System error interrupt
#define ISR_TUN 0x4000 // time out interrupt
#define ISR__SWInt 0x100 // Software interrupt
#define ISR__TDU 0x80 // Tx Descriptor unavailable
#define ISR_SWInt 0x100 // Software interrupt
#define ISR_TDU 0x80 // Tx Descriptor unavailable
#define ISR_FIFOOVW 0x40 // Rx Fifo overflow
#define ISR_PUN 0x20 // Packet underrun/link change
#define ISR_RXOVW 0x10 // Rx overflow/Rx Descriptor unavailable
@ -227,6 +227,7 @@ typedef struct rtl1839if {
uint32_t tx_complete;
uint16_t rx_pos;
uint8_t tx_inuse[4];
volatile uint8_t polling;
} rtl1839if_t;
/*

View file

@ -80,7 +80,7 @@ inline static int spinlock_destroy(spinlock_t* s) {
* - -EINVAL (-22) on failure
*/
inline static int spinlock_lock(spinlock_t* s) {
//int32_t ticket;
int32_t ticket;
task_t* curr_task;
if (BUILTIN_EXPECT(!s, 0))
@ -92,7 +92,7 @@ inline static int spinlock_lock(spinlock_t* s) {
return 0;
}
#if 0
#if 1
ticket = atomic_int32_inc(&s->queue);
while(atomic_int32_read(&s->dequeue) != ticket) {
NOP1;
@ -118,7 +118,7 @@ inline static int spinlock_unlock(spinlock_t* s) {
s->counter--;
if (!s->counter) {
s->owner = MAX_TASKS;
#if 0
#if 1
atomic_int32_inc(&s->dequeue);
#else
atomic_int32_set(&s->dequeue,1);
@ -172,7 +172,7 @@ inline static int spinlock_irqsave_destroy(spinlock_irqsave_t* s) {
*/
inline static int spinlock_irqsave_lock(spinlock_irqsave_t* s) {
uint32_t flags;
//int32_t ticket;
int32_t ticket;
if (BUILTIN_EXPECT(!s, 0))
return -EINVAL;
@ -183,7 +183,7 @@ inline static int spinlock_irqsave_lock(spinlock_irqsave_t* s) {
return 0;
}
#if 0
#if 1
ticket = atomic_int32_inc(&s->queue);
while (atomic_int32_read(&s->dequeue) != ticket) {
NOP1;
@ -215,7 +215,7 @@ inline static int spinlock_irqsave_unlock(spinlock_irqsave_t* s) {
flags = s->flags;
s->coreid = (uint32_t) -1;
s->flags = 0;
#if 0
#if 1
atomic_int32_inc(&s->dequeue);
#else
atomic_int32_set(&s->dequeue,1);

View file

@ -202,7 +202,7 @@ static int TCPServer(void* arg)
{
start = rdtsc();
kprintf("\nReceiving from client, packet size %s ... ", PacketSize(ctl.data));
kprintf("\nReceiving from client, packet size %s ... \n", PacketSize(ctl.data));
cBuffer[0] = 0;
nData = 0;
@ -229,7 +229,7 @@ static int TCPServer(void* arg)
} else if (ctl.cmd == CMD_S2C) {
start = rdtsc();
kprintf("\nSending to client, packet size %s ... ", PacketSize(ctl.data));
kprintf("\nSending to client, packet size %s ... \n", PacketSize(ctl.data));
cBuffer[0] = 0;
nData = 0;