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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [eth/] [mips/] [upd985xx/] [v2_0/] [src/] [if_upd985xx.c] - Blame information for rev 622

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      if_upd985xx.c
4
//
5
//      Ethernet drivers
6
//      NEC UPD985XX device ethernet specific support
7
//
8
//==========================================================================
9
//####ECOSGPLCOPYRIGHTBEGIN####
10
// -------------------------------------------
11
// This file is part of eCos, the Embedded Configurable Operating System.
12
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13
//
14
// eCos is free software; you can redistribute it and/or modify it under
15
// the terms of the GNU General Public License as published by the Free
16
// Software Foundation; either version 2 or (at your option) any later version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19
// 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 along
24
// with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
//
27
// As a special exception, if other files instantiate templates or use macros
28
// or inline functions from this file, or you compile this file and link it
29
// with other works to produce a work based on this file, this file does not
30
// by itself cause the resulting work to be covered by the GNU General Public
31
// License. However the source code for this file must still be made available
32
// in accordance with section (3) of the GNU General Public License.
33
//
34
// This exception does not invalidate any other reasons why a work based on
35
// this file might be covered by the GNU General Public License.
36
//
37
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38
// at http://sources.redhat.com/ecos/ecos-license/
39
// -------------------------------------------
40
//####ECOSGPLCOPYRIGHTEND####
41
//####BSDCOPYRIGHTBEGIN####
42
//
43
// -------------------------------------------
44
//
45
// Portions of this software may have been derived from OpenBSD or other sources,
46
// and are covered by the appropriate copyright disclaimers included herein.
47
//
48
// -------------------------------------------
49
//
50
//####BSDCOPYRIGHTEND####
51
//==========================================================================
52
//#####DESCRIPTIONBEGIN####
53
//
54
// Author(s):    hmt, gthomas
55
// Contributors:
56
// Date:         2001-06-28
57
// Purpose:      
58
// Description:  hardware driver for uPD985xx ethernet devices
59
//              
60
//
61
//####DESCRIPTIONEND####
62
//
63
//==========================================================================
64
 
65
#include <pkgconf/system.h>
66
#include <pkgconf/devs_eth_mips_upd985xx.h>
67
#include <pkgconf/io_eth_drivers.h>
68
 
69
#include <cyg/infra/cyg_type.h>
70
#include <cyg/infra/cyg_ass.h>
71
#include <cyg/hal/hal_arch.h>
72
#include <cyg/hal/hal_intr.h>
73
#include <cyg/hal/hal_cache.h>
74
#include <cyg/infra/diag.h>
75
#include <cyg/hal/drv_api.h>
76
#include <cyg/io/eth/netdev.h>
77
#include <cyg/io/eth/eth_drv.h>
78
 
79
#ifdef CYGPKG_NET
80
#include <pkgconf/net.h>
81
#include <net/if.h>  /* Needed for struct ifnet */
82
#else
83
#include <cyg/hal/hal_if.h>
84
#endif
85
 
86
#include <cyg/devs/eth/upd985xx_eth.h>
87
 
88
#include <cyg/io/eth/eth_drv_stats.h>
89
 
90
// ------------------------------------------------------------------------
91
 
92
#ifdef CYGDBG_DEVS_ETH_MIPS_UPD985XX_CHATTER
93
#define nDEBUG_TRAFFIC  // This one prints stuff as packets come and go
94
#define nDEBUG_IOCTL    // ioctl() call printing
95
#define DEBUG           // Startup printing mainly
96
#endif
97
 
98
#define os_printf diag_printf
99
#define db_printf diag_printf
100
 
101
#define STATIC static
102
 
103
// ------------------------------------------------------------------------
104
// I/O access macros as inlines for later changes to >1 device?
105
//
106
// (If we need to do this, then these macros would *assume* the
107
//  presence of a valid p_eth_upd985xx just like we always have)
108
 
109
static inline void OUTL( volatile cyg_uint32 *io_address, cyg_uint32 value )
110
{   *io_address = value;   }
111
 
112
static inline cyg_uint32 INL( volatile cyg_uint32 *io_address )
113
{   return *io_address;    }
114
 
115
// These map cachable addresses to uncachable ones and vice versa.
116
// This is all fixed on MIPS.  8-9xxxxxxx uncachable, A-Bxxxxxxx cachable.
117
#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))
118
static inline cyg_uint8 *virt_to_bus(cyg_uint32 p_memory)
119
{
120
    return (cyg_uint8 *)(0xa0000000u + (p_memory  & ~0xe0000000u));
121
}
122
#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_))
123
static inline cyg_uint8 *bus_to_virt(cyg_uint32 p_memory)
124
{
125
    return (cyg_uint8 *)(0x80000000u + (p_memory  & ~0xe0000000u));
126
}
127
 
128
 
129
// ------------------------------------------------------------------------
130
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_S1
131
#define FLUSH_WRITES() CYG_MACRO_START          \
132
    (void) INL( ETH_RXSR );                     \
133
CYG_MACRO_END
134
#else
135
#define FLUSH_WRITES() CYG_EMPTY_STATEMENT
136
#endif
137
 
138
// ------------------------------------------------------------------------
139
//
140
//                      DEVICES AND PACKET QUEUES
141
//
142
// ------------------------------------------------------------------------
143
 
144
// 128 bytes extra for VLAN packets should be enough; AFAICT usually the
145
// encapsulation is only 4 or 10 bytes extra.
146
#define MAX_ETHERNET_PACKET_SIZE  1536  // Ethernet Rx packet size
147
#define MAX_OVERSIZE_PACKET_SIZE  1664  // VLAN Rx packet size
148
#define MAX_RX_PACKET_SIZE        MAX_OVERSIZE_PACKET_SIZE
149
 
150
#define NUM_RXBUFS (8)
151
 
152
// This one is the hardware definition.
153
struct bufdesc {
154
    volatile cyg_uint32 attr;
155
    cyg_uint8 *ptr;
156
};
157
 
158
// Rx databuffer.
159
STATIC cyg_uint8 rx_databuf[ NUM_RXBUFS ] [ MAX_RX_PACKET_SIZE ];
160
 
161
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
162
// Tx databuffer
163
STATIC cyg_uint8 tx_databuf[ MAX_RX_PACKET_SIZE ];
164
#endif
165
 
166
struct eth_upd985xx {
167
    cyg_uint8 active, index, tx_busy, mac_addr_ok;
168
    cyg_uint8 vector; // interrupt numbers are small
169
    cyg_uint8 phy_status; // from PHY_STATUS_ flags below
170
    cyg_uint8 hardwired_esa;
171
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
172
    cyg_uint8 promisc;
173
#endif
174
    cyg_uint8 mac_address[6];
175
 
176
    cyg_handle_t   interrupt_handle;
177
    cyg_interrupt  interrupt_object;
178
 
179
    struct cyg_netdevtab_entry *ndp;
180
 
181
    // these shall hold uncached addresses of the structures following...
182
    volatile struct bufdesc *txring;
183
    volatile struct bufdesc *rxring_active;
184
    volatile struct bufdesc *rxring_next;
185
    int rxring_active_index;
186
    int rxring_next_index;
187
    cyg_uint32 intrs;
188
    cyg_uint32 tx_keys[1];
189
 
190
    // -----------------------------------------------------------------
191
    // Statistics counters
192
    cyg_uint32 count_rx_resource;
193
    cyg_uint32 count_rx_restart;
194
    cyg_uint32 count_interrupts;
195
    cyg_uint32 count_bad_isr_restarts;
196
    cyg_uint32 count_bad_tx_completion;
197
 
198
    // -----------------------------------------------------------------
199
    // DO NOT ACCESS THESE DIRECTLY - THE DEVICE HAS TO SEE THEM UNCACHED
200
 
201
    // Initially, enough for one whole transmission to be described in one go,
202
    // plus a null link on the end.
203
    struct bufdesc tx_bufdesc[ MAX_ETH_DRV_SG + 2 ];
204
 
205
    // Pending rx buffers, of full size.
206
    struct bufdesc rx_bufdesc[ NUM_RXBUFS+1 ];
207
 
208
    // -----------------------------------------------------------------
209
};
210
 
