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

Subversion Repositories or1k

[/] [or1k/] [tags/] [nog_patch_52/] [or1ksim/] [peripheral/] [eth.c] - Blame information for rev 884

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
   Copyright (C) 2001 by Erez Volk, erez@opencores.org
3
                         Ivan Guzvinec, ivang@opencores.org
4
 
5
   This file is part of OpenRISC 1000 Architectural Simulator.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
*/
21
 
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <string.h>
25
#include <sys/types.h>
26
#include <sys/stat.h>   
27
#include <fcntl.h>      
28
#include <sys/poll.h>   
29
#include <sys/time.h>   
30
#include <unistd.h>     
31
#include <errno.h>
32
 
33 867 markom
#include "config.h"
34 696 ivang
#include "abstract.h"
35
#include "ethernet_i.h"
36
#include "dma.h"
37
#include "sim-config.h"
38
#include "fields.h"
39
#include "crc32.h"
40
 
41
static struct eth_device eths[MAX_ETHERNETS];
42
 
43 702 ivang
/* simulator interface */
44
static void eth_reset_controller( struct eth_device *eth);
45 696 ivang
/* register interface */
46
static void eth_write32( unsigned long addr, unsigned long value );
47
static unsigned long eth_read32( unsigned long addr );
48
/* clock */
49
static void eth_controller_tx_clock( struct eth_device * );
50
static void eth_controller_rx_clock( struct eth_device * );
51
/* utility functions */
52
static int eth_find_controller( unsigned long addr, struct eth_device **eth, unsigned long *reladdr );
53 702 ivang
static ssize_t eth_read_rx_file( struct eth_device *, void *, size_t );
54
static void eth_skip_rx_file( struct eth_device *, off_t );
55
static void eth_rewind_rx_file( struct eth_device *, off_t );
56
static void eth_rx_next_packet( struct eth_device * );
57
static void eth_write_tx_bd_num( struct eth_device *, unsigned long value );
58 696 ivang
/* ========================================================================= */
59 702 ivang
/*  TX LOGIC                                                                 */
60 696 ivang
/*---------------------------------------------------------------------------*/
61
 
62
/*
63
 * TX clock
64
 * Responsible for starting and finishing TX
65
 */
66
void eth_controller_tx_clock( struct eth_device *eth )
67
{
68 702 ivang
    int breakpoint = 0;
69
    int bAdvance   = 1;
70 867 markom
#if HAVE_ETH_PHY
71 702 ivang
    struct sockaddr_ll sll;
72 849 markom
#endif /* HAVE_ETH_PHY */
73 702 ivang
    long nwritten;
74
    unsigned long read_word;
75 696 ivang
 
76
    switch (eth->tx.state) {
77 702 ivang
        case ETH_TXSTATE_IDLE:
78
        if ( TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) ) {
79
 
80
            /* wait for TxBuffer to be ready */
81 705 ivang
                debug (3, "TX - entering state WAIT4BD (%d)\n", eth->tx.bd_index);
82 702 ivang
            eth->tx.state = ETH_TXSTATE_WAIT4BD;
83
        }
84
        break;
85 696 ivang
    case ETH_TXSTATE_WAIT4BD:
86 702 ivang
        /* Read buffer descriptor */
87
        eth->tx.bd = eth->regs.bd_ram[eth->tx.bd_index];
88
        eth->tx.bd_addr = eth->regs.bd_ram[eth->tx.bd_index + 1];
89
 
90
        if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, READY ) ) {
91
            /*****************/
92
            /* initialize TX */
93
            eth->tx.bytes_left = eth->tx.packet_length = GET_FIELD( eth->tx.bd, ETH_TX_BD, LENGTH );
94
            eth->tx.bytes_sent = 0;
95
 
96
            /*   Initialize error status bits */
97
            CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, DEFER );
98
            CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, COLLISION );
99
            CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, RETRANSMIT );
100
            CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, UNDERRUN );
101
            CLEAR_FLAG( eth->tx.bd, ETH_TX_BD, NO_CARRIER );
102
            SET_FIELD ( eth->tx.bd, ETH_TX_BD, RETRY, 0 );
103
 
104
            /* Find out minimum length */
105
            if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, PAD ) ||
106
                 TEST_FLAG( eth->regs.moder, ETH_MODER, PAD ) )
107
                eth->tx.minimum_length = GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MINFL );
108
            else
109
                eth->tx.minimum_length = eth->tx.packet_length;
110
 
111
            /* Find out maximum length */
112
            if ( TEST_FLAG( eth->regs.moder, ETH_MODER, HUGEN ) )
113
                eth->tx.maximum_length = eth->tx.packet_length;
114
            else
115
                eth->tx.maximum_length = GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MAXFL );
116
 
117
            /* Do we need CRC on this packet? */
118
            if ( TEST_FLAG( eth->regs.moder, ETH_MODER, CRCEN ) ||
119
                 (TEST_FLAG( eth->tx.bd, ETH_TX_BD, CRC) &&
120
                  TEST_FLAG( eth->tx.bd, ETH_TX_BD, LAST)) )
