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

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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