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

4.104.114.84.95
Last change on this file since c22aeb4 was c22aeb4, checked in by Joel Sherrill <joel.sherrill@…>, on 10/31/02 at 20:13:18

2002-10-31 Joel Sherrill <joel@…>

  • network/dec21140.c: Removed warnings.
  • Property mode set to 100644
File size: 23.9 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.OARcorp.com/rtems/license.html.
9 *
10 * $Id$
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 * ------------------------------------------------------------------------
28 */
29
30#include <rtems.h>
31
32/*
33 *  This driver only supports architectures with the new style
34 *  exception processing.  The following checks try to keep this
35 *  from being compiled on systems which can't support this driver.
36 */
37
38#if defined(__i386__)
39  #define DEC21140_SUPPORTED
40#endif
41
42#if defined(__PPC__) && (defined(mpc604) || defined(mpc750))
43  #define DEC21140_SUPPORTED
44#endif
45
46#if defined(DEC21140_SUPPORTED)
47#include <bsp.h>
48#if defined(__i386__)
49#include <pcibios.h>
50#endif
51#if defined(__PPC__)
52#include <bsp/pci.h>
53#include <libcpu/byteorder.h>
54#include <libcpu/io.h>
55#endif
56
57#include <stdlib.h>
58#include <stdio.h>
59#include <stdarg.h>
60#include <rtems/error.h>
61#include <rtems/bspIo.h>
62#include <rtems/rtems_bsdnet.h>
63
64#include <sys/param.h>
65#include <sys/mbuf.h>
66
67#include <sys/socket.h>
68#include <sys/sockio.h>
69#include <net/if.h>
70#include <netinet/in.h>
71#include <netinet/if_ether.h>
72 
73#if defined(__i386__)
74#include <irq.h>
75#endif
76#if defined(__PPC)
77#include <bsp/irq.h>
78#endif
79
80#ifdef malloc
81#undef malloc
82#endif
83#ifdef free
84#undef free
85#endif
86
87#define DEC_DEBUG
88
89/* note: the 21143 isn't really a DEC, it's an Intel chip */
90#define PCI_INVALID_VENDORDEVICEID      0xffffffff
91#define PCI_VENDOR_ID_DEC 0x1011
92#define PCI_DEVICE_ID_DEC_21140 0x0009
93#define PCI_DEVICE_ID_DEC_21143 0x0019
94
95#define IO_MASK  0x3
96#define MEM_MASK  0xF
97
98/* command and status registers, 32-bit access, only if IO-ACCESS */
99#define ioCSR0  0x00    /* bus mode register */
100#define ioCSR1  0x08    /* transmit poll demand */
101#define ioCSR2  0x10    /* receive poll demand */
102#define ioCSR3  0x18    /* receive list base address */
103#define ioCSR4  0x20    /* transmit list base address */
104#define ioCSR5  0x28    /* status register */
105#define ioCSR6  0x30    /* operation mode register */
106#define ioCSR7  0x38    /* interrupt mask register */
107#define ioCSR8  0x40    /* missed frame counter */
108#define ioCSR9  0x48    /* Ethernet ROM register */
109#define ioCSR10 0x50    /* reserved */
110#define ioCSR11 0x58    /* full-duplex register */
111#define ioCSR12 0x60    /* SIA status register */
112#define ioCSR13 0x68
113#define ioCSR14 0x70
114#define ioCSR15 0x78    /* SIA general register */
115
116/* command and status registers, 32-bit access, only if MEMORY-ACCESS */
117#define memCSR0  0x00   /* bus mode register */
118#define memCSR1  0x02   /* transmit poll demand */
119#define memCSR2  0x04   /* receive poll demand */
120#define memCSR3  0x06   /* receive list base address */
121#define memCSR4  0x08   /* transmit list base address */
122#define memCSR5  0x0A   /* status register */
123#define memCSR6  0x0C   /* operation mode register */
124#define memCSR7  0x0E   /* interrupt mask register */
125#define memCSR8  0x10   /* missed frame counter */
126#define memCSR9  0x12   /* Ethernet ROM register */
127#define memCSR10 0x14   /* reserved */
128#define memCSR11 0x16   /* full-duplex register */
129#define memCSR12 0x18   /* SIA status register */
130#define memCSR13 0x1A
131#define memCSR14 0x1C
132#define memCSR15 0x1E   /* SIA general register */
133
134#define DEC_REGISTER_SIZE    0x100   /* to reserve virtual memory */
135
136#define RESET_CHIP   0x00000001
137#if defined(__PPC)
138#define CSR0_MODE    0x0030e002   /* 01b08000 */
139#else
140#define CSR0_MODE    0x0020e002   /* 01b08000 */
141#endif
142#define ROM_ADDRESS  0x00004800
143#define CSR6_INIT    0x022cc000   /* 022c0000 020c0000 */ 
144#define CSR6_TX      0x00002000   
145#define CSR6_TXRX    0x00002002   
146#define IT_SETUP     0x000100c0   /* 000100e0 */
147#define CLEAR_IT     0xFFFFFFFF   
148#define NO_IT        0x00000000   
149
150#define NRXBUFS 32      /* number of receive buffers */
151#define NTXBUFS 16      /* number of transmit buffers */
152
153/* message descriptor entry */
154struct MD {
155    /* used by hardware */
156    volatile unsigned32 status;
157    volatile unsigned32 counts;
158    unsigned32 buf1, buf2; 
159    /* used by software */
160    volatile struct mbuf *m;
161    volatile struct MD *next;
162};
163
164/*
165 * Number of DECs supported by this driver
166 */
167#define NDECDRIVER      1
168
169/*
170 * Receive buffer size -- Allow for a full ethernet packet including CRC
171 */
172#define RBUF_SIZE       1536
173
174#define ET_MINLEN 60            /* minimum message length */
175
176/*
177 * RTEMS event used by interrupt handler to signal driver tasks.
178 * This must not be any of the events used by the network task synchronization.
179 */
180#define INTERRUPT_EVENT RTEMS_EVENT_1
181
182/*
183 * RTEMS event used to start transmit daemon.
184 * This must not be the same as INTERRUPT_EVENT.
185 */
186#define START_TRANSMIT_EVENT    RTEMS_EVENT_2
187
188#if defined(__PPC)
189#define phys_to_bus(address) ((unsigned int)((address)) + PCI_DRAM_OFFSET)
190#define bus_to_phys(address) ((unsigned int)((address)) - PCI_DRAM_OFFSET)
191#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PPC_CACHE_ALIGNMENT
192#else
193extern void Wait_X_ms( unsigned int timeToWait );
194#define phys_to_bus(address) ((unsigned int) ((address)))
195#define bus_to_phys(address) ((unsigned int) ((address)))
196#define rtems_bsp_delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 )
197#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZE
198
199inline void st_le32(volatile unsigned32 *addr, unsigned32 value)
200{
201  *(addr)=value ;
202}
203
204inline unsigned32 ld_le32(volatile unsigned32 *addr)
205{
206  return(*addr);
207}
208
209#endif
210
211#if (MCLBYTES < RBUF_SIZE)
212# error "Driver must have MCLBYTES > RBUF_SIZE"
213#endif
214
215/*
216 * Per-device data
217 */
218 struct dec21140_softc {
219
220   struct arpcom                        arpcom;
221
222   rtems_irq_connect_data       irqInfo;
223
224   volatile struct MD           *MDbase;
225   volatile unsigned char       *bufferBase;
226   int                          acceptBroadcast;
227   rtems_id                     rxDaemonTid;
228   rtems_id                     txDaemonTid;
229   
230   volatile struct MD   *TxMD;
231   volatile struct MD   *SentTxMD;
232   int         PendingTxCount;
233   int         TxSuspended;
234
235  unsigned int                  port;
236  volatile unsigned int         *base;
237   
238  /*
239   * Statistics
240   */
241  unsigned long rxInterrupts;
242  unsigned long rxNotFirst;
243  unsigned long rxNotLast;
244  unsigned long rxGiant;
245  unsigned long rxNonOctet;
246  unsigned long rxRunt;
247  unsigned long rxBadCRC;
248  unsigned long rxOverrun;
249  unsigned long rxCollision;
250 
251  unsigned long txInterrupts;
252  unsigned long txDeferred;
253  unsigned long txHeartbeat;
254  unsigned long txLateCollision;
255  unsigned long txRetryLimit;
256  unsigned long txUnderrun;
257  unsigned long txLostCarrier;
258  unsigned long txRawWait;
259};
260
261static struct dec21140_softc dec21140_softc[NDECDRIVER];
262
263/*
264 * DEC21140 interrupt handler
265 */
266static rtems_isr
267dec21140Enet_interrupt_handler (rtems_vector_number v)
268{
269    volatile unsigned32 *tbase;
270    unsigned32 status;
271    struct dec21140_softc *sc;
272
273    sc = &dec21140_softc[0];
274    tbase = (unsigned32 *)(sc->base) ;
275
276    /*
277     * Read status
278     */
279    status = ld_le32(tbase+memCSR5);
280    st_le32((tbase+memCSR5), status); /* clear the bits we've read */
281
282    /*
283     * Frame received?
284     */
285    if (status & 0x000000c0){
286      sc->rxInterrupts++;
287      rtems_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
288    }
289}
290
291static void nopOn(const rtems_irq_connect_data* notUsed)
292{
293  /*
294   * code should be moved from dec21140Enet_initialize_hardware
295   * to this location
296   */
297}
298
299static int dec21140IsOn(const rtems_irq_connect_data* irq)
300{
301  return BSP_irq_enabled_at_i8259s (irq->name);
302}
303
304
305/*
306 * This routine reads a word (16 bits) from the serial EEPROM.
307 */
308/*  EEPROM_Ctrl bits. */
309#define EE_SHIFT_CLK            0x02    /* EEPROM shift clock. */
310#define EE_CS                   0x01    /* EEPROM chip select. */
311#define EE_DATA_WRITE           0x04    /* EEPROM chip data in. */
312#define EE_WRITE_0              0x01
313#define EE_WRITE_1              0x05
314#define EE_DATA_READ            0x08    /* EEPROM chip data out. */
315#define EE_ENB                  (0x4800 | EE_CS)
316
317/* The EEPROM commands include the alway-set leading bit. */
318#define EE_WRITE_CMD    (5 << 6)
319#define EE_READ_CMD     (6 << 6)
320#define EE_ERASE_CMD    (7 << 6)
321
322static int eeget16(volatile unsigned int *ioaddr, int location)
323{
324        int i;
325        unsigned short retval = 0;
326        int read_cmd = location | EE_READ_CMD;
327       
328        st_le32(ioaddr, EE_ENB & ~EE_CS);
329        st_le32(ioaddr, EE_ENB);
330       
331        /* Shift the read command bits out. */
332        for (i = 10; i >= 0; i--) {
333                short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
334                st_le32(ioaddr, EE_ENB | dataval);
335                rtems_bsp_delay_in_bus_cycles(200);
336                st_le32(ioaddr, EE_ENB | dataval | EE_SHIFT_CLK);
337                rtems_bsp_delay_in_bus_cycles(200);
338                st_le32(ioaddr, EE_ENB | dataval); /* Finish EEPROM a clock tick. */
339                rtems_bsp_delay_in_bus_cycles(200);
340        }
341        st_le32(ioaddr, EE_ENB);
342       
343        for (i = 16; i > 0; i--) {
344                st_le32(ioaddr, EE_ENB | EE_SHIFT_CLK);
345                rtems_bsp_delay_in_bus_cycles(200);
346                retval = (retval << 1) | ((ld_le32(ioaddr) & EE_DATA_READ) ? 1 : 0);
347                st_le32(ioaddr, EE_ENB);
348                rtems_bsp_delay_in_bus_cycles(200);
349        }
350
351        /* Terminate the EEPROM access. */
352        st_le32(ioaddr, EE_ENB & ~EE_CS);
353        return ( ((retval<<8)&0xff00) | ((retval>>8)&0xff) );
354}
355
356/*
357 * Initialize the ethernet hardware
358 */
359static void
360dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
361{
362  rtems_status_code st;
363  volatile unsigned int *tbase;
364  int i;
365  volatile unsigned char *cp, *setup_frm, *eaddrs;
366  volatile unsigned char *buffer;
367  volatile struct MD *rmd;
368
369  tbase = sc->base;
370
371  /*
372   * WARNING : First write in CSR6
373   *           Then Reset the chip ( 1 in CSR0)
374   */
375  st_le32( (tbase+memCSR6), CSR6_INIT); 
376  st_le32( (tbase+memCSR0), RESET_CHIP); 
377  rtems_bsp_delay_in_bus_cycles(200);
378
379  /*
380   * Init CSR0
381   */
382  st_le32( (tbase+memCSR0), CSR0_MODE); 
383
384#ifdef DEC_DEBUG
385  printk("DC2114x %x:%x:%x:%x:%x:%x IRQ %d IO %x M %x .........\n",
386         sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
387         sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
388         sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
389         sc->irqInfo.name, sc->port, (unsigned) sc->base);
390#endif
391 
392  /*
393   * Init RX ring
394   */
395  cp = (volatile unsigned char *)malloc(((NRXBUFS+NTXBUFS)*sizeof(struct MD))
396                                        + (NTXBUFS*RBUF_SIZE)
397                                        + CPU_CACHE_ALIGNMENT_FOR_BUFFER);
398  sc->bufferBase = cp;
399  cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp)
400         & (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);
401#if defined(__i386__)
402#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
403  if (_CPU_is_paging_enabled())
404    _CPU_change_memory_mapping_attribute
405                   (NULL, cp,
406                    ((NRXBUFS+NTXBUFS)*sizeof(struct MD))
407                    + (NTXBUFS*RBUF_SIZE),
408                    PTE_CACHE_DISABLE | PTE_WRITABLE);
409#endif
410#endif
411  rmd = (volatile struct MD*)cp;
412  sc->MDbase = rmd;
413  buffer = cp + ((NRXBUFS+NTXBUFS)*sizeof(struct MD));
414  st_le32( (tbase+memCSR3), (long)(phys_to_bus((long)(sc->MDbase))));
415  for (i=0 ; i<NRXBUFS; i++){
416    struct mbuf *m;
417   
418    /* allocate an mbuf for each receive descriptor */
419    MGETHDR (m, M_WAIT, MT_DATA);
420    MCLGET (m, M_WAIT);
421    m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
422    rmd->m = m;
423
424    rmd->buf2   = phys_to_bus(rmd+1);
425    rmd->buf1   = phys_to_bus(mtod(m, void *)); 
426    rmd->counts = 0xfdc00000 | (RBUF_SIZE);
427    rmd->status = 0x80000000;
428    rmd->next   = rmd + 1;
429    rmd++;
430  }
431  /*
432   * mark last RX buffer.
433   */
434  sc->MDbase [NRXBUFS-1].counts = 0xfec00000 | (RBUF_SIZE);
435  sc->MDbase [NRXBUFS-1].next   = sc->MDbase;
436
437  /*
438   * Init TX ring
439   */
440  st_le32( (tbase+memCSR4), (long)(phys_to_bus((long)(rmd))) );
441  for (i=0 ; i<NTXBUFS; i++){
442    (rmd+i)->buf2   = phys_to_bus(rmd+i+1);
443    (rmd+i)->buf1   = phys_to_bus(buffer + (i*RBUF_SIZE));
444    (rmd+i)->counts = 0x01000000;
445    (rmd+i)->status = 0x0;
446    (rmd+i)->next   = rmd+i+1;
447    (rmd+i)->m      = 0;
448  }
449
450  /*
451   * mark last TX buffer.
452   */
453  (rmd+NTXBUFS-1)->buf2   = phys_to_bus(rmd);
454  (rmd+NTXBUFS-1)->next   = rmd;
455 
456  /*
457   * Set up interrupts
458   */
459  sc->irqInfo.hdl = (rtems_irq_hdl)dec21140Enet_interrupt_handler;
460  sc->irqInfo.on  = nopOn;
461  sc->irqInfo.off = nopOn;
462  sc->irqInfo.isOn = dec21140IsOn; 
463  st = BSP_install_rtems_irq_handler (&sc->irqInfo);
464  if (!st)
465    rtems_panic ("Can't attach DEC21140 interrupt handler for irq %d\n",
466                  sc->irqInfo.name);
467
468  st_le32( (tbase+memCSR7), NO_IT);
469
470  /*
471   * Build setup frame
472   */
473  setup_frm = (volatile unsigned char *)(bus_to_phys(rmd->buf1));
474  eaddrs = (char *)(sc->arpcom.ac_enaddr);
475  /* Fill the buffer with our physical address. */
476  for (i = 1; i < 16; i++) {
477        *setup_frm++ = eaddrs[0];
478        *setup_frm++ = eaddrs[1];
479        *setup_frm++ = eaddrs[0];
480        *setup_frm++ = eaddrs[1];
481        *setup_frm++ = eaddrs[2];
482        *setup_frm++ = eaddrs[3];
483        *setup_frm++ = eaddrs[2];
484        *setup_frm++ = eaddrs[3];
485        *setup_frm++ = eaddrs[4];
486        *setup_frm++ = eaddrs[5];
487        *setup_frm++ = eaddrs[4];
488        *setup_frm++ = eaddrs[5];
489  }
490  /* Add the broadcast address when doing perfect filtering */
491  memset((void*) setup_frm, 0xff, 12);
492  rmd->counts = 0x09000000 | 192 ;
493  rmd->status = 0x80000000;
494  st_le32( (tbase+memCSR6), CSR6_INIT | CSR6_TX);
495  st_le32( (tbase+memCSR1), 1);
496  while (rmd->status != 0x7fffffff);
497  rmd->counts = 0x01000000;   
498  sc->TxMD = rmd+1;
499 
500  /*
501   * Enable RX and TX
502   */
503  st_le32( (tbase+memCSR5), IT_SETUP);
504  st_le32( (tbase+memCSR7), IT_SETUP);
505  st_le32( (unsigned int*)(tbase+memCSR6), CSR6_INIT | CSR6_TXRX);
506}
507
508static void
509dec21140_rxDaemon (void *arg)
510{
511  volatile unsigned int *tbase;
512  struct ether_header *eh;
513  struct dec21140_softc *dp = (struct dec21140_softc *)&dec21140_softc[0];
514  struct ifnet *ifp = &dp->arpcom.ac_if;
515  struct mbuf *m;
516  volatile struct MD *rmd;
517  unsigned int len;
518  rtems_event_set events;
519 
520  tbase = dec21140_softc[0].base ;
521  rmd = dec21140_softc[0].MDbase;
522
523  for (;;){
524
525    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
526                                RTEMS_WAIT|RTEMS_EVENT_ANY,
527                                RTEMS_NO_TIMEOUT,
528                                &events);
529   
530    while((rmd->status & 0x80000000) == 0){
531      /* pass on the packet in the mbuf */
532      len = (rmd->status >> 16) & 0x7ff;
533      m = (struct mbuf *)(rmd->m);
534      m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
535      eh = mtod (m, struct ether_header *);
536      m->m_data += sizeof(struct ether_header);
537      ether_input (ifp, eh, m);
538       
539      /* get a new mbuf for the 21140 */
540      MGETHDR (m, M_WAIT, MT_DATA);
541      MCLGET (m, M_WAIT);
542      m->m_pkthdr.rcvif = ifp;
543      rmd->m = m;
544      rmd->buf1 = phys_to_bus(mtod(m, void *)); 
545
546      rmd->status = 0x80000000;
547     
548      rmd=rmd->next;
549    }
550  }     
551}
552
553static void
554sendpacket (struct ifnet *ifp, struct mbuf *m)
555{
556  struct dec21140_softc *dp = ifp->if_softc;
557  volatile struct MD *tmd;
558  volatile unsigned char *temp;
559  struct mbuf *n;
560  unsigned int len;
561  volatile unsigned int *tbase;
562
563  tbase = dp->base;
564  /*
565   * Waiting for Transmitter ready
566   */   
567  tmd = dec21140_softc[0].TxMD;
568  n = m;
569
570  while ((tmd->status & 0x80000000) != 0){
571    tmd=tmd->next;
572    }
573
574  len = 0;
575  temp = (volatile unsigned char *)(bus_to_phys(tmd->buf1));
576 
577  for (;;){
578    len += m->m_len;
579    memcpy((void*) temp, (char *)m->m_data, m->m_len);
580    temp += m->m_len ;
581    if ((m = m->m_next) == NULL)
582      break;
583  }
584
585  if (len < ET_MINLEN) len = ET_MINLEN;
586  tmd->counts =  0xe1000000 | (len & 0x7ff); 
587  tmd->status = 0x80000000;
588
589  st_le32( (tbase+memCSR1), 0x1);
590
591  m_freem(n);
592  dec21140_softc[0].TxMD = tmd->next;
593}
594
595/*
596 * Driver transmit daemon
597 */
598void
599dec21140_txDaemon (void *arg)
600{
601  struct dec21140_softc *sc = (struct dec21140_softc *)arg;
602  struct ifnet *ifp = &sc->arpcom.ac_if;
603  struct mbuf *m;
604  rtems_event_set events;
605
606  for (;;) {
607    /*
608     * Wait for packet
609     */
610
611    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
612
613    /*
614     * Send packets till queue is empty
615     */
616    for (;;) {
617      /*
618       * Get the next mbuf chain to transmit.
619       */
620      IF_DEQUEUE(&ifp->if_snd, m);
621      if (!m)
622        break;
623      sendpacket (ifp, m);
624    }
625    ifp->if_flags &= ~IFF_OACTIVE;
626  }
627}       
628
629
630static void
631dec21140_start (struct ifnet *ifp)
632{
633        struct dec21140_softc *sc = ifp->if_softc;
634
635        rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
636        ifp->if_flags |= IFF_OACTIVE;
637}
638
639/*
640 * Initialize and start the device
641 */
642static void
643dec21140_init (void *arg)
644{
645  struct dec21140_softc *sc = arg;
646  struct ifnet *ifp = &sc->arpcom.ac_if;
647
648  if (sc->txDaemonTid == 0) {
649   
650    /*
651     * Set up DEC21140 hardware
652     */
653    dec21140Enet_initialize_hardware (sc);
654   
655    /*
656     * Start driver tasks
657     */
658    sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
659                                            dec21140_rxDaemon, sc);
660    sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
661                                            dec21140_txDaemon, sc);
662  }
663
664  /*
665   * Tell the world that we're running.
666   */
667  ifp->if_flags |= IFF_RUNNING;
668
669}
670
671/*
672 * Stop the device
673 */
674static void
675dec21140_stop (struct dec21140_softc *sc)
676{
677  volatile unsigned int *tbase;
678  struct ifnet *ifp = &sc->arpcom.ac_if;
679
680  ifp->if_flags &= ~IFF_RUNNING;
681
682  /*
683   * Stop the transmitter
684   */
685  tbase=dec21140_softc[0].base ;
686  st_le32( (tbase+memCSR7), NO_IT);
687  st_le32( (tbase+memCSR6), CSR6_INIT);
688  free((void*)sc->bufferBase);
689}
690
691
692/*
693 * Show interface statistics
694 */
695static void
696dec21140_stats (struct dec21140_softc *sc)
697{
698        printf ("      Rx Interrupts:%-8lu", sc->rxInterrupts);
699        printf ("       Not First:%-8lu", sc->rxNotFirst);
700        printf ("        Not Last:%-8lu\n", sc->rxNotLast);
701        printf ("              Giant:%-8lu", sc->rxGiant);
702        printf ("            Runt:%-8lu", sc->rxRunt);
703        printf ("       Non-octet:%-8lu\n", sc->rxNonOctet);
704        printf ("            Bad CRC:%-8lu", sc->rxBadCRC);
705        printf ("         Overrun:%-8lu", sc->rxOverrun);
706        printf ("       Collision:%-8lu\n", sc->rxCollision);
707
708        printf ("      Tx Interrupts:%-8lu", sc->txInterrupts);
709        printf ("        Deferred:%-8lu", sc->txDeferred);
710        printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
711        printf ("         No Carrier:%-8lu", sc->txLostCarrier);
712        printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
713        printf ("  Late Collision:%-8lu\n", sc->txLateCollision);
714        printf ("           Underrun:%-8lu", sc->txUnderrun);
715        printf (" Raw output wait:%-8lu\n", sc->txRawWait);
716}
717
718/*
719 * Driver ioctl handler
720 */
721static int
722dec21140_ioctl (struct ifnet *ifp, int command, caddr_t data)
723{
724        struct dec21140_softc *sc = ifp->if_softc;
725        int error = 0;
726
727        switch (command) {
728        case SIOCGIFADDR:
729        case SIOCSIFADDR:
730                ether_ioctl (ifp, command, data);
731                break;
732
733        case SIOCSIFFLAGS:
734                switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
735                case IFF_RUNNING:
736                        dec21140_stop (sc);
737                        break;
738
739                case IFF_UP:
740                        dec21140_init (sc);
741                        break;
742
743                case IFF_UP | IFF_RUNNING:
744                        dec21140_stop (sc);
745                        dec21140_init (sc);
746                        break;
747
748                default:
749                        break;
750                }
751                break;
752
753        case SIO_RTEMS_SHOW_STATS:
754                dec21140_stats (sc);
755                break;
756               
757        /*
758         * FIXME: All sorts of multicast commands need to be added here!
759         */
760        default:
761                error = EINVAL;
762                break;
763        }
764
765        return error;
766}
767
768/*
769 * Attach an DEC21140 driver to the system
770 */
771int
772rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
773{
774        struct dec21140_softc *sc;
775        struct ifnet *ifp;
776        int mtu;
777        int i;
778#if defined(__i386__)
779    int deviceId = PCI_DEVICE_ID_DEC_21140; /* network card device ID */
780#endif
781       
782        /*
783         * First, find a DEC board
784         */
785#if defined(__i386__)
786        int signature;
787        int value;
788        char interrupt;
789        int diag;
790
791        if (pcib_init() == PCIB_ERR_NOTPRESENT)
792          rtems_panic("PCI BIOS not found !!");
793       
794        /*
795         * Try to find the network card on the PCI bus. Probe for a DEC 21140
796     * card first. If not found probe the bus for a DEC/Intel 21143 card.
797         */
798    deviceId = PCI_DEVICE_ID_DEC_21140;
799    diag = pcib_find_by_devid( PCI_VENDOR_ID_DEC, deviceId,
800                               0, &signature);
801    if ( diag == PCIB_ERR_SUCCESS)
802      printk( "DEC 21140 PCI network card found\n" );
803    else
804    {
805      deviceId = PCI_DEVICE_ID_DEC_21143;
806      diag = pcib_find_by_devid( PCI_VENDOR_ID_DEC, deviceId,
807                                 0, &signature);
808      if ( diag == PCIB_ERR_SUCCESS)
809        printk( "DEC/Intel 21143 PCI network card found\n" );
810      else
811        rtems_panic("DEC PCI network card not found !!\n");
812    }
813#endif 
814#if defined(__PPC)
815        unsigned char ucSlotNumber, ucFnNumber;
816        unsigned int  ulDeviceID, lvalue, tmp; 
817        unsigned char cvalue;
818
819        for(ucSlotNumber=0;ucSlotNumber<PCI_MAX_DEVICES;ucSlotNumber++) {
820          for(ucFnNumber=0;ucFnNumber<PCI_MAX_FUNCTIONS;ucFnNumber++) {
821            (void)pci_read_config_dword(0,
822                                        ucSlotNumber,
823                                        ucFnNumber,
824                                        PCI_VENDOR_ID,
825                                        &ulDeviceID);
826            if(ulDeviceID==PCI_INVALID_VENDORDEVICEID) {
827              /*
828               * This slot is empty
829               */
830              continue;
831            }
832            if (ulDeviceID == ((PCI_DEVICE_ID_DEC_21140<<16) + PCI_VENDOR_ID_DEC))
833              break;
834          }
835          if (ulDeviceID == ((PCI_DEVICE_ID_DEC_21140<<16) + PCI_VENDOR_ID_DEC)){
836            printk("DEC Adapter found !!\n");
837            break;
838          }
839        }
840       
841        if(ulDeviceID==PCI_INVALID_VENDORDEVICEID)
842          rtems_panic("DEC PCI board not found !!\n");
843#endif 
844        /*
845         * Find a free driver
846         */
847        for (i = 0 ; i < NDECDRIVER ; i++) {
848                sc = &dec21140_softc[i];
849                ifp = &sc->arpcom.ac_if;
850                if (ifp->if_softc == NULL)
851                        break;
852        }
853        if (i >= NDECDRIVER) {
854                printk ("Too many DEC drivers.\n");
855                return 0;
856        }
857
858        /*
859         * Process options
860         */
861#if defined(__i386__)
862
863    /* the 21143 chip must be enabled before it can be accessed */
864    if ( deviceId == PCI_DEVICE_ID_DEC_21143 )
865      pcib_conf_write32( signature, 0x40, 0 );
866
867        pcib_conf_read32(signature, 16, &value);
868        sc->port = value & ~IO_MASK;
869       
870        pcib_conf_read32(signature, 20, &value);
871        if (_CPU_is_paging_enabled())
872          _CPU_map_phys_address((void **) &(sc->base),
873                                (void *)(value & ~MEM_MASK),
874                                DEC_REGISTER_SIZE ,
875                                PTE_CACHE_DISABLE | PTE_WRITABLE);
876        else
877          sc->base = (unsigned int *)(value & ~MEM_MASK);
878       
879        pcib_conf_read8(signature, 60, &interrupt);
880          sc->irqInfo.name = (rtems_irq_symbolic_name)interrupt;
881#endif
882#if defined(__PPC)
883        (void)pci_read_config_dword(0,
884                                    ucSlotNumber,
885                                    ucFnNumber,
886                                    PCI_BASE_ADDRESS_0,
887                                    &lvalue);
888
889        sc->port = lvalue & (unsigned int)(~IO_MASK);
890       
891        (void)pci_read_config_dword(0,
892                                    ucSlotNumber,
893                                    ucFnNumber,
894                                    PCI_BASE_ADDRESS_1  ,
895                                    &lvalue);
896
897
898        tmp = (unsigned int)(lvalue & (unsigned int)(~MEM_MASK))
899          + (unsigned int)PCI_MEM_BASE;
900        sc->base = (unsigned int *)(tmp);
901
902        (void)pci_read_config_byte(0,
903                                   ucSlotNumber,
904                                   ucFnNumber,
905                                   PCI_INTERRUPT_LINE,
906                                   &cvalue);
907        sc->irqInfo.name = (rtems_irq_symbolic_name)cvalue;
908#endif
909        if (config->hardware_address) {
910          memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
911                  ETHER_ADDR_LEN);
912        }
913        else {
914          union {char c[64]; unsigned short s[32];} rombuf;
915          int i;
916
917          for (i=0; i<32; i++){
918            rombuf.s[i] = eeget16(sc->base+memCSR9, i);
919          }
920#if defined(__i386__)
921          for (i=0 ; i<(ETHER_ADDR_LEN/2); i++){
922            sc->arpcom.ac_enaddr[2*i]   = rombuf.c[20+2*i+1];
923            sc->arpcom.ac_enaddr[2*i+1] = rombuf.c[20+2*i];
924          } 
925#endif
926#if defined(__PPC)
927          memcpy (sc->arpcom.ac_enaddr, rombuf.c+20, ETHER_ADDR_LEN);
928#endif
929        }
930
931        if (config->mtu)
932                mtu = config->mtu;
933        else
934                mtu = ETHERMTU;
935
936        sc->acceptBroadcast = !config->ignore_broadcast;
937
938        /*
939         * Set up network interface values
940         */
941        ifp->if_softc = sc;
942        ifp->if_unit = i + 1;
943        ifp->if_name = "dc";
944        ifp->if_mtu = mtu;
945        ifp->if_init = dec21140_init;
946        ifp->if_ioctl = dec21140_ioctl;
947        ifp->if_start = dec21140_start;
948        ifp->if_output = ether_output;
949        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
950        if (ifp->if_snd.ifq_maxlen == 0)
951                ifp->if_snd.ifq_maxlen = ifqmaxlen;
952
953        /*
954         * Attach the interface
955         */
956        if_attach (ifp);
957        ether_ifattach (ifp);
958
959        printk( "DC2114x : driver has been attached\n" );
960        return 1;
961};
962#endif /* DEC21140_SUPPORTED */
963
Note: See TracBrowser for help on using the repository browser.