211
struct eth_upd985xx eth_upd985xx[CYGNUM_DEVS_ETH_MIPS_UPD985XX_DEV_COUNT] = {
212
    {
213
        index: 0,
214
        vector: CYGNUM_HAL_INTERRUPT_ETHER,
215
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
216
        promisc: 0,
217
#endif
218
#ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA
219
        hardwired_esa: 1,
220
        mac_address: CYGDAT_DEVS_ETH_UPD985XX_ETH0_ESA,
221
        mac_addr_ok: 1,
222
#else
223
        hardwired_esa: 0,
224
        mac_addr_ok: 0,
225
#endif
226
    }
227
};
228
 
229
// eth0
230
 
231
ETH_DRV_SC(upd985xx_sc0,
232
           &eth_upd985xx[0],            // Driver specific data
233
           CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME, // name for this interface
234
           eth_upd985xx_start,
235
           eth_upd985xx_stop,
236
           eth_upd985xx_ioctl,
237
           eth_upd985xx_can_send,
238
           eth_upd985xx_send,
239
           eth_upd985xx_recv,
240
           eth_upd985xx_deliver,
241
           eth_upd985xx_poll,
242
           eth_upd985xx_int_vector
243
    );
244
 
245
NETDEVTAB_ENTRY(upd985xx_netdev0,
246
                "upd985xx-" CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME,
247
                upd985xx_eth_upd985xx_init,
248
                &upd985xx_sc0);
249
 
250
 
251
// This is in a macro so that if more devices arrive it can easily be changed
252
#define CHECK_NDP_SC_LINK() CYG_MACRO_START                              \
253
    CYG_ASSERT( ((void *)ndp == (void *)&upd985xx_netdev0), "Bad ndp" ); \
254
    CYG_ASSERT( ((void *)sc == (void *)&upd985xx_sc0), "Bad sc" );       \
255
    CYG_ASSERT( (void *)p_eth_upd985xx == sc->driver_private,            \
256
                "sc pointer bad" );                                      \
257
    CYG_ASSERT( (void *)p_eth_upd985xx == (void *)&eth_upd985xx[0],      \
258
                "bad p_eth_upd985x" );                                   \
259
CYG_MACRO_END
260
 
261
#define NUM_ELEMENTS( _x_ ) (sizeof( (_x_) ) / sizeof( (_x_[0]) ) )
262
 
263
// ------------------------------------------------------------------------
264
//
265
//                       FUNCTION PROTOTYPES
266
//
267
// ------------------------------------------------------------------------
268
STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx);
269
STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx);
270
STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx);
271
STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx);
272
 
273
#ifdef CYGPKG_NET
274
STATIC int eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx,
275
                                  int promisc, int oversized);
276
#endif
277
 
278
STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx);
279
STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx);
280
 
281
#define PHY_STATUS_LINK    (1)
282
#define PHY_STATUS_FDX     (2)
283
#define PHY_STATUS_100MBPS (4)
284
STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx );
285
STATIC int eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data );
286
 
287
// ------------------------------------------------------------------------
288
//
289
//                       MII ACCESS TO PHY DEVICE
290
//
291
// ------------------------------------------------------------------------
292
 
293
STATIC cyg_bool mii_read( cyg_uint32 reg, cyg_uint32 *pvalue,
294
                          struct eth_upd985xx *p_eth_upd985xx )
295
{
296
    int i = 1000;
297
    // wait a bit for it to be idle
298
    while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
299
                  & INL(ETH_MIND)) )
300
        if ( --i < 0 )
301
            return false;
302
    // Tell it the register address and PHY address
303
    OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg );
304
    OUTL( ETH_MCMD, ETH_MCMD_RSTAT ); // "do a read"
305
    // wait for the read to complete
306
    while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
307
                  & INL(ETH_MIND)) )
308
        if ( --i < 0 )
309
            return false;
310
    // so get the data
311
    *pvalue = INL( ETH_MRDD );
312
    return true;
313
}
314
 
315
#if 0
316
STATIC cyg_bool mii_write( cyg_uint32 reg, cyg_uint32 value,
317
                          struct eth_upd985xx *p_eth_upd985xx )
318
{
319
    int i = 1000;
320
    // wait a bit for it to be idle
321
    while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
322
                  & INL(ETH_MIND)) )
323
        if ( --i < 0 )
324
            return false;
325
    // Tell it the register address and PHY address
326
    OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg );
327
    // And write the data:
328
    OUTL( ETH_MWTD, value );
329
    // wait a bit for it to be idle
330
    while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
331
                  & INL(ETH_MIND)) )
332
        if ( --i < 0 )
333
            return false;
334
    return true;
335
}
336
#endif
337
 
338
// ------------------------------------------------------------------------
339
//
340
//                       INTERRUPT HANDLERS
341
//
342
// ------------------------------------------------------------------------
343
 
344
STATIC cyg_uint32 eth_isr(cyg_vector_t vector, cyg_addrword_t data)
345
{
346
    cyg_drv_interrupt_mask( vector );
347
 
348
    return CYG_ISR_CALL_DSR;        // schedule DSR
349
}
350
 
351
// ------------------------------------------------------------------------
352
// This is a callback from the higher level thread in consequence of the DSR
353
STATIC void
354
eth_upd985xx_deliver(struct eth_drv_sc *sc)
355
{
356
    register int intrs;
357
    struct eth_upd985xx *p_eth_upd985xx;
358
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
359
 
360
    p_eth_upd985xx->count_interrupts++;
361
 
362
    intrs = INL( ETH_ISR ); // Read-clear
363
    // Acknowledge once at the start anyway to prevent an interrupt loop in
364
    // case of a transient - interrupts latch in the interrupt controller
365
    // as well as in the ethernet device.
366
    cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
367
 
368
#ifdef DEBUG_TRAFFIC
369
    os_printf("\n[[[[[[[ Deliver intrs = %x\n", intrs );
370
#endif
371
 
372
    // Guard possible external entry points
373
    if ( ! p_eth_upd985xx->active )
374
        return; // without unmasking the interrupt
375
 
376
    while ( intrs ) {
377
        if ( 0xffff0000 & intrs ) {
378
            // Then something very bad has happened
379
            p_eth_upd985xx->count_bad_isr_restarts++;
380
            CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" );
381
            eth_upd985xx_stop( sc );
382
            eth_upd985xx_start( sc, NULL, 0 );
383
            intrs = INL( ETH_ISR ); // Read-clear
384
        }
385
        p_eth_upd985xx->intrs = intrs;
386
        if ( ( ETH_ISR_XMTDN | ETH_ISR_TABR ) & intrs ) {
387
            // Scan for completed Txen and inform the stack
388
            TxDone(p_eth_upd985xx);
389
        }
390
        if ( ( ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU ) & intrs ) {
391
            // Pass any rx data up the stack
392
            PacketRxReady(p_eth_upd985xx);
393
        }
394
        // Now we have made the interrupt causes go away, acknowledge and
395
        // *then* read the ISR again.  That way the race can result in a
396
        // spurious interrupt rather than a lost interrupt.
397
        cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
398
        intrs = INL( ETH_ISR ); // Read-clear
399
#ifdef DEBUG_TRAFFIC
400
        if ( intrs )
401
            os_printf("------- Again intrs = %x\n", intrs );
402
#endif
403
    }
404
#ifdef DEBUG_TRAFFIC
405
    os_printf("]]]]]]]] Done intrs = %x\n\n", intrs );
406
#endif
407
 
408
    cyg_drv_interrupt_unmask(p_eth_upd985xx->vector);
409
}
410
 
411
// ------------------------------------------------------------------------
412
// Device table entry to operate the chip in a polled mode.
413
// Only diddle the interface we were asked to!
414
 
415
STATIC void
416
eth_upd985xx_poll(struct eth_drv_sc *sc)
417
{
418
    struct eth_upd985xx *p_eth_upd985xx;
419
 
420
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
421
 
422
    // As it happens, this driver always requests the DSR to be called:
423
    (void)eth_isr( p_eth_upd985xx->vector, (cyg_addrword_t)sc );
424
    eth_upd985xx_deliver( sc );
425
}
426
 
