OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [i386/] [pc386/] [ne2000/] [ne2000.c] - Blame information for rev 173

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:48 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
/* Forward declarations to avoid warnings */
190
 
191
static void ne_stop (struct ne_softc *sc);
192
static void ne_init (void *arg);
193
 
194
/* Find the NE2000 device which is attached at a particular interrupt
195
   vector.  */
196
 
197
static struct ne_softc *
198
ne_device_for_irno (int irno)
199
{
200
  int i;
201
 
202
  for (i = 0; i < NNEDRIVER; ++i)
203
    {
204
      if (ne_softc[i].irno == irno
205
          && ne_softc[i].arpcom.ac_if.if_softc != NULL)
206
        return &ne_softc[i];
207
    }
208
 
209
  return NULL;
210
}
211
 
212
/* Read data from an NE2000 device.  Read LEN bytes at ADDR, storing
213
   them into P.  */
214
 
215
static void
216
ne_read_data (struct ne_softc *sc, int addr, int len, unsigned char *p)
217
{
218
  unsigned int port = sc->port;
219
  unsigned int dport = port + DATAPORT;
220
 
221
  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
222
  outport_byte (port + RBCR0, len);
223
  outport_byte (port + RBCR1, len >> 8);
224
  outport_byte (port + RSAR0, addr);
225
  outport_byte (port + RSAR1, addr >> 8);
226
  outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
227
 
228
  if (sc->byte_transfers)
229
    while (len > 0) {
230
      unsigned char d;
231
 
232
      inport_byte (dport, d);
233
      *p++ = d;
234
      len--;
235
    }
236
  else  /* word transfers */
237
    while (len > 0) {
238
      unsigned short d;
239
 
240
      inport_word (dport, d);
241
      *p++ = d;
242
      *p++ = d >> 8;
243
      len -= 2;
244
    }
245
 
246
  outport_byte (port + ISR, MSK_RDC);
247
}
248
 
249
/* Handle the current NE2000 status.  This is called when the device
250
   signals an interrupt.  It is also called at other times while
251
   NE2000 interrupts have been disabled.  */
252
 
253
static void
254
ne_check_status (struct ne_softc *sc)
255
{
256
  unsigned int port = sc->port;
257
  unsigned char status;
258
 
259
  /* It seems that we need to use a loop here, because if the NE2000
260
     signals an interrupt because packet transmission is complete, and
261
     then receives a packet while interrupts are disabled, it seems to
262
     sometimes fail to signal the interrupt for the received packet
263
     when interrupts are reenabled.  (Based on the behaviour of the
264
     Realtek 8019AS chip).  */
265
 
266
  while (1) {
267
    inport_byte (port + ISR, status);
268
    if (status == 0)
269
      break;
270
 
271
#ifdef DEBUG_NE2000
272
    printk ("NE2000 status 0x%x (8259 enabled: %s; mask: %x)\n", status,
273
            i8259s_cache & (1 << sc->irno) ? "no" : "yes",
274
            i8259s_cache);
275
#endif
276
 
277
    /* Check for incoming packet overwrite.  */
278
    if (status & MSK_OVW) {
279
      unsigned char status2;
280
 
281
      ++sc->stats.overruns;
282
      outport_byte (port + CMDR, MSK_PG0 | MSK_STP | MSK_RD2);
283
      Wait_X_ms (2);
284
      outport_byte (port + RBCR0, 0);
285
      outport_byte (port + RBCR1, 0);
286
      inport_byte (port + ISR, status2);
287
      status |= status2 & (MSK_PTX | MSK_TXE);
288
      outport_byte (port + TCR, MSK_LOOP);
289
      outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
290
      sc->overrun = 1;
291
      if ((status & (MSK_PTX | MSK_TXE)) == 0)
292
        sc->resend = 1;
293
      rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
294
    }
295
 
296
    /* Check for transmitted packet.  The transmit daemon may now be
297
       able to send another packet to the device.  */
298
    if ((status & (MSK_PTX | MSK_TXE)) != 0) {
299
      ++sc->stats.tx_acks;
300
      outport_byte (port + ISR, status & (MSK_PTX | MSK_TXE));
301
      --sc->inuse;
302
      sc->transmitting = 0;
303
      if (sc->inuse > 0 || (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) != 0)
304
        rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
305
    }
306
 
307
    /* Check for received packet.  */
308
    if ((status & (MSK_PRX | MSK_RXE)) != 0) {
309
      ++sc->stats.rx_acks;
310
      outport_byte (port + ISR, status & (MSK_PRX | MSK_RXE));
311
      rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
312
    }
313
 
314
    /* Check for counter change.  */
315
    if ((status & MSK_CNT) != 0) {
316
      unsigned char add;
317
 
318
      inport_byte (port + CNTR0, add);
319
      sc->stats.rx_frame_errors += add;
320
      inport_byte (port + CNTR1, add);
321
      sc->stats.rx_crc_errors += add;
322
      inport_byte (port + CNTR2, add);
323
      sc->stats.rx_missed_errors += add;
324
      outport_byte (port + ISR, MSK_CNT);
325
    }
326
  }
327
 
328
  outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
329
}
330
 
