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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [eth/] [smsc/] [lan91cxx/] [current/] [src/] [if_lan91cxx.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      dev/if_lan91cxx.c
4
//
5
//      Ethernet device driver for SMSC LAN91CXX compatible controllers
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, 2003, 2004 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):    hmt, based on lan900 (for LAN91C110) driver by jskov
43
//               jskov, based on CS8900 driver by Gary Thomas
44
// Contributors: gthomas, jskov, hmt, jco@ict.es, nickg
45
// Date:         2001-01-22
46
// Purpose:      
47
// Description:  hardware driver for LAN91CXX "LAN9000" ethernet
48
// Notes:        Pointer register is not saved/restored on receive interrupts.
49
//               The pointer is shared by both receive/transmit code.
50
//               But the net stack manages atomicity for you here.
51
//
52
//               The controller has an autorelease mode that allows TX packets
53
//               to be freed automatically on successful transmission - but
54
//               that is not used since we're only sending one packet at a
55
//               time anyway.
56
//               We may want to pingpong in future for throughput reasons.
57
//
58
//               <jco@ict.es> Added support for PCMCIA mode and shifted
59
//               address buses.
60
//
61
//####DESCRIPTIONEND####
62
//
63
//==========================================================================
64
 
65
// Based on LAN91C110 and LAN91C96
66
 
67
#include <pkgconf/system.h>
68
#include <pkgconf/devs_eth_smsc_lan91cxx.h>
69
#include <pkgconf/io_eth_drivers.h>
70
 
71
#include <cyg/infra/cyg_type.h>
72
#include <cyg/hal/hal_arch.h>
73
#include <cyg/hal/hal_intr.h>
74
#include <cyg/hal/hal_diag.h>
75
#include <cyg/infra/cyg_ass.h>
76
#include <cyg/infra/diag.h>
77
#include <cyg/hal/drv_api.h>
78
#include <cyg/io/eth/netdev.h>
79
#include <cyg/io/eth/eth_drv.h>
80
#ifdef CYGPKG_NET
81
#include <pkgconf/net.h>
82
#include <cyg/kernel/kapi.h>
83
#include <net/if.h>  /* Needed for struct ifnet */
84
#endif
85
 
86
#ifdef CYGPKG_INFRA_DEBUG
87
// Then we log, OOI, the number of times we get a bad packet number
88
// from the tx done fifo.
89
int lan91cxx_txfifo_good = 0;
90
int lan91cxx_txfifo_bad = 0;
91
#endif
92
 
93
// Set to perms of:
94
// 0 disables all debug output
95
// 1 for process debug output
96
// 2 for added data IO output: get_reg, put_reg
97
// 4 for packet allocation/free output
98
// 8 for only startup status, so we can tell we're installed OK
99
#define DEBUG 0
100
 
101
 
102
#if DEBUG
103
#if defined(CYGPKG_REDBOOT)
104
static void db_printf( char *fmt, ... )
105
{
106
    extern int start_console(void);
107
    extern void end_console(int);
108
    va_list a;
109
    int old_console;
110
    va_start( a, fmt );
111
    old_console = start_console();
112
    diag_vprintf( fmt, a );
113
    end_console(old_console);
114
    va_end( a );
115
}
116
#else
117
#if 0
118
static void db_printf( char *fmt, ... )
119
{
120
    va_list a;
121
    int old_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
122
    va_start( a, fmt );
123
    CYGACC_CALL_IF_SET_CONSOLE_COMM( 0 );
124
    diag_vprintf( fmt, a );
125
    CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
126
    va_end( a );
127
}
128
#else
129
#define db_printf diag_printf
130
#endif
131
#endif
132
#else
133
#if 0
134
static void db_printf( char *fmt, ... )
135
{
136
    va_list a;
137
    int old_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
138
    va_start( a, fmt );
139
    CYGACC_CALL_IF_SET_CONSOLE_COMM( 0 );
140
    diag_vprintf( fmt, a );
141
    CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
142
    va_end( a );
143
}
144
#else
145
#define db_printf( fmt, ... )
146
#endif
147
#endif
148
 
149
 
150
#if DEBUG & 1
151
#define DEBUG_FUNCTION() do { db_printf("%s\n", __FUNCTION__); } while (0)
152
#else
153
#define DEBUG_FUNCTION() do {} while(0)
154
#endif
155
 
156
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
157
#define KEEP_STATISTICS
158
#endif
159
 
160
#ifdef KEEP_STATISTICS
161
#define INCR_STAT( _x_ )        (cpd->stats. _x_ ++)
162
#else
163
#define INCR_STAT( _x_ )        CYG_EMPTY_STATEMENT
164
#endif
165
 
166
#include "smsc_lan91cxx.h"
167
 
168
#ifdef LAN91CXX_IS_LAN91C111
169
static void lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
170
                               cyg_uint8 phyreg, cyg_uint16 value);
171
static cyg_uint16 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
172
                                    cyg_uint8 phyreg);
173
#endif
174
 
175
static void lan91cxx_poll(struct eth_drv_sc *sc);
176
 
177
 
178
#ifdef LAN91CXX_IS_LAN91C111
179
// Revision A of the LAN91C111 has a bug in which it does not set the
180
// ODD bit in the status word and control byte of received packets. We
181
// work around this by assuming the bit is always set and tacking the
182
// extra odd byte onto the packet anyway. Higher protocol levels never
183
// believe the packet size reported by the driver and always use the
184
// values in the protocol headers. So this workaround is quite safe.
185
// In theory nobody should be using the RevA part now, but it appears
186
// that some people still have some in their parts bins.
187
#define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) \
188
        (((__cpd)->c111_reva)?1:((__stat) & LAN91CXX_RX_STATUS_ODDFRM))
189
#define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) \
190
        (((__cpd)->c111_reva)?1:((__val) & LAN91CXX_CONTROLBYTE_ODD))
191
#else
192
#define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) ((__stat) & LAN91CXX_RX_STATUS_ODDFRM)
193
#define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) ((__val) & LAN91CXX_CONTROLBYTE_ODD)
194
#endif
195
 
196
#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
197
static cyg_interrupt lan91cxx_interrupt;
198
static cyg_handle_t  lan91cxx_interrupt_handle;
199
 
200
// This ISR is called when the ethernet interrupt occurs
201
static int lan91cxx_isr(cyg_vector_t vector, cyg_addrword_t data)
202
             /* , HAL_SavedRegisters *regs */
203
{
204
    struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
205
    struct lan91cxx_priv_data *cpd =
206
        (struct lan91cxx_priv_data *)sc->driver_private;
207
 
208
//    DEBUG_FUNCTION();
209
 
210
    INCR_STAT( interrupts );
211
 
212
    cyg_drv_interrupt_mask(cpd->interrupt);
213
    cyg_drv_interrupt_acknowledge(cpd->interrupt);
214
 
215
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
216
}
217
#endif
218
 
219
// The deliver function (ex-DSR)  handles the ethernet [logical] processing
220
static void
221
lan91cxx_deliver(struct eth_drv_sc *sc)
222
{
223
    struct lan91cxx_priv_data *cpd =
224
        (struct lan91cxx_priv_data *)sc->driver_private;
225
 
226
//    DEBUG_FUNCTION();
227
 
228
    // Service the interrupt:
229
    lan91cxx_poll(sc);
230
    // Allow interrupts to happen again
231
    cyg_drv_interrupt_unmask(cpd->interrupt);
232
}
233
 
