OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [ts_386ex/] [network/] [ne2000.c] - Blame information for rev 493

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*  ne2k.c -- RTEMS NE2000 Ethernet driver.
2
 *  Written by Ian Lance Taylor, Zembu Labs.
3
 *  October, 1998.
4
 *
5
 *  The license and distribution terms for this file may be
6
 *  found in found in the file LICENSE in this distribution or at
7
 *  http://www.OARcorp.com/rtems/license.html.
8
 *
9
 *  $Id: ne2000.c,v 1.2 2001-09-27 11:59:50 chris Exp $
10
 *
11
 *  Both the ne2000 and the wd80x3 are based on the National Semiconductor
12
 *  8390 chip, so there is a fair amount of overlap between the two
13
 *  drivers.  It would be possible in principle to combine some code into
14
 *  a separate set of subroutines called by both.  In fact, the drivers in
15
 *  both OpenBSD and Linux work this way.  I didn't bother, because for
16
 *  the relatively simple drivers used by RTEMS, the overlap is not
17
 *  especially large, and any reasonable use of subroutines would lead to
18
 *  slightly less efficient code.
19
 
20
 *  This ne2000 driver uses two transmit buffers.  While one packet is
21
 *  being transmitted over the Ethernet, RTEMS will upload another.  Since
22
 *  uploading a packet to the ne2000 is rather slow, I don't think there
23
 *  is any point to having more than two transmit buffers.  However, the
24
 *  code does make it possible, by changing NE_TX_BUFS, although that
25
 *  would of course reduce the number of receive buffers.
26
 *
27
 *  I suspect that the wd80x3 driver would benefit slightly from copying
28
 *  the multiple transmit buffer code.  However, I have no way to test
29
 *  that.
30
 */
31
 
32
#include <bsp.h>
33
#include <wd80x3.h>
34
 
35
#include <stdio.h>
36
#include <assert.h>
37
 
38
#include <rtems/error.h>
39
#include <rtems/rtems_bsdnet.h>
40
 
41
#include <sys/param.h>
42
#include <sys/mbuf.h>
43
#include <sys/socket.h>
44
#include <sys/sockio.h>
45
 
46
#include <net/if.h>
47
 
48
#include <netinet/in.h>
49
#include <netinet/if_ether.h>
50
 
51
#include <irq.h>
52
 
53
/* Define this to force byte-wide data transfers with the NIC. This
54
   is needed for boards like the TS-1325 386EX PC, which support only
55
   an 8-bit PC/104 bus.  Undefine this on a normal PC.*/
56
 
57
/* #define NE2000_BYTE_TRANSFERS */
58
 
59
/* Define this to print debugging messages with printk.  */
60
 
61
/* #define DEBUG_NE2000 */
62
 
63
/* We expect to be able to read a complete packet into an mbuf.  */
64
 
65
#if (MCLBYTES < 1520)
66
# error "Driver must have MCLBYTES >= 1520"
67
#endif
68
 
69
/* The 8390 macro definitions in wd80x3.h expect RO to be defined.  */
70
#define RO 0
71
 
72
/* Minimum size of Ethernet packet.  */
73
#define ET_MINLEN 60
74
 
75
/* The number of NE2000 devices supported by this driver.  */
76
 
77
#define NNEDRIVER       1
78
 
79
/* RTEMS event number used by the interrupt handler to signal the
80
   driver task.  This must not be any of the events used by the
81
   network task synchronization.  */
82
#define INTERRUPT_EVENT RTEMS_EVENT_1
83
 
84
/* RTEMS event number used to start the transmit daemon.  This must
85
   not be the same as INTERRUPT_EVENT.  */
86
#define START_TRANSMIT_EVENT RTEMS_EVENT_2
87
 
88
/* Interrupts we want to handle from the device.  */
89
 
90
#define NE_INTERRUPTS \
91
  (MSK_PRX | MSK_PTX | MSK_RXE | MSK_TXE | MSK_OVW | MSK_CNT)
92
 
93
/* The size of a page in device memory.  */
94
 
95
#define NE_PAGE_SIZE (256)
96
 
97
/* The first page address in device memory.  */
98
 
99
#define NE_START_PAGE (0x40)
100
 
101
/* The last page address, plus 1.  */
102
 
103
#define NE_STOP_PAGE (0x80)
104
 
105
/* The number of pages used for a single transmit buffer.  This is
106
   1536 bytes, enough for a full size packet.  */
107
 
108
#define NE_TX_PAGES (6)
109
 
