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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [eth/] [intel/] [i21143/] [v2_0/] [src/] [if_i21143.c] - Blame information for rev 193

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      if_i21143.c
4
//
5
//      Intel 21143 ethernet driver
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, 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 version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//####BSDCOPYRIGHTBEGIN####
41
//
42
// -------------------------------------------
43
//
44
// Portions of this software may have been derived from OpenBSD or
45
// other sources, and are covered by the appropriate copyright
46
// disclaimers included herein.
47
//
48
// -------------------------------------------
49
//
50
//####BSDCOPYRIGHTEND####
51
//==========================================================================
52
//#####DESCRIPTIONBEGIN####
53
//
54
// Author(s):    hmt
55
// Contributors: 
56
// Date:         2000-09-17
57
// Purpose:      
58
// Description:  hardware driver for 21143 Intel PRO/100+ ethernet
59
//
60
//####DESCRIPTIONEND####
61
//
62
//==========================================================================
63
 
64
#include <pkgconf/system.h>
65
#ifdef CYGPKG_IO_ETH_DRIVERS
66
#include <pkgconf/io_eth_drivers.h>
67
#endif
68
#include <pkgconf/devs_eth_intel_i21143.h>
69
 
70
// Config for the instantiating package:
71
#include CYGDAT_DEVS_ETH_INTEL_I21143_CFG
72
 
73
#include <cyg/infra/cyg_type.h>
74
#include <cyg/infra/cyg_ass.h>
75
#include <cyg/hal/hal_arch.h>
76
#include <cyg/hal/hal_intr.h>
77
#include <cyg/hal/hal_cache.h>          // HAL_DCACHE_STORE
78
#include <cyg/infra/diag.h>
79
#include <cyg/hal/hal_if.h>
80
#include <cyg/hal/drv_api.h>
81
#include <cyg/io/eth/netdev.h>
82
#include <cyg/io/eth/eth_drv.h>
83
 
84
#ifdef CYGPKG_NET
85
#include <pkgconf/net.h>
86
#include <net/if.h>  /* Needed for struct ifnet */
87
#endif
88
 
89
#ifdef CYGPKG_IO_PCI
90
#include <cyg/io/pci.h>
91
#include CYGHWR_MEMORY_LAYOUT_H
92
#else
93
#error "Need PCI package here"
94
#endif
95
 
96
// ------------------------------------------------------------------------
97
// Exported statistics and the like
98
// defined in <cyg/io/eth/eth_drv_stats.h> - already included.
99
 
100
#define KEEP_STATISTICS
101
 
102
#ifdef KEEP_STATISTICS
103
# define INCR_STAT( _x_ ) (p_i21143->stats. _x_ ++)
104
#else
105
# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
106
#endif
107
 
108
// ------------------------------------------------------------------------
109
//
110
//                      DEVICES AND PACKET QUEUES
111
//
112
// ------------------------------------------------------------------------
113
 
114
#define RX_DESCRIPTORS (4) // 4 packets.
115
#define RX_BUFFERS     RX_DESCRIPTORS
116
#define TX_DESCRIPTORS MAX_ETH_DRV_SG // Enough for one tx, even if fragmented
117
 
118
#define MAX_RX_PACKET_SIZE  1536        // maximum Rx packet size
119
#define MAX_TX_PACKET_SIZE  1536        // maximum Tx packet size
120
 
121
// ------------------------------------------------------------------------
122
 
123
typedef struct buffer_descriptor {
124
    volatile cyg_uint32 des0;
125
    volatile cyg_uint32 des1;
126
    volatile cyg_uint32 buf1;
127
    volatile cyg_uint32 buf2;
128
} BUFDES;
129
 
130
 
131
typedef struct i21143 {
132
    cyg_uint8                           // (split up for atomic byte access)
133
        found:1,                        // was hardware discovered?
134
        mac_addr_ok:1,                  // can we bring up?
135
        active:1,                       // has this if been brung up?
136
        hardwired_esa:1,                // set if ESA is hardwired via CDL
137
        spare1:4;
138
    cyg_uint8 tx_endbuf;                // transmit in progress flag too
139
#define NO_TX_IN_PROGRESS (255)
140
    cyg_uint8  index;                   // 0 or 1 or whatever
141
    cyg_uint8  line_status;             // line status when last inspected
142
    cyg_uint32 devid;                   // PCI device id
143
    cyg_uint32 io_address;              // memory mapped I/O address
144
    cyg_uint8  mac_address[6];          // mac (hardware) address
145
    cyg_uint16 phy_autoneg_remote;      // remote link status cache
146
    void *ndp;                          // Network Device Pointer
147
 
148
    int next_rx_descriptor;             // descriptor index for buffers
149
    volatile BUFDES *rx_ring;           // location of Rx descriptors
150
 
151
    volatile BUFDES *tx_ring;           // location of Tx descriptors
152
    unsigned long tx_keys[1];           // keys for tx q management
153
 
154
    // Interrupt handling stuff
155
    cyg_vector_t    vector;             // interrupt vector
156
    cyg_handle_t    interrupt_handle;   // handle for int.handler
157
    cyg_interrupt   interrupt_object;
158
 
159
    // Refer to following items only though uncached addresses from the
160
    // tx_ring and rxring pointers:
161
    volatile BUFDES _tx[TX_DESCRIPTORS];
162
    volatile BUFDES _rx[RX_DESCRIPTORS];
163
 
164
    cyg_uint8 _rxbufs[ RX_BUFFERS ] [ MAX_RX_PACKET_SIZE ] ;
165
 
166
#ifdef KEEP_STATISTICS
167
    struct stats {
168
        unsigned int tx_good;
169
        unsigned int tx_max_collisions;
170
        unsigned int tx_late_collisions;
171
        unsigned int tx_underrun;
172
        unsigned int tx_carrier_loss;
173
        unsigned int tx_deferred;
174
        unsigned int tx_sqetesterrors;
175
        unsigned int tx_single_collisions;
176
        unsigned int tx_mult_collisions;
177
        unsigned int tx_total_collisions;
178
 
179
        unsigned int rx_good;
180
        unsigned int rx_crc_errors;
181
        unsigned int rx_align_errors;
182
        unsigned int rx_resource_errors;
183
//        unsigned int rx_overrun_errors;
184
        unsigned int rx_collisions;
185
        unsigned int rx_short_frames;
186
        unsigned int rx_too_long_frames;
187
        unsigned int rx_symbol_errors;
188
 
189
        unsigned int interrupts;
190
        unsigned int rx_count;
191
        unsigned int rx_deliver;
192
        unsigned int rx_resource;
193
        unsigned int rx_restart;
194
 
195
        unsigned int tx_count;
196
        unsigned int tx_complete;
197
        unsigned int tx_dropped;
198
    } stats;
199
#endif // KEEP_STATISTICS
200
} I21143;
201
 
202
// ------------------------------------------------------------------------
203
// After defining that, now we can instantiate the device(s):
204
 
205
 
206
#include CYGDAT_DEVS_ETH_INTEL_I21143_INL
207
 
208
// ------------------------------------------------------------------------
209
// Access to cached/uncached/physical memory, to map from CPU-view
210
// addresses to PCI-bus master's view - however that is:
211
// 
212
// We'll use these macros, so that different platforms can define them
213
// externally:
214
//  o CYGHWR_PCI_VIRT_TO_BUS( x )
215
//    - address for the PCI device to use
216
//  o CYGHWR_CACHED_TO_UNCACHED( x )
217
//    - access to memory that the PCI device will look at
218
//  o CYGHWR_BUS_TO_UNCACHED( x )
219
//    - back from an address in the PCI structures to one for us to look at
220
//      to see what it said.
221
 
222
#ifndef CYGHWR_PCI_VIRT_TO_BUS
223
# ifdef CYGARC_PHYSICAL_ADDRESS
224
#  define CYGHWR_PCI_VIRT_TO_BUS( _x_ ) CYGARC_PHYSICAL_ADDRESS( (_x_) )
225
# else
226
#  error No CYGHWR_PCI_VIRT_TO_BUS() defined!
227
//#define CYGHWR_PCI_VIRT_TO_BUS( _x_ )  (_x_)
228
# endif
229
#endif
230
 
231
#ifndef CYGHWR_CACHED_TO_UNCACHED
232
# ifdef CYGARC_UNCACHED_ADDRESS
233
#  define CYGHWR_CACHED_TO_UNCACHED( _x_ ) CYGARC_UNCACHED_ADDRESS( (_x_) )
234
# else   
235
#  define CYGHWR_CACHED_TO_UNCACHED( _x_ )  (_x_)
236
# endif
237
#endif
238
 
239
#ifndef CYGHWR_BUS_TO_UNCACHED
240
# ifdef CYGARC_UNCACHED_ADDRESS
241
#  define CYGHWR_BUS_TO_UNCACHED( _x_ ) CYGARC_UNCACHED_ADDRESS( (_x_) )
242
# else   
243
#  define CYGHWR_BUS_TO_UNCACHED( _x_ )  (_x_)
244
# endif
245
#endif
246
 
247
// ------------------------------------------------------------------------
248
// Prototypes and declarations
249
 
250
static int pci_init_find_21143s( void );
251
static int i21143_configure(struct i21143* p_i21143, int promisc);
252
static void i21143_reset(struct i21143* p_i21143);
253
static void InitTxRing(struct i21143* p_i21143);
254
static void InitRxRing(struct i21143* p_i21143);
255
static void eth_set_mac_address( struct i21143* p_i21143, cyg_uint8 *addr );
256
 
257
static void mii_write_register( int ioaddr, int regnum, int value );
258
static int mii_read_register( int ioaddr, int regnum );
259
 
260
static int get_eeprom_size( int ioaddr );
261
static int read_eeprom_word( int ioaddr, int addrbits, int address );
262
 
263
// ------------------------------------------------------------------------
264
//
265
//                   21143 GENERAL STATUS REGISTER
266
//
267
// ------------------------------------------------------------------------
268
#define GEN_STATUS_FDX          0x04    // 1 = full duplex, 0 = half
269
#define GEN_STATUS_100MBPS      0x02    // 1 = 100 Mbps, 0 = 10 Mbps
270
#define GEN_STATUS_LINK         0x01    // 1 = link up, 0 = link down
271
 
272
// returns status in terms of the above:
273
static int i21143_status( struct i21143* p_i21143 );
274
 
275
// A cheap check for changes: true if changed, is all:
276
static int i21143_status_changed( struct i21143* p_i21143 );
277
 
278
// ------------------------------------------------------------------------
279
 
280
#define CYGDAT_DEVS_ETH_DESCRIPTION "Intel i21143 10/100 Ethernet [DEC]"
281
 
282
#define ETH_DEV_DOT3STATSETHERCHIPSET 1,3,6,1,2,1,10,7,8,2,5
283
 
284
// ------------------------------------------------------------------------
285
 
286
#ifdef CYGDBG_DEVS_ETH_INTEL_I21143_CHATTER
287
#define nDEBUG_TRAFFIC  // This one prints stuff as packets come and go
288
#define DEBUG          // Startup printing mainly
289
#define nDEBUG_EE       // Some EEPROM specific retries &c
290
#define nDEBUG_TRAFFIC_TXDETAILS // tx bufs layout
291
#define nDEBUG_DUMP_REGS
292
#define nDEBUG_MAC
293
#define nDEBUG_STARTSTOPRESET
294
#endif
295
 
296
// ------------------------------------------------------------------------
297
// I/O access macros as inlines for type safety
298
 
299
#if (CYG_BYTEORDER == CYG_MSBFIRST)
300
 
301
#define HAL_CTOLE32(x)  ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
302
#define HAL_LE32TOC(x)  ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | (((x) >> 24) & 0xff))
303
 
304
#define HAL_CTOLE16(x)  ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
305
#define HAL_LE16TOC(x)  ((((x) & 0xff) << 8) | (((x) & 0xff00) >> 8))
306
 
307
//static inline void OUTB(cyg_uint8 value, cyg_uint32 io_address)
308
//{
309
//    HAL_WRITE_UINT8( io_address, value);
310
//}
311
//
312
//static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
313
//{
314
//    HAL_WRITE_UINT16( io_address, (((value & 0xff) << 8) | ((value & 0xff00) >> 8)) );
315
//}
316
 
317
static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
318
{
319
    HAL_WRITE_UINT32( io_address,
320
                      ((((value) & 0xff) << 24) | (((value) & 0xff00) << 8) | (((value) & 0xff0000) >> 8) | (((value) >> 24) & 0xff)) );
321
}
322
 
323
//static inline cyg_uint8 INB(cyg_uint32 io_address)
324
//{   
325
//    cyg_uint8 d;
326
//    HAL_READ_UINT8( io_address, d );
327
//    return d;
328
//}
329
//
330
//static inline cyg_uint16 INW(cyg_uint32 io_address)
331
//{
332
//    cyg_uint16 d;
333
//    HAL_READ_UINT16( io_address, d );
334
//    return (((d & 0xff) << 8) | ((d & 0xff00) >> 8));
335
//}
336
 
337
static inline cyg_uint32 INL(cyg_uint32 io_address)
338
{
339
    cyg_uint32 d;
340
    HAL_READ_UINT32( io_address, d );
341
    return ((((d) & 0xff) << 24) | (((d) & 0xff00) << 8) | (((d) & 0xff0000) >> 8) | (((d) >> 24) & 0xff));
342
}
343
#else
344
 
345
// Maintaining the same styleee as above...
346
#define HAL_CTOLE32(x)  ((((x))))
347
#define HAL_LE32TOC(x)  ((((x))))
348
 
349
#define HAL_CTOLE16(x)  ((((x))))
350
#define HAL_LE16TOC(x)  ((((x))))
351
 
352
//static inline void OUTB(cyg_uint8  value, cyg_uint32 io_address)
353
//{   HAL_WRITE_UINT8( io_address, value );   }
354
//
355
//static inline void OUTW(cyg_uint16 value, cyg_uint32 io_address)
356
//{   HAL_WRITE_UINT16( io_address, value );   }
357
 
358
static inline void OUTL(cyg_uint32 value, cyg_uint32 io_address)
359
{   HAL_WRITE_UINT32( io_address, value );   }
360
 
361
//static inline cyg_uint8  INB(cyg_uint32 io_address)
362
// {   cyg_uint8  _t_; HAL_READ_UINT8(  io_address, _t_ ); return _t_;   }
363
//
364
//static inline cyg_uint16 INW(cyg_uint32 io_address)
365
// {   cyg_uint16 _t_; HAL_READ_UINT16( io_address, _t_ ); return _t_;   }
366
 
367
static inline cyg_uint32 INL(cyg_uint32 io_address)
368
 {   cyg_uint32 _t_; HAL_READ_UINT32( io_address, _t_ ); return _t_;   }
369
 
370
#endif // byteorder
371
 
372
// ------------------------------------------------------------------------
373
 
374
static inline void udelay(int delay)
375
{
376
    CYGACC_CALL_IF_DELAY_US(delay);
377
}
378
 
379
// ------------------------------------------------------------------------
380
#ifdef DEBUG_DUMP_REGS
381
#define MII 1
382
#define ETH 2
383
#define BOTH 3
384
void debug_dump_regs( cyg_uint32 ioaddr, int which )
385
{
386
    int i;
387
 
388
    if ( MII & which )
389
        for ( i = 0; i <= 0x19 ; i++ ) {
390
            int v;
391
            if ( 0x08 == i ) i = 0x10;
392
            v = mii_read_register( ioaddr, i );
393
            diag_printf( "MII/PHY register %2x%c = %04x\n", i, 'h', v );
394
        }
395
    if ( ETH & which )
396
        for ( i = 0; i < 16; i++ ) {
397
            cyg_uint32 v;
398
            v = INL( (ioaddr + (i << 3)) );
399
            diag_printf( "21143 register CSR%2d (at %2x%c) = %08x\n", i, (i << 3), 'h', v );
400
        }
401
}
402
#endif
403
// ------------------------------------------------------------------------
404
//
405
//               REGISTERS (CSRs) and THEIR BITS
406
//
407
// ------------------------------------------------------------------------
408
 