427
// ------------------------------------------------------------------------
428
// Determine interrupt vector used by a device - for attaching GDB stubs
429
// packet handler.
430
STATIC int
431
eth_upd985xx_int_vector(struct eth_drv_sc *sc)
432
{
433
    struct eth_upd985xx *p_eth_upd985xx;
434
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
435
    return (p_eth_upd985xx->vector);
436
}
437
 
438
// ------------------------------------------------------------------------
439
 
440
STATIC int
441
eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data )
442
{
443
    cyg_uint8 *p = (cyg_uint8 *)data;
444
    cyg_uint8 *mac_address;
445
 
446
    mac_address = &p_eth_upd985xx->mac_address[0];
447
 
448
    mac_address[5] = p[5];
449
    mac_address[4] = p[4];
450
    mac_address[3] = p[3];
451
    mac_address[2] = p[2];
452
    mac_address[1] = p[1];
453
    mac_address[0] = p[0];
454
 
455
    p_eth_upd985xx->mac_addr_ok = 1;
456
 
457
    // Set the ESA in the device regs
458
    OUTL( ETH_LSA2,
459
          (p_eth_upd985xx->mac_address[1]) |
460
          (p_eth_upd985xx->mac_address[0] << 8 ) );
461
    OUTL( ETH_LSA1,
462
          (p_eth_upd985xx->mac_address[5]) |
463
          (p_eth_upd985xx->mac_address[4] << 8 ) |
464
          (p_eth_upd985xx->mac_address[3] << 16 ) |
465
          (p_eth_upd985xx->mac_address[2] << 24) );
466
 
467
    return 0; // OK
468
}
469
 
470
// ------------------------------------------------------------------------
471
 
472
STATIC void
473
eth_upd985xx_reset( struct eth_upd985xx *p_eth_upd985xx )
474
{
475
    int i;
476
 
477
    // Reset whole device: Software Reset (clears automatically)
478
    OUTL( ETH_CCR, ETH_CCR_SRT );
479
    for ( i = 0; i < 10000; i++ ) /* nothing */;
480
    // Reset internal units
481
    OUTL( ETH_MACC2, ETH_MACC2_MCRST | ETH_MACC2_RFRST | ETH_MACC2_TFRST );
482
    for ( i = 0; i < 10000; i++ ) /* nothing */;
483
    FLUSH_WRITES();
484
    OUTL( ETH_MACC2, 0 ); // (and release reset)
485
    // Enable CRC adding, padding
486
    FLUSH_WRITES();
487
    OUTL( ETH_MACC1,
488
          ETH_MACC1_CRCEN | ETH_MACC1_PADEN |
489
          ETH_MACC1_TXFC | ETH_MACC1_RXFC | ETH_MACC1_PARF );
490
    FLUSH_WRITES();
491
    OUTL( ETH_MACC2, ETH_MACC2_APD ); // Auto VLAN pad
492
    FLUSH_WRITES();
493
    OUTL( ETH_HT1, 0 );
494
    FLUSH_WRITES();
495
    OUTL( ETH_HT2, 0 );
496
 
497
    // Enable rx of broadcasts, multicasts, but not promiscuous...
498
    FLUSH_WRITES();
499
#if defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 ) && \
500
    !defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY )
501
    // Unless we are faking it.
502
    OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM | ETH_AFR_PRO );
503
#else
504
    OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM );
505
#endif
506
 
507
    FLUSH_WRITES();
508
    OUTL( ETH_IPGT, 0x00000013 );
509
    FLUSH_WRITES();
510
    OUTL( ETH_IPGR, 0x00000e13 );
511
    FLUSH_WRITES();
512
    OUTL( ETH_CLRT, 0x0000380f );
513
    FLUSH_WRITES();
514
    OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE );
515
 
516
    // Select a clock for the MII
517
    FLUSH_WRITES();
518
    OUTL( ETH_MIIC, ETH_MIIC_66 ); // Example code sets to 66.
519
    // Set VLAN type reg
520
    FLUSH_WRITES();
521
    OUTL( ETH_VLTP, ETH_VLTP_VLTP );
522
 
523
    // Set the ESA in the device regs
524
    if ( p_eth_upd985xx->mac_addr_ok ) {
525
        FLUSH_WRITES();
526
        OUTL( ETH_LSA2,
527
              (p_eth_upd985xx->mac_address[1]) |
528
              (p_eth_upd985xx->mac_address[0] << 8 ) );
529
        FLUSH_WRITES();
530
        OUTL( ETH_LSA1,
531
              (p_eth_upd985xx->mac_address[5]) |
532
              (p_eth_upd985xx->mac_address[4] << 8 ) |
533
              (p_eth_upd985xx->mac_address[3] << 16 ) |
534
              (p_eth_upd985xx->mac_address[2] << 24) );
535
    }
536
 
537
    FLUSH_WRITES();
538
    OUTL( ETH_RXFCR, ETH_RXFCR_UWM_DEFAULT |
539
                     ETH_RXFCR_LWM_DEFAULT | ETH_RXFCR_DRTH16W );
540
 
541
    FLUSH_WRITES();
542
    // Fault E4 - use only 32 for FLTH, not the previously recommended 48 (words)
543
    // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4
544
    // but no config opt is provided.
545
    OUTL( ETH_TXFCR, ETH_TXFCR_TPTV_DEFAULT |
546
                     ETH_TXFCR_TX_DRTH_DEFAULT | (32 << ETH_TXFCR_TX_FLTH_SHIFT) );
547
 
548
    // Transmit and receive config regs we hit when enabling those
549
    // functions separately, and the wet string end of the receiver
550
    // which is controlled by   MACC1 |= ETH_MACC1_SRXEN;
551
 
552
    // Tx and Rx interrupts enabled internally; 
553
    // Tx done/aborted, and rx OK.
554
    FLUSH_WRITES();
555
    OUTL( ETH_MSR, ETH_ISR_XMTDN | ETH_ISR_TABR |
556
                   ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU );
557
    FLUSH_WRITES();
558
}
559
 