121
                eth->tx.add_crc = 1;
122
            else
123
                eth->tx.add_crc = 0;
124
 
125
            if ( TEST_FLAG( eth->regs.moder, ETH_MODER, DLYCRCEN ) )
126
                eth->tx.crc_dly = 1;
127
            else
128
                eth->tx.crc_dly = 0;
129
            /* XXX - For now we skip CRC calculation */
130
 
131
            debug( 3, "Ethernet: Starting TX of %u bytes (min. %u, max. %u)\n", eth->tx.packet_length,
132
                   eth->tx.minimum_length, eth->tx.maximum_length );
133
 
134
            if (eth->rtx_type == ETH_RTX_FILE) {
135
                /* write packet length to file */
136
                nwritten = write( eth->txfd, &(eth->tx.packet_length), sizeof(eth->tx.packet_length) );
137
            }
138
 
139
            /************************************************/
140
            /* start transmit with reading packet into FIFO */
141
                debug (3, "TX - entering state READFIFO\n");
142
            eth->tx.state = ETH_TXSTATE_READFIFO;
143
        }
144
        else if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) ) {
145
            /* stop TX logic */
146
                debug (3, "TX - entering state IDLE\n");
147
            eth->tx.state = ETH_TXSTATE_IDLE;
148
        }
149
 
150
        /* stay in this state if (TXEN && !READY) */
151
        break;
152 696 ivang
    case ETH_TXSTATE_READFIFO:
153 744 simons
#if 1
154 702 ivang
        if ( eth->tx.bytes_sent < eth->tx.packet_length ) {
155
            read_word = eval_mem32(eth->tx.bytes_sent + eth->tx.bd_addr, &breakpoint);
156
            eth->tx_buff[eth->tx.bytes_sent]   = (unsigned char)(read_word >> 24);
157
            eth->tx_buff[eth->tx.bytes_sent+1] = (unsigned char)(read_word >> 16);
158
            eth->tx_buff[eth->tx.bytes_sent+2] = (unsigned char)(read_word >> 8);
159
            eth->tx_buff[eth->tx.bytes_sent+3] = (unsigned char)(read_word);
160
            eth->tx.bytes_sent += 4;
161
        }
162 744 simons
#else
163
        if ( eth->tx.bytes_sent < eth->tx.packet_length ) {
164
            eth->tx_buff[eth->tx.bytes_sent] = eval_mem8(eth->tx.bytes_sent + eth->tx.bd_addr, &breakpoint);
165
            eth->tx.bytes_sent += 1;
166
        }
167
#endif
168 702 ivang
        else {
169
            debug (3, "TX - entering state TRANSMIT\n");
170
            eth->tx.state = ETH_TXSTATE_TRANSMIT;
171
        }
172
        break;
173 696 ivang
    case ETH_TXSTATE_TRANSMIT:
174 702 ivang
        /* send packet */
175
        switch (eth->rtx_type) {
176
        case ETH_RTX_FILE:
177
            nwritten = write( eth->txfd, eth->tx_buff, eth->tx.packet_length );
178
            break;
179 867 markom
#if HAVE_ETH_PHY
180 702 ivang
        case ETH_RTX_SOCK:
181
            memset(&sll, 0, sizeof(sll));
182 705 ivang
            sll.sll_ifindex = eth->ifr.ifr_ifindex;
183
            nwritten = sendto(eth->rtx_sock, eth->tx_buff, eth->tx.packet_length, 0, (struct sockaddr *)&sll, sizeof(sll));
184 849 markom
#endif /* HAVE_ETH_PHY */
185 702 ivang
        }
186
 
187
        /* set BD status */
188
        if (nwritten == eth->tx.packet_length) {
189
            CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
190
            SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB);
191 836 ivang
            debug (4, "ETH_INT_SOURCE = %0x\n", eth->regs.int_source);
192 702 ivang
 
193 705 ivang
            debug (3, "TX - entering state IDLE\n");
194 702 ivang
            eth->tx.state = ETH_TXSTATE_IDLE;
195
            debug (3, "send (%d)bytes OK\n", nwritten);
196
        }
197
        else {
198
            /* XXX - implement retry mechanism here! */
199
            CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, READY);
200
            CLEAR_FLAG (eth->tx.bd, ETH_TX_BD, COLLISION);
201
            SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXE);
202
 
203
                debug (3, "TX - entering state IDLE\n");
204
            eth->tx.state = ETH_TXSTATE_IDLE;
205
            debug (3, "send FAILED!\n");
206
        }
207
 
208
        eth->regs.bd_ram[eth->tx.bd_index] = eth->tx.bd;
209
 
210
        /* advance to next BD */
211
        if (bAdvance) {
212
            if ( TEST_FLAG( eth->tx.bd, ETH_TX_BD, WRAP ) ||
213
                            eth->tx.bd_index >= ETH_BD_COUNT )
214
                eth->tx.bd_index = 0;
215
            else
216
                eth->tx.bd_index += 2;
217
        }