234
static int
235
lan91cxx_int_vector(struct eth_drv_sc *sc)
236
{
237
    struct lan91cxx_priv_data *cpd =
238
        (struct lan91cxx_priv_data *)sc->driver_private;
239
 
240
    return (cpd->interrupt);
241
}
242
 
243
static bool
244
smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
245
{
246
    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
247
    struct lan91cxx_priv_data *cpd =
248
        (struct lan91cxx_priv_data *)sc->driver_private;
249
    unsigned short val;
250
    int i;
251
#if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
252
    unsigned char ecor, ecsr;
253
#endif
254
    cyg_bool esa_configured = false;
255
 
256
    DEBUG_FUNCTION();
257
 
258
    cpd->txbusy = cpd->within_send = 0;
259
 
260
#ifdef CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR
261
    cpd->addrsh = CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR;
262
#else
263
    cpd->addrsh = 0;
264
#endif
265
 
266
#if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
267
 
268
    // If the chip is configured in PCMCIA mode, the internal
269
    // registers mapped in the attribute memory should be
270
    // initialized (i.e. to enable the I/O map)
271
 
272
    ecor = get_att(sc, LAN91CXX_ECOR);
273
 
274
    // pulse SRESET on ECOR
275
    ecor |= LAN91CXX_ECOR_RESET;
276
    put_att(sc, LAN91CXX_ECOR, ecor);
277
 
278
    CYGACC_CALL_IF_DELAY_US(1);
279
 
280
    ecor &= ~LAN91CXX_ECOR_RESET;
281
    put_att(sc, LAN91CXX_ECOR, ecor);
282
 
283
    // then, enable I/O map
284
    ecor |= LAN91CXX_ECOR_ENABLE;
285
    put_att(sc, LAN91CXX_ECOR, ecor);
286
 
287
    // verify the register contents
288
    if (ecor != get_att(sc, LAN91CXX_ECOR))
289
        db_printf("LAN91CXX - Cannot access PCMCIA attribute registers\n");
290
 
291
    ecsr = get_att(sc, LAN91CXX_ECSR);
292
#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_8_BIT
293
#error "91CXX 8-bit mode not yet supported."
294
    ecsr |= LAN91CXX_ECSR_IOIS8;
295
#else
296
    ecsr &= ~LAN91CXX_ECSR_IOIS8;
297
#endif
298
    put_att(sc, LAN91CXX_ECSR, ecsr);
299
 
300
#endif
301
 
302
#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
303
    // Initialize environment, setup interrupt handler
304
    cyg_drv_interrupt_create(cpd->interrupt,
305
                             CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
306
                             (cyg_addrword_t)sc, //  Data item passed to interrupt handler
307
                             (cyg_ISR_t *)lan91cxx_isr,
308
                             (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR
309
                             &lan91cxx_interrupt_handle,
310
                             &lan91cxx_interrupt);
311
    cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
312
#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
313
    cyg_drv_interrupt_acknowledge(cpd->interrupt);
314
    cyg_drv_interrupt_unmask(cpd->interrupt);
315
 
316
    // probe chip by reading the signature in BS register
317
    val = get_banksel(sc);
318
#if DEBUG & 9
319
    db_printf("LAN91CXX - supposed BankReg @ %x = %04x\n",
320
                cpd->base+LAN91CXX_BS, val );
321
#endif
322
 
323
    if ((0xff00 & val) !=  0x3300) {
324
        CYG_FAIL("No 91Cxx signature" );
325
        diag_printf("smsc_lan91cxx_init: No 91Cxx signature found\n");
326
        return false;
327
    }
328
 
329
    val = get_reg(sc, LAN91CXX_REVISION);
330
 
331
#if DEBUG & 9
332
    db_printf("LAN91CXX - type: %01x, rev: %01x\n",
333
                (val>>4)&0xf, val & 0xf);
334
#endif
335
 
336
#ifdef LAN91CXX_IS_LAN91C111
337
    // Set RevA flag for LAN91C111 so we can cope with the odd-bit bug.
338
    cpd->c111_reva = (val == 0x3390);
339
#endif
340
 
341
    // The controller may provide a function used to set up the ESA
342
    if (cpd->config_enaddr)
343
        (*cpd->config_enaddr)(cpd);
344
 
345
    // Reset chip
346
    put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
347
    put_reg(sc, LAN91CXX_RCR, 0);
348
 
349
    val = get_reg(sc, LAN91CXX_EPH_STATUS);
350
#ifndef LAN91CXX_IS_LAN91C111
351
    // LINK_OK on 91C111 is just a general purpose input and may not
352
    // have anything to do with the link.
353
    if (!(val & LAN91CXX_STATUS_LINK_OK)) {
354
        db_printf("no link\n");
355
        return false;  // Link not connected
356
    }
357
#endif
358
 
359
 
360
#if DEBUG & 9
361
    db_printf("LAN91CXX - status: %04x\n", val);
362
#endif
363
 
364
#if 0 < CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
365
    // Use statically configured ESA from the private data
366
#if DEBUG & 9
367
    db_printf("LAN91CXX - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
368
                cpd->enaddr[0],
369
                cpd->enaddr[1],
370
                cpd->enaddr[2],
371
                cpd->enaddr[3],
372
                cpd->enaddr[4],
373
                cpd->enaddr[5] );
374
#endif // DEBUG
375
    // Set up hardware address
376
    for (i = 0;  i < sizeof(cpd->enaddr);  i += 2)
377
        put_reg(sc, LAN91CXX_IA01+i/2,
378
                cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
379
#else // not CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
380
    // Find ESA - check possible sources in sequence and stop when
381
    // one provides the ESA:
382
    //   RedBoot option (via provide_esa)
383
    //   Compile-time configuration
384
    //   EEPROM
385
 
386
    if (NULL != cpd->provide_esa) {
387
        esa_configured = cpd->provide_esa(cpd);
388
# if DEBUG & 8
389
        if (esa_configured)
390
            db_printf("Got ESA from RedBoot option\n");
391
# endif
392
    }
393
    if (!esa_configured && cpd->hardwired_esa) {
394
        // ESA is already set in cpd->esa[]
395
        esa_configured = true;
396
# if DEBUG & 8
397
        db_printf("Got ESA from cpd\n");
398
# endif
399
    }
400
    if (esa_configured) {
401
        // Set up hardware address
402
        for (i = 0;  i < sizeof(cpd->enaddr);  i += 2)
403
            put_reg(sc, LAN91CXX_IA01+i/2,
404
                    cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
405
    } else {
406
        // Use the address from the serial EEPROM
407
        // Read out hardware address
408
        for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
409
            unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
410
            cpd->enaddr[i] =   (unsigned char)(0xff & z);
411
            cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
412
        }
413
        esa_configured = true;
414
# if DEBUG & 8
415
        db_printf("Got ESA from eeprom\n");
416
# endif
417
    }
418
#if DEBUG & 9
419
    db_printf("LAN91CXX - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
420
                cpd->enaddr[0],
421
                cpd->enaddr[1],
422
                cpd->enaddr[2],
423
                cpd->enaddr[3],
424
                cpd->enaddr[4],
425
                cpd->enaddr[5] );
426
#endif // DEBUG
427
#endif // !CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
428
 
429
    // Initialize upper level driver
430
    (sc->funs->eth_drv->init)(sc, cpd->enaddr);
431
    return true;
432
}
433
 
434
static void
435
lan91cxx_stop(struct eth_drv_sc *sc)
436
{
437
    struct lan91cxx_priv_data *cpd =
438
        (struct lan91cxx_priv_data *)sc->driver_private;
439
    DEBUG_FUNCTION();
440
 
441
    CYG_ASSERT( cpd->within_send < 10, "stop: Excess send recursions" );
442
    cpd->within_send++;
443
    // Complete any outstanding activity:
444
    if ( cpd->txbusy ) {
445
        cpd->txbusy = 0;
446
#if DEBUG & 9
447
        db_printf("LAN91CXX - Stopping, cleaning up pending TX\n" );
448
#endif
449
        (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
450
    }
451
    // Reset chip
452
    put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
453
    put_reg(sc, LAN91CXX_RCR, 0);
454
    cpd->txbusy = cpd->within_send = 0;
455
}
456
 
457
//
458
// This function is called to "start up" the interface.  It may be called
459
// multiple times, even when the hardware is already running.  It will be
460
// called whenever something "hardware oriented" changes and should leave
461
// the hardware ready to send/receive packets.
462
//
463
static void
464
lan91cxx_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
465
{
466
    cyg_uint16 intr;
467
#ifdef LAN91CXX_IS_LAN91C111
468
    int delay;
469
#endif
470
#ifdef CYGPKG_NET
471
    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
472
#endif
473
    DEBUG_FUNCTION();
474
 
475
#ifdef LAN91CXX_IS_LAN91C111
476
    // 91C111 Errata. Internal PHY comes up disabled. Must enable here.
477
    lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_RST);
478
    CYGACC_CALL_IF_DELAY_US(500000);
479
    lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_ANEG_EN |
480
                                                 LAN91CXX_PHY_CTRL_SPEED);
481
 
482
#ifdef LAN91CXX_FORCE_10MHZ
483
    lan91cxx_write_phy( sc, 0, LAN91CXX_PHY_AUTO_AD, 0x0061);
484
#endif
485
 
486
    // Start auto-negotiation
487
    put_reg(sc, LAN91CXX_RPCR,
488
            LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK | LAN91CXX_RPCR_ANEG);
489
 
490
    // wait for auto-negotiation to finish.
491
    // give it ~5 seconds before giving up (no cable?)
492
    delay = 50;
493
    while (!(lan91cxx_read_phy(sc, 0, LAN91CXX_PHY_STAT) & 0x20)) {
494
        if (--delay <= 0)
495
            break;
496
        CYGACC_CALL_IF_DELAY_US(100000);
497
    }
498
#if DEBUG & 1
499
    if (delay <= 0)
500
            diag_printf("auto-negotiation failed.\n");
501
#endif
502
#endif
503
 
504
    put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_reset_mmu);
505
 
506
    put_reg(sc, LAN91CXX_INTERRUPT, 0);   // disable interrupts
507
    intr = get_reg(sc, LAN91CXX_INTERRUPT);
508
    put_reg(sc, LAN91CXX_INTERRUPT, intr &      // ack old interrupts
509
            (LAN91CXX_INTERRUPT_TX_INT | LAN91CXX_INTERRUPT_TX_EMPTY_INT |
510
            LAN91CXX_INTERRUPT_RX_OVRN_INT | LAN91CXX_INTERRUPT_ERCV_INT));
511
    put_reg(sc, LAN91CXX_RCR,
512
#ifdef RCR_HAS_ABORT_ENB // 91C96 does not - page 46.
513
            LAN91CXX_RCR_ABORT_ENB |
514
#endif
515
            LAN91CXX_RCR_STRIP_CRC |
516
            LAN91CXX_RCR_RXEN | LAN91CXX_RCR_ALMUL);
517
    put_reg(sc, LAN91CXX_TCR, LAN91CXX_TCR_TXENA | LAN91CXX_TCR_PAD_EN);
518
    put_reg(sc, LAN91CXX_CONTROL, 0);
519
    put_reg(sc, LAN91CXX_INTERRUPT,       // enable interrupts
520
            LAN91CXX_INTERRUPT_RCV_INT_M);
521
 
522
#ifdef CYGPKG_NET
523
    if (( 0
524
#ifdef ETH_DRV_FLAGS_PROMISC_MODE
525
         != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
526
#endif
527
        ) || (ifp->if_flags & IFF_PROMISC)
528
        ) {
529
        // Then we select promiscuous mode.
530
        unsigned short rcr;
531
        rcr = get_reg(sc, LAN91CXX_RCR );
532
        rcr |= LAN91CXX_RCR_PRMS;
533
        put_reg(sc, LAN91CXX_RCR, rcr );
534
    }
535
#endif
536
}
537
 