110
/* The number of transmit buffers.  We use two, so we can load one
111
   packet while the other is being sent.  */
112
 
113
#define NE_TX_BUFS (2)
114
 
115
/* We use the first pages in memory as transmit buffers, and the
116
   remaining ones as receive buffers.  */
117
 
118
#define NE_FIRST_TX_PAGE (NE_START_PAGE)
119
 
120
#define NE_FIRST_RX_PAGE (NE_FIRST_TX_PAGE + NE_TX_PAGES * NE_TX_BUFS)
121
 
122
/* Data we store for each NE2000 device.  */
123
 
124
struct ne_softc {
125
  /* The bsdnet information structure.  */
126
  struct arpcom arpcom;
127
 
128
  /* The interrupt request number.  */
129
  unsigned int irno;
130
  /* The base IO port number.  */
131
  unsigned int port;
132
 
133
  /* Whether we accept broadcasts.  */
134
  int accept_broadcasts;
135
 
136
  /* The thread ID of the transmit task.   */
137
  rtems_id tx_daemon_tid;
138
  /* The thread ID of the receive task.  */
139
  rtems_id rx_daemon_tid;
140
 
141
  /* Whether we use byte-transfers with the device. */
142
  rtems_boolean byte_transfers;
143
 
144
  /* The number of memory buffers which the transmit daemon has loaded
145
     with data to be sent, but which have not yet been completely
146
     sent.  */
147
  int inuse;
148
  /* The index of the next available transmit memory buffer.  */
149
  int nextavail;
150
  /* The index of the next transmit buffer to send.  */
151
  int nextsend;
152
  /* Nonzero if the device is currently transmitting a packet.  */
153
  int transmitting;
154
  /* The length of the data stored in each transmit buffer.  */
155
  int sendlen[NE_TX_BUFS];
156
 
157
  /* Set if we have a packet overrun while receiving.  */
158
  int overrun;
159
  /* Set if we should resend after an overrun.  */
160
  int resend;
161
 
162
  /* Statistics.  */
163
  struct {
164
    /* Number of packets received.  */
165
    unsigned long rx_packets;
166
    /* Number of packets sent.  */
167
    unsigned long tx_packets;
168
    /* Number of interrupts.  */
169
    unsigned long interrupts;
170
    /* Number of receive acknowledgements.  */
171
    unsigned long rx_acks;
172
    /* Number of transmit acknowledgements.  */
173
    unsigned long tx_acks;
174
    /* Number of packet overruns.  */
175
    unsigned long overruns;
176
    /* Number of frame errors.  */
177
    unsigned long rx_frame_errors;
178
    /* Number of CRC errors.  */
179
    unsigned long rx_crc_errors;
180
    /* Number of missed packets.  */
181
    unsigned long rx_missed_errors;
182
  } stats;
183
};
184
 
185
/* The list of NE2000 devices on this system.  */
186
 
187
static struct ne_softc ne_softc[NNEDRIVER];
188
 
189
/* Find the NE2000 device which is attached at a particular interrupt
190
   vector.  */
191
 
192
static struct ne_softc *
193
ne_device_for_irno (int irno)
194
{
195
  int i;
196
 
197
  for (i = 0; i < NNEDRIVER; ++i)
198
    {
199
      if (ne_softc[i].irno == irno
200
          && ne_softc[i].arpcom.ac_if.if_softc != NULL)
201
        return &ne_softc[i];
202
    }
203
 
204
  return NULL;
205
}
206
 
207
/* Read data from an NE2000 device.  Read LEN bytes at ADDR, storing
208
   them into P.  */
209
 
210
static void
211
ne_read_data (struct ne_softc *sc, int addr, int len, unsigned char *p)
212
{
213
  unsigned int port = sc->port;
214
  unsigned int dport = port + DATAPORT;
215
 
216
  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
217
  outport_byte (port + RBCR0, len);
218
  outport_byte (port + RBCR1, len >> 8);
219
  outport_byte (port + RSAR0, addr);
220
  outport_byte (port + RSAR1, addr >> 8);
221
  outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
222
 
223
  if (sc->byte_transfers)
224
    while (len > 0) {
225
      unsigned char d;
226
 
227
      inport_byte (dport, d);
228
      *p++ = d;
229
      len--;
230
    }
231
  else  /* word transfers */
232
    while (len > 0) {
233
      unsigned short d;
234
 
235
      inport_word (dport, d);
236
      *p++ = d;
237
      *p++ = d >> 8;
238
      len -= 2;
239
    }
240
 
241
  outport_byte (port + ISR, MSK_RDC);
242
}
243
 
