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

Subversion Repositories openrisc

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

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
   Copyright (C) 2008 Embecosm Limited
6
 
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of Or1ksim, the OpenRISC 1000 Architectural Simulator.
10
 
11
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15
 
16
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20
 
21
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http://www.gnu.org/licenses/>.  */
23
 
24
/* This program is commented throughout in a fashion suitable for processing
25
   with Doxygen. */
26
 
27
 
28
/* Autoconf and/or portability configuration */
29
#include "config.h"
30
#include "port.h"
31
 
32
/* System includes */
33
#include <stdlib.h>
34
#include <stdio.h>
35
#include <sys/types.h>
36
#include <sys/stat.h>
37
#include <fcntl.h>
38
#include <sys/poll.h>
39
#include <sys/time.h>
40
#include <unistd.h>
41
#include <errno.h>
42
#include <netinet/in.h>
43
#include <sys/ioctl.h>
44
#include <sys/socket.h>
45
#include <net/if.h>
46
 
47
/* Package includes */
48
#include "arch.h"
49
#include "config.h"
50
#include "abstract.h"
51
#include "eth.h"
52
#include "dma.h"
53
#include "sim-config.h"
54
#include "fields.h"
55
#include "crc32.h"
56
#include "vapi.h"
57
#include "pic.h"
58
#include "sched.h"
59
#include "toplevel-support.h"
60
#include "sim-cmd.h"
61
 
62
struct eth_device
63
{
64
  /* Is peripheral enabled */
65
  int enabled;
66
 
67
  /* Base address in memory */
68
  oraddr_t baseaddr;
69
 
70
  /* Which DMA controller is this MAC connected to */
71
  unsigned dma;
72
  unsigned tx_channel;
73
  unsigned rx_channel;
74
 
75
  /* Our address */
76
  unsigned char mac_address[ETHER_ADDR_LEN];
77
 
78
  /* interrupt line */
79
  unsigned long mac_int;
80
 
81
  /* VAPI ID */
82
  unsigned long base_vapi_id;
83
 
84 428 julius
  /* Ethernet PHY address */
85
  unsigned long phy_addr;
86
 
87 19 jeremybenn
  /* RX and TX file names and handles */
88
  char *rxfile, *txfile;
89
  int txfd;
90
  int rxfd;
91
  off_t loopback_offset;
92
 
93
  /* Socket interface name */
94
  char *sockif;
95
 
96
  int rtx_sock;
97
  int rtx_type;
98
  struct ifreq ifr;
99
  fd_set rfds, wfds;
100
 
101
  /* Current TX state */
102
  struct
103
  {
104
    unsigned long state;
105
    unsigned long bd_index;
106
    unsigned long bd;
107
    unsigned long bd_addr;
108
    unsigned working, waiting_for_dma, error;
109
    long packet_length;
110
    unsigned minimum_length, maximum_length;
111
    unsigned add_crc;
112
    unsigned crc_dly;
113
    unsigned long crc_value;
114
    long bytes_left, bytes_sent;
115
  } tx;
116
 
117
  /* Current RX state */
118
  struct
119
  {
120
    unsigned long state;
121
    unsigned long bd_index;
122
    unsigned long bd;
123
    unsigned long bd_addr;
124
    int fd;
125
    off_t *offset;
126
    unsigned working, error, waiting_for_dma;
127
    long packet_length, bytes_read, bytes_left;
128
  } rx;
129
 
130
  /* Visible registers */
131
  struct
132
  {
133
    unsigned long moder;
134
    unsigned long int_source;
135
    unsigned long int_mask;
136
    unsigned long ipgt;
137
    unsigned long ipgr1;
138
    unsigned long ipgr2;
139
    unsigned long packetlen;
140
    unsigned long collconf;
141
    unsigned long tx_bd_num;
142
    unsigned long controlmoder;
143
    unsigned long miimoder;
144
    unsigned long miicommand;
145
    unsigned long miiaddress;
146
    unsigned long miitx_data;
147
    unsigned long miirx_data;
148
    unsigned long miistatus;
149
    unsigned long hash0;
150
    unsigned long hash1;
151
 
152
    /* Buffer descriptors */
153
    unsigned long bd_ram[ETH_BD_SPACE / 4];
154
  } regs;
155
 
156
  unsigned char rx_buff[ETH_MAXPL];
157
  unsigned char tx_buff[ETH_MAXPL];
158
  unsigned char lo_buff[ETH_MAXPL];
159
};
160
 
161
 
162
/* simulator interface */
163
static void eth_vapi_read (unsigned long id, unsigned long data, void *dat);
164
/* register interface */
165
static void eth_write32 (oraddr_t addr, uint32_t value, void *dat);
166
static uint32_t eth_read32 (oraddr_t addr, void *dat);
167
/* clock */
168
static void eth_controller_tx_clock (void *);
169
static void eth_controller_rx_clock (void *);
170
/* utility functions */
171
static ssize_t eth_read_rx_file (struct eth_device *, void *, size_t);
172
static void eth_skip_rx_file (struct eth_device *, off_t);
173
static void eth_rx_next_packet (struct eth_device *);
174
static void eth_write_tx_bd_num (struct eth_device *, unsigned long value);
175 428 julius
static void eth_miim_trans (void *dat);
176 19 jeremybenn
/* ========================================================================= */
177
/*  TX LOGIC                                                                 */
178
/*---------------------------------------------------------------------------*/
179
 
180
/*
181
 * TX clock
182
 * Responsible for starting and finishing TX
183
 */
184
static void
185
eth_controller_tx_clock (void *dat)
186
{
187
  struct eth_device *eth = dat;
188
  int bAdvance = 1;
189
#if HAVE_ETH_PHY
190
  struct sockaddr_ll sll;
191
#endif /* HAVE_ETH_PHY */
192
  long nwritten = 0;
193
  unsigned long read_word;
194
 
195
  switch (eth->tx.state)
196
    {
197
    case ETH_TXSTATE_IDLE:
198
      eth->tx.state = ETH_TXSTATE_WAIT4BD;
199
      break;
200
    case ETH_TXSTATE_WAIT4BD:
201
      /* Read buffer descriptor */
202
      eth->tx.bd = eth->regs.bd_ram[eth->tx.bd_index];
203
      eth->tx.bd_addr = eth->regs.bd_ram[eth->tx.bd_index + 1];
204
 
205
      if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, READY))
206
        {
207
            /*****************/
208
          /* initialize TX */
209
          eth->tx.bytes_left = eth->tx.packet_length =
210
            GET_FIELD (eth->tx.bd, ETH_TX_BD, LENGTH);
211
          eth->tx.bytes_sent = 0;
212
 
213
          /*   Initialize error status bits */
214
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, DEFER);
215
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, COLLISION);
216
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, RETRANSMIT);
217
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, UNDERRUN);
218
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, NO_CARRIER);
219
          SET_FIELD (eth->tx.bd, ETH_TX_BD, RETRY, 0);
220
 
