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

4.104.114.84.95
Last change on this file since 5c36c47 was 5c36c47, checked in by Ralf Corsepius <ralf.corsepius@…>, on 09/19/05 at 03:18:52

2005-09-19 Ralf Corsepius <ralf.corsepius@…>

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