331
/* Handle an NE2000 interrupt.  */
332
 
333
static void
334
ne_interrupt_handler (rtems_vector_number v)
335
{
336
  struct ne_softc *sc;
337
 
338
  sc = ne_device_for_irno (v);
339
  if (sc == NULL)
340
    return;
341
 
342
  ++sc->stats.interrupts;
343
 
344
  ne_check_status (sc);
345
}
346
 
347
/* Turn NE2000 interrupts on.  */
348
 
349
static void
350
ne_interrupt_on (const rtems_irq_connect_data *irq)
351
{
352
  struct ne_softc *sc;
353
 
354
#ifdef DEBUG_NE2000
355
  printk ("ne_interrupt_on\n");
356
#endif
357
  sc = ne_device_for_irno (irq->name);
358
  if (sc != NULL)
359
    outport_byte (sc->port + IMR, NE_INTERRUPTS);
360
}
361
 
362
/* Turn NE2000 interrupts off.  See ne_interrupt_on.  */
363
 
364
static void
365
ne_interrupt_off (const rtems_irq_connect_data *irq)
366
{
367
  struct ne_softc *sc;
368
 
369
#ifdef DEBUG_NE2000
370
  printk ("ne_interrupt_off\n");
371
#endif
372
  sc = ne_device_for_irno (irq->name);
373
  if (sc != NULL)
374
    outport_byte (sc->port + IMR, 0);
375
}
376
 
377
/* Return whether NE2000 interrupts are on.  */
378
 
379
static int
380
ne_interrupt_is_on (const rtems_irq_connect_data *irq)
381
{
382
  return BSP_irq_enabled_at_i8259s (irq->name);
383
}
384
 
385
/* Initialize the NE2000 hardware.  */
386
 
387
static void
388
ne_init_hardware (struct ne_softc *sc)
389
{
390
  unsigned int port = sc->port;
391
  int i;
392
  rtems_irq_connect_data irq;
393
 
394
#ifdef DEBUG_NE2000
395
  printk ("ne_init_hardware\n");
396
#endif
397
 
398
  /* Initialize registers.  */
399
 
400
  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
401
 
402
  if (sc->byte_transfers) {
403
    outport_byte (port + DCR, MSK_FT10 | MSK_BMS);
404
  }
405
  else {
406
    outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
407
  }
408
 
409
  outport_byte (port + RBCR0, 0);
410
  outport_byte (port + RBCR1, 0);
411
  outport_byte (port + RCR, MSK_MON);
412
  outport_byte (port + TCR, MSK_LOOP);
413
  outport_byte (port + IMR, 0);
414
  outport_byte (port + ISR, 0xff);
415
  outport_byte (port + PSTOP, NE_STOP_PAGE);
416
  outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
417
  outport_byte (port + BNRY, NE_STOP_PAGE - 1);
418
 
419
  /* Set the Ethernet hardware address.  */
420
 
421
  outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
422
  for (i = 0; i < ETHER_ADDR_LEN; ++i)
423
    outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]);