538
//
539
// This routine is called to perform special "control" opertions
540
//
541
static int
542
lan91cxx_control(struct eth_drv_sc *sc, unsigned long key,
543
               void *data, int data_length)
544
{
545
    unsigned char *esa = (unsigned char *)data;
546
    int i;
547
    unsigned short reg;
548
    struct lan91cxx_priv_data *cpd =
549
        (struct lan91cxx_priv_data *)sc->driver_private;
550
 
551
    DEBUG_FUNCTION();
552
 
553
    switch (key) {
554
    case ETH_DRV_SET_MAC_ADDRESS:
555
#if 9 & DEBUG
556
        db_printf("LAN91CXX - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
557
                esa[0],
558
                esa[1],
559
                esa[2],
560
                esa[3],
561
                esa[4],
562
                esa[5] );
563
#ifndef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
564
        db_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n");
565
#endif
566
#endif // DEBUG
567
 
568
#ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
569
        // Only now can we command the chip to perform EEPROM writes:
570
 
571
        // select arbitrary writing to the EEPROM
572
        reg = get_reg(sc, LAN91CXX_CONTROL);
573
        reg |= LAN91CXX_CONTROL_EEPROM_SELECT;
574
        put_reg(sc, LAN91CXX_CONTROL, reg );
575
 
576
        for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
577
            int j;
578
            // Set the address register
579
            put_reg(sc, LAN91CXX_POINTER, LAN91CXX_ESA_EEPROM_OFFSET + i/2);
580
            // Poke the data
581
            put_reg(sc, LAN91CXX_GENERAL, esa[i] | (esa[i+1] << 8));
582
            // Command the store
583
            reg = get_reg(sc, LAN91CXX_CONTROL);
584
            reg |= LAN91CXX_CONTROL_STORE;
585
            put_reg(sc, LAN91CXX_CONTROL, reg );
586
            // and poll for completion
587
            for ( j = 1024 * 1024; 0 < j ; j-- ) {
588
                reg = get_reg(sc, LAN91CXX_CONTROL);
589
                if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
590
                    break;
591
            }
592
            CYG_ASSERT( 0 < j, "EEPROM write timout!" );
593
        }
594
 
595
        reg = get_reg(sc, LAN91CXX_CONTROL);
596
        CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY),
