OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [i386ex/] [network/] [network.c] - Blame information for rev 389

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.