409
// All registers are 32bit entities on 64bit boundaries.
410
 
411
#define CSR0         (ioaddr + ( 0 << 3))
412
#define CSR1         (ioaddr + ( 1 << 3))
413
#define CSR2         (ioaddr + ( 2 << 3))
414
#define CSR3         (ioaddr + ( 3 << 3))
415
#define CSR4         (ioaddr + ( 4 << 3))
416
#define CSR5         (ioaddr + ( 5 << 3))
417
#define CSR6         (ioaddr + ( 6 << 3))
418
#define CSR7         (ioaddr + ( 7 << 3))
419
#define CSR8         (ioaddr + ( 8 << 3))
420
#define CSR9         (ioaddr + ( 9 << 3))
421
#define CSR10        (ioaddr + (10 << 3))
422
#define CSR11        (ioaddr + (11 << 3))
423
#define CSR12        (ioaddr + (12 << 3))
424
#define CSR13        (ioaddr + (13 << 3))
425
#define CSR14        (ioaddr + (14 << 3))
426
#define CSR15        (ioaddr + (15 << 3))
427
 
428
#define CSR1_PM CSR1
429
#define CSR2_PM CSR2
430
 
431
#define CSR_BUSMODE          CSR0 
432
#define CSR_TXPOLL           CSR1 
433
#define CSR_RXPOLL           CSR2 
434
#define CSR_RXBASE           CSR3 
435
#define CSR_TXBASE           CSR4 
436
#define CSR_STATUS           CSR5 
437
#define CSR_OPMODE           CSR6 
438
#define CSR_INTR_ENABLE      CSR7 
439
#define CSR_MISS_OFL_COUNT   CSR8 
440
#define CSR_ROM_MII_MGT      CSR9 
441
#define CSR_ROM_PGM_ADDR     CSR10
442
#define CSR_INTR_MITIGATION  CSR11
443
#define CSR_SIA_STATUS       CSR12
444
#define CSR_SIA_CONN         CSR13
445
#define CSR_SIA_TXRX         CSR14
446
#define CSR_SIA_GPPORT       CSR15
447
 
448
#define CSR_WUFILTER         CSR1_PM
449
#define CSR_WUEVENTS         CSR2_PM
450
 
451
// -------- BUSMODE
452
#define CSR_BUSMODE_PM            (1<<26)
453
#define CSR_BUSMODE_WIE           (1<<24)
454
#define CSR_BUSMODE_RLE           (1<<23)
455
#define CSR_BUSMODE_RME           (1<<21)
456
#define CSR_BUSMODE_DBO_BE        (1<<20)
457
#define CSR_BUSMODE_DBO_LE        (  0  )
458
#define CSR_BUSMODE_TAP_SHIFT (17)
459
#define CSR_BUSMODE_CAL_SHIFT (14)
460
#define CSR_BUSMODE_PBL_SHIFT ( 8)
461
#define CSR_BUSMODE_ENDIAN_BE     (1<< 7)
462
#define CSR_BUSMODE_ENDIAN_LE     (  0  )
463
#define CSR_BUSMODE_DSL_SHIFT ( 2)
464
#define CSR_BUSMODE_BAR           (1<< 1)
465
#define CSR_BUSMODE_RESET         (1<< 0)
466
 
467
// -------- STATUS
468
#define CSR_STATUS_LC             (1<<27)
469
#define CSR_STATUS_GPI            (1<<26)
470
#define CSR_STATUS_EB             (7 << 23)
471
 
472
#define CSR_STATUS_TXSTATUS       (7 << 20)
473
#define CSR_STATUS_TXSTATUS_STOPPED       (0 << 20)
474
#define CSR_STATUS_TXSTATUS_SUSPENDED     (6 << 20)
475
 
476
#define CSR_STATUS_RXSTATUS       (7 << 17)
477
#define CSR_STATUS_RXSTATUS_STOPPED       (0 << 17)
478
#define CSR_STATUS_RXSTATUS_SUSPENDED     (4 << 17)
479
 
480
#define CSR_STATUS_NIS            (1<<16)
481
#define CSR_STATUS_AIS            (1<<15)
482
#define CSR_STATUS_ERI            (1<<14)
483
#define CSR_STATUS_FBE            (1<<13)
484
#define CSR_STATUS_LNF            (1<<12)
485
#define CSR_STATUS_GTE            (1<<11)
486
#define CSR_STATUS_ETI            (1<<10)
487
#define CSR_STATUS_RWT            (1<< 9)
488
#define CSR_STATUS_RX_STOPPED     (1<< 8)
489
#define CSR_STATUS_RBU            (1<< 7)
490
#define CSR_STATUS_RX_INTR        (1<< 6)
491
#define CSR_STATUS_UNF            (1<< 5)
492
#define CSR_STATUS_LNP_ANC        (1<< 4)
493
#define CSR_STATUS_TJT            (1<< 3)
494
#define CSR_STATUS_TBU            (1<< 2)
495
#define CSR_STATUS_TX_STOPPED     (1<< 1)
496
#define CSR_STATUS_TX_INTR        (1<< 0)
497
 
498
// -------- OPMODE
499
 
500
#define CSR_OPMODE_SC          (1<<31)
501
#define CSR_OPMODE_RA          (1<<30)
502
#define CSR_OPMODE_IGNOREMSB   (1<<26)
503
#define CSR_OPMODE_MUST_BE_ONE (1<<25)
504
#define CSR_OPMODE_SCR         (1<<24)
505
#define CSR_OPMODE_PCS         (1<<23)
506
#define CSR_OPMODE_TTM         (1<<22)
507
#define CSR_OPMODE_SF          (1<<21)
508
#define CSR_OPMODE_HBD         (1<<19)
509
#define CSR_OPMODE_PS          (1<<18)
510
#define CSR_OPMODE_PS_MIISYM        (1<<18)
511
#define CSR_OPMODE_CA          (1<<17)
512
#define CSR_OPMODE_TX_THRES_SHIFT (14)
513
#define CSR_OPMODE_TX_START    (1<<13)
514
#define CSR_OPMODE_FC          (1<<12)
515
#define CSR_OPMODE_LOOPBACK_SHIFT (10)
516
#define CSR_OPMODE_FD          (1<< 9)
517
#define CSR_OPMODE_MULTICAST   (1<< 7)
518
#define CSR_OPMODE_PROMISC     (1<< 6)
519
#define CSR_OPMODE_SB          (1<< 5)
520
#define CSR_OPMODE_IF          (1<< 4)
521
#define CSR_OPMODE_PB          (1<< 3)
522
#define CSR_OPMODE_HO          (1<< 2)
523
#define CSR_OPMODE_RX_START    (1<< 1)
524
#define CSR_OPMODE_HP          (1<< 0)
525
 
526
// -------- INTR_ENABLE
527
// uses the same bits as STATUS, hurrah!
528
 
529
// -------- MISS_OFL_COUNT
530
#define CSR_MISS_OFL_COUNT_NO_RXBUFS_MASK  (0x0001ffff)
531
#define CSR_MISS_OFL_COUNT_NO_RXBUFS_SHIFT ( 0)
532
#define CSR_MISS_OFL_COUNT_NO_RXFIFO_MASK  (0x1ffe0000)
533
#define CSR_MISS_OFL_COUNT_NO_RXFIFO_SHIFT (17)
534
 
535
// -------- ROM_MII_MGT
536
#define CSR_ROM_MII_MGT_MDI   (1<<19)
537
#define CSR_ROM_MII_MGT_MOM   (1<<18)
538
#define CSR_ROM_MII_MGT_MOM_READ   (1<<18)
539
#define CSR_ROM_MII_MGT_MDO   (1<<17)
540
#define CSR_ROM_MII_MGT_MDC   (1<<16)
541
#define CSR_ROM_MII_MGT_RD    (1<<14)
542
#define CSR_ROM_MII_MGT_WR    (1<<13)
543
#define CSR_ROM_MII_MGT_BR    (1<<12)
544
#define CSR_ROM_MII_MGT_SR    (1<<11)
545
#define CSR_ROM_MII_MGT_REG   (1<<10)
546
#define CSR_ROM_MII_MGT_SR_DO (1<< 3)
547
#define CSR_ROM_MII_MGT_SR_DI (1<< 2)
548
#define CSR_ROM_MII_MGT_SR_CK (1<< 1)
549
#define CSR_ROM_MII_MGT_SR_CS (1<< 0)
550
 
551
#define CSR_ROM_MII_MGT_DATA  (0xff)
552
 
553
// -------- SIA defaults
554
#define CSR_SIA_CONN_DEFAULT   (0)
555
#define CSR_SIA_TXRX_DEFAULT   (0)
556
#define CSR_SIA_GPPORT_DEFAULT (8)
557
 
558
// ------------------------------------------------------------------------
559
//
560
//               RECEIVE/TRANSMIT FRAME DESCRIPTORS
561
//
562
// ------------------------------------------------------------------------
563
 
564
 
565
//#if (CYG_BYTEORDER == CYG_MSBFIRST)
566
 
567
// Common to both Rx and Tx DES0
568
#define DES0_STATUS_OWN          (1<<31)
569
#define DES0_STATUS_OWN_DONE     (0<<31)
570
#define DES0_STATUS_OWN_OPEN     (1<<31)
571
 
572
#define DES0_STATUS_ERROR        (1<<15)
573
 
574
// Rx specific results:
575
#define RDES0_STATUS_FF          (1<<30)
576
#define RDES0_STATUS_DE          (1<<14)
577
#define RDES0_STATUS_RF          (1<<11)
578
#define RDES0_STATUS_MF          (1<<10)
579
#define RDES0_STATUS_FIRST       (1<< 9)
580
#define RDES0_STATUS_LAST        (1<< 8)
581
#define RDES0_STATUS_TOOLONG     (1<< 7)
582
#define RDES0_STATUS_LATECOLL    (1<< 6)
583
#define RDES0_STATUS_FT          (1<< 5)
584
#define RDES0_STATUS_RW          (1<< 4)
585
#define RDES0_STATUS_RE          (1<< 3)
586
#define RDES0_STATUS_DB          (1<< 2)
587
#define RDES0_STATUS_CRC         (1<< 1)
588
#define RDES0_STATUS_ZERO        (1<< 0)
589
 
590
#define RDES0_COUNT_MASK     (0x3fff0000)      
591
#define RDES0_COUNT_SHIFT    ( 16 )      
592
 
593
// Tx specific results:
594
#define TDES0_STATUS_TJTO        (1<<14)
595
#define TDES0_STATUS_LO          (1<<11)
596
#define TDES0_STATUS_NC          (1<<10)
597
#define TDES0_STATUS_LC          (1<< 9)
598
#define TDES0_STATUS_EC          (1<< 8)
599
#define TDES0_STATUS_HF          (1<< 7)
600
#define TDES0_STATUS_LF          (1<< 2)
601
#define TDES0_STATUS_UFL         (1<< 1)
602
#define TDES0_STATUS_DE          (1<< 0)
603
#define TDES0_STATUS_CC_MASK     (0x78) 
604
#define TDES0_STATUS_CC_SHIFT    ( 3 )
605
 
606
// Common to both Rx and Tx DES1
607
#define DES1_ENDRING             (1<<25)
608
#define DES1_2ACHAIN             (1<<24)
609
#define DES1_B2SIZE_MASK         (0x7ff << 11)
610
#define DES1_B2SIZE_SHIFT        (11)
611
#define DES1_B1SIZE_MASK         (0x7ff)
612
#define DES1_B1SIZE_SHIFT        (0)
613
 
614
// Rx DES1 has no special bits - Rx descriptors have no "controls"
615
 
616
// Tx specific controls in DES1:
617
#define TDES1_CONTROL_INTERRUPT  (1<<31)
618
#define TDES1_CONTROL_LAST       (1<<30)
619
#define TDES1_CONTROL_FIRST      (1<<29)
620
#define TDES1_CONTROL_SETUP_FT1  (1<<28)
621
#define TDES1_CONTROL_SETUP      (1<<27)
622
#define TDES1_CONTROL_NO_CRC     (1<<26)
623
#define TDES1_CONTROL_NO_PAD     (1<<23)
624
#define TDES1_CONTROL_SETUP_FT0  (1<<22)
625
 
626
// ------------------------------------------------------------------------
627
//
628
// PHY common constants - registers are read over MII.
629
// 
630
// I don't know how much they have in common, but I think MII is pretty
631
// standard, and the "mandated" registers ought to be common.
632
 
633
#define PHY_CONTROL_REG     (0)
634
#define PHY_STATUS_REG      (1)
635
#define PHY_ID_ONE          (2)
636
#define PHY_ID_TWO          (3)
637
#define PHY_AUTONEG_ADVERT  (4)
638
#define PHY_AUTONEG_REMOTE  (5)
639
 
640
#define PHY_CONTROL_RESET           (1<<15)
641
#define PHY_CONTROL_LOOPBACK        (1<<14)
642
#define PHY_CONTROL_SPEED100        (1<<13)
643
#define PHY_CONTROL_AUTONEG_EN      (1<<12)
644
#define PHY_CONTROL_POWERDOWN       (1<<11)
645
#define PHY_CONTROL_MII_DIS         (1<<10)
646
#define PHY_CONTROL_AUTONEG_RST     (1<< 9)
647
#define PHY_CONTROL_DPLX_FULL       (1<< 8)
648
#define PHY_CONTROL_COLLTEST        (1<< 7)
649
 
650
#define PHY_STATUS_CAP_T4           (1<<15)
651
#define PHY_STATUS_CAP_100TXF       (1<<14)
652
#define PHY_STATUS_CAP_100TXH       (1<<13)
653
#define PHY_STATUS_CAP_10TF         (1<<12)
654
#define PHY_STATUS_CAP_10TH         (1<<11)
655
#define PHY_STATUS_CAP_SUPR         (1<< 6)
656
#define PHY_STATUS_AUTONEG_ACK      (1<< 5)
657
#define PHY_STATUS_REMOTEFAULT      (1<< 4)
658
#define PHY_STATUS_CAP_AUTONEG      (1<< 3)
659
#define PHY_STATUS_LINK_OK          (1<< 2)
660
#define PHY_STATUS_JABBER           (1<< 1)
661
#define PHY_STATUS_EXTREGS          (1<< 0)
662
 
663
// These are the same for both AUTONEG registers
664
#define PHY_AUTONEG_NEXT            (1<<15)
665
#define PHY_AUTONEG_ACK             (1<<14)
666
#define PHY_AUTONEG_REMOTEFAULT     (1<<13)
667
#define PHY_AUTONEG_100BASET4       (1<< 9)
668
#define PHY_AUTONEG_100BASETX_FDX   (1<< 8)
669
#define PHY_AUTONEG_100BASETX_HDX   (1<< 7)
670
#define PHY_AUTONEG_10BASET_FDX     (1<< 6)
671
#define PHY_AUTONEG_10BASET_HDX     (1<< 5)
672
#define PHY_AUTONEG_CSMA_802_3      (1<< 0)
673
 
674
// ------------------------------------------------------------------------
675
//
676
//                      DEVICES AND PACKET QUEUES
677
//
678
// ------------------------------------------------------------------------
679
 
680
// Use arrays provided by platform header to verify pointers.
681
#ifdef CYGDBG_USE_ASSERTS
682
#define CHECK_NDP_SC_LINK()                                                     \
683
    CYG_MACRO_START                                                             \
