OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [sw/] [tests/] [ethmac/] [sim/] [ethmac-rxtx.c] - Diff between revs 409 and 411

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 409 Rev 411
Line 39... Line 39...
//// Public License along with this source; if not, download it   ////
//// Public License along with this source; if not, download it   ////
//// from http://www.opencores.org/lgpl.shtml                     ////
//// from http://www.opencores.org/lgpl.shtml                     ////
////                                                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
 
 
#include "or32-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" // comment this out, UART uses simulation putc()
#include "ethmac.h"
#include "open-eth.h"
 
#include "printf.h"
 
#include "eth-phy-mii.h"
#include "eth-phy-mii.h"
 
 
volatile unsigned tx_done;
volatile unsigned tx_done;
volatile unsigned rx_done;
volatile unsigned rx_done;
static int next_tx_buf_num;
static int next_tx_buf_num;
Line 59... Line 56...
/* 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);
 
 
/* Defining RTLSIM turns off use of real printf'ing to save time in simulation */
 
#define RTLSIM
 
 
 
#ifdef RTLSIM
 
#define printk
 
#else
 
#define printk 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 92... Line 81...
/* Buffer size
/* Buffer size
*/
*/
#define OETH_RX_BUFF_SIZE       0x600-4
#define OETH_RX_BUFF_SIZE       0x600-4
#define OETH_TX_BUFF_SIZE       0x600-4
#define OETH_TX_BUFF_SIZE       0x600-4
 
 
/* 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          1518
#define MAX_FRAME_SIZE          1518
 
 
/* The buffer descriptors track the ring buffers.
/* The buffer descriptors track the ring buffers.
Line 132... Line 107...
};
};
 
 
#define PHYNUM 7
#define PHYNUM 7
 
 
// Data array of data to transmit, tx_data_array[]
// Data array of data to transmit, tx_data_array[]
#include "eth-rxtx-data.h"
//#include "eth-rxtx-data.h" // Not used
int tx_data_pointer;
int tx_data_pointer;
 
 
/* Scan the MIIM bus for PHYs */
 
void scan_ethphys(void)
 
{
 
  unsigned int phynum,regnum, i;
 
 
 
  volatile oeth_regs *regs;
 
  regs = (oeth_regs *)(OETH_REG_BASE);
 
 
 
  regs->miitx_data = 0;
 
 
 
  for(phynum=0;phynum<32;phynum++)
 
    {
 
      for (regnum=0;regnum<8;regnum++)
 
        {
 
          printk("scan_ethphys: phy %d r%d ",phynum, regnum);
 
 
 
          /* Now actually perform the read on the MIIM bus*/
 
          regs->miiaddress = (regnum << 8) | phynum;
 
          regs->miicommand = OETH_MIICOMMAND_RSTAT;
 
           /* Wait for command to be registered*/
 
          while(!(regs->miistatus & OETH_MIISTATUS_BUSY));
 
 
 
          regs->miicommand = 0;
 
 
 
          while(regs->miistatus & OETH_MIISTATUS_BUSY);
 
 
 
          printk("%x\n",regs->miirx_data);
 
        }
 
    }
 
}
 
 
 
 
 
 
 
void ethmac_scanstatus(void)
 
{
 
  volatile oeth_regs *regs;
 
  regs = (oeth_regs *)(OETH_REG_BASE);
 
 
 
 
 
  printk("Oeth: regs->miistatus %x regs->miirx_data %x\n",regs->miistatus, regs->miirx_data);
 
  regs->miiaddress = 0;
 
  regs->miitx_data = 0;
 
  regs->miicommand = OETH_MIICOMMAND_SCANSTAT;
 
  printk("Oeth: regs->miiaddress %x regs->miicommand %x\n",regs->miiaddress, regs->miicommand);
 
  //regs->miicommand = 0; 
 
  volatile int i; for(i=0;i<1000;i++);
 
  while(regs->miistatus & OETH_MIISTATUS_BUSY) ;
 
  //spin_cursor(); 
 
  //printk("\r"); 
 
  //or32_exit(0);
 
}
 
 
 
