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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [peripheral/] [eth.c] - Diff between revs 224 and 428

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

Rev 224 Rev 428
Line 79... Line 79...
  unsigned long mac_int;
  unsigned long mac_int;
 
 
  /* VAPI ID */
  /* VAPI ID */
  unsigned long base_vapi_id;
  unsigned long base_vapi_id;
 
 
 
  /* Ethernet PHY address */
 
  unsigned long phy_addr;
 
 
  /* RX and TX file names and handles */
  /* RX and TX file names and handles */
  char *rxfile, *txfile;
  char *rxfile, *txfile;
  int txfd;
  int txfd;
  int rxfd;
  int rxfd;
  off_t loopback_offset;
  off_t loopback_offset;
Line 167... Line 170...
/* utility functions */
/* utility functions */
static ssize_t eth_read_rx_file (struct eth_device *, void *, size_t);
static ssize_t eth_read_rx_file (struct eth_device *, void *, size_t);
static void eth_skip_rx_file (struct eth_device *, off_t);
static void eth_skip_rx_file (struct eth_device *, off_t);
static void eth_rx_next_packet (struct eth_device *);
static void eth_rx_next_packet (struct eth_device *);
static void eth_write_tx_bd_num (struct eth_device *, unsigned long value);
static void eth_write_tx_bd_num (struct eth_device *, unsigned long value);
 
static void eth_miim_trans (void *dat);
/* ========================================================================= */
/* ========================================================================= */
/*  TX LOGIC                                                                 */
/*  TX LOGIC                                                                 */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 
 
/*
/*
Line 708... Line 712...
          break;
          break;
#endif /* HAVE_ETH_PHY */
#endif /* HAVE_ETH_PHY */
        }
        }
 
 
      /* Set registers to default values */
      /* Set registers to default values */
 
      /* Zero all registers */
      memset (&(eth->regs), 0, sizeof (eth->regs));
      memset (&(eth->regs), 0, sizeof (eth->regs));
 
      /* Set those with non-zero reset defaults */
      eth->regs.moder = 0x0000A000;
      eth->regs.moder = 0x0000A000;
      eth->regs.ipgt = 0x00000012;
      eth->regs.ipgt = 0x00000012;
      eth->regs.ipgr1 = 0x0000000C;
      eth->regs.ipgr1 = 0x0000000C;
      eth->regs.ipgr2 = 0x00000012;
      eth->regs.ipgr2 = 0x00000012;
      eth->regs.packetlen = 0x003C0600;
      eth->regs.packetlen = 0x003C0600;
Line 729... Line 735...
      if (eth->base_vapi_id)
      if (eth->base_vapi_id)
        {
        {
          vapi_install_multi_handler (eth->base_vapi_id, ETH_NUM_VAPI_IDS,
          vapi_install_multi_handler (eth->base_vapi_id, ETH_NUM_VAPI_IDS,
                                      eth_vapi_read, dat);
                                      eth_vapi_read, dat);
        }
        }
 
 
    }
    }
}
}
 
 
/* ========================================================================= */
/* ========================================================================= */
 
 
Line 809... Line 816...
    case ETH_MIIADDRESS:
    case ETH_MIIADDRESS:
      return eth->regs.miiaddress;
      return eth->regs.miiaddress;
    case ETH_MIITX_DATA:
    case ETH_MIITX_DATA:
      return eth->regs.miitx_data;
      return eth->regs.miitx_data;
    case ETH_MIIRX_DATA:
    case ETH_MIIRX_DATA:
 
      /*printf("or1ksim: read MIIM RX: 0x%x\n",(int)eth->regs.miirx_data);*/
      return eth->regs.miirx_data;
      return eth->regs.miirx_data;
    case ETH_MIISTATUS:
    case ETH_MIISTATUS:
      return eth->regs.miistatus;
      return eth->regs.miistatus;
    case ETH_MAC_ADDR0:
    case ETH_MAC_ADDR0:
      return (((unsigned long) eth->mac_address[3]) << 24) |
      return (((unsigned long) eth->mac_address[3]) << 24) |