424
 
425
#ifdef DEBUG_NE2000
426
  printk ("Using ethernet address: ");
427
  for (i = 0; i < ETHER_ADDR_LEN; ++i)
428
    printk("%x ",sc->arpcom.ac_enaddr[i]);
429
  printk ("\n");
430
#endif
431
 
432
  /* Clear the multicast address.  */
433
  for (i = 0; i < MARsize; ++i)
434
    outport_byte (port + MAR + i, 0);
435
 
436
  outport_byte (port + CURR, NE_FIRST_RX_PAGE);
437
 
438
  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
439
 
440
  /* Put the device on line.  */
441
  outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
442
 
443
  /* Set up interrupts.  */
444
 
445
  irq.name = sc->irno;
446
  irq.hdl = ne_interrupt_handler;
447
  irq.on = ne_interrupt_on;
448
  irq.off = ne_interrupt_off;
449
  irq.isOn = ne_interrupt_is_on;
450
 
451
  if (! BSP_install_rtems_irq_handler (&irq))
452
    rtems_panic ("Can't attach NE interrupt handler for irq %d.\n",
453
                 sc->irno);
454
 
455
  /* Prepare to receive packets.  */
456
 
457
  outport_byte (port + TCR, 0);
458
  outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0));
459
}
460
 
461
/* The NE2000 packet receive daemon.  This task is started when the
462
   NE2000 driver is initialized.  */
463
 
464
static void
465
ne_rx_daemon (void *arg)
466
{
467
  struct ne_softc *sc = (struct ne_softc *) arg;
468
  struct ifnet *ifp = &sc->arpcom.ac_if;
469
  unsigned int port = sc->port;
470
  unsigned int dport = port + DATAPORT;
471
 
472
  while (1) {
473
    rtems_event_set events;
474
 
475
    /* Wait for the interrupt handler to tell us that there is a
476
       packet ready to receive.  */
477
    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
478
                                RTEMS_WAIT | RTEMS_EVENT_ANY,
479
                                RTEMS_NO_TIMEOUT,
480
                                &events);
481
 
482
    /* Don't let the device interrupt us now.  */
483
    outport_byte (port + IMR, 0);
484
 
485
    while (1) {
486
      unsigned char startpage, currpage;
487
      unsigned short statnext, len;
488
      int next;
489
      struct mbuf *m;
490
      unsigned char *p;
491
      int startaddr;
492
      int toend;
493
      struct ether_header *eh;
494
 
495
      inport_byte (port + BNRY, startpage);
496
 
497
      outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
498
      inport_byte (port + CURR, currpage);
499
      outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
500
 
501
      ++startpage;
502
      if (startpage >= NE_STOP_PAGE)
503
        startpage = NE_FIRST_RX_PAGE;
504
 
505
      if (startpage == currpage)
506
        break;
507
 
508
#ifdef DEBUG_NE2000
509
      printk ("ne_rx_daemon: start page %x; current page %x\n",
510
              startpage, currpage);
511
#endif
512
 
513
      /* Read the buffer header.  This is 1 byte receive status, 1
514
         byte page of next buffer, 2 bytes length.  */
515
      outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
516
      outport_byte (port + RBCR0, 4);
517
      outport_byte (port + RBCR1, 0);
518
      outport_byte (port + RSAR0, 0);
519
      outport_byte (port + RSAR1, startpage);
520
      outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
521
 
522
      if (sc->byte_transfers) {
523
        unsigned char data;
524
 
525
        inport_byte (dport, data);  /* Throw away status  */
526
        inport_byte (dport, data);
527
        next = data;
528
 
529
        inport_byte (dport, data);
530
        len = data;
531
        inport_byte (dport, data);
532
        len |= data << 8;
533
      }
534
      else {                        /* Word transfers  */
535
        inport_word (dport, statnext);
536
        inport_word (dport, len);
537
 
538
        next = statnext >> 8;
539
      }
540
 
541
      outport_byte (port + ISR, MSK_RDC);
542
 
543
      if (next >= NE_STOP_PAGE)
544
        next = NE_FIRST_RX_PAGE;
545
 
546
      /* The first four bytes of the length are the buffer header.  */
547
      len -= 4;
548
      startaddr = startpage * NE_PAGE_SIZE + 4;
549
 
550
      MGETHDR (m, M_WAIT, MT_DATA);
551
      MCLGET (m, M_WAIT);
552
      m->m_pkthdr.rcvif = ifp;
553
 
554
      p = mtod (m, unsigned char *);
555
      m->m_len = m->m_pkthdr.len = len - sizeof (struct ether_header);
556
 
557
      toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr;
558
      if (toend < len) {
559
        ne_read_data (sc, startaddr, toend, p);
560
        p += toend;
561
        len -= toend;
562
        startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
563
      }
564
 
565
      if (len > 0)
566
        ne_read_data (sc, startaddr, len, p);
567
 
568
      eh = mtod (m, struct ether_header *);
569
      m->m_data += sizeof (struct ether_header);
570
      ether_input (ifp, eh, m);
571
 
572
      ++sc->stats.rx_packets;
573
 
574
      outport_byte (port + BNRY, next - 1);
575
    }
576
 
577
    if (sc->overrun) {
578
      outport_byte (port + ISR, MSK_OVW);
579
      outport_byte (port + TCR, 0);
580
      if (sc->resend)
581
        outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
582
      sc->resend = 0;
583
      sc->overrun = 0;
584
    }
585
 
586
    /* Reenable device interrupts.  */
587
    outport_byte (port + IMR, NE_INTERRUPTS);
588
  }
