#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "board.h" gpio_if_t gpio_led_data; gpio_if_t gpio_led_dir; gpio_if_t gpio_btn_data; gpio_if_t gpio_btn_dir; Mii_t mii; #define BUFFER_SIZE (32*1024*1024) #define WITH_DHCP_CLIENT fifo_t rx_descr_fifo; uint32_t *g_pBuf; uint32_t *g_buf_start; uint32_t *g_pBuf_end; typedef struct _srx_descr_t { uint32_t size; uint32_t *pBuf; uint32_t emac_status; uint32_t pkt_valid; } rx_descr_t; #define PHY_ADDR 0 #define PHY_IDO_REG 2 #define PHY_ID1_REG 3 void Time_print(void) { time_t curr_date; struct tm *pDate; curr_date = time(NULL); pDate = gmtime(&curr_date); puts(asctime(pDate)); } void handler6(void) { uint32_t i, num_bytes, num_words; volatile uint32_t *pEmac_ctrl = (uint32_t*)SYS_EMAC_RX_CTRL; volatile uint32_t *pEmac_size = (uint32_t*)SYS_EMAC_RX_SIZE; volatile uint32_t *pEmac_data = (uint32_t*)SYS_EMAC_RX_DATA; rx_descr_t rx_descr; if(EMAC_RX_is_avail()) { num_bytes = EMAC_RX_get_size(); num_words = num_bytes >> 2; if (num_bytes & 3) num_words++; rx_descr.pBuf = g_pBuf; rx_descr.size = num_bytes; rx_descr.emac_status = *pEmac_ctrl; rx_descr.pkt_valid = EMAC_RX_is_valid(); EMAC_RX_request(); for (i=0; i < num_words; i++) { *(g_pBuf++) = *(pEmac_data++); } if ((g_pBuf + 32768) > g_pBuf_end) g_pBuf = g_buf_start; EMAC_RX_free(); fifo_write(&rx_descr_fifo, (uint8_t*)&rx_descr, sizeof(rx_descr_t), 0, FIFO_NONBLOCK); } } void mii_loopback_enable(Mii_t *pMii, uint16_t phy_id, uint32_t speed) { uint16_t val; switch(speed) { case MPHY_CONTROL_SPD_SEL_10: val = MPHY_CONTROL_DUPLEX; MiiGpio_PhyWrite(pMii, phy_id, MPHY_CONTROL_REG, val); break; case MPHY_CONTROL_SPD_SEL_100: val = MPHY_CONTROL_SPD_SEL_LSB | MPHY_CONTROL_DUPLEX; MiiGpio_PhyWrite(pMii, phy_id, MPHY_CONTROL_REG, val); break; case MPHY_CONTROL_SPD_SEL_1000: val = MPHY_CONTROL_SPD_SEL_MSB | MPHY_CONTROL_DUPLEX; MiiGpio_PhyWrite(pMii, phy_id, MPHY_CONTROL_REG, val); break; default: break; } val = MiiGpio_PhyRead(pMii, phy_id, MPHY_CONTROL_REG); val |= MPHY_CONTROL_RESET; MiiGpio_PhyWrite(pMii, phy_id, MPHY_CONTROL_REG, val); val = MiiGpio_PhyRead(pMii, phy_id, MPHY_CONTROL_REG); val |= MPHY_CONTROL_LOOPBACK; MiiGpio_PhyWrite(pMii, phy_id, MPHY_CONTROL_REG, val); } void Phy_print_regs(Mii_t *pMii, uint16_t phy_id) { uint16_t i, j, val; printf("Phy registers:\n"); for (i=0; i < 32; i += 8) { for (j=0; j < 8; j++) { printf("%02X: %04X ", i+j, MiiGpio_PhyRead(pMii, phy_id, i+j)); } printf("\n"); } } // ------------------------------------------------------------------- uint8_t eth_bcst[6]= {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; uint8_t eth_zero[6]= {0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t eth_myself[6] = {0x00,0x00,0x31,0x10,0x19,0x70}; uint8_t ip_zero[4] = {0, 0, 0, 0}; uint8_t ip_bcast[4] = {255, 255, 255, 255}; uint8_t rxSrc[6]= {0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t rxDst[6]= {0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t arpHwSrc[6]= {0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t arpHwDst[6]= {0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t arpIpDst[4] = {192, 168, 178, 20}; uint8_t myIP[4] = {192, 168, 178, 31}; uint8_t mac_dst[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t mac_src[6] = {0x00, 0x00, 0x31, 0x10, 0x19, 0x70}; // data 64 .. 1500 uint8_t test_data[] = { 0x08, 0x00, 0x45, 0x00, 0x00, 0x30, 0xB3, 0xFE, 0x00, 0x00, 0x80, 0x11, 0x72, 0xBA, 0x0A, 0x00, 0x00, 0x03, 0x0A, 0x00, 0x00, 0x02, 0x04, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x89, 0x4D, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 }; uint8_t crc32_test_data[] = { 0x00, 0x0A, 0xE6, 0xF0, 0x05, 0xA3, 0x00, 0x12, 0x34, 0x56, 0x78, 0x90, 0x08, 0x00, 0x45, 0x00, 0x00, 0x30, 0xB3, 0xFE, 0x00, 0x00, 0x80, 0x11, 0x72, 0xBA, 0x0A, 0x00, 0x00, 0x03, 0x0A, 0x00, 0x00, 0x02, 0x04, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x89, 0x4D, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 }; // ------------------------------------------------------------------- int main() { uint16_t phy_reg; uint32_t res, i, j, size, rx_pkt_cnt, rx_inv_pkt_cnt, tx_pkt_cnt, rx_byte_cnt, tx_byte_cnt; volatile uint32_t *pEmac_rx_ctrl = (uint32_t*)SYS_EMAC_RX_CTRL; volatile uint32_t *pEmac_rx_size = (uint32_t*)SYS_EMAC_RX_SIZE; volatile uint32_t *pEmac_tx_ctrl = (uint32_t*)SYS_EMAC_TX_CTRL; volatile uint32_t *pEmac_tx_size = (uint32_t*)SYS_EMAC_TX_SIZE; volatile uint32_t *pEmac_data = (uint32_t*)SYS_EMAC_DATA_CACHED; volatile uint32_t *pEmac_maddr = (uint32_t*)SYS_EMAC_MADDR; volatile uint8_t *pEmac_maddr8 = (uint8_t*)SYS_EMAC_MADDR; uint8_t buffer[2048], data[1460]; packet_t packet; uint32_t start, stop; rx_descr_t rx_descr; setbuf(stdout, NULL); // Init GPIO BTN gpio_init(&gpio_btn_data, SYS_GPIO_0_DATA, GPIO_0_MASK_BTN, GPIO_0_ALIGN_BTN); gpio_init(&gpio_btn_dir, SYS_GPIO_0_DIR, GPIO_0_MASK_BTN, GPIO_0_ALIGN_BTN); gpio_clr(&gpio_btn_dir, GPIO_0_MASK_BTN); // Init GPIO LED gpio_init(&gpio_led_data, SYS_GPIO_0_DATA, GPIO_0_MASK_LED, GPIO_0_ALIGN_LED); gpio_init(&gpio_led_dir, SYS_GPIO_0_DIR, GPIO_0_MASK_LED, GPIO_0_ALIGN_LED); gpio_set(&gpio_led_dir, GPIO_0_MASK_LED); g_buf_start = (uint32_t*)malloc(BUFFER_SIZE); g_pBuf_end = g_buf_start + BUFFER_SIZE/sizeof(uint32_t); g_pBuf = g_buf_start; fifo_alloc(&rx_descr_fifo, sizeof(rx_descr_t)*BUFFER_SIZE/64); // LED gpio_write(&gpio_led_data, 0); // Create PHY interface MiiGpio_Init(&mii); // Reset PHY MiiGpio_Reset(&mii); // Phy_loopback_enable(&mii, PHY_ADDR, MPHY_CONTROL_SPD_SEL_100); // printf("Set loopback mode.\n\r"); /* set 100mbps and reset PHY */ phy_reg = 0x3300; MiiGpio_PhyWrite(&mii, PHY_ADDR, 0, phy_reg | 0x8000); /* wait for reset to complete */ while (MiiGpio_PhyRead(&mii, PHY_ADDR, 0) & 0x8000); /* set auto negotiation */ phy_reg = MiiGpio_PhyRead(&mii, PHY_ADDR, 0); MiiGpio_PhyWrite(&mii, PHY_ADDR, 0, phy_reg | 0x0200); /* wait for auto negotiation to complete */ while (!(MiiGpio_PhyRead(&mii, PHY_ADDR, 1) & 0x0024)) { usleep(10000); } Phy_print_regs(&mii, PHY_ADDR); EMAC_RX_reset(); EMAC_TX_reset(); rx_pkt_cnt = 0; rx_byte_cnt = 0; rx_inv_pkt_cnt = 0; tx_pkt_cnt = 0; tx_byte_cnt = 0; // Disable promiscious mode // *pEmac_rx_ctrl |= EMAC_RX_CTRL_PROMISCIOUS; *pEmac_rx_ctrl |= EMAC_RX_CTRL_GIGABIT; *pEmac_tx_ctrl |= EMAC_TX_CTRL_GIGABIT; // Set MAC address *(pEmac_maddr+0) = 0x00003110; *(pEmac_maddr+1) = 0x19700000; printf("Own MAC address = "); for (i=0; i < 6; i++) { printf("%02X", pEmac_maddr8[i]); if (i < 5) printf(":"); } printf("\n"); printf("SYS_EMAC_RX_STAT = %08X\n", *pEmac_rx_ctrl); printf("SYS_EMAC_MADDR_0 = %08X\n", *(pEmac_maddr+0)); printf("SYS_EMAC_MADDR_1 = %08X\n", *(pEmac_maddr+1)); for (i=0; i < sizeof(data); i++) data[i] = i; interrupt_register(6, (void*)handler6); interrupt_enable(6); *pEmac_rx_ctrl |= EMAC_RX_CTRL_INTEN; while(1) { while (fifo_read(&rx_descr_fifo, (uint8_t*)&rx_descr, sizeof(rx_descr_t), 0, FIFO_NONBLOCK)) { rx_pkt_cnt++; rx_byte_cnt += rx_descr.size; rx_inv_pkt_cnt += !rx_descr.pkt_valid; printf("---------------------------------------------------------------\n"); printf("Packet %d\n", rx_pkt_cnt); printf("---------------------------------------------------------------\n"); printf("RX data (%d bytes):\n", rx_descr.size); PrintBuffer8((uint8_t*)rx_descr.pBuf, 16, rx_descr.size); printf("\n"); printf("Total : %.2f kbyte\n", rx_pkt_cnt, (double)rx_byte_cnt/(1024)); printf("%d invalid packets received\n", rx_inv_pkt_cnt); printf("EMAC-Status (RX) : %08X\n", rx_descr.emac_status); printf("\n"); } res = gpio_read(&gpio_btn_data); if (!res) continue; #ifdef WITH_DHCP_CLIENT ARP *pARP; IPV4 *pIPV4; UDP *pUDP; DHCP *pDHCP; printf("---------------------------------------------------------------\n"); printf("- Send DHCP Discover ------------------------------------------\n"); printf("---------------------------------------------------------------\n"); Eth_pkt_create(&packet, TYPE_PROTO_IP, eth_myself, eth_bcst); DHCP_request_send(&packet, DHCP_MSG_DHCPDISCOVER, eth_myself, ip_zero, ip_bcast, NULL); Eth_pkt_send(&packet); sleep(500); do { int32_t size = Eth_pkt_recv(buffer); PrintBuffer8((uint8_t*)buffer, 16, size); pIPV4 = (IPV4*)&buffer[sizeof(eth_hdr_t)]; pUDP = (UDP*)&buffer[sizeof(eth_hdr_t) + sizeof(IPV4)]; pDHCP = (DHCP*)&buffer[sizeof(eth_hdr_t) + sizeof(IPV4) + sizeof(UDP)]; } while (pUDP->dst_port != 68); printf("---------------------------------------------------------------\n"); printf("- Send DHCP Request -------------------------------------------\n"); printf("---------------------------------------------------------------\n"); Eth_pkt_create(&packet, TYPE_PROTO_IP, eth_myself, eth_bcst); DHCP_request_send(&packet, DHCP_MSG_DHCPREQUEST, eth_myself, ip_zero, ip_bcast, pDHCP); Eth_pkt_send(&packet); sleep(500); continue; printf("---------------------------------------------------------------\n"); printf("- Send ARP Request --------------------------------------------\n"); printf("---------------------------------------------------------------\n"); Eth_pkt_create(&packet, TYPE_PROTO_ARP, eth_myself, eth_bcst); ArpRequest(&packet, eth_myself, myIP, eth_zero, arpIpDst); Eth_pkt_send(&packet); sleep(500); Eth_pkt_recv(buffer); pARP = (ARP*)&buffer[sizeof(eth_hdr_t)]; printf("---------------------------------------------------------------\n"); printf("- Send ICMP ---------------------------------------------------\n"); printf("---------------------------------------------------------------\n"); Eth_pkt_create(&packet, TYPE_PROTO_IP, eth_myself, pARP->eth_addr_src); ICMPSendRequest(&packet, myIP, arpIpDst, data, sizeof(data)); Eth_pkt_send(&packet); printf("---------------------------------------------------------------\n"); printf("- Send ARP UDP ------------------------------------------------\n"); printf("---------------------------------------------------------------\n"); Eth_pkt_create(&packet, TYPE_PROTO_IP, eth_myself, pARP->eth_addr_src); UDP_create(&packet, myIP, 10001, arpIpDst, 10002, data, sizeof(data)); Eth_pkt_send(&packet); continue; #endif start = clock(); Eth_pkt_create(&packet, TYPE_PROTO_IP, eth_myself, eth_bcst); UDP_create(&packet, myIP, 10001, arpIpDst, 10002, data, sizeof(data)); for (j=0; j < 10000; j++) { size = Eth_pkt_send(&packet); tx_byte_cnt += size; tx_pkt_cnt++; } stop = clock(); fprintf(stdout, "\n"); fprintf(stdout, "TX number of burst packets : %d\n", j); fprintf(stdout, "Throughput: %.2f Mbit/s\n\n", 8.0E-6*(j*size)/((double)(stop-start)/CLOCKS_PER_SEC)); fprintf(stdout, "%d packets transmitted (%d bytes)\n\n", tx_pkt_cnt, tx_byte_cnt); } return 0; }