source: rtems/c/src/lib/libbsp/powerpc/dmv177/sonic/sonic.c @ ae320e0

4.104.114.84.9
Last change on this file since ae320e0 was ae320e0, checked in by Joel Sherrill <joel.sherrill@…>, on Aug 12, 1998 at 11:53:23 PM

Removed spurious prints and cleaned up XXX.

  • Property mode set to 100644
File size: 42.0 KB
Line 
1void break_when_you_get_here();
2/*
3 *******************************************************************
4 *******************************************************************
5 **                                                               **
6 **         RTEMS/KA9Q DRIVER FOR NATIONAL DP83932 `SONIC'        **
7 **         SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER         **
8 **                                                               **
9 *******************************************************************
10 *******************************************************************
11 */
12
13/*
14 * $Revision$   $Date$   $Author$
15 * $State$
16 */
17
18/*
19 * References:
20 * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
21 *    Controller data sheet.  TL/F/10492, RRD-B30M105, National Semiconductor,
22 *    1995.
23 *
24 * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
25 *    Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
26 *    RRD-B30M75, National Semiconductor, March, 1991.
27 *
28 * 3) SVME/DMV-171 Single Board Computer Documentation Package, #805905,
29 *    DY 4 Systems Inc., Kanata, Ontario, September, 1996.
30 */
31
32#include "sonic.h"
33
34#include <rtems/error.h>
35#include <ka9q/rtems_ka9q.h>
36#include <ka9q/global.h>
37#include <ka9q/domain.h>
38#include <ka9q/enet.h>
39#include <ka9q/iface.h>
40#include <ka9q/netuser.h>
41#include <ka9q/trace.h>
42#include <ka9q/commands.h>
43
44/*
45 * Debug levels
46 *
47 */
48
49#define SONIC_DEBUG_NONE             0x0000
50#define SONIC_DEBUG_ALL              0xFFFF
51#define SONIC_DEBUG_PRINT_REGISTERS  0x0001
52#define SONIC_DEBUG_MEMORY           0x0002
53#define SONIC_DEBUG_MEMORY_ALLOCATE  0x0004
54#define SONIC_DEBUG_FRAGMENTS        0x0008
55#define SONIC_DEBUG_CAM              0x0008
56#define SONIC_DEBUG_DESCRIPTORS      0x0010
57#define SONIC_DEBUG_ERRORS           0x0020
58
59#define SONIC_DEBUG (SONIC_DEBUG_ERRORS)
60
61/* (SONIC_DEBUG_MEMORY|SONIC_DEBUG_DESCRIPTORS) */
62
63/* SONIC_DEBUG_ALL */
64
65
66/*
67 * XXX
68 */
69
70#include <dmv170.h>
71
72/*
73 *  Use the top line if you want more symbols.
74 */
75
76#define SONIC_STATIC
77/* #define SONIC_STATIC static */
78
79/*
80 * Number of devices supported by this driver
81 */
82#ifndef NSONIC
83# define NSONIC 1
84#endif
85
86/*
87 * Default location of device registers
88 */
89#ifndef SONIC_BASE_ADDRESS
90# define SONIC_BASE_ADDRESS 0xF3000000
91# warning "Using default SONIC_BASE_ADDRESS."
92#endif
93
94/*
95 * Default interrupt vector
96 */
97#ifndef SONIC_VECTOR
98# define SONIC_VECTOR 1
99# warning "Using default SONIC_VECTOR."
100#endif
101
102/*
103 * Default device configuration register values
104 * Conservative, generic values.
105 * DCR:
106 *      No extended bus mode
107 *      Unlatched bus retry
108 *      Programmable outputs unused
109 *      Asynchronous bus mode
110 *      User definable pins unused
111 *      No wait states (access time controlled by DTACK*)
112 *      32-bit DMA
113 *      Empty/Fill DMA mode
114 *      Maximum Transmit/Receive FIFO
115 * DC2:
116 *      Extended programmable outputs unused
117 *      Normal HOLD request
118 *      Packet compress output unused
119 *      No reject on CAM match
120 */
121#define SONIC_DCR \
122   (DCR_DW32 | DCR_WAIT0 | DCR_PO0 | DCR_PO1  | DCR_RFT4 | DCR_TFT8)
123#ifndef SONIC_DCR
124# define SONIC_DCR (DCR_DW32 | DCR_TFT28)
125#endif
126#ifndef SONIC_DC2
127# define SONIC_DC2 (0)
128#endif
129
130/*
131 * Default sizes of transmit and receive descriptor areas
132 */
133#define RDA_COUNT     20
134#define TDA_COUNT     100
135
136/*
137 *
138 * As suggested by National Application Note 746, make the
139 * receive resource area bigger than the receive descriptor area.
140 */
141#define RRA_EXTRA_COUNT  0
142
143/*
144 * RTEMS event used by interrupt handler to signal daemons.
145 */
146#define INTERRUPT_EVENT  RTEMS_EVENT_1
147
148/*
149 * Largest Ethernet frame.
150 */
151#define MAXIMUM_FRAME_SIZE  1518
152
153/*
154 * Receive buffer size.
155 * Allow for a pointer, plus a full ethernet frame (including Frame
156 * Check Sequence) rounded up to a 4-byte boundary.
157 */
158#define RBUF_SIZE  ((sizeof (void *) + (MAXIMUM_FRAME_SIZE) + 3) & ~3)
159#define RBUF_WC    ((((MAXIMUM_FRAME_SIZE) + 3) & ~3) / 2)
160
161/*
162 * Macros for manipulating 32-bit pointers as 16-bit fragments
163 */
164#define LSW(p)   ((rtems_unsigned16)((rtems_unsigned32)(p)))
165#define MSW(p)   ((rtems_unsigned16)((rtems_unsigned32)(p) >> 16))
166#define PTR(m,l) ((void*)(((rtems_unsigned16)(m)<<16)|(rtems_unsigned16)(l)))
167
168/*
169 * Hardware-specific storage
170 */
171struct sonic {
172  /*
173   * Connection to KA9Q
174   */
175  struct iface                     *iface;
176
177  /*
178   * Default location of device registers
179   * ===CACHE===
180   * This area must be non-cacheable, guarded.
181   */
182  void                             *sonic;
183
184  /*
185   * Interrupt vector
186   */
187  rtems_vector_number             vector;
188
189  /*
190   * Task waiting for transmit resources
191   */
192  rtems_id                        txWaitTid;
193
194  /*
195   * Receive resource area
196   */
197  int                             rdaCount;
198  ReceiveResourcePointer_t        rsa;
199  ReceiveResourcePointer_t        rea;
200  CamDescriptorPointer_t          cdp;
201  ReceiveDescriptorPointer_t      rda;
202  ReceiveDescriptorPointer_t      rdp_last;
203
204  /*
205   * Transmit descriptors
206   */
207  int                             tdaCount;
208  TransmitDescriptorPointer_t     tdaHead;  /* Last filled */
209  TransmitDescriptorPointer_t     tdaTail;  /* Next to retire */
210  int                             tdaActiveCount;
211
212  /*
213   * Statistics
214   */
215  unsigned long                   Interrupts;
216  unsigned long                   rxInterrupts;
217  unsigned long                   rxMissed;
218  unsigned long                   rxGiant;
219  unsigned long                   rxNonOctet;
220  unsigned long                   rxBadCRC;
221  unsigned long                   rxCollision;
222
223  unsigned long                   txInterrupts;
224  unsigned long                   txSingleCollision;
225  unsigned long                   txMultipleCollision;
226  unsigned long                   txCollision;
227  unsigned long                   txDeferred;
228  unsigned long                   txUnderrun;
229  unsigned long                   txLateCollision;
230  unsigned long                   txExcessiveCollision;
231  unsigned long                   txExcessiveDeferral;
232  unsigned long                   txLostCarrier;
233  unsigned long                   txRawWait;
234};
235SONIC_STATIC struct sonic sonic[NSONIC];
236
237/*
238 ******************************************************************
239 *                                                                *
240 *                        Support Routines                        *
241 *                                                                *
242 ******************************************************************
243 */
244
245void sonic_write_register(
246  void       *base,
247  unsigned32  regno,
248  unsigned32  value
249);
250
251unsigned32 sonic_read_register(
252  void       *base,
253  unsigned32  regno
254);
255
256void sonic_enable_interrupts(
257  void       *rp,
258  unsigned32  mask
259)
260{
261  rtems_interrupt_level level;
262
263  rtems_interrupt_disable( level );
264      sonic_write_register(
265         rp,
266         SONIC_REG_IMR,
267         sonic_read_register(rp, SONIC_REG_IMR) | mask
268      );
269  rtems_interrupt_enable( level );
270}
271
272/*
273 * Allocate non-cacheable memory on a single 64k page.
274 * Very simple minded -- just keeps trying till the memory is on a single page.
275 */
276SONIC_STATIC void * sonic_allocate(unsigned int nbytes)
277{
278  void *p;
279  unsigned long a1, a2;
280
281  for (;;) {
282    /*
283     * ===CACHE===
284     * Change malloc to malloc_noncacheable_guarded.
285     */
286    p = calloc(1, nbytes);
287    if (p == NULL)
288      rtems_panic ("No memory!");
289    a1 = (unsigned long)p;
290    a2 = a1 + nbytes - 1;
291    if ((a1 >> 16) == (a2 >> 16))
292      break;
293  }
294#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_ALLOCATE)
295  printf( "sonic_allocate %d bytes at %p\n", nbytes, p );
296#endif
297  return p;
298}
299
300/*
301 * Shut down the interface.
302 * This is a pretty simple-minded routine.  It doesn't worry
303 * about cleaning up mbufs, shutting down daemons, etc.
304 */
305
306SONIC_STATIC int sonic_stop (struct iface *iface)
307{
308  int i;
309  struct sonic *dp = &sonic[iface->dev];
310  void *rp = dp->sonic;
311
312  /*
313   * Stop the transmitter and receiver.
314   */
315  sonic_write_register( rp, SONIC_REG_CR, CR_HTX | CR_RXDIS );
316
317  /*
318   * Wait for things to stop.
319   * For safety's sake, there is an alternate exit.
320   */
321  i = 0;
322  while (sonic_read_register( rp, SONIC_REG_CR ) & (CR_RXEN | CR_TXP)) {
323    if (++i == 10000)
324      break;
325  }
326
327  /*
328   * Reset the device
329   */
330  sonic_write_register( rp, SONIC_REG_CR, CR_RST );
331  sonic_write_register( rp, SONIC_REG_IMR, 0 );
332  return 0;
333}
334
335/*
336 * Show interface statistics
337 */
338
339SONIC_STATIC void sonic_show (struct iface *iface)
340{
341  struct sonic *dp = &sonic[iface->dev];
342
343  printf (" Total Interrupts:%-8lu", dp->Interrupts);
344  printf ("    Rx Interrupts:%-8lu", dp->rxInterrupts);
345  printf ("            Giant:%-8lu", dp->rxGiant);
346  printf ("        Non-octet:%-8lu\n", dp->rxNonOctet);
347  printf ("          Bad CRC:%-8lu", dp->rxBadCRC);
348  printf ("        Collision:%-8lu", dp->rxCollision);
349  printf ("           Missed:%-8lu\n", dp->rxMissed);
350
351  printf (    "    Tx Interrupts:%-8lu", dp->txInterrupts);
352  printf (  "           Deferred:%-8lu", dp->txDeferred);
353  printf ("        Lost Carrier:%-8lu\n", dp->txLostCarrier);
354  printf (   "Single Collisions:%-8lu", dp->txSingleCollision);
355  printf ( "Multiple Collisions:%-8lu", dp->txMultipleCollision);
356  printf ("Excessive Collisions:%-8lu\n", dp->txExcessiveCollision);
357  printf (   " Total Collisions:%-8lu", dp->txCollision);
358  printf ( "     Late Collision:%-8lu", dp->txLateCollision);
359  printf ("            Underrun:%-8lu\n", dp->txUnderrun);
360  printf (   "  Raw output wait:%-8lu\n", dp->txRawWait);
361}
362
363/*
364 ******************************************************************
365 *                                                                *
366 *                        Interrupt Handler                       *
367 *                                                                *
368 ******************************************************************
369 */
370
371SONIC_STATIC rtems_isr sonic_interrupt_handler (rtems_vector_number v)
372{
373  struct sonic *dp = sonic;
374  void *rp;
375
376#if (NSONIC > 1)
377  /*
378   * Find the device which requires service
379   */
380  for (;;) {
381    if (dp->vector == v)
382      break;
383    if (++dp == &sonic[NSONIC])
384      return;  /* Spurious interrupt? */
385  }
386#endif /* NSONIC > 1 */
387
388  /*
389   * Get pointer to SONIC registers
390   */
391  rp = dp->sonic;
392
393  dp->Interrupts++;
394
395  /*
396   * Packet received or receive buffer area exceeded?
397   */
398  if ((sonic_read_register( rp, SONIC_REG_IMR ) & (IMR_PRXEN | IMR_RBAEEN)) &&
399      (sonic_read_register( rp, SONIC_REG_ISR ) & (ISR_PKTRX | ISR_RBAE))) {
400    sonic_write_register(
401       rp,
402       SONIC_REG_IMR,
403       sonic_read_register( rp, SONIC_REG_IMR) & ~(IMR_PRXEN | IMR_RBAEEN)
404    );
405    dp->rxInterrupts++;
406    rtems_event_send (dp->iface->rxproc, INTERRUPT_EVENT);
407  }
408
409  /*
410   * Packet started, transmitter done or transmitter error?
411   */
412  if ((sonic_read_register( rp, SONIC_REG_IMR ) & (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN))
413   && (sonic_read_register( rp, SONIC_REG_ISR ) & (ISR_PINT | ISR_TXDN | ISR_TXER))) {
414    sonic_write_register(
415       rp,
416       SONIC_REG_IMR,
417       sonic_read_register( rp, SONIC_REG_IMR) &
418                  ~(IMR_PINTEN | IMR_PTXEN | IMR_TXEREN)
419    );
420    dp->txInterrupts++;
421    rtems_event_send (dp->txWaitTid, INTERRUPT_EVENT);
422  }
423}
424
425/*
426 ******************************************************************
427 *                                                                *
428 *                      Transmitter Routines                      *
429 *                                                                *
430 ******************************************************************
431 */
432
433/*
434 * Soak up transmit descriptors that have been sent.
435 */
436
437SONIC_STATIC void sonic_retire_tda (struct sonic *dp)
438{
439  rtems_unsigned16 status;
440  unsigned int collisions;
441
442  /*
443   * Repeat for all completed transmit descriptors.
444   */
445  while ((dp->tdaActiveCount != 0)
446      && ((status = dp->tdaTail->status) != 0)) {
447
448#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
449    printf( "retire TDA %p (0x%04x)\n", dp->tdaTail, status );
450#endif
451
452#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
453    if ( status != 0x0001 )
454      printf( "ERROR: retire TDA %p (0x%04x)\n", dp->tdaTail, status );
455#endif
456
457    /*
458     * Check for errors which stop the transmitter.
459     */
460    if (status & (TDA_STATUS_EXD |
461        TDA_STATUS_EXC |
462        TDA_STATUS_FU |
463        TDA_STATUS_BCM)) {
464      /*
465       * Restart the transmitter if there are
466       * packets waiting to go.
467       */
468      rtems_unsigned16 link;
469      link = *(dp->tdaTail->linkp);
470
471      if ((link & TDA_LINK_EOL) == 0) {
472        void *rp = dp->sonic;
473
474        sonic_write_register( rp, SONIC_REG_CTDA, link );
475        sonic_write_register( rp, SONIC_REG_CR, CR_TXP );
476      }
477    }
478
479    /*
480     * Update network statistics
481     */
482    collisions = (status & TDA_STATUS_COLLISION_MASK) >> TDA_STATUS_COLLISION_SHIFT;
483    if (collisions) {
484      if (collisions == 1)
485        dp->txSingleCollision++;
486      else
487        dp->txMultipleCollision++;
488      dp->txCollision += collisions;
489    }
490    if (status & TDA_STATUS_EXC)
491      dp->txExcessiveCollision++;
492    if (status & TDA_STATUS_OWC)
493      dp->txLateCollision++;
494    if (status & TDA_STATUS_EXD)
495      dp->txExcessiveDeferral++;
496    if (status & TDA_STATUS_DEF)
497      dp->txDeferred++;
498    if (status & TDA_STATUS_FU)
499      dp->txUnderrun++;
500    if (status & TDA_STATUS_CRSL)
501      dp->txLostCarrier++;
502
503    /*
504     *  Free the packet and reset a couple of fields
505     */
506    dp->tdaActiveCount--;
507    free_p ((struct mbuf **)&dp->tdaTail->mbufp);
508
509    dp->tdaTail->frag[0].frag_link = LSW(dp->tdaTail->link_pad);
510    dp->tdaTail->frag_count        = 0;
511
512    /*
513     * Move to the next transmit descriptor
514     */
515    dp->tdaTail = dp->tdaTail->next;
516#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
517    printf( "next TDA %p\n", dp->tdaTail );
518#endif
519  }
520}
521
522/*
523 * Send raw packet (caller provides header).
524 * This code runs in the context of the interface transmit
525 * task (most packets)  or in the context of the network
526 * task (for ARP requests).
527 */
528
529SONIC_STATIC int sonic_raw (struct iface *iface, struct mbuf **bpp)
530{
531  struct sonic *dp = &sonic[iface->dev];
532  void *rp = dp->sonic;
533  struct mbuf *bp;
534  TransmitDescriptorPointer_t tdp;
535  volatile struct TransmitDescriptorFragLink *fp;
536  unsigned int packetSize;
537  int i;
538  static char padBuf[64];
539
540  /*
541   * Update the log.
542   */
543  iface->rawsndcnt++;
544  iface->lastsent = secclock ();
545  dump (iface, IF_TRACE_OUT, *bpp);
546
547  /*
548   * It would not do to have two tasks active in the transmit
549   * loop at the same time.
550   * The blocking is simple-minded since the odds of two tasks
551   * simultaneously attempting to use this code are low.  The only
552   * way that two tasks can try to run here is:
553   *  1) Task A enters this code and ends up having to
554   *     wait for a transmit buffer descriptor.
555   *  2) Task B gains control and tries to transmit a packet.
556   * The RTEMS/KA9Q scheduling semaphore ensures that there
557   * are no race conditions associated with manipulating the
558   * txWaitTid variable.
559   */
560  if (dp->txWaitTid) {
561#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
562    printf( "TX: conflict delay\n" );
563#endif
564    dp->txRawWait++;
565    while (dp->txWaitTid)
566      rtems_ka9q_ppause (10);
567  }
568
569  /*
570   * Free up transmit descriptors.
571   */
572  sonic_retire_tda (dp);
573
574  /*
575   * Wait for transmit descriptor to become available.
576   */
577  if (dp->tdaActiveCount == dp->tdaCount) {
578#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
579    puts( "Wait for more TDAs" );
580#endif
581    /*
582     * Find out who we are
583     */
584    if (dp->txWaitTid == 0)
585      rtems_task_ident (RTEMS_SELF, 0, &dp->txWaitTid);
586
587    /*
588     * Clear old events.
589     */
590    sonic_write_register( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
591
592    /*
593     * Wait for transmit descriptor to become available.
594     * Note that the transmit descriptors are checked
595     * *before* * entering the wait loop -- this catches
596     * the possibility that a transmit descriptor became
597     * available between the `if' the started this block,
598     * and the clearing of the interrupt status register.
599     */
600    sonic_retire_tda (dp);
601    while (dp->tdaActiveCount == dp->tdaCount) {
602      /*
603       * Enable transmitter interrupts.
604       */
605      sonic_enable_interrupts( rp, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
606
607      /*
608       * Wait for interrupt
609       */
610      rtems_ka9q_event_receive (INTERRUPT_EVENT,
611            RTEMS_WAIT|RTEMS_EVENT_ANY,
612            RTEMS_NO_TIMEOUT);
613      sonic_write_register( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
614      sonic_retire_tda (dp);
615    }
616  }
617
618  /*
619   * Get the head of the packet mbuf chain.
620   */
621  bp = *bpp;
622
623  /*
624   * Fill in the transmit descriptor fragment descriptors.
625   * ===CACHE===
626   * If data cache is operating in write-back mode, flush cached
627   * data to memory.
628   */
629  tdp = dp->tdaHead->next;
630  tdp->mbufp = bp;
631  packetSize = 0;
632  fp = tdp->frag;
633  for (i = 0 ; i < MAXIMUM_FRAGS_PER_DESCRIPTOR ; i++, fp++) {
634    fp->frag_lsw = LSW(bp->data);
635    fp->frag_msw = MSW(bp->data);
636    fp->frag_size = bp->cnt;
637    packetSize += bp->cnt;
638
639#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
640    printf( "fp %p 0x%04x%04x %d\n",
641      fp, fp->frag_msw, fp->frag_lsw, fp->frag_size );
642#endif
643    /*
644     * Break out of the loop if this mbuf is the last in the frame.
645     */
646    if ((bp = bp->next) == NULL)
647      break;
648  }
649
650  /*
651   * Pad short packets.
652   */
653  if  ((packetSize < 64) && (i < MAXIMUM_FRAGS_PER_DESCRIPTOR)) {
654    int padSize = 64 - packetSize;
655    fp++;
656    fp->frag_lsw = LSW(padBuf);
657    fp->frag_msw = MSW(padBuf);
658    fp->frag_size = padSize;
659#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
660    printf( "PAD fp %p 0x%04x%04x %d\n",
661         fp, fp->frag_msw, fp->frag_lsw, fp->frag_size );
662#endif
663    packetSize += padSize;
664    i++;
665  }
666
667  /*
668   * Fill Transmit Descriptor
669   */
670  tdp->pkt_size = packetSize;
671  tdp->frag_count = i + 1;
672  tdp->status = 0;
673
674  /*
675   * Chain onto list and start transmission.
676   */
677
678  tdp->linkp = &(fp+1)->frag_link;
679  *tdp->linkp = LSW(tdp->next) | TDA_LINK_EOL;
680  if ( dp->tdaHead->frag_count )
681    *dp->tdaHead->linkp &= ~TDA_LINK_EOL;
682  dp->tdaActiveCount++;
683  dp->tdaHead = tdp;
684
685  sonic_enable_interrupts( rp, (IMR_PINTEN | IMR_PTXEN | IMR_TXEREN) );
686  sonic_write_register( rp, SONIC_REG_CR, CR_TXP );
687
688  /*
689   * Let KA9Q know the packet is on the way
690   */
691
692  dp->txWaitTid = 0;
693  *bpp = NULL;
694  return 0;
695}
696
697/*
698 ******************************************************************
699 *                                                                *
700 *                        Receiver Routines                       *
701 *                                                                *
702 ******************************************************************
703 */
704
705/*
706 * Wait for SONIC to hand over a Receive Descriptor.
707 */
708
709SONIC_STATIC void sonic_rda_wait(
710  struct sonic *dp,
711  ReceiveDescriptorPointer_t rdp
712)
713{
714  int i;
715  void *rp = dp->sonic;
716
717  /*
718   * Wait for Receive Descriptor.
719   * The order of the tests is very important.
720   *    The RDA is checked after RBAE is detected.  This ensures that
721   *    the driver processes all RDA entries before reusing the RRA
722   *    entry holding the giant packet.
723   *    The event wait is done after the RDA and RBAE checks.  This
724   *    catches the possibility that a Receive Descriptor became ready
725   *    between the call to this function and the clearing of the
726   *    interrupt status register bit.
727   */
728  for (;;) {
729    /*
730     * Has a giant packet arrived?
731     * The National DP83932C data sheet is very vague on what
732     * happens under this condition.  The description of the
733     * Interrupt Status Register (Section 4.3.6) states,
734     * ``Reception is aborted and the SONIC fetches the next
735     * available resource descriptors in the RRA.  The buffer
736     * space is not re-used and an RDA is not setup for the
737     * truncated packet.''
738     * I take ``Reception is aborted''  to mean that the RXEN
739     * bit in the Command Register is cleared and must be set
740     * by the driver to begin reception again.
741     * Unfortunately, an alternative interpretation could be
742     * that only reception of the current packet is aborted.
743     * This would be more difficult to recover from....
744     */
745    if (sonic_read_register( rp, SONIC_REG_ISR ) & ISR_RBAE) {
746
747#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
748      printf( "ERROR: looks like a giant packet -- RBAE\n" );
749#endif
750
751      /*
752       * One more check to soak up any Receive Descriptors
753       * that may already have been handed back to the driver.
754       */
755      if (rdp->in_use == RDA_IN_USE) {
756#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
757      printf( "ERROR: nope just an RBAE\n" );
758#endif
759        break;
760      }
761
762      /*
763       * Check my interpretation of the SONIC manual.
764       */
765      if (sonic_read_register( rp, SONIC_REG_CR ) & CR_RXEN)
766        rtems_panic ("SONIC RBAE/RXEN");
767
768      /*
769       * Update statistics
770       */
771      dp->rxGiant++;
772
773      /*
774       * Reuse receive buffer.
775       * Again, the manual is subject to interpretation.  The
776       * RRP register is described as, `the lower address of
777       * the next descriptor the SONIC will read.''
778       * Since, acording to the ISR/RBAE notes, the SONIC has
779       * ``fetched the next available resource descriptor in
780       * the RRA'', I interpret this to mean that that the
781       * driver has to move the RRP back *two* entries to
782       * reuse the receive buffer holding the giant packet.
783       */
784      for (i = 0 ; i < 2 ; i++) {
785        if (sonic_read_register( rp, SONIC_REG_RRP ) ==
786            sonic_read_register( rp, SONIC_REG_RSA ))
787          sonic_write_register(
788            rp,
789            SONIC_REG_RRP,
790            sonic_read_register( rp, SONIC_REG_REA )
791          );
792          sonic_write_register(
793             rp,
794             SONIC_REG_RRP,
795             sonic_read_register(rp, SONIC_REG_RRP) - sizeof(ReceiveResource_t)
796          );
797      }
798
799      /*
800       * Restart reception
801       */
802      sonic_write_register( rp, SONIC_REG_ISR, ISR_RBAE );
803      sonic_write_register( rp, SONIC_REG_CR, CR_RXEN );
804    }
805
806    /*
807     * Clear old packet-received events.
808     */
809    sonic_write_register( rp, SONIC_REG_ISR, ISR_PKTRX );
810
811    /*
812     * Has Receive Descriptor become available?
813     */
814    if (rdp->in_use == RDA_IN_USE)
815      break;
816
817    /*
818     * Enable interrupts.
819     */
820    sonic_enable_interrupts( rp, (IMR_PRXEN | IMR_RBAEEN) );
821
822    /*
823     * Wait for interrupt.
824     */
825    rtems_ka9q_event_receive (INTERRUPT_EVENT,
826            RTEMS_WAIT|RTEMS_EVENT_ANY,
827            RTEMS_NO_TIMEOUT);
828  }
829#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
830  printf( "RDA %p\n", rdp );
831#endif
832
833#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
834    if (rdp->status & 0x000E)
835      printf( "ERROR: RDA %p (0x%04x)\n", rdp, rdp->status );
836#endif
837
838}
839
840/*
841 * SCC reader task
842 */
843
844SONIC_STATIC void sonic_rx (int dev, void *p1, void *p2)
845{
846  struct iface *iface = (struct iface *)p1;
847  struct sonic *dp = (struct sonic *)p2;
848  void *rp = dp->sonic;
849  struct mbuf *bp;
850  rtems_unsigned16 status;
851  ReceiveDescriptorPointer_t rdp;
852  ReceiveResourcePointer_t rwp, rea;
853  rtems_unsigned16 newMissedTally, oldMissedTally;
854  int continuousCount;
855
856  rwp = dp->rsa;
857  rea = dp->rea;
858  rdp = dp->rda;
859
860  /*
861   * Start the receiver
862   */
863  oldMissedTally = sonic_read_register( rp, SONIC_REG_MPT );
864  sonic_write_register( rp, SONIC_REG_CR, CR_RRRA );
865  sonic_write_register( rp, SONIC_REG_CR, CR_RXEN );
866
867  /*
868   * Input packet handling loop
869   */
870  continuousCount = 0;
871  for (;;) {
872    /*
873     * Wait till SONIC supplies a Receive Descriptor.
874     */
875    if (rdp->in_use == RDA_FREE) {
876      continuousCount = 0;
877      sonic_rda_wait (dp, rdp);
878    }
879
880#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
881    printf( "Incoming packet %p status=0x%04x\n", rdp, rdp->status );
882#endif
883
884    /*
885     * Check that packet is valid
886     */
887    status = rdp->status;
888    if (status & RDA_STATUS_PRX) {
889      struct mbuf **mbp;
890      void *p;
891
892      /*
893       * Get the mbuf pointer
894       */
895      p = PTR(rdp->pkt_msw, rdp->pkt_lsw);
896      mbp = (struct mbuf **)p - 1;
897      bp = *mbp;
898
899      /*
900       * Pass the packet up the chain.
901       * The mbuf count is reduced to remove
902       * the frame check sequence at the end
903       * of the packet.
904       * ===CACHE===
905       * Invalidate cache entries for this memory.
906       */
907      bp->cnt = rdp->byte_count - sizeof (uint32);
908      net_route (iface, &bp);
909
910      /*
911       * Give the network code a chance to digest the
912       * packet.  This guards against a flurry of
913       * incoming packets (usually an ARP storm) from
914       * using up all the available memory.
915       */
916      if (++continuousCount >= dp->rdaCount) {
917#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
918        printf( "ERROR: RX processed too many in a row\n" );
919#endif
920        kwait_null ();
921      }
922
923      /*
924       * Sanity check that Receive Resource Area is
925       * still in sync with Receive Descriptor Area
926       * The buffer reported in the Receive Descriptor
927       * should be the same as the buffer in the Receive
928       * Resource we are about to reuse.
929       */
930/* XXX figure out whether this is valid or not */
931#if 0
932      if ((LSW(p) != rwp->buff_ptr_lsw)
933       || (MSW(p) != rwp->buff_ptr_msw))
934        rtems_panic ("SONIC RDA/RRA");
935#endif
936
937      /*
938       * Allocate a new mbuf.
939       */
940      bp = ambufw (RBUF_SIZE);
941      mbp = (struct mbuf **)bp->data;
942      bp->data += sizeof *mbp;
943      *mbp = bp;
944
945      /*
946       * Reuse Receive Resource.
947       */
948      rwp->buff_ptr_lsw = LSW(bp->data);
949      rwp->buff_ptr_msw = MSW(bp->data);
950      rwp++;
951      if (rwp == rea) {
952#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
953        printf( "Wrapping RWP from %p to %p\n", rwp, dp->rsa );
954#endif
955        rwp = dp->rsa;
956      }
957      sonic_write_register( rp, SONIC_REG_RWP , LSW(rwp) );
958
959      /*
960       * Tell the SONIC to reread the RRA.
961       */
962      if (sonic_read_register( rp, SONIC_REG_ISR ) & ISR_RBE)
963        sonic_write_register( rp, SONIC_REG_ISR, ISR_RBE );
964    }
965    else {
966      if (status & RDA_STATUS_COL)
967        dp->rxCollision++;
968      if (status & RDA_STATUS_FAER)
969        dp->rxNonOctet++;
970      else if (status & RDA_STATUS_CRCR)
971        dp->rxBadCRC++;
972    }
973
974    /*
975     * Count missed packets
976     */
977    newMissedTally = sonic_read_register( rp, SONIC_REG_MPT );
978    if (newMissedTally != oldMissedTally) {
979      dp->rxMissed += (newMissedTally - oldMissedTally) & 0xFFFF;
980      newMissedTally = oldMissedTally;
981    }
982
983    /*
984     * Move to next receive descriptor
985     */
986    rdp->in_use = RDA_FREE;
987    rdp = rdp->next;
988    rdp->link &= ~RDA_LINK_EOL;
989  }
990}
991
992/*
993 ******************************************************************
994 *                                                                *
995 *                     Initialization Routines                    *
996 *                                                                *
997 ******************************************************************
998 */
999
1000/*
1001 * Initialize the SONIC hardware
1002 */
1003SONIC_STATIC void sonic_initialize_hardware(
1004  struct sonic *dp,
1005  int broadcastFlag
1006)
1007{
1008  void *rp = dp->sonic;
1009  int i;
1010  unsigned char *hwaddr;
1011  rtems_isr_entry old_handler;
1012  TransmitDescriptorPointer_t tdp;
1013  ReceiveDescriptorPointer_t ordp, rdp;
1014  ReceiveResourcePointer_t rwp;
1015  struct mbuf *bp;
1016  CamDescriptorPointer_t cdp;
1017
1018  /*
1019   *  The Revision B SONIC has a horrible bug known as the "Zero
1020   *  Length Packet bug".  The initial board used to develop this
1021   *  driver had a newer revision of the SONIC so there was no reason
1022   *  to check for this.  If you have the Revision B SONIC chip, then
1023   *  you need to add some code to the RX path to handle this weirdness.
1024   */
1025
1026  if ( sonic_read_register( rp, SONIC_REG_SR ) < SONIC_REVISION_C ) {
1027    rtems_fatal_error_occurred( 0x0BADF00D );  /* don't eat this part :) */
1028  }
1029 
1030  /*
1031   *  Set up circular linked list in Transmit Descriptor Area.
1032   *  Use the PINT bit in the transmit configuration field to
1033   *  request an interrupt on every other transmitted packet.
1034   *
1035   *  NOTE: sonic_allocate() zeroes all of the memory allocated.
1036   */
1037
1038  dp->tdaActiveCount = 0;
1039  dp->tdaTail = sonic_allocate(dp->tdaCount * sizeof *tdp);
1040#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
1041  printf( "tdaTail = %p\n", dp->tdaTail );
1042#endif
1043  tdp = dp->tdaTail;
1044  for (i = 0 ; i < dp->tdaCount ; i++) {
1045    /*
1046     *  status, pkt_config, pkt_size, and all fragment fields
1047     *  are set to zero by sonic_allocate.
1048     */
1049
1050/* XXX not used by the BSD drivers
1051    if (i & 1)
1052      tdp->pkt_config = TDA_CONFIG_PINT;
1053*/
1054
1055    tdp->frag_count        = 0;
1056    tdp->frag[0].frag_link = LSW(tdp + 1);
1057    tdp->link_pad          = LSW(tdp + 1) | TDA_LINK_EOL;
1058    tdp->linkp             = &((tdp + 1)->frag[0].frag_link);
1059    tdp->next              = (TransmitDescriptor_t *)(tdp + 1);
1060    tdp++;
1061  }
1062  tdp--;
1063  dp->tdaHead = tdp;
1064  tdp->link_pad = LSW(dp->tdaTail) | TDA_LINK_EOL;
1065  tdp->next = (TransmitDescriptor_t *)dp->tdaTail;
1066  tdp->linkp = &dp->tdaTail->frag[0].frag_link;
1067
1068  /*
1069   *  Set up circular linked list in Receive Descriptor Area.
1070   *  Leaves dp->rda pointing at the `beginning' of the list.
1071   *
1072   *  NOTE: The RDA and CDP must have the same MSW for their addresses.
1073   */
1074
1075  dp->rda = sonic_allocate(
1076              (dp->rdaCount * sizeof(ReceiveDescriptor_t)) + 
1077                sizeof(CamDescriptor_t) );
1078  dp->cdp = (CamDescriptorPointer_t) ((unsigned char *)dp->rda +
1079        (dp->rdaCount * sizeof(ReceiveDescriptor_t)));
1080#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
1081  printf( "rda area = %p\n", dp->rda );
1082  printf( "cdp area = %p\n", dp->cdp );
1083#endif
1084
1085  ordp = rdp = dp->rda;
1086  for (i = 0 ; i < dp->rdaCount ; i++) {
1087    /*
1088     *  status, byte_count, pkt_ptr0, pkt_ptr1, and seq_no are set
1089     *  to zero by sonic_allocate.
1090     */
1091    rdp->link   = LSW(rdp + 1);
1092    rdp->in_use = RDA_FREE;
1093    rdp->next   = (ReceiveDescriptor_t *)(rdp + 1);
1094    ordp = rdp;
1095    rdp++;
1096  }
1097  /*
1098   *  Link the last desriptor to the 1st one and mark it as the end
1099   *  of the list.
1100   */
1101  ordp->next   = dp->rda;
1102  ordp->link   = LSW(dp->rda) | RDA_LINK_EOL;
1103  dp->rdp_last = rdp;
1104 
1105  /*
1106   * Allocate the receive resource area.
1107   * In accordance with National Application Note 746, make the
1108   * receive resource area bigger than the receive descriptor area.
1109   * This has the useful side effect of making the receive resource
1110   * area big enough to hold the CAM descriptor area.
1111   */
1112
1113  dp->rsa = sonic_allocate((dp->rdaCount + RRA_EXTRA_COUNT) * sizeof *dp->rsa);
1114#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
1115  printf( "rsa area = %p\n", dp->rsa );
1116#endif
1117
1118  /*
1119   *  Set up list in Receive Resource Area.
1120   *  Allocate space for incoming packets.
1121   */
1122
1123  rwp = dp->rsa;
1124  for (i = 0 ; i < (dp->rdaCount + RRA_EXTRA_COUNT) ; i++, rwp++) {
1125    struct mbuf **mbp;
1126
1127    /*
1128     * Allocate memory for buffer.
1129     * Place a pointer to the mbuf at the beginning of the buffer
1130     * so we can find the mbuf when the SONIC returns the buffer
1131     * to the driver.
1132     */
1133    bp = ambufw (RBUF_SIZE);
1134    mbp = (struct mbuf **)bp->data;
1135    bp->data += sizeof *mbp;
1136    *mbp = bp;
1137
1138    /*
1139     * Set up RRA entry
1140     */
1141
1142    rwp->buff_ptr_lsw = LSW(bp->data);
1143    rwp->buff_ptr_msw = MSW(bp->data);
1144    rwp->buff_wc_lsw = RBUF_WC;
1145    rwp->buff_wc_msw = 0;
1146  }
1147  dp->rea = rwp;
1148#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
1149  printf( "rea area = %p\n", dp->rea );
1150#endif
1151
1152
1153  /*
1154   * Issue a software reset.
1155   */
1156  sonic_write_register( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );
1157
1158  /*
1159   * Set up data configuration registers.
1160   */
1161  sonic_write_register( rp, SONIC_REG_DCR, SONIC_DCR );
1162  sonic_write_register( rp, SONIC_REG_DCR2, SONIC_DC2 );
1163
1164  sonic_write_register( rp, SONIC_REG_CR, CR_STP | CR_RXDIS | CR_HTX );
1165
1166  /*
1167   * Mask all interrupts
1168   */
1169  sonic_write_register( rp, SONIC_REG_IMR, 0x3fff );
1170
1171  /*
1172   * Clear outstanding interrupts.
1173   */
1174  sonic_write_register( rp, SONIC_REG_ISR, 0x7FFF );
1175
1176  /*
1177   *  Clear the tally counters
1178   */
1179
1180  sonic_write_register( rp, SONIC_REG_CRCT, 0xFFFF );
1181  sonic_write_register( rp, SONIC_REG_FAET, 0xFFFF );
1182  sonic_write_register( rp, SONIC_REG_MPT, 0xFFFF );
1183  sonic_write_register( rp, SONIC_REG_RSC, 0 );
1184
1185  /*
1186   *  Set the Receiver mode
1187   *
1188   *  Enable/disable reception of broadcast packets
1189   */
1190
1191  if (broadcastFlag)
1192    sonic_write_register( rp, SONIC_REG_RCR, RCR_BRD );
1193  else
1194    sonic_write_register( rp, SONIC_REG_RCR, 0 );
1195
1196  /*
1197   * Set up Resource Area pointers
1198   */
1199
1200  sonic_write_register( rp, SONIC_REG_URRA, MSW(dp->rsa) );
1201  sonic_write_register( rp, SONIC_REG_RSA, LSW(dp->rsa) );
1202
1203  sonic_write_register( rp, SONIC_REG_REA, LSW(dp->rea) );
1204
1205  sonic_write_register( rp, SONIC_REG_RRP, LSW(dp->rsa) );
1206  sonic_write_register( rp, SONIC_REG_RWP, LSW(dp->rsa) ); /* XXX was rea */
1207
1208  sonic_write_register( rp, SONIC_REG_URDA, MSW(dp->rda) );
1209  sonic_write_register( rp, SONIC_REG_CRDA, LSW(dp->rda) );
1210
1211  sonic_write_register( rp, SONIC_REG_UTDA, MSW(dp->tdaTail) );
1212  sonic_write_register( rp, SONIC_REG_CTDA, LSW(dp->tdaTail) );
1213
1214  /*
1215   * Set End Of Buffer Count register to the value recommended
1216   * in Note 1 of Section 3.4.4.4 of the SONIC data sheet.
1217   */
1218
1219  sonic_write_register( rp, SONIC_REG_EOBC, RBUF_WC - 2 );
1220
1221  /*
1222   *  Issue the load RRA command
1223   */
1224
1225  sonic_write_register( rp, SONIC_REG_CR, CR_RRRA );
1226  while (sonic_read_register( rp, SONIC_REG_CR ) & CR_RRRA)
1227    continue;
1228
1229  /*
1230   * Remove device reset
1231   */
1232
1233  sonic_write_register( rp, SONIC_REG_CR, 0 );
1234
1235  /*
1236   *  Set up the SONIC CAM with our hardware address.
1237   */
1238
1239  hwaddr = dp->iface->hwaddr;
1240  cdp = dp->cdp;
1241
1242#if (SONIC_DEBUG & SONIC_DEBUG_CAM)
1243  printf( "hwaddr: %2x:%2x:%2x:%2x:%2x:%2x\n",
1244     hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5] );
1245#endif
1246
1247  cdp->cep  = 0;                     /* Fill first and only entry in CAM */
1248  cdp->cap0 = hwaddr[1] << 8 | hwaddr[0];
1249  cdp->cap1 = hwaddr[3] << 8 | hwaddr[2];
1250  cdp->cap2 = hwaddr[5] << 8 | hwaddr[4];
1251  cdp->ce   = 0x0001;                /* Enable first entry in CAM */
1252
1253  sonic_write_register( rp, SONIC_REG_CDC, 1 );      /* 1 entry in CDA */
1254  sonic_write_register( rp, SONIC_REG_CDP, LSW(cdp) );
1255  sonic_write_register( rp, SONIC_REG_CR,  CR_LCAM );  /* Load the CAM */
1256
1257  while (sonic_read_register( rp, SONIC_REG_CR ) & CR_LCAM)
1258    continue;
1259
1260  /*
1261   * Verify that CAM was properly loaded.
1262   */
1263
1264  sonic_write_register( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );
1265
1266#if (SONIC_DEBUG & SONIC_DEBUG_CAM)
1267  sonic_write_register( rp, SONIC_REG_CEP, 0 );  /* Select first entry in CAM */
1268    printf ("Loaded Ethernet address into SONIC CAM.\n"
1269      "  Wrote %04x%04x%04x - %#x\n"
1270      "   Read %04x%04x%04x - %#x\n", 
1271        cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,
1272        sonic_read_register( rp, SONIC_REG_CAP2 ),
1273        sonic_read_register( rp, SONIC_REG_CAP1 ),
1274        sonic_read_register( rp, SONIC_REG_CAP0 ),
1275        sonic_read_register( rp, SONIC_REG_CE ));
1276#endif
1277
1278  sonic_write_register( rp, SONIC_REG_CEP, 0 );  /* Select first entry in CAM */
1279  if ((sonic_read_register( rp, SONIC_REG_CAP2 ) != cdp->cap2)
1280   || (sonic_read_register( rp, SONIC_REG_CAP1 ) != cdp->cap1)
1281   || (sonic_read_register( rp, SONIC_REG_CAP0 ) != cdp->cap0)
1282   || (sonic_read_register( rp, SONIC_REG_CE ) != cdp->ce)) {
1283    printf ("Failed to load Ethernet address into SONIC CAM.\n"
1284      "  Wrote %04x%04x%04x - %#x\n"
1285      "   Read %04x%04x%04x - %#x\n", 
1286        cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,
1287        sonic_read_register( rp, SONIC_REG_CAP2 ),
1288        sonic_read_register( rp, SONIC_REG_CAP1 ),
1289        sonic_read_register( rp, SONIC_REG_CAP0 ),
1290        sonic_read_register( rp, SONIC_REG_CE ));
1291    rtems_panic ("SONIC LCAM");
1292  }
1293
1294  sonic_write_register(rp, SONIC_REG_CR, CR_TXP | CR_RXEN | CR_STP);
1295
1296  /*
1297   * Attach SONIC interrupt handler
1298   */
1299  sonic_write_register( rp, SONIC_REG_IMR, 0 );
1300  old_handler = set_vector(sonic_interrupt_handler, dp->vector, 0);
1301
1302  /*
1303   * Remainder of hardware initialization is
1304   * done by the receive and transmit daemons.
1305   */
1306}
1307
1308/*
1309 * Attach an SONIC driver to the system
1310 * This is the only `extern' function in the driver.
1311 *
1312 * argv[0]: interface label, e.g. "rtems"
1313 * The remainder of the arguments are optional key/value pairs:
1314 * mtu ##                  --  maximum transmission unit, default 1500
1315 * broadcast y/n           -- accept or ignore broadcast packets, default yes
1316 * rbuf ##                 -- Set number of receive descriptor entries
1317 * tbuf ##                 -- Set number of transmit descriptor entries
1318 * ip ###.###.###.###      -- IP address
1319 * ether ##:##:##:##:##:## -- Ethernet address
1320 * reg ######              -- Address of SONIC device registers
1321 * vector ###              -- SONIC interrupt vector
1322 */
1323int
1324rtems_ka9q_driver_attach (int argc, char *argv[], void *p)
1325{
1326  struct sonic *dp;
1327  struct iface *iface;
1328  char *cp;
1329  int argIndex;
1330  int broadcastFlag;
1331  char cbuf[30];
1332
1333  /*
1334   * Find an unused entry
1335   */
1336  dp = sonic;
1337  for (;;) {
1338    if (dp == &sonic[NSONIC]) {
1339      printf ("No more SONIC devices.\n");
1340      return -1;
1341    }
1342    if (dp->iface == NULL)
1343      break;
1344    dp++;
1345  }
1346  if (if_lookup (argv[0]) != NULL) {
1347    printf ("Interface %s already exists\n", argv[0]);
1348    return -1;
1349  }
1350
1351  /*
1352   *  zero out the control structure
1353   */
1354
1355  memset( dp, 0, sizeof(struct sonic) );
1356
1357  /*
1358   * Create an inteface descriptor
1359   */
1360  iface = callocw (1, sizeof *iface);
1361  iface->name = strdup (argv[0]);
1362  iface->dev = dp - sonic;
1363
1364  /*
1365   * Set default values
1366   */
1367  broadcastFlag = 1;
1368  dp->txWaitTid = 0;
1369  dp->rdaCount = RDA_COUNT;
1370  dp->tdaCount = TDA_COUNT;
1371  iface->mtu = 1500;
1372  iface->addr = Ip_addr;
1373  iface->hwaddr = mallocw (EADDR_LEN);
1374  memset (iface->hwaddr, 0x08, EADDR_LEN);
1375  dp->sonic = (struct SonicRegisters *)SONIC_BASE_ADDRESS;
1376  dp->vector = SONIC_VECTOR;
1377
1378  /*
1379   * Parse remaining arguments
1380   */
1381  for (argIndex = 1 ; argIndex < (argc - 1) ; argIndex++) {
1382    if (strcmp ("mtu", argv[argIndex]) == 0) {
1383      iface->mtu = strtoul (argv[++argIndex], NULL, 0);
1384    }
1385    else if (strcmp ("broadcast", argv[argIndex]) == 0) {
1386      if (*argv[++argIndex] == 'n')
1387        broadcastFlag = 0;
1388    }
1389    else if (strcmp ("rbuf", argv[argIndex]) == 0) {
1390      /*
1391       * The minimum RDA count is 2.  A single-entry RDA
1392       * would be difficult to use since the SONIC does
1393       * not release (in_use = 0) the RDA that has the
1394       * EOL bit set.
1395       */
1396      dp->rdaCount = strtoul (argv[++argIndex], NULL, 0);
1397      if ((dp->rdaCount <= 1) || (dp->rdaCount > 200)) {
1398        printf ("RDA option (%d) is invalid.\n", dp->rdaCount);
1399        return -1;
1400      }
1401    }
1402    else if (strcmp ("tbuf", argv[argIndex]) == 0) {
1403      dp->tdaCount = strtoul (argv[++argIndex], NULL, 0);
1404      if ((dp->tdaCount <= 1) || (dp->tdaCount > 200)) {
1405        printf ("TDA option (%d) is invalid.\n", dp->tdaCount);
1406        return -1;
1407      }
1408    }
1409    else if (strcmp ("ip", argv[argIndex]) == 0) {
1410      iface->addr = resolve (argv[++argIndex]);
1411    }
1412    else if (strcmp ("ether", argv[argIndex]) == 0) {
1413      gether (iface->hwaddr, argv[++argIndex]);
1414    }
1415    else if (strcmp ("reg", argv[argIndex]) == 0) {
1416      dp->sonic = (struct SonicRegisters *)strtoul (argv[++argIndex], NULL, 0);
1417    }
1418    else if (strcmp ("vector", argv[argIndex]) == 0) {
1419      dp->vector = strtoul (argv[++argIndex], NULL, 0);
1420    }
1421    else {
1422      printf ("Argument %d (%s) is invalid.\n", argIndex, argv[argIndex]);
1423      return -1;
1424    }
1425  }
1426  printf ("Ethernet address: %s\n", pether (cbuf, iface->hwaddr));
1427  iface->raw = sonic_raw;
1428  iface->stop = sonic_stop;
1429  iface->show = sonic_show;
1430  dp->iface = iface;
1431  setencap (iface, "Ethernet");
1432
1433  /*
1434   * Set up SONIC hardware
1435   */
1436  sonic_initialize_hardware (dp, broadcastFlag);
1437
1438  /*
1439   * Chain onto list of interfaces
1440   */
1441  iface->next = Ifaces;
1442  Ifaces = iface;
1443
1444  /*
1445   * Start I/O daemons
1446   */
1447  cp = if_name (iface, " tx");
1448  iface->txproc = newproc (cp, 2048, if_tx, iface->dev, iface, NULL, 0);
1449  free (cp);
1450  cp = if_name (iface, " rx");
1451  iface->rxproc = newproc (cp, 2048, sonic_rx, iface->dev, iface, dp, 0);
1452  free (cp);
1453  return 0;
1454}
1455
1456#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
1457#include <stdio.h>
1458
1459char SONIC_Reg_name[64][6]= {
1460    "CR",         /* 0x00 */
1461    "DCR",        /* 0x01 */
1462    "RCR",        /* 0x02 */
1463    "TCR",        /* 0x03 */
1464    "IMR",        /* 0x04 */
1465    "ISR",        /* 0x05 */
1466    "UTDA",       /* 0x06 */
1467    "CTDA",       /* 0x07 */
1468    "0x08",       /* 0x08 */
1469    "0x09",       /* 0x09 */
1470    "0x0A",       /* 0x0A */
1471    "0x0B",       /* 0x0B */
1472    "0x0C",       /* 0x0C */
1473    "URDA",       /* 0x0D */
1474    "CRDA",       /* 0x0E */
1475    "0x0F",       /* 0x0F */
1476    "0x10",       /* 0x10 */
1477    "0x11",       /* 0x11 */
1478    "0x12",       /* 0x12 */
1479    "EOBC",       /* 0x13 */
1480    "URRA",       /* 0x14 */
1481    "RSA",        /* 0x15 */
1482    "REA",        /* 0x16 */
1483    "RRP",        /* 0x17 */
1484    "RWP",        /* 0x18 */
1485    "0x19",       /* 0x19 */
1486    "0x1A",       /* 0x1A */
1487    "0x1B",       /* 0x1B */
1488    "0x1C",       /* 0x1C */
1489    "0x0D",       /* 0x1D */
1490    "0x1E",       /* 0x1E */
1491    "0x1F",       /* 0x1F */
1492    "0x20",       /* 0x20 */
1493    "CEP",        /* 0x21 */
1494    "CAP2",       /* 0x22 */
1495    "CAP1",       /* 0x23 */
1496    "CAP0",       /* 0x24 */
1497    "CE",         /* 0x25 */
1498    "CDP",        /* 0x26 */
1499    "CDC",        /* 0x27 */
1500    "SR",         /* 0x28 */
1501    "WT0",        /* 0x29 */
1502    "WT1",        /* 0x2A */
1503    "RSC",        /* 0x2B */
1504    "CRCT",       /* 0x2C */
1505    "FAET",       /* 0x2D */
1506    "MPT",        /* 0x2E */
1507    "MDT",        /* 0x2F */
1508    "0x30",       /* 0x30 */
1509    "0x31",       /* 0x31 */
1510    "0x32",       /* 0x32 */
1511    "0x33",       /* 0x33 */
1512    "0x34",       /* 0x34 */
1513    "0x35",       /* 0x35 */
1514    "0x36",       /* 0x36 */
1515    "0x37",       /* 0x37 */
1516    "0x38",       /* 0x38 */
1517    "0x39",       /* 0x39 */
1518    "0x3A",       /* 0x3A */
1519    "0x3B",       /* 0x3B */
1520    "0x3C",       /* 0x3C */
1521    "0x3D",       /* 0x3D */
1522    "0x3E",       /* 0x3E */
1523    "DCR2"        /* 0x3F */
1524};
1525#endif
1526void sonic_write_register(
1527  void       *base,
1528  unsigned32  regno,
1529  unsigned32  value
1530)
1531{
1532  volatile unsigned32 *p = base;
1533
1534#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
1535  printf( "%p Write 0x%04x to %s (0x%02x)\n",
1536      &p[regno], value, SONIC_Reg_name[regno], regno );
1537  fflush( stdout );
1538#endif
1539  p[regno] = value;
1540}
1541
1542unsigned32 sonic_read_register(
1543  void       *base,
1544  unsigned32  regno
1545)
1546{
1547  volatile unsigned32 *p = base;
1548  unsigned32           value;
1549
1550  value = p[regno];
1551#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
1552  printf( "%p Read 0x%04x from %s (0x%02x)\n",
1553      &p[regno], value, SONIC_Reg_name[regno], regno );
1554  fflush( stdout );
1555#endif
1556  return value;
1557}
Note: See TracBrowser for help on using the repository browser.