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

4.104.114.84.95
Last change on this file since a73a977 was 461fa1bc, checked in by Joel Sherrill <joel.sherrill@…>, on 10/20/00 at 13:11:39

2000-10-20 Joel Sherrill <joel@…>

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