560
// ------------------------------------------------------------------------
561
//
562
//                NETWORK INTERFACE INITIALIZATION
563
//
564
// ------------------------------------------------------------------------
565
STATIC bool
566
upd985xx_eth_upd985xx_init(struct cyg_netdevtab_entry * ndp)
567
{
568
    struct eth_drv_sc *sc;
569
    cyg_uint8 *mac_address;
570
    struct eth_upd985xx *p_eth_upd985xx;
571
 
572
#ifdef DEBUG
573
    db_printf("upd985xx_eth_upd985xx_init\n");
574
#endif
575
 
576
    sc = (struct eth_drv_sc *)(ndp->device_instance);
577
    p_eth_upd985xx = (struct eth_upd985xx *)(sc->driver_private);
578
 
579
    CHECK_NDP_SC_LINK();
580
 
581
    p_eth_upd985xx->tx_busy = 0;
582
 
583
    // record the net dev pointer
584
    p_eth_upd985xx->ndp = (void *)ndp;
585
 
586
    mac_address = &p_eth_upd985xx->mac_address[0];
587
 
588
#ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA
589
    if ( ! p_eth_upd985xx->hardwired_esa ) {
590
        cyg_uint8 *p;
591
        union macar {
592
            struct {
593
                cyg_uint32 macar1, macar2, macar3;
594
            } integers;
595
            cyg_uint8 bytes[12];
596
        } eeprom;
597
 
598
        eeprom.integers.macar1 = INL( MACAR1 );  // MAC Address Register 1
599
        eeprom.integers.macar2 = INL( MACAR2 );  // MAC Address Register 2
600
        eeprom.integers.macar3 = INL( MACAR3 );  // MAC Address Register 3
601
 
602
        if ( (0 != eeprom.integers.macar1 ||
603
 
604
 
605
             &&
606
             (0xffffffff != eeprom.integers.macar1 ||
607
              0xffffffff != eeprom.integers.macar2 ||
608
              0xffffffff != eeprom.integers.macar3 ) ) {
609
            // Then we have good data in the EEPROM
610
#ifdef DEBUG
611
            os_printf( "EEPROM data %08x %08x %08x\n",
612
                       eeprom.integers.macar1,
613
                       eeprom.integers.macar2,
614
                       eeprom.integers.macar3 );
615
#endif
616
            p = &eeprom.bytes[0]; // pick up either set of ESA info
617
            if ( 1 == p_eth_upd985xx->index )
618
                p += 6;
619
 
620
            mac_address[5] = p[5];
621
            mac_address[4] = p[4];
622
            mac_address[3] = p[3];
623
            mac_address[2] = p[2];
624
            mac_address[1] = p[1];
625
            mac_address[0] = p[0];
626
            p_eth_upd985xx->mac_addr_ok = 1;
627
        }
628
        else {
629
            // Fake it so we can get RedBoot going on a board with no EEPROM
630
            mac_address[0] = 0;
631
            mac_address[1] = 0xBA;
632
            mac_address[2] = 0xD0;
633
            mac_address[3] = 0xEE;
634
            mac_address[4] = 0x00;
635
            mac_address[5] = p_eth_upd985xx->index;
636
            p_eth_upd985xx->mac_addr_ok = 1;
637
        }
638
    }
639
#endif // CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA
640
 
641
    // Init the underlying hardware and insert the ESA:
642
    eth_upd985xx_reset(p_eth_upd985xx);
643
 
644
#ifdef DEBUG
645
    os_printf("MAC Address %s, ESA = %02X %02X %02X %02X %02X %02X\n",
646
              p_eth_upd985xx->mac_addr_ok ? "OK" : "**BAD**",
647
              mac_address[0], mac_address[1], mac_address[2], mac_address[3],
648
              mac_address[4], mac_address[5]);
649
#endif
650
 
651
    // Set up the pointers to data structures
652
    InitTxRing(p_eth_upd985xx);
653
 
654
    // Construct the interrupt handler
655
    p_eth_upd985xx->active = 0;
656
    cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
657
    cyg_drv_interrupt_mask(p_eth_upd985xx->vector);
658
    cyg_drv_interrupt_create(
659
        p_eth_upd985xx->vector,
660
        0,                              // Priority - unused
661
        (CYG_ADDRWORD)sc,               // Data item passed to ISR & DSR
662
        eth_isr,                        // ISR
663
        eth_drv_dsr,                    // DSR (generic)
664
        &p_eth_upd985xx->interrupt_handle, // handle to intr obj
665
        &p_eth_upd985xx->interrupt_object ); // space for int obj
666
 
667
    cyg_drv_interrupt_attach(p_eth_upd985xx->interrupt_handle);
668
 
669
    // Initialize upper level driver
670
    if ( p_eth_upd985xx->mac_addr_ok )
671
        (sc->funs->eth_drv->init)(sc, &(p_eth_upd985xx->mac_address[0]) );
672
    else
673
        (sc->funs->eth_drv->init)(sc, 0 );
674
 
675
    return (1);
676
}
677
 
678
// ------------------------------------------------------------------------
679
//
680
//  Function : eth_upd985xx_start
681
//
682
// ------------------------------------------------------------------------
683
STATIC void
684
eth_upd985xx_start( struct eth_drv_sc *sc,
685
                    unsigned char *enaddr, int flags )
686
{
687
    struct eth_upd985xx *p_eth_upd985xx;
688
    cyg_uint32 ss;
689
#ifdef CYGPKG_NET
690
    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
691
#endif
692
 
693
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
694
 
695
#ifdef DEBUG
696
    os_printf("eth_upd985xx_start %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx );
697
#endif
698
 
699
    if ( p_eth_upd985xx->active )
700
        eth_upd985xx_stop( sc );
701
 
702
    p_eth_upd985xx->active = 1;
703
 
704
#ifdef CYGPKG_NET
705
    /* Enable promiscuous mode if requested, reception of oversized frames always.
706
     * The latter is needed for VLAN support and shouldn't hurt even if we're not
707
     * using VLANs.
708
     */
709
    eth_upd985xx_configure(p_eth_upd985xx, !!(ifp->if_flags & IFF_PROMISC), 1);
710
#endif
711
 
712
    // renegotiate link status
713
    p_eth_upd985xx->phy_status = eth_upd985xx_status( p_eth_upd985xx );
714
 
715
    if ( p_eth_upd985xx->phy_status & PHY_STATUS_FDX ) {
716
        cyg_uint32 ss;
717
        // then enable full duplex in the MAC
718
        ss = INL( ETH_MACC1 );
719
        ss |= ETH_MACC1_FDX;
720
        OUTL( ETH_MACC1, ss );
721
    }
722
 
723
#ifdef DEBUG
724
    {
725
        int status = p_eth_upd985xx->phy_status;
726
        os_printf("eth_upd985xx_start %d Link = %s, %s Mbps, %s Duplex\n",
727
                  p_eth_upd985xx->index,
728
                  status & PHY_STATUS_LINK ? "Up" : "Down",
729
                  status & PHY_STATUS_100MBPS ?  "100" : "10",
730
                  status & PHY_STATUS_FDX ? "Full" : "Half"
731
            );
732
    }
733
#endif
734
 
735
 
736
    // Start the receive engine
737
    p_eth_upd985xx->count_rx_restart++;
738
    // Initialize all but one buffer: [B0,B1,B2,...Bx,NULL,LINK]
739
    InitRxRing( p_eth_upd985xx );
740
    // Point the hardware at the list of buffers
741
    OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active );
742
    // Tell it about the buffers via the rx descriptor count
743
    OUTL( ETH_RXPDR, ETH_RXPDR_AL | (NUM_RXBUFS-1) );
744
    // Ack any pending interrupts from the system
745
    p_eth_upd985xx->intrs = INL( ETH_ISR ); // Read-clear
746
    // Start the rx.
747
    OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 );
748
 
749
    // Enable the wet string end of the receiver
750
    ss = INL( ETH_MACC1 );
751
    ss |= ETH_MACC1_SRXEN;
752
    OUTL( ETH_MACC1, ss );
753
 
754
    // And unmask the interrupt
755
    cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
756
    cyg_drv_interrupt_unmask(p_eth_upd985xx->vector);
757
}
758
 
759
// ------------------------------------------------------------------------
760
//
761
//  Function : eth_upd985xx_status; 10/100 and Full/Half Duplex (FDX/HDX)
762
//
763
// ------------------------------------------------------------------------
764
STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx )
765
{
766
    int status;
767
    int i, j;
768
    // Some of these bits latch and only reflect "the truth" on a 2nd reading.
769
    // So read and discard.
770
    mii_read( PHY_CONTROL_REG, &i, p_eth_upd985xx );
771
    mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx );
772
    // Use the "and" of the local and remote capabilities words to infer
773
    // what is selected:
774
    status = 0;
775
    if ( mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx ) ) {
776
        if ( PHY_STATUS_LINK_OK & i )
777
            status |= PHY_STATUS_LINK;
778
    }
779
    if ( mii_read( PHY_AUTONEG_ADVERT, &j, p_eth_upd985xx ) &&
780
         mii_read( PHY_AUTONEG_REMOTE, &i, p_eth_upd985xx ) ) {
781
#if defined( DEBUG_TRAFFIC ) || defined( DEBUG_IOCTL )
782
        os_printf( "MII: capabilities are %04x, %04x; common %04x\n",
783
                   i, j, i & j );
784
#endif
785
        j &= i; // select only common capabilities
786
 
787
        if ( (PHY_AUTONEG_100BASET4 |
788
              PHY_AUTONEG_100BASETX_FDX |
789
              PHY_AUTONEG_100BASETX_HDX)  & j )
790
            status |= PHY_STATUS_100MBPS;
791
        if ( (PHY_AUTONEG_100BASETX_FDX | PHY_AUTONEG_10BASET_FDX) & j )
792
            status |= PHY_STATUS_FDX;
793
    }
794
    return status;
795
}
796
 
797
// ------------------------------------------------------------------------
798
//
799
//  Function : eth_upd985xx_stop
800
//
801
// ------------------------------------------------------------------------
802
 