597
                    "EEPROM still busy!" );
598
        // Clear the EEPROM selection bit
599
        reg &=~LAN91CXX_CONTROL_EEPROM_SELECT;
600
        put_reg(sc, LAN91CXX_CONTROL, reg );
601
        // and check it "took"
602
        reg = get_reg(sc, LAN91CXX_CONTROL);
603
        CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_SELECT),
604
                    "EEPROM still selected!" );
605
        // and command a complete reload
606
        reg |= LAN91CXX_CONTROL_RELOAD;
607
        put_reg(sc, LAN91CXX_CONTROL, reg );
608
        for ( i = 1024 * 1024; 0 < i ; i-- ) {
609
            reg = get_reg(sc, LAN91CXX_CONTROL);
610
            if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
611
                break;
612
        }
613
        CYG_ASSERT( 0 < i, "EEPROM reload timout!" );
614
        // Now extract the MAC address that is in the chip, and tell the
615
        // system about it.
616
        for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
617
            unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
618
            cpd->enaddr[i] =   (unsigned char)(0xff & z);
619
            cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
620
        }
621
#if DEBUG & 9
622
        db_printf("LAN91CXX - eeprom new ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
623
                    cpd->enaddr[0],
624
                    cpd->enaddr[1],
625
                    cpd->enaddr[2],
626
                    cpd->enaddr[3],
627
                    cpd->enaddr[4],
628
                    cpd->enaddr[5] );
629
#endif // DEBUG
630
        for (i = 0;  i < sizeof(cpd->enaddr);  i++ ) {
631
            CYG_ASSERT( esa[i] == cpd->enaddr[i], "ESA not written correctly" );
632
            if ( esa[i] != cpd->enaddr[i] )
633
                return 1; // the operation failed.
634
        }
635
#else // not CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
636
        // Whatever, we can write the MAC address into the interface info,
637
        // and the chip registers no problem.
638
        for ( i = 0; i < sizeof(cpd->enaddr);  i++ )
639
            cpd->enaddr[i] = esa[i];
640
        for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
641
            reg = cpd->enaddr[i] | (cpd->enaddr[i+1] << 8);
642
            put_reg(sc, LAN91CXX_IA01+i/2, reg );
643
        }
644
#endif // !CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
645
        return 0;
646
 
647
#ifdef ETH_DRV_GET_MAC_ADDRESS
648
    case ETH_DRV_GET_MAC_ADDRESS:
649
        // Extract the MAC address that is in the chip, and tell the
650
        // system about it.
651
        for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
652
            unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
653
            esa[i] =   (unsigned char)(0xff & z);
654
            esa[i+1] = (unsigned char)(0xff & (z >> 8));
655
        }
656
        return 0;
657
#endif
658
 
659
#ifdef ETH_DRV_GET_IF_STATS_UD
660
    case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
661
#endif
662
        // drop through
663
#ifdef ETH_DRV_GET_IF_STATS
664
    case ETH_DRV_GET_IF_STATS:
665
#endif
666
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
667
    {
668
        struct ether_drv_stats *p = (struct ether_drv_stats *)data;
669
        // Chipset entry is no longer supported; RFC1573.
670
        for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
671
            p->snmp_chipset[i] = 0;
672
 
673
        // This perhaps should be a config opt, so you can make up your own
674
        // description, or supply it from the instantiation.
675
        strcpy( p->description, "SMSC LAN91Cxx" );
676
        // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
677
 
678
        reg = get_reg(sc, LAN91CXX_EPH_STATUS);
679
        if ((reg & LAN91CXX_STATUS_LINK_OK) == 0) {
680
            p->operational = 2;         // LINK DOWN
681
            p->duplex = 1;              // UNKNOWN
682
            p->speed = 0;
683
        }
684
        else {
685
            p->operational = 3;         // LINK UP
686
            p->duplex = 2;              // 2 = SIMPLEX, 3 = DUPLEX
687
            p->speed = 10 * 1000000;    // it's only a 10Mbit device
688
        }
689
 
690
#ifdef KEEP_STATISTICS
691
        {
692
            struct smsc_lan91cxx_stats *ps = &(cpd->stats);
693
 
694
            // Admit to it...
695
            p->supports_dot3        = true;
696
 
697
            p->tx_good              = ps->tx_good             ;
698
            p->tx_max_collisions    = ps->tx_max_collisions   ;
699
            p->tx_late_collisions   = ps->tx_late_collisions  ;
700
            p->tx_underrun          = ps->tx_underrun         ;
701
            p->tx_carrier_loss      = ps->tx_carrier_loss     ;
702
            p->tx_deferred          = ps->tx_deferred         ;
703
            p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;
704
            p->tx_single_collisions = ps->tx_single_collisions;
705
            p->tx_mult_collisions   = ps->tx_mult_collisions  ;
706
            p->tx_total_collisions  = ps->tx_total_collisions ;
707
            p->rx_good              = ps->rx_good             ;
708
            p->rx_crc_errors        = ps->rx_crc_errors       ;
709
            p->rx_align_errors      = ps->rx_align_errors     ;
710
            p->rx_resource_errors   = ps->rx_resource_errors  ;
711
            p->rx_overrun_errors    = ps->rx_overrun_errors   ;
712
            p->rx_collisions        = ps->rx_collisions       ;
713
            p->rx_short_frames      = ps->rx_short_frames     ;
714
            p->rx_too_long_frames   = ps->rx_too_long_frames  ;
715
            p->rx_symbol_errors     = ps->rx_symbol_errors    ;
716
 
717
            p->interrupts           = ps->interrupts          ;
718
            p->rx_count             = ps->rx_count            ;
719
            p->rx_deliver           = ps->rx_deliver          ;
720
            p->rx_resource          = ps->rx_resource         ;
721
            p->rx_restart           = ps->rx_restart          ;
722
            p->tx_count             = ps->tx_count            ;
723
            p->tx_complete          = ps->tx_complete         ;
724
            p->tx_dropped           = ps->tx_dropped          ;
725
        }
726
#endif // KEEP_STATISTICS
727
 
728
        p->tx_queue_len = 1;
729
 
730
        return 0; // OK
731
    }
732
#endif
733
    default:
734
        break;
735
    }
736
    return 1;
737
}
738
 
739
//
740
// This routine is called to see if it is possible to send another packet.
741
// It will return non-zero if a transmit is possible, zero otherwise.
742
//
743
static int
744
lan91cxx_can_send(struct eth_drv_sc *sc)
745
{
746
    struct lan91cxx_priv_data *cpd =
747
        (struct lan91cxx_priv_data *)sc->driver_private;
748
    int tcr;
749
 
750
//    DEBUG_FUNCTION();
751
 
752
#ifndef LAN91CXX_IS_LAN91C111
753
    // LINK_OK on 91C111 is just a general purpose input and may not
754
    // have anything to do with the link.
755
    if ((get_reg(sc, LAN91CXX_EPH_STATUS) & LAN91CXX_STATUS_LINK_OK) == 0) {
756
        db_printf("no link\n");
757
        return false;  // Link not connected
758
    }
759
#endif
760
 
761
    CYG_ASSERT( cpd->within_send < 10, "can_send: Excess send recursions" );
762
    cpd->within_send++;
763
 
764
    tcr = get_reg(sc, LAN91CXX_TCR);
765
    if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
766
#if DEBUG & 1
767
        db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
768
#endif
769
        // Complete any outstanding activity:
770
        if ( cpd->txbusy ) {
771
            cpd->txbusy = 0;
772
#if DEBUG & 9
773
            db_printf("LAN91CXX - can_send, cleaning up pending TX\n" );
774
#endif
775
            (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
776
        }
777
        tcr |= LAN91CXX_TCR_TXENA;
778
        put_reg(sc, LAN91CXX_TCR, tcr);
779
    }
780
 
781
    // This helps unstick deadly embraces.
782
    lan91cxx_poll( sc ); // Deal with any outstanding rx state
783
    cpd->within_send--;
784
 
785
    return (cpd->txbusy == 0) && (0 == cpd->within_send);
786
}
787
 