221
          /* Find out minimum length */
222
          if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, PAD) ||
223
              TEST_FLAG (eth->regs.moder, ETH_MODER, PAD))
224
            eth->tx.minimum_length =
225
              GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MINFL);
226
          else
227
            eth->tx.minimum_length = eth->tx.packet_length;
228
 
229
          /* Find out maximum length */
230
          if (TEST_FLAG (eth->regs.moder, ETH_MODER, HUGEN))
231
            eth->tx.maximum_length = eth->tx.packet_length;
232
          else
233
            eth->tx.maximum_length =
234
              GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MAXFL);
235
 
236
          /* Do we need CRC on this packet? */
237
          if (TEST_FLAG (eth->regs.moder, ETH_MODER, CRCEN) ||
238
              (TEST_FLAG (eth->tx.bd, ETH_TX_BD, CRC) &&
239
               TEST_FLAG (eth->tx.bd, ETH_TX_BD, LAST)))
240
            eth->tx.add_crc = 1;
241
          else
242
            eth->tx.add_crc = 0;
243
 
244
          if (TEST_FLAG (eth->regs.moder, ETH_MODER, DLYCRCEN))
245
            eth->tx.crc_dly = 1;
246
          else
247
            eth->tx.crc_dly = 0;
248
          /* XXX - For now we skip CRC calculation */
249
 
250
          if (eth->rtx_type == ETH_RTX_FILE)
251
            {
252
              /* write packet length to file */
253
              nwritten =
254
                write (eth->txfd, &(eth->tx.packet_length),
255
                       sizeof (eth->tx.packet_length));
256
            }
257
 
258
            /************************************************/
259
          /* start transmit with reading packet into FIFO */
260
          eth->tx.state = ETH_TXSTATE_READFIFO;
261
        }
262
 
263
      /* stay in this state if (TXEN && !READY) */
264
      break;
265
    case ETH_TXSTATE_READFIFO:
266
#if 1
267
      if (eth->tx.bytes_sent < eth->tx.packet_length)
268
        {
269
          read_word =
270
            eval_direct32 (eth->tx.bytes_sent + eth->tx.bd_addr, 0, 0);
271
          eth->tx_buff[eth->tx.bytes_sent] =
272
            (unsigned char) (read_word >> 24);
273
          eth->tx_buff[eth->tx.bytes_sent + 1] =
274
            (unsigned char) (read_word >> 16);
275
          eth->tx_buff[eth->tx.bytes_sent + 2] =
276
            (unsigned char) (read_word >> 8);
277
          eth->tx_buff[eth->tx.bytes_sent + 3] = (unsigned char) (read_word);
278
          eth->tx.bytes_sent += 4;
279
        }
280
#else
281
      if (eth->tx.bytes_sent < eth->tx.packet_length)
282
        {
283
          eth->tx_buff[eth->tx.bytes_sent] =
284
            eval_direct8 (eth->tx.bytes_sent + eth->tx.bd_addr, 0, 0);
285
          eth->tx.bytes_sent += 1;
286
        }
287
#endif
288
      else
289
        {
290
          eth->tx.state = ETH_TXSTATE_TRANSMIT;
291
        }
292
      break;
293
    case ETH_TXSTATE_TRANSMIT:
294
      /* send packet */
295
      switch (eth->rtx_type)
296
        {
297
        case ETH_RTX_FILE:
298
          nwritten = write (eth->txfd, eth->tx_buff, eth->tx.packet_length);
299
          break;
300
#if HAVE_ETH_PHY
301
        case ETH_RTX_SOCK:
302
          memset (&sll, 0, sizeof (sll));
303
          sll.sll_ifindex = eth->ifr.ifr_ifindex;
304
          nwritten =
305
            sendto (eth->rtx_sock, eth->tx_buff, eth->tx.packet_length, 0,
306
                    (struct sockaddr *) &sll, sizeof (sll));
307
#endif /* HAVE_ETH_PHY */
308
        }
309
 
310
      /* set BD status */
311
      if (nwritten == eth->tx.packet_length)
312
        {
313
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
314
          SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB);
315
 
316
          eth->tx.state = ETH_TXSTATE_WAIT4BD;
317
        }
318
      else
319
        {
320
          /* XXX - implement retry mechanism here! */
321
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
322
          CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, COLLISION);
323
          SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXE);
324
 
325
          eth->tx.state = ETH_TXSTATE_WAIT4BD;
326
        }
327
 
328
      eth->regs.bd_ram[eth->tx.bd_index] = eth->tx.bd;
329
 
330
      /* generate OK interrupt */
331
      if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXE_M) ||
332
          TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, TXB_M))
333
        {
334
          if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, IRQ))
335
            report_interrupt (eth->mac_int);
336
        }
337
 
338
      /* advance to next BD */
339
      if (bAdvance)
340
        {
341
          if (TEST_FLAG (eth->tx.bd, ETH_TX_BD, WRAP) ||
342
              eth->tx.bd_index >= ETH_BD_COUNT)
343
            eth->tx.bd_index = 0;
344
          else
345
            eth->tx.bd_index += 2;
346
        }
347
 
348
      break;
349
    }
350
 
351
  /* Reschedule */
352
  SCHED_ADD (eth_controller_tx_clock, dat, 1);
353
}
354
 
355
/* ========================================================================= */
356
 
357
 
358
/* ========================================================================= */
359
/*  RX LOGIC                                                                 */
360
/*---------------------------------------------------------------------------*/
361
 
362
/*
363
 * RX clock
364
 * Responsible for starting and finishing RX
365
 */
366
static void
367
eth_controller_rx_clock (void *dat)
368
{
369
  struct eth_device *eth = dat;
370
  long nread;
371
  unsigned long send_word;
372
 
373
 
374
  switch (eth->rx.state)
375
    {
376
    case ETH_RXSTATE_IDLE:
377
      eth->rx.state = ETH_RXSTATE_WAIT4BD;
378
      break;
379
 
380
    case ETH_RXSTATE_WAIT4BD:
381
      eth->rx.bd = eth->regs.bd_ram[eth->rx.bd_index];
382
      eth->rx.bd_addr = eth->regs.bd_ram[eth->rx.bd_index + 1];
383
 
384
      if (TEST_FLAG (eth->rx.bd, ETH_RX_BD, READY))
385
        {
386
            /*****************/
387
          /* Initialize RX */
388
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, MISS);
389
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, INVALID);
390
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, DRIBBLE);
391
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, UVERRUN);
392
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, COLLISION);
393
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, TOOBIG);
394
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
395
 
396
          /* Setup file to read from */
397
          if (TEST_FLAG (eth->regs.moder, ETH_MODER, LOOPBCK))
398
            {
399
              eth->rx.fd = eth->txfd;
400
              eth->rx.offset = &(eth->loopback_offset);
401
            }
402
          else
403
            {
404
              eth->rx.fd = eth->rxfd;
405
              eth->rx.offset = 0;
406
            }
