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

4.104.114.84.95
Last change on this file since 5d2fe483 was 5d2fe483, checked in by Joel Sherrill <joel.sherrill@…>, on 05/08/01 at 22:58:46

2001-05-07 Ralf Corsepius <corsepiu@…>

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