589
}
590
 
591
/* Load an NE2000 packet onto the device.  */
592
 
593
static void
594
ne_loadpacket (struct ne_softc *sc, struct mbuf *m)
595
{
596
  unsigned int port = sc->port;
597
  unsigned int dport = port + DATAPORT;
598
  struct mbuf *mhold = m;
599
  int leftover;
600
  unsigned char leftover_data;
601
  int timeout;
602
 
603
#ifdef DEBUG_NE2000
604
  printk ("Uploading NE2000 packet\n");
605
#endif
606
 
607
  /* Reset remote DMA complete flag.  */
608
  outport_byte (port + ISR, MSK_RDC);
609
 
610
  /* Write out the count.  */
611
  outport_byte (port + RBCR0, m->m_pkthdr.len);
612
  outport_byte (port + RBCR1, m->m_pkthdr.len >> 8);
613
 
614
  sc->sendlen[sc->nextavail] = m->m_pkthdr.len;
615
 
616
  /* Tell the device which address we want to write to.  */
617
  outport_byte (port + RSAR0, 0);
618
  outport_byte (port + RSAR1,
619
                NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
620
 
621
  /* Set up the write.  */
622
  outport_byte (port + CMDR, MSK_PG0 | MSK_RWR | MSK_STA);
623
 
624
  /* Transfer the mbuf chain to device memory.  NE2000 devices require
625
     that the data be transferred as words, so we need to handle odd
626
     length mbufs.  Never occurs if we force byte transfers. */
627
 
628
  leftover = 0;
629
  leftover_data = '\0';
630
 
631
  for (; m != NULL; m = m->m_next) {
632
    int len;
633
    unsigned char *data;
634
 
635
    len = m->m_len;
636
    if (len == 0)
637
      continue;
638
 
639
    data = mtod (m, unsigned char *);
640
 
641
    if (leftover) {
642
      unsigned char next;
643
 
644
      /* Data left over from previous mbuf in chain.  */
645
      next = *data++;
646
      --len;
647
      outport_word (dport, leftover_data | (next << 8));
648
      leftover = 0;
649
    }
650
 
651
    /* If using byte transfers, len always ends up as zero so
652
       there are no leftovers. */
653
 
654
    if (sc->byte_transfers)
655
      while (len > 0) {
656
        outport_byte (dport, *data++);
657
        len--;
658
      }
659
    else
660
      while (len > 1) {
661
        outport_word (dport, data[0] | (data[1] << 8));
662
        data += 2;
663
        len -= 2;
664
      }
665
 
666
    if (len > 0)
667
      {
668
        leftover = 1;
669
        leftover_data = *data++;
670
      }
671
  }
672
 
673
  if (leftover)
674
    outport_word (dport, leftover_data);
675
 
676
  m_freem (mhold);
677
 
678
  /* Wait for the device to complete accepting the data, with a
679
     limiting counter so that we don't wait too long.  */
680
  for (timeout = 0; timeout < 100; ++timeout)
681
    {
682
      unsigned char status;
683
 
684
      inport_byte (port + ISR, status);
685
 
686
#ifdef DEBUG_NE2000
687
      if ((status &~ MSK_RDC) != 0)
688
        printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
689
                status);
690
#endif
691
 
692
      if ((status & MSK_RDC) != 0) {
693
        outport_byte (port + ISR, MSK_RDC);
694
        break;
695
      }
696
    }
697
 
698
  if (timeout >= 100)
699
    printk ("Timed out waiting for acknowledgement of uploaded NE2000 packet\n");
700
 
701
  ++sc->nextavail;
702
  if (sc->nextavail == NE_TX_BUFS)
703
    sc->nextavail = 0;
704
}
705
 
