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

5
Last change on this file since 17fd0ff was 17fd0ff, checked in by Sebastian Huber <sebastian.huber@…>, on 01/12/18 at 06:56:42

bsps: Move wd80x3.h to libchip/wd80x3.h

This header is used also by the motorola_powerpc BSP.

Update #3254.

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