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

4.104.114.84.95
Last change on this file since 8529cf6 was 8529cf6, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/01/04 at 10:09:10

2004-04-01 Ralf Corsepius <ralf_corsepius@…>

  • network/network.c: Include <rtems/asm.h> instead of <asm.h>.
  • include/bsp.h: Include <rtems/clockdrv.h> instead of <clockdrv.h>.
  • include/bsp.h: Include <rtems/console.h> instead of <console.h>.
  • include/bsp.h: Include <rtems/iosupp.h> instead of <iosupp.h>.
  • 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 <rtems/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   rtems_status_code sc;
1929#ifdef DEBUG_ISR
1930 printk("I");
1931#endif
1932
1933 UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:on ISR entry");
1934
1935 if ( !(i8259s_cache & 0x20 )) {
1936   printk("****Error: network ISR running, no IRR!\n");
1937   printk("****Error: i8259s_cache = 0x%x\n",i8259s_cache );
1938   printk_time();
1939 }
1940
1941 scbStatus = uti596_softc.scb.status & 0xf000;
1942
1943 if ( scbStatus ){
1944   /* acknowledge interrupts */
1945   /*   printk("***INFO: ACK %x\n", scbStatus);*/
1946   uti596_softc.scb.command = scbStatus;
1947   outport_word(CHAN_ATTN, 0);
1948   
1949   if( uti596_softc.resetDone ) {
1950     /* stack is attached */
1951     UTI_WAIT_COMMAND_ACCEPTED(20000, "****ERROR:ACK");
1952   }
1953   else {
1954     /*     printk("***INFO: ACK'd w/o processing. status = %x\n", scbStatus); */
1955     return;
1956   }
1957 }
1958 else {
1959   printk("\n***ERROR: Spurious interrupt. Resetting...\n");
1960   uti596_softc.nic_reset = 1;
1961 }
1962 
1963 if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ){
1964   printk_time();
1965   printk("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus);
1966   uti596_softc.nic_reset = 1;
1967   return;
1968 }
1969
1970 if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) {
1971   printk_time();
1972   printk("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus);
1973   uti596_softc.nic_reset = 1;
1974   return;
1975 }
1976
1977 if ( scbStatus & SCB_CUS_SUSPENDED ) {
1978   printk_time();
1979   printk("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus);
1980   uti596_softc.nic_reset = 1;
1981   return;
1982 }
1983
1984 if ( scbStatus & RU_SUSPENDED  ) {
1985   printk_time();
1986   printk("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus);
1987   uti596_softc.nic_reset = 1;
1988   return;
1989 }
1990 
1991 if ( scbStatus & SCB_STAT_RNR ) {
1992   printk_time();
1993   printk("\n*****WARNING: RNR %x\n",scbStatus);
1994   printk("*****INFO: RFD cmd: %x status:%x\n",
1995          uti596_softc.pBeginRFA -> cmd,
1996          uti596_softc.pBeginRFA -> stat);
1997 }
1998 
1999 /*
2000  * Receive Unit Control
2001  */
2002 if ( scbStatus & SCB_STAT_FR ) { /* a frame has been received */
2003   uti596_softc.rxInterrupts++;
2004   
2005#ifdef DBG_FR
2006   printk("\nISR:FR\n");
2007#endif
2008   if ( uti596_softc.pBeginRFA == I596_NULL ||  !( uti596_softc.pBeginRFA -> stat & STAT_C)){
2009     dump_scb();
2010     uti596_softc.nic_reset = 1;
2011   }
2012   else
2013     while ( uti596_softc.pBeginRFA != I596_NULL &&
2014             ( uti596_softc.pBeginRFA -> stat & STAT_C)) {
2015       
2016#ifdef DBG_ISR
2017       printk("ISR:pBeginRFA != NULL\n");
2018#endif
2019       count_rx ++;
2020       if ( count_rx > 1)
2021         printk("****WARNING: Received 2 frames on 1 interrupt \n");
2022
2023       /*
2024        * Give Received Frame to the ULCS
2025        */     
2026       uti596_softc.countRFD--;
2027       
2028       if ( uti596_softc.countRFD < 0 )
2029         printk("Count < 0 !!!: count == %d, beginRFA = %p\n",
2030                uti596_softc.countRFD, uti596_softc.pBeginRFA);
2031       
2032       uti596_softc.stats.rx_packets++;
2033       pIsrRfd = uti596_softc.pBeginRFA -> next; /* the append destroys the link */
2034       uti596append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );
2035       
2036       /*
2037        * if we have just received the a frame int he last unknown RFD,
2038        * then it is certain that the RFA is empty.
2039        */
2040       if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) {
2041         UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n");
2042         uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;
2043       }
2044       
2045#ifdef DBG_ISR
2046       printk("Wake %#x\n",uti596_softc.rxDaemonTid);
2047#endif
2048       sc = rtems_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT);
2049       if ( sc != RTEMS_SUCCESSFUL )
2050         rtems_panic ("Can't notify rxDaemon: %s\n",
2051                      rtems_status_text (sc));
2052#ifdef DBG_RAW_ISR
2053       else
2054         printk("Rx Wake: %#x\n",uti596_softc.rxDaemonTid);
2055#endif
2056       
2057       uti596_softc.pBeginRFA = pIsrRfd;
2058     } /* end while */
2059   
2060   if ( uti596_softc.pBeginRFA == I596_NULL ){ /* adjust the pEndRFA to reflect an empty list */
2061     if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 )
2062       printk("Last Unk is NULL, BeginRFA is null, and count == %d\n",uti596_softc.countRFD);
2063     
2064     uti596_softc.pEndRFA = I596_NULL;
2065     if ( uti596_softc.countRFD != 0 ) {
2066       printk("****ERROR:Count is %d, but begin ptr is NULL\n",uti596_softc.countRFD );
2067     }
2068   }
2069   
2070 } /* end scb_stat_fr */
2071 
2072 /*
2073  * Check For Command Complete
2074  */
2075 if (  scbStatus & SCB_STAT_CX ){
2076#ifdef DBG_ISR
2077   printk("ISR:CU\n");
2078#endif   
2079   
2080   pIsrCmd = uti596_softc.pCmdHead;
2081   
2082   /*
2083    * For ALL completed commands
2084    */
2085   if ( pIsrCmd !=  I596_NULL && pIsrCmd->status & STAT_C  ){
2086     
2087#ifdef DBG_RAW_ISR
2088       printk("ISR:pIsrCmd != NULL\n");
2089#endif
2090     
2091     /*
2092      * Adjust the command block list
2093      */
2094     uti596_softc.pCmdHead = pIsrCmd -> next;
2095     
2096     /*
2097      * If there are MORE commands to process,
2098      * the serialization in the raw routine has failed.
2099      * ( Perhaps AddCmd is bad? )
2100      */
2101     UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL,
2102                    "****ERROR: command serialization failed\n");
2103     /*
2104      * What if the command did not complete OK?
2105      */
2106     switch ( pIsrCmd->command & 0x7)
2107       {
2108       case CmdConfigure:
2109
2110         /*      printk("****INFO:Configure OK\n"); */
2111         uti596_softc.cmdOk = 1;
2112         break;
2113         
2114       case CmdDump:
2115         
2116#ifdef DBG_ISR
2117           printk("dump!\n");
2118#endif
2119         uti596_softc.cmdOk = 1;
2120         break;
2121
2122       case CmdDiagnose:
2123         
2124#ifdef DBG_ISR
2125           printk("diagnose!\n");
2126#endif
2127         uti596_softc.cmdOk = 1;
2128         break;
2129         
2130       case CmdSASetup:
2131
2132         /*      printk("****INFO:Set address interrupt\n");     */
2133         if ( pIsrCmd -> status & STAT_OK )
2134           uti596_softc.cmdOk = 1;
2135         else
2136           printk("****ERROR:SET ADD FAILED\n");
2137         break;
2138         
2139       case CmdTx:
2140         {
2141           UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n");
2142#ifdef DBG_ISR
2143           printk("wake TX:0x%x\n",uti596_softc.txDaemonTid);
2144#endif
2145           if ( uti596_softc.txDaemonTid ){  /* Ensure that the transmitter is present */
2146             sc = rtems_event_send (uti596_softc.txDaemonTid,
2147                                    INTERRUPT_EVENT);
2148
2149           if ( sc != RTEMS_SUCCESSFUL )
2150             printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",
2151                    uti596_softc.txDaemonTid, rtems_status_text (sc) );
2152#ifdef DBG_RAW_ISR
2153           else
2154             printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);
2155#endif     
2156           }
2157         } /* End case Cmd_Tx */
2158         break;
2159         
2160       case CmdMulticastList:
2161
2162         printk("***ERROR:Multicast?!\n");
2163         pIsrCmd->next = I596_NULL;
2164         break;
2165         
2166       case CmdTDR:
2167         {
2168           unsigned long status = *( (unsigned long *)pIsrCmd)+1;
2169           printk("****ERROR:TDR?!\n");
2170           
2171           if (status & STAT_C)
2172             {
2173               /*
2174                * mark the TDR command successful
2175                */
2176               uti596_softc.cmdOk = 1;
2177             }
2178           else
2179             {
2180               if (status & 0x4000)
2181                 printk("****WARNING:Transceiver problem.\n");
2182               if (status & 0x2000)
2183                 printk("****WARNING:Termination problem.\n");
2184               if (status & 0x1000)
2185                 printk("****WARNING:Short circuit.\n");
2186               
2187               /*              printk("****INFO:Time %ld.\n", status & 0x07ff); */
2188             }
2189         }
2190         break;
2191         
2192       default:
2193         /*
2194          * This should never be reached
2195          */
2196         printk("CX but NO known command\n");
2197       } /* end switch */
2198     pIsrCmd = uti596_softc.pCmdHead; /* next command */
2199     if ( pIsrCmd != I596_NULL )
2200       printk("****WARNING: more commands in list, but no start to NIC\n");
2201   } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C  */
2202   else {
2203     if ( pIsrCmd != I596_NULL ) { /* The command MAY be NULL from a RESET */
2204       
2205       /* Reset the ethernet card, and wake the transmitter (if necessary) */
2206       printk_time();
2207       printk("****INFO: Request board reset ( tx )\n");
2208       uti596_softc.nic_reset = 1;
2209       if ( uti596_softc.txDaemonTid){  /* Ensure that a transmitter is present */
2210         sc = rtems_event_send (uti596_softc.txDaemonTid,
2211                                INTERRUPT_EVENT);
2212         
2213         if ( sc != RTEMS_SUCCESSFUL )
2214           printk("****ERROR:Could NOT send event to tid 0x%x : %s\n",uti596_softc.txDaemonTid, rtems_status_text (sc) );
2215#ifdef DBG_RAW_ISR
2216         else
2217           printk("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid);
2218#endif     
2219       }
2220     }
2221   }
2222 }  /* end if command complete */   
2223 
2224 
2225 /* if the receiver has stopped,
2226  * check if this is a No Resources scenario,
2227  * Try to add more RFD's ( no RBDs are used )
2228  */
2229 if ( uti596_softc.started ) {
2230   if ( scbStatus & SCB_STAT_RNR ){
2231#ifdef DBG_ISR
2232     printk("INFO:RNR: status %#x \n", uti596_softc.scb.status );
2233#endif
2234     /*
2235      * THE RECEIVER IS OFF!
2236      */
2237     if ( uti596_softc.pLastUnkRFD != I596_NULL  ){ /* We have an unknown RFD, it is not inbound*/
2238       if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) /* in use */
2239         uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD;      /* update end */
2240       else {     
2241         /*
2242          *  It is NOT in use, and since RNR, we know EL bit of pEndRFA was read!
2243          *  So, unlink it from the RFA and move it to the saved queue.
2244          *  But pBegin can equal LastUnk!
2245          */
2246       
2247           if ( uti596_softc.pEndRFA != I596_NULL ){      /* check added feb24. */
2248#ifdef DEBUG_RFA
2249             if (uti596_softc.pEndRFA -> next != uti596_softc.pLastUnkRFD){
2250               printk("***ERROR:UNK: %p not end->next: %p, end: %p\n",
2251                      uti596_softc.pLastUnkRFD,uti596_softc.pEndRFA -> next,uti596_softc.pEndRFA);
2252               printk("***INFO:countRFD now %d\n",       uti596_softc.countRFD);
2253               printk("\n\n");
2254
2255             }
2256#endif
2257             uti596_softc.pEndRFA -> next = I596_NULL;   /* added feb 16 */
2258           }
2259         uti596append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );
2260         uti596_softc.savedCount++;
2261         uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD;
2262         uti596_softc.countRFD--;                    /* It was not in the RFA */
2263         /*
2264          * The Begin pointer CAN advance this far. We must resynch the CPU side
2265          * with the chip.
2266          */
2267         if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {
2268#ifdef DEBUG_RFA
2269           if ( uti596_softc.countRFD != 0 ) {
2270             printk("****INFO:About to set begin to NULL, with count == %d\n", uti596_softc.countRFD );
2271             printk("\n\n");
2272           }
2273#endif
2274           uti596_softc.pBeginRFA = I596_NULL;
2275           UTI_596_ASSERT(uti596_softc.countRFD == 0,"****ERROR:Count must be zero here!\n");
2276         }
2277       }
2278
2279       uti596_softc.pLastUnkRFD = I596_NULL;
2280 
2281     } /* end if exists UnkRFD */
2282
2283     /*
2284      * Append the saved queue to  the RFA. 
2285      * Any further RFD's being supplied will be added to
2286      * this new list.
2287      */
2288     if ( uti596_softc.pSavedRfdQueue != I596_NULL ) { /* entries to add */
2289       if ( uti596_softc.pBeginRFA == I596_NULL ) {    /* add at beginning to list */
2290#ifdef DEBUG_RFA
2291         if(uti596_softc.countRFD != 0) {
2292           printk("****ERROR:Begin pointer is NULL, but count == %d\n",uti596_softc.countRFD);
2293         }
2294#endif
2295         uti596_softc.pBeginRFA      = uti596_softc.pSavedRfdQueue;
2296         uti596_softc.pEndRFA        = uti596_softc.pEndSavedQueue;
2297         uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL;  /* Reset the End */
2298       }
2299       else { 
2300#ifdef DEBUG_RFA
2301         if ( uti596_softc.countRFD <= 0) {
2302           printk("****ERROR:Begin pointer is not NULL, but count == %d\n",uti596_softc.countRFD);
2303         }
2304#endif
2305         UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n");
2306         UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n");
2307         
2308         uti596_softc.pEndRFA->next   = uti596_softc.pSavedRfdQueue;
2309         uti596_softc.pEndRFA->cmd   &= ~CMD_EOL;      /* clear the end of list */
2310         uti596_softc.pEndRFA         = uti596_softc.pEndSavedQueue;
2311         uti596_softc.pSavedRfdQueue  = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */
2312#ifdef DEBUG_ISR
2313         printk("count: %d, saved: %d \n", uti596_softc.countRFD , uti596_softc.savedCount);
2314#endif
2315 
2316       }
2317       /*       printk("Isr: countRFD = %d\n",uti596_softc.countRFD); */
2318       uti596_softc.countRFD += uti596_softc.savedCount;
2319       /* printk("Isr: after countRFD = %d\n",uti596_softc.countRFD); */
2320       uti596_softc.savedCount = 0;
2321     }
2322
2323 
2324#ifdef DBG_596_RFD
2325     printk("The list starts here %p\n",uti596_softc.pBeginRFA );
2326#endif
2327     
2328     if ( uti596_softc.countRFD > 1) {
2329       /****REMOVED FEB 18.
2330         &&           
2331          !( uti596_softc.pBeginRFA -> stat & (STAT_C | STAT_B ))) {
2332       *****/
2333       printk_time();
2334       printk("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat);
2335       printk("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd);
2336       uti596_softc.pBeginRFA -> stat = 0;
2337       UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n");
2338       uti596_softc.scb.pRfd = uti596_softc.pBeginRFA;
2339       /* start RX here  */
2340       printk("****INFO: ISR Starting receiver\n");
2341       uti596_softc.scb.command = RX_START; /* should this also be CU start? */
2342       outport_word(CHAN_ATTN, 0);
2343    }
2344     /*****REMOVED FEB 18.
2345       else {
2346       printk("****WARNING: Receiver NOT Started -- countRFD = %d\n", uti596_softc.countRFD);
2347       printk("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
2348              uti596_softc.scb.command,
2349              uti596_softc.scb.status,
2350              uti596_softc.countRFD);
2351       
2352       printk("\nRFA: \n");
2353       for ( pISR_Rfd = uti596_softc.pBeginRFA;
2354             pISR_Rfd != I596_NULL;
2355             pISR_Rfd = pISR_Rfd->next)
2356         printk("Frame @ %x, status: %x, cmd: %x\n",
2357                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
2358       
2359       printk("\nInbound: \n");
2360       for ( pISR_Rfd = uti596_softc.pInboundFrameQueue;
2361             pISR_Rfd != I596_NULL;
2362             pISR_Rfd = pISR_Rfd->next)
2363         printk("Frame @ %x, status: %x, cmd: %x\n",
2364                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
2365       
2366       
2367       printk("\nSaved: \n");
2368       for ( pISR_Rfd = uti596_softc.pSavedRfdQueue;
2369             pISR_Rfd != I596_NULL;
2370             pISR_Rfd = pISR_Rfd->next)
2371         printk("Frame @ %x, status: %x, cmd: %x\n",
2372                pISR_Rfd, pISR_Rfd->stat, pISR_Rfd->cmd);
2373       printk("\nUnknown: %p\n",uti596_softc.pLastUnkRFD);
2374     }
2375     *****/
2376   } /* end stat_rnr */ 
2377
2378 } /* end if receiver started */
2379 /* UTI_596_ASSERT(uti596_softc.scb.status == scbStatus, "****WARNING:scbStatus change!\n"); */
2380 
2381#ifdef DBG_ISR
2382   printk("X\n");
2383#endif
2384 count_rx=0;
2385
2386 /*
2387  * Do this last, to ensure that the reset is called at the right time.
2388  */
2389 if ( uti596_softc.nic_reset ){
2390   uti596_softc.nic_reset = 0;
2391   sc = rtems_event_send(uti596_softc.resetDaemonTid, NIC_RESET_EVENT);
2392   if ( sc != RTEMS_SUCCESSFUL )
2393     rtems_panic ("Can't notify resetDaemon: %s\n", rtems_status_text (sc));
2394 }
2395
2396 return;
2397 }
2398
2399
2400/***********************************************************************
2401 *  Function:   void uti596dequeue
2402 *
2403 *  Description:
2404 *              removes an RFD from the received frame queue,
2405 *
2406 *  Algorithm:
2407 *
2408 ***********************************************************************/
2409
2410struct i596_rfd * uti596dequeue( struct i596_rfd ** ppQ )
2411 {
2412   ISR_Level level;
2413
2414   struct i596_rfd * pRfd;
2415   _ISR_Disable(level);
2416   
2417   /* invalid address, or empty queue or emptied queue */
2418   if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {
2419     _ISR_Enable(level);
2420     return I596_NULL;
2421   }
2422   
2423     pRfd = *ppQ;            /* The dequeued buffer           */
2424     *ppQ = pRfd->next;      /* advance the queue pointer     */
2425     pRfd->next = I596_NULL; /* unlink the rfd being returned */
2426
2427
2428   _ISR_Enable(level);
2429   return pRfd;
2430}       
2431
2432/***********************************************************************
2433 *  Function:   void uti596append
2434 *
2435 *  Description:
2436 *              adds an RFD to the end of the received frame queue,
2437 *              for processing by the rxproc.
2438 *              Also removes this RFD from the RFA
2439 *
2440 *  Algorithm:
2441 *
2442 ***********************************************************************/
2443
2444void uti596append( struct i596_rfd ** ppQ , struct i596_rfd * pRfd )
2445{
2446
2447  struct i596_rfd *p;
2448
2449  if ( pRfd != NULL && pRfd != I596_NULL) {
2450    pRfd -> next = I596_NULL;
2451    pRfd -> cmd |= CMD_EOL;    /* set EL bit */
2452   
2453    if ( *ppQ == NULL || *ppQ == I596_NULL ) {
2454      /* Empty or emptied */
2455      *ppQ = pRfd;
2456    }
2457    else
2458      {
2459        for ( p=*ppQ; p -> next != I596_NULL; p=p->next)
2460          ;
2461       
2462        p->cmd &= ~CMD_EOL; /* Clear EL bit at end */
2463        p->next = pRfd;
2464      }
2465  }
2466  else
2467    printf("Illegal attempt to append: %p\n", pRfd);
2468}
2469
2470
2471/***********************************************************************
2472 *  Function:   uti596stop
2473 *
2474 *  Description:
2475 *             stop the driver
2476 *
2477 *  Algorithm:
2478 *             mark driver as not started,
2479 *             mark transmitter as busy
2480 *             abort any transmissions/receptions
2481 *             clean-up all buffers ( RFD's et. al. )
2482 *             
2483 *             
2484 *
2485 *
2486 ***********************************************************************/
2487
2488
2489/* static */
2490void uti596_stop(struct uti596_softc *sc)
2491{
2492    sc->started  = 0;
2493
2494#ifdef DBG_596
2495        printf("%s: Shutting down ethercard, status was %4.4x.\n",
2496               uti596_softc.pIface->name, uti596_softc.scb.status);
2497#endif
2498
2499    printf("Stopping interface\n");
2500    sc->scb.command = CUC_ABORT|RX_ABORT;
2501    outport_word( CHAN_ATTN, 0 );
2502
2503}
2504
2505
2506static int
2507uti596_ioctl (struct ifnet *ifp, int command, caddr_t data)
2508{
2509        struct uti596_softc *sc = ifp->if_softc;
2510        int error = 0;
2511
2512        switch (command) {
2513        case SIOCGIFADDR:
2514        case SIOCSIFADDR:
2515                printk("SIOCSIFADDR\n");
2516                ether_ioctl (ifp, command, data);
2517                break;
2518
2519        case SIOCSIFFLAGS:
2520                printk("SIOCSIFFLAGS\n");
2521                switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
2522                case IFF_RUNNING:
2523                printk("IFF_RUNNING\n");
2524                        uti596_stop (sc);
2525                        break;
2526
2527                case IFF_UP:
2528                printk("IFF_UP\n");
2529                        uti596_init (sc);
2530                        break;
2531
2532                case IFF_UP | IFF_RUNNING:
2533                printk("IFF_UP and RUNNING\n");
2534                        uti596_stop (sc);
2535                        uti596_init (sc);
2536                        break;
2537
2538                default:
2539                printk("default\n");
2540
2541                        break;
2542                }
2543                break;
2544
2545        case SIO_RTEMS_SHOW_STATS:
2546                printk("show stats\n");
2547                uti596_stats (sc);
2548                break;
2549               
2550        /*
2551         * FIXME: All sorts of multicast commands need to be added here!
2552         */
2553        default:
2554                printk("default: EINVAL\n");
2555                error = EINVAL;
2556                break;
2557        }
2558        return error;
2559}
2560
2561
2562/***********************************************************************
2563 *  Function:   uti596_stats
2564 *
2565 *  Description:
2566 *             print out the collected data
2567 *
2568 *  Algorithm:
2569 *            use printf
2570 *
2571 ***********************************************************************/
2572
2573
2574void
2575uti596_stats(struct uti596_softc *sc)
2576      {
2577        printf(" CPU Reports:\n");
2578        printf ("Tx raw send count:%-8lu",  sc->rawsndcnt);
2579        printf ("Rx Interrupts:%-8lu",  sc->rxInterrupts);
2580        printf ("Tx Interrupts:%-8lu\n",  sc->txInterrupts);
2581        printf ("Rx Packets:%-8u",  sc->stats.rx_packets);
2582        printf ("Tx Attempts:%-u\n",  sc->stats.tx_packets);
2583       
2584        printf ("Rx Dropped:%-8u",     sc->stats.rx_dropped);
2585        printf ("Rx IP Packets:%-8u",  sc->stats.rx_packets);
2586        printf ("Tx Errors:%-8u\n",      sc->stats.tx_errors);
2587        printf ("Tx aborted:%-8u",     sc->stats.tx_aborted_errors);
2588        printf ("Tx Dropped:%-8u\n",     sc->stats.tx_dropped);
2589        printf ("Tx IP packets:%-8u",  sc->stats.tx_packets);
2590       
2591        printf ("Collisions Detected:%-8u\n",  sc->stats.collisions);
2592        printf ("Tx Heartbeat Errors:%-8u",  sc->stats.tx_heartbeat_errors);
2593        printf ("Tx Carrier Errors:%-8u\n",    sc->stats.tx_carrier_errors);
2594        printf ("Tx Aborted Errors:%-8u",    sc->stats.tx_aborted_errors);
2595        printf ("Rx Length Errors:%-8u\n",     sc->stats.rx_length_errors);
2596        printf ("Rx Overrun Errors:%-8u",    sc->stats.rx_over_errors);
2597        printf ("Rx Fifo Errors:%-8u\n",       sc->stats.rx_fifo_errors);
2598        printf ("Rx Framing Errors:%-8u",    sc->stats.rx_frame_errors);
2599        printf ("Rx crc errors:%-8u\n",        sc->stats.rx_crc_errors);
2600
2601        printf ("TX WAITS: %-8lu\n", sc->txRawWait);
2602
2603        printf ("NIC resets: %-8u\n", sc->stats.nic_reset_count);
2604
2605        printf("NIC reports\n");
2606
2607        dump_scb();
2608      }
2609
2610void dumpQ(void) {
2611
2612  struct i596_rfd *pRfd;
2613
2614           printf("savedQ:\n");
2615           for( pRfd = uti596_softc.pSavedRfdQueue;
2616                pRfd != I596_NULL;
2617                pRfd = pRfd -> next)
2618             printf("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd);
2619           printf("Inbound:\n");
2620           for( pRfd = uti596_softc.pInboundFrameQueue;
2621                pRfd != I596_NULL;
2622                pRfd = pRfd -> next)
2623             printf("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd);
2624            printf("Last Unk: %p\n", uti596_softc.pLastUnkRFD );
2625         
2626           printf("RFA:\n");
2627           for( pRfd = uti596_softc.pBeginRFA;
2628                pRfd != I596_NULL;
2629                pRfd = pRfd -> next)
2630             printf("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd);
2631}
2632
2633void uti596Diagnose(int verbose){
2634  struct i596_cmd diagnose;
2635  int count=10000;
2636
2637  diagnose.command = CmdDiagnose;
2638  diagnose.status = 0;
2639  uti596addPolledCmd(&diagnose);
2640  while( !( diagnose.status & STAT_C ) && count ) {
2641    if(verbose)
2642      printf(".");
2643    count --;
2644  }
2645  if(verbose)
2646    printf("Status diagnostic: 0x%2.2x\n", diagnose.status);
2647
2648}
2649void show_buffers (void)
2650{
2651    struct i596_rfd *pRfd;
2652
2653      printf("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
2654             uti596_softc.scb.command,
2655             uti596_softc.scb.status,
2656             uti596_softc.countRFD);
2657 
2658      printf("\nRFA: \n");
2659      for ( pRfd = uti596_softc.pBeginRFA;
2660            pRfd != I596_NULL;
2661            pRfd = pRfd->next)
2662        printf("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
2663               pRfd, pRfd->stat, pRfd->cmd);
2664     
2665      printf("\nInbound: \n");
2666      for ( pRfd = uti596_softc.pInboundFrameQueue;
2667            pRfd != I596_NULL;
2668            pRfd = pRfd->next)
2669        printf("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
2670               pRfd, pRfd->stat, pRfd->cmd);
2671     
2672
2673      printf("\nSaved: \n");
2674      for ( pRfd = uti596_softc.pSavedRfdQueue;
2675            pRfd != I596_NULL;
2676            pRfd = pRfd->next)
2677        printf("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
2678               pRfd, pRfd->stat, pRfd->cmd);
2679    printf("\nUnknown: %p\n",uti596_softc.pLastUnkRFD);
2680
2681}
2682void show_queues(void)
2683{
2684    struct i596_rfd *pRfd;
2685
2686
2687      printf("CMD: 0x%x, Status: 0x%x\n",
2688             uti596_softc.scb.command,
2689             uti596_softc.scb.status);
2690      printf("saved Q\n");
2691     
2692      for ( pRfd = uti596_softc.pSavedRfdQueue;
2693            pRfd != I596_NULL &&
2694              pRfd != NULL;
2695            pRfd = pRfd->next)
2696        printf("0x%p\n", pRfd);
2697     
2698      printf("End saved Q 0x%p\n", uti596_softc.pEndSavedQueue);
2699     
2700      printf("\nRFA:\n");
2701      for ( pRfd = uti596_softc.pBeginRFA;
2702            pRfd != I596_NULL &&
2703              pRfd != NULL;
2704            pRfd = pRfd->next)
2705        printf("0x%p\n", pRfd);
2706     
2707      printf("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA);
2708}
2709
2710
2711void uti596_init(void * arg){
2712
2713  struct uti596_softc  *sc = arg;
2714  struct ifnet *ifp = &sc->arpcom.ac_if;
2715
2716
2717  if (sc->txDaemonTid == 0) {
2718
2719    uti596_initialize_hardware(sc);
2720   
2721    /*
2722     * Start driver tasks
2723     */
2724   
2725    sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, sc);
2726    sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, sc);
2727    sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096,
2728                                               uti596_resetDaemon, sc);
2729   
2730   
2731#ifdef DBG_INIT
2732    printf("After attach, status of board = 0x%x\n", sc->scb.status );
2733#endif
2734    outport_word(0x380, 0xf); /* reset the LED's */
2735
2736  }
2737
2738  /*
2739   * Enable receiver
2740   */
2741  UTI_WAIT_COMMAND_ACCEPTED(4000, "init:Before RX_START");
2742  sc->scb.pRfd = sc -> pBeginRFA;
2743  sc->scb.command = RX_START;
2744  outport_word(CHAN_ATTN,0 );
2745  UTI_WAIT_COMMAND_ACCEPTED(4000, "init:RX_START");
2746  /*
2747   * Tell the world that we're running.
2748   */
2749  ifp->if_flags |= IFF_RUNNING;
2750 
2751}
2752void dump_scb(void){
2753  printk("status 0x%x\n",uti596_softc.scb.status);
2754  printk("command 0x%x\n",uti596_softc.scb.command);
2755  printk("cmd 0x%x\n",(int)uti596_softc.scb.pCmd);
2756  printk("rfd 0x%x\n",(int)uti596_softc.scb.pRfd); 
2757  printk("crc_err 0x%x\n",uti596_softc.scb.crc_err);
2758  printk("align_err 0x%x\n",uti596_softc.scb.align_err);
2759  printk("resource_err 0x%x\n",uti596_softc.scb.resource_err );
2760  printk("over_err 0x%x\n",uti596_softc.scb.over_err);
2761  printk("rcvdt_err 0x%x\n",uti596_softc.scb.rcvdt_err);
2762  printk("short_err 0x%x\n",uti596_softc.scb.short_err);
2763  printk("t_on 0x%x\n",uti596_softc.scb.t_on);
2764  printk("t_off 0x%x\n",uti596_softc.scb.t_off);
2765}
2766
2767void printk_time(void){
2768    rtems_time_of_day tm_struct;
2769
2770    rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
2771    printk("Current time: %d:%d:%d \n", tm_struct.hour, tm_struct.minute, tm_struct.second); 
2772}
Note: See TracBrowser for help on using the repository browser.