source: rtems/bsps/arm/gumstix/net/rtl8019.c @ a3fe23c

5
Last change on this file since a3fe23c was 031df391, checked in by Sebastian Huber <sebastian.huber@…>, on 04/23/18 at 07:53:31

bsps: Move legacy network drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

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