788
//
789
// This routine is called to send data to the hardware.
790
static void
791
lan91cxx_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
792
            int total_len, unsigned long key)
793
{
794
    struct lan91cxx_priv_data *cpd =
795
        (struct lan91cxx_priv_data *)sc->driver_private;
796
    int i, len, plen, tcr;
797
 
798
    cyg_uint8 *sdata;
799
    cyg_uint16 data = 0;
800
    int dpos = 0;
801
    unsigned short ints, control;
802
    cyg_uint16 packet, status;
803
 
804
    DEBUG_FUNCTION();
805
 
806
    INCR_STAT( tx_count );
807
 
808
#if DEBUG & 1
809
    ints = get_reg(sc, LAN91CXX_INTERRUPT);
810
    db_printf("%s:START: ints: %04x\n", __FUNCTION__, ints);
811
#endif
812
 
813
    // Worry about the TX engine stopping.
814
    tcr = get_reg(sc, LAN91CXX_TCR);
815
    if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
816
#if DEBUG & 1
817
        db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
818
#endif
819
        tcr |= LAN91CXX_TCR_TXENA;
820
        put_reg(sc, LAN91CXX_TCR, tcr);
821
    }
822
 
823
    // This helps unstick deadly embraces.
824
    CYG_ASSERT( cpd->within_send < 10, "send: Excess send recursions" );
825
    cpd->within_send++;
826
    lan91cxx_poll( sc ); // Deal with any outstanding rx state
827
    cpd->within_send--;
828
 
829
    cpd->txbusy = 1;
830
    cpd->txkey = key;
831
 
832
    // Find packet length
833
    plen = 0;
834
    for (i = 0;  i < sg_len;  i++)
835
        plen += sg_list[i].len;
836
 
837
    CYG_ASSERT( plen == total_len, "sg data length mismatch" );
838
 
839
    // Alloc new TX packet
840
    do {
841
        put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_alloc_for_tx
842
#ifndef LAN91CXX_IS_LAN91C111
843
                | ((plen >> 8) & 0x07)
844
#endif
845
            );
846
 
847
        i = 1024 * 1024;
848
        do {
849
            status = get_reg(sc, LAN91CXX_INTERRUPT);
850
        } while (0 == (status & LAN91CXX_INTERRUPT_ALLOC_INT) && (--i > 0) );
851
        if ( i )
852
            packet = get_reg(sc, LAN91CXX_PNR);
853
        else
854
            packet = 0xffff;
855
#if DEBUG & 1
856
        db_printf("%s: allocated packet %04x\n", __FUNCTION__, packet);
857
#endif
858
        packet = packet >> 8;
859
        if (packet & 0x80) {
860
            // Hm.. Isn't this a dead end?
861
#if DEBUG & 1
862
            db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
863
#endif
864
            // Not if we can make progress with what's filling memory.
865
            lan91cxx_poll( sc ); // Deal with any outstanding state
866
            continue;
867
        }
868
    } while (0);
869
 
870
#if DEBUG & 4
871
    db_printf("#####Tx packet allocated 0x%04x (previous 0x%04x)\n",
872
                packet, cpd->txpacket);
873
#endif
874
    cpd->txpacket = packet;
875
 
876
    put_reg(sc, LAN91CXX_PNR, packet);
877
    // Note: Check FIFO state here before continuing?
878
    put_reg(sc, LAN91CXX_POINTER, LAN91CXX_POINTER_AUTO_INCR | 0x0000);
879
    // Pointer is now set, and the proper bank is selected for
880
    // data writes.
881
 
882
    // Prepare header:
883
    put_data(sc, CYG_CPU_TO_LE16(0));        // reserve space for status word
884
    // packet length (includes status, byte-count and control shorts)
885
    put_data(sc, CYG_CPU_TO_LE16(0x7FE & (plen + 6)) ); // Always even, always < 15xx(dec)
886
 
887
    for (i = 0;  i < sg_len;  i++) {
888
        sdata = (cyg_uint8 *)sg_list[i].buf;
889
        len = sg_list[i].len;
890
        while( len > 0 )
891
        {
892
            data |= *sdata<<((dpos&1)*8);
893
            dpos++, len--, sdata++;
894
            if( (dpos & 1) == 0 )
895
            {
896
                put_data(sc, CYG_CPU_TO_LE16(data));
897
                data = 0;
898
            }
899
        }
900
    }
901
 
902
    // Lay down the control short unconditionally at the end.
903
    // (or it might use random memory contents)
904
    control = 0;
905
    if( 1 & plen ) {
906
        // Need to set ODD flag and insert the data
907
        control = data;
908
        control |= LAN91CXX_CONTROLBYTE_ODD;
909
    }
910
    control |= LAN91CXX_CONTROLBYTE_CRC; // Just in case...
911
    put_data(sc, CYG_CPU_TO_LE16(control));
912
 
913
    // Enqueue the packet
914
    put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_enq_packet);
915
 
916
    // Ack TX empty int and unmask it.
917
    ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
918
    put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_ACK);
919
    put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_M);
920
 
921
#if DEBUG & 1
922
    ints = get_reg(sc, LAN91CXX_INTERRUPT);
923
    db_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, ints);
924
#endif
925
}
926
 
