source: rtems/c/src/lib/libbsp/i386/pc386/ne2000/ne2000.c @ 441b90e

4.115
Last change on this file since 441b90e was c145d73, checked in by Ralf Corsepius <ralf.corsepius@…>, on 10/17/11 at 12:37:24

2011-10-17 Ralf Corsépius <ralf.corsepius@…>

  • ne2000/ne2000.c: Remove unused var "stat".
  • Property mode set to 100644
File size: 32.4 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 the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
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 <stdlib.h>
37#include <assert.h>
38#include <errno.h>
39
40#include <rtems/error.h>
41#include <rtems/rtems_bsdnet.h>
42
43#include <sys/param.h>
44#include <sys/mbuf.h>
45#include <sys/socket.h>
46#include <sys/sockio.h>
47
48#include <net/if.h>
49
50#include <netinet/in.h>
51#include <netinet/if_ether.h>
52
53#include <bsp/irq.h>
54
55/* Define this to force byte-wide data transfers with the NIC. This
56   is needed for boards like the TS-1325 386EX PC, which support only
57   an 8-bit PC/104 bus.  Undefine this on a normal PC.*/
58
59/* #define NE2000_BYTE_TRANSFERS */
60
61/* Define this to print debugging messages with printk.  */
62
63/* #define DEBUG_NE2000 */
64/* #define DEBUG_NE */
65
66/* We expect to be able to read a complete packet into an mbuf.  */
67
68#if (MCLBYTES < 1520)
69# error "Driver must have MCLBYTES >= 1520"
70#endif
71
72/* The 8390 macro definitions in wd80x3.h expect RO to be defined.  */
73#define RO 0
74
75/* Minimum size of Ethernet packet.  */
76#define ET_MINLEN 60
77
78/* The number of NE2000 devices supported by this driver.  */
79
80#define NNEDRIVER 1
81
82/* RTEMS event number used by the interrupt handler to signal the
83   driver task.  This must not be any of the events used by the
84   network task synchronization.  */
85#define INTERRUPT_EVENT RTEMS_EVENT_1
86
87/* RTEMS event number used to start the transmit daemon.  This must
88   not be the same as INTERRUPT_EVENT.  */
89#define START_TRANSMIT_EVENT RTEMS_EVENT_2
90
91/* Interrupts we want to handle from the device.  */
92
93#define NE_INTERRUPTS \
94  (MSK_PRX | MSK_PTX | MSK_RXE | MSK_TXE | MSK_OVW | MSK_CNT)
95
96/* The size of a page in device memory.  */
97
98#define NE_PAGE_SIZE (256)
99
100/* The first page address in device memory.  */
101
102#define NE_START_PAGE (0x40)
103
104/* The last page address, plus 1.  */
105
106#define NE_STOP_PAGE (0x80)
107
108/* The number of pages used for a single transmit buffer.  This is
109   1536 bytes, enough for a full size packet.  */
110
111#define NE_TX_PAGES (6)
112
113/* The number of transmit buffers.  We use two, so we can load one
114   packet while the other is being sent.  */
115
116#define NE_TX_BUFS (2)
117
118/* We use the first pages in memory as transmit buffers, and the
119   remaining ones as receive buffers.  */
120
121#define NE_FIRST_TX_PAGE (NE_START_PAGE)
122
123#define NE_FIRST_RX_PAGE (NE_FIRST_TX_PAGE + NE_TX_PAGES * NE_TX_BUFS)
124
125/* Data we store for each NE2000 device.  */
126
127struct ne_softc {
128  /* The bsdnet information structure.  */
129  struct arpcom arpcom;
130
131  /* The interrupt request number.  */
132  unsigned int irno;
133  /* The base IO port number.  */
134  unsigned int port;
135
136  /* Whether we accept broadcasts.  */
137  int accept_broadcasts;
138
139  /* The thread ID of the transmit task.   */
140  rtems_id tx_daemon_tid;
141  /* The thread ID of the receive task.  */
142  rtems_id rx_daemon_tid;
143
144  /* Whether we use byte-transfers with the device. */
145  bool byte_transfers;
146
147  /* The number of memory buffers which the transmit daemon has loaded
148     with data to be sent, but which have not yet been completely
149     sent.  */
150  int inuse;
151  /* The index of the next available transmit memory buffer.  */
152  int nextavail;
153  /* The index of the next transmit buffer to send.  */
154  int nextsend;
155  /* Nonzero if the device is currently transmitting a packet.  */
156  int transmitting;
157  /* The length of the data stored in each transmit buffer.  */
158  int sendlen[NE_TX_BUFS];
159
160  /* Set if we have a packet overrun while receiving.  */
161  int overrun;
162  /* Set if we should resend after an overrun.  */
163  int resend;
164
165  /* Statistics.  */
166  struct {
167    /* Number of packets received.  */
168    unsigned long rx_packets;
169    /* Number of packets sent.  */
170    unsigned long tx_packets;
171    /* Number of interrupts.  */
172    unsigned long interrupts;
173    /* Number of receive acknowledgements.  */
174    unsigned long rx_acks;
175    /* Number of transmit acknowledgements.  */
176    unsigned long tx_acks;
177    /* Number of packet overruns.  */
178    unsigned long overruns;
179    /* Number of frame errors.  */
180    unsigned long rx_frame_errors;
181    /* Number of CRC errors.  */
182    unsigned long rx_crc_errors;
183    /* Number of missed packets.  */
184    unsigned long rx_missed_errors;
185  } stats;
186};
187
188/* The list of NE2000 devices on this system.  */
189
190static struct ne_softc ne_softc[NNEDRIVER];
191
192/*
193 * receive ring descriptor
194 *
195 * The National Semiconductor DS8390 Network interface controller uses
196 * the following receive ring headers.  The way this works is that the
197 * memory on the interface card is chopped up into 256 bytes blocks.
198 * A contiguous portion of those blocks are marked for receive packets
199 * by setting start and end block #'s in the NIC.  For each packet that
200 * is put into the receive ring, one of these headers (4 bytes each) is
201 * tacked onto the front. The first byte is a copy of the receiver status
202 * register at the time the packet was received.
203 */
204struct ne_ring
205{
206        unsigned char rsr;    /* receiver status */
207        unsigned char next;   /* pointer to next packet */
208        unsigned char cnt_lo; /* bytes in packet (length + 4)   */
209        unsigned char cnt_hi; /* 16-bit, little-endian value    */
210};
211
212/* Forward declarations to avoid warnings */
213
214static void ne_init_irq_handler (int irno);
215static void ne_stop (struct ne_softc *sc);
216static void ne_stop_hardware (struct ne_softc *sc);
217static void ne_init (void *arg);
218static void ne_init_hardware (struct ne_softc *sc);
219
220static void ne_reset(struct ne_softc *sc);
221#ifdef DEBUG_NE
222static void ne_dump(struct ne_softc *sc);
223#endif
224
225/* Find the NE2000 device which is attached at a particular interrupt
226   vector.  */
227
228static struct ne_softc *
229ne_device_for_irno (int irno)
230{
231  int i;
232
233  for (i = 0; i < NNEDRIVER; ++i)
234    {
235      if (ne_softc[i].irno == irno
236          && ne_softc[i].arpcom.ac_if.if_softc != NULL)
237        return &ne_softc[i];
238    }
239
240  return NULL;
241}
242
243/* Read data from an NE2000 device.  Read LEN bytes at ADDR, storing
244   them into P.  */
245
246static void
247ne_read_data (struct ne_softc *sc, int addr, int len, unsigned char *p)
248{
249  unsigned int port = sc->port;
250  unsigned int dport = port + DATAPORT;
251
252  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
253  outport_byte (port + RBCR0, len);
254  outport_byte (port + RBCR1, len >> 8);
255  outport_byte (port + RSAR0, addr);
256  outport_byte (port + RSAR1, addr >> 8);
257  outport_byte (port + CMDR, MSK_PG0 | MSK_RRE | MSK_STA);
258
259  if (sc->byte_transfers)
260  {
261    unsigned char d;
262    while (len > 0)
263    {
264      inport_byte(dport, d);
265      *p++ = d;
266      len--;
267    }
268  }
269  else  /* word transfers */
270  {
271    unsigned short d;
272    while (len > 1)
273    {
274      inport_word(dport, d);
275      *p++ = d;
276      *p++ = d >> 8;
277      len -= 2;
278    }
279    if (len)
280    {
281      inport_word(dport, d);
282      *p++ = d;
283    }
284  }
285
286  outport_byte (port + ISR, MSK_RDC);
287}
288
289/* Handle the current NE2000 status.  This is called when the device
290   signals an interrupt.  It is also called at other times while
291   NE2000 interrupts have been disabled.  */
292
293static void
294ne_check_status (struct ne_softc *sc, int from_irq_handler)
295{
296  struct ifnet *ifp = &sc->arpcom.ac_if;
297  unsigned int port = sc->port;
298  unsigned char status;
299
300  /* It seems that we need to use a loop here, because if the NE2000
301     signals an interrupt because packet transmission is complete, and
302     then receives a packet while interrupts are disabled, it seems to
303     sometimes fail to signal the interrupt for the received packet
304     when interrupts are reenabled.  (Based on the behaviour of the
305     Realtek 8019AS chip).  */
306
307  /* int count = 0; */
308  while (1)
309  {
310    inport_byte (port + ISR, status);
311    if (status == 0)
312      break;
313
314    /* ack */
315    outport_byte (port + ISR, status);
316
317#ifdef DEBUG_NE2000
318    printk ("NE2000 status 0x%x (8259 enabled: %s; mask: %x)\n", status,
319            i8259s_cache & (1 << sc->irno) ? "no" : "yes",
320            i8259s_cache);
321#endif
322
323    /* Check for incoming packet overwrite.  */
324    if (status & MSK_OVW)
325    {
326      ifp->if_timer = 0;
327#ifdef DEBUG_NE
328      printk("^");
329#endif
330      ++sc->stats.overruns;
331      ne_reset(sc);
332      /* Reenable device interrupts.  */
333      if (from_irq_handler)
334        outport_byte(port + IMR, NE_INTERRUPTS);
335      return;
336    }
337
338    /* Check for transmitted packet.  The transmit daemon may now be
339       able to send another packet to the device.  */
340    if ((status & (MSK_PTX | MSK_TXE)) != 0)
341    {
342      ifp->if_timer = 0;
343      ++sc->stats.tx_acks;
344      --sc->inuse;
345      sc->transmitting = 0;
346      if (sc->inuse > 0 || (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) != 0)
347        rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
348    }
349
350    /* Check for received packet.  */
351    if ((status & (MSK_PRX | MSK_RXE)) != 0)
352    {
353      ++sc->stats.rx_acks;
354      rtems_event_send (sc->rx_daemon_tid, INTERRUPT_EVENT);
355    }
356
357    /* Check for counter change.  */
358    if ((status & MSK_CNT) != 0)
359    {
360      unsigned char add;
361      inport_byte (port + CNTR0, add);
362      sc->stats.rx_frame_errors += add;
363      inport_byte (port + CNTR1, add);
364      sc->stats.rx_crc_errors += add;
365      inport_byte (port + CNTR2, add);
366      sc->stats.rx_missed_errors += add;
367    }
368
369    break;
370    /* if (++count >= 1000)
371    {
372      printk("status: %x\n", status);
373      ne_reset(sc);
374      if (from_irq_handler)
375        outport_byte(port + IMR, NE_INTERRUPTS);
376      return;
377    } */
378  }
379
380  outport_byte (port + CMDR, MSK_PG0 | MSK_STA | MSK_RD2);
381}
382
383/* Handle an NE2000 interrupt.  */
384
385static void
386ne_interrupt_handler (rtems_irq_hdl_param cdata)
387{
388  rtems_vector_number v = (rtems_vector_number) cdata;
389  struct ne_softc *sc;
390
391  sc = ne_device_for_irno (v);
392  if (sc == NULL)
393    return;
394
395  ++sc->stats.interrupts;
396
397#ifdef DEBUG_NE
398  printk("!");
399#endif
400  ne_check_status(sc, 1);
401}
402
403/* Turn NE2000 interrupts on.  */
404
405static void
406ne_interrupt_on (const rtems_irq_connect_data *irq)
407{
408  struct ne_softc *sc;
409
410#ifdef DEBUG_NE
411  printk ("ne_interrupt_on()\n");
412#endif
413  sc = ne_device_for_irno (irq->name);
414  if (sc != NULL)
415    outport_byte (sc->port + IMR, NE_INTERRUPTS);
416}
417
418/* Turn NE2000 interrupts off.  See ne_interrupt_on.  */
419
420static void
421ne_interrupt_off (const rtems_irq_connect_data *irq)
422{
423  struct ne_softc *sc;
424
425#ifdef DEBUG_NE
426  printk ("ne_interrupt_off()\n");
427#endif
428  sc = ne_device_for_irno (irq->name);
429  if (sc != NULL)
430    outport_byte (sc->port + IMR, 0);
431}
432
433/* Return whether NE2000 interrupts are on.  */
434
435static int
436ne_interrupt_is_on (const rtems_irq_connect_data *irq)
437{
438  return BSP_irq_enabled_at_i8259s (irq->name);
439}
440
441/* Initialize the NE2000 hardware.  */
442
443static void
444ne_init_hardware (struct ne_softc *sc)
445{
446  unsigned int port = sc->port;
447  int i;
448
449#ifdef DEBUG_NE2000
450  printk ("ne_init_hardware()\n");
451#endif
452
453  /* Initialize registers.  */
454
455  /* Set interface for page 0, Remote DMA complete, Stopped */
456  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
457
458  /* Set FIFO threshold to 8, No auto-init Remote DMA, byte order=80x86 */
459  /* byte-wide DMA xfers */
460  if (sc->byte_transfers)
461    outport_byte (port + DCR, MSK_FT10 | MSK_BMS);
462  /* word-wide DMA xfers */
463  else
464    outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
465
466  /* Clear Remote Byte Count Registers */
467  outport_byte (port + RBCR0, 0);
468  outport_byte (port + RBCR1, 0);
469
470  /* For the moment, don't store incoming packets in memory. */
471  outport_byte (port + RCR, MSK_MON);
472
473  /* Place NIC in internal loopback mode */
474  outport_byte (port + TCR, MSK_LOOP);
475
476  /* Initialize transmit/receive (ring-buffer) Page Start */
477  outport_byte (port + TPSR, NE_FIRST_TX_PAGE);
478  outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
479
480  /* Initialize Receiver (ring-buffer) Page Stop and Boundary */
481  outport_byte (port + PSTOP, NE_STOP_PAGE);
482  outport_byte (port + BNRY, NE_STOP_PAGE - 1);
483
484  /* Clear all interrupts */
485  outport_byte (port + ISR, 0xff);
486  /* Disable all interrupts */
487  outport_byte (port + IMR, 0);
488
489  /* Program Command Register for page 1 */
490  outport_byte (port + CMDR, MSK_PG1 | MSK_RD2 | MSK_STP);
491
492  /* Set the Ethernet hardware address.  */
493  for (i = 0; i < ETHER_ADDR_LEN; ++i)
494    outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]);
495
496  /* Set Current Page pointer to next_packet */
497  outport_byte (port + CURR, NE_FIRST_RX_PAGE);
498
499  /* Clear the multicast address.  */
500  for (i = 0; i < MARsize; ++i)
501    outport_byte (port + MAR + i, 0);
502
503  /* Set page 0 registers */
504  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
505
506  /* accept broadcast + multicast */
507  outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0) | MSK_AM);
508
509  /* Start interface */
510  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
511
512  /* Take interface out of loopback */
513  outport_byte (port + TCR, 0);
514}
515
516/* Set up interrupts.
517*/
518static void
519ne_init_irq_handler(int irno)
520{
521  rtems_irq_connect_data irq;
522
523#ifdef DEBUG_NE
524  printk("ne_init_irq_handler(%d)\n", irno);
525#endif
526  irq.name = irno;
527  irq.hdl = ne_interrupt_handler;
528  irq.handle = (rtems_irq_hdl) irno;
529  irq.on = ne_interrupt_on;
530  irq.off = ne_interrupt_off;
531  irq.isOn = ne_interrupt_is_on;
532
533  if (!BSP_install_rtems_irq_handler (&irq))
534    rtems_panic ("Can't attach NE interrupt handler for irq %d\n", irno);
535}
536
537/* The NE2000 packet receive daemon.  This task is started when the
538   NE2000 driver is initialized.  */
539
540#ifdef DEBUG_NE
541static int ccc = 0; /* experinent! */
542#endif
543
544static void
545ne_rx_daemon (void *arg)
546{
547  struct ne_softc *sc = (struct ne_softc *) arg;
548  struct ifnet *ifp = &sc->arpcom.ac_if;
549  unsigned int port = sc->port;
550
551  while (1)
552  {
553    rtems_event_set events;
554
555    /* Wait for the interrupt handler to tell us that there is a
556       packet ready to receive.  */
557    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
558                                RTEMS_WAIT | RTEMS_EVENT_ANY,
559                                RTEMS_NO_TIMEOUT,
560                                &events);
561
562    /* Don't let the device interrupt us now.  */
563    outport_byte (port + IMR, 0);
564
565    while (1)
566    {
567      unsigned char startpage, currpage;
568      unsigned short len;
569      unsigned char next, cnt1, cnt2;
570      struct mbuf *m;
571      unsigned char *p;
572      int startaddr;
573      int toend;
574      struct ether_header *eh;
575      struct ne_ring hdr; /* ring buffer header */
576      int reset;
577
578      inport_byte (port + BNRY, startpage);
579
580      outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
581      inport_byte (port + CURR, currpage);
582      outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
583
584      ++startpage;
585      if (startpage >= NE_STOP_PAGE)
586        startpage = NE_FIRST_RX_PAGE;
587
588      if (startpage == currpage)
589        break;
590
591#ifdef DEBUG_NE2000
592      printk ("ne_rx_daemon: start page %x; current page %x\n",
593              startpage, currpage);
594#endif
595
596      reset = 0;
597
598      /* Read the buffer header */
599      startaddr = startpage * NE_PAGE_SIZE;
600      ne_read_data(sc, startaddr, sizeof(hdr), (unsigned char *)&hdr);
601      next = hdr.next;
602      if (next >= NE_STOP_PAGE)
603        next = NE_FIRST_RX_PAGE;
604
605      /* check packet length */
606      len = ( hdr.cnt_hi << 8 ) | hdr.cnt_lo;
607      if (currpage < startpage)
608        cnt1 = currpage + (NE_STOP_PAGE - NE_FIRST_RX_PAGE) - startpage;
609      else
610        cnt1 = currpage - startpage;
611      cnt2 = len / NE_PAGE_SIZE;
612      if (len % NE_PAGE_SIZE)
613        cnt2++;
614      if (cnt1 < cnt2)
615      {
616#ifdef DEBUG_NE
617        printk("(%x<%x:%x)", cnt1, cnt2, len);
618/*
619        printk("start page 0x%x; current page 0x%x\n",
620                startpage, currpage);
621        printk("cnt1 < cnt2 (0x%x, 0x%x); len 0x%x\n",
622                cnt1, cnt2, len);
623*/
624#endif
625        reset = 1;
626      }
627      if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
628          len < (ETHER_MIN_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
629          len > MCLBYTES)
630      {
631#ifdef DEBUG_NE
632        printk("(%x)", len);
633/*
634        printk("start page 0x%x; current page 0x%x\n",
635                startpage, currpage);
636        printk("len out of range: 0x%x\n", len);
637        printk("stat: 0x%x, next: 0x%x\n", hdr.rsr, hdr.next);
638*/
639#endif
640        reset = 1;
641      }
642#ifdef DEBUG_NE
643      if (++ccc == 100)
644      { ccc = 0; reset = 1;
645        printk("T");
646      }
647#endif
648
649      /* reset interface */
650      if (reset)
651      {
652        ne_reset(sc);
653        goto Next;
654      }
655
656      /* The first four bytes of the length are the buffer header.  */
657      len -= sizeof(struct ne_ring);
658      startaddr += sizeof(struct ne_ring);
659
660      MGETHDR (m, M_WAIT, MT_DATA);
661      MCLGET (m, M_WAIT);
662      m->m_pkthdr.rcvif = ifp;
663
664      p = mtod (m, unsigned char *);
665      m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
666
667      toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr;
668      if (toend < len)
669      {
670        ne_read_data (sc, startaddr, toend, p);
671        p += toend;
672        len -= toend;
673        startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
674      }
675
676      if (len > 0)
677        ne_read_data (sc, startaddr, len, p);
678
679      eh = mtod (m, struct ether_header *);
680      m->m_data += sizeof (struct ether_header);
681
682#ifdef DEBUG_NE
683  /* printk("[r%d]", ((hdr.cnt_hi<<8) + hdr.cnt_lo - sizeof(hdr))); */
684  printk("<");
685#endif
686      ether_input (ifp, eh, m);
687      ++sc->stats.rx_packets;
688
689      outport_byte (port + BNRY, next - 1);
690    }
691
692    if (sc->overrun) {
693      outport_byte (port + ISR, MSK_OVW);
694      outport_byte (port + TCR, 0);
695      if (sc->resend)
696        outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
697      sc->resend = 0;
698      sc->overrun = 0;
699    }
700
701  Next:
702    /* Reenable device interrupts.  */
703    outport_byte (port + IMR, NE_INTERRUPTS);
704  }
705}
706
707/* Load an NE2000 packet onto the device.  */
708
709static void
710ne_loadpacket (struct ne_softc *sc, struct mbuf *m)
711{
712  unsigned int port = sc->port;
713  unsigned int dport = port + DATAPORT;
714  struct mbuf *mhold = m;
715  int leftover;
716  unsigned char leftover_data;
717  int timeout;
718  int send_cnt = 0;
719
720#ifdef DEBUG_NE2000
721  printk ("Uploading NE2000 packet\n");
722#endif
723
724  /* Reset remote DMA complete flag.  */
725  outport_byte (port + ISR, MSK_RDC);
726
727  /* Write out the count.  */
728  outport_byte (port + RBCR0, m->m_pkthdr.len);
729  outport_byte (port + RBCR1, m->m_pkthdr.len >> 8);
730
731  sc->sendlen[sc->nextavail] = m->m_pkthdr.len;
732
733  /* Tell the device which address we want to write to.  */
734  outport_byte (port + RSAR0, 0);
735  outport_byte (port + RSAR1,
736                NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
737
738  /* Set up the write.  */
739  outport_byte (port + CMDR, MSK_PG0 | MSK_RWR | MSK_STA);
740
741  /* Transfer the mbuf chain to device memory.  NE2000 devices require
742     that the data be transferred as words, so we need to handle odd
743     length mbufs.  Never occurs if we force byte transfers. */
744
745  leftover = 0;
746  leftover_data = '\0';
747
748  for (; m != NULL; m = m->m_next) {
749    int len;
750    unsigned char *data;
751
752    len = m->m_len;
753    if (len == 0)
754      continue;
755
756    data = mtod (m, unsigned char *);
757
758    if (leftover) {
759      unsigned char next;
760
761      /* Data left over from previous mbuf in chain.  */
762      next = *data++;
763      --len;
764      outport_word (dport, leftover_data | (next << 8));
765      send_cnt += 2;
766      leftover = 0;
767    }
768
769    /* If using byte transfers, len always ends up as zero so
770       there are no leftovers. */
771
772    if (sc->byte_transfers)
773      while (len > 0) {
774        outport_byte (dport, *data++);
775        len--;
776      }
777    else
778      while (len > 1) {
779        outport_word (dport, data[0] | (data[1] << 8));
780        data += 2;
781        len -= 2;
782        send_cnt += 2;
783      }
784
785    if (len > 0)
786      {
787        leftover = 1;
788        leftover_data = *data++;
789      }
790  }
791
792  if (leftover)
793  {
794    outport_word (dport, leftover_data);
795    send_cnt += 2;
796  }
797
798#ifdef DEBUG_NE
799  /* printk("{l%d|%d}", send_cnt, sc->nextavail); */
800  printk("v");
801#endif
802  m_freem (mhold);
803
804  /* Wait for the device to complete accepting the data, with a
805     limiting counter so that we don't wait too long.  */
806  for (timeout = 0; timeout < 100; ++timeout)
807    {
808      unsigned char status;
809
810      inport_byte (port + ISR, status);
811
812#ifdef DEBUG_NE2000
813      if ((status &~ MSK_RDC) != 0)
814        printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
815                status);
816#endif
817
818      if ((status & MSK_RDC) != 0) {
819        outport_byte (port + ISR, MSK_RDC);
820        break;
821      }
822    }
823
824  if (timeout >= 100)
825    printk ("Timed out waiting for acknowledgement of uploaded NE2000 packet\n");
826
827  ++sc->nextavail;
828  if (sc->nextavail == NE_TX_BUFS)
829    sc->nextavail = 0;
830}
831
832/* Tell the NE2000 to transmit a buffer whose contents we have already
833   loaded onto the device.  */
834
835static void
836ne_transmit (struct ne_softc *sc)
837{
838  struct ifnet *ifp = &sc->arpcom.ac_if;
839  unsigned int port = sc->port;
840  int len;
841
842#ifdef DEBUG_NE2000
843  printk ("Transmitting NE2000 packet\n");
844#endif
845
846  len = sc->sendlen[sc->nextsend];
847  if (len < ET_MINLEN)
848    len = ET_MINLEN;
849  outport_byte (port + TBCR0, len);
850  outport_byte (port + TBCR1, len >> 8);
851
852  outport_byte (port + TPSR, NE_FIRST_TX_PAGE + (sc->nextsend * NE_TX_PAGES));
853
854  outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
855
856#ifdef DEBUG_NE
857  /* printk("{s%d|%d}", len, sc->nextsend); */
858  printk(">");
859#endif
860  ++sc->nextsend;
861  if (sc->nextsend == NE_TX_BUFS)
862    sc->nextsend = 0;
863
864  ++sc->stats.tx_packets;
865
866  /* set watchdog timer */
867  ifp->if_timer = 2;
868}
869
870/* The NE2000 packet transmit daemon.  This task is started when the
871   NE2000 driver is initialized.  */
872
873static void
874ne_tx_daemon (void *arg)
875{
876  struct ne_softc *sc = (struct ne_softc *) arg;
877  unsigned int port = sc->port;
878  struct ifnet *ifp = &sc->arpcom.ac_if;
879
880  while (1) {
881    rtems_event_set events;
882
883    /* Wait for a packet to be ready for sending, or for there to be
884       room for another packet in the device memory.  */
885    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
886                                RTEMS_EVENT_ANY | RTEMS_WAIT,
887                                RTEMS_NO_TIMEOUT,
888                                &events);
889
890#ifdef DEBUG_NE2000
891    printk ("ne_tx_daemon\n");
892#endif
893
894    /* This daemon handles both uploading data onto the device and
895       telling the device to transmit data which has been uploaded.
896       These are separate tasks, because while the device is
897       transmitting one buffer we will upload another.  */
898
899    /* Don't let the device interrupt us now.  */
900    outport_byte (port + IMR, 0);
901
902    while (1) {
903      struct mbuf *m;
904
905      /* If the device is not transmitting a packet, and we have
906         uploaded a packet, tell the device to transmit it.  */
907      if (! sc->transmitting && sc->inuse > 0) {
908        sc->transmitting = 1;
909        ne_transmit (sc);
910      }
911
912      /* If we don't have any more buffers to send, quit now.  */
913      if (ifp->if_snd.ifq_head == NULL) {
914        ifp->if_flags &= ~IFF_OACTIVE;
915        break;
916      }
917
918      /* Allocate a buffer to load data into.  If there are none
919         available, quit until a buffer has been transmitted.  */
920      if (sc->inuse >= NE_TX_BUFS)
921        break;
922
923      ++sc->inuse;
924
925      IF_DEQUEUE (&ifp->if_snd, m);
926      if (m == NULL)
927        panic ("ne_tx_daemon");
928
929      ne_loadpacket (sc, m);
930
931      /* Check the device status.  It may have finished transmitting
932         the last packet.  */
933      ne_check_status(sc, 0);
934    }
935
936    /* Reenable device interrupts.  */
937    outport_byte (port + IMR, NE_INTERRUPTS);
938  }
939}
940
941/* Start sending an NE2000 packet.  */
942
943static void
944ne_start (struct ifnet *ifp)
945{
946  struct ne_softc *sc = ifp->if_softc;
947
948#ifdef DEBUG_NE
949  printk("S");
950#endif
951  /* Tell the transmit daemon to wake up and send a packet.  */
952  rtems_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
953  ifp->if_flags |= IFF_OACTIVE;
954}
955
956/* Initialize and start and NE2000.  */
957
958static void
959ne_init (void *arg)
960{
961  struct ne_softc *sc = (struct ne_softc *) arg;
962  struct ifnet *ifp = &sc->arpcom.ac_if;
963
964#ifdef DEBUG_NE
965  printk("ne_init()\n");
966  ne_dump(sc);
967#endif
968
969  /* only once... */
970  if (sc->tx_daemon_tid == 0)
971  {
972    sc->inuse = 0;
973    sc->nextavail = 0;
974    sc->nextsend = 0;
975    sc->transmitting = 0;
976
977    ne_init_hardware (sc);
978
979    sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc);
980    sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc);
981
982    /* install rtems irq handler */
983    ne_init_irq_handler(sc->irno);
984  }
985
986  ifp->if_flags |= IFF_RUNNING;
987}
988
989/* Stop an NE2000.  */
990
991static void
992ne_stop (struct ne_softc *sc)
993{
994  sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
995
996  ne_stop_hardware(sc);
997
998  sc->inuse = 0;
999  sc->nextavail = 0;
1000  sc->nextsend = 0;
1001  sc->transmitting = 0;
1002  sc->overrun = 0;
1003  sc->resend = 0;
1004}
1005
1006static void
1007ne_stop_hardware (struct ne_softc *sc)
1008{
1009  unsigned int port = sc->port;
1010  int i;
1011
1012  /* Stop everything.  */
1013  outport_byte (port + CMDR, MSK_STP | MSK_RD2);
1014
1015  /* Wait for the interface to stop, using I as a time limit.  */
1016  for (i = 0; i < 5000; ++i)
1017    {
1018      unsigned char status;
1019
1020      inport_byte (port + ISR, status);
1021      if ((status & MSK_RST) != 0)
1022        break;
1023    }
1024}
1025
1026/* reinitializing interface
1027*/
1028static void
1029ne_reset(struct ne_softc *sc)
1030{
1031  ne_stop(sc);
1032  ne_init_hardware(sc);
1033  sc->arpcom.ac_if.if_flags |= IFF_RUNNING;
1034  sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
1035#ifdef DEBUG_NE
1036  printk("*");
1037#endif
1038}
1039
1040#ifdef DEBUG_NE
1041/* show anything about ne
1042*/
1043static void
1044ne_dump(struct ne_softc *sc)
1045{
1046  int i;
1047  printk("\nne configuration:\n");
1048  printk("ethernet addr:");
1049  for (i=0; i<ETHER_ADDR_LEN; i++)
1050    printk(" %x", sc->arpcom.ac_enaddr[i]);
1051  printk("\n");
1052  printk("irq = %d\n", sc->irno);
1053  printk("port = 0x%x\n", sc->port);
1054  printk("accept_broadcasts = %d\n", sc->accept_broadcasts);
1055  printk("byte_transfers = %d\n", sc->byte_transfers);
1056}
1057#endif
1058
1059/* Show NE2000 interface statistics.  */
1060
1061static void
1062ne_stats (struct ne_softc *sc)
1063{
1064  printf ("    Received packets: %-8lu", sc->stats.rx_packets);
1065  printf (" Transmitted packets: %-8lu\n", sc->stats.tx_packets);
1066  printf ("        Receive acks: %-8lu", sc->stats.rx_acks);
1067  printf ("       Transmit acks: %-8lu\n", sc->stats.tx_acks);
1068  printf ("     Packet overruns: %-8lu", sc->stats.overruns);
1069  printf ("        Frame errors: %-8lu\n", sc->stats.rx_frame_errors);
1070  printf ("          CRC errors: %-8lu", sc->stats.rx_crc_errors);
1071  printf ("      Missed packets: %-8lu\n", sc->stats.rx_missed_errors);
1072  printf ("          Interrupts: %-8lu\n", sc->stats.interrupts);
1073}
1074
1075static int ne_set_multicast_filter(struct ne_softc* sc)
1076{
1077  int i=0;
1078  unsigned int port = sc->port;
1079  unsigned char cmd = 0;
1080       
1081  /* Save CMDR settings */
1082  inport_byte(port + CMDR, cmd);
1083  /* Change to page 1 */
1084  outport_byte(port + CMDR, cmd | MSK_PG1);
1085
1086  /* Set MAR to accept _all_ multicast packets */
1087  for (i = 0; i < MARsize; ++i) {
1088    outport_byte (port + MAR + i, 0xFF);
1089  }
1090
1091  /* Revert to original CMDR settings */
1092  outport_byte(port + CMDR, cmd);
1093
1094  return 0;
1095}
1096
1097/* NE2000 driver ioctl handler.  */
1098
1099static int
1100ne_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
1101{
1102  struct ne_softc *sc = ifp->if_softc;
1103  int error = 0;
1104
1105  switch (command) {
1106  case SIOCGIFADDR:
1107  case SIOCSIFADDR:
1108    error = ether_ioctl (ifp, command, data);
1109    break;
1110
1111  case SIOCSIFFLAGS:
1112    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
1113    case IFF_RUNNING:
1114      ne_stop (sc);
1115      break;
1116
1117    case IFF_UP:
1118      ne_init (sc);
1119      break;
1120
1121    case IFF_UP | IFF_RUNNING:
1122      ne_stop (sc);
1123      ne_init (sc);
1124      break;
1125
1126    default:
1127      break;
1128    }
1129    break;
1130 
1131  case SIOCADDMULTI:
1132  case SIOCDELMULTI:
1133  {
1134    struct ifreq* ifr = (struct ifreq*) data;
1135    error = (command == SIOCADDMULTI ?
1136      ether_addmulti(ifr, &(sc->arpcom)) :
1137      ether_delmulti(ifr, &(sc->arpcom)) );
1138    /* ENETRESET indicates that driver should update its multicast filters */
1139    if(error == ENETRESET) {
1140      error = ne_set_multicast_filter(sc);
1141    }
1142    break;
1143  }
1144
1145  case SIO_RTEMS_SHOW_STATS:
1146    ne_stats (sc);
1147    break;
1148
1149  default:
1150    error = EINVAL;
1151    break;
1152  }
1153
1154  return error;
1155}
1156
1157/*
1158 * Device timeout/watchdog routine. Entered if the device neglects to
1159 *      generate an interrupt after a transmit has been started on it.
1160 */
1161static void
1162ne_watchdog(struct ifnet *ifp)
1163{
1164  struct ne_softc *sc = ifp->if_softc;
1165
1166  printk("ne2000: device timeout\n");
1167    ifp->if_oerrors++;
1168
1169  ne_reset(sc);
1170}
1171
1172static void
1173print_byte(unsigned char b)
1174{
1175  printk("%x%x", b >> 4, b & 0x0f);
1176}
1177
1178/* Attach an NE2000 driver to the system.  */
1179
1180int
1181rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
1182{
1183  int i;
1184  struct ne_softc *sc;
1185  struct ifnet *ifp;
1186  int mtu;
1187
1188  /* dettach ... */
1189  if (!attach)
1190    return 0;
1191
1192  /* Find a free driver.  */
1193  sc = NULL;
1194  for (i = 0; i < NNEDRIVER; ++i) {
1195    sc = &ne_softc[i];
1196    ifp = &sc->arpcom.ac_if;
1197    if (ifp->if_softc == NULL)
1198      break;
1199  }
1200
1201  if (sc == NULL) {
1202    printf ("Too many NE2000 drivers.\n");
1203    return 0;
1204  }
1205
1206  memset (sc, 0, sizeof *sc);
1207
1208  /* Check whether we do byte-wide or word-wide transfers.  */
1209
1210#ifdef NE2000_BYTE_TRANSFERS
1211  sc->byte_transfers = true;
1212#else
1213  sc->byte_transfers = false;
1214#endif
1215
1216  /* Handle the options passed in by the caller.  */
1217
1218  if (config->mtu != 0)
1219    mtu = config->mtu;
1220  else
1221    mtu = ETHERMTU;
1222
1223  if (config->irno != 0)
1224    sc->irno = config->irno;
1225  else {
1226    const char* opt;
1227    opt = bsp_cmdline_arg ("--ne2k-irq=");
1228    if (opt) {
1229      opt += sizeof ("--ne2k-irq=") - 1;
1230      sc->irno = strtoul (opt, 0, 0);
1231    }
1232    if (sc->irno == 0) {
1233      /* We use 5 as the default IRQ.  */
1234      sc->irno = 5;
1235    }
1236  }
1237
1238  if (config->port != 0)
1239    sc->port = config->port;
1240  else {
1241    const char* opt;
1242    opt = bsp_cmdline_arg ("--ne2k-port=");
1243    if (opt) {
1244      opt += sizeof ("--ne2k-port=") - 1;
1245      sc->port = strtoul (opt, 0, 0);
1246    }
1247    if (config->port == 0) {
1248      /* We use 0x300 as the default IO port number.  */
1249      sc->port = 0x300;
1250    }
1251  }
1252
1253  sc->accept_broadcasts = ! config->ignore_broadcast;
1254
1255  if (config->hardware_address != NULL)
1256    memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
1257            ETHER_ADDR_LEN);
1258  else
1259    {
1260      unsigned char prom[16];
1261      int ia;
1262
1263      /* Read the PROM to get the Ethernet hardware address.  */
1264
1265      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
1266
1267      if (sc->byte_transfers) {
1268        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
1269      }
1270      else {
1271        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
1272      }
1273
1274      outport_byte (sc->port + RBCR0, 0);
1275      outport_byte (sc->port + RBCR1, 0);
1276      outport_byte (sc->port + RCR, MSK_MON);
1277      outport_byte (sc->port + TCR, MSK_LOOP);
1278      outport_byte (sc->port + IMR, 0);
1279      outport_byte (sc->port + ISR, 0xff);
1280
1281      ne_read_data (sc, 0, sizeof prom, prom);
1282
1283      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
1284
1285      for (ia = 0; ia < ETHER_ADDR_LEN; ++ia)
1286        sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
1287    }
1288
1289  /* Set up the network interface.  */
1290
1291  ifp->if_softc = sc;
1292  ifp->if_unit = i + 1;
1293  ifp->if_name = "ne";
1294  ifp->if_mtu = mtu;
1295  ifp->if_init = ne_init;
1296  ifp->if_ioctl = ne_ioctl;
1297  ifp->if_watchdog = ne_watchdog;
1298  ifp->if_start = ne_start;
1299  ifp->if_output = ether_output;
1300  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1301  if (ifp->if_snd.ifq_maxlen == 0)
1302    ifp->if_snd.ifq_maxlen = ifqmaxlen;
1303
1304  /* Attach the interface.  */
1305
1306  if_attach (ifp);
1307  ether_ifattach (ifp);
1308
1309  printk("network device '%s' <", config->name);
1310  print_byte(sc->arpcom.ac_enaddr[0]);
1311  for (i=1; i<ETHER_ADDR_LEN; i++)
1312  { printk(":");
1313    print_byte(sc->arpcom.ac_enaddr[i]);
1314  }
1315  printk("> initialized on port 0x%x, irq %d\n", sc->port, sc->irno);
1316
1317  return 1;
1318}
Note: See TracBrowser for help on using the repository browser.