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

4.104.114.84.95
Last change on this file since efab64d was efab64d, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/11/04 at 09:09:41

2004-10-11 Ralf Corsepius <ralf_corsepius@…>

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