OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [peripheral/] [eth.c] - Blame information for rev 538

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 jeremybenn
/* ethernet.c -- Simulation of Ethernet MAC
2
 
3
   Copyright (C) 2001 by Erez Volk, erez@opencores.org
4
                         Ivan Guzvinec, ivang@opencores.org
5 443 jeremybenn
   Copyright (C) 2008, 2001 Embecosm Limited
6 437 julius
   Copyright (C) 2010 ORSoC
7 19 jeremybenn
 
8
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
9 437 julius
   Contributor Julius Baxter <julius@orsoc.se>
10 19 jeremybenn
 
11
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
12
 
13
   This program is free software; you can redistribute it and/or modify it
14
   under the terms of the GNU General Public License as published by the Free
15
   Software Foundation; either version 3 of the License, or (at your option)
16
   any later version.
17
 
18
   This program is distributed in the hope that it will be useful, but WITHOUT
19
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
21
   more details.
22
 
23
   You should have received a copy of the GNU General Public License along
24
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
25
 
26
/* This program is commented throughout in a fashion suitable for processing
27
   with Doxygen. */
28
 
29
 
30
/* Autoconf and/or portability configuration */
31
#include "config.h"
32
#include "port.h"
33
 
34
/* System includes */
35
#include <stdlib.h>
36
#include <stdio.h>
37 434 jeremybenn
 
38
#include <sys/socket.h>
39
#include <sys/ioctl.h>
40
#include <sys/stat.h>
41 19 jeremybenn
#include <sys/types.h>
42
#include <fcntl.h>
43 434 jeremybenn
 
44 19 jeremybenn
#include <sys/poll.h>
45
#include <unistd.h>
46
#include <errno.h>
47
 
48 538 julius
#if HAVE_LINUX_IF_TUN_H==1
49 434 jeremybenn
#include <linux/if.h>
50
#include <linux/if_tun.h>
51 538 julius
#endif
52 434 jeremybenn
 
53 19 jeremybenn
/* Package includes */
54
#include "arch.h"
55
#include "config.h"
56
#include "abstract.h"
57
#include "eth.h"
58
#include "dma.h"
59
#include "sim-config.h"
60
#include "fields.h"
61
#include "crc32.h"
62
#include "vapi.h"
63
#include "pic.h"
64
#include "sched.h"
65
#include "toplevel-support.h"
66
#include "sim-cmd.h"
67
 
68 443 jeremybenn
 
69
/* Control debug messages */
70 450 jeremybenn
#define ETH_DEBUG 0
71 443 jeremybenn
#ifndef ETH_DEBUG
72
# define ETH_DEBUG  1
73
#endif
74
 
75 460 jeremybenn
/*! Period (clock cycles) for rescheduling Rx and Tx controllers.
76
    Experimenting with FTP on one machine suggests that a value of 500-2000 is
77
    optimal. It's a trade off between prompt response and extra computational
78
    load for Or1ksim. */
79
#define  RTX_RESCHED_PERIOD  2000
80 443 jeremybenn
 
81 450 jeremybenn
/*! MAC address that is always accepted. */
82
static const unsigned char mac_broadcast[ETHER_ADDR_LEN] =
83
  { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
84
 
85 443 jeremybenn
/* -------------------------------------------------------------------------- */
86
/*!Structure describing the Ethernet device                                   */
87
/* -------------------------------------------------------------------------- */
88 19 jeremybenn
struct eth_device
89
{
90 443 jeremybenn
  /* Basic stuff about the device */
91
  int                enabled;           /* Is peripheral enabled */
92
  oraddr_t           baseaddr;          /* Base address in memory */
93
  unsigned long int  base_vapi_id;      /* Start of VAPI ID block */
94 19 jeremybenn
 
95 443 jeremybenn
  /* DMA controller this MAC is connected to, and associated channels */
96 19 jeremybenn
  unsigned dma;
97
  unsigned tx_channel;
98
  unsigned rx_channel;
99
 
100 443 jeremybenn
  /* Details of the hardware */
101
  unsigned char      mac_address[ETHER_ADDR_LEN];  /* Ext HW address */
102
  unsigned long int  phy_addr;          /* Int HW address */
103
  unsigned long int  mac_int;           /* interrupt line number */
104 451 jeremybenn
  int                dummy_crc;         /* Flag indicating if we add CRC */
105 443 jeremybenn
  int                int_line_stat;     /* interrupt line status */
106 19 jeremybenn
 
107 443 jeremybenn
  /* External interface deatils */
108
  int rtx_type;                         /* Type of external i/f: FILE or TAP */
109 19 jeremybenn
 
110 434 jeremybenn
  /* RX and TX file names and handles for FILE type connection. */
111 443 jeremybenn
  char  *rxfile;                        /* Rx filename */
112
  char  *txfile;                        /* Tx filename */
113
  int    txfd;                          /* Rx file handle */
114
  int    rxfd;                          /* Tx file handle */
115 19 jeremybenn
 
116 434 jeremybenn
  /* Info for TAP type connections */
117 443 jeremybenn
  char *tap_dev;                        /* The TAP device */
118
  int   rtx_fd;                         /* TAP device handle */
119 19 jeremybenn
 
120 450 jeremybenn
  /* Indices into the buffer descriptors. */
121
  unsigned long int  tx_bd_index;
122
  unsigned long int  rx_bd_index;
123 19 jeremybenn
 
124
  /* Visible registers */
125
  struct
126
  {
127 443 jeremybenn
    unsigned long int  moder;
128
    unsigned long int  int_source;
129
    unsigned long int  int_mask;
130
    unsigned long int  ipgt;
131
    unsigned long int  ipgr1;
132
    unsigned long int  ipgr2;
133
    unsigned long int  packetlen;
134
    unsigned long int  collconf;
135
    unsigned long int  tx_bd_num;
136
    unsigned long int  controlmoder;
137
    unsigned long int  miimoder;
138
    unsigned long int  miicommand;
139
    unsigned long int  miiaddress;
140
    unsigned long int  miitx_data;
141
    unsigned long int  miirx_data;
142
    unsigned long int  miistatus;
143
    unsigned long int  hash0;
144
    unsigned long int  hash1;
145 19 jeremybenn
 
146
    /* Buffer descriptors */
147 443 jeremybenn
    unsigned long int  bd_ram[ETH_BD_SPACE / 4];
148 19 jeremybenn
  } regs;
149
};
150
 
151
 
152 443 jeremybenn
/* -------------------------------------------------------------------------- */
153 450 jeremybenn
/*!Write an Ethernet packet to a FILE interface.
154 443 jeremybenn
 
155 450 jeremybenn
   This writes a single Ethernet packet to a FILE interface. The format is to
156
   write the length, then the data.
157 443 jeremybenn
 
158 450 jeremybenn
   @param[in] eth     Pointer to the relevant Ethernet data structure.
159
   @param[in] buf     Where to get the data.
160
   @param[in] length  Length of data to write.
161 443 jeremybenn
 
162 450 jeremybenn
   @return  The length if successful, a negative value otherwise.             */
163
/* -------------------------------------------------------------------------- */
164
static ssize_t
165
eth_write_file_packet (struct eth_device *eth,
166
                       unsigned char     *buf,
167
                       unsigned long int  length)
168
{
169
  ssize_t  nwritten;
170 443 jeremybenn
 
171 450 jeremybenn
  /* Write length to file. */
172
  nwritten = write (eth->txfd, &(length), sizeof (length));
173
  if (nwritten != sizeof (length))
174
    {
175
      fprintf (stderr, "ERROR: Failed to write Ethernet packet length: %s.\n",
176
               strerror (errno));
177
      return  -1;
178
    }
179 443 jeremybenn
 
180 450 jeremybenn
  /* write data to file */
181
  nwritten = write (eth->txfd, buf, length);
182
  if (nwritten != length)
183
    {
184
      fprintf (stderr, "ERROR: Failed to write Ethernet packet data: %s.\n",
185
               strerror (errno));
186
      return  -1;
187
    }
188 443 jeremybenn
 
189 450 jeremybenn
  return  nwritten;
190
 
191
}       /* eth_write_file_packet () */
192
 
193
 
194 538 julius
#if HAVE_LINUX_IF_TUN_H==1
195
 
196 443 jeremybenn
/* -------------------------------------------------------------------------- */
197 450 jeremybenn
/*!Write an Ethernet packet to a TAP interface.
198
 
199
   This writes a single Ethernet packet to a TAP interface.
200
 
201
   @param[in] eth     Pointer to the relevant Ethernet data structure.
202
   @param[in] buf     Where to get the data.
203
   @param[in] length  Length of data to write.
204
 
205
   @return  The length if successful, a negative value otherwise.             */
206
/* -------------------------------------------------------------------------- */
207
static ssize_t
208
eth_write_tap_packet (struct eth_device *eth,
209
                      unsigned char     *buf,
210
                      unsigned long int  length)
211 443 jeremybenn
{
212 538 julius
  ssize_t  nwritten = 0;
213 443 jeremybenn
 
214 538 julius
 
215
 
216 450 jeremybenn
#if ETH_DEBUG
217
  int  j;
218 443 jeremybenn
 
219 450 jeremybenn
  printf ("Writing TAP\n");
220
  printf ("  packet %d bytes:", (int) length);
221
 
222
  for (j = 0; j < length; j++)
223 443 jeremybenn
    {
224 450 jeremybenn
      if (0 == (j % 16))
225
        {
226
          printf ("\n");
227
        }
228
      else if (0 == (j % 8))
229
        {
230
          printf (" ");
231
        }
232
 
233
      printf ("%.2x ", buf[j]);
234
    }
235
 
236
  printf("\nend packet:\n");
237
#endif    
238 443 jeremybenn
 
239 450 jeremybenn
  /* Write the data to the TAP */
240
  nwritten = write (eth->rtx_fd, buf, length);
241
  if (nwritten != length)
242
    {
243
      fprintf (stderr, "ERROR: Failed to write Ethernet packet data: %s.\n",
244
               strerror (errno));
245
      return  -1;
246
    }
247 443 jeremybenn
 
248 450 jeremybenn
  return  nwritten;
249 443 jeremybenn
 
250 450 jeremybenn
}       /* eth_write_tap_packet () */
251 538 julius
#endif
252 443 jeremybenn
 
253
 
254 450 jeremybenn
/* -------------------------------------------------------------------------- */
255
/*!Write an Ethernet packet.
256 443 jeremybenn
 
257 450 jeremybenn
   This writes a single Ethernet packet to the outside world from the supplied
258
   buffer. It deals with the different types of external interface.
259 443 jeremybenn
 
260 450 jeremybenn
   @param[in] eth     Pointer to the relevant Ethernet data structure.
261
   @param[in] buf     Where to get the data.
262
   @param[in] length  Length of data to write.
263 443 jeremybenn
 
264 450 jeremybenn
   @return  The length if successful, zero if no packet was available,
265
            a negative value otherwise.                                       */
266
/* -------------------------------------------------------------------------- */
267
static ssize_t
268
eth_write_packet (struct eth_device *eth,
269
                  unsigned char     *buf,
270
                  ssize_t            length)
271
{
272
  /* Send packet according to interface type. */
273
  switch (eth->rtx_type)
274
    {
275
    case ETH_RTX_FILE: return  eth_write_file_packet (eth, buf, length);
276 538 julius
#if HAVE_LINUX_IF_TUN_H==1
277 450 jeremybenn
    case ETH_RTX_TAP:  return  eth_write_tap_packet (eth, buf, length);
278 538 julius
#endif
279 443 jeremybenn
 
280 450 jeremybenn
    default:
281
      fprintf (stderr, "Unknown Ethernet write interface: ignored.\n");
282
      return  (ssize_t) -1;
283
    }
284
}       /* eth_write_packet () */
285 443 jeremybenn
 
286
 
287 450 jeremybenn
/* -------------------------------------------------------------------------- */
288
/*!Flush a Tx buffer descriptor to the outside world.
289 19 jeremybenn
 
290 450 jeremybenn
   We know the buffer descriptor is full, so write it to the appropriate
291
   outside interface.
292
 
293
   @param[in] eth  The Ethernet data structure.                               */
294
/* -------------------------------------------------------------------------- */
295
static void
296
eth_flush_bd (struct eth_device *eth)
297
{
298
  /* First word of BD is flags and length, second is pointer to buffer */
299
  unsigned long int  bd_info = eth->regs.bd_ram[eth->tx_bd_index];
300
  unsigned long int  bd_addr = eth->regs.bd_ram[eth->tx_bd_index + 1];
301
  unsigned char      buf[ETH_MAXPL];
302
  long int           packet_length;
303
  long int           bytes_sent;
304 460 jeremybenn
  int                ok_to_int_p;
305 450 jeremybenn
 
306
  /* Get the packet length */
307
  packet_length = GET_FIELD (bd_info, ETH_TX_BD, LENGTH);
308
 
309
  /* Clear error status bits and retry count. */
310
  CLEAR_FLAG (bd_info, ETH_TX_BD, DEFER);
311
  CLEAR_FLAG (bd_info, ETH_TX_BD, COLLISION);
312
  CLEAR_FLAG (bd_info, ETH_TX_BD, RETRANSMIT);
313
  CLEAR_FLAG (bd_info, ETH_TX_BD, UNDERRUN);
314
  CLEAR_FLAG (bd_info, ETH_TX_BD, NO_CARRIER);
315
 
316
  SET_FIELD (bd_info, ETH_TX_BD, RETRY, 0);
317
 
318
  /* Copy data from buffer descriptor address into our local buf. */
319
  for (bytes_sent = 0; bytes_sent < packet_length; bytes_sent +=4)
320
    {
321
      unsigned long int  read_word =
322
        eval_direct32 (bytes_sent + bd_addr, 0, 0);
323
 
324
      buf[bytes_sent]     = (unsigned char) (read_word >> 24);
325
      buf[bytes_sent + 1] = (unsigned char) (read_word >> 16);
326
      buf[bytes_sent + 2] = (unsigned char) (read_word >> 8);
327
      buf[bytes_sent + 3] = (unsigned char) (read_word);
328
    }
329
 
330
  /* Send packet according to interface type and set BD status. If we didn't
331
     write the whole packet, then we retry. */
332
  if (eth_write_packet (eth, buf, packet_length) == packet_length)
333
    {
334
      CLEAR_FLAG (bd_info, ETH_TX_BD, READY);
335
      SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB);
336 460 jeremybenn
      ok_to_int_p = TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXB_M);
337 450 jeremybenn
    }
