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

4.104.114.84.95
Last change on this file since 163b29a was 4f6d73a, checked in by Joel Sherrill <joel.sherrill@…>, on 03/03/99 at 16:22:57

Patch from Erik Ivanenko <erik.ivanenko@…> to correct a bug
that shows up if the BSP uses memory near address 0.

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