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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [or1ksim/] [peripheral/] [eth.c] - Blame information for rev 1767

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

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

powered by: WebSVN 2.1.0

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