338
  else
339
    {
340
      /* Does this retry mechanism really work? */
341
      CLEAR_FLAG (bd_info, ETH_TX_BD, READY);
342
      CLEAR_FLAG (bd_info, ETH_TX_BD, COLLISION);
343
      SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXE);
344 460 jeremybenn
      ok_to_int_p = TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXE_M);
345 443 jeremybenn
#if ETH_DEBUG
346 450 jeremybenn
      printf ("Transmit retry request.\n");
347 443 jeremybenn
#endif
348 450 jeremybenn
    }
349 19 jeremybenn
 
350 450 jeremybenn
  /* Update the flags in the buffer descriptor */
351
  eth->regs.bd_ram[eth->tx_bd_index] = bd_info;
352 19 jeremybenn
 
353 450 jeremybenn
  /* Generate interrupt to indicate transfer complete, under the
354
     following criteria all being met:
355
     - either INT_MASK flag for Tx (OK or error) is set
356 460 jeremybenn
     - the buffer descriptor has its IRQ flag set
357 450 jeremybenn
     - there is no interrupt in progress.
358 437 julius
 
359 450 jeremybenn
     @todo We ought to warn if we get here and fail to set an IRQ. */
360 460 jeremybenn
  if (ok_to_int_p && TEST_FLAG (bd_info, ETH_TX_BD, IRQ))
361 450 jeremybenn
    {
362
      if (eth->int_line_stat)
363 19 jeremybenn
        {
364 450 jeremybenn
          fprintf (stderr, "Warning: Interrupt active during Tx.\n");
365
        }
366
      else
367
        {
368 437 julius
#if ETH_DEBUG
369 443 jeremybenn
          printf ("TRANSMIT interrupt\n");
370 437 julius
#endif
371 443 jeremybenn
          report_interrupt (eth->mac_int);
372
          eth->int_line_stat = 1;
373 19 jeremybenn
        }
374 450 jeremybenn
    }
375 19 jeremybenn
 
376 450 jeremybenn
  /* Advance to next BD, wrapping around if appropriate. */
377
  if (TEST_FLAG (bd_info, ETH_TX_BD, WRAP) ||
378
      eth->tx_bd_index >= ((eth->regs.tx_bd_num - 1) * 2))
379
    {
380
      eth->tx_bd_index = 0;
381 19 jeremybenn
    }
382 450 jeremybenn
  else
383
    {
384
      eth->tx_bd_index += 2;
385
    }
386
}       /* eth_flush_bd () */
387 19 jeremybenn
 
388
 
389 443 jeremybenn
/* -------------------------------------------------------------------------- */
390 450 jeremybenn
/*!Tx clock function.
391 443 jeremybenn
 
392 450 jeremybenn
   Responsible for starting and completing any TX actions.
393 443 jeremybenn
 
394
   The original version had 4 states, which allowed modeling the transfer of
395 450 jeremybenn
   data one byte per cycle.  For now we use only the one state for
396
   efficiency. When we find something in a buffer descriptor, we transmit
397
   it.
398 443 jeremybenn
 
399 450 jeremybenn
   We reschedule every cycle. There is no point in trying to do anything if
400
   there is an interrupt still being processed by the core.
401 443 jeremybenn
 
402
   @todo We should eventually reinstate the one byte per cycle transfer.
403
 
404
   @param[in] dat  The Ethernet data structure, passed as a void pointer.    */
405
/* -------------------------------------------------------------------------- */
406 19 jeremybenn
static void
407 450 jeremybenn
eth_controller_tx_clock (void *dat)
408 19 jeremybenn
{
409
  struct eth_device *eth = dat;
410
 
411 450 jeremybenn
  /* Only do anything if there is not an interrupt outstanding. */
412
  if (!eth->int_line_stat)
413 19 jeremybenn
    {
414 450 jeremybenn
      /* First word of BD is flags. If we have a buffer ready, get it and
415
         transmit it. */
416
      if (TEST_FLAG (eth->regs.bd_ram[eth->tx_bd_index], ETH_TX_BD, READY))
417
        {
418
          eth_flush_bd (eth);
419
        }
420
    }
421 19 jeremybenn
 
422 460 jeremybenn
  /* Reschedule to wake up again. */
423 451 jeremybenn
  SCHED_ADD (eth_controller_tx_clock, dat, RTX_RESCHED_PERIOD);
424 434 jeremybenn
 
425 450 jeremybenn
}       /* eth_controller_tx_clock () */
426 19 jeremybenn
 
427
 
428 450 jeremybenn
/* -------------------------------------------------------------------------- */
429
/*!Read an Ethernet packet from a FILE interface.
430 437 julius
 
431 450 jeremybenn
   This reads a single Ethernet packet from the outside world via a FILE
432
   interface.
433 434 jeremybenn
 
434 450 jeremybenn
   The format is 4 bytes of packet length, followed by the packet data.
435 434 jeremybenn
 
436 450 jeremybenn
   @param[in]  eth  Pointer to the relevant Ethernet data structure
437
   @param[out] buf  Where to put the data
438 434 jeremybenn
 
439 450 jeremybenn
   @return  The length if successful, zero if no packet was available
440
            (i.e. EOF), a negative value otherwise.                           */
441
/* -------------------------------------------------------------------------- */
442
static ssize_t
443
eth_read_file_packet (struct eth_device *eth,
444
                      unsigned char     *buf)
445
{
446
  ssize_t  packet_length;
447
  ssize_t  nread;
448 434 jeremybenn
 
449 450 jeremybenn
  /* Read packet length. We may be at EOF. */
450
  nread = read (eth->rxfd, &(packet_length), sizeof (packet_length));
451 19 jeremybenn
 
452 450 jeremybenn
  if (0 == nread)
453
    {
454
      return  0;                 /* No more packets */
455
    }
456
  else if (nread < sizeof (packet_length))
457
    {
458
      fprintf (stderr, "ERROR: Failed to read length from file.\n");
459
      return  -1;
460
    }
461 460 jeremybenn
 
462 450 jeremybenn
  /* Packet must be big enough to hold a header */
463
  if (packet_length < ETHER_HDR_LEN)
464
    {
465
      fprintf (stderr, "Warning: Ethernet packet length %zd too small.\n",
466
               packet_length);
467
      return  -1;
468
    }
469 19 jeremybenn
 
470 450 jeremybenn
  /* Read the packet proper. */
471
  nread = read (eth->rxfd, buf, packet_length);
472 19 jeremybenn
 
473 450 jeremybenn
  if (nread != packet_length)
474
    {
475
      fprintf (stderr, "ERROR: Failed to read packet from file.\n");
476
      return  -1;
477
    }
478 19 jeremybenn
 
479 450 jeremybenn
  return  packet_length;
480 19 jeremybenn
 
481 450 jeremybenn
}       /* eth_read_file_packet () */
482 19 jeremybenn
 
483
 
484 538 julius
#if HAVE_LINUX_IF_TUN_H==1
485
 
486 450 jeremybenn
/* -------------------------------------------------------------------------- */
487
/*!Read an Ethernet packet from a FILE interface.
488 19 jeremybenn
 
489 450 jeremybenn
   This reads a single Ethernet packet from the outside world via a TAP
490
   interface.
491 19 jeremybenn
 
492 450 jeremybenn
   A complete packet is always read, so its length (minus CRC) is the amount
493
   read.
494
 
495
   @param[in]  eth  Pointer to the relevant Ethernet data structure
496
   @param[out] buf  Where to put the data
497
 
498
   @return  The length if successful, zero if no packet was available,
499
            a negative value otherwise.                                       */
500
/* -------------------------------------------------------------------------- */
501
static ssize_t
502
eth_read_tap_packet (struct eth_device *eth,
503
                     unsigned char     *buf)