407
          eth->rx.state = ETH_RXSTATE_RECV;
408
        }
409
      else if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN))
410
        {
411
          eth->rx.state = ETH_RXSTATE_IDLE;
412
        }
413
      else
414
        {
415
          nread =
416
            recv (eth->rtx_sock, eth->rx_buff, ETH_MAXPL, /*MSG_PEEK | */
417
                  MSG_DONTWAIT);
418
          if (nread > 0)
419
            {
420
              SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
421
              if (TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, BUSY_M))
422
                report_interrupt (eth->mac_int);
423
            }
424
        }
425
      break;
426
 
427
    case ETH_RXSTATE_RECV:
428
      switch (eth->rtx_type)
429
        {
430
        case ETH_RTX_FILE:
431
          /* Read packet length */
432
          if (eth_read_rx_file
433
              (eth, &(eth->rx.packet_length),
434
               sizeof (eth->rx.packet_length)) <
435
              sizeof (eth->rx.packet_length))
436
            {
437
              /* TODO: just do what real ethernet would do (some kind of error state) */
438
              sim_done ();
439
              break;
440
            }
441
 
442
          /* Packet must be big enough to hold a header */
443
          if (eth->rx.packet_length < ETHER_HDR_LEN)
444
            {
445
              eth_rx_next_packet (eth);
446
 
447
              eth->rx.state = ETH_RXSTATE_WAIT4BD;
448
              break;
449
            }
450
 
451
          eth->rx.bytes_read = 0;
452
          eth->rx.bytes_left = eth->rx.packet_length;
453
 
454
          /* for now Read entire packet into memory */
455
          nread = eth_read_rx_file (eth, eth->rx_buff, eth->rx.bytes_left);
456
          if (nread < eth->rx.bytes_left)
457
            {
458
              eth->rx.error = 1;
459
              break;
460
            }
461
 
462
          eth->rx.packet_length = nread;
463
          eth->rx.bytes_left = nread;
464
          eth->rx.bytes_read = 0;
465
 
466
          eth->rx.state = ETH_RXSTATE_WRITEFIFO;
467
 
468
          break;
469
 
470
        case ETH_RTX_SOCK:
471
          nread = recv (eth->rtx_sock, eth->rx_buff, ETH_MAXPL, MSG_DONTWAIT);
472
 
473
          if (nread == 0)
474
            {
475
              break;
476
            }
477
          else if (nread < 0)
478
            {
479
              if (errno != EAGAIN)
480
                {
481
                  break;
482
                }
483
              else
484
                break;
485
            }
486
          /* If not promiscouos mode, check the destination address */
487
          if (!TEST_FLAG (eth->regs.moder, ETH_MODER, PRO))
488
            {
489
              if (TEST_FLAG (eth->regs.moder, ETH_MODER, IAM)
490
                  && (eth->rx_buff[0] & 1))
491
                {
492
                  /* Nothing for now */
493
                }
494
 
495
              if (eth->mac_address[5] != eth->rx_buff[0] ||
496
                  eth->mac_address[4] != eth->rx_buff[1] ||
497
                  eth->mac_address[3] != eth->rx_buff[2] ||
498
                  eth->mac_address[2] != eth->rx_buff[3] ||
499
                  eth->mac_address[1] != eth->rx_buff[4] ||
500
                  eth->mac_address[0] != eth->rx_buff[5])
501
                break;
502
            }
503
 
504
          eth->rx.packet_length = nread;
505
          eth->rx.bytes_left = nread;
506
          eth->rx.bytes_read = 0;
507
 
508
          eth->rx.state = ETH_RXSTATE_WRITEFIFO;
509
 
510
          break;
511
        case ETH_RTX_VAPI:
512
          break;
513
        }
514
      break;
515
 
516
    case ETH_RXSTATE_WRITEFIFO:
517
#if 1
518
      send_word = ((unsigned long) eth->rx_buff[eth->rx.bytes_read] << 24) |
519
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 1] << 16) |
520
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 2] << 8) |
521
        ((unsigned long) eth->rx_buff[eth->rx.bytes_read + 3]);
522
      set_direct32 (eth->rx.bd_addr + eth->rx.bytes_read, send_word, 0, 0);
523
      /* update counters */
524
      eth->rx.bytes_left -= 4;
525
      eth->rx.bytes_read += 4;
526
#else
527
      set_direct8 (eth->rx.bd_addr + eth->rx.bytes_read,
528
                   eth->rx_buff[eth->rx.bytes_read], 0, 0);
529
      eth->rx.bytes_left -= 1;
530
      eth->rx.bytes_read += 1;
531
#endif
532
 
533
      if (eth->rx.bytes_left <= 0)
534
        {
535
          /* Write result to bd */
536
          SET_FIELD (eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length);
537
          CLEAR_FLAG (eth->rx.bd, ETH_RX_BD, READY);
538
          SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, RXB);
539
 
540
          if (eth->rx.packet_length <
541
              (GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MINFL) - 4))
542
            SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOSHORT);
543
          if (eth->rx.packet_length >
544
              GET_FIELD (eth->regs.packetlen, ETH_PACKETLEN, MAXFL))
545
            SET_FLAG (eth->rx.bd, ETH_RX_BD, TOOBIG);
546
 
547
          eth->regs.bd_ram[eth->rx.bd_index] = eth->rx.bd;
548
 
549
          /* advance to next BD */
550
          if (TEST_FLAG (eth->rx.bd, ETH_RX_BD, WRAP)
551
              || eth->rx.bd_index >= ETH_BD_COUNT)
552
            eth->rx.bd_index = eth->regs.tx_bd_num << 1;
553
          else
554
            eth->rx.bd_index += 2;
555
 
556
          if ((TEST_FLAG (eth->regs.int_mask, ETH_INT_MASK, RXB_M)) &&
557
              (TEST_FLAG (eth->rx.bd, ETH_RX_BD, IRQ)))
558
            {
559
              report_interrupt (eth->mac_int);
560
            }
561
 
562
          /* ready to receive next packet */
563
          eth->rx.state = ETH_RXSTATE_IDLE;
564
        }
565
      break;
566
    }
567
 
568
  /* Reschedule */
569
  SCHED_ADD (eth_controller_rx_clock, dat, 1);
570
}
571
 
572
/* ========================================================================= */
573
/* Move to next RX BD */
574
static void
575
eth_rx_next_packet (struct eth_device *eth)
576
{
577
  /* Skip any possible leftovers */
578
  if (eth->rx.bytes_left)
579
    eth_skip_rx_file (eth, eth->rx.bytes_left);
580
}
581
 
582
/* "Skip" bytes in RX file */
583
static void
584
eth_skip_rx_file (struct eth_device *eth, off_t count)
585
{
586
  eth->rx.offset += count;
587
}
588
 
589
/*
590
 * Utility function to read from the ethernet RX file
591
 * This function moves the file pointer to the current place in the packet before reading
592
 */
