source: rtems/c/src/lib/libbsp/i386/i386ex/network/network.c @ ce337500

4.104.114.84.95
Last change on this file since ce337500 was 844de99, checked in by Joel Sherrill <joel.sherrill@…>, on 11/04/02 at 14:27:49

2002-11-04 Joel Sherrill <joel@…>

  • console/console.c, network/network.c: Removed warnings.
  • Property mode set to 100644
File size: 73.8 KB
Line 
1/* uti595.c: An 82596 ethernet driver for rtems-bsd.
2 *
3 *  $Id$
4 */
5
6void dump_scb(void);
7void printk_time(void);
8
9#ifdef DBG_VERSION
10#define BREAKPOINT()  asm("   int $3");
11#else
12#define BREAKPOINT()
13#endif
14
15#define KERNEL
16
17
18/*
19   
20  EII: Oct 16 : Version 0.0
21
22*/
23
24#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
25#define DMA_MASK_REG     0x0A
26#define DMA_MODE_REG     0x0B
27#define DMA_ENABLE       0x0
28#define DMA_DISABLE      0x4   
29
30struct i596_rfd *pISR_Rfd; 
31
32void show_buffers (void);
33void show_queues(void);
34
35void outbyte(char);
36void dumpQ(void);
37
38#define UTI_596_ASSERT( condition, str ) { if (!( condition ) ) printk(str); }
39int count_rx = 0;
40
41/* static char *version = "uti596.c:v0.0 11/13/97\n"; */
42
43#include <bsp.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <rtems/error.h>
47#include <rtems/rtems_bsdnet.h>
48
49#include <sys/param.h>
50#include <sys/mbuf.h>
51#include <sys/socket.h>
52#include <sys/sockio.h>
53
54#include <net/if.h>
55
56#include <netinet/in.h>
57#include <netinet/if_ether.h>
58
59#include "uti596.h"
60#include "netexterns.h"
61
62#include <asm.h>
63#include <string.h>
64
65
66/* #include "../misc/utils.h" */
67
68static struct uti596_softc uti596_softc;
69
70
71static    int scbStatus;
72static    struct i596_cmd *pIsrCmd;
73static    struct i596_rfd *pIsrRfd;
74
75/*
76 * Initial 596 configuration
77 */
78char uti596initSetup[] = {
79        0x0E,   /* length, prefetch off ( no RBD's ) */
80        0xC8,   /* fifo to 8, monitor off */
81        0x40,   /* don't save bad frames ( was save= 80, use intel's 40 )*/
82        0x2E,   /* No source address insertion, 8 byte preamble */
83        0x00,   /* priority and backoff defaults */
84        0x60,   /* interframe spacing */
85        0x00,   /* slot time LSB */
86        0xf2,   /* slot time and retries */
87        0x0C,   /* */
88        0x08,   /* collision detect */
89        0x40,   /* minimum frame length */
90        0xfb,   /* tried C8 same as byte 1 in bits 6-7, else ignored*/
91        0x00,
92        0x3f    /*  no multi IA */ };
93/*
94 *  Externally defined symbols
95 */
96#define RX_BUF_COUNT     15
97#define TX_BUF_COUNT     4
98#define TX_BD_PER_BUF    4
99
100#define INTERRUPT_EVENT         RTEMS_EVENT_1
101#define START_TRANSMIT_EVENT    RTEMS_EVENT_2
102#define NIC_RESET_EVENT         RTEMS_EVENT_3
103
104#define RBUF_SIZE       1520
105
106
107/*
108 * Local Routines
109 */
110
111/* These are extern, and non-inline  for testing purposes */
112
113void        uti596addCmd                  (struct i596_cmd *pCmd);
114void        uti596_initMem                (struct uti596_softc *);
115void        uti596_init                   (void * );
116int         uti596initRxBufs              (int num);
117int         uti596_initRFA                (int num);
118int         uti596initRxBufs              (int num);
119static int  uti596_ioctl                  (struct ifnet *, int, caddr_t);
120rtems_isr   uti596DynamicInterruptHandler (rtems_vector_number);
121
122void        uti596_txDaemon               (void *);
123void        uti596_rxDaemon               (void *);
124void        uti596_resetDaemon            (void *);
125
126void        uti596_stop                   (struct uti596_softc *);
127static void uti596_start                  (struct ifnet *);
128
129void        uti596reset            (void);
130
131void         uti596_stats      (struct uti596_softc *);
132
133void uti596_initialize_hardware(struct uti596_softc *);
134void uti596_reset_hardware(struct uti596_softc *);
135
136void uti596clearListStatus(struct i596_rfd *);
137void uti596addPolledCmd(struct i596_cmd *);
138
139void uti596supplyFD(struct i596_rfd *);
140
141struct i596_rfd * uti596dequeue( struct i596_rfd ** );
142void uti596append( struct i596_rfd ** , struct i596_rfd * );
143
144#ifdef DEBUG_INIT
145static void         print_eth              (unsigned char *);
146static void         print_hdr              (unsigned char *);
147static void         print_pkt              (unsigned char *);
148#endif
149
150void send_packet(struct ifnet *, struct mbuf *);
151
152#define UTI_596_IRQ 5
153#define UTI_596_ETH_MIN_SIZE 60
154
155/* Waits for the command word to clear.  The command word is cleared AFTER the interrupt is
156 * generated. This allows the CPU to issue the next command
157 */
158#define  UTI_WAIT_COMMAND_ACCEPTED(duration,function)\
159{   int waitcount = duration; \
160    while (  uti596_softc.scb.command ) \
161      if (--waitcount == 0) \
162        { \
163          printk("%s: i82596 timed out with status %x, cmd %x.\n", function, \
164                  uti596_softc.scb.status,  uti596_softc.scb.command); \
165          break; \
166        } \
167}
168/*************************************************************************/
169
170void
171uti596_request_reset(void){
172   rtems_status_code sc;
173
174   uti596_softc.nic_reset = 0;
175   sc = rtems_event_send(uti596_softc.resetDaemonTid, NIC_RESET_EVENT);
176   if ( sc != RTEMS_SUCCESSFUL )
177     rtems_panic ("Can't notify resetDaemon: %s\n", rtems_status_text (sc));
178}
179
180
181
182static void uti596_maskOn(const rtems_irq_connect_data* irq)
183{
184  /*
185   * code should be moved from initialize_hardware
186   * to this location ?
187   */
188  (void) BSP_irq_enable_at_i8259s (irq->name);
189}
190
191static void uti596_maskOff(const rtems_irq_connect_data* irq)
192{
193  /*
194   * code should be moved from initialize_hardware
195   * to this location ?
196   */
197  (void) BSP_irq_disable_at_i8259s (irq->name);
198}
199
200static int uti596_isOn(const rtems_irq_connect_data* irq)
201{
202  return BSP_irq_enabled_at_i8259s (irq->name);
203}
204
205
206/***********************************************************************
207 *  Function:   uti596initRFA(int num) ( New )
208 *
209 *  Description:
210 *              attempts to allocate and initialize ( chain together )
211 *              the requested number of FD's
212 *
213 *  Algorithm:
214 *
215 ***********************************************************************/
216
217
218int uti596_initRFA(int num)
219{
220    struct i596_rfd *pRfd;
221    int i = 0;
222
223
224#ifdef DBG_596
225    printf ("%s: uti596_initRFA %d.\n", num);
226#endif
227
228    /*
229     * Initialize the first rfd in the rfa
230     */
231    pRfd = (struct i596_rfd *) calloc (1,sizeof (struct i596_rfd));
232    if ( !pRfd ) {
233      printf("Can't allocate all buffers: only %d allocated\n", i);
234      return 0;
235    }
236    else {
237      uti596_softc.countRFD = 1;
238      uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
239    printf ( "First Rfd allocated is: %p\n",
240             uti596_softc.pBeginRFA);
241    }
242
243    for (i = 1; i < num; i++) {
244      pRfd = (struct i596_rfd *) calloc (1,sizeof (struct i596_rfd) );
245      if ( pRfd != NULL ) {
246        uti596_softc.countRFD++;
247        uti596_softc.pEndRFA -> next = pRfd; /* link it in   */   
248        uti596_softc.pEndRFA         = pRfd; /* move the end */
249#ifdef DBG_596_RFA
250        printf("Allocated RFD @ %p\n", pRfd);
251#endif
252      }
253      else {   
254        printf("Can't allocate all buffers: only %d allocated\n", i);
255        break;
256      }
257    } /* end for */
258   
259    uti596_softc.pEndRFA -> next = I596_NULL;
260    UTI_596_ASSERT(uti596_softc.countRFD == RX_BUF_COUNT,"INIT:WRONG RFD COUNT\n" );
261   
262#ifdef DBG_596_RFA
263    printf ( "Head of RFA is buffer %p\nEnd of RFA is buffer %p \n",
264             uti596_softc.pBeginRFA,
265             uti596_softc.pEndRFA );
266#endif
267    /* initialize the Rfd's */
268    for ( pRfd = uti596_softc.pBeginRFA;
269          pRfd != I596_NULL;
270          pRfd = pRfd -> next ) {
271         
272      pRfd->cmd = 0x0000;
273      pRfd->stat = 0x0000;
274      pRfd->pRbd =  I596_NULL;
275      pRfd->count = 0;  /* number of bytes in buffer: usually less than size */
276      pRfd->size = 1532;      /* was 1532;  buffer size ( All RBD ) */
277      if ( pRfd -> data == NULL )
278        printf("Can't allocate the RFD data buffer\n");
279    }
280
281    /* mark the last FD */
282    uti596_softc.pEndRFA -> cmd = CMD_EOL; /* moved jan 13 from before the init stuff */
283
284#ifdef DBG_596_RFA
285    printf ( "Head of RFA is buffer @ %p \n", uti596_softc.pBeginRFA );
286#endif
287
288
289    uti596_softc.pSavedRfdQueue =
290      uti596_softc.pEndSavedQueue = I596_NULL;   /* initially empty */
291   
292    uti596_softc.savedCount = 0;
293
294    uti596_softc.nop.cmd.command = CmdNOp; /* initialize the nop command */
295
296    return (i); /* the number of allocated buffers */
297   
298}
299/***********************************************************************
300 *  Function:   uti596supplyFD
301 *
302 *  Description: returns a buffer to the receive frame pool.
303 *               call this with Inetrrupts disabled!
304 *
305 *  Algorithm:
306 *
307 ***********************************************************************/
308void uti596supplyFD(struct i596_rfd * pRfd )
309{
310 struct i596_rfd *pLastRfd;
311
312
313 UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD!\n");
314 pRfd -> cmd  = CMD_EOL;
315 pRfd -> pRbd = I596_NULL;
316 pRfd -> next = I596_NULL;
317 pRfd -> stat = 0x0000;      /* clear STAT_C and STAT_B bits */
318
319 /*
320  * Check if the list is empty:
321  */
322 if ( uti596_softc.pBeginRFA == I596_NULL ) { 
323   /* Init a list w/ one entry */
324   uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd;
325   UTI_596_ASSERT(uti596_softc.countRFD == 0, "Null begin, but non-zero count\n");
326   if ( uti596_softc.pLastUnkRFD != I596_NULL )
327     printf("LastUnkRFD is NOT NULL!!\n");
328   uti596_softc.countRFD = 1;
329   return;
330 }
331 /*
332  * Check if the last RFD is used/read by the 596.
333  */
334 pLastRfd = uti596_softc.pEndRFA;
335 
336 if (    pLastRfd != I596_NULL &&
337      ! (pLastRfd -> stat & ( STAT_C | STAT_B ) )) { /* C = complete, B = busy (prefetched) */
338   
339   /*
340    * Not yet too late to add it
341    */
342   pLastRfd -> next = pRfd;
343   pLastRfd -> cmd &= ~CMD_EOL;  /* RESET_EL : reset EL bit to 0  */
344   uti596_softc.countRFD++;  /* Lets assume we add it successfully
345                                If not, the RFD may be used, and may decrement countRFD < 0 !!*/
346   /*
347    * Check if the last RFD was used while appending.
348    */
349   if ( pLastRfd -> stat & ( STAT_C | STAT_B ) ) { /* completed or was prefetched */
350     /*
351      * Either the EL bit of the last rfd has been read by the 82596,
352      * and it will stop after reception,( true when RESET_EL not reached ) or
353      * the EL bit was NOT read by the 82596 and it will use the linked
354      * RFD for the next reception. ( true is RESET_EL was reached )
355      * So, it is unknown whether or not the linked rfd will be used.
356      * Therefore, the end of list CANNOT be updated.
357      */
358     UTI_596_ASSERT ( uti596_softc.pLastUnkRFD == I596_NULL, "Too many Unk RFD's\n" );
359     uti596_softc.pLastUnkRFD = pRfd;             
360     return;
361   }
362   else {
363     /*
364      * The RFD being added was not touched by the 82596
365      */
366     if (uti596_softc.pLastUnkRFD != I596_NULL ) {
367   
368       uti596append(&uti596_softc.pSavedRfdQueue, pRfd); /* Only here! saved Q */
369       uti596_softc.pEndSavedQueue = pRfd;
370       uti596_softc.savedCount++;
371       uti596_softc.countRFD--;
372       
373     }
374     else {
375       uti596_softc.pEndRFA = pRfd;           /* the RFA has been extended */
376       if ( ( uti596_softc.scb.status & SCB_STAT_RNR ||
377              uti596_softc.scb.status & RU_NO_RESOURCES ) &&
378            uti596_softc.countRFD > 1 ) {   /* was == 2 */
379         uti596_softc.pBeginRFA -> cmd &= ~CMD_EOL;  /* Ensure that beginRFA is not EOL */
380         
381         UTI_596_ASSERT(uti596_softc.pEndRFA -> next == I596_NULL, "supply: List buggered\n");
382         UTI_596_ASSERT(uti596_softc.pEndRFA -> cmd & CMD_EOL, "supply: No EOL at end.\n");
383         UTI_596_ASSERT(uti596_softc.scb.command == 0, "Supply: scb command must be zero\n");
384#ifdef DBG_START
385         printf("Supply FD: starting receiver");
386#endif
387         /* start the receiver */
388         UTI_596_ASSERT(uti596_softc.pBeginRFA != I596_NULL, "rx start w/ NULL begin! \n");
389         uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
390         uti596_softc.scb.command = RX_START | SCB_STAT_RNR;  /* Don't ack RNR! The receiver should be stopped in this case */
391         UTI_596_ASSERT( !(uti596_softc.scb.status & SCB_STAT_FR),"FRAME RECEIVED INT COMING!\n");
392         outport_byte(CHAN_ATTN, 0);
393       }
394     }
395     return;
396     
397   }
398 }
399 else {
400   /*
401    * too late , pLastRfd in use ( or NULL ),
402    * in either case, EL bit has been read, and RNR condition will occur
403    */
404   uti596append( &uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */
405   
406   uti596_softc.pEndSavedQueue = pRfd;                /* reset end of saved queue */ 
407   uti596_softc.savedCount++;
408   
409   
410   return;
411 }
412}
413
414static void
415uti596_start (struct ifnet *ifp)
416{
417        struct uti596_softc *sc = ifp->if_softc;
418
419        rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
420        ifp->if_flags |= IFF_OACTIVE;
421}
422
423void
424uti596_initialize_hardware(struct uti596_softc *sc)
425{
426  int boguscnt = 1000;
427  rtems_status_code status_code;
428
429  printf("uti596_initialize_hardware\n");
430 
431  /* reset the board  */
432  outport_word( PORT_ADDR, 0 );
433  outport_word( PORT_ADDR, 0 );
434
435  uti596_softc.pScp = (struct i596_scp *) calloc(1,sizeof(struct i596_scp) + 0xf);
436#ifdef DBG_INIT
437  printf("initialize_hardware:Scp address initially %p\n", sc->pScp);
438#endif
439  sc->pScp = (struct i596_scp *)
440    ((((int)uti596_softc.pScp) + 0xf) & 0xfffffff0);
441
442#ifdef DBG_INIT
443  printf("initialize_hardware:change scp address to : %p\n",sc->pScp);
444#endif
445 
446  /* change the scp address */
447#ifdef DBG_INIT
448  printf("Change the SCP address\n");
449#endif
450 
451  /*
452   * Set the DMA mode to enable the 82596 to become a bus-master
453   */
454  outport_byte(DMA_MASK_REG,DMA_DISABLE);      /* disable_dma */
455  outport_byte(DMA_MODE_REG,DMA_MODE_CASCADE); /* set dma mode */
456  outport_byte(DMA_MASK_REG,DMA_ENABLE);       /* enable dma */
457
458  /* reset the board  */
459  outport_word( PORT_ADDR, 0 );
460  outport_word( PORT_ADDR, 0 );
461 
462  outport_word(PORT_ADDR, ((((int)sc->pScp) &  0xffff) | 2 ));
463  outport_word(PORT_ADDR, (( (int)sc->pScp) >> 16 ) & 0xffff );
464 
465  /* This is linear mode, LOCK function is disabled  */
466 
467  sc->pScp->sysbus = 0x00540000;
468  sc->pScp->iscp   = &sc->iscp;
469  sc->iscp.scb     = &sc->scb;
470  sc->iscp.stat    = 0x0001;
471 
472  sc->pCmdHead     = sc->scb.pCmd = I596_NULL;
473 
474#ifdef DBG_596
475  printf("Starting i82596.\n");
476#endif
477 
478  /* Pass the scb address to the 596 */
479  outport_word(CHAN_ATTN,0);
480 
481  while (sc->iscp.stat)
482    if (--boguscnt == 0)
483      {
484        printf("initialize_hardware: timed out with status %4.4lx\n",
485               sc->iscp.stat );
486        break;
487      }
488 
489  /* clear the command word */
490  sc->scb.command = 0;
491     
492  /*
493   * Set up interrupts ( NEW irq style )
494   */
495  sc->irqInfo.name = UTI_596_IRQ;
496  sc->irqInfo.hdl  = ( void * ) uti596DynamicInterruptHandler;
497  sc->irqInfo.on   = uti596_maskOn;
498  sc->irqInfo.off  = uti596_maskOff;
499  sc->irqInfo.isOn = uti596_isOn;
500 
501  status_code = BSP_install_rtems_irq_handler (&sc->irqInfo);
502  if (!status_code)
503    rtems_panic ("Can't attach uti596 interrupt handler for irq %d\n",
504                  sc->irqInfo.name);
505
506  /* Initialize the 82596 memory ( Transmit buffers ) */
507  uti596_initMem(sc);
508 
509#ifdef DBG_INIT
510  printf("After attach, status of board = 0x%x\n", sc->scb.status );
511#endif
512  outport_word(0x380, 0xf); /* reset the LED's */
513}
514
515
516void
517uti596_reset_hardware(struct uti596_softc *sc)
518{
519  int boguscnt = 1000;
520  rtems_status_code status_code;
521  struct i596_cmd *pCmd;
522 
523
524  printf("uti596_reset_hardware\n");
525  pCmd = sc->pCmdHead;  /* This is a tx command for sure (99.99999%)  */
526 
527  /* reset the board  */
528  outport_word( PORT_ADDR, 0 );
529  outport_word( PORT_ADDR, 0 );
530
531  if ( sc->pScp == NULL ) {
532    printf("Calloc scp\n");
533    uti596_softc.pScp = (struct i596_scp *) calloc(1,sizeof(struct i596_scp) + 0xf);
534  }
535
536#ifdef DBG_RESET
537  printf("reset_hardware:Scp address %p\n", sc->pScp);
538#endif
539  sc->pScp = (struct i596_scp *)
540    ((((int)uti596_softc.pScp) + 0xf) & 0xfffffff0);
541 
542#ifdef DBG_RESET
543  printf("reset_hardware:change scp address to : %p\n",sc->pScp);
544#endif
545
546 
547  /* change the scp address */
548#ifdef DBG_RESET
549  printf("Change the SCP address\n");
550#endif
551 
552  /*
553   * Set the DMA mode to enable the 82596 to become a bus-master
554   */
555  outport_byte(DMA_MASK_REG,DMA_DISABLE);      /* disable_dma */
556  outport_byte(DMA_MODE_REG,DMA_MODE_CASCADE); /* set dma mode */
557  outport_byte(DMA_MASK_REG,DMA_ENABLE);       /* enable dma */
558
559  /* reset the board  */
560  outport_word( PORT_ADDR, 0 );
561  outport_word( PORT_ADDR, 0 );
562 
563  /*  outport_word(PORT_ADDR, ((((int)uti596_softc.pScp) &  0xffff) | 2 ));
564  outport_word(PORT_ADDR, (( (int)uti596_softc.pScp) >> 16 ) & 0xffff ); */
565 
566  outport_word(PORT_ADDR, ((((int)sc->pScp) &  0xffff) | 2 ));
567  outport_word(PORT_ADDR, (( (int)sc->pScp) >> 16 ) & 0xffff );
568 
569  /* This is linear mode, LOCK function is disabled  */
570 
571  sc->pScp->sysbus = 0x00540000;
572  sc->pScp->iscp   = &sc->iscp;
573  sc->iscp.scb     = &sc->scb;
574  sc->iscp.stat    = 0x0001;
575 
576  sc->pCmdHead     = sc->scb.pCmd = I596_NULL;
577  /*
578   * Wake the transmitter if needed.
579   */
580  if ( uti596_softc.txDaemonTid && pCmd != I596_NULL ){ 
581    printf("****RESET: wakes transmitter!\n");
582    status_code = rtems_event_send (uti596_softc.txDaemonTid,
583                           INTERRUPT_EVENT);
584   
585    if ( status_code != RTEMS_SUCCESSFUL )
586      printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",
587             uti596_softc.txDaemonTid, rtems_status_text (status_code) );
588  }
589 
590#ifdef DBG_596
591  printf("reset_hardware: starting i82596.\n");
592#endif
593 
594  /* Pass the scb address to the 596 */
595  outport_word(CHAN_ATTN,0);
596 
597  while (sc->iscp.stat)
598    if (--boguscnt == 0)
599      {
600        printf("reset_hardware: timed out with status %4.4lx\n",
601               sc->iscp.stat );
602        break;
603      }
604 
605  /* clear the command word */
606  sc->scb.command = 0;
607       
608#ifdef DBG_RESET
609  printf("After reset_hardware, status of board = 0x%x\n", sc->scb.status );
610#endif
611
612  outport_word(0x380, 0xf); /* reset the LED's */
613}
614
615
616/***********************************************************************
617 *  Function:   uti596_initMem
618 *
619 *  Description:
620 *             creates the necessary descriptors for the
621 *             uti596 board, hooks the interrupt, and starts the board.
622 *             Assumes that interrupts are hooked.
623 *
624 *  Algorithm:
625 *
626 ***********************************************************************/
627
628
629 void
630uti596_initMem(struct uti596_softc * sc)
631{
632    int i,count;
633    struct i596_tbd *pTbd;
634
635    sc->resetDone = 0; /* ??? */
636
637    /*
638     * Set up receive frame area (RFA)
639     */
640    i = uti596_initRFA( sc->rxBdCount );
641    if ( i < sc->rxBdCount  )
642      printf("init_rfd: only able to allocate %d receive frame descriptors\n", i);
643   
644    sc->scb.pRfd =  sc->pBeginRFA;
645
646#ifdef DBG_INIT
647    printf(" IRQ %d.\n", sc->irqInfo.name);
648#endif   
649   
650    /*
651     * Diagnose the health of the board
652     */
653    uti596Diagnose(1);
654
655    /*
656     * set up the i596 config command
657     */
658#ifdef DBG_INIT
659    printf("Configuring\n");
660#endif
661
662    sc->set_conf.cmd.command = CmdConfigure;
663    memcpy (sc->set_conf.data, uti596initSetup, 14);
664    uti596addPolledCmd( (struct i596_cmd *) &sc->set_conf);
665
666    /****
667    * POLL
668    ****/
669
670    count = 2000;
671    while( !( sc->set_conf.cmd.status & STAT_C ) && --count )
672      printf(".");
673
674    if ( count )
675      printf("Configure OK, count = %d\n",count);
676    else
677      printf("***Configure failed\n");
678
679    /*******/
680
681    /*
682     * Create the IA setup command
683     */
684
685#ifdef DBG_INIT
686    printf("Setting Address\n");
687#endif
688    sc->set_add.cmd.command = CmdSASetup;
689    for ( i=0; i<6; i++)
690      sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];
691
692    sc->cmdOk = 0;
693    uti596addPolledCmd((struct i596_cmd *)&sc->set_add);
694        /*******/
695   
696    count = 2000;
697    while( !(sc->set_add.cmd.status & STAT_C ) && --count)
698      printf(".");
699   
700    if ( count )
701      printf ("Set Address OK, count= %d\n",count);
702    else
703      printf("Set Address Failed\n");
704    /*******/
705
706#ifdef DBG_INIT
707    printf( "After initialization, status and command: 0x%x, 0x%x\n",
708            sc->scb.status, sc->scb.status);
709     
710#endif
711
712    /* initialize transmit buffer descriptors*/
713    sc->pLastUnkRFD = I596_NULL;
714    sc->pTxCmd         = (struct tx_cmd *) calloc (1,sizeof (struct tx_cmd) );
715    sc->pTbd           = (struct i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
716    sc->pTxCmd -> pTbd = sc->pTbd;
717    sc->pTxCmd->cmd.command  = CMD_FLEX|CmdTx;
718    sc->pTxCmd->pad          = 0;
719    sc->pTxCmd->size         = 0; /* all bytes are in list of TBD's */                         
720
721    pTbd = sc->pTbd;
722
723    for ( i=0; i<sc->txBdCount; i++)
724      pTbd = pTbd -> next = (struct i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
725     
726    pTbd -> next = I596_NULL;
727
728    memset ( &sc->zeroes, 0, 64);   
729
730#ifdef DBG_596
731    printf( "After receiver start, status and command: 0x%x, 0x%x\n",
732            sc->scb.status, sc->scb.status);
733#endif
734    printf("uti596_initMem allows ISR's\n");
735    sc->resetDone = 1; /* now need ISR  */
736
737}
738
739
740
741/***********************************************************************
742 *  Function:   uti596dump
743 *
744 *  Description: Dump 596 registers
745 *
746 *  Algorithm:
747 ***********************************************************************/
748/* static */ int
749uti596dump(char * pDumpArea)
750{
751  struct i596_dump dumpCmd;
752  int boguscnt = 25000000; /* over a second! */
753
754
755#ifdef DBG_596 
756printf("uti596dump:\n");
757#endif
758
759  dumpCmd.cmd.command = CmdDump;
760  dumpCmd.cmd.next    = I596_NULL;
761  dumpCmd.pData       = pDumpArea;
762  uti596_softc.cmdOk = 0;
763  uti596addCmd        ( (struct i596_cmd *)&dumpCmd);
764  while (1)
765    if ( --boguscnt == 0){
766      printf("Dump command was not processed within spin loop delay\n");
767      return 0;
768    }
769    else {
770      if ( uti596_softc.cmdOk )
771        return 1; /* successful completion */
772    }
773     
774 
775}
776
777/***********************************************************************
778 *  Function:   uti596_rxDaemon
779 *
780 *  Description: Receiver task
781 *
782 *  Algorithm: Extract the packet from an RFD, and place into an
783 *             mbuf chain.  Place the mbuf chain in the network task
784 *             queue. Assumes that the frame check sequence is removed
785 *             by the 82596.
786 *
787 ***********************************************************************/
788
789/* static */ void
790uti596_rxDaemon(void *arg)
791{
792  struct uti596_softc *sc = (struct uti596_softc *)arg;
793  struct ifnet *ifp = &sc->arpcom.ac_if;
794  struct mbuf *m;
795
796  struct i596_rfd *pRfd;
797  ISR_Level level;
798  int tid;
799  rtems_event_set events;
800  struct ether_header *eh;
801 
802  int frames = 0;
803 
804#ifdef DBG_596
805  printf ("uti596_rxDaemon\n");
806  printf("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd);
807#endif   
808
809  rtems_task_ident (0, 0, &tid);
810
811#ifdef DBG_596
812  printf("RX tid = 0x%x\n", tid);
813#endif   
814
815    for(;;) {
816      /*
817       * Wait for packet.
818       */
819#ifdef DBG_596
820      printf("Receiver sleeps\n");
821#endif
822
823      rtems_bsdnet_event_receive (INTERRUPT_EVENT,
824                                  RTEMS_WAIT|RTEMS_EVENT_ANY,
825                                  RTEMS_NO_TIMEOUT,
826                                  &events);
827     
828#ifdef DBG_596
829      printf("Receiver wakes\n");
830#endif
831      /*
832       * While received frames are available. Note that the frame may be
833       * a fragment, so it is NOT a complete packet.
834       */
835      pRfd = uti596dequeue( &sc->pInboundFrameQueue);
836      while ( pRfd &&
837              pRfd != I596_NULL &&
838              pRfd -> stat & STAT_C )
839        {
840
841#ifdef DEBUG_INIT
842          printf("\nReceived packet:\n");
843          print_eth( pRfd->data);
844#endif
845          if ( pRfd->stat & STAT_OK){
846            /*   a good frame. Allocate an mbuf to take it from the queue */
847
848            int pkt_len = pRfd->count & 0x3fff; /* the actual # of bytes received */
849
850#ifdef DBG_596
851            printf("Good frame, @%p, data @%p length %d\n", pRfd, pRfd -> data , pkt_len);
852#endif
853            frames++;
854
855           
856            /*
857             * Allocate an mbuf to give to the stack
858             * The format of the data portion of the RFD is:
859             * <ethernet header, payload>. 
860             * The FRAME CHECK SEQUENCE / CRC is stripped by the uti596.
861             * This is to be optimized later.... should not have to memcopy!
862             */
863            MGETHDR(m, M_WAIT, MT_DATA);
864            MCLGET(m, M_WAIT);
865
866            m->m_pkthdr.rcvif = ifp;
867            /* move everything into an mbuf */
868            memcpy(m->m_data,
869                   pRfd->data,
870                   pkt_len);
871
872            m->m_len = m->m_pkthdr.len = pkt_len - sizeof(struct ether_header) - 4;
873
874            /* move the header to an mbuf */
875            eh = mtod (m, struct ether_header *);
876            m->m_data += sizeof(struct ether_header);
877
878#ifdef DBG_596
879              printf("m->m_ext: %p pRfd -> data: %p\n",
880                     m->m_ext,  pRfd -> data);
881#endif
882#ifdef DEBUG_INIT_2
883            printf("mbuf contains:\n");
884            print_eth( (char *) (((int)m->m_data)-sizeof(struct ether_header)));
885            for ( i = 0; i<20; i++)
886              printf(".");
887
888#endif
889#ifdef DBG_VERSION
890          BREAKPOINT();
891#endif
892            ether_input (ifp, eh, m);
893
894          } /* end if STAT_OK */
895           
896          else {
897            /*
898             * A bad frame is present: Note that this could be the last RFD!
899             */
900#ifdef DBG_596
901            printf("Bad frame\n");
902#endif
903            /*
904             * FIX ME: use the statistics from the SCB
905             */
906            sc->stats.rx_errors++;
907            if ((sc->scb.pRfd->stat) & 0x0001)
908              sc->stats.collisions++;
909            if ((sc->scb.pRfd->stat) & 0x0080)
910              sc->stats.rx_length_errors++;
911            if ((sc->scb.pRfd->stat) & 0x0100)
912              sc->stats.rx_over_errors++;
913            if ((sc->scb.pRfd->stat) & 0x0200)
914              sc->stats.rx_fifo_errors++;
915            if ((sc->scb.pRfd->stat) & 0x0400)
916              sc->stats.rx_frame_errors++;
917            if ((sc->scb.pRfd->stat) & 0x0800)
918              sc->stats.rx_crc_errors++;
919            if ((sc->scb.pRfd->stat) & 0x1000)
920              sc->stats.rx_length_errors++;
921          }
922
923          UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD\n");
924
925#ifdef DBG_SUPPLY_FD
926          printf("Supply FD Starting\n");
927#endif
928          _ISR_Disable(level);
929          uti596supplyFD ( pRfd );   /* Return RFD to RFA. CAN WE REALLY?*/
930          _ISR_Enable(level);
931#ifdef DBG_SUPPLY_FD
932          printf("Supply FD Complete\n");
933#endif
934#ifdef DBG_VERSION
935          BREAKPOINT();
936#endif
937
938          pRfd = uti596dequeue( &sc->pInboundFrameQueue); /* grab next frame */
939         
940        } /* end while */
941    } /* end for(;;)*/
942   
943#ifdef DBG_596
944    printf ("frames %d\n", frames);
945#endif
946   
947}
948
949 /***********************************************************************
950  *  Function:   uti596clearListStatus
951  *
952  *  Description:
953  *             Clear the stat fields for all rfd's
954  *  Algorithm:
955  *
956  ***********************************************************************/
957
958void
959uti596clearListStatus(struct i596_rfd *pRfd)
960{
961
962  while ( pRfd != I596_NULL ) {
963    pRfd -> stat = 0;           /* clear the status field */
964    pRfd = pRfd-> next;
965  }
966}
967
968void uti596reset(void)
969 {
970   int i,count;
971   struct uti596_softc *sc = &uti596_softc;
972   /*   struct i596_rfd * pRfd; */
973
974#ifdef DBG_RESET
975     printf ("reset: begins\n");
976#endif
977
978  sc->resetDone = 0;
979  sc->irqInfo.off(&sc->irqInfo);
980
981  UTI_WAIT_COMMAND_ACCEPTED(10000, "reset: wait for previous command complete"); 
982
983  /* abort ALL of the current work */
984    /* FEB 17 REMOVED
985    >>>>>
986    sc->scb.command = CUC_ABORT | RX_ABORT;
987    outport_word(CHAN_ATTN,0);
988    UTI_WAIT_COMMAND_ACCEPTED(4000, "reset: abort requested");
989    <<<<<
990    */
991
992  uti596_reset_hardware(&uti596_softc); /* reset the ethernet hardware. must re-config */
993
994#ifdef DBG_RESET
995  uti596Diagnose(1);
996#endif
997
998  sc->set_conf.cmd.command = CmdConfigure;
999  memcpy (sc->set_conf.data, uti596initSetup, 14);
1000  uti596addPolledCmd( (struct i596_cmd *) &sc->set_conf);
1001 
1002  /****
1003   * POLL
1004   ****/
1005 
1006  count = 2000;
1007  while( !( sc->set_conf.cmd.status & STAT_C ) && --count )
1008    printf(".");
1009 
1010  if ( count )
1011    printf("Configure OK, count = %d\n",count);
1012  else
1013    printf("***reset: Configure failed\n");
1014 
1015  /*
1016   * Create the IA setup command
1017   */
1018 
1019#ifdef DBG_RESET
1020  printf("reset: Setting Address\n");
1021#endif
1022  sc->set_add.cmd.command = CmdSASetup;
1023  for ( i=0; i<6; i++)
1024    sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];
1025 
1026  sc->cmdOk = 0;
1027  uti596addPolledCmd((struct i596_cmd *)&sc->set_add);
1028 
1029  count = 2000;
1030  while( !(sc->set_add.cmd.status & STAT_C ) && --count)
1031    printf(".");
1032 
1033  if ( count )
1034    printf ("Reset Set Address OK, count= %d\n",count);
1035  else
1036    printf("Reset Set Address Failed\n");
1037  /*******/
1038
1039  sc->pCmdHead = sc->pCmdTail = sc->scb.pCmd = I596_NULL; /* Feb 17. clear these out */
1040
1041#ifdef DBG_RESET
1042  printf( "After reset, status and command: 0x%x, 0x%x\n",
1043          sc->scb.status, sc->scb.status);
1044 
1045#endif
1046 
1047
1048  /* restore the RFA */
1049
1050  /*dumpQ();*/
1051
1052  if ( sc->pLastUnkRFD != I596_NULL ) {
1053    sc-> pEndRFA =  sc->pLastUnkRFD; /* The end position can be updated */
1054    sc-> pLastUnkRFD = I596_NULL;           
1055  }
1056 
1057  sc->pEndRFA->next = sc->pSavedRfdQueue;
1058  if ( sc->pSavedRfdQueue != I596_NULL ) {
1059    sc->pEndRFA = sc->pEndSavedQueue;
1060    sc->pSavedRfdQueue = sc->pEndSavedQueue = I596_NULL;
1061    sc -> countRFD = sc->rxBdCount ;
1062  }
1063
1064  /*   if ( sc->pInboundFrameQueue != I596_NULL ){
1065    do {
1066      pRfd = sc->pInboundFrameQueue->next;
1067      sc->pEndRFA -> next = sc->pInboundFrameQueue;
1068      sc->pInboundFrameQueue = pRfd;
1069     } while( pRfd != I596_NULL ) ;
1070   
1071  }
1072  */
1073
1074  sc->scb.pRfd =  sc->pBeginRFA; /* readdress the head of the RFA in the SCB */
1075
1076  uti596clearListStatus(sc->pBeginRFA );
1077
1078  /*  dumpQ();*/
1079
1080  printf("Reset:Starting NIC\n");
1081  sc->scb.command = RX_START;
1082  sc->started = 1;               /* we assume that the start works */
1083  sc->resetDone = 1;             /* moved here from after channel attn. */
1084  outport_word(CHAN_ATTN,0 );
1085  UTI_WAIT_COMMAND_ACCEPTED(4000, "reset");
1086  printf("Reset:Start complete \n");
1087  UTI_596_ASSERT(sc->pCmdHead == I596_NULL, "Reset: CMD not cleared\n");
1088  sc->irqInfo.on(&sc->irqInfo);  /* moved back here. Tried it before RX command issued. */
1089   
1090  /* uti596addCmd(&uti506_softc.nop); */ /* just for fun */
1091 
1092#ifdef DBG_RESET
1093  printf("reset: complete\n");
1094#endif
1095 }
1096 
1097 /***********************************************************************
1098  *  Function:   uti596addCmd
1099  *
1100  *  Description:
1101  *             This routine adds a command onto the end of the
1102  *             command chain
1103  *
1104  *  Algorithm:
1105  *            Add the command to the end of and existing chain,
1106  *            or start the chain and issue a CUC_START
1107  *
1108  *
1109  ***********************************************************************/
1110
1111 /* static */ void uti596addCmd(struct i596_cmd *pCmd)
1112 {
1113     ISR_Level level;
1114
1115 #ifdef DBG_596
1116     printf("Adding command 0x%x\n", pCmd -> command );
1117 #endif
1118
1119#ifdef DEBUG_ADD
1120     
1121     switch ( pCmd -> command & 0x7 ){ /* check bottom 7 bits */
1122     case CmdConfigure:
1123       printf("ADD: Configure Command 0x%x\n", pCmd->command);
1124       break;
1125     case CmdSASetup:
1126       printf("ADD: Set Address Command 0x%x\n", pCmd->command);
1127       break;
1128     case CmdMulticastList:
1129       printf("ADD: Multi-cast list 0x%x\n", pCmd->command);
1130       break;
1131     case CmdNOp:
1132        printf("ADD: NO op 0x%x\n", pCmd->command);
1133        break;
1134     case CmdTDR:
1135        printf("ADD: TDR 0x%x\n", pCmd->command);
1136        break;
1137     case CmdDump:
1138       printf("ADD: Dump 0x%x\n", pCmd->command);
1139       break;
1140     case CmdDiagnose:
1141       printf("ADD: Diagnose 0x%x\n", pCmd->command);
1142       break;
1143     case CmdTx:
1144       break;
1145     default:
1146       printf("****Unknown Command encountered 0x%x\n", pCmd->command);
1147       break;
1148     } /* end switch */
1149       
1150#endif
1151
1152
1153
1154     pCmd->status = 0;
1155     pCmd->command |= (CMD_EOL | CMD_INTR ); /* all commands last in list & return an interrupt */
1156
1157     pCmd->next = I596_NULL;
1158
1159     _ISR_Disable(level);
1160     if (uti596_softc.pCmdHead == I596_NULL)
1161       {
1162         uti596_softc.pCmdHead =     
1163           uti596_softc.pCmdTail =
1164           uti596_softc.scb.pCmd = pCmd;
1165#ifdef DBG_596
1166         printf("First Cmd\n");
1167#endif
1168         UTI_WAIT_COMMAND_ACCEPTED(10000,"add command"); /* wait for acceptance of previous command */
1169         /* CHANGED TO |= Mar. 27 4:20 pm, was just =. changed back jun 18 1998. The wait assures command = 0 */
1170         uti596_softc.scb.command = CUC_START;
1171         outport_word (CHAN_ATTN,0);
1172     _ISR_Enable(level);
1173       }
1174     else
1175       {
1176#ifdef DBG_596
1177         printf("Chained Cmd\n");
1178#endif
1179         uti596_softc.pCmdTail->next = pCmd;
1180         uti596_softc.pCmdTail = pCmd;           /* added Jan 30 */
1181     _ISR_Enable(level);
1182       }
1183
1184
1185#ifdef DBG_596
1186         printf("Scb status & command 0x%x 0x%x\n",
1187                uti596_softc.scb.status,
1188                uti596_softc.scb.command );
1189#endif
1190         
1191 }
1192 
1193 /***********************************************************************
1194  *  Function:   uti596addPolledCmd
1195  *
1196  *  Description:
1197  *             This routine issues a single command then polls for it's
1198  *             completion.  TO BE CALLED FROM ISR ONLY
1199  *
1200  *  Algorithm:
1201  *            Give the command to the driver. ( CUC_START is ALWAYS required )
1202  *            Poll for completion.
1203  *
1204  ***********************************************************************/
1205
1206void uti596addPolledCmd(struct i596_cmd *pCmd)
1207 {
1208
1209 #ifdef DBG_596
1210     printf("Adding command 0x%x\n", pCmd -> command );
1211 #endif
1212
1213#ifdef DBG_POLLED_CMD
1214     
1215     switch ( pCmd -> command & 0x7 ){ /* check bottom 7 bits */
1216     case CmdConfigure:
1217       printf("PolledCMD: Configure Command 0x%x\n", pCmd->command);
1218       break;
1219     case CmdSASetup:
1220       printf("PolledCMD: Set CMDress Command 0x%x\n", pCmd->command);
1221       break;
1222     case CmdMulticastList:
1223       printf("PolledCMD: Multi-cast list 0x%x\n", pCmd->command);
1224       break;
1225     case CmdNOp:
1226        printf("PolledCMD: NO op 0x%x\n", pCmd->command);
1227        break;
1228     case CmdTDR:
1229        printf("PolledCMD: TDR 0x%x\n", pCmd->command);
1230        break;
1231     case CmdDump:
1232       printf("PolledCMD: Dump 0x%x\n", pCmd->command);
1233       break;
1234     case CmdDiagnose:
1235       printf("PolledCMD: Diagnose 0x%x\n", pCmd->command);
1236       break;
1237     case CmdTx:
1238       break;
1239     default:
1240       printf("PolledCMD: ****Unknown Command encountered 0x%x\n", pCmd->command);
1241       break;
1242     } /* end switch */
1243       
1244#endif
1245
1246     pCmd->status = 0;
1247     pCmd->command |=  CMD_EOL ; /* only command in list*/
1248
1249     pCmd->next = I596_NULL;
1250
1251     UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: wait prev");
1252
1253     uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
1254     uti596_softc.scb.command = CUC_START;
1255     outport_word (CHAN_ATTN,0);
1256
1257     UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: start");
1258     uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL;
1259
1260#ifdef DBG_POLLED_CMD
1261     printf("Scb status & command 0x%x 0x%x\n",
1262            uti596_softc.scb.status,
1263            uti596_softc.scb.command );
1264#endif
1265         
1266 }
1267/*
1268 * Driver transmit daemon
1269 */
1270void
1271uti596_txDaemon (void *arg)
1272{
1273        struct uti596_softc *sc = (struct uti596_softc *)arg;
1274        struct ifnet *ifp = &sc->arpcom.ac_if;
1275        struct mbuf *m;
1276        rtems_event_set events;
1277
1278        for (;;) {
1279          /*
1280           * Wait for packet from stack
1281           */
1282          rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
1283                                      RTEMS_EVENT_ANY | RTEMS_WAIT,
1284                                      RTEMS_NO_TIMEOUT, &events);
1285         
1286          /*
1287           * Send packets till queue is empty.
1288           * Ensure that irq is on before sending.
1289           */
1290          for (;;) {
1291              /* Feb 17: No need to make sure a reset is in progress,
1292               *         Since reset daemon runs at same priority as this thread
1293               */
1294              /*
1295               * Get the next mbuf chain to transmit.
1296               */
1297              IF_DEQUEUE(&ifp->if_snd, m);
1298              if (!m)
1299                break;
1300             
1301              send_packet (ifp, m); /* blocks */
1302          } /* end for */
1303          ifp->if_flags &= ~IFF_OACTIVE; /* no more to send, mark output inactive  */
1304        }
1305}
1306
1307 
1308/*
1309 * NIC reset daemon.
1310 */
1311void
1312uti596_resetDaemon (void *arg)
1313{
1314        struct uti596_softc *sc = (struct uti596_softc *)arg;
1315        rtems_event_set events;
1316        rtems_time_of_day tm_struct;
1317
1318        /* struct ifnet *ifp = &sc->arpcom.ac_if; */
1319
1320        for (;;) {
1321          /*
1322           * Wait for reset event from ISR
1323           */
1324          rtems_bsdnet_event_receive (NIC_RESET_EVENT,
1325                                      RTEMS_EVENT_ANY | RTEMS_WAIT,
1326                                      RTEMS_NO_TIMEOUT, &events);
1327
1328          rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
1329          printf("reset daemon: Resetting NIC @ %d:%d:%d \n",
1330                 tm_struct.hour, tm_struct.minute, tm_struct.second);
1331
1332          sc->stats.nic_reset_count++;
1333          /*
1334           * Reinitialize the network card
1335           */
1336          rtems_bsdnet_semaphore_obtain ();
1337          uti596reset();
1338          rtems_bsdnet_semaphore_release ();
1339        }
1340}
1341
1342 
1343 /***********************************************************************
1344  *  Function:   send_packet
1345  *
1346  *  Description: Send a raw ethernet packet
1347  *             
1348  *  Algorithm:
1349  *             increment some stats counters,
1350  *             create the transmit command,
1351  *             add the command to the CBL,
1352  *             wait for event
1353  *
1354  ***********************************************************************/
1355
1356void send_packet(struct ifnet *ifp, struct mbuf *m)
1357{
1358  struct i596_tbd *pPrev = I596_NULL,
1359    *pRemainingTbdList,
1360    *pTbd;
1361  struct mbuf *n, *input_m = m;
1362 
1363  struct uti596_softc *sc = ifp->if_softc; /* is this available from ifp ?*/
1364
1365  struct mbuf *l = NULL;
1366  unsigned int length = 0;
1367  rtems_status_code status;
1368  int bd_count = 0;
1369  rtems_event_set events;
1370
1371  /*
1372   * For all mbufs in the chain,
1373   *  fill a transmit buffer descriptor
1374   */
1375  pTbd = sc->pTxCmd->pTbd;
1376
1377  do {             
1378    if (m->m_len) {
1379      /*
1380       * Fill in the buffer descriptor
1381       */
1382      length    += m->m_len;
1383      pTbd->data = mtod (m, void *);
1384      pTbd->size = m->m_len;
1385      pPrev      = pTbd;
1386      pTbd       = pTbd -> next;
1387      l          = m;
1388      m          = m->m_next;
1389    }
1390    else {
1391      /*
1392       * Just toss empty mbufs
1393       */
1394      MFREE (m, n);
1395      m = n;
1396      if (l != NULL)
1397        l->m_next = m;
1398    }
1399  } while( m != NULL && ++bd_count < 16 );
1400
1401
1402  /* This should never happen */
1403  if ( bd_count == 16 ) {
1404    printf("TX ERROR:Too many mbufs in the packet!!!\n");
1405    printf("Must coalesce!\n");
1406  }
1407 
1408 
1409  if ( length < UTI_596_ETH_MIN_SIZE ) {
1410    pTbd->data = sc->zeroes;       /* add padding to pTbd */
1411    pTbd->size = UTI_596_ETH_MIN_SIZE - length; /* zeroes have no effect on the CRC */
1412  }
1413  else
1414    pTbd = pPrev; /* Don't use pTbd in the send routine */
1415 
1416  /*  Disconnect the packet from the list of Tbd's  */
1417  pRemainingTbdList = pTbd->next;
1418  pTbd->next  = I596_NULL;     
1419  pTbd->size |= UTI_596_END_OF_FRAME;   
1420 
1421#ifdef DBG_RAW
1422  printf("RAW:Add cmd and sleep\n");
1423#endif
1424 
1425  sc->rawsndcnt++;     
1426   
1427#ifdef DBG_RAW
1428  printf ("sending packet\n");
1429#endif
1430 
1431  /* Sending Zero length packet: shouldn't happen */
1432  if (pTbd->size <= 0) return ;
1433
1434
1435#ifdef DEBUG_INIT_2
1436  printf("\nTransmitter adds packet\n");
1437  print_hdr    ( sc->pTxCmd->pTbd->data ); /* print the first part */
1438  print_pkt    ( sc->pTxCmd->pTbd->next->data ); /* print the first part */
1439  /*  print_echo(sc->pTxCmd->pTbd->data); */
1440#endif
1441#ifdef DBG_VERSION
1442          BREAKPOINT();
1443#endif
1444
1445
1446  /* add the command to the output command queue */
1447  uti596addCmd ( (struct i596_cmd *) sc->pTxCmd );
1448 
1449  /* sleep until the command has been processed or Timeout encountered. */
1450  status= rtems_bsdnet_event_receive (INTERRUPT_EVENT,
1451                                      RTEMS_WAIT|RTEMS_EVENT_ANY,
1452                                      RTEMS_NO_TIMEOUT,
1453                                      &events);
1454   
1455  if ( status != RTEMS_SUCCESSFUL ) {
1456    printf("Could not sleep %s\n", rtems_status_text(status));
1457  }
1458 
1459#ifdef DBG_RAW
1460  printf("RAW: wake\n");
1461#endif
1462 
1463  sc->txInterrupts++;
1464     
1465#ifdef DEBUG_INIT
1466  printf("\nTransmitter issued packet\n");
1467  print_hdr    ( sc->pTxCmd->pTbd -> data ); /* print the first part */
1468  print_pkt    ( sc->pTxCmd->pTbd ->next-> data ); /* print the first part */
1469#endif
1470
1471  if ( sc->pTxCmd -> cmd.status & STAT_OK )
1472    sc->stats.tx_packets++;
1473  else
1474    {
1475#ifdef DBG_RAW
1476      printf("******Driver Error 0x%x\n", sc->pTxCmd -> cmd.status );
1477#endif
1478      sc->stats.tx_errors++;
1479      if ( sc->pTxCmd->cmd.status  & 0x0020 )
1480        sc->stats.tx_retries_exceeded++;
1481      if (!(sc->pTxCmd->cmd.status & 0x0040))
1482        sc->stats.tx_heartbeat_errors++;
1483      if ( sc->pTxCmd->cmd.status  & 0x0400 )
1484        sc->stats.tx_carrier_errors++;
1485      if ( sc->pTxCmd->cmd.status  & 0x0800 )
1486        sc->stats.collisions++;
1487      if ( sc->pTxCmd->cmd.status  & 0x1000 )
1488        sc->stats.tx_aborted_errors++;
1489    } /* end if stat_ok */       
1490 
1491  /*
1492   * Restore the transmited buffer descriptor chain.
1493   */
1494  pTbd -> next = pRemainingTbdList;
1495 
1496  /*
1497   * Free the mbufs used by the sender.
1498   */
1499  m = input_m;
1500  while ( m != NULL ) {
1501    MFREE(m,n);
1502    m = n;
1503  }
1504
1505 
1506}
1507
1508 /***********************************************************************
1509  *  Function:   print_eth
1510  *
1511  *  Description:
1512  *              Print the contents of an ethernet packet header
1513  *              CANNOT BE CALLED FROM ISR
1514  *
1515  *  Algorithm:
1516  *            Print Destination, Src, and type of packet
1517  *
1518  ***********************************************************************/
1519
1520 /* static */ void print_eth(unsigned char *add)
1521 {
1522     int i;
1523     short int length;
1524
1525     printf("Packet Location %p\n", add);
1526
1527     printf ("Dest  ");
1528
1529     for (i = 0; i < 6; i++)
1530         printf(" %2.2X", add[i]);
1531
1532     printf ("\n");
1533
1534     printf ("Source");
1535
1536     for (i = 6; i < 12; i++)
1537         printf(" %2.2X", add[i]);
1538
1539     printf ("\n");
1540
1541     printf ("frame type %2.2X%2.2X\n", add[12], add[13]);
1542
1543     if ( add[12] == 0x08 && add[13] == 0x06 )
1544       { /* an ARP */
1545         printf("Hardware type : %2.2X%2.2X\n", add[14],add[15]);
1546         printf("Protocol type : %2.2X%2.2X\n", add[16],add[17]);
1547         printf("Hardware size : %2.2X\n", add[18]);
1548         printf("Protocol size : %2.2X\n", add[19]);
1549         printf("op            : %2.2X%2.2X\n", add[20],add[21]);
1550
1551         printf("Sender Enet addr: ");
1552
1553         for ( i=0; i< 5 ; i++)
1554           printf( "%x:", add[22 + i]);
1555
1556         printf("%x\n", add[27]);
1557
1558         printf("Sender IP addr: ");
1559         for ( i=0; i< 3 ; i++)
1560           printf( "%u.", add[28 + i]);
1561
1562         printf("%u\n", add[31]);
1563
1564         printf("Target Enet addr: ");
1565         for ( i=0; i< 5 ; i++)
1566           printf( "%x:", add[32 + i]);
1567         printf("%x\n", add[37]);
1568
1569         printf("Target IP addr: ");
1570
1571         for ( i=0; i< 3 ; i++)
1572           printf( "%u.", add[38 + i]);
1573         printf("%u\n", add[41]);
1574
1575        }
1576
1577     if ( add[12] == 0x08 && add[13] == 0x00 )
1578       { /* an IP packet */
1579         printf("*********************IP HEADER******************\n");
1580         printf("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15]);
1581         printf("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] ));
1582         printf("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n",
1583                add[18],add[19], add[20], add[21]);
1584         printf("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n",
1585                add[22],add[23],add[24],add[25]);
1586         printf("IP packet type: %2.2X code %2.2X\n", add[34],add[35]);
1587
1588         printf("Source IP address: ");
1589         for ( i=0; i< 3 ; i++)
1590           printf( "%u.", add[26 + i]);
1591
1592         printf("%u\n", add[29]);
1593
1594         printf("Destination IP address: ");
1595         for ( i=0; i< 3 ; i++)
1596           printf( "%u.", add[30 + i]);
1597         printf("%u\n", add[33]);
1598
1599         /* printf("********************IP Packet Data*******************\n");
1600                 length -=20;
1601         for ( i=0; i < length ; i++)
1602           printf("0x%2.2x ", add[34+i]);
1603         printf("\n");
1604
1605         printf("ICMP checksum: %2.2x %2.2x\n", add[36], add[37]);
1606         printf("ICMP identifier: %2.2x %2.2x\n", add[38], add[39]);
1607         printf("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41]);
1608         */
1609        }
1610
1611
1612 }
1613#ifdef DEBUG_INIT
1614
1615 /***********************************************************************
1616  *  Function:   print_eth
1617  *
1618  *  Description:
1619  *              Print the contents of an ethernet packet header
1620  *              CANNOT BE CALLED FROM ISR
1621  *
1622  *  Algorithm:
1623  *            Print Destination, Src, and type of packet
1624  *
1625  ***********************************************************************/
1626
1627 /* static */ void print_hdr(unsigned char *add)
1628 {
1629     int i;
1630     short int length;
1631
1632     printf("Header Location %p\n", add);
1633
1634     printf ("Dest  ");
1635
1636     for (i = 0; i < 6; i++)
1637         printf(" %2.2X", add[i]);
1638
1639     printf ("\n");
1640
1641     printf ("Source");
1642
1643     for (i = 6; i < 12; i++)
1644         printf(" %2.2X", add[i]);
1645
1646     printf ("\n");
1647
1648     printf ("frame type %2.2X%2.2X\n", add[12], add[13]);
1649
1650
1651 }
1652 /***********************************************************************
1653  *  Function:   print_pkt
1654  *
1655  *  Description:
1656  *              Print the contents of an ethernet packet header
1657  *              CANNOT BE CALLED FROM ISR
1658  *
1659  *  Algorithm:
1660  *            Print Destination, Src, and type of packet
1661  *
1662  ***********************************************************************/
1663
1664 /* static */ void print_pkt(unsigned char *add)
1665 {
1666     int i;
1667     short int length;
1668
1669     printf("Data Location %p\n", add);
1670
1671     if ( add[0] == 0x08 && add[1] == 0x06 )
1672       { /* an ARP */
1673         printf("Hardware type : %2.2X%2.2X\n", add[14],add[15]);
1674         printf("Protocol type : %2.2X%2.2X\n", add[16],add[17]);
1675         printf("Hardware size : %2.2X\n", add[18]);
1676         printf("Protocol size : %2.2X\n", add[19]);
1677         printf("op            : %2.2X%2.2X\n", add[20],add[21]);
1678
1679         printf("Sender Enet addr: ");
1680
1681         for ( i=0; i< 5 ; i++)
1682           printf( "%x:", add[22 + i]);
1683
1684         printf("%x\n", add[27]);
1685
1686         printf("Sender IP addr: ");
1687         for ( i=0; i< 3 ; i++)
1688           printf( "%u.", add[28 + i]);
1689
1690         printf("%u\n", add[31]);
1691
1692         printf("Target Enet addr: ");
1693         for ( i=0; i< 5 ; i++)
1694           printf( "%x:", add[32 + i]);
1695         printf("%x\n", add[37]);
1696
1697         printf("Target IP addr: ");
1698
1699         for ( i=0; i< 3 ; i++)
1700           printf( "%u.", add[38 + i]);
1701         printf("%u\n", add[41]);
1702
1703        }
1704
1705     if ( add[0] == 0x08 && add[1] == 0x00 )
1706       { /* an IP packet */
1707         printf("*********************IP HEADER******************\n");
1708         printf("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15]);
1709         printf("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] ));
1710         printf("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n",
1711                add[18],add[19], add[20], add[21]);
1712         printf("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n",
1713                add[22],add[23],add[24],add[25]);
1714         printf("IP packet type: %2.2X code %2.2X\n", add[34],add[35]);
1715
1716         printf("Source IP address: ");
1717         for ( i=0; i< 3 ; i++)
1718           printf( "%u.", add[26 + i]);
1719
1720         printf("%u\n", add[29]);
1721
1722         printf("Destination IP address: ");
1723         for ( i=0; i< 3 ; i++)
1724           printf( "%u.", add[30 + i]);
1725         printf("%u\n", add[33]);
1726
1727         printf("********************IP Packet Data*******************\n");
1728         length -=20;
1729         for ( i=0; i < length ; i++)
1730           printf("0x%2.2x ", add[34+i]);
1731         printf("\n");
1732
1733         printf("ICMP checksum: %2.2x %2.2x\n", add[36], add[37]);
1734         printf("ICMP identifier: %2.2x %2.2x\n", add[38], add[39]);
1735         printf("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41]);
1736        }
1737
1738
1739 }
1740 /***********************************************************************
1741  *  Function:   print_echo
1742  *
1743  *  Description:
1744  *              Print the contents of an ethernet packet header
1745  *              CANNOT BE CALLED FROM ISR
1746  *
1747  *  Algorithm:
1748  *            Prints only echo packets
1749  *
1750  ***********************************************************************/
1751
1752 /* static */ void print_echo(unsigned char *add)
1753 {
1754     int i;
1755     short int length;
1756
1757     if ( add[12] == 0x08 && add[13] == 0x00 ){ /* an IP packet */
1758       
1759       printf("Packet Location %p\n", add);
1760       
1761       printf ("Dest  ");
1762       
1763       for (i = 0; i < 6; i++)
1764         printf(" %2.2X", add[i]);
1765       
1766       printf ("\n");
1767       
1768       printf ("Source");
1769       
1770       for (i = 6; i < 12; i++)
1771         printf(" %2.2X", add[i]);
1772       
1773       printf ("\n");
1774       
1775       printf ("frame type %2.2X%2.2X\n", add[12], add[13]);
1776       
1777       printf("*********************IP HEADER******************\n");
1778       printf("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15]);
1779       printf("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] ));
1780       printf("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n",
1781              add[18],add[19], add[20], add[21]);
1782       printf("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n",
1783              add[22],add[23],add[24],add[25]);
1784       printf("IP packet type: %2.2X code %2.2X\n", add[34],add[35]);
1785       
1786       printf("Source IP address: ");
1787       for ( i=0; i< 3 ; i++)
1788         printf( "%u.", add[26 + i]);
1789       
1790       printf("%u\n", add[29]);
1791       
1792       printf("Destination IP address: ");
1793       for ( i=0; i< 3 ; i++)
1794         printf( "%u.", add[30 + i]);
1795       printf("%u\n", add[33]);
1796       
1797       printf("********************IP Packet Data*******************\n");
1798       length -=20;
1799       for ( i=0; i < length ; i++)
1800         printf("0x%2.2x ", add[34+i]);
1801       printf("\n");
1802       
1803       printf("ICMP checksum: %2.2x %2.2x\n", add[36], add[37]);
1804       printf("ICMP identifier: %2.2x %2.2x\n", add[38], add[39]);
1805       printf("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41]);
1806     }   
1807 }
1808#endif
1809 
1810 /***********************************************************************
1811  *  Function:   uti596_attach
1812  *
1813  *  Description:
1814  *              User requested attach of driver to hardware
1815  *
1816  *  Algorithm:
1817  *
1818  *              Check that the board is present
1819  *              parse and store the command line parameters
1820  *                 argv[0]: interface label, e.g., "uti596"
1821  *                 argv[1]: maximum transmission unit, bytes, e.g., "1500"
1822  *                 argv[2]: IP address (optional)
1823  *              initialize required rx and tx buffers
1824  *              hook interrupt
1825  *              issue start command and some diagnostics
1826  *              return       
1827  *
1828  ***********************************************************************/
1829
1830
1831int uti596_attach(struct rtems_bsdnet_ifconfig * pConfig )
1832{
1833  struct uti596_softc *sc = &uti596_softc;          /* soft config */
1834  struct ifnet * ifp = &sc->arpcom.ac_if;
1835  int i = 0;
1836 
1837#ifdef DBG_ATTACH
1838  printf("attach");
1839#endif
1840
1841 
1842  sc->started = 0; /* The NIC is not started yet */
1843  sc->ioAddr = IO_ADDR;
1844
1845  /* Indicate to ULCS that this is initialized */ 
1846  ifp->if_softc = sc; 
1847  sc -> pScp = NULL;
1848 
1849  /* Assign the name */
1850  ifp->if_name = "uti";
1851 
1852  /* Assign the unit number */
1853  ifp->if_unit = 1;
1854 
1855  /* Assign mtu */
1856  if ( pConfig -> mtu )
1857    ifp->if_mtu = pConfig -> mtu;
1858  else
1859    ifp->if_mtu = ETHERMTU;
1860 
1861  /* Assign and possibly override the hw address */
1862
1863  if ( !pConfig->hardware_address) { /* Read the ethernet address from the board */
1864    for (i = 0; i < 8; i++)
1865      inport_byte(NIC_ADDR+i,sc->arpcom.ac_enaddr[i] );
1866  }
1867  else {
1868    /* hwaddr override */
1869    memcpy (sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
1870  }
1871 
1872  /* Test for valid hwaddr */
1873  if(memcmp(sc->arpcom.ac_enaddr,"\xAA\x55\x01",3)!= 0)/* b0 of byte 0 != 0 => multicast */
1874    return ENODEV;
1875 
1876  /* Assign requested receive buffer descriptor count */
1877  if (pConfig->rbuf_count)
1878    sc->rxBdCount = pConfig->rbuf_count;
1879  else
1880    sc->rxBdCount = RX_BUF_COUNT;
1881
1882  /* Assign requested tx buffer descriptor count */
1883  if (pConfig->xbuf_count)
1884    sc->txBdCount = pConfig->xbuf_count;
1885  else
1886    sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF;
1887
1888  /* ignore_broadcast is an unused feature... accept broadcast */
1889  /* sc->acceptBroadcast = !pConfig->ignore_broadcast; */
1890
1891  ifp->if_snd.ifq_maxlen = ifqmaxlen;
1892  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
1893
1894  /* to init_hardware */
1895  sc->started = 1;
1896  sc->pInboundFrameQueue = I596_NULL;
1897 
1898 
1899  ifp->if_ioctl = uti596_ioctl;
1900  ifp->if_init  = uti596_init;
1901  ifp->if_start    = uti596_start;
1902  ifp->if_output   = ether_output;
1903 
1904  sc->scb.command = 0;
1905 
1906  /*
1907   * Attach the interface
1908   */
1909  if_attach (ifp);
1910  ether_ifattach (ifp);
1911  return 1;
1912
1913 }
1914 
1915
1916 /***********************************************************************
1917  *  Function:   uti596DynamicInterruptHandler
1918  *
1919  *  Description:
1920  *             This is the interrupt handler for the uti596 board
1921  *
1922  *  Algorithm:
1923  *
1924  ***********************************************************************/
1925
1926 /* static */ rtems_isr uti596DynamicInterruptHandler(rtems_vector_number irq)
1927 {
1928#ifdef DEBUG_ISR
1929 printk("I");
1930#endif
1931
1932 UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:on ISR entry");
1933
1934 if ( !(i8259s_cache & 0x20 )) {
1935   printk("****Error: network ISR running, no IRR!\n");
1936   printk("****Error: i8259s_cache = 0x%x\n",i8259s_cache );
1937   printk_time();
1938 }
1939
1940 scbStatus = uti596_softc.scb.status & 0xf000;
1941
1942 if ( scbStatus ){
1943   /* acknowledge interrupts */
1944   /*   printk("***INFO: ACK %x\n", scbStatus);*/
1945   uti596_softc.scb.command = scbStatus;
1946   outport_word(CHAN_ATTN, 0);
1947   
1948   if( uti596_softc.resetDone ) {
1949     /* stack is attached */
1950     UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:ACK");
1951   }
1952   else {
1953     /*     printk("***INFO: ACK'd w/o processing. status = %x\n", scbStatus); */
1954     return;
1955   }
1956 }
1957 else {
1958   printk("\n***ERROR: Spurious interrupt. Resetting...\n");
1959   uti596_softc.nic_reset = 1;
1960 }
1961 
1962 if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ){
1963   printk_time();
1964   printk("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus);
1965   uti596_softc.nic_reset = 1;
1966   return;
1967 }
1968
1969 if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {
1970   printk_time();
1971   printk("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus);
1972   uti596_softc.nic_reset = 1;
1973   return;
1974 }
1975
1976 if ( scbStatus & SCB_CUS_SUSPENDED ) {
1977   printk_time();
1978   printk("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus);
1979   uti596_softc.nic_reset = 1;
1980   return;
1981 }
1982
1983 if ( scbStatus & RU_SUSPENDED  ) {
1984   printk_time();
1985   printk("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus);
1986   uti596_softc.nic_reset = 1;
1987   return;
1988 }
1989 
1990 if ( scbStatus & SCB_STAT_RNR ) {
1991   printk_time();
1992   printk("\n*****WARNING: RNR %x\n",scbStatus);
1993   printk("*****INFO: RFD cmd: %x status:%x\n",
1994          uti596_softc.pBeginRFA -> cmd,
1995          uti596_softc.pBeginRFA -> stat);
1996 }
1997 
1998 /*
1999  * Receive Unit Control
2000  */
2001 if ( scbStatus & SCB_STAT_FR ) { /* a frame has been received */
2002   uti596_softc.rxInterrupts++;
2003   
2004#ifdef DBG_FR
2005   printk("\nISR:FR\n");
2006#endif
2007   if ( uti596_softc.pBeginRFA == I596_NULL ||  !( uti596_softc.pBeginRFA -> stat & STAT_C)){
2008     dump_scb();
2009     uti596_softc.nic_reset = 1;
2010   }
2011   else
2012     while ( uti596_softc.pBeginRFA != I596_NULL &&
2013             ( uti596_softc.pBeginRFA -> stat & STAT_C)) {
2014       
2015#ifdef DBG_ISR
2016       printk("ISR:pBeginRFA != NULL\n");
2017#endif
2018       count_rx ++;
2019       if ( count_rx > 1)
2020         printk("****WARNING: Received 2 frames on 1 interrupt \n");
2021
2022       /*
2023        * Give Received Frame to the ULCS
2024        */     
2025       uti596_softc.countRFD--;
2026       
2027       if ( uti596_softc.countRFD < 0 )
2028         printk("Count < 0 !!!: count == %d, beginRFA = %p\n",
2029                uti596_softc.countRFD, uti596_softc.pBeginRFA);
2030       
2031       uti596_softc.stats.rx_packets++;
2032       pIsrRfd = uti596_softc.pBeginRFA -> next; /* the append destroys the link */
2033       uti596append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );
2034       
2035       /*
2036        * if we have just received the a frame int he last unknown RFD,
2037        * then it is certain that the RFA is empty.
2038        */
2039       if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) {
2040         UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n");
2041         uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;
2042       }
2043       
2044#ifdef DBG_ISR
2045       printk("Wake %#x\n",uti596_softc.rxDaemonTid);
2046#endif
2047       sc = rtems_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT);
2048       if ( sc != RTEMS_SUCCESSFUL )
2049         rtems_panic ("Can't notify rxDaemon: %s\n",
2050                      rtems_status_text (sc));
2051#ifdef DBG_RAW_ISR
2052       else
2053         printk("Rx Wake: %#x\n",uti596_softc.rxDaemonTid);
2054#endif
2055       
2056       uti596_softc.pBeginRFA = pIsrRfd;
2057     } /* end while */
2058   
2059   if ( uti596_softc.pBeginRFA == I596_NULL ){ /* adjust the pEndRFA to reflect an empty list */
2060     if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 )
2061       printk("Last Unk is NULL, BeginRFA is null, and count == %d\n",uti596_softc.countRFD);
2062     
2063     uti596_softc.pEndRFA = I596_NULL;
2064     if ( uti596_softc.countRFD != 0 ) {
2065       printk("****ERROR:Count is %d, but begin ptr is NULL\n",uti596_softc.countRFD );
2066     }
2067   }
2068   
2069 } /* end scb_stat_fr */
2070 
2071 /*
2072  * Check For Command Complete
2073  */
2074 if (  scbStatus & SCB_STAT_CX ){
2075#ifdef DBG_ISR
2076   printk("ISR:CU\n");
2077#endif   
2078   
2079   pIsrCmd = uti596_softc.pCmdHead;
2080   
2081   /*
2082    * For ALL completed commands
2083    */
2084   if ( pIsrCmd !=  I596_NULL && pIsrCmd->status & STAT_C  ){
2085     
2086#ifdef DBG_RAW_ISR
2087       printk("ISR:pIsrCmd != NULL\n");
2088#endif
2089     
2090     /*
2091      * Adjust the command block list
2092      */
2093     uti596_softc.pCmdHead = pIsrCmd -> next;
2094     
2095     /*
2096      * If there are MORE commands to process,
2097      * the serialization in the raw routine has failed.
2098      * ( Perhaps AddCmd is bad? )
2099      */
2100     UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL,
2101                    "****ERROR: command serialization failed\n");
2102     /*
2103      * What if the command did not complete OK?
2104      */
2105     switch ( pIsrCmd->command & 0x7)
2106       {
2107       case CmdConfigure:
2108
2109         /*      printk("****INFO:Configure OK\n"); */
2110         uti596_softc.cmdOk = 1;
2111         break;
2112         
2113       case CmdDump:
2114         
2115#ifdef DBG_ISR
2116           printk("dump!\n");
2117#endif
2118         uti596_softc.cmdOk = 1;
2119         break;
2120
2121       case CmdDiagnose:
2122         
2123#ifdef DBG_ISR
2124           printk("diagnose!\n");
2125#endif
2126         uti596_softc.cmdOk = 1;
2127         break;
2128         
2129       case CmdSASetup:
2130
2131         /*      printk("****INFO:Set address interrupt\n");     */
2132         if ( pIsrCmd -> status & STAT_OK )
2133           uti596_softc.cmdOk = 1;
2134         else
2135           printk("****ERROR:SET ADD FAILED\n");
2136         break;
2137         
2138       case CmdTx:
2139         {
2140           UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n");
2141#ifdef DBG_ISR
2142           printk("wake TX:0x%x\n",uti596_softc.txDaemonTid);
2143#endif
2144           if ( uti596_softc.txDaemonTid ){  /* Ensure that the transmitter is present */
2145             sc = rtems_event_send (uti596_softc.txDaemonTid,
2146                                    INTERRUPT_EVENT);
2147
2148           if ( sc != RTEMS_SUCCESSFUL )
2149             printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",
2150                    uti596_softc.txDaemonTid, rtems_status_text (sc) );
2151#ifdef DBG_RAW_ISR
2152           else
2153             printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);
2154#endif     
2155           }
2156         } /* End case Cmd_Tx */
2157         break;
2158         
2159       case CmdMulticastList:
2160
2161         printk("***ERROR:Multicast?!\n");
2162         pIsrCmd->next = I596_NULL;
2163         break;
2164         
2165       case CmdTDR:
2166         {
2167           unsigned long status = *( (unsigned long *)pIsrCmd)+1;
2168           printk("****ERROR:TDR?!\n");
2169           
2170           if (status & STAT_C)
2171             {
2172               /*
2173                * mark the TDR command successful
2174                */
2175               uti596_softc.cmdOk = 1;
2176             }
2177           else
2178             {
2179               if (status & 0x4000)
2180                 printk("****WARNING:Transceiver problem.\n");
2181               if (status & 0x2000)
2182                 printk("****WARNING:Termination problem.\n");
2183               if (status & 0x1000)
2184                 printk("****WARNING:Short circuit.\n");
2185               
2186               /*              printk("****INFO:Time %ld.\n", status & 0x07ff); */
2187             }
2188         }
2189         break;
2190         
2191       default:
2192         /*
2193          * This should never be reached
2194          */
2195         printk("CX but NO known command\n");
2196       } /* end switch */
2197     pIsrCmd = uti596_softc.pCmdHead; /* next command */
2198     if ( pIsrCmd != I596_NULL )
2199       printk("****WARNING: more commands in list, but no start to NIC\n");
2200   } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C  */
2201   else {
2202     if ( pIsrCmd != I596_NULL ) { /* The command MAY be NULL from a RESET */
2203       
2204       /* Reset the ethernet card, and wake the transmitter (if necessary) */
2205       printk_time();
2206       printk("****INFO: Request board reset ( tx )\n");
2207       uti596_softc.nic_reset = 1;
2208       if ( uti596_softc.txDaemonTid){  /* Ensure that a transmitter is present */
2209         sc = rtems_event_send (uti596_softc.txDaemonTid,
2210                                INTERRUPT_EVENT);
2211         
2212         if ( sc != RTEMS_SUCCESSFUL )
2213           printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",uti596_softc.txDaemonTid, rtems_status_text (sc) );
2214#ifdef DBG_RAW_ISR
2215         else
2216           printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);
2217#endif     
2218       }
2219     }
2220   }
2221 }  /* end if command complete */   
2222 
2223 
2224 /* if the receiver has stopped,
2225  * check if this is a No Resources scenario,
2226  * Try to add more RFD's ( no RBDs are used )
2227  */
2228 if ( uti596_softc.started ) {
2229   if ( scbStatus & SCB_STAT_RNR ){
2230#ifdef DBG_ISR
2231     printk("INFO:RNR: status %#x \n", uti596_softc.scb.status );
2232#endif
2233     /*
2234      * THE RECEIVER IS OFF!
2235      */
2236     if ( uti596_softc.pLastUnkRFD != I596_NULL  ){ /* We have an unknown RFD, it is not inbound*/
2237       if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) /* in use */
2238         uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD;      /* update end */
2239       else {     
2240         /*
2241          *  It is NOT in use, and since RNR, we know EL bit of pEndRFA was read!
2242          *  So, unlink it from the RFA and move it to the saved queue.
2243          *  But pBegin can equal LastUnk!
2244          */
2245       
2246           if ( uti596_softc.pEndRFA != I596_NULL ){      /* check added feb24. */
2247#ifdef DEBUG_RFA
2248             if (uti596_softc.pEndRFA -> next != uti596_softc.pLastUnkRFD){
2249               printk("***ERROR:UNK: %p not end->next: %p, end: %p\n",
2250                      uti596_softc.pLastUnkRFD,uti596_softc.pEndRFA -> next,uti596_softc.pEndRFA);
2251               printk("***INFO:countRFD now %d\n",       uti596_softc.countRFD);
2252               printk("\n\n");
2253
2254             }
2255#endif
2256             uti596_softc.pEndRFA -> next = I596_NULL;   /* added feb 16 */
2257           }
2258         uti596append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );
2259         uti596_softc.savedCount++;
2260         uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD;
2261         uti596_softc.countRFD--;                    /* It was not in the RFA */
2262         /*
2263          * The Begin pointer CAN advance this far. We must resynch the CPU side
2264          * with the chip.
2265          */
2266         if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {
2267#ifdef DEBUG_RFA
2268           if ( uti596_softc.countRFD != 0 ) {
2269             printk("****INFO:About to set begin to NULL, with count == %d\n", uti596_softc.countRFD );
2270             printk("\n\n");
2271           }
2272#endif
2273           uti596_softc.pBeginRFA = I596_NULL;
2274           UTI_596_ASSERT(uti596_softc.countRFD == 0,"****ERROR:Count must be zero here!\n");
2275         }
2276       }
2277
2278       uti596_softc.pLastUnkRFD = I596_NULL;
2279 
2280     } /* end if exists UnkRFD */
2281
2282     /*
2283      * Append the saved queue to  the RFA. 
2284      * Any further RFD's being supplied will be added to
2285      * this new list.
2286      */
2287     if ( uti596_softc.pSavedRfdQueue != I596_NULL ) { /* entries to add */
2288       if ( uti596_softc.pBeginRFA == I596_NULL ) {    /* add at beginning to list */
2289#ifdef DEBUG_RFA
2290         if(uti596_softc.countRFD != 0) {
2291           printk("****ERROR:Begin pointer is NULL, but count == %d\n",uti596_softc.countRFD);
2292         }
2293#endif
2294         uti596_softc.pBeginRFA      = uti596_softc.pSavedRfdQueue;
2295         uti596_softc.pEndRFA        = uti596_softc.pEndSavedQueue;
2296         uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL;  /* Reset the End */
2297       }
2298       else { 
2299#ifdef DEBUG_RFA
2300         if ( uti596_softc.countRFD <= 0) {
2301           printk("****ERROR:Begin pointer is not NULL, but count == %d\n",uti596_softc.countRFD);
2302         }
2303#endif
2304         UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n");
2305         UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n");
2306         
2307         uti596_softc.pEndRFA->next   = uti596_softc.pSavedRfdQueue;
2308         uti596_softc.pEndRFA->cmd   &= ~CMD_EOL;      /* clear the end of list */
2309         uti596_softc.pEndRFA         = uti596_softc.pEndSavedQueue;
2310         uti596_softc.pSavedRfdQueue  = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */
2311#ifdef DEBUG_ISR
2312         printk("count: %d, saved: %d \n", uti596_softc.countRFD , uti596_softc.savedCount);
2313#endif
2314 
2315       }
2316       /*       printk("Isr: countRFD = %d\n",uti596_softc.countRFD); */
2317       uti596_softc.countRFD += uti596_softc.savedCount;
2318       /* printk("Isr: after countRFD = %d\n",uti596_softc.countRFD); */
2319       uti596_softc.savedCount = 0;
2320     }
2321
2322 
2323#ifdef DBG_596_RFD
2324     printk("The list starts here %p\n",uti596_softc.pBeginRFA );
2325#endif
2326     
2327     if ( uti596_softc.countRFD > 1) {
2328       /****REMOVED FEB 18.
2329         &&           
2330          !( uti596_softc.pBeginRFA -> stat & (STAT_C | STAT_B ))) {
2331       *****/
2332       printk_time();
2333       printk("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat);
2334       printk("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd);
2335       uti596_softc.pBeginRFA -> stat = 0;
2336       UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n");
2337       uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
2338       /* start RX here  */
2339       printk("****INFO: ISR Starting receiver\n");
2340       uti596_softc.scb.command = RX_START; /* should this also be CU start? */
2341       outport_word(CHAN_ATTN, 0);
2342    }
2343     /*****REMOVED FEB 18.
2344       else {
2345       printk("****WARNING: Receiver NOT Started -- countRFD = %d\n", uti596_softc.countRFD);
2346       printk("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
2347              uti596_softc.scb.command,
2348              uti596_softc.scb.status,
2349              uti596_softc.countRFD);
2350       
2351       printk("\nRFA: \n");
2352       for ( pISR_Rfd = uti596_softc.pBeginRFA;
2353             pISR_Rfd != I596_NULL;
2354             pISR_Rfd = pISR_Rfd->next)
2355         printk("Frame @ %x, status: %x, cmd: %x\n",
2356                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
2357       
2358       printk("\nInbound: \n");
2359       for ( pISR_Rfd = uti596_softc.pInboundFrameQueue;
2360             pISR_Rfd != I596_NULL;
2361             pISR_Rfd = pISR_Rfd->next)
2362         printk("Frame @ %x, status: %x, cmd: %x\n",
2363                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
2364       
2365       
2366       printk("\nSaved: \n");
2367       for ( pISR_Rfd = uti596_softc.pSavedRfdQueue;
2368             pISR_Rfd != I596_NULL;
2369             pISR_Rfd = pISR_Rfd->next)
2370         printk("Frame @ %x, status: %x, cmd: %x\n",
2371                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
2372       printk("\nUnknown: %p\n",uti596_softc.pLastUnkRFD);
2373     }
2374     *****/
2375   } /* end stat_rnr */ 
2376
2377 } /* end if receiver started */
2378 /* UTI_596_ASSERT(uti596_softc.scb.status == scbStatus, "****WARNING:scbStatus change!\n"); */
2379 
2380#ifdef DBG_ISR
2381   printk("X\n");
2382#endif
2383 count_rx=0;
2384
2385 /*
2386  * Do this last, to ensure that the reset is called at the right time.
2387  */
2388 if ( uti596_softc.nic_reset ){
2389   uti596_softc.nic_reset = 0;
2390   sc = rtems_event_send(uti596_softc.resetDaemonTid, NIC_RESET_EVENT);
2391   if ( sc != RTEMS_SUCCESSFUL )
2392     rtems_panic ("Can't notify resetDaemon: %s\n", rtems_status_text (sc));
2393 }
2394
2395 return;
2396 }
2397
2398
2399/***********************************************************************
2400 *  Function:   void uti596dequeue
2401 *
2402 *  Description:
2403 *              removes an RFD from the received frame queue,
2404 *
2405 *  Algorithm:
2406 *
2407 ***********************************************************************/
2408
2409struct i596_rfd * uti596dequeue( struct i596_rfd ** ppQ )
2410 {
2411   ISR_Level level;
2412
2413   struct i596_rfd * pRfd;
2414   _ISR_Disable(level);
2415   
2416   /* invalid address, or empty queue or emptied queue */
2417   if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {
2418     _ISR_Enable(level);
2419     return I596_NULL;
2420   }
2421   
2422     pRfd = *ppQ;            /* The dequeued buffer           */
2423     *ppQ = pRfd->next;      /* advance the queue pointer     */
2424     pRfd->next = I596_NULL; /* unlink the rfd being returned */
2425
2426
2427   _ISR_Enable(level);
2428   return pRfd;
2429}       
2430
2431/***********************************************************************
2432 *  Function:   void uti596append
2433 *
2434 *  Description:
2435 *              adds an RFD to the end of the received frame queue,
2436 *              for processing by the rxproc.
2437 *              Also removes this RFD from the RFA
2438 *
2439 *  Algorithm:
2440 *
2441 ***********************************************************************/
2442
2443void uti596append( struct i596_rfd ** ppQ , struct i596_rfd * pRfd )
2444{
2445
2446  struct i596_rfd *p;
2447
2448  if ( pRfd != NULL && pRfd != I596_NULL) {
2449    pRfd -> next = I596_NULL;
2450    pRfd -> cmd |= CMD_EOL;    /* set EL bit */
2451   
2452    if ( *ppQ == NULL || *ppQ == I596_NULL ) {
2453      /* Empty or emptied */
2454      *ppQ = pRfd;
2455    }
2456    else
2457      {
2458        for ( p=*ppQ; p -> next != I596_NULL; p=p->next)
2459          ;
2460       
2461        p->cmd &= ~CMD_EOL; /* Clear EL bit at end */
2462        p->next = pRfd;
2463      }
2464  }
2465  else
2466    printf("Illegal attempt to append: %p\n", pRfd);
2467}
2468
2469
2470/***********************************************************************
2471 *  Function:   uti596stop
2472 *
2473 *  Description:
2474 *             stop the driver
2475 *
2476 *  Algorithm:
2477 *             mark driver as not started,
2478 *             mark transmitter as busy
2479 *             abort any transmissions/receptions
2480 *             clean-up all buffers ( RFD's et. al. )
2481 *             
2482 *             
2483 *
2484 *
2485 ***********************************************************************/
2486
2487
2488/* static */
2489void uti596_stop(struct uti596_softc *sc)
2490{
2491    sc->started  = 0;
2492
2493#ifdef DBG_596
2494        printf("%s: Shutting down ethercard, status was %4.4x.\n",
2495               uti596_softc.pIface->name, uti596_softc.scb.status);
2496#endif
2497
2498    printf("Stopping interface\n");
2499    sc->scb.command = CUC_ABORT|RX_ABORT;
2500    outport_word( CHAN_ATTN, 0 );
2501
2502}
2503
2504
2505static int
2506uti596_ioctl (struct ifnet *ifp, int command, caddr_t data)
2507{
2508        struct uti596_softc *sc = ifp->if_softc;
2509        int error = 0;
2510
2511        switch (command) {
2512        case SIOCGIFADDR:
2513        case SIOCSIFADDR:
2514                printk("SIOCSIFADDR\n");
2515                ether_ioctl (ifp, command, data);
2516                break;
2517
2518        case SIOCSIFFLAGS:
2519                printk("SIOCSIFFLAGS\n");
2520                switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
2521                case IFF_RUNNING:
2522                printk("IFF_RUNNING\n");
2523                        uti596_stop (sc);
2524                        break;
2525
2526                case IFF_UP:
2527                printk("IFF_UP\n");
2528                        uti596_init (sc);
2529                        break;
2530
2531                case IFF_UP | IFF_RUNNING:
2532                printk("IFF_UP and RUNNING\n");
2533                        uti596_stop (sc);
2534                        uti596_init (sc);
2535                        break;
2536
2537                default:
2538                printk("default\n");
2539
2540                        break;
2541                }
2542                break;
2543
2544        case SIO_RTEMS_SHOW_STATS:
2545                printk("show stats\n");
2546                uti596_stats (sc);
2547                break;
2548               
2549        /*
2550         * FIXME: All sorts of multicast commands need to be added here!
2551         */
2552        default:
2553                printk("default: EINVAL\n");
2554                error = EINVAL;
2555                break;
2556        }
2557        return error;
2558}
2559
2560
2561/***********************************************************************
2562 *  Function:   uti596_stats
2563 *
2564 *  Description:
2565 *             print out the collected data
2566 *
2567 *  Algorithm:
2568 *            use printf
2569 *
2570 ***********************************************************************/
2571
2572
2573void
2574uti596_stats(struct uti596_softc *sc)
2575      {
2576        printf(" CPU Reports:\n");
2577        printf ("Tx raw send count:%-8lu",  sc->rawsndcnt);
2578        printf ("Rx Interrupts:%-8lu",  sc->rxInterrupts);
2579        printf ("Tx Interrupts:%-8lu\n",  sc->txInterrupts);
2580        printf ("Rx Packets:%-8u",  sc->stats.rx_packets);
2581        printf ("Tx Attempts:%-u\n",  sc->stats.tx_packets);
2582       
2583        printf ("Rx Dropped:%-8u",     sc->stats.rx_dropped);
2584        printf ("Rx IP Packets:%-8u",  sc->stats.rx_packets);
2585        printf ("Tx Errors:%-8u\n",      sc->stats.tx_errors);
2586        printf ("Tx aborted:%-8u",     sc->stats.tx_aborted_errors);
2587        printf ("Tx Dropped:%-8u\n",     sc->stats.tx_dropped);
2588        printf ("Tx IP packets:%-8u",  sc->stats.tx_packets);
2589       
2590        printf ("Collisions Detected:%-8u\n",  sc->stats.collisions);
2591        printf ("Tx Heartbeat Errors:%-8u",  sc->stats.tx_heartbeat_errors);
2592        printf ("Tx Carrier Errors:%-8u\n",    sc->stats.tx_carrier_errors);
2593        printf ("Tx Aborted Errors:%-8u",    sc->stats.tx_aborted_errors);
2594        printf ("Rx Length Errors:%-8u\n",     sc->stats.rx_length_errors);
2595        printf ("Rx Overrun Errors:%-8u",    sc->stats.rx_over_errors);
2596        printf ("Rx Fifo Errors:%-8u\n",       sc->stats.rx_fifo_errors);
2597        printf ("Rx Framing Errors:%-8u",    sc->stats.rx_frame_errors);
2598        printf ("Rx crc errors:%-8u\n",        sc->stats.rx_crc_errors);
2599
2600        printf ("TX WAITS: %-8lu\n", sc->txRawWait);
2601
2602        printf ("NIC resets: %-8u\n", sc->stats.nic_reset_count);
2603
2604        printf("NIC reports\n");
2605
2606        dump_scb();
2607      }
2608
2609void dumpQ(void) {
2610
2611  struct i596_rfd *pRfd;
2612
2613           printf("savedQ:\n");
2614           for( pRfd = uti596_softc.pSavedRfdQueue;
2615                pRfd != I596_NULL;
2616                pRfd = pRfd -> next)
2617             printf("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd);
2618           printf("Inbound:\n");
2619           for( pRfd = uti596_softc.pInboundFrameQueue;
2620                pRfd != I596_NULL;
2621                pRfd = pRfd -> next)
2622             printf("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd);
2623            printf("Last Unk: %p\n", uti596_softc.pLastUnkRFD );
2624         
2625           printf("RFA:\n");
2626           for( pRfd = uti596_softc.pBeginRFA;
2627                pRfd != I596_NULL;
2628                pRfd = pRfd -> next)
2629             printf("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd);
2630}
2631
2632void uti596Diagnose(int verbose){
2633  struct i596_cmd diagnose;
2634  int count=10000;
2635
2636  diagnose.command = CmdDiagnose;
2637  diagnose.status = 0;
2638  uti596addPolledCmd(&diagnose);
2639  while( !( diagnose.status & STAT_C ) && count ) {
2640    if(verbose)
2641      printf(".");
2642    count --;
2643  }
2644  if(verbose)
2645    printf("Status diagnostic: 0x%2.2x\n", diagnose.status);
2646
2647}
2648void show_buffers (void)
2649{
2650    struct i596_rfd *pRfd;
2651
2652      printf("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
2653             uti596_softc.scb.command,
2654             uti596_softc.scb.status,
2655             uti596_softc.countRFD);
2656 
2657      printf("\nRFA: \n");
2658      for ( pRfd = uti596_softc.pBeginRFA;
2659            pRfd != I596_NULL;
2660            pRfd = pRfd->next)
2661        printf("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
2662               pRfd, pRfd->stat, pRfd->cmd);
2663     
2664      printf("\nInbound: \n");
2665      for ( pRfd = uti596_softc.pInboundFrameQueue;
2666            pRfd != I596_NULL;
2667            pRfd = pRfd->next)
2668        printf("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
2669               pRfd, pRfd->stat, pRfd->cmd);
2670     
2671
2672      printf("\nSaved: \n");
2673      for ( pRfd = uti596_softc.pSavedRfdQueue;
2674            pRfd != I596_NULL;
2675            pRfd = pRfd->next)
2676        printf("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
2677               pRfd, pRfd->stat, pRfd->cmd);
2678    printf("\nUnknown: %p\n",uti596_softc.pLastUnkRFD);
2679
2680}
2681void show_queues(void)
2682{
2683    struct i596_rfd *pRfd;
2684
2685
2686      printf("CMD: 0x%x, Status: 0x%x\n",
2687             uti596_softc.scb.command,
2688             uti596_softc.scb.status);
2689      printf("saved Q\n");
2690     
2691      for ( pRfd = uti596_softc.pSavedRfdQueue;
2692            pRfd != I596_NULL &&
2693              pRfd != NULL;
2694            pRfd = pRfd->next)
2695        printf("0x%p\n", pRfd);
2696     
2697      printf("End saved Q 0x%p\n", uti596_softc.pEndSavedQueue);
2698     
2699      printf("\nRFA:\n");
2700      for ( pRfd = uti596_softc.pBeginRFA;
2701            pRfd != I596_NULL &&
2702              pRfd != NULL;
2703            pRfd = pRfd->next)
2704        printf("0x%p\n", pRfd);
2705     
2706      printf("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA);
2707}
2708
2709
2710void uti596_init(void * arg){
2711
2712  struct uti596_softc  *sc = arg;
2713  struct ifnet *ifp = &sc->arpcom.ac_if;
2714
2715
2716  if (sc->txDaemonTid == 0) {
2717
2718    uti596_initialize_hardware(sc);
2719   
2720    /*
2721     * Start driver tasks
2722     */
2723   
2724    sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, sc);
2725    sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, sc);
2726    sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096,
2727                                               uti596_resetDaemon, sc);
2728   
2729   
2730#ifdef DBG_INIT
2731    printf("After attach, status of board = 0x%x\n", sc->scb.status );
2732#endif
2733    outport_word(0x380, 0xf); /* reset the LED's */
2734
2735  }
2736
2737  /*
2738   * Enable receiver
2739   */
2740  UTI_WAIT_COMMAND_ACCEPTED(4000, "init:Before RX_START");
2741  sc->scb.pRfd = sc -> pBeginRFA;
2742  sc->scb.command = RX_START;
2743  outport_word(CHAN_ATTN,0 );
2744  UTI_WAIT_COMMAND_ACCEPTED(4000, "init:RX_START");
2745  /*
2746   * Tell the world that we're running.
2747   */
2748  ifp->if_flags |= IFF_RUNNING;
2749 
2750}
2751void dump_scb(void){
2752  printk("status 0x%x\n",uti596_softc.scb.status);
2753  printk("command 0x%x\n",uti596_softc.scb.command);
2754  printk("cmd 0x%x\n",(int)uti596_softc.scb.pCmd);
2755  printk("rfd 0x%x\n",(int)uti596_softc.scb.pRfd); 
2756  printk("crc_err 0x%x\n",uti596_softc.scb.crc_err);
2757  printk("align_err 0x%x\n",uti596_softc.scb.align_err);
2758  printk("resource_err 0x%x\n",uti596_softc.scb.resource_err );
2759  printk("over_err 0x%x\n",uti596_softc.scb.over_err);
2760  printk("rcvdt_err 0x%x\n",uti596_softc.scb.rcvdt_err);
2761  printk("short_err 0x%x\n",uti596_softc.scb.short_err);
2762  printk("t_on 0x%x\n",uti596_softc.scb.t_on);
2763  printk("t_off 0x%x\n",uti596_softc.scb.t_off);
2764}
2765
2766void printk_time(void){
2767    rtems_time_of_day tm_struct;
2768
2769    rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
2770    printk("Current time: %d:%d:%d \n", tm_struct.hour, tm_struct.minute, tm_struct.second); 
2771}
Note: See TracBrowser for help on using the repository browser.