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

4.104.114.84.95
Last change on this file since ff73cf6 was ff73cf6, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/15/06 at 06:00:03

Use ioctl_command_t as arg in ioctl-functions.

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