Line 36... |
Line 36... |
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
|
|
#include "cpu-utils.h"
|
#include "cpu-utils.h"
|
//#include "spr-defs.h"
|
|
#include "board.h"
|
#include "board.h"
|
#include "int.h"
|
#include "int.h"
|
#include "uart.h"
|
#include "uart.h"
|
#include "ethmac.h"
|
#include "ethmac.h"
|
#include "printf.h"
|
#include "printf.h"
|
Line 53... |
Line 52... |
//#define OUR_IP_LONG 0xc0a8649b
|
//#define OUR_IP_LONG 0xc0a8649b
|
|
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x0,0x14 // 192.168.0.20
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x0,0x14 // 192.168.0.20
|
//#define OUR_IP_LONG 0xc0a80014
|
//#define OUR_IP_LONG 0xc0a80014
|
|
|
|
|
|
//#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x22 // 192.168.1.34
|
|
//#define OUR_IP_LONG 0xc0a80122
|
|
|
#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x2 // 192.168.1.2
|
#define OUR_IP_BYTES 0xc0,0xa8,0x1,0x2 // 192.168.1.2
|
#define OUR_IP_LONG 0xc0a80102
|
#define OUR_IP_LONG 0xc0a80102
|
|
|
static char our_ip[4] = {OUR_IP_BYTES};
|
static char our_ip[4] = {OUR_IP_BYTES};
|
|
|
Line 70... |
Line 73... |
void oeth_dump_bds();
|
void oeth_dump_bds();
|
/* Interrupt functions */
|
/* Interrupt functions */
|
void oeth_interrupt(void);
|
void oeth_interrupt(void);
|
static void oeth_rx(void);
|
static void oeth_rx(void);
|
static void oeth_tx(void);
|
static void oeth_tx(void);
|
|
/* Function to calculate checksum of ping responses we send */
|
|
unsigned short calculate_checksum(char* dats, unsigned int len) ;
|
|
|
#define NEVER_PRINT_PACKET 1
|
// Global used to control whether we print out packets as we receive them
|
|
int print_packet_contents;
|
#define DISABLE_PRINTF 0
|
|
|
|
#if DISABLE_PRINTF==1
|
|
#undef printf
|
|
#endif
|
|
/* Let the ethernet packets use a space beginning here for buffering */
|
/* Let the ethernet packets use a space beginning here for buffering */
|
#define ETH_BUFF_BASE 0x01000000
|
#define ETH_BUFF_BASE 0x01000000
|
|
|
|
|
#define RXBUFF_PREALLOC 1
|
#define RXBUFF_PREALLOC 1
|
Line 93... |
Line 94... |
*/
|
*/
|
#define TX_TIMEOUT (2*HZ)
|
#define TX_TIMEOUT (2*HZ)
|
|
|
/* Buffer number (must be 2^n)
|
/* Buffer number (must be 2^n)
|
*/
|
*/
|
#define OETH_RXBD_NUM 8
|
#define OETH_RXBD_NUM 32
|
#define OETH_TXBD_NUM 8
|
#define OETH_TXBD_NUM 32
|
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1)
|
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1)
|
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1)
|
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1)
|
|
|
/* Buffer size
|
/* Buffer size
|
*/
|
*/
|
#define OETH_RX_BUFF_SIZE 2048
|
#define OETH_RX_BUFF_SIZE 2048
|
#define OETH_TX_BUFF_SIZE 2048
|
#define OETH_TX_BUFF_SIZE 2048
|
|
|
/* OR32 Page size def */
|
|
#define PAGE_SHIFT 13
|
|
#define PAGE_SIZE (1UL << PAGE_SHIFT)
|
|
|
|
/* How many buffers per page
|
|
*/
|
|
#define OETH_RX_BUFF_PPGAE (PAGE_SIZE/OETH_RX_BUFF_SIZE)
|
|
#define OETH_TX_BUFF_PPGAE (PAGE_SIZE/OETH_TX_BUFF_SIZE)
|
|
|
|
/* How many pages is needed for buffers
|
|
*/
|
|
#define OETH_RX_BUFF_PAGE_NUM (OETH_RXBD_NUM/OETH_RX_BUFF_PPGAE)
|
|
#define OETH_TX_BUFF_PAGE_NUM (OETH_TXBD_NUM/OETH_TX_BUFF_PPGAE)
|
|
|
|
/* Buffer size (if not XXBUF_PREALLOC
|
/* Buffer size (if not XXBUF_PREALLOC
|
*/
|
*/
|
#define MAX_FRAME_SIZE 0x600
|
#define MAX_FRAME_SIZE 0x600
|
//#define MAX_FRAME_SIZE 2500
|
//#define MAX_FRAME_SIZE 2500
|
|
|
Line 849... |
Line 836... |
regs->miitx_data = 0;
|
regs->miitx_data = 0;
|
regs->miiaddress = 0;
|
regs->miiaddress = 0;
|
regs->miicommand = 0;
|
regs->miicommand = 0;
|
|
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1;
|
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1;
|
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5;
|
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 |
|
|
ETH_MACADDR4 << 8 | ETH_MACADDR5;
|
|
|
/* Clear all pending interrupts
|
/* Clear all pending interrupts
|
*/
|
*/
|
regs->int_src = 0xffffffff;
|
regs->int_src = 0xffffffff;
|
|
|
/* Promisc, IFG, CRCEn
|
/* Promisc, IFG, CRCEn
|
*/
|
*/
|
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD;
|
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG |
|
|
OETH_MODER_CRCEN | OETH_MODER_FULLD;
|
|
|
/* Enable interrupt sources.
|
/* Enable interrupt sources.
|
*/
|
*/
|
|
|
regs->int_mask = OETH_INT_MASK_TXB |
|
regs->int_mask = OETH_INT_MASK_TXB |
|
Line 888... |
Line 877... |
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
|
|
/* Preallocated ethernet buffer setup */
|
/* Preallocated ethernet buffer setup */
|
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */
|
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */
|
|
|
/* Setup for TX buffers*/
|
// Setup TX Buffers
|
for(i = 0, k = 0; i < OETH_TX_BUFF_PAGE_NUM; i++) {
|
for(i = 0; i < OETH_TXBD_NUM; i++) {
|
for(j = 0; j < OETH_TX_BUFF_PPGAE; j++, k++) {
|
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
|
//tx_bd[k].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
|
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
|
tx_bd[k].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
|
tx_bd[i].addr = mem_addr;
|
tx_bd[k].addr = mem_addr;
|
|
mem_addr += OETH_TX_BUFF_SIZE;
|
mem_addr += OETH_TX_BUFF_SIZE;
|
}
|
}
|
}
|
|
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
|
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
|
|
|
/* Setup for RX buffers */
|
// Setup RX buffers
|
for(i = 0, k = 0; i < OETH_RX_BUFF_PAGE_NUM; i++) {
|
for(i = 0; i < OETH_RXBD_NUM; i++) {
|
for(j = 0; j < OETH_RX_BUFF_PPGAE; j++, k++) {
|
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ
|
rx_bd[k].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; /* Enable interrupt */
|
rx_bd[i].addr = mem_addr;
|
rx_bd[k].addr = mem_addr;
|
|
mem_addr += OETH_RX_BUFF_SIZE;
|
mem_addr += OETH_RX_BUFF_SIZE;
|
}
|
}
|
}
|
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps
|
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; /* Final buffer has wrap bit set */
|
|
|
|
/* Enable receiver and transmiter
|
/* Enable receiver and transmiter
|
*/
|
*/
|
regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
|
regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
|
|
|
Line 968... |
Line 953... |
/* Go through the TX buffs, search for unused one */
|
/* Go through the TX buffs, search for unused one */
|
for(i = next_tx_buf_num; i < OETH_TXBD_NUM; i++) {
|
for(i = next_tx_buf_num; i < OETH_TXBD_NUM; i++) {
|
|
|
if(!(tx_bd[i].len_status & OETH_TX_BD_READY)) /* Looking for buffer NOT ready for transmit. ie we can manipulate it */
|
if(!(tx_bd[i].len_status & OETH_TX_BD_READY)) /* Looking for buffer NOT ready for transmit. ie we can manipulate it */
|
{
|
{
|
#if NEVER_PRINT_PACKET==0
|
if (print_packet_contents)
|
printf("Oeth: Using TX_bd at 0x%lx\n",(unsigned long)&tx_bd[i]);
|
printf("Oeth: Using TX_bd at 0x%lx\n",(unsigned long)&tx_bd[i]);
|
#endif
|
|
if (next_tx_buf_num == OETH_TXBD_NUM-1) next_tx_buf_num = 0;
|
if (next_tx_buf_num == OETH_TXBD_NUM-1) next_tx_buf_num = 0;
|
else next_tx_buf_num++;
|
else next_tx_buf_num++;
|
|
|
return (struct oeth_bd*) &tx_bd[i];
|
return (struct oeth_bd*) &tx_bd[i];
|
}
|
}
|
Line 993... |
Line 978... |
|
|
/* print packet contents */
|
/* print packet contents */
|
static void
|
static void
|
oeth_print_packet(unsigned long add, int len)
|
oeth_print_packet(unsigned long add, int len)
|
{
|
{
|
#if NEVER_PRINT_PACKET==1
|
|
return;
|
|
#endif
|
|
|
|
int truncate = (len > 256);
|
int truncate = (len > 256);
|
int length_to_print = truncate ? 256 : len;
|
int length_to_print = truncate ? 256 : len;
|
|
|
int i;
|
int i;
|
Line 1037... |
Line 1019... |
{
|
{
|
printf("No more TX buffers available\n");
|
printf("No more TX buffers available\n");
|
return;
|
return;
|
}
|
}
|
*/
|
*/
|
#if NEVER_PRINT_PACKET==0
|
if (print_packet_contents)
|
printf("Oeth: Using TX_bd buffer address: 0x%lx\n",(unsigned long) tx_bd->addr);
|
printf("Oeth: Using TX_bd buffer address: 0x%lx\n",(unsigned long) tx_bd->addr);
|
#endif
|
|
|
|
/* Clear all of the status flags.
|
/* Clear all of the status flags.
|
*/
|
*/
|
tx_bd->len_status &= ~OETH_TX_BD_STATS;
|
tx_bd->len_status &= ~OETH_TX_BD_STATS;
|
|
|
Line 1775... |
Line 1756... |
int pkt_len, i;
|
int pkt_len, i;
|
int bad = 0;
|
int bad = 0;
|
|
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
|
|
|
#if NEVER_PRINT_PACKET==0
|
if (print_packet_contents)
|
printf("rx");
|
printf("rx");
|
#endif
|
|
|
|
/* Find RX buffers marked as having received data */
|
/* Find RX buffers marked as having received data */
|
for(i = 0; i < OETH_RXBD_NUM; i++)
|
for(i = 0; i < OETH_RXBD_NUM; i++)
|
{
|
{
|
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */
|
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */
|
Line 1821... |
Line 1801... |
/* Do something here with the data - copy it into userspace, perhaps. */
|
/* Do something here with the data - copy it into userspace, perhaps. */
|
// See if it's an ARP packet
|
// See if it's an ARP packet
|
packet_check_arp_header((void *)rx_bdp[i].addr );
|
packet_check_arp_header((void *)rx_bdp[i].addr );
|
// See if it's an ICMP echo request
|
// See if it's an ICMP echo request
|
packet_check_icmp_header((void *)rx_bdp[i].addr );
|
packet_check_icmp_header((void *)rx_bdp[i].addr );
|
#if NEVER_PRINT_PACKET==0
|
if (print_packet_contents)
|
|
{
|
oeth_print_packet(rx_bdp[i].addr, rx_bdp[i].len_status >> 16);
|
oeth_print_packet(rx_bdp[i].addr, rx_bdp[i].len_status >> 16);
|
printf("\t end of packet\n\n");
|
printf("\t end of packet\n\n");
|
#endif
|
}
|
/* finish up */
|
/* finish up */
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
|
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
|
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
|
|
|
|
|
Line 1842... |
Line 1823... |
static void
|
static void
|
oeth_tx(void)
|
oeth_tx(void)
|
{
|
{
|
volatile oeth_bd *tx_bd;
|
volatile oeth_bd *tx_bd;
|
int i;
|
int i;
|
#if NEVER_PRINT_PACKET==0
|
if (print_packet_contents)
|
printf("tx");
|
printf("tx");
|
#endif
|
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
|
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
|
|
|
/* Go through the TX buffs, search for one that was just sent */
|
/* Go through the TX buffs, search for one that was just sent */
|
for(i = 0; i < OETH_TXBD_NUM; i++)
|
for(i = 0; i < OETH_TXBD_NUM; i++)
|
{
|
{
|
Line 1859... |
Line 1840... |
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */
|
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */
|
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
|
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
|
|
|
/* Probably good to check for TX errors here */
|
/* Probably good to check for TX errors here */
|
|
|
#if NEVER_PRINT_PACKET==0
|
if (print_packet_contents)
|
printf("T%d",i);
|
printf("T%d",i);
|
#endif
|
|
|
|
}
|
}
|
}
|
}
|
return;
|
return;
|
}
|
}
|
|
|
|
|
int main ()
|
int main ()
|
{
|
{
|
|
|
|
print_packet_contents = 0; // Default to not printing packet contents.
|
|
|
/* Initialise vector handler */
|
/* Initialise vector handler */
|
int_init();
|
int_init();
|
|
|
/* Install ethernet interrupt handler, it is enabled here too */
|
/* Install ethernet interrupt handler, it is enabled here too */
|
int_add(ETH0_IRQ, oeth_interrupt, 0);
|
int_add(ETH0_IRQ, oeth_interrupt, 0);
|
Line 1884... |
Line 1865... |
cpu_enable_user_interrupts();
|
cpu_enable_user_interrupts();
|
|
|
last_char=0; /* Variable init for spin_cursor() */
|
last_char=0; /* Variable init for spin_cursor() */
|
next_tx_buf_num = 4; /* init for tx buffer counter */
|
next_tx_buf_num = 4; /* init for tx buffer counter */
|
|
|
#ifndef RTLSIM
|
|
uart_init(DEFAULT_UART); // init the UART before we can printf
|
uart_init(DEFAULT_UART); // init the UART before we can printf
|
printf("\n\teth ping program\n\n");
|
printf("\n\teth ping program\n\n");
|
printf("\n\tboard IP: %d.%d.%d.%d\n",our_ip[0]&0xff,our_ip[1]&0xff,
|
printf("\n\tboard IP: %d.%d.%d.%d\n",our_ip[0]&0xff,our_ip[1]&0xff,
|
our_ip[2]&0xff,our_ip[3]&0xff);
|
our_ip[2]&0xff,our_ip[3]&0xff);
|
#endif
|
|
|
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */
|
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */
|
|
|
//scan_ethphys(); /* Scan MIIM bus for PHYs */
|
//scan_ethphys(); /* Scan MIIM bus for PHYs */
|
//jb ethphy_init(); /* Attempt reset and configuration of PHY via MIIM */
|
//ethphy_init(); /* Attempt reset and configuration of PHY via MIIM */
|
//ethmac_scanstatus(); /* Enable scanning of status register via MIIM */
|
//ethmac_scanstatus(); /* Enable scanning of status register via MIIM */
|
|
|
/* clear tx_done, the tx interrupt handler will set it when it's been transmitted */
|
|
tx_done = 0;
|
|
|
|
|
|
#ifndef RTLSIM
|
|
/* Loop, monitoring user input from TTY */
|
/* Loop, monitoring user input from TTY */
|
while(1)
|
while(1)
|
{
|
{
|
char c;
|
char c;
|
|
|
while(!uart_check_for_char(DEFAULT_UART))
|
while(!uart_check_for_char(DEFAULT_UART))
|
{
|
{
|
spin_cursor();
|
spin_cursor();
|
oeth_monitor_rx();
|
//oeth_monitor_rx();
|
}
|
}
|
|
|
c = uart_getc(DEFAULT_UART);
|
c = uart_getc(DEFAULT_UART);
|
|
|
if (c == 's')
|
if (c == 's')
|
Line 1923... |
Line 1897... |
tx_packet((void*)big_ping_packet, 1514);
|
tx_packet((void*)big_ping_packet, 1514);
|
if (c == 'h')
|
if (c == 'h')
|
scan_ethphys();
|
scan_ethphys();
|
if (c == 'i')
|
if (c == 'i')
|
ethphy_init();
|
ethphy_init();
|
|
if (c == 'P')
|
|
print_packet_contents = print_packet_contents ? 0 : 1;
|
if (c == 'p')
|
if (c == 'p')
|
oeth_printregs();
|
oeth_printregs();
|
if (c == '0')
|
if (c == '0')
|
scan_ethphy(0);
|
scan_ethphy(0);
|
if (c == '1')
|
if (c == '1')
|
Line 1955... |
Line 1931... |
printf("\t---\n");
|
printf("\t---\n");
|
}
|
}
|
|
|
}
|
}
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|