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

4.104.114.84.95
Last change on this file since cc2fcc1 was cc2fcc1, checked in by Eric Norum <WENorum@…>, on 10/20/05 at 18:38:26

Numerous changes and cleanups to support MVME2100.

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