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

4.104.11
Last change on this file since c193baad was c193baad, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Apr 9, 2010 at 8:24:57 PM

unify irq data types and code, merge s3c2400/s3c2410 support

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