593
static ssize_t
594
eth_read_rx_file (struct eth_device *eth, void *buf, size_t count)
595
{
596
  ssize_t result;
597
 
598
  if (eth->rx.fd <= 0)
599
    {
600
      return 0;
601
    }
602
 
603
  if (eth->rx.offset)
604
    if (lseek (eth->rx.fd, *(eth->rx.offset), SEEK_SET) == (off_t) - 1)
605
      {
606
        return 0;
607
      }
608
 
609
  result = read (eth->rx.fd, buf, count);
610
  if (eth->rx.offset && result >= 0)
611
    *(eth->rx.offset) += result;
612
 
613
  return result;
614
}
615
 
616
/* ========================================================================= */
617
 
618
/*
619
  Reset. Initializes all registers to default and places devices in
620
         memory address space.
621
*/
622
static void
623
eth_reset (void *dat)
624
{
625
  struct eth_device *eth = dat;
626
#if HAVE_ETH_PHY
627
  int j;
628
  struct sockaddr_ll sll;
629
#endif /* HAVE_ETH_PHY */
630
 
631
  if (eth->baseaddr != 0)
632
    {
633
      switch (eth->rtx_type)
634
        {
635
        case ETH_RTX_FILE:
636
          /* (Re-)open TX/RX files */
637
          if (eth->rxfd > 0)
638
            close (eth->rxfd);
639
          if (eth->txfd > 0)
640
            close (eth->txfd);
641
          eth->rxfd = eth->txfd = -1;
642
 
643
          if ((eth->rxfd = open (eth->rxfile, O_RDONLY)) < 0)
644
            fprintf (stderr, "Cannot open Ethernet RX file \"%s\"\n",
645
                     eth->rxfile);
646
          if ((eth->txfd = open (eth->txfile, O_RDWR | O_CREAT | O_APPEND
647
#if defined(O_SYNC)             /* BSD / Mac OS X manual doesn't know about O_SYNC */
648
                                 | O_SYNC
649
#endif
650
                                 ,
651
                                 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0)
652
            fprintf (stderr, "Cannot open Ethernet TX file \"%s\"\n",
653
                     eth->txfile);
654
          eth->loopback_offset = lseek (eth->txfd, 0, SEEK_END);
655
 
656
          break;
657
#if HAVE_ETH_PHY
658
        case ETH_RTX_SOCK:
659
          /* (Re-)open TX/RX sockets */
660
          if (eth->rtx_sock != 0)
661
            break;
662
 
663
          eth->rtx_sock = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL));
664
          if (eth->rtx_sock == -1)
665
            {
666
              fprintf (stderr, "Cannot open rtx_sock.\n");
667
              return;
668
            }
669
 
670
          /* get interface index number */
671
          memset (&(eth->ifr), 0, sizeof (eth->ifr));
672
          strncpy (eth->ifr.ifr_name, eth->sockif, IFNAMSIZ);
673
          if (ioctl (eth->rtx_sock, SIOCGIFINDEX, &(eth->ifr)) == -1)
674
            {
675
              fprintf (stderr, "SIOCGIFINDEX failed!\n");
676
              return;
677
            }
678
 
679
          /* Bind to interface... */
680
          memset (&sll, 0xff, sizeof (sll));
681
          sll.sll_family = AF_PACKET;   /* allways AF_PACKET */
682
          sll.sll_protocol = htons (ETH_P_ALL);
683
          sll.sll_ifindex = eth->ifr.ifr_ifindex;
684
          if (bind (eth->rtx_sock, (struct sockaddr *) &sll, sizeof (sll)) ==
685
              -1)
686
            {
687
              fprintf (stderr, "Error bind().\n");
688
              return;
689
            }
690
 
691
          /* first, flush all received packets. */
692
          do
693
            {
694
              fd_set fds;
695
              struct timeval t;
696
 
697
              FD_ZERO (&fds);
698
              FD_SET (eth->rtx_sock, &fds);
699
              memset (&t, 0, sizeof (t));
700
              j = select (FD_SETSIZE, &fds, NULL, NULL, &t);
701
              if (j > 0)
702
                recv (eth->rtx_sock, eth->rx_buff, j, 0);
703
            }
704
          while (j);
705
 
706
          break;
707
#else /* HAVE_ETH_PHY */
708
        case ETH_RTX_SOCK:
709
          fprintf (stderr,
710
                   "Ethernet phy not enabled in this configuration.  Configure with --enable-ethphy.\n");
711
          exit (1);
712
          break;
713
#endif /* HAVE_ETH_PHY */
714
        }
715
 
716
      /* Set registers to default values */
717 428 julius
      /* Zero all registers */
718 19 jeremybenn
      memset (&(eth->regs), 0, sizeof (eth->regs));
719 428 julius
      /* Set those with non-zero reset defaults */
720 19 jeremybenn
      eth->regs.moder = 0x0000A000;
721
      eth->regs.ipgt = 0x00000012;
722
      eth->regs.ipgr1 = 0x0000000C;
723
      eth->regs.ipgr2 = 0x00000012;
724
      eth->regs.packetlen = 0x003C0600;
725
      eth->regs.collconf = 0x000F003F;
726
      eth->regs.miimoder = 0x00000064;
727
      eth->regs.tx_bd_num = 0x00000040;
728
 
729
      /* Initialize TX/RX status */
730
      memset (&(eth->tx), 0, sizeof (eth->tx));
731
      memset (&(eth->rx), 0, sizeof (eth->rx));
732
      eth->rx.bd_index = eth->regs.tx_bd_num << 1;
733
 
734
      /* Initialize VAPI */
735
      if (eth->base_vapi_id)
736
        {
737
          vapi_install_multi_handler (eth->base_vapi_id, ETH_NUM_VAPI_IDS,
738
                                      eth_vapi_read, dat);
739
        }
740 428 julius
 
741 19 jeremybenn
    }
742
}
743
 
744
/* ========================================================================= */
745
 
746
 
