Changeset a2117cd6 in rtems


Ignore:
Timestamp:
Sep 7, 2002, 11:09:47 PM (17 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, master
Children:
4e7ba21
Parents:
19ed3cf
Message:

2002-09-07 Chris Johns <ccj@…>

  • network/Makefile.am, network/README.cs8900, network/cs8900.c, network/cs8900.h: Significant update which corrects the problem where the cs8900.c file was actually the BSP glue. Joel did some hacking so this file will compile. Previously it required providing a target.h file to compile.
  • network/cs8900.c.bsp: New file.
Location:
c/src/libchip
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • c/src/libchip/ChangeLog

    r19ed3cf ra2117cd6  
     12002-09-07      Chris Johns <ccj@acm.org>
     2
     3        * network/Makefile.am, network/README.cs8900, network/cs8900.c,
     4        network/cs8900.h: Significant update which corrects the problem
     5        where the cs8900.c file was actually the BSP glue.  Joel did
     6        some hacking so this file will compile.  Previously it required
     7        providing a target.h file to compile.
     8        * network/cs8900.c.bsp: New file.
     9
    1102002-08-11      Ralf Corsepius <corsepiu@faw.uni-ulm.de>
    211
  • c/src/libchip/network/Makefile.am

    r19ed3cf ra2117cd6  
    99LIB = $(ARCH)/$(LIBNAME).a
    1010
    11 # add cs8900.c to work with it and make it compile
    12 C_FILES = dec21140.c i82586.c sonic.c if_fxp.c
     11C_FILES = cs8900.c dec21140.c i82586.c sonic.c if_fxp.c
    1312C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
    1413
     
    5352
    5453EXTRA_DIST = README README.cs8900 README.dec21140 README.i82586 README.sonic \
    55     cs8900.c dec21140.c i82586.c if_fxp.c sonic.c
     54    cs8900.c cs8900.c.bsp dec21140.c i82586.c if_fxp.c sonic.c
    5655
    5756include $(top_srcdir)/../../../automake/local.am
  • c/src/libchip/network/README.cs8900

    r19ed3cf ra2117cd6  
    22#  $Id$
    33#
     4
     5Target Support
     6==============
     7
     8The target is required to provide the low level support routines as
     9listed in the Configuration section of this file.
     10
     11The file cs8900.c.bsp is an example BSP file for a Coldfire processor.
    412
    513Conditionals
  • c/src/libchip/network/cs8900.c

    r19ed3cf ra2117cd6  
    1111  COPYRIGHT (c) 1989-1998.
    1212  On-Line Applications Research Corporation (OAR).
     13  Copyright assigned to U.S. Government, 1994.
    1314
    1415  The license and distribution terms for this file may be
    1516  found in the file LICENSE in this distribution or at
    1617  http://www.OARcorp.com/rtems/license.html.
    17  
     18
    1819  ------------------------------------------------------------------------
    1920
    2021  CS8900 net boot driver.
    2122
     23*/
     24
     25#include <sys/errno.h>
     26#include <string.h>
     27#include <stdio.h>
     28
     29/* #include <target.h>
     30  chris explain what this is to contain and provide a default one */
     31#include "cs8900.h"
     32
     33/***********************************************************
     34 ***********************************************************
     35           BEGIN SECTION OF DEFAULT DEFINES
     36 ***********************************************************
     37 ***********************************************************/
     38
     39/*
     40 * Number of devices supported by this driver
    2241 */
    23 
    24 #include <rtems/bspIo.h>
    25 #include <rtems.h>
    26 
    27 #include <libchip/cs8900.h>
     42#ifndef CS8900_DEVICES
     43#define CS8900_DEVICES 1
     44#endif
     45
     46/*
     47 *  This variable really should come from a per device configuration
     48 *  table so the base can vary by adapter.
     49 */
     50
     51#ifndef CS8900_IO_BASE
     52extern unsigned int bsp_cs8900_io_base;
     53#define CS8900_IO_BASE bsp_cs8900_io_base
     54#endif
     55
     56/*
     57 *  This variable really should come from a per device configuration
     58 *  table so the base can vary by adapter.
     59 */
     60
     61#ifndef CS8900_MEMORY_BASE
     62extern unsigned int bsp_cs8900_memory_base;
     63#define CS8900_MEMORY_BASE bsp_cs8900_memory_base
     64#endif
     65
     66/*
     67 *  This could go to a BSP provided callout.
     68 */
     69#ifndef WATCHDOG_TOGGLE
     70#define WATCHDOG_TOGGLE()
     71#endif
     72
     73/*
     74 *  This variable really should come from a per device configuration
     75 *  table so the base can vary by adapter.
     76 *
     77 *  chris this is probably not a good default  --joel
     78 */
     79
     80#ifndef CS8900_RX_QUEUE_SIZE
     81#define CS8900_RX_QUEUE_SIZE 1
     82#endif
     83
     84/***********************************************************
     85 ***********************************************************
     86              END SECTION OF DEFAULT DEFINES
     87 ***********************************************************
     88 ***********************************************************/
     89
     90/*
     91 * We expect to be able to read a complete packet into an mbuf.
     92 */
     93
     94#if (MCLBYTES < 1520)
     95#error "CS8900 Driver must have MCLBYTES >= 1520"
     96#endif
     97
     98/*
     99 * Task event usage.
     100 */
     101
     102#define CS8900_RX_OK_EVENT    RTEMS_EVENT_1
     103#define CS8900_TX_START_EVENT RTEMS_EVENT_1
     104#define CS8900_TX_OK_EVENT    RTEMS_EVENT_2
     105#define CS8900_TX_WAIT_EVENT  RTEMS_EVENT_3
    28106
    29107/*
     
    31109 */
    32110
    33 #ifdef CS8900_VERBOSE
    34 static BOOLEAN cs8900_io_verbose;
     111static cs8900_device cs8900[CS8900_DEVICES];
     112
     113/*
     114 * IO Packet Page inteface.
     115 */
     116
     117static inline unsigned short
     118io_pp_get_reg_16 (int dev, unsigned short reg)
     119{
     120  cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PACKET_PAGE_PTR,
     121                     0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
     122  return cs8900_io_get_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT0);
     123}
     124
     125static inline unsigned long
     126io_pp_get_reg_32 (int dev, unsigned short reg)
     127{
     128  cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PACKET_PAGE_PTR,
     129                     0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
     130  return ((cs8900_io_get_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT0) << 16) |
     131          cs8900_io_get_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT1));
     132}
     133
     134static inline void
     135io_pp_set_reg_16 (int dev, unsigned short reg, unsigned short data)
     136{
     137  cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PACKET_PAGE_PTR,
     138                     0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
     139  cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT0, data);
     140}
     141
     142static inline void
     143io_pp_set_reg_32 (int dev, unsigned short reg, unsigned long data)
     144{
     145  cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PACKET_PAGE_PTR,
     146                     0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
     147  cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT0, data >> 16);
     148  cs8900_io_set_reg (dev, CS8900_IO_BASE + CS8900_IO_PP_DATA_PORT1, data);
     149}
     150
     151static inline void
     152io_pp_bit_set_reg_16 (int dev, unsigned short reg, unsigned short mask)
     153{
     154  io_pp_set_reg_16 (dev, reg, io_pp_get_reg_16 (dev, reg) | mask);
     155}
     156
     157static inline void
     158io_pp_bit_clear_reg_16 (int dev, unsigned short reg, unsigned short mask)
     159{
     160  io_pp_set_reg_16 (dev, reg, io_pp_get_reg_16 (dev, reg) & ~mask);
     161}
     162
     163/*
     164 * Memory Mapped Packet Page interface.
     165 */
     166
     167static inline unsigned short
     168mem_pp_get_reg (int dev, unsigned short reg)
     169{
     170  return cs8900_mem_get_reg (dev, CS8900_MEMORY_BASE + reg);
     171}
     172
     173static inline void
     174mem_pp_set_reg (int dev, unsigned short reg, unsigned short data)
     175{
     176  cs8900_mem_set_reg (dev, CS8900_MEMORY_BASE + reg, data);
     177}
     178
     179static inline void
     180mem_pp_bit_set_reg (int dev, unsigned short reg, unsigned short mask)
     181{
     182  mem_pp_set_reg (dev, reg, mem_pp_get_reg (dev, reg) | mask);
     183}
     184
     185static inline void
     186mem_pp_bit_clear_reg (int dev, unsigned short reg, unsigned short mask)
     187{
     188  mem_pp_set_reg (dev, reg, mem_pp_get_reg (dev, reg) & ~mask);
     189}
     190
     191/*
     192 * Trace defines and control structures.
     193 */
     194 
     195#define CS8900_T_INT         (0)
     196#define CS8900_T_RX_OK       (1)
     197#define CS8900_T_RX_DROPPED  (2)
     198#define CS8900_T_NO_MBUF     (3)
     199#define CS8900_T_NO_CLUSTERS (4)
     200#define CS8900_T_RX_BEGIN    (5)
     201#define CS8900_T_RX_END      (6)
     202
     203#if CS8900_TRACE
     204
     205static const char *cs8900_trace_labels[] =
     206{
     207  "int",
     208  "rx ok",
     209  "rx dropped",
     210  "no mbuf",
     211  "no clusters",
     212  "rx begin",
     213  "rx end"
     214};
     215
     216/*
     217 * Assumes a micro-second timer such as the Coldfire.
     218 */
     219
     220rtems_unsigned32 rtems_read_timer ();
     221
     222static inline void
     223cs8900_trace (cs8900_device *cs, unsigned short key, unsigned long var)
     224{
     225  rtems_interrupt_level level;
     226 
     227  rtems_interrupt_disable (level);
     228 
     229  if (cs->trace_in < CS8900_TRACE_SIZE)
     230  {
     231    cs->trace_key[cs->trace_in]  = key;
     232    cs->trace_var[cs->trace_in]  = var;
     233    cs->trace_time[cs->trace_in] = rtems_read_timer ();
     234    cs->trace_in++;
     235  }
     236 
     237  rtems_interrupt_enable (level);
     238}
     239#else
     240#define cs8900_trace(c, k, v)
    35241#endif
    36242
    37 static rtems_isr_void_entry old_handler[CS8900_DEVICES];
    38 static void                 *old_parameter[CS8900_DEVICES];
    39 
    40 /*
    41  * Tables of IO addresses and interrupt levels for each device attached.
     243/*
     244 * Bring the chip online.
    42245 */
    43246
    44 static const unsigned long ethernet_io_base[CS8900_DEVICES] =
    45 {
    46   ETHERNET_BASE
     247static void
     248cs8900_hardware_init (cs8900_device *cs)
     249{
     250  unsigned long  prod_id;
     251  unsigned short status;
     252  int            dev = cs->dev;
     253
     254  /*
     255   * Do nothing while the device is calibrating and checking the EEPROM.
     256   * We must wait 20msecs.
     257   */
     258 
     259  io_pp_bit_set_reg_16 (dev, CS8900_PP_SelfCTL, CS8900_SELF_CTRL_RESET);
     260
     261  rtems_task_wake_after (TOD_MILLISECONDS_TO_TICKS (20));
     262 
     263  status = io_pp_get_reg_16 (dev, CS8900_PP_SelfST);
     264   
     265  if (((status & CS8900_SELF_STATUS_INITD) == 0) ||
     266      ((status & CS8900_SELF_STATUS_INITD) &&
     267       (status & CS8900_SELF_STATUS_EEPROM_PRESENT) &&
     268       (status & CS8900_SELF_STATUS_SIBUST)))
     269  {
     270    printf ("CS8900: %s. Initialisation aborted.\n",
     271            (status & CS8900_SELF_STATUS_INITD) ?
     272            "EEPROM read/write failed to complete" :
     273            "Failed to complete to reset");     
     274    return;
     275  }
     276 
     277  /* Probe the device for its ID */
     278
     279  prod_id = io_pp_get_reg_32 (dev, CS8900_PP_PROD_ID);
     280
     281  if ((prod_id >> 16) != CS8900_ESIA_ID)
     282  {
     283    printf ("CS9800: Invalid EISA ID, read product code 0x%08lx\n", prod_id);
     284    return;
     285  }
     286
     287  if ((prod_id & 0x000000ff) != 0)
     288  {
     289    printf ("CS9800: Unsupported product id, read product code 0x%08lx\n",
     290            prod_id);
     291    return;
     292  }
     293
     294  printf ("CS8900 Rev %ld, %s, %s.\n",
     295          (prod_id >> 8) & 0x1f,
     296          status & CS8900_SELF_STATUS_3_3_V ? "3.3V" : "5.0V",
     297          status & CS8900_SELF_STATUS_EEPROM_PRESENT ?
     298          "EEPROM present" : "no EEPROM");
     299
     300  /*
     301   * Switch to memory base accesses as they are faster. No indirect access.
     302   */
     303 
     304  io_pp_set_reg_16 (dev, CS8900_PP_MEM_BASE, CS8900_MEMORY_BASE);
     305  io_pp_set_reg_16 (dev, CS8900_PP_MEM_BASE + 2, (CS8900_MEMORY_BASE >> 16) & 0xf);
     306 
     307  io_pp_set_reg_16 (dev,
     308                    CS8900_PP_BusCTL,
     309                    CS8900_BUS_CTRL_RESET_RX_DMA |
     310                    CS8900_BUS_CTRL_USE_SA |
     311                    CS8900_BUS_CTRL_MEMORY_ENABLE);
     312  io_pp_set_reg_16 (dev,
     313                    CS8900_PP_BusCTL,
     314                    CS8900_BUS_CTRL_USE_SA |
     315                    CS8900_BUS_CTRL_MEMORY_ENABLE);
     316
     317  /*
     318   * We are now in memory mapped mode.
     319   */
     320
     321  /*
     322   * Program the Line Control register with the mode we want.
     323   *
     324   * No auto detect support at the moment. Only 10BaseT.
     325   */
     326
     327  mem_pp_set_reg (dev, CS8900_PP_LineCFG, CS8900_LINE_CTRL_10BASET);
     328 
     329  /*
     330   * Ask the user for the MAC address, the program into the device.
     331   */
     332
     333#define MACO(o) cs->arpcom.ac_enaddr[o]
     334 
     335  mem_pp_set_reg (dev, CS8900_PP_IA,
     336                  (((unsigned int) MACO (1)) << 8) |
     337                  ((unsigned int) MACO (0)));
     338  mem_pp_set_reg (dev, CS8900_PP_IA + 2,
     339                  (((unsigned int) MACO (3)) << 8) |
     340                  ((unsigned int) MACO (2)));
     341  mem_pp_set_reg (dev, CS8900_PP_IA + 4,
     342                  (((unsigned int) MACO (5)) << 8) |
     343                  ((unsigned int) MACO (4)));
     344
     345  /*
     346   * Set the Buffer configuration.
     347   */
     348
     349  mem_pp_set_reg (dev, CS8900_PP_BufCFG,
     350                  CS8900_BUFFER_CONFIG_RDY_FOR_TX |
     351                  CS8900_BUFFER_CONFIG_TX_UNDERRUN |
     352                  CS8900_BUFFER_CONFIG_TX_COL_OVF |
     353                  CS8900_BUFFER_CONFIG_RX_MISSED_OVF);
     354
     355  /*
     356   * Set the Receiver configuration.
     357   */
     358
     359  mem_pp_set_reg (dev, CS8900_PP_RxCFG,
     360                  CS8900_RX_CONFIG_RX_OK |
     361                  CS8900_RX_CONFIG_CRC_ERROR |
     362                  CS8900_RX_CONFIG_RUNT|
     363                  CS8900_RX_CONFIG_EXTRA_DATA);
     364
     365  /*
     366   * Set the Receiver control.
     367   */
     368
     369  mem_pp_set_reg (dev, CS8900_PP_RxCTL,
     370                  CS8900_RX_CTRL_RX_OK |
     371                  CS8900_RX_CTRL_MULTICAST |
     372                  CS8900_RX_CTRL_INDIVIDUAL |
     373                  CS8900_RX_CTRL_BROADCAST);
     374 
     375  /*
     376   * Set the Transmitter configuration.
     377   */
     378
     379  mem_pp_set_reg (dev, CS8900_PP_TxCFG,
     380                  CS8900_TX_CONFIG_TX_OK |
     381                  CS8900_TX_CONFIG_OUT_OF_WINDOW |
     382                  CS8900_TX_CONFIG_JABBER |
     383                  CS8900_TX_CONFIG_16_COLLISION);
     384
     385  /*
     386   * Attach the interrupt handler.
     387   */
     388
     389  cs8900_attach_interrupt (dev, cs);
     390 
     391  /*
     392   * Program the interrupt level we require then enable interrupts.
     393   */
     394
     395  mem_pp_set_reg (dev, CS8900_PP_INT, 0);
     396
     397  mem_pp_bit_set_reg (dev, CS8900_PP_BusCTL,
     398                      CS8900_BUS_CTRL_ENABLE_INT);
     399}
     400
     401rtems_isr
     402cs8900_interrupt (rtems_vector_number v, void *csp)
     403{
     404  cs8900_device  *cs = csp;
     405  int            dev = cs->dev;
     406  unsigned short isq = 0;
     407  struct mbuf    *m;
     408  unsigned char  *p;
     409
     410  ++cs->eth_stats.interrupts;
     411
     412  while (1)
     413  {
     414    isq = mem_pp_get_reg (dev, CS8900_PP_ISQ);
     415
     416    cs8900_trace (cs, CS8900_T_INT, isq);
     417
     418    WATCHDOG_TOGGLE ();
     419   
     420    /*
     421     * No more interrupts to service.
     422     */
     423
     424    if (isq == 0)
     425      return;
     426   
     427    switch (isq & 0x1f)
     428    {
     429      case 0x04:
     430
     431        /*
     432         * RxEvent.
     433         */
     434
     435        ++cs->eth_stats.rx_interrupts;
     436
     437        if (isq & CS8900_RX_EVENT_RX_OK)
     438        {
     439          m = cs->rx_ready_head;
     440          if (m)
     441          {
     442            cs->rx_ready_head = m->m_nextpkt;
     443            if (cs->rx_ready_head == 0)
     444              cs->rx_ready_tail = 0;
     445            m->m_nextpkt = 0;
     446            cs->rx_ready_len--;
     447           
     448            p = mtod (m, unsigned char *);
     449     
     450            m->m_pkthdr.len = cs8900_get_data_block (dev, p);
     451
     452            if (cs->rx_loaded_tail == 0)
     453              cs->rx_loaded_head = m;
     454            else
     455              cs->rx_loaded_tail->m_nextpkt = m;
     456            cs->rx_loaded_tail = m;
     457            cs->rx_loaded_len++;
     458
     459            if (cs->rx_loaded_len == 1)
     460            {
     461              cs8900_trace (cs, CS8900_T_RX_OK, cs->rx_loaded_len);
     462              rtems_event_send (cs->rx_task, CS8900_RX_OK_EVENT);
     463            }
     464          }
     465          else
     466          {
     467            ++cs->eth_stats.rx_dropped;
     468           
     469            cs8900_trace (cs, CS8900_T_RX_DROPPED, cs->rx_loaded_len);     
     470
     471            if (cs->rx_loaded_len == 0)
     472              rtems_event_send (cs->rx_task, CS8900_RX_OK_EVENT);
     473          }
     474        }
     475        else
     476        {
     477          if (isq & CS8900_RX_EVENT_CRC_ERROR)
     478            ++cs->eth_stats.rx_crc_errors;
     479
     480          if (isq & CS8900_RX_EVENT_RUNT)
     481            ++cs->eth_stats.rx_runt_errors;
     482         
     483          if (isq & CS8900_RX_EVENT_EXTRA_DATA)
     484            ++cs->eth_stats.rx_oversize_errors;
     485        }
     486        break;
     487
     488      case 0x08:
     489       
     490        /*
     491         * TxEvent.
     492         */
     493
     494        ++cs->eth_stats.tx_interrupts;
     495
     496        if (cs->tx_active)
     497        {
     498          if (isq & CS8900_TX_EVENT_TX_OK)
     499            ++cs->eth_stats.tx_ok;
     500
     501          cs->tx_active = 0;
     502       
     503          rtems_event_send (cs->tx_task, CS8900_TX_OK_EVENT);
     504        }
     505        break;
     506
     507      case 0x0c:
     508       
     509        /*
     510         * BufEvent.
     511         */
     512       
     513        if (isq & CS8900_BUFFER_EVENT_RDY_FOR_TX)
     514        {
     515          if (cs->tx_active)
     516          {
     517            ++cs->eth_stats.tx_rdy4tx;
     518            rtems_event_send (cs->tx_task, CS8900_TX_WAIT_EVENT);
     519          }
     520        }
     521        else if (isq & CS8900_BUFFER_EVENT_TX_UNDERRUN)
     522        {
     523          ++cs->eth_stats.tx_underrun_errors;
     524          if (cs->tx_active)
     525            rtems_event_send (cs->tx_task, CS8900_TX_OK_EVENT);
     526        }
     527        else if (isq & CS8900_BUFFER_EVENT_SW_INT)
     528        {
     529          ++cs->eth_stats.int_swint_res;
     530        }
     531        break;
     532
     533      case 0x10:
     534       
     535        /*
     536         * RxMiss.
     537         */
     538       
     539        cs->eth_stats.rx_missed_errors +=
     540          mem_pp_get_reg (dev, CS8900_PP_RxMISS) >> 6;
     541        break;
     542
     543      case 0x12:
     544       
     545        /*
     546         * TxCol.
     547         */
     548
     549        cs->eth_stats.tx_collisions +=
     550          mem_pp_get_reg (dev, CS8900_PP_TxCol) >> 6;
     551        break;
     552
     553      default:
     554        break;
     555    }
     556  }
     557 
     558}
     559
     560int
     561cs8900_link_active (int dev)
     562{
     563  return ((mem_pp_get_reg (dev, CS8900_PP_LineST) & CS8900_LINE_STATUS_LINK_OK) ?
     564          1 : 0);
     565}
     566
     567static inline void
     568cs8900_rx_refill_queue (cs8900_device *cs)
     569{
     570  struct ifnet          *ifp = &cs->arpcom.ac_if;
     571  struct mbuf           *m;
     572  rtems_interrupt_level level;
     573 
     574  /*
     575   * Hold a single queue of mbuf's at the interface. This
     576   * will lower the latency of the driver.
     577   */
     578
     579  while (cs->rx_ready_len < CS8900_RX_QUEUE_SIZE)
     580  {
     581    MGETHDR (m, M_DONTWAIT, MT_DATA);
     582   
     583    if (!m)
     584    {
     585      ++cs->eth_stats.rx_no_mbufs;
     586      cs8900_trace (cs, CS8900_T_NO_MBUF, cs->eth_stats.rx_no_mbufs);     
     587      return;
     588    }
     589         
     590    MCLGET (m, M_DONTWAIT);
     591   
     592    if (!m->m_ext.ext_buf)
     593    {
     594      ++cs->eth_stats.rx_no_clusters;
     595      cs8900_trace (cs, CS8900_T_NO_CLUSTERS, cs->eth_stats.rx_no_clusters);     
     596      m_free (m);
     597      return;
     598    }
     599    m->m_pkthdr.rcvif = ifp;
     600    m->m_nextpkt = 0;
     601
     602    rtems_interrupt_disable (level);
     603   
     604    if (cs->rx_ready_tail == 0)
     605      cs->rx_ready_head = m;
     606    else
     607      cs->rx_ready_tail->m_nextpkt = m;
     608    cs->rx_ready_tail = m;
     609    cs->rx_ready_len++;
     610
     611    rtems_interrupt_enable (level);
     612  }
     613}
     614
     615static void
     616cs8900_rx_task (void *arg)
     617{
     618  cs8900_device         *cs = arg;
     619  int                   dev = cs->dev;
     620  struct ifnet          *ifp = &cs->arpcom.ac_if;
     621  rtems_event_set       events;
     622  struct mbuf           *m;
     623  struct ether_header   *eh;
     624  rtems_status_code     sc;
     625  rtems_interrupt_level level;
     626
     627  /*
     628   * Turn the receiver and transmitter on.
     629   */
     630 
     631  mem_pp_bit_set_reg (dev, CS8900_PP_LineCFG,
     632                      CS8900_LINE_CTRL_RX_ON |
     633                      CS8900_LINE_CTRL_TX_ON);
     634 
     635  /*
     636   * Start the software interrupt watchdog.
     637   */
     638 
     639  rtems_interrupt_disable (level);
     640  mem_pp_bit_set_reg (dev, CS8900_PP_BufCFG,
     641                      CS8900_BUFFER_CONFIG_SW_INT);
     642  ++cs->eth_stats.int_swint_req;
     643  rtems_interrupt_enable (level);
     644 
     645  /*
     646   * Loop reading packets.
     647   */
     648
     649  while (1)
     650  {
     651    cs8900_rx_refill_queue (cs);
     652   
     653    sc = rtems_bsdnet_event_receive (CS8900_RX_OK_EVENT,
     654                                     RTEMS_WAIT | RTEMS_EVENT_ANY,
     655                                     TOD_MILLISECONDS_TO_TICKS (250),
     656                                     &events);
     657
     658    cs8900_rx_refill_queue (cs);
     659   
     660    if (sc == RTEMS_TIMEOUT)
     661    {
     662      /*
     663       * We need to check the interrupt hardware in the cs8900a
     664       * has not locked up. It seems this occurs if the ISQ
     665       * queue fills up.
     666       * To test we generate a software interrupt and watch
     667       * a counter go up. If the counter does not go for 2
     668       * software interrupts requests we flush the ISQ queue.
     669       */
     670
     671      if ((cs->eth_stats.int_swint_req - cs->eth_stats.int_swint_res) > 1)
     672      {
     673        printf ("cs8900: int lockup, isq flush\n");
     674
     675        mem_pp_bit_clear_reg (dev, CS8900_PP_BusCTL,
     676                              CS8900_BUS_CTRL_ENABLE_INT);
     677       
     678        while (mem_pp_get_reg (dev, CS8900_PP_ISQ) != 0);
     679       
     680        cs->eth_stats.int_swint_req = cs->eth_stats.int_swint_res = 0;
     681        ++cs->eth_stats.int_lockup;
     682       
     683        mem_pp_bit_set_reg (dev, CS8900_PP_BusCTL,
     684                            CS8900_BUS_CTRL_ENABLE_INT);
     685      }
     686     
     687      rtems_interrupt_disable (level);
     688      mem_pp_bit_set_reg (dev, CS8900_PP_BufCFG,
     689                          CS8900_BUFFER_CONFIG_SW_INT);
     690      ++cs->eth_stats.int_swint_req;
     691      rtems_interrupt_enable (level);
     692    }
     693
     694    cs8900_trace (cs, CS8900_T_RX_BEGIN, cs->rx_loaded_len);
     695   
     696    while (cs->rx_loaded_len)
     697    {
     698      rtems_interrupt_disable (level);
     699   
     700      m = cs->rx_loaded_head;
     701      if (m)
     702      {
     703        cs->rx_loaded_head = m->m_nextpkt;
     704        if (cs->rx_loaded_head == 0)
     705          cs->rx_loaded_tail = 0;
     706        m->m_nextpkt = 0;
     707        cs->rx_loaded_len--;
     708       
     709        rtems_interrupt_enable (level);
     710       
     711        m->m_pkthdr.rcvif = ifp;
     712       
     713        cs->eth_stats.rx_bytes += m->m_pkthdr.len;
     714       
     715        m->m_len = m->m_pkthdr.len = m->m_pkthdr.len - sizeof (struct ether_header);
     716       
     717        eh = mtod (m, struct ether_header *);
     718        m->m_data += sizeof (struct ether_header);
     719     
     720        ++cs->eth_stats.rx_packets;
     721       
     722        ether_input (ifp, eh, m);
     723      }
     724      else
     725      {
     726        rtems_interrupt_enable (level);
     727      }
     728    }
     729    cs8900_trace (cs, CS8900_T_RX_END, cs->rx_loaded_len);
     730  }
     731}
     732
     733static void
     734cs8900_tx_task (void *arg)
     735{
     736  cs8900_device     *cs = arg;
     737  int               dev = cs->dev;
     738  struct ifnet      *ifp = &cs->arpcom.ac_if;
     739  rtems_event_set   events;
     740  struct mbuf       *m;
     741  rtems_status_code sc;
     742
     743  /*
     744   * Wait for the link to come up.
     745   */
     746
     747  rtems_task_wake_after (TOD_MILLISECONDS_TO_TICKS (750));
     748
     749  /*
     750   * Loop processing the tx queue.
     751   */
     752
     753  while (1)
     754  {
     755    /*
     756     * Fetch the mbuf list from the interface's queue.
     757     */
     758
     759    IF_DEQUEUE (&ifp->if_snd, m);
     760
     761    /*
     762     * If something actually is present send it.
     763     */
     764
     765    if (!m)
     766    {
     767      ifp->if_flags &= ~IFF_OACTIVE;
     768
     769      rtems_bsdnet_event_receive (CS8900_TX_START_EVENT,
     770                                  RTEMS_WAIT | RTEMS_EVENT_ANY,
     771                                  RTEMS_NO_TIMEOUT,
     772                                  &events);
     773    }
     774    else
     775    {
     776      if (cs8900_link_active (dev))
     777      {
     778        int resending;
     779       
     780        do
     781        {
     782          unsigned short buf_status;
     783
     784          resending = 0;
     785         
     786          cs->tx_active = 1;
     787         
     788          mem_pp_set_reg (dev, CS8900_PP_TxCMD,
     789                          CS8900_TX_CMD_STATUS_TX_START_ENTIRE |
     790                          CS8900_TX_CMD_STATUS_FORCE);
     791          mem_pp_set_reg (dev, CS8900_PP_TxLength, m->m_pkthdr.len);
     792         
     793          buf_status = mem_pp_get_reg (dev, CS8900_PP_BusST);
     794
     795          /*
     796           * If the bid for memory in the device fails trash the
     797           * transmit and try again next time.
     798           */
     799
     800          if (buf_status & CS8900_BUS_STATUS_TX_BID_ERROR)
     801            ++cs->eth_stats.tx_bid_errors;
     802          else
     803          {
     804            /*
     805             * If the buffer is not read enable the interrupt and then wait.
     806             */
     807           
     808            if ((buf_status & CS8900_BUS_STATUS_RDY_FOR_TX_NOW) == 0)
     809            {
     810              cs->eth_stats.tx_wait_for_rdy4tx++;
     811              sc = rtems_bsdnet_event_receive (CS8900_TX_WAIT_EVENT,
     812                                               RTEMS_WAIT | RTEMS_EVENT_ANY,
     813                                               TOD_MILLISECONDS_TO_TICKS (750),
     814                                               &events);
     815              if (sc == RTEMS_TIMEOUT)
     816              {
     817                /*
     818                 * For some reason the wait request has been dropped,
     819                 * so lets resend from the start.
     820                 */
     821
     822                printf ("tx resend\n");
     823                ++cs->eth_stats.tx_resends;
     824                resending = 1;
     825              }
     826            }
     827
     828            if (!resending)
     829            {
     830              cs8900_tx_load (dev, m);
     831              cs->eth_stats.tx_packets++;
     832              cs->eth_stats.tx_bytes += m->m_pkthdr.len;
     833            }
     834          }
     835        }
     836        while (resending);
     837       
     838        m_freem (m);
     839       
     840        do
     841        {
     842          rtems_bsdnet_event_receive (CS8900_TX_OK_EVENT,
     843                                      RTEMS_WAIT | RTEMS_EVENT_ANY,
     844                                      RTEMS_NO_TIMEOUT,
     845                                      &events);
     846        }
     847        while (cs->tx_active);
     848      }
     849      else
     850      {
     851        ++cs->eth_stats.tx_dropped;
     852        m_freem (m);
     853      }
     854    }
     855  }
     856}
     857
     858static void
     859cs8900_start (struct ifnet *ifp)
     860{
     861  cs8900_device *cs = ifp->if_softc;
     862
     863  /*
     864   * Tell the transmit daemon to wake up and send a packet.
     865   */
     866
     867  ifp->if_flags |= IFF_OACTIVE;
     868
     869  rtems_event_send (cs->tx_task, CS8900_TX_START_EVENT);
     870}
     871
     872static void
     873cs8900_stop (cs8900_device *cs)
     874{
     875  int dev = cs->dev;
     876
     877  mem_pp_bit_clear_reg (dev, CS8900_PP_LineCFG,
     878                        CS8900_LINE_CTRL_RX_ON |
     879                        CS8900_LINE_CTRL_TX_ON);
     880 
     881  mem_pp_bit_clear_reg (dev, CS8900_PP_BusCTL,
     882                        CS8900_BUS_CTRL_ENABLE_INT);
     883}
     884
     885static const char *eth_statistics_labels[] =
     886{
     887  "rx packets",
     888  "tx packets",
     889  "rx bytes",
     890  "tx bytes",
     891  "rx interrupts",
     892  "tx interrupts",
     893  "rx dropped",
     894  "rx no mbuf",
     895  "rx no custers",
     896  "rx oversize errors",
     897  "rx crc errors",
     898  "rx runt errors",
     899  "rx missed errors",
     900  "tx ok",
     901  "tx collisions",
     902  "tx bid errors",
     903  "tx wait for rdy4tx",
     904  "tx rdy4tx",
     905  "tx underrun errors",
     906  "tx dropped",
     907  "tx resends",
     908  "int swint req",
     909  "int swint res",
     910  "int lockup",
     911  "interrupts"
    47912};
    48913
    49 static const unsigned long ethernet_mem_base[CS8900_DEVICES] =
    50 {
    51   ETHERNET_BASE + CS8900_MEMORY_BASE
    52 };
    53 
    54 static const unsigned int ethernet_irq_level[CS8900_DEVICES] =
    55 {
    56   ETHERNET_IRQ_LEVEL
    57 };
    58 
    59 static const unsigned int ethernet_irq_priority[CS8900_DEVICES] =
    60 {
    61   ETHERNET_IRQ_PRIORITY
    62 };
    63 
    64 static const unsigned int ethernet_irq_vector[CS8900_DEVICES] =
    65 {
    66   ETHERNET_IRQ_VECTOR,
    67 };
    68 
    69 void cs8900_io_set_reg (int dev, unsigned short reg, unsigned short data)
    70 {
    71 #ifdef CS8900_DATA_BUS_SWAPPED
    72   data = (data >> 8) | (data << 8);
     914static void
     915cs8900_stats (cs8900_device *cs)
     916{
     917  int           dev = cs->dev;
     918  int           i;
     919  int           max_label = 0;
     920  int           len;
     921  unsigned long *value = (unsigned long*) &cs->eth_stats.rx_packets;
     922
     923  cs->eth_stats.rx_missed_errors +=
     924    mem_pp_get_reg (dev, CS8900_PP_RxMISS) >> 6;
     925   
     926  cs->eth_stats.tx_collisions +=
     927    mem_pp_get_reg (dev, CS8900_PP_TxCol) >> 6;
     928 
     929  printf ("Network Driver Stats for CS8900 :\n");
     930
     931  for (i = 0; i < (sizeof (eth_statistics_labels) / sizeof (const char *)); i++)
     932  {
     933    len = strlen (eth_statistics_labels[i]);
     934    if (len > max_label)
     935      max_label = len;
     936  }
     937
     938  max_label += 2;
     939
     940  printf ("%*s - %10u %*s - %10u\n",
     941          max_label, "rx ready len", cs->rx_ready_len,
     942          max_label, "rx loaded len", cs->rx_loaded_len);
     943 
     944  for (i = 0;
     945       i < (sizeof (eth_statistics_labels) / sizeof (const char *));
     946       i++)
     947  {
     948    printf ("%*s - %10lu",
     949            max_label, eth_statistics_labels[i], value[i]);
     950   
     951    i++;
     952   
     953    if (i < (sizeof (eth_statistics_labels) / sizeof (const char *)))
     954      printf (" %*s - %10lu",
     955              max_label, eth_statistics_labels[i], value[i]);
     956    printf ("\n");
     957  }
     958
     959#if CS8900_TRACE
     960 
     961  for (i = 0; i < cs->trace_in; i++)
     962  {
     963    printf ("%8ld.%03ld ", cs->trace_time[i] / 1000, cs->trace_time[i] % 1000);
     964   
     965    if (cs->trace_key[i] < sizeof (cs8900_trace_labels) / sizeof (char*))
     966      printf ("%s : ", cs8900_trace_labels[cs->trace_key[i]]);
     967    else
     968      printf ("unknown trace key, %d : ", cs->trace_key[i]);
     969
     970    if (cs->trace_key[i] == CS8900_T_INT)
     971    {
     972      printf ("0x%04lx ", cs->trace_var[i]);
     973      if (cs->trace_var[i] == 0)
     974        printf ("end");
     975      else
     976      {
     977        switch (cs->trace_var[i] & 0x1f)
     978        {
     979          case 0x04:
     980            printf ("rx event");
     981            break;
     982
     983          case 0x08:
     984            printf ("tx event");
     985            break;
     986
     987          case 0x0c:
     988            printf ("buffer event");
     989            break;
     990
     991          case 0x10:
     992            printf ("rx missed");
     993            break;
     994
     995          case 0x12:
     996            printf ("tx collisions");
     997            break;
     998
     999          case 0x1f:
     1000            printf ("tx request");
     1001            break;
     1002         
     1003          case 0x1e:
     1004            printf ("tx wait 4 tx");
     1005            break;
     1006         
     1007          case 0x1d:
     1008            printf ("tx already active");
     1009            break;
     1010         
     1011          default:
     1012            printf ("unknown event");
     1013            break;
     1014        }
     1015      }
     1016    }
     1017    else
     1018      printf ("0x%08lx", cs->trace_var[i]);
     1019   
     1020    printf ("\n");
     1021  }
     1022
     1023  cs->trace_in = 0;
     1024 
    731025#endif
    74 
    75 #ifdef CS8900_VERBOSE
    76   if (cs8900_io_verbose)
    77     printf ("CS8900: io set reg=0x%04x, data=0x%04x\n", reg, data);
     1026}
     1027
     1028static void
     1029cs8900_init (void *arg)
     1030{
     1031  cs8900_device *cs  = arg;
     1032  int           dev  = cs->dev;
     1033  struct ifnet  *ifp = &cs->arpcom.ac_if;
     1034
     1035  if (cs->rx_task == 0)
     1036  {
     1037
     1038    /*
     1039     * Set up the hardware.
     1040     */
     1041   
     1042    cs8900_hardware_init (cs);
     1043
     1044    /*
     1045     * Start driver task. We have only one task.
     1046     */
     1047   
     1048    cs->rx_task = rtems_bsdnet_newproc ("CSr0", 4096, cs8900_rx_task, cs);
     1049    cs->tx_task = rtems_bsdnet_newproc ("CSt0", 4096, cs8900_tx_task, cs);
     1050  }
     1051
     1052#ifdef todo
     1053  /*
     1054   * Set flags appropriately
     1055   */
     1056  if (ifp->if_flags & IFF_PROMISC)
     1057  else
    781058#endif
    79    
    80   WRITE_REGISTER_16 (ethernet_io_base[dev] + reg, data);
    81 }
    82 
    83 unsigned short cs8900_io_get_reg (int dev, unsigned short reg)
    84 {
    85   unsigned long data;
    86 
    87   READ_REGISTER_16 (ethernet_io_base[dev] + reg, data);
    88 
    89 #ifdef CS8900_DATA_BUS_SWAPPED
    90   data = (data >> 8) | (data << 8);
    91 #endif
    92  
    93 #ifdef CS8900_VERBOSE
    94   if (cs8900_io_verbose)
    95     printk ("CS8900: io get reg=0x%04x, data=0x%04x\n", reg, data);
    96 #endif
    97  
    98   return data;
    99 }
    100 
    101 void cs8900_mem_set_reg (int dev, unsigned long reg, unsigned short data)
    102 {
    103 #ifdef CS8900_DATA_BUS_SWAPPED
    104   data = (data >> 8) | (data << 8);
    105 #endif
    106 
    107 #ifdef CS8900_VERBOSE
    108   if (cs8900_io_verbose)
    109     printk ("CS8900: mem set reg=0x%04x, data=0x%04x\n", reg, data);
    110 #endif
    111 
    112   WRITE_REGISTER_16 (ethernet_io_base[dev] + reg, data);
    113 }
    114 
    115 unsigned short cs8900_mem_get_reg (int dev, unsigned long reg)
    116 {
    117   unsigned short data;
    118   READ_REGISTER_16 (ethernet_io_base[dev] + reg, data);
    119  
    120 #ifdef CS8900_DATA_BUS_SWAPPED
    121   data = (data >> 8) | (data << 8);
    122 #endif
    123 
    124 #ifdef CS8900_VERBOSE
    125   if (cs8900_io_verbose)
    126     printk ("CS8900: mem get reg=0x%04x, data=0x%04x\n", reg, data);
    127 #endif
    128 
    129   return data;
    130 }
    131 
    132 void cs8900_put_data_block (int dev, int len, unsigned char *data)
    133 {
    134 #ifndef CS8900_DATA_BUS_SWAPPED
    135   unsigned short swap_word;
    136 #endif
    137   unsigned short *src = (unsigned short *) ((unsigned long) data);
    138   unsigned short *dst = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_TxFrameLoc);
    139 
    140   while (len > 1)
    141   {
    142 #ifndef CS8900_DATA_BUS_SWAPPED
    143     swap_word = *src++;
    144     *dst++ = (swap_word >> 8) | (swap_word << 8);
    145 #else
    146     *dst++ = *src++;
    147 #endif
    148     len -= 2;
    149   }
    150 
    151   if (len)
    152   {
    153 #ifndef CS8900_DATA_BUS_SWAPPED
    154     swap_word = *src++;
    155     *dst++ = (swap_word >> 8) | (swap_word << 8);
    156 #else
    157     *dst++ = *src++;
    158 #endif
    159   } 
    160 }
    161 
    162 unsigned short cs8900_get_data_block (int dev, unsigned char *data)
    163 {
    164   unsigned short          swap_word;
    165   volatile unsigned short *src = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_RxLength);
    166   unsigned short          *dst;
    167   unsigned short          len;
    168   unsigned short          rx_len;
    169   unsigned short          len_odd;
    170  
    171 #ifdef CS8900_DATA_BUS_SWAPPED
    172     swap_word = *src++;
    173     len = (swap_word >> 8) | (swap_word << 8);
    174 #else
    175     len = *src++;
    176 #endif
    177    
    178   dst = (unsigned short *) ((unsigned long) data);
    179 
    180   len_odd = len & 1;
    181   rx_len  = len & ~1;
    182  
    183   for (; rx_len; rx_len -= 2)
    184   {
    185 #ifndef CS8900_DATA_BUS_SWAPPED
    186     swap_word = *src++;
    187     *dst++ = (swap_word >> 8) | (swap_word << 8);
    188 #else
    189     *dst++ = *src++;
    190 #endif
    191   }
    192 
    193   if (len_odd)
    194   {
    195 #ifndef CS8900_DATA_BUS_SWAPPED
    196     swap_word = *src++;
    197     *dst++ = (swap_word >> 8) | (swap_word << 8);
    198 #else
    199     *dst++ = *src++;
    200 #endif
    201   }
    202 
    203   return len;
    204 }
    205 
    206 void
    207 cs8900_tx_load (int dev, struct mbuf *m)
    208 {
    209   volatile unsigned short *dst = (unsigned short *) (ethernet_mem_base[dev] + CS8900_PP_TxFrameLoc);
    210   unsigned int            len;
    211   unsigned char           *src;
    212   int                     remainder = 0;
    213   unsigned char           remainder_data = '\0';
    214  
    215   while (m)
    216   {
     1059 
     1060  /*
     1061   * Tell the world that we're running.
     1062   */
     1063 
     1064  ifp->if_flags |= IFF_RUNNING;
     1065
     1066  /*
     1067   * Set the Line Control to bring the receive and transmitter online.
     1068   */
     1069
     1070  mem_pp_bit_set_reg (dev, CS8900_PP_LineCFG,
     1071                      CS8900_LINE_CTRL_RX_ON |
     1072                      CS8900_LINE_CTRL_TX_ON);
     1073
     1074  mem_pp_bit_set_reg (dev, CS8900_PP_BusCTL,
     1075                      CS8900_BUS_CTRL_ENABLE_INT);
     1076}
     1077
     1078static int
     1079cs8900_ioctl (struct ifnet *ifp, int cmd, caddr_t data)
     1080{
     1081  cs8900_device *cs = ifp->if_softc;
     1082  int           error = 0;
     1083
     1084  switch (cmd)
     1085  {
     1086    case SIOCGIFADDR:
     1087    case SIOCSIFADDR:
     1088     
     1089      error = ether_ioctl (ifp, cmd, data);
     1090      break;
     1091
     1092    case SIOCSIFFLAGS:
     1093     
     1094      switch (ifp->if_flags & (IFF_UP | IFF_RUNNING))
     1095      {
     1096        case IFF_RUNNING:
     1097         
     1098          cs8900_stop (cs);
     1099          break;
     1100
     1101        case IFF_UP:
     1102         
     1103          cs8900_init (cs);
     1104          break;
     1105
     1106        case IFF_UP | IFF_RUNNING:
     1107         
     1108          cs8900_stop (cs);
     1109          cs8900_init (cs);
     1110          break;
     1111
     1112        default:
     1113          break;
     1114      }
     1115      break;
     1116
     1117    case SIO_RTEMS_SHOW_STATS:
     1118     
     1119      cs8900_stats (cs);
     1120      break;
     1121
     1122      /* FIXME: Multicast commands must be added here.  */
     1123
     1124    default:
     1125      error = EINVAL;
     1126      break;
     1127  }
     1128
     1129  return error;
     1130}
     1131
     1132int
     1133cs8900_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching)
     1134{
     1135  cs8900_device *cs;
     1136  struct ifnet  *ifp;
     1137  int           mtu;
     1138  int           unit;
     1139  char          *name;
     1140
     1141  /*
     1142    * Parse driver name
     1143   */
     1144 
     1145  if ((unit = rtems_bsdnet_parse_driver_name (config, &name)) < 0)
     1146    return 0;
     1147 
     1148  /*
     1149   * Is driver free?
     1150   */
     1151 
     1152  if (unit >= CS8900_DEVICES)
     1153  {
     1154    printf ("Bad CS8900 unit number for device `%s'.\n", config->name);
     1155    return 0;
     1156  }
     1157 
     1158  cs      = &cs8900[unit];
     1159  cs->dev = unit;
     1160  ifp     = &cs->arpcom.ac_if;
     1161
     1162  if (attaching)
     1163  {
     1164    if (ifp->if_softc)
     1165    {
     1166      printf ("Driver `%s' already in use.\n", config->name);
     1167      return 0;
     1168    }
     1169
    2171170    /*
    218      * We can get empty mbufs from the stack.
     1171     * Process options
    2191172     */
    220 
    221     len = m->m_len;
    222     src = mtod (m, unsigned char*);
    223 
    224     if (len)
     1173   
     1174    if (config->hardware_address)
     1175      memcpy (cs->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
     1176    else
     1177      cs8900_get_mac_addr (unit, cs->arpcom.ac_enaddr);
     1178 
     1179    if (config->mtu)
     1180      mtu = config->mtu;
     1181    else
     1182      mtu = ETHERMTU;
     1183   
     1184    cs->accept_bcast = !config->ignore_broadcast;
     1185   
     1186    /*
     1187     * Set up network interface values.
     1188     */
     1189   
     1190    ifp->if_softc  = cs;
     1191    ifp->if_unit   = unit;
     1192    ifp->if_name   = name;
     1193    ifp->if_mtu    = mtu;
     1194    ifp->if_init   = cs8900_init;
     1195    ifp->if_ioctl  = cs8900_ioctl;
     1196    ifp->if_start  = cs8900_start;
     1197    ifp->if_output = ether_output;
     1198    ifp->if_flags  = IFF_BROADCAST | IFF_SIMPLEX;
     1199   
     1200    if (ifp->if_snd.ifq_maxlen == 0)
     1201      ifp->if_snd.ifq_maxlen = ifqmaxlen;
     1202   
     1203    /*
     1204     * Attach the interface to the stack.
     1205     */
     1206   
     1207    if_attach (ifp);
     1208    ether_ifattach (ifp);
     1209  }
     1210  else
     1211  {
     1212    if (!ifp->if_softc)
    2251213    {
    226       if (remainder)
    227       {
    228 #ifndef CS8900_DATA_BUS_SWAPPED
    229         *dst++ = remainder_data | (*src++ << 8);
    230 #else
    231         *dst++ = *src++ | (remainder_data << 8);
    232 #endif
    233         len--;
    234         remainder = 0;
    235       }
    236 
    237       if (len & 1)
    238       {
    239         remainder = 1;
    240         len--;
    241       }
    242    
    243       for (; len; len -= 2)
    244 #ifndef CS8900_DATA_BUS_SWAPPED
    245         *dst++ = (*src++) | (*(++src) << 8);
    246 #else
    247       *dst++ = (*src++ << 8) | *(++src);
    248 #endif
    249    
    250       if (remainder)
    251         remainder_data = *src++;
     1214      printf ("Driver `%s' not found.\n", config->name);
     1215      return 0;
    2521216    }
    253    
    254     m = m->m_next;
    255   }
    256 
    257   if (remainder)
    258   {
    259 #ifndef CS8900_DATA_BUS_SWAPPED
    260     *dst = (unsigned short) remainder_data;
    261 #else
    262     *dst = (unsigned short) (remainder_data << 8);
    263 #endif
    264   }
    265 }
    266 
    267 void cs8900_attach_interrupt (int dev, cs8900_device *cs)
    268 {
    269   rtems_interrupt_catch_with_void (cs8900_interrupt,
    270                                    ethernet_irq_vector[dev],
    271                                    &old_handler[dev],
    272                                    cs,
    273                                    &old_parameter[dev]);
    274  
    275   CF_SIM_WRITE_ICR (CF_BASE,
    276                     ethernet_irq_level[dev],
    277                     CF_SIM_ICR_AVEC_AUTO,
    278                     ethernet_irq_level[dev],
    279                     ethernet_irq_priority[dev]);
    280   CF_SIM_IMR_ENABLE (CF_BASE, 1 << ethernet_irq_level[dev]);
    281 }
    282 
    283 void cs8900_detach_interrupt (int dev)
    284 {
    285   CF_SIM_IMR_DISABLE (CF_BASE, 1 << ethernet_irq_level[dev]);
    286  
    287   rtems_interrupt_catch_with_void (old_handler,
    288                                    ethernet_irq_vector[dev],
    289                                    NULL,
    290                                    old_parameter[dev],
    291                                    NULL);
    292 }
    293 
    294 void cs8900_get_mac_addr (int dev, unsigned char *mac_address)
    295 {
    296   memcpy (mac_address, rct_get_mac_address (dev), 6);
    297 }
     1217
     1218    cs8900_stop (cs);
     1219    cs8900_detach_interrupt (unit);
     1220  }
     1221 
     1222  return 1;
     1223 
     1224}
  • c/src/libchip/network/cs8900.h

    r19ed3cf ra2117cd6  
    33  $Id$
    44  ------------------------------------------------------------------------
    5 
     5 
    66  My Right Boot, a boot ROM for embedded hardware.
    77 
     
    3838#include <netinet/in.h>
    3939#include <netinet/if_ether.h>
     40
     41/* #include <target.h> what does this provide? joel to chris */
    4042
    4143#define ET_MINLEN 60
     
    383385   */
    384386
    385   struct arpcom arpcom;
     387  struct arpcom  arpcom;
    386388
    387389  /*
     
    418420
    419421  eth_statistics eth_stats;
    420 
     422 
    421423} cs8900_device;
    422424
Note: See TracChangeset for help on using the changeset viewer.