244
/* Handle the current NE2000 status.  This is called when the device
245
   signals an interrupt.  It is also called at other times while
246
   NE2000 interrupts have been disabled.  */
247
 
248
static void
249
ne_check_status (struct ne_softc *sc)
250
{
251
  unsigned int port = sc->port;
252
  unsigned char status;
253
 
254
  /* It seems that we need to use a loop here, because if the NE2000
255
     signals an interrupt because packet transmission is complete, and
256
     then receives a packet while interrupts are disabled, it seems to
257
     sometimes fail to signal the interrupt for the received packet
258
     when interrupts are reenabled.  (Based on the behaviour of the
259
     Realtek 8019AS chip).  */
260
 
261
  while (1) {
262
    inport_byte (port + ISR, status);
263
    if (status == 0)
264
      break;
265
 
266
#ifdef DEBUG_NE2000
267
    printk ("NE2000 status 0x%x (8259 enabled: %s; mask: %x)\n", status,
268
            i8259s_cache & (1 << sc->irno) ? "no" : "yes",
269
            i8259s_cache);
270
#endif
271
 
272
    /* Check for incoming packet overwrite.  */
273
    if (status & MSK_OVW) {
274
      unsigned char status2;
275
 
276
      ++sc->stats.overruns;
277
      outport_byte (port + CMDR, MSK_PG0 | MSK_STP | MSK_RD2);
278
      Wait_X_ms (2);
279
      outport_byte (port + RBCR0, 0);
280
      outport_byte (port + RBCR1, 0);
281
      inport_byte (port + ISR, status2);
282
      status |= status2 & (MSK_PTX | MSK_TXE);
283
      outport_byte (port + TCR, MSK_LOOP);
284
      outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
285
      sc->overrun = 1;
286
      if ((status & (MSK_PTX | MSK_TXE)) == 0)
287
        sc->resend = 1;
288
      rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
289
    }
290
 
291
    /* Check for transmitted packet.  The transmit daemon may now be
292
       able to send another packet to the device.  */
293
    if ((status & (MSK_PTX | MSK_TXE)) != 0) {
294
      ++sc->stats.tx_acks;
295
      outport_byte (port + ISR, status & (MSK_PTX | MSK_TXE));
296
      --sc->inuse;
297
      sc->transmitting = 0;
298
      if (sc->inuse > 0 || (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) != 0)
299
        rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
300
    }
301
 
302
    /* Check for received packet.  */
303
    if ((status & (MSK_PRX | MSK_RXE)) != 0) {
304
      ++sc->stats.rx_acks;
305
      outport_byte (port + ISR, status & (MSK_PRX | MSK_RXE));
306
      rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
307
    }
308
 
309
    /* Check for counter change.  */
310
    if ((status & MSK_CNT) != 0) {
311
      unsigned char add;
312
 
313
      inport_byte (port + CNTR0, add);
314
      sc->stats.rx_frame_errors += add;
315
      inport_byte (port + CNTR1, add);
316
      sc->stats.rx_crc_errors += add;
317
      inport_byte (port + CNTR2, add);
318
      sc->stats.rx_missed_errors += add;
319
      outport_byte (port + ISR, MSK_CNT);
320
    }
321
  }
322
 
323
  outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
324
}
325
 
326
/* Handle an NE2000 interrupt.  */
327
 
328
static rtems_isr
329
ne_interrupt_handler (rtems_vector_number v)
330
{
331
  struct ne_softc *sc;
332
 
333
  sc = ne_device_for_irno (v);
334
  if (sc == NULL)
335
    return;
336
 
337
  ++sc->stats.interrupts;
338
 
339
  ne_check_status (sc);
340
}
341
 
342
/* Turn NE2000 interrupts on.  */
343
 
344
static void
345
ne_interrupt_on (const rtems_irq_connect_data *irq)
346
{
347
  struct ne_softc *sc;
348
 
349
#ifdef DEBUG_NE2000
350
  printk ("ne_interrupt_on\n");
351
#endif
352
  sc = ne_device_for_irno (irq->name);
353
  if (sc != NULL)
354
    outport_byte (sc->port + IMR, NE_INTERRUPTS);
355
}
356
 
357
/* Turn NE2000 interrupts off.  See ne_interrupt_on.  */
358
 