Line 901... Line 909...
    case ETH_MIIMODER:
    case ETH_MIIMODER:
      eth->regs.miimoder = value;
      eth->regs.miimoder = value;
      return;
      return;
    case ETH_MIICOMMAND:
    case ETH_MIICOMMAND:
      eth->regs.miicommand = value;
      eth->regs.miicommand = value;
 
      /* Perform MIIM transaction, if required */
 
      eth_miim_trans(dat);
      return;
      return;
    case ETH_MIIADDRESS:
    case ETH_MIIADDRESS:
      eth->regs.miiaddress = value;
      eth->regs.miiaddress = value;
      return;
      return;
    case ETH_MIITX_DATA:
    case ETH_MIITX_DATA:
      eth->regs.miitx_data = value;
      eth->regs.miitx_data = value;
      return;
      return;
    case ETH_MIIRX_DATA:
    case ETH_MIIRX_DATA:
      eth->regs.miirx_data = value;
      /* Register is R/O
 
      eth->regs.miirx_data = value;
 
      */
      return;
      return;
    case ETH_MIISTATUS:
    case ETH_MIISTATUS:
      eth->regs.miistatus = value;
      /* Register is R/O
 
      eth->regs.miistatus = value;
 
      */
      return;
      return;
 
 
    case ETH_MAC_ADDR0:
    case ETH_MAC_ADDR0:
      eth->mac_address[0] = value & 0xFF;
      eth->mac_address[0] = value & 0xFF;
      eth->mac_address[1] = (value >> 8) & 0xFF;
      eth->mac_address[1] = (value >> 8) & 0xFF;
      eth->mac_address[2] = (value >> 16) & 0xFF;
      eth->mac_address[2] = (value >> 16) & 0xFF;
      eth->mac_address[3] = (value >> 24) & 0xFF;
      eth->mac_address[3] = (value >> 24) & 0xFF;
Line 1231... Line 1246...
{
{
  struct eth_device *eth = dat;
  struct eth_device *eth = dat;
  eth->base_vapi_id = val.int_val;
  eth->base_vapi_id = val.int_val;
}
}
 
 
 
 
 
static void
 
eth_phy_addr (union param_val  val,
 
              void            *dat)
 
{
 
  struct eth_device *eth = dat;
 
  eth->phy_addr = val.int_val & ETH_MIIADDR_FIAD_MASK;
 
}
 
 
 
 
 
/*---------------------------------------------------------------------------*/
 
/*!Emulate MIIM transaction to ethernet PHY
 
 
 
   @param[in] dat  The config data structure                                 */
 
/*---------------------------------------------------------------------------*/
 
static void
 
eth_miim_trans (void *dat)
 
