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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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