source: rtems/c/src/lib/libbsp/arm/gumstix/rtl8019/rtl8019.c @ 021bc66

4.104.115
Last change on this file since 021bc66 was 021bc66, checked in by Sebastian Huber <sebastian.huber@…>, on 05/03/10 at 14:49:57

2010-05-03 Sebastian Huber <sebastian.huber@…>

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