diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index a202a1bb..4551edc1 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -735,7 +735,7 @@ int arch_paging_init(void) kprintf("Map message passing buffers at 0x%x\n", viraddr); // map the FPGA registers - viraddr = map_region(FPGA_BASE, FPGA_BASE, (16*1024*1024) >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_NO_CACHE); + viraddr = map_region(FPGA_BASE, FPGA_BASE, 0x10000 >> PAGE_SHIFT, MAP_KERNEL_SPACE|MAP_NO_CACHE); kprintf("Map FPGA regsiters at 0x%x\n", viraddr); #endif diff --git a/drivers/net/rckemac.c b/drivers/net/rckemac.c index 8e996dc6..b2b07f4e 100644 --- a/drivers/net/rckemac.c +++ b/drivers/net/rckemac.c @@ -17,6 +17,12 @@ * This file is part of MetalSVM. */ +/* + * This eMAC driver required at least sccKit 1.4.0 and based on + * the eMAC Driver Description (section 9.6.5) in the + * SccKit 1.4.0 User’s Guide (Revision 0.92 Part 9). + */ + #include #include #include @@ -50,7 +56,7 @@ #define EMAC_RX_CONTROL 0x9000 #define EMAC_TX_CONTROL 0x9900 -/* Xilinx IP configuration - offsets */ +/* IP configuration - offsets */ #define CONFIG_FLOW_CONTROL_ADD 0xC0 #define TRANSMITTER_ADDRESS 0x80 #define RECEIVER1_ADDRESS 0x40 @@ -94,18 +100,30 @@ #define CLINE_ALIGN(_x) (((_x) + CLINE_SIZE - 1) & CLINE_MASK) #define CLINE_PACKETS(_x) (CLINE_ALIGN(_x) >> CLINE_SHIFT) +/* Flush */ +#define CL1FLUSH __asm__ volatile (".byte 0x0F; .byte 0x0A;\n") + +/* Read 16bit from buffer */ +#define U16(_addr) (256 * (*((uint8_t*) (_addr + 1))) + (*((uint8_t*)(_addr)))) + #define MAC_ADDRESS 0x00454D414331ULL #define MAC_HI(_x) ((((_x) >> 32)) & 0xFFFF) #define MAC_LO(_x) (((_x) ) & 0xFFFFFFFF) -static struct netif* mynetif[4] = {NULL, NULL, NULL, NULL}; +static struct netif* mynetif; -static inline int read_emac(int num_emac, int offset, int core) +static int read_emac(int num_emac, int offset, int core) { - return *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)); + int ret; + + ret = *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)); + /* no error: read twice, as xilinx ip need some time... */ + ret = *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)); + + return ret; } -static inline void write_emac(int num_emac, int offset, int core, int value) +static void write_emac(int num_emac, int offset, int core, int value) { *((volatile int*) (FPGA_BASE + num_emac * 0x1000 + offset + core * 4)) = value; } @@ -121,14 +139,14 @@ static err_t rckemacif_output(struct netif* netif, struct pbuf* p) rckemacif_t* rckemacif = netif->state; uint32_t i; struct pbuf *q; - void *addr = NULL; - uint16_t read_offset = 0; - int rest = 0; - int packets = 0; + void *addr; + uint16_t read_offset; + int rest; + int packets; int sum = 0; /* check for over/underflow */ - if (BUILTIN_EXPECT(p->tot_len > 1536, 0)) { + if (BUILTIN_EXPECT((p->tot_len < 20) || (p->tot_len > 1536), 0)) { LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_output: illegal packet length %d => drop\n", p->len)); return ERR_IF; } @@ -170,8 +188,8 @@ again: * q traverses through linked list of pbuf's * This list MUST consist of a single packet ONLY */ - for (q = p, i = 0; q != 0; q = q->next) { - memcpy(addr + 2 + i, q->payload, q->len); + for (q=p, i=0; q!=0; q=q->next) { + memcpy(((uint8_t*)addr) + 2 + i, q->payload, q->len); i += q->len; } @@ -193,7 +211,7 @@ again: q = p; i = 0; while ((q != 0) && (i < bytes_to_copy)) { sz = q->len > bytes_to_copy-i ? bytes_to_copy-i : q->len; - memcpy(addr + 2 + i, q->payload, sz); + memcpy(((uint8_t*) addr) + 2 + i, q->payload, sz); bytes_left -= sz; i += sz; if (i < bytes_to_copy) @@ -207,12 +225,12 @@ again: i = 0; if (sz < q->len) { - memcpy(addr, q->payload + sz, q->len - sz); + memcpy((uint8_t*) addr, q->payload + sz, q->len - sz); bytes_left -= (q->len - sz); i = q->len - sz; } for(q=q->next; (q != 0); q = q->next) { - memcpy(addr+i, q->payload, q->len); + memcpy(((uint8_t*) addr) + i, q->payload, q->len); i += q->len; } @@ -228,8 +246,7 @@ again: *((volatile int*) rckemacif->tx_buffer) = 2; /* set new write offset */ - LWIP_DEBUGF(NETIF_DEBUG, ("Update tx write offset: %d (read offset %d)\n", rckemacif->tx_write_offset, read_offset)); - + //LWIP_DEBUGF(NETIF_DEBUG, ("Update tx write offset: %d (read offset %d)\n", rckemacif->tx_write_offset, read_offset)); write_emac(rckemacif->num_emac, EMAC_TX_CONTROL+EMAC_TX_BUFFER_WRITE_OFFSET, rckemacif->core, rckemacif->tx_write_offset); #if ETH_PAD_SIZE @@ -241,151 +258,177 @@ again: return ERR_OK; } -#if 0 -static void rtl_rx_inthandler(struct netif* netif) +static void rckemacif_rx_handler(struct netif* netif, unsigned int write_offset) { - rtl1839if_t* rtl8139if = netif->state; - uint16_t header; - uint16_t length, i; - uint8_t cmd; - struct pbuf *p = NULL; + rckemacif_t* rckemacif = netif->state; + unsigned short read_offset; + unsigned int counter; + volatile void *addr; + uint16_t i, length; + struct pbuf *p; struct pbuf* q; - 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); + if (write_offset > rckemacif->rx_buffer_max) { + LWIP_DEBUGF(NETIF_DEBUG, ("Warning, write offset > buffer max!! (%d > %d)\n", write_offset, rckemacif->rx_buffer_max)); + read_offset = 1; + write_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, rckemacif->core, read_offset); + rckemacif->rx_read_offset = read_offset; + return; + } + + while(1) { + if ((write_offset != 0) && (rckemacif->rx_read_offset != write_offset)) { + read_offset = rckemacif->rx_read_offset; + read_offset++; + if (read_offset < 1 || read_offset > rckemacif->rx_buffer_max) { + read_offset = 1; + } + addr = rckemacif->rx_buffer + read_offset * 32; + + length = U16(addr); + + // Check for over/underflow + if ((length < 20) || (length > 1536)) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_rx_handler(): illegal packet length %d => drop\n", length)); + LWIP_DEBUGF(NETIF_DEBUG, ("start read at %d; write_offset at %d; addr: %p, packet len: %d\n", read_offset, write_offset, addr, length)); + + read_offset = write_offset; +#if 1 + kprintf("Buffer:\n"); + for (i = 0; i < 32; i++) { + kprintf("%2.2x ", ((char*)addr)[i] & 0xFF); + } + kprintf("\n"); + + kprintf("Buffer0:\n"); + for (i = 0; i < 32; i++) { + kprintf("%2.2x ", ((char*)rckemacif->rx_buffer)[i] & 0xFF); + } + kprintf("\n"); +#endif + + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + + goto rxDone; + } - 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); #if ETH_PAD_SIZE length += ETH_PAD_SIZE; /* allow room for Ethernet padding */ #endif + //LWIP_DEBUGF(NETIF_DEBUG, ("length %u, read_offset %u, write_offset %u\n", length, read_offset, write_offset)); p = pbuf_alloc(PBUF_RAW, length, PBUF_POOL); if (p) { #if ETH_PAD_SIZE pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ #endif - for (q=p; q!=NULL; q=q->next) { - for(i=0; ilen; i++) { - ((uint8_t*) q->payload)[i] = rtl8139if->rx_buffer[rtl8139if->rx_pos]; - rtl8139if->rx_pos = (rtl8139if->rx_pos + 1) % (8192+16); - } - } + if (read_offset < write_offset) { + for (q=p, counter=0; q!=NULL; q=q->next) { + for(i=0; ilen; i++, counter++) { + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[2 + counter]; + } + } + + read_offset += CLINE_PACKETS(p->len + 2) - 1; + } else { + int rest; + int bytesLeft = length; + int bytesToCopy = length; + + /* rest to the end of buffer - 2 bytes length information */ + rest = (rckemacif->rx_buffer_max - read_offset + 1) * 32 - 2; + if (length > rest) + bytesToCopy = rest; + LWIP_DEBUGF(NETIF_DEBUG, ("bytes to copy: %d, bytesLeft: %d\n", bytesToCopy, bytesLeft)); + + for (q=p, counter=0; q!=NULL; q=q->next) { + for(i=0; ilen; i++, counter++) { + if (counter < bytesToCopy) + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[2 + counter]; + else + goto out; + } + } +out: + bytesLeft -= bytesToCopy; + + if (bytesLeft != 0) { + addr = rckemacif->rx_buffer + 0x20; + LWIP_DEBUGF(NETIF_DEBUG, ("copying from %p, left: %d (%x)\n", addr, bytesLeft, ((uint8_t*)addr)[0])); + for(counter=0; (ilen) && (counter < bytesLeft); i++, counter++) + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter]; + for(q=q->next; (q!=NULL) && (counter < bytesLeft); q=q->next) { + for(i=0; (ilen) && (counter < bytesLeft); i++, counter++) { + ((uint8_t*) q->payload)[i] = ((uint8_t*)addr)[counter]; + } + } + read_offset = CLINE_PACKETS(bytesLeft); + } else { + read_offset += CLINE_PACKETS(p->len + 2) - 1; + } + } + #if ETH_PAD_SIZE pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ #endif - mailbox_ptr_post(&rtl8139if->mbox, (void*)p); - //rtl8139if_input(netif, p); + mailbox_ptr_post(&rckemacif->mbox, (void*)p); 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); + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_rx_inthandler: not enough memory!\n")); 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); - outportw(rtl8139if->iobase + CAPR, rtl8139if->rx_pos - 0x10); - } else { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139if_rx_inthandler: invalid header!\n")); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - break; - } - - cmd = inportb(rtl8139if->iobase + CR); +rxDone: + /* set new read pointer */ + //LWIP_DEBUGF(NETIF_DEBUG, ("Update rx read offset: %d\n", read_offset)); + write_emac(rckemacif->num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, rckemacif->core, read_offset); + rckemacif->rx_read_offset = read_offset; + } else break; } } -static void rtl_tx_inthandler(struct netif* netif) -{ - rtl1839if_t* rtl8139if = netif->state; - uint32_t checks = rtl8139if->tx_queue - rtl8139if->tx_complete; - uint32_t txstatus; - uint8_t tmp8; - - while(checks > 0) - { - tmp8 = rtl8139if->tx_complete % 4; - txstatus = inportl(rtl8139if->iobase + TSD0 + tmp8 * 4); - - if (!(txstatus & (TSD_TOK|TSD_TUN|TSD_TABT))) - return; - - if (txstatus & (TSD_TABT | TSD_OWC)) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139_tx_inthandler: major error\n")); - continue; - } - - if (txstatus & TSD_TUN) { - LWIP_DEBUGF(NETIF_DEBUG, ("rtl8139_tx_inthandler: transmit underrun\n")); - } - - if (txstatus & TSD_TOK) { - rtl8139if->tx_inuse[tmp8] = 0; - rtl8139if->tx_complete++; - checks--; - } - } -} -#endif - static void rckemacif_handler(struct state* s) { - LWIP_DEBUGF(NETIF_DEBUG, ("HELLO! Got interrupt!\n")); + unsigned int status, tmp; + unsigned int write_offset; + rckemacif_t* rckemacif = mynetif->state; -#if 0 - rtl1839if_t* rtl8139if = mynetif->state; - uint16_t isr_contents; - - 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_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); - } + status = *((volatile int*) (FPGA_BASE + IRQ_STATUS + rckemacif->core * 2 * 4)); + // read twice to be sure + status = *((volatile int*) (FPGA_BASE + IRQ_STATUS + rckemacif->core * 2 * 4)); + if (!(status & (1 << rckemacif->num_emac))) { + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_handler: no interrupt\n")); + return; } -#endif + +nexttry: + /* check for updated write offset */ + CL1FLUSH; + 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; + } + + /* Set interrupt bit */ + tmp = *((volatile unsigned int*) rckemacif->irq_address); + tmp &= ~(EMAC_IRQ_MASK); + *((volatile unsigned int*) rckemacif->irq_address) = tmp; + + /* Reset */ + *((volatile unsigned*) (FPGA_BASE + IRQ_RESET + rckemacif->core * 2 * 4)) = (1 << rckemacif->num_emac); } err_t rckemacif_wait(struct netif* netif, uint32_t poll) { - return ERR_OK; -#if 0 rckemacif_t* rckemacif = netif->state; struct eth_hdr *ethhdr; struct pbuf *p = NULL; err_t err = ERR_OK; - LWIP_DEBUGF(NETIF_DEBUG, ("Hello from rckemacif_wait!\n")); - if (poll) { if (mailbox_ptr_tryfetch(&(rckemacif->mbox), (void**) &p)) return err; @@ -396,6 +439,8 @@ err_t rckemacif_wait(struct netif* netif, uint32_t poll) /* points to packet payload, which starts with an Ethernet header */ ethhdr = p->payload; + //LWIP_DEBUGF(NETIF_DEBUG, ("Got packet of type 0x%x!\n", htons(ethhdr->type))); + switch (htons(ethhdr->type)) { /* IP or ARP packet? */ case ETHTYPE_ARP: @@ -406,7 +451,7 @@ err_t rckemacif_wait(struct netif* netif, uint32_t poll) case ETHTYPE_PPPOE: #endif /* PPPOE_SUPPORT */ /* full packet send to tcpip_thread to process */ - if ((err = mynetif[netif->num]->input(p, mynetif[netif->num])) != ERR_OK) { + if ((err = mynetif->input(p, mynetif)) != ERR_OK) { LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_poll: IP input error\n")); pbuf_free(p); } @@ -417,21 +462,20 @@ err_t rckemacif_wait(struct netif* netif, uint32_t poll) } return err; -#endif } err_t rckemacif_init(struct netif* netif) { rckemacif_t* rckemacif; - int num, num_emac; + int num_emac; int macPorts; int i, tmp, x, y, z, core; uint64_t tile_offset; - uint16_t write_offset = 0; - uint16_t read_offset = 0; - int mode = 0; - int subdest = 0; - int route = 0; + uint16_t write_offset; + uint16_t read_offset; + int mode; + int subdest; + int route; LWIP_ASSERT("netif != NULL", (netif != NULL)); @@ -457,7 +501,8 @@ err_t rckemacif_init(struct netif* netif) kfree(rckemacif, sizeof(rckemacif_t)); return ERR_MEM; } - memset(rckemacif->rx_buffer, 0, BUFFER_SIZE); + memset(rckemacif->rx_buffer, 0x00, 0x20); + memset(rckemacif->rx_buffer + 0x20, 0xDA, BUFFER_SIZE - 0x20); rckemacif->rx_buffer_max = CLINE_PACKETS(BUFFER_SIZE) - 1; /* allocate the send buffers */ @@ -468,7 +513,8 @@ err_t rckemacif_init(struct netif* netif) kfree(rckemacif, sizeof(rckemacif_t)); return ERR_MEM; } - memset(rckemacif->tx_buffer, 0, BUFFER_SIZE); + memset(rckemacif->tx_buffer, 0x00, 0x20); + memset(rckemacif->tx_buffer + 0x20, 0xDA, BUFFER_SIZE - 0x20); rckemacif->tx_buffer_max = CLINE_PACKETS(BUFFER_SIZE) - 1; mailbox_ptr_init(&rckemacif->mbox); @@ -478,42 +524,42 @@ err_t rckemacif_init(struct netif* netif) * (offset, subdest, route) */ if (z == 0) { - tmp = ReadConfigReg(CRB_OWN + GLCFG0); - rckemacif->irq_address = CRB_OWN + GLCFG0; + tmp = ReadConfigReg(CRB_OWN + LUT0); + rckemacif->irq_address = (void*) (CRB_OWN + GLCFG0); } else { - tmp = ReadConfigReg(CRB_OWN + GLCFG1); - rckemacif->irq_address = CRB_OWN + GLCFG1; + tmp = ReadConfigReg(CRB_OWN + LUT1); + rckemacif->irq_address = (void*) (CRB_OWN + GLCFG1); } - tile_offset = (unsigned long long)((unsigned long long) tmp & 0x3FF) << 24; + tile_offset = (uint64_t)((uint64_t) tmp & 0x3FF) << 24; subdest = (tmp >> 10) & 0x07; route = (tmp >> 13) & 0xFF; mode = (subdest << 8) + route; + LWIP_DEBUGF(NETIF_DEBUG, ("tile_offset = 0x%llx\n", tile_offset)); /* get fpga/sccKit port settings */ tmp = *((volatile int*)(FPGA_BASE + 0x822C)); + tmp = *((volatile int*)(FPGA_BASE + 0x822C)); macPorts = ((tmp >> 9 ) & 0xFF); - LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: eMAC0: %s eMAC1: %s eMAC2: %s eMAC3: %s\n", - (macPorts & EMAC0) != 0 ? "present" : "-", - (macPorts & EMAC1) != 0 ? "present" : "-", - (macPorts & EMAC2) != 0 ? "present" : "-", - (macPorts & EMAC3) != 0 ? "present" : "-")); + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: eMAC0: %s eMAC1: %s eMAC2: %s eMAC3: %s\n", + (macPorts & EMAC0) != 0 ? "present" : "-", + (macPorts & EMAC1) != 0 ? "present" : "-", + (macPorts & EMAC2) != 0 ? "present" : "-", + (macPorts & EMAC3) != 0 ? "present" : "-")); // determine device and emac number - for(num=0; (num<4) && (mynetif[num] != NULL); num++) - ; - if (num >= 4) - return ERR_ARG; - for(i=0, num_emac=0; (i<=num) && (num_emac < 4); i++) { - while (((macPorts & (1 << num_emac)) == 0) && (num_emac < 4)) - num_emac++; - } + num_emac=0; + while (((macPorts & (1 << num_emac)) == 0) && (num_emac < 4)) + num_emac++; if (num_emac >= 4) return ERR_ARG; - mynetif[num] = netif; + mynetif = netif; rckemacif->num_emac = num_emac; - LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: map device %d to eMAC %d\n", num, num_emac)); + LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: used eMAC device %d\n", num_emac)); + + tmp = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); + tmp = read_emac(num_emac, EMAC_IPCONF+RECEIVER1_ADDRESS, 0); if (core == 0) { /* Only core 0 initialize the xilinx port */ @@ -524,23 +570,23 @@ err_t rckemacif_init(struct netif* netif) int add_filter_mod = 0; /* Disable tx and rx flow control of eMAC */ - LWIP_DEBUGF(NETIF_DEBUG, ("Disabling tx/rx flow control of eMAC%d\n", num_emac)); - flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); + LWIP_DEBUGF(NETIF_DEBUG, ("Disabling tx/rx flow control of eMAC%d\n", num_emac)); + flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); /* Set top 3 bits of the flow control configuration to zero, * therefore disabling tx and rx flow control */ flow_control &= 0x7FFFFFF; - write_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0, flow_control); + write_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0, flow_control); /* Sanity check */ flow_control = read_emac(num_emac, EMAC_IPCONF+CONFIG_FLOW_CONTROL_ADD, 0); - LWIP_DEBUGF(NETIF_DEBUG, (" CONFIG_FLOW_CONTROL_ADD set: 0x%x\n", flow_control)); + LWIP_DEBUGF(NETIF_DEBUG, (" CONFIG_FLOW_CONTROL_ADD set: 0x%x\n", flow_control)); /* Setting the tx configuration bit to enable the transmitter and * set to full duplex mode. */ - LWIP_DEBUGF(NETIF_DEBUG, ("Setting rx configuration of eMAC%d\n", num_emac)); + LWIP_DEBUGF(NETIF_DEBUG, ("Setting rx configuration of eMAC%d\n", num_emac)); transmitter_addr = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); /* Now set the relevant bits and write back into the register: @@ -552,7 +598,7 @@ err_t rckemacif_init(struct netif* netif) write_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0, transmitter_addr); transmitter_addr = read_emac(num_emac, EMAC_IPCONF+TRANSMITTER_ADDRESS, 0); - LWIP_DEBUGF(NETIF_DEBUG, (" TRANSMITTER_ADDRESS set: %x\n", transmitter_addr)); + LWIP_DEBUGF(NETIF_DEBUG, (" TRANSMITTER_ADDRESS set: %x\n", transmitter_addr)); /* Setting the rx configuration bit to enable the transmitter and * set to full duplex mode. @@ -602,32 +648,29 @@ err_t rckemacif_init(struct netif* netif) * 31 (promiscuous mode) = 1 not working, but thats ok! */ add_filter_mod |= (1 << 31); - write_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0, add_filter_mod); + write_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0, add_filter_mod); - add_filter_mod = read_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0); + add_filter_mod = read_emac(num_emac, EMAC_IPCONF+ADD_FILTER_MOD, 0); LWIP_DEBUGF(NETIF_DEBUG, (" ADD_FILTER_MOD set: %x\n", add_filter_mod)); } sleep(3); /* Start address */ - LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer %p (%lx phys)\n", rckemacif->rx_buffer, virt_to_phys(rckemacif->rx_buffer))); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer %p (%lx phys)\n", rckemacif->rx_buffer, virt_to_phys((uint32_t)rckemacif->rx_buffer))); /**** Receiver configuration ****/ - uint32_t utmp = virt_to_phys(rckemacif->rx_buffer); - uint32_t addr_offset = tile_offset + utmp; - addr_offset >>= 5; - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core, addr_offset); - utmp = read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer set to @%x\n", utmp)); + uint64_t addr_offset = (tile_offset + (uint64_t) virt_to_phys((uint32_t) rckemacif->rx_buffer)) >> 5; + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core, (uint32_t) addr_offset); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer set to @%x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_START_ADDRESS, core))); - /* Set buffer write offset */ + /* Get buffer write offset */ write_offset = read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_WRITE_OFFSET, core); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer write offset at: %d\n", write_offset)); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer write offset at: %d\n", write_offset)); /* Set buffer read offset to write offset */ - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core, write_offset); + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core, write_offset); LWIP_DEBUGF(NETIF_DEBUG, (" RX Buffer read offset set to: %d\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_READ_OFFSET, core))); rckemacif->rx_read_offset = write_offset; @@ -637,49 +680,46 @@ err_t rckemacif_init(struct netif* netif) /* Threshold */ write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core, 0x01); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Threshold set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core))); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Threshold set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_BUFFER_THRESHOLD, core))); /* Route */ - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core, (core << 24) | (((y << 4) | x) << 16) | mode); + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core, (z << 24) | (((y << 4) | x) << 16) | mode); LWIP_DEBUGF(NETIF_DEBUG, (" RX Mode set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_MODE, core))); // determine mac address - uint32_t mac1 = *((uint32_t*)(FPGA_BASE+0x7E00)); - uint32_t mac2 = *((uint32_t*)(FPGA_BASE+0x7E04)); - uint64_t mac = (((unsigned long long)mac1) << 32) + ( unsigned long long ) mac2; + uint32_t mac1 = *((volatile uint32_t*)(FPGA_BASE+0x7E00)); + uint32_t mac2 = *((volatile uint32_t*)(FPGA_BASE+0x7E04)); + uint64_t mac = (((unsigned long long)mac1) << 32) + (unsigned long long) mac2; if (mac == 0x00) mac = MAC_ADDRESS; /* Calculate mac address of core depending on selected emac device */ mac = mac + (1 << num_emac) * 0x100 + core; + for (i=0; i<6; i++) + mynetif->hwaddr[5-i] = (mac >> (i*8)) & 0xFF; LWIP_DEBUGF(NETIF_DEBUG, ("rckemacif_init: MAC address ")); - for (i=0; i<6; i++) { - mynetif[num]->hwaddr[i] = mac & 0xFF; - mac = mac >> 8; - LWIP_DEBUGF(NETIF_DEBUG, ("%02x ", mynetif[num]->hwaddr[i])); - } + for (i=0; i<6; i++) + LWIP_DEBUGF(NETIF_DEBUG, ("%02x ", mynetif->hwaddr[i])); LWIP_DEBUGF(NETIF_DEBUG, ("\n")); write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core, MAC_HI(mac)); - LWIP_DEBUGF(NETIF_DEBUG, (" MAC1 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core))); - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core, MAC_LO(mac)); - LWIP_DEBUGF(NETIF_DEBUG, (" MAC2 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core))); + LWIP_DEBUGF(NETIF_DEBUG, (" MAC1 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_HI, core))); + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core, MAC_LO(mac)); + LWIP_DEBUGF(NETIF_DEBUG, (" MAC2 set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_MAC_ADDRESS_LO, core))); - /* Activate network port by setting enable bit */ - write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core, 0x01); - LWIP_DEBUGF(NETIF_DEBUG, (" RX Port enable set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core))); + /* Activate network port by setting enable bit */ + write_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core, 0x01); + LWIP_DEBUGF(NETIF_DEBUG, (" RX Port enable set to %x\n", read_emac(num_emac, EMAC_RX_CONTROL + EMAC_RX_NETWORK_PORT_ENABLE, core))); /**** Transfer configuration ****/ /* Start address */ - LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer %p (%lx phys)\n", rckemacif->tx_buffer, virt_to_phys(rckemacif->tx_buffer))); - utmp = virt_to_phys(rckemacif->tx_buffer); - write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core, (tmp + tile_offset) >> 5); - utmp = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core); - LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer set to @%x\n", tmp)); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer %p (%lx phys)\n", rckemacif->tx_buffer, virt_to_phys((uint32_t)rckemacif->tx_buffer))); + write_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core, (uint32_t) (((uint64_t) virt_to_phys((uint32_t)rckemacif->tx_buffer) + tile_offset) >> 5)); + LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer set to @%x\n", read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_START_ADDRESS, core))); - /* Get buffer read offset */ - read_offset = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_READ_OFFSET, core); + /* Get buffer read offset */ + read_offset = read_emac(num_emac, EMAC_TX_CONTROL + EMAC_TX_BUFFER_READ_OFFSET, core); LWIP_DEBUGF(NETIF_DEBUG, (" TX Buffer read offset at: %d\n", read_offset)); /* Set buffer write offset to read offset */ @@ -717,7 +757,7 @@ err_t rckemacif_init(struct netif* netif) /* administrative details */ netif->name[0] = 'e'; netif->name[1] = 'n'; - netif->num = num; + netif->num = 0; /* downward functions */ netif->output = etharp_output; netif->linkoutput = rckemacif_output; diff --git a/drivers/net/rckemac.h b/drivers/net/rckemac.h index b8a8a5ae..2c53523f 100644 --- a/drivers/net/rckemac.h +++ b/drivers/net/rckemac.h @@ -31,10 +31,10 @@ typedef struct rckemacif { struct eth_addr *ethaddr; /* Add whatever per-interface state that is needed here. */ - uint8_t* tx_buffer; uint8_t* rx_buffer; uint32_t rx_buffer_max; uint32_t rx_read_offset; + uint8_t* tx_buffer; uint32_t tx_buffer_max; uint32_t tx_write_offset; void* irq_address;