684
    int zzz, valid_netdev = 0, valid_sc = 0;                                    \
685
    for(zzz = 0; zzz < CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT; zzz++) {         \
686
        if (i21143_netdev_array[zzz] == ndp) valid_netdev = 1;                  \
687
        if (i21143_sc_array[zzz] == sc) valid_sc = 1;                           \
688
        if (valid_sc || valid_netdev) break;                                    \
689
    }                                                                           \
690
    CYG_ASSERT( valid_netdev, "Bad ndp" );                                      \
691
    CYG_ASSERT( valid_sc, "Bad sc" );                                           \
692
    CYG_ASSERT( (void *)p_i21143 == i21143_sc_array[zzz]->driver_private,       \
693
                "sc pointer bad" );                                             \
694
    CYG_MACRO_END
695
#else
696
#define CHECK_NDP_SC_LINK()
697
#endif
698
 
699
#define IF_BAD_21143( _p_ )                                             \
700
if (({                                                                  \
701
    int zzz, valid_p = 0;                                               \
702
    for(zzz = 0; zzz < CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT; zzz++) { \
703
        if (i21143_priv_array[zzz] == (_p_)) {                          \
704
            valid_p = 1;                                                \
705
            break;                                                      \
706
        }                                                               \
707
    }                                                                   \
708
    CYG_ASSERT(valid_p, "Bad pointer-to-i21143");                       \
709
    (!valid_p);                                                         \
710
}))
711
 
712
 
713
 
714
#if defined( DEBUG_TRAFFIC_TXDETAILS ) || defined( DEBUG_MAC )
715
static void dump_tx_details( struct i21143 *p_i21143, char *s )
716
{
717
    int i;
718
    cyg_uint32 prev = 0x0f0f0f0f;
719
    for ( i = 0; i < TX_DESCRIPTORS ; i++ ) {
720
        if ( 0 != (p_i21143->tx_ring[i].des1 |
721
                   p_i21143->tx_ring[i].buf1 |
722
                   p_i21143->tx_ring[i].buf2)
723
             || ((p_i21143->tx_ring[i].des0 != prev ) ) ) {
724
            prev = p_i21143->tx_ring[i].des0;
725
            diag_printf( "%10s: bd[%2d] = %08x %08x %8x %x",
726
                         s,
727
                         i,
728
                         p_i21143->tx_ring[i].des0,
729
                         p_i21143->tx_ring[i].des1,
730
                         p_i21143->tx_ring[i].buf1,
731
                         p_i21143->tx_ring[i].buf2 );
732
            diag_printf( " %s, %s%s %s\n",
733
                         p_i21143->tx_ring[i].des0 & DES0_STATUS_OWN_OPEN ? "Open" : "Done" ,
734
                         p_i21143->tx_ring[i].des1 & TDES1_CONTROL_FIRST ? "First" : "" ,
735
                         p_i21143->tx_ring[i].des1 & TDES1_CONTROL_LAST ? "Last" : "" ,
736
                         p_i21143->tx_ring[i].des1 & TDES1_CONTROL_INTERRUPT ? "Interrupt" : "" );
737
        }
738
    }
739
}
740
#endif
741
 
742
// ------------------------------------------------------------------------
743
//
744
//                NETWORK INTERFACE INITIALIZATION
745
//
746
//  Function : i21143_init
747
//
748
//  Description :
749
//       This routine resets, configures, and initializes the chip.
750
//
751
// ------------------------------------------------------------------------
752
static bool
753
i21143_init(struct cyg_netdevtab_entry * ndp)
754
{
755
    static int initialized = 0; // only probe PCI et al *once*
756
 
757
    struct eth_drv_sc *sc;
758
    struct i21143 *p_i21143;
759
    cyg_uint8 mac_address[ETHER_ADDR_LEN];
760
 
761
#ifdef DEBUG
762
    diag_printf("intel_i21143_init\n");
763
#endif
764
 
765
    sc = (struct eth_drv_sc *)(ndp->device_instance);
766
    p_i21143 = (struct i21143 *)(sc->driver_private);
767
 
768
    IF_BAD_21143( p_i21143 ) {
769
#ifdef DEBUG
770
        diag_printf( "Bad device private pointer %x\n", sc->driver_private );
771
#endif
772
        return 0;
773
    }
774
 
775
    CHECK_NDP_SC_LINK();
776
 
777
    p_i21143->ndp = (void *)ndp;
778
 
779
    if ( 0 == initialized++ ) {
780
        // then this is the first time ever:
781
        if ( ! pci_init_find_21143s() ) {
782
#ifdef DEBUG
783
            diag_printf( "pci_init_find_21143s failed" );
784
#endif
785
            return 0;
786
        }
787
    }
788
 
789
    // If this device is not present, exit
790
    if (0 == p_i21143->found)
791
        return 0;
792
 
793
    p_i21143->mac_addr_ok = 0;
794
 
795
    if ( p_i21143->hardwired_esa )
796
        eth_set_mac_address( p_i21143, NULL ); // use that already there
797
                                        // (actually a NOP because !active)
798
    else {
799
        int ee_addrbits;
800
        int val[3];
801
        int good = 0;
802
 
803
        ee_addrbits = get_eeprom_size( p_i21143->io_address );
804
#ifdef DEBUG_EE
805
        diag_printf( "EEPROM size = %d\n", ee_addrbits );
806
#endif
807
        if ( 6 == ee_addrbits || 8 == ee_addrbits ) {
808
            int i;
809
            for ( i = 0; i < 3; i++ ) {
810
                val[i] = read_eeprom_word( p_i21143->io_address,
811
                                           ee_addrbits,
812
                                           i );
813
#ifdef DEBUG_EE
814
                diag_printf( "EEPROM: word at %04x = %04x\n", i, val[i] );
815
#endif
816
            }
817
            if ( 0x0000 != (val[0] | val[1] | val[2] ) && // some nonzero bits
818
                 0xffff != (val[0] & val[1] & val[2] ) && // not all ones
819
                 0x0000 == (val[0] & 0x80) ) {            // not multicast
820
                mac_address[0] = val[0] & 0xff;
821
                mac_address[1] = val[0] >> 8;
822
                mac_address[2] = val[1] & 0xff;
823
                mac_address[3] = val[1] >> 8;
824
                mac_address[4] = val[2] & 0xff;
825
                mac_address[5] = val[2] >> 8;
826
                good = 1;
827
#ifdef DEBUG_MAC
828
                diag_printf( "EEPROM ESA OK: %04x %04x %04x\n",
829
                             val[0], val[1], val[2] );
830
#endif
831
            }
832
        }
833
        if ( !good ) {
834
            // Invent one
835
            mac_address[0] = 0x01;
836
            mac_address[1] = 0x23;
837
            mac_address[2] = 0x45;
838
            mac_address[3] = 0x67;
839
            mac_address[4] = 0x98;
840
            mac_address[5] = 0x76;
841
        }
842
        // Just copy into the structure - not into hardware 'cos !active
843
        eth_set_mac_address( p_i21143, &mac_address[0] );
844
    }
845
 
846
#if defined( DEBUG ) || defined( DEBUG_MAC )
847
    diag_printf("MAC Address %s, ESA = %02X %02X %02X %02X %02X %02X\n",
848
                p_i21143->mac_addr_ok ? "OK" : "**BAD**",
849
                p_i21143->mac_address[0],
850
                p_i21143->mac_address[1],
851
                p_i21143->mac_address[2],
852
                p_i21143->mac_address[3],
853
                p_i21143->mac_address[4],
854
                p_i21143->mac_address[5]);
855
#endif
856
 
857
    // Initialize upper level driver
858
    if ( p_i21143->mac_addr_ok )
859
        (sc->funs->eth_drv->init)(sc, &(p_i21143->mac_address[0]) );
860
    else
861
        (sc->funs->eth_drv->init)(sc, NULL );
862
 
863
    return (1);
864
}
865
 
866
// ------------------------------------------------------------------------
867
//
868
//  Function : i21143_start
869
//
870
// ------------------------------------------------------------------------
871
static void
872
i21143_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
873
{
874
    struct i21143 *p_i21143;
875
    cyg_uint32 ioaddr;
876
    cyg_uint32 l;
877
#ifdef CYGPKG_NET
878
    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
879
#endif
880
 
881
    p_i21143 = (struct i21143 *)sc->driver_private;
882
    ioaddr = p_i21143->io_address; // get 21143's I/O address
883
 
884
    IF_BAD_21143( p_i21143 ) {
885
#ifdef DEBUG
886
        diag_printf( "i21143_start: Bad device pointer %x\n", p_i21143 );
887
#endif
888
        return;
889
    }
890
 
891
    if ( ! p_i21143->mac_addr_ok ) {
892
#ifdef DEBUG
893
        diag_printf("i21143_start %d: invalid MAC address, "
894
                  "can't bring up interface\n",
895
                  p_i21143->index );
896
#endif
897
        return;
898
    }
899
 
900
#ifdef DEBUG
901
    diag_printf( "i21143_start: enters\n" );
902
#endif
903
 
904
    if ( p_i21143->active )
905
        i21143_stop( sc );
906
 
907
    // Update the cached copy of the status reg just in case
908
    l = i21143_status( p_i21143 );
909
    if ( l != p_i21143->line_status ) {
910
        // It has changed!
911
        i21143_reset(p_i21143);             // sets line_status itself
912
    }
913
 
914
    // Enable device
915
    p_i21143->active = 1;
916
 
917
    // Initialize tx status
918
    p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;
919
 
920
    eth_set_mac_address( p_i21143, NULL ); // to put it in the device
921
 
922
    // After eth_set_mac_address() initialize the data structs for use:
923
    InitRxRing( p_i21143 );
924
    InitTxRing( p_i21143 );
925
 
926
    // Enable promiscuous mode if requested.
927
    i21143_configure(p_i21143, 0
928
#ifdef CYGPKG_NET
929
                     || !!(ifp->if_flags & IFF_PROMISC)
930
#endif
931
#ifdef ETH_DRV_FLAGS_PROMISC_MODE
932
                     || !!(flags & ETH_DRV_FLAGS_PROMISC_MODE)
933
#endif
934
 
935
                     );
936
#ifdef DEBUG
937
    {
938
        int status = p_i21143->line_status;
939
        diag_printf("i21143_start %d flg %x Link = %s, %s Mbps, %s Duplex\n",
940
                    p_i21143->index,
941
                    *(int *)p_i21143,
942
                    (GEN_STATUS_LINK    & status) ?   "Up" : "Down",
943
                    (GEN_STATUS_100MBPS & status) ?  "100" : "10",
944
                    (GEN_STATUS_FDX     & status) ? "Full" : "Half");
945
    }
946
#endif
947
 
948
    // Load pointer to Rx Ring and enable receiver
949
    OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)p_i21143->rx_ring ), CSR_RXBASE );
950
    // Enable receive interrupts
951
    l = INL( CSR_INTR_ENABLE );
952
    l |= 0
953
     | CSR_STATUS_NIS
954
     | CSR_STATUS_AIS
955
     // CSR_STATUS_ERI      
956
     // CSR_STATUS_FBE      
957
     // CSR_STATUS_LNF      
958
     // CSR_STATUS_GTE      
959
     // CSR_STATUS_ETI      
960
     // CSR_STATUS_RWT      
961
     | CSR_STATUS_RX_STOPPED
962
     | CSR_STATUS_RBU
963
     | CSR_STATUS_RX_INTR
964
     // CSR_STATUS_UNF      
965
     // CSR_STATUS_LNP_ANC  
966
     // CSR_STATUS_TJT      
967
     | CSR_STATUS_TBU
968
     | CSR_STATUS_TX_STOPPED
969
     | CSR_STATUS_TX_INTR
970
        ;
971
    OUTL( l, CSR_INTR_ENABLE );
972
    // and start the receiver
973
    l = INL( CSR_OPMODE );
974
    l |= (CSR_OPMODE_RX_START);
975
    OUTL( l, CSR_OPMODE );
976
    INCR_STAT( rx_restart );
977
#ifdef DEBUG_DUMP_REGS
978
    debug_dump_regs( ioaddr, BOTH );
979
#endif
980
}
981
 
982
// ------------------------------------------------------------------------
983
//
984
//  Function : i21143_status
985
//
986
// ------------------------------------------------------------------------
987
int
988
i21143_status( struct i21143* p_i21143 )
989
{
990
    int status;
991
    int i, j;
992
    cyg_uint32 ioaddr;
993
 
994
    IF_BAD_21143( p_i21143 ) {
995
#ifdef DEBUG
996
        diag_printf( "i21143_status: Bad device pointer %x\n", p_i21143 );
997
#endif
998
        return 0;
999
    }
1000
 
1001
    ioaddr = p_i21143->io_address; // get 21143's I/O address
1002
 
1003
    // Some of these bits latch and only reflect "the truth" on a 2nd reading.
1004
    // So read and discard.
1005
    status = mii_read_register( ioaddr, PHY_CONTROL_REG );
1006
    status = mii_read_register( ioaddr, PHY_STATUS_REG  );
1007
    // Use the "and" of the local and remote capabilities words to infer
1008
    // what is selected:
1009
    status = 0;
1010
    i = mii_read_register( ioaddr, PHY_STATUS_REG );
1011
    if ( PHY_STATUS_LINK_OK & i )
1012
        status |= GEN_STATUS_LINK;
1013
 
1014
    i = mii_read_register( ioaddr, PHY_AUTONEG_ADVERT );
1015
    j = mii_read_register( ioaddr, PHY_AUTONEG_REMOTE );
1016
    p_i21143->phy_autoneg_remote = j;
1017
#if defined( DEBUG_TRAFFIC ) || defined( DEBUG_IOCTL )
1018
    diag_printf( "MII: capabilities are %04x, %04x; common %04x\n",
1019
               i, j, i & j );
1020
#endif
1021
    j &= i; // select only common capabilities
1022
 
1023
    if ( (PHY_AUTONEG_100BASET4 |
1024
          PHY_AUTONEG_100BASETX_FDX |
1025
          PHY_AUTONEG_100BASETX_HDX)  & j )
1026
        status |= GEN_STATUS_100MBPS;
1027
    if ( (PHY_AUTONEG_100BASETX_FDX | PHY_AUTONEG_10BASET_FDX) & j )
1028
        status |= GEN_STATUS_FDX;
1029
 
1030
    return status;
1031
}
1032
 
1033
int
1034
i21143_status_changed( struct i21143* p_i21143 )
1035
{
1036
    cyg_uint32 ioaddr;
1037
    int j;
1038
    ioaddr = p_i21143->io_address; // get 21143's I/O address
1039
 
1040
    j = mii_read_register( ioaddr, PHY_AUTONEG_REMOTE );
1041
    return ( j != p_i21143->phy_autoneg_remote );
1042
}
1043
 
1044
// ------------------------------------------------------------------------
1045
//
1046
//  Function : i21143_stop
1047
//
1048
// ------------------------------------------------------------------------
1049
 
1050
static void
1051
i21143_stop( struct eth_drv_sc *sc )
1052
{
1053
    struct i21143 *p_i21143;
1054
 
1055
    p_i21143 = (struct i21143 *)sc->driver_private;
1056
 
1057
    IF_BAD_21143( p_i21143 ) {
1058
#ifdef DEBUG
1059
        diag_printf( "i21143_stop: Bad device pointer %x\n", p_i21143 );
1060
#endif
1061
        return;
1062
    }
1063
 
1064
#ifdef DEBUG_STARTSTOPRESET
1065
    diag_printf("i21143_stop %d flg %x\n", p_i21143->index, *(int *)p_i21143 );
1066
#endif
1067
 
1068
    p_i21143->active = 0;               // stop people tormenting it
1069
 
1070
    if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf) {
1071
        cyg_uint32 key;
1072
 
1073
        CYG_ASSERT( TX_DESCRIPTORS > p_i21143->tx_endbuf, "tx_endbuf range" );
1074
 
1075
        key = p_i21143->tx_keys[ 0 ];
1076
        // Common "done" code - key nonzero => report done
1077
        if (key) {
1078
            p_i21143->tx_keys[ 0 ] = 0;
1079
            p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;
1080
            // Then tell the stack we are done:
1081
            INCR_STAT( tx_complete );
1082
            (sc->funs->eth_drv->tx_done)( sc, key, 0 );
1083
        }
1084
    }