803
STATIC void eth_upd985xx_stop( struct eth_drv_sc *sc )
804
{
805
    struct eth_upd985xx *p_eth_upd985xx;
806
 
807
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
808
 
809
    // No more interrupts
810
    cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
811
    cyg_drv_interrupt_mask(p_eth_upd985xx->vector);
812
 
813
#ifdef DEBUG
814
    os_printf("eth_upd985xx_stop %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx );
815
#endif
816
 
817
    p_eth_upd985xx->active = 0;         // stop people tormenting it
818
 
819
    if ( p_eth_upd985xx->tx_busy ) {
820
        // Then it is finshed now, by force:
821
        cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ];
822
        // Turn off the transmitter (before the callback to the stack).
823
        OUTL( ETH_TXCR, 0 );
824
#ifdef DEBUG_TRAFFIC
825
        os_printf("Stop: tidying up TX, KEY %x\n", key );
826
#endif
827
        // Leave tx_busy true so no recursion can occur here.
828
        // Then tell the stack we are done:
829
        if ( key ) {
830
            (sc->funs->eth_drv->tx_done)( sc, key, 0 );
831
        }
832
    }
833
    p_eth_upd985xx->tx_keys[ 0 ] = 0;
834
    p_eth_upd985xx->tx_busy = p_eth_upd985xx->active = 0;
835
 
836
    eth_upd985xx_reset(p_eth_upd985xx);
837
 
838
    ResetTxRing( p_eth_upd985xx );
839
}
840
 
841
 
842
// ------------------------------------------------------------------------
843
//
844
//  Function : InitRxRing
845
//
846
// ------------------------------------------------------------------------
847
STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx)
848
{
849
    int i;
850
    struct bufdesc *bp;
851
 
852
    // first just blat the various flags and addresses: the first N
853
    // bufdescs point to data buffers, the last one is NULL.
854
    bp = (struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[0] );
855
    // Record the initial active buffer:
856
    p_eth_upd985xx->rxring_active = bp;
857
    p_eth_upd985xx->rxring_active_index = 0;
858
    for ( i = 0; i < NUM_RXBUFS - 1; i++, bp++ ) {
859
        bp->ptr = VIRT_TO_BUS( &rx_databuf[i][0] );
860
        bp->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU
861
                     | (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) );
862
    }
863
    CYG_ASSERT( i == NUM_RXBUFS-1, "Penultimate rx buffer index mismatch" );
864
    CYG_ASSERT( (cyg_uint8 *)bp ==
865
                VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS-1] ),
866
                "Penultimate rx buffer address mismatch" );
867
 
868
    // NULL out the penultimate one
869
    bp->ptr = NULL;
870
    bp->attr = 0;
871
    // And record it as next one to use
872
    p_eth_upd985xx->rxring_next = bp;
873
    p_eth_upd985xx->rxring_next_index = NUM_RXBUFS-1;
874
 
875
    // Step on to the extra entry at the end which makes a ring:
876
    bp++;
877
    CYG_ASSERT( (cyg_uint8 *)bp ==
878
                VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS] ),
879
                "Ultimate rx buffer address mismatch" );
880
 
881
    // Link the Ultimate back to the start
882
    bp->ptr = (cyg_uint8 *)p_eth_upd985xx->rxring_active; // Zeroth entry
883
    bp->attr = ETH_BUF_D_L_LINK;
884
 
885
    // All done.
886
}
887
 
888
 
889
// ------------------------------------------------------------------------
890
//
891
//  Function : NextRxRing
892
//
893
// ------------------------------------------------------------------------
894
 
895
STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx )
896
{
897
    volatile struct bufdesc *next, *dead;
898
    int iactive;
899
    int inext;
900
 
901
    iactive = p_eth_upd985xx->rxring_active_index;
902
    inext = p_eth_upd985xx->rxring_next_index;
903
 
904
    // Preconditions:
905
    CYG_ASSERT( 0 <=   inext && inext   < NUM_RXBUFS, "Bad inext" );
906
    CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" );
907
    CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] )
908
                == (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" );
909
    CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] )
910
                == (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" );
911
    CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" );
912
    CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" );
913
    CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" );
914
    CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) ==
915
                p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" );
916
    CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext),
917
                "Chasing pointers mismatch" );
918
 
919
    // Select the new bufdesc to be active - ie. next to scan for reception:
920
    if ( ++iactive >= NUM_RXBUFS )
921
        iactive = 0;
922
    dead = p_eth_upd985xx->rxring_active; // the one that just died
923
    // Step ahead the new active buffer:
924
    p_eth_upd985xx->rxring_active = (volatile struct bufdesc *)
925
        VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] );
926
    p_eth_upd985xx->rxring_active_index = iactive;
927
 
928
    // Blow away the currently active entry; we have dealt with it already
929
    // and it is needed for an end stop to the ring:
930
    dead->ptr = NULL;
931
    dead->attr = 0;
932
 
933
    // Select the next bufdesc to enliven
934
    next = p_eth_upd985xx->rxring_next;
935
    next->ptr = VIRT_TO_BUS( &rx_databuf[inext][0] );
936
    next->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU
937
                   | (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) );
938
 
939
    // And update the external info to reflect this:
940
    if ( ++inext >= NUM_RXBUFS )
941
        inext = 0;
942
    next = (volatile struct bufdesc *)
943
        VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] );
944
 
945
    p_eth_upd985xx->rxring_next = next;
946
    p_eth_upd985xx->rxring_next_index = inext;
947
 
948
    // Postconditions:
949
    CYG_ASSERT( 0 <=   inext && inext   < NUM_RXBUFS, "Bad inext" );
950
    CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" );
951
    CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] )
952
                == (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" );
953
    CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] )
954
                == (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" );
955
    CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" );
956
    CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" );
957
    CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" );
958
    CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) ==
959
                p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" );
960
    CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext),
961
                "Chasing pointers mismatch" );
962
}
963
 
964
// ------------------------------------------------------------------------
965
//
966
//  Function : PacketRxReady        (Called from delivery thread)
967
//
968
// ------------------------------------------------------------------------
969
STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx)
970
{
971
    struct cyg_netdevtab_entry *ndp;
972
    struct eth_drv_sc *sc;
973
    cyg_uint32 ss, length;
974
    cyg_bool reset_required = 0;
975
 
976
    ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp);
977
    sc = (struct eth_drv_sc *)(ndp->device_instance);
978
 
979
    CHECK_NDP_SC_LINK();
980
 
981
#ifdef DEBUG_TRAFFIC
982
    ss = INL( ETH_RXSR );
983
    os_printf("PacketRxReady: RXSR %x\n", ss );
984
#endif
985
 
986
    if ( ETH_ISR_RBDRU & p_eth_upd985xx->intrs )
987
        reset_required = 1; // Out of buffers
988
    if ( ! ETH_ISR_RCVDN & p_eth_upd985xx->intrs )
989
        reset_required = 1; // or if no reception completed, reset anyway
990
 
991
    // For all ready rx blocks...