927
static void
928
lan91cxx_TxEvent(struct eth_drv_sc *sc, int stat)
929
{
930
    unsigned short packet, ints, tcr;
931
    struct lan91cxx_priv_data *cpd =
932
        (struct lan91cxx_priv_data *)sc->driver_private;
933
    int success = 1;
934
 
935
    DEBUG_FUNCTION();
936
 
937
    INCR_STAT( tx_complete );
938
 
939
    // Ack and mask TX interrupt set
940
    ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
941
    ints |= LAN91CXX_INTERRUPT_TX_SET_ACK;
942
    ints &= ~LAN91CXX_INTERRUPT_TX_SET_M;
943
    put_reg(sc, LAN91CXX_INTERRUPT, ints);
944
 
945
    // Get number of completed packet and read the status word
946
    packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
947
#if DEBUG & 1
948
    db_printf("%s:START: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
949
#endif
950
 
951
#ifdef KEEP_STATISTICS
952
    {
953
        unsigned short reg;
954
 
955
        reg = get_reg( sc, LAN91CXX_EPH_STATUS );
956
 
957
        // Covering each bit in turn...
958
        if ( reg & LAN91CXX_STATUS_TX_UNRN   ) INCR_STAT( tx_underrun );
959
        //if ( reg & LAN91CXX_STATUS_LINK_OK ) INCR_STAT(  );
960
        //if ( reg & LAN91CXX_STATUS_CTR_ROL ) INCR_STAT(  );
961
        //if ( reg & LAN91CXX_STATUS_EXC_DEF ) INCR_STAT(  );
962
        if ( reg & LAN91CXX_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
963
        if ( reg & LAN91CXX_STATUS_LATCOL    ) INCR_STAT( tx_late_collisions );
964
        //if ( reg & LAN91CXX_STATUS_WAKEUP  ) INCR_STAT(  );
965
        if ( reg & LAN91CXX_STATUS_TX_DEFR   ) INCR_STAT( tx_deferred );
966
        //if ( reg & LAN91CXX_STATUS_LTX_BRD ) INCR_STAT(  );
967
        if ( reg & LAN91CXX_STATUS_SQET      ) INCR_STAT( tx_sqetesterrors );
968
        if ( reg & LAN91CXX_STATUS_16COL     ) INCR_STAT( tx_max_collisions );
969
        //if ( reg & LAN91CXX_STATUS_LTX_MULT) INCR_STAT(  );
970
        if ( reg & LAN91CXX_STATUS_MUL_COL   ) INCR_STAT( tx_mult_collisions );
971
        if ( reg & LAN91CXX_STATUS_SNGL_COL  ) INCR_STAT( tx_single_collisions );
972
        if ( reg & LAN91CXX_STATUS_TX_SUC    ) INCR_STAT( tx_good );
973
 
974
        cpd->stats.tx_total_collisions =
975
            cpd->stats.tx_late_collisions +
976
            cpd->stats.tx_max_collisions +
977
            cpd->stats.tx_mult_collisions +
978
            cpd->stats.tx_single_collisions;
979
 
980
        // We do not need to look in the Counter Register (LAN91CXX_COUNTER)
981
        // because it just mimics the info we already have above.
982
    }
983
#endif // KEEP_STATISTICS
984
    // We do not really care about Tx failure.  Ethernet is not a reliable
985
    // medium.  But we do care about the TX engine stopping.
986
    tcr = get_reg(sc, LAN91CXX_TCR);
987
    if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
988
#if DEBUG & 1
989
        db_printf("%s: ENGINE RESTART: tcr 0x%04x eph 0x%04x ints 0x%04x\n", __FUNCTION__, tcr, get_reg(sc, LAN91CXX_EPH_STATUS), ints);
990
#endif
991
        tcr |= LAN91CXX_TCR_TXENA;
992
        put_reg(sc, LAN91CXX_TCR, tcr);
993
        success = 0; // And treat this as an error...
994
    }
995
 
996
    packet &= 0xff;
997
 
998
    // It certainly appears that occasionally the tx fifo tells lies; we
999
    // get the wrong packet number.  Freeing the one we allocated seems to
1000
    // give correct operation.
1001
#ifdef CYGPKG_INFRA_DEBUG
1002
    // Then we log, OOI, the number of times we get a bad packet number
1003
    // from the tx done fifo.
1004
    if (cpd->txpacket != packet )
1005
        lan91cxx_txfifo_bad++;
1006
    else
1007
        lan91cxx_txfifo_good++;
1008
#endif
1009
#if DEBUG & 4
1010
    db_printf("#####Tx packet freed 0x%04x (expected 0x%04x)\n", packet, cpd->txpacket );
1011
#endif
1012
    // and then free the packet
1013
    put_reg(sc, LAN91CXX_PNR, cpd->txpacket);
1014
    put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_rel_packet);
1015
 
1016
    // Ack the TX int which is supposed to clear the packet from the TX
1017
    // completion queue.
1018
    ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
1019
    ints |= LAN91CXX_INTERRUPT_TX_FIFO_ACK;
1020
    put_reg(sc, LAN91CXX_INTERRUPT, ints);
1021
 
1022
#if DEBUG & 1
1023
    // Hm... The free doesn't seem to have the desired effect?!?
1024
    ints = get_reg(sc, LAN91CXX_INTERRUPT);
1025
    packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
1026
    db_printf("%s:END: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
1027
#endif
1028
 
1029
    if ( cpd->txbusy ) {
1030
        cpd->txbusy = 0;
1031
        (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
1032
    }
1033
}
1034
 
1035
void get_data_init(struct eth_drv_sc *sc)
1036
{
1037
    struct lan91cxx_priv_data *cpd =
1038
        (struct lan91cxx_priv_data *)sc->driver_private;
1039
 
1040
    cpd->data_buf = 0xa5a5a5a5;
1041
    cpd->data_pos = sizeof(rxd_t);
1042
}
1043
 
1044
cyg_uint8 get_data_byte(struct eth_drv_sc *sc)
1045
{
1046
    cyg_uint8 c;
1047
    struct lan91cxx_priv_data *cpd =
1048
        (struct lan91cxx_priv_data *)sc->driver_private;
1049
 
1050
    if( cpd->data_pos == sizeof(rxd_t) )
1051
    {
1052
        cpd->data_buf = get_data(sc);
1053
        cpd->data_pos = 0;
1054
    }
1055
 
1056
    c = (cpd->data_buf>>(cpd->data_pos*8))&0xFF;
1057
    cpd->data_pos++;
1058
 
1059
    return c;
1060
 
1061
}
1062
 
1063
cyg_uint16 get_data_short(struct eth_drv_sc *sc)
1064
{
1065
    cyg_uint16 val;
1066
 
1067
    val = get_data_byte(sc);
1068
    val |= get_data_byte(sc)<<8;
1069
 
1070
    return CYG_LE16_TO_CPU(val);
1071
}
1072
 
1073
//
1074
// This function is called when a packet has been received.  Its job is
1075
// to prepare to unload the packet from the hardware.  Once the length of
1076
// the packet is known, the upper layer of the driver can be told.  When
1077
// the upper layer is ready to unload the packet, the internal function
1078
// 'lan91cxx_recv' will be called to actually fetch it from the hardware.
1079
//
1080
static void
1081
lan91cxx_RxEvent(struct eth_drv_sc *sc)
1082
{
1083
    struct lan91cxx_priv_data *cpd =
1084
        (struct lan91cxx_priv_data *)sc->driver_private;
1085
    unsigned short stat, len;
1086
 
1087
    DEBUG_FUNCTION();
1088
 
1089
    stat = get_reg(sc, LAN91CXX_FIFO_PORTS);
1090
#if DEBUG & 1
1091
    db_printf("RxEvent - FIFOs: 0x%04x\n", stat);
1092
#endif
1093
    if ( 0x8000 & stat ) {
1094
        // Then the Rx FIFO is empty
1095
#if DEBUG & 4
1096
        db_printf("#####RxEvent with empty fifo\n");
1097
#endif
1098
        return;
1099
    }
1100
 
1101
    INCR_STAT( rx_count );
1102
 
1103
#if DEBUG & 4
1104
    db_printf("#####Rx packet allocated 0x%04x (previous 0x%04x)\n",
1105
                0xff & (stat >> 8), cpd->rxpacket );
1106
#endif
1107
    // There is an Rx Packet ready
1108
    cpd->rxpacket = 0xff & (stat >> 8);
1109
 
1110
    // Read status and (word) length
1111
    put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1112
                                 LAN91CXX_POINTER_AUTO_INCR | 0x0000));
1113
    get_data_init(sc);
1114
 
1115
    stat = get_data_short(sc);
1116
    len = get_data_short(sc);
1117
    len = len - 6;     // minus header/footer words
1118
 
1119
#ifdef KEEP_STATISTICS
1120
    if ( stat & LAN91CXX_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors );
1121
    //if ( stat & LAN91CXX_RX_STATUS_BCAST    ) INCR_STAT(  );
1122
    if ( stat & LAN91CXX_RX_STATUS_BADCRC   ) INCR_STAT( rx_crc_errors );
1123
    if ( stat & LAN91CXX_RX_STATUS_TOOLONG  ) INCR_STAT( rx_too_long_frames );
1124
    if ( stat & LAN91CXX_RX_STATUS_TOOSHORT ) INCR_STAT( rx_short_frames );
1125
    //if ( stat & LAN91CXX_RX_STATUS_MCAST    ) INCR_STAT(  );
1126
#endif // KEEP_STATISTICS
1127
 
1128
    if ((stat & LAN91CXX_RX_STATUS_BAD) == 0) {
1129
        INCR_STAT( rx_good );
1130
        // Then it's OK
1131
 
1132
        if( LAN91CXX_RX_STATUS_IS_ODD(cpd,stat) )
1133
            len++;
1134
 
1135
#if DEBUG & 1
1136
        db_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len);
1137
#endif
1138
        // Check for bogusly short packets; can happen in promisc mode:
1139
        // Asserted against and checked by upper layer driver.
1140
#ifdef CYGPKG_NET
1141
        if ( len > sizeof( struct ether_header ) )
1142
            // then it is acceptable; offer the data to the network stack
1143
#endif
1144
        (sc->funs->eth_drv->recv)(sc, len);
1145
 
1146
        return;
1147
    }