706
/* Tell the NE2000 to transmit a buffer whose contents we have already
707
   loaded onto the device.  */
708
 
709
static void
710
ne_transmit (struct ne_softc *sc)
711
{
712
  unsigned int port = sc->port;
713
  int len;
714
 
715
#ifdef DEBUG_NE2000
716
  printk ("Transmitting NE2000 packet\n");
717
#endif
718
 
719
  len = sc->sendlen[sc->nextsend];
720
  if (len < ET_MINLEN)
721
    len = ET_MINLEN;
722
  outport_byte (port + TBCR0, len);
723
  outport_byte (port + TBCR1, len >> 8);
724
 
725
  outport_byte (port + TPSR, NE_FIRST_TX_PAGE + (sc->nextsend * NE_TX_PAGES));
726
 
727
  outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
728
 
729
  ++sc->nextsend;
730
  if (sc->nextsend == NE_TX_BUFS)
731
    sc->nextsend = 0;
732
 
733
  ++sc->stats.tx_packets;
734
}
735
 
736
/* The NE2000 packet transmit daemon.  This task is started when the
737
   NE2000 driver is initialized.  */
738
 
739
static void
740
ne_tx_daemon (void *arg)
741
{
742
  struct ne_softc *sc = (struct ne_softc *) arg;
743
  unsigned int port = sc->port;
744
  struct ifnet *ifp = &sc->arpcom.ac_if;
745
 
746
  while (1) {
747
    rtems_event_set events;
748
 
749
    /* Wait for a packet to be ready for sending, or for there to be
750
       room for another packet in the device memory.  */
751
    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
752
                                RTEMS_EVENT_ANY | RTEMS_WAIT,
753
                                RTEMS_NO_TIMEOUT,
754
                                &events);
755
 
756
#ifdef DEBUG_NE2000
757
    printk ("ne_tx_daemon\n");
758
#endif
759
 
760
    /* This daemon handles both uploading data onto the device and
761
       telling the device to transmit data which has been uploaded.
762
       These are separate tasks, because while the device is
763
       transmitting one buffer we will upload another.  */
764
 
765
    /* Don't let the device interrupt us now.  */
766
    outport_byte (port + IMR, 0);
767
 
768
    while (1) {
769
      struct mbuf *m;
770
 
771
      /* If the device is not transmitting a packet, and we have
772
         uploaded a packet, tell the device to transmit it.  */
773
      if (! sc->transmitting && sc->inuse > 0) {
774
        sc->transmitting = 1;
775
        ne_transmit (sc);
776
      }
777
 
778
      /* If we don't have any more buffers to send, quit now.  */
779
      if (ifp->if_snd.ifq_head == NULL) {
780
        ifp->if_flags &= ~IFF_OACTIVE;
781
        break;
782
      }
783
 
784
      /* Allocate a buffer to load data into.  If there are none
785
         available, quit until a buffer has been transmitted.  */
786
      if (sc->inuse >= NE_TX_BUFS)
787
        break;
788
 
789
      ++sc->inuse;
790
 
791
      IF_DEQUEUE (&ifp->if_snd, m);
792
      if (m == NULL)
793
        panic ("ne_tx_daemon");
794
 
795
      ne_loadpacket (sc, m);
796
 
797
      /* Check the device status.  It may have finished transmitting
798
         the last packet.  */
799
      ne_check_status (sc);
800
    }
801
 
802
    /* Reenable device interrupts.  */
803
    outport_byte (port + IMR, NE_INTERRUPTS);
804
  }