992
    do {
993
        volatile struct bufdesc *bp;
994
 
995
        bp = p_eth_upd985xx->rxring_active; // Current rx candidate
996
 
997
        ss = bp->attr;
998
#ifdef DEBUG_TRAFFIC
999
        os_printf("PacketRxReady attr %x at %x\n", ss, bp );
1000
#endif
1001
        if ( ETH_BUF_OWN_CPU == (ETH_BUF_OWN & ss) ) {
1002
            // Then the packet is untouched...
1003
            break;
1004
        }
1005
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
1006
        // Perform address recognition by hand, hardware is in promisc mode
1007
        // (we have settable "software" promisc mode too of course)
1008
        if ( ETH_BUF_OK & ss ) {
1009
            cyg_uint8 *esa = (cyg_uint8 *)bp->ptr; // (this is a non-cachable address)
1010
            int ok = 0;
1011
            if ( p_eth_upd985xx->promisc )
1012
                ok = 1; // accept the packet
1013
            else
1014
            if ( p_eth_upd985xx->mac_address[0] == esa[0] &&
1015
                 p_eth_upd985xx->mac_address[1] == esa[1] &&
1016
                 p_eth_upd985xx->mac_address[2] == esa[2] &&
1017
                 p_eth_upd985xx->mac_address[3] == esa[3] &&
1018
                 p_eth_upd985xx->mac_address[4] == esa[4] &&
1019
                 p_eth_upd985xx->mac_address[5] == esa[5] )
1020
                ok = 1; // Then they are equal - accept
1021
            else
1022
            if ( 0xff == esa[0] &&
1023
                 0xff == esa[1] &&
1024
                 0xff == esa[2] &&
1025
                 0xff == esa[3] &&
1026
                 0xff == esa[4] &&
1027
                 0xff == esa[5] )
1028
                ok = 1; // Then they are equal - accept
1029
 
1030
            if ( !ok )
1031
                ss = 0; // Easiest way...
1032
        }
1033
#endif
1034
        if ( ETH_BUF_OK & ss ) {
1035
            length = ETH_BUF_SIZE & ss;
1036
#ifdef DEBUG_TRAFFIC
1037
            os_printf("PacketRxReady found a packet size %d attr %x\n", length, ss );
1038
#endif
1039
            // Asserts for the length in-range can fire, with good status
1040
            // in the block, so be defensive here instead.  Belt and braces.
1041
            if ( 63 < length && length <= MAX_RX_PACKET_SIZE ) {
1042
                CYG_ASSERT( ETH_BUF_D_L_DATA == (ETH_BUF_D_L & ss), "Not data buffer" );
1043
                CYG_ASSERT( length > 63, "Tiny packet" );
1044
                CYG_ASSERT( length <= MAX_RX_PACKET_SIZE, "Too big packet" );
1045
                CYG_ASSERT( ETH_BUF_LAST & ss, "Not last buffer" );
1046
                (sc->funs->eth_drv->recv)( sc, length );
1047
            } // Else drop it on the floor.
1048
        }
1049
 
1050
        // Step along to the next buffer descriptor...
1051
        NextRxRing( p_eth_upd985xx );
1052
        if ( ! reset_required ) {
1053
            // And tell the device it can have a biscuit:
1054
            OUTL( ETH_RXPDR, ETH_RXPDR_AL | 1 );
1055
 
1056
            // Now, before moving on to the next packet, find out if receptions
1057
            // had caught up with us before adding that new buffer:
1058
            ss = INL( ETH_RXPDR );
1059
            ss &= ETH_RXPDR_RNOD;
1060
            ss >>= ETH_RXPDR_RNOD_SHIFT;
1061
            if ( 1 >= ss ) {
1062
                // Then it was zero before.  So the rx engine is stopped.
1063
#ifdef DEBUG_TRAFFIC
1064
                os_printf( "***ZERO rx buffers were left\n" );
1065
#endif
1066
                reset_required = 1;
1067
            }
1068
            // Otherwise we carry on as usual.
1069
        }
1070
    } while ( 1 );
1071
 
1072
    if ( reset_required ) {
1073
        p_eth_upd985xx->count_rx_resource++;
1074
        // Disable the wet string end of the receiver
1075
        ss = INL( ETH_MACC1 );
1076
        ss &=~ETH_MACC1_SRXEN;
1077
        OUTL( ETH_MACC1, ss );
1078
        // Disable the DMA engine
1079
        OUTL( ETH_RXCR, 0 );
1080
        // Reset the RxRing from scratch
1081
        InitRxRing( p_eth_upd985xx );
1082
        // Point the hardware at the list of buffers
1083
        OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active );
1084
        // Tell it about the buffers via the rx descriptor count:
1085
        ss = INL( ETH_RXPDR );
1086
        ss &= ETH_RXPDR_RNOD;
1087
        ss >>= ETH_RXPDR_RNOD_SHIFT;
1088
        // This awful register *increments* by what you write, even if the
1089
        // machinery is halted.  Vile filthy evil rubbish.
1090
        OUTL( ETH_RXPDR, ETH_RXPDR_AL | ((NUM_RXBUFS-1) - ss)  );
1091
        ss = INL( ETH_RXPDR );
1092
        CYG_ASSERT( (ETH_RXPDR_AL | (NUM_RXBUFS-1)) == ss, "RXPDR not right" );
1093
        // Start the rx.
1094
        OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 );
1095
        // Enable the wet string end of the receiver
1096
        ss = INL( ETH_MACC1 );
1097
        ss |= ETH_MACC1_SRXEN;
1098
        OUTL( ETH_MACC1, ss );
1099
        // All done.
1100
#ifdef DEBUG_TRAFFIC
1101
        os_printf( "***Rx Machine restarted\n" );
1102
#endif
1103
    }
1104
}
1105
 
1106
// and the callback function
1107
 
1108
STATIC void
1109
eth_upd985xx_recv( struct eth_drv_sc *sc,
1110
                   struct eth_drv_sg *sg_list, int sg_len )
1111
{
1112
    struct eth_upd985xx *p_eth_upd985xx;
1113
    int total_len;
1114
    struct eth_drv_sg *last_sg;
1115
    cyg_uint8 *from_p;
1116
    volatile struct bufdesc *bp;
1117
 
1118
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1119
 
1120
    // Guard possible external entry points
1121
    if ( ! p_eth_upd985xx->active )
1122
        return;
1123
 
1124
    bp = p_eth_upd985xx->rxring_active; // Current rx candidate
1125
 
1126
#ifdef DEBUG_TRAFFIC
1127
    os_printf("Rx status %x\n", bp->attr );
1128
#endif
1129
 
1130
    if ( 0 == (ETH_BUF_OK & bp->attr) )
1131
        return;
1132
 
1133
    total_len = ETH_BUF_SIZE & bp->attr;
1134
 
1135
#ifdef DEBUG_TRAFFIC
1136
    os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n",
1137
              p_eth_upd985xx->index, (int)p_eth_upd985xx,
1138
              bp->attr,
1139
              sg_len, total_len);
1140
#endif
1141
 
1142
    // Copy the data to the network stack
1143
    from_p = bp->ptr; // (this is a non-cachable address)
1144
 
1145
    // check we have memory to copy into; we would be called even if
1146
    // caller was out of memory in order to maintain our state.
1147
    if ( 0 == sg_len || 0 == sg_list )
1148
        return; // caller was out of mbufs
1149
 
1150
    CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
1151
    CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
1152
 
1153
    for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1154
        cyg_uint8 *to_p;
1155
        int l;
1156
 
1157
        to_p = (cyg_uint8 *)(sg_list->buf);
1158
        l = sg_list->len;
1159
 
1160
        CYG_ASSERT( 0 <= l, "sg length -ve" );
1161
 
1162
        if ( 0 >= l || 0 == to_p )
1163
            return; // caller was out of mbufs
1164
 
1165
        if ( l > total_len )
1166
            l = total_len;
1167
 
1168
        memcpy( to_p, from_p, l );
1169
        from_p += l;
1170
        total_len -= l;
1171
    }
1172
 
1173
    CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
1174
    CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
1175
    CYG_ASSERT( bp->ptr < from_p, "from_p wild in rx" );
1176
    CYG_ASSERT( bp->ptr + MAX_RX_PACKET_SIZE >= from_p,
1177
                "from_p overflow in rx" );
1178
}
1179
 
1180
 
1181
// ------------------------------------------------------------------------
1182
//
1183
//  Function : InitTxRing
1184
//
1185
// ------------------------------------------------------------------------
1186
STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx)
1187
{
1188
    int i;
1189
    volatile struct bufdesc *bp;
1190
 
1191
    p_eth_upd985xx->txring =
1192
        (struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->tx_bufdesc[0] );
1193
 
1194
    bp = p_eth_upd985xx->txring;
1195
 
1196
    for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ); i++, bp++ ) {
1197
        bp->ptr = NULL;
1198
        bp->attr = 0;
1199
    }
1200
    // Last one is a NULL link
1201
    bp--;
1202
    bp->ptr = NULL;
1203
    bp->attr = ETH_BUF_D_L_LINK;
1204
 
1205
    ResetTxRing(p_eth_upd985xx);
1206
}
1207
 
1208
// ------------------------------------------------------------------------
1209
//
1210
//  Function : ResetTxRing
1211
//
1212
// ------------------------------------------------------------------------
1213
STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx)
1214
{
1215
    int i;
1216
    volatile struct bufdesc *bp;
1217
    bp = p_eth_upd985xx->txring;
1218
    for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ) - 1; i++, bp++ ) {
1219
        bp->attr =
1220
            ETH_BUF_LAST |
1221
            ETH_BUF_D_L_DATA |
1222
            ETH_BUF_OWN_CPU |
1223
            (ETH_BUF_SIZE & 0);
1224
    }