504
{
505 538 julius
 
506 450 jeremybenn
  struct pollfd  fds[1];
507
  int            n;
508
  ssize_t        packet_length;
509
 
510
  /* Poll to see if there is data to read */
511
  fds[0].fd     = eth->rtx_fd;
512
  fds[0].events = POLLIN;
513 434 jeremybenn
 
514 450 jeremybenn
  n = poll (fds, 1, 0);
515
  if (n < 0)
516
    {
517
      fprintf (stderr, "Warning: Poll for TAP receive failed %s: ignored.\n",
518
               strerror (errno));
519
      return  -1;
520
    }
521
  else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
522
    {
523
      /* Data to be read from TAP */
524
      packet_length = read (eth->rtx_fd, buf, ETH_MAXPL);
525 437 julius
#if ETH_DEBUG
526 450 jeremybenn
      printf ("%d bytes read from TAP.\n", (int) packet_length);
527 437 julius
#endif
528 450 jeremybenn
      if (packet_length < 0)
529
        {
530
          fprintf (stderr, "Warning: Read of RXTATE_RECV failed: %s.\n",
531
                   strerror (errno));
532
          SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXE);
533
 
534
          /* Signal interrupt if enabled, and no interrupt currently in
535
             progress. */
536
          if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXE_M) &&
537
              !eth->int_line_stat)
538
            {
539 437 julius
#if ETH_DEBUG
540 450 jeremybenn
              printf ("Ethernet failed receive interrupt\n");
541 437 julius
#endif
542 450 jeremybenn
              report_interrupt (eth->mac_int);
543
              eth->int_line_stat = 1;
544
            }
545
        }
546
 
547
      return  packet_length;
548
    }
549
  else
550
    {
551
      return  0;                 /* No packet */
552
    }
553
}       /* eth_read_tap_packet () */
554 434 jeremybenn
 
555 538 julius
#endif
556 437 julius
 
557 450 jeremybenn
/* -------------------------------------------------------------------------- */
558
/*!Read an Ethernet packet.
559 434 jeremybenn
 
560 450 jeremybenn
   This reads a single Ethernet packet from the outside world into the
561
   supplied buffer. It deals with the different types of external interface.
562 19 jeremybenn
 
563 450 jeremybenn
   @param[in]  eth  Pointer to the relevant Ethernet data structure
564
   @param[out] buf  Where to put the data
565 436 julius
 
566 450 jeremybenn
   @return  The length if successful, zero if no packet was available,
567
            a negative value otherwise.                                       */
568
/* -------------------------------------------------------------------------- */
569
static ssize_t
570
eth_read_packet (struct eth_device *eth,
571
                 unsigned char     *buf)
572
{
573
  switch (eth->rtx_type)
574
    {
575
    case ETH_RTX_FILE: return  eth_read_file_packet (eth, buf);
576 538 julius
#if HAVE_LINUX_IF_TUN_H==1
577 450 jeremybenn
    case ETH_RTX_TAP:  return  eth_read_tap_packet (eth, buf);
578 538 julius
#endif
579 19 jeremybenn
 
580 450 jeremybenn
    default:
581
      fprintf (stderr, "Unknown Ethernet read interface: ignored.\n");
582
      return  (ssize_t) -1;
583
    }
584
}       /* eth_read_packet () */
585 19 jeremybenn
 
586
 
587 450 jeremybenn
/* -------------------------------------------------------------------------- */
588
/*!Fill a buffer descriptor
589
 
590
   A buffer descriptor is empty. Attempt to fill it from the outside world.
591
 
592
   @param[in] eth  The Ethernet data structure, passed as a void pointer.    */
593
/* -------------------------------------------------------------------------- */
594
static void
595
eth_fill_bd (struct eth_device *eth)
596
{
597
 
598
  /* First word of BD is flags and length, second is pointer to buffer */
599
  unsigned long int  bd_info = eth->regs.bd_ram[eth->rx_bd_index];
600
  unsigned long int  bd_addr = eth->regs.bd_ram[eth->rx_bd_index + 1];
601
 
602
  long int           packet_length;
603
  long int           bytes_read;
604
  unsigned char      buf[ETH_MAXPL];
605
 
606
  /* Clear various status bits */
607
  CLEAR_FLAG (bd_info, ETH_RX_BD, MISS);
608
  CLEAR_FLAG (bd_info, ETH_RX_BD, INVALID);
609
  CLEAR_FLAG (bd_info, ETH_RX_BD, DRIBBLE);
610
  CLEAR_FLAG (bd_info, ETH_RX_BD, UVERRUN);
611
  CLEAR_FLAG (bd_info, ETH_RX_BD, COLLISION);
612
  CLEAR_FLAG (bd_info, ETH_RX_BD, TOOBIG);
613
  CLEAR_FLAG (bd_info, ETH_RX_BD, TOOSHORT);
614
 
615
  /* Loopback is permitted. We believe that Linux never uses it, so we'll
616
     note the attempt and ignore.
617
 
618
     @todo We should support this. */
619
  if (TEST_FLAG (eth->regs.moder, ETH_MODER, LOOPBCK))
620
    {
621
      PRINTF ("Ethernet loopback requested.\n");
622
      fprintf (stderr, "ERROR: Loopback not supported. Ignored.\n");
623
    }
624
 
625
  packet_length = eth_read_packet (eth, buf);
626
  if (packet_length <= 0)
627
    {
628
      /* Empty packet or error. No more to do here. */
629
      return;
630
    }
631
 
632
/* Got a packet successfully. If not promiscuous mode, check the destination
633
   address is meant for us. */
634
  if (!TEST_FLAG (eth->regs.moder, ETH_MODER, PRO))
635
    {
636
      if (TEST_FLAG (eth->regs.moder, ETH_MODER, IAM))
637
        {
638
          /* There is little documentation of how IAM is supposed to work. It
639
             seems that some mapping function (not defined) maps the address
640
             down to a number in the range 0-63. If that bit is set in
641
             HASH0/HASH1 registers, the packet is accepted. */
642
          fprintf (stderr, "Warning: Individual Address Mode ignored.\n");
643 19 jeremybenn
        }
644 450 jeremybenn
 
645
      /* Check for HW address match. */
646
      if ((0 != bcmp (eth->mac_address, buf, ETHER_ADDR_LEN)) &&
647
          (0 != bcmp (mac_broadcast,    buf, ETHER_ADDR_LEN)))
648
        {
649
#if ETH_DEBUG           
650
          printf ("packet for %.2x:%.2x:%.2x:%.2x:%.2x:%.2x ignored.\n",
651
                  buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
652
#endif
653
          /* Not for us. No more to do here. */
654
          return;
655
        }
656
    }
657 19 jeremybenn
 
658 450 jeremybenn
  /* Transfer the buffer into the BD. */
659 437 julius
#if ETH_DEBUG
660 450 jeremybenn
  printf ("writing to Rx BD%d: %d bytes @ 0x%.8x\n",
661
          (int) eth->rx_bd_index / 2,  (int) packet_length,
662
          (unsigned int)bd_addr);
663 437 julius
#endif
664 450 jeremybenn
 
665
  for (bytes_read = 0; bytes_read < packet_length; bytes_read +=4)
666
    {
667
      unsigned long int  send_word =
668
        ((unsigned long) buf[bytes_read]     << 24) |
669
        ((unsigned long) buf[bytes_read + 1] << 16) |
670
        ((unsigned long) buf[bytes_read + 2] <<  8) |
671
        ((unsigned long) buf[bytes_read + 3]      );
672
      set_direct32 (bd_addr + bytes_read, send_word, 0, 0);
673
    }
674
 
675
#if ETH_DEBUG
676
  printf("BD filled with 0x%08lx bytes.\n", bytes_read);
677
#endif
678
 
679
  /* Write result to BD.
680 451 jeremybenn
 
681
     The OpenRISC MAC hardware passes on the CRC (which it should not). The
682
     Linux drivers have been written to expect a value (which they ignore). So
683
     for consistency, we pretend the length is 4 bytes longer.
684
 
685
     This is now controlled by a configuration parameter, dummy_crc. For
686
     backwards compatibility, it defaults to TRUE. */
687
  SET_FIELD (bd_info, ETH_RX_BD, LENGTH,
688
             packet_length + (eth->dummy_crc ? 4 : 0));
689 450 jeremybenn
  CLEAR_FLAG (bd_info, ETH_RX_BD, READY);
690
  SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXB);
691
 
692
  eth->regs.bd_ram[eth->rx_bd_index] = bd_info;
693
 
694
  /* Advance to next BD. The Rx BDs start after the Tx BDs. */
695
  if (TEST_FLAG (bd_info, ETH_RX_BD, WRAP) ||
696
      (eth->rx_bd_index >= ETH_BD_COUNT))
697
    {
698
      eth->rx_bd_index = eth->regs.tx_bd_num * 2;
699
    }
700
  else
701
    {
702
      eth->rx_bd_index += 2;
703
    }
704
 
705
  /* Raise an interrupt if necessary. */
706
  if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXB_M) &&
707
      TEST_FLAG (bd_info, ETH_RX_BD, IRQ))
708
    {
709
      if (eth->int_line_stat)
710
        {
711
          fprintf (stderr, "Warning: Interrupt active during Rx.\n");
712 436 julius
        }
713 450 jeremybenn
      else
714
        {
715 437 julius
#if ETH_DEBUG
716 450 jeremybenn
          printf ("Rx successful receive interrupt\n");
717 437 julius
#endif
718 450 jeremybenn
          report_interrupt (eth->mac_int);
719
          eth->int_line_stat = 1;
720
        }
721
    }
722
}       /* eth_fill_bd () */
723 19 jeremybenn
 
724
 
725 450 jeremybenn
/* -------------------------------------------------------------------------- */
726 451 jeremybenn
/*!Ignore a packet from the TAP interface.
727 437 julius
 
728 450 jeremybenn
   We don't have a BD ready, so any packets waiting should be thrown away.
729
 
730 451 jeremybenn
   @param[in] eth  The Ethernet data structure.
731
 
732
   @return  1 (TRUE) if more or more packets were discarded, zero otherwise.  */
733 450 jeremybenn
/* -------------------------------------------------------------------------- */
734 451 jeremybenn
static int
735
eth_ignore_tap_packets (struct eth_device *eth)
736 450 jeremybenn
{
737 451 jeremybenn
  int  result = 0;
738 538 julius
 
739
#if HAVE_LINUX_IF_TUN_H==1
740
 
741 451 jeremybenn
  int  n;
742 538 julius
 
743 451 jeremybenn
  /* Read packets until there are none left. */
744
  do
745
    {
746
      struct pollfd  fds[1];
747 450 jeremybenn
 
748 451 jeremybenn
      /* Poll to see if there is anything to be read. */
749
      fds[0].fd     = eth->rtx_fd;
750
      fds[0].events = POLLIN;
751
 
752
      n = poll (fds, 1, 0);
753
      if (n < 0)
754 450 jeremybenn
        {
755 451 jeremybenn
          /* Give up with a warning if poll fails */
756
          fprintf (stderr,
757
                   "Warning: Poll error while emptying TAP: %s: ignored.\n",
758
                   strerror (errno));
759
          return  result;
760
        }
761
      else if ((n > 0) && ((fds[0].revents & POLLIN) == POLLIN))
762
        {
763
          unsigned char  buf[ETH_MAXPL];
764
          ssize_t        nread = eth_read_packet (eth, buf);
765
 
766
          if (nread < 0)
767 19 jeremybenn
            {
768 451 jeremybenn
              /* Give up with a warning if read fails */
769
              fprintf (stderr,
770
                       "Warning: Read of when Ethernet busy failed %s.\n",
771
                       strerror (errno));
772
              return  result;
773 450 jeremybenn
            }
774 451 jeremybenn
          else if (nread > 0)
775 450 jeremybenn
            {
776 451 jeremybenn
              /* Record that a packet was thrown away. */
777
              result = 1;
778 437 julius
#if ETH_DEBUG
779 451 jeremybenn
              printf ("Ethernet discarding %d bytes from TAP while BD full.\n",
780
                      nread);
781 437 julius
#endif
782 19 jeremybenn
            }
783 450 jeremybenn
        }
784
    }
785 451 jeremybenn
  while (n > 0);
786 19 jeremybenn
 
787 538 julius
#endif
788
 
789 451 jeremybenn
  return  result;
790 450 jeremybenn
 
791 451 jeremybenn
}       /* eth_ignore_tap_packets () */
792
 
