source: rtems/c/src/lib/libbsp/i386/pc386/ne2000/ne2000.c @ 7b0ff008

4.104.114.84.95
Last change on this file since 7b0ff008 was 7b0ff008, checked in by Joel Sherrill <joel.sherrill@…>, on 01/04/00 at 13:48:48

Made to compile again.

  • Property mode set to 100644
File size: 25.9 KB
Line 
1/*  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$
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
124struct 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
187static struct ne_softc ne_softc[NNEDRIVER];
188
189/* Forward declarations to avoid warnings */
190
191static void ne_stop (struct ne_softc *sc);
192static void ne_init (void *arg);
193
194/* Find the NE2000 device which is attached at a particular interrupt
195   vector.  */
196
197static struct ne_softc *
198ne_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
215static void
216ne_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
253static void
254ne_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
333static void
334ne_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
349static void
350ne_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
364static void
365ne_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
379static int
380ne_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
387static void
388ne_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
464static void
465ne_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
593static void
594ne_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
709static void
710ne_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
739static void
740ne_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
809static void
810ne_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
821static void
822ne_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
844static void
845ne_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
873static void
874ne_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
889static int
890ne_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
937int
938rtems_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}
Note: See TracBrowser for help on using the repository browser.