- refactored network
git-svn-id: http://moon:8086/svn/mips@204 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
+407
@@ -0,0 +1,407 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include "libsys.h"
|
||||
#include "fifo.h"
|
||||
#include "emac.h"
|
||||
#include "ethernet.h"
|
||||
#include "arp.h"
|
||||
#include "icmp.h"
|
||||
#include "ipv4.h"
|
||||
#include "udp.h"
|
||||
#include "dhcp.h"
|
||||
#include "gpio.h"
|
||||
#include "mii-bitbang.h"
|
||||
#include "marvell_88e1111.h"
|
||||
|
||||
gpio_if_t gpio;
|
||||
gpio_if_t mii_gpio;
|
||||
|
||||
#define BUFFER_SIZE (32*1024*1024)
|
||||
|
||||
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
|
||||
|
||||
#define NOT_SIM 1
|
||||
|
||||
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(gpio_if_t *pObj, uint16_t phy_id, uint32_t speed)
|
||||
{
|
||||
uint16_t val;
|
||||
|
||||
switch(speed)
|
||||
{
|
||||
case MPHY_CONTROL_SPD_SEL_10:
|
||||
val = MPHY_CONTROL_DUPLEX;
|
||||
MiiGpio_PhyWrite(pObj, phy_id, MPHY_CONTROL_REG, val);
|
||||
break;
|
||||
|
||||
case MPHY_CONTROL_SPD_SEL_100:
|
||||
val = MPHY_CONTROL_SPD_SEL_LSB | MPHY_CONTROL_DUPLEX;
|
||||
MiiGpio_PhyWrite(pObj, phy_id, MPHY_CONTROL_REG, val);
|
||||
break;
|
||||
|
||||
case MPHY_CONTROL_SPD_SEL_1000:
|
||||
val = MPHY_CONTROL_SPD_SEL_MSB | MPHY_CONTROL_DUPLEX;
|
||||
MiiGpio_PhyWrite(pObj, phy_id, MPHY_CONTROL_REG, val);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
val = MiiGpio_PhyRead(&mii_gpio, phy_id, MPHY_CONTROL_REG);
|
||||
val |= MPHY_CONTROL_RESET;
|
||||
MiiGpio_PhyWrite(&mii_gpio, phy_id, MPHY_CONTROL_REG, val);
|
||||
|
||||
val = MiiGpio_PhyRead(&mii_gpio, phy_id, MPHY_CONTROL_REG);
|
||||
val |= MPHY_CONTROL_LOOPBACK;
|
||||
MiiGpio_PhyWrite(&mii_gpio, phy_id, MPHY_CONTROL_REG, val);
|
||||
|
||||
}
|
||||
|
||||
void Phy_print_regs(gpio_if_t *pObj, 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(&mii_gpio, 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;
|
||||
ARP *pARP;
|
||||
IPV4 *pIPV4;
|
||||
UDP *pUDP;
|
||||
DHCP *pDHCP;
|
||||
uint32_t start, stop;
|
||||
rx_descr_t rx_descr;
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
gpio_init(&gpio, SYS_GPIO_0_BASE);
|
||||
|
||||
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, GPIO_0_MASK_LED, GPIO_0_ALIGN_LED, GPIO_DIR_OFFSET, GPIO_0_MASK_LED);
|
||||
gpio_write(&gpio, GPIO_0_MASK_LED, GPIO_0_ALIGN_LED, GPIO_DATA_OFFSET, 0);
|
||||
|
||||
// MDIO
|
||||
gpio_write(&gpio, GPIO_0_MASK_MDIO, GPIO_0_ALIGN_MDIO, GPIO_DIR_OFFSET, GPIO_0_MDIO_RST | GPIO_0_MDIO_MDC);
|
||||
|
||||
// Reset PHY
|
||||
gpio_write(&gpio, GPIO_0_MDIO_RST, GPIO_0_ALIGN_MDIO, GPIO_DATA_OFFSET, 1);
|
||||
#if NOT_SIM
|
||||
sleep(1);
|
||||
gpio_write(&gpio, GPIO_0_MDIO_RST, GPIO_0_ALIGN_MDIO, GPIO_DATA_OFFSET, 0);
|
||||
sleep(100);
|
||||
|
||||
gpio_read(&gpio, ~0, 0, GPIO_DIR_OFFSET, &res);
|
||||
|
||||
printf("Dir = %08X\n", res);
|
||||
// while(1)
|
||||
{
|
||||
gpio_read(&gpio, GPIO_0_MASK_LED, GPIO_0_ALIGN_LED, GPIO_DATA_OFFSET, &res);
|
||||
printf("LED-Data = %08X\n", res);
|
||||
gpio_write(&gpio, GPIO_0_MASK_LED, GPIO_0_ALIGN_LED, GPIO_DATA_OFFSET, res + 1);
|
||||
gpio_read(&gpio, GPIO_0_MASK_BTN, GPIO_0_ALIGN_BTN, GPIO_DATA_OFFSET, &res);
|
||||
printf("Btn-Data = %08X\n", res);
|
||||
gpio_read(&gpio, GPIO_0_MASK_MDIO, GPIO_0_ALIGN_MDIO, GPIO_DATA_OFFSET, &res);
|
||||
printf("MDIO-Data = %08X\n", res);
|
||||
sleep(100);
|
||||
}
|
||||
#endif
|
||||
|
||||
MiiGpio_Init(&mii_gpio);
|
||||
// Phy_loopback_enable(&mii_gpio, PHY_ADDR, MPHY_CONTROL_SPD_SEL_100);
|
||||
// printf("Set loopback mode.\n\r");
|
||||
|
||||
/* set 100mbps and reset PHY */
|
||||
phy_reg = 0x3300;
|
||||
MiiGpio_PhyWrite(&mii_gpio, PHY_ADDR, 0, phy_reg | 0x8000);
|
||||
|
||||
/* wait for reset to complete */
|
||||
while (MiiGpio_PhyRead(&mii_gpio, PHY_ADDR, 0) & 0x8000);
|
||||
|
||||
/* set auto negotiation */
|
||||
phy_reg = MiiGpio_PhyRead(&mii_gpio, PHY_ADDR, 0);
|
||||
MiiGpio_PhyWrite(&mii_gpio, PHY_ADDR, 0, phy_reg | 0x0200);
|
||||
|
||||
/* wait for auto negotiation to complete */
|
||||
while (!(MiiGpio_PhyRead(&mii_gpio, PHY_ADDR, 1) & 0x0024))
|
||||
{
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
Phy_print_regs(&mii_gpio, 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");
|
||||
}
|
||||
|
||||
gpio_read(&gpio, GPIO_0_MASK_BTN, GPIO_0_ALIGN_BTN, GPIO_DATA_OFFSET, &res);
|
||||
|
||||
if (!res)
|
||||
continue;
|
||||
|
||||
// printf("SYS_EMAC_RX_STAT = %08X\n", *pEmac_rx_ctrl);
|
||||
// printf("SYS_EMAC_RX_SIZE = %08X\n", *pEmac_rx_size);
|
||||
|
||||
/*
|
||||
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
|
||||
{
|
||||
Eth_pkt_recv(buffer);
|
||||
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);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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)];
|
||||
|
||||
Eth_pkt_create(&packet, TYPE_PROTO_IP, eth_myself, pARP->eth_addr_src);
|
||||
ICMPSendRequest(&packet, myIP, arpIpDst, data, sizeof(data));
|
||||
Eth_pkt_send(&packet);
|
||||
|
||||
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;
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user