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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [libchip/] [network/] [cs8900.c] - Rev 1765

Compare with Previous | Blame | View Log

/*
  ------------------------------------------------------------------------
  cs8900.c,v 1.3 2002/01/04 18:17:23 joel Exp
  ------------------------------------------------------------------------
 
  My Right Boot, a boot ROM for embedded hardware.
 
  Copyright Cybertec Pty Ltd, 2000
  All rights reserved Cybertec Pty Ltd, 2000
 
  COPYRIGHT (c) 1989-1998.
  On-Line Applications Research Corporation (OAR).
 
  The license and distribution terms for this file may be
  found in the file LICENSE in this distribution or at
  http://www.OARcorp.com/rtems/license.html.
 
  ------------------------------------------------------------------------
 
  CS8900 net boot driver.
 
 */
 
#include <rtems/bspIo.h>
#include <rtems.h>
 
#include <libchip/cs8900.h>
 
/*
 * Our local data.
 */
 
#ifdef CS8900_VERBOSE
static BOOLEAN cs8900_io_verbose;
#endif
 
static rtems_isr_void_entry old_handler[CS8900_DEVICES];
static void                 *old_parameter[CS8900_DEVICES];
 
/*
 * Tables of IO addresses and interrupt levels for each device attached.
 */
 
static const unsigned long ethernet_io_base[CS8900_DEVICES] =
{
  ETHERNET_BASE
};
 
static const unsigned long ethernet_mem_base[CS8900_DEVICES] =
{
  ETHERNET_BASE + CS8900_MEMORY_BASE
};
 
static const unsigned int ethernet_irq_level[CS8900_DEVICES] =
{
  ETHERNET_IRQ_LEVEL
};
 
static const unsigned int ethernet_irq_priority[CS8900_DEVICES] =
{
  ETHERNET_IRQ_PRIORITY
};
 
static const unsigned int ethernet_irq_vector[CS8900_DEVICES] =
{
  ETHERNET_IRQ_VECTOR,
};
 
void cs8900_io_set_reg (int dev, unsigned short reg, unsigned short data)
{
#ifdef CS8900_DATA_BUS_SWAPPED
  data = (data >> 8) | (data << 8);
#endif
 
#ifdef CS8900_VERBOSE
  if (cs8900_io_verbose)
    printf ("CS8900: io set reg=0x%04x, data=0x%04x\n", reg, data);
#endif
 
  WRITE_REGISTER_16 (ethernet_io_base[dev] + reg, data);
}
 
unsigned short cs8900_io_get_reg (int dev, unsigned short reg)
{
  unsigned long data;
 
  READ_REGISTER_16 (ethernet_io_base[dev] + reg, data);
 
#ifdef CS8900_DATA_BUS_SWAPPED
  data = (data >> 8) | (data << 8);
#endif
 
#ifdef CS8900_VERBOSE
  if (cs8900_io_verbose)
    printk ("CS8900: io get reg=0x%04x, data=0x%04x\n", reg, data);
#endif
 
  return data;
}
 
void cs8900_mem_set_reg (int dev, unsigned long reg, unsigned short data)
{
#ifdef CS8900_DATA_BUS_SWAPPED
  data = (data >> 8) | (data << 8);
#endif
 
#ifdef CS8900_VERBOSE
  if (cs8900_io_verbose)
    printk ("CS8900: mem set reg=0x%04x, data=0x%04x\n", reg, data);
#endif
 
  WRITE_REGISTER_16 (ethernet_io_base[dev] + reg, data);
}
 
unsigned short cs8900_mem_get_reg (int dev, unsigned long reg)
{
  unsigned short data;
  READ_REGISTER_16 (ethernet_io_base[dev] + reg, data);
 
#ifdef CS8900_DATA_BUS_SWAPPED
  data = (data >> 8) | (data << 8);
#endif
 
#ifdef CS8900_VERBOSE
  if (cs8900_io_verbose)
    printk ("CS8900: mem get reg=0x%04x, data=0x%04x\n", reg, data);
#endif
 
  return data;
}
 
