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

4.104.114.84.95
Last change on this file since a8e1959 was a8e1959, checked in by Jennifer Averett <Jennifer.Averett@…>, on 05/04/05 at 19:38:49

2005-05-04 Jennifer Averett <jennifer.averett@…>

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