747
/*
748
  Print register values on stdout
749
*/
750
static void
751
eth_status (void *dat)
752
{
753
  struct eth_device *eth = dat;
754
 
755
  PRINTF ("\nEthernet MAC at 0x%" PRIxADDR ":\n", eth->baseaddr);
756
  PRINTF ("MODER        : 0x%08lX\n", eth->regs.moder);
757
  PRINTF ("INT_SOURCE   : 0x%08lX\n", eth->regs.int_source);
758
  PRINTF ("INT_MASK     : 0x%08lX\n", eth->regs.int_mask);
759
  PRINTF ("IPGT         : 0x%08lX\n", eth->regs.ipgt);
760
  PRINTF ("IPGR1        : 0x%08lX\n", eth->regs.ipgr1);
761
  PRINTF ("IPGR2        : 0x%08lX\n", eth->regs.ipgr2);
762
  PRINTF ("PACKETLEN    : 0x%08lX\n", eth->regs.packetlen);
763
  PRINTF ("COLLCONF     : 0x%08lX\n", eth->regs.collconf);
764
  PRINTF ("TX_BD_NUM    : 0x%08lX\n", eth->regs.tx_bd_num);
765
  PRINTF ("CTRLMODER    : 0x%08lX\n", eth->regs.controlmoder);
766
  PRINTF ("MIIMODER     : 0x%08lX\n", eth->regs.miimoder);
767
  PRINTF ("MIICOMMAND   : 0x%08lX\n", eth->regs.miicommand);
768
  PRINTF ("MIIADDRESS   : 0x%08lX\n", eth->regs.miiaddress);
769
  PRINTF ("MIITX_DATA   : 0x%08lX\n", eth->regs.miitx_data);
770
  PRINTF ("MIIRX_DATA   : 0x%08lX\n", eth->regs.miirx_data);
771
  PRINTF ("MIISTATUS    : 0x%08lX\n", eth->regs.miistatus);
772
  PRINTF ("MAC Address  : %02X:%02X:%02X:%02X:%02X:%02X\n",
773
          eth->mac_address[0], eth->mac_address[1], eth->mac_address[2],
774
          eth->mac_address[3], eth->mac_address[4], eth->mac_address[5]);
775
  PRINTF ("HASH0        : 0x%08lX\n", eth->regs.hash0);
776
  PRINTF ("HASH1        : 0x%08lX\n", eth->regs.hash1);
777
}
778
 
779
/* ========================================================================= */
780
 
781
 
782
/*
783
  Read a register
784
*/
785
static uint32_t
786
eth_read32 (oraddr_t addr, void *dat)
787
{
788
  struct eth_device *eth = dat;
789
 
790
  switch (addr)
791
    {
792
    case ETH_MODER:
793
      return eth->regs.moder;
794
    case ETH_INT_SOURCE:
795
      return eth->regs.int_source;
796
    case ETH_INT_MASK:
797
      return eth->regs.int_mask;
798
    case ETH_IPGT:
799
      return eth->regs.ipgt;
800
    case ETH_IPGR1:
801
      return eth->regs.ipgr1;
802
    case ETH_IPGR2:
803
      return eth->regs.ipgr2;
804
    case ETH_PACKETLEN:
805
      return eth->regs.packetlen;
806
    case ETH_COLLCONF:
807
      return eth->regs.collconf;
808
    case ETH_TX_BD_NUM:
809
      return eth->regs.tx_bd_num;
810
    case ETH_CTRLMODER:
811
      return eth->regs.controlmoder;
812
    case ETH_MIIMODER:
813
      return eth->regs.miimoder;
814
    case ETH_MIICOMMAND:
815
      return eth->regs.miicommand;
816
    case ETH_MIIADDRESS:
817
      return eth->regs.miiaddress;
818
    case ETH_MIITX_DATA:
819
      return eth->regs.miitx_data;
820
    case ETH_MIIRX_DATA:
821 428 julius
      /*printf("or1ksim: read MIIM RX: 0x%x\n",(int)eth->regs.miirx_data);*/
822 19 jeremybenn
      return eth->regs.miirx_data;
823
    case ETH_MIISTATUS:
824
      return eth->regs.miistatus;
825
    case ETH_MAC_ADDR0:
826
      return (((unsigned long) eth->mac_address[3]) << 24) |
827
        (((unsigned long) eth->mac_address[2]) << 16) |
828
        (((unsigned long) eth->mac_address[1]) << 8) |
829
        (unsigned long) eth->mac_address[0];
830
    case ETH_MAC_ADDR1:
831
      return (((unsigned long) eth->mac_address[5]) << 8) |
832
        (unsigned long) eth->mac_address[4];
833
    case ETH_HASH0:
834
      return eth->regs.hash0;
835
    case ETH_HASH1:
836
      return eth->regs.hash1;
837
      /*case ETH_DMA_RX_TX: return eth_rx( eth ); */
838
    }
839
 
840
  if ((addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE))
841
    return eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4];
842
 
843
  PRINTF ("eth_read32( 0x%" PRIxADDR " ): Illegal address\n",
844
          addr + eth->baseaddr);
845
  return 0;
846
}
847
 
848
/* ========================================================================= */
849
 
850
 
851
/*
852
  Write a register
853
*/
854
static void
855
eth_write32 (oraddr_t addr, uint32_t value, void *dat)
856
{
857
  struct eth_device *eth = dat;
858
 
859
  switch (addr)
860
    {
861
    case ETH_MODER:
862
 
863
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, RXEN) &&
864
          TEST_FLAG (value, ETH_MODER, RXEN))
865
        SCHED_ADD (eth_controller_rx_clock, dat, 1);
866
      else if (!TEST_FLAG (value, ETH_MODER, RXEN))
867
        SCHED_FIND_REMOVE (eth_controller_rx_clock, dat);
868
 
869
      if (!TEST_FLAG (eth->regs.moder, ETH_MODER, TXEN) &&
870
          TEST_FLAG (value, ETH_MODER, TXEN))
871
        SCHED_ADD (eth_controller_tx_clock, dat, 1);
872
      else if (!TEST_FLAG (value, ETH_MODER, TXEN))
873
        SCHED_FIND_REMOVE (eth_controller_tx_clock, dat);
874
 
875
      eth->regs.moder = value;
876
 
877
      if (TEST_FLAG (value, ETH_MODER, RST))
878
        eth_reset (dat);
879
      return;
880
    case ETH_INT_SOURCE:
881
      if (!(eth->regs.int_source & ~value) && eth->regs.int_source)
882
        clear_interrupt (eth->mac_int);
883
      eth->regs.int_source &= ~value;
884
      return;
885
    case ETH_INT_MASK:
886
      eth->regs.int_mask = value;
887
      return;
888
    case ETH_IPGT:
889
      eth->regs.ipgt = value;
890
      return;
891
    case ETH_IPGR1:
892
      eth->regs.ipgr1 = value;
893
      return;
894
    case ETH_IPGR2:
895
      eth->regs.ipgr2 = value;
896
      return;
897
    case ETH_PACKETLEN:
898
      eth->regs.packetlen = value;
899
      return;
900
    case ETH_COLLCONF:
901
      eth->regs.collconf = value;
902
      return;
903
    case ETH_TX_BD_NUM:
904
      eth_write_tx_bd_num (eth, value);
905
      return;
906
    case ETH_CTRLMODER:
907
      eth->regs.controlmoder = value;
908
      return;
909
    case ETH_MIIMODER:
910
      eth->regs.miimoder = value;
911
      return;
912
    case ETH_MIICOMMAND:
913
      eth->regs.miicommand = value;
914 428 julius
      /* Perform MIIM transaction, if required */
915
      eth_miim_trans(dat);
916 19 jeremybenn
      return;
917
    case ETH_MIIADDRESS:
918
      eth->regs.miiaddress = value;
919
      return;
920
    case ETH_MIITX_DATA:
921
      eth->regs.miitx_data = value;
922
      return;
923
    case ETH_MIIRX_DATA:
