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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [eth/] [m68k/] [mcf5272/] [current/] [src/] [if_mcf5272.c] - Blame information for rev 817

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      if_mcfxxxx.c
4
//
5
//          Ethernet driver for Freescale MCFxxxx coldfires
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    bartv
43
// Contributors:
44
// Date:         2003-06-04
45
// Description:  hardware driver for MCFxxxx ethernet devices.
46
//
47
//####DESCRIPTIONEND####
48
//==========================================================================
49
 
50
#include <pkgconf/system.h>
51
#include CYGBLD_HAL_PLATFORM_H
52
#include <pkgconf/devs_eth_mcfxxxx.h>
53
#include <pkgconf/io_eth_drivers.h>
54
 
55
#include <cyg/infra/cyg_type.h>
56
#include <cyg/infra/cyg_ass.h>
57
#include <cyg/hal/hal_arch.h>
58
#include <cyg/hal/hal_io.h>
59
#include <cyg/hal/hal_intr.h>
60
#include <cyg/hal/hal_cache.h>
61
#include <cyg/hal/hal_if.h>
62
#include <cyg/infra/diag.h>
63
#include <cyg/hal/drv_api.h>
64
#include <cyg/io/eth/netdev.h>
65
#include <cyg/io/eth/eth_drv.h>
66
#include <string.h>
67
#ifdef CYGPKG_NET
68
#include <pkgconf/net.h>
69
#include <net/if.h>  /* Needed for struct ifnet */
70
#endif
71
#include <cyg/io/eth/eth_drv_stats.h>
72
 
73
// ----------------------------------------------------------------------------
74
// Support for multiple devices - still incomplete. 
75
# define EIR(_eth_)             (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_EIR)
76
# define EIMR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_EIMR)
77
# define RDAR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_RDAR)
78
# define TDAR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_TDAR)
79
# define ECR(_eth_)             (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_ECR)
80
# define MMFR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_MMFR)
81
# define MSCR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_MSCR)
82
# define MIBC(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_MIBC)
83
# define RCR(_eth_)             (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_RCR)
84
# define TCR(_eth_)             (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_TCR)
85
# define PALR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_PALR)
86
# define PAUR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_PAUR)
87
# define OPD(_eth_)             (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_OPD)
88
# define IAUR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_IAUR)
89
# define IALR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_IALR)
90
# define GAUR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_GAUR)
91
# define GALR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_GALR)
92
# define TFWR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_TFWR)
93
# define FRBR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_FRBR)
94
# define FRSR(_eth_)            (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_FRSR)
95
# define ERDSR(_eth_)           (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_ERDSR)
96
# define ETDSR(_eth_)           (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_ETDSR)
97
# define EMRBR(_eth_)           (HAL_MCFxxxx_ETH0_BASE + HAL_MCFxxxx_ETHx_EMRBR)
98
 
99
// ----------------------------------------------------------------------------
100
// Debug support, in the form of diagnostics and a simple trace
101
// buffer. Also make it easy to enable stats without messing about
102
// with the configuration.
103
 
104
#define DIAG_LEVEL     0
105
#define DIAG_BUFFERED  0
106
#define DIAG_WRAP      1
107
#ifndef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
108
//# define CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS 1
109
#endif
110
 
111
#if (DIAG_LEVEL <= 0)
112
 
113
# define DIAG(_level_, _fmt_, ...)                  \
114
    CYG_MACRO_START                                 \
115
    CYG_MACRO_END
116
 
117
# define DIAGPKT(_level_, _msg_, _pkt_, _len_)      \
118
    CYG_MACRO_START                                 \
119
    CYG_MACRO_END
120
 
121
#elif (! DIAG_BUFFERED)
122
 
123
#  define DIAG(_level_, _fmt_, ...)                                             \
124
    CYG_MACRO_START                                                             \
