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

4.104.114.84.95
Last change on this file since 0c0419a1 was 0c0419a1, checked in by Joel Sherrill <joel.sherrill@…>, on 08/08/98 at 17:57:23

Reordered some stuff.

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