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

4.104.114.84.95
Last change on this file since cd38196f was cd38196f, checked in by Joel Sherrill <joel.sherrill@…>, on 09/27/04 at 17:34:00

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

PR 607/networking

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