924 428 julius
      /* Register is R/O
925 19 jeremybenn
      eth->regs.miirx_data = value;
926 428 julius
      */
927 19 jeremybenn
      return;
928
    case ETH_MIISTATUS:
929 428 julius
      /* Register is R/O
930 19 jeremybenn
      eth->regs.miistatus = value;
931 428 julius
      */
932 19 jeremybenn
      return;
933 428 julius
 
934 19 jeremybenn
    case ETH_MAC_ADDR0:
935
      eth->mac_address[0] = value & 0xFF;
936
      eth->mac_address[1] = (value >> 8) & 0xFF;
937
      eth->mac_address[2] = (value >> 16) & 0xFF;
938
      eth->mac_address[3] = (value >> 24) & 0xFF;
939
      return;
940
    case ETH_MAC_ADDR1:
941
      eth->mac_address[4] = value & 0xFF;
942
      eth->mac_address[5] = (value >> 8) & 0xFF;
943
      return;
944
    case ETH_HASH0:
945
      eth->regs.hash0 = value;
946
      return;
947
    case ETH_HASH1:
948
      eth->regs.hash1 = value;
949
      return;
950
 
951
      /*case ETH_DMA_RX_TX: eth_tx( eth, value ); return; */
952
    }
953
 
954
  if ((addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE))
955
    {
956
      eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4] = value;
957
      return;
958
    }
959
 
960
  PRINTF ("eth_write32( 0x%" PRIxADDR " ): Illegal address\n",
961
          addr + eth->baseaddr);
962
  return;
963
}
964
 
965
/* ========================================================================= */
966
 
967
 
968
/*
969
 *   VAPI connection to outside
970
 */
971
static void
972
eth_vapi_read (unsigned long id, unsigned long data, void *dat)
973
{
974
  unsigned long which;
975
  struct eth_device *eth = dat;
976
 
977
  which = id - eth->base_vapi_id;
978
 
979
  if (!eth)
980
    {
981
      return;
982
    }
983
 
984
  switch (which)
985
    {
986
    case ETH_VAPI_DATA:
987
      break;
988
    case ETH_VAPI_CTRL:
989
      break;
990
    }
991
}
992
 
993
/* ========================================================================= */
994
 
995
 
996
/* When TX_BD_NUM is written, also reset current RX BD index */
997
static void
998
eth_write_tx_bd_num (struct eth_device *eth, unsigned long value)
999
{
1000
  eth->regs.tx_bd_num = value & 0xFF;
1001
  eth->rx.bd_index = eth->regs.tx_bd_num << 1;
1002
}
1003
 
1004
/* ========================================================================= */
1005
 
1006
/*-----------------------------------------------[ Ethernet configuration ]---*/
1007
 
1008
 
1009
/*---------------------------------------------------------------------------*/
1010
/*!Enable or disable the Ethernet interface
1011
 
1012
   @param[in] val  The value to use
1013
   @param[in] dat  The config data structure                                 */
1014
/*---------------------------------------------------------------------------*/
1015
static void
1016
eth_enabled (union param_val  val,
1017
             void            *dat)
1018
{
1019
  struct eth_device *eth = dat;
1020
 
1021
  eth->enabled = val.int_val;
1022
 
1023
}       /* eth_enabled() */
1024
 
1025
 
1026
/*---------------------------------------------------------------------------*/
1027
/*!Set the Ethernet interface base address
1028
 
1029
   @param[in] val  The value to use
1030
   @param[in] dat  The config data structure                                 */
1031
/*---------------------------------------------------------------------------*/
1032
static void
1033
eth_baseaddr (union param_val  val,
1034
              void            *dat)
1035
{
1036
  struct eth_device *eth = dat;
1037
 
1038
  eth->baseaddr = val.addr_val;
1039
 
1040
}       /* eth_baseaddr() */
1041
 
1042
 
1043
/*---------------------------------------------------------------------------*/
1044
/*!Set the Ethernet DMA port
1045
 
1046
   This is not currently supported, so a warning message is printed.
1047
 
1048
   @param[in] val  The value to use
1049
   @param[in] dat  The config data structure                                 */
1050
/*---------------------------------------------------------------------------*/
1051
static void
1052
eth_dma (union param_val  val,
1053
         void            *dat)
1054
{
1055
  struct eth_device *eth = dat;
1056
 
1057
  fprintf (stderr, "Warning: External Ethernet DMA not currently supported\n");
1058
  eth->dma = val.addr_val;
1059
 
1060
}       /* eth_dma() */
1061
 
1062
 
1063
/*---------------------------------------------------------------------------*/
1064
/*!Set the Ethernet IRQ
1065
 
1066
   @param[in] val  The value to use
1067
   @param[in] dat  The config data structure                                 */
1068
/*---------------------------------------------------------------------------*/
1069
static void
1070
eth_irq (union param_val  val,
1071
         void            *dat)
1072
{
1073
  struct eth_device *eth = dat;
1074
 
1075
  eth->mac_int = val.int_val;
1076
 
1077
}       /* eth_irq() */
1078
 
1079
 
1080
/*---------------------------------------------------------------------------*/
1081
/*!Set the Ethernet interface type
1082
 
1083
   Currently two types are supported, file and socket. Use of the socket
1084
   requires a compile time option.
1085
 
1086
   @param[in] val  The value to use. 0 for file, 1 for socket.
1087
   @param[in] dat  The config data structure                                 */
1088
/*---------------------------------------------------------------------------*/
1089
static void
1090
eth_rtx_type (union param_val  val,
1091
              void            *dat)
1092
{
1093
  struct eth_device *eth = dat;
1094
 
1095
  if (val.int_val)
1096
    {
1097
#ifndef HAVE_ETH_PHY
1098
      fprintf (stderr, "Warning: Ethernet PHY socket not enabled in this "
1099
               "configuration (configure with --enable-ethphy): ignored\n");
1100
      return;
1101
#endif
1102
    }
1103
 
1104
  eth->rtx_type = val.int_val;
1105
 
1106
}       /* eth_rtx_type() */
1107
 
1108
 
1109
/*---------------------------------------------------------------------------*/
1110
/*!Set the Ethernet DMA Rx channel
1111
 
1112
   External DMA is not currently supported, so a warning message is printed.
1113
 
1114
   @param[in] val  The value to use
1115
   @param[in] dat  The config data structure                                 */
1116
/*---------------------------------------------------------------------------*/
1117
static void
1118
eth_rx_channel (union param_val  val,
1119
                void            *dat)
1120
{
1121
  struct eth_device *eth = dat;
1122
 
1123
  fprintf (stderr, "Warning: External Ethernet DMA not currently supported: "
1124
           "Rx channel ignored\n");
1125
  eth->rx_channel = val.int_val;
1126
 
1127
}       /* eth_rx_channel() */
1128
 
1129
 
1130
/*---------------------------------------------------------------------------*/
1131
/*!Set the Ethernet DMA Tx channel
1132
 
1133
   External DMA is not currently supported, so a warning message is printed.
1134
 
1135
   @param[in] val  The value to use
1136
   @param[in] dat  The config data structure                                 */