359
static void
360
ne_interrupt_off (const rtems_irq_connect_data *irq)
361
{
362
  struct ne_softc *sc;
363
 
364
#ifdef DEBUG_NE2000
365
  printk ("ne_interrupt_off\n");
366
#endif
367
  sc = ne_device_for_irno (irq->name);
368
  if (sc != NULL)
369
    outport_byte (sc->port + IMR, 0);
370
}
371
 
372
/* Return whether NE2000 interrupts are on.  */
373
 
374
static int
375
ne_interrupt_is_on (const rtems_irq_connect_data *irq)
376
{
377
  return BSP_irq_enabled_at_i8259s (irq->name);
378
}
379
 
380
/* Initialize the NE2000 hardware.  */
381
 
382
static void
383
ne_init_hardware (struct ne_softc *sc)
384
{
385
  unsigned int port = sc->port;
386
  int i;
387
  rtems_irq_connect_data irq;
388
 
389
#ifdef DEBUG_NE2000
390
  printk ("ne_init_hardware\n");
391
#endif
392
 
393
  /* Initialize registers.  */
394
 
395
  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
396
 
397
  if (sc->byte_transfers) {
398
    outport_byte (port + DCR, MSK_FT10 | MSK_BMS);
399
  }
400
  else {
401
    outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
402
  }
403
 
404
  outport_byte (port + RBCR0, 0);
405
  outport_byte (port + RBCR1, 0);
406
  outport_byte (port + RCR, MSK_MON);
407
  outport_byte (port + TCR, MSK_LOOP);
408
  outport_byte (port + IMR, 0);
409
  outport_byte (port + ISR, 0xff);
410
  outport_byte (port + PSTOP, NE_STOP_PAGE);
411
  outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
412
  outport_byte (port + BNRY, NE_STOP_PAGE - 1);
413
 
414
  /* Set the Ethernet hardware address.  */
415
 
416
  outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
417
  for (i = 0; i < ETHER_ADDR_LEN; ++i)
418
    outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]);
419
 
420
#ifdef DEBUG_NE2000
421
  printk ("Using ethernet address: ");
422
  for (i = 0; i < ETHER_ADDR_LEN; ++i)
423
    printk("%x ",sc->arpcom.ac_enaddr[i]);
424
  printk ("\n");
425
#endif
426
 
427
  /* Clear the multicast address.  */
428
  for (i = 0; i < MARsize; ++i)
429
    outport_byte (port + MAR + i, 0);
430
 
431
  outport_byte (port + CURR, NE_FIRST_RX_PAGE);
432
 
433
  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
434
 
435
  /* Put the device on line.  */
436
  outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
437
 
438
  /* Set up interrupts.  */
439
 
440
  irq.name = sc->irno;
441
  irq.hdl = ne_interrupt_handler;
442
  irq.on = ne_interrupt_on;
443
  irq.off = ne_interrupt_off;
444
  irq.isOn = ne_interrupt_is_on;
445
 
446
  if (! BSP_install_rtems_irq_handler (&irq))
447
    rtems_panic ("Can't attach NE interrupt handler for irq %d.\n",
448
                 sc->irno);
449
 
450
  /* Prepare to receive packets.  */
451
 
452
  outport_byte (port + TCR, 0);
453
  outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0));
454
}
455
 
456
/* The NE2000 packet receive daemon.  This task is started when the
457
   NE2000 driver is initialized.  */
458
 