218
 
219
        /* generate OK interrupt */
220
        if ( TEST_FLAG(eth->regs.int_mask, ETH_INT_MASK, TXE_M) ||
221
             TEST_FLAG(eth->regs.int_mask, ETH_INT_MASK, TXB_M) )
222
        {
223
            report_interrupt( eth->mac_int );
224
        }
225
 
226
        break;
227 696 ivang
    }
228
}
229
/* ========================================================================= */
230
 
231
 
232
/* ========================================================================= */
233 702 ivang
/*  RX LOGIC                                                                 */
234 696 ivang
/*---------------------------------------------------------------------------*/
235
 
236
/*
237
 * RX clock
238
 * Responsible for starting and finishing RX
239
 */
240
void eth_controller_rx_clock( struct eth_device *eth )
241
{
242 702 ivang
    int i;
243
    int breakpoint = 0;
244
    long nread;
245
    unsigned long send_word;
246
 
247
    fd_set rfds;
248
 
249 696 ivang
    switch (eth->rx.state) {
250
    case ETH_RXSTATE_IDLE:
251 702 ivang
        if ( TEST_FLAG( eth->regs.moder, ETH_MODER, RXEN) ) {
252 705 ivang
                debug (3, "RX - entering state WAIT4BD (%d)\n", eth->rx.bd_index);
253 702 ivang
            eth->rx.state = ETH_RXSTATE_WAIT4BD;
254
        }
255
        break;
256
 
257 696 ivang
    case ETH_RXSTATE_WAIT4BD:
258 702 ivang
        eth->rx.bd = eth->regs.bd_ram[eth->rx.bd_index];
259
        eth->rx.bd_addr = eth->regs.bd_ram[eth->rx.bd_index + 1];
260
 
261
        if ( TEST_FLAG( eth->rx.bd, ETH_RX_BD, READY ) ) {
262
            /*****************/
263
            /* Initialize RX */
264
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, MISS );
265
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, INVALID );
266
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, DRIBBLE );
267
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, UVERRUN );
268
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, COLLISION );
269
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, TOOBIG );
270
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, TOOSHORT );
271
 
272
            debug( 3,  "Ethernet: Starting RX\n" );
273
 
274
            /* Setup file to read from */
275
            if ( TEST_FLAG( eth->regs.moder, ETH_MODER, LOOPBCK ) ) {
276
                eth->rx.fd = eth->txfd;
277
                eth->rx.offset = &(eth->loopback_offset);
278
            } else {
279
                eth->rx.fd = eth->rxfd;
280
                eth->rx.offset = 0;
281
            }
282
                debug (3, "RX - entering state RECV\n");
283
            eth->rx.state = ETH_RXSTATE_RECV;
284
        }
285 705 ivang
        else if (!TEST_FLAG( eth->regs.moder, ETH_MODER, RXEN)) {
286
          debug (3, "RX - entering state IDLE\n");
287
          eth->rx.state = ETH_RXSTATE_IDLE;
288
        }
289
        else {
290 744 simons
            nread = recv(eth->rtx_sock, eth->rx_buff, ETH_MAXPL, /*MSG_PEEK | */MSG_DONTWAIT);
291 705 ivang
            if (nread > 0) {
292 702 ivang
                SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, BUSY);
293 723 ivang
                if ( TEST_FLAG(eth->regs.int_mask, ETH_INT_MASK, BUSY_M) )
294
                  report_interrupt(eth->mac_int);
295 702 ivang
            }
296
        }
297
        break;
298
 
299 696 ivang
    case ETH_RXSTATE_RECV:
