Ignore:
Timestamp:
Jun 12, 2000, 3:00:15 PM (20 years ago)
Author:
Joel Sherrill <joel.sherrill@…>
Branches:
4.10, 4.11, 4.8, 4.9, 5, master
Children:
edeed26
Parents:
0ab65474
Message:

Merged from 4.5.0-beta3a

File:
1 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/m68k/mvme167/network/network.c

    r0ab65474 rdf49c60  
    1 /* uti596.c: An 82596 ethernet driver for rtems-bsd.
     1/*  network.c: An 82596 ethernet driver for rtems-bsd.
    22 *
    33 *  $Id$
     
    1010 *  you must run with polled console I/O.
    1111 */
    12 
    13 #define DBG_596
    14 #define DBG_596_RFA
     12 
     13/*
     14#define DBG_ADD_CMD
     15#define DBG_WAIT
     16#define DBG_SEND
     17#define DBG_MEM
     18#define DBG_SELFTEST_CMD
     19#define DBG_DUMP_CMD
     20#define DBG_RESET
     21#define DBG_ATTACH
    1522#define DBG_START
    1623#define DBG_INIT
    17 #define DBG_INIT_2
    18 /*#define DBG_INIT_3*/
    19 #define DBG_RESET
    20 #define DBG_VERSION
     24#define DBG_STOP
     25#define DBG_RX
    2126#define DBG_ISR
    22 #define DBG_RAW_ISR
    23 #define DBG_596_RFD
    24 #define DBG_FR
    25 #define DBG_RAW
    26 #define DBG_ATTACH
    27 #define DBG_POLLED_CMD
    28 #define DBG_ADD
    29 #define DBG_SUPPLY_FD
    30 
     27#define DBG_IOCTL
     28#define DBG_STAT
     29#define DBG_PACKETS
     30*/
    3131
    3232/*
    3333 * Default number of buffer descriptors and buffer sizes.
    3434 */
    35 #define RX_BUF_COUNT     15
    36 #define TX_BUF_COUNT     4
    37 #define TX_BD_PER_BUF    4
    38 
    39 #define RBUF_SIZE       1520
    40 
    41 #define UTI_596_ETH_MIN_SIZE 60
     35#define RX_BUF_COUNT   15
     36#define TX_BUF_COUNT   4
     37#define TX_BD_PER_BUF  4
     38
     39#define RBUF_SIZE  1520
     40
     41#define UTI_596_ETH_MIN_SIZE  60
    4242
    4343/*
     
    6363
    6464#include "uti596.h"
    65 #include "netexterns.h"
    66 
     65
     66/* If we are running interrupt driven I/O no debug output is printed */
    6767#if CD2401_POLLED_IO == 1
    68         #define printk(arglist) printk arglist;
     68   #define printk(arglist) printk arglist;
    6969#else
    70         #define printk(arglist)
     70   #define printk(arglist)
    7171#endif
    7272
    73 #define  UTI_596_ASSERT( condition, str )  if (!( condition ) ) { printk((str)) }
    74 
    75 int     count_rx = 0;
    76 i596_rfd *pISR_Rfd;
    77 
     73#define UTI_596_ASSERT( condition, str )  if (!( condition ) ) { printk((str)) }
     74
     75/* Types of PORT commands */
     76#define UTI596_RESET_PORT_FUNCTION              0
     77#define UTI596_SELFTEST_PORT_FUNCTION   1
     78#define UTI596_SCP_PORT_FUNCTION        2
     79#define UTI596_DUMP_PORT_FUNCTION       3
     80
     81/* Types of waiting for commands */
     82#define UTI596_NO_WAIT                                  0
     83#define UTI596_WAIT_FOR_CU_ACCEPT               1
     84#define UTI596_WAIT_FOR_INITIALIZATION  2
     85#define UTI596_WAIT_FOR_STAT_C                  3
     86
     87/* Device dependent data structure */
    7888static uti596_softc_ uti596_softc;
    7989
     90/* Globals */
     91int count_rx = 0;
    8092static int scbStatus;
    8193static rtems_status_code sc;
     
    8799 */
    88100char uti596initSetup[] = {
    89         0x0E,   /* Byte 0: length, prefetch off ( no RBD's ) */
    90         0xC8,   /* Byte 1: fifo to 8, monitor off */
    91         0x40,   /* Byte 2: don't save bad frames ( was save= 80, use intel's 40 )*/
    92         0x2E,   /* Byte 3: No source address insertion, 8 byte preamble */
    93         0x00,   /* Byte 4: priority and backoff defaults */
    94         0x60,   /* Byte 5: interframe spacing */
    95         0x00,   /* Byte 6: slot time LSB */
    96         0xf2,   /* Byte 7: slot time and retries */
    97         0x0E,   /* Byte 8: not promisc, disable bcast, tx no crs, crc inserted 32bit, 802.3 framing */
    98         0x08,   /* Byte 9: collision detect */
    99         0x40,   /* Byte 10: minimum frame length */
    100         0xfb,   /* Byte 11: tried C8 same as byte 1 in bits 6-7, else ignored*/
    101         0x00,   /* Byte 12: disable full duplex */
    102         0x3f    /* Byte 13: no multi IA, backoff enabled */
     101  0x0E,   /* Byte 0: length, prefetch off ( no RBD's ) */
     102  0xC8,   /* Byte 1: fifo to 8, monitor off */
     103  0x40,   /* Byte 2: don't save bad frames ( was save= 80, use intel's 40 )*/
     104  0x2E,   /* Byte 3: No source address insertion, 8 byte preamble */
     105  0x00,   /* Byte 4: priority and backoff defaults */
     106  0x60,   /* Byte 5: interframe spacing */
     107  0x00,   /* Byte 6: slot time LSB */
     108  0xf2,   /* Byte 7: slot time and retries */
     109  0x0C,   /* Byte 8: not promisc, enable bcast, tx no crs, crc inserted 32bit, 802.3 framing */
     110  0x08,   /* Byte 9: collision detect */
     111  0x40,   /* Byte 10: minimum frame length */
     112  0xfb,   /* Byte 11: tried C8 same as byte 1 in bits 6-7, else ignored*/
     113  0x00,   /* Byte 12: disable full duplex */
     114  0x3f    /* Byte 13: no multi IA, backoff enabled */
    103115};
    104116
    105117
    106 /* Required RTEMS network driver functions and tasks (reset daemon extra) */
    107 
    108 static void uti596_start( struct ifnet * );
    109 void uti596_init( void * );
    110 void uti596_stop( uti596_softc_ * );
    111 void uti596_txDaemon( void * );
    112 void uti596_rxDaemon( void * );
     118/* Local Routines */
     119
     120static unsigned long word_swap ( unsigned long );
     121static void * malloc_16byte_aligned ( void **, void ** adjusted_pointer, size_t );
     122RTEMS_INLINE_ROUTINE void uti596_writePortFunction ( void *, unsigned long );
     123RTEMS_INLINE_ROUTINE void uti596_portReset( void );
     124static unsigned long uti596_portSelfTest( i596_selftest * );
     125static int uti596_portDump ( i596_dump_result * );
     126static int uti596_wait ( uti596_softc_ *, unsigned8 );
     127static int uti596_issueCA ( uti596_softc_ *, unsigned8 );
     128static void uti596_addCmd ( i596_cmd * );
     129static void uti596_addPolledCmd ( i596_cmd * );
     130static void uti596_CU_dump ( i596_dump_result * );
     131static void uti596_dump_scb ( void );
     132static int uti596_setScpAndScb ( uti596_softc_ * );
     133static int uti596_diagnose ( void );
     134static int uti596_configure ( uti596_softc_ * );
     135static int uti596_IAsetup ( uti596_softc_ * );
     136static int uti596_initTBD ( uti596_softc_ * );
     137static int uti596_initRFA ( int );
     138static void uti596_initMem ( uti596_softc_ * );
     139static void uti596_initialize ( uti596_softc_ * );
     140static void uti596_initialize_hardware ( uti596_softc_ * );
     141static void uti596_reset_hardware ( uti596_softc_ *);
     142static void uti596_reset ( void );
     143static void uti596_clearListStatus ( i596_rfd * );
     144static i596_rfd * uti596_dequeue ( i596_rfd ** );
     145static void uti596_append ( i596_rfd ** , i596_rfd * );
     146static void uti596_supplyFD ( i596_rfd * );
     147static void send_packet ( struct ifnet *, struct mbuf * );
     148
     149
     150/* Required RTEMS network driver functions and tasks (plus reset daemon) */
     151
     152static void uti596_start ( struct ifnet * );
     153void uti596_init ( void * );
     154void uti596_stop ( uti596_softc_ * );
     155void uti596_txDaemon ( void * );
     156void uti596_rxDaemon ( void * );
    113157void uti596_resetDaemon( void * );
    114 rtems_isr uti596_DynamicInterruptHandler (rtems_vector_number );
    115 static int uti596_ioctl( struct ifnet *, int, caddr_t );
    116 void uti596_stats( uti596_softc_ * );
    117 
    118 /* Local Routines */
    119 
    120 void uti596_initialize_hardware( uti596_softc_ * );
    121 void uti596_initMem( uti596_softc_ * );
    122 int uti596_initRFA( int );
    123 void uti596addPolledCmd( i596_cmd * );
    124 void uti596Diagnose( int );
    125 i596_rfd * uti596dequeue( i596_rfd ** );
    126 void uti596reset( void );
    127 void uti596_reset_hardware( uti596_softc_ *);
    128 void uti596clearListStatus( i596_rfd * );
    129 void send_packet( struct ifnet *, struct mbuf * );
    130 void uti596addCmd( i596_cmd *pCmd );
    131 void uti596supplyFD( i596_rfd * );
    132 void uti596append( i596_rfd ** , i596_rfd * );
    133 
    134 void printk_time( void );
    135 void dump_scb( void );
    136 
    137 #ifdef DBG_INIT_3
     158rtems_isr uti596_DynamicInterruptHandler ( rtems_vector_number );
     159static int uti596_ioctl ( struct ifnet *, int, caddr_t );
     160void uti596_stats ( uti596_softc_ * );
     161
     162#ifdef DBG_PACKETS
     163static void dumpQ( void );
     164static void show_buffers( void );
     165static void show_queues( void );
    138166static void print_eth  ( unsigned char * );
    139167static void print_hdr  ( unsigned char * );
     
    142170#endif
    143171
    144 int uti596dump( char * );
    145 void dumpQ( void );
    146 void show_buffers( void );
    147 void show_queues( void );
    148 
    149 /* Helper function for reading/writing big endian memory structures */
    150 unsigned long word_swap(unsigned long);
    151 
    152 
    153 /* Waits for the command word to clear.  The command word is cleared AFTER the interrupt is
    154  * generated. This allows the CPU to issue the next command
    155  */
    156 #define  UTI_WAIT_COMMAND_ACCEPTED(duration,function)                                                                                           \
    157 {               rtems_interval ticks_per_second, start_ticks, end_ticks;                                                                \
    158                 rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);           \
    159                 rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);                                \
    160                 end_ticks = start_ticks + ticks_per_second;                                                                                                                     \
    161                 do {                                                                                                                                                                                                                                                                            \
    162                         if (uti596_softc.scb.command == 0)                                                                                                                                              \
    163                                 break;                                                                                                                                                                                                                                                  \
    164                         else {                                                                                                                                                                                                                                                          \
    165                                 rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);                \
    166                         }                                                                                                                                                                                                                                                                                       \
    167                 } while (start_ticks <= end_ticks);                                                                                                                                                     \
    168                 if ((uti596_softc.scb.command != 0) || (start_ticks > end_ticks))                       \
    169                         printf("%s: i82596 timed out with status %x, cmd %x.\n", function,              \
    170                   uti596_softc.scb.status,  uti596_softc.scb.command);          \
    171 }
    172 
    173 #define  UTI_WAIT_TICKS                                                                                         \
    174 {               rtems_interval ticks_per_second, start_ticks, end_ticks;                                                                \
    175                 rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);           \
    176                 rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);                                \
    177                 end_ticks = start_ticks + ticks_per_second;                                                                                                                     \
    178                 do {                                                                                                                                                                                                                                                                            \
    179                                 rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);                \
    180                 } while (start_ticks <= end_ticks);                                                                                                                                                     \
    181 }
    182 /************************************************************************/
    183 
    184 
    185  /***********************************************************************
    186   *  Function:   uti596_attach
    187   *
    188   *  Description:
    189   *              Configure the driver, and connect to the network stack
    190   *
    191   *  Algorithm:
    192   *
    193   *              Check parameters in the ifconfig structure, and
    194   *                set driver parameters accordingly.
    195   *              initialize required rx and tx buffers
    196   *              link driver data structure onto device list
    197   *              return 1 on successful completion
    198   *
    199   ***********************************************************************/
    200 
    201 int uti596_attach(
    202   struct rtems_bsdnet_ifconfig * pConfig
    203 )
    204 {
    205   uti596_softc_ *sc = &uti596_softc;    /* device dependent data structure */
    206   struct ifnet * ifp = &sc->arpcom.ac_if;                       /* ifnet structure */
    207 
    208         int unitNumber;
    209         char *unitName;
    210 
    211 #ifdef DBG_ATTACH
    212   printk(("uti596_attach: begins\n"))
    213 #endif
    214 
    215   /* The NIC is not started yet */
    216   sc->started = 0;
    217 
    218   /* Indicate to ULCS that this is initialized */
    219   ifp->if_softc = sc;
    220   sc->pScp = NULL;
    221 
    222         /* Parse driver name */
    223         if ((unitNumber = rtems_bsdnet_parse_driver_name (pConfig, &unitName)) < 0)
    224                 return 0;
    225 
    226   ifp->if_name = unitName;
    227   ifp->if_unit = unitNumber;
    228 
    229   /* Assign mtu */
    230   if ( pConfig -> mtu )
    231     ifp->if_mtu = pConfig -> mtu;
    232   else
    233     ifp->if_mtu = ETHERMTU;
    234 
    235   /* For now the ethernet address must be specified in the ifconfig structure,
    236    * else FIXME so it can be read in from BBRAM at $FFFC1F2C (6 bytes)
    237    * mvme167 manual p. 1-47
     172
     173
     174/*
     175 *  word_swap
     176 *
     177 *  Return a 32 bit value, swapping the upper and lower words first.
     178 *
     179 *  Input parameters:
     180 *    val - 32 bit value to swap
     181 *
     182 *  Output parameters: NONE
     183 *
     184 *  Return value:
     185 *    Input value with upper and lower 16-bit words swapped
     186 */
     187static unsigned long word_swap(
     188  unsigned long val
     189)
     190{
     191  return (((val >> 16)&(0x0000ffff)) | ((val << 16)&(0xffff0000)));
     192}
     193
     194
     195/*
     196 *  malloc_16byte_aligned
     197 *
     198 *  Allocate a block of a least nbytes aligned on a 16-byte boundary.
     199 *  Clients are responsible to store both the real address and the adjusted
     200 *  address. The real address must be used to free the block.
     201 *
     202 *  Input parameters:
     203 *    real_pointer - pointer to a void * pointer in which to store the starting
     204 *                   address of the block. Required for free.
     205 *    adjusted_pointer - pointer to a void * pointer in which to store the
     206 *                       starting address of the block rounded up to the next
     207 *                       16 byte boundary.
     208 *    nbytes - number of bytes of storage requested
     209 *
     210 *  Output parameters:
     211 *    real_pointer - starting address of the block.
     212 *    adjusted_pointer - starting address of the block rounded up to the next
     213 *                       16 byte boundary.
     214 *
     215 *  Return value:
     216 *    starting address of the block rounded up to the next 16 byte boundary.
     217 *    NULL if no storage was allocated.
     218 */
     219static void * malloc_16byte_aligned(
     220  void ** real_pointer,
     221  void ** adjusted_pointer,
     222  size_t nbytes
     223)
     224{
     225  *real_pointer = malloc( nbytes + 0xF, 0, M_NOWAIT );
     226  *adjusted_pointer = (void *)(((unsigned long)*real_pointer + 0xF ) & 0xFFFFFFF0 );
     227  return *adjusted_pointer;
     228}
     229
     230
     231/*
     232 *  uti596_scp_alloc
     233 *
     234 *  Allocate a new scp, possibly freeing a previously allocated one.
     235 *
     236 *  Input parameters:
     237 *    sc - pointer to the global uti596_softc in which to store pointers
     238 *         to the newly allocated block.
     239 *
     240 *  Output parameters: NONE
     241 *
     242 *  Return value:
     243 *    Pointer to the newly allocated, 16-byte aligned scp.
     244 */
     245static i596_scp * uti596_scp_alloc(
     246  uti596_softc_ * sc
     247)
     248{
     249  if( sc->base_scp != NULL ) {
     250    #ifdef DBG_MEM
     251    printk(("uti596_scp_alloc: Already have an SCP at %p\n", sc->base_scp))
     252    #endif
     253    return sc->pScp;
     254  }
     255   
     256  /* allocate enough memory for the Scp block to be aligned on 16 byte boundary */
     257  malloc_16byte_aligned( (void *)&(sc->base_scp), (void *)&(sc->pScp), sizeof( i596_scp ) );
     258                                       
     259  #ifdef DBG_MEM
     260  printk(("uti596_scp_alloc: Scp base address is %p\n", sc->base_scp))
     261  printk(("uti596_scp_alloc: Scp aligned address is : %p\n",sc->pScp))
     262  #endif
     263
     264  return sc->pScp;
     265}
     266
     267
     268/*
     269 *  uti596_writePortFunction
     270 * 
     271 *  Write the command into the PORT.
     272 * 
     273 *  Input parameters:
     274 *    addr - 16-byte aligned address to write into the PORT.
     275 *    cmd - 4-bit cmd to write into the PORT
     276 *
     277 *  Output parameters: NONE
     278 *
     279 *  Return value: NONE
     280 *   
     281 *  The Motorola manual swapped the high and low registers.
     282 */
     283RTEMS_INLINE_ROUTINE void uti596_writePortFunction(
     284  void * addr,
     285  unsigned long cmd
     286)
     287{
     288  i82596->port_lower = (unsigned short)(((unsigned long)addr & 0xFFF0) | cmd);
     289  i82596->port_upper = (unsigned short)(((unsigned long)addr >> 16 ) & 0xFFFF);
     290}
     291
     292
     293/*
     294 *  uti596_portReset
     295 *
     296 *  Issue a port Reset to the uti596
     297 *
     298 *  Input parameters: NONE
     299 *
     300 *  Output parameters: NONE
     301 *
     302 *  Return value: NONE
     303 */
     304RTEMS_INLINE_ROUTINE void uti596_portReset( void )
     305{
     306  uti596_writePortFunction( NULL, UTI596_RESET_PORT_FUNCTION );
     307}
     308
     309
     310/*
     311 *  uti596_portSelfTest
     312 *
     313 *  Perform a self-test. Wait for up to 1 second for the test to
     314 *  complete. Normally, the test should complete in a very short time,
     315 *  so busy waiting is not  an issue.
     316 *
     317 *  Input parameters:
     318 *    stp - pointer to a 16-byte aligned uti596_selftest structure.
     319 *
     320 *  Output parameters: NONE
     321 *
     322 *  Return value:
     323 *    32-bit result field if successful, -1 otherwise.
     324 */
     325static unsigned long uti596_portSelfTest(
     326  i596_selftest * stp
     327)
     328{
     329  rtems_interval ticks_per_second, start_ticks, end_ticks;
     330 
     331  stp->results = 0xFFFFFFFF;
     332  uti596_writePortFunction( stp, UTI596_SELFTEST_PORT_FUNCTION );
     333
     334  rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
     335        rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     336        end_ticks = start_ticks + ticks_per_second;     
     337       
     338  do {
     339    if( stp->results != 0xFFFFFFFF )
     340      break;
     341                else
     342                        rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     343        } while (start_ticks <= end_ticks);
     344
     345  if (start_ticks > end_ticks ) {
     346    #ifdef DBG_SELFTEST_CMD
     347    printk(("uti596_selftest: Timed out\n" ))
     348                #endif
     349                return -1;
     350  }
     351  else {
     352    #ifdef DBG_SELFTEST_CMD
     353    printk(("uti596_selftest: Succeeded with signature = 0x%08x, result = 0x%08x\n",
     354                         stp->signature,
     355             stp->results))
     356                #endif
     357                return stp->results;
     358        }
     359}
     360
     361 
     362/*
     363 *  uti596_portDump
     364 *
     365 *  Perform a dump Wait for up to 1 second for the test to
     366 *  complete. Normally, the test should complete in a very short time,
     367 *  so busy waiting is not an issue.
     368 *
     369 *  Input parameters:
     370 *    dp - pointer to a 16-byte aligned uti596_dump structure.
     371 *
     372 *  Output parameters: NONE
     373 *
     374 *  Return value:
     375 *    16-bit dump_status field if successful, -1 otherwise.
     376 */
     377static int uti596_portDump(
     378  i596_dump_result * dp
     379)
     380{
     381  rtems_interval ticks_per_second, start_ticks, end_ticks;
     382 
     383  dp->dump_status = 0;
     384  uti596_writePortFunction( dp, UTI596_DUMP_PORT_FUNCTION );
     385
     386  rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
     387        rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     388        end_ticks = start_ticks + ticks_per_second;     
     389       
     390  do {
     391    if( dp->dump_status != 0xA006 )
     392      break;
     393                else
     394                        rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     395        } while (start_ticks <= end_ticks);
     396
     397  if (start_ticks > end_ticks ) {
     398    #ifdef DBG_DUMP_CMD
     399    printk(("uti596_dump: Timed out with dump at 0x%08x\n", (unsigned long)dp ))
     400                #endif
     401                return -1;
     402  }
     403  else {
     404    #ifdef DBG_DUMP_CMD
     405    printk(("uti596_dump: Succeeded with dump at = 0x%08x\n", (unsigned long)dp ))
     406                #endif
     407                return dp->dump_status;
     408        }
     409}
     410
     411
     412/*
     413 *  uti596_wait
     414 *
     415 *  Wait for a certain condition.
     416 * 
     417 *  Input parameters:
     418 *    sc - pointer to the uti596_softc struct
     419 *    wait_type - UTI596_NO_WAIT
     420 *                UTI596_WAIT_FOR_CU_ACCEPT
     421 *                UTI596_WAIT_FOR_INITIALIZATION
     422 *                UTI596_WAIT_FOR_STAT_C
     423 *
     424 *  Output parameters: NONE
     425 *
     426 *  Return value:
     427 *    0 if successful, -1 otherwise.
     428 */
     429static int uti596_wait(
     430  uti596_softc_ *sc,
     431  unsigned8 waitType
     432)
     433{
     434  rtems_interval ticks_per_second, start_ticks, end_ticks;
     435 
     436  switch( waitType ) {
     437    case UTI596_NO_WAIT:
     438      return 0;
     439
     440    case UTI596_WAIT_FOR_CU_ACCEPT:
     441      rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
     442                  rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     443                  end_ticks = start_ticks + ticks_per_second;
     444
     445                  do {
     446                          if (sc->scb.command == 0)
     447                                  break;
     448                          else
     449                                  rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     450                       
     451                  } while (start_ticks <= end_ticks);
     452                 
     453                  if( (sc->scb.command != 0) || (start_ticks > end_ticks) ) {
     454                          printf("i82596 timed out with status %x, cmd %x.\n",
     455               sc->scb.status,  sc->scb.command);
     456        return -1;
     457      }
     458      else
     459        return 0;
     460 
     461    case UTI596_WAIT_FOR_INITIALIZATION:
     462      rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
     463                  rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     464                  end_ticks = start_ticks + ticks_per_second;
     465
     466                  do {
     467                    if( !sc->iscp.busy )
     468                      break;
     469                                else
     470                                        rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     471                        } while (start_ticks <= end_ticks);
     472
     473                  if (start_ticks > end_ticks ) {
     474                    #ifdef DBG_WAIT
     475                    printk(("uti596_setScpAndScb: Timed out\n"  ))
     476                                #endif
     477                                return -1;
     478                  }
     479                  else {
     480                    #ifdef DBG_WAIT
     481                    printk(("uti596_setScpAndScb: Succeeded\n" ))
     482                                #endif
     483                                return 0;
     484                        }
     485
     486         case UTI596_WAIT_FOR_STAT_C:
     487           rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
     488                 rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     489                 end_ticks = start_ticks + ticks_per_second;
     490
     491                 do {
     492                   if( *sc->pCurrent_command_status & STAT_C )
     493                      break;
     494                         else
     495                                        rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
     496                        } while (start_ticks <= end_ticks);
     497                       
     498                  if (start_ticks > end_ticks ) {
     499                    #ifdef DBG_WAIT
     500                    printk(("uti596_initMem: timed out - STAT_C not obtained\n"  ))
     501                                #endif
     502                                return -1;
     503                  }
     504                  else {
     505                    #ifdef DBG_WAIT
     506                    printk(("uti596_initMem: STAT_C obtained OK\n" ))
     507                                #endif
     508                                return 0;
     509                        }
     510         }
     511         return -1;
     512}
     513 
     514 
     515/*
     516 *  uti596_issueCA
     517 *
     518 *  Issue a Channel Attention command. Possibly wait for the
     519 *  command to start or complete.
     520 * 
     521 *  Input parameters:
     522 *    sc - pointer to the uti596_softc
     523 *    wait_type - UTI596_NO_WAIT
     524 *                UTI596_WAIT_BEGIN
     525 *                UTI596_WAIT_COMPLETION
     526 *
     527 *  Output parameters: NONE
     528 *
     529 *  Return value:
     530 *    0 if successful, -1 otherwise.
     531 */
     532static int uti596_issueCA(
     533  uti596_softc_ *sc,
     534  unsigned8 waitType
     535)
     536{
     537  /* Issue Channel Attention */
     538  i82596->chan_attn = 0x00000000;
     539 
     540  return (uti596_wait ( sc, waitType ));
     541}
     542
     543
     544/*
     545 *  uti596_addCmd
     546 *
     547 *  Add a uti596_cmd onto the end of the CBL command chain,
     548 *      or to the start if the chain is empty.
     549 *
     550 *  Input parameters:
     551 *      pCmd - a pointer to the command to be added.
     552 *
     553 *  Output parameters: NONE
     554 *
     555 *  Return value: NONE
     556 */
     557static void uti596_addCmd(
     558  i596_cmd *pCmd
     559)
     560{
     561  ISR_Level level;
     562
     563        #ifdef DBG_ADD_CMD
     564  printk(("uti596_addCmd: Adding command 0x%x\n", pCmd -> command ))
     565        #endif
     566
     567  /* Mark command as last in list, to return an interrupt */
     568  pCmd->command |= (CMD_EOL | CMD_INTR );
     569  pCmd->status = 0;
     570  pCmd->next = I596_NULL;
     571
     572  _ISR_Disable(level);
     573   
     574  if (uti596_softc.pCmdHead == I596_NULL) {
     575    uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
     576    uti596_softc.scb.cmd_pointer = word_swap ((unsigned long)pCmd);
     577
     578                uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
     579                uti596_softc.scb.command = CUC_START;
     580        uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );
     581     
     582        _ISR_Enable(level);
     583  }
     584  else {
     585    uti596_softc.pCmdTail->next = (i596_cmd *) word_swap ((unsigned long)pCmd);
     586    uti596_softc.pCmdTail = pCmd;
     587    _ISR_Enable(level);
     588        }
     589
     590        #ifdef DBG_ADD_CMD
     591  printk(("uti596_addCmd: Scb status & command 0x%x 0x%x\n",
     592           uti596_softc.scb.status,
     593           uti596_softc.scb.command ))
     594        #endif
     595}
     596
     597
     598/*
     599 *  uti596_addPolledCmd
     600 *
     601 *  Add a single uti596_cmd to the end of the command block list
     602 *  for processing, send a CU_START and wait for its acceptance
     603 *
     604 *  Input parameters:
     605 *      sc - a pointer to the uti596_softc struct
     606 *
     607 *  Output parameters: NONE
     608 *
     609 *  Return value: NONE
     610 */
     611void uti596_addPolledCmd(
     612  i596_cmd *pCmd
     613)
     614{
     615
     616        #ifdef DBG_ADD_CMD
     617  printk(("uti596_addPolledCmd: Adding command 0x%x\n", pCmd -> command ))
     618        #endif
     619
     620        pCmd->status = 0;
     621  pCmd->command |=  CMD_EOL ; /* only command in list*/
     622  pCmd->next = I596_NULL;
     623
     624  uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
     625
     626  uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
     627  uti596_softc.scb.cmd_pointer = word_swap((unsigned long)pCmd);
     628  uti596_softc.scb.command = CUC_START;
     629  uti596_issueCA ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
     630
     631  uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL;
     632  uti596_softc.scb.cmd_pointer = (unsigned long) I596_NULL;
     633
     634        #ifdef DBG_ADD_CMD
     635  printk(("uti596_addPolledCmd: Scb status & command 0x%x 0x%x\n",
     636           uti596_softc.scb.status,
     637           uti596_softc.scb.command ))
     638        #endif
     639}
     640
     641
     642/*
     643 *  uti596_CU_dump
     644 *
     645 *  Dump the LANC 82596 registers
     646 *      The outcome is the same as the portDump() but executed
     647 *      via the CU instead of via a PORT access.
     648 *
     649 *  Input parameters:
     650 *      drp - a pointer to a i596_dump_result structure.
     651 *
     652 *  Output parameters: NONE
     653 *
     654 *  Return value: NONE
     655 */
     656static void uti596_CU_dump ( i596_dump_result * drp)
     657{
     658  i596_dump dumpCmd;
     659
     660  dumpCmd.cmd.command = CmdDump;
     661  dumpCmd.cmd.next    = I596_NULL;
     662  dumpCmd.pData       = (char *) drp;
     663  uti596_softc.cmdOk  = 0;
     664  uti596_addCmd ( (i596_cmd *) &dumpCmd );
     665
     666}
     667
     668
     669/*
     670 *  uti596_dump_scb
     671 *
     672 *  Dump the system control block
     673 *  This function expands to nothing when using interrupt driven I/O
     674 *
     675 *  Input parameters: NONE
     676 *
     677 *  Output parameters: NONE
     678 *
     679 *  Return value: NONE
     680 */
     681static void uti596_dump_scb ( void )
     682{
     683  printk(("status 0x%x\n",uti596_softc.scb.status))
     684  printk(("command 0x%x\n",uti596_softc.scb.command))
     685  printk(("cmd 0x%x\n",(int)uti596_softc.scb.pCmd))
     686  printk(("rfd 0x%x\n",(int)uti596_softc.scb.pRfd))
     687  printk(("crc_err 0x%x\n",uti596_softc.scb.crc_err))
     688  printk(("align_err 0x%x\n",uti596_softc.scb.align_err))
     689  printk(("resource_err 0x%x\n",uti596_softc.scb.resource_err ))
     690  printk(("over_err 0x%x\n",uti596_softc.scb.over_err))
     691  printk(("rcvdt_err 0x%x\n",uti596_softc.scb.rcvdt_err))
     692  printk(("short_err 0x%x\n",uti596_softc.scb.short_err))
     693  printk(("t_on 0x%x\n",uti596_softc.scb.t_on))
     694  printk(("t_off 0x%x\n",uti596_softc.scb.t_off))
     695}
     696
     697
     698/*
     699 *  uti596_setScpAndScb
     700 *
     701 *  Issue the first channel attention after reset and wait for the busy
     702 *  field to clear in the iscp.
     703 *
     704 *  Input parameters:
     705 *    sc - pointer to the global uti596_softc
     706 *
     707 *  Output parameters: NONE
     708 *
     709 *  Return value:
     710 *    0 if successful, -1 otherwise.
     711 */
     712static int uti596_setScpAndScb(
     713  uti596_softc_ * sc
     714)
     715{
     716  /* set the busy flag in the iscp */
     717  sc->iscp.busy = 1;
     718
     719  /* the command block list (CBL) is empty */
     720  sc->scb.command = 0;
     721  sc->scb.cmd_pointer = (unsigned long) I596_NULL;      /* all 1's */
     722  sc->pCmdHead = sc->scb.pCmd = I596_NULL;                          /* all 1's */
     723
     724  uti596_writePortFunction( sc->pScp, UTI596_SCP_PORT_FUNCTION );
     725 
     726  /* Issue CA: pass the scb address to the 596 */
     727  return ( uti596_issueCA ( sc, UTI596_WAIT_FOR_INITIALIZATION ) );
     728}
     729
     730
     731/*
     732 *  uti596_diagnose
     733 *
     734 *  Send a diagnose command to the CU
     735 *
     736 *  Input parameters: NONE
     737 *
     738 *  Output parameters: NONE
     739 *
     740 *  Return value:
     741 *      0 if successful, -1 otherwise
     742 */
     743static int uti596_diagnose( void )
     744{
     745  i596_cmd diagnose;
     746
     747  diagnose.command = CmdDiagnose;
     748  diagnose.status = 0;
     749  uti596_softc.pCurrent_command_status = &diagnose.status;
     750  uti596_addPolledCmd(&diagnose);
     751  return (uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_STAT_C ));
     752
     753        #ifdef DBG_INIT
     754  printk(("Status diagnostic: 0xa000 is a success ... 0x%2.2x\n", diagnose.status))
     755        #endif
     756}
     757
     758
     759/*
     760 *  uti596_configure
     761 *
     762 *  Send the CU a configure command with the desired
     763 *  configuration structure
     764 *
     765 *  Input parameters:
     766 *      sc - a pointer to the uti596_softc struct
     767 *
     768 *  Output parameters: NONE
     769 *
     770 *  Return value:
     771 *      0 if successful, -1 otherwise
     772 */
     773static int uti596_configure (
     774        uti596_softc_ * sc
     775)
     776{
     777  sc->set_conf.cmd.command = CmdConfigure;
     778  memcpy (sc->set_conf.data, uti596initSetup, 14);
     779  uti596_addPolledCmd( (i596_cmd *) &sc->set_conf);
     780
     781  /* Poll for successful command completion */
     782  sc->pCurrent_command_status = &(sc->set_conf.cmd.status);
     783  return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) );
     784}
     785
     786
     787/*
     788 *  uti596_IAsetup
     789 *
     790 *  Send the CU an Individual Address setup command with
     791 *  the ethernet hardware address
     792 *
     793 *  Input parameters:
     794 *      sc - a pointer to the uti596_softc struct
     795 *
     796 *  Output parameters: NONE
     797 *
     798 *  Return value:
     799 *      0 if successful, -1 otherwise
     800 */
     801static int uti596_IAsetup (
     802        uti596_softc_ * sc
     803)
     804{
     805        int i;
     806       
     807  sc->set_add.cmd.command = CmdSASetup;
     808  for ( i=0; i<6; i++) {
     809    sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];
     810  }
     811  sc->cmdOk = 0;
     812  uti596_addPolledCmd((i596_cmd *)&sc->set_add);
     813
     814  /* Poll for successful command completion */
     815  sc->pCurrent_command_status = &(sc->set_add.cmd.status);
     816  return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) );
     817}
     818
     819
     820/*
     821 *  uti596_initTBD
     822 *
     823 *  Initialize transmit buffer descriptors
     824 *    dynamically allocate mem for the number of tbd's required
     825 *
     826 *  Input parameters:
     827 *      sc - a pointer to the uti596_softc struct
     828 *
     829 *  Output parameters: NONE
     830 *
     831 *  Return value:
     832 *      0 if successful, -1 otherwise
     833 */
     834static int uti596_initTBD ( uti596_softc_ * sc )
     835{
     836        int i;
     837  i596_tbd *pTbd, *pPrev;
     838
     839  /* Set up a transmit command with a tbd ready */
     840  sc->pLastUnkRFD = I596_NULL;
     841  sc->pTxCmd = (i596_tx *) calloc (1,sizeof (struct i596_tx) );
     842  sc->pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
     843  if ((sc->pTxCmd == NULL) || (sc->pTbd == NULL)) {
     844        return -1;
     845        }
     846  sc->pTxCmd->pTbd = (i596_tbd *) word_swap ((unsigned long) sc->pTbd);
     847  sc->pTxCmd->cmd.command = CMD_FLEX|CmdTx;
     848  sc->pTxCmd->pad = 0;
     849  sc->pTxCmd->count = 0; /* all bytes are in list of TBD's */
     850
     851  pPrev = pTbd = sc->pTbd;
     852
     853  /* Allocate a linked list of tbd's each with it's 'next' field written
     854   * with upper and lower words swapped (for big endian), and mark the end.
    238855   */
    239   if ( pConfig->hardware_address) {
    240     memcpy (sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
    241   }
    242 
    243   /* Assign requested receive buffer descriptor count */
    244   if (pConfig->rbuf_count)
    245     sc->rxBdCount = pConfig->rbuf_count;
    246   else
    247     sc->rxBdCount = RX_BUF_COUNT;
    248 
    249   /* Assign requested tx buffer descriptor count */
    250   if (pConfig->xbuf_count)
    251     sc->txBdCount = pConfig->xbuf_count;
    252   else
    253     sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
    254 
    255   /* Set up fields in the ifnet structure*/
    256   ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
    257   ifp->if_snd.ifq_maxlen = ifqmaxlen;
    258         ifp->if_init = uti596_init;
    259   ifp->if_ioctl = uti596_ioctl;
    260   ifp->if_start = uti596_start;
    261   ifp->if_output = ether_output;
    262 
    263   /* uti596_softc housekeeping */
    264   sc->started = 1;
    265   sc->pInboundFrameQueue = I596_NULL;
    266   sc->scb.command = 0;
     856  for ( i=0; i<sc->txBdCount; i++) {
     857    if ( (pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) )) == NULL ) {
     858      return -1;
     859    }
     860    pPrev->next = (i596_tbd *) word_swap ((unsigned long) pTbd);
     861    pPrev = pTbd;
     862  }
     863  pTbd->next = I596_NULL;
     864  return 0;
     865}
     866
     867
     868/*
     869 *  uti596_initRFA
     870 *
     871 *  Initialize the Receive Frame Area
     872 *    dynamically allocate mem for the number of rfd's required
     873 *
     874 *  Input parameters:
     875 *      sc - a pointer to the uti596_softc struct
     876 *
     877 *  Output parameters: NONE
     878 *
     879 *  Return value:
     880 *      # of buffer descriptors successfully allocated
     881 */
     882static int uti596_initRFA( int num )
     883{
     884  i596_rfd *pRfd;
     885  int i = 0;
     886
     887        #ifdef DBG_INIT
     888  printk(("uti596_initRFA: begins\n   Requested frame descriptors ... %d.\n", num))
     889        #endif
    267890
    268891  /*
    269    * Attach the interface
     892   * Create the first RFD in the RFA
    270893   */
    271   if_attach (ifp);
    272   ether_ifattach (ifp);
    273   return 1;
    274 }
    275 
    276 /***********************************************************************
    277  *  Function:  uti596_start
    278  *
    279  *  Description:
    280  *             start the driver
    281  *
    282  *  Algorithm:
    283  *                                       send an event to the tx task
    284  *             set the if_flags
    285  *
    286  ***********************************************************************/
    287 static void uti596_start(
    288   struct ifnet *ifp
    289 )
    290 {
    291   uti596_softc_ *sc = ifp->if_softc;
    292 #ifdef DBG_INIT
    293   printk(("uti596_start: begins\n"))
    294 #endif
    295   rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
    296   ifp->if_flags |= IFF_OACTIVE;
    297 }
    298 
    299 /***********************************************************************
    300  *  Function:  uti596_init
    301  *
    302  *  Description:
    303  *             driver initialization
    304  *
    305  *  Algorithm:
    306  *             initialize the 82596
    307  *             start driver tx and rx tasks, and reset task
    308  *             send the RX_START command the the RU
    309  *             set if_flags
    310  *
    311  *
    312  ***********************************************************************/
    313 void uti596_init(
    314   void * arg
    315 )
    316 {
    317   uti596_softc_ *sc = arg;
    318   struct ifnet *ifp = &sc->arpcom.ac_if;
    319 
    320   if (sc->txDaemonTid == 0) {
    321 
    322     /*
    323      * Initialize the 82596
    324      */
    325 #ifdef DBG_INIT
    326     printk(("uti596_init: begins\nuti596_init: initializing the 82596...\n"))
    327 #endif
    328     uti596_initialize_hardware(sc);
    329 
    330     /*
    331      * Start driver tasks
    332      */
    333 #ifdef DBG_INIT
    334     printk(("uti596_init: starting driver tasks...\n"))
    335 #endif
    336     sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, sc);
    337     sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, sc);
    338     sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096, uti596_resetDaemon, sc);
    339 
    340 #ifdef DBG_INIT
    341     printk(("uti596_init: After attach, status of board = 0x%x\n", sc->scb.status ))
    342 #endif
    343   }
    344 
    345   /*
    346    * Enable receiver
    347    */
    348 #ifdef DBG_INIT
    349     printk(("uti596_init: enabling the reciever...\n" ))
    350 #endif
    351   sc->scb.command = RX_START;
    352   i82596->chan_attn = 0x00000000;
    353   UTI_WAIT_COMMAND_ACCEPTED(4000,"uti596_init: RX_START");
    354  
    355   /*
    356    * Tell the world that we're running.
    357    */
    358   ifp->if_flags |= IFF_RUNNING;
    359 #ifdef DBG_INIT
    360     printk(("uti596_init: completed.\n"))
    361 #endif 
    362 }
    363 
    364 /***********************************************************************
    365  *  Function:   uti596stop
    366  *
    367  *  Description:
    368  *             stop the driver
    369  *
    370  *  Algorithm:
    371  *             mark driver as not started,
    372  *             mark transmitter as busy
    373  *             abort any transmissions/receptions
    374  *             clean-up all buffers ( RFD's et. al. )
    375  *
    376  *
    377  *
    378  *
    379  ***********************************************************************/
    380 
    381 /* static */ void uti596_stop(
    382   uti596_softc_ *sc
    383 )
    384 {
    385         struct ifnet *ifp = &sc->arpcom.ac_if;
    386 
    387         ifp->if_flags &= ~IFF_RUNNING;
    388   sc->started = 0;
    389 
    390 #ifdef DBG_596
    391     printk(("uti596stop: %s: Shutting down ethercard, status was %4.4x.\n",
    392            uti596_softc.arpcom.ac_if.if_name, uti596_softc.scb.status))
    393 #endif
    394 
    395     printk(("Stopping interface\n"))
    396     sc->scb.command = CUC_ABORT | RX_ABORT;
    397     i82596->chan_attn = 0x00000000;
    398 }
    399 
    400 
    401 
    402 /***********************************************************************
    403  *  Function:   void uti596_txDaemon
    404  *
    405  *  Description: Transmit task
    406  * 
    407  *  Algorithm: Get mbufs to be transmitted, stuff into RFDs, send
    408  * 
    409  ***********************************************************************/
    410 
    411 void uti596_txDaemon(
    412   void *arg
    413 )
    414 {
    415   uti596_softc_ *sc = (uti596_softc_ *)arg;
    416   struct ifnet *ifp = &sc->arpcom.ac_if;
    417   struct mbuf *m;
    418   rtems_event_set events;
    419 
    420   for (;;) {
    421    /*
    422     * Wait for packet from stack
    423     */
    424     rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
    425                                 RTEMS_EVENT_ANY | RTEMS_WAIT,
    426                                 RTEMS_NO_TIMEOUT, &events);
    427 
    428    /*
    429     * Send packets till queue is empty.
    430     * Ensure that irq is on before sending.
    431     */
    432     for (;;) {
    433      /* Get the next mbuf chain to transmit. */
    434       IF_DEQUEUE(&ifp->if_snd, m);
    435       if (!m)
    436         break;
    437 
    438       send_packet (ifp, m); /* blocks */
    439     }
    440     ifp->if_flags &= ~IFF_OACTIVE; /* no more to send, mark output inactive  */
    441   }
    442 }
    443 
    444 /***********************************************************************
    445  *  Function:   uti596_rxDaemon
    446  *
    447  *  Description: Receiver task
    448  *
    449  *  Algorithm: Extract the packet from an RFD, and place into an
    450  *             mbuf chain.  Place the mbuf chain in the network task
    451  *             queue. Assumes that the frame check sequence is removed
    452  *             by the 82596.
    453  *
    454  ***********************************************************************/
    455 
    456 /* static */ void uti596_rxDaemon(
    457   void *arg
    458 )
    459 {
    460   uti596_softc_ *sc = (uti596_softc_ *)arg;
    461   struct ifnet *ifp = &sc->arpcom.ac_if;
    462   struct mbuf *m;
    463 
    464   i596_rfd *pRfd;
    465   ISR_Level level;
    466   int tid;
    467   rtems_event_set events;
    468   struct ether_header *eh;
    469 
    470   int frames = 0;
    471 #ifdef DBG_INIT_3
    472         int i;
    473 #endif
    474 
    475 #ifdef DBG_596
    476   printk(("uti596_rxDaemon: begin\n"))
    477   printk(("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd))
    478 #endif
    479 
    480   rtems_task_ident (0, 0, &tid);
    481 
    482 #ifdef DBG_596
    483   printk(("uti596_rxDaemon: RX tid = 0x%x\n", tid))
    484 #endif
    485 
    486     for(;;) {
    487       /*
    488        * Wait for packet.
    489        */
    490 #ifdef DBG_596
    491       printk(("uti596_rxDaemon: Receiver sleeps\n"))
    492 #endif
    493 
    494       rtems_bsdnet_event_receive (INTERRUPT_EVENT,
    495                                   RTEMS_WAIT|RTEMS_EVENT_ANY,
    496                                   RTEMS_NO_TIMEOUT,
    497                                   &events);
    498 
    499 #ifdef DBG_596
    500       printk(("uti596_rxDaemon: Receiver wakes\n"))
    501 #endif
    502       /*
    503        * While received frames are available. Note that the frame may be
    504        * a fragment, so it is NOT a complete packet.
    505        */
    506       pRfd = uti596dequeue( &sc->pInboundFrameQueue);
    507       while ( pRfd &&
    508               pRfd != I596_NULL &&
    509               pRfd -> stat & STAT_C )
    510         {
    511 
    512 #ifdef DBG_INIT_3
    513           printk(("\nuti596_rxDaemon: Received packet:\n"))
    514           print_eth( pRfd->data);
    515 #endif
    516           if ( pRfd->stat & STAT_OK) {                                  /*   a good frame */
    517             int pkt_len = pRfd->count & 0x3fff; /* the actual # of bytes received */
    518 
    519 #ifdef DBG_596
    520             printk(("uti596_rxDaemon: Good frame, @%p, data @%p length %d\n", pRfd, pRfd -> data , pkt_len))
    521 #endif
    522             frames++;
    523 
    524             /*
    525              * Allocate an mbuf to give to the stack
    526              * The format of the data portion of the RFD is:
    527              * <ethernet header, payload>.
    528              * The FRAME CHECK SEQUENCE / CRC is stripped by the uti596.
    529              * This is to be optimized later.... should not have to memcopy!
    530              */
    531             MGETHDR(m, M_WAIT, MT_DATA);
    532             MCLGET(m, M_WAIT);
    533 
    534             m->m_pkthdr.rcvif = ifp;
    535             /* move everything into an mbuf */
    536             memcpy(m->m_data,
    537                                  pRfd->data,
    538                    pkt_len);
    539 
    540             m->m_len = m->m_pkthdr.len = pkt_len - sizeof(struct ether_header) - 4;
    541 
    542             /* move the header to an mbuf */
    543             eh = mtod (m, struct ether_header *);
    544             m->m_data += sizeof(struct ether_header);
    545 
    546 #ifdef DBG_596
    547             printk(("uti596_rxDaemon: m->m_ext: %p pRfd -> data: %p\n",
    548                     m->m_ext, pRfd->data))
    549 #endif
    550 #ifdef DBG_INIT_3
    551             printk(("uti596_rxDaemon: mbuf contains:\n"))
    552             print_eth( (char *) (((int)m->m_data)-sizeof(struct ether_header)));
    553             for ( i = 0; i<20; i++) {
    554               printk(("."))
    555             }
    556 #endif
    557             ether_input (ifp, eh, m);
    558 
    559           } /* end if STAT_OK */
    560 
    561           else {
    562             /*
    563              * A bad frame is present: Note that this could be the last RFD!
    564              */
    565 #ifdef DBG_596
    566             printk(("uti596_rxDaemon: Bad frame\n"))
    567 #endif
    568             /*
    569              * FIX ME: use the statistics from the SCB
    570              */
    571             sc->stats.rx_errors++;
    572             if ((sc->scb.pRfd->stat) & 0x0001)
    573               sc->stats.collisions++;
    574             if ((sc->scb.pRfd->stat) & 0x0080)
    575               sc->stats.rx_length_errors++;
    576             if ((sc->scb.pRfd->stat) & 0x0100)
    577               sc->stats.rx_over_errors++;
    578             if ((sc->scb.pRfd->stat) & 0x0200)
    579               sc->stats.rx_fifo_errors++;
    580             if ((sc->scb.pRfd->stat) & 0x0400)
    581               sc->stats.rx_frame_errors++;
    582             if ((sc->scb.pRfd->stat) & 0x0800)
    583               sc->stats.rx_crc_errors++;
    584             if ((sc->scb.pRfd->stat) & 0x1000)
    585               sc->stats.rx_length_errors++;
    586           }
    587 
    588           UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD\n")
    589 
    590 #ifdef DBG_SUPPLY_FD
    591           printk(("uti596_rxDaemon: Supply FD Starting\n"))
    592 #endif
    593           _ISR_Disable(level);
    594           uti596supplyFD ( pRfd );   /* Return RFD to RFA. */
    595           _ISR_Enable(level);
    596 #ifdef DBG_SUPPLY_FD
    597           printk(("uti596_rxDaemon: Supply FD Complete\n"))
    598 #endif
    599           pRfd = uti596dequeue( &sc->pInboundFrameQueue); /* grab next frame */
    600 
    601         } /* end while */
    602     } /* end for(;;) */
    603 
    604 #ifdef DBG_596
    605     printk (("uti596_rxDaemon: frames ... %d\n", frames))
    606 #endif
    607 }
    608 
    609 /***********************************************************************
    610  *  Function:   void uti596_resetDaemon
    611  *
    612  *  Description:
    613  ***********************************************************************/
    614 void uti596_resetDaemon(
    615   void *arg
    616 )
    617 {
    618   uti596_softc_ *sc = (uti596_softc_ *)arg;
    619   rtems_event_set events;
    620   rtems_time_of_day tm_struct;
    621 
    622   /* struct ifnet *ifp = &sc->arpcom.ac_if; */
    623 
    624   for (;;) {
    625    /* Wait for reset event from ISR */
    626     rtems_bsdnet_event_receive (NIC_RESET_EVENT,
    627                                 RTEMS_EVENT_ANY | RTEMS_WAIT,
    628                                 RTEMS_NO_TIMEOUT, &events);
    629 
    630     rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
    631     printk(("reset daemon: Resetting NIC @ %d:%d:%d \n",
    632            tm_struct.hour, tm_struct.minute, tm_struct.second))
    633 
    634     sc->stats.nic_reset_count++;
    635     /* Reinitialize the LANC */
    636     rtems_bsdnet_semaphore_obtain ();
    637     uti596reset();
    638     rtems_bsdnet_semaphore_release ();
    639   }
    640 }
    641 
    642 
    643  /***********************************************************************
    644   *  Function:   uti596_DynamicInterruptHandler
    645   *
    646   *  Description:
    647   *             This is the interrupt handler for the uti596 board
    648   *
    649   *  Algorithm:
    650   *
    651   ***********************************************************************/
    652 
    653 /* static */ rtems_isr uti596_DynamicInterruptHandler(
    654   rtems_vector_number irq
    655 )
    656 {
    657 #ifdef DEBUG_ISR
    658   printk(("uti596_DynamicInterruptHandler: begins"))
    659 #endif
    660 
    661  UTI_WAIT_COMMAND_ACCEPTED(20000,"****ERROR:on ISR entry");
    662 
    663  scbStatus = uti596_softc.scb.status & 0xf000;
    664 
    665  if ( scbStatus ) {
    666    /* acknowledge interrupts */
    667    
    668    /* Write to the ICLR bit in the PCCchip2 control registers to clear
    669     * the INT status bit. Clearing INT here *before* sending the CA signal
    670     * to the 82596 should ensure that interrupts won't be lost.
    671     */
    672     pccchip2->LANC_int_ctl |=0x08;
    673     pccchip2->LANC_berr_ctl |=0x08;
    674    
    675     /* printk(("***INFO: ACK %x\n", scbStatus))*/
    676    
    677     /* Send the CA signal to acknowledge interrupt */
    678     uti596_softc.scb.command = scbStatus;
    679     i82596->chan_attn = 0x00000000;
    680 
    681     if( uti596_softc.resetDone ) {
    682       /* stack is attached */
    683       UTI_WAIT_COMMAND_ACCEPTED(20000,"****ERROR:ACK");
     894  pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd));
     895  if ( !pRfd ) {
     896    printk(("Can't allocate first buffer.\n"))
     897    return 0;
     898  }
     899  else {
     900    uti596_softc.countRFD = 1;
     901    uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
     902  }
     903
     904  /* Create remaining RFDs */
     905  for (i = 1; i < num; i++) {
     906    pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd) );
     907    if ( pRfd != NULL ) {
     908      uti596_softc.countRFD++;                          /* update count */
     909      uti596_softc.pEndRFA->next =
     910        (i596_rfd *) word_swap ((unsigned long) pRfd);  /* write the link */
     911      uti596_softc.pEndRFA = pRfd;                                                                              /* move the end */
    684912    }
    685913    else {
    686       /* printk(("***INFO: ACK'd w/o processing. status = %x\n", scbStatus)) */
    687       return;
     914      printk(("Can't allocate all buffers: only %d allocated\n", i))
     915      break;
    688916    }
    689   }
    690   else {
    691     printk(("\n***ERROR: Spurious interrupt. Resetting...\n"))
    692     uti596_softc.nic_reset = 1;
    693   }
    694 
    695 
    696   if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ){
    697     printk_time();
    698     printk(("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus))
    699     uti596_softc.nic_reset = 1;
    700     return;
    701   }
    702 
    703   if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {
    704     printk_time();
    705     printk(("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus))
    706     uti596_softc.nic_reset = 1;
    707     return;
    708   }
    709 
    710   if ( scbStatus & SCB_CUS_SUSPENDED ) {
    711     printk_time();
    712     printk(("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus))
    713     uti596_softc.nic_reset = 1;
    714     return;
    715   }
    716 
    717   if ( scbStatus & RU_SUSPENDED  ) {
    718     printk_time();
    719     printk(("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus))
    720     uti596_softc.nic_reset = 1;
    721     return;
    722   }
    723 
    724   if ( scbStatus & SCB_STAT_RNR ) {
    725     printk_time();
    726     printk(("\n*****WARNING: RNR %x\n",scbStatus))
    727     if (uti596_softc.pBeginRFA != I596_NULL) {
    728         printk(("*****INFO: RFD cmd: %x status:%x\n", uti596_softc.pBeginRFA->cmd,
    729                                         uti596_softc.pBeginRFA->stat))
    730     }
    731     else {
    732         printk(("*****WARNING: RNR condition with NULL BeginRFA\n"))
    733     }         
    734   }
    735 
    736  /*
    737   * Receive Unit Control
    738   *   a frame is received
    739   */
    740   if ( scbStatus & SCB_STAT_FR ) {
    741     uti596_softc.rxInterrupts++;
    742  
    743 #ifdef DBG_FR
    744     printk(("uti596_DynamicInterruptHandler: Frame received\n"))
    745 #endif
    746     if ( uti596_softc.pBeginRFA == I596_NULL ||
    747          !( uti596_softc.pBeginRFA -> stat & STAT_C)) {
    748      dump_scb();
    749      uti596_softc.nic_reset = 1;
    750     }
    751     else {
    752       while ( uti596_softc.pBeginRFA != I596_NULL &&
    753            ( uti596_softc.pBeginRFA -> stat & STAT_C)) {
    754 
    755 #ifdef DBG_ISR
    756         printk(("uti596_DynamicInterruptHandler: pBeginRFA != NULL\n"))
    757 #endif
    758         count_rx ++;
    759         if ( count_rx > 1) {
    760           printk(("****WARNING: Received 2 frames on 1 interrupt \n"))
    761                                 }
    762        /* Give Received Frame to the ULCS */
    763         uti596_softc.countRFD--;
    764 
    765         if ( uti596_softc.countRFD < 0 ) {
    766           printk(("ISR: Count < 0 !!! count == %d, beginRFA = %p\n",
    767                  uti596_softc.countRFD, uti596_softc.pBeginRFA))
    768                                 }
    769         uti596_softc.stats.rx_packets++;
    770         /* the rfd next link is stored with upper and lower words swapped so read it that way */
    771         pIsrRfd = (i596_rfd *) word_swap ((unsigned long)uti596_softc.pBeginRFA->next);
    772         /* the append destroys the link */
    773         uti596append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );
    774 
    775        /*
    776         * if we have just received the a frame in the last unknown RFD,
    777         * then it is certain that the RFA is empty.
    778         */
    779         if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) {
    780           UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n")
    781           uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;
    782         }
    783 
    784 #ifdef DBG_ISR
    785         printk(("uti596_DynamicInterruptHandler: Wake %#x\n",uti596_softc.rxDaemonTid))
    786 #endif
    787         sc = rtems_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT);
    788         if ( sc != RTEMS_SUCCESSFUL ) {
    789           rtems_panic("Can't notify rxDaemon: %s\n",
    790                     rtems_status_text (sc));
    791         }
    792 #ifdef DBG_RAW_ISR
    793         else {
    794           printk(("uti596_DynamicInterruptHandler: Rx Wake: %#x\n",uti596_softc.rxDaemonTid))
    795                                 }
    796 #endif
    797 
    798         uti596_softc.pBeginRFA = pIsrRfd;
    799       } /* end while */
    800     } /* end if */
    801 
    802     if ( uti596_softc.pBeginRFA == I596_NULL ) {
    803       /* adjust the pEndRFA to reflect an empty list */
    804       if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 ) {
    805         printk(("Last Unk is NULL, BeginRFA is null, and count == %d\n",
    806                uti596_softc.countRFD))
    807                         }
    808       uti596_softc.pEndRFA = I596_NULL;
    809       if ( uti596_softc.countRFD != 0 ) {
    810         printk(("****ERROR:Count is %d, but begin ptr is NULL\n",
    811                uti596_softc.countRFD ))
    812       }
    813     }
    814   } /* end if ( scbStatus & SCB_STAT_FR ) */
    815 
    816 
    817  /*
    818   * Command Unit Control
    819   *   a command is completed
    820   */
    821   if ( scbStatus & SCB_STAT_CX ) {
    822 #ifdef DBG_ISR
    823     printk(("uti596_DynamicInterruptHandler: CU\n"))
    824 #endif
    825 
    826     pIsrCmd = uti596_softc.pCmdHead;
    827 
    828    /* For ALL completed commands */
    829    if ( pIsrCmd !=  I596_NULL && pIsrCmd->status & STAT_C  ) {
    830 
    831 #ifdef DBG_RAW_ISR
    832        printk(("uti596_DynamicInterruptHandler: pIsrCmd != NULL\n"))
    833 #endif
    834 
    835       /* Adjust the command block list */
    836       uti596_softc.pCmdHead = (i596_cmd *) word_swap ((unsigned long)pIsrCmd->next);
    837 
    838      /*
    839       * If there are MORE commands to process,
    840       * the serialization in the raw routine has failed.
    841       * ( Perhaps AddCmd is bad? )
    842       */
    843       UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL, "****ERROR: command serialization failed\n")
    844                    
    845       /* What if the command did not complete OK? */
    846       switch ( pIsrCmd->command & 0x7) {
    847         case CmdConfigure:
    848 
    849           /*      printk(("****INFO:Configure OK\n")) */
    850           uti596_softc.cmdOk = 1;
    851           break;
    852 
    853         case CmdDump:
    854 #ifdef DBG_ISR
    855           printk(("uti596_DynamicInterruptHandler: dump!\n"))
    856 #endif
    857           uti596_softc.cmdOk = 1;
    858           break;
    859 
    860         case CmdDiagnose:
    861 #ifdef DBG_ISR
    862           printk(("uti596_DynamicInterruptHandler: diagnose!\n"))
    863 #endif
    864           uti596_softc.cmdOk = 1;
    865           break;
    866 
    867         case CmdSASetup:
    868           /* printk(("****INFO:Set address interrupt\n")) */
    869           if ( pIsrCmd -> status & STAT_OK ) {
    870             uti596_softc.cmdOk = 1;
    871           }
    872           else {
    873             printk(("****ERROR:SET ADD FAILED\n"))
    874                                         }
    875           break;
    876 
    877         case CmdTx:
    878           UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n")
    879 #ifdef DBG_ISR
    880           printk(("uti596_DynamicInterruptHandler: wake TX:0x%x\n",uti596_softc.txDaemonTid))
    881 #endif
    882           if ( uti596_softc.txDaemonTid ) {
    883             /* Ensure that the transmitter is present */
    884             sc = rtems_event_send (uti596_softc.txDaemonTid,
    885                                  INTERRUPT_EVENT);
    886 
    887             if ( sc != RTEMS_SUCCESSFUL ) {
    888               printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",
    889                      uti596_softc.txDaemonTid, rtems_status_text (sc) ))
    890             }
    891 #ifdef DBG_RAW_ISR
    892             else {
    893               printk(("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid))
    894             }
    895 #endif
    896           }
    897           break;
    898 
    899         case CmdMulticastList:
    900           printk(("***ERROR:Multicast?!\n"))
    901           pIsrCmd->next = I596_NULL;
    902           break;
    903 
    904         case CmdTDR: {
    905                   unsigned long status = *( (unsigned long *)pIsrCmd)+1;
    906                   printk(("****ERROR:TDR?!\n"))
    907 
    908                   if (status & STAT_C) {
    909                     /* mark the TDR command successful */
    910                     uti596_softc.cmdOk = 1;
    911                   }
    912                   else {
    913                     if (status & 0x4000) {
    914                       printk(("****WARNING:Transceiver problem.\n"))
    915                     }
    916                     if (status & 0x2000) {
    917                       printk(("****WARNING:Termination problem.\n"))
    918                     }
    919                     if (status & 0x1000) {
    920                       printk(("****WARNING:Short circuit.\n"))
    921                       /* printk(("****INFO:Time %ld.\n", status & 0x07ff)) */
    922                     }
    923                   }
    924           }
    925           break;
    926 
    927         default: {
    928           /*
    929            * This should never be reached
    930            */
    931           printk(("CX but NO known command\n"))
    932         }
    933       } /* end switch */
    934 
    935       pIsrCmd = uti596_softc.pCmdHead; /* next command */
    936       if ( pIsrCmd != I596_NULL ) {
    937         printk(("****WARNING: more commands in list, but no start to NIC\n"))
    938       }
    939     } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C  */
    940    
    941     else {
    942       if ( pIsrCmd != I596_NULL ) {
    943         /* The command MAY be NULL from a RESET */
    944         /* Reset the ethernet card, and wake the transmitter (if necessary) */
    945         printk_time();
    946         printk(("****INFO: Request board reset ( tx )\n"))
    947         uti596_softc.nic_reset = 1;
    948         if ( uti596_softc.txDaemonTid) {
    949           /* Ensure that a transmitter is present */
    950           sc = rtems_event_send (uti596_softc.txDaemonTid,
    951                                  INTERRUPT_EVENT);
    952           if ( sc != RTEMS_SUCCESSFUL ) {
    953             printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",uti596_softc.txDaemonTid, rtems_status_text (sc) ))
    954                                         }
    955 #ifdef DBG_RAW_ISR
    956           else {
    957             printk(("uti596_DynamicInterruptHandler: ****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid))
    958                                         }
    959 #endif
    960         }
    961       }
    962     }
    963   }  /* end if command complete */
    964 
    965 
    966  /*
    967   * If the receiver has stopped,
    968   * check if this is a No Resources scenario,
    969   * Try to add more RFD's ( no RBDs are used )
    970   */
    971   if ( uti596_softc.started ) {
    972     if ( scbStatus & SCB_STAT_RNR ) {
    973 #ifdef DBG_ISR
    974       printk(("uti596_DynamicInterruptHandler: INFO:RNR: status %#x \n", uti596_softc.scb.status ))
    975 #endif
    976      /*
    977       * THE RECEIVER IS OFF!
    978       */
    979       if ( uti596_softc.pLastUnkRFD != I596_NULL  ) {
    980         /* We have an unknown RFD, it is not inbound */
    981         if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) { /* in use */
    982           uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD;            /* update end */
    983         }
    984         else {
    985          /*
    986           *  It is NOT in use, and since RNR, we know EL bit of pEndRFA was read!
    987           *  So, unlink it from the RFA and move it to the saved queue.
    988           *  But pBegin can equal LastUnk!
    989           */
    990 
    991           if ( uti596_softc.pEndRFA != I596_NULL ) {
    992             /* check added feb24. */
    993 #ifdef DEBUG_RFA
    994             if ((i596_rfd *)word_swap((unsigned long)uti596_softc.pEndRFA->next) != uti596_softc.pLastUnkRFD) {
    995               printk(("***ERROR:UNK: %p not end->next: %p, end: %p\n",
    996                      uti596_softc.pLastUnkRFD,
    997                      uti596_softc.pEndRFA -> next,
    998                      uti596_softc.pEndRFA))
    999               printk(("***INFO:countRFD now %d\n",
    1000                      uti596_softc.countRFD))
    1001               printk(("\n\n"))
    1002             }
    1003 #endif
    1004             uti596_softc.pEndRFA -> next = I596_NULL;   /* added feb 16 */
    1005           }
    1006           uti596append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );
    1007           uti596_softc.savedCount++;
    1008           uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD;
    1009           uti596_softc.countRFD--;                    /* It was not in the RFA */
    1010          /*
    1011           * The Begin pointer CAN advance this far. We must resynch the CPU side
    1012           * with the chip.
    1013           */
    1014           if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {
    1015 #ifdef DEBUG_RFA
    1016             if ( uti596_softc.countRFD != 0 ) {
    1017               printk(("****INFO:About to set begin to NULL, with count == %d\n\n",
    1018                      uti596_softc.countRFD ))
    1019             }
    1020 #endif
    1021             uti596_softc.pBeginRFA = I596_NULL;
    1022             UTI_596_ASSERT(uti596_softc.countRFD == 0, "****ERROR:Count must be zero here!\n")
    1023           }
    1024         }
    1025         uti596_softc.pLastUnkRFD = I596_NULL;
    1026       } /* end if exists UnkRFD */
    1027 
    1028      /*
    1029       * Append the saved queue to  the RFA.
    1030       * Any further RFD's being supplied will be added to
    1031       * this new list.
    1032       */
    1033       if ( uti596_softc.pSavedRfdQueue != I596_NULL ) {
    1034         /* entries to add */
    1035         if ( uti596_softc.pBeginRFA == I596_NULL ) {
    1036           /* add at beginning to list */
    1037 #ifdef DEBUG_RFA
    1038           if(uti596_softc.countRFD != 0) {
    1039             printk(("****ERROR:Begin pointer is NULL, but count == %d\n",
    1040                    uti596_softc.countRFD))
    1041           }
    1042 #endif
    1043           uti596_softc.pBeginRFA      = uti596_softc.pSavedRfdQueue;
    1044           uti596_softc.pEndRFA        = uti596_softc.pEndSavedQueue;
    1045           uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL;  /* Reset the End */
    1046         }
    1047         else {
    1048 #ifdef DEBUG_RFA
    1049           if ( uti596_softc.countRFD <= 0) {
    1050             printk(("****ERROR:Begin pointer is not NULL, but count == %d\n",
    1051                    uti596_softc.countRFD))
    1052           }
    1053 #endif
    1054           UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n")
    1055           UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n")
    1056 
    1057           uti596_softc.pEndRFA->next   = (i596_rfd *)word_swap((unsigned long)uti596_softc.pSavedRfdQueue);
    1058           uti596_softc.pEndRFA->cmd   &= ~CMD_EOL;      /* clear the end of list */
    1059           uti596_softc.pEndRFA         = uti596_softc.pEndSavedQueue;
    1060           uti596_softc.pSavedRfdQueue  = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */
    1061 #ifdef DEBUG_ISR
    1062           printk(("uti596_DynamicInterruptHandler: count... %d, saved ... %d \n",
    1063                  uti596_softc.countRFD,
    1064                  uti596_softc.savedCount))
    1065 #endif
    1066         }
    1067         /* printk(("Isr: countRFD = %d\n",uti596_softc.countRFD)) */
    1068         uti596_softc.countRFD += uti596_softc.savedCount;
    1069         /* printk(("Isr: after countRFD = %d\n",uti596_softc.countRFD)) */
    1070         uti596_softc.savedCount = 0;
    1071       }
    1072 
    1073 #ifdef DBG_596_RFD
    1074       printk(("uti596_DynamicInterruptHandler: The list starts here %p\n",uti596_softc.pBeginRFA ))
    1075 #endif
    1076 
    1077       if ( uti596_softc.countRFD > 1) {
    1078         printk_time();
    1079         printk(("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat))
    1080         printk(("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd))
    1081         uti596_softc.pBeginRFA -> stat = 0;
    1082         UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n")
    1083         uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
    1084         uti596_softc.scb.Rfd_val = word_swap((unsigned long)uti596_softc.pBeginRFA);
    1085         /* start RX here  */
    1086         printk(("****INFO: ISR Starting receiver\n"))
    1087         uti596_softc.scb.command = RX_START; /* should this also be CU start? */
    1088         i82596->chan_attn = 0x00000000;
    1089       }
    1090     } /* end stat_rnr */
    1091   } /* end if receiver started */
    1092 
    1093 #ifdef DBG_ISR
    1094   printk(("uti596_DynamicInterruptHandler: X\n"))
    1095 #endif
    1096   count_rx=0;
    1097  
    1098  
    1099  /* Do this last, to ensure that the reset is called at the right time. */
    1100   if ( uti596_softc.nic_reset ) {
    1101     uti596_softc.nic_reset = 0;
    1102     sc = rtems_event_send(uti596_softc.resetDaemonTid, NIC_RESET_EVENT);
    1103     if ( sc != RTEMS_SUCCESSFUL )
    1104       rtems_panic ("Can't notify resetDaemon: %s\n", rtems_status_text (sc));
    1105   }
    1106   return;
    1107 }
    1108 
    1109 /***********************************************************************
    1110  *  Function:  uti596_ioctl
    1111  *
    1112  *  Description:
    1113  *             driver ioctl function
    1114  *             handles SIOCGIFADDR, SIOCSIFADDR, SIOCSIFFLAGS
    1115  *             
    1116  *  Algorithm:
    1117  *
    1118  ***********************************************************************/
    1119  
    1120 static int uti596_ioctl(
    1121   struct ifnet *ifp,
    1122   int command, caddr_t data
    1123 )
    1124 {
    1125   uti596_softc_ *sc = ifp->if_softc;
    1126   int error = 0;
    1127 
    1128 #ifdef DBG_INIT
    1129   printk(("uti596_ioctl: begins\n", sc->pScp))
    1130 #endif
    1131 
    1132   switch (command) {
    1133     case SIOCGIFADDR:
    1134     case SIOCSIFADDR:
    1135       printk(("SIOCSIFADDR\n"))
    1136       ether_ioctl (ifp, command, data);
    1137       break;
    1138 
    1139     case SIOCSIFFLAGS:
    1140       printk(("SIOCSIFFLAGS\n"))
    1141       switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
    1142         case IFF_RUNNING:
    1143           printk(("IFF_RUNNING\n"))
    1144           uti596_stop (sc);
    1145           break;
    1146 
    1147         case IFF_UP:
    1148           printk(("IFF_UP\n"))
    1149           uti596_init (sc);
    1150           break;
    1151 
    1152         case IFF_UP | IFF_RUNNING:
    1153           printk(("IFF_UP and RUNNING\n"))
    1154           uti596_stop (sc);
    1155           uti596_init (sc);
    1156           break;
    1157 
    1158         default:
    1159           printk(("default\n"))
    1160           break;
    1161       }
    1162       break;
    1163 
    1164     case SIO_RTEMS_SHOW_STATS:
    1165       printk(("show stats\n"))
    1166       uti596_stats (sc);
    1167       break;
    1168 
    1169     /* FIXME: All sorts of multicast commands need to be added here! */
    1170     default:
    1171       printk(("default: EINVAL\n"))
    1172       error = EINVAL;
    1173       break;
    1174   }
    1175  
    1176   return error;
    1177 }
    1178 
    1179 /***********************************************************************
    1180  *  Function:   uti596_stats
    1181  *
    1182  *  Description:
    1183  *             print out the collected data
    1184  *
    1185  *  Algorithm:
    1186  *            use printf
    1187  *
    1188  ***********************************************************************/
    1189 
    1190 void uti596_stats(
     917  } /* end for */
     918
     919  uti596_softc.pEndRFA->next = I596_NULL;
     920  UTI_596_ASSERT(uti596_softc.countRFD == RX_BUF_COUNT,"INIT:WRONG RFD COUNT\n" )
     921
     922  #ifdef DBG_INIT
     923  printk (("uti596_initRFA: Head of RFA is buffer %p \n\
     924            uti596_initRFA: End of RFA is buffer %p \n",
     925            uti596_softc.pBeginRFA, uti596_softc.pEndRFA ))
     926        #endif
     927
     928  /* Walk and initialize the RFD's */
     929  for ( pRfd = uti596_softc.pBeginRFA;
     930        pRfd != I596_NULL;
     931        pRfd = (i596_rfd *) word_swap ((unsigned long)pRfd->next) )
     932  {
     933    pRfd->cmd   = 0x0000;
     934    pRfd->stat  = 0x0000;
     935    pRfd->pRbd  = I596_NULL;
     936    pRfd->count = 0;            /* number of bytes in buffer: usually less than size */
     937    pRfd->size   = 1532;  /* was 1532;  buffer size ( All RBD ) */
     938  } /* end for */
     939
     940  /* mark the last RFD as the last one in the RDL */
     941  uti596_softc.pEndRFA -> cmd = CMD_EOL;
     942  uti596_softc.pSavedRfdQueue =
     943    uti596_softc.pEndSavedQueue = I596_NULL;   /* initially empty */
     944
     945  uti596_softc.savedCount = 0;
     946  uti596_softc.nop.cmd.command = CmdNOp; /* initialize the nop command */
     947
     948  return (i); /* the number of allocated buffers */
     949}
     950
     951
     952/*
     953 *  uti596_initMem
     954 *
     955 *  Initialize the 82596 memory structures for Tx and Rx
     956 *    dynamically allocate mem for the number of tbd's required
     957 *
     958 *  Input parameters:
     959 *      sc - a pointer to the uti596_softc struct
     960 *
     961 *  Output parameters: NONE
     962 *
     963 *  Return value: NONE
     964 */
     965void uti596_initMem(
     966  uti596_softc_ * sc
     967)
     968{
     969  int i;
     970
     971  #ifdef DBG_INIT
     972  printk(("uti596_initMem: begins\n"))
     973  #endif
     974
     975  sc->resetDone = 0;
     976
     977  /*
     978   * Set up receive frame area (RFA)
     979   */
     980  i = uti596_initRFA( sc->rxBdCount );
     981  if ( i < sc->rxBdCount ) {
     982    printk(("init_rfd: only able to allocate %d receive frame descriptors\n", i))
     983  }
     984               
     985  /*
     986   * Write the SCB with a pointer to the receive frame area
     987   * and keep a pointer for our use.
     988   */
     989  sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA);
     990  sc->scb.pRfd =  sc->pBeginRFA;
     991
     992  /*
     993   * Diagnose the health of the board
     994   */
     995  uti596_diagnose();
     996
     997  /*
     998   * Configure the 82596
     999   */
     1000  uti596_configure( sc );
     1001
     1002  /*
     1003   * Set up the Individual (hardware) Address
     1004   */
     1005  uti596_IAsetup ( sc );
     1006
     1007        /*
     1008         * Initialize the transmit buffer descriptors
     1009         */
     1010  uti596_initTBD( sc );
     1011
     1012  /* Padding used to fill short tx frames */
     1013  memset ( &sc->zeroes, 0, 64);
     1014
     1015  /* now need ISR  */
     1016  sc->resetDone = 1;
     1017}
     1018
     1019/*
     1020 *  uti596_initialize
     1021 *
     1022 *  Reset the 82596 and initialize it with a new SCP.
     1023 * 
     1024 *  Input parameters:
     1025 *    sc - pointer to the uti596_softc
     1026 *
     1027 *  Output parameters: NONE
     1028 *
     1029 *  Return value: NONE
     1030 */
     1031void uti596_initialize(
    11911032  uti596_softc_ *sc
    11921033)
    11931034{
    1194   printf("CPU Reports:\n");
    1195   printf ("  Tx raw send count:%-8lu",  sc->rawsndcnt);
    1196   printf ("  Rx Interrupts:%-8lu",  sc->rxInterrupts);
    1197   printf ("  Tx Interrupts:%-8lu\n",  sc->txInterrupts);
    1198   printf ("  Rx Packets:%-8u",  sc->stats.rx_packets);
    1199   printf ("  Tx Attempts:%-u\n",  sc->stats.tx_packets);
    1200 
    1201   printf ("  Rx Dropped:%-8u",  sc->stats.rx_dropped);
    1202   printf ("  Rx IP Packets:%-8u",  sc->stats.rx_packets);
    1203   printf ("  Tx Errors:%-8u\n",  sc->stats.tx_errors);
    1204   printf ("  Tx aborted:%-8u",  sc->stats.tx_aborted_errors);
    1205   printf ("  Tx Dropped:%-8u\n",  sc->stats.tx_dropped);
    1206   printf ("  Tx IP packets:%-8u",  sc->stats.tx_packets);
    1207 
    1208   printf ("  Collisions Detected:%-8u\n",  sc->stats.collisions);
    1209   printf ("  Tx Heartbeat Errors:%-8u",  sc->stats.tx_heartbeat_errors);
    1210   printf ("  Tx Carrier Errors:%-8u\n",  sc->stats.tx_carrier_errors);
    1211   printf ("  Tx Aborted Errors:%-8u",  sc->stats.tx_aborted_errors);
    1212   printf ("  Rx Length Errors:%-8u\n",  sc->stats.rx_length_errors);
    1213   printf ("  Rx Overrun Errors:%-8u",  sc->stats.rx_over_errors);
    1214   printf ("  Rx Fifo Errors:%-8u\n",  sc->stats.rx_fifo_errors);
    1215   printf ("  Rx Framing Errors:%-8u",  sc->stats.rx_frame_errors);
    1216   printf ("  Rx crc errors:%-8u\n",  sc->stats.rx_crc_errors);
    1217 
    1218   printf ("  TX WAITS: %-8lu\n",  sc->txRawWait);
    1219 
    1220   printf ("  NIC resets: %-8u\n",  sc->stats.nic_reset_count);
    1221 
    1222   printf("  NIC reports\n");
    1223 
    1224   dump_scb();
    1225 }
    1226 
    1227 
    1228 /***********************************************************************
    1229  *************************** LOCAL ROUTINES ****************************
    1230  ***********************************************************************/
    1231 
    1232 
    1233 /***********************************************************************
    1234  *  Function:   void uti596_initialize_hardware
    1235  *
    1236  *  Description:
    1237  ***********************************************************************/
    1238 void uti596_initialize_hardware(
    1239   uti596_softc_ *sc
    1240 )
    1241 {
    1242   int boguscnt = 1000;
    1243   rtems_isr_entry dummy;
    1244 
    1245   printk(("uti596_initialize_hardware: begins\n"))
    1246 
    1247   pccchip2->LANC_berr_ctl       = 0x40;          /* Enable snooping */
    1248  
    1249   /* reset the board  */
    1250   i82596->port_lower = 0x0000;  /* Each Port access must consist of two 16-bit writes */
    1251   i82596->port_upper = 0x0000;
    1252 
    1253   /* allocate enough memory for the Scp block to be aligned on 16 bit boundary */
    1254   uti596_softc.pScp = (i596_scp *) calloc(1,sizeof(struct i596_scp) + 0xf);
    1255                                        
    1256 #ifdef DBG_INIT
    1257   printk(("uti596_initialize_hardware: Scp address initially %p\n", sc->pScp))
    1258 #endif
    1259  
    1260   /* align the block */
    1261   sc->pScp = (i596_scp *)
    1262     ((((int)uti596_softc.pScp) + 0xf) & 0xfffffff0);
    1263 
    1264 #ifdef DBG_INIT
    1265   printk(("uti596_initialize_hardware: change scp address to : %p\n",sc->pScp))
    1266 #endif
    1267 
    1268   /* change the scp address */
    1269 #ifdef DBG_INIT
    1270   printk(("uti596_initialize_hardware: Change the SCP address\n"))
    1271 #endif
    1272 
    1273   /* reset the board  */
    1274   i82596->port_lower = 0x0000;
    1275   i82596->port_upper = 0x0000;
    1276  
    1277   /* supply the Scp address
    1278    * Lower Command Word D31-D16; Upper Command Word D15-D0
    1279    */
    1280   i82596->port_lower = (((int)sc->pScp) & 0xfff0) | 0x0002;
    1281   i82596->port_upper = (((int)sc->pScp) >> 16 ) & 0xffff;
    1282 
    1283  
     1035  /* Reset the device. Stops it from doing whatever it might be doing.  */
     1036  uti596_portReset();
     1037
     1038  /* Get a new System Configuration Pointer */
     1039  uti596_scp_alloc( sc );
     1040
    12841041  /* write the SYSBUS: interrupt pin active high, LOCK disabled,
    12851042   * internal triggering, linear mode
    12861043   */
    1287   sc->pScp->sysbus = word_swap(0x00540000);
     1044  sc->pScp->sysbus = 0x54;
    12881045 
    12891046  /* provide the iscp to the scp, keep a pointer for our use */
    1290   sc->pScp->iscp_val = word_swap((unsigned long)&sc->iscp);
     1047  sc->pScp->iscp_pointer = word_swap((unsigned long)&sc->iscp);
    12911048  sc->pScp->iscp = &sc->iscp;
    12921049
    12931050  /* provide the scb to the iscp, keep a pointer for our use */
    1294   sc->iscp.scb_val = word_swap((unsigned long)&sc->scb);
     1051  sc->iscp.scb_pointer = word_swap((unsigned long)&sc->scb);
    12951052  sc->iscp.scb = &sc->scb;
    12961053
    1297   /* set the busy flag in the iscp */
    1298   sc->iscp.stat = word_swap(0x00000001);
    1299 
    1300   /* the command block list (CBL) is empty */
    1301   sc->scb.Cmd_val = (unsigned long) I596_NULL;  /* all 1's */
    1302   sc->pCmdHead = sc->scb.pCmd = I596_NULL;                      /* all 1's */
    1303 
    1304 #ifdef DBG_596
    1305   printk(("uti596_initialize_hardware: Starting i82596.\n"))
    1306 #endif
    1307 
    1308   /* Issue CA: pass the scb address to the 596 */
    1309   i82596->chan_attn = 0x00000000;
    1310 
    1311   UTI_WAIT_TICKS
    1312 
    1313   /* Wait for the 596 to read the SCB address and clear 'stat' */
    1314   while (sc->iscp.stat) {
    1315     if (--boguscnt == 0) {
    1316         printk(("initialize_hardware: timed out with status %4.4lx\n",
    1317                sc->iscp.stat ))
    1318         break;
    1319     }
    1320   } /* end while */
    1321 
     1054  #ifdef DBG_INIT
     1055  printk(("uti596_initialize: Starting i82596.\n"))
     1056  #endif
     1057
     1058  /* Set up the 82596 */
     1059  uti596_setScpAndScb( sc );
     1060 
    13221061  /* clear the scb command word */
    13231062  sc->scb.command = 0;
     1063}
     1064
     1065
     1066/*
     1067 *  uti596_initialize_hardware
     1068 *
     1069 *  Reset the 82596 and initialize it with a new SCP. Enable bus snooping.
     1070 *  Install the interrupt handlers.
     1071 * 
     1072 *  Input parameters:
     1073 *    sc - pointer to the uti596_softc
     1074 *
     1075 *  Output parameters: NONE
     1076 *
     1077 *  Return value: NONE
     1078 */
     1079void uti596_initialize_hardware(
     1080  uti596_softc_ *sc
     1081)
     1082{
     1083  rtems_isr_entry dummy;
     1084
     1085  printk(("uti596_initialize_hardware: begins\n"))
     1086
     1087  /* Get the PCCChip2 to assert bus snooping signals on behalf of the i82596 */
     1088  pccchip2->LANC_berr_ctl       = 0x40;
     1089
     1090  uti596_initialize( sc );
    13241091 
    13251092  /*
     
    13291096  pccchip2->LANC_int_ctl        = 0x5d;         /* lvl 5, enabled, edge-sensitive rising */
    13301097  pccchip2->LANC_berr_ctl       = 0x5d;         /* bus error: lvl 5, enabled, snoop control
    1331                                                                                                                                          * will supply dirty data and leave dirty data
     1098                                                                                                                                         * will supply dirty data and leave dirty data
    13321099                                                                                                                                         * on read access and sink any data on write
    13331100                                                                                                                                         */
    1334 
    13351101  /*
    13361102   * Install the interrupt handler
     
    13381104   */ 
    13391105  dummy = (rtems_isr_entry) set_vector( uti596_DynamicInterruptHandler, 0x57, 1 );
    1340  
    13411106
    13421107  /* Initialize the 82596 memory */
    13431108  uti596_initMem(sc);
    13441109
    1345 #ifdef DBG_INIT
     1110  #ifdef DBG_INIT
    13461111  printk(("uti596_initialize_hardware: After attach, status of board = 0x%x\n", sc->scb.status ))
    1347 #endif
    1348 }
    1349 
    1350 /***********************************************************************
    1351  *  Function:   uti596_initMem
    1352  *
    1353  *  Description:
    1354  *             creates the necessary descriptors for the
    1355  *             uti596 board, hooks the interrupt, and starts the board.
    1356  *             Assumes that interrupts are hooked.
    1357  *
    1358  *  Algorithm:
    1359  *
    1360  ***********************************************************************/
    1361 
    1362 void uti596_initMem(
    1363   uti596_softc_ * sc
    1364 )
    1365 {
    1366     int i,count;
    1367     i596_tbd *pTbd, *pPrev;
    1368 
    1369 #ifdef DBG_INIT
    1370   printk(("uti596_initMem: begins\n"))
    1371 #endif
    1372 
    1373     sc->resetDone = 0;
    1374 
    1375     /*
    1376      * Set up receive frame area (RFA)
    1377      */
    1378 #ifdef DBG_INIT
    1379     printk(("uti596_initMem: Initializing the RFA...\n"))
    1380 #endif
    1381     i = uti596_initRFA( sc->rxBdCount );
    1382     if ( i < sc->rxBdCount ) {
    1383       printk(("init_rfd: only able to allocate %d receive frame descriptors\n", i))
    1384                 }
    1385                
    1386                 sc->scb.Rfd_val = word_swap((unsigned long)sc->pBeginRFA);
    1387     sc->scb.pRfd =  sc->pBeginRFA;
    1388 
    1389     /*
    1390      * Diagnose the health of the board
    1391      *   send the CU a diagnostic command
    1392      */
    1393 #ifdef DBG_INIT
    1394     printk(("uti596_initMem: Running diagnostics...\n"))
    1395 #endif
    1396     uti596Diagnose(1);
    1397 
    1398     /*
    1399      * Configure the 82596
    1400      *   send the CU a configure command with our initial setup
    1401      */
    1402 #ifdef DBG_INIT
    1403     printk(("uti596_initMem: Configuring...\n"))
    1404 #endif
    1405     sc->set_conf.cmd.command = CmdConfigure;
    1406     memcpy (sc->set_conf.data, uti596initSetup, 14);
    1407     uti596addPolledCmd( (i596_cmd *) &sc->set_conf);
    1408 
    1409     /* Poll for successful command completion */
    1410     count = 2000;
    1411     while( !( sc->set_conf.cmd.status & STAT_C ) && --count ) {
    1412       printk(("."))
     1112  #endif
     1113}
     1114
     1115
     1116/*
     1117 *  uti596_reset_hardware
     1118 *
     1119 *  Reset the 82596 and initialize it with an SCP.
     1120 * 
     1121 *  Input parameters:
     1122 *    sc - pointer to the uti596_softc
     1123 *
     1124 *  Output parameters: NONE
     1125 *
     1126 *  Return value: NONE
     1127 */
     1128void uti596_reset_hardware(
     1129  uti596_softc_ *sc
     1130)
     1131{
     1132  rtems_status_code status_code;
     1133  i596_cmd *pCmd;
     1134
     1135  pCmd = sc->pCmdHead;  /* This is a tx command for sure (99.99999%)  */
     1136
     1137  /* the command block list (CBL) is empty */
     1138  sc->scb.cmd_pointer = (unsigned long) I596_NULL;      /* all 1's */
     1139  sc->pCmdHead = sc->scb.pCmd = I596_NULL;                          /* all 1's */
     1140
     1141  #ifdef DBG_RESET
     1142  printk(("uti596_reset_hardware\n"))
     1143  #endif
     1144  uti596_initialize( sc );
     1145 
     1146  /*
     1147   * Wake the transmitter if needed.
     1148   */
     1149  if ( sc->txDaemonTid && pCmd != I596_NULL ) {
     1150    printk(("****RESET: wakes transmitter!\n"))
     1151    status_code = rtems_event_send (sc->txDaemonTid,
     1152                           INTERRUPT_EVENT);
     1153
     1154    if ( status_code != RTEMS_SUCCESSFUL ) {
     1155      printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",
     1156             sc->txDaemonTid, rtems_status_text (status_code) ))
    14131157    }
    1414 
    1415     if ( count ) {
    1416       printk(("Configure OK, count = %d\n",count))
    1417     }
    1418     else {
    1419       printk(("***Configure failed\n"))
    1420                 }
    1421     /*
    1422      * Set up the Internet Address
    1423      *   send the CU an IA-setup command
    1424      */
    1425 #ifdef DBG_INIT
    1426     printk(("uti596_initMem: Setting Address...\n"))
    1427 #endif
    1428     sc->set_add.cmd.command = CmdSASetup;
    1429     for ( i=0; i<6; i++) {
    1430       sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];
    1431 #ifdef DBG_INIT
    1432       printk(("uti596_initMem: copying byte %d: 0x%x\n", i, sc->set_add.data[i]))
    1433 #endif
    1434     }
    1435     sc->cmdOk = 0;
    1436     uti596addPolledCmd((i596_cmd *)&sc->set_add);
    1437 
    1438                 /* Poll for successful command completion */
    1439     count = 2000;
    1440     while( !(sc->set_add.cmd.status & STAT_C ) && --count) {
    1441       printk(("."))
    1442     }
    1443 
    1444     if ( count ) {
    1445       printk(("Set Address OK, count= %d\n",count))
    1446     }
    1447     else {
    1448       printk(("Set Address Failed\n"))
    1449                 }
    1450 #ifdef DBG_INIT
    1451     printk(( "uti596_initMem: After initialization, status and command: 0x%x, 0x%x\n",
    1452             sc->scb.status, sc->scb.status))
    1453 #endif
    1454 
    1455     /*
    1456      *Initialize transmit buffer descriptors
    1457      */
    1458 #ifdef DBG_INIT
    1459     printk(( "uti596_initMem:Initializing TBDs...\n"))
    1460 #endif
    1461     sc->pLastUnkRFD                                             = I596_NULL;
    1462     sc->pTxCmd                                                          = (i596_tx *) calloc (1,sizeof (struct i596_tx) );
    1463     sc->pTbd                                                                    = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
    1464         sc->pTxCmd->pTbd                                        = (i596_tbd *) word_swap ((unsigned long) sc->pTbd);
    1465     sc->pTxCmd->cmd.command             = CMD_FLEX|CmdTx;
    1466     sc->pTxCmd->pad                                             = 0;
    1467     sc->pTxCmd->count                                   = 0; /* all bytes are in list of TBD's */
    1468 
    1469     pPrev = pTbd = sc->pTbd;
    1470 
    1471                 /* Allocate a linked list of tbd's each with it's 'next' field written
    1472                  * with upper and lower words swapped (for big endian), and mark the end.
    1473                  */
    1474     for ( i=0; i<sc->txBdCount; i++) {
    1475       pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
    1476       pPrev->next = (i596_tbd *) word_swap ((unsigned long) pTbd);
    1477       pPrev = pTbd;
    1478                 }
    1479     pTbd->next = I596_NULL;
    1480 
    1481                 /* Padding used to fill short tx frames */
    1482     memset ( &sc->zeroes, 0, 64);
    1483 
    1484 #ifdef DBG_596
    1485     printk(( "uti596_initMem: After receiver start, status and command: 0x%x, 0x%x\n",
    1486             sc->scb.status, sc->scb.status))
    1487 #endif
    1488 
    1489 #ifdef DBG_596
    1490     printk(("uti596_initMem allows ISR's\n"))
    1491 #endif
    1492     sc->resetDone = 1; /* now need ISR  */
    1493 }
    1494 
    1495 /***********************************************************************
    1496  *  Function:   uti596initRFA(int num)
    1497  *
    1498  *  Description:
    1499  *              attempts to allocate and initialize ( chain together )
    1500  *              the requested number of FD's
    1501  *
    1502  *  Algorithm:
    1503  *
    1504  ***********************************************************************/
    1505 
    1506 int uti596_initRFA( int num )
    1507 {
    1508     i596_rfd *pRfd;
    1509     int i = 0;
    1510 
    1511 #ifdef DBG_596
    1512     printk(("uti596_initRFA: begins\n   Requested frame descriptors ... %d.\n", num))
    1513 #endif
    1514 
    1515     /*
    1516      * Create the first RFD in the RFA
    1517      */
    1518     pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd));
    1519     if ( !pRfd ) {
    1520       printk(("Can't allocate first buffer.\n"))
    1521       return 0;
    1522     }
    1523     else {
    1524       uti596_softc.countRFD = 1;
    1525       uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
    1526     printk(("First Rfd allocated @: %p\n",
    1527              uti596_softc.pBeginRFA))
    1528     }
    1529 
    1530                 /* Create remaining RFAs */
    1531     for (i = 1; i < num; i++) {
    1532       pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd) );
    1533       if ( pRfd != NULL ) {
    1534         uti596_softc.countRFD++;                                                                                                                                /* update count */
    1535         uti596_softc.pEndRFA->next =
    1536           (i596_rfd *) word_swap ((unsigned long) pRfd); /* write the link */
    1537         uti596_softc.pEndRFA = pRfd;                                                                                                            /* move the end */
    1538 #ifdef DBG_596_RFA
    1539         printk(("uti596_initRFA: Allocated RFD @ %p\n", pRfd))
    1540 #endif
    1541       }
    1542       else {
    1543         printk(("Can't allocate all buffers: only %d allocated\n", i))
    1544         break;
    1545       }
    1546     } /* end for */
    1547 
    1548     uti596_softc.pEndRFA->next = I596_NULL;
    1549     UTI_596_ASSERT(uti596_softc.countRFD == RX_BUF_COUNT,"INIT:WRONG RFD COUNT\n" )
    1550 
    1551 #ifdef DBG_596_RFA
    1552     printk (("uti596_initRFA: Head of RFA is buffer %p \n\
    1553                                         uti596_initRFA: End of RFA is buffer %p \n",
    1554               uti596_softc.pBeginRFA,
    1555               uti596_softc.pEndRFA ))
    1556 #endif
    1557     /* Initialize the RFD's */
    1558     for ( pRfd = uti596_softc.pBeginRFA;
    1559           pRfd != I596_NULL;
    1560           pRfd = (i596_rfd *) word_swap ((unsigned long)pRfd->next) ) {
    1561 
    1562       pRfd->cmd         = 0x0000;
    1563       pRfd->stat  = 0x0000;
    1564       pRfd->pRbd        = I596_NULL;
    1565       pRfd->count = 0;  /* number of bytes in buffer: usually less than size */
    1566       pRfd->size        = 1532;      /* was 1532;  buffer size ( All RBD ) */
    1567       if ( pRfd -> data == NULL ) {
    1568         printk(("Can't allocate the RFD data buffer\n"))
    1569       }
    1570     }
    1571 
    1572     /* mark the last RFD as the last one in the RDL */
    1573     uti596_softc.pEndRFA -> cmd = CMD_EOL;
    1574 
    1575     uti596_softc.pSavedRfdQueue =
    1576       uti596_softc.pEndSavedQueue = I596_NULL;   /* initially empty */
    1577 
    1578     uti596_softc.savedCount = 0;
    1579 
    1580     uti596_softc.nop.cmd.command = CmdNOp; /* initialize the nop command */
    1581 
    1582     return (i); /* the number of allocated buffers */
    1583 }
    1584 
    1585  /***********************************************************************
    1586   *  Function:   uti596addPolledCmd
    1587   *
    1588   *  Description:
    1589   *             This routine issues a single command then polls for it's
    1590   *             completion.
    1591   *
    1592   *  Algorithm:
    1593   *            Give the command to the driver. ( CUC_START is ALWAYS required )
    1594   *            Poll for completion.
    1595   *
    1596   ***********************************************************************/
    1597 
    1598 void uti596addPolledCmd(
    1599   i596_cmd *pCmd
    1600 )
    1601 {
    1602 
    1603  #ifdef DBG_596
    1604      printk(("uti596addPolledCmd: Adding command 0x%x\n", pCmd -> command ))
    1605  #endif
    1606 
    1607 #ifdef DBG_POLLED_CMD
    1608 
    1609      switch ( pCmd -> command & 0x7 ) {    /* check bottom 3 bits */
    1610      case CmdConfigure:
    1611        printk(("uti596addPolledCmd: Configure Command 0x%x\n", pCmd->command))
    1612        break;
    1613      case CmdSASetup:
    1614        printk(("uti596addPolledCmd: Set CMDress Command 0x%x\n", pCmd->command))
    1615        break;
    1616      case CmdMulticastList:
    1617        printk(("uti596addPolledCmd: Multi-cast list 0x%x\n", pCmd->command))
    1618        break;
    1619      case CmdNOp:
    1620        printk(("uti596addPolledCmd: NO op 0x%x\n", pCmd->command))
    1621        break;
    1622      case CmdTDR:
    1623        printk(("uti596addPolledCmd: TDR 0x%x\n", pCmd->command))
    1624        break;
    1625      case CmdDump:
    1626        printk(("uti596addPolledCmd: Dump 0x%x\n", pCmd->command))
    1627        break;
    1628      case CmdDiagnose:
    1629        printk(("uti596addPolledCmd: Diagnose 0x%x\n", pCmd->command))
    1630        break;
    1631      case CmdTx:
    1632        break;
    1633      default:
    1634        printk(("PolledCMD: ****Unknown Command encountered 0x%x\n", pCmd->command))
    1635        break;
    1636      } /* end switch */
    1637 
    1638 #endif
    1639 
    1640      pCmd->status = 0;
    1641      pCmd->command |=  CMD_EOL ; /* only command in list*/
    1642 
    1643      pCmd->next = I596_NULL;
    1644 
    1645      UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: wait prev");
    1646 
    1647      uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
    1648      uti596_softc.scb.Cmd_val = word_swap((unsigned long)pCmd);
    1649      uti596_softc.scb.command = CUC_START;
    1650      i82596->chan_attn = 0x00000000;
    1651 
    1652      UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: start");
    1653      uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL;
    1654                  uti596_softc.scb.Cmd_val = (unsigned long) I596_NULL;
    1655 
    1656 #ifdef DBG_POLLED_CMD
    1657      printk(("uti596addPolledCmd: Scb status & command 0x%x 0x%x\n",
    1658             uti596_softc.scb.status,
    1659             uti596_softc.scb.command ))
    1660 #endif
    1661 }
    1662 
    1663 
    1664 /***********************************************************************
    1665  *  Function:   void uti596Diagnose
    1666  *
    1667  *  Description:
    1668  *             
    1669  ***********************************************************************/
    1670 void uti596Diagnose(
    1671   int verbose
    1672 )
    1673 {
    1674   i596_cmd diagnose;
    1675   int count=10000;
    1676 
    1677   diagnose.command = CmdDiagnose;
    1678   diagnose.status = 0;
    1679   uti596addPolledCmd(&diagnose);
    1680   while( !( diagnose.status & STAT_C ) && count ) {
    1681     if(verbose) {
    1682       printk(("."))
    1683     }
    1684     count --;
    1685   }
    1686   if(verbose) {
    1687     printk(("Status diagnostic: 0xa000 is a success ... 0x%2.2x\n", diagnose.status))
    1688   }
    1689 }
    1690 
    1691 /***********************************************************************
    1692  *  Function:   void uti596dequeue
    1693  *
    1694  *  Description:
    1695  *              removes an RFD from the received frame queue,
    1696  *
    1697  *  Algorithm:
    1698  *
    1699  ***********************************************************************/
    1700 i596_rfd * uti596dequeue(
    1701   i596_rfd ** ppQ
    1702 )
    1703 {
    1704   ISR_Level level;
    1705 
    1706   i596_rfd * pRfd;
    1707   _ISR_Disable(level);
    1708 
    1709   /* invalid address, or empty queue or emptied queue */
    1710   if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {
    1711     _ISR_Enable(level);
    1712      return I596_NULL;
    1713   }
    1714 
    1715   pRfd = *ppQ;                                                                                                          /* The dequeued buffer           */
    1716   *ppQ = (i596_rfd *) \
    1717           word_swap ((unsigned long) pRfd->next); /* advance the queue pointer     */
    1718   pRfd->next = I596_NULL;                                                                                                       /* unlink the rfd being returned */
    1719 
    1720   _ISR_Enable(level);
    1721   return pRfd;
    1722 }
    1723 
    1724 /***********************************************************************
    1725  *  Function:   void uti596reset
    1726  *
    1727  *  Description:
    1728  ***********************************************************************/
    1729 void uti596reset( void )
    1730 {
    1731    int i,count;
    1732    uti596_softc_ *sc = &uti596_softc;
    1733    /*   i596_rfd * pRfd; */
    1734 
    1735 #ifdef DBG_RESET
    1736      printk(("uti596reset: begin\n"))
    1737 #endif
    1738 
     1158  }
     1159
     1160  #ifdef DBG_RESET
     1161  printk(("uti596_reset_hardware: After reset_hardware, status of board = 0x%x\n", sc->scb.status ))
     1162  #endif
     1163}
     1164
     1165
     1166/*
     1167 *  uti596_clearListStatus
     1168 *
     1169 *  Clear the stat fields for all RFDs
     1170 *
     1171 *  Input parameters:
     1172 *      pRfd - a pointer to the head of the RFA
     1173 *
     1174 *  Output parameters: NONE
     1175 *
     1176 *  Return value: NONE
     1177 */
     1178void uti596_clearListStatus(
     1179  i596_rfd *pRfd
     1180)
     1181{
     1182  while ( pRfd != I596_NULL ) {
     1183    pRfd -> stat = 0;
     1184    pRfd = (i596_rfd *) word_swap((unsigned long)pRfd-> next);
     1185  }
     1186}
     1187
     1188
     1189/*
     1190 *  uti596_reset
     1191 *
     1192 *  Reset the 82596 and reconfigure
     1193 *
     1194 *  Input parameters: NONE
     1195 *
     1196 *  Output parameters: NONE
     1197 *
     1198 *  Return value: NONE
     1199 */
     1200void uti596_reset( void )
     1201{
     1202  uti596_softc_ *sc = &uti596_softc;
     1203
     1204        #ifdef DBG_RESET
     1205  printk(("uti596_reset: begin\n"))
     1206        #endif
     1207
     1208        /* Wait for the CU to be available, then
     1209         * reset the ethernet hardware. Must re-config.
     1210         */
    17391211  sc->resetDone = 0;
    1740   UTI_WAIT_COMMAND_ACCEPTED(10000, "reset: wait for previous command complete");
    1741   uti596_reset_hardware(&uti596_softc); /* reset the ethernet hardware. must re-config */
    1742 
    1743 #ifdef DBG_RESET
    1744   uti596Diagnose(1);
    1745 #endif
    1746 
    1747   sc->set_conf.cmd.command = CmdConfigure;
    1748   memcpy (sc->set_conf.data, uti596initSetup, 14);
    1749   uti596addPolledCmd( (i596_cmd *) &sc->set_conf);
    1750 
    1751   /* POLL */
    1752   count = 2000;
    1753   while( !( sc->set_conf.cmd.status & STAT_C ) && --count ) {
    1754     printk(("."))
    1755   }
    1756 
    1757   if ( count ) {
    1758     printk(("Configure OK, count = %d\n",count))
    1759   }
    1760   else {
    1761     printk(("reset: Configure failed\n"))
    1762   }
     1212        uti596_wait ( sc, UTI596_WAIT_FOR_CU_ACCEPT );
     1213  uti596_reset_hardware ( &uti596_softc );
     1214
     1215        #ifdef DBG_RESET
     1216  uti596_diagnose();
     1217        #endif
    17631218
    17641219  /*
    1765    * Create the IA setup command
     1220   * Configure the 82596
    17661221   */
    1767 
    1768 #ifdef DBG_RESET
    1769   printk(("uti596reset: Setting Address\n"))
    1770 #endif
    1771   sc->set_add.cmd.command = CmdSASetup;
    1772   for ( i=0; i<6; i++) {
    1773     sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];
    1774   }
    1775   sc->cmdOk = 0;
    1776   uti596addPolledCmd((i596_cmd *)&sc->set_add);
    1777 
    1778   count = 2000;
    1779   while( !(sc->set_add.cmd.status & STAT_C ) && --count) {
    1780     printk(("."))
    1781         }
    1782   if ( count ) {
    1783     printk(("Reset Set Address OK, count= %d\n",count))
    1784   }
    1785   else {
    1786     printk(("Reset Set Address Failed\n"))
    1787   }
     1222  uti596_configure( sc );
     1223
     1224  /*
     1225   * Set up the Individual (hardware) Address
     1226   */
     1227  uti596_IAsetup ( sc );
    17881228
    17891229  sc->pCmdHead = sc->pCmdTail = sc->scb.pCmd = I596_NULL;
    17901230
    1791 #ifdef DBG_RESET
    1792   printk(( "uti596reset: After reset, status and command: 0x%x, 0x%x\n",
    1793           sc->scb.status, sc->scb.status))
    1794 #endif
    17951231
    17961232  /* restore the RFA */
    1797 
    1798   /* dumpQ(); */
    17991233
    18001234  if ( sc->pLastUnkRFD != I596_NULL ) {
     
    18101244  }
    18111245
    1812   sc->scb.pRfd =  sc->pBeginRFA; /* readdress the head of the RFA in the SCB */
    1813   sc->scb.Rfd_val = word_swap((unsigned long)sc->pBeginRFA);
    1814 
    1815   uti596clearListStatus(sc->pBeginRFA );
    1816 
    1817   /*  dumpQ(); */
    1818 
    1819   printk(("Reset:Starting NIC\n"))
     1246  /* Re-address the head of the RFA in the SCB */
     1247  sc->scb.pRfd =  sc->pBeginRFA;
     1248  sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA);
     1249
     1250        /* Clear the status of all RFDs */
     1251  uti596_clearListStatus( sc->pBeginRFA );
     1252
     1253  printk(("uti596_reset: Starting NIC\n"))
     1254
     1255  /* Start the receiver */
    18201256  sc->scb.command = RX_START;
    1821   sc->started = 1;               /* we assume that the start works */
     1257  sc->started = 1;               /* assume that the start is accepted */
    18221258  sc->resetDone = 1;
    1823   i82596->chan_attn = 0x00000000;
    1824   UTI_WAIT_COMMAND_ACCEPTED(4000, "reset");
    1825   printk(("Reset:Start complete \n"))
     1259  uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT );
     1260 
    18261261  UTI_596_ASSERT(sc->pCmdHead == I596_NULL, "Reset: CMD not cleared\n")
    18271262
    1828 #ifdef DBG_RESET
    1829   printk(("uti596reset: completed\n"))
    1830 #endif
    1831 }
    1832 
    1833 
    1834 /***********************************************************************
    1835  *  Function:   void uti596_reset_hardware
    1836  *
    1837  *  Description:
    1838  ***********************************************************************/
    1839 void uti596_reset_hardware(
    1840   uti596_softc_ *sc
    1841 )
    1842 {
    1843   int boguscnt = 1000;
    1844   rtems_status_code status_code;
    1845   i596_cmd *pCmd;
    1846 
    1847 
    1848   printk(("uti596_reset_hardware\n"))
    1849   pCmd = sc->pCmdHead;  /* This is a tx command for sure (99.99999%)  */
    1850 
    1851   /* reset the board  */
    1852   i82596->port_lower = 0x0000;
    1853   i82596->port_upper = 0x0000;
    1854 
    1855   if ( sc->pScp == NULL ) {
    1856     printk(("Calloc scp\n"))
    1857     uti596_softc.pScp = (i596_scp *) calloc(1,sizeof(struct i596_scp) + 0xf);
    1858   }
    1859 
    1860 #ifdef DBG_RESET
    1861   printk(("uti596_reset_hardware: Scp address %p\n", sc->pScp))
    1862 #endif
    1863 
    1864   /* align the block */
    1865   sc->pScp = (i596_scp *)
    1866     ((((int)uti596_softc.pScp) + 0xf) & 0xfffffff0);
    1867 
    1868 #ifdef DBG_RESET
    1869   printk(("uti596_reset_hardware: change scp address to : %p\n",sc->pScp))
    1870 #endif
    1871 
    1872   /* change the scp address */
    1873 #ifdef DBG_RESET
    1874   printk(("uti596_reset_hardware: Change the SCP address\n"))
    1875 #endif
    1876 
    1877   /* reset the board  */
    1878   i82596->port_lower = 0x0000;
    1879   i82596->port_upper = 0x0000;
     1263        #ifdef DBG_RESET
     1264  printk(("uti596_reset: completed\n"))
     1265        #endif
     1266}
     1267
     1268
     1269/*
     1270 *  uti596_dequeue
     1271 *
     1272 *  Remove an RFD from the received fram queue
     1273 *
     1274 *  Input parameters:
     1275 *      ppQ - a pointer to a i596_rfd pointer
     1276 *
     1277 *  Output parameters: NONE
     1278 *
     1279 *  Return value:
     1280 *      pRfd - a pointer to the dequeued RFD
     1281 */
     1282i596_rfd * uti596_dequeue(
     1283  i596_rfd ** ppQ
     1284)
     1285{
     1286  ISR_Level level;
     1287  i596_rfd * pRfd;
    18801288 
    1881   /* supply the Scp address
    1882    * Lower Command Word D31-D16; Upper Command Word D15-D0
    1883    */
    1884   i82596->port_lower = (((int)sc->pScp) & 0xfff0) | 0x0002;
    1885   i82596->port_upper = (((int)sc->pScp) >> 16 ) & 0xffff;
    1886 
    1887   /* write the SYSBUS: interrupt pin active high, LOCK disabled,
    1888    * internal triggering, linear mode
    1889    */
    1890   sc->pScp->sysbus = word_swap(0x00540000);
     1289  _ISR_Disable(level);
     1290
     1291  /* invalid address, or empty queue or emptied queue */
     1292  if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {
     1293    _ISR_Enable(level);
     1294     return I596_NULL;
     1295  }
    18911296 
    1892   /* provide the iscp to the scp, keep a pointer for our use */
    1893   sc->pScp->iscp_val = word_swap((unsigned long)&sc->iscp);
    1894   sc->pScp->iscp = &sc->iscp;
    1895 
    1896   /* provide the scb to the iscp, keep a pointer for our use */
    1897   sc->iscp.scb_val = word_swap((unsigned long)&sc->scb);
    1898   sc->iscp.scb = &sc->scb;
    1899 
    1900   /* set the busy flag in the iscp */
    1901   sc->iscp.stat = word_swap(0x00000001);
    1902 
    1903   /* the command block list (CBL) is empty */
    1904   sc->scb.Cmd_val = (unsigned long) I596_NULL;  /* all 1's */
    1905   sc->pCmdHead = sc->scb.pCmd = I596_NULL;                      /* all 1's */
    1906 
    1907   /*
    1908    * Wake the transmitter if needed.
    1909    */
    1910   if ( uti596_softc.txDaemonTid && pCmd != I596_NULL ) {
    1911     printk(("****RESET: wakes transmitter!\n"))
    1912     status_code = rtems_event_send (uti596_softc.txDaemonTid,
    1913                            INTERRUPT_EVENT);
    1914 
    1915     if ( status_code != RTEMS_SUCCESSFUL ) {
    1916       printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",
    1917              uti596_softc.txDaemonTid, rtems_status_text (status_code) ))
     1297        /*
     1298         * Point to the dequeued buffer, then
     1299         * adjust the queue pointer and detach the buffer
     1300         */
     1301  pRfd = *ppQ;     
     1302  *ppQ = (i596_rfd *) word_swap ((unsigned long) pRfd->next);
     1303  pRfd->next = I596_NULL;  /* unlink the rfd being returned */
     1304
     1305  _ISR_Enable(level);
     1306  return pRfd;
     1307}
     1308
     1309
     1310/*
     1311 *  uti596_append
     1312 *
     1313 *  Remove an RFD buffer from the RFA and tack it on to
     1314 *      the received frame queue for processing.
     1315 *
     1316 *  Input parameters:
     1317 *       ppQ - a pointer to the queue pointer
     1318 *      pRfd - a pointer to the buffer to be returned
     1319 *
     1320 *  Output parameters: NONE
     1321 *
     1322 *  Return value: NONE
     1323 */
     1324
     1325void uti596_append(
     1326  i596_rfd ** ppQ,
     1327  i596_rfd * pRfd
     1328)
     1329{
     1330
     1331  i596_rfd *p;
     1332
     1333  if ( pRfd != NULL && pRfd != I596_NULL) {
     1334    pRfd -> next = I596_NULL;
     1335    pRfd -> cmd |= CMD_EOL;    /* set EL bit */
     1336
     1337    if ( *ppQ == NULL || *ppQ == I596_NULL ) {
     1338      /* empty list */
     1339      *ppQ = pRfd;
    19181340    }
    1919   }
    1920 
    1921 #ifdef DBG_596
    1922   printk(("uti596_reset_hardware: starting i82596.\n"))
    1923 #endif
    1924 
    1925   /* Pass the scb address to the 596 */
    1926   i82596->chan_attn = 0x00000000;
    1927 
    1928   while (sc->iscp.stat)
    1929     if (--boguscnt == 0)
    1930       {
    1931         printk(("reset_hardware: timed out with status %4.4lx\n",
    1932                sc->iscp.stat ))
    1933         break;
    1934       }
    1935 
    1936   /* clear the command word */
    1937   sc->scb.command = 0;
    1938 
    1939 #ifdef DBG_RESET
    1940   printk(("uti596_reset_hardware: After reset_hardware, status of board = 0x%x\n", sc->scb.status ))
    1941 #endif
    1942 }
    1943 
    1944  /***********************************************************************
    1945   *  Function:   uti596clearListStatus
    1946   *
    1947   *  Description:
    1948   *             Clear the stat fields for all rfd's
    1949   *  Algorithm:
    1950   *
    1951   ***********************************************************************/
    1952 
    1953 void uti596clearListStatus(
    1954   i596_rfd *pRfd
    1955 )
    1956 {
    1957   while ( pRfd != I596_NULL ) {
    1958     pRfd -> stat = 0;
    1959     pRfd = (i596_rfd *) word_swap((unsigned long)pRfd-> next);
    1960   }
    1961 }
    1962 
    1963  /***********************************************************************
    1964   *  Function:   send_packet
    1965   *
    1966   *  Description: Send a raw ethernet packet
    1967   *
    1968   *  Algorithm:
    1969   *             increment some stats counters,
    1970   *             create the transmit command,
    1971   *             add the command to the CBL,
    1972   *             wait for event
    1973   *
    1974   ***********************************************************************/
    1975 
     1341    else {
     1342      /* walk to the end of the list */
     1343      for ( p=*ppQ;
     1344            p->next != I596_NULL;
     1345            p=(i596_rfd *) word_swap ((unsigned long)p->next) );
     1346
     1347      /* append the rfd */
     1348      p->cmd &= ~CMD_EOL;  /* Clear EL bit at end */
     1349      p->next = (i596_rfd *) word_swap ((unsigned long)pRfd);
     1350    }
     1351  }
     1352  else {
     1353    printk(("Illegal attempt to append: %p\n", pRfd))
     1354  }
     1355}
     1356
     1357
     1358/*
     1359 *  uti596_supplyFD
     1360 *
     1361 *  Return a buffer (RFD) to the receive frame area (RFA).
     1362 *  Call with interrupts disabled.
     1363 *
     1364 *  Input parameters:
     1365 *      pRfd - a pointer to the buffer to be returned
     1366 *
     1367 *  Output parameters: NONE
     1368 *
     1369 *  Return value: NONE
     1370 */
     1371void uti596_supplyFD (
     1372  i596_rfd * pRfd
     1373)
     1374{
     1375 i596_rfd *pLastRfd;
     1376
     1377 UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD!\n")
     1378 
     1379 pRfd -> cmd  = CMD_EOL;
     1380 pRfd -> pRbd = I596_NULL;
     1381 pRfd -> next = I596_NULL;
     1382 pRfd -> stat = 0x0000;      /* clear STAT_C and STAT_B bits */
     1383
     1384 /*
     1385  * Check if the list is empty:
     1386  */
     1387 if ( uti596_softc.pBeginRFA == I596_NULL ) {
     1388
     1389         /* Start a list with one entry */
     1390   uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
     1391   UTI_596_ASSERT(uti596_softc.countRFD == 0, "Null begin, but non-zero count\n")
     1392   if ( uti596_softc.pLastUnkRFD != I596_NULL ) {
     1393     printk(("LastUnkRFD is NOT NULL!!\n"))
     1394   }
     1395   uti596_softc.countRFD = 1;
     1396   return;
     1397 }
     1398 
     1399 /*
     1400  * Check if the last RFD is used/read by the 596.
     1401  */
     1402 pLastRfd = uti596_softc.pEndRFA;
     1403
     1404 /* C = complete, B = busy (prefetched) */
     1405 if ( pLastRfd != I596_NULL && ! (pLastRfd -> stat & ( STAT_C | STAT_B ) )) {
     1406 
     1407   /*
     1408    * Not yet too late to add it
     1409    */
     1410   pLastRfd -> next = (i596_rfd *) word_swap ((unsigned long)pRfd);
     1411   pLastRfd -> cmd &= ~CMD_EOL;  /* RESET_EL : reset EL bit to 0  */
     1412   uti596_softc.countRFD++;  /* Lets assume we add it successfully
     1413                                If not, the RFD may be used, and may
     1414                                decrement countRFD < 0 !! */
     1415   /*
     1416    * Check if the last RFD was used while appending.
     1417    */
     1418   if ( pLastRfd -> stat & ( STAT_C | STAT_B ) ) { /* completed or was prefetched */
     1419     /*
     1420      * Either the EL bit of the last rfd has been read by the 82596,
     1421      * and it will stop after reception,( true when RESET_EL not reached ) or
     1422      * the EL bit was NOT read by the 82596 and it will use the linked
     1423      * RFD for the next reception. ( true when RESET_EL was reached )
     1424      * So, it is unknown whether or not the linked rfd will be used.
     1425      * Therefore, the end of list CANNOT be updated.
     1426      */
     1427     UTI_596_ASSERT ( uti596_softc.pLastUnkRFD == I596_NULL, "Too many Unk RFD's\n" )
     1428     uti596_softc.pLastUnkRFD = pRfd;
     1429     return;
     1430   }
     1431   else {
     1432     /*
     1433      * The RFD being added was not touched by the 82596
     1434      */
     1435     if (uti596_softc.pLastUnkRFD != I596_NULL ) {
     1436
     1437       uti596_append(&uti596_softc.pSavedRfdQueue, pRfd); /* Only here! saved Q */
     1438       uti596_softc.pEndSavedQueue = pRfd;
     1439       uti596_softc.savedCount++;
     1440       uti596_softc.countRFD--;
     1441
     1442     }
     1443     else {
     1444     
     1445       uti596_softc.pEndRFA = pRfd;   /* the RFA has been extended */
     1446       
     1447       if ( ( uti596_softc.scb.status & SCB_STAT_RNR ||
     1448              uti596_softc.scb.status & RU_NO_RESOURCES ) &&
     1449              uti596_softc.countRFD > 1 ) {
     1450             
     1451         /* Ensure that beginRFA is not EOL */
     1452         uti596_softc.pBeginRFA -> cmd &= ~CMD_EOL;
     1453
     1454         UTI_596_ASSERT(uti596_softc.pEndRFA -> next == I596_NULL, "supply: List buggered\n")
     1455         UTI_596_ASSERT(uti596_softc.pEndRFA -> cmd & CMD_EOL, "supply: No EOL at end.\n")
     1456         UTI_596_ASSERT(uti596_softc.scb.command == 0, "Supply: scb command must be zero\n")
     1457
     1458                                 #ifdef DBG_MEM
     1459         printk(("uti596_supplyFD: starting receiver"))
     1460                                 #endif
     1461
     1462         /* start the receiver */
     1463         UTI_596_ASSERT(uti596_softc.pBeginRFA != I596_NULL, "rx start w/ NULL begin! \n")
     1464         uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
     1465         uti596_softc.scb.rfd_pointer = word_swap ((unsigned long) uti596_softc.pBeginRFA);
     1466         
     1467         /* Don't ack RNR! The receiver should be stopped in this case */
     1468         uti596_softc.scb.command = RX_START | SCB_STAT_RNR;
     1469         
     1470         UTI_596_ASSERT( !(uti596_softc.scb.status & SCB_STAT_FR),"FRAME RECEIVED INT COMING!\n")
     1471
     1472         /* send CA signal */
     1473         uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );
     1474       }
     1475     }
     1476     return;
     1477   }
     1478 }
     1479 else {
     1480   /*
     1481    * too late , pLastRfd in use ( or NULL ),
     1482    * in either case, EL bit has been read, and RNR condition will occur
     1483    */
     1484   uti596_append( &uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */
     1485
     1486   uti596_softc.pEndSavedQueue = pRfd;  /* reset end of saved queue */
     1487   uti596_softc.savedCount++;
     1488
     1489   return;
     1490 }
     1491}
     1492
     1493
     1494/*
     1495 *  send_packet
     1496 *
     1497 *  Send a raw ethernet packet, add a
     1498 *      transmit command to the CBL
     1499 *
     1500 *  Input parameters:
     1501 *      ifp - a pointer to the ifnet structure
     1502 *        m     -       a pointer to the mbuf being sent
     1503 *
     1504 *  Output parameters: NONE
     1505 *
     1506 *  Return value: NONE
     1507 */
    19761508void send_packet(
    19771509  struct ifnet *ifp, struct mbuf *m
     
    19821514  i596_tbd *pTbd;
    19831515  struct mbuf *n, *input_m = m;
    1984 
    19851516  uti596_softc_ *sc = ifp->if_softc;
    1986 
    19871517  struct mbuf *l = NULL;
    19881518  unsigned int length = 0;
     
    20291559  if ( length < UTI_596_ETH_MIN_SIZE ) {
    20301560    pTbd->data = (char *) word_swap ((unsigned long) sc->zeroes); /* add padding to pTbd */
    2031     pTbd->size = UTI_596_ETH_MIN_SIZE - length;                                                                         /* zeroes have no effect on the CRC */
    2032   }
    2033   else
    2034     pTbd = pPrev; /* Don't use pTbd in the send routine */
     1561    pTbd->size = UTI_596_ETH_MIN_SIZE - length; /* zeroes have no effect on the CRC */
     1562  }
     1563  else   /* Don't use pTbd in the send routine */
     1564    pTbd = pPrev;
    20351565
    20361566  /*  Disconnect the packet from the list of Tbd's  */
     
    20391569  pTbd->size |= UTI_596_END_OF_FRAME;
    20401570
    2041 #ifdef DBG_RAW
    2042   printk(("send_packet: RAW - Add cmd and sleep\n"))
    2043 #endif
    2044 
    20451571  sc->rawsndcnt++;
    20461572
    2047 #ifdef DBG_RAW
    2048   printk(("send_packet: RAW - sending packet\n"))
    2049 #endif
     1573        #ifdef DBG_SEND
     1574  printk(("send_packet: sending packet\n"))
     1575        #endif
    20501576
    20511577  /* Sending Zero length packet: shouldn't happen */
    2052   if (pTbd->size <= 0) return ;
    2053 
    2054 #ifdef DBG_INIT_3
    2055   printk(("\nsend_packet: Transmitter adds packet\n"))
    2056   print_hdr    ( sc->pTxCmd->pTbd->data ); /* print the first part */
    2057   print_pkt    ( sc->pTxCmd->pTbd->next->data ); /* print the first part */
    2058   /*  print_echo(sc->pTxCmd->pTbd->data); */
    2059 #endif
     1578  if (pTbd->size <= 0) return;
     1579
     1580        #ifdef DBG_PACKETS
     1581  printk     (("\nsend_packet: Transmitter adds packet\n"))
     1582  print_hdr  ( sc->pTxCmd->pTbd->data ); /* print the first part */
     1583  print_pkt  ( sc->pTxCmd->pTbd->next->data ); /* print the first part */
     1584  print_echo (sc->pTxCmd->pTbd->data);
     1585        #endif
    20601586
    20611587  /* add the command to the output command queue */
    2062   uti596addCmd ( (i596_cmd *) sc->pTxCmd );
     1588  uti596_addCmd ( (i596_cmd *) sc->pTxCmd );
    20631589
    20641590  /* sleep until the command has been processed or Timeout encountered. */
     
    20721598  }
    20731599
    2074 #ifdef DBG_RAW
     1600        #ifdef DBG_SEND
    20751601  printk(("send_packet: RAW - wake\n"))
    2076 #endif
     1602        #endif
    20771603
    20781604  sc->txInterrupts++;
    2079 
    2080 #ifdef DBG_INIT_3
    2081   printk(("\nsend_packet: Transmitter issued packet\n"))
    2082   print_hdr    ( sc->pTxCmd->pTbd -> data ); /* print the first part */
    2083   print_pkt    ( sc->pTxCmd->pTbd ->next-> data ); /* print the first part */
    2084 #endif
    20851605
    20861606  if ( sc->pTxCmd -> cmd.status & STAT_OK ) {
     
    20881608  }
    20891609  else {
    2090 #ifdef DBG_RAW
    2091       printk(("******send_packet: Driver Error 0x%x\n", sc->pTxCmd -> cmd.status ))
    2092 #endif
    2093       sc->stats.tx_errors++;
    2094       if ( sc->pTxCmd->cmd.status  & 0x0020 )
    2095         sc->stats.tx_retries_exceeded++;
    2096       if (!(sc->pTxCmd->cmd.status & 0x0040))
    2097         sc->stats.tx_heartbeat_errors++;
    2098       if ( sc->pTxCmd->cmd.status  & 0x0400 )
    2099         sc->stats.tx_carrier_errors++;
    2100       if ( sc->pTxCmd->cmd.status  & 0x0800 )
    2101         sc->stats.collisions++;
    2102       if ( sc->pTxCmd->cmd.status  & 0x1000 )
    2103         sc->stats.tx_aborted_errors++;
     1610
     1611    printk(("*** send_packet: Driver Error 0x%x\n", sc->pTxCmd -> cmd.status ))
     1612
     1613    sc->stats.tx_errors++;
     1614    if ( sc->pTxCmd->cmd.status  & 0x0020 )
     1615      sc->stats.tx_retries_exceeded++;
     1616    if (!(sc->pTxCmd->cmd.status & 0x0040))
     1617      sc->stats.tx_heartbeat_errors++;
     1618    if ( sc->pTxCmd->cmd.status  & 0x0400 )
     1619      sc->stats.tx_carrier_errors++;
     1620    if ( sc->pTxCmd->cmd.status  & 0x0800 )
     1621      sc->stats.collisions++;
     1622    if ( sc->pTxCmd->cmd.status  & 0x1000 )
     1623      sc->stats.tx_aborted_errors++;
    21041624  } /* end if stat_ok */
    21051625
    21061626  /*
    2107    * Restore the transmited buffer descriptor chain.
     1627   * Restore the transmitted buffer descriptor chain.
    21081628   */
    21091629  pTbd -> next = (i596_tbd *) word_swap ((unsigned long)pRemainingTbdList);
     
    21191639}
    21201640
    2121  /***********************************************************************
    2122   *  Function:   uti596addCmd
    2123   *
    2124   *  Description:
    2125   *             This routine adds a command onto the end of the
    2126   *             command chain
    2127   *
    2128   *  Algorithm:
    2129   *            Add the command to the end of an existing chain,
    2130   *            or start the chain and issue a CUC_START
    2131   *
    2132   *
    2133   ***********************************************************************/
    2134 
    2135 /* static */ void uti596addCmd(
    2136   i596_cmd *pCmd
    2137 )
    2138 {
    2139      ISR_Level level;
    2140 
    2141  #ifdef DBG_596
    2142      printk(("uti596addCmd: Adding command 0x%x\n", pCmd -> command ))
    2143  #endif
    2144 
    2145 #ifdef DBG_ADD
    2146 
    2147      switch ( pCmd -> command & 0x7 ){ /* check bottom 3 bits */
    2148      case CmdConfigure:
    2149        printk(("uti596addCmd: Configure Command 0x%x\n", pCmd->command))
    2150        break;
    2151      case CmdSASetup:
    2152        printk(("uti596addCmd: Set Address Command 0x%x\n", pCmd->command))
    2153        break;
    2154      case CmdMulticastList:
    2155        printk(("uti596addCmd: Multi-cast list 0x%x\n", pCmd->command))
    2156        break;
    2157      case CmdNOp:
    2158        printk(("uti596addCmd: NO op 0x%x\n", pCmd->command))
    2159        break;
    2160      case CmdTDR:
    2161        printk(("uti596addCmd: TDR 0x%x\n", pCmd->command))
    2162        break;
    2163      case CmdDump:
    2164        printk(("uti596addCmd: Dump 0x%x\n", pCmd->command))
    2165        break;
    2166      case CmdDiagnose:
    2167        printk(("uti596addCmd: Diagnose 0x%x\n", pCmd->command))
    2168        break;
    2169      case CmdTx:
    2170        break;
    2171      default:
    2172        printk(("****Unknown Command encountered 0x%x\n", pCmd->command))
    2173        break;
    2174      } /* end switch */
    2175 #endif
    2176 
    2177      pCmd->status = 0;
    2178      pCmd->command |= (CMD_EOL | CMD_INTR ); /* all commands last in list & return an interrupt */
    2179 
    2180      pCmd->next = I596_NULL;
    2181 
    2182      _ISR_Disable(level);
    2183      if (uti596_softc.pCmdHead == I596_NULL)
    2184        {
    2185          uti596_softc.pCmdHead =
    2186            uti596_softc.pCmdTail =
    2187            uti596_softc.scb.pCmd = pCmd;
    2188          uti596_softc.scb.Cmd_val = word_swap ((unsigned long)pCmd);
    2189 #ifdef DBG_596
    2190          printk(("uti596addCmd: First Cmd\n"))
    2191 #endif
    2192          UTI_WAIT_COMMAND_ACCEPTED(10000,"add command"); /* wait for acceptance of previous command */
    2193          uti596_softc.scb.command = CUC_START;
    2194          i82596->chan_attn = 0x00000000;
    2195      _ISR_Enable(level);
     1641
     1642/***********************************************************************
     1643 *  Function:   uti596_attach
     1644 *
     1645 *  Description:
     1646 *              Configure the driver, and connect to the network stack
     1647 *
     1648 *  Algorithm:
     1649 *
     1650 *              Check parameters in the ifconfig structure, and
     1651 *              set driver parameters accordingly.
     1652 *              Initialize required rx and tx buffers.
     1653 *              Link driver data structure onto device list.
     1654 *              Return 1 on successful completion.
     1655 *
     1656 ***********************************************************************/
     1657
     1658int uti596_attach(
     1659  struct rtems_bsdnet_ifconfig * pConfig
     1660)
     1661{
     1662  uti596_softc_ *sc = &uti596_softc;                            /* device dependent data structure */
     1663  struct ifnet * ifp = &sc->arpcom.ac_if;   /* ifnet structure */
     1664
     1665        int unitNumber;
     1666        char *unitName;
     1667
     1668        #ifdef DBG_ATTACH
     1669  printk(("uti596_attach: begins\n"))
     1670        #endif
     1671
     1672  /* The NIC is not started yet */
     1673  sc->started = 0;
     1674
     1675  /* Indicate to ULCS that this is initialized */
     1676  ifp->if_softc = sc;
     1677  sc->pScp = NULL;
     1678
     1679        /* Parse driver name */
     1680        if ((unitNumber = rtems_bsdnet_parse_driver_name (pConfig, &unitName)) < 0)
     1681                return 0;
     1682
     1683  ifp->if_name = unitName;
     1684  ifp->if_unit = unitNumber;
     1685
     1686  /* Assign mtu */
     1687  if ( pConfig -> mtu )
     1688    ifp->if_mtu = pConfig -> mtu;
     1689  else
     1690    ifp->if_mtu = ETHERMTU;
     1691
     1692  /* Ethernet address can be specified in the ifconfig structure or
     1693   * it can be read in from BBRAM at $FFFC1F2C (6 bytes)
     1694   * mvme167 manual p. 1-47
     1695   */
     1696  if ( pConfig->hardware_address) {
     1697    memcpy (sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
     1698  }
     1699  else {
     1700    memcpy (sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);
     1701  }
     1702
     1703  /* Assign requested receive buffer descriptor count */
     1704  if (pConfig->rbuf_count)
     1705    sc->rxBdCount = pConfig->rbuf_count;
     1706  else
     1707    sc->rxBdCount = RX_BUF_COUNT;
     1708
     1709  /* Assign requested tx buffer descriptor count */
     1710  if (pConfig->xbuf_count)
     1711    sc->txBdCount = pConfig->xbuf_count;
     1712  else
     1713    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
     1714
     1715  /* Set up fields in the ifnet structure*/
     1716  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
     1717  ifp->if_snd.ifq_maxlen = ifqmaxlen;
     1718        ifp->if_init = uti596_init;
     1719  ifp->if_ioctl = uti596_ioctl;
     1720  ifp->if_start = uti596_start;
     1721  ifp->if_output = ether_output;
     1722
     1723  /* uti596_softc housekeeping */
     1724  sc->started = 1;
     1725  sc->pInboundFrameQueue = I596_NULL;
     1726  sc->scb.command = 0;
     1727
     1728  /*
     1729   * Attach the interface
     1730   */
     1731  if_attach (ifp);
     1732  ether_ifattach (ifp);
     1733  return 1;
     1734}
     1735
     1736/***********************************************************************
     1737 *  Function:  uti596_start
     1738 *
     1739 *  Description:
     1740 *             start the driver
     1741 *
     1742 *  Algorithm:
     1743 *             send an event to the tx task
     1744 *             set the if_flags
     1745 *
     1746 ***********************************************************************/
     1747static void uti596_start(
     1748  struct ifnet *ifp
     1749)
     1750{
     1751  uti596_softc_ *sc = ifp->if_softc;
     1752 
     1753        #ifdef DBG_START
     1754  printk(("uti596_start: begins\n"))
     1755        #endif
     1756       
     1757  rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
     1758  ifp->if_flags |= IFF_OACTIVE;
     1759}
     1760
     1761/***********************************************************************
     1762 *  Function:  uti596_init
     1763 *
     1764 *  Description:
     1765 *             driver initialization
     1766 *
     1767 *  Algorithm:
     1768 *             initialize the 82596
     1769 *             start driver tx and rx tasks, and reset task
     1770 *             send the RX_START command the the RU
     1771 *             set if_flags
     1772 *
     1773 *
     1774 ***********************************************************************/
     1775void uti596_init(
     1776  void * arg
     1777)
     1778{
     1779  uti596_softc_ *sc = arg;
     1780  struct ifnet *ifp = &sc->arpcom.ac_if;
     1781
     1782  if (sc->txDaemonTid == 0) {
     1783
     1784    /*
     1785     * Initialize the 82596
     1786     */
     1787                #ifdef DBG_INIT
     1788    printk(("uti596_init: begins\nuti596_init: initializing the 82596...\n"))
     1789                #endif
     1790    uti596_initialize_hardware(sc);
     1791
     1792    /*
     1793     * Start driver tasks
     1794     */
     1795                #ifdef DBG_INIT
     1796    printk(("uti596_init: starting driver tasks...\n"))
     1797                #endif
     1798    sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, sc);
     1799    sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, sc);
     1800    sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096, uti596_resetDaemon, sc);
     1801
     1802                #ifdef DBG_INIT
     1803    printk(("uti596_init: After attach, status of board = 0x%x\n", sc->scb.status ))
     1804                #endif
     1805  }
     1806
     1807  /*
     1808   * Enable receiver
     1809   */
     1810                #ifdef DBG_INIT
     1811    printk(("uti596_init: enabling the reciever...\n" ))
     1812                #endif
     1813  sc->scb.command = RX_START;
     1814  uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT );
     1815 
     1816  /*
     1817   * Tell the world that we're running.
     1818   */
     1819  ifp->if_flags |= IFF_RUNNING;
     1820                #ifdef DBG_INIT
     1821    printk(("uti596_init: completed.\n"))
     1822                #endif 
     1823}
     1824
     1825/***********************************************************************
     1826 *  Function:   uti596stop
     1827 *
     1828 *  Description:
     1829 *             stop the driver
     1830 *
     1831 *  Algorithm:
     1832 *             mark driver as not started,
     1833 *             mark transmitter as busy
     1834 *             abort any transmissions/receptions
     1835 *             clean-up all buffers ( RFD's et. al. )
     1836 *
     1837 *
     1838 ***********************************************************************/
     1839
     1840/* static */ void uti596_stop(
     1841  uti596_softc_ *sc
     1842)
     1843{
     1844        struct ifnet *ifp = &sc->arpcom.ac_if;
     1845
     1846        ifp->if_flags &= ~IFF_RUNNING;
     1847  sc->started = 0;
     1848
     1849                #ifdef DBG_STOP
     1850    printk(("uti596stop: %s: Shutting down ethercard, status was %4.4x.\n",
     1851           uti596_softc.arpcom.ac_if.if_name, uti596_softc.scb.status))
     1852                #endif
     1853
     1854    printk(("Stopping interface\n"))
     1855    sc->scb.command = CUC_ABORT | RX_ABORT;
     1856    i82596->chan_attn = 0x00000000;
     1857}
     1858
     1859
     1860
     1861/***********************************************************************
     1862 *  Function:   void uti596_txDaemon
     1863 *
     1864 *  Description: Transmit task
     1865 * 
     1866 *  Algorithm: Get mbufs to be transmitted, stuff into RFDs, send
     1867 * 
     1868 ***********************************************************************/
     1869
     1870void uti596_txDaemon(
     1871  void *arg
     1872)
     1873{
     1874  uti596_softc_ *sc = (uti596_softc_ *)arg;
     1875  struct ifnet *ifp = &sc->arpcom.ac_if;
     1876  struct mbuf *m;
     1877  rtems_event_set events;
     1878
     1879  for (;;) {
     1880   /*
     1881    * Wait for packet from stack
     1882    */
     1883    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
     1884                                RTEMS_EVENT_ANY | RTEMS_WAIT,
     1885                                RTEMS_NO_TIMEOUT, &events);
     1886
     1887   /*
     1888    * Send packets till queue is empty.
     1889    * Ensure that irq is on before sending.
     1890    */
     1891    for (;;) {
     1892     /* Get the next mbuf chain to transmit. */
     1893      IF_DEQUEUE(&ifp->if_snd, m);
     1894      if (!m)
     1895        break;
     1896
     1897      send_packet (ifp, m); /* blocks */
     1898    }
     1899    ifp->if_flags &= ~IFF_OACTIVE; /* no more to send, mark output inactive  */
     1900  }
     1901}
     1902
     1903/***********************************************************************
     1904 *  Function:   uti596_rxDaemon
     1905 *
     1906 *  Description: Receiver task
     1907 *
     1908 *  Algorithm: Extract the packet from an RFD, and place into an
     1909 *             mbuf chain.  Place the mbuf chain in the network task
     1910 *             queue. Assumes that the frame check sequence is removed
     1911 *             by the 82596.
     1912 *
     1913 ***********************************************************************/
     1914
     1915/* static */ void uti596_rxDaemon(
     1916  void *arg
     1917)
     1918{
     1919  uti596_softc_ *sc = (uti596_softc_ *)arg;
     1920  struct ifnet *ifp = &sc->arpcom.ac_if;
     1921  struct mbuf *m;
     1922
     1923  i596_rfd *pRfd;
     1924  ISR_Level level;
     1925  int tid;
     1926  rtems_event_set events;
     1927  struct ether_header *eh;
     1928
     1929  int frames = 0;
     1930
     1931        #ifdef DBG_RX
     1932  printk(("uti596_rxDaemon: begin\n"))
     1933  printk(("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd))
     1934        #endif
     1935
     1936  rtems_task_ident (0, 0, &tid);
     1937
     1938  for(;;) {
     1939    /*
     1940     * Wait for packet.
     1941     */
     1942        #ifdef DBG_RX
     1943     printk(("uti596_rxDaemon: Receiver sleeps\n"))
     1944        #endif
     1945
     1946     rtems_bsdnet_event_receive (INTERRUPT_EVENT,
     1947                                 RTEMS_WAIT|RTEMS_EVENT_ANY,
     1948                                 RTEMS_NO_TIMEOUT,
     1949                                 &events);
     1950
     1951                 #ifdef DBG_RX
     1952     printk(("uti596_rxDaemon: Receiver wakes\n"))
     1953                 #endif
     1954     /*
     1955      * While received frames are available. Note that the frame may be
     1956      * a fragment, so it is NOT a complete packet.
     1957      */
     1958     pRfd = uti596_dequeue( &sc->pInboundFrameQueue);
     1959     while ( pRfd &&
     1960             pRfd != I596_NULL &&
     1961             pRfd -> stat & STAT_C )
     1962     {
     1963
     1964       if ( pRfd->stat & STAT_OK) {                             /* a good frame */
     1965         int pkt_len = pRfd->count & 0x3fff;    /* the actual # of bytes received */
     1966
     1967                                 #ifdef DBG_RX
     1968         printk(("uti596_rxDaemon: Good frame, @%p, data @%p length %d\n", pRfd, pRfd -> data , pkt_len))
     1969                                 #endif
     1970         frames++;
     1971
     1972         /*
     1973          * Allocate an mbuf to give to the stack
     1974          * The format of the data portion of the RFD is:
     1975          * <ethernet header, payload>.
     1976          * The FRAME CHECK SEQUENCE / CRC is stripped by the uti596.
     1977          * This is to be optimized later.... should not have to memcopy!
     1978          */
     1979         MGETHDR(m, M_WAIT, MT_DATA);
     1980         MCLGET(m, M_WAIT);
     1981
     1982         m->m_pkthdr.rcvif = ifp;
     1983         /* move everything into an mbuf */
     1984         memcpy(m->m_data, pRfd->data, pkt_len);
     1985         m->m_len = m->m_pkthdr.len = pkt_len - sizeof(struct ether_header) - 4;
     1986
     1987         /* move the header to an mbuf */
     1988         eh = mtod (m, struct ether_header *);
     1989         m->m_data += sizeof(struct ether_header);
     1990
     1991                                 #ifdef DBG_PACKETS
     1992                                 {
     1993                                         int i;
     1994                 printk(("uti596_rxDaemon: mbuf contains:\n"))
     1995                 print_eth( (char *) (((int)m->m_data)-sizeof(struct ether_header)));
     1996                 for ( i = 0; i<20; i++) {
     1997                           printk(("."))
     1998                 }
     1999         }
     2000                                 #endif
     2001
     2002         ether_input (ifp, eh, m);
     2003
     2004       } /* end if STAT_OK */
     2005
     2006       else {
     2007         /*
     2008          * A bad frame is present: Note that this could be the last RFD!
     2009          */
     2010                                 #ifdef DBG_RX
     2011         printk(("uti596_rxDaemon: Bad frame\n"))
     2012                                 #endif
     2013         /*
     2014          * FIX ME: use the statistics from the SCB
     2015          */
     2016         sc->stats.rx_errors++;
     2017         if ((sc->scb.pRfd->stat) & 0x0001)
     2018           sc->stats.collisions++;
     2019         if ((sc->scb.pRfd->stat) & 0x0080)
     2020           sc->stats.rx_length_errors++;
     2021         if ((sc->scb.pRfd->stat) & 0x0100)
     2022           sc->stats.rx_over_errors++;
     2023         if ((sc->scb.pRfd->stat) & 0x0200)
     2024           sc->stats.rx_fifo_errors++;
     2025         if ((sc->scb.pRfd->stat) & 0x0400)
     2026           sc->stats.rx_frame_errors++;
     2027         if ((sc->scb.pRfd->stat) & 0x0800)
     2028           sc->stats.rx_crc_errors++;
     2029         if ((sc->scb.pRfd->stat) & 0x1000)
     2030           sc->stats.rx_length_errors++;
    21962031       }
    2197      else
    2198        {
    2199 #ifdef DBG_596
    2200          printk(("uti596addCmd: Chained Cmd\n"))
    2201 #endif
    2202          uti596_softc.pCmdTail->next = (i596_cmd *) word_swap ((unsigned long)pCmd);
    2203          uti596_softc.pCmdTail = pCmd;
    2204      _ISR_Enable(level);
    2205        }
    2206 
    2207 #ifdef DBG_596
    2208          printk(("uti596addCmd: Scb status & command 0x%x 0x%x\n",
    2209                 uti596_softc.scb.status,
    2210                 uti596_softc.scb.command ))
    2211 #endif
     2032
     2033       UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD\n")
     2034
     2035       _ISR_Disable(level);
     2036       uti596_supplyFD ( pRfd );   /* Return RFD to RFA. */
     2037       _ISR_Enable(level);
     2038
     2039       pRfd = uti596_dequeue( &sc->pInboundFrameQueue); /* grab next frame */
     2040
     2041     } /* end while */
     2042  } /* end for() */
     2043
     2044        #ifdef DBG_RX
     2045  printk (("uti596_rxDaemon: frames ... %d\n", frames))
     2046        #endif
    22122047}
    22132048
    22142049
    22152050/***********************************************************************
    2216  *  Function:   uti596supplyFD
    2217  *
    2218  *  Description: returns a buffer to the receive frame pool.
    2219  *               call this with Inetrrupts disabled!
    2220  *
    2221  *  Algorithm:
    2222  *
     2051 *  Function:   void uti596_resetDaemon
     2052 *
     2053 *  Description:
     2054 ***********************************************************************/
     2055void uti596_resetDaemon(
     2056  void *arg
     2057)
     2058{
     2059  uti596_softc_ *sc = (uti596_softc_ *)arg;
     2060  rtems_event_set events;
     2061  rtems_time_of_day tm_struct;
     2062
     2063  /* struct ifnet *ifp = &sc->arpcom.ac_if; */
     2064
     2065  for (;;) {
     2066   /* Wait for reset event from ISR */
     2067    rtems_bsdnet_event_receive (NIC_RESET_EVENT,
     2068                                RTEMS_EVENT_ANY | RTEMS_WAIT,
     2069                                RTEMS_NO_TIMEOUT, &events);
     2070
     2071    rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
     2072    printk(("reset daemon: Resetting NIC @ %d:%d:%d \n",
     2073           tm_struct.hour, tm_struct.minute, tm_struct.second))
     2074
     2075    sc->stats.nic_reset_count++;
     2076    /* Reinitialize the LANC */
     2077    rtems_bsdnet_semaphore_obtain ();
     2078    uti596_reset();
     2079    rtems_bsdnet_semaphore_release ();
     2080  }
     2081}
     2082
     2083
     2084/***********************************************************************
     2085 *  Function:   uti596_DynamicInterruptHandler
     2086 *
     2087 *  Description:
     2088 *             This is the interrupt handler for the uti596 board
     2089 *
     2090 ***********************************************************************/
     2091
     2092/* static */ rtems_isr uti596_DynamicInterruptHandler(
     2093  rtems_vector_number irq
     2094)
     2095{
     2096        #ifdef DBG_ISR
     2097  printk(("uti596_DynamicInterruptHandler: begins"))
     2098        #endif
     2099
     2100 uti596_wait (&uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT);
     2101
     2102 scbStatus = uti596_softc.scb.status & 0xf000;
     2103
     2104 if ( scbStatus ) {
     2105   /* acknowledge interrupts */
     2106   
     2107   /* Write to the ICLR bit in the PCCchip2 control registers to clear
     2108    * the INT status bit. Clearing INT here *before* sending the CA signal
     2109    * to the 82596 should ensure that interrupts won't be lost.
     2110    */
     2111    pccchip2->LANC_int_ctl |=0x08;
     2112    pccchip2->LANC_berr_ctl |=0x08;
     2113   
     2114    /* printk(("***INFO: ACK %x\n", scbStatus))*/
     2115   
     2116    /* Send the CA signal to acknowledge interrupt */
     2117    uti596_softc.scb.command = scbStatus;
     2118    uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );
     2119
     2120    if( uti596_softc.resetDone ) {
     2121      /* stack is attached */
     2122      uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
     2123    }
     2124    else {
     2125      printk(("***INFO: ACK'd w/o processing. status = %x\n", scbStatus))
     2126      return;
     2127    }
     2128  }
     2129  else {
     2130    printk(("\n***ERROR: Spurious interrupt. Resetting...\n"))
     2131    uti596_softc.nic_reset = 1;
     2132  }
     2133
     2134
     2135  if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ) {
     2136    printk(("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus))
     2137    uti596_softc.nic_reset = 1;
     2138    return;
     2139  }
     2140
     2141  if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {
     2142    printk(("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus))
     2143    uti596_softc.nic_reset = 1;
     2144    return;
     2145  }
     2146
     2147  if ( scbStatus & SCB_CUS_SUSPENDED ) {
     2148    printk(("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus))
     2149    uti596_softc.nic_reset = 1;
     2150    return;
     2151  }
     2152
     2153  if ( scbStatus & RU_SUSPENDED  ) {
     2154    printk(("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus))
     2155    uti596_softc.nic_reset = 1;
     2156    return;
     2157  }
     2158
     2159  if ( scbStatus & SCB_STAT_RNR ) {
     2160    printk(("\n*****WARNING: RNR %x\n",scbStatus))
     2161    if (uti596_softc.pBeginRFA != I596_NULL) {
     2162        printk(("*****INFO: RFD cmd: %x status:%x\n", uti596_softc.pBeginRFA->cmd,
     2163                                        uti596_softc.pBeginRFA->stat))
     2164    }
     2165    else {
     2166        printk(("*****WARNING: RNR condition with NULL BeginRFA\n"))
     2167    }         
     2168  }
     2169
     2170 /*
     2171  * Receive Unit Control
     2172  *   a frame is received
     2173  */
     2174  if ( scbStatus & SCB_STAT_FR ) {
     2175    uti596_softc.rxInterrupts++;
     2176 
     2177                #ifdef DBG_ISR
     2178    printk(("uti596_DynamicInterruptHandler: Frame received\n"))
     2179                #endif
     2180    if ( uti596_softc.pBeginRFA == I596_NULL ||
     2181       !( uti596_softc.pBeginRFA -> stat & STAT_C)) {
     2182      uti596_dump_scb();
     2183      uti596_softc.nic_reset = 1;
     2184    }
     2185    else {
     2186      while ( uti596_softc.pBeginRFA != I596_NULL &&
     2187           ( uti596_softc.pBeginRFA -> stat & STAT_C)) {
     2188
     2189                                #ifdef DBG_ISR
     2190        printk(("uti596_DynamicInterruptHandler: pBeginRFA != NULL\n"))
     2191                                #endif
     2192        count_rx ++;
     2193        if ( count_rx > 1) {
     2194          printk(("****WARNING: Received 2 frames on 1 interrupt \n"))
     2195                                }
     2196       /* Give Received Frame to the ULCS */
     2197        uti596_softc.countRFD--;
     2198
     2199        if ( uti596_softc.countRFD < 0 ) {
     2200          printk(("ISR: Count < 0 !!! count == %d, beginRFA = %p\n",
     2201                 uti596_softc.countRFD, uti596_softc.pBeginRFA))
     2202                                }
     2203        uti596_softc.stats.rx_packets++;
     2204        /* the rfd next link is stored with upper and lower words swapped so read it that way */
     2205        pIsrRfd = (i596_rfd *) word_swap ((unsigned long)uti596_softc.pBeginRFA->next);
     2206        /* the append destroys the link */
     2207        uti596_append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );
     2208
     2209       /*
     2210        * if we have just received the a frame in the last unknown RFD,
     2211        * then it is certain that the RFA is empty.
     2212        */
     2213        if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) {
     2214          UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n")
     2215          uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;
     2216        }
     2217
     2218                                #ifdef DBG_ISR
     2219        printk(("uti596_DynamicInterruptHandler: Wake %#x\n",uti596_softc.rxDaemonTid))
     2220                                #endif
     2221        sc = rtems_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT);
     2222        if ( sc != RTEMS_SUCCESSFUL ) {
     2223          rtems_panic("Can't notify rxDaemon: %s\n",
     2224                    rtems_status_text (sc));
     2225        }
     2226                                #ifdef DBG_ISR
     2227        else {
     2228          printk(("uti596_DynamicInterruptHandler: Rx Wake: %#x\n",uti596_softc.rxDaemonTid))
     2229        }
     2230                                #endif
     2231
     2232        uti596_softc.pBeginRFA = pIsrRfd;
     2233      } /* end while */
     2234    } /* end if */
     2235
     2236    if ( uti596_softc.pBeginRFA == I596_NULL ) {
     2237      /* adjust the pEndRFA to reflect an empty list */
     2238      if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 ) {
     2239        printk(("Last Unk is NULL, BeginRFA is null, and count == %d\n",
     2240               uti596_softc.countRFD))
     2241                        }
     2242      uti596_softc.pEndRFA = I596_NULL;
     2243      if ( uti596_softc.countRFD != 0 ) {
     2244        printk(("****ERROR:Count is %d, but begin ptr is NULL\n",
     2245               uti596_softc.countRFD ))
     2246      }
     2247    }
     2248  } /* end if ( scbStatus & SCB_STAT_FR ) */
     2249
     2250
     2251 /*
     2252  * Command Unit Control
     2253  *   a command is completed
     2254  */
     2255  if ( scbStatus & SCB_STAT_CX ) {
     2256                #ifdef DBG_ISR
     2257    printk(("uti596_DynamicInterruptHandler: CU\n"))
     2258                #endif
     2259
     2260    pIsrCmd = uti596_softc.pCmdHead;
     2261
     2262   /* For ALL completed commands */
     2263   if ( pIsrCmd !=  I596_NULL && pIsrCmd->status & STAT_C  ) {
     2264
     2265                         #ifdef DBG_ISR
     2266       printk(("uti596_DynamicInterruptHandler: pIsrCmd != NULL\n"))
     2267                         #endif
     2268
     2269      /* Adjust the command block list */
     2270      uti596_softc.pCmdHead = (i596_cmd *) word_swap ((unsigned long)pIsrCmd->next);
     2271
     2272     /*
     2273      * If there are MORE commands to process,
     2274      * the serialization in the raw routine has failed.
     2275      * ( Perhaps AddCmd is bad? )
     2276      */
     2277      UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL, "****ERROR: command serialization failed\n")
     2278                   
     2279      /* What if the command did not complete OK? */
     2280      switch ( pIsrCmd->command & 0x7) {
     2281        case CmdConfigure:
     2282
     2283          uti596_softc.cmdOk = 1;
     2284          break;
     2285
     2286        case CmdDump:
     2287                                        #ifdef DBG_ISR
     2288          printk(("uti596_DynamicInterruptHandler: dump!\n"))
     2289                                        #endif
     2290          uti596_softc.cmdOk = 1;
     2291          break;
     2292
     2293        case CmdDiagnose:
     2294                                        #ifdef DBG_ISR
     2295          printk(("uti596_DynamicInterruptHandler: diagnose!\n"))
     2296                                        #endif
     2297          uti596_softc.cmdOk = 1;
     2298          break;
     2299
     2300        case CmdSASetup:
     2301          /* printk(("****INFO:Set address interrupt\n")) */
     2302          if ( pIsrCmd -> status & STAT_OK ) {
     2303            uti596_softc.cmdOk = 1;
     2304          }
     2305          else {
     2306            printk(("****ERROR:SET ADD FAILED\n"))
     2307                                        }
     2308          break;
     2309
     2310        case CmdTx:
     2311          UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n")
     2312                                        #ifdef DBG_ISR
     2313          printk(("uti596_DynamicInterruptHandler: wake TX:0x%x\n",uti596_softc.txDaemonTid))
     2314                                        #endif
     2315          if ( uti596_softc.txDaemonTid ) {
     2316            /* Ensure that the transmitter is present */
     2317            sc = rtems_event_send (uti596_softc.txDaemonTid,
     2318                                 INTERRUPT_EVENT);
     2319
     2320            if ( sc != RTEMS_SUCCESSFUL ) {
     2321              printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",
     2322                     uti596_softc.txDaemonTid, rtems_status_text (sc) ))
     2323            }
     2324                                                #ifdef DBG_ISR
     2325            else {
     2326              printk(("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid))
     2327            }
     2328                                                #endif
     2329          }
     2330          break;
     2331
     2332        case CmdMulticastList:
     2333          printk(("***ERROR:Multicast?!\n"))
     2334          pIsrCmd->next = I596_NULL;
     2335          break;
     2336
     2337        case CmdTDR: {
     2338                  unsigned long status = *( (unsigned long *)pIsrCmd)+1;
     2339                  printk(("****ERROR:TDR?!\n"))
     2340
     2341                  if (status & STAT_C) {
     2342                    /* mark the TDR command successful */
     2343                    uti596_softc.cmdOk = 1;
     2344                  }
     2345                  else {
     2346                    if (status & 0x4000) {
     2347                      printk(("****WARNING:Transceiver problem.\n"))
     2348                    }
     2349                    if (status & 0x2000) {
     2350                      printk(("****WARNING:Termination problem.\n"))
     2351                    }
     2352                    if (status & 0x1000) {
     2353                      printk(("****WARNING:Short circuit.\n"))
     2354                      /* printk(("****INFO:Time %ld.\n", status & 0x07ff)) */
     2355                    }
     2356                  }
     2357          }
     2358          break;
     2359
     2360        default: {
     2361          /*
     2362           * This should never be reached
     2363           */
     2364          printk(("CX but NO known command\n"))
     2365        }
     2366      } /* end switch */
     2367
     2368      pIsrCmd = uti596_softc.pCmdHead; /* next command */
     2369      if ( pIsrCmd != I596_NULL ) {
     2370        printk(("****WARNING: more commands in list, but no start to NIC\n"))
     2371      }
     2372    } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C  */
     2373   
     2374    else {
     2375      if ( pIsrCmd != I596_NULL ) {
     2376        /* The command MAY be NULL from a RESET */
     2377        /* Reset the ethernet card, and wake the transmitter (if necessary) */
     2378        printk(("****INFO: Request board reset ( tx )\n"))
     2379        uti596_softc.nic_reset = 1;
     2380        if ( uti596_softc.txDaemonTid) {
     2381          /* Ensure that a transmitter is present */
     2382          sc = rtems_event_send (uti596_softc.txDaemonTid,
     2383                                 INTERRUPT_EVENT);
     2384          if ( sc != RTEMS_SUCCESSFUL ) {
     2385            printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",
     2386                                         uti596_softc.txDaemonTid, rtems_status_text (sc) ))
     2387          }
     2388                                        #ifdef DBG_ISR
     2389          else {
     2390            printk(("uti596_DynamicInterruptHandler: ****INFO:Tx wake: %#x\n",
     2391                                         uti596_softc.txDaemonTid))
     2392          }
     2393                                        #endif
     2394        }
     2395      }
     2396    }
     2397  }  /* end if command complete */
     2398
     2399
     2400 /*
     2401  * If the receiver has stopped,
     2402  * check if this is a No Resources scenario,
     2403  * Try to add more RFD's ( no RBDs are used )
     2404  */
     2405  if ( uti596_softc.started ) {
     2406    if ( scbStatus & SCB_STAT_RNR ) {
     2407                        #ifdef DBG_ISR
     2408      printk(("uti596_DynamicInterruptHandler: INFO:RNR: status %#x \n",
     2409                                uti596_softc.scb.status ))
     2410                        #endif
     2411     /*
     2412      * THE RECEIVER IS OFF!
     2413      */
     2414      if ( uti596_softc.pLastUnkRFD != I596_NULL  ) {
     2415        /* We have an unknown RFD, it is not inbound */
     2416        if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) { /* in use */
     2417          uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD;            /* update end */
     2418        }
     2419        else {
     2420         /*
     2421          *  It is NOT in use, and since RNR, we know EL bit of pEndRFA was read!
     2422          *  So, unlink it from the RFA and move it to the saved queue.
     2423          *  But pBegin can equal LastUnk!
     2424          */
     2425
     2426          if ( uti596_softc.pEndRFA != I596_NULL ) {
     2427            /* check added feb24. */
     2428                                                #ifdef DBG_ISR
     2429            if ((i596_rfd *)word_swap((unsigned long)uti596_softc.pEndRFA->next) != uti596_softc.pLastUnkRFD) {
     2430              printk(("***ERROR:UNK: %p not end->next: %p, end: %p\n",
     2431                     uti596_softc.pLastUnkRFD,
     2432                     uti596_softc.pEndRFA -> next,
     2433                     uti596_softc.pEndRFA))
     2434              printk(("***INFO:countRFD now %d\n",
     2435                     uti596_softc.countRFD))
     2436              printk(("\n\n"))
     2437            }
     2438                                                #endif
     2439            uti596_softc.pEndRFA -> next = I596_NULL;   /* added feb 16 */
     2440          }
     2441          uti596_append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );
     2442          uti596_softc.savedCount++;
     2443          uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD;
     2444          uti596_softc.countRFD--;                    /* It was not in the RFA */
     2445         /*
     2446          * The Begin pointer CAN advance this far. We must resynch the CPU side
     2447          * with the chip.
     2448          */
     2449          if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {
     2450                                                #ifdef DBG_ISR
     2451            if ( uti596_softc.countRFD != 0 ) {
     2452              printk(("****INFO:About to set begin to NULL, with count == %d\n\n",
     2453                     uti596_softc.countRFD ))
     2454            }
     2455                                                #endif
     2456            uti596_softc.pBeginRFA = I596_NULL;
     2457            UTI_596_ASSERT(uti596_softc.countRFD == 0, "****ERROR:Count must be zero here!\n")
     2458          }
     2459        }
     2460        uti596_softc.pLastUnkRFD = I596_NULL;
     2461      } /* end if exists UnkRFD */
     2462
     2463     /*
     2464      * Append the saved queue to  the RFA.
     2465      * Any further RFD's being supplied will be added to
     2466      * this new list.
     2467      */
     2468      if ( uti596_softc.pSavedRfdQueue != I596_NULL ) {
     2469        /* entries to add */
     2470        if ( uti596_softc.pBeginRFA == I596_NULL ) {
     2471          /* add at beginning to list */
     2472                                        #ifdef DBG_ISR
     2473          if(uti596_softc.countRFD != 0) {
     2474            printk(("****ERROR:Begin pointer is NULL, but count == %d\n",
     2475                   uti596_softc.countRFD))
     2476          }
     2477                                        #endif
     2478          uti596_softc.pBeginRFA      = uti596_softc.pSavedRfdQueue;
     2479          uti596_softc.pEndRFA        = uti596_softc.pEndSavedQueue;
     2480          uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL;  /* Reset the End */
     2481        }
     2482        else {
     2483                                        #ifdef DBG_ISR
     2484          if ( uti596_softc.countRFD <= 0) {
     2485            printk(("****ERROR:Begin pointer is not NULL, but count == %d\n",
     2486                   uti596_softc.countRFD))
     2487          }
     2488                                        #endif
     2489          UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n")
     2490          UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n")
     2491
     2492          uti596_softc.pEndRFA->next   = (i596_rfd *)word_swap((unsigned long)uti596_softc.pSavedRfdQueue);
     2493          uti596_softc.pEndRFA->cmd   &= ~CMD_EOL;      /* clear the end of list */
     2494          uti596_softc.pEndRFA         = uti596_softc.pEndSavedQueue;
     2495          uti596_softc.pSavedRfdQueue  = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */
     2496                                        #ifdef DBG_ISR
     2497          printk(("uti596_DynamicInterruptHandler: count... %d, saved ... %d \n",
     2498                 uti596_softc.countRFD,
     2499                 uti596_softc.savedCount))
     2500                                        #endif
     2501        }
     2502        /* printk(("Isr: countRFD = %d\n",uti596_softc.countRFD)) */
     2503        uti596_softc.countRFD += uti596_softc.savedCount;
     2504        /* printk(("Isr: after countRFD = %d\n",uti596_softc.countRFD)) */
     2505        uti596_softc.savedCount = 0;
     2506      }
     2507
     2508                        #ifdef DBG_ISR
     2509      printk(("uti596_DynamicInterruptHandler: The list starts here %p\n",uti596_softc.pBeginRFA ))
     2510                        #endif
     2511
     2512      if ( uti596_softc.countRFD > 1) {
     2513        printk(("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat))
     2514        printk(("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd))
     2515        uti596_softc.pBeginRFA -> stat = 0;
     2516        UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n")
     2517        uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
     2518        uti596_softc.scb.rfd_pointer = word_swap((unsigned long)uti596_softc.pBeginRFA);
     2519        /* start RX here  */
     2520        printk(("****INFO: ISR Starting receiver\n"))
     2521        uti596_softc.scb.command = RX_START; /* should this also be CU start? */
     2522        i82596->chan_attn = 0x00000000;
     2523      }
     2524    } /* end stat_rnr */
     2525  } /* end if receiver started */
     2526
     2527        #ifdef DBG_ISR
     2528  printk(("uti596_DynamicInterruptHandler: X\n"))
     2529        #endif
     2530  count_rx=0;
     2531 
     2532 
     2533 /* Do this last, to ensure that the reset is called at the right time. */
     2534  if ( uti596_softc.nic_reset ) {
     2535    uti596_softc.nic_reset = 0;
     2536    sc = rtems_event_send(uti596_softc.resetDaemonTid, NIC_RESET_EVENT);
     2537    if ( sc != RTEMS_SUCCESSFUL )
     2538      rtems_panic ("Can't notify resetDaemon: %s\n", rtems_status_text (sc));
     2539  }
     2540  return;
     2541}
     2542
     2543
     2544/***********************************************************************
     2545 *  Function:  uti596_ioctl
     2546 *
     2547 *  Description:
     2548 *             driver ioctl function
     2549 *             handles SIOCGIFADDR, SIOCSIFADDR, SIOCSIFFLAGS
     2550 *             
    22232551 ***********************************************************************/
    22242552 
    2225 void uti596supplyFD(
    2226   i596_rfd * pRfd
    2227 )
    2228 {
    2229  i596_rfd *pLastRfd;
    2230 
    2231  UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD!\n")
    2232  pRfd -> cmd  = CMD_EOL;
    2233  pRfd -> pRbd = I596_NULL;
    2234  pRfd -> next = I596_NULL;
    2235  pRfd -> stat = 0x0000;      /* clear STAT_C and STAT_B bits */
    2236 
    2237  /*
    2238   * Check if the list is empty:
    2239   */
    2240  if ( uti596_softc.pBeginRFA == I596_NULL ) {
    2241    /* Init a list w/ one entry */
    2242    uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
    2243    UTI_596_ASSERT(uti596_softc.countRFD == 0, "Null begin, but non-zero count\n")
    2244    if ( uti596_softc.pLastUnkRFD != I596_NULL ) {
    2245      printk(("LastUnkRFD is NOT NULL!!\n"))
    2246    }
    2247    uti596_softc.countRFD = 1;
    2248    return;
    2249  }
    2250  /*
    2251   * Check if the last RFD is used/read by the 596.
    2252   */
    2253  pLastRfd = uti596_softc.pEndRFA;
    2254 
    2255  if (    pLastRfd != I596_NULL &&
    2256       ! (pLastRfd -> stat & ( STAT_C | STAT_B ) )) { /* C = complete, B = busy (prefetched) */
    2257 
    2258    /*
    2259     * Not yet too late to add it
    2260     */
    2261    pLastRfd -> next = (i596_rfd *) word_swap ((unsigned long)pRfd);
    2262    pLastRfd -> cmd &= ~CMD_EOL;  /* RESET_EL : reset EL bit to 0  */
    2263    uti596_softc.countRFD++;  /* Lets assume we add it successfully
    2264                                 If not, the RFD may be used, and may decrement countRFD < 0 !!*/
    2265    /*
    2266     * Check if the last RFD was used while appending.
    2267     */
    2268    if ( pLastRfd -> stat & ( STAT_C | STAT_B ) ) { /* completed or was prefetched */
    2269      /*
    2270       * Either the EL bit of the last rfd has been read by the 82596,
    2271       * and it will stop after reception,( true when RESET_EL not reached ) or
    2272       * the EL bit was NOT read by the 82596 and it will use the linked
    2273       * RFD for the next reception. ( true is RESET_EL was reached )
    2274       * So, it is unknown whether or not the linked rfd will be used.
    2275       * Therefore, the end of list CANNOT be updated.
    2276       */
    2277      UTI_596_ASSERT ( uti596_softc.pLastUnkRFD == I596_NULL, "Too many Unk RFD's\n" )
    2278      uti596_softc.pLastUnkRFD = pRfd;
    2279      return;
    2280    }
    2281    else {
    2282      /*
    2283       * The RFD being added was not touched by the 82596
    2284       */
    2285      if (uti596_softc.pLastUnkRFD != I596_NULL ) {
    2286 
    2287        uti596append(&uti596_softc.pSavedRfdQueue, pRfd); /* Only here! saved Q */
    2288        uti596_softc.pEndSavedQueue = pRfd;
    2289        uti596_softc.savedCount++;
    2290        uti596_softc.countRFD--;
    2291 
    2292      }
    2293      else {
    2294        uti596_softc.pEndRFA = pRfd;                                     /* the RFA has been extended */
    2295        if ( ( uti596_softc.scb.status & SCB_STAT_RNR ||
    2296               uti596_softc.scb.status & RU_NO_RESOURCES ) &&
    2297               uti596_softc.countRFD > 1 ) {
    2298          uti596_softc.pBeginRFA -> cmd &= ~CMD_EOL;             /* Ensure that beginRFA is not EOL */
    2299 
    2300          UTI_596_ASSERT(uti596_softc.pEndRFA -> next == I596_NULL, "supply: List buggered\n")
    2301          UTI_596_ASSERT(uti596_softc.pEndRFA -> cmd & CMD_EOL, "supply: No EOL at end.\n")
    2302          UTI_596_ASSERT(uti596_softc.scb.command == 0, "Supply: scb command must be zero\n")
    2303 #ifdef DBG_START
    2304          printk(("uti596supplyFD: starting receiver"))
    2305 #endif
    2306          /* start the receiver */
    2307          UTI_596_ASSERT(uti596_softc.pBeginRFA != I596_NULL, "rx start w/ NULL begin! \n")
    2308          uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
    2309          uti596_softc.scb.Rfd_val = word_swap ((unsigned long) uti596_softc.pBeginRFA);
    2310          uti596_softc.scb.command = RX_START | SCB_STAT_RNR;  /* Don't ack RNR! The receiver
    2311                                                                                                                                                                                                                                  * should be stopped in this case */
    2312          UTI_596_ASSERT( !(uti596_softc.scb.status & SCB_STAT_FR),"FRAME RECEIVED INT COMING!\n")
    2313          i82596->chan_attn = 0x00000000;        /* send CA signal */
    2314        }
    2315      }
    2316      return;
    2317 
    2318    }
    2319  }
    2320  else {
    2321    /*
    2322     * too late , pLastRfd in use ( or NULL ),
    2323     * in either case, EL bit has been read, and RNR condition will occur
    2324     */
    2325    uti596append( &uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */
    2326 
    2327    uti596_softc.pEndSavedQueue = pRfd;                /* reset end of saved queue */
    2328    uti596_softc.savedCount++;
    2329 
    2330    return;
    2331  }
    2332 }
     2553static int uti596_ioctl(
     2554  struct ifnet *ifp,
     2555  int command, caddr_t data
     2556)
     2557{
     2558  uti596_softc_ *sc = ifp->if_softc;
     2559  int error = 0;
     2560
     2561        #ifdef DBG_IOCTL
     2562  printk(("uti596_ioctl: begins\n", sc->pScp))
     2563        #endif
     2564
     2565  switch (command) {
     2566    case SIOCGIFADDR:
     2567    case SIOCSIFADDR:
     2568      printk(("SIOCSIFADDR\n"))
     2569      ether_ioctl (ifp, command, data);
     2570      break;
     2571
     2572    case SIOCSIFFLAGS:
     2573      printk(("SIOCSIFFLAGS\n"))
     2574      switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
     2575        case IFF_RUNNING:
     2576          printk(("IFF_RUNNING\n"))
     2577          uti596_stop (sc);
     2578          break;
     2579
     2580        case IFF_UP:
     2581          printk(("IFF_UP\n"))
     2582          uti596_init (sc);
     2583          break;
     2584
     2585        case IFF_UP | IFF_RUNNING:
     2586          printk(("IFF_UP and RUNNING\n"))
     2587          uti596_stop (sc);
     2588          uti596_init (sc);
     2589          break;
     2590
     2591        default:
     2592          printk(("default\n"))
     2593          break;
     2594      }
     2595      break;
     2596
     2597    case SIO_RTEMS_SHOW_STATS:
     2598      printk(("show stats\n"))
     2599      uti596_stats (sc);
     2600      break;
     2601
     2602    /* FIXME: All sorts of multicast commands need to be added here! */
     2603    default:
     2604      printk(("default: EINVAL\n"))
     2605      error = EINVAL;
     2606      break;
     2607  }
     2608 
     2609  return error;
     2610}
     2611
    23332612
    23342613/***********************************************************************
    2335  *  Function:   void uti596append
     2614 *  Function:   uti596_stats
    23362615 *
    23372616 *  Description:
    2338  *              adds an RFD to the end of the received frame queue,
    2339  *              for processing by the rxproc.
    2340  *              Also removes this RFD from the RFA
     2617 *             print out the collected data
    23412618 *
    23422619 *  Algorithm:
     2620 *            use printf
    23432621 *
    23442622 ***********************************************************************/
    2345 void uti596append(
    2346   i596_rfd ** ppQ,
    2347   i596_rfd * pRfd
    2348 )
    2349 {
    2350 
    2351   i596_rfd *p;
    2352 
    2353   if ( pRfd != NULL && pRfd != I596_NULL) {
    2354     pRfd -> next = I596_NULL;
    2355     pRfd -> cmd |= CMD_EOL;    /* set EL bit */
    2356 
    2357     if ( *ppQ == NULL || *ppQ == I596_NULL ) {
    2358       /* empty list */
    2359       *ppQ = pRfd;
    2360     }
    2361     else {
    2362       /* walk to the end of the list */
    2363       for ( p=*ppQ;
    2364                         p->next != I596_NULL;
    2365                         p=(i596_rfd *) word_swap ((unsigned long)p->next) );
    2366 
    2367       /* append the rfd */
    2368       p->cmd &= ~CMD_EOL; /* Clear EL bit at end */
    2369       p->next = (i596_rfd *) word_swap ((unsigned long)pRfd);
    2370     }
    2371   }
    2372   else {
    2373     printk(("Illegal attempt to append: %p\n", pRfd))
    2374   }
    2375 }
    2376 
    2377 /***********************************************************************
    2378  *  Function:   void printk_time
    2379  *
    2380  *  Description:
    2381  ***********************************************************************/
    2382 void printk_time( void )
    2383 {
    2384   rtems_time_of_day tm_struct;
    2385 
    2386   rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
    2387   printk(("Current time: %d:%d:%d \n",
    2388          tm_struct.hour,
    2389          tm_struct.minute,
    2390          tm_struct.second))
    2391 }
    2392 
    2393 /***********************************************************************
    2394  *  Function:   void dump_scb
    2395  *
    2396  *  Description:
    2397  ***********************************************************************/
    2398 void dump_scb( void )
    2399 {
    2400   printk(("status 0x%x\n",uti596_softc.scb.status))
    2401   printk(("command 0x%x\n",uti596_softc.scb.command))
    2402   printk(("cmd 0x%x\n",(int)uti596_softc.scb.pCmd))
    2403   printk(("rfd 0x%x\n",(int)uti596_softc.scb.pRfd))
    2404   printk(("crc_err 0x%x\n",uti596_softc.scb.crc_err))
    2405   printk(("align_err 0x%x\n",uti596_softc.scb.align_err))
    2406   printk(("resource_err 0x%x\n",uti596_softc.scb.resource_err ))
    2407   printk(("over_err 0x%x\n",uti596_softc.scb.over_err))
    2408   printk(("rcvdt_err 0x%x\n",uti596_softc.scb.rcvdt_err))
    2409   printk(("short_err 0x%x\n",uti596_softc.scb.short_err))
    2410   printk(("t_on 0x%x\n",uti596_softc.scb.t_on))
    2411   printk(("t_off 0x%x\n",uti596_softc.scb.t_off))
    2412 }
    2413 
    2414 
    2415 #ifdef DBG_INIT_3
    2416 
    2417  /***********************************************************************
    2418   **
    2419   **                                                                                    Debugging Functions
    2420   **
    2421   ***********************************************************************/
    2422 
    2423 
    2424  /***********************************************************************
    2425   *  Function:   print_eth
    2426   *
    2427   *  Description:
    2428   *              Print the contents of an ethernet packet header
    2429   *              CANNOT BE CALLED FROM ISR
    2430   *
    2431   *  Algorithm:
    2432   *            Print Destination, Src, and type of packet
    2433   *
    2434   ***********************************************************************/
    2435 
    2436 /* static */ void print_eth(
     2623
     2624void uti596_stats(
     2625  uti596_softc_ *sc
     2626)
     2627{
     2628  printf ("CPU Reports:\n");
     2629  printf ("  Tx raw send count:%-8lu",  sc->rawsndcnt);
     2630  printf ("  Rx Interrupts:%-8lu",  sc->rxInterrupts);
     2631  printf ("  Tx Interrupts:%-8lu\n",  sc->txInterrupts);
     2632  printf ("  Rx Packets:%-8u",  sc->stats.rx_packets);
     2633  printf ("  Tx Attempts:%-u\n",  sc->stats.tx_packets);
     2634
     2635  printf ("  Rx Dropped:%-8u",  sc->stats.rx_dropped);
     2636  printf ("  Rx IP Packets:%-8u",  sc->stats.rx_packets);
     2637  printf ("  Tx Errors:%-8u\n",  sc->stats.tx_errors);
     2638  printf ("  Tx aborted:%-8u",  sc->stats.tx_aborted_errors);
     2639  printf ("  Tx Dropped:%-8u\n",  sc->stats.tx_dropped);
     2640  printf ("  Tx IP packets:%-8u",  sc->stats.tx_packets);
     2641
     2642  printf ("  Collisions Detected:%-8u\n",  sc->stats.collisions);
     2643  printf ("  Tx Heartbeat Errors:%-8u",  sc->stats.tx_heartbeat_errors);
     2644  printf ("  Tx Carrier Errors:%-8u\n",  sc->stats.tx_carrier_errors);
     2645  printf ("  Tx Aborted Errors:%-8u",  sc->stats.tx_aborted_errors);
     2646  printf ("  Rx Length Errors:%-8u\n",  sc->stats.rx_length_errors);
     2647  printf ("  Rx Overrun Errors:%-8u",  sc->stats.rx_over_errors);
     2648  printf ("  Rx Fifo Errors:%-8u\n",  sc->stats.rx_fifo_errors);
     2649  printf ("  Rx Framing Errors:%-8u",  sc->stats.rx_frame_errors);
     2650  printf ("  Rx crc errors:%-8u\n",  sc->stats.rx_crc_errors);
     2651
     2652  printf ("  TX WAITS: %-8lu\n",  sc->txRawWait);
     2653
     2654  printf ("  NIC resets: %-8u\n",  sc->stats.nic_reset_count);
     2655
     2656  printf ("  NIC reports\n");
     2657
     2658        #ifdef DBG_STAT
     2659  uti596_dump_scb();
     2660  #endif
     2661}
     2662
     2663
     2664
     2665
     2666/************************ PACKET DEBUG ROUTINES ************************/
     2667
     2668#ifdef DBG_PACKETS
     2669
     2670/*
     2671 *  dumpQ
     2672 *
     2673 *  Dumps frame queues for debugging
     2674 */
     2675static void dumpQ( void )
     2676{
     2677  i596_rfd *pRfd;
     2678
     2679  printk(("savedQ:\n"))
     2680 
     2681  for( pRfd = uti596_softc.pSavedRfdQueue;
     2682       pRfd != I596_NULL;
     2683       pRfd = pRfd -> next) {
     2684      printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
     2685  }
     2686     
     2687  printk(("Inbound:\n"))
     2688 
     2689  for( pRfd = uti596_softc.pInboundFrameQueue;
     2690       pRfd != I596_NULL;
     2691       pRfd = pRfd -> next) {
     2692    printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
     2693  }
     2694   
     2695  printk(("Last Unk: %p\n", uti596_softc.pLastUnkRFD ))
     2696  printk(("RFA:\n"))
     2697 
     2698  for( pRfd = uti596_softc.pBeginRFA;
     2699       pRfd != I596_NULL;
     2700       pRfd = pRfd -> next) {
     2701    printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
     2702  }
     2703}
     2704
     2705
     2706/*
     2707 *  show_buffers
     2708 * 
     2709 *  Print out the RFA and frame queues
     2710 */
     2711static void show_buffers (void)
     2712{
     2713  i596_rfd *pRfd;
     2714
     2715  printk(("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
     2716         uti596_softc.scb.command,
     2717         uti596_softc.scb.status,
     2718         uti596_softc.countRFD))
     2719
     2720  printk(("\nRFA: \n"))
     2721 
     2722  for ( pRfd = uti596_softc.pBeginRFA;
     2723        pRfd != I596_NULL;
     2724        pRfd = pRfd->next) {
     2725    printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
     2726            pRfd, pRfd->stat, pRfd->cmd))
     2727        }
     2728  printk(("\nInbound: \n"))
     2729 
     2730  for ( pRfd = uti596_softc.pInboundFrameQueue;
     2731        pRfd != I596_NULL;
     2732        pRfd = pRfd->next) {
     2733    printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
     2734            pRfd, pRfd->stat, pRfd->cmd))
     2735        }
     2736
     2737  printk(("\nSaved: \n"))
     2738 
     2739  for ( pRfd = uti596_softc.pSavedRfdQueue;
     2740        pRfd != I596_NULL;
     2741        pRfd = pRfd->next) {
     2742    printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
     2743             pRfd, pRfd->stat, pRfd->cmd))
     2744  }
     2745           
     2746  printk(("\nUnknown: %p\n",uti596_softc.pLastUnkRFD))
     2747}
     2748
     2749
     2750/*
     2751 *  show_queues
     2752 *
     2753 *  Print out the saved frame queue and the RFA
     2754 */
     2755static void show_queues(void)
     2756{
     2757  i596_rfd *pRfd;
     2758
     2759  printk(("CMD: 0x%x, Status: 0x%x\n",
     2760         uti596_softc.scb.command,
     2761         uti596_softc.scb.status))
     2762  printk(("saved Q\n"))
     2763
     2764  for ( pRfd = uti596_softc.pSavedRfdQueue;
     2765        pRfd != I596_NULL &&
     2766        pRfd != NULL;
     2767        pRfd = pRfd->next) {
     2768    printk(("0x%p\n", pRfd))
     2769  }
     2770
     2771  printk(("End saved Q 0x%p\n", uti596_softc.pEndSavedQueue))
     2772
     2773  printk(("\nRFA:\n"))
     2774 
     2775  for ( pRfd = uti596_softc.pBeginRFA;
     2776        pRfd != I596_NULL &&
     2777        pRfd != NULL;
     2778        pRfd = pRfd->next) {
     2779    printk(("0x%p\n", pRfd))
     2780  }
     2781
     2782  printk(("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA))
     2783}
     2784
     2785
     2786/*
     2787 *  print_eth
     2788 *
     2789 *  Print the contents of an ethernet packet
     2790 *  CANNOT BE CALLED FROM ISR
     2791 */
     2792static void print_eth(
    24372793  unsigned char *add
    24382794)
     
    24462802  for (i = 0; i < 6; i++) {
    24472803    printk ((" %2.2X", add[i]))
    2448         }
     2804        }
    24492805  printk (("\n"))
    24502806  printk (("Source"))
    24512807
    24522808  for (i = 6; i < 12; i++) {
    2453         printk ((" %2.2X", add[i]))
     2809        printk ((" %2.2X", add[i]))
    24542810  }
    24552811 
     
    24682824    for ( i=0; i< 5 ; i++) {
    24692825      printk (("%x:", add[22 + i]))
    2470                 }
     2826                }
    24712827    printk (("%x\n", add[27]))
    24722828    printk (("Sender IP addr: "))
     
    24742830    for ( i=0; i< 3 ; i++) {
    24752831      printk (("%u.", add[28 + i]))
    2476                 }
     2832                }
    24772833    printk (("%u\n", add[31]))
    24782834    printk (("Target Enet addr: "))
     
    24802836    for ( i=0; i< 5 ; i++) {
    24812837      printk (( "%x:", add[32 + i]))
    2482                 }
     2838                }
    24832839    printk (("%x\n", add[37]))
    24842840    printk (("Target IP addr: "))
     
    24902846  }
    24912847
    2492   if ( add[12] == 0x08 && add[13] == 0x00 ) { /* an IP packet */
     2848
     2849  if ( add[12] == 0x08 && add[13] == 0x00 ) {
     2850        /* an IP packet */
    24932851    printk (("*********************IP HEADER******************\n"))
    24942852    printk (("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15]))
     
    25032861    for ( i=0; i< 3 ; i++) {
    25042862      printk (("%u.", add[26 + i]))
    2505                 }
     2863    }
    25062864    printk (("%u\n", add[29]))
    25072865    printk (("Destination IP address: "))
     
    25092867    for ( i=0; i< 3 ; i++) {
    25102868      printk (("%u.", add[30 + i]))
    2511                 }
     2869    }
    25122870    printk (("%u\n", add[33]))
    2513     /* printk(("********************IP Packet Data*******************\n"))
    2514     length -=20;
    2515     for ( i=0; i < length ; i++) {
    2516       printk(("0x%2.2x ", add[34+i]))
    2517     }
    2518     printk(("\n"))
    2519 
    2520     printk(("ICMP checksum: %2.2x %2.2x\n", add[36], add[37]))
    2521     printk(("ICMP identifier: %2.2x %2.2x\n", add[38], add[39]))
    2522     printk(("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41]))
    2523     */
    2524   }
    2525 }
    2526 
    2527  /***********************************************************************
    2528   *  Function:   print_hdr
    2529   *
    2530   *  Description:
    2531   *              Print the contents of an ethernet packet header
    2532   *              CANNOT BE CALLED FROM ISR
    2533   *
    2534   *  Algorithm:
    2535   *            Print Destination, Src, and type of packet
    2536   *
    2537   ***********************************************************************/
    2538 
    2539 /* static */ void print_hdr(
     2871  }
     2872}
     2873
     2874
     2875/*
     2876 *  print_hdr
     2877 *
     2878 *  Print the contents of an ethernet packet header
     2879 *  CANNOT BE CALLED FROM ISR
     2880 */
     2881static  void print_hdr(
    25402882  unsigned char *add
    25412883)
     
    25492891  for (i = 0; i < 6; i++) {
    25502892    printk ((" %2.2X", add[i]))
    2551         }
     2893        }
    25522894  printk (("\nSource"))
    25532895
    25542896  for (i = 6; i < 12; i++) {
    25552897    printk ((" %2.2X", add[i]))
    2556         }
     2898        }
    25572899  printk (("\nframe type %2.2X%2.2X\n", add[12], add[13]))
    25582900  printk (("print_hdr: completed"))
    25592901}
    25602902
    2561  /***********************************************************************
    2562   *  Function:   print_pkt
    2563   *
    2564   *  Description:
    2565   *              Print the contents of an ethernet packet header
    2566   *              CANNOT BE CALLED FROM ISR
    2567   *
    2568   *  Algorithm:
    2569   *            Print Destination, Src, and type of packet
    2570   *
    2571   ***********************************************************************/
    2572 
    2573 /* static */ void print_pkt(
     2903
     2904/*
     2905 *  Function:   print_pkt
     2906 *
     2907 *  Print the contents of an ethernet packet & data
     2908 *  CANNOT BE CALLED FROM ISR
     2909 */
     2910static void print_pkt(
    25742911  unsigned char *add
    25752912)
     
    25922929    for ( i=0; i< 5 ; i++) {
    25932930      printk (( "%x:", add[22 + i]))
    2594                 }
     2931                }
    25952932    printk (("%x\n", add[27]))
    25962933    printk (("Sender IP addr: "))
     
    25982935    for ( i=0; i< 3 ; i++) {
    25992936      printk (("%u.", add[28 + i]))
    2600                 }
     2937                }
    26012938    printk (("%u\n", add[31]))
    26022939    printk (("Target Enet addr: "))
    26032940   
    26042941    for ( i=0; i< 5 ; i++) {
    2605       printk (( "%x:", add[32 + i]))   
     2942      printk (( "%x:", add[32 + i]))   
    26062943    }
    26072944    printk (("%x\n", add[37]))
     
    26282965    for ( i=0; i< 3 ; i++) {
    26292966      printk(( "%u.", add[26 + i]))
    2630                 }
     2967                }
    26312968    printk(("%u\n", add[29]))
    26322969    printk(("Destination IP address: "))
     
    26502987}
    26512988
    2652  /***********************************************************************
    2653   *  Function:   print_echo
    2654   *
    2655   *  Description:
    2656   *              Print the contents of an ethernet packet header
    2657   *              CANNOT BE CALLED FROM ISR
    2658   *
    2659   *  Algorithm:
    2660   *            Prints only echo packets
    2661   *
    2662   ***********************************************************************/
    2663 
    2664 /* static */ void print_echo(
     2989
     2990/*
     2991 *  print_echo
     2992 *
     2993 *  Print the contents of an echo packet
     2994 *  CANNOT BE CALLED FROM ISR
     2995 */
     2996static void print_echo(
    26652997  unsigned char *add
    26662998)
     
    26783010    for (i = 0; i < 6; i++) {
    26793011      printk ((" %2.2X", add[i]))
    2680                 }
     3012                }
    26813013    printk (("\n"))
    26823014    printk (("Source"))
     
    26843016    for (i = 6; i < 12; i++) {
    26853017      printk ((" %2.2X", add[i]))
    2686                 }
     3018                }
    26873019    printk (("\n"))
    26883020    printk (("frame type %2.2X%2.2X\n", add[12], add[13]))
     
    27003032    for ( i=0; i< 3 ; i++) {
    27013033      printk (("%u.", add[26 + i]))
    2702                 }
     3034                }
    27033035    printk (("%u\n", add[29]))
    27043036    printk (("Destination IP address: "))
     
    27133045    for ( i=0; i < length ; i++) {
    27143046      printk(("0x%2.2x ", add[34+i]))
    2715                 }
     3047                }
    27163048    printk(("\n"))
    27173049    printk(("ICMP checksum: %2.2x %2.2x\n", add[36], add[37]))
     
    27233055
    27243056#endif
    2725 
    2726 /***********************************************************************
    2727  *  Function:   uti596dump
    2728  *
    2729  *  Description: Dump 596 registers
    2730  *
    2731  *  Algorithm:
    2732  ***********************************************************************/
    2733 /* static */ int uti596dump(
    2734   char * pDumpArea
    2735 )
    2736 {
    2737   i596_dump dumpCmd;
    2738   int boguscnt = 25000000; /* over a second! */
    2739 
    2740 #ifdef DBG_596
    2741   printk(("uti596dump: begin\n"))
    2742 #endif
    2743 
    2744   dumpCmd.cmd.command = CmdDump;
    2745   dumpCmd.cmd.next    = I596_NULL;
    2746   dumpCmd.pData       = pDumpArea;
    2747   uti596_softc.cmdOk = 0;
    2748   uti596addCmd        ( (i596_cmd *)&dumpCmd);
    2749   while (1) {
    2750     if ( --boguscnt == 0) {
    2751       printk(("Dump command was not processed within spin loop delay\n"))
    2752       return 0;
    2753     }
    2754     else {
    2755       if ( uti596_softc.cmdOk ) {
    2756         return 1; /* successful completion */
    2757       }
    2758     }
    2759   }
    2760 }
    2761 
    2762 /***********************************************************************
    2763  *  Function:   void dumpQ
    2764  *
    2765  *  Description:
    2766  ***********************************************************************/
    2767 void dumpQ( void )
    2768 {
    2769   i596_rfd *pRfd;
    2770 
    2771   printk(("savedQ:\n"))
    2772  
    2773   for( pRfd = uti596_softc.pSavedRfdQueue;
    2774        pRfd != I596_NULL;
    2775        pRfd = pRfd -> next) {
    2776       printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
    2777   }
    2778      
    2779   printk(("Inbound:\n"))
    2780  
    2781   for( pRfd = uti596_softc.pInboundFrameQueue;
    2782        pRfd != I596_NULL;
    2783        pRfd = pRfd -> next) {
    2784     printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
    2785   }
    2786    
    2787   printk(("Last Unk: %p\n", uti596_softc.pLastUnkRFD ))
    2788   printk(("RFA:\n"))
    2789  
    2790   for( pRfd = uti596_softc.pBeginRFA;
    2791        pRfd != I596_NULL;
    2792        pRfd = pRfd -> next) {
    2793     printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
    2794   }
    2795 }
    2796 
    2797 
    2798 /***********************************************************************
    2799  *  Function:   void show_buffers
    2800  *
    2801  *  Description:
    2802  ***********************************************************************/
    2803 void show_buffers (void)
    2804 {
    2805   i596_rfd *pRfd;
    2806 
    2807   printk(("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
    2808          uti596_softc.scb.command,
    2809          uti596_softc.scb.status,
    2810          uti596_softc.countRFD))
    2811 
    2812   printk(("\nRFA: \n"))
    2813  
    2814   for ( pRfd = uti596_softc.pBeginRFA;
    2815         pRfd != I596_NULL;
    2816         pRfd = pRfd->next) {
    2817     printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
    2818             pRfd, pRfd->stat, pRfd->cmd))
    2819         }
    2820   printk(("\nInbound: \n"))
    2821  
    2822   for ( pRfd = uti596_softc.pInboundFrameQueue;
    2823         pRfd != I596_NULL;
    2824         pRfd = pRfd->next) {
    2825     printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
    2826             pRfd, pRfd->stat, pRfd->cmd))
    2827         }
    2828 
    2829   printk(("\nSaved: \n"))
    2830  
    2831   for ( pRfd = uti596_softc.pSavedRfdQueue;
    2832         pRfd != I596_NULL;
    2833         pRfd = pRfd->next) {
    2834     printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
    2835              pRfd, pRfd->stat, pRfd->cmd))
    2836   }
    2837            
    2838   printk(("\nUnknown: %p\n",uti596_softc.pLastUnkRFD))
    2839 }
    2840 
    2841 /***********************************************************************
    2842  *  Function:   void show_queues
    2843  *
    2844  *  Description:
    2845  ***********************************************************************/
    2846 void show_queues(void)
    2847 {
    2848   i596_rfd *pRfd;
    2849 
    2850   printk(("CMD: 0x%x, Status: 0x%x\n",
    2851          uti596_softc.scb.command,
    2852          uti596_softc.scb.status))
    2853   printk(("saved Q\n"))
    2854 
    2855   for ( pRfd = uti596_softc.pSavedRfdQueue;
    2856         pRfd != I596_NULL &&
    2857         pRfd != NULL;
    2858         pRfd = pRfd->next) {
    2859     printk(("0x%p\n", pRfd))
    2860   }
    2861 
    2862   printk(("End saved Q 0x%p\n", uti596_softc.pEndSavedQueue))
    2863 
    2864   printk(("\nRFA:\n"))
    2865  
    2866   for ( pRfd = uti596_softc.pBeginRFA;
    2867         pRfd != I596_NULL &&
    2868         pRfd != NULL;
    2869         pRfd = pRfd->next) {
    2870     printk(("0x%p\n", pRfd))
    2871   }
    2872 
    2873   printk(("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA))
    2874 }
    2875 
    2876  /***********************************************************************
    2877   *  Function:   word_swap
    2878   *
    2879   *  Description:
    2880   *              Return a 32 bit value, swapping the upper
    2881   *                                                      and lower words first.
    2882   *
    2883   ***********************************************************************/
    2884 unsigned long word_swap (unsigned long val)
    2885 {
    2886   return (((val >> 16)&(0x0000ffff)) | ((val << 16)&(0xffff0000)));
    2887 }
    2888 
    2889 
Note: See TracChangeset for help on using the changeset viewer.