source: rtems/c/src/libchip/network/dec21140.c @ cd38196f

4.104.114.84.95
Last change on this file since cd38196f was cd38196f, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 27, 2004 at 5:34:00 PM

2004-04-09 Greg Menke <gregory.menke@…>

PR 607/networking

  • libchip/network/dec21140.c: Made PCI configuration minimum sane instead of fully specifying unused PCI features.
  • Property mode set to 100644
File size: 31.0 KB
Line 
1/*
2 *  RTEMS driver for TULIP based Ethernet Controller
3 *
4 *  Copyright (C) 1999 Emmanuel Raguet. raguet@crf.canon.fr
5 *
6 *  The license and distribution terms for this file may be
7 *  found in found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 *
10 * $Id$
11 *
12 * ------------------------------------------------------------------------
13 * [22.05.2000,StWi/CWA] added support for the DEC/Intel 21143 chip
14 *
15 * The 21143 support is (for now) only available for the __i386 target,
16 * because that's the only testing platform I have. It should (to my best
17 * knowledge) work in the same way for the "__PPC" target, but someone
18 * should test this first before it's put into the code. Thanks go to
19 * Andrew Klossner who provided the vital information about the
20 * Intel 21143 chip.
21 * (FWIW: I tested this driver using a Kingston KNE100TX with 21143PD chip)
22 *
23 * The driver will automatically detect whether there is a 21140 or 21143
24 * network card in the system and activate support accordingly. It will
25 * look for the 21140 first. If the 21140 is not found the driver will
26 * look for the 21143.
27 * ------------------------------------------------------------------------
28 *
29 * 2003-03-13, Greg Menke, gregory.menke@gsfc.nasa.gov
30 *
31 * Added support for up to 8 units (which is an arbitrary limit now),
32 * consolidating their support into a single pair of rx/tx daemons and a
33 * single ISR for all vectors servicing the DEC units.  The driver now
34 * simply uses whatever INTERRUPT_LINE the card supplies, requiring it
35 * be configured either by the boot monitor or bspstart() hackery.
36 * Tested on a MCP750 PPC based system with 2 DEC21140 boards.
37 *
38 * Also fixed a few bugs related to board configuration, start and stop.
39 *
40 */
41
42#include <rtems.h>
43
44/*
45 *  This driver only supports architectures with the new style
46 *  exception processing.  The following checks try to keep this
47 *  from being compiled on systems which can't support this driver.
48 */
49
50#if defined(__i386__)
51  #define DEC21140_SUPPORTED
52#endif
53
54#if defined(__PPC__) && (defined(mpc604) || defined(mpc750) || defined(mpc603e))
55  #define DEC21140_SUPPORTED
56#endif
57
58#if defined(DEC21140_SUPPORTED)
59#include <bsp.h>
60#if defined(__i386__)
61#include <pcibios.h>
62#endif
63#if defined(__PPC__)
64#include <bsp/pci.h>
65#include <libcpu/byteorder.h>
66#include <libcpu/io.h>
67#endif
68
69#include <stdlib.h>
70#include <stdio.h>
71#include <stdarg.h>
72#include <string.h>
73#include <errno.h>
74#include <rtems/error.h>
75#include <rtems/bspIo.h>
76#include <rtems/rtems_bsdnet.h>
77
78#include <sys/param.h>
79#include <sys/mbuf.h>
80
81#include <sys/socket.h>
82#include <sys/sockio.h>
83#include <net/if.h>
84#include <netinet/in.h>
85#include <netinet/if_ether.h>
86
87#if defined(__i386__)
88#include <irq.h>
89#endif
90#if defined(__PPC__)
91#include <bsp/irq.h>
92#endif
93
94#ifdef malloc
95#undef malloc
96#endif
97#ifdef free
98#undef free
99#endif
100
101#define DEC_DEBUG
102
103/* note: the 21143 isn't really a DEC, it's an Intel chip */
104#define PCI_INVALID_VENDORDEVICEID      0xffffffff
105#define PCI_VENDOR_ID_DEC               0x1011
106#define PCI_DEVICE_ID_DEC_21140         0x0009
107#define PCI_DEVICE_ID_DEC_21143         0x0019
108
109#define DRIVER_PREFIX   "dc"
110
111#define IO_MASK   0x3
112#define MEM_MASK  0xF
113
114/* command and status registers, 32-bit access, only if IO-ACCESS */
115#define ioCSR0  0x00    /* bus mode register */
116#define ioCSR1  0x08    /* transmit poll demand */
117#define ioCSR2  0x10    /* receive poll demand */
118#define ioCSR3  0x18    /* receive list base address */
119#define ioCSR4  0x20    /* transmit list base address */
120#define ioCSR5  0x28    /* status register */
121#define ioCSR6  0x30    /* operation mode register */
122#define ioCSR7  0x38    /* interrupt mask register */
123#define ioCSR8  0x40    /* missed frame counter */
124#define ioCSR9  0x48    /* Ethernet ROM register */
125#define ioCSR10 0x50    /* reserved */
126#define ioCSR11 0x58    /* full-duplex register */
127#define ioCSR12 0x60    /* SIA status register */
128#define ioCSR13 0x68
129#define ioCSR14 0x70
130#define ioCSR15 0x78    /* SIA general register */
131
132/* command and status registers, 32-bit access, only if MEMORY-ACCESS */
133#define memCSR0  0x00   /* bus mode register */
134#define memCSR1  0x02   /* transmit poll demand */
135#define memCSR2  0x04   /* receive poll demand */
136#define memCSR3  0x06   /* receive list base address */
137#define memCSR4  0x08   /* transmit list base address */
138#define memCSR5  0x0A   /* status register */
139#define memCSR6  0x0C   /* operation mode register */
140#define memCSR7  0x0E   /* interrupt mask register */
141#define memCSR8  0x10   /* missed frame counter */
142#define memCSR9  0x12   /* Ethernet ROM register */
143#define memCSR10 0x14   /* reserved */
144#define memCSR11 0x16   /* full-duplex register */
145#define memCSR12 0x18   /* SIA status register */
146#define memCSR13 0x1A
147#define memCSR14 0x1C
148#define memCSR15 0x1E   /* SIA general register */
149
150#define DEC_REGISTER_SIZE    0x100   /* to reserve virtual memory */
151
152
153
154
155#define RESET_CHIP   0x00000001
156#if defined(__PPC__)
157#define CSR0_MODE    0x0030e002   /* 01b08000 */
158#else
159#define CSR0_MODE    0x0020e002   /* 01b08000 */
160#endif
161#define ROM_ADDRESS  0x00004800
162#define CSR6_INIT    0x022cc000   /* 022c0000 020c0000 */
163#define CSR6_TX      0x00002000
164#define CSR6_TXRX    0x00002002
165#define IT_SETUP     0x000100c0   /* 000100e0 */
166#define CLEAR_IT     0xFFFFFFFF
167#define NO_IT        0x00000000
168
169
170
171/* message descriptor entry */
172struct MD {
173    /* used by hardware */
174    volatile uint32_t   status;
175    volatile uint32_t   counts;
176    volatile uint32_t   buf1, buf2;
177    /* used by software */
178    volatile struct mbuf *m;
179    volatile struct MD *next;
180} __attribute__ ((packed));
181
182
183
184
185/*
186** These buffers allocated for each unit, so ensure
187**
188**   rtems_bsdnet_config.mbuf_bytecount
189**   rtems_bsdnet_config.mbuf_cluster_bytecount
190**
191** are adequately sized to provide enough clusters and mbufs for all the
192** units.  The default bsdnet configuration is sufficient for one dec
193** unit, but will be nearing exhaustion with 2 or more.  Although a
194** little expensive in memory, the following configuration should
195** eliminate all mbuf/cluster issues;
196**
197**   rtems_bsdnet_config.mbuf_bytecount           = 128*1024;
198**   rtems_bsdnet_config.mbuf_cluster_bytecount   = 256*1024;
199*/
200
201#define NRXBUFS 16      /* number of receive buffers */
202#define NTXBUFS 16      /* number of transmit buffers */
203
204
205/*
206 * Number of DEC boards supported by this driver
207 */
208#define NDECDRIVER      8
209
210
211/*
212 * Receive buffer size -- Allow for a full ethernet packet including CRC
213 */
214#define RBUF_SIZE       1536
215
216#define ET_MINLEN       60      /* minimum message length */
217
218
219/*
220** Events, one per unit.  The event is sent to the rx task from the isr
221** or from the stack to the tx task whenever a unit needs service.  The
222** rx/tx tasks identify the requesting unit(s) by their particular
223** events so only requesting units are serviced.
224*/
225
226static rtems_event_set unit_signals[NDECDRIVER]= { RTEMS_EVENT_1,
227                                                   RTEMS_EVENT_2,
228                                                   RTEMS_EVENT_3,
229                                                   RTEMS_EVENT_4,
230                                                   RTEMS_EVENT_5,
231                                                   RTEMS_EVENT_6,
232                                                   RTEMS_EVENT_7,
233                                                   RTEMS_EVENT_8 };
234
235
236#if defined(__PPC__)
237#define phys_to_bus(address) ((unsigned int)((address)) + PCI_DRAM_OFFSET)
238#define bus_to_phys(address) ((unsigned int)((address)) - PCI_DRAM_OFFSET)
239#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PPC_CACHE_ALIGNMENT
240#else
241extern void Wait_X_ms( unsigned int timeToWait );
242#define phys_to_bus(address) ((unsigned int) ((address)))
243#define bus_to_phys(address) ((unsigned int) ((address)))
244#define rtems_bsp_delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 )
245#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZE
246
247static inline void st_le32(volatile uint32_t   *addr, uint32_t   value)
248{
249  *(addr)=value ;
250}
251
252static inline uint32_t   ld_le32(volatile uint32_t   *addr)
253{
254  return(*addr);
255}
256
257#endif
258
259#if (MCLBYTES < RBUF_SIZE)
260# error "Driver must have MCLBYTES > RBUF_SIZE"
261#endif
262
263
264
265
266
267/*
268 * Per-device data
269 */
270struct dec21140_softc {
271
272      struct arpcom             arpcom;
273
274      rtems_irq_connect_data    irqInfo;
275      rtems_event_set           ioevent;
276
277      int                       numRxbuffers, numTxbuffers;
278
279      volatile struct MD        *MDbase;
280      volatile struct MD        *nextRxMD;
281      volatile unsigned char    *bufferBase;
282      int                       acceptBroadcast;
283
284      volatile struct MD   *TxMD;
285      volatile struct MD   *SentTxMD;
286      int         PendingTxCount;
287      int         TxSuspended;
288
289      unsigned int                      port;
290      volatile unsigned int             *base;
291
292      /*
293       * Statistics
294       */
295      unsigned long     rxInterrupts;
296      unsigned long     rxNotFirst;
297      unsigned long     rxNotLast;
298      unsigned long     rxGiant;
299      unsigned long     rxNonOctet;
300      unsigned long     rxRunt;
301      unsigned long     rxBadCRC;
302      unsigned long     rxOverrun;
303      unsigned long     rxCollision;
304
305      unsigned long     txInterrupts;
306      unsigned long     txDeferred;
307      unsigned long     txHeartbeat;
308      unsigned long     txLateCollision;
309      unsigned long     txRetryLimit;
310      unsigned long     txUnderrun;
311      unsigned long     txLostCarrier;
312      unsigned long     txRawWait;
313};
314
315static struct dec21140_softc dec21140_softc[NDECDRIVER];
316static rtems_id rxDaemonTid;
317static rtems_id txDaemonTid;
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335/*
336 * This routine reads a word (16 bits) from the serial EEPROM.
337 */
338/*  EEPROM_Ctrl bits. */
339#define EE_SHIFT_CLK            0x02    /* EEPROM shift clock. */
340#define EE_CS                   0x01    /* EEPROM chip select. */
341#define EE_DATA_WRITE           0x04    /* EEPROM chip data in. */
342#define EE_WRITE_0              0x01
343#define EE_WRITE_1              0x05
344#define EE_DATA_READ            0x08    /* EEPROM chip data out. */
345#define EE_ENB                  (0x4800 | EE_CS)
346
347/* The EEPROM commands include the alway-set leading bit. */
348#define EE_WRITE_CMD    (5 << 6)
349#define EE_READ_CMD     (6 << 6)
350#define EE_ERASE_CMD    (7 << 6)
351
352static int eeget16(volatile unsigned int *ioaddr, int location)
353{
354   int i;
355   unsigned short retval = 0;
356   int read_cmd = location | EE_READ_CMD;
357
358   st_le32(ioaddr, EE_ENB & ~EE_CS);
359   st_le32(ioaddr, EE_ENB);
360
361   /* Shift the read command bits out. */
362   for (i = 10; i >= 0; i--) {
363      short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
364      st_le32(ioaddr, EE_ENB | dataval);
365      rtems_bsp_delay_in_bus_cycles(200);
366      st_le32(ioaddr, EE_ENB | dataval | EE_SHIFT_CLK);
367      rtems_bsp_delay_in_bus_cycles(200);
368      st_le32(ioaddr, EE_ENB | dataval); /* Finish EEPROM a clock tick. */
369      rtems_bsp_delay_in_bus_cycles(200);
370   }
371   st_le32(ioaddr, EE_ENB);
372
373   for (i = 16; i > 0; i--) {
374      st_le32(ioaddr, EE_ENB | EE_SHIFT_CLK);
375      rtems_bsp_delay_in_bus_cycles(200);
376      retval = (retval << 1) | ((ld_le32(ioaddr) & EE_DATA_READ) ? 1 : 0);
377      st_le32(ioaddr, EE_ENB);
378      rtems_bsp_delay_in_bus_cycles(200);
379   }
380
381   /* Terminate the EEPROM access. */
382   st_le32(ioaddr, EE_ENB & ~EE_CS);
383   return ( ((retval<<8)&0xff00) | ((retval>>8)&0xff) );
384}
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407static void no_op(const rtems_irq_connect_data* irq)
408{
409   return;
410}
411
412
413
414
415static int dec21140IsOn(const rtems_irq_connect_data* irq)
416{
417  return BSP_irq_enabled_at_i8259s (irq->name);
418}
419
420
421
422
423/*
424 * DEC21140 interrupt handler
425 */
426static rtems_isr
427dec21140Enet_interrupt_handler ( struct dec21140_softc *sc )
428{
429   volatile uint32_t      *tbase;
430   uint32_t               status;
431
432   tbase = (uint32_t*)(sc->base);
433
434   /*
435    * Read status
436    */
437   status = ld_le32(tbase+memCSR5);
438   st_le32((tbase+memCSR5), status);
439
440   /*
441    * Frame received?
442    */
443   if( status & 0x000000c0 )
444   {
445      sc->rxInterrupts++;
446      rtems_event_send(rxDaemonTid, sc->ioevent);
447   }
448}
449
450
451
452static rtems_isr
453dec21140Enet_interrupt_handler_entry()
454{
455   int i;
456
457   /*
458   ** Check all the initialized dec units for interrupt service
459   */
460
461   for(i=0; i< NDECDRIVER; i++ )
462   {
463      if( dec21140_softc[i].base )
464         dec21140Enet_interrupt_handler( &dec21140_softc[i] );
465   }
466}
467
468
469
470
471
472
473
474
475
476
477/*
478 * Initialize the ethernet hardware
479 */
480static void
481dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
482{
483   int i,st;
484   volatile unsigned int  *tbase;
485   volatile unsigned char *cp, *setup_frm, *eaddrs;
486   volatile unsigned char *buffer;
487   volatile struct MD     *rmd;
488
489
490#ifdef DEC_DEBUG
491   printk("dec2114x : %02x:%02x:%02x:%02x:%02x:%02x   name '%s%d', io %x, mem %x, int %d\n",
492          sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
493          sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
494          sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
495          sc->arpcom.ac_if.if_name, sc->arpcom.ac_if.if_unit,
496          sc->port, (unsigned) sc->base, sc->irqInfo.name );
497#endif
498
499
500
501   tbase = sc->base;
502
503   /*
504    * WARNING : First write in CSR6
505    *           Then Reset the chip ( 1 in CSR0)
506    */
507   st_le32( (tbase+memCSR6), CSR6_INIT);
508   st_le32( (tbase+memCSR0), RESET_CHIP);
509   rtems_bsp_delay_in_bus_cycles(200);
510
511   st_le32( (tbase+memCSR7), NO_IT);
512
513   /*
514    * Init CSR0
515    */
516   st_le32( (tbase+memCSR0), CSR0_MODE);
517
518   /*
519    * Init RX ring
520    */
521   cp = (volatile unsigned char *)malloc(((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD))
522                                         + (sc->numTxbuffers*RBUF_SIZE)
523                                         + CPU_CACHE_ALIGNMENT_FOR_BUFFER);
524   sc->bufferBase = cp;
525   cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp) & (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);
526#if defined(__i386__)
527#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
528   if (_CPU_is_paging_enabled())
529      _CPU_change_memory_mapping_attribute
530         (NULL, cp,
531          ((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD))
532          + (sc->numTxbuffers*RBUF_SIZE),
533          PTE_CACHE_DISABLE | PTE_WRITABLE);
534#endif
535#endif
536   rmd = (volatile struct MD*)cp;
537   sc->MDbase = rmd;
538   sc->nextRxMD = sc->MDbase;
539
540   buffer = cp + ((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD));
541   st_le32( (tbase+memCSR3), (long)(phys_to_bus((long)(sc->MDbase))));
542
543   for (i=0 ; i<sc->numRxbuffers; i++)
544   {
545      struct mbuf *m;
546
547      /* allocate an mbuf for each receive descriptor */
548      MGETHDR (m, M_WAIT, MT_DATA);
549      MCLGET (m, M_WAIT);
550      m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
551      rmd->m = m;
552
553      rmd->buf2   = phys_to_bus(rmd+1);
554      rmd->buf1   = phys_to_bus(mtod(m, void *));
555      rmd->status = 0x80000000;
556      rmd->counts = 0xfdc00000 | (RBUF_SIZE);
557      rmd->next   = rmd+1;
558      rmd++;
559   }
560   /*
561    * mark last RX buffer.
562    */
563   sc->MDbase [sc->numRxbuffers-1].buf2   = 0;
564   sc->MDbase [sc->numRxbuffers-1].counts = 0xfec00000 | (RBUF_SIZE);
565   sc->MDbase [sc->numRxbuffers-1].next   = sc->MDbase;
566
567
568
569   /*
570    * Init TX ring
571    */
572   st_le32( (tbase+memCSR4), (long)(phys_to_bus((long)(rmd))) );
573   for (i=0 ; i<sc->numTxbuffers; i++){
574      (rmd+i)->buf2   = phys_to_bus(rmd+i+1);
575      (rmd+i)->buf1   = phys_to_bus(buffer + (i*RBUF_SIZE));
576      (rmd+i)->counts = 0x01000000;
577      (rmd+i)->status = 0x0;
578      (rmd+i)->next   = rmd+i+1;
579      (rmd+i)->m      = 0;
580   }
581
582   /*
583    * mark last TX buffer.
584    */
585   (rmd+sc->numTxbuffers-1)->buf2   = phys_to_bus(rmd);
586   (rmd+sc->numTxbuffers-1)->next   = rmd;
587
588
589   /*
590    * Build setup frame
591    */
592   setup_frm = (volatile unsigned char *)(bus_to_phys(rmd->buf1));
593   eaddrs = (char *)(sc->arpcom.ac_enaddr);
594   /* Fill the buffer with our physical address. */
595   for (i = 1; i < 16; i++) {
596      *setup_frm++ = eaddrs[0];
597      *setup_frm++ = eaddrs[1];
598      *setup_frm++ = eaddrs[0];
599      *setup_frm++ = eaddrs[1];
600      *setup_frm++ = eaddrs[2];
601      *setup_frm++ = eaddrs[3];
602      *setup_frm++ = eaddrs[2];
603      *setup_frm++ = eaddrs[3];
604      *setup_frm++ = eaddrs[4];
605      *setup_frm++ = eaddrs[5];
606      *setup_frm++ = eaddrs[4];
607      *setup_frm++ = eaddrs[5];
608   }
609
610   /* Add the broadcast address when doing perfect filtering */
611   memset((void*) setup_frm, 0xff, 12);
612   rmd->counts = 0x09000000 | 192 ;
613   rmd->status = 0x80000000;
614   st_le32( (tbase+memCSR6), CSR6_INIT | CSR6_TX);
615   st_le32( (tbase+memCSR1), 1);
616
617   while (rmd->status != 0x7fffffff);
618   rmd->counts = 0x01000000;
619
620   sc->TxMD = rmd+1;
621
622
623
624
625
626   sc->irqInfo.hdl  = (rtems_irq_hdl)dec21140Enet_interrupt_handler_entry;
627   sc->irqInfo.on   = no_op;
628   sc->irqInfo.off  = no_op;
629   sc->irqInfo.isOn = dec21140IsOn;
630
631#ifdef BSP_SHARED_HANDLER_SUPPORT
632   st = BSP_install_rtems_shared_irq_handler( &sc->irqInfo );
633#else
634   st = BSP_install_rtems_irq_handler( &sc->irqInfo );
635#endif
636
637   if (!st)
638      rtems_panic ("dec2114x : Interrupt name %d already in use\n", sc->irqInfo.name );
639}
640
641
642
643
644
645
646
647static void
648dec21140_rxDaemon (void *arg)
649{
650   volatile unsigned int *tbase;
651   volatile struct MD    *rmd;
652   struct dec21140_softc *sc;
653   struct ifnet          *ifp;
654   struct ether_header   *eh;
655   struct mbuf           *m;
656   unsigned int          i,len;
657   rtems_event_set       events;
658
659   for (;;)
660   {
661
662      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
663                                  RTEMS_WAIT|RTEMS_EVENT_ANY,
664                                  RTEMS_NO_TIMEOUT,
665                                  &events);
666
667      for(i=0; i< NDECDRIVER; i++ )
668      {
669         sc = &dec21140_softc[i];
670         if( sc->base )
671         {
672            if( events & sc->ioevent )
673            {
674               ifp   = &sc->arpcom.ac_if;
675               tbase = sc->base;
676               rmd   = sc->nextRxMD;
677
678               /*
679               ** Read off all the packets we've received on this unit
680               */
681               while((rmd->status & 0x80000000) == 0)
682               {
683                  /* printk("unit %i rx\n", ifp->if_unit ); */
684
685                  /* pass on the packet in the mbuf */
686                  len = (rmd->status >> 16) & 0x7ff;
687                  m = (struct mbuf *)(rmd->m);
688                  m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
689                  eh = mtod (m, struct ether_header *);
690                  m->m_data += sizeof(struct ether_header);
691                  ether_input (ifp, eh, m);
692
693                  /* get a new mbuf for the 21140 */
694                  MGETHDR (m, M_WAIT, MT_DATA);
695                  MCLGET (m, M_WAIT);
696                  m->m_pkthdr.rcvif = ifp;
697                  rmd->m = m;
698                  rmd->buf1 = phys_to_bus(mtod(m, void *));
699
700                  /* mark the descriptor as ready to receive */
701                  rmd->status = 0x80000000;
702
703                  rmd=rmd->next;
704               }
705
706               sc->nextRxMD = rmd;
707            }
708         }
709      }
710
711   }
712}
713
714
715
716
717
718
719
720static void
721sendpacket (struct ifnet *ifp, struct mbuf *m)
722{
723   struct dec21140_softc   *dp = ifp->if_softc;
724   volatile struct MD      *tmd;
725   volatile unsigned char  *temp;
726   struct mbuf             *n;
727   unsigned int            len;
728   volatile unsigned int   *tbase;
729
730   tbase = dp->base;
731   /*
732    * Waiting for Transmitter ready
733    */
734
735   tmd = dp->TxMD;
736   n = m;
737
738   while ((tmd->status & 0x80000000) != 0)
739   {
740      tmd=tmd->next;
741   }
742
743   len = 0;
744   temp = (volatile unsigned char *)(bus_to_phys(tmd->buf1));
745
746   for (;;)
747   {
748      len += m->m_len;
749      memcpy((void*) temp, (char *)m->m_data, m->m_len);
750      temp += m->m_len ;
751      if ((m = m->m_next) == NULL)
752         break;
753   }
754
755   if (len < ET_MINLEN) len = ET_MINLEN;
756   tmd->counts =  0xe1000000 | (len & 0x7ff);
757   tmd->status = 0x80000000;
758
759   st_le32( (tbase+memCSR1), 0x1);
760
761   m_freem(n);
762
763   dp->TxMD = tmd->next;
764}
765
766
767
768
769
770/*
771 * Driver transmit daemon
772 */
773void
774dec21140_txDaemon (void *arg)
775{
776   struct dec21140_softc *sc;
777   struct ifnet          *ifp;
778   struct mbuf           *m;
779   int i;
780   rtems_event_set       events;
781
782   for (;;)
783   {
784      /*
785       * Wait for packets bound for any of the dec units
786       */
787      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
788                                  RTEMS_EVENT_ANY | RTEMS_WAIT,
789                                  RTEMS_NO_TIMEOUT, &events);
790
791      for(i=0; i< NDECDRIVER; i++ )
792      {
793         sc  = &dec21140_softc[i];
794         if( sc->base )
795         {
796            if( events & sc->ioevent )
797            {
798               ifp = &sc->arpcom.ac_if;
799
800               /*
801                * Send packets till queue is empty
802                */
803               for(;;)
804               {
805                  IF_DEQUEUE(&ifp->if_snd, m);
806                  if( !m ) break;
807                  /* printk("unit %i tx\n", ifp->if_unit ); */
808                  sendpacket (ifp, m);
809               }
810
811               ifp->if_flags &= ~IFF_OACTIVE;
812            }
813         }
814      }
815
816   }
817}
818
819
820
821
822static void
823dec21140_start (struct ifnet *ifp)
824{
825   struct dec21140_softc *sc = ifp->if_softc;
826   rtems_event_send( txDaemonTid, sc->ioevent );
827   ifp->if_flags |= IFF_OACTIVE;
828}
829
830
831
832
833
834/*
835 * Initialize and start the device
836 */
837static void
838dec21140_init (void *arg)
839{
840   struct dec21140_softc *sc = arg;
841   struct ifnet *ifp = &sc->arpcom.ac_if;
842   volatile unsigned int *tbase;
843
844   /*
845    * Set up DEC21140 hardware if its not already been done
846    */
847   if( !sc->irqInfo.hdl )
848   {
849      dec21140Enet_initialize_hardware (sc);
850   }
851
852   /*
853    * Enable RX and TX
854    */
855   tbase = sc->base;
856   st_le32( (tbase+memCSR5), IT_SETUP);
857   st_le32( (tbase+memCSR7), IT_SETUP);
858   st_le32( (unsigned int*)(tbase+memCSR6), CSR6_INIT | CSR6_TXRX);
859
860   /*
861    * Tell the world that we're running.
862    */
863   ifp->if_flags |= IFF_RUNNING;
864}
865
866
867
868
869
870
871
872/*
873 * Stop the device
874 */
875static void
876dec21140_stop (struct dec21140_softc *sc)
877{
878  volatile unsigned int *tbase;
879  struct ifnet *ifp = &sc->arpcom.ac_if;
880
881  ifp->if_flags &= ~IFF_RUNNING;
882
883  /*
884   * Stop the transmitter
885   */
886  tbase = sc->base;
887  st_le32( (tbase+memCSR7), NO_IT);
888  st_le32( (tbase+memCSR6), CSR6_INIT);
889
890  /*  free((void*)sc->bufferBase); */
891}
892
893
894/*
895 * Show interface statistics
896 */
897static void
898dec21140_stats (struct dec21140_softc *sc)
899{
900        printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);
901        printf ("       Not First:%-8lu", sc->rxNotFirst);
902        printf ("        Not Last:%-8lu\n", sc->rxNotLast);
903        printf ("              Giant:%-8lu", sc->rxGiant);
904        printf ("            Runt:%-8lu", sc->rxRunt);
905        printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);
906        printf ("            Bad CRC:%-8lu", sc->rxBadCRC);
907        printf ("         Overrun:%-8lu", sc->rxOverrun);
908        printf ("       Collision:%-8lu\n", sc->rxCollision);
909
910        printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
911        printf ("        Deferred:%-8lu", sc->txDeferred);
912        printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
913        printf ("         No Carrier:%-8lu", sc->txLostCarrier);
914        printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
915        printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
916        printf ("           Underrun:%-8lu", sc->txUnderrun);
917        printf (" Raw output wait:%-8lu\n", sc->txRawWait);
918}
919
920
921
922
923/*
924 * Driver ioctl handler
925 */
926static int
927dec21140_ioctl (struct ifnet *ifp, int command, caddr_t data)
928{
929   struct dec21140_softc *sc = ifp->if_softc;
930   int error = 0;
931
932   switch (command) {
933      case SIOCGIFADDR:
934      case SIOCSIFADDR:
935         ether_ioctl (ifp, command, data);
936         break;
937
938      case SIOCSIFFLAGS:
939         switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
940            case IFF_RUNNING:
941               dec21140_stop (sc);
942               break;
943
944            case IFF_UP:
945               dec21140_init (sc);
946               break;
947
948            case IFF_UP | IFF_RUNNING:
949               dec21140_stop (sc);
950               dec21140_init (sc);
951               break;
952
953            default:
954               break;
955         }
956         break;
957
958      case SIO_RTEMS_SHOW_STATS:
959         dec21140_stats (sc);
960         break;
961
962         /*
963          * FIXME: All sorts of multicast commands need to be added here!
964          */
965      default:
966         error = EINVAL;
967         break;
968   }
969
970   return error;
971}
972
973
974
975
976
977
978
979/*
980int iftap(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m )
981{
982   int i;
983
984   if(  ifp->if_unit == 1 ) return 0;
985
986   printf("unit %i, src ", ifp->if_unit );
987   for(i=0; i< ETHER_ADDR_LEN; i++) printf("%02x", (char) eh->ether_shost[i] );
988   printf(" dest ");
989   for(i=0; i< ETHER_ADDR_LEN; i++) printf("%02x", (char) eh->ether_dhost[i] );
990   printf("\n");
991
992   return -1;
993}
994*/
995
996
997
998
999
1000/*
1001 * Attach an DEC21140 driver to the system
1002 */
1003int
1004rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
1005{
1006   struct dec21140_softc *sc;
1007   struct ifnet *ifp;
1008   char         *unitName;
1009   int          unitNumber;
1010   int          mtu;
1011   unsigned char cvalue;
1012#if defined(__i386__)
1013   int          signature;
1014   int          value;
1015   char         interrupt;
1016   int          diag;
1017   unsigned int deviceId;
1018#endif
1019#if defined(__PPC__)
1020   int          pbus, pdev, pfun;
1021   int          tmp;
1022   unsigned int lvalue;
1023#endif
1024
1025
1026   /*
1027    * Get the instance number for the board we're going to configure
1028    * from the user.
1029    */
1030   if( (unitNumber = rtems_bsdnet_parse_driver_name( config, &unitName)) == -1 )
1031   {
1032      return 0;
1033   }
1034   if( strcmp(unitName, DRIVER_PREFIX) )
1035   {
1036      printk("dec2114x : unit name '%s' not %s\n", unitName, DRIVER_PREFIX );
1037      return 0;
1038   }
1039
1040
1041#if defined(__i386__)
1042   /*
1043    * First, find a DEC board
1044    */
1045
1046   if (pcib_init() == PCIB_ERR_NOTPRESENT)
1047      rtems_panic("PCI BIOS not found !!");
1048
1049   /*
1050    * Try to find the network card on the PCI bus. Probe for a DEC 21140
1051    * card first. If not found probe the bus for a DEC/Intel 21143 card.
1052    */
1053   deviceId = PCI_DEVICE_ID_DEC_21140;
1054   diag = pcib_find_by_devid( PCI_VENDOR_ID_DEC, deviceId, unitNumber-1, &signature);
1055
1056   if ( diag == PCIB_ERR_SUCCESS)
1057      printk( "DEC 21140 PCI network card found\n" );
1058   else
1059   {
1060      deviceId = PCI_DEVICE_ID_DEC_21143;
1061      diag = pcib_find_by_devid( PCI_VENDOR_ID_DEC, deviceId, unitNumber-1, &signature);
1062      if ( diag == PCIB_ERR_SUCCESS)
1063         printk( "DEC/Intel 21143 PCI network card found\n" );
1064      else
1065      {
1066         printk("No DEC/Intel 21140/3 PCI network card found !!\n");
1067         return 0;
1068      }
1069   }
1070#endif
1071#if defined(__PPC__)
1072   /*
1073    * Find the board
1074    */
1075   if( BSP_pciFindDevice( PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21140,
1076                          unitNumber-1, &pbus, &pdev, &pfun) == -1 )
1077   {
1078      if( BSP_pciFindDevice( PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21143,
1079                             unitNumber-1, &pbus, &pdev, &pfun) != -1 )
1080      {
1081         printk("dec21143 : found device '%s', PPC support has not been tested.  Using it anyway.\n",
1082                config->name );
1083
1084         pci_write_config_dword(pbus,
1085                                pdev,
1086                                pfun,
1087                                0x40,
1088                                PCI_DEVICE_ID_DEC_21143 );
1089
1090      }
1091      else
1092      {
1093         printk("dec2114x : device '%s' not found on PCI bus\n", config->name );
1094         return 0;
1095      }
1096   }
1097
1098#ifdef DEC_DEBUG
1099   else
1100   {
1101      printk("dec21140 : found device '%s', bus 0x%02x, dev 0x%02x, func 0x%02x\n",
1102             config->name, pbus, pdev, pfun);
1103   }
1104#endif
1105
1106#endif
1107
1108
1109
1110
1111   if ((unitNumber < 1) || (unitNumber > NDECDRIVER))
1112   {
1113      printk("dec2114x : unit %i is invalid, must be (1 <= n <= %d)\n", unitNumber);
1114      return 0;
1115   }
1116
1117   sc = &dec21140_softc[unitNumber - 1];
1118   ifp = &sc->arpcom.ac_if;
1119   if (ifp->if_softc != NULL)
1120   {
1121      printk("dec2114x : unit %i already in use.\n", unitNumber );
1122      return 0;
1123   }
1124
1125
1126   /*
1127   ** Get this unit's rx/tx event
1128   */
1129   sc->ioevent = unit_signals[unitNumber-1];
1130
1131   /*
1132   ** Save the buffer counts
1133   */
1134   sc->numRxbuffers = (config->rbuf_count) ? config->rbuf_count : NRXBUFS;
1135   sc->numTxbuffers = (config->xbuf_count) ? config->xbuf_count : NTXBUFS;
1136
1137
1138   /*
1139    * Get card address spaces & retrieve its isr vector
1140    */
1141#if defined(__i386__)
1142
1143   /* the 21143 chip must be enabled before it can be accessed */
1144   if ( deviceId == PCI_DEVICE_ID_DEC_21143 )
1145      pcib_conf_write32( signature, 0x40, 0 );
1146
1147   pcib_conf_read32(signature, 16, &value);
1148   sc->port = value & ~IO_MASK;
1149
1150   pcib_conf_read32(signature, 20, &value);
1151   if (_CPU_is_paging_enabled())
1152      _CPU_map_phys_address((void **) &(sc->base),
1153                            (void *)(value & ~MEM_MASK),
1154                            DEC_REGISTER_SIZE ,
1155                            PTE_CACHE_DISABLE | PTE_WRITABLE);
1156   else
1157      sc->base = (unsigned int *)(value & ~MEM_MASK);
1158
1159   pcib_conf_read8(signature, 60, &interrupt);
1160   cvalue = interrupt;
1161#endif
1162#if defined(__PPC__)
1163   (void)pci_read_config_dword(pbus,
1164                               pdev,
1165                               pfun,
1166                               PCI_BASE_ADDRESS_0,
1167                               &lvalue);
1168
1169   sc->port = lvalue & (unsigned int)(~IO_MASK);
1170
1171   (void)pci_read_config_dword(pbus,
1172                               pdev,
1173                               pfun,
1174                               PCI_BASE_ADDRESS_1,
1175                               &lvalue);
1176
1177   tmp = (unsigned int)(lvalue & (unsigned int)(~MEM_MASK))
1178      + (unsigned int)PCI_MEM_BASE;
1179
1180   sc->base = (unsigned int *)(tmp);
1181
1182   pci_read_config_byte(pbus,
1183                        pdev,
1184                        pfun,
1185                        PCI_INTERRUPT_LINE,
1186                        &cvalue);
1187
1188#endif
1189
1190   /*
1191   ** Prep the board
1192   */
1193
1194#if defined(__PPC__)
1195   pci_write_config_word(pbus, pdev, pfun,
1196#endif
1197#if defined(__i386__)
1198   pcib_conf_write16(signature, 
1199#endif
1200      PCI_COMMAND,
1201      (uint16_t) ( PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER ) );
1202
1203   /*
1204   ** Store the interrupt name, we'll use it later when we initialize
1205   ** the board.
1206   */
1207   memset(&sc->irqInfo,0,sizeof(rtems_irq_connect_data));
1208   sc->irqInfo.name = cvalue;
1209
1210
1211   /* printk("dec2114x : unit %d base address %08x.\n", unitNumber, sc->base ); */
1212
1213
1214   /*
1215   ** Setup ethernet address
1216   */
1217   if (config->hardware_address) {
1218      memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
1219              ETHER_ADDR_LEN);
1220   }
1221   else {
1222      union {char c[64]; unsigned short s[32];} rombuf;
1223      int i;
1224
1225      for (i=0; i<32; i++){
1226         rombuf.s[i] = eeget16( sc->base + memCSR9, i);
1227      }
1228#if defined(__i386__)
1229      for (i=0 ; i<(ETHER_ADDR_LEN/2); i++){
1230         sc->arpcom.ac_enaddr[2*i]   = rombuf.c[20+2*i+1];
1231         sc->arpcom.ac_enaddr[2*i+1] = rombuf.c[20+2*i];
1232      }
1233#endif
1234#if defined(__PPC__)
1235      memcpy (sc->arpcom.ac_enaddr, rombuf.c+20, ETHER_ADDR_LEN);
1236#endif
1237   }
1238
1239   if (config->mtu)
1240      mtu = config->mtu;
1241   else
1242      mtu = ETHERMTU;
1243
1244   sc->acceptBroadcast = !config->ignore_broadcast;
1245
1246   /*
1247    * Set up network interface values
1248    */
1249
1250/*   ifp->if_tap = iftap; */
1251
1252   ifp->if_softc = sc;
1253   ifp->if_unit = unitNumber;
1254   ifp->if_name = unitName;
1255   ifp->if_mtu = mtu;
1256   ifp->if_init = dec21140_init;
1257   ifp->if_ioctl = dec21140_ioctl;
1258   ifp->if_start = dec21140_start;
1259   ifp->if_output = ether_output;
1260   ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
1261   if (ifp->if_snd.ifq_maxlen == 0)
1262      ifp->if_snd.ifq_maxlen = ifqmaxlen;
1263
1264   /*
1265    * Attach the interface
1266    */
1267   if_attach (ifp);
1268   ether_ifattach (ifp);
1269
1270#ifdef DEC_DEBUG
1271   printk( "dec2114x : driver attached\n" );
1272#endif
1273
1274
1275   /*
1276    * Start driver tasks if this is the first dec unit initialized
1277    */
1278   if (txDaemonTid == 0)
1279   {
1280      rxDaemonTid = rtems_bsdnet_newproc( "DCrx", 4096,
1281                                          dec21140_rxDaemon, NULL);
1282
1283      txDaemonTid = rtems_bsdnet_newproc( "DCtx", 4096,
1284                                          dec21140_txDaemon, NULL);
1285#ifdef DEC_DEBUG
1286      printk( "dec2114x : driver tasks created\n" );
1287#endif
1288   }
1289
1290   return 1;
1291};
1292
1293#endif /* DEC21140_SUPPORTED */
Note: See TracBrowser for help on using the repository browser.