1085
 
1086
    i21143_reset(p_i21143);             // that should stop it
1087
}
1088
 
1089
 
1090
// ------------------------------------------------------------------------
1091
//
1092
//  Function : InitRxRing
1093
//
1094
// ------------------------------------------------------------------------
1095
static void
1096
InitRxRing(struct i21143* p_i21143)
1097
{
1098
    int i;
1099
    volatile BUFDES *bp;
1100
 
1101
    p_i21143->rx_ring =
1102
        (BUFDES *)CYGHWR_CACHED_TO_UNCACHED( &(p_i21143->_rx[0]) );
1103
 
1104
    bp = p_i21143->rx_ring;
1105
    for ( i = 0 ; i < RX_DESCRIPTORS; i++ ) {
1106
        bp->des0 = DES0_STATUS_OWN_OPEN; // NIC owns it, not the CPU
1107
        bp->des1 = (MAX_RX_PACKET_SIZE << DES1_B1SIZE_SHIFT);
1108
        bp->buf1 = CYGHWR_PCI_VIRT_TO_BUS( &( p_i21143->_rxbufs[i][0] ) );
1109
        bp->buf2 = 0;
1110
        bp++;
1111
    }
1112
    bp--; // last one
1113
    bp->des1 |= DES1_ENDRING;
1114
 
1115
    p_i21143->next_rx_descriptor = 0;
1116
}
1117
 
1118
// ------------------------------------------------------------------------
1119
//
1120
//  Function : PacketRxReady     (Called from delivery thread & foreground)
1121
//
1122
// ------------------------------------------------------------------------
1123
static void
1124
PacketRxReady(struct i21143* p_i21143)
1125
{
1126
    volatile BUFDES *bp;
1127
    int index;
1128
    struct eth_drv_sc *sc;
1129
    int count;
1130
    {
1131
        struct cyg_netdevtab_entry *ndp;
1132
        ndp = (struct cyg_netdevtab_entry *)(p_i21143->ndp);
1133
        sc = (struct eth_drv_sc *)(ndp->device_instance);
1134
        CHECK_NDP_SC_LINK();
1135
    }
1136
 
1137
    CYG_ASSERT( 0 <= p_i21143->next_rx_descriptor, "rx descriptor underflow" );
1138
    CYG_ASSERT( RX_DESCRIPTORS > p_i21143->next_rx_descriptor, "rx descriptor overflow" );
1139
 
1140
    index = p_i21143->next_rx_descriptor;
1141
 
1142
    // Scan receive buffers
1143
    for ( count = 0; count < RX_DESCRIPTORS; count++ ) {
1144
        cyg_uint32 ldes0;
1145
        int length;
1146
 
1147
        bp = &p_i21143->rx_ring[ index ];
1148
 
1149
        CYG_ASSERT( 0 == bp->buf2, "Corrupt bp->buf2" );
1150
        CYG_ASSERT( 0 != bp->buf1, "Null bp->buf1" );
1151
        CYG_ASSERT( (MAX_RX_PACKET_SIZE << DES1_B1SIZE_SHIFT) == (bp->des1 &~ DES1_ENDRING),
1152
                    "Corrupt bp->des1" );
1153
 
1154
        ldes0 = bp->des0;
1155
 
1156
#ifdef DEBUG_TRAFFIC
1157
        diag_printf( "PacketRxReady: index %d des0 = %08x, %s, %s, %d bytes\n",
1158
                     index, ldes0,
1159
                     (ldes0 & DES0_STATUS_OWN) ? "open" : "done",
1160
                     ((RDES0_STATUS_FIRST | RDES0_STATUS_LAST | DES0_STATUS_ERROR) & ldes0)
1161
                     == (RDES0_STATUS_FIRST | RDES0_STATUS_LAST) ? "OK" : "--",
1162
                     (RDES0_COUNT_MASK & ldes0) >> RDES0_COUNT_SHIFT );
1163
#endif        
1164
 
1165
        if ( DES0_STATUS_OWN_OPEN == (ldes0 & DES0_STATUS_OWN) )
1166
            // This buffer bilong the device
1167
            break;
1168
 
1169
        INCR_STAT( rx_count );
1170
 
1171
        // Otherwise, this one is for us
1172
        if ( ((RDES0_STATUS_FIRST | RDES0_STATUS_LAST | DES0_STATUS_ERROR) & ldes0)
1173
             == (RDES0_STATUS_FIRST | RDES0_STATUS_LAST) ) {
1174
            // A complete packet and no error bit
1175
 
1176
            length = (RDES0_COUNT_MASK & ldes0) >> RDES0_COUNT_SHIFT;
1177
 
1178
            CYG_ASSERT( MAX_RX_PACKET_SIZE >= length, "Oversize Rx" );
1179
 
1180
            // tell the callback the right packet
1181
            p_i21143->next_rx_descriptor = index;
1182
 
1183
            INCR_STAT( rx_good );
1184
 
1185
#ifdef CYGPKG_NET
1186
            if ( length > sizeof( struct ether_header ) )
1187
            // then it is acceptable; offer the data to the network stack
1188
#endif
1189
            (sc->funs->eth_drv->recv)( sc, length );
1190
 
1191
            // All done!
1192
        }
1193
#ifdef KEEP_STATISTICS
1194
        else {
1195
            if ( RDES0_STATUS_LAST & ldes0 ) {
1196
                // Then we have good error info; analyse and count the errors
1197
                if ( ldes0 & ( RDES0_STATUS_CRC ) )
1198
                    INCR_STAT( rx_crc_errors );
1199
                if ( ldes0 & ( RDES0_STATUS_DB ) )
1200
                    INCR_STAT( rx_align_errors );
1201
                if ( ldes0 & ( RDES0_STATUS_LATECOLL ) )
1202
                    INCR_STAT( rx_collisions );
1203
                if ( ldes0 & ( RDES0_STATUS_TOOLONG ) )
1204
                    INCR_STAT( rx_too_long_frames );
1205
                if ( ldes0 & ( RDES0_STATUS_RF ) )
1206
                    INCR_STAT( rx_short_frames );
1207
                if ( ldes0 & ( RDES0_STATUS_RE ) )
1208
                    INCR_STAT( rx_symbol_errors );
1209
            }
1210
            else
1211
                // Dunno what went wrong really...
1212
                INCR_STAT( rx_resource_errors );
1213
        }
1214
#endif // KEEP_STATISTICS
1215
 
1216
        // Open the buffer for the device to use
1217
        bp->des0 = DES0_STATUS_OWN_OPEN; // NIC owns it, not the CPU
1218
 
1219
        // Step i around the ring buffer...
1220
        index++;
1221
        if ( index >= RX_DESCRIPTORS )
1222
            index = 0;
1223
    }
1224
 
1225
    // record the right packet for next time
1226
    p_i21143->next_rx_descriptor = index;
1227
 
1228
    CYG_ASSERT( 0 <= p_i21143->next_rx_descriptor, "rx descriptor underflow" );
1229
    CYG_ASSERT( RX_DESCRIPTORS > p_i21143->next_rx_descriptor, "rx descriptor overflow" );
1230
 
1231
    {   //  We should not have needed ioaddr before this point.
1232
        cyg_uint32 ioaddr;
1233
        cyg_uint32 l;
1234
 
1235
        // Now examine the state of the receive engine and prompt it accordingly.
1236
        ioaddr = p_i21143->io_address; // get 21143's I/O address
1237
        l = INL( CSR_STATUS );
1238
 
1239
#ifdef DEBUG_TRAFFIC
1240
        diag_printf( "PacketRxReady: done scan, next %d, status %08x %s\n",
1241
                     p_i21143->next_rx_descriptor, l,
1242
                     (CSR_STATUS_RXSTATUS & l) != CSR_STATUS_RXSTATUS_STOPPED ?
1243
                     "Running" : "Stopped" );
1244
#endif
1245
 
1246
        if ( (CSR_STATUS_RXSTATUS & l) != CSR_STATUS_RXSTATUS_STOPPED ) {
1247
            // Then ping it into life
1248
            OUTL( 0, CSR_RXPOLL );
1249
        }
1250
        else {
1251
            // Oh dear, it's stopped; we must initialize and start the rx machine
1252
            InitRxRing( p_i21143 );
1253
            OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)p_i21143->rx_ring ), CSR_RXBASE );
1254
            l = INL( CSR_OPMODE );
1255
            l |= CSR_OPMODE_RX_START;
1256
            OUTL( l, CSR_OPMODE );
1257
            INCR_STAT( rx_resource );
1258
            INCR_STAT( rx_restart );
1259
        }
1260
    }
1261
}
1262
 
1263
 
1264
// and the callback function
1265
 
1266
static void
1267
i21143_recv( struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len )
1268
{
1269
    volatile BUFDES *bp;
1270
    struct i21143 *p_i21143;
1271
    cyg_uint32 from_p;
1272
    int total_len;
1273
    struct eth_drv_sg *last_sg;
1274
 
1275
    p_i21143 = (struct i21143 *)(sc->driver_private);
1276
 
1277
    CYG_ASSERT( 0 <= p_i21143->next_rx_descriptor, "rx descriptor underflow" );
1278
    CYG_ASSERT( RX_DESCRIPTORS > p_i21143->next_rx_descriptor, "rx descriptor overflow" );
1279
 
1280
    bp = &p_i21143->rx_ring[ p_i21143->next_rx_descriptor ];
1281
 
1282
    CYG_ASSERT( 0 == bp->buf2, "Corrupt bp->buf2" );
1283
    CYG_ASSERT( 0 != bp->buf1, "Null bp->buf1" );
1284
    CYG_ASSERT( DES0_STATUS_OWN_DONE == (bp->des0 & DES0_STATUS_OWN), "bp not done" );
1285
 
1286
    // Copy the data to the network stack
1287
    from_p = CYGHWR_BUS_TO_UNCACHED( bp->buf1 );
1288
    total_len = (RDES0_COUNT_MASK & bp->des0) >> RDES0_COUNT_SHIFT;
1289
 
1290
#ifdef DEBUG_TRAFFIC
1291
    diag_printf("Recv callback: index %d des0 = %08x: %d sg's, %d bytes\n",
1292
                p_i21143->next_rx_descriptor, bp->des0, sg_len, total_len);
1293
#endif
1294
 
1295
    // check we have memory to copy into; we would be called even if
1296
    // caller was out of memory in order to maintain our state.
1297
    if ( 0 == sg_len || 0 == sg_list )
1298
        return; // caller was out of mbufs
1299
 
1300
    INCR_STAT( rx_deliver );
1301
 
1302
    CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
1303
    CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
1304
 
1305
    for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1306
        cyg_uint8 *to_p;
1307
        int l;
1308
 
1309
        to_p = (cyg_uint8 *)(sg_list->buf);
1310
        l = sg_list->len;
1311
 
1312
        CYG_ASSERT( 0 <= l, "sg length -ve" );
1313
 
1314
        if ( 0 >= l || 0 == to_p )
1315
            return; // caller was out of mbufs
1316
 
1317
        if ( l > total_len )
1318
            l = total_len;
1319
 
1320
        memcpy( to_p, (unsigned char *)from_p, l );
1321
        from_p += l;
1322
        total_len -= l;
1323
    }
1324
 
1325
    CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
1326
    CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
1327
    CYG_ASSERT( CYGHWR_BUS_TO_UNCACHED( bp->buf1 ) < from_p, "from_p wild in rx" );
1328
    CYG_ASSERT( CYGHWR_BUS_TO_UNCACHED( bp->buf1 ) + MAX_RX_PACKET_SIZE >= from_p,
1329
                "from_p overflow in rx" );
1330
}
1331
 
1332
 
1333
// ------------------------------------------------------------------------
1334
//
1335
//  Function : InitTxRing
1336
//
1337
// ------------------------------------------------------------------------
1338
static void
1339
InitTxRing(struct i21143* p_i21143)
1340
{
1341
    int i;
1342
    volatile BUFDES *bp;
1343
 
1344
    p_i21143->tx_ring =
1345
        (BUFDES *)CYGHWR_CACHED_TO_UNCACHED( &(p_i21143->_tx[0]) );
1346
 
1347
    bp = p_i21143->tx_ring;
1348
    for ( i = 0 ; i < TX_DESCRIPTORS; i++ ) {
1349
        bp->des0 = DES0_STATUS_OWN_DONE; // CPU owns it, not the NIC
1350
        bp->des1 = 0;
1351
        bp->buf1 = bp->buf2 = 0;
1352
        bp++;
1353
    }
1354
    bp--; // last one
1355
    bp->des1 |= DES1_ENDRING;
1356
}
1357
 
1358
// ------------------------------------------------------------------------
1359
//
1360
//  Function : TxDone          (Called from delivery thread)
1361
//
1362
// This returns Tx's from the Tx Machine to the stack (ie. reports
1363
// completion) - allowing for missed interrupts, and so on.
1364
// ------------------------------------------------------------------------
1365
 