1137
/*---------------------------------------------------------------------------*/
1138
static void
1139
eth_tx_channel (union param_val  val,
1140
                void            *dat)
1141
{
1142
  struct eth_device *eth = dat;
1143
 
1144
  fprintf (stderr, "Warning: External Ethernet DMA not currently supported: "
1145
           "Tx channel ignored\n");
1146
  eth->tx_channel = val.int_val;
1147
 
1148
}       /* eth_tx_channel() */
1149
 
1150
 
1151
/*---------------------------------------------------------------------------*/
1152
/*!Set the Ethernet DMA Rx file
1153
 
1154
   Free any previously allocated value.
1155
 
1156
   @param[in] val  The value to use
1157
   @param[in] dat  The config data structure                                 */
1158
/*---------------------------------------------------------------------------*/
1159
static void
1160
eth_rxfile (union param_val  val,
1161
            void            *dat)
1162
{
1163
  struct eth_device *eth = dat;
1164
 
1165
  if (NULL != eth->rxfile)
1166
    {
1167
      free (eth->rxfile);
1168
      eth->rxfile = NULL;
1169
    }
1170
 
1171
  if (!(eth->rxfile = strdup (val.str_val)))
1172
    {
1173
      fprintf (stderr, "Peripheral Ethernet: Run out of memory\n");
1174
      exit (-1);
1175
    }
1176
}       /* eth_rxfile() */
1177
 
1178
 
1179
/*---------------------------------------------------------------------------*/
1180
/*!Set the Ethernet DMA Tx file
1181
 
1182
   Free any previously allocated value.
1183
 
1184
   @param[in] val  The value to use
1185
   @param[in] dat  The config data structure                                 */
1186
/*---------------------------------------------------------------------------*/
1187
static void
1188
eth_txfile (union param_val  val,
1189
            void            *dat)
1190
{
1191
  struct eth_device *eth = dat;
1192
 
1193
  if (NULL != eth->txfile)
1194
    {
1195
      free (eth->txfile);
1196
      eth->txfile = NULL;
1197
    }
1198
 
1199
  if (!(eth->txfile = strdup (val.str_val)))
1200
    {
1201
      fprintf (stderr, "Peripheral Ethernet: Run out of memory\n");
1202
      exit (-1);
1203
    }
1204
}       /* eth_txfile() */
1205
 
1206
 
1207
/*---------------------------------------------------------------------------*/
1208
/*!Set the Ethernet socket interface
1209
 
1210
   Free any previously allocated value. This is only meaningful if the socket
1211
   interface is configured.
1212
 
1213
   @param[in] val  The value to use
1214
   @param[in] dat  The config data structure                                 */
1215
/*---------------------------------------------------------------------------*/
1216
static void
1217
eth_sockif (union param_val  val,
1218
            void            *dat)
1219
{
1220
  struct eth_device *eth = dat;
1221
 
1222
#ifndef HAVE_ETH_PHY
1223
  fprintf (stderr, "Warning: Ethernet PHY socket not enabled in this "
1224
           "configuration (configure with --enable-ethphy): "
1225
           "sockif ignored\n");
1226
  return;
1227
#endif
1228
 
1229
  if (NULL != eth->sockif)
1230
    {
1231
      free (eth->sockif);
1232
      eth->sockif = NULL;
1233
    }
1234
 
1235
  if (!(eth->sockif = strdup (val.str_val)))
1236
    {
1237
      fprintf (stderr, "Peripheral Ethernet: Run out of memory\n");
1238
      exit (-1);
1239
    }
1240
}       /* eth_sockif() */
1241
 
1242
 
1243
static void
1244
eth_vapi_id (union param_val  val,
1245
             void            *dat)
1246
{
1247
  struct eth_device *eth = dat;
1248
  eth->base_vapi_id = val.int_val;
1249
}
1250
 
1251 428 julius
 
1252
static void
1253
eth_phy_addr (union param_val  val,
1254
              void            *dat)
1255
{
1256
  struct eth_device *eth = dat;
1257
  eth->phy_addr = val.int_val & ETH_MIIADDR_FIAD_MASK;
1258
}
1259
 
1260
 
1261 19 jeremybenn
/*---------------------------------------------------------------------------*/
1262 428 julius
/*!Emulate MIIM transaction to ethernet PHY
1263
 
1264
   @param[in] dat  The config data structure                                 */