void
void
eth_mii_write(char phynum, short regnum, short data)
eth_mii_write(char phynum, short regnum, short data)
{
{
  static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
  static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
Line 213... Line 137...
}
}
 
 
 
 
 
 
// Wait here until all packets have been transmitted
// Wait here until all packets have been transmitted
void wait_until_all_tx_clear(void)
void
 
wait_until_all_tx_clear(void)
{
{
 
 
  int i;
  int i;
  volatile oeth_bd *tx_bd;
  volatile oeth_bd *tx_bd;
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
 
 
  int some_tx_waiting = 1;
  int some_tx_waiting = 1;
Line 228... Line 152...
    {
    {
      some_tx_waiting = 0;
      some_tx_waiting = 0;
      /* Go through the TX buffs, search for unused one */
      /* Go through the TX buffs, search for unused one */
      for(i = 0; i < OETH_TXBD_NUM; i++) {
      for(i = 0; i < OETH_TXBD_NUM; i++) {
 
 
        if((tx_bd[i].len_status & OETH_TX_BD_READY)) // Looking for buffer ready for transmit
        // Looking for buffer ready for transmit
 
        if((tx_bd[i].len_status & OETH_TX_BD_READY))
          some_tx_waiting = 1;
          some_tx_waiting = 1;
 
 
      }
      }
    }
    }
}
}
Line 260... Line 185...
  cr |= BMCR_SPEED100; // Clear fast eth. bit
  cr |= BMCR_SPEED100; // Clear fast eth. bit
  eth_mii_write(phynum, MII_BMCR, cr);
  eth_mii_write(phynum, MII_BMCR, cr);
}
}
 
 
 
 
void ethmac_setup(void)
void
 
ethmac_setup(void)
{
{
  // from arch/or32/drivers/open_eth.c
  // from arch/or32/drivers/open_eth.c
  volatile oeth_regs *regs;
  volatile oeth_regs *regs;
 
 
  regs = (oeth_regs *)(OETH_REG_BASE);
  regs = (oeth_regs *)(OETH_REG_BASE);
Line 369... Line 295...
    rx_bd[i].addr = mem_addr;
    rx_bd[i].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; // Last buffer wraps
 
 
  /* Enable JUST the transmiter
  /* Enable RX and TX in MAC
  */
  */
  regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN);
  regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN);
  regs->moder |= /*OETH_MODER_RXEN |*/ OETH_MODER_TXEN;
  regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
 
 
  next_tx_buf_num = 0; // init tx buffer pointer
  next_tx_buf_num = 0; // init tx buffer pointer
 
 
  return;
  return;
}
}
Line 526... Line 452...
  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;
 
 
  printk("r");
 
 
 
 
 
  /* 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++)
    {
    {
      bad=0;
      bad=0;
Line 604... Line 528...
          /* Probably good to check for TX errors here */
          /* Probably good to check for TX errors here */
 
 
          /* set our test variable */
          /* set our test variable */
          tx_done++;
          tx_done++;
 
 
          printk("T%d",i);
 
 
 
        }
        }
    }
    }
  return;
  return;
}
}
 
 
// A function and defines to fill and transmit a packet
// A function and defines to fill and transmit a packet
#define MAX_TX_BUFFER 1532
#define MAX_TX_BUFFER 1532
static char tx_buffer[MAX_TX_BUFFER];
static char tx_buffer[MAX_TX_BUFFER];
static unsigned long tx_data = 0x26fab2f2;
 
static inline char gen_next_tx_byte(void)
 
{
 
  // Bit of LFSR action
 
  tx_data = ((~(((((tx_data&(1<<25))>>25)^((tx_data&(1<<13))>>13))^((tx_data&(1<<2))>>2)))&0x01) | (tx_data<<1));
 
  //tx_data =(!((tx_data>>26) ^ (tx_data>>14) ^ (tx_data>>5) ^ (tx_data>>3)) & 0x1) | (tx_data<<1);
 
return (char) tx_data & 0xff;
 
}
 
 
 