1366
static void
1367
TxDone(struct i21143* p_i21143)
1368
{
1369
    struct eth_drv_sc *sc;
1370
    unsigned long key = 0;
1371
    cyg_uint32 ioaddr;
1372
 
1373
    {
1374
        struct cyg_netdevtab_entry *ndp;
1375
        ndp = (struct cyg_netdevtab_entry *)(p_i21143->ndp);
1376
        sc = (struct eth_drv_sc *)(ndp->device_instance);
1377
        CHECK_NDP_SC_LINK();
1378
    }
1379
 
1380
    ioaddr = p_i21143->io_address; // get 21143's I/O address
1381
 
1382
#ifdef DEBUG_TRAFFIC_TXDETAILS
1383
    dump_tx_details( p_i21143, "TxDone" );
1384
#endif
1385
 
1386
    if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf) {
1387
        cyg_uint32 l;
1388
        volatile BUFDES *bp;
1389
        cyg_uint32 des;
1390
 
1391
        CYG_ASSERT( TX_DESCRIPTORS > p_i21143->tx_endbuf, "tx_endbuf range" );
1392
 
1393
        l = INL( CSR_STATUS ); // Important: read this first
1394
 
1395
        bp = p_i21143->tx_ring;
1396
        bp += p_i21143->tx_endbuf; // The descriptor with the "end" marker
1397
 
1398
        // It's not clear where error status gets written if the error is
1399
        // *before* the end-marked bufdesc.  We'll see.
1400
 
1401
        des = bp->des1;
1402
        CYG_ASSERT( TDES1_CONTROL_LAST & des , "Last buf not marked" );
1403
        CYG_ASSERT( TDES1_CONTROL_INTERRUPT & des , "No interrupt req" );
1404
        CYG_ASSERT( 0 == (DES1_2ACHAIN & des), "Buffer chained" );
1405
        CYG_ASSERT( 0 == ((TDES1_CONTROL_SETUP |
1406
                           TDES1_CONTROL_SETUP_FT1 |
1407
                           TDES1_CONTROL_SETUP_FT0 |
1408
                           TDES1_CONTROL_NO_CRC |
1409
                           TDES1_CONTROL_NO_PAD)
1410
                          & des),   "Buffer wierd flags" );
1411
        des = bp->des0;
1412
        if ( DES0_STATUS_OWN_DONE == (des & DES0_STATUS_OWN) ) {
1413
            // Then it finished; somehow...
1414
            key = p_i21143->tx_keys[ 0 ];
1415
#ifdef DEBUG_TRAFFIC
1416
            diag_printf("TxDone: KEY %x, %d descs, status %08x\n",
1417
                        key, p_i21143->tx_endbuf+1, des );
1418
#endif
1419
#ifdef KEEP_STATISTICS
1420
            // Then look for an error code from the tx records...
1421
            if ( ! ( DES0_STATUS_ERROR & des ) )
1422
                INCR_STAT( tx_good );
1423
            // Not all the following are errors, so check all
1424
            if ( des & ( TDES0_STATUS_LO | TDES0_STATUS_NC ) )
1425
                INCR_STAT( tx_carrier_loss );
1426
            if ( des & ( TDES0_STATUS_LC ) )
1427
                INCR_STAT( tx_late_collisions );
1428
            if ( des & ( TDES0_STATUS_EC ) )
1429
                INCR_STAT( tx_max_collisions );
1430
            if ( des & ( TDES0_STATUS_LF ) )
1431
                INCR_STAT( tx_sqetesterrors );
1432
            if ( des & ( TDES0_STATUS_UFL ) )
1433
                INCR_STAT( tx_underrun );
1434
            if ( des & ( TDES0_STATUS_DE ) )
1435
                INCR_STAT( tx_deferred );
1436
            // Now count collisions per se:
1437
            des = ((des & TDES0_STATUS_CC_MASK) >> TDES0_STATUS_CC_SHIFT);
1438
            if ( 0 < des ) {
1439
                INCR_STAT( tx_total_collisions );
1440
                if ( 1 < des )
1441
                    INCR_STAT( tx_mult_collisions );
1442
                else
1443
                    INCR_STAT( tx_single_collisions );
1444
            }
1445
#endif // KEEP_STATISTICS
1446
        }
1447
        else {
1448
            // a Tx is in progress, but it has not yet completed;
1449
            // probably wise to check on the tx machine status.
1450
            if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) ||
1451
                 ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_SUSPENDED) ) {
1452
                // then it's not active right now!
1453
                key = p_i21143->tx_keys[ 0 ];
1454
#ifdef DEBUG_TRAFFIC
1455
                diag_printf("TxDone STOPPED!  KEY %x, %d descs, status %08x, CSR_STATUS %08x\n",
1456
                            key, p_i21143->tx_endbuf, des, l );
1457
#endif
1458
                INCR_STAT( tx_underrun ); // at a guess...
1459
            }
1460
        }
1461
 
1462
        // Common "done" code - key nonzero => report done
1463
        if (key) {
1464
            p_i21143->tx_keys[ 0 ] = 0;
1465
            p_i21143->tx_endbuf = NO_TX_IN_PROGRESS;
1466
            // Then tell the stack we are done:
1467
            INCR_STAT( tx_complete );
1468
            (sc->funs->eth_drv->tx_done)( sc, key, 0 );
1469
        }
1470
    }
1471
}
1472
 
1473
 
1474
// ------------------------------------------------------------------------
1475
//
1476
//  Function : i21143_can_send
1477
//
1478
// ------------------------------------------------------------------------
1479
 
1480
static int
1481
i21143_can_send(struct eth_drv_sc *sc)
1482
{
1483
    struct i21143 *p_i21143;
1484
 
1485
    p_i21143 = (struct i21143 *)sc->driver_private;
1486
 
1487
    IF_BAD_21143( p_i21143 ) {
1488
#ifdef DEBUG_TRAFFIC
1489
        diag_printf( "i21143_can_send: Bad device pointer %x\n", p_i21143 );
1490
#endif
1491
        return 0;
1492
    }
1493
 
1494
    if ( p_i21143->active ) {
1495
        if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf )
1496
            // Poll for Tx completion
1497
            TxDone( p_i21143 );
1498
 
1499
        // Poll for receptions
1500
        PacketRxReady( p_i21143 );
1501
    }
1502
 
1503
#ifdef neverDEBUG_TRAFFIC
1504
    diag_printf( "i21143_can_send: returning %d\n",
1505
                 (NO_TX_IN_PROGRESS == p_i21143->tx_endbuf) && p_i21143->active );
1506
#endif
1507
 
1508
    return (NO_TX_IN_PROGRESS == p_i21143->tx_endbuf) && p_i21143->active;
1509
}
1510
 
1511
// ------------------------------------------------------------------------
1512
//
1513
//  Function : i21143_send
1514
//
1515
// ------------------------------------------------------------------------
1516
 
1517
static void
1518
i21143_send(struct eth_drv_sc *sc,
1519
            struct eth_drv_sg *sg_list, int sg_len, int total_len,
1520
            unsigned long key)
1521
{
1522
    struct i21143 *p_i21143;
1523
    cyg_uint32 ioaddr;
1524
    struct eth_drv_sg *last_sg;
1525
    volatile BUFDES *bp;
1526
    int bufcount;
1527
    cyg_uint32 x;
1528
 
1529
    p_i21143 = (struct i21143 *)sc->driver_private;
1530
 
1531
    IF_BAD_21143( p_i21143 ) {
1532
#ifdef DEBUG_TRAFFIC
1533
        diag_printf( "i21143_send: Bad device pointer %x\n", p_i21143 );
1534
#endif
1535
        return;
1536
    }
1537
 
1538
    if ( NO_TX_IN_PROGRESS != p_i21143->tx_endbuf) {
1539
        // Then we cannot do this
1540
#ifdef DEBUG_TRAFFIC
1541
        diag_printf( "i21143_send: tx busy %x, %d bufs key %x\n",
1542
                     p_i21143, p_i21143->tx_endbuf, p_i21143->tx_keys[0] );
1543
#endif
1544
        CYG_FAIL( "Send call when already busy" );
1545
        INCR_STAT( tx_dropped );
1546
        return;
1547
    }
1548
 
1549
    ioaddr = p_i21143->io_address;
1550
 
1551
    bp = p_i21143->tx_ring;
1552
    bufcount = 0;
1553
 
1554
#ifdef DEBUG_TRAFFIC
1555
    diag_printf( "i21143_send() key %x\n", key );
1556
#endif
1557
 
1558
    INCR_STAT( tx_count );
1559
 
1560
    for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1561
        cyg_uint8 *from_p;
1562
        int l;
1563
 
1564
        from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
1565
        l = sg_list->len;
1566
 
1567
        if ( l > total_len )
1568
            l = total_len;
1569
 
1570
        // Ensure the mbuf contents really is in RAM where DMA can see it.
1571
        // (Must round to cache lines apparantly for some MIPS)
1572
        HAL_DCACHE_STORE( ((CYG_ADDRESS)from_p) &~(HAL_DCACHE_LINE_SIZE-1),
1573
                          l + HAL_DCACHE_LINE_SIZE );
1574
 
1575
        // There are two pointer, length pairs in each descriptor.  We only
1576
        // bother using the first one - the code saved is small but so is
1577
        // the overhead of memory.
1578
        bp->buf1 = CYGHWR_PCI_VIRT_TO_BUS( from_p ); // uncached real RAM address
1579
        bp->buf2 = 0;
1580
        // Record length and add endring flag iff end of ring - never leave
1581
        // it blank in memory!
1582
        x = (l << DES1_B1SIZE_SHIFT) & DES1_B1SIZE_MASK; // plus zero buf2 size.
1583
        if ( (TX_DESCRIPTORS-1) == bufcount )
1584
            x |= DES1_ENDRING;
1585
        bp->des1 = x;
1586
 
1587
        // Leave writing the zeroth bufdesc DES0 until all are complete:
1588
        // the tx engine will be stopped looking there.
1589
        if ( 0 < bufcount ) // then we can write DES0 also.
1590
            bp->des0 = DES0_STATUS_OWN_OPEN;
1591
 
1592
        total_len -= l;
1593
        bp++;
1594
        bufcount++;
1595
 
1596
        if ( 0 > total_len )
1597
            break; // Should exit via sg_last normally
1598
    }
1599
 
1600
    CYG_ASSERT( 0 == total_len, "length mismatch in tx" );
1601
    CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" );
1602
 
1603
    CYG_ASSERT( bp > &p_i21143->tx_ring[0], "bp underflow" );
1604
 
1605
    bp--; // back to the last-used bp.
1606
    bufcount--;
1607
    p_i21143->tx_endbuf = bufcount;     // record that we are busy
1608
    p_i21143->tx_keys[0] = key;         // and the key to return
1609
 
1610
    CYG_ASSERT( bp < &p_i21143->tx_ring[ TX_DESCRIPTORS ], "bp underflow" );
1611
 
1612
    // Mark this the last valid buffer.
1613
    bp->des1 |= TDES1_CONTROL_LAST | TDES1_CONTROL_INTERRUPT;
1614
 
1615
    CYG_ASSERT( &(p_i21143->tx_ring[bufcount]) == bp, "Bp/bufcount misstep" );
1616
 
1617
    bp++;
1618
    bufcount++;
1619
 
1620
    // Make the rest be null links
1621
    for ( /* bp */ ; bp < &p_i21143->tx_ring[ TX_DESCRIPTORS ]; bp++ ) {
1622
        bp->buf1 = 0;
1623
        bp->buf2 = 0;
1624
        x = 0; // zero size for both buffers
1625
        if ( (TX_DESCRIPTORS-1) == bufcount )
1626
            x |= DES1_ENDRING;
1627
        bp->des1 = x;
1628
        bp->des0 = DES0_STATUS_OWN_OPEN;
1629
        bufcount++;
1630
    }
1631
 
1632
    // Now it's safe to write the zeroth descriptor:
1633
    p_i21143->tx_ring->des1 |= TDES1_CONTROL_FIRST;
1634
    p_i21143->tx_ring->des0 = DES0_STATUS_OWN_OPEN;
1635
 
1636
#ifdef DEBUG_TRAFFIC_TXDETAILS
1637
    dump_tx_details( p_i21143, "i21143_send" );
1638
#endif
1639
 
1640
    // And start off the tx system
1641
    x = INL( CSR_STATUS );
1642
 
1643
#ifdef DEBUG_TRAFFIC
1644
    diag_printf( "i21143_send: ready, status %08x %s\n",
1645
                 x,
1646
                 (CSR_STATUS_TXSTATUS & x) != CSR_STATUS_TXSTATUS_STOPPED ?
1647
                 "Running" : "Stopped" );
1648
#endif
1649
 
1650
    if ( CSR_STATUS_TXSTATUS_STOPPED == (CSR_STATUS_TXSTATUS & x) ) {
1651
        cyg_uint32 l;
1652
        // Then we must initialize and start the tx machine
1653
        OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)p_i21143->tx_ring ), CSR_TXBASE );
1654
        l = INL( CSR_OPMODE );
1655
        l |= CSR_OPMODE_TX_START;
1656
        OUTL( l, CSR_OPMODE );
1657
    }
1658
    else if ( CSR_STATUS_TXSTATUS_SUSPENDED == (CSR_STATUS_TXSTATUS & x) ) {
1659
        // Then we just have to ping it
1660
        OUTL( 0, CSR_TXPOLL );
1661
    }
1662
    else {
1663
#ifdef DEBUG_TRAFFIC
1664
        diag_printf( "i21143_send: tx not ready %x CSR_STATUS %08x\n", p_i21143, x );
1665
#endif
1666
        CYG_FAIL( "Tx is not ready to tx" );
1667
 
1668
        // Try to recover by brutal means...
1669
        i21143_stop( sc );              // will return the key
1670
        i21143_start( sc, NULL, 0 );
1671
    }
1672
}
1673
 
1674
// ------------------------------------------------------------------------
1675
//
1676
//  Function : i21143_reset
1677
//
1678
// ------------------------------------------------------------------------
1679
static void
1680
i21143_reset(struct i21143* p_i21143)
1681
{
1682
    cyg_uint32 ioaddr = p_i21143->io_address;
1683
    cyg_uint32 l;
1684
    int i, status;
1685
    // First stop the tx and rx engines - doc suggests that's necessary
1686
    // before writing the reset reg, but it seems a little paranoid.
1687
 
1688
    l = INL( CSR_OPMODE );
1689
    l &=~ (CSR_OPMODE_RX_START | CSR_OPMODE_TX_START);
1690
    OUTL( l, CSR_OPMODE );
1691
 
1692
    for ( i = 0; i < 10000; i++) {
1693
        l = INL( CSR_STATUS );
1694
        if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) &&
1695
             ((CSR_STATUS_RXSTATUS & l) == CSR_STATUS_RXSTATUS_STOPPED) )
1696
            break;
1697
    }
1698
#ifdef DEBUG_STARTSTOPRESET
1699
    diag_printf( "i21143_reset: rx and tx idle after %d iters, status %x\n",
1700
                 i, l );
1701
#endif
1702
 
1703
    // Acknowledge all the interrupts from these activities
1704
    // within the device:
1705
    OUTL( 0xffffffff, CSR_STATUS ); // clear all bits
1706
 
1707
    // Now reset the device.  We are going to re-init all params anyway, so
1708
    // ignore other settings:
1709
    OUTL( CSR_BUSMODE_RESET, CSR_BUSMODE );
1710
 
1711
    udelay( 100 ); // let reset take effect.  "50 PCI clock cycles"
1712
 
1713
    for ( i = 0; i < 10000; i++) {
1714
        l = INL( CSR_BUSMODE );
1715
        if ( (CSR_BUSMODE_RESET & l) == 0 )
1716
            break;
1717
    }
1718
#ifdef DEBUG_STARTSTOPRESET
1719
    diag_printf( "i21143_reset: reset zero after %d iters, busmode %x\n",
1720
                 i, l );
1721
#endif
1722
 
1723
    // Gross initialization
1724
    OUTL( 0 // No other options
1725
          // CSR_BUSMODE_PM        
1726
          // CSR_BUSMODE_WIE       
1727
          // CSR_BUSMODE_RLE       
1728
          // CSR_BUSMODE_RME       
1729
          // CSR_BUSMODE_DBO_BE    
1730
          // CSR_BUSMODE_DBO_LE    
1731
          // CSR_BUSMODE_TAP_SHIFT 
1732
          | (1 << CSR_BUSMODE_CAL_SHIFT)
1733
          | (4 << CSR_BUSMODE_PBL_SHIFT)
1734
          // CSR_BUSMODE_ENDIAN_BE 
1735
          // CSR_BUSMODE_ENDIAN_LE 
1736
          // CSR_BUSMODE_DSL_SHIFT 
1737
          // CSR_BUSMODE_BAR       
1738
          // CSR_BUSMODE_RESET     
1739
 
1740
          , CSR_BUSMODE );
1741
 
1742
    // No interrupt sources enabled yet
1743
    OUTL( 0, CSR_INTR_ENABLE );
1744
 
1745
    OUTL( 0
1746
          // CSR_ROM_MII_MGT_MDI
1747
          | CSR_ROM_MII_MGT_MOM_READ
1748
          // CSR_ROM_MII_MGT_MDO  
1749
          // CSR_ROM_MII_MGT_MDC  
1750
          // CSR_ROM_MII_MGT_RD   
1751
          // CSR_ROM_MII_MGT_WR   
1752
          // CSR_ROM_MII_MGT_BR   
1753
          // CSR_ROM_MII_MGT_SR   
1754
          // CSR_ROM_MII_MGT_REG  
1755
          // CSR_ROM_MII_MGT_SR_DO
1756
          // CSR_ROM_MII_MGT_SR_DI
1757
          // CSR_ROM_MII_MGT_SR_CK
1758
          // CSR_ROM_MII_MGT_SR_CS
1759
          | 0xff,
1760
 
1761
          CSR_ROM_MII_MGT );