void cs8900_put_data_block (int dev, int len, unsigned char *data)
{
#ifndef CS8900_DATA_BUS_SWAPPED
  unsigned short swap_word;
#endif
  unsigned short *src = (unsigned short *) ((unsigned long) data);
  unsigned short *dst = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_TxFrameLoc);
 
  while (len > 1)
  {
#ifndef CS8900_DATA_BUS_SWAPPED
    swap_word = *src++;
    *dst++ = (swap_word >> 8) | (swap_word << 8);
#else
    *dst++ = *src++;
#endif
    len -= 2;
  }
 
  if (len)
  {
#ifndef CS8900_DATA_BUS_SWAPPED
    swap_word = *src++;
    *dst++ = (swap_word >> 8) | (swap_word << 8);
#else
    *dst++ = *src++;
#endif
  }  
}
 
unsigned short cs8900_get_data_block (int dev, unsigned char *data)
{
  unsigned short          swap_word;
  volatile unsigned short *src = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_RxLength);
  unsigned short          *dst;
  unsigned short          len;
  unsigned short          rx_len;
  unsigned short          len_odd;
 
#ifdef CS8900_DATA_BUS_SWAPPED
    swap_word = *src++;
    len = (swap_word >> 8) | (swap_word << 8);
#else
    len = *src++;
#endif
 
  dst = (unsigned short *) ((unsigned long) data);
 
  len_odd = len & 1;
  rx_len  = len & ~1;
 
  for (; rx_len; rx_len -= 2)
  {
#ifndef CS8900_DATA_BUS_SWAPPED
    swap_word = *src++;
    *dst++ = (swap_word >> 8) | (swap_word << 8);
#else
    *dst++ = *src++;
#endif
  }
 
  if (len_odd)
  {
#ifndef CS8900_DATA_BUS_SWAPPED
    swap_word = *src++;
    *dst++ = (swap_word >> 8) | (swap_word << 8);
#else
    *dst++ = *src++;
#endif
  }
 
  return len;
}
 
void
cs8900_tx_load (int dev, struct mbuf *m)
{
  volatile unsigned short *dst = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_TxFrameLoc);
  unsigned int            len;
  unsigned char           *src;
  int                     remainder = 0;
  unsigned char           remainder_data = '\0';
 
  while (m)
  {
    /*
     * We can get empty mbufs from the stack.
     */
 
    len = m->m_len;
    src = mtod (m, unsigned char*);
 
    if (len)
    {
      if (remainder)
      {
#ifndef CS8900_DATA_BUS_SWAPPED
        *dst++ = remainder_data | (*src++ << 8);
#else
        *dst++ = *src++ | (remainder_data << 8);
#endif
        len--;
        remainder = 0;
      }
 
      if (len & 1)
      {
        remainder = 1;
        len--;
      }
 
      for (; len; len -= 2)
#ifndef CS8900_DATA_BUS_SWAPPED
        *dst++ = (*src++) | (*(++src) << 8);
#else
      *dst++ = (*src++ << 8) | *(++src);
#endif
 
      if (remainder)
        remainder_data = *src++;
    }
 
    m = m->m_next;
  }
 
  if (remainder)
  {
#ifndef CS8900_DATA_BUS_SWAPPED
    *dst = (unsigned short) remainder_data;
#else
    *dst = (unsigned short) (remainder_data << 8);
#endif
  }
}
 
void cs8900_attach_interrupt (int dev, cs8900_device *cs)
{
  rtems_interrupt_catch_with_void (cs8900_interrupt, 
                                   ethernet_irq_vector[dev], 
                                   &old_handler[dev],
                                   cs,
                                   &old_parameter[dev]);
 
  CF_SIM_WRITE_ICR (CF_BASE, 
                    ethernet_irq_level[dev],
                    CF_SIM_ICR_AVEC_AUTO, 
                    ethernet_irq_level[dev], 
                    ethernet_irq_priority[dev]);
  CF_SIM_IMR_ENABLE (CF_BASE, 1 << ethernet_irq_level[dev]);
}
 
void cs8900_detach_interrupt (int dev)
{
  CF_SIM_IMR_DISABLE (CF_BASE, 1 << ethernet_irq_level[dev]);
 
  rtems_interrupt_catch_with_void (old_handler, 
                                   ethernet_irq_vector[dev], 
                                   NULL,
                                   old_parameter[dev],
                                   NULL);
}
 
void cs8900_get_mac_addr (int dev, unsigned char *mac_address)
{
  memcpy (mac_address, rct_get_mac_address (dev), 6);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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