805
}
806
 
807
/* Start sending an NE2000 packet.  */
808
 
809
static void
810
ne_start (struct ifnet *ifp)
811
{
812
  struct ne_softc *sc = ifp->if_softc;
813
 
814
  /* Tell the transmit daemon to wake up and send a packet.  */
815
  rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
816
  ifp->if_flags |= IFF_OACTIVE;
817
}
818
 
819
/* Initialize and start and NE2000.  */
820
 
821
static void
822
ne_init (void *arg)
823
{
824
  struct ne_softc *sc = (struct ne_softc *) arg;
825
  struct ifnet *ifp = &sc->arpcom.ac_if;
826
 
827
  if (sc->tx_daemon_tid == 0) {
828
    sc->inuse = 0;
829
    sc->nextavail = 0;
830
    sc->nextsend = 0;
831
    sc->transmitting = 0;
832
 
833
    ne_init_hardware (sc);
834
 
835
    sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc);
836
    sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc);
837
  }
838
 
839
  ifp->if_flags |= IFF_RUNNING;
840
}
841
 
842
/* Stop an NE2000.  */
843
 
844
static void
845
ne_stop (struct ne_softc *sc)
846
{
847
  unsigned int port = sc->port;
848
  int i;
849
 
850
  sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
851
 
852
  /* Stop everything.  */
853
  outport_byte (port + CMDR, MSK_STP | MSK_RD2);
854
 
855
  /* Wait for the interface to stop, using I as a time limit.  */
856
  for (i = 0; i < 5000; ++i)
857
    {
858
      unsigned char status;
859
 
860
      inport_byte (port + ISR, status);
861
      if ((status & MSK_RST) != 0)
862
        break;
863
    }
864
 
865
  sc->inuse = 0;
866
  sc->nextavail = 0;
867
  sc->nextsend = 0;
868
  sc->transmitting = 0;
869
}
870
 
871
/* Show NE2000 interface statistics.  */
872
 
873
static void
874
ne_stats (struct ne_softc *sc)
875
{
876
  printf ("    Received packets: %-8lu", sc->stats.rx_packets);
877
  printf (" Transmitted packets: %-8lu\n", sc->stats.tx_packets);
878
  printf ("        Receive acks: %-8lu", sc->stats.rx_acks);
879
  printf ("       Transmit acks: %-8lu\n", sc->stats.tx_acks);
880
  printf ("     Packet overruns: %-8lu", sc->stats.overruns);
881
  printf ("        Frame errors: %-8lu\n", sc->stats.rx_frame_errors);
882
  printf ("          CRC errors: %-8lu", sc->stats.rx_crc_errors);
883
  printf ("      Missed packets: %-8lu\n", sc->stats.rx_missed_errors);
884
  printf ("          Interrupts: %-8lu\n", sc->stats.interrupts);
885
}
886
 
887
/* NE2000 driver ioctl handler.  */
888
 
889
static int
890
ne_ioctl (struct ifnet *ifp, int command, caddr_t data)
891
{
892
  struct ne_softc *sc = ifp->if_softc;
893
  int error = 0;
894
 
895
  switch (command) {
896
  case SIOCGIFADDR:
897
  case SIOCSIFADDR:
898
    error = ether_ioctl (ifp, command, data);
899
    break;
900
 
901
  case SIOCSIFFLAGS:
902
    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
903
    case IFF_RUNNING:
904
      ne_stop (sc);
905
      break;
906
 
907
    case IFF_UP:
908
      ne_init (sc);
909
      break;
910
 
911
    case IFF_UP | IFF_RUNNING:
912
      ne_stop (sc);
913
      ne_init (sc);
914
      break;
915
 
916
    default:
917
      break;
918
    }
919
    break;
920
 
921
  case SIO_RTEMS_SHOW_STATS:
922
    ne_stats (sc);
923
    break;
924
 
925
    /* FIXME: Multicast commands must be added here.  */
926
 
927
  default:
928
    error = EINVAL;
929
    break;
930
  }