1762
 
1763
    // -----------------------------------
1764
    // Now find out about the status of the PHY via MII
1765
#if 0
1766
    // Try resetting the PHY and power-cycling it:
1767
    mii_write_register( ioaddr, PHY_CONTROL_REG, PHY_CONTROL_RESET | PHY_CONTROL_AUTONEG_EN);
1768
    while (1) {
1769
        int v;
1770
        v = mii_read_register( ioaddr, PHY_CONTROL_REG );
1771
        if ( 0 == (v & PHY_CONTROL_RESET) )
1772
            break;
1773
    }
1774
 
1775
    mii_write_register( ioaddr, PHY_CONTROL_REG,
1776
                        PHY_CONTROL_POWERDOWN | PHY_CONTROL_MII_DIS | PHY_CONTROL_AUTONEG_EN );
1777
    udelay( 1000 );
1778
    mii_write_register( ioaddr, PHY_CONTROL_REG, PHY_CONTROL_AUTONEG_EN | PHY_CONTROL_AUTONEG_RST );
1779
 
1780
    udelay( 1000 );
1781
 
1782
    while (1) {
1783
        int v;
1784
        v = mii_read_register( ioaddr, PHY_STATUS_REG );
1785
        if ( PHY_STATUS_AUTONEG_ACK & v )
1786
            break;
1787
    }
1788
#endif
1789
 
1790
#ifdef DEBUG_DUMP_REGS
1791
    debug_dump_regs( ioaddr, MII );
1792
#endif
1793
 
1794
    status = i21143_status( p_i21143 );
1795
    p_i21143->line_status = status;     // record it for SNMP info
1796
#ifdef DEBUG_STARTSTOPRESET
1797
    diag_printf("i21143_reset %d flg %x Link = %s, %s Mbps, %s Duplex\n",
1798
                p_i21143->index,
1799
                *(int *)p_i21143,
1800
                (GEN_STATUS_LINK    & status) ?   "Up" : "Down",
1801
                (GEN_STATUS_100MBPS & status) ?  "100" : "10",
1802
                (GEN_STATUS_FDX     & status) ? "Full" : "Half");
1803
#endif
1804
 
1805
    OUTL( -1, CSR_ROM_PGM_ADDR );
1806
    OUTL(  0, CSR_INTR_MITIGATION );
1807
 
1808
    // CSR13, 14 = 0; select SIA mode temporarily.
1809
//    OUTL( CSR_OPMODE_MUST_BE_ONE, CSR_OPMODE);
1810
    OUTL( CSR_SIA_CONN_DEFAULT, CSR_SIA_CONN );
1811
    OUTL( CSR_SIA_TXRX_DEFAULT, CSR_SIA_TXRX );
1812
    OUTL( CSR_SIA_GPPORT_DEFAULT, CSR_SIA_GPPORT );
1813
 
1814
    // Last one, CSR6
1815
    l = 0
1816
        | CSR_OPMODE_SC
1817
        // CSR_OPMODE_RA
1818
        // CSR_OPMODE_IGNOREMSB   
1819
        | CSR_OPMODE_MUST_BE_ONE
1820
        // CSR_OPMODE_SCR      do not set for MII mode 
1821
        // CSR_OPMODE_PCS      do not set for MII mode   
1822
        // CSR_OPMODE_TTM      set for 10Mb, not set for 100Mb
1823
        | CSR_OPMODE_SF          // Set the store&forward bit so we can keep-
1824
        | CSR_OPMODE_HBD         //  -up at 100Mbit
1825
        | CSR_OPMODE_PS_MIISYM
1826
        | CSR_OPMODE_CA
1827
        // CSR_OPMODE_TX_THRES_SHIFT
1828
        // CSR_OPMODE_TX_START    
1829
        // CSR_OPMODE_FC          
1830
        // (0 << CSR_OPMODE_LOOPBACK_SHIFT)
1831
        // CSR_OPMODE_FD
1832
        // CSR_OPMODE_MULTICAST         // Pass all multicast
1833
        // CSR_OPMODE_PROMISC           // Promisc mode
1834
        // CSR_OPMODE_SB          
1835
        // CSR_OPMODE_IF                // Inverse filtering (!)         
1836
        // CSR_OPMODE_PB          
1837
        // CSR_OPMODE_HO                // 0: Perfect filter
1838
        // CSR_OPMODE_RX_START          //    1: hashing for /all/ addresses
1839
        // CSR_OPMODE_HP                // 0: Perfect filter of N address
1840
        ;                               //    1: imperfect hash filter + 1 fixed addr 
1841
 
1842
    if ( GEN_STATUS_FDX & status )
1843
        l |= CSR_OPMODE_FD;
1844
    if ( ! (GEN_STATUS_100MBPS & status) )
1845
        l |= CSR_OPMODE_TTM;
1846
 
1847
    OUTL( l, CSR_OPMODE );
1848
 
1849
}
1850
 
1851
// ------------------------------------------------------------------------
1852
//
1853
//                       INTERRUPT HANDLERS
1854
//
1855
// ------------------------------------------------------------------------
1856
 
1857
static cyg_uint32
1858
eth_isr(cyg_vector_t vector, cyg_addrword_t data)
1859
{
1860
    cyg_drv_interrupt_mask( vector );
1861
 
1862
#ifdef DEBUG_TRAFFIC
1863
    diag_printf( "i21143_isr, vector %d\n", vector );
1864
#endif
1865
 
1866
    return CYG_ISR_CALL_DSR;        // schedule DSR
1867
}
1868
 
1869
 
1870
// An indirection is used because (if we have multiple devices) we don't
1871
// know all the "sc" values at the time the interrupts are created.
1872
static
1873
void eth_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
1874
{
1875
    struct i21143* p_i21143 = (struct i21143 *)data;
1876
    struct cyg_netdevtab_entry *ndp =
1877
        (struct cyg_netdevtab_entry *)(p_i21143->ndp);
1878
    struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
1879
 
1880
    INCR_STAT( interrupts );
1881
 
1882
    // but here, it must be a *sc:
1883
    eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
1884
}
1885
 
1886
// ------------------------------------------------------------------------
1887
// Deliver routine:
1888
 
1889
void
1890
i21143_deliver(struct eth_drv_sc *sc)
1891
{
1892
    struct i21143* p_i21143 = (struct i21143 *)(sc->driver_private);
1893
    cyg_uint32 status;
1894
    cyg_uint32 ioaddr;
1895
 
1896
    IF_BAD_21143( p_i21143 ) {
1897
#ifdef DEBUG_TRAFFIC
1898
        diag_printf( "i21143_deliver: Bad device pointer %x\n", p_i21143 );
1899
#endif
1900
        return;
1901
    }
1902
 
1903
    ioaddr = p_i21143->io_address;
1904
    status = INL( CSR_STATUS );
1905
 
1906
#ifdef DEBUG_TRAFFIC
1907
    diag_printf( "i21143_deliver: status %08x\n", status );
1908
#endif
1909
 
1910
    // Acknowledge all INT sources that were active
1911
    OUTL( status, CSR_STATUS );
1912
 
1913
    // Search for link status changes
1914
    if ( i21143_status_changed( p_i21143 ) ) {
1915
#ifdef DEBUG_TRAFFIC
1916
        diag_printf( "i21143_can_send: status changed\n" );
1917
#endif
1918
        i21143_stop( sc );
1919
        i21143_start( sc, NULL, 0 );
1920
    }
1921
 
1922
    if ( (CSR_STATUS_TBU | CSR_STATUS_TX_STOPPED | CSR_STATUS_TX_INTR)
1923
         & status ) {
1924
        TxDone( p_i21143 );
1925
    }
1926
 
1927
    if ( (CSR_STATUS_RX_STOPPED | CSR_STATUS_RBU | CSR_STATUS_RX_INTR)
1928
         & status ) {
1929
        PacketRxReady( p_i21143 );
1930
    }
1931
 
1932
    cyg_drv_interrupt_acknowledge(p_i21143->vector);
1933
    cyg_drv_interrupt_unmask( p_i21143->vector );
1934
}
1935
 
1936
// ------------------------------------------------------------------------
1937
// Device table entry to operate the chip in a polled mode.
1938
// Only diddle the interface we were asked to!
1939
 
1940
void
1941
i21143_poll(struct eth_drv_sc *sc)
1942
{
1943
    struct i21143 *p_i21143;
1944
    p_i21143 = (struct i21143 *)sc->driver_private;
1945
 
1946
    IF_BAD_21143( p_i21143 ) {
1947
#ifdef DEBUG_TRAFFIC
1948
        diag_printf( "i21143_poll: Bad device pointer %x\n", p_i21143 );
1949
#endif
1950
        return;
1951
    }
1952
 
1953
    // As it happens, this driver always requests the DSR to be called:
1954
    (void)eth_isr( p_i21143->vector, (cyg_addrword_t)p_i21143 );
1955
 
1956
    // (no harm in calling this ints-off also, when polled)
1957
    i21143_deliver( sc );
1958
}
1959
 
1960
// ------------------------------------------------------------------------
1961
// Determine interrupt vector used by a device - for attaching GDB stubs
1962
// packet handler.
1963
int
1964
i21143_int_vector(struct eth_drv_sc *sc)
1965
{
1966
    struct i21143 *p_i21143;
1967
    p_i21143 = (struct i21143 *)sc->driver_private;
1968
    return (p_i21143->vector);
1969
}
1970
 
1971
// ------------------------------------------------------------------------
1972
//
1973
//  Function : pci_init_find_21143s
1974
//
1975
// This is called exactly once at the start of time to:
1976
//  o scan the PCI bus for objects
1977
//  o record them in the device table
1978
//  o acquire all the info needed for the driver to access them
1979
//  o instantiate interrupts for them
1980
//  o attach those interrupts appropriately
1981
// ------------------------------------------------------------------------
1982
static cyg_pci_match_func find_21143s_match_func;
1983
 
1984
static cyg_bool
1985
find_21143s_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
1986
{
1987
    return
1988
        (/* (0x8086 == v) || */ (0x1011 == v)) && // (Intel or) DEC
1989
        (0x0019 == d); //  [DC21142/3][PCI/CardBus 10/100 Mbit Ethernet Ctlr] 
1990
}
1991
 
1992
static int
1993
pci_init_find_21143s( void )
1994
{
1995
    cyg_pci_device_id devid;
1996
    cyg_pci_device dev_info;
1997
    cyg_uint32 l;
1998
    int device_index;
1999
    int found_devices = 0;
2000
 
2001
#ifdef DEBUG
2002
    diag_printf("pci_init_find_21143s()\n");
2003
#endif
2004
 
2005
    cyg_pci_init();
2006
#ifdef DEBUG
2007
    diag_printf("Finished cyg_pci_init();\n");
2008
#endif
2009
 
2010
    devid = CYG_PCI_NULL_DEVID;
2011
 
2012
    for (device_index = 0;
2013
         device_index < CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT;
2014
         device_index++) {
2015
        struct i21143 *p_i21143 = i21143_priv_array[device_index];
2016
 
2017
        p_i21143->index = device_index;
2018
 
2019
        // See above for find_21143s_match_func - it selects any of several
2020
        // variants.  This is necessary in case we have multiple mixed-type
2021
        // devices on one board in arbitrary orders.
2022
        if (cyg_pci_find_matching( &find_21143s_match_func, NULL, &devid )) {
2023
#ifdef DEBUG
2024
            diag_printf("eth%d = 21143\n", device_index);
2025
#endif
2026
            cyg_pci_get_device_info(devid, &dev_info);
2027
 
2028
            p_i21143->interrupt_handle = 0; // Flag not attached.
2029
            if (cyg_pci_translate_interrupt(&dev_info, &p_i21143->vector)) {
2030
#ifdef DEBUG
2031
                diag_printf(" Wired to HAL vector %d\n", p_i21143->vector);
2032
#endif
2033
                cyg_drv_interrupt_create(
2034
                    p_i21143->vector,
2035
                    0,                  // Priority - unused
2036
                    (CYG_ADDRWORD)p_i21143, // Data item passed to ISR & DSR
2037
                    eth_isr,            // ISR
2038
                    eth_dsr,            // DSR
2039
                    &p_i21143->interrupt_handle, // handle to intr obj
2040
                    &p_i21143->interrupt_object ); // space for int obj
2041
 
2042
                cyg_drv_interrupt_attach(p_i21143->interrupt_handle);
2043
 
2044
                cyg_drv_interrupt_configure( p_i21143->vector, 1, 0 );
2045
 
2046
                // Don't unmask the interrupt yet, that could get us into a
2047
                // race.
2048
            }
2049
            else {
2050
                p_i21143->vector=0;
2051
#ifdef DEBUG
2052
                diag_printf(" Does not generate interrupts.\n");
2053
#endif
2054
            }
2055
 
2056
            if (cyg_pci_configure_device(&dev_info)) {
2057
#ifdef DEBUG
2058
                int i;
2059
                diag_printf("Found device on bus %d, devfn 0x%02x:\n",
2060
                          CYG_PCI_DEV_GET_BUS(devid),
2061
                          CYG_PCI_DEV_GET_DEVFN(devid));
2062
 
2063
                if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
2064
                    diag_printf(" Note that board is active. Probed"
2065
                              " sizes and CPU addresses invalid!\n");
2066
                }
2067
                diag_printf(" Vendor    0x%04x", dev_info.vendor);
2068
                diag_printf("\n Device    0x%04x", dev_info.device);
2069
                diag_printf("\n Command   0x%04x, Status 0x%04x\n",
2070
                          dev_info.command, dev_info.status);
2071
 
2072
                diag_printf(" Class/Rev 0x%08x", dev_info.class_rev);
2073
                diag_printf("\n Header 0x%02x\n", dev_info.header_type);
2074
 
2075
                diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
2076
                          dev_info.header.normal.sub_vendor,
2077
                          dev_info.header.normal.sub_id);
2078
 
2079
                for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
2080
                    diag_printf(" BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
2081
                    diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
2082
                              dev_info.base_size[i], dev_info.base_map[i]);
2083
                }
2084
                diag_printf(" eth%d configured\n", device_index);
2085
#endif
2086
                found_devices++;
2087
                p_i21143->found = 1;
2088
                p_i21143->active = 0;
2089
                p_i21143->devid = devid;
2090
                p_i21143->io_address = dev_info.base_map[0];
2091
#ifdef DEBUG
2092
                diag_printf(" I/O address = 0x%08x\n", dev_info.base_map[0]);
2093
#endif
2094
 
2095
#ifdef pciDEBUG
2096
                diag_printf( "Before wakeup\n" );
2097
                for ( i = 0; i <= 0xe0; i += 4 ) {
2098
                    if ( i == 0x18 ) i = 0x28;
2099
                    if ( i == 0x58 ) i = 0xdc;
2100
                    cyg_pci_read_config_uint32( devid, i, &l );
2101
                    diag_printf( "PCI Config reg %02x = 0x%08x\n", i, l );
2102
                }
2103
#endif
2104
                // Awaken the device through the CFDD device-specific
2105
                // register - which boots up with it asleep - great.
2106
                l = 0;
2107
                cyg_pci_write_config_uint32( devid, 0x40, l );
2108
#ifdef pciDEBUG
2109
                diag_printf( "After wakeup\n" );
2110
                for ( i = 0; i <= 0xe0; i += 4 ) {
2111
                    if ( i == 0x18 ) i = 0x28;
2112
                    if ( i == 0x58 ) i = 0xdc;
2113
                    cyg_pci_read_config_uint32( devid, i, &l );
2114
                    diag_printf( "PCI Config reg %02x = 0x%08x\n", i, l );
2115
                }
2116
#endif
2117
                // Now the PCI part of the device is configured, reset
2118
                // it. This should make it safe to enable the
2119
                // interrupt
2120
                i21143_reset(p_i21143);
2121
 
2122
                // This is the indicator for "uses an interrupt"
2123
                if (p_i21143->interrupt_handle != 0) {
2124
                    cyg_drv_interrupt_acknowledge(p_i21143->vector);
2125
                    cyg_drv_interrupt_unmask(p_i21143->vector);
2126
                }
2127
#ifdef DEBUG
2128
                diag_printf(" **** Device enabled for I/O only and Bus Master\n");
2129
#endif
2130
            }