793
 
794 450 jeremybenn
/* -------------------------------------------------------------------------- */
795
/*!Rx clock function.
796
 
797
   Responsible for starting and completing any RX actions.
798
 
799
   The original version had 4 states, which allowed modeling the transfer of
800
   data one byte per cycle.  For now we use only the one state for
801
   efficiency. When the buffer is empty, we fill it from the external world.
802
 
803
   We schedule to wake up again each cycle. This means we will get called when
804
   the core is still processing the previous interrupt. To avoid races, we do
805
   nothing until the interrupt is cleared.
806
 
807
   @todo We should eventually reinstate the one byte per cycle transfer.
808
 
809
   @param[in] dat  The Ethernet data structure, passed as a void pointer.    */
810
/* -------------------------------------------------------------------------- */
811
static void
812
eth_controller_rx_clock (void *dat)
813
{
814
  struct eth_device *eth = dat;
815
 
816
  /* Only do anything if there is not an interrupt outstanding. */
817
  if (!eth->int_line_stat)
818
    {
819
      /* First word of the BD is flags, where we can test if it's ready. */
820
      if (TEST_FLAG (eth->regs.bd_ram[eth->rx_bd_index], ETH_RX_BD, READY))
821
        {
822
          /* The BD is empty, so we try to fill it with data from the outside
823
             world. */
824
          eth_fill_bd (eth);    /* BD ready to be filled. */
825 19 jeremybenn
        }
826 450 jeremybenn
      else if ((TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN)) &&
827
               (ETH_RTX_FILE == eth->rtx_type))
828
        {
829
          /* The BD is full, Rx is enabled and we are reading from an external
830
             TAP interface. We can't take any more, so we'll throw oustanding
831
             input packets on the floor.
832
 
833
             @note We don't do this for file I/O, since it would discard
834
             everything immediately! */
835 451 jeremybenn
          if (eth_ignore_tap_packets (eth))
836
            {
837
              /* A packet has been thrown away, so mark the INT_SOURCE
838
                 register accordingly. */
839
              SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
840
 
841
              /* Raise an interrupt if necessary. */
842
              if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, BUSY_M))
843
                {
844
                  if (eth->int_line_stat)
845
                    {
846
                      fprintf (stderr,
847
                               "Warning: Interrupt active during ignore.\n");
848
                    }
849
                  else
850
                    {
851
#if ETH_DEBUG
852
                      printf ("Ethernet Rx BUSY interrupt\n");
853
#endif
854
                      report_interrupt (eth->mac_int);
855
                      eth->int_line_stat = 1;
856
                    }
857
                }
858
            }
859 450 jeremybenn
        }
860 19 jeremybenn
    }
861
 
862 460 jeremybenn
  /* Whatever happens, we reschedule a wake up in the future. */
863 451 jeremybenn
  SCHED_ADD (eth_controller_rx_clock, dat, RTX_RESCHED_PERIOD);
864 19 jeremybenn
 
865 450 jeremybenn
}       /* eth_controller_rx_clock () */
866
 
867
 
868 451 jeremybenn
/* -------------------------------------------------------------------------- */
869
/*!VAPI connection to outside.
870 19 jeremybenn
 
871 451 jeremybenn
   Used for remote testing of the interface. Currently does nothing.
872 19 jeremybenn
 
873 451 jeremybenn
   @param[in] id  The VAPI ID to use.
874
   @param[in] data  Any data associated (unused here).
875
   @param[in] dat   The Ethernet data structure, cast to a void pointer.      */
876
/* -------------------------------------------------------------------------- */
877 443 jeremybenn
static void
878 451 jeremybenn
eth_vapi_read (unsigned long int  id,
879
               unsigned long int  data,
880
               void              *dat)
881 19 jeremybenn
{
882 451 jeremybenn
  unsigned long int  which;
883 443 jeremybenn
  struct eth_device *eth = dat;
884 19 jeremybenn
 
885 443 jeremybenn
  which = id - eth->base_vapi_id;
886
 
887
  if (!eth)
888 19 jeremybenn
    {
889 443 jeremybenn
      return;
890 19 jeremybenn
    }
891
 
892 443 jeremybenn
  switch (which)
893
    {
894
    case ETH_VAPI_DATA:
895
      break;
896
    case ETH_VAPI_CTRL:
897
      break;
898
    }
899 19 jeremybenn
}
900
 
901 451 jeremybenn
 
902 434 jeremybenn
/* -------------------------------------------------------------------------- */
903 451 jeremybenn
/*!Print register values on stdout
904 434 jeremybenn
 
905
   @param[in] dat  The Ethernet interface data structure.                     */
906
/* -------------------------------------------------------------------------- */
907 19 jeremybenn
static void
908 451 jeremybenn
eth_status (void *dat)
909 19 jeremybenn
{
910
  struct eth_device *eth = dat;
911
 
912 451 jeremybenn
  PRINTF ("\nEthernet MAC at 0x%" PRIxADDR ":\n", eth->baseaddr);
913
  PRINTF ("MODER        : 0x%08lX\n", eth->regs.moder);
914
  PRINTF ("INT_SOURCE   : 0x%08lX\n", eth->regs.int_source);
915
  PRINTF ("INT_MASK     : 0x%08lX\n", eth->regs.int_mask);
916
  PRINTF ("IPGT         : 0x%08lX\n", eth->regs.ipgt);
917
  PRINTF ("IPGR1        : 0x%08lX\n", eth->regs.ipgr1);
918
  PRINTF ("IPGR2        : 0x%08lX\n", eth->regs.ipgr2);
919
  PRINTF ("PACKETLEN    : 0x%08lX\n", eth->regs.packetlen);
920
  PRINTF ("COLLCONF     : 0x%08lX\n", eth->regs.collconf);
921
  PRINTF ("TX_BD_NUM    : 0x%08lX\n", eth->regs.tx_bd_num);
922
  PRINTF ("CTRLMODER    : 0x%08lX\n", eth->regs.controlmoder);
923
  PRINTF ("MIIMODER     : 0x%08lX\n", eth->regs.miimoder);
924
  PRINTF ("MIICOMMAND   : 0x%08lX\n", eth->regs.miicommand);
925
  PRINTF ("MIIADDRESS   : 0x%08lX\n", eth->regs.miiaddress);
926
  PRINTF ("MIITX_DATA   : 0x%08lX\n", eth->regs.miitx_data);
927
  PRINTF ("MIIRX_DATA   : 0x%08lX\n", eth->regs.miirx_data);
928
  PRINTF ("MIISTATUS    : 0x%08lX\n", eth->regs.miistatus);
929
  PRINTF ("MAC Address  : %02X:%02X:%02X:%02X:%02X:%02X\n",
930
          eth->mac_address[5], eth->mac_address[4], eth->mac_address[3],
931
          eth->mac_address[2], eth->mac_address[1], eth->mac_address[0]);
932
  PRINTF ("HASH0        : 0x%08lX\n", eth->regs.hash0);
933
  PRINTF ("HASH1        : 0x%08lX\n", eth->regs.hash1);
934
 
935
}       /* eth_status () */
936
 
937
 
938
/* -------------------------------------------------------------------------- */
939
/*!Open the external file interface to the Ethernet
940
 
941
   The data is represented by an input and an output file.
942
 
943
   @param[in] eth  The Ethernet interface data structure.                     */