void
void
fill_and_tx_packet(int size)
fill_and_tx_packet(int size)
{
{
  int i;
  int i;
  char tx_byte;
 
 
 
 
 
  volatile oeth_regs *regs;
  volatile oeth_regs *regs;
  regs = (oeth_regs *)(OETH_REG_BASE);
  regs = (oeth_regs *)(OETH_REG_BASE);
 
 
  volatile oeth_bd *tx_bd;
  volatile oeth_bd *tx_bd;
 
 
  //tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
  tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
  tx_bd = (volatile oeth_bd*) &tx_bd[next_tx_buf_num];
  tx_bd = (volatile oeth_bd*) &tx_bd[next_tx_buf_num];
 
 
 
 
  // If it's in use - wait
  // If it's in use - wait
  while ((tx_bd->len_status & OETH_TX_BD_IRQ));
  while ((tx_bd->len_status & OETH_TX_BD_IRQ));
 
 
#ifndef _ETH_RXTX_DATA_H_  
  // Use rand() function to generate data for transmission
  /* Copy the data into the transmit buffer, byte at a time */
  // Assumption: ethernet buffer descriptors are 4byte aligned
  char* data_b = (char*) tx_bd->addr;
  char* data_b = (char*) tx_bd->addr;
  for(i=0;i<size;i++)
  // We will fill with words until there' less than a word to go
 
  int words_to_fill = size / sizeof(unsigned int);
 
 
 
  unsigned int* data_w = (unsigned int*) data_b;
 
 
 
  for(i=0;i<words_to_fill;i++)
 
    data_w[i] = rand();
 
 
 
  // Point data_b to offset wher word fills ended
 
  data_b += (words_to_fill * sizeof(unsigned int));
 
 
 
  int leftover_size = size - (words_to_fill * sizeof(unsigned int));
 
 
 
  for(i=0;i<leftover_size;i++)
    {
    {
      data_b[i] = gen_next_tx_byte();
      data_b[i] = rand() & 0xff;
    }
    }
#endif
 
 
 
  tx_packet((void*)0, size);
  tx_packet((void*)0, size);
}
}
 
 
 
// Send a packet, the very first byte of which will be read by the testbench
 
// and used to indicate which test we'll use.
 
void
 
send_ethmac_rxtx_test_init_packet(char test)
 
{
 
  char cmd_tx_buffer[40];
 
  cmd_tx_buffer[0] = test;
 
  tx_packet(cmd_tx_buffer,  40); // Smallest packet that can be sent (I think)
 
}
 
 
// Loop to check if a number is prime by doing mod divide of the number
// Loop to check if a number is prime by doing mod divide of the number
// to test by every number less than it
// to test by every number less than it
int
int
is_prime_number(unsigned long n)
is_prime_number(unsigned long n)
Line 669... Line 601...
      return 0;
      return 0;
  return 1;
  return 1;
}
}
 
 
 
 
//#define WAIT_PACKET_TX(x) while(tx_done<x)
int
#define WAIT_PACKET_TX(x)
main ()
 
 
int main ()
 
{
{
  tx_data_pointer = 0;
  tx_data_pointer = 0;
 
 
  /* Initialise handler vector */
  /* Initialise handler vector */
  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);
 
 
  /* Enable interrupts in supervisor register */
  /* Enable interrupts in supervisor register */
  mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_IEE);
  cpu_enable_user_interrupts();
 
 
 
  /* Enable CPU timer */
 
  cpu_enable_timer();
 
 
  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 */
 
 
  /* clear tx_done, the tx interrupt handler will set it when it's been
  /* clear tx_done, the tx interrupt handler will set it when it's been
     transmitted */
     transmitted */
  tx_done = 0;
  tx_done = 0;
  rx_done = 0;
  rx_done = 0;
 
 
  printf("Start of large txdata buffer: 0x%x\n",
 
         (unsigned long)&tx_data_array[0]);
 
  printf("Slut of large txdata buffer: 0x%x\n",
 
         (unsigned long)&tx_data_array[262144]);
 
 
 
 
 
  ethphy_set_100mbit(0);
  ethphy_set_100mbit(0);
 
 
  oeth_enable_rx();
  send_ethmac_rxtx_test_init_packet(0xff); // Test value of 0xFF
 
 
 
  //oeth_enable_rx();
 
 