2131
            else {
2132
                p_i21143->found = 0;
2133
                p_i21143->active = 0;
2134
#ifdef DEBUG
2135
                diag_printf("Failed to configure device %d\n",device_index);
2136
#endif
2137
            }
2138
        }
2139
        else {
2140
            p_i21143->found = 0;
2141
            p_i21143->active = 0;
2142
#ifdef DEBUG
2143
            diag_printf("eth%d not found\n", device_index);
2144
#endif
2145
        }
2146
    }
2147
 
2148
    if (0 == found_devices)
2149
        return 0;
2150
 
2151
    // Now a delay to ensure the hardware has "come up" before you try to
2152
    // use it.
2153
    udelay( 1000 );
2154
    return 1;
2155
}
2156
 
2157
// ------------------------------------------------------------------------
2158
//
2159
//  Function : i21143_configure
2160
//
2161
//  Return : 0 = It worked.
2162
//           non0 = It failed.
2163
// ------------------------------------------------------------------------
2164
 
2165
static int i21143_configure(struct i21143* p_i21143, int promisc )
2166
{
2167
    cyg_uint32 ioaddr;
2168
    cyg_uint32 l;
2169
 
2170
    IF_BAD_21143( p_i21143 ) {
2171
#ifdef DEBUG
2172
        diag_printf( "configure: Bad device pointer %x\n",
2173
                   p_i21143 );
2174
#endif
2175
        return -1;
2176
    }
2177
 
2178
    ioaddr = p_i21143->io_address;
2179
 
2180
    l = INL( CSR_OPMODE );
2181
    if ( promisc )
2182
        l |= CSR_OPMODE_PROMISC;
2183
    else
2184
        l &=~ CSR_OPMODE_PROMISC;
2185
    OUTL( l, CSR_OPMODE );
2186
 
2187
    return 0;
2188
}
2189
 
2190
// ------------------------------------------------------------------------
2191
//
2192
//  Function : i21143_ioctl
2193
//
2194
// ------------------------------------------------------------------------
2195
static int
2196
i21143_ioctl(struct eth_drv_sc *sc, unsigned long key,
2197
             void *data, int data_length)
2198
{
2199
    struct i21143 *p_i21143;
2200
 
2201
    p_i21143 = (struct i21143 *)sc->driver_private;
2202
 
2203
    IF_BAD_21143( p_i21143 ) {
2204
#ifdef DEBUG
2205
        diag_printf( "i21143_ioctl/control: Bad device pointer %x\n", p_i21143 );
2206
#endif
2207
        return -1;
2208
    }
2209
 
2210
#ifdef DEBUG_TRAFFIC
2211
    diag_printf( "i21143_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
2212
               p_i21143->index, p_i21143, key, data, data_length );
2213
#endif
2214
 
2215
    switch ( key ) {
2216
 
2217
#ifdef ETH_DRV_SET_MAC_ADDRESS
2218
    case ETH_DRV_SET_MAC_ADDRESS: {
2219
        int act;
2220
        if ( 6 != data_length )
2221
            return -2;
2222
        act = p_i21143->active;
2223
        i21143_stop( sc );
2224
        eth_set_mac_address( p_i21143, data );
2225
        if ( act )
2226
            i21143_start( sc, NULL, 0 );
2227
        return 0;
2228
    }
2229
#endif
2230
 
2231
#ifdef ETH_DRV_GET_IF_STATS_UD
2232
    case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
2233
//        ETH_STATS_INIT( sc );    // so UPDATE the statistics structure
2234
#endif
2235
        // drop through
2236
#ifdef ETH_DRV_GET_IF_STATS
2237
    case ETH_DRV_GET_IF_STATS:
2238
#endif
2239
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
2240
    {
2241
        struct ether_drv_stats *p = (struct ether_drv_stats *)data;
2242
        int i;
2243
        static unsigned char my_chipset[]
2244
            = { ETH_DEV_DOT3STATSETHERCHIPSET };
2245
 
2246
        strcpy( p->description, CYGDAT_DEVS_ETH_DESCRIPTION );
2247
        CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
2248
 
2249
        for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
2250
            if ( 0 == (p->snmp_chipset[i] = my_chipset[i]) )
2251
                break;
2252
 
2253
        i = p_i21143->line_status;      // use cached copy - else sloooow
2254
 
2255
        if ( !( i & GEN_STATUS_LINK) ) {
2256
            p->operational = 2;         // LINK DOWN
2257
            p->duplex = 1;              // UNKNOWN
2258
            p->speed = 0;
2259
        }
2260
        else {
2261
            p->operational = 3;            // LINK UP
2262
            p->duplex = (i & GEN_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX
2263
            p->speed = ((i & GEN_STATUS_100MBPS) ? 100 : 10) * 1000000;
2264
        }
2265
 
2266
#ifdef KEEP_STATISTICS
2267
        {
2268
            struct stats *ps = &p_i21143->stats;
2269
 
2270
            // Admit to it...
2271
            p->supports_dot3        = true;
2272
 
2273
            // Those commented out are not available on this chip.
2274
 
2275
            p->tx_good              = ps->tx_good             ;
2276
            p->tx_max_collisions    = ps->tx_max_collisions   ;
2277
            p->tx_late_collisions   = ps->tx_late_collisions  ;
2278
            p->tx_underrun          = ps->tx_underrun         ;
2279
            p->tx_carrier_loss      = ps->tx_carrier_loss     ;
2280
            p->tx_deferred          = ps->tx_deferred         ;
2281
            p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;
2282
            p->tx_single_collisions = ps->tx_single_collisions;
2283
            p->tx_mult_collisions   = ps->tx_mult_collisions  ;
2284
            p->tx_total_collisions  = ps->tx_total_collisions ;
2285
 
2286
            p->rx_good              = ps->rx_good             ;
2287
            p->rx_crc_errors        = ps->rx_crc_errors       ;
2288
            p->rx_align_errors      = ps->rx_align_errors     ;
2289
            p->rx_resource_errors   = ps->rx_resource_errors  ;
2290
//            p->rx_overrun_errors    = ps->rx_overrun_errors   ;
2291
            p->rx_collisions        = ps->rx_collisions       ;
2292
            p->rx_short_frames      = ps->rx_short_frames     ;
2293
            p->rx_too_long_frames   = ps->rx_too_long_frames  ;
2294
            p->rx_symbol_errors     = ps->rx_symbol_errors    ;
2295
 
2296
            p->interrupts           = ps->interrupts          ;
2297
            p->rx_count             = ps->rx_count            ;
2298
            p->rx_deliver           = ps->rx_deliver          ;
2299
            p->rx_resource          = ps->rx_resource         ;
2300
            p->rx_restart           = ps->rx_restart          ;
2301
 
2302
            p->tx_count             = ps->tx_count            ;
2303
            p->tx_complete          = ps->tx_complete         ;
2304
            p->tx_dropped           = ps->tx_dropped          ;
2305
        }
2306
#endif // KEEP_STATISTICS
2307
 
2308
        p->tx_queue_len = 1;
2309
 
2310
        return 0; // OK
2311
    }
2312
#endif
2313
 
2314
    default:
2315
        break;
2316
    }
2317
    return -1;
2318
}
2319
 
2320
// ------------------------------------------------------------------------
2321
 
2322
static void
2323
eth_set_mac_address( struct i21143* p_i21143, cyg_uint8 *addr )
2324
{
2325
    cyg_uint32 ioaddr = p_i21143->io_address;
2326
    cyg_uint32 l;
2327
    int i;
2328
    volatile BUFDES *bp;
2329
    cyg_uint8 *datap;
2330
 
2331
#define SETUP_SIZE (192)
2332
 
2333
    cyg_uint32 buf[ SETUP_SIZE/4 ]; // for word alignment
2334
 
2335
    // We need to send a pseudo-transmit which contains setup data.
2336
 
2337
    if ( NULL == addr )
2338
        addr = &p_i21143->mac_address[0];
2339
    else {
2340
        p_i21143->mac_address[0] = addr[0];
2341
        p_i21143->mac_address[1] = addr[1];
2342
        p_i21143->mac_address[2] = addr[2];
2343
        p_i21143->mac_address[3] = addr[3];
2344
        p_i21143->mac_address[4] = addr[4];
2345
        p_i21143->mac_address[5] = addr[5];
2346
    }
2347
 
2348
    if ( ! p_i21143->active ) {
2349
        // Then do not torment the hardware - starting
2350
        // the interface will do that.
2351
        p_i21143->mac_addr_ok = 1;
2352
        return;
2353
    }
2354
 
2355
    InitTxRing( p_i21143 ); // Since we are about to use this struct
2356
 
2357
    bp = p_i21143->tx_ring;
2358
 
2359
    bp->des0 = DES0_STATUS_OWN_DONE; // Safety: not for the NIC yet
2360
 
2361
    bp->buf1 = CYGHWR_PCI_VIRT_TO_BUS( ((cyg_uint32)&buf[0]) );
2362
    bp->buf2 = 0;
2363
 
2364
    datap = (cyg_uint8 *)CYGHWR_BUS_TO_UNCACHED( bp->buf1 );
2365
 
2366
    bp->des1 =
2367
        DES1_ENDRING |
2368
        TDES1_CONTROL_SETUP |
2369
        //TDES1_CONTROL_SETUP_FT0 |  // 0,0 <=> perfect filtering
2370
        //TDES1_CONTROL_SETUP_FT1 | 
2371
        (SETUP_SIZE << DES1_B1SIZE_SHIFT);
2372
    // The filtering type is 00 = perfect filtering of 16 addresses
2373
    // (including the broadcast address, I think)
2374
 
2375
    for ( i = 0; i < SETUP_SIZE ; i++ )
2376
        datap[i] = 0xff; // fill the space with the broadcast address
2377
 
2378
    // Insert the address: do it in an endian agnostic fashion.
2379
    // [If we were doing perfect plus hash table it would be slot
2380
    //  13 at offset 156.  Lower halfwords only.]
2381
    // So we'll use slot 13 anyway; the other slots are all FFs.
2382
 
2383
    datap[156] = addr[0];
2384
    datap[157] = addr[1];
2385
    datap[158] = addr[1];
2386
    datap[159] = addr[0];
2387
    datap[160] = addr[2];
2388
    datap[161] = addr[3];
2389
    datap[162] = addr[3];
2390
    datap[163] = addr[2];
2391
    datap[164] = addr[4];
2392
    datap[165] = addr[5];
2393
    datap[166] = addr[5];
2394
    datap[167] = addr[4];
2395
 
2396
    // Make the rest be null links
2397
    for ( i = 1; i < TX_DESCRIPTORS; i++ ) {
2398
        int x;
2399
        p_i21143->tx_ring[ i ].buf1 = 0;
2400
        p_i21143->tx_ring[ i ].buf2 = 0;
2401
        x = 0; // zero size for both buffers
2402
        if ( (TX_DESCRIPTORS-1) == i )
2403
            x |= DES1_ENDRING;
2404
         p_i21143->tx_ring[ i ].des1 = x;
2405
         p_i21143->tx_ring[ i ].des0 = DES0_STATUS_OWN_OPEN;
2406
    }
2407
 
2408
    // Tell the device the address
2409
    OUTL( CYGHWR_PCI_VIRT_TO_BUS( (cyg_uint32)bp ), CSR_TXBASE );
2410
    // Open the descriptor to the device
2411
    bp->des0 = DES0_STATUS_OWN_OPEN;
2412
 
2413
#ifdef DEBUG_MAC
2414
    dump_tx_details( p_i21143, "set_mac starting:" );
2415
#endif
2416
    // And set it going
2417
    l = INL( CSR_OPMODE );
2418
    l |= CSR_OPMODE_TX_START;
2419
    OUTL( l, CSR_OPMODE );
2420
 
2421
    // Wait for the buffer to be closed
2422
    for ( i = 0; i < 10000; i++ )
2423
        if ( DES0_STATUS_OWN_DONE == (DES0_STATUS_OWN & bp->des0) )
2424
            break;
2425
#ifdef DEBUG_MAC
2426
    diag_printf( "eth_set_mac_address: %d loops: bufdesc status tdes0 %08x, tdes1 %08x\n",
2427
                 i, bp->des0, bp->des1 );
2428
#endif
2429
 
2430
    // Wait for it to be done
2431
    for ( i = 0; i < 10000; i++ ) {
2432
        l = INL( CSR_STATUS );
2433
        if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) ||
2434
             ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_SUSPENDED) )
2435
            break;
2436
    }
2437
 
2438
#ifdef DEBUG_MAC
2439
    diag_printf( "eth_set_mac_address: tx done after %d iters; status %x\n",
2440
                 i, l );
2441
#endif
2442
 
2443
#ifdef DEBUG_MAC
2444
    dump_tx_details( p_i21143, "set_mac all done:" );
2445
#endif
2446
 
2447
    // Kill the tx engine
2448
    l = INL( CSR_OPMODE );
2449
    l &=~ CSR_OPMODE_TX_START;
2450
    OUTL( l, CSR_OPMODE );
2451
 
2452
    for ( i = 0; i < 10000; i++ ) {
2453
        l = INL( CSR_STATUS );
2454
        if ( ((CSR_STATUS_TXSTATUS & l) == CSR_STATUS_TXSTATUS_STOPPED) )
2455
            break;
2456
    }
2457
#ifdef DEBUG_MAC
2458
    diag_printf( "eth_set_mac_address: tx stopped after %d iters; status %x\n",
2459
                 i, l );
2460
#endif
2461
 
2462
    // Acknowledge all the interrupts from these activities
2463
    // within the device:
2464
    OUTL( 0xffffffff, CSR_STATUS ); // clear all bits
2465
 
2466
    p_i21143->mac_addr_ok = 1;
2467
 
2468
}
2469
 
2470
// ------------------------------------------------------------------------
2471
//
2472
//                     MDIO
2473
//
2474
// Device-specific bit-twiddling and line driving side-effects
2475
 
2476
// CYGACC_CALL_IF_DELAY_US() drags in huge amounts of scheduler locking and
2477
// the like 'cos it's a VV call!  We only want a delay of 1uS tops, so:
2478
 
2479
#define MII_DELAY() do { int z; for ( z = 0; z < 20; z++ ) ; } while (0)
2480
 
2481
#if 0
2482
# define MII_PRINTF diag_printf
2483
# define MII_STUFF "%4s | %4s | %4s | %4s [%08x]\n",    \
2484
    (l & (1<<19)) ? "MDI" : "---",                      \
2485
    (l & (1<<18)) ? "Read" : "Wr",                      \
2486
    (l & (1<<17)) ? "MDO" : "---",                      \
2487
    (l & (1<<16)) ? "CLK" : "clk",                      \
2488
    l
2489
#else
2490
# define MII_PRINTF( foo )
2491
# define MII_STUFF
2492
#endif
2493
 
2494
static inline void mii_clock_up( int ioaddr )
2495
{
2496
    cyg_uint32 l;
2497
    l = INL( CSR_ROM_MII_MGT );
2498
    l |= CSR_ROM_MII_MGT_MDC;
2499
    OUTL( l, CSR_ROM_MII_MGT );
2500
    MII_PRINTF( "mii_clock_up  : " MII_STUFF  );
2501
    MII_DELAY();
2502
}
2503
 