300 702 ivang
        switch (eth->rtx_type) {
301
        case ETH_RTX_FILE:
302
            /* Read packet length */
303
            if ( eth_read_rx_file( eth, &(eth->rx.packet_length), sizeof(eth->rx.packet_length) )
304
                     < sizeof(eth->rx.packet_length) ) {
305
                /* TODO: just do what real ethernet would do (some kind of error state) */
306 836 ivang
                debug (4, "eth_start_rx(): File does not have a packet ready for RX (len = %d)\n", eth->rx.packet_length );
307 884 markom
                runtime.sim.cont_run = 0;
308 702 ivang
                break;
309
            }
310
 
311
            /* Packet must be big enough to hold a header */
312
            if ( eth->rx.packet_length < ETH_HLEN ){
313
                debug( 3,  "eth_start_rx(): Packet too small\n" );
314
                eth_rx_next_packet( eth );
315
 
316 836 ivang
                debug (3, "RX - entering state IDLE\n");
317 702 ivang
                eth->rx.state = ETH_RXSTATE_IDLE;
318
                break;
319
            }
320
 
321
            eth->rx.bytes_read = 0;
322
            eth->rx.bytes_left = eth->rx.packet_length;
323
 
324
            /* for now Read entire packet into memory */
325
            nread = eth_read_rx_file( eth, eth->rx_buff, eth->rx.bytes_left );
326 844 ivang
            if ( nread < eth->rx.bytes_left ) {
327 702 ivang
                debug (3, "Read %d from %d. Error!\n", nread, eth->rx.bytes_left);
328 844 ivang
                eth->rx.error = 1;
329
                break;
330
            }
331
 
332
            eth->rx.packet_length = nread;
333
            eth->rx.bytes_left = nread;
334
            eth->rx.bytes_read = 0;
335
 
336
            debug (3, "RX - entering state WRITEFIFO\n");
337
            eth->rx.state = ETH_RXSTATE_WRITEFIFO;
338
 
339 702 ivang
            break;
340
 
341
        case ETH_RTX_SOCK:
342
            nread = recv(eth->rtx_sock, eth->rx_buff, ETH_MAXPL, MSG_DONTWAIT);
343 744 simons
 
344
            if (nread == 0)
345
                break;
346
            else if (nread < 0) {
347
                if ( errno != EAGAIN ) {
348 702 ivang
                            debug (3, "recv() FAILED!\n");
349
                            break;
350
                        }
351
                        else {
352
                        break;
353
                    }
354 744 simons
            }
355
            /* If not promiscouos mode, check the destination address */
356
            if (!TEST_FLAG(eth->regs.moder, ETH_MODER, PRO)) {
357
                if (TEST_FLAG(eth->regs.moder, ETH_MODER, IAM) && (eth->rx_buff[0] & 1)) {
358
                /* Nothing for now */
359
                }
360
 
361
                if (eth->mac_address[5] != eth->rx_buff[0] ||
362
                    eth->mac_address[4] != eth->rx_buff[1] ||
363
                    eth->mac_address[3] != eth->rx_buff[2] ||
364
                    eth->mac_address[2] != eth->rx_buff[3] ||
365
                    eth->mac_address[1] != eth->rx_buff[4] ||
366
                    eth->mac_address[0] != eth->rx_buff[5])
367
                        break;
368
            }
369
 
370 841 simons
            eth->rx.packet_length = nread;
371
            eth->rx.bytes_left = nread;
372
            eth->rx.bytes_read = 0;
373
 
374
            debug (3, "RX - entering state WRITEFIFO\n");
375
            eth->rx.state = ETH_RXSTATE_WRITEFIFO;
376
 
377 702 ivang
            break;
378
        }
379 841 simons
        break;
380
 
381 696 ivang
    case ETH_RXSTATE_WRITEFIFO:
382 744 simons
#if 1
383 702 ivang
        send_word = ((unsigned long)eth->rx_buff[eth->rx.bytes_read]   << 24) |
384
                    ((unsigned long)eth->rx_buff[eth->rx.bytes_read+1] << 16) |
385
                    ((unsigned long)eth->rx_buff[eth->rx.bytes_read+2] << 8)  |
386
                    ((unsigned long)eth->rx_buff[eth->rx.bytes_read+3] );
387
        set_mem32( eth->rx.bd_addr + eth->rx.bytes_read, send_word, &breakpoint);
388
        /* update counters */
389
        debug (3, "Write %d, left %d - %08lXd\n", eth->rx.bytes_read, eth->rx.bytes_left, send_word);
390
        eth->rx.bytes_left -= 4;
391
        eth->rx.bytes_read += 4;
392 744 simons
#else
393
        set_mem8( eth->rx.bd_addr + eth->rx.bytes_read, eth->rx_buff[eth->rx.bytes_read], &breakpoint);
394
        eth->rx.bytes_left -= 1;
395
        eth->rx.bytes_read += 1;
396
#endif
397
 
398 702 ivang
        if ( eth->rx.bytes_left <= 0 ) {
399
            /* Write result to bd */
400
            SET_FIELD( eth->rx.bd, ETH_RX_BD, LENGTH, eth->rx.packet_length );
401
            CLEAR_FLAG( eth->rx.bd, ETH_RX_BD, READY);
402 705 ivang
            SET_FLAG( eth->regs.int_source, ETH_INT_SOURCE, RXB);
403 836 ivang
            debug (4, "ETH_INT_SOURCE = %0x\n", eth->regs.int_source);
404 702 ivang
 
405
            if ( eth->rx.packet_length < GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MINFL ) )
406 744 simons
                SET_FLAG( eth->rx.bd, ETH_RX_BD, TOOSHORT);
407
            if ( eth->rx.packet_length > GET_FIELD( eth->regs.packetlen, ETH_PACKETLEN, MAXFL ) )
408 702 ivang
                SET_FLAG( eth->rx.bd, ETH_RX_BD, TOOBIG);
409
 
410
            eth->regs.bd_ram[eth->rx.bd_index] = eth->rx.bd;
411
 
412
            /* advance to next BD */
413
            if ( TEST_FLAG( eth->rx.bd, ETH_RX_BD, WRAP ) || eth->rx.bd_index >= ETH_BD_COUNT )