944
/* -------------------------------------------------------------------------- */
945
static void
946
eth_open_file_if (struct eth_device *eth)
947
{
948
  /* (Re-)open TX/RX files */
949
  if (eth->rxfd >= 0)
950
    {
951
      close (eth->rxfd);
952
    }
953
 
954
  if (eth->txfd >= 0)
955
    {
956
      close (eth->txfd);
957
    }
958
 
959
  eth->rxfd = -1;
960
  eth->txfd = -1;
961
 
962
  eth->rxfd = open (eth->rxfile, O_RDONLY);
963
  if (eth->rxfd < 0)
964
    {
965
      fprintf (stderr, "Warning: Cannot open Ethernet RX file \"%s\": %s\n",
966
               eth->rxfile, strerror (errno));
967
    }
968
 
969
  eth->txfd = open (eth->txfile,
970
#if defined(O_SYNC)             /* BSD/MacOS X doesn't know about O_SYNC */
971
                    O_SYNC |
972 437 julius
#endif
973 451 jeremybenn
                    O_RDWR | O_CREAT | O_APPEND,
974
                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
975
  if (eth->txfd < 0)
976
    {
977
      fprintf (stderr, "Warning: Cannot open Ethernet TX file \"%s\": %s\n",
978
               eth->txfile, strerror (errno));
979
    }
980
}       /* eth_open_file_if () */
981 434 jeremybenn
 
982 538 julius
#if HAVE_LINUX_IF_TUN_H==1
983 451 jeremybenn
 
984
/* -------------------------------------------------------------------------- */
985
/*!Open the external TAP interface to the Ethernet
986
 
987
   Packets are transferred over a TAP/TUN interface. We assume a persistent
988
   tap interface has been set up and is owned by the user, so they can open
989
   and manipulate it. See the User Guide for details of setting this up.
990
 
991
   @todo We don't flush the TAP interface. Should we?
992
 
993
   @param[in] eth  The Ethernet interface data structure.                     */
994
/* -------------------------------------------------------------------------- */
995
static void
996
eth_open_tap_if (struct eth_device *eth)
997
{
998 538 julius
 
999 451 jeremybenn
  struct ifreq       ifr;
1000
 
1001
  /* We don't support re-opening. If it's open, it stays open. */
1002
  if (eth->rtx_fd >= 0)
1003 19 jeremybenn
    {
1004 434 jeremybenn
      return;
1005
    }
1006
 
1007 451 jeremybenn
  /* Open the TUN/TAP device */
1008
  eth->rtx_fd = open ("/dev/net/tun", O_RDWR);
1009
  if( eth->rtx_fd < 0 )
1010 434 jeremybenn
    {
1011 451 jeremybenn
      fprintf (stderr, "Warning: Failed to open TUN/TAP device: %s\n",
1012
               strerror (errno));
1013
      eth->rtx_fd = -1;
1014
      return;
1015
    }
1016 434 jeremybenn
 
1017 451 jeremybenn
  /* Turn it into a specific TAP device. If we haven't specified a specific
1018
     (persistent) device, one will be created, but that requires superuser, or
1019
     at least CAP_NET_ADMIN capabilities. */
1020
  memset (&ifr, 0, sizeof(ifr));
1021
  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
1022
  strncpy (ifr.ifr_name, eth->tap_dev, IFNAMSIZ);
1023 19 jeremybenn
 
1024 451 jeremybenn
  if (ioctl (eth->rtx_fd, TUNSETIFF, (void *) &ifr) < 0)
1025
    {
1026 508 jeremybenn
      fprintf (stderr, "Warning: Failed to set TAP device %s: %s\n",
1027
               eth->tap_dev, strerror (errno));
1028 451 jeremybenn
      close (eth->rtx_fd);
1029
      eth->rtx_fd = -1;
1030
      return;
1031
    }
1032
#if ETH_DEBUG
1033
      PRINTF ("Opened TAP %s\n", ifr.ifr_name);
1034
#endif
1035 538 julius
 
1036 451 jeremybenn
}       /* eth_open_tap_if () */
1037 19 jeremybenn
 
1038 538 julius
#endif
1039 19 jeremybenn
 
1040 538 julius
 
1041 451 jeremybenn
/* -------------------------------------------------------------------------- */
1042
/*!Open the external interface to the Ethernet
1043 19 jeremybenn
 
1044 451 jeremybenn
   Calls the appropriate function for the interface type.
1045 19 jeremybenn
 
1046 451 jeremybenn
   @param[in] eth  The Ethernet interface data structure.                     */
1047
/* -------------------------------------------------------------------------- */
1048
static void
1049
eth_open_if (struct eth_device *eth)
1050
{
1051
  switch (eth->rtx_type)
1052
    {
1053
    case ETH_RTX_FILE: eth_open_file_if (eth); break;
1054 538 julius
#if HAVE_LINUX_IF_TUN_H==1
1055 451 jeremybenn
    case ETH_RTX_TAP:  eth_open_tap_if (eth);  break;
1056 538 julius
#endif
1057 451 jeremybenn
 
1058
    default:
1059
      fprintf (stderr, "Unknown Ethernet interface: ignored.\n");
1060 434 jeremybenn
      break;
1061 451 jeremybenn
    }
1062
}       /* eth_open_if () */
1063 19 jeremybenn
 
1064
 
1065 451 jeremybenn
/* -------------------------------------------------------------------------- */
1066
/*!Reset the Ethernet.
1067 19 jeremybenn
 
1068 451 jeremybenn
   Open the correct type of simulation interface to the outside world.
1069 19 jeremybenn
 
1070 451 jeremybenn
   Initialize all registers to default and places devices in memory address
1071
   space.
1072 19 jeremybenn
 
1073 451 jeremybenn
   @param[in] dat  The Ethernet interface data structure.                     */
1074
/* -------------------------------------------------------------------------- */
1075
static void
1076
eth_reset (void *dat)
1077
{
1078
  struct eth_device *eth = dat;
1079
 
1080 437 julius
#if ETH_DEBUG
1081 451 jeremybenn
  printf ("Resetting Ethernet\n");
1082 437 julius
#endif
1083 451 jeremybenn
 
1084
  /* Nothing to do if we do not have a base address set, or we are not
1085
     enabled. */
1086
  if (!eth->enabled || (0 == eth->baseaddr))
1087
    {
1088
      return;
1089 19 jeremybenn
    }
1090
 
1091 451 jeremybenn
  eth_open_if (eth);
1092
 
1093 434 jeremybenn
  /* Set registers to default values */
1094
  memset (&(eth->regs), 0, sizeof (eth->regs));
1095 19 jeremybenn
 
1096 451 jeremybenn
  eth->regs.moder     = 0x0000A000;     /* Padding & CRC enabled */
1097
  eth->regs.ipgt      = 0x00000012;     /* Half duplex (matches MODER) */
1098
  eth->regs.ipgr1     = 0x0000000C;     /* Recommended value */
1099
  eth->regs.ipgr2     = 0x00000012;     /* Recommended value */
1100
  eth->regs.packetlen = 0x003C0600;     /* MINFL 60, MAXFL 1,536 bytes */
1101
  eth->regs.collconf  = 0x000F003F;     /* MAXRET 15, COLLVALID 63 */
1102
  eth->regs.tx_bd_num = 0x00000040;     /* Max Tx BD */
1103
  eth->regs.miimoder  = 0x00000064;     /* Send preamble, CLKDIV 100 */
1104 19 jeremybenn
 
1105 450 jeremybenn
  /* Reset TX/RX BD indexes. The Rx BD indexes start after the Tx BD indexes. */
1106
  eth->tx_bd_index = 0;
1107
  eth->rx_bd_index = eth->regs.tx_bd_num * 2;
1108 434 jeremybenn
 
1109 437 julius
  /* Reset IRQ line status */
1110
  eth->int_line_stat = 0;
1111
 
1112 434 jeremybenn
  /* Initialize VAPI */
1113
  if (eth->base_vapi_id)
1114
    {
1115
      vapi_install_multi_handler (eth->base_vapi_id, ETH_NUM_VAPI_IDS,
1116
                                  eth_vapi_read, dat);
1117
    }
1118
}       /* eth_reset () */
1119
 
1120
 
1121 451 jeremybenn
#if ETH_DEBUG
1122
/* -------------------------------------------------------------------------- */
1123
/*!Map a register address to its name
1124
 
1125
   @param[in[ addr  The address of the register to name (offset from base).
1126
 
1127
   @return  The name of the register.                                         */
1128
/* -------------------------------------------------------------------------- */
1129
static char *
1130
eth_regname (oraddr_t  addr)
1131 19 jeremybenn
{
1132 451 jeremybenn
  static char  bdstr[8];                /* For "BD[nnn]" */
1133 19 jeremybenn
 
1134 451 jeremybenn
  switch (addr)
1135
    {
1136
    case ETH_MODER:      return  "MODER";
1137
    case ETH_INT_SOURCE: return  "INT_SOURCE";
1138
    case ETH_INT_MASK:   return  "INT_MASK";
1139
    case ETH_IPGT:       return  "IPGT";
1140
    case ETH_IPGR1:      return  "IPGR1";
1141
    case ETH_IPGR2:      return  "IPGR2";
1142
    case ETH_PACKETLEN:  return  "PACKETLEN";
1143
    case ETH_COLLCONF:   return  "COLLCONF";
1144
    case ETH_TX_BD_NUM:  return  "TX_BD_NUM";
1145
    case ETH_CTRLMODER:  return  "CTRLMODER";
1146
    case ETH_MIIMODER:   return  "MIIMODER";
1147
    case ETH_MIICOMMAND: return  "MIICOMMAND";
1148
    case ETH_MIIADDRESS: return  "MIIADDRESS";
1149
    case ETH_MIITX_DATA: return  "MIITX_DATA";
1150
    case ETH_MIIRX_DATA: return  "MIIRX_DATA";
1151
    case ETH_MIISTATUS:  return  "MIISTATUS";
1152
    case ETH_MAC_ADDR0:  return  "MAC_ADDR0";
1153
    case ETH_MAC_ADDR1:  return  "MAC_ADDR1";
1154
    case ETH_HASH0:      return  "HASH0";
1155
    case ETH_HASH1:      return  "HASH1";
1156 19 jeremybenn
 
1157 451 jeremybenn
    default:
1158
      /* Buffer descriptors are a special case. */
1159
      if ((addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE))
1160
        {
1161
          sprintf (bdstr, "BD[%.3d]", (addr - ETH_BD_BASE) / 4);
1162
          return  bdstr;
1163
        }
1164
      else
1165
        {
1166
          return  "INVALID";
1167
        }
1168
    }
1169
}       /* eth_regname () */
1170
#endif
1171 19 jeremybenn
 
1172
 
1173 451 jeremybenn
/* -------------------------------------------------------------------------- */
1174
/*!Read a register
1175
 
1176
   @param[in] addr  The address of the register to read (offset from base).
1177
   @param[in] dat   The Ethernet interface data structure, cast to a void
1178
                    pointer.
1179
 
1180
   @return  The value read.                                                   */
1181
/* -------------------------------------------------------------------------- */
1182 19 jeremybenn
static uint32_t
1183 451 jeremybenn
eth_read32 (oraddr_t  addr,
1184
            void     *dat)
1185 19 jeremybenn
{
1186
  struct eth_device *eth = dat;
1187 451 jeremybenn
  uint32_t           res;
1188 19 jeremybenn
 
1189
  switch (addr)
1190
    {
1191 451 jeremybenn
    case ETH_MODER:      res = eth->regs.moder;        break;
1192
    case ETH_INT_SOURCE: res = eth->regs.int_source;   break;
1193
    case ETH_INT_MASK:   res = eth->regs.int_mask;     break;
1194
    case ETH_IPGT:       res = eth->regs.ipgt;         break;
1195
    case ETH_IPGR1:      res = eth->regs.ipgr1;        break;
1196
    case ETH_IPGR2:      res = eth->regs.ipgr2;        break;
1197
    case ETH_PACKETLEN:  res = eth->regs.packetlen;    break;
1198
    case ETH_COLLCONF:   res = eth->regs.collconf;     break;
1199
    case ETH_TX_BD_NUM:  res = eth->regs.tx_bd_num;    break;
1200
    case ETH_CTRLMODER:  res = eth->regs.controlmoder; break;
1201
    case ETH_MIIMODER:   res = eth->regs.miimoder;     break;
1202
    case ETH_MIICOMMAND: res = eth->regs.miicommand;   break;
1203
    case ETH_MIIADDRESS: res = eth->regs.miiaddress;   break;
1204
    case ETH_MIITX_DATA: res = eth->regs.miitx_data;   break;
1205
    case ETH_MIIRX_DATA: res = eth->regs.miirx_data;   break;
1206
    case ETH_MIISTATUS:  res = eth->regs.miistatus;    break;
1207
    case ETH_MAC_ADDR0:
1208
      res =
1209
        (((unsigned long) eth->mac_address[2]) << 24) |
1210
        (((unsigned long) eth->mac_address[3]) << 16) |
1211
        (((unsigned long) eth->mac_address[4]) <<  8) |
1212
          (unsigned long) eth->mac_address[5];
1213
      break;
1214
    case ETH_MAC_ADDR1:
1215
      res =
1216
        (((unsigned long) eth->mac_address[0]) <<  8) |
1217
          (unsigned long) eth->mac_address[1];
1218
      break;
1219
    case ETH_HASH0:      res = eth->regs.hash0;        break;
1220
    case ETH_HASH1:      res = eth->regs.hash1;        break;
1221
 
1222
    default:
1223
      /* Buffer descriptors are a special case. */
1224
      if ((addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE))
1225
        {
1226
          res = eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4];
1227
          break;
1228
        }
1229
      else
1230
        {
1231
          fprintf (stderr,
1232
                   "Warning: eth_read32( 0x%" PRIxADDR " ): Illegal address\n",
1233
                   addr + eth->baseaddr);
1234
          res = 0;
1235
        }
1236
    }
1237
 
1238
#if ETH_DEBUG
1239
  /* Only trace registers of particular interest */
1240
  switch (addr)
1241
    {
1242 19 jeremybenn
    case ETH_MODER:
1243
    case ETH_INT_SOURCE:
1244
    case ETH_INT_MASK:
1245
    case ETH_IPGT:
1246
    case ETH_IPGR1:
1247
    case ETH_IPGR2:
1248
    case ETH_PACKETLEN:
1249
    case ETH_COLLCONF:
1250
    case ETH_TX_BD_NUM:
1251
    case ETH_CTRLMODER:
1252
    case ETH_MAC_ADDR0:
1253
    case ETH_MAC_ADDR1:
1254 451 jeremybenn
      printf ("eth_read32: %s = 0x%08lx\n", eth_regname (addr),
1255
              (unsigned long int) res);
1256 19 jeremybenn
    }
1257 451 jeremybenn
#endif
1258 19 jeremybenn
 
1259 451 jeremybenn
  return  res;
1260 19 jeremybenn
 
1261 451 jeremybenn
}       /* eth_read32 () */
1262 19 jeremybenn
 