931
 
932
  return error;
933
}
934
 
935
/* Attach an NE2000 driver to the system.  */
936
 
937
int
938
rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config)
939
{
940
  int i;
941
  struct ne_softc *sc;
942
  struct ifnet *ifp;
943
  int mtu;
944
 
945
  /* Find a free driver.  */
946
  sc = NULL;
947
  for (i = 0; i < NNEDRIVER; ++i) {
948
    sc = &ne_softc[i];
949
    ifp = &sc->arpcom.ac_if;
950
    if (ifp->if_softc == NULL)
951
      break;
952
  }
953
 
954
  if (sc == NULL) {
955
    printf ("Too many NE2000 drivers.\n");
956
    return 0;
957
  }
958
 
959
  memset (sc, 0, sizeof *sc);
960
 
961
  /* Check whether we do byte-wide or word-wide transfers.  */
962
 
963
#ifdef NE2000_BYTE_TRANSFERS
964
  sc->byte_transfers = TRUE;
965
#else
966
  sc->byte_transfers = FALSE;
967
#endif
968
 
969
  /* Handle the options passed in by the caller.  */
970
 
971
  if (config->mtu != 0)
972
    mtu = config->mtu;
973
  else
974
    mtu = ETHERMTU;
975
 
976
  if (config->irno != 0)
977
    sc->irno = config->irno;
978
  else {
979
    /* We use 5 as the default IRQ.  */
980
    sc->irno = 5;
981
  }
982
 
983
  if (config->port != 0)
984
    sc->port = config->port;
985
  else {
986
    /* We use 0x300 as the default IO port number.  */
987
    sc->port = 0x300;
988
  }
989
 
990
  sc->accept_broadcasts = ! config->ignore_broadcast;
991
 
992
  if (config->hardware_address != NULL)
993
    memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
994
            ETHER_ADDR_LEN);
995
  else
996
    {
997
      unsigned char prom[16];
998
      int ia;
999
 
1000
      /* Read the PROM to get the Ethernet hardware address.  */
1001
 
1002
      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
1003
 
1004
      if (sc->byte_transfers) {
1005
        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
1006
      }
1007
      else {
1008
        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
1009
      }
1010
 
1011
      outport_byte (sc->port + RBCR0, 0);
1012
      outport_byte (sc->port + RBCR1, 0);
1013
      outport_byte (sc->port + RCR, MSK_MON);
1014
      outport_byte (sc->port + TCR, MSK_LOOP);
1015
      outport_byte (sc->port + IMR, 0);
1016
      outport_byte (sc->port + ISR, 0xff);
1017
 
1018
      ne_read_data (sc, 0, sizeof prom, prom);
1019
 
1020
      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
1021
 
1022
      for (ia = 0; ia < ETHER_ADDR_LEN; ++ia)
1023
        sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
1024
    }
1025
 
1026
  /* Set up the network interface.  */
1027
 
1028
  ifp->if_softc = sc;
1029
  ifp->if_unit = i + 1;
1030
  ifp->if_name = "ne";
1031
  ifp->if_mtu = mtu;
1032
  ifp->if_init = ne_init;
1033
  ifp->if_ioctl = ne_ioctl;
1034
  ifp->if_start = ne_start;
1035
  ifp->if_output = ether_output;
1036
  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
1037
  if (ifp->if_snd.ifq_maxlen == 0)
1038
    ifp->if_snd.ifq_maxlen = ifqmaxlen;
1039
 
1040
  /* Attach the interface.  */
1041
 
1042
  if_attach (ifp);
1043
  ether_ifattach (ifp);
1044
 
1045
  return 1;
1046
}

powered by: WebSVN 2.1.0

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