1148
 
1149
    // Not OK for one reason or another...
1150
#if DEBUG & 1
1151
    db_printf("RxEvent - bad rx: stat: 0x%04x, len: 0x%04x\n", stat, len);
1152
    db_printf("PHY %2d: %04x\n",0,lan91cxx_read_phy( sc, 0, 0));
1153
    db_printf("PHY %2d: %04x\n",1,lan91cxx_read_phy( sc, 0, 1));
1154
    db_printf("PHY %2d: %04x\n",2,lan91cxx_read_phy( sc, 0, 2));
1155
    db_printf("PHY %2d: %04x\n",3,lan91cxx_read_phy( sc, 0, 3));
1156
    db_printf("PHY %2d: %04x\n",4,lan91cxx_read_phy( sc, 0, 4));
1157
    db_printf("PHY %2d: %04x\n",5,lan91cxx_read_phy( sc, 0, 5));
1158
    db_printf("PHY %2d: %04x\n",16,lan91cxx_read_phy( sc, 0, 16));
1159
    db_printf("PHY %2d: %04x\n",17,lan91cxx_read_phy( sc, 0, 17));
1160
    db_printf("PHY %2d: %04x\n",18,lan91cxx_read_phy( sc, 0, 18));
1161
    db_printf("PHY %2d: %04x\n",19,lan91cxx_read_phy( sc, 0, 19));
1162
    db_printf("PHY %2d: %04x\n",20,lan91cxx_read_phy( sc, 0, 20));
1163
#endif
1164
 
1165
    // Free packet
1166
    put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
1167
}
1168
 
1169
 
1170
//
1171
// This function is called as a result of the "eth_drv_recv()" call above.
1172
// Its job is to actually fetch data for a packet from the hardware once
1173
// memory buffers have been allocated for the packet.  Note that the buffers
1174
// may come in pieces, using a scatter-gather list.  This allows for more
1175
// efficient processing in the upper layers of the stack.
1176
//
1177
static void
1178
lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
1179
{
1180
#if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || \
1181
    defined(KEEP_STATISTICS) || defined(LAN91CXX_IS_LAN91C111)
1182
    struct lan91cxx_priv_data *cpd =
1183
        (struct lan91cxx_priv_data *)sc->driver_private;
1184
#endif
1185
    int i;
1186
    short mlen=0, plen;
1187
    cyg_uint8 *data=NULL;
1188
    short val;
1189
    unsigned char *cp, cval;
1190
 
1191
    DEBUG_FUNCTION();
1192
 
1193
    INCR_STAT( rx_deliver );
1194
 
1195
    put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1196
                                 LAN91CXX_POINTER_AUTO_INCR));
1197
    get_data_init(sc);
1198
 
1199
    val = get_data_short(sc);
1200
    plen = get_data_short(sc);
1201
    plen = plen - 6;
1202
 
1203
    for (i = 0;  i < sg_len;  i++) {
1204
        int clen;
1205
        data = (cyg_uint8 *)sg_list[i].buf;
1206
        mlen = sg_list[i].len;
1207
 
1208
        clen = mlen;
1209
        if( clen > plen )
1210
            clen = plen;
1211
 
1212
#if DEBUG & 1
1213
        db_printf("%s : mlen 0x%04x plen 0x%04x clen 0x%04x\n", __FUNCTION__, mlen, plen, clen);
1214
#endif
1215
        mlen -= clen;
1216
        plen -= clen;
1217
 
1218
        if (data) {
1219
            while( clen > 0 ) {
1220
                *data++ = get_data_byte(sc);
1221
                clen--;
1222
            }
1223
        }
1224
        else { // must actively discard ie. read it from the chip anyway.
1225
#if DEBUG & 1            
1226
            db_printf("lan91cxx_recv: No data!!!!!\n");
1227
#endif
1228
            while( clen > 0 ) {
1229
                (void)get_data_byte(sc);
1230
                clen--;
1231
            }
1232
        }
1233
#if DEBUG & 1
1234
        diag_dump_buf( sg_list[i].buf, sg_list[i].len > 64 ? 64 : sg_list[i].len );
1235
#endif
1236
    }
1237
    val = get_data_short(sc); // Read control word (and potential data) unconditionally
1238
 
1239
    cp = (unsigned char *)data;
1240
 
1241
    CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX,
1242
               "Controlbyte is not for Rx");
1243
    CYG_ASSERT( (1 == mlen) == (0 != LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val)),
1244
                "Controlbyte does not match");
1245
    if (data && (1 == mlen) && LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val) ) {
1246
        cval = val & 0x00ff;    // last byte contains data
1247
        *cp = cval;
1248
    }
1249
 
1250
    val = get_reg(sc, LAN91CXX_FIFO_PORTS);
1251
#if DEBUG & 4
1252
    if ( 0x8000 & val ) // Then the Rx FIFO is empty
1253
        db_printf("#####Rx packet NOT freed, stat is 0x%04x (expected 0x%04x)\n",
1254
                    val, cpd->rxpacket);
1255
    else
1256
        db_printf("#####Rx packet freed 0x%04x (expected 0x%04x)\n",
1257
                    0xff & (val >> 8), cpd->rxpacket );