414 705 ivang
                eth->rx.bd_index = eth->regs.tx_bd_num;
415 702 ivang
            else
416 705 ivang
                eth->rx.bd_index += 2;
417 702 ivang
 
418 705 ivang
            if ( TEST_FLAG(eth->regs.int_mask, ETH_INT_MASK, RXB_M) ) {
419 702 ivang
                report_interrupt( eth->mac_int );
420
            }
421
 
422
            /* ready to receive next packet */
423
                debug (3, "RX - entering state IDLE\n");
424
            eth->rx.state = ETH_RXSTATE_IDLE;
425
        }
426
        break;
427 696 ivang
    }
428
}
429 702 ivang
 
430 696 ivang
/* ========================================================================= */
431 702 ivang
/* Move to next RX BD */
432
void eth_rx_next_packet( struct eth_device *eth )
433
{
434
    /* Skip any possible leftovers */
435
    if ( eth->rx.bytes_left )
436
        eth_skip_rx_file( eth, eth->rx.bytes_left );
437
}
438
/* "Skip" bytes in RX file */
439
void eth_skip_rx_file( struct eth_device *eth, off_t count )
440
{
441
    eth->rx.offset += count;
442
}
443 696 ivang
 
444 702 ivang
/* Move RX file position back */
445
void eth_rewind_rx_file( struct eth_device *eth, off_t count )
446
{
447
    eth->rx.offset -= count;
448
}
449
/*
450
 * Utility function to read from the ethernet RX file
451
 * This function moves the file pointer to the current place in the packet before reading
452
 */
453
ssize_t eth_read_rx_file( struct eth_device *eth, void *buf, size_t count )
454
{
455
    ssize_t result;
456
 
457
    if ( eth->rx.fd <= 0 ) {
458
        debug( 3,  "Ethernet: No RX file\n" );
459
        return 0;
460
    }
461
 
462
    if ( eth->rx.offset )
463
        if ( lseek( eth->rx.fd, *(eth->rx.offset), SEEK_SET ) == (off_t)-1 ) {
464
            debug( 3,  "Ethernet: Error seeking RX file\n" );
465
            return 0;
466
        }
467 696 ivang
 
468 702 ivang
    result = read( eth->rx.fd, buf, count );
469 836 ivang
    debug (4, "Ethernet: read result = %d \n", result);
470 702 ivang
    if ( eth->rx.offset && result >= 0 )
471
        *(eth->rx.offset) += result;
472
 
473
    return result;
474
}
475
 
476
/* ========================================================================= */
477
 
478 696 ivang
/*
479 702 ivang
  Reset. Initializes all registers to default and places devices in
480
         memory address space.
481 696 ivang
*/
482
void eth_reset()
483
{
484
    static int first_time = 1;
485
    unsigned i;
486
 
487
    if (!config.nethernets)
488 702 ivang
        return;
489 696 ivang
 
490 841 simons
    if ( first_time )
491 702 ivang
        memset( eths, 0, sizeof(eths) );
492 696 ivang
 
493
    for ( i = 0; i < MAX_ETHERNETS; ++ i ) {
494 702 ivang
        struct eth_device *eth = &(eths[i]);
495
 
496 849 markom
        if (!HAVE_ETH_PHY && eth->rtx_type == ETH_RTX_SOCK) {
497
          fprintf (stderr, "Ethernet phy not enabled in this configuration.  Configure with --enable-ethphy.\n");
498
          exit (1);
499
        }
500 702 ivang
        eth->eth_number = i;
501
        eth_reset_controller( eth );
502 841 simons
        if ( eth->baseaddr && first_time )
503
            register_memoryarea( eth->baseaddr, ETH_ADDR_SPACE, 4, eth_read32, eth_write32 );
504 696 ivang
    }
505 841 simons
 
506
    if ( first_time )
507
        first_time = 0;
508 696 ivang
}
509 841 simons
 
510 696 ivang
/* ========================================================================= */
511
 
512
 
