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

4.104.114.95
Last change on this file since cc4c524b was cc4c524b, checked in by Joel Sherrill <joel.sherrill@…>, on 08/19/08 at 20:02:37

2008-08-19 Joel Sherrill <joel.sherrill@…>

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