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

4.104.114.95
Last change on this file since e3a1d425 was e3a1d425, checked in by Joel Sherrill <joel.sherrill@…>, on 08/19/08 at 19:34:08

2008-08-19 Joel Sherrill <joel.sherrill@…>

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