513 702 ivang
static void eth_reset_controller(struct eth_device *eth)
514
{
515
    int i = eth->eth_number;
516
    int j;
517 867 markom
#if HAVE_ETH_PHY
518 702 ivang
    struct sockaddr_ll sll;
519 849 markom
#endif /* HAVE_ETH_PHY */
520 702 ivang
 
521
    eth->baseaddr = config.ethernets[i].baseaddr;
522
 
523
    if ( eth->baseaddr != 0 ) {
524
        /* Mark which DMA controller and channels */
525
        eth->dma        = config.ethernets[i].dma;
526 725 ivang
        eth->mac_int    = config.ethernets[i].irq;
527 702 ivang
        eth->tx_channel = config.ethernets[i].tx_channel;
528
        eth->rx_channel = config.ethernets[i].rx_channel;
529 725 ivang
        eth->rtx_type   = config.ethernets[i].rtx_type;
530 702 ivang
 
531
        switch (eth->rtx_type) {
532
        case ETH_RTX_FILE:
533
            /* (Re-)open TX/RX files */
534
            eth->rxfile = config.ethernets[i].rxfile;
535
            eth->txfile = config.ethernets[i].txfile;
536
 
537
            if ( eth->rxfd > 0 )
538
                close( eth->rxfd );
539
            if ( eth->txfd > 0 )
540
                close( eth->txfd );
541
            eth->rxfd = eth->txfd = -1;
542
 
543
            if ( (eth->rxfd = open( eth->rxfile, O_RDONLY )) < 0 )
544
                fprintf( stderr, "Cannot open Ethernet RX file \"%s\"\n", eth->rxfile );
545
            if ( (eth->txfd = open( eth->txfile,
546
                                    O_RDWR | O_CREAT | O_APPEND | O_SYNC,
547
                                    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH )) < 0 )
548
                fprintf( stderr, "Cannot open Ethernet TX file \"%s\"\n", eth->txfile );
549
            eth->loopback_offset = lseek( eth->txfd, 0, SEEK_END );
550
 
551
            break;
552 867 markom
#if HAVE_ETH_PHY
553 702 ivang
        case ETH_RTX_SOCK:
554
            /* (Re-)open TX/RX sockets */
555
            if (eth->rtx_sock != 0)
556
                break;
557
 
558
            debug (3, "RTX oppening socket...\n");
559
            eth->rtx_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
560
            if (eth->rtx_sock == -1) {
561
                fprintf( stderr, "Cannot open rtx_sock.\n");
562
                return;
563
            }
564
 
565
            /* get interface index number */
566
            debug (3, "RTX getting interface...\n");
567
            memset(&(eth->ifr), 0, sizeof(eth->ifr));
568 725 ivang
            strncpy(eth->ifr.ifr_name, config.ethernets[i].sockif, IFNAMSIZ);
569 702 ivang
            if (ioctl(eth->rtx_sock, SIOCGIFINDEX, &(eth->ifr)) == -1) {
570
                fprintf( stderr, "SIOCGIFINDEX failed!\n");
571
                return;
572
            }
573
            debug (3, "RTX Socket Interface : %d\n", eth->ifr.ifr_ifindex);
574
 
575
            /* Bind to interface... */
576
            debug (3, "Binding to the interface ifindex=%d\n", eth->ifr.ifr_ifindex);
577
            memset(&sll, 0xff, sizeof(sll));
578
            sll.sll_family = AF_PACKET;    /* allways AF_PACKET */
579
            sll.sll_protocol = htons(ETH_P_ALL);
580
            sll.sll_ifindex = eth->ifr.ifr_ifindex;
581
            if (bind(eth->rtx_sock, (struct sockaddr *)&sll, sizeof(sll)) == -1) {
582
                fprintf( stderr, "Error bind().\n");
583
                return;
584
            }
585
 
586
            /* first, flush all received packets. */
587
            debug (3, "Flush");
588
            do {
589
                fd_set fds;
590
                struct timeval t;
591
 
592
                debug( 3, ".");
593
                FD_ZERO(&fds);
594
                FD_SET(eth->rtx_sock, &fds);
595
                memset(&t, 0, sizeof(t));
596
                j = select(FD_SETSIZE, &fds, NULL, NULL, &t);
597
                if (j > 0)
598
                    recv(eth->rtx_sock, eth->rx_buff, j, 0);
599
            } while (j);
600
            debug (3, "\n");
601
 
602
            break;
603 849 markom
#endif /* HAVE_ETH_PHY */
604 702 ivang
        }
605
 
606
        /* Set registers to default values */
607
        memset( &(eth->regs), 0, sizeof(eth->regs) );
608
        eth->regs.moder = 0x0000A000;
609
        eth->regs.ipgt = 0x00000012;
610
        eth->regs.ipgr1 = 0x0000000C;
611
        eth->regs.ipgr2 = 0x00000012;
612
        eth->regs.packetlen = 0x003C0600;
613
        eth->regs.collconf = 0x000F003F;
614
        eth->regs.miimoder = 0x00000064;
615
        eth->regs.tx_bd_num = 0x00000080;
616
 
617
        /* Initialize TX/RX status */
618
        memset( &(eth->tx), 0, sizeof(eth->tx) );
619
        memset( &(eth->rx), 0, sizeof(eth->rx) );
620
        eth->rx.bd_index = eth->regs.tx_bd_num;
621
    }
622
}
623
/* ========================================================================= */
624
 
625
 