#define ETH_TX_MIN_PACKET_SIZE 512
#define ETH_TX_MIN_PACKET_SIZE 512
#define ETH_TX_NUM_PACKETS (ETH_TX_MIN_PACKET_SIZE + 32)
#define ETH_TX_NUM_PACKETS (ETH_TX_MIN_PACKET_SIZE + 32)
 
 
  #define CALCULATE_PRIMES 0
 
 
 
  char prime_check_results[2048];
 
  unsigned long num_to_check;
  unsigned long num_to_check;
  for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
  for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
      num_to_check<ETH_TX_NUM_PACKETS;
      num_to_check<ETH_TX_NUM_PACKETS;
      num_to_check++)
      num_to_check++)
    {
 
      fill_and_tx_packet(num_to_check);
      fill_and_tx_packet(num_to_check);
#if CALCULATE_PRIMES==1
 
      prime_check_results[num_to_check-5]
 
        = (char) is_prime_number(num_to_check);
 
      report(num_to_check | (0x1e<<24));
 
      report(prime_check_results[num_to_check-5] | (0x2e<<24));
 
#endif
 
    }
 
 
 
  oeth_disable_rx();
  oeth_disable_rx();
 
 
  // Now for 10mbit mode...
  // Now for 10mbit mode...
  ethphy_set_10mbit(0);
  ethphy_set_10mbit(0);
Line 731... Line 650...
  oeth_enable_rx();
  oeth_enable_rx();
 
 
  for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
  for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
      num_to_check<ETH_TX_NUM_PACKETS;
      num_to_check<ETH_TX_NUM_PACKETS;
      num_to_check++)
      num_to_check++)
    {
 
      fill_and_tx_packet(num_to_check);
      fill_and_tx_packet(num_to_check);
#if CALCULATE_PRIMES==1
 
      prime_check_results[num_to_check+(OETH_TX_BUFF_SIZE-5)]
 
        = (char) is_prime_number(num_to_check+OETH_TX_BUFF_SIZE);
 
      report(num_to_check | (0x1e<<24));
 
      report(prime_check_results[num_to_check+(OETH_TX_BUFF_SIZE-5)]
 
             | (0x2e<<24)
 
             );
 
#endif
 
    }
 
 
 
  oeth_disable_rx();
  oeth_disable_rx();
 
 
  // Go back to 100-mbit mode
  // Go back to 100-mbit mode
  ethphy_set_100mbit(0);
  ethphy_set_100mbit(0);
Line 753... Line 662...
  oeth_enable_rx();
  oeth_enable_rx();
 
 
  for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
  for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
      num_to_check<ETH_TX_NUM_PACKETS;
      num_to_check<ETH_TX_NUM_PACKETS;
      num_to_check++)
      num_to_check++)
    {
 
      fill_and_tx_packet(num_to_check);
      fill_and_tx_packet(num_to_check);
#if CALCULATE_PRIMES==1
 
      prime_check_results[num_to_check+(OETH_TX_BUFF_SIZE-5)]
 
        = (char) is_prime_number(num_to_check+OETH_TX_BUFF_SIZE);
 
      report(num_to_check | (0x1e<<24));
 
      report(prime_check_results[num_to_check+(OETH_TX_BUFF_SIZE-5)]
 
             | (0x2e<<24)
 
             );
 
#endif
 
    }
 
 
 
 
 
  exit(0x8000000d);
  exit(0x8000000d);
 
 
 
 
}
}
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.