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

4.104.115
Last change on this file since b0f45d8 was 0b6ca8aa, checked in by Joel Sherrill <joel.sherrill@…>, on 09/20/08 at 22:20:14

2008-09-20 Joel Sherrill <joel.sherrill@…>

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