459
static void
460
ne_rx_daemon (void *arg)
461
{
462
  struct ne_softc *sc = (struct ne_softc *) arg;
463
  struct ifnet *ifp = &sc->arpcom.ac_if;
464
  unsigned int port = sc->port;
465
  unsigned int dport = port + DATAPORT;
466
 
467
  while (1) {
468
    rtems_event_set events;
469
 
470
    /* Wait for the interrupt handler to tell us that there is a
471
       packet ready to receive.  */
472
    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
473
                                RTEMS_WAIT | RTEMS_EVENT_ANY,
474
                                RTEMS_NO_TIMEOUT,
475
                                &events);
476
 
477
    /* Don't let the device interrupt us now.  */
478
    outport_byte (port + IMR, 0);
479
 
480
    while (1) {
481
      unsigned char startpage, currpage;
482
      unsigned short statnext, len;
483
      int next;
484
      struct mbuf *m;
485
      unsigned char *p;
486
      int startaddr;
487
      int toend;
488
      struct ether_header *eh;
489
 
490
      inport_byte (port + BNRY, startpage);
491
 
492
      outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
493
      inport_byte (port + CURR, currpage);
494
      outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
495
 
496
      ++startpage;
497
      if (startpage >= NE_STOP_PAGE)
498
        startpage = NE_FIRST_RX_PAGE;
499
 
500
      if (startpage == currpage)
501
        break;
502
 
503
#ifdef DEBUG_NE2000
504
      printk ("ne_rx_daemon: start page %x; current page %x\n",
505
              startpage, currpage);
506
#endif
507
 
508
      /* Read the buffer header.  This is 1 byte receive status, 1
509
         byte page of next buffer, 2 bytes length.  */
510
      outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
511
      outport_byte (port + RBCR0, 4);
512
      outport_byte (port + RBCR1, 0);
513
      outport_byte (port + RSAR0, 0);
514
      outport_byte (port + RSAR1, startpage);
515
      outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
516
 
517
      if (sc->byte_transfers) {
518
        unsigned char data;
519
 
520
        inport_byte (dport, data);  /* Throw away status  */
521
        inport_byte (dport, data);
522
        next = data;
523
 
524
        inport_byte (dport, data);
525
        len = data;
526
        inport_byte (dport, data);
527
        len |= data << 8;
528
      }
529
      else {                        /* Word transfers  */
530
        inport_word (dport, statnext);
531
        inport_word (dport, len);
532
 
533
        next = statnext >> 8;
534
      }
535
 
536
      outport_byte (port + ISR, MSK_RDC);
537
 
538
      if (next >= NE_STOP_PAGE)
539
        next = NE_FIRST_RX_PAGE;
540
 
541
      /* The first four bytes of the length are the buffer header.  */
542
      len -= 4;
543
      startaddr = startpage * NE_PAGE_SIZE + 4;
544
 
545
      MGETHDR (m, M_WAIT, MT_DATA);
546
      MCLGET (m, M_WAIT);
547
      m->m_pkthdr.rcvif = ifp;
548
 
549
      p = mtod (m, unsigned char *);
550
      m->m_len = m->m_pkthdr.len = len - sizeof (struct ether_header);
551
 
552
      toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr;
553
      if (toend < len) {
554
        ne_read_data (sc, startaddr, toend, p);
555
        p += toend;
556
        len -= toend;
557
        startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
558
      }
559
 
560
      if (len > 0)
561
        ne_read_data (sc, startaddr, len, p);
562
 
563
      eh = mtod (m, struct ether_header *);
564
      m->m_data += sizeof (struct ether_header);
565
      ether_input (ifp, eh, m);
566
 
567
      ++sc->stats.rx_packets;
568
 
569
      outport_byte (port + BNRY, next - 1);
570
    }
571
 
572
    if (sc->overrun) {
573
      outport_byte (port + ISR, MSK_OVW);
574
      outport_byte (port + TCR, 0);
575
      if (sc->resend)
576
        outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
577
      sc->resend = 0;
578
      sc->overrun = 0;
579
    }
580
 
581
    /* Reenable device interrupts.  */
582
    outport_byte (port + IMR, NE_INTERRUPTS);
583
  }
584
}
585
 
586
/* Load an NE2000 packet onto the device.  */
587
 