125
    if ((_level_) <= DIAG_LEVEL) {                                              \
126
        diag_printf("mcfxxxx_eth %s : " _fmt_ "\n", __func__, ## __VA_ARGS__);  \
127
    }                                                                           \
128
    CYG_MACRO_END
129
 
130
# define DIAGPKT(_level_, _msg_, _pkt_, _len_)                                  \
131
    CYG_MACRO_START                                                             \
132
    if ((_level_) <= DIAG_LEVEL) {                                              \
133
        diag_printf("mcfxxxx_eth %s : pkt %p, len %d\n", __func__,              \
134
                    (cyg_uint8*)_pkt_, _len_);                                  \
135
    }                                                                           \
136
    CYG_MACRO_END
137
 
138
#else
139
// Trace buffer size. This has to be kept smallish or RedBoot will overrun
140
// its RAM allocation. With 24 bytes per entry, 300 entries require a bit
141
// under 8K.
142
# define DIAG_BUFFER_SIZE      300
143
typedef struct mcfxxxx_eth_trace {
144
    const char*     fn;
145
    const char*     msg;
146
    cyg_uint32      len;
147
    cyg_uint8       packet[14];
148
} mcfxxxx_eth_trace_entry;
149
static mcfxxxx_eth_trace_entry  mcfxxxx_eth_trace_data[DIAG_BUFFER_SIZE];
150
static int                      mcfxxxx_eth_trace_next      = DIAG_BUFFER_SIZE - 1;
151
static cyg_bool                 mcfxxxx_eth_trace_wrapped   = false;
152
 
153
static void
154
mcfxxxx_eth_trace(const char* fn, const char* msg, cyg_uint8* packet, cyg_uint32 len)
155
{
156
    mcfxxxx_eth_trace_entry* entry = &(mcfxxxx_eth_trace_data[mcfxxxx_eth_trace_next]);
157
 
158
# ifdef DIAG_WRAP
159
    if (0 == mcfxxxx_eth_trace_next) {
160
        mcfxxxx_eth_trace_next = DIAG_BUFFER_SIZE - 1;
161
        mcfxxxx_eth_trace_wrapped = true;
162
    } else {
163
        mcfxxxx_eth_trace_next -= 1;
164
    }
165
# else
166
    if (mcfxxxx_eth_trace_next < 0) {
167
        return;
168
    }
169
    mcfxxxx_eth_trace_next -= 1;
170
# endif
171
 
172
    entry->fn   = fn;
173
    entry->msg  = msg;
174
    entry->len  = len;
175
    if ((cyg_uint8*)0 == packet) {
176
        memset(entry->packet, 0, 14);
177
    } else {
178
        memcpy(entry->packet, packet, 14);
179
    }
180
}
181
 
182
#  define DIAG(_level_, _fmt_, ...)                                         \
183
    CYG_MACRO_START                                                         \
184
    if ((_level_) <= DIAG_LEVEL) {                                          \
185
        mcfxxxx_eth_trace(__func__, _fmt_, (cyg_uint8*)0, 0);               \
186
    }                                                                       \
187
    CYG_MACRO_END
188
 
189
# define DIAGPKT(_level_, _msg_, _pkt_, _len_)                              \
190
    CYG_MACRO_START                                                         \
191
    if ((_level_) <= DIAG_LEVEL) {                                          \
192
        mcfxxxx_eth_trace(__func__, _msg_, (cyg_uint8*)_pkt_, _len_);       \
193
    }                                                                       \
194
    CYG_MACRO_END
195
 
196
#endif
197
 
198
#if (DIAG_LEVEL < 3)
199
# define WRITE32(_addr_, _val_)         HAL_WRITE_UINT32(_addr_, _val_)
200
# define READ32( _addr_, _var_)         HAL_READ_UINT32(_addr_, _var_)
201
#else
202
 
203
# define WRITE32(_addr_, _val_)                                             \
204
    CYG_MACRO_START                                                         \
205
    DIAG(DIAG_LEVEL, "WRITE %s %08x <= 0x%08x", # _addr_, _addr_, _val_) ;  \
206
    HAL_WRITE_UINT32(_addr_, _val_);                                        \
207
    CYG_MACRO_END
208
 
209
#define READ32(_addr_, _var_)                                               \
210
    CYG_MACRO_START                                                         \
211
    HAL_READ_UINT32(_addr_, _var_);                                         \
212
    DIAG(DIAG_LEVEL, "READ  %s %08x == 0x%08x", # _addr_, _addr_, _var_) ;  \
213
    CYG_MACRO_END
214
 
215
#endif
216
 
217
#if 0
218
// A function that gets placed in RAM. This can be called by flash-resident
219
// code, e.g. RedBoot, when I need a breakpoint on a specific condition.
220
static void mcfxxxx_eth_ramfn(void) __attribute__((section (".2ram.mcfxxxx_eth_ramfn")));
221
static int  mcfxxxx_eth_ramfn_calls;
222
static void
223
mcfxxxx_eth_ramfn(void)
224
{
225
    mcfxxxx_eth_ramfn_calls += 1;
226
}
227
#endif
228
 
229
// ----------------------------------------------------------------------------
230
#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
231
# define INCR_STAT(_a_)                 \
232
    CYG_MACRO_START                     \
233
    _a_ += 1;                           \
234
    CYG_MACRO_END
235
#else
236
# define INCR_STAT(_a_)
237
#endif
238
 
239
// ----------------------------------------------------------------------------
240
// Most existing MCFxxxx chips have a single on-chip ethernet device,
241
// so all device-specific data could be held in statics. However, in
242
// case this driver ever gets re-used for a chip with multiple
243
// ethernet devices that data is held in a driver-specific structure.
244
//
245
// The driver currently supports n rx buffers, configurable, each of
246
// maximum size. Incoming frames are then copied to higher-level's code
247
// sg lists.
248
//
249
// For tx the current code supports a single outgoing transmission at a
250
// time. This does limit outgoing bandwidth a bit, but only a bit, and
251
// saves memory and complexity.
252
//
253
// There are actually two implementations of the TX code. The MCF5272
254
// has no alignment restrictions for the data being transmitted, so it
255
// is possible to avoid a copy and put the higher-level sg_list entries
256
// directly into the device's ring buffer. The MCF5282 does have
257
// alignment restrictions and the sg_list entries may not be suitably
258
// aligned, so a copy operation is necessary.
259
// NOTE: a possible optimization is to detect aligned vs. misaligned
260
// data and only copy the bits that need aligning. This would significantly
261
// complicate the code and it is not clear that data would be aligned
262
// sufficiently often to make it worthwhile, at least not without work
263
// inside the TCP/IP stack.
264
//
265
// With only one outgoing transmission at a time a full ring buffer seems
266
// overkill. However it appears that the hardware can get confused if the
267
// ring buffer consists of only a single entry, so the code has to
268
// implement a full ring buffer anyway
269
 
270
#if defined(HAL_DCACHE_LINE_SIZE) && (HAL_DCACHE_LINE_SIZE != 16)
271
# error Driver code needs adjusting for cache line sizes other than 16 bytes.
272
#endif
273
 
274
#if defined(CYGPKG_HAL_M68K_MCF5272)
275
 
276
# undef TX_NEEDS_ALIGNMENT
277
# define TX_BUFFER_SIZE 0
278
 
279
// Always use an even number of buffer descriptors, to preserve
280
// alignment to a 16-byte boundary. We need one more entry in the
281
// ring buffer than SG_LIST_SIZE.
282
# if (0 == (CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE & 0x01))
283
#  define TX_BUFFER_DESCRIPTOR_COUNT   (CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE + 2)
284
# else
285
#  define TX_BUFFER_DESCRIPTOR_COUNT   (CYGNUM_IO_ETH_DRIVERS_SG_LIST_SIZE + 1)
286
# endif
287
 
288
// This #elif should probably become a #else
289
#elif defined(CYGPKG_HAL_M68K_MCF5282) || defined(CYGPKG_HAL_M68K_MCF532x)
290
 
291
# define TX_NEEDS_ALIGNMENT             1
292
# define TX_BUFFER_SIZE                 1520
293
# define TX_BUFFER_DESCRIPTOR_COUNT     2
294
 
295
#else
296
 
297
# error Current processor unsupported
298
 
299
#endif
300
 
301
#if (0 == (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS & 0x01)) || (0 == HAL_DCACHE_SIZE)
302
# define RX_BUFFER_DESCRIPTOR_PADDING   0
303
#else
304
# define RX_BUFFER_DESCRIPTOR_PADDING   16
305
#endif
306
 
307
typedef struct mcfxxxx_eth {
308
 
309
    // There are two separate interrupt vectors to worry about, RXF
310
    // and TXF. Other interrupt sources such as error conditions are
311
    // handled by the main tx/rx code, not by separate interrupt
312
    // handlers.
313
    cyg_handle_t    interrupt_handle_rx;
314
    cyg_interrupt   interrupt_data_rx;
315
    cyg_handle_t    interrupt_handle_tx;
316
    cyg_interrupt   interrupt_data_tx;
317
 
318
    // Pointers to the buffer descriptors. These index the data[] array
319
    // below.
320
    hal_mcfxxxx_eth_buffer_descriptor*  txbds;
321
    hal_mcfxxxx_eth_buffer_descriptor*  rxbds;
322
 
323
#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
324
    cyg_uint32      interrupts;
325
    cyg_uint32      tx_count;
326
    cyg_uint32      tx_good;
327
    cyg_uint32      tx_max_collisions;
328
    cyg_uint32      tx_late_collisions;
329
    cyg_uint32      tx_underrun;
330
    cyg_uint32      tx_carrier_loss;
331
    cyg_uint32      tx_deferred;
332
    cyg_uint32      tx_single_collisions;
333
    cyg_uint32      tx_mult_collisions;
334
    cyg_uint32      tx_total_collisions;
335
 
336
    cyg_uint32      rx_count;
337
    cyg_uint32      rx_good;
338
    cyg_uint32      rx_crc_errors;
339
    cyg_uint32      rx_align_errors;
340
    cyg_uint32      rx_overrun_errors;
341
    cyg_uint32      rx_short_frames;
342
    cyg_uint32      rx_too_long_frames;
343
#endif
344
 
345
    unsigned long   tx_key;
346
 
347
    cyg_uint8       tx_index;
348
    cyg_uint8       started;
349
    cyg_uint8       tx_can_send;
350
    cyg_uint8       tx_done;
351
    cyg_uint8       rx_rdy;
352
    cyg_uint8       rx_next_buffer;
353
    cyg_uint16      rx_len;
354
    cyg_uint8       mac[6];
355
 
356
    // We need:
357
    // 1) padding to get the data aligned to a 16-byte boundary. A
358
    //    16 byte alignment for the rx and tx buffer descriptors is
359
    //    recommended, and should also help with flushing/invalidating
360
    //    cache lines when necessary.
361
    // 2) n 1520 byte rx buffers. 1520 is a multiple of 16 so maintains
362
    //    alignment.
363
    // 3) possibly a 1520 byte tx buffer, as per TX_ALIGNED_BUF_SIZE.
364
    // 4) some number of tx buffer descriptors, as per TX_BUFFER_COUNT.
365
    //    This number will be even, maintaining alignment to 16 bytes.
366
    // 5) some number of rx buffer descriptors. The number of RX buffers
367
    //    need not be even since each buffer is large.
368
    // 6) padding for the RXBUFFERS to ensure that cache lines are not
369
    //    shared between buffer descriptors and other data.
370
    cyg_uint8   data[15 +
371
                     (1520 * CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS) +
372
                     TX_BUFFER_SIZE +
373
                     (TX_BUFFER_DESCRIPTOR_COUNT * sizeof(hal_mcfxxxx_eth_buffer_descriptor)) +
374
                     (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS * sizeof(hal_mcfxxxx_eth_buffer_descriptor)) +
375
                     RX_BUFFER_DESCRIPTOR_PADDING
376
        ];
377
} mcfxxxx_eth;
378
 
379
// This structure is held in bss so all stats etc. are automatically zeroed.
380
static mcfxxxx_eth  mcfxxxx_eth_info;
381
 
382
ETH_DRV_SC(mcfxxxx_eth_sc0,
383
           (void*) &mcfxxxx_eth_info,
384
           CYGDAT_DEVS_ETH_MCFxxxx_NAME,
385
           mcfxxxx_eth_start,
386
           mcfxxxx_eth_stop,
387
           mcfxxxx_eth_ioctl,
388
           mcfxxxx_eth_can_send,
389
           mcfxxxx_eth_send,
390
           mcfxxxx_eth_recv,
391
           mcfxxxx_eth_deliver,
392
           mcfxxxx_eth_poll,
393
           mcfxxxx_eth_int_vector
394
    );
395
 
396
NETDEVTAB_ENTRY(mcfxxxx_eth_netdev0,
397
                "mcfxxxx-" CYGDAT_DEVS_ETH_MCFxxxx_NAME,
398
                mcfxxxx_eth_init,
399
                &mcfxxxx_eth_sc0);
400
 
401
static cyg_uint32   mcfxxxx_eth_isr_rx(cyg_vector_t, cyg_addrword_t);
402
static void         mcfxxxx_eth_dsr_rx(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
403
static cyg_uint32   mcfxxxx_eth_isr_tx(cyg_vector_t, cyg_addrword_t);
404
static void         mcfxxxx_eth_dsr_tx(cyg_vector_t, cyg_ucount32, cyg_addrword_t);
405
 
406
// ----------------------------------------------------------------------------
407
// The MAC address. Usually this will be supplied by the platform HAL, but some
408
// platforms may not have appropriate hardware. In that case the address will
409
// normally come from RedBoot's config info, with a fallback configurable
410
// value.
411
#ifdef CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC
412
 
413
# if !defined(HAL_MCFxxxx_ETH_GET_MAC_ADDRESS)
414
#  error Platform HAL should have provided a MAC address macro
415
# endif
416
 
417
#else
418
 
419
static cyg_uint8    mcfxxxx_eth_default_mac[6]  = { CYGDAT_DEVS_ETH_MCFxxxx_PLATFORM_MAC } ;
420
 
421
# ifdef CYGPKG_REDBOOT
422
#  include <pkgconf/redboot.h>
423
#  ifdef CYGSEM_REDBOOT_FLASH_CONFIG
424
#   include <redboot.h>
425
#   include <flash_config.h>
426
RedBoot_config_option("Network hardware address [MAC]",
427
                      mcfxxxx_mac,
428
                      ALWAYS_ENABLED, true,
429
                      CONFIG_ESA, 0
430
    );
431
#  endif
432
# endif
433
 
434
static void
435
mcfxxxx_eth_get_config_mac_address(cyg_uint8* mac)
436
{
437
    int mac_ok  = 0;
438
#ifdef CYGPKG_REDBOOT
439
# ifdef CYGSEM_REDBOOT_FLASH_CONFIG
440
    mac_ok  = flash_get_config("mcfxxxx_mac", mac, CONFIG_ESA);
441
# endif    
442
#else
443
    // Not in RedBoot. Do we have virtual vectors?
444
# ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
445
    mac_ok  = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, "mcfxxxx_mac", mac, CYGNUM_FLASH_CFG_TYPE_CONFIG_ESA);
446
# endif    
447
#endif
448
    if (! mac_ok) {
449
        memcpy(mac, mcfxxxx_eth_default_mac, 6);
450
    }
451
}
452
 
453
#endif // CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC
454
 
455
// ----------------------------------------------------------------------------
456
 
457
static bool
458
mcfxxxx_eth_init(struct cyg_netdevtab_entry* ndp)
459
{
460
    struct eth_drv_sc*      sc  = (struct eth_drv_sc*)  ndp->device_instance;
461
    struct  mcfxxxx_eth*    eth = (struct mcfxxxx_eth*) sc->driver_private;
462
    CYG_ADDRWORD            ptr;
463
    cyg_uint8*              rxbuffers;
464
    cyg_uint8*              txbuffer;
465
    cyg_uint32              i;
466
 
467
    DIAG(1, "entry");
468
 
469
#ifdef HAL_MCFxxxx_ETH_DETECT_DEVICE
470
    if (! HAL_MCFxxxx_ETH_DETECT_DEVICE(HAL_MCFxxxx_ETH0_BASE) ) {
471
        DIAG(1, "device disabled by HAL");
472
        return 0;
473
    }
474
#endif
475
 
476
#ifdef CYGSEM_HAL_USE_ROM_MONITOR
477
    // If we are debugging over RedBoot, it is possible that there is an
478
    // outgoing packet still queued up. Give it a chance to get out, a
479
    // couple of milliseconds should suffice.
480
    for (i = 0; i < 20; i++) {
481
        cyg_uint32              x_des_active;
482
        READ32(TDAR(eth), x_des_active);
483
        if (0 == (x_des_active & HAL_MCFxxxx_ETHx_TDAR_X_DES_ACTIVE)) {
484
            break;
485
        }
486
        HAL_DELAY_US(100);
487
    }
488
#endif
489
 
490
    // Set the whole ethernet device to disabled. Then the other registers
491
    // can be manipulated safely. The device gets activated in the start
492
    // function. The reset also sets all registers to their default values.
493
    WRITE32(ECR(eth), HAL_MCFxxxx_ETHx_ECR_RESET);
494
 
495
    eth->started        = 0;
496
    // While the reset is going on, sort out the buffers and buffer descriptors.
497
    // These should be aligned to a 16-byte boundary.
498
    ptr          = (CYG_ADDRWORD) eth->data;
499
    ptr          = (ptr + 15) & ~15;
500
    // First the rx buffers, n * 1520 bytes.
501
    rxbuffers    = (cyg_uint8*) ptr;
502
    ptr         += (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS * 1520);
503
    // We are still aligned to a 16-byte boundary. Now for the tx buffer if necessary.
504
    txbuffer     = (cyg_uint8*) ptr;
505
    ptr         += TX_BUFFER_SIZE;
506
    // Still aligned. The tx buffer descriptors. This will be an even number
507
    // so alignment is maintained.
508
    eth->txbds   = (hal_mcfxxxx_eth_buffer_descriptor*) ptr;
509
    ptr         += (TX_BUFFER_DESCRIPTOR_COUNT * sizeof(hal_mcfxxxx_eth_buffer_descriptor));
510
    // And finally the rx buffer descriptors.
511
    eth->rxbds   = (hal_mcfxxxx_eth_buffer_descriptor*) ptr;
512
 
513
    // We can fill in the buffer fields in the various rx buffer descriptors.
514
    // The length and flag fields are handled by _start().
515
    for (i = 0; i < CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS; i++) {
516
        eth->rxbds[i].ethbd_buffer   = rxbuffers;
517
        rxbuffers                   += 1520;
518
    }
519
 
520
    // Ditto for the tx buffers, if tx involves copying into an
521
    // aligned buffer. Only one entry in the ring buffer will be used
522
    // at a time, so the two buffer descriptors can share the same
523
    // buffer.
524
#ifdef TX_NEEDS_ALIGNMENT
525
    eth->txbds[0].ethbd_buffer  = txbuffer;
526
    eth->txbds[1].ethbd_buffer  = txbuffer;
527
#endif
528
 
529
    // rx_next_buffer tracks the next rx buffer descriptor which the
530
    // hardware may process.
531
    eth->rx_next_buffer     = 0;
532
 
533
    // Determine the MAC address. This has to be done by the platform HAL if possible
534
#ifdef CYGINT_DEVS_ETH_MCFxxxx_PLATFORM_MAC
535
    HAL_MCFxxxx_ETH_GET_MAC_ADDRESS(eth->mac);
536
#else
537
    mcfxxxx_eth_get_config_mac_address(eth->mac);
538
#endif
539
 
540
    // The interrupt handlers can also be installed here. All
541
    // interrupts are masked after the reset so nothing will
542
    // actually happen. Separate ISR's and DSR's are used for
543
    // the various interrupt sources.
544
    cyg_drv_interrupt_create(CYGNUM_HAL_ISR_ERX,
545
                             CYGNUM_DEVS_ETH_MCFxxxx_ISR_RX_PRIORITY,
546
                             (CYG_ADDRWORD) sc,
547
                             &mcfxxxx_eth_isr_rx,
548
                             &mcfxxxx_eth_dsr_rx,
549
                             &(eth->interrupt_handle_rx),
550
                             &(eth->interrupt_data_rx));
551
    cyg_drv_interrupt_attach(eth->interrupt_handle_rx);
552
    cyg_drv_interrupt_unmask(CYGNUM_HAL_ISR_ERX);
553
 
554
    cyg_drv_interrupt_create(CYGNUM_HAL_ISR_ETX,
555
                             CYGNUM_DEVS_ETH_MCFxxxx_ISR_TX_PRIORITY,
556
                             (CYG_ADDRWORD) sc,
557
                             &mcfxxxx_eth_isr_tx,
558
                             &mcfxxxx_eth_dsr_tx,
559
                             &(eth->interrupt_handle_tx),
560
                             &(eth->interrupt_data_tx));
561
    cyg_drv_interrupt_attach(eth->interrupt_handle_tx);
562
    cyg_drv_interrupt_unmask(CYGNUM_HAL_ISR_ETX);
563
 
564
    // An EBERR bus error will halt the ethernet device and raise an
565
    // interrupt. Arguably this should be handled here, but the assumption
566
    // is that the interrupt will never be raised because the driver will
567
    // never be given a bogus pointer.
568
 
569
    // Now the rest of the hardware can be initialized. First control
570
    // the GPIO pins, or whatever else needs doing on a per-processor
571
    // basis. For now the PHY is enabled unconditionally.
572
    // NOTE: much of this initialization code should be moved to a
573
    // separate reset function which can be called during start-up or
574
    // after an internal bus error.
575
#ifdef HAL_MCFxxxx_ETH0_PROC_INIT
576
    HAL_MCFxxxx_ETH0_PROC_INIT(1);
577
#endif    
578
#ifdef HAL_MCFxxxx_ETH0_PLATFORM_INIT
579
    HAL_MCFxxxx_ETH0_PLATFORM_INIT();
580
#endif    
581
 
582
    // Now for the ethernet device itself. The order used here is as
583
    // per the MCF5282 User's Manual.
584
    //
585
    // EIMR:     We want interrupts for complete frame transfers only
586
    WRITE32(EIMR(eth), HAL_MCFxxxx_ETHx_EIMR_TXF  | HAL_MCFxxxx_ETHx_EIMR_RXF);
587
 
588
    // EIR:     Cleared by the reset, but just in case.
589
    WRITE32(EIR(eth), 0xFFF80000);
590
    // TFWR:     Leave to its default value
591
#if defined(HAL_MCFxxxx_ETHx_IAUR)
592
    // IAUR & IALR.     The MCF5282 also has a unicast hash table, allowing the
593
    //                  device to accept frames sent to several different addresses.
594
    //                  This is not supported, only an exact match is used.
595
    WRITE32(IAUR(eth), 0x0);
596
    WRITE32(IALR(eth), 0x0);
597
#endif
598
    // Multicast hash table (GAUR & GALR). All 1's should be equivalent
599
    // to multi-all. All 0's should be equivalent to no-multi.
600
    WRITE32(GAUR(eth), 0x0);
601
    WRITE32(GALR(eth),  0x0);
602
    // MAC address (PAUR & PALR)
603
    i = (eth->mac[4] << 24) | (eth->mac[5] << 16);
604
    WRITE32(PAUR(eth), i);
605
    i = (eth->mac[0] << 24) | (eth->mac[1] << 16) | (eth->mac[2] << 8) | (eth->mac[3] << 0);
606
    WRITE32(PALR(eth), i);
607
#if defined(HAL_MCFxxxx_ETHx_OPD)
608
    // OPD: not actually used, but reset it to its default anyway
609
    WRITE32(OPD(eth), 0x00010000);
610
#endif
611
    // RCR:     Default to half-duplex mode. Promiscuous mode may get
612
    //          set by start().
613
    //          MII mode should be platform-specific, 7-wire mode is possible.
614
    //          On an mcf5282 the register also contains the max frame length
615
#if defined(HAL_MCFxxxx_ETHx_RCR_MAX_FL_VALUE)
616
    WRITE32(RCR(eth), HAL_MCFxxxx_ETHx_RCR_MAX_FL_VALUE | HAL_MCFxxxx_ETHx_RCR_MII_MODE | HAL_MCFxxxx_ETHx_RCR_DRT);
617
#else 
618
    WRITE32(RCR(eth), HAL_MCFxxxx_ETHx_RCR_MII_MODE | HAL_MCFxxxx_ETHx_RCR_DRT);
619
#endif    
620
    // TCR:     default to half-duplex
621
    WRITE32(TCR(eth), 0);
622
 
623
    // MSCR/MII_SPEED.
624
    // MDC_FREQUENCY == HZ / (4 * reg value)
625
    // MDC_FREQUENCY should be <= 2.5MHz
626
    WRITE32(MSCR(eth), ((CYGHWR_HAL_SYSTEM_CLOCK_HZ - 1) / (4 * 2500000)) + 1);
627
 
628
    // FRSR:       Leave to its default value
629
    // EMRBR:   The receiver buffer size is 1520 (must be a multiple of 16 and > frame size)
630
    WRITE32(EMRBR(eth), 1520);
631
    // The buffer descriptor rings, ERDSR & ETDSR
632
    WRITE32(ERDSR(eth), (cyg_uint32)eth->rxbds);
633
    WRITE32(ETDSR(eth), (cyg_uint32)eth->txbds);
634
 
635
    // Other registers:
636
    // IVEC: readonly
637
    // RDAR:        Set by start() and by the receive code
638
    // TDAR:        Set by start() and by the transmit code
639
    // MMFR:        There is no need to access the phy
640
    // R_BOUND:     Read-only
641
    // MFLR:        The default length is already 1518 bytes, so leave it.
642
    //              (This register does not exist on the 5282)
643
 
644
    // The ethernet device gets enabled in _start()
645
 
646
    DIAG(1, "calling higher-level");
647
 
648
    // Initialize the upper level driver
649
    (sc->funs->eth_drv->init)(sc, eth->mac);
650
 
651
    DIAG(1, "done");
652
 
653
    return 1;
654
}
655
 
656
// ----------------------------------------------------------------------------
657
 
658
// The driver only supports one transmit at a time, and a global is used
659
// to keep track of whether or not a transmit is in progress.
660
static int
661
mcfxxxx_eth_can_send(struct eth_drv_sc* sc)
662
{
663
    struct  mcfxxxx_eth*    eth = (struct mcfxxxx_eth*) sc->driver_private;
664
    if (eth->tx_can_send) {
665
        DIAG(1, "yes");
666
    } else {
667
        DIAG(3, "no");
668
    }
669
    return eth->tx_can_send;
670
}
671
 
672
// There are two implementations of the transmit code, one for the case
673
// where the data needs to be copied into an aligned buffer, the other
674
// for when the data can be used in place.
675
 
676
static void
677
mcfxxxx_eth_send(struct eth_drv_sc* sc,
678
                 struct eth_drv_sg* sg_list, int sg_len, int total_len,
679
                 unsigned long key)
680
{
681
    struct  mcfxxxx_eth*    eth     = (struct mcfxxxx_eth*) sc->driver_private;
682
    cyg_uint32              index   = eth->tx_index;
683
    int                     i;
684
 
685
    DIAG(1, " total_len %d", total_len);
686
    eth->tx_can_send    = 0;
687
    eth->tx_key         = key;
688
 
689
#ifdef TX_NEEDS_ALIGNMENT
690
    {
691
        // The aligned buffer is permanently held in the buffer descriptor.
692
        cyg_uint8*   buf = eth->txbds[index].ethbd_buffer;
693
        for (i = 0; i < sg_len; i++) {
694
            memcpy(buf, (cyg_uint8*) sg_list[i].buf, sg_list[i].len);
695
            buf += sg_list[i].len;
696
        }
697
        eth->txbds[index].ethbd_length  = total_len;
698
        eth->txbds[index].ethbd_flags  |= HAL_MCFxxxx_ETHx_TXBD_R + HAL_MCFxxxx_ETHx_TXBD_L + HAL_MCFxxxx_ETHx_TXBD_TC;
699
        DIAGPKT(1, "start", buf, total_len);
700
 
701
# ifdef HAL_DCACHE_STORE
702
        // Make sure the data has been written to memory.
703
        HAL_DCACHE_STORE(eth->txbds[index].ethbd_buffer, total_len);
704
# endif
705
    }
706
#else
707
    {
708
        cyg_uint32 last_index = index;
709
        for (i = 0; i < sg_len; i++) {
710
            eth->txbds[index].ethbd_flags   &= ~(HAL_MCFxxxx_ETHx_TXBD_L | HAL_MCFxxxx_ETHx_TXBD_TC);
711
            // The R bit can be set immediately, rather than in the
712
            // usual reverse order to prevent an underrun. This is
713
            // because a new send is only initiated when the transmit
714
            // engine is idle.
715
            eth->txbds[index].ethbd_flags   |= HAL_MCFxxxx_ETHx_TXBD_R;
716
            eth->txbds[index].ethbd_length   = sg_list[i].len;
717
            eth->txbds[index].ethbd_buffer   = (cyg_uint8*) sg_list[i].buf;
718
# ifdef HAL_DCACHE_STORE
719
            HAL_DCACHE_STORE(eth->txbds[index].ethbd_buffer, sg_list[i].len);
720
# endif            
721
            last_index  = index;
722
            if (index == (TX_BUFFER_DESCRIPTOR_COUNT - 1)) {
723
                index = 0;
724
            } else {
725
                index += 1;
726
            }
727
        }
728
        eth->txbds[last_index].ethbd_flags |= HAL_MCFxxxx_ETHx_TXBD_L | HAL_MCFxxxx_ETHx_TXBD_TC;
729
 
730
        eth->tx_index  = last_index;
731
        DIAGPKT(1, "start", sg_list[0].buf, total_len);
732
    }
733
#endif
734
 
735
    // Make sure all the buffer descriptors have been written to memory.
736
    // No need to invalidate the cache entries, the driver does not look
737
    // for any bits changed by the hardware except on the 5272 which
738
    // does not have a data cache at all.
739
#ifdef HAL_DCACHE_STORE    
740
    HAL_DCACHE_STORE(&(eth->txbds[0]), TX_BUFFER_DESCRIPTOR_COUNT * sizeof(hal_mcfxxxx_eth_buffer_descriptor));
741
#endif    
742
    WRITE32(TDAR(eth), HAL_MCFxxxx_ETHx_TDAR_X_DES_ACTIVE);
743
}
744
 
745
// The TX interrupt should only trigger when a whole frame has been
746
// transmitted. There is no need to worry about nested tx interrupts,
747
// at most one transmit can be in progress at any one time. Just
748
// clear the interrupt pending bit and leave the rest to the DSR.
749
static cyg_uint32
750
mcfxxxx_eth_isr_tx(cyg_vector_t vector, cyg_addrword_t data)
751
{
752
    HAL_WRITE_UINT32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_TXF | HAL_MCFxxxx_ETHx_EIR_TXB);
753
    return CYG_ISR_CALL_DSR;
754
}
755
 
756
static void
757
mcfxxxx_eth_dsr_tx(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
758
{
759
    struct eth_drv_sc*  sc      = (struct eth_drv_sc*) data;
760
    mcfxxxx_eth*        eth     = (mcfxxxx_eth*)(sc->driver_private);
761
 
762
    INCR_STAT(eth->interrupts);
763
#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
764
 
765
# if defined(CYGPKG_HAL_M68K_MCF5272)
766
    {
767
        cyg_uint16          flags;
768
        // The MCF5272 has all appropriate error flags in the tx buffer descriptor.
769
        flags = eth->txbds[eth->tx_index].ethbd_flags & (HAL_MCFxxxx_ETHx_TXBD_DEF | HAL_MCFxxxx_ETHx_TXBD_LC | HAL_MCFxxxx_ETHx_TXBD_RL |
770
                                                         HAL_MCFxxxx_ETHx_TXBD_RC_MASK | HAL_MCFxxxx_ETHx_TXBD_UN | HAL_MCFxxxx_ETHx_TXBD_CSL);
771
        if (0 == flags) {
772
            INCR_STAT(eth->tx_good);
773
        } else {
774
            if (flags & HAL_MCFxxxx_ETHx_TXBD_RL) {
775
                eth->tx_max_collisions    = 16;
776
                INCR_STAT(eth->tx_total_collisions);
777
            } else {
778
                int collisions = (flags & HAL_MCFxxxx_ETHx_TXBD_RC_MASK) >> HAL_MCFxxxx_ETHx_TXBD_RC_SHIFT;
779
                if (collisions > 0) {
780
                    INCR_STAT(eth->tx_total_collisions);
781
                    if (collisions > eth->tx_max_collisions) {
782
                        eth->tx_max_collisions = collisions;
783
                    }
784
                    if (1 == collisions) {
785
                        INCR_STAT(eth->tx_single_collisions);
786
                    } else {
787
                        INCR_STAT(eth->tx_mult_collisions);
788
                    }
789
                }
790
            }
791
            if (flags & HAL_MCFxxxx_ETHx_TXBD_LC) {
792
                INCR_STAT(eth->tx_late_collisions);
793
            }
794
            if (flags & HAL_MCFxxxx_ETHx_TXBD_UN) {
795
                INCR_STAT(eth->tx_underrun);
796
            }
797
            if (flags & HAL_MCFxxxx_ETHx_TXBD_CSL) {
798
                INCR_STAT(eth->tx_carrier_loss);
799
            }
800
            if (flags & HAL_MCFxxxx_ETHx_TXBD_DEF) {
801
                INCR_STAT(eth->tx_deferred);
802
            }
803
        }
804
    }
805
# else
806
    {
807
        // Assume MCF5282-compatible.
808
        // There are no error bits in the tx buffer descriptor. Instead it is
809
        // possible to check the interrupt status register, look for error
810
        // flags, and clear them.
811
        cyg_uint32  flags;
812
        HAL_READ_UINT32(EIR(eth), flags);
813
        flags &= (HAL_MCFxxxx_ETHx_EIR_LC | HAL_MCFxxxx_ETHx_EIR_RL | HAL_MCFxxxx_ETHx_EIR_UN);
814
        if (0 == flags) {
815
            INCR_STAT(eth->tx_good);
816
        } else {
817
            if (flags & HAL_MCFxxxx_ETHx_EIR_LC) {
818
                INCR_STAT(eth->tx_late_collisions);
819
            }
820
            if (flags & HAL_MCFxxxx_ETHx_EIR_RL) {
821
                INCR_STAT(eth->tx_total_collisions);
822
                INCR_STAT(eth->tx_mult_collisions);
823
            }
824
            if (flags & HAL_MCFxxxx_ETHx_EIR_UN) {
825
                INCR_STAT(eth->tx_underrun);
826
            }
827
            // Clear these interrupt flags
828
            HAL_WRITE_UINT32(EIR(eth), flags);
829
        }
830
    }
831
# endif
832
#endif
833
 
834
    eth->tx_done    = 1;
835
    eth->tx_index   = eth->tx_index + 1;
836
    if (TX_BUFFER_DESCRIPTOR_COUNT == eth->tx_index) {
837
        eth->tx_index = 0;
838
    }
839
    // There is no need to worry about cleaning up the buffer descriptors.
840
    // The hardware will have cleared the R bit, which is the only one that
841
    // must be cleared.
842
    DIAG(1, "packet sent");
843
    eth_drv_dsr(vector, count, data);
844
}
845
 
846
// ----------------------------------------------------------------------------
847
 
848
// A whole ethernet frame has been received and reported to higher-level
849
// code, which has allocated an mbuf. The frame is identified by the
850
// rx_next_buffer field of the mcfxxxx_eth structure, which gets set in
851
// deliver(). The data must be copied into the mbuf, and then the
852
// hardware needs to be told that this buffer is available again.
853
// The hardware stores a 4-byte checksum in the receive buffer
854
// which must be discarded.
855
static void
856
mcfxxxx_eth_recv(struct eth_drv_sc* sc, struct eth_drv_sg* sg_list, int sg_len)
857
{
858
    mcfxxxx_eth*    eth     = (mcfxxxx_eth*) sc->driver_private;
859
    int             index   = eth->rx_next_buffer;
860
    cyg_uint8*      buf     = eth->rxbds[index].ethbd_buffer;
861
    int             len     = eth->rx_len - 4;
862
    int             i;
863
 
864
    DIAGPKT(1, "packet received", buf, len);
865
 
866
    for (i = 0; (i < sg_len) && (len > 0); i++) {
867
        if (0 == sg_list[i].buf) {
868
            break;
869
        } else if (len <= sg_list[i].len) {
870
            memcpy((void*) sg_list[i].buf, buf, len);
871
            break;
872
        } else {
873
            memcpy((void*) sg_list[i].buf, buf, sg_list[i].len);
874
            buf += sg_list[i].len;
875
            len -= sg_list[i].len;
876
        }
877
    }
878
 
879
    // Once the data has been copied out of the RX buffer, clear the
880
    // cache lines ready for the next packet. Use an invalidate if
881
    // available, otherwise a flush.
882
#if defined(HAL_DCACHE_INVALIDATE)
883
    HAL_DCACHE_INVALIDATE(eth->rxbds[index].ethbd_buffer, eth->rx_len);
884
#elif defined(HAL_DCACHE_FLUSH)
885
    HAL_DCACHE_FLUSH(eth->rxbds[index].ethbd_buffer, eth->rx_len);
886
#endif
887
}
888
 
889
// The RX interrupt triggers whenever a whole frame has been received (or
890
// when an error has occurred). The hardware may be busy receiving into the
891
// next buffer.
892
//
893
// Because of the ring buffer several packets may arrive before the cpu gets
894
// around to processing them. It is possible to save a little bit of load
895
// by masking the rxf interrupt inside the ethernet device, then doing the
896
// acknowledge and an unmask inside the deliver() code.
897
static cyg_uint32
898
mcfxxxx_eth_isr_rx(cyg_vector_t vector, cyg_addrword_t data)
899
{
900
    WRITE32(EIMR(eth), HAL_MCFxxxx_ETHx_EIMR_TXF);
901
    return CYG_ISR_CALL_DSR;
902
}
903
 
904
static void
905
mcfxxxx_eth_dsr_rx(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
906
{
907
    struct eth_drv_sc*  sc  = (struct eth_drv_sc*) data;
908
    mcfxxxx_eth*        eth = (mcfxxxx_eth*)(sc->driver_private);
909
 
910
    INCR_STAT(eth->interrupts);
911
    eth->rx_rdy = 1;
912
    eth_drv_dsr(vector, count, data);
913
}
914
 
915
// ----------------------------------------------------------------------------
916
// deliver() is usually called from thread context, after the DSR has woken
917
// up the packet handling thread. It needs to report completed transmits so
918
// that higher-level code can release the mbuf, and report all received
919
// frames.
920
 
921
static void
922
mcfxxxx_eth_deliver(struct eth_drv_sc* sc)
923
{
924
    mcfxxxx_eth*    eth = (mcfxxxx_eth*) sc->driver_private;
925
 
926
    DIAG(1, "entry");
927
 
928
    if (eth->tx_done) {
929
        DIAG(1, "tx_done");
930
        INCR_STAT(eth->tx_count);
931
        eth->tx_done        = 0;
932
        eth->tx_can_send    = 1;
933
        (*sc->funs->eth_drv->tx_done)(sc, eth->tx_key, 1);
934
    }
935
 
936
    if (eth->rx_rdy) {
937
        int bd_emptied  = 0;
938
        int frame_found = 0;
939
 
940
        DIAG(1, "rx_rdy");
941
        eth->rx_rdy = 0;
942
 
943
        // Acknowledge any packets that have been received and will be processed
944
        // by the loop below. There is a small possibility of a packet arriving
945
        // in the middle of this loop, causing an rxf interrupt to become pending
946
        // even though the packet will get processed by the loop. This is harmless.
947
        // The rxb interrupt is cleared as well because that comes for free, making
948
        // debugging slightly easier.
949
        WRITE32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_RXF | HAL_MCFxxxx_ETHx_EIR_RXB);
950
 
951
        DIAG(1, "updated eir");
952
        // Loop while there are non-empty packets. This has to be done with a bit
953
        // of care. Packets should be processed in the right order where possible,
954
        // which means keeping track of the last packet received. However it is
955
        // necessary to check all the buffers - for some reason the hardware does
956
        // not always put the next frame in the expected buffer.
957
        //
958
        // This code interacts with any data cache in unpleasant ways. A buffer
959
        // descriptor is only 8 bytes, i.e. half a cache line, and since
960
        // typically the system is configured with several rx buffers some of
961
        // these may get updated by the hardware at any time. The only safe
962
        // way to handle this is to disable the data cache when accessing the
963
        // rx buffer descriptors and thus make sure that there are never any
964
        // modified cachelines for the tx buffer descriptors.
965
        do {
966
            int         current;
967
            int         i;
968
 
969
            current     = eth->rx_next_buffer;
970
            frame_found = 0;
971
 
972
            for (i = 0; i < CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS; i++) {
973
                // Note: these absolutely must be held in registers. The package's
974
                // CDL imposes constraints to ensure the driver is built with
975
                // sufficient optimization.
976
                register cyg_uint16 flags;
977
                register cyg_uint16 len;
978
                register hal_mcfxxxx_eth_buffer_descriptor* rxbd = &(eth->rxbds[current]);
979
#if defined(HAL_DCACHE_SIZE) && (HAL_DCACHE_SIZE > 0)
980
                register int cache_enabled;
981
                HAL_DCACHE_IS_ENABLED(cache_enabled);
982
                if (cache_enabled) {
983
                    register int ints_enabled;
984
                    HAL_DISABLE_INTERRUPTS(ints_enabled);
985
                    HAL_DCACHE_DISABLE();
986
                    flags   = rxbd->ethbd_flags;
987
                    len     = rxbd->ethbd_length;
988
                    if (! (flags & HAL_MCFxxxx_ETHx_RXBD_E)) {
989
                        rxbd->ethbd_flags  = (flags & HAL_MCFxxxx_ETHx_RXBD_W) | HAL_MCFxxxx_ETHx_RXBD_E;
990
                        rxbd->ethbd_length = 1518;
991
                    }
992
                    HAL_DCACHE_ENABLE();
993
                    HAL_RESTORE_INTERRUPTS(ints_enabled);
994
                } else
995
#endif
996
                {
997
                    flags   = rxbd->ethbd_flags;
998
                    len     = rxbd->ethbd_length;
999
                    if (! (flags & HAL_MCFxxxx_ETHx_RXBD_E)) {
1000
                        rxbd->ethbd_flags  = (flags & HAL_MCFxxxx_ETHx_RXBD_W) | HAL_MCFxxxx_ETHx_RXBD_E;
1001
                        rxbd->ethbd_length = 1518;
1002
                    }
1003
                }
1004
 
1005
                if (flags & HAL_MCFxxxx_ETHx_RXBD_E) {
1006
                    current = (current == (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS - 1)) ? 0 : (current + 1);
1007
                    continue;
1008
                }
1009
 
1010
                // Full frames should fill one buffer. However if an over-sized frame
1011
                // is received then the first 1520 bytes will go into one buffer, the
1012
                // remaining into the next. The LG flag will get set only in the last
1013
                // buffer descriptor. Just mark the first buffer as empty after the
1014
                // if.
1015
                if (flags & HAL_MCFxxxx_ETHx_RXBD_L) {
1016
                    // We have the last frame in a packet.
1017
#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
1018
                    INCR_STAT(eth->rx_count);
1019
                    if (flags & HAL_MCFxxxx_ETHx_RXBD_OV) {
1020
                        // An overrun does not invalidate the current frame
1021
                        INCR_STAT(eth->rx_overrun_errors);
1022
                    }
1023
#endif
1024
 
1025
                    if (flags & (HAL_MCFxxxx_ETHx_RXBD_LG | HAL_MCFxxxx_ETHx_RXBD_NO | HAL_MCFxxxx_ETHx_RXBD_CR | HAL_MCFxxxx_ETHx_RXBD_TR)) {
1026
                        // The packet is invalid and should be discarded.
1027
#ifdef CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS
1028
                        if (flags & (HAL_MCFxxxx_ETHx_RXBD_LG | HAL_MCFxxxx_ETHx_RXBD_TR)) {
1029
                            INCR_STAT(eth->rx_too_long_frames);
1030
                        }
1031
                        if (flags & HAL_MCFxxxx_ETHx_RXBD_NO) {
1032
                            INCR_STAT(eth->rx_align_errors);
1033
                        }
1034
                        if (flags & HAL_MCFxxxx_ETHx_RXBD_CR) {
1035
                            INCR_STAT(eth->rx_crc_errors);
1036
                        }
1037
#endif
1038
                    } else {
1039
                        // A valid packet
1040
                        INCR_STAT(eth->rx_good);
1041
                        eth->rx_len         = len;
1042
                        eth->rx_next_buffer = current;
1043
                        (*sc->funs->eth_drv->recv)(sc, len - 4);
1044
                    }
1045
                }
1046
 
1047
                // Move on to the next buffer descriptor.
1048
                frame_found                 = 1;
1049
                bd_emptied                  = 1;
1050
                eth->rx_next_buffer         = (current == (CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS - 1)) ? 0 : (current + 1);
1051
                break;
1052
            }
1053
        } while(frame_found);
1054
 
1055
        // If at least one buffer was marked as now empty, inform the hardware.
1056
        if (bd_emptied) {
1057
            WRITE32(RDAR(eth), HAL_MCFxxxx_ETHx_RDAR_R_DES_ACTIVE);
1058
        }
1059
    }
1060
 
1061
    // And make sure rx interrupts are unmasked again.
1062
    WRITE32(EIMR(eth), HAL_MCFxxxx_ETHx_EIMR_TXF  | HAL_MCFxxxx_ETHx_EIMR_RXF);
1063
}
1064
 
1065
// ----------------------------------------------------------------------------
1066
 
1067
// Polling does not need any special action, just check for pending interrupts
1068
// and act as if an interrupt had occurred.
1069
static void
1070
mcfxxxx_eth_poll(struct eth_drv_sc* sc)
1071
{
1072
    struct  mcfxxxx_eth*    eth = (struct mcfxxxx_eth*) sc->driver_private;
1073
    cyg_uint32              eir;
1074
 
1075
    DIAG(4, "entry");
1076
 
1077
    READ32(EIR(eth), eir);
1078
 
1079
    if (eir & HAL_MCFxxxx_ETHx_EIR_TXF) {
1080
        WRITE32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_TXF | HAL_MCFxxxx_ETHx_EIR_TXB);
1081
        eth->tx_done    = 1;
1082
        eth->tx_index   = eth->tx_index + 1;
1083
        if (TX_BUFFER_DESCRIPTOR_COUNT == eth->tx_index) {
1084
            eth->tx_index = 0;
1085
        }
1086
    }
1087
    if (eir & HAL_MCFxxxx_ETHx_EIR_RXF) {
1088
        eth->rx_rdy     = 1;
1089
    }
1090
    if (eth->tx_done || eth->rx_rdy) {
1091
        mcfxxxx_eth_deliver(sc);
1092
    }
1093
}
1094
 
1095
// intvector() is used by RedBoot/stubs to ensure ctrl-C will get through
1096
// if ethernet is used for the debug channel.
1097
static int
1098
mcfxxxx_eth_int_vector(struct eth_drv_sc* sc)
1099
{
1100
    return CYGNUM_HAL_ISR_ERX;
1101
}
1102
 
1103
// ----------------------------------------------------------------------------
1104
 
1105
// SET_MAC_ADDRESS is straightforward, it just requires updating two registers.
1106
// SET_MC_ALL and SET_MC_LIST can be implemented by setting all bits in the
1107
// hash table. That should cause the hardware to match all multicast packets.
1108
 
1109
static int
1110
mcfxxxx_eth_ioctl(struct eth_drv_sc* sc, unsigned long key, void* data, int data_length)
1111
{
1112
    mcfxxxx_eth*    eth = (mcfxxxx_eth*) sc->driver_private;
1113
 
1114
    DIAG(1, "entry");
1115
 
1116
    switch(key) {
1117
      case ETH_DRV_SET_MAC_ADDRESS:
1118
        {
1119
            cyg_uint32  reg;
1120
            memcpy(eth->mac, data, 6);
1121
            reg = (eth->mac[4] << 24) | (eth->mac[5] << 16);
1122
            WRITE32(PAUR(eth), reg);
1123
            reg = (eth->mac[0] << 24) | (eth->mac[1] << 16) | (eth->mac[2] << 8) | (eth->mac[3] << 0);
1124
            WRITE32(PALR(eth), reg);
1125
            return 0;
1126
        }
1127
 
1128
      case ETH_DRV_SET_MC_ALL:
1129
      case ETH_DRV_SET_MC_LIST:
1130
        {
1131
            WRITE32(GAUR(eth), 0xFFFFFFFF);
1132
            WRITE32(GALR(eth),  0xFFFFFFFF);
1133
            return 0;
1134
        }
1135
#if defined(CYGFUN_DEVS_ETH_MCFxxxx_STATISTICS) && defined(ETH_DRV_GET_IF_STATS_UD)
1136
      case ETH_DRV_GET_IF_STATS_UD:
1137
      case ETH_DRV_GET_IF_STATS:
1138
        {
1139
            struct ether_drv_stats* stats   = (struct ether_drv_stats*) data;
1140
            cyg_uint32              tcr;
1141
 
1142
            strcpy(stats->description, "Freescale MCFxxxx ethernet device");
1143
            stats->snmp_chipset[0]      = '\0';
1144
            READ32(TCR(eth), tcr);
1145
            if (0 == (tcr & HAL_MCFxxxx_ETHx_TCR_FDEN)) {
1146
                stats->duplex               = 2;                // simplex
1147
            } else {
1148
                stats->duplex               = 3;                // full duplex
1149
            }
1150
            stats->operational          = eth->started ? 3 : 2;
1151
            stats->speed                = 10 * 1000000;     // assume 10MHz. This would require querying the phy
1152
            stats->supports_dot3        = 1;
1153
            stats->tx_queue_len         = 1;                // fixed by the driver design
1154
            stats->tx_dropped           = 0;                // can_send() is robust
1155
 
1156
            stats->interrupts           = eth->interrupts;
1157
 
1158
            stats->tx_count             = eth->tx_count;
1159
            stats->tx_good              = eth->tx_good;
1160
            stats->tx_max_collisions    = eth->tx_max_collisions;
1161
            stats->tx_late_collisions   = eth->tx_late_collisions;
1162
            stats->tx_underrun          = eth->tx_underrun;
1163
            stats->tx_carrier_loss      = eth->tx_carrier_loss;
1164
            stats->tx_deferred          = eth->tx_deferred;
1165
            stats->tx_single_collisions = eth->tx_single_collisions;
1166
            stats->tx_mult_collisions   = eth->tx_mult_collisions;
1167
            stats->tx_total_collisions  = eth->tx_total_collisions;
1168
 
1169
            stats->rx_count             = eth->rx_count;
1170
            stats->rx_good              = eth->rx_good;
1171
            stats->rx_crc_errors        = eth->rx_crc_errors;
1172
            stats->rx_align_errors      = eth->rx_align_errors;
1173
            stats->rx_overrun_errors    = eth->rx_overrun_errors;
1174
            stats->rx_short_frames      = eth->rx_short_frames;
1175
            stats->rx_too_long_frames   = eth->rx_too_long_frames;
1176
 
1177
            return 0;
1178
        }
1179
#endif
1180
 
1181
      default:
1182
        return 1;
1183
    }
1184
}
1185
 
1186
// ----------------------------------------------------------------------------
1187
 
1188
// Starting involves setting up initial empty buffer descriptors, then
1189
// enabling the ethernet device. Optionally promiscuous mode needs to be
1190
// set as well.
1191
 
1192
#if 0
1193
static int
1194
mcfxxxx_eth_read_phy(int addr, int reg)
1195
{
1196
    cyg_uint32  events;
1197
    int         ints_state;
1198
    int         i;
1199
    int         result  = -1;
1200
 
1201
    HAL_DISABLE_INTERRUPTS(ints_state);
1202
    WRITE32(MMFR(eth),
1203
                     HAL_MCFxxxx_ETHx_MMFR_ST_VALUE |
1204
                     HAL_MCFxxxx_ETHx_MMFR_OP_READ |
1205
                     (addr << HAL_MCFxxxx_ETHx_MMFR_PA_SHIFT) |
1206
                     (reg << HAL_MCFxxxx_ETHx_MMFR_RA_SHIFT) |
1207
                     HAL_MCFxxxx_ETHx_MMFR_TA_VALUE |
1208
                     (0x00 << HAL_MCFxxxx_ETHx_MMFR_DATA_SHIFT));
1209
 
1210
    // When the phy has responded the MII interrupt bit should be set.
1211
    for (i = 0; i < 10; i++) {
1212
        // 16 bits * both ways @ 2.5MHz, should just take a few microseconds.
1213
        // This happens in a loop, just in case.
1214
        HAL_DELAY_US(10);
1215
        READ32(EIR(eth), events);
1216
        if (events & HAL_MCFxxxx_ETHx_EIR_MII) {
1217
            WRITE32(EIR(eth), HAL_MCFxxxx_ETHx_EIR_MII);
1218
            READ32(MMFR(eth), result);
1219
            result  &= 0x0000FFFF;
1220
            break;
1221
        }
1222
    }
1223
 
1224
    HAL_RESTORE_INTERRUPTS(ints_state);
1225
    return result;
1226
}
1227
#endif
1228
 
1229
static void
1230
mcfxxxx_eth_start(struct eth_drv_sc* sc, unsigned char* enaddr, int flags)
1231
{
1232
    mcfxxxx_eth*    eth = (mcfxxxx_eth*) sc->driver_private;
1233
    cyg_uint32      rcr;
1234
    int             i;
1235
 
1236
    if (eth->started) {
1237
        return;
1238
    }
1239
 
1240
    DIAG(1, "entry");
1241
 
1242
    eth->tx_can_send    = 1;
1243
    eth->tx_done        = 0;
1244
    eth->rx_rdy         = 0;
1245
 
1246
    // Clear all tx buffer descriptors, setting the WRAP bit on the last one.
1247
    for (i = 0; i < TX_BUFFER_DESCRIPTOR_COUNT; i++) {
1248
        eth->txbds[i].ethbd_flags     = 0;
1249
    }
1250
    eth->txbds[TX_BUFFER_DESCRIPTOR_COUNT - 1].ethbd_flags    = HAL_MCFxxxx_ETHx_TXBD_W;
1251
    eth->tx_index = 0;
1252
 
1253
    // Set all rx buffer descriptors to empty.
1254
    for (i = 0; i < CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS; i++) {
1255
        eth->rxbds[i].ethbd_flags   = HAL_MCFxxxx_ETHx_RXBD_E;
1256
        eth->rxbds[i].ethbd_length  = 1518;
1257
    }
1258
    eth->rxbds[CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS - 1].ethbd_flags = HAL_MCFxxxx_ETHx_RXBD_E | HAL_MCFxxxx_ETHx_RXBD_W;
1259
 
1260
    // None of the rx buffers should be in the cache so no need to invalidate.
1261
    // The rxbds must be written to memory. The txbds will be taken care of
1262
    // by the transmit code when there are packets to transmit.
1263
#ifdef HAL_DCACHE_STORE
1264
    HAL_DCACHE_STORE(&(eth->rxbds[0]), CYGNUM_DEVS_ETH_MCFxxxx_RXBUFFERS * sizeof(hal_mcfxxxx_eth_buffer_descriptor));
1265
#endif
1266
 
1267
#if 0
1268
    // Interact with the phy to see if the RCR DRT and X_CTRNL FDEN
1269
    // bits should be set. Default to half-duplex.
1270
    // NOTE: this should be conditional on the presence of a phy, and the
1271
    // platform should be able to override the default phy settings. It
1272
    // is also necessary to search the phy address space.
1273
    {
1274
        int     addr    = -1;
1275
        int     i;
1276
        int     reg;
1277
 
1278
        // Find the phy's address. If the phy is not present the id register
1279
        // will read as 0x00FFFF.
1280
        for (i = 0; i < 32; i++) {
1281
            reg = mcfxxxx_eth_read_phy(i, 2);
1282
            if ((-1 != reg) && (0x0000FFFF != reg)) {
1283
                addr = i;
1284
                break;
1285
            }
1286
        }
1287
 
1288
        if (-1 != addr) {
1289
            // Read the status register, especially the link bit
1290
            reg = mcfxxxx_eth_read_phy(addr, 1);
1291
            if (reg & 0x04) {
1292
                // The link is up. What was negotiated with the partner?
1293
                reg = mcfxxxx_eth_read_phy(addr, 5);
1294
                if (reg & 0x0140) {
1295
                    // Full duplex, either 100 or 10. Clear the RCR DRT bit, set
1296
                    // the TCR FDEN bit
1297
                    cyg_uint32  rcr;
1298
                    READ32(RCR(eth), rcr);
1299
                    WRITE32(RCR(eth), rcr & ~ HAL_MCFxxxx_ETHx_RCR_DRT);
1300
                    WRITE32(TCR(eth), HAL_MCFxxxx_ETHx_TCR_FDEN);
1301
                }
1302
            }
1303
        }
1304
    }
1305
#endif
1306
 
1307
    // The RCR register can have additional bits set on some processors,
1308
    // e.g. on the mcf5282 it contains the maximum frame length. Change it only
1309
    // by read/modify/write.
1310
    READ32(RCR(eth), rcr);
1311
#ifdef CYGPKG_NET    
1312
    if (flags & IFF_PROMISC) {
1313
        rcr |= HAL_MCFxxxx_ETHx_RCR_PROM;
1314
    } else {
1315
        rcr &= ~HAL_MCFxxxx_ETHx_RCR_PROM;
1316
    }
1317
#else
1318
    rcr &= ~HAL_MCFxxxx_ETHx_RCR_PROM;
1319
#endif
1320
    WRITE32(RCR(eth), rcr);
1321
 
1322
    // The hardware is now ready
1323
    // The documentation says that setting R_DES_ACTIVE could also be done before asserting
1324
    // ETHER_EN, but that appears incorrect: you'll never get any packets.
1325
    WRITE32(ECR(eth),  HAL_MCFxxxx_ETHx_ECR_ETHER_EN);
1326
    WRITE32(RDAR(eth), HAL_MCFxxxx_ETHx_RDAR_R_DES_ACTIVE);
1327
    WRITE32(TDAR(eth), HAL_MCFxxxx_ETHx_TDAR_X_DES_ACTIVE);
1328
 
1329
    eth->started = 1;
1330
 
1331
    DIAG(1, "done");
1332
}
1333
 
1334
// Stopping can be done simply by disabling the device, which causes
1335
// all transmits and receives to be aborted. There should be no further
1336
// interrupts.
1337
static void
1338
mcfxxxx_eth_stop(struct eth_drv_sc* sc)
1339
{
1340
    mcfxxxx_eth*    eth = (mcfxxxx_eth*) sc->driver_private;
1341
 
1342
    DIAG(1, "entry");
1343
 
1344
    eth->started    = 0;
1345
    WRITE32(ECR(eth), 0);
1346
    eth->tx_done    = 0;
1347
    eth->rx_rdy     = 0;
1348
    if (! eth->tx_can_send) {
1349
        (*sc->funs->eth_drv->tx_done)(sc, eth->tx_key, 1);
1350
        eth->tx_can_send    = 1;
1351
    }
1352
 
1353
    DIAG(1, "done");
1354
}

powered by: WebSVN 2.1.0

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