626 696 ivang
/*
627
  Print register values on stdout
628
*/
629
void eth_status( void )
630
{
631
    unsigned i;
632
 
633
    for ( i = 0; i < MAX_ETHERNETS; ++ i ) {
634 702 ivang
        struct eth_device *eth = &(eths[i]);
635
 
636
        if ( eth->baseaddr == 0 )
637
            continue;
638
 
639
        printf( "\nEthernet MAC %u at 0x%08X:\n", i, eth->baseaddr );
640
        printf( "MODER        : 0x%08lX\n", eth->regs.moder );
641
        printf( "INT_SOURCE   : 0x%08lX\n", eth->regs.int_source );
642
        printf( "INT_MASK     : 0x%08lX\n", eth->regs.int_mask );
643
        printf( "IPGT         : 0x%08lX\n", eth->regs.ipgt );
644
        printf( "IPGR1        : 0x%08lX\n", eth->regs.ipgr1 );
645
        printf( "IPGR2        : 0x%08lX\n", eth->regs.ipgr2 );
646
        printf( "PACKETLEN    : 0x%08lX\n", eth->regs.packetlen );
647
        printf( "COLLCONF     : 0x%08lX\n", eth->regs.collconf );
648
        printf( "TX_BD_NUM    : 0x%08lX\n", eth->regs.tx_bd_num );
649
        printf( "CTRLMODER    : 0x%08lX\n", eth->regs.controlmoder );
650
        printf( "MIIMODER     : 0x%08lX\n", eth->regs.miimoder );
651
        printf( "MIICOMMAND   : 0x%08lX\n", eth->regs.miicommand );
652
        printf( "MIIADDRESS   : 0x%08lX\n", eth->regs.miiaddress );
653
        printf( "MIITX_DATA   : 0x%08lX\n", eth->regs.miitx_data );
654
        printf( "MIIRX_DATA   : 0x%08lX\n", eth->regs.miirx_data );
655
        printf( "MIISTATUS    : 0x%08lX\n", eth->regs.miistatus );
656
        printf( "MAC Address  : %02X:%02X:%02X:%02X:%02X:%02X\n",
657
                eth->mac_address[0], eth->mac_address[1], eth->mac_address[2],
658
                eth->mac_address[3], eth->mac_address[4], eth->mac_address[5] );
659 744 simons
        printf( "HASH0        : 0x%08lX\n", eth->regs.hash0 );
660
        printf( "HASH1        : 0x%08lX\n", eth->regs.hash1 );
661 696 ivang
    }
662
}
663
/* ========================================================================= */
664
 
665
 
666
/*
667
  Simulation hook. Must be called every clock cycle to simulate Ethernet MAC.
668
*/
669
void eth_clock()
670
{
671
    unsigned i;
672
 
673
    for ( i = 0; i < config.nethernets; ++ i ) {
674 702 ivang
        eth_controller_tx_clock( &(eths[i]) );
675
        eth_controller_rx_clock( &(eths[i]) );
676 696 ivang
    }
677
}
678
/* ========================================================================= */
679
 
680
 
681
/*
682
  Read a register
683
*/
684
unsigned long eth_read32( unsigned long addr )
685
{
686
    struct eth_device *eth;
687 702 ivang
    if ( !eth_find_controller( addr, &eth, &addr ) )    {
688
        printf( "eth_read32( 0x%08lX ): Not in registered range(s)\n", addr );
689
        return 0;
690 696 ivang
    }
691
 
692
    switch( addr ) {
693
    case ETH_MODER: return eth->regs.moder;
694
    case ETH_INT_SOURCE: return eth->regs.int_source;
695
    case ETH_INT_MASK: return eth->regs.int_mask;
696
    case ETH_IPGT: return eth->regs.ipgt;
697
    case ETH_IPGR1: return eth->regs.ipgr1;
698
    case ETH_IPGR2: return eth->regs.ipgr2;
699
    case ETH_PACKETLEN: return eth->regs.packetlen;
700
    case ETH_COLLCONF: return eth->regs.collconf;
701
    case ETH_TX_BD_NUM: return eth->regs.tx_bd_num;
702
    case ETH_CTRLMODER: return eth->regs.controlmoder;
703
    case ETH_MIIMODER: return eth->regs.miimoder;
704
    case ETH_MIICOMMAND: return eth->regs.miicommand;
705
    case ETH_MIIADDRESS: return eth->regs.miiaddress;
706
    case ETH_MIITX_DATA: return eth->regs.miitx_data;
707
    case ETH_MIIRX_DATA: return eth->regs.miirx_data;
708
    case ETH_MIISTATUS: return eth->regs.miistatus;
709
    case ETH_MAC_ADDR0: return (((unsigned long)eth->mac_address[3]) << 24) |
710 702 ivang
                               (((unsigned long)eth->mac_address[2]) << 16) |
711
                               (((unsigned long)eth->mac_address[1]) << 8) |
712
                                 (unsigned long)eth->mac_address[0];
713 696 ivang
    case ETH_MAC_ADDR1: return (((unsigned long)eth->mac_address[5]) << 8) |
714 702 ivang
                                 (unsigned long)eth->mac_address[4];
715 744 simons
    case ETH_HASH0: return eth->regs.hash0;
716
    case ETH_HASH1: return eth->regs.hash1;
717 702 ivang
    /*case ETH_DMA_RX_TX: return eth_rx( eth );*/
718 696 ivang
    }
719
 
720
    if ( (addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE) )
721 702 ivang
        return eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4];
722 696 ivang
 