588
static void
589
ne_loadpacket (struct ne_softc *sc, struct mbuf *m)
590
{
591
  unsigned int port = sc->port;
592
  unsigned int dport = port + DATAPORT;
593
  struct mbuf *mhold = m;
594
  int leftover;
595
  unsigned char leftover_data;
596
  int timeout;
597
 
598
#ifdef DEBUG_NE2000
599
  printk ("Uploading NE2000 packet\n");
600
#endif
601
 
602
  /* Reset remote DMA complete flag.  */
603
  outport_byte (port + ISR, MSK_RDC);
604
 
605
  /* Write out the count.  */
606
  outport_byte (port + RBCR0, m->m_pkthdr.len);
607
  outport_byte (port + RBCR1, m->m_pkthdr.len >> 8);
608
 
609
  sc->sendlen[sc->nextavail] = m->m_pkthdr.len;
610
 
611
  /* Tell the device which address we want to write to.  */
612
  outport_byte (port + RSAR0, 0);
613
  outport_byte (port + RSAR1,
614
                NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
615
 
616
  /* Set up the write.  */
617
  outport_byte (port + CMDR, MSK_PG0 | MSK_RWR | MSK_STA);
618
 
619
  /* Transfer the mbuf chain to device memory.  NE2000 devices require
620
     that the data be transferred as words, so we need to handle odd
621
     length mbufs.  Never occurs if we force byte transfers. */
622
 
623
  leftover = 0;
624
  leftover_data = '\0';
625
 
626
  for (; m != NULL; m = m->m_next) {
627
    int len;
628
    unsigned char *data;
629
 
630
    len = m->m_len;
631
    if (len == 0)
632
      continue;
633
 
634
    data = mtod (m, unsigned char *);
635
 
636
    if (leftover) {
637
      unsigned char next;
638
 
639
      /* Data left over from previous mbuf in chain.  */
640
      next = *data++;
641
      --len;
642
      outport_word (dport, leftover_data | (next << 8));
643
      leftover = 0;
644
    }
645
 
646
    /* If using byte transfers, len always ends up as zero so
647
       there are no leftovers. */
648
 
649
    if (sc->byte_transfers)
650
      while (len > 0) {
651
        outport_byte (dport, *data++);
652
        len--;
653
      }
654
    else
655
      while (len > 1) {
656
        outport_word (dport, data[0] | (data[1] << 8));
657
        data += 2;
658
        len -= 2;
659
      }
660
 
661
    if (len > 0)
662
      {
663
        leftover = 1;
664
        leftover_data = *data++;
665
      }
666
  }
667
 
668
  if (leftover)
669
    outport_word (dport, leftover_data);
670
 
671
  m_freem (mhold);
672
 
673
  /* Wait for the device to complete accepting the data, with a
674
     limiting counter so that we don't wait too long.  */
675
  for (timeout = 0; timeout < 100; ++timeout)
676
    {
677
      unsigned char status;
678
 
679
      inport_byte (port + ISR, status);
680
 
681
#ifdef DEBUG_NE2000
682
      if ((status &~ MSK_RDC) != 0)
683
        printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
684
                status);
685
#endif
686
 
687
      if ((status & MSK_RDC) != 0) {
688
        outport_byte (port + ISR, MSK_RDC);
689
        break;
690
      }
691
    }
692
 
693
  if (timeout >= 100)
694
    printk ("Timed out waiting for acknowledgement of uploaded NE2000 packet\n");
695
 
696
  ++sc->nextavail;
697
  if (sc->nextavail == NE_TX_BUFS)
698
    sc->nextavail = 0;
699
}
700
 
701
/* Tell the NE2000 to transmit a buffer whose contents we have already
702
   loaded onto the device.  */
703
 
704
static void
705
ne_transmit (struct ne_softc *sc)
706
{
707
  unsigned int port = sc->port;
708
  int len;
709
 
710
#ifdef DEBUG_NE2000
711
  printk ("Transmitting NE2000 packet\n");
712
#endif
713
 
714
  len = sc->sendlen[sc->nextsend];
715
  if (len < ET_MINLEN)
716
    len = ET_MINLEN;
717
  outport_byte (port + TBCR0, len);
718
  outport_byte (port + TBCR1, len >> 8);
719
 
720
  outport_byte (port + TPSR, NE_FIRST_TX_PAGE + (sc->nextsend * NE_TX_PAGES));
721
 
722
  outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
723
 
724
  ++sc->nextsend;
725
  if (sc->nextsend == NE_TX_BUFS)
726
    sc->nextsend = 0;
727
 
728
  ++sc->stats.tx_packets;
729
}
730
 
731
/* The NE2000 packet transmit daemon.  This task is started when the
732
   NE2000 driver is initialized.  */
733
 
