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

Last change on this file since d3f0606 was d3f0606, checked in by Joel Sherrill <joel.sherrill@…>, on 09/27/04 at 17:33:07

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

PR 607/networking

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