1225
}
1226
 
1227
// ------------------------------------------------------------------------
1228
//
1229
//  Function : TxDone          (Called from delivery thread)
1230
//
1231
// This returns Tx's from the Tx Machine to the stack (ie. reports
1232
// completion) - allowing for missed interrupts, and so on.
1233
// ------------------------------------------------------------------------
1234
 
1235
STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx)
1236
{
1237
    struct cyg_netdevtab_entry *ndp;
1238
    struct eth_drv_sc *sc;
1239
 
1240
    ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp);
1241
    sc = (struct eth_drv_sc *)(ndp->device_instance);
1242
 
1243
    CHECK_NDP_SC_LINK();
1244
 
1245
    if ( p_eth_upd985xx->tx_busy ) {
1246
        cyg_uint32 ss;
1247
 
1248
        ss = INL( ETH_TXSR ); // Get tx status
1249
        if ( ss & (ETH_TXSR_CSE |
1250
                   ETH_TXSR_TUDR |
1251
                   ETH_TXSR_TGNT |
1252
                   ETH_TXSR_LCOL |
1253
                   ETH_TXSR_ECOL |
1254
                   ETH_TXSR_TEDFR |
1255
                   ETH_TXSR_TDFR |
1256
                   ETH_TXSR_TBRO |
1257
                   ETH_TXSR_TMUL |
1258
                   ETH_TXSR_TDONE ) ) {
1259
            // Then it finished; somehow...
1260
            cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ];
1261
 
1262
            // Turn off the transmitter (before the callback to the stack).
1263
            OUTL( ETH_TXCR, 0 );
1264
 
1265
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E8
1266
            // Must take action after certain types of tx failure:
1267
            if ( ss & (ETH_TXSR_TUDR |
1268
                       ETH_TXSR_LCOL |
1269
                       ETH_TXSR_ECOL) ) {
1270
                p_eth_upd985xx->count_bad_tx_completion++;
1271
                CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" );
1272
                eth_upd985xx_stop( sc );
1273
                eth_upd985xx_start( sc, NULL, 0 );
1274
                key = 0; // Important!  Stop above already fed it back.
1275
            }
1276
#endif
1277
 
1278
#ifdef DEBUG_TRAFFIC
1279
            os_printf("TxDone %d %x: KEY %x\n",
1280
                      p_eth_upd985xx->index, (int)p_eth_upd985xx, key );
1281
#endif
1282
            // Finished, ready for the next one
1283
            p_eth_upd985xx->tx_keys[ 0 ] = 0;
1284
            p_eth_upd985xx->tx_busy = 0;
1285
            // Then tell the stack we are done:
1286
            if (key) {
1287
                (sc->funs->eth_drv->tx_done)( sc, key,
1288
 
1289
            }
1290
        }
1291
    }
1292
}
1293
 
1294
 
1295
// ------------------------------------------------------------------------
1296
//
1297
//  Function : eth_upd985xx_can_send
1298
//
1299
// ------------------------------------------------------------------------
1300
 
1301
STATIC int
1302
eth_upd985xx_can_send(struct eth_drv_sc *sc)
1303
{
1304
    struct eth_upd985xx *p_eth_upd985xx;
1305
 
1306
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1307
 
1308
    // Guard possible external entry points
1309
    if ( ! p_eth_upd985xx->active )
1310
        return 0;
1311
 
1312
    return ! p_eth_upd985xx->tx_busy;
1313
}
1314
 
1315
// ------------------------------------------------------------------------
1316
//
1317
//  Function : eth_upd985xx_send
1318
//
1319
// ------------------------------------------------------------------------
1320
 
1321
STATIC void
1322
eth_upd985xx_send(struct eth_drv_sc *sc,
1323
            struct eth_drv_sg *sg_list, int sg_len, int total_len,
1324
            unsigned long key)
1325
{
1326
    struct eth_upd985xx *p_eth_upd985xx;
1327
    struct eth_drv_sg *last_sg;
1328
    volatile struct bufdesc *bp;
1329
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
1330
    struct eth_drv_sg local_sg[2];
1331
#endif
1332
 
1333
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1334
 
1335
#ifdef DEBUG_TRAFFIC
1336
    os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x\n",
1337
              p_eth_upd985xx->index, (int)p_eth_upd985xx, sg_len, total_len, key );
1338
#endif
1339
 
1340
    if ( ! p_eth_upd985xx->active )
1341
        return;                         // device inactive, no return
1342
 
1343
    CYG_ASSERT( ! p_eth_upd985xx->tx_busy, "Can't send when busy!" );
1344
 
1345
    p_eth_upd985xx->tx_busy++;
1346
 
1347
    p_eth_upd985xx->tx_keys[0] = key;
1348
    bp = &p_eth_upd985xx->txring[0]; // Current free tx
1349
    CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
1350
    CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
1351
 
1352
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
1353
    // We must copy any Tx that is more than two SGs into just one buffer.
1354
    if ( sg_len > 2 ) {
1355
        cyg_uint8 *from_p, *to_p;
1356
        to_p = &tx_databuf[0]; // normal cached address
1357
        if ( sizeof( tx_databuf ) < total_len )
1358
            total_len = sizeof( tx_databuf );
1359
        for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1360
            int l;
1361
 
1362
            from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
1363
            l = sg_list->len;
1364
 
1365
            if ( l > total_len )
1366
                l = total_len;
1367
 
1368
            memcpy( to_p, from_p, l ); // All in cached memory
1369
            to_p += l;
1370
            total_len -= l;
1371
 
1372
            if ( 0 > total_len )
1373
                break; // Should exit via sg_last normally
1374
        }
1375
 
1376
        // Set up SGs describing the single tx buffer
1377
        total_len = to_p - &tx_databuf[0];
1378
        local_sg[0].buf = (CYG_ADDRESS)&tx_databuf[0];
1379
        local_sg[0].len = (CYG_ADDRWORD)total_len;
1380
        local_sg[1].buf = (CYG_ADDRESS)0;
1381
        local_sg[1].len = (CYG_ADDRWORD)0;
1382
 
1383
        // And make the subsequent code use it.
1384
        sg_len = 1;
1385
        sg_list = &local_sg[0];
1386
    }
1387
#endif
1388
 
1389
    for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1390
        cyg_uint8 *from_p;
1391
        int l;
1392
 
1393
        from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
1394
        l = sg_list->len;
1395
 
1396
        if ( l > total_len )
1397
            l = total_len;
1398
 
1399
        // Ensure the mbuf contents really is in RAM where DMA can see it.
1400
        // (Must round to cache lines apparantly for 4120)
1401
        HAL_DCACHE_STORE( ((CYG_ADDRESS)from_p) &~(HAL_DCACHE_LINE_SIZE-1),
1402
                          l + HAL_DCACHE_LINE_SIZE );
1403
 
1404
        bp->ptr = VIRT_TO_BUS( from_p ); // uncached real RAM address
1405
        bp->attr &=~(ETH_BUF_LAST | ETH_BUF_SIZE);
1406
        bp->attr |= ETH_BUF_SIZE & l;
1407
        bp->attr |= ETH_BUF_D_L_DATA;
1408
 
1409
        total_len -= l;
1410
        bp++;
1411
 
1412
        if ( 0 > total_len )
1413
            break; // Should exit via sg_last normally
1414
    }
1415
 
1416
    CYG_ASSERT( bp > &p_eth_upd985xx->txring[0], "bp underflow" );
1417
    CYG_ASSERT( bp < &p_eth_upd985xx->txring[
1418
        NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc)
1419
        ], "bp underflow" );
1420
 
1421
    bp--;
1422
    bp->attr |= ETH_BUF_LAST;
1423
 
1424
    // Make the rest be null links
1425
    for ( bp++; bp <
1426
              &p_eth_upd985xx->txring[NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc)];
1427
          bp++ ) {
1428
        bp->attr = ETH_BUF_D_L_LINK;
1429
        bp->ptr = NULL;
1430
    }
1431
 
1432
    CYG_ASSERT( 0 == total_len, "length mismatch in tx" );
