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

4.10
Last change on this file since 17cc97d was 17cc97d, checked in by Joel Sherrill <joel.sherrill@…>, on 04/11/11 at 17:27:57

2011-04-11 Keith Robertson <kjrobert at alumni dot uwaterloo dot ca>

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