1258
#endif
1259
    CYG_ASSERT( (0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet" );
1260
 
1261
    // Free packet
1262
    put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
1263
}
1264
 
1265
 
1266
static void
1267
lan91cxx_poll(struct eth_drv_sc *sc)
1268
{
1269
    unsigned short event;
1270
    struct lan91cxx_priv_data *cpd =
1271
        (struct lan91cxx_priv_data *)sc->driver_private;
1272
 
1273
//    DEBUG_FUNCTION();
1274
    while (1) {
1275
        cyg_drv_interrupt_acknowledge(cpd->interrupt);
1276
        // Get the (unmasked) requests
1277
        event = get_reg(sc, LAN91CXX_INTERRUPT);
1278
        event = event & (event >> 8) & 0xff;
1279
 
1280
        if (0 == event)
1281
            break;
1282
#if 0
1283
        if (event & LAN91CXX_INTERRUPT_ERCV_INT) {
1284
            // Early receive interrupt
1285
            db_printf("Early receive interrupt\n");
1286
        }
1287
        else if (event & LAN91CXX_INTERRUPT_EPH_INT) {
1288
            // ethernet protocol handler failures
1289
            db_printf("Ethernet protocol handler failures\n");
1290
        }
1291
        else if (event & LAN91CXX_INTERRUPT_RX_OVRN_INT) {
1292
            // receive overrun
1293
            db_printf("Receive overrun\n");
1294
        }
1295
        else if (event & LAN91CXX_INTERRUPT_ALLOC_INT) {
1296
            // allocation interrupt
1297
            db_printf("Allocation interrupt\n");
1298
        }
1299
        else
1300
#endif
1301
        if (event & LAN91CXX_INTERRUPT_TX_SET) {
1302
            lan91cxx_TxEvent(sc, event);
1303
        }
1304
        if (event & LAN91CXX_INTERRUPT_RCV_INT) {
1305
            lan91cxx_RxEvent(sc);
1306
        }
1307
        if (event & ~(LAN91CXX_INTERRUPT_TX_SET | LAN91CXX_INTERRUPT_RCV_INT))
1308
            db_printf("%s: Unknown interrupt: 0x%04x\n",
1309
                        __FUNCTION__, event);
1310
    }
1311
}
1312
 
1313
#ifdef LAN91CXX_IS_LAN91C111
1314
 
1315
static cyg_uint16
1316
lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr, cyg_uint8 phyreg)
1317
{
1318
    int i, mask, input_idx, clk_idx = 0;
1319
    cyg_uint16 mii_reg, value;
1320
    cyg_uint8 bits[64];
1321
 
1322
    // 32 consecutive ones on MDO to establish sync
1323
    for (i = 0; i < 32; ++i)
1324
        bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1325
 
1326
    // Start code <01>
1327
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1328
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1329
 
1330
    // Read command <10>
1331
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1332
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1333
 
1334
    // Output the PHY address, msb first
1335
    for (mask = 0x10; mask; mask >>= 1) {
1336
        if (phyaddr & mask)
1337
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1338
        else
1339
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1340
    }
1341
 
1342
    // Output the phy register number, msb first
1343
    for (mask = 0x10; mask; mask >>= 1) {
1344
        if (phyreg & mask)
1345
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1346
        else
1347
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1348
    }
1349
 
1350
    // Tristate and turnaround (1 bit times)
1351
    bits[clk_idx++] = 0;
1352
 
1353
    // Input starts at this bit time
1354
    input_idx = clk_idx;
1355
 
1356
    // Will input 16 bits
1357
    for (i = 0; i < 16; ++i)
1358
        bits[clk_idx++] = 0;
1359
 
1360
    // Final clock bit
1361
    bits[clk_idx++] = 0;
1362
 
1363
    // Get the current MII register value
1364
    mii_reg = get_reg(sc, LAN91CXX_MGMT);
1365
 
1366
    // Turn off all MII Interface bits
1367
    mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
1368
                 LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
1369
 
1370
    // Clock all 64 cycles
1371
    for (i = 0; i < sizeof(bits); ++i) {
1372
        // Clock Low - output data
1373
        put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
1374
        CYGACC_CALL_IF_DELAY_US(50);
1375
 
1376
        // Clock Hi - input data
1377
        put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
1378
        CYGACC_CALL_IF_DELAY_US(50);
1379
 
1380
        bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1381
    }
1382
 
1383
    // Return to idle state
1384
    put_reg(sc, LAN91CXX_MGMT, mii_reg);
1385
    CYGACC_CALL_IF_DELAY_US(50);
1386
 
1387
    // Recover input data
1388
    for (value = 0, i = 0; i < 16; ++i) {
1389
        value <<= 1;
1390
        if (bits[input_idx++] & LAN91CXX_MGMT_MDI)
1391
            value |= 1;
1392
    }
1393
    return value;
1394
}
1395
 
1396
static void
1397
lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
1398
                   cyg_uint8 phyreg, cyg_uint16 value)
1399
{
1400
    int i, mask, clk_idx = 0;
1401
    cyg_uint16 mii_reg;
1402
    cyg_uint8 bits[65];
1403
 
1404
    // 32 consecutive ones on MDO to establish sync
1405
    for (i = 0; i < 32; ++i)
1406
        bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1407
 
1408
    // Start code <01>
1409
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1410
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1411
 
1412
    // Write command <01>
1413
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1414
    bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1415
 
1416
    // Output the PHY address, msb first
1417
    for (mask = 0x10; mask; mask >>= 1) {
1418
        if (phyaddr & mask)
1419
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1420
        else
1421
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1422
    }
1423
 
1424
    // Output the phy register number, msb first
1425
    for (mask = 0x10; mask; mask >>= 1) {
1426
        if (phyreg & mask)
1427
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1428
        else
1429
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1430
    }
1431
 
1432
    // Tristate and turnaround (2 bit times)
1433
    bits[clk_idx++] = 0;
1434
    bits[clk_idx++] = 0;
1435
 
1436
    // Write out 16 bits of data, msb first
1437
    for (mask = 0x8000; mask; mask >>= 1) {
1438
        if (value & mask)
1439
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1440
        else
1441
            bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1442
    }
1443
 
1444
    // Final clock bit (tristate)
1445
    bits[clk_idx++] = 0;
1446
 
1447
    // Get the current MII register value
1448
    mii_reg = get_reg(sc, LAN91CXX_MGMT);
1449
 
1450
    // Turn off all MII Interface bits
1451
    mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
1452
                 LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
1453
 
1454
    // Clock all cycles
1455
    for (i = 0; i < sizeof(bits); ++i) {
1456
        // Clock Low - output data
1457
        put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
1458
        CYGACC_CALL_IF_DELAY_US(50);
1459
 
1460
        // Clock Hi - input data
1461
        put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
1462
        CYGACC_CALL_IF_DELAY_US(50);
1463
 
1464
//      bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1465
    }
1466
 
1467
    // Return to idle state
1468
    put_reg(sc, LAN91CXX_MGMT, mii_reg);
1469
    CYGACC_CALL_IF_DELAY_US(50);
1470
}
1471
#endif // LAN91CXX_IS_LAN91C111
1472
 
1473
// EOF if_lan91cxx.c

powered by: WebSVN 2.1.0

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