2504
static inline void mii_clock_down( int ioaddr )
2505
{
2506
    cyg_uint32 l;
2507
    l = INL( CSR_ROM_MII_MGT );
2508
    l &=~ CSR_ROM_MII_MGT_MDC;
2509
    OUTL( l, CSR_ROM_MII_MGT );
2510
    MII_PRINTF( "mii_clock_down: " MII_STUFF  );
2511
    MII_DELAY();
2512
}
2513
 
2514
static inline void mii_read_mode( int ioaddr )
2515
{
2516
    cyg_uint32 l;
2517
    l = INL( CSR_ROM_MII_MGT );
2518
    l |= CSR_ROM_MII_MGT_MOM_READ;
2519
    OUTL( l, CSR_ROM_MII_MGT );
2520
    MII_PRINTF( "mii_read_mode : " MII_STUFF  );
2521
    MII_DELAY();
2522
}
2523
 
2524
static inline int mii_read_data_bit( int ioaddr )
2525
{
2526
    cyg_uint32 l;
2527
    l = INL( CSR_ROM_MII_MGT );
2528
    MII_PRINTF( "mii_read_data : " MII_STUFF  );
2529
    return CSR_ROM_MII_MGT_MDI == (CSR_ROM_MII_MGT_MDI & l);
2530
}
2531
 
2532
static inline void mii_write_data_bit( int ioaddr, int databit )
2533
{
2534
    cyg_uint32 l;
2535
    l = INL( CSR_ROM_MII_MGT );
2536
    if ( databit )
2537
        l |= CSR_ROM_MII_MGT_MDO;
2538
    else
2539
        l &=~ CSR_ROM_MII_MGT_MDO;
2540
    l &=~ CSR_ROM_MII_MGT_MOM; // drive the mdio line
2541
    OUTL( l, CSR_ROM_MII_MGT );
2542
    MII_PRINTF( "mii_write_data: " MII_STUFF  );
2543
    MII_DELAY();
2544
}
2545
 
2546
// Pass ioaddr around "invisibly"
2547
#define MII_CLOCK_UP()            mii_clock_up(ioaddr)
2548
#define MII_CLOCK_DOWN()          mii_clock_down(ioaddr)
2549
#define MII_READ_MODE()           mii_read_mode(ioaddr)
2550
#define MII_READ_DATA_BIT()       mii_read_data_bit(ioaddr)
2551
#define MII_WRITE_DATA_BIT( _d_ ) mii_write_data_bit(ioaddr,(_d_))
2552
 
2553
// ------------------------------------------------------------------------
2554
//
2555
//                     MDIO
2556
//
2557
// Management data over the MII interface - nasty hand driven serial stuff
2558
//
2559
 
2560
static void mii_write_bits( int ioaddr, int val, int bitcount )
2561
{
2562
    int i;
2563
    // These are deliberately signed ints so that we can send an overlong
2564
    // preamble if we want by saying "send -1 of width 40 bits and relying
2565
    // on sign extension.
2566
    for ( i = bitcount - 1; i >= 0; i-- ) {
2567
        MII_CLOCK_DOWN();
2568
        MII_WRITE_DATA_BIT( (val >> i) & 1 );
2569
        MII_CLOCK_UP();
2570
    }
2571
}
2572
 
2573
static int mii_read_bits( int ioaddr, int bitcount )
2574
{
2575
    int i;
2576
    int val = 0;
2577
    for ( i = bitcount - 1; i >= 0; i-- ) {
2578
        MII_CLOCK_DOWN();
2579
        val <<= 1;
2580
        val |= MII_READ_DATA_BIT();
2581
        MII_CLOCK_UP();
2582
    }
2583
    return val;
2584
}
2585
 
2586
#define MII_WRITE_BITS( val, bitcount ) mii_write_bits( ioaddr, val, bitcount )
2587
#define MII_READ_BITS( bitcount )       mii_read_bits( ioaddr, bitcount )
2588
 
2589
// Now define subsections of the protocol in terms of the above
2590
 
2591
#define MII_WRITE_PREAMBLE()    MII_WRITE_BITS( -1, 40 )  // >32 x 1s
2592
#define MII_WRITE_START()       MII_WRITE_BITS( 1, 2 )    // 01
2593
#define MII_WRITE_WRITE_CMD()   MII_WRITE_BITS( 1, 2 )    // 01
2594
#define MII_WRITE_READ_CMD()    MII_WRITE_BITS( 2, 2 )    // 10
2595
 
2596
#define PHY_ADDRESS (1)
2597
 
2598
#define MII_WRITE_PHY_ADDR()    MII_WRITE_BITS( PHY_ADDRESS, 5 )
2599
#define MII_WRITE_REGNUM( _r_ ) MII_WRITE_BITS( (_r_), 5 )
2600
 
2601
#define MII_WRITE_TURNAROUND()  MII_WRITE_BITS( 2, 2 )
2602
 
2603
#define MII_READ_TURNAROUND()   CYG_MACRO_START         \
2604
  MII_READ_MODE(); /* to turn off driving the line */   \
2605
  (void)(MII_READ_BITS( 2 )); /* discard TA "bits" */   \
2606
CYG_MACRO_END
2607
 
2608
#define MII_IDLE() CYG_MACRO_START                              \
2609
  MII_READ_MODE(); /* to turn off driving the line */           \
2610
  ((void)MII_READ_BITS( 5 )); /* extra clocks in Hi-Z mode */   \
2611
  MII_CLOCK_DOWN();                                             \
2612
CYG_MACRO_END
2613
 
2614
#define MII_READ_REGVAL()       MII_READ_BITS( 16 )
2615
#define MII_WRITE_REGVAL( _v_ ) MII_WRITE_BITS( (_v_), 16 )
2616
 
2617
static int mii_read_register( int ioaddr, int regnum )
2618
{
2619
    int value;
2620
    MII_WRITE_PREAMBLE();
2621
    MII_WRITE_START();
2622
    MII_WRITE_READ_CMD();
2623
    MII_WRITE_PHY_ADDR();
2624
    MII_WRITE_REGNUM( regnum );
2625
    MII_READ_TURNAROUND();
2626
    value = MII_READ_REGVAL();
2627
    MII_IDLE();
2628
    return value;
2629
}
2630
 
2631
static void mii_write_register( int ioaddr, int regnum, int value )
2632
{
2633
    MII_WRITE_PREAMBLE();
2634
    MII_WRITE_START();
2635
    MII_WRITE_WRITE_CMD();
2636
    MII_WRITE_PHY_ADDR();
2637
    MII_WRITE_REGNUM( regnum );
2638
    MII_WRITE_TURNAROUND();
2639
    MII_WRITE_REGVAL( value );
2640
    MII_IDLE();
2641
}
2642
 
2643
// ------------------------------------------------------------------------
2644
//
2645
// Serial EEPROM access  - much like the other Intel ethernet
2646
//
2647
 
2648
// CYGACC_CALL_IF_DELAY_US() drags in huge amounts of scheduler locking and
2649
// the like 'cos it's a VV call!  Waste of time, mostly.
2650
 
2651
#define EE_DELAY() do { int z; for ( z = 0; z < 0x1000; z++ ) ; } while (0)
2652
 
2653
#if 0
2654
# define EE_PRINTF diag_printf
2655
# define EE_STUFF "%4s | %4s | %4s | %4s [%08x]\n",     \
2656
    (l & (1<<2)) ? "eeDI" : "---",                      \
2657
    (l & (1<<0)) ? "eeCS" : "--",                       \
2658
    (l & (1<<3)) ? "eeDO" : "---",                      \
2659
    (l & (1<<1)) ? "CLK"  : "clk",                      \
2660
    l & 0xfffff
2661
#else
2662
# define EE_PRINTF( foo )
2663
# define EE_STUFF
2664
#endif
2665
 
2666
 
2667
static inline void ee_select( int ioaddr )
2668
{
2669
    cyg_uint32 l;
2670
    l = CSR_ROM_MII_MGT_SR | CSR_ROM_MII_MGT_RD
2671
        | CSR_ROM_MII_MGT_MOM_READ; // Keep MII in read mode
2672
    OUTL( l, CSR_ROM_MII_MGT );
2673
    EE_DELAY();
2674
    l |= CSR_ROM_MII_MGT_SR_CS;
2675
    OUTL( l, CSR_ROM_MII_MGT );
2676
    EE_PRINTF( "ee_select    : " EE_STUFF  );
2677
    EE_DELAY();
2678
}
2679
 
2680
static inline void ee_deselect( int ioaddr )
2681
{
2682
    cyg_uint32 l;
2683
    l = CSR_ROM_MII_MGT_SR | CSR_ROM_MII_MGT_RD
2684
        | CSR_ROM_MII_MGT_MOM_READ; // Keep MII in read mode
2685
    OUTL( l, CSR_ROM_MII_MGT );
2686
    EE_PRINTF( "ee_deselect 1: " EE_STUFF  );
2687
    EE_DELAY();
2688
    EE_DELAY();
2689
    EE_DELAY();
2690
    l = 0
2691
        | CSR_ROM_MII_MGT_MOM_READ; // Keep MII in read mode
2692
    OUTL( l, CSR_ROM_MII_MGT );
2693
    EE_PRINTF( "ee_deselect 2: " EE_STUFF  );
2694
    EE_DELAY();
2695
    EE_DELAY();
2696
    EE_DELAY();
2697
}
2698
 
2699
static inline void ee_clock_up( int ioaddr )
2700
{
2701
    cyg_uint32 l;
2702
    l = INL( CSR_ROM_MII_MGT );
2703
    l |= CSR_ROM_MII_MGT_SR_CK;
2704
    OUTL( l, CSR_ROM_MII_MGT );
2705
    EE_PRINTF( "ee_clock_up  : " EE_STUFF  );
2706
    EE_DELAY();
2707
}
2708
 
2709
static inline void ee_clock_down( int ioaddr )
2710
{
2711
    cyg_uint32 l;
2712
    l = INL( CSR_ROM_MII_MGT );
2713
    l &=~ CSR_ROM_MII_MGT_SR_CK;
2714
    OUTL( l, CSR_ROM_MII_MGT );
2715
    EE_PRINTF( "ee_clock_down: " EE_STUFF  );
2716
    EE_DELAY();
2717
}
2718
 
2719
static inline int ee_read_data_bit( int ioaddr )
2720
{
2721
    cyg_uint32 l;
2722
    l = INL( CSR_ROM_MII_MGT );
2723
    EE_PRINTF( "ee_read_data : " EE_STUFF  );
2724
    return CSR_ROM_MII_MGT_SR_DO == (CSR_ROM_MII_MGT_SR_DO & l);
2725
}
2726
 
2727
static inline void ee_write_data_bit( int ioaddr, int databit )
2728
{
2729
    cyg_uint32 l;
2730
    l = INL( CSR_ROM_MII_MGT );
2731
    if ( databit )
2732
        l |= CSR_ROM_MII_MGT_SR_DI;
2733
    else
2734
        l &=~ CSR_ROM_MII_MGT_SR_DI;
2735
    OUTL( l, CSR_ROM_MII_MGT );
2736
    EE_PRINTF( "ee_write_data: " EE_STUFF  );
2737
    EE_DELAY();
2738
}
2739
 
2740
// Pass ioaddr around "invisibly"
2741
#define EE_SELECT()              ee_select(ioaddr)
2742
#define EE_DESELECT()            ee_deselect(ioaddr)
2743
#define EE_CLOCK_UP()            ee_clock_up(ioaddr)
2744
#define EE_CLOCK_DOWN()          ee_clock_down(ioaddr)
2745
#define EE_READ_DATA_BIT()       ee_read_data_bit(ioaddr)
2746
#define EE_WRITE_DATA_BIT( _d_ ) ee_write_data_bit(ioaddr,(_d_))
2747
 
2748
// ------------------------------------------------------------------------
2749
 
2750
static int
2751
get_eeprom_size( int ioaddr )
2752
{
2753
    int i, addrbits, tmp;
2754
 
2755
    // Should already be not-selected, but anyway:
2756
    EE_SELECT();
2757
 
2758
    // Shift the read command bits out.
2759
    for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
2760
        tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command.
2761
        EE_WRITE_DATA_BIT(tmp);
2762
        EE_CLOCK_UP();
2763
        EE_CLOCK_DOWN();
2764
    }
2765
    // Now clock out address zero, looking for the dummy 0 data bit
2766
    for ( i = 1; i <= 12; i++ ) {
2767
        EE_WRITE_DATA_BIT(0);
2768
        EE_CLOCK_UP();
2769
        tmp = EE_READ_DATA_BIT();
2770
        EE_CLOCK_DOWN();
2771
        if ( !tmp )
2772
            break;
2773
    }
2774
 
2775
#ifdef DEBUG_EE
2776
    diag_printf( "eeprom data bits %d\n", i );
2777
#endif
2778
 
2779
    if ( 6 != i && 8 != i && 1 != i) {
2780
#ifdef DEBUG_EE
2781
        diag_printf( "*****EEPROM data bits not 6, 8 or 1*****\n" );
2782
#endif
2783
        addrbits = 1; // Flag no eeprom here.
2784
    }
2785
    else
2786
        addrbits = i;
2787
 
2788
    // read in the data regardless
2789
    tmp = 0;
2790
    for (i = 15; i >= 0; i--) {
2791
        EE_CLOCK_UP();
2792
        if ( EE_READ_DATA_BIT() )
2793
            tmp |= (1<<i);
2794
        EE_CLOCK_DOWN();
2795
    }
2796
 
2797
#ifdef DEBUG_EE
2798
    diag_printf( "eeprom first data word %x\n", tmp );
2799
#endif
2800
 
2801
    // Terminate the EEPROM access.
2802
    EE_DESELECT();
2803
 
2804
    return addrbits;
2805
}
2806
 
2807
static int
2808
read_eeprom_word( int ioaddr, int addrbits, int address )
2809
{
2810
    int i, tmp;
2811
 
2812
    // Should already be not-selected, but anyway:
2813
    EE_SELECT();
2814
 
2815
    // Shift the read command bits out.
2816
    for (i = 3; i >= 0; i--) { // Doc says to shift out a zero then:
2817
        tmp = (6 & (1 << i)) ? 1 : 0; // "6" is the "read" command.
2818
        EE_WRITE_DATA_BIT(tmp);
2819
        EE_CLOCK_UP();
2820
        EE_CLOCK_DOWN();
2821
    }
2822
    // Now clock out address
2823
    for ( i = addrbits - 1; i >= 0 ; i-- ) {
2824
        tmp = (address & (1<<i)) ? 1 : 0;
2825
        EE_WRITE_DATA_BIT(tmp);
2826
        EE_CLOCK_UP();
2827
        tmp = EE_READ_DATA_BIT();
2828
        EE_CLOCK_DOWN();
2829
 
2830
        CYG_ASSERT( (0 == tmp) == (0 == i), "Looking for zero handshake bit" );
2831
    }
2832
 
2833
    // read in the data
2834
    tmp = 0;
2835
    for (i = 15; i >= 0; i--) {
2836
        EE_CLOCK_UP();
2837
        if ( EE_READ_DATA_BIT() )
2838
            tmp |= (1<<i);
2839
        EE_CLOCK_DOWN();
2840
    }
2841
 
2842
    // Terminate the EEPROM access.
2843
    EE_DESELECT();
2844
 
2845
#ifdef DEBUG_EE
2846
    diag_printf( "eeprom address %4x: data %4x\n", address, tmp );
2847
#endif
2848
 
2849
    return tmp;
2850
}
2851
 
2852
// ------------------------------------------------------------------------
2853
 
2854
// EOF if_i21143.c
2855
 

powered by: WebSVN 2.1.0

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