1263
 
1264 451 jeremybenn
/* -------------------------------------------------------------------------- */
1265
/*!Emulate MIIM transaction to ethernet PHY
1266 19 jeremybenn
 
1267 451 jeremybenn
   @param[in] eth  Ethernet device datastruture.                              */
1268
/* -------------------------------------------------------------------------- */
1269 19 jeremybenn
static void
1270 451 jeremybenn
eth_miim_trans (struct eth_device *eth)
1271
{
1272
  switch (eth->regs.miicommand)
1273
    {
1274
    case ((1 << ETH_MIICOMM_WCDATA_OFFSET)):
1275
      /* Perhaps something to emulate here later, but for now do nothing */
1276
      break;
1277
 
1278
    case ((1 << ETH_MIICOMM_RSTAT_OFFSET)):
1279
      /*First check if it's the correct PHY to address */
1280
      if (((eth->regs.miiaddress >> ETH_MIIADDR_FIAD_OFFSET)&
1281
           ETH_MIIADDR_FIAD_MASK) == eth->phy_addr)
1282
        {
1283
          /* Correct PHY - now switch based on the register address in the PHY*/
1284
          switch ((eth->regs.miiaddress >> ETH_MIIADDR_RGAD_OFFSET)&
1285
                  ETH_MIIADDR_RGAD_MASK)
1286
            {
1287
            case MII_BMCR:
1288
              eth->regs.miirx_data = BMCR_FULLDPLX;
1289
              break;
1290
            case MII_BMSR:
1291
              eth->regs.miirx_data = BMSR_LSTATUS | BMSR_ANEGCOMPLETE |
1292
                BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | BMSR_100FULL;
1293
              break;
1294
            case MII_PHYSID1:
1295
              eth->regs.miirx_data = 0x22; /* Micrel PHYID */
1296
              break;
1297
            case MII_PHYSID2:
1298
              eth->regs.miirx_data = 0x1613; /* Micrel PHYID */
1299
              break;
1300
            case MII_ADVERTISE:
1301
              eth->regs.miirx_data = ADVERTISE_FULL;
1302
              break;
1303
            case MII_LPA:
1304
              eth->regs.miirx_data = LPA_DUPLEX | LPA_100;
1305
              break;
1306
            case MII_EXPANSION:
1307
              eth->regs.miirx_data = 0;
1308
              break;
1309
            case MII_CTRL1000:
1310
              eth->regs.miirx_data = 0;
1311
              break;
1312
            case MII_STAT1000:
1313
              eth->regs.miirx_data = 0;
1314
              break;
1315
            case MII_ESTATUS:
1316
              eth->regs.miirx_data = 0;
1317
              break;
1318
            case MII_DCOUNTER:
1319
              eth->regs.miirx_data = 0;
1320
              break;
1321
            case MII_FCSCOUNTER:
1322
              eth->regs.miirx_data = 0;
1323
              break;
1324
            case MII_NWAYTEST:
1325
              eth->regs.miirx_data = 0;
1326
              break;
1327
            case MII_RERRCOUNTER:
1328
              eth->regs.miirx_data = 0;
1329
              break;
1330
            case MII_SREVISION:
1331
              eth->regs.miirx_data = 0;
1332
              break;
1333
            case MII_RESV1:
1334
              eth->regs.miirx_data = 0;
1335
              break;
1336
            case MII_LBRERROR:
1337
              eth->regs.miirx_data = 0;
1338
              break;
1339
            case MII_PHYADDR:
1340
              eth->regs.miirx_data = eth->phy_addr;
1341
              break;
1342
            case MII_RESV2:
1343
              eth->regs.miirx_data = 0;
1344
              break;
1345
            case MII_TPISTATUS:
1346
              eth->regs.miirx_data = 0;
1347
              break;
1348
            case MII_NCONFIG:
1349
              eth->regs.miirx_data = 0;
1350
              break;
1351
            default:
1352
              eth->regs.miirx_data = 0xffff;
1353
              break;
1354
            }
1355
        }
1356
      else
1357
        {
1358
          eth->regs.miirx_data = 0xffff; /* PHY doesn't exist, read all 1's */
1359
        }
1360
 
1361
      break;
1362
 
1363
    case ((1 << ETH_MIICOMM_SCANS_OFFSET)):
1364
      /* From MAC's datasheet:
1365
         A host initiates the Scan Status Operation by asserting the SCANSTAT
1366
         signal. The MIIM performs a continuous read operation of the PHY
1367
         Status register. The PHY is selected by the FIAD[4:0] signals. The
1368
         link status LinkFail signal is asserted/deasserted by the MIIM module
1369
         and reflects the link status bit of the PHY Status register. The
1370
         signal NVALID is used for qualifying the validity of the LinkFail
1371
         signals and the status data PRSD[15:0]. These signals are invalid
1372
         until the first scan status operation ends. During the scan status
1373
         operation, the BUSY signal is asserted until the last read is
1374
         performed (the scan status operation is stopped).
1375
 
1376
         So for now - do nothing, leave link status indicator as permanently
1377
         with link.
1378
      */
1379
 
1380
      break;
1381
 
1382
    default:
1383
      break;
1384
    }
1385
}       /* eth_miim_trans () */
1386
 
1387
 
1388
 
1389
/* -------------------------------------------------------------------------- */
1390
/*!Write a register
1391
 
1392 460 jeremybenn
   @note Earlier versions of this code treated ETH_INT_SOURCE as an "interrupt
1393
         pending" register and reissued interrupts if ETH_INT_MASK was
1394
         changed, enabling an interrupt that had previously been cleared. This
1395
         led to spurious double interrupt. In the present version, the only
1396
         way an interrupt can be generated is at the time ETH_INT_SOURCE is
1397
         set in the Tx/Rx controllers and the only way an interrupt can be
1398
         cleared is by writing to ETH_INT_SOURCE.
1399
 
1400 451 jeremybenn
   @param[in] addr   The address of the register to read (offset from base).
1401
   @param[in] value  The value to write.
1402
   @param[in] dat    The Ethernet interface data structure, cast to a void
1403
                     pointer.                                                 */
1404
/* -------------------------------------------------------------------------- */
1405
static void
1406 19 jeremybenn
eth_write32 (oraddr_t addr, uint32_t value, void *dat)
1407
{
1408
  struct eth_device *eth = dat;
1409
 
1410 451 jeremybenn
#if ETH_DEBUG
1411
  /* Only trace registers of particular interest */
1412 19 jeremybenn
  switch (addr)
1413 460 jeremybenn
    {
1414
    case ETH_MODER:
1415
    case ETH_INT_SOURCE:
1416
    case ETH_INT_MASK:
1417
    case ETH_IPGT:
1418
    case ETH_IPGR1:
1419
    case ETH_IPGR2:
1420
    case ETH_PACKETLEN:
1421
    case ETH_COLLCONF:
1422
    case ETH_TX_BD_NUM:
1423
    case ETH_CTRLMODER:
1424
    case ETH_MAC_ADDR0:
1425
    case ETH_MAC_ADDR1:
1426
      printf ("eth_write32: 0x%08lx to %s ", (unsigned long int) value,
1427
              eth_regname (addr));
1428
    }
1429
 
1430 457 julius
  /* Detail register transitions on MODER, INT_SOURCE AND INT_MASK */
1431
  switch (addr)
1432 460 jeremybenn
    {
1433
    case ETH_MODER:
1434
      printf (" 0x%08lx -> ", (unsigned long) eth->regs.moder);
1435
      break;
1436
    case ETH_INT_SOURCE:
1437
      printf (" 0x%08lx -> ", (unsigned long) eth->regs.int_source);
1438
      break;
1439
    case ETH_INT_MASK:
1440
      printf (" 0x%08lx -> ", (unsigned long) eth->regs.int_mask);
1441
      break;
1442
    }
1443 437 julius
#endif
1444 451 jeremybenn
 
1445
  switch (addr)
1446
    {
1447
    case ETH_MODER:
1448 19 jeremybenn
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN) &&
1449
          TEST_FLAG (value, ETH_MODER, RXEN))
1450 436 julius
        {
1451 451 jeremybenn
          /* Enabling receive, flush any oustanding input (TAP only), reset
1452
             the BDs and schedule the Rx controller on the next clock
1453
             cycle. */
1454
          if (ETH_RTX_TAP == eth->rtx_type)
1455
            {
1456
              (void) eth_ignore_tap_packets (eth);
1457
            }
1458
 
1459
          eth->rx_bd_index = eth->regs.tx_bd_num * 2;
1460 436 julius
          SCHED_ADD (eth_controller_rx_clock, dat, 1);
1461
        }
1462 437 julius
      else if (!TEST_FLAG (value, ETH_MODER, RXEN) &&
1463
               TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
1464 451 jeremybenn
        {
1465
          /* Disabling Rx, so stop scheduling the Rx controller. */
1466
          SCHED_FIND_REMOVE (eth_controller_rx_clock, dat);
1467
        }
1468 19 jeremybenn
 
1469
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN) &&
1470
          TEST_FLAG (value, ETH_MODER, TXEN))
1471 436 julius
        {
1472 451 jeremybenn
          /* Enabling transmit, reset the BD and schedule the Tx controller on
1473
             the next clock cycle. */
1474 450 jeremybenn
          eth->tx_bd_index = 0;
1475 436 julius
          SCHED_ADD (eth_controller_tx_clock, dat, 1);
1476
        }
1477 437 julius
      else if (!TEST_FLAG (value, ETH_MODER, TXEN) &&
1478
               TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN))
1479 451 jeremybenn
        {
1480
          /* Disabling Tx, so stop scheduling the Tx controller. */
1481
          SCHED_FIND_REMOVE (eth_controller_tx_clock, dat);
1482
        }
1483 19 jeremybenn
 
1484 451 jeremybenn
      /* Reset the interface if so requested. */
1485
      if (TEST_FLAG (value, ETH_MODER, RST))
1486
        {
1487
          eth_reset (dat);
1488
        }
1489 19 jeremybenn
 
1490 451 jeremybenn
      eth->regs.moder = value;          /* Update the register */
1491
      break;
1492
 
1493 19 jeremybenn
    case ETH_INT_SOURCE:
1494 437 julius
      eth->regs.int_source &= ~value;