{
 
  struct eth_device *eth = dat;
 
  switch (eth->regs.miicommand)
 
    {
 
    case ((1 << ETH_MIICOMM_WCDATA_OFFSET)):
 
      /* Perhaps something to emulate here later, but for now do nothing */
 
      break;
 
 
 
    case ((1 << ETH_MIICOMM_RSTAT_OFFSET)):
 
 
 
      printf("or1ksim: eth_miim_trans: phy %d\n",(int)
 
             ((eth->regs.miiaddress >> ETH_MIIADDR_FIAD_OFFSET)&
 
              ETH_MIIADDR_FIAD_MASK));
 
      printf("or1ksim: eth_miim_trans: reg %d\n",(int)
 
             ((eth->regs.miiaddress >> ETH_MIIADDR_RGAD_OFFSET)&
 
              ETH_MIIADDR_RGAD_MASK));
 
 
 
      /*First check if it's the correct PHY to address */
 
      if (((eth->regs.miiaddress >> ETH_MIIADDR_FIAD_OFFSET)&
 
           ETH_MIIADDR_FIAD_MASK) == eth->phy_addr)
 
        {
 
          /* Correct PHY - now switch based on the register address in the PHY*/
 
          switch ((eth->regs.miiaddress >> ETH_MIIADDR_RGAD_OFFSET)&
 
                  ETH_MIIADDR_RGAD_MASK)
 
            {
 
            case MII_BMCR:
 
              eth->regs.miirx_data = BMCR_FULLDPLX;
 
              break;
 
            case MII_BMSR:
 
              eth->regs.miirx_data = BMSR_LSTATUS | BMSR_ANEGCOMPLETE |
 
                BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | BMSR_100FULL;
 
              break;
 
            case MII_PHYSID1:
 
              eth->regs.miirx_data = 0x22; /* Micrel PHYID */
 
              break;
 
            case MII_PHYSID2:
 
              eth->regs.miirx_data = 0x1613; /* Micrel PHYID */
 
              break;
 
            case MII_ADVERTISE:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_LPA:
 
              eth->regs.miirx_data = LPA_DUPLEX | LPA_100;
 
              break;
 
            case MII_EXPANSION:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_CTRL1000:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_STAT1000:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_ESTATUS:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_DCOUNTER:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_FCSCOUNTER:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_NWAYTEST:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_RERRCOUNTER:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_SREVISION:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_RESV1:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_LBRERROR:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_PHYADDR:
 
              eth->regs.miirx_data = eth->phy_addr;
 
              break;
 
            case MII_RESV2:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_TPISTATUS:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            case MII_NCONFIG:
 
              eth->regs.miirx_data = 0;
 
              break;
 
            default:
 
              eth->regs.miirx_data = 0xffff;
 
              break;
 
            }
 
        }
 
      else
 
        eth->regs.miirx_data = 0xffff; /* PHY doesn't exist, read all 1's */
 
      break;
 
 
 
    case ((1 << ETH_MIICOMM_SCANS_OFFSET)):
 
      /* From MAC's datasheet:
 
         A host initiates the Scan Status Operation by asserting the SCANSTAT
 
         signal. The MIIM performs a continuous read operation of the PHY
 
         Status register. The PHY is selected by the FIAD[4:0] signals. The
 
         link status LinkFail signal is asserted/deasserted by the MIIM module
 
         and reflects the link status bit of the PHY Status register. The
 
         signal NVALID is used for qualifying the validity of the LinkFail
 
         signals and the status data PRSD[15:0]. These signals are invalid
 
         until the first scan status operation ends. During the scan status
 
         operation, the BUSY signal is asserted until the last read is
 
         performed (the scan status operation is stopped).
 
 
 
         So for now - do nothing, leave link status indicator as permanently
 
         with link.
 
      */
 
 
 
      break;
 
 
 
    default:
 
      break;
 
    }
 
 
 
}
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Initialize a new Ethernet configuration
/*!Initialize a new Ethernet configuration
 
 
   ALL parameters are set explicitly to default values.                      */
   ALL parameters are set explicitly to default values.                      */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
Line 1260... Line 1415...
  new->tx_channel   = 0;
  new->tx_channel   = 0;
  new->rxfile       = strdup ("eth_rx");
  new->rxfile       = strdup ("eth_rx");
  new->txfile       = strdup ("eth_tx");
  new->txfile       = strdup ("eth_tx");
  new->sockif       = strdup ("or1ksim_eth");
  new->sockif       = strdup ("or1ksim_eth");
  new->base_vapi_id = 0;
  new->base_vapi_id = 0;
 
  new->phy_addr     = 0;
 
 
  return new;
  return new;
}
}
 
 
static void
static void
Line 1315... Line 1471...
  reg_config_param (sec, "tx_channel", PARAMT_INT,  eth_tx_channel);
  reg_config_param (sec, "tx_channel", PARAMT_INT,  eth_tx_channel);
  reg_config_param (sec, "rxfile",     PARAMT_STR,  eth_rxfile);
  reg_config_param (sec, "rxfile",     PARAMT_STR,  eth_rxfile);
  reg_config_param (sec, "txfile",     PARAMT_STR,  eth_txfile);
  reg_config_param (sec, "txfile",     PARAMT_STR,  eth_txfile);
  reg_config_param (sec, "sockif",     PARAMT_STR,  eth_sockif);
  reg_config_param (sec, "sockif",     PARAMT_STR,  eth_sockif);
  reg_config_param (sec, "vapi_id",    PARAMT_INT,  eth_vapi_id);
  reg_config_param (sec, "vapi_id",    PARAMT_INT,  eth_vapi_id);
 
  reg_config_param (sec, "phy_addr",   PARAMT_INT,  eth_phy_addr);
 
 
}       /* reg_ethernet_sec() */
}       /* reg_ethernet_sec() */
 
 
 
 
 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.