723
    printf( "eth_read32( 0x%08lX ): Illegal address\n", addr + eth->baseaddr );
724 884 markom
    runtime.sim.cont_run = 0;
725 696 ivang
    return 0;
726
}
727
/* ========================================================================= */
728
 
729
 
730
/*
731
  Write a register
732
*/
733
void eth_write32( unsigned long addr, unsigned long value )
734
{
735
    struct eth_device *eth;
736 702 ivang
    if ( !eth_find_controller( addr, &eth, &addr ) )    {
737
        printf( "eth_write32( 0x%08lX ): Not in registered range(s)\n", addr );
738
    return;
739 696 ivang
    }
740
 
741
    switch( addr ) {
742 841 simons
    case ETH_MODER: eth->regs.moder = value; if (TEST_FLAG(value, ETH_MODER, RST)) eth_reset(); return;
743 744 simons
    case ETH_INT_SOURCE: eth->regs.int_source &= ~value; return;
744 696 ivang
    case ETH_INT_MASK: eth->regs.int_mask = value; return;
745
    case ETH_IPGT: eth->regs.ipgt = value; return;
746
    case ETH_IPGR1: eth->regs.ipgr1 = value; return;
747
    case ETH_IPGR2: eth->regs.ipgr2 = value; return;
748
    case ETH_PACKETLEN: eth->regs.packetlen = value; return;
749
    case ETH_COLLCONF: eth->regs.collconf = value; return;
750
    case ETH_TX_BD_NUM: eth_write_tx_bd_num( eth, value ); return;
751
    case ETH_CTRLMODER: eth->regs.controlmoder = value; return;
752
    case ETH_MIIMODER: eth->regs.miimoder = value; return;
753
    case ETH_MIICOMMAND: eth->regs.miicommand = value; return;
754
    case ETH_MIIADDRESS: eth->regs.miiaddress = value; return;
755
    case ETH_MIITX_DATA: eth->regs.miitx_data = value; return;
756
    case ETH_MIIRX_DATA: eth->regs.miirx_data = value; return;
757
    case ETH_MIISTATUS: eth->regs.miistatus = value; return;
758
    case ETH_MAC_ADDR0:
759 702 ivang
        eth->mac_address[0] = value & 0xFF;
760
        eth->mac_address[1] = (value >> 8) & 0xFF;
761
        eth->mac_address[2] = (value >> 16) & 0xFF;
762
        eth->mac_address[3] = (value >> 24) & 0xFF;
763
        return;
764 696 ivang
    case ETH_MAC_ADDR1:
765 702 ivang
        eth->mac_address[4] = value & 0xFF;
766
        eth->mac_address[5] = (value >> 8) & 0xFF;
767
        return;
768 744 simons
    case ETH_HASH0: eth->regs.hash0 = value; return;
769
    case ETH_HASH1: eth->regs.hash1 = value; return;
770 702 ivang
 
771
    /*case ETH_DMA_RX_TX: eth_tx( eth, value ); return;*/
772 696 ivang
    }
773
 
774
    if ( (addr >= ETH_BD_BASE) && (addr < ETH_BD_BASE + ETH_BD_SPACE) ) {
775 702 ivang
        eth->regs.bd_ram[(addr - ETH_BD_BASE) / 4] = value;
776
        return;
777 696 ivang
    }
778
 
779
    printf( "eth_write32( 0x%08lX ): Illegal address\n", addr + eth->baseaddr );
780 884 markom
    runtime.sim.cont_run = 0;
781 696 ivang
    return;
782
}
783
/* ========================================================================= */
784
 
785
 
786 702 ivang
/* When TX_BD_NUM is written, also reset current RX BD index */
787
void eth_write_tx_bd_num( struct eth_device *eth, unsigned long value )
788
{
789
    eth->rx.bd_index = eth->regs.tx_bd_num = value & 0xFF;
790
}
791
/* ========================================================================= */
792
 
793
 
794 696 ivang
/*
795
  Convert a memory address to a oontroller struct and relative address.
796
  Return nonzero on success
797
*/
798
int eth_find_controller( unsigned long addr, struct eth_device **eth, unsigned long *reladdr )
799
{
800
    unsigned i;
801
    *eth = NULL;
802
 
803
    for ( i = 0; i < MAX_ETHERNETS && *eth == NULL; ++ i ) {
804 702 ivang
        if ( (addr >= eths[i].baseaddr) && (addr < eths[i].baseaddr + ETH_ADDR_SPACE) )
805
            *eth = &(eths[i]);
806
        }
807 696 ivang
 
808
    /* verify we found a controller */
809
    if ( *eth == NULL )
810 702 ivang
        return 0;
811 696 ivang
 
812
    /* Verify legal address */
813
    if ( (addr - (*eth)->baseaddr) % 4 != 0 )
814 702 ivang
        return 0;
815 696 ivang
 
816
    *reladdr = addr - (*eth)->baseaddr;
817
    return 1;
818
}

powered by: WebSVN 2.1.0

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