1495 436 julius
 
1496 451 jeremybenn
      /* Clear IRQ line if all interrupt sources have been dealt with
1497
 
1498
         @todo  Is this really right? */
1499 437 julius
      if (!(eth->regs.int_source & eth->regs.int_mask) && eth->int_line_stat)
1500
        {
1501
          clear_interrupt (eth->mac_int);
1502
          eth->int_line_stat = 0;
1503
        }
1504 451 jeremybenn
      break;
1505
 
1506 19 jeremybenn
    case ETH_INT_MASK:
1507
      eth->regs.int_mask = value;
1508 451 jeremybenn
 
1509 460 jeremybenn
      /* The old code would report an interrupt if we enabled an interrupt
1510
         when if we enabled interrupts and the core was not currently
1511
         processing an interrupt, and there was an interrupt pending.
1512 451 jeremybenn
 
1513 460 jeremybenn
         However this led (at least on some machines) to orphaned interrupts
1514
         in the device driver. So in this version of the code we do not report
1515
         interrupts on a mask change.
1516
 
1517
         This is not apparently consistent with the Verilog, but it does mean
1518
         that the orphaned interrupts problem does not occur, and has no
1519
         apparent effect on Ethernet performance. More investigation is needed
1520
         to determine if this is a bug in Or1ksim interrupt handling, or a bug
1521
         in the device driver, which does not manifest with real HW.
1522
 
1523 451 jeremybenn
         Otherwise clear down the interrupt.
1524
 
1525
         @todo  Is this really right. */
1526 437 julius
      if ((eth->regs.int_source & eth->regs.int_mask) && !eth->int_line_stat)
1527 451 jeremybenn
        {
1528 460 jeremybenn
#if ETH_DEBUG
1529
          printf ("ETH_MASK changed with apparent pending interrupt.\n");
1530
#endif
1531 451 jeremybenn
        }
1532
      else if (eth->int_line_stat)
1533
        {
1534
          clear_interrupt (eth->mac_int);
1535
          eth->int_line_stat = 0;
1536
        }
1537 460 jeremybenn
 
1538 451 jeremybenn
      break;
1539
 
1540
    case ETH_IPGT:       eth->regs.ipgt         = value; break;
1541
    case ETH_IPGR1:      eth->regs.ipgr1        = value; break;
1542
    case ETH_IPGR2:      eth->regs.ipgr2        = value; break;
1543
    case ETH_PACKETLEN:  eth->regs.packetlen    = value; break;
1544
    case ETH_COLLCONF:   eth->regs.collconf     = value; break;
1545
 
1546 19 jeremybenn
    case ETH_TX_BD_NUM:
1547 443 jeremybenn
      /* When TX_BD_NUM is written, also reset current RX BD index */
1548
      eth->regs.tx_bd_num = value & 0xFF;
1549 451 jeremybenn
      eth->rx_bd_index = eth->regs.tx_bd_num * 2;
1550
      break;
1551
 
1552
    case ETH_CTRLMODER:  eth->regs.controlmoder = value; break;
1553
    case ETH_MIIMODER:   eth->regs.miimoder     = value; break;
1554
 
1555 19 jeremybenn
    case ETH_MIICOMMAND:
1556
      eth->regs.miicommand = value;
1557 428 julius
      /* Perform MIIM transaction, if required */
1558 443 jeremybenn
      eth_miim_trans (eth);
1559 451 jeremybenn
      break;
1560 428 julius
 
1561 451 jeremybenn
    case ETH_MIIADDRESS: eth->regs.miiaddress   = value; break;
1562
    case ETH_MIITX_DATA: eth->regs.miitx_data   = value; break;
1563
    case ETH_MIIRX_DATA: /* Register is R/O */           break;
1564
    case ETH_MIISTATUS:  /* Register is R/O */           break;
1565
 
1566 19 jeremybenn
    case ETH_MAC_ADDR0:
1567 451 jeremybenn
      eth->mac_address[5] =  value        & 0xFF;
1568
      eth->mac_address[4] = (value >>  8) & 0xFF;
1569 450 jeremybenn
      eth->mac_address[3] = (value >> 16) & 0xFF;
1570
      eth->mac_address[2] = (value >> 24) & 0xFF;
1571 451 jeremybenn
      break;
1572
 
1573 19 jeremybenn
    case ETH_MAC_ADDR1:
1574 451 jeremybenn
      eth->mac_address[1] =  value        & 0xFF;
1575
      eth->mac_address[0] = (value >>  8) & 0xFF;
1576
      break;
1577 19 jeremybenn
 
1578 451 jeremybenn
    case ETH_HASH0:      eth->regs.hash0 = value;        break;
1579
    case ETH_HASH1:      eth->regs.hash1 = value;        break;
1580 19 jeremybenn
 
1581 451 jeremybenn
    default:
1582
      if ((addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE))
1583
        {
1584
          eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4] = value;
1585
        }
1586
      else
1587
        {
1588
          fprintf (stderr,
1589
                   "Warning: eth_write32( 0x%" PRIxADDR " ): Illegal address\n",
1590
                   addr + eth->baseaddr);
1591
        }
1592
      break;
1593 19 jeremybenn
    }
1594 457 julius
 
1595
#if ETH_DEBUG
1596
  switch (addr)
1597 460 jeremybenn
    {
1598
    case ETH_MODER:
1599
      printf ("0x%08lx\n", (unsigned long) eth->regs.moder);
1600
      break;
1601
    case ETH_INT_SOURCE:
1602
      printf ("0x%08lx\n", (unsigned long) eth->regs.int_source);
1603
      break;
1604
    case ETH_INT_MASK:
1605
      printf ("0x%08lx\n", (unsigned long) eth->regs.int_mask);
1606
      break;
1607
    case ETH_IPGT:
1608
    case ETH_IPGR1:
1609
    case ETH_IPGR2:
1610
    case ETH_PACKETLEN:
1611
    case ETH_COLLCONF:
1612
    case ETH_TX_BD_NUM:
1613
    case ETH_CTRLMODER:
1614
    case ETH_MAC_ADDR0:
1615
    case ETH_MAC_ADDR1:
1616
      printf("\n");
1617
      break;
1618
    }
1619 457 julius
 
1620
#endif
1621
 
1622 451 jeremybenn
}       /* eth_write32 () */
1623 19 jeremybenn
 
1624
 
1625
/*---------------------------------------------------------------------------*/
1626
/*!Enable or disable the Ethernet interface
1627
 
1628
   @param[in] val  The value to use
1629
   @param[in] dat  The config data structure                                 */
1630
/*---------------------------------------------------------------------------*/
1631
static void
1632
eth_enabled (union param_val  val,
1633
             void            *dat)
1634
{
1635
  struct eth_device *eth = dat;
1636
 
1637
  eth->enabled = val.int_val;
1638
 
1639
}       /* eth_enabled() */
1640
 
1641
 
1642
/*---------------------------------------------------------------------------*/
1643
/*!Set the Ethernet interface base address
1644
 
1645
   @param[in] val  The value to use
1646
   @param[in] dat  The config data structure                                 */
1647
/*---------------------------------------------------------------------------*/
1648
static void
1649
eth_baseaddr (union param_val  val,
1650
              void            *dat)
1651
{
1652
  struct eth_device *eth = dat;
1653
 
1654
  eth->baseaddr = val.addr_val;
1655
 
1656
}       /* eth_baseaddr() */
1657
 
1658
 
1659
/*---------------------------------------------------------------------------*/
1660
/*!Set the Ethernet DMA port
1661
 
1662
   This is not currently supported, so a warning message is printed.
1663
 
1664
   @param[in] val  The value to use
1665
   @param[in] dat  The config data structure                                 */
1666
/*---------------------------------------------------------------------------*/
1667
static void
1668
eth_dma (union param_val  val,
1669
         void            *dat)
1670
{
1671
  struct eth_device *eth = dat;
1672
 
1673
  fprintf (stderr, "Warning: External Ethernet DMA not currently supported\n");
1674
  eth->dma = val.addr_val;
1675
 
1676
}       /* eth_dma() */
1677
 
1678
 
1679
/*---------------------------------------------------------------------------*/
1680
/*!Set the Ethernet IRQ
1681
 
1682
   @param[in] val  The value to use
1683
   @param[in] dat  The config data structure                                 */
1684
/*---------------------------------------------------------------------------*/
1685
static void
1686
eth_irq (union param_val  val,
1687
         void            *dat)
1688
{
1689
  struct eth_device *eth = dat;
1690
 
1691
  eth->mac_int = val.int_val;
1692
 
1693
}       /* eth_irq() */
1694
 
1695
 
1696
/*---------------------------------------------------------------------------*/
1697
/*!Set the Ethernet interface type
1698
 
1699 434 jeremybenn
   Currently two types are supported, file and tap.
1700 19 jeremybenn
 
1701 434 jeremybenn
   @param[in] val  The value to use. Currently "file" and "tap" are supported.
1702 19 jeremybenn
   @param[in] dat  The config data structure                                 */
1703
/*---------------------------------------------------------------------------*/
1704
static void
1705
eth_rtx_type (union param_val  val,
1706
              void            *dat)
1707
{
1708
  struct eth_device *eth = dat;
1709
 
1710 434 jeremybenn
  if (0 == strcasecmp ("file", val.str_val))
1711 19 jeremybenn
    {
1712 434 jeremybenn
      printf ("Ethernet FILE type\n");
1713
      eth->rtx_type = ETH_RTX_FILE;
1714 19 jeremybenn
    }
1715 538 julius
#if HAVE_LINUX_IF_TUN_H==1
1716 434 jeremybenn
  else if (0 == strcasecmp ("tap", val.str_val))
1717
    {
1718
      printf ("Ethernet TAP type\n");
1719
      eth->rtx_type = ETH_RTX_TAP;
1720
    }
1721 538 julius
#endif
1722 434 jeremybenn
  else
1723
    {
1724
      fprintf (stderr, "Warning: Unknown Ethernet type: file assumed.\n");
1725
      eth->rtx_type = ETH_RTX_FILE;
1726
    }
1727 19 jeremybenn
}       /* eth_rtx_type() */
1728
 
1729
 
1730
/*---------------------------------------------------------------------------*/
1731
/*!Set the Ethernet DMA Rx channel
1732
 
1733
   External DMA is not currently supported, so a warning message is printed.
1734
 
1735
   @param[in] val  The value to use
1736
   @param[in] dat  The config data structure                                 */
1737
/*---------------------------------------------------------------------------*/
1738
static void
1739
eth_rx_channel (union param_val  val,
1740
                void            *dat)
1741
{
1742
  struct eth_device *eth = dat;
1743
 
1744
  fprintf (stderr, "Warning: External Ethernet DMA not currently supported: "
1745
           "Rx channel ignored\n");
1746
  eth->rx_channel = val.int_val;
1747
 
1748
}       /* eth_rx_channel() */
1749
 
1750
 
1751
/*---------------------------------------------------------------------------*/
1752
/*!Set the Ethernet DMA Tx channel
1753
 
1754
   External DMA is not currently supported, so a warning message is printed.
1755
 
1756
   @param[in] val  The value to use
1757
   @param[in] dat  The config data structure                                 */