1265
/*---------------------------------------------------------------------------*/
1266
static void
1267
eth_miim_trans (void *dat)
1268
{
1269
  struct eth_device *eth = dat;
1270
  switch (eth->regs.miicommand)
1271
    {
1272
    case ((1 << ETH_MIICOMM_WCDATA_OFFSET)):
1273
      /* Perhaps something to emulate here later, but for now do nothing */
1274
      break;
1275
 
1276
    case ((1 << ETH_MIICOMM_RSTAT_OFFSET)):
1277
 
1278
      printf("or1ksim: eth_miim_trans: phy %d\n",(int)
1279
             ((eth->regs.miiaddress >> ETH_MIIADDR_FIAD_OFFSET)&
1280
              ETH_MIIADDR_FIAD_MASK));
1281
      printf("or1ksim: eth_miim_trans: reg %d\n",(int)
1282
             ((eth->regs.miiaddress >> ETH_MIIADDR_RGAD_OFFSET)&
1283
              ETH_MIIADDR_RGAD_MASK));
1284
 
1285
      /*First check if it's the correct PHY to address */
1286
      if (((eth->regs.miiaddress >> ETH_MIIADDR_FIAD_OFFSET)&
1287
           ETH_MIIADDR_FIAD_MASK) == eth->phy_addr)
1288
        {
1289
          /* Correct PHY - now switch based on the register address in the PHY*/
1290
          switch ((eth->regs.miiaddress >> ETH_MIIADDR_RGAD_OFFSET)&
1291
                  ETH_MIIADDR_RGAD_MASK)
1292
            {
1293
            case MII_BMCR:
1294
              eth->regs.miirx_data = BMCR_FULLDPLX;
1295
              break;
1296
            case MII_BMSR:
1297
              eth->regs.miirx_data = BMSR_LSTATUS | BMSR_ANEGCOMPLETE |
1298
                BMSR_10HALF | BMSR_10FULL | BMSR_100HALF | BMSR_100FULL;
1299
              break;
1300
            case MII_PHYSID1:
1301
              eth->regs.miirx_data = 0x22; /* Micrel PHYID */
1302
              break;
1303
            case MII_PHYSID2:
1304
              eth->regs.miirx_data = 0x1613; /* Micrel PHYID */
1305
              break;
1306
            case MII_ADVERTISE:
1307
              eth->regs.miirx_data = 0;
1308
              break;
1309
            case MII_LPA:
1310
              eth->regs.miirx_data = LPA_DUPLEX | LPA_100;
1311
              break;
1312
            case MII_EXPANSION:
1313
              eth->regs.miirx_data = 0;
1314
              break;
1315
            case MII_CTRL1000:
1316
              eth->regs.miirx_data = 0;
1317
              break;
1318
            case MII_STAT1000:
1319
              eth->regs.miirx_data = 0;
1320
              break;
1321
            case MII_ESTATUS:
1322
              eth->regs.miirx_data = 0;
1323
              break;
1324
            case MII_DCOUNTER:
1325
              eth->regs.miirx_data = 0;
1326
              break;
1327
            case MII_FCSCOUNTER:
1328
              eth->regs.miirx_data = 0;
1329
              break;
1330
            case MII_NWAYTEST:
1331
              eth->regs.miirx_data = 0;
1332
              break;
1333
            case MII_RERRCOUNTER:
1334
              eth->regs.miirx_data = 0;
1335
              break;
1336
            case MII_SREVISION:
1337
              eth->regs.miirx_data = 0;
1338
              break;
1339
            case MII_RESV1:
1340
              eth->regs.miirx_data = 0;
1341
              break;
1342
            case MII_LBRERROR:
1343
              eth->regs.miirx_data = 0;
1344
              break;
1345
            case MII_PHYADDR:
1346
              eth->regs.miirx_data = eth->phy_addr;
1347
              break;
1348
            case MII_RESV2:
1349
              eth->regs.miirx_data = 0;
1350
              break;
1351
            case MII_TPISTATUS:
1352
              eth->regs.miirx_data = 0;
1353
              break;
1354
            case MII_NCONFIG:
1355
              eth->regs.miirx_data = 0;
1356
              break;
1357
            default:
1358
              eth->regs.miirx_data = 0xffff;
1359
              break;
1360
            }
1361
        }
1362
      else
1363
        eth->regs.miirx_data = 0xffff; /* PHY doesn't exist, read all 1's */
1364
      break;
1365
 
1366
    case ((1 << ETH_MIICOMM_SCANS_OFFSET)):
1367
      /* From MAC's datasheet:
1368
         A host initiates the Scan Status Operation by asserting the SCANSTAT
1369
         signal. The MIIM performs a continuous read operation of the PHY
1370
         Status register. The PHY is selected by the FIAD[4:0] signals. The
1371
         link status LinkFail signal is asserted/deasserted by the MIIM module
1372
         and reflects the link status bit of the PHY Status register. The
1373
         signal NVALID is used for qualifying the validity of the LinkFail
1374
         signals and the status data PRSD[15:0]. These signals are invalid
1375
         until the first scan status operation ends. During the scan status
1376
         operation, the BUSY signal is asserted until the last read is
1377
         performed (the scan status operation is stopped).
1378
 
1379
         So for now - do nothing, leave link status indicator as permanently
1380
         with link.
1381
      */
1382
 
1383
      break;
1384
 
1385
    default:
1386
      break;
1387
    }
1388
 
1389
}
1390
 
1391
/*---------------------------------------------------------------------------*/
1392 19 jeremybenn
/*!Initialize a new Ethernet configuration
1393
 
1394
   ALL parameters are set explicitly to default values.                      */
1395
/*---------------------------------------------------------------------------*/
1396
static void *
1397
eth_sec_start (void)
1398
{
1399
  struct eth_device *new = malloc (sizeof (struct eth_device));
1400
 
1401
  if (!new)
1402
    {
1403
      fprintf (stderr, "Peripheral Eth: Run out of memory\n");
1404
      exit (-1);
1405
    }
1406
 
1407
  memset (new, 0, sizeof (struct eth_device));
1408
 
1409
  new->enabled      = 1;
1410
  new->baseaddr     = 0;
1411
  new->dma          = 0;
1412
  new->mac_int      = 0;
1413
  new->rtx_type     = 0;
1414
  new->rx_channel   = 0;
1415
  new->tx_channel   = 0;
1416
  new->rxfile       = strdup ("eth_rx");
1417
  new->txfile       = strdup ("eth_tx");
1418
  new->sockif       = strdup ("or1ksim_eth");
1419
  new->base_vapi_id = 0;
1420 428 julius
  new->phy_addr     = 0;
1421 19 jeremybenn
 
1422
  return new;
1423
}
1424
 
1425
static void
1426
eth_sec_end (void *dat)
1427
{
1428
  struct eth_device *eth = dat;
1429
  struct mem_ops ops;
1430
 
1431
  if (!eth->enabled)
1432
    {
1433
      free (eth->rxfile);
1434
      free (eth->txfile);
1435
      free (eth->sockif);
1436
      free (eth);
1437
      return;
1438
    }
1439
 
1440
  memset (&ops, 0, sizeof (struct mem_ops));
1441
 
1442
  ops.readfunc32 = eth_read32;
1443
  ops.writefunc32 = eth_write32;
1444
  ops.read_dat32 = dat;
1445
  ops.write_dat32 = dat;
1446
 
1447
  /* FIXME: Correct delay? */
1448
  ops.delayr = 2;
1449
  ops.delayw = 2;
1450
  reg_mem_area (eth->baseaddr, ETH_ADDR_SPACE, 0, &ops);
1451
  reg_sim_stat (eth_status, dat);
1452
  reg_sim_reset (eth_reset, dat);
1453
}
1454
 
1455
 
1456
/*---------------------------------------------------------------------------*/
1457
/*!Register a new Ethernet configuration                                     */
1458
/*---------------------------------------------------------------------------*/
1459
void
1460
reg_ethernet_sec ()
1461
{
1462
  struct config_section *sec =
1463
    reg_config_sec ("ethernet", eth_sec_start, eth_sec_end);
1464
 
1465 224 jeremybenn
  reg_config_param (sec, "enabled",    PARAMT_INT,  eth_enabled);
1466
  reg_config_param (sec, "baseaddr",   PARAMT_ADDR, eth_baseaddr);
1467
  reg_config_param (sec, "dma",        PARAMT_INT,  eth_dma);
1468
  reg_config_param (sec, "irq",        PARAMT_INT,  eth_irq);
1469
  reg_config_param (sec, "rtx_type",   PARAMT_INT,  eth_rtx_type);
1470
  reg_config_param (sec, "rx_channel", PARAMT_INT,  eth_rx_channel);
1471
  reg_config_param (sec, "tx_channel", PARAMT_INT,  eth_tx_channel);
1472
  reg_config_param (sec, "rxfile",     PARAMT_STR,  eth_rxfile);
1473
  reg_config_param (sec, "txfile",     PARAMT_STR,  eth_txfile);
1474
  reg_config_param (sec, "sockif",     PARAMT_STR,  eth_sockif);
1475
  reg_config_param (sec, "vapi_id",    PARAMT_INT,  eth_vapi_id);
1476 428 julius
  reg_config_param (sec, "phy_addr",   PARAMT_INT,  eth_phy_addr);
1477 19 jeremybenn
 
1478
}       /* reg_ethernet_sec() */
1479
 

powered by: WebSVN 2.1.0

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