734
static void
735
ne_tx_daemon (void *arg)
736
{
737
  struct ne_softc *sc = (struct ne_softc *) arg;
738
  unsigned int port = sc->port;
739
  struct ifnet *ifp = &sc->arpcom.ac_if;
740
 
741
  while (1) {
742
    rtems_event_set events;
743
 
744
    /* Wait for a packet to be ready for sending, or for there to be
745
       room for another packet in the device memory.  */
746
    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
747
                                RTEMS_EVENT_ANY | RTEMS_WAIT,
748
                                RTEMS_NO_TIMEOUT,
749
                                &events);
750
 
751
#ifdef DEBUG_NE2000
752
    printk ("ne_tx_daemon\n");
753
#endif
754
 
755
    /* This daemon handles both uploading data onto the device and
756
       telling the device to transmit data which has been uploaded.
757
       These are separate tasks, because while the device is
758
       transmitting one buffer we will upload another.  */
759
 
760
    /* Don't let the device interrupt us now.  */
761
    outport_byte (port + IMR, 0);
762
 
763
    while (1) {
764
      struct mbuf *m;
765
 
766
      /* If the device is not transmitting a packet, and we have
767
         uploaded a packet, tell the device to transmit it.  */
768
      if (! sc->transmitting && sc->inuse > 0) {
769
        sc->transmitting = 1;
770
        ne_transmit (sc);
771
      }
772
 
773
      /* If we don't have any more buffers to send, quit now.  */
774
      if (ifp->if_snd.ifq_head == NULL) {
775
        ifp->if_flags &= ~IFF_OACTIVE;
776
        break;
777
      }
778
 
779
      /* Allocate a buffer to load data into.  If there are none
780
         available, quit until a buffer has been transmitted.  */
781
      if (sc->inuse >= NE_TX_BUFS)
782
        break;
783
 
784
      ++sc->inuse;
785
 
786
      IF_DEQUEUE (&ifp->if_snd, m);
787
      if (m == NULL)
788
        panic ("ne_tx_daemon");
789
 
790
      ne_loadpacket (sc, m);
791
 
792
      /* Check the device status.  It may have finished transmitting
793
         the last packet.  */
794
      ne_check_status (sc);
795
    }
796
 
797
    /* Reenable device interrupts.  */
798
    outport_byte (port + IMR, NE_INTERRUPTS);
799
  }
800
}
801
 
802
/* Start sending an NE2000 packet.  */
803
 
804
static void
805
ne_start (struct ifnet *ifp)
806
{
807
  struct ne_softc *sc = ifp->if_softc;
808
 
809
  /* Tell the transmit daemon to wake up and send a packet.  */
810
  rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
811
  ifp->if_flags |= IFF_OACTIVE;
812
}
813
 
814
/* Initialize and start and NE2000.  */
815
 
816
static void
817
ne_init (void *arg)
818
{
819
  struct ne_softc *sc = (struct ne_softc *) arg;
820
  struct ifnet *ifp = &sc->arpcom.ac_if;
821
 
822
  if (sc->tx_daemon_tid == 0) {
823
    sc->inuse = 0;
824
    sc->nextavail = 0;
825
    sc->nextsend = 0;
826
    sc->transmitting = 0;
827
 
828
    ne_init_hardware (sc);
829
 
830
    sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc);
831
    sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc);
832
  }
833
 
834
  ifp->if_flags |= IFF_RUNNING;
835
}
836
 
837
/* Stop an NE2000.  */
838
 
839
static void
840
ne_stop (struct ne_softc *sc)
841
{
842
  unsigned int port = sc->port;
843
  int i;
844
 
845
  sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
846
 
847
  /* Stop everything.  */
848
  outport_byte (port + CMDR, MSK_STP | MSK_RD2);
849
 
850
  /* Wait for the interface to stop, using I as a time limit.  */
851
  for (i = 0; i < 5000; ++i)
852
    {
853
      unsigned char status;
854
 
855
      inport_byte (port + ISR, status);
856
      if ((status & MSK_RST) != 0)
857
        break;
858
    }
859
 
860
  sc->inuse = 0;
861
  sc->nextavail = 0;
862
  sc->nextsend = 0;
863
  sc->transmitting = 0;
864
}
865
 
866
/* Show NE2000 interface statistics.  */
867
 
868
static void
869
ne_stats (struct ne_softc *sc)
870
{
871
  printf ("    Received packets: %-8lu", sc->stats.rx_packets);
872
  printf (" Transmitted packets: %-8lu\n", sc->stats.tx_packets);
873
  printf ("        Receive acks: %-8lu", sc->stats.rx_acks);
874
  printf ("       Transmit acks: %-8lu\n", sc->stats.tx_acks);
875
  printf ("     Packet overruns: %-8lu", sc->stats.overruns);
876
  printf ("        Frame errors: %-8lu\n", sc->stats.rx_frame_errors);
877
  printf ("          CRC errors: %-8lu", sc->stats.rx_crc_errors);
878
  printf ("      Missed packets: %-8lu\n", sc->stats.rx_missed_errors);
879
  printf ("          Interrupts: %-8lu\n", sc->stats.interrupts);
880
}
881
 
882
/* NE2000 driver ioctl handler.  */
883
 