1433
    CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" );
1434
 
1435
    // And start off the tx system
1436
 
1437
    // Point the hardware at the list of buffers
1438
    OUTL( ETH_TXDPR, (cyg_uint32)p_eth_upd985xx->txring );
1439
    // and start the tx.
1440
 
1441
    // Fault E4 - use only 8 for DTBS, not the previously recommended 16.
1442
    // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4
1443
    // but no config opt is provided.
1444
 
1445
    // Fault E7: ETH_TXCR_AFCE must not be used.
1446
    // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E7
1447
    // but no config opt is provided.
1448
 
1449
    OUTL( ETH_TXCR, ETH_TXCR_TXE | ETH_TXCR_DTBS_8 /* | ETH_TXCR_AFCE */ );
1450
}
1451
 
1452
#ifdef CYGPKG_NET
1453
// ------------------------------------------------------------------------
1454
//
1455
//  Function : eth_upd985xx_configure
1456
//
1457
//  Return : 0 = It worked.
1458
//           non0 = It failed.
1459
// ------------------------------------------------------------------------
1460
 
1461
STATIC int
1462
eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx, int promisc, int oversized)
1463
{
1464
    int ss;
1465
 
1466
    // We implement permission of oversize packets by changing LMAX (rather
1467
    // than enabling HUGEN in ETH_MACC1) because we rely on only one
1468
    // reception per rx descriptor.  General oversize packets could eat
1469
    // many rx descriptors and we would become ...confused.
1470
 
1471
    // Sanity check the numbers we're about to use.
1472
    CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_OVERSIZE_PACKET_SIZE,
1473
                "Oversize packet would overflow rx buffer" );
1474
    CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_ETHERNET_PACKET_SIZE,
1475
                "Ethernet packet would overflow rx buffer" );
1476
    if ( oversized )
1477
        OUTL( ETH_LMAX, MAX_OVERSIZE_PACKET_SIZE );
1478
    else
1479
        OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE );
1480
 
1481
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
1482
    ss = promisc ? 1 : 0; // avoid unused var warning
1483
    p_eth_upd985xx->promisc = ss;
1484
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY
1485
    // Then we must also set the mode in the chip
1486
    ss = INL( ETH_AFR );
1487
    if ( promisc )
1488
        ss |= ETH_AFR_PRO;
1489
    else
1490
        ss &=~ETH_AFR_PRO;
1491
    OUTL( ETH_AFR, ss );
1492
#endif // CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY
1493
#else
1494
    ss = INL( ETH_AFR );
1495
    if ( promisc )
1496
        ss |= ETH_AFR_PRO;
1497
    else
1498
        ss &=~ETH_AFR_PRO;
1499
    OUTL( ETH_AFR, ss );
1500
#endif
1501
    return 0; // OK
1502
}
1503
#endif
1504
 
1505
// ------------------------------------------------------------------------
1506
//
1507
//  Function : eth_upd985xx_ioctl
1508
//
1509
// ------------------------------------------------------------------------
1510
STATIC int
1511
eth_upd985xx_ioctl(struct eth_drv_sc *sc, unsigned long key,
1512
                   void *data, int data_length)
1513
{
1514
    struct eth_upd985xx *p_eth_upd985xx;
1515
 
1516
    p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1517
 
1518
#ifdef DEBUG_IOCTL
1519
    db_printf( "eth_upd985xx_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
1520
               p_eth_upd985xx->index, p_eth_upd985xx, key, data, data_length );
1521
#endif
1522
 
1523
    // DO NOT guard possible external entry points - want to be able eg. to
1524
    // set a mac address of a down interface before bringing it up!
1525
 
1526
    switch ( key ) {
1527
 
1528
#ifdef ETH_DRV_SET_MAC_ADDRESS
1529
    case ETH_DRV_SET_MAC_ADDRESS:
1530
        if ( 6 != data_length )
1531
            return -2;
1532
        return eth_set_mac_address( p_eth_upd985xx, data );
1533
#endif
1534
 
1535
#ifdef ETH_DRV_GET_IF_STATS_UD
1536
    case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
1537
#endif
1538
        // drop through
1539
#ifdef ETH_DRV_GET_IF_STATS
1540
    case ETH_DRV_GET_IF_STATS:
1541
#endif
1542
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
1543
    {
1544
        struct ether_drv_stats *p = (struct ether_drv_stats *)data;
1545
        int i;
1546
 
1547
        // Chipset entry is no longer supported; RFC1573.
1548
        for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
1549
            p->snmp_chipset[i] = 0;
1550
 
1551
        // This perhaps should be a config opt, so you can make up your own
1552
        // description, or supply it from the instantiation.
1553
        strcpy( p->description, "NEC uPD985xx on-chip ethernet (CANDY)" );
1554
        // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
1555
 
1556
        i = eth_upd985xx_status( p_eth_upd985xx );
1557
 
1558
        if ( !( i & PHY_STATUS_LINK) ) {
1559
            p->operational = 2;         // LINK DOWN
1560
            p->duplex = 1;              // UNKNOWN
1561
            p->speed = 0;
1562
        }
1563
        else {
1564
            p->operational = 3;            // LINK UP
1565
            p->duplex = (i & PHY_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX
1566
            p->speed = ((i & PHY_STATUS_100MBPS) ? 100 : 10) * 1000000;
1567
        }
1568
 
1569
        // Admit to it...
1570
        p->supports_dot3        = true;
1571
 
1572
        // Those commented out are not available on this chip.
1573
        p->tx_good              = INL( ETH_TPCT   )   ;
1574
        p->tx_max_collisions    = INL( ETH_TXCL   )   ;
1575
        p->tx_late_collisions   = INL( ETH_TLCL   )   ;
1576
        //p->tx_underrun          = INL(    )   ;
1577
        p->tx_carrier_loss      = INL( ETH_TCSE   )   ;
1578
        p->tx_deferred          = INL( ETH_TDFR   ) +
1579
                                  INL( ETH_TXDF   )    ;
1580
        //p->tx_sqetesterrors     = INL(    )   ;
1581
        p->tx_single_collisions = INL( ETH_TSCL   )   ;
1582
        p->tx_mult_collisions   = INL( ETH_TMCL   )   ;
1583
        p->tx_total_collisions  = INL( ETH_TSCL   ) +
1584
                                  INL( ETH_TMCL   ) +
1585
                                  INL( ETH_TLCL   ) +
1586
                                  INL( ETH_TXCL   )   ;
1587
        p->rx_good              = INL( ETH_RPKT   )   ;
1588
        p->rx_crc_errors        = INL( ETH_RFCS   )   ;
1589
        p->rx_align_errors      = INL( ETH_RALN   )   ;
1590
        p->rx_resource_errors   = p_eth_upd985xx->count_rx_resource;
1591
        //p->rx_overrun_errors    = INL(    )   ;
1592
        //p->rx_collisions        = INL(    )   ;
1593
        p->rx_short_frames      = INL( ETH_RUND   )   ;
1594
        p->rx_too_long_frames   = INL( ETH_ROVR   )   ;
1595
        p->rx_symbol_errors     = INL( ETH_RXUO   )   ;
1596
 
1597
        p->interrupts           = p_eth_upd985xx->count_interrupts;
1598
        p->rx_count             = INL( ETH_RBYT   )   ;
1599
        p->rx_deliver           = INL( ETH_RPKT   )   ;
1600
        p->rx_resource          = p_eth_upd985xx->count_rx_resource;
1601
        p->rx_restart           = p_eth_upd985xx->count_rx_resource +
1602
                                  p_eth_upd985xx->count_rx_restart;
1603
        p->tx_count             = INL( ETH_TBYT   )   ;
1604
        p->tx_complete          = INL( ETH_TPCT   )   ;
1605
        p->tx_dropped           = INL( ETH_TNCL   )   ;
1606
 
1607
        p->tx_queue_len = 1;
1608
 
1609
        return 0; // OK
1610
    }
1611
#endif
1612
 
1613
    default:
1614
        break;
1615
    }
1616
    return -1;
1617
}
1618
 
1619
// ------------------------------------------------------------------------
1620
 
1621
// EOF if_upd985xx.c

powered by: WebSVN 2.1.0

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