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

4.104.114.84.95
Last change on this file since f82dabae was f82dabae, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/04/05 at 18:09:59

Use libcpu/byteorder.h for i386.

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