source: rtems/c/src/lib/libbsp/arm/gumstix/rtl8019/rtl8019.c @ 28352fae

4.104.115
Last change on this file since 28352fae was a17bc42, checked in by Joel Sherrill <joel.sherrill@…>, on 08/21/09 at 17:49:31

2009-08-21 Xi Yang <hiyangxi@…>

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