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

5
Last change on this file since d8d6a08 was d8d6a08, checked in by Sebastian Huber <sebastian.huber@…>, on 01/27/18 at 10:12:44

bsps: Move network define to source files

Define INSIDE_RTEMS_BSD_TCPIP_STACK in the network interface driver
source files to avoid some build system magic.

  • Property mode set to 100644
File size: 32.3 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.org/license/LICENSE.
8 *
9 *  Both the ne2000 and the wd80x3 are based on the National Semiconductor
10 *  8390 chip, so there is a fair amount of overlap between the two
11 *  drivers.  It would be possible in principle to combine some code into
12 *  a separate set of subroutines called by both.  In fact, the drivers in
13 *  both OpenBSD and Linux work this way.  I didn't bother, because for
14 *  the relatively simple drivers used by RTEMS, the overlap is not
15 *  especially large, and any reasonable use of subroutines would lead to
16 *  slightly less efficient code.
17
18 *  This ne2000 driver uses two transmit buffers.  While one packet is
19 *  being transmitted over the Ethernet, RTEMS will upload another.  Since
20 *  uploading a packet to the ne2000 is rather slow, I don't think there
21 *  is any point to having more than two transmit buffers.  However, the
22 *  code does make it possible, by changing NE_TX_BUFS, although that
23 *  would of course reduce the number of receive buffers.
24 *
25 *  I suspect that the wd80x3 driver would benefit slightly from copying
26 *  the multiple transmit buffer code.  However, I have no way to test
27 *  that.
28 */
29
30#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
31
32#include <bsp.h>
33#include <libchip/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_bsdnet_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_bsdnet_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/* Initialize the NE2000 hardware.  */
434
435static void
436ne_init_hardware (struct ne_softc *sc)
437{
438  unsigned int port = sc->port;
439  int i;
440
441#ifdef DEBUG_NE2000
442  printk ("ne_init_hardware()\n");
443#endif
444
445  /* Initialize registers.  */
446
447  /* Set interface for page 0, Remote DMA complete, Stopped */
448  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
449
450  /* Set FIFO threshold to 8, No auto-init Remote DMA, byte order=80x86 */
451  /* byte-wide DMA xfers */
452  if (sc->byte_transfers)
453    outport_byte (port + DCR, MSK_FT10 | MSK_BMS);
454  /* word-wide DMA xfers */
455  else
456    outport_byte (port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
457
458  /* Clear Remote Byte Count Registers */
459  outport_byte (port + RBCR0, 0);
460  outport_byte (port + RBCR1, 0);
461
462  /* For the moment, don't store incoming packets in memory. */
463  outport_byte (port + RCR, MSK_MON);
464
465  /* Place NIC in internal loopback mode */
466  outport_byte (port + TCR, MSK_LOOP);
467
468  /* Initialize transmit/receive (ring-buffer) Page Start */
469  outport_byte (port + TPSR, NE_FIRST_TX_PAGE);
470  outport_byte (port + PSTART, NE_FIRST_RX_PAGE);
471
472  /* Initialize Receiver (ring-buffer) Page Stop and Boundary */
473  outport_byte (port + PSTOP, NE_STOP_PAGE);
474  outport_byte (port + BNRY, NE_STOP_PAGE - 1);
475
476  /* Clear all interrupts */
477  outport_byte (port + ISR, 0xff);
478  /* Disable all interrupts */
479  outport_byte (port + IMR, 0);
480
481  /* Program Command Register for page 1 */
482  outport_byte (port + CMDR, MSK_PG1 | MSK_RD2 | MSK_STP);
483
484  /* Set the Ethernet hardware address.  */
485  for (i = 0; i < ETHER_ADDR_LEN; ++i)
486    outport_byte (port + PAR + i, sc->arpcom.ac_enaddr[i]);
487
488  /* Set Current Page pointer to next_packet */
489  outport_byte (port + CURR, NE_FIRST_RX_PAGE);
490
491  /* Clear the multicast address.  */
492  for (i = 0; i < MARsize; ++i)
493    outport_byte (port + MAR + i, 0);
494
495  /* Set page 0 registers */
496  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
497
498  /* accept broadcast + multicast */
499  outport_byte (port + RCR, (sc->accept_broadcasts ? MSK_AB : 0) | MSK_AM);
500
501  /* Start interface */
502  outport_byte (port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STA);
503
504  /* Take interface out of loopback */
505  outport_byte (port + TCR, 0);
506}
507
508/* Set up interrupts.
509*/
510static void
511ne_init_irq_handler(int irno)
512{
513  rtems_irq_connect_data irq;
514
515#ifdef DEBUG_NE
516  printk("ne_init_irq_handler(%d)\n", irno);
517#endif
518  irq.name = irno;
519  irq.hdl = ne_interrupt_handler;
520  irq.handle = (rtems_irq_hdl) irno;
521  irq.on = ne_interrupt_on;
522  irq.off = ne_interrupt_off;
523  irq.isOn = NULL;
524
525  if (!BSP_install_rtems_irq_handler (&irq))
526    rtems_panic ("Can't attach NE interrupt handler for irq %d\n", irno);
527}
528
529/* The NE2000 packet receive daemon.  This task is started when the
530   NE2000 driver is initialized.  */
531
532#ifdef DEBUG_NE
533static int ccc = 0; /* experinent! */
534#endif
535
536static void
537ne_rx_daemon (void *arg)
538{
539  struct ne_softc *sc = (struct ne_softc *) arg;
540  struct ifnet *ifp = &sc->arpcom.ac_if;
541  unsigned int port = sc->port;
542
543  while (1)
544  {
545    rtems_event_set events;
546
547    /* Wait for the interrupt handler to tell us that there is a
548       packet ready to receive.  */
549    rtems_bsdnet_event_receive (INTERRUPT_EVENT,
550                                RTEMS_WAIT | RTEMS_EVENT_ANY,
551                                RTEMS_NO_TIMEOUT,
552                                &events);
553
554    /* Don't let the device interrupt us now.  */
555    outport_byte (port + IMR, 0);
556
557    while (1)
558    {
559      unsigned char startpage, currpage;
560      unsigned short len;
561      unsigned char next, cnt1, cnt2;
562      struct mbuf *m;
563      unsigned char *p;
564      int startaddr;
565      int toend;
566      struct ether_header *eh;
567      struct ne_ring hdr; /* ring buffer header */
568      int reset;
569
570      inport_byte (port + BNRY, startpage);
571
572      outport_byte (port + CMDR, MSK_PG1 | MSK_RD2);
573      inport_byte (port + CURR, currpage);
574      outport_byte (port + CMDR, MSK_PG0 | MSK_RD2);
575
576      ++startpage;
577      if (startpage >= NE_STOP_PAGE)
578        startpage = NE_FIRST_RX_PAGE;
579
580      if (startpage == currpage)
581        break;
582
583#ifdef DEBUG_NE2000
584      printk ("ne_rx_daemon: start page %x; current page %x\n",
585              startpage, currpage);
586#endif
587
588      reset = 0;
589
590      /* Read the buffer header */
591      startaddr = startpage * NE_PAGE_SIZE;
592      ne_read_data(sc, startaddr, sizeof(hdr), (unsigned char *)&hdr);
593      next = hdr.next;
594      if (next >= NE_STOP_PAGE)
595        next = NE_FIRST_RX_PAGE;
596
597      /* check packet length */
598      len = ( hdr.cnt_hi << 8 ) | hdr.cnt_lo;
599      if (currpage < startpage)
600        cnt1 = currpage + (NE_STOP_PAGE - NE_FIRST_RX_PAGE) - startpage;
601      else
602        cnt1 = currpage - startpage;
603      cnt2 = len / NE_PAGE_SIZE;
604      if (len % NE_PAGE_SIZE)
605        cnt2++;
606      if (cnt1 < cnt2)
607      {
608#ifdef DEBUG_NE
609        printk("(%x<%x:%x)", cnt1, cnt2, len);
610/*
611        printk("start page 0x%x; current page 0x%x\n",
612                startpage, currpage);
613        printk("cnt1 < cnt2 (0x%x, 0x%x); len 0x%x\n",
614                cnt1, cnt2, len);
615*/
616#endif
617        reset = 1;
618      }
619      if (len > (ETHER_MAX_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
620          len < (ETHER_MIN_LEN - ETHER_CRC_LEN + sizeof(struct ne_ring)) ||
621          len > MCLBYTES)
622      {
623#ifdef DEBUG_NE
624        printk("(%x)", len);
625/*
626        printk("start page 0x%x; current page 0x%x\n",
627                startpage, currpage);
628        printk("len out of range: 0x%x\n", len);
629        printk("stat: 0x%x, next: 0x%x\n", hdr.rsr, hdr.next);
630*/
631#endif
632        reset = 1;
633      }
634#ifdef DEBUG_NE
635      if (++ccc == 100)
636      { ccc = 0; reset = 1;
637        printk("T");
638      }
639#endif
640
641      /* reset interface */
642      if (reset)
643      {
644        ne_reset(sc);
645        goto Next;
646      }
647
648      /* The first four bytes of the length are the buffer header.  */
649      len -= sizeof(struct ne_ring);
650      startaddr += sizeof(struct ne_ring);
651
652      MGETHDR (m, M_WAIT, MT_DATA);
653      MCLGET (m, M_WAIT);
654      m->m_pkthdr.rcvif = ifp;
655
656      p = mtod (m, unsigned char *);
657      m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
658
659      toend = NE_STOP_PAGE * NE_PAGE_SIZE - startaddr;
660      if (toend < len)
661      {
662        ne_read_data (sc, startaddr, toend, p);
663        p += toend;
664        len -= toend;
665        startaddr = NE_FIRST_RX_PAGE * NE_PAGE_SIZE;
666      }
667
668      if (len > 0)
669        ne_read_data (sc, startaddr, len, p);
670
671      eh = mtod (m, struct ether_header *);
672      m->m_data += sizeof (struct ether_header);
673
674#ifdef DEBUG_NE
675  /* printk("[r%d]", ((hdr.cnt_hi<<8) + hdr.cnt_lo - sizeof(hdr))); */
676  printk("<");
677#endif
678      ether_input (ifp, eh, m);
679      ++sc->stats.rx_packets;
680
681      outport_byte (port + BNRY, next - 1);
682    }
683
684    if (sc->overrun) {
685      outport_byte (port + ISR, MSK_OVW);
686      outport_byte (port + TCR, 0);
687      if (sc->resend)
688        outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
689      sc->resend = 0;
690      sc->overrun = 0;
691    }
692
693  Next:
694    /* Reenable device interrupts.  */
695    outport_byte (port + IMR, NE_INTERRUPTS);
696  }
697}
698
699/* Load an NE2000 packet onto the device.  */
700
701static void
702ne_loadpacket (struct ne_softc *sc, struct mbuf *m)
703{
704  unsigned int port = sc->port;
705  unsigned int dport = port + DATAPORT;
706  struct mbuf *mhold = m;
707  int leftover;
708  unsigned char leftover_data;
709  int timeout;
710  int send_cnt = 0;
711
712#ifdef DEBUG_NE2000
713  printk ("Uploading NE2000 packet\n");
714#endif
715
716  /* Reset remote DMA complete flag.  */
717  outport_byte (port + ISR, MSK_RDC);
718
719  /* Write out the count.  */
720  outport_byte (port + RBCR0, m->m_pkthdr.len);
721  outport_byte (port + RBCR1, m->m_pkthdr.len >> 8);
722
723  sc->sendlen[sc->nextavail] = m->m_pkthdr.len;
724
725  /* Tell the device which address we want to write to.  */
726  outport_byte (port + RSAR0, 0);
727  outport_byte (port + RSAR1,
728                NE_FIRST_TX_PAGE + (sc->nextavail * NE_TX_PAGES));
729
730  /* Set up the write.  */
731  outport_byte (port + CMDR, MSK_PG0 | MSK_RWR | MSK_STA);
732
733  /* Transfer the mbuf chain to device memory.  NE2000 devices require
734     that the data be transferred as words, so we need to handle odd
735     length mbufs.  Never occurs if we force byte transfers. */
736
737  leftover = 0;
738  leftover_data = '\0';
739
740  for (; m != NULL; m = m->m_next) {
741    int len;
742    unsigned char *data;
743
744    len = m->m_len;
745    if (len == 0)
746      continue;
747
748    data = mtod (m, unsigned char *);
749
750    if (leftover) {
751      unsigned char next;
752
753      /* Data left over from previous mbuf in chain.  */
754      next = *data++;
755      --len;
756      outport_word (dport, leftover_data | (next << 8));
757      send_cnt += 2;
758      leftover = 0;
759    }
760
761    /* If using byte transfers, len always ends up as zero so
762       there are no leftovers. */
763
764    if (sc->byte_transfers)
765      while (len > 0) {
766        outport_byte (dport, *data++);
767        len--;
768      }
769    else
770      while (len > 1) {
771        outport_word (dport, data[0] | (data[1] << 8));
772        data += 2;
773        len -= 2;
774        send_cnt += 2;
775      }
776
777    if (len > 0)
778      {
779        leftover = 1;
780        leftover_data = *data++;
781      }
782  }
783
784  if (leftover)
785  {
786    outport_word (dport, leftover_data);
787    send_cnt += 2;
788  }
789
790#ifdef DEBUG_NE
791  /* printk("{l%d|%d}", send_cnt, sc->nextavail); */
792  printk("v");
793#endif
794  m_freem (mhold);
795
796  /* Wait for the device to complete accepting the data, with a
797     limiting counter so that we don't wait too long.  */
798  for (timeout = 0; timeout < 100; ++timeout)
799    {
800      unsigned char status;
801
802      inport_byte (port + ISR, status);
803
804#ifdef DEBUG_NE2000
805      if ((status &~ MSK_RDC) != 0)
806        printk ("Status 0x%x while waiting for acknowledgement of uploaded packet\n",
807                status);
808#endif
809
810      if ((status & MSK_RDC) != 0) {
811        outport_byte (port + ISR, MSK_RDC);
812        break;
813      }
814    }
815
816  if (timeout >= 100)
817    printk ("Timed out waiting for acknowledgement of uploaded NE2000 packet\n");
818
819  ++sc->nextavail;
820  if (sc->nextavail == NE_TX_BUFS)
821    sc->nextavail = 0;
822}
823
824/* Tell the NE2000 to transmit a buffer whose contents we have already
825   loaded onto the device.  */
826
827static void
828ne_transmit (struct ne_softc *sc)
829{
830  struct ifnet *ifp = &sc->arpcom.ac_if;
831  unsigned int port = sc->port;
832  int len;
833
834#ifdef DEBUG_NE2000
835  printk ("Transmitting NE2000 packet\n");
836#endif
837
838  len = sc->sendlen[sc->nextsend];
839  if (len < ET_MINLEN)
840    len = ET_MINLEN;
841  outport_byte (port + TBCR0, len);
842  outport_byte (port + TBCR1, len >> 8);
843
844  outport_byte (port + TPSR, NE_FIRST_TX_PAGE + (sc->nextsend * NE_TX_PAGES));
845
846  outport_byte (port + CMDR, MSK_PG0 | MSK_TXP | MSK_RD2 | MSK_STA);
847
848#ifdef DEBUG_NE
849  /* printk("{s%d|%d}", len, sc->nextsend); */
850  printk(">");
851#endif
852  ++sc->nextsend;
853  if (sc->nextsend == NE_TX_BUFS)
854    sc->nextsend = 0;
855
856  ++sc->stats.tx_packets;
857
858  /* set watchdog timer */
859  ifp->if_timer = 2;
860}
861
862/* The NE2000 packet transmit daemon.  This task is started when the
863   NE2000 driver is initialized.  */
864
865static void
866ne_tx_daemon (void *arg)
867{
868  struct ne_softc *sc = (struct ne_softc *) arg;
869  unsigned int port = sc->port;
870  struct ifnet *ifp = &sc->arpcom.ac_if;
871
872  while (1) {
873    rtems_event_set events;
874
875    /* Wait for a packet to be ready for sending, or for there to be
876       room for another packet in the device memory.  */
877    rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
878                                RTEMS_EVENT_ANY | RTEMS_WAIT,
879                                RTEMS_NO_TIMEOUT,
880                                &events);
881
882#ifdef DEBUG_NE2000
883    printk ("ne_tx_daemon\n");
884#endif
885
886    /* This daemon handles both uploading data onto the device and
887       telling the device to transmit data which has been uploaded.
888       These are separate tasks, because while the device is
889       transmitting one buffer we will upload another.  */
890
891    /* Don't let the device interrupt us now.  */
892    outport_byte (port + IMR, 0);
893
894    while (1) {
895      struct mbuf *m;
896
897      /* If the device is not transmitting a packet, and we have
898         uploaded a packet, tell the device to transmit it.  */
899      if (! sc->transmitting && sc->inuse > 0) {
900        sc->transmitting = 1;
901        ne_transmit (sc);
902      }
903
904      /* If we don't have any more buffers to send, quit now.  */
905      if (ifp->if_snd.ifq_head == NULL) {
906        ifp->if_flags &= ~IFF_OACTIVE;
907        break;
908      }
909
910      /* Allocate a buffer to load data into.  If there are none
911         available, quit until a buffer has been transmitted.  */
912      if (sc->inuse >= NE_TX_BUFS)
913        break;
914
915      ++sc->inuse;
916
917      IF_DEQUEUE (&ifp->if_snd, m);
918      if (m == NULL)
919        panic ("ne_tx_daemon");
920
921      ne_loadpacket (sc, m);
922
923      /* Check the device status.  It may have finished transmitting
924         the last packet.  */
925      ne_check_status(sc, 0);
926    }
927
928    /* Reenable device interrupts.  */
929    outport_byte (port + IMR, NE_INTERRUPTS);
930  }
931}
932
933/* Start sending an NE2000 packet.  */
934
935static void
936ne_start (struct ifnet *ifp)
937{
938  struct ne_softc *sc = ifp->if_softc;
939
940#ifdef DEBUG_NE
941  printk("S");
942#endif
943  /* Tell the transmit daemon to wake up and send a packet.  */
944  rtems_bsdnet_event_send (sc->tx_daemon_tid, START_TRANSMIT_EVENT);
945  ifp->if_flags |= IFF_OACTIVE;
946}
947
948/* Initialize and start and NE2000.  */
949
950static void
951ne_init (void *arg)
952{
953  struct ne_softc *sc = (struct ne_softc *) arg;
954  struct ifnet *ifp = &sc->arpcom.ac_if;
955
956#ifdef DEBUG_NE
957  printk("ne_init()\n");
958  ne_dump(sc);
959#endif
960
961  /* only once... */
962  if (sc->tx_daemon_tid == 0)
963  {
964    sc->inuse = 0;
965    sc->nextavail = 0;
966    sc->nextsend = 0;
967    sc->transmitting = 0;
968
969    ne_init_hardware (sc);
970
971    sc->tx_daemon_tid = rtems_bsdnet_newproc ("SCtx", 4096, ne_tx_daemon, sc);
972    sc->rx_daemon_tid = rtems_bsdnet_newproc ("SCrx", 4096, ne_rx_daemon, sc);
973
974    /* install rtems irq handler */
975    ne_init_irq_handler(sc->irno);
976  }
977
978  ifp->if_flags |= IFF_RUNNING;
979}
980
981/* Stop an NE2000.  */
982
983static void
984ne_stop (struct ne_softc *sc)
985{
986  sc->arpcom.ac_if.if_flags &= ~IFF_RUNNING;
987
988  ne_stop_hardware(sc);
989
990  sc->inuse = 0;
991  sc->nextavail = 0;
992  sc->nextsend = 0;
993  sc->transmitting = 0;
994  sc->overrun = 0;
995  sc->resend = 0;
996}
997
998static void
999ne_stop_hardware (struct ne_softc *sc)
1000{
1001  unsigned int port = sc->port;
1002  int i;
1003
1004  /* Stop everything.  */
1005  outport_byte (port + CMDR, MSK_STP | MSK_RD2);
1006
1007  /* Wait for the interface to stop, using I as a time limit.  */
1008  for (i = 0; i < 5000; ++i)
1009    {
1010      unsigned char status;
1011
1012      inport_byte (port + ISR, status);
1013      if ((status & MSK_RST) != 0)
1014        break;
1015    }
1016}
1017
1018/* reinitializing interface
1019*/
1020static void
1021ne_reset(struct ne_softc *sc)
1022{
1023  ne_stop(sc);
1024  ne_init_hardware(sc);
1025  sc->arpcom.ac_if.if_flags |= IFF_RUNNING;
1026  sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
1027#ifdef DEBUG_NE
1028  printk("*");
1029#endif
1030}
1031
1032#ifdef DEBUG_NE
1033/* show anything about ne
1034*/
1035static void
1036ne_dump(struct ne_softc *sc)
1037{
1038  int i;
1039  printk("\nne configuration:\n");
1040  printk("ethernet addr:");
1041  for (i=0; i<ETHER_ADDR_LEN; i++)
1042    printk(" %x", sc->arpcom.ac_enaddr[i]);
1043  printk("\n");
1044  printk("irq = %d\n", sc->irno);
1045  printk("port = 0x%x\n", sc->port);
1046  printk("accept_broadcasts = %d\n", sc->accept_broadcasts);
1047  printk("byte_transfers = %d\n", sc->byte_transfers);
1048}
1049#endif
1050
1051/* Show NE2000 interface statistics.  */
1052
1053static void
1054ne_stats (struct ne_softc *sc)
1055{
1056  printf ("    Received packets: %-8lu", sc->stats.rx_packets);
1057  printf (" Transmitted packets: %-8lu\n", sc->stats.tx_packets);
1058  printf ("        Receive acks: %-8lu", sc->stats.rx_acks);
1059  printf ("       Transmit acks: %-8lu\n", sc->stats.tx_acks);
1060  printf ("     Packet overruns: %-8lu", sc->stats.overruns);
1061  printf ("        Frame errors: %-8lu\n", sc->stats.rx_frame_errors);
1062  printf ("          CRC errors: %-8lu", sc->stats.rx_crc_errors);
1063  printf ("      Missed packets: %-8lu\n", sc->stats.rx_missed_errors);
1064  printf ("          Interrupts: %-8lu\n", sc->stats.interrupts);
1065}
1066
1067static int ne_set_multicast_filter(struct ne_softc* sc)
1068{
1069  int i=0;
1070  unsigned int port = sc->port;
1071  unsigned char cmd = 0;
1072       
1073  /* Save CMDR settings */
1074  inport_byte(port + CMDR, cmd);
1075  /* Change to page 1 */
1076  outport_byte(port + CMDR, cmd | MSK_PG1);
1077
1078  /* Set MAR to accept _all_ multicast packets */
1079  for (i = 0; i < MARsize; ++i) {
1080    outport_byte (port + MAR + i, 0xFF);
1081  }
1082
1083  /* Revert to original CMDR settings */
1084  outport_byte(port + CMDR, cmd);
1085
1086  return 0;
1087}
1088
1089/* NE2000 driver ioctl handler.  */
1090
1091static int
1092ne_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
1093{
1094  struct ne_softc *sc = ifp->if_softc;
1095  int error = 0;
1096
1097  switch (command) {
1098  case SIOCGIFADDR:
1099  case SIOCSIFADDR:
1100    error = ether_ioctl (ifp, command, data);
1101    break;
1102
1103  case SIOCSIFFLAGS:
1104    switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
1105    case IFF_RUNNING:
1106      ne_stop (sc);
1107      break;
1108
1109    case IFF_UP:
1110      ne_init (sc);
1111      break;
1112
1113    case IFF_UP | IFF_RUNNING:
1114      ne_stop (sc);
1115      ne_init (sc);
1116      break;
1117
1118    default:
1119      break;
1120    }
1121    break;
1122 
1123  case SIOCADDMULTI:
1124  case SIOCDELMULTI:
1125  {
1126    struct ifreq* ifr = (struct ifreq*) data;
1127    error = (command == SIOCADDMULTI ?
1128      ether_addmulti(ifr, &(sc->arpcom)) :
1129      ether_delmulti(ifr, &(sc->arpcom)) );
1130    /* ENETRESET indicates that driver should update its multicast filters */
1131    if(error == ENETRESET) {
1132      error = ne_set_multicast_filter(sc);
1133    }
1134    break;
1135  }
1136
1137  case SIO_RTEMS_SHOW_STATS:
1138    ne_stats (sc);
1139    break;
1140
1141  default:
1142    error = EINVAL;
1143    break;
1144  }
1145
1146  return error;
1147}
1148
1149/*
1150 * Device timeout/watchdog routine. Entered if the device neglects to
1151 *      generate an interrupt after a transmit has been started on it.
1152 */
1153static void
1154ne_watchdog(struct ifnet *ifp)
1155{
1156  struct ne_softc *sc = ifp->if_softc;
1157
1158  printk("ne2000: device timeout\n");
1159    ifp->if_oerrors++;
1160
1161  ne_reset(sc);
1162}
1163
1164static void
1165print_byte(unsigned char b)
1166{
1167  printk("%x%x", b >> 4, b & 0x0f);
1168}
1169
1170/* Attach an NE2000 driver to the system.  */
1171
1172int
1173rtems_ne_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
1174{
1175  int i;
1176  struct ne_softc *sc;
1177  struct ifnet *ifp;
1178  int mtu;
1179
1180  /* dettach ... */
1181  if (!attach)
1182    return 0;
1183
1184  /* Find a free driver.  */
1185  sc = NULL;
1186  for (i = 0; i < NNEDRIVER; ++i) {
1187    sc = &ne_softc[i];
1188    ifp = &sc->arpcom.ac_if;
1189    if (ifp->if_softc == NULL)
1190      break;
1191  }
1192
1193  if (sc == NULL) {
1194    printf ("Too many NE2000 drivers.\n");
1195    return 0;
1196  }
1197
1198  memset (sc, 0, sizeof *sc);
1199
1200  /* Check whether we do byte-wide or word-wide transfers.  */
1201
1202#ifdef NE2000_BYTE_TRANSFERS
1203  sc->byte_transfers = true;
1204#else
1205  sc->byte_transfers = false;
1206#endif
1207
1208  /* Handle the options passed in by the caller.  */
1209
1210  if (config->mtu != 0)
1211    mtu = config->mtu;
1212  else
1213    mtu = ETHERMTU;
1214
1215  if (config->irno != 0)
1216    sc->irno = config->irno;
1217  else {
1218    const char* opt;
1219    opt = bsp_cmdline_arg ("--ne2k-irq=");
1220    if (opt) {
1221      opt += sizeof ("--ne2k-irq=") - 1;
1222      sc->irno = strtoul (opt, 0, 0);
1223    }
1224    if (sc->irno == 0) {
1225      /* We use 5 as the default IRQ.  */
1226      sc->irno = 5;
1227    }
1228  }
1229
1230  if (config->port != 0)
1231    sc->port = config->port;
1232  else {
1233    const char* opt;
1234    opt = bsp_cmdline_arg ("--ne2k-port=");
1235    if (opt) {
1236      opt += sizeof ("--ne2k-port=") - 1;
1237      sc->port = strtoul (opt, 0, 0);
1238    }
1239    if (config->port == 0) {
1240      /* We use 0x300 as the default IO port number.  */
1241      sc->port = 0x300;
1242    }
1243  }
1244
1245  sc->accept_broadcasts = ! config->ignore_broadcast;
1246
1247  if (config->hardware_address != NULL)
1248    memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
1249            ETHER_ADDR_LEN);
1250  else
1251    {
1252      unsigned char prom[16];
1253      int ia;
1254
1255      /* Read the PROM to get the Ethernet hardware address.  */
1256
1257      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
1258
1259      if (sc->byte_transfers) {
1260        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS);
1261      }
1262      else {
1263        outport_byte (sc->port + DCR, MSK_FT10 | MSK_BMS | MSK_WTS);
1264      }
1265
1266      outport_byte (sc->port + RBCR0, 0);
1267      outport_byte (sc->port + RBCR1, 0);
1268      outport_byte (sc->port + RCR, MSK_MON);
1269      outport_byte (sc->port + TCR, MSK_LOOP);
1270      outport_byte (sc->port + IMR, 0);
1271      outport_byte (sc->port + ISR, 0xff);
1272
1273      ne_read_data (sc, 0, sizeof prom, prom);
1274
1275      outport_byte (sc->port + CMDR, MSK_PG0 | MSK_RD2 | MSK_STP);
1276
1277      for (ia = 0; ia < ETHER_ADDR_LEN; ++ia)
1278        sc->arpcom.ac_enaddr[ia] = prom[ia * 2];
1279    }
1280
1281  /* Set up the network interface.  */
1282
1283  ifp->if_softc = sc;
1284  ifp->if_unit = i + 1;
1285  ifp->if_name = "ne";
1286  ifp->if_mtu = mtu;
1287  ifp->if_init = ne_init;
1288  ifp->if_ioctl = ne_ioctl;
1289  ifp->if_watchdog = ne_watchdog;
1290  ifp->if_start = ne_start;
1291  ifp->if_output = ether_output;
1292  ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1293  if (ifp->if_snd.ifq_maxlen == 0)
1294    ifp->if_snd.ifq_maxlen = ifqmaxlen;
1295
1296  /* Attach the interface.  */
1297
1298  if_attach (ifp);
1299  ether_ifattach (ifp);
1300
1301  printk("network device '%s' <", config->name);
1302  print_byte(sc->arpcom.ac_enaddr[0]);
1303  for (i=1; i<ETHER_ADDR_LEN; i++)
1304  { printk(":");
1305    print_byte(sc->arpcom.ac_enaddr[i]);
1306  }
1307  printk("> initialized on port 0x%x, irq %d\n", sc->port, sc->irno);
1308
1309  return 1;
1310}
Note: See TracBrowser for help on using the repository browser.