source: rtems/bsps/shared/net/dec21140.c @ 762fa62

5
Last change on this file since 762fa62 was 27de4e1f, checked in by Sebastian Huber <sebastian.huber@…>, on 04/03/18 at 05:20:11

bsps: Move libchip to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

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