884
static int
885
ne_ioctl (struct ifnet *ifp, int command, caddr_t data)
886
{
887
  struct ne_softc *sc = ifp->if_softc;
888
  int error = 0;
889
 
890
  switch (command) {
891
  case SIOCGIFADDR:
892
  case SIOCSIFADDR:
893
    error = ether_ioctl (ifp, command, data);
894
    break;
895
 
896
  case SIOCSIFFLAGS:
897
    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
898
    case IFF_RUNNING:
899
      ne_stop (sc);
900
      break;
901
 
902
    case IFF_UP:
903
      ne_init (sc);
904
      break;
905
 
906
    case IFF_UP | IFF_RUNNING:
907
      ne_stop (sc);
908
      ne_init (sc);
909
      break;
910
 
911
    default:
912
      break;
913
    }
914
    break;
915
 
916
  case SIO_RTEMS_SHOW_STATS:
917
    ne_stats (sc);
918
    break;
919
 
920
    /* FIXME: Multicast commands must be added here.  */
921
 
922
  default:
923
    error = EINVAL;
924
    break;
925
  }
926
 
927
  return error;
928
}
929
 
930
/* Attach an NE2000 driver to the system.  */
931
 
932
int
933
rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config)
934
{
935
  int i;
936
  struct ne_softc *sc;
937
  struct ifnet *ifp;
938
  int mtu;
939
 
940
  /* Find a free driver.  */
941
  sc = NULL;
942
  for (i = 0; i < NNEDRIVER; ++i) {
943
    sc = &ne_softc[i];
944
    ifp = &sc->arpcom.ac_if;
945
    if (ifp->if_softc == NULL)
946
      break;
947
  }
948
 
949
  if (sc == NULL) {
950
    printf ("Too many NE2000 drivers.\n");
951
    return 0;
952
  }
953
 
954
  memset (sc, 0, sizeof *sc);
955
 
956
  /* Check whether we do byte-wide or word-wide transfers.  */
957
 
958
#ifdef NE2000_BYTE_TRANSFERS
959
  sc->byte_transfers = TRUE;
960
#else
961
  sc->byte_transfers = FALSE;
962
#endif
963
 
964
  /* Handle the options passed in by the caller.  */
965
 
966
  if (config->mtu != 0)
967
    mtu = config->mtu;
968
  else
969
    mtu = ETHERMTU;
970
 
971
  if (config->irno != 0)
972
    sc->irno = config->irno;
973
  else {
974
    /* We use 5 as the default IRQ.  */
975
    sc->irno = 5;
976
  }
977
 
978
  if (config->port != 0)
979
    sc->port = config->port;
980
  else {
981
    /* We use 0x300 as the default IO port number.  */
982
    sc->port = 0x300;
983
  }
984
 
985
  sc->accept_broadcasts = ! config->ignore_broadcast;
986
 
987
  if (config->hardware_address != NULL)
988
    memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
989
            ETHER_ADDR_LEN);
990
  else
991
    {
992
      unsigned char prom[16];
993
      int ia;
994
 
995
      /* Read the PROM to get the Ethernet hardware address.  */
996
 
997
      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
998
 
999
      if (sc->byte_transfers) {
1000
        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
1001
      }
1002
      else {
1003
        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
1004
      }
1005
 
1006
      outport_byte (sc->port + RBCR0, 0);
1007
      outport_byte (sc->port + RBCR1, 0);
1008
      outport_byte (sc->port + RCR, MSK_MON);
1009
      outport_byte (sc->port + TCR, MSK_LOOP);
1010
      outport_byte (sc->port + IMR, 0);
1011
      outport_byte (sc->port + ISR, 0xff);
1012
 
1013
      ne_read_data (sc, 0, sizeof prom, prom);
1014
 
1015
      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
1016
 
1017
      for (ia = 0; ia < ETHER_ADDR_LEN; ++ia)
1018
        sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
1019
    }
1020
 
1021
  /* Set up the network interface.  */
1022
 
1023
  ifp->if_softc = sc;
1024
  ifp->if_unit = i + 1;
1025
  ifp->if_name = "ne";
1026
  ifp->if_mtu = mtu;
1027
  ifp->if_init = ne_init;
1028
  ifp->if_ioctl = ne_ioctl;
1029
  ifp->if_start = ne_start;
1030
  ifp->if_output = ether_output;
1031
  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
1032
  if (ifp->if_snd.ifq_maxlen == 0)
1033
    ifp->if_snd.ifq_maxlen = ifqmaxlen;
1034
 
1035
  /* Attach the interface.  */
1036
 
1037
  if_attach (ifp);
1038
  ether_ifattach (ifp);
1039
 
1040
  return 1;
1041
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.