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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [devs/] [eth/] [smsc/] [lan91cxx/] [v2_0/] [src/] [if_lan91cxx.c] - Blame information for rev 300

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

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

powered by: WebSVN 2.1.0

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