1758
/*---------------------------------------------------------------------------*/
1759
static void
1760
eth_tx_channel (union param_val  val,
1761
                void            *dat)
1762
{
1763
  struct eth_device *eth = dat;
1764
 
1765
  fprintf (stderr, "Warning: External Ethernet DMA not currently supported: "
1766
           "Tx channel ignored\n");
1767
  eth->tx_channel = val.int_val;
1768
 
1769
}       /* eth_tx_channel() */
1770
 
1771
 
1772
/*---------------------------------------------------------------------------*/
1773
/*!Set the Ethernet DMA Rx file
1774
 
1775
   Free any previously allocated value.
1776
 
1777
   @param[in] val  The value to use
1778
   @param[in] dat  The config data structure                                 */
1779
/*---------------------------------------------------------------------------*/
1780
static void
1781
eth_rxfile (union param_val  val,
1782
            void            *dat)
1783
{
1784
  struct eth_device *eth = dat;
1785
 
1786
  if (NULL != eth->rxfile)
1787
    {
1788
      free (eth->rxfile);
1789
      eth->rxfile = NULL;
1790
    }
1791
 
1792
  if (!(eth->rxfile = strdup (val.str_val)))
1793
    {
1794
      fprintf (stderr, "Peripheral Ethernet: Run out of memory\n");
1795
      exit (-1);
1796
    }
1797
}       /* eth_rxfile() */
1798
 
1799
 
1800
/*---------------------------------------------------------------------------*/
1801
/*!Set the Ethernet DMA Tx file
1802
 
1803
   Free any previously allocated value.
1804
 
1805
   @param[in] val  The value to use
1806
   @param[in] dat  The config data structure                                 */
1807
/*---------------------------------------------------------------------------*/
1808
static void
1809
eth_txfile (union param_val  val,
1810
            void            *dat)
1811
{
1812
  struct eth_device *eth = dat;
1813
 
1814
  if (NULL != eth->txfile)
1815
    {
1816
      free (eth->txfile);
1817
      eth->txfile = NULL;
1818
    }
1819
 
1820
  if (!(eth->txfile = strdup (val.str_val)))
1821
    {
1822
      fprintf (stderr, "Peripheral Ethernet: Run out of memory\n");
1823
      exit (-1);
1824
    }
1825
}       /* eth_txfile() */
1826
 
1827
 
1828
/*---------------------------------------------------------------------------*/
1829 434 jeremybenn
/*!Set the Ethernet TAP device.
1830 19 jeremybenn
 
1831 434 jeremybenn
   If we are not superuser (or do not have CAP_NET_ADMIN priviledges), then we
1832
   must work with a persistent TAP device that is already set up. This option
1833
   specifies the device to user.
1834 19 jeremybenn
 
1835 434 jeremybenn
   @param[in] val  The value to use.
1836 19 jeremybenn
   @param[in] dat  The config data structure                                 */
1837
/*---------------------------------------------------------------------------*/
1838
static void
1839 434 jeremybenn
eth_tap_dev (union param_val  val,
1840
              void            *dat)
1841 19 jeremybenn
{
1842
  struct eth_device *eth = dat;
1843
 
1844 434 jeremybenn
  if (NULL != eth->tap_dev)
1845 19 jeremybenn
    {
1846 434 jeremybenn
      free (eth->tap_dev);
1847
      eth->tap_dev = NULL;
1848 19 jeremybenn
    }
1849
 
1850 434 jeremybenn
  eth->tap_dev = strdup (val.str_val);
1851
 
1852
  if (NULL == eth->tap_dev)
1853 19 jeremybenn
    {
1854 434 jeremybenn
      fprintf (stderr, "ERROR: Peripheral Ethernet: Run out of memory\n");
1855 19 jeremybenn
      exit (-1);
1856
    }
1857 434 jeremybenn
}       /* eth_tap_dev() */
1858 19 jeremybenn
 
1859
 
1860 451 jeremybenn
/*---------------------------------------------------------------------------*/
1861
/*!Set the PHY address
1862
 
1863
   Used to identify different physical interfaces (important for MII).
1864
 
1865
   @param[in] val  The value to use.
1866
   @param[in] dat  The config data structure                                 */
1867
/*---------------------------------------------------------------------------*/
1868 19 jeremybenn
static void
1869 451 jeremybenn
eth_phy_addr (union param_val  val,
1870
              void            *dat)
1871
{
1872
  struct eth_device *eth = dat;
1873
  eth->phy_addr = val.int_val & ETH_MIIADDR_FIAD_MASK;
1874
 
1875
}       /* eth_phy_addr () */
1876
 
1877
 
1878
/*---------------------------------------------------------------------------*/
1879
/*!Enable or disable a dummy CRC
1880
 
1881
   The MAC should not report anything about the CRC back to the core. However
1882
   the hardware implementation of the OpenRISC MAC does, and the Linux drivers
1883
   have been written to expect the value (which they ignore).
1884
 
1885
   Setting this parameter causes a dummy CRC to be added. For consistency with
1886
   the hardware, its default setting is TRUE.
1887
 
1888
   @param[in] val  The value to use
1889
   @param[in] dat  The config data structure                                 */
1890
/*---------------------------------------------------------------------------*/
1891
static void
1892
eth_dummy_crc (union param_val  val,
1893 19 jeremybenn
             void            *dat)
1894
{
1895
  struct eth_device *eth = dat;
1896
 
1897 451 jeremybenn
  eth->dummy_crc = val.int_val;
1898 428 julius
 
1899 451 jeremybenn
}       /* eth_dummy_crc() */
1900
 
1901
 
1902
/*---------------------------------------------------------------------------*/
1903
/*!Set the VAPI id
1904
 
1905
   Used for remote testing of the interface.
1906
 
1907
   @param[in] val  The value to use.
1908
   @param[in] dat  The config data structure                                 */
1909
/*---------------------------------------------------------------------------*/
1910 428 julius
static void
1911 451 jeremybenn
eth_vapi_id (union param_val  val,
1912
             void            *dat)
1913 428 julius
{
1914
  struct eth_device *eth = dat;
1915 451 jeremybenn
  eth->base_vapi_id = val.int_val;
1916 428 julius
 
1917 451 jeremybenn
}       /* eth_vapi_id () */
1918 428 julius
 
1919 451 jeremybenn
 
1920 19 jeremybenn
/*---------------------------------------------------------------------------*/
1921 451 jeremybenn
/*!Start the initialization of a new Ethernet configuration
1922 19 jeremybenn
 
1923
   ALL parameters are set explicitly to default values.                      */
1924
/*---------------------------------------------------------------------------*/
1925
static void *
1926
eth_sec_start (void)
1927
{
1928
  struct eth_device *new = malloc (sizeof (struct eth_device));
1929
 
1930
  if (!new)
1931
    {
1932
      fprintf (stderr, "Peripheral Eth: Run out of memory\n");
1933
      exit (-1);
1934
    }
1935
 
1936
  memset (new, 0, sizeof (struct eth_device));
1937
 
1938
  new->enabled      = 1;
1939
  new->baseaddr     = 0;
1940
  new->dma          = 0;
1941
  new->mac_int      = 0;
1942 437 julius
  new->int_line_stat= 0;
1943 434 jeremybenn
  new->rtx_type     = ETH_RTX_FILE;
1944 19 jeremybenn
  new->rx_channel   = 0;
1945
  new->tx_channel   = 0;
1946 451 jeremybenn
  new->rtx_fd       = -1;
1947 19 jeremybenn
  new->rxfile       = strdup ("eth_rx");
1948
  new->txfile       = strdup ("eth_tx");
1949 434 jeremybenn
  new->tap_dev      = strdup ("");
1950 451 jeremybenn
  new->phy_addr     = 0;
1951
  new->dummy_crc    = 1;
1952 19 jeremybenn
  new->base_vapi_id = 0;
1953
 
1954
  return new;
1955
 
1956 451 jeremybenn
}       /* eth_sec_start () */
1957
 
1958
 
1959
/*---------------------------------------------------------------------------*/
1960
/*!Complete the initialization of a new Ethernet configuration
1961
 
1962
   ALL parameters are set explicitly to default values.                      */
1963
/*---------------------------------------------------------------------------*/
1964 19 jeremybenn
static void
1965
eth_sec_end (void *dat)
1966
{
1967
  struct eth_device *eth = dat;
1968
  struct mem_ops ops;
1969
 
1970
  if (!eth->enabled)
1971
    {
1972
      free (eth->rxfile);
1973
      free (eth->txfile);
1974 434 jeremybenn
      free (eth->tap_dev);
1975 19 jeremybenn
      free (eth);
1976
      return;
1977
    }
1978
 
1979
  memset (&ops, 0, sizeof (struct mem_ops));
1980
 
1981
  ops.readfunc32 = eth_read32;
1982
  ops.writefunc32 = eth_write32;
1983
  ops.read_dat32 = dat;
1984
  ops.write_dat32 = dat;
1985
 
1986
  /* FIXME: Correct delay? */
1987
  ops.delayr = 2;
1988
  ops.delayw = 2;
1989
  reg_mem_area (eth->baseaddr, ETH_ADDR_SPACE, 0, &ops);
1990
  reg_sim_stat (eth_status, dat);
1991
  reg_sim_reset (eth_reset, dat);
1992
 
1993 451 jeremybenn
}       /* eth_sec_end () */
1994 19 jeremybenn
 
1995 451 jeremybenn
 
1996 19 jeremybenn
/*---------------------------------------------------------------------------*/
1997
/*!Register a new Ethernet configuration                                     */
1998
/*---------------------------------------------------------------------------*/
1999
void
2000
reg_ethernet_sec ()
2001
{
2002
  struct config_section *sec =
2003
    reg_config_sec ("ethernet", eth_sec_start, eth_sec_end);
2004
 
2005 224 jeremybenn
  reg_config_param (sec, "enabled",    PARAMT_INT,  eth_enabled);
2006
  reg_config_param (sec, "baseaddr",   PARAMT_ADDR, eth_baseaddr);
2007
  reg_config_param (sec, "dma",        PARAMT_INT,  eth_dma);
2008
  reg_config_param (sec, "irq",        PARAMT_INT,  eth_irq);
2009 434 jeremybenn
  reg_config_param (sec, "rtx_type",   PARAMT_STR,  eth_rtx_type);
2010 224 jeremybenn
  reg_config_param (sec, "rx_channel", PARAMT_INT,  eth_rx_channel);
2011
  reg_config_param (sec, "tx_channel", PARAMT_INT,  eth_tx_channel);
2012
  reg_config_param (sec, "rxfile",     PARAMT_STR,  eth_rxfile);
2013
  reg_config_param (sec, "txfile",     PARAMT_STR,  eth_txfile);
2014 434 jeremybenn
  reg_config_param (sec, "tap_dev",    PARAMT_STR,  eth_tap_dev);
2015 451 jeremybenn
  reg_config_param (sec, "phy_addr",   PARAMT_INT,  eth_phy_addr);
2016
  reg_config_param (sec, "dummy_crc",  PARAMT_INT,  eth_dummy_crc);
2017 224 jeremybenn
  reg_config_param (sec, "vapi_id",    PARAMT_INT,  eth_vapi_id);
2018 19 jeremybenn
 
2019
}       /* reg_ethernet_sec() */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.