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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [devs/] [eth/] [via/] [rhine/] [current/] [src/] [if_rhine.c] - Blame information for rev 794

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      dev/if_rhine.c
4
//
5
//      Ethernet device driver for VIA RHINE 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 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):    jskov, based on pcnet driver
43
// Contributors: gthomas, jskov, hmt
44
// Date:         2001-05-30
45
// Purpose:      
46
// Description:  hardware driver for VIA Rhine ethernet
47
//
48
// FIXME:        Make endian safe
49
//               Make use of virtual addressing for memory shared over PCI
50
//                (see _ADDR_MASK).          
51
//               Link failure not detected for some reason.
52
//
53
//####DESCRIPTIONEND####
54
//
55
//==========================================================================
56
 
57
#include <pkgconf/system.h>
58
#include <pkgconf/devs_eth_via_rhine.h>
59
#include <pkgconf/io_eth_drivers.h>
60
 
61
#include <cyg/infra/cyg_type.h>
62
#include <cyg/hal/hal_arch.h>
63
#include <cyg/hal/hal_intr.h>
64
#include <cyg/infra/cyg_ass.h>
65
#include <cyg/infra/diag.h>
66
#include <cyg/hal/drv_api.h>
67
#include <cyg/io/eth/netdev.h>
68
#include <cyg/io/eth/eth_drv.h>
69
#ifdef CYGPKG_NET
70
#include <pkgconf/net.h>
71
#include <cyg/kernel/kapi.h>
72
#include <net/if.h>  /* Needed for struct ifnet */
73
#include <pkgconf/io_eth_drivers.h>
74
#endif
75
#include CYGHWR_MEMORY_LAYOUT_H
76
 
77
#ifdef CYGPKG_IO_PCI
78
#include <cyg/io/pci.h>
79
#else
80
#error "Need PCI package here"
81
#endif
82
 
83
#define _BUF_SIZE 1544
84
 
85
#ifdef CYGPKG_INFRA_DEBUG
86
// Then we log, OOI, the number of times we get a bad packet number
87
// from the tx done fifo.
88
int rhine_txfifo_good = 0;
89
int rhine_txfifo_bad = 0;
90
#endif
91
 
92
#include "via_rhine.h"
93
 
94
#define __WANT_DEVS
95
#include CYGDAT_DEVS_ETH_VIA_RHINE_INL
96
#undef  __WANT_DEVS
97
 
98
static void rhine_poll(struct eth_drv_sc *sc);
99
 
100
// This ISR is called when the ethernet interrupt occurs
101
static cyg_uint32
102
rhine_isr(cyg_vector_t vector, cyg_addrword_t data)
103
{
104
    struct rhine_priv_data *cpd = (struct rhine_priv_data *)data;
105
 
106
    DEBUG_FUNCTION();
107
 
108
    INCR_STAT( interrupts );
109
 
110
    cyg_drv_interrupt_mask(cpd->interrupt);
111
    cyg_drv_interrupt_acknowledge(cpd->interrupt);
112
    return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
113
}
114
 
115
static void
116
rhine_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
117
{
118
    // This conditioning out is necessary because of explicit calls to this
119
    // DSR - which would not ever be called in the case of a polled mode
120
    // usage ie. in RedBoot.
121
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
122
    struct rhine_priv_data* cpd = (struct rhine_priv_data *)data;
123
    struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
124
    struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
125
 
126
    // but here, it must be a *sc:
127
    eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
128
#else
129
# ifndef CYGPKG_REDBOOT
130
#  error Empty Rhine ethernet DSR is compiled.  Is this what you want?
131
# endif
132
#endif
133
}
134
 
135
// The deliver function (ex-DSR)  handles the ethernet [logical] processing
136
static void
137
rhine_deliver(struct eth_drv_sc *sc)
138
{
139
    struct rhine_priv_data *cpd = (struct rhine_priv_data *)sc->driver_private;
140
 
141
    DEBUG_FUNCTION();
142
 
143
    // Service the interrupt:
144
    rhine_poll(sc);
145
    // Allow interrupts to happen again
146
    cyg_drv_interrupt_unmask(cpd->interrupt);
147
}
148
 
149
static int
150
rhine_int_vector(struct eth_drv_sc *sc)
151
{
152
    struct rhine_priv_data *cpd =
153
        (struct rhine_priv_data *)sc->driver_private;
154
 
155
    return (cpd->interrupt);
156
}
157
 
158
// ------------------------------------------------------------------------
159
// Physical interface
160
#if 0 // fix warning since this isn't actually used
161
static void
162
rhine_write_MII(struct rhine_priv_data *cpd, int id, int reg, cyg_uint16 value)
163
{
164
    cyg_uint8 stat;
165
    int i = 1000;
166
 
167
    // Wait for a previous access to complete (within reason)
168
    do {
169
        HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
170
    } while ((stat & (RHINE_MIICR_RCMD | RHINE_MIICR_WCMD)) && i-- > 0);
171
 
172
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, 0);
173
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PHYADR, id);
174
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIIAD, reg);
175
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_MIIDATA, value);
176
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, RHINE_MIICR_WCMD);
177
}
178
#endif
179
 
180
static int
181
rhine_read_MII(struct rhine_priv_data *cpd, int id, int reg)
182
{
183
    int i = 1000;
184
    cyg_uint8 stat;
185
    cyg_uint16 val;
186
 
187
    // Wait for a previous access to complete (within reason)
188
    do {
189
        HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
190
    } while ((stat & (RHINE_MIICR_RCMD | RHINE_MIICR_WCMD)) && i-- > 0);
191
 
192
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, 0);
193
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PHYADR, id);
194
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIIAD, reg);
195
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, RHINE_MIICR_RCMD);
196
 
197
    i = 1000;
198
    do {
199
        HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
200
    } while ((stat & RHINE_MIICR_RCMD) && i-- > 0);
201
 
202
    HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_MIIDATA, val);
203
    return val;
204
}
205
 
206
// ------------------------------------------------------------------------
207
// Memory management
208
//
209
// Simply carve off from the front of the PCI mapped window into real memory
210
static cyg_uint32 rhine_heap_size;
211
static cyg_uint8 *rhine_heap_base;
212
static cyg_uint8 *rhine_heap_free;
213
 
214
static void*
215
pciwindow_mem_alloc(int size)
216
{
217
    void *p_memory;
218
    int _size = size;
219
 
220
    CYG_ASSERT(
221
        (CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE <= (int)rhine_heap_free)
222
        &&
223
        ((CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE +
224
          CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE) > (int)rhine_heap_free)
225
        &&
226
        (0 < rhine_heap_size)
227
        &&
228
        (CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE >= rhine_heap_size)
229
        &&
230
        (CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE == (int)rhine_heap_base),
231
        "Heap variables corrupted" );
232
 
233
    p_memory = (void *)0;
234
    size = (size + 3) & ~3;
235
    if ( (rhine_heap_free+size) < (rhine_heap_base+rhine_heap_size) ) {
236
        cyg_uint32 *p;
237
        p_memory = (void *)rhine_heap_free;
238
        rhine_heap_free += size;
239
        for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
240
            *p++ = 0;
241
    }
242
 
243
#if DEBUG & 9
244
    diag_printf("Allocated %d bytes at %08x\n", size, p_memory);
245
#endif
246
 
247
    return p_memory;
248
}
249
 
250
static cyg_pci_match_func find_rhine_match_func;
251
 
252
static cyg_bool
253
find_rhine_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
254
{
255
#if DEBUG & 9
256
    diag_printf("PCI match vendor %04x device %04x\n", v, d);
257
#endif
258
    return
259
        (0x1106 == v) &&                // vendor: VIA
260
        ((0x3065 == d) ||               // device: DL10030A
261
         (0x3043 == d));                // device: VT86C100A
262
}
263
 
264
static int
265
pci_init_find_rhines( void )
266
{
267
    cyg_pci_device_id devid;
268
    cyg_pci_device dev_info;
269
    cyg_uint16 cmd;
270
    int device_index;
271
    int found_devices = 0;
272
 
273
    DEBUG_FUNCTION();
274
 
275
#ifdef CYGARC_UNCACHED_ADDRESS
276
    CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) ==
277
                CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE,
278
      "PCI window configured does not match PCI memory section base" );
279
#else
280
    CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window ==
281
                CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE,
282
      "PCI window configured does not match PCI memory section base" );
283
#endif
284
    CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE ==
285
                CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE,
286
        "PCI window configured does not match PCI memory section size" );
287
 
288
    if (
289
#ifdef CYGARC_UNCACHED_ADDRESS
290
         CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) !=
291
#else
292
         (CYG_ADDRWORD)CYGMEM_SECTION_pci_window !=
293
#endif
294
         CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE
295
         ||
296
         CYGMEM_SECTION_pci_window_SIZE !=
297
         CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE ) {
298
#if DEBUG & 8
299
        diag_printf("pci_init_find_rhines(): PCI window misconfigured\n");
300
#endif
301
        return 0;
302
    }
303
 
304
    // First initialize the heap in PCI window'd memory
305
    rhine_heap_size = CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE;
306
    rhine_heap_base = (cyg_uint8 *)CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE;
307
    rhine_heap_free = rhine_heap_base;
308
 
309
    cyg_pci_init();
310
#if DEBUG & 8
311
    diag_printf("Finished cyg_pci_init();\n");
312
#endif
313
 
314
    devid = CYG_PCI_NULL_DEVID;
315
 
316
    for (device_index = 0;
317
         device_index < CYGNUM_DEVS_ETH_VIA_RHINE_DEV_COUNT;
318
         device_index++) {
319
        struct rhine_priv_data* cpd = rhine_priv_array[device_index];
320
 
321
        cpd->index = device_index;
322
 
323
        // See above for find_rhine_match_func - it selects any of several
324
        // variants.  This is necessary in case we have multiple mixed-type
325
        // devices on one board in arbitrary orders.
326
        if (cyg_pci_find_matching( &find_rhine_match_func, NULL, &devid )) {
327
#if DEBUG & 8
328
            diag_printf("eth%d = rhine\n", device_index);
329
#endif
330
            cyg_pci_get_device_info(devid, &dev_info);
331
 
332
            cpd->interrupt_handle = 0; // Flag not attached.
333
            if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) {
334
#if DEBUG & 8
335
                diag_printf(" Wired to HAL vector %d\n", cpd->interrupt);
336
#endif
337
                cyg_drv_interrupt_create(
338
                    cpd->interrupt,
339
                    1,                  // Priority - unused
340
                    (cyg_addrword_t)cpd,// Data item passed to ISR & DSR
341
                    rhine_isr,          // ISR
342
                    rhine_dsr,          // DSR
343
                    &cpd->interrupt_handle, // handle to intr obj
344
                    &cpd->interrupt_object ); // space for int obj
345
 
346
                cyg_drv_interrupt_attach(cpd->interrupt_handle);
347
 
348
                // Don't unmask the interrupt yet, that could get us into a
349
                // race.
350
            }
351
            else {
352
                cpd->interrupt = 0;
353
#if DEBUG & 8
354
                diag_printf(" Does not generate interrupts.\n");
355
#endif
356
            }
357
 
358
            if (cyg_pci_configure_device(&dev_info)) {
359
#if DEBUG & 8
360
                int i;
361
                diag_printf("Found device on bus %d, devfn 0x%02x:\n",
362
                          CYG_PCI_DEV_GET_BUS(devid),
363
                          CYG_PCI_DEV_GET_DEVFN(devid));
364
 
365
                if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
366
                    diag_printf(" Note that board is active. Probed"
367
                              " sizes and CPU addresses invalid!\n");
368
                }
369
                diag_printf(" Vendor    0x%04x", dev_info.vendor);
370
                diag_printf("\n Device    0x%04x", dev_info.device);
371
                diag_printf("\n Command   0x%04x, Status 0x%04x\n",
372
                          dev_info.command, dev_info.status);
373
 
374
                diag_printf(" Class/Rev 0x%08x", dev_info.class_rev);
375
                diag_printf("\n Header 0x%02x\n", dev_info.header_type);
376
 
377
                diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
378
                          dev_info.header.normal.sub_vendor,
379
                          dev_info.header.normal.sub_id);
380
 
381
                for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
382
                    diag_printf(" BAR[%d]    0x%08x /", i, dev_info.base_address[i]);
383
                    diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
384
                              dev_info.base_size[i], dev_info.base_map[i]);
385
                }
386
                diag_printf(" eth%d configured\n", device_index);
387
#endif
388
                found_devices++;
389
                cpd->found = 1;
390
                cpd->active = 0;
391
                cpd->devid = devid;
392
                cpd->base = (unsigned char*) dev_info.base_map[0];
393
#if DEBUG & 8
394
                diag_printf(" I/O address = 0x%08x\n", cpd->base);
395
#endif
396
 
397
                // Don't use cyg_pci_set_device_info since it clears
398
                // some of the fields we want to print out below.
399
                cyg_pci_read_config_uint16(dev_info.devid,
400
                                           CYG_PCI_CFG_COMMAND, &cmd);
401
                cmd |= (CYG_PCI_CFG_COMMAND_IO         // enable I/O space
402
                        | CYG_PCI_CFG_COMMAND_MEMORY   // enable memory space
403
                        | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
404
                cyg_pci_write_config_uint16(dev_info.devid,
405
                                            CYG_PCI_CFG_COMMAND, cmd);
406
 
407
                // Extra init code needed for D-Link controller. This
408
                // is snuffed from the Linux driver and was provided
409
                // by D-Link. I've been unable to find documentation
410
                // for the part.
411
                if (0x3065 == dev_info.device) {
412
                    cyg_uint8 tmp;
413
 
414
#if DEBUG & 8
415
                    diag_printf("Pre-reset init code for D-Link.\n");
416
#endif
417
                    HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_STICKYHW, tmp);
418
                    tmp &= 0xfc;
419
                    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_STICKYHW, tmp);
420
 
421
                    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_WOL_CG_CLR, 0x80);
422
                    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_WOL_CR_CLR, 0xff);
423
                    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_PWR_CSR_CLR, 0xff);
424
                }
425
 
426
                // Now the PCI part of the device is configured, reset
427
                // it. This should make it safe to enable the
428
                // interrupt
429
                HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR1, RHINE_CR1_SRST);
430
 
431
                // Reload ESA from EEPROM
432
                {
433
                    cyg_uint8 tmp;
434
                    int i;
435
 
436
#if DEBUG & 8
437
                    diag_printf("Reload ESA from EEPROM...");
438
#endif
439
                    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_EECSR, 0x20);
440
                    for (i = 0; i < 150; i++) {
441
                        HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_EECSR, tmp);
442
                        if (!(tmp & 0x20)) {
443
                            break;
444
                        }
445
                    }
446
#if DEBUG & 8
447
                    if (tmp & 0x20)
448
                        diag_printf("Timed out\n");
449
                    else
450
                        diag_printf("Done\n");
451
#endif
452
                }
453
 
454
                // This is the indicator for "uses an interrupt"
455
                if (cpd->interrupt_handle != 0) {
456
                    cyg_drv_interrupt_acknowledge(cpd->interrupt);
457
                    cyg_drv_interrupt_unmask(cpd->interrupt);
458
#if DEBUG & 8
459
                    diag_printf(" Enabled interrupt %d\n", cpd->interrupt);
460
#endif
461
                }
462
#if DEBUG & 8
463
                diag_printf(" **** Device enabled for I/O and Memory "
464
                            "and Bus Master\n");
465
#endif
466
            }
467
            else {
468
                cpd->found = 0;
469
                cpd->active = 0;
470
#if DEBUG & 8
471
                diag_printf("Failed to configure device %d\n", device_index);
472
#endif
473
            }
474
        }
475
        else {
476
            cpd->found = 0;
477
            cpd->active = 0;
478
#if DEBUG & 8
479
            diag_printf("eth%d not found\n", device_index);
480
#endif
481
        }
482
    }
483
 
484
    if (0 == found_devices)
485
        return 0;
486
 
487
    return 1;
488
}
489
 
490
static bool
491
via_rhine_init(struct cyg_netdevtab_entry *tab)
492
{
493
    static int initialized = 0; // only probe PCI et al *once*
494
    struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
495
    struct rhine_priv_data *cpd =
496
        (struct rhine_priv_data *)sc->driver_private;
497
    cyg_uint8 *d, *p, *p_next;
498
    int i;
499
    cyg_addrword_t ba;
500
 
501
    DEBUG_FUNCTION();
502
 
503
    if ( 0 == initialized++ ) {
504
        // then this is the first time ever:
505
        if ( ! pci_init_find_rhines() ) {
506
#if DEBUG & 8
507
            diag_printf( "pci_init_find_rhines failed" );
508
#endif
509
            return false;
510
        }
511
    }
512
 
513
    // If this device is not present, exit
514
    if (0 == cpd->found)
515
        return 0;
516
 
517
#if DEBUG & 8
518
    diag_printf( "Rhine device SC %08x CPD %08x\n", sc, cpd);
519
#endif
520
 
521
    // Look for physical MII device
522
    for (i = 0; i < 32; i++) {
523
        cyg_uint16 mii_status = rhine_read_MII(cpd, i, MII_BMSR);
524
        if (mii_status != 0x0000 && mii_status != 0xffff) {
525
            cpd->phys_id = i;
526
#if DEBUG & 8
527
            diag_printf("Found MII interface at id %d, status %04x, adv 0x%04x, link 0x%04x\n",
528
                        cpd->phys_id, mii_status, rhine_read_MII(cpd,i,4), rhine_read_MII(cpd,i,5));
529
#endif
530
            break;
531
        }
532
    }
533
#if DEBUG & 8
534
    if (i == 32)
535
        diag_printf("No MII interface found!");
536
#endif
537
 
538
    // Prepare ESA
539
    if (cpd->hardwired_esa) {
540
        // Force the NIC to use the specified ESA
541
        for (i = 0; i < 6; i++)
542
            HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PAR0 + i, cpd->esa[i]);
543
    } else {
544
        // Use the address from the serial EEPROM
545
        for (i = 0; i < 6; i++)
546
            HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_PAR0 + i, cpd->esa[i]);
547
    }
548
#if DEBUG & 8
549
    diag_printf("RHINE - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
550
                (cpd->hardwired_esa) ? "static" : "eeprom",
551
                cpd->esa[0],
552
                cpd->esa[1],
553
                cpd->esa[2],
554
                cpd->esa[3],
555
                cpd->esa[4],
556
                cpd->esa[5] );
557
#endif
558
 
559
    // Prepare RX and TX rings
560
    p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*RHINE_RD_SIZE));
561
    d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));
562
    for (i = 0; i < cpd->rx_ring_cnt; i++) {
563
        p_next = p + RHINE_RD_SIZE;
564
        HAL_PCI_CPU_TO_BUS((cyg_uint32)d, ba);
565
        _SU32(p, RHINE_RDES2) = ba;
566
        _SU32(p, RHINE_RDES1) = _BUF_SIZE;
567
        HAL_PCI_CPU_TO_BUS((cyg_uint32)p_next, ba);
568
        _SU32(p, RHINE_RDES3) = ba;
569
        _SU32(p, RHINE_RDES0) = RHINE_RDES0_OWN;
570
#if DEBUG & 8
571
        diag_printf("Set RDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
572
                    (unsigned long)p,
573
                    _SU32(p, RHINE_RDES0), _SU32(p, RHINE_RDES1),
574
                    _SU32(p, RHINE_RDES2), _SU32(p, RHINE_RDES3));
575
#endif
576
        p = p_next;
577
        d += _BUF_SIZE;
578
    }
579
    // last entry wraps to the first
580
    p -= RHINE_RD_SIZE;
581
    HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->rx_ring, ba);
582
    _SU32(p, RHINE_RDES3) = ba;
583
#if DEBUG & 8
584
    diag_printf("Set RDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
585
                (unsigned long)p,
586
                _SU32(p, RHINE_RDES0), _SU32(p, RHINE_RDES1),
587
                _SU32(p, RHINE_RDES2), _SU32(p, RHINE_RDES3));
588
#endif
589
    cpd->rx_ring_next = 0;
590
    // CPU to PCI space translation
591
    HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->rx_ring, ba);
592
    HAL_PCI_IO_WRITE_UINT32(cpd->base + RHINE_CUR_RX, ba);
593
 
594
    p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*RHINE_TD_SIZE));
595
    d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));
596
    for (i = 0; i < cpd->tx_ring_cnt; i++) {
597
 
598
        _SU32(p, RHINE_TDES0) = 0;
599
        _SU32(p, RHINE_TDES1) = (RHINE_TDES1_IC|RHINE_TDES1_EDP|RHINE_TDES1_STP|RHINE_TDES1_C);
600
        HAL_PCI_CPU_TO_BUS((cyg_uint32)d, ba);
601
        _SU32(p, RHINE_TDES2) = ba;
602
        HAL_PCI_CPU_TO_BUS((cyg_uint32)(p + RHINE_TD_SIZE), ba);
603
        _SU32(p, RHINE_TDES3) = ba;
604
#if DEBUG & 8
605
        diag_printf("Set TDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
606
                    (unsigned long)p,
607
                    _SU32(p, RHINE_TDES0), _SU32(p, RHINE_TDES1),
608
                    _SU32(p, RHINE_TDES2), _SU32(p, RHINE_TDES3));
609
#endif
610
        p += RHINE_TD_SIZE;
611
        d += _BUF_SIZE;
612
    }
613
 
614
    // last entry wraps to the first
615
    p -= RHINE_TD_SIZE;
616
    HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->tx_ring, ba);
617
    _SU32(p, RHINE_TDES3) = ba;
618
#if DEBUG & 8
619
    diag_printf("Set TDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
620
                (unsigned long)p,
621
                _SU32(p, RHINE_TDES0), _SU32(p, RHINE_TDES1),
622
                _SU32(p, RHINE_TDES2), _SU32(p, RHINE_TDES3));
623
#endif
624
    cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
625
    HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->tx_ring, ba);
626
    HAL_PCI_IO_WRITE_UINT32(cpd->base + RHINE_CUR_TX, ba);
627
 
628
    cpd->txbusy = 0;
629
 
630
#if DEBUG & 9
631
    {
632
        cyg_uint8 tmp1, tmp2;
633
        HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_CR0, tmp1);
634
        HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_CR1, tmp2);
635
        diag_printf("CR0: %02x  CR1: %02x\n", tmp1, tmp2);
636
    }
637
#endif
638
 
639
    // and record the net dev pointer
640
    cpd->ndp = (void *)tab;
641
 
642
    // Initialize upper level driver
643
    (sc->funs->eth_drv->init)(sc, cpd->esa);
644
 
645
#if DEBUG & 9
646
    diag_printf("Done\n");
647
#endif
648
    return true;
649
}
650
 
651
static void
652
rhine_stop(struct eth_drv_sc *sc)
653
{
654
    struct rhine_priv_data *cpd =
655
        (struct rhine_priv_data *)sc->driver_private;
656
 
657
    DEBUG_FUNCTION();
658
 
659
    // Stop chip
660
    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR0, RHINE_CR0_STOP);
661
}
662
 
663
//
664
// This function is called to "start up" the interface.  It may be called
665
// multiple times, even when the hardware is already running.  It will be
666
// called whenever something "hardware oriented" changes and should leave
667
// the hardware ready to send/receive packets.
668
//
669
static void
670
rhine_start(struct eth_drv_sc *sc, unsigned char *esa, int flags)
671
{
672
#ifdef CYGPKG_NET
673
    struct ifnet *ifp = &sc->sc_arpcom.ac_if;
674
#endif
675
    struct rhine_priv_data *cpd =
676
        (struct rhine_priv_data *)sc->driver_private;
677
 
678
    DEBUG_FUNCTION();
679
    // Disable device
680
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, RHINE_CR0_STOP);
681
    // Ack old interrupts
682
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, 0xffff);
683
    // Enable interrupts
684
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, RHINE_IMR_INIT);
685
    // Enable duplex
686
    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR1, RHINE_CR1_DPOLL /* | RHINE_CR1_FDX*/);
687
    // Accept broadcast, multicast and small packets
688
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_RCR, RHINE_RCR_AB | RHINE_RCR_AM | RHINE_RCR_AR);
689
    // Tweak some magic (undocumented) parameters
690
    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_BCR0, RHINE_BCR0_MAGIC_INIT);
691
    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_BCR1, RHINE_BCR1_MAGIC_INIT);
692
 
693
#if 1 // FIXME
694
    HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_TCR, 0x20);
695
#endif
696
 
697
#ifdef CYGPKG_NET
698
    if (( 0
699
#ifdef ETH_DRV_FLAGS_PROMISC_MODE
700
         != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
701
#endif
702
        ) || (ifp->if_flags & IFF_PROMISC)
703
        ) {
704
        // Then we select promiscuous mode.
705
        cyg_uint8 rcr;
706
        HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_RCR, rcr);
707
        rcr |= RHINE_RCR_PRO;
708
        HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_RCR, rcr);
709
    }
710
#endif
711
    // Enable device
712
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, RHINE_CR0_STRT | RHINE_CR0_RXON | RHINE_CR0_TXON);
713
}
714
 
715
//
716
// This routine is called to perform special "control" opertions
717
//
718
static int
719
rhine_control(struct eth_drv_sc *sc, unsigned long key,
720
               void *data, int data_length)
721
{
722
    cyg_uint8 *esa = (cyg_uint8 *)data;
723
    int i, res;
724
    cyg_uint8 reg, old_stat;
725
    struct rhine_priv_data *cpd =
726
        (struct rhine_priv_data *)sc->driver_private;
727
 
728
    DEBUG_FUNCTION();
729
 
730
    // Stop the controller while accessing (possibly altering) registers
731
    HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, old_stat);
732
    reg = old_stat;
733
    reg |= RHINE_CR0_STOP;
734
    reg &= ~RHINE_CR0_STRT;
735
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, reg);
736
 
737
    res = 0;                            // expect success
738
    switch (key) {
739
    case ETH_DRV_SET_MAC_ADDRESS:
740
#if DEBUG & 9
741
        diag_printf("RHINE - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
742
                esa[0],
743
                esa[1],
744
                esa[2],
745
                esa[3],
746
                esa[4],
747
                esa[5] );
748
#endif // DEBUG
749
 
750
        for ( i = 0; i < sizeof(cpd->esa);  i++ ) {
751
            cpd->esa[i] = esa[i];
752
            HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PAR0 + i, esa[i]);
753
        }
754
        break;
755
 
756
#ifdef ETH_DRV_GET_MAC_ADDRESS
757
    case ETH_DRV_GET_MAC_ADDRESS:
758
        // Extract the MAC address that is in the chip, and tell the
759
        // system about it.
760
        for (i = 0;  i < sizeof(cpd->esa);  i++) {
761
            HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_PAR0 + i, esa[i]);
762
        }
763
        break;
764
#endif
765
 
766
#ifdef ETH_DRV_GET_IF_STATS_UD
767
    case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
768
#endif
769
        // drop through
770
#ifdef ETH_DRV_GET_IF_STATS
771
    case ETH_DRV_GET_IF_STATS:
772
#endif
773
 
774
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
775
    {
776
        cyg_uint8 reg;
777
        struct ether_drv_stats *p = (struct ether_drv_stats *)data;
778
        // Chipset entry is no longer supported; RFC1573.
779
        for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
780
            p->snmp_chipset[i] = 0;
781
 
782
        // This perhaps should be a config opt, so you can make up your own
783
        // description, or supply it from the instantiation.
784
        strcpy( p->description, "VIA Rhine" );
785
        // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
786
 
787
        HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIISR, reg);
788
        if (reg & RHINE_MIISR_LNKFL) {
789
            p->operational = 2;         // LINK DOWN
790
            p->duplex = 1;              // UNKNOWN
791
            p->speed = 0;
792
        }
793
        else {
794
            p->operational = 3;         // LINK UP
795
            p->speed = (reg & RHINE_MIISR_SPEED) ? 10 * 1000000 : 100 * 1000000;
796
            HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR1, reg);
797
            if (reg & RHINE_CR1_FDX)
798
                p->duplex = 3;              // 3 = DUPLEX
799
            else
800
                p->duplex = 2;              // 2 = SIMPLEX
801
        }
802
 
803
#ifdef KEEP_STATISTICS
804
        {
805
            struct via_rhine_stats *ps = &(cpd->stats);
806
 
807
            // Admit to it...
808
            p->supports_dot3        = true;
809
 
810
            p->tx_good              = ps->tx_good             ;
811
            p->tx_max_collisions    = ps->tx_max_collisions   ;
812
            p->tx_late_collisions   = ps->tx_late_collisions  ;
813
            p->tx_underrun          = ps->tx_underrun         ;
814
            p->tx_carrier_loss      = ps->tx_carrier_loss     ;
815
            p->tx_deferred          = ps->tx_deferred         ;
816
            p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;
817
            p->tx_single_collisions = ps->tx_single_collisions;
818
            p->tx_mult_collisions   = ps->tx_mult_collisions  ;
819
            p->tx_total_collisions  = ps->tx_total_collisions ;
820
            p->rx_good              = ps->rx_good             ;
821
            p->rx_crc_errors        = ps->rx_crc_errors       ;
822
            p->rx_align_errors      = ps->rx_align_errors     ;
823
            p->rx_resource_errors   = ps->rx_resource_errors  ;
824
            p->rx_overrun_errors    = ps->rx_overrun_errors   ;
825
            p->rx_collisions        = ps->rx_collisions       ;
826
            p->rx_short_frames      = ps->rx_short_frames     ;
827
            p->rx_too_long_frames   = ps->rx_too_long_frames  ;
828
            p->rx_symbol_errors     = ps->rx_symbol_errors    ;
829
 
830
            p->interrupts           = ps->interrupts          ;
831
            p->rx_count             = ps->rx_count            ;
832
            p->rx_deliver           = ps->rx_deliver          ;
833
            p->rx_resource          = ps->rx_resource         ;
834
            p->rx_restart           = ps->rx_restart          ;
835
            p->tx_count             = ps->tx_count            ;
836
            p->tx_complete          = ps->tx_complete         ;
837
            p->tx_dropped           = ps->tx_dropped          ;
838
        }
839
#endif // KEEP_STATISTICS
840
 
841
        p->tx_queue_len = 1;
842
        break;
843
    }
844
#endif
845
    default:
846
        res = 1;
847
        break;
848
    }
849
 
850
    // Restore controller state
851
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, old_stat);
852
 
853
    return res;
854
}
855
 
856
//
857
// This routine is called to see if it is possible to send another packet.
858
// It will return non-zero if a transmit is possible, zero otherwise.
859
//
860
static int
861
rhine_can_send(struct eth_drv_sc *sc)
862
{
863
    cyg_uint8 stat;
864
    struct rhine_priv_data *cpd =
865
        (struct rhine_priv_data *)sc->driver_private;
866
 
867
    DEBUG_FUNCTION();
868
 
869
    // This MII read forces the MIISR to get updated
870
    (void) rhine_read_MII(cpd, cpd->phys_id, MII_BMSR);
871
    HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIISR, stat);
872
    if (stat & RHINE_MIISR_LNKFL) {
873
#if DEBUG & 1
874
        diag_printf("*** Link failure\n");
875
#endif
876
        return false;  // Link not connected
877
    }
878
 
879
    return (cpd->txbusy == 0);
880
}
881
 
882
//
883
// This routine is called to send data to the hardware.
884
static void
885
rhine_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
886
            int total_len, unsigned long key)
887
{
888
    struct rhine_priv_data *cpd =
889
        (struct rhine_priv_data *)sc->driver_private;
890
    int i, len, plen, ring_entry;
891
 
892
    cyg_uint8* sdata = NULL;
893
    cyg_uint8 *d, *buf, *txd;
894
    cyg_uint16 status;
895
    cyg_uint8 cr0;
896
 
897
    DEBUG_FUNCTION();
898
 
899
    INCR_STAT( tx_count );
900
 
901
    // Worry about the engine stopping.
902
    HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, status);
903
    if ( 0 == (RHINE_CR0_STRT & status) ) {
904
#if DEBUG & 1
905
        diag_printf("%s: ENGINE RESTART: status %04x\n", __FUNCTION__, status);
906
#endif
907
        status &= ~RHINE_CR0_STOP;
908
        status |= RHINE_CR0_STRT;
909
        HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, status);
910
    }
911
 
912
    cpd->txbusy = 1;
913
    cpd->txkey = key;
914
 
915
    // Find packet length
916
    plen = 0;
917
    for (i = 0;  i < sg_len;  i++)
918
        plen += sg_list[i].len;
919
 
920
    CYG_ASSERT( plen == total_len, "sg data length mismatch" );
921
 
922
    // Get next TX descriptor
923
    ring_entry = cpd->tx_ring_free;
924
    do {
925
        if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
926
            // Is this a dead end? Probably is.
927
#if DEBUG & 1
928
            diag_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
929
#endif
930
            continue;
931
        }
932
 
933
        cpd->tx_ring_free++;
934
        cpd->tx_ring_owned++;
935
        if (cpd->tx_ring_free == cpd->tx_ring_cnt)
936
            cpd->tx_ring_free = 0;
937
    } while (0);
938
 
939
    txd = cpd->tx_ring + ring_entry*RHINE_TD_SIZE;
940
    buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
941
    CYG_ASSERT(0 == (_SU32(txd, RHINE_TDES0) & RHINE_TDES0_OWN),
942
               "TX descriptor not free");
943
 
944
#if DEBUG & 4
945
    diag_printf("##Tx descriptor index %d TDES %08x buffer %08x\n",
946
                ring_entry, txd, buf);
947
#endif
948
 
949
    // Put data into buffer
950
    d = buf;
951
    for (i = 0;  i < sg_len;  i++) {
952
        sdata = (cyg_uint8 *)sg_list[i].buf;
953
        len = sg_list[i].len;
954
 
955
        CYG_ASSERT( sdata, "No sg data pointer here" );
956
        while(len--)
957
            *d++ = *sdata++;
958
    }
959
    CYG_ASSERT( sdata, "No sg data pointer outside" );
960
 
961
    // Annoyingly the chip doesn't pad to minimal packet size, so do
962
    // that by steam
963
    if (plen < 60) {
964
        plen = 60;
965
#if DEBUG & 4
966
        diag_printf("Padded %d bytes packet to 60 bytes\n", plen);
967
#endif
968
    }
969
 
970
    CYG_ASSERT( (plen & RHINE_TDES1_TLNG_mask) == plen, "packet too long");
971
    CYG_ASSERT( (plen & RHINE_TDES1_TLNG_mask) >= 60, "packet too short");
972
    _SU32(txd, RHINE_TDES1) &= ~RHINE_TDES1_TLNG_mask;
973
    _SU32(txd, RHINE_TDES1) |= plen;
974
    _SU32(txd, RHINE_TDES0) = RHINE_TDES0_OWN;
975
 
976
#if DEBUG & 1 // FIXME
977
    diag_printf("Before TX: Desc (@0x%08lx) %08x %08x %08x %08x\n Next (@0x%08lx) %08x %08x %08x %08x\n",
978
                (unsigned long) txd,
979
                _SU32(txd, RHINE_TDES0), _SU32(txd, RHINE_TDES1),
980
                _SU32(txd, RHINE_TDES2), _SU32(txd, RHINE_TDES3),
981
                (  (unsigned long)txd)+0x10,
982
                _SU32(txd, (0x10+RHINE_TDES0)), _SU32(txd, (0x10+RHINE_TDES1)),
983
                _SU32(txd,(0x10+ RHINE_TDES2)), _SU32(txd,(0x10+ RHINE_TDES3)));
984
#endif
985
 
986
    // Ack TX empty int
987
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PTX);
988
    // Set transmit demand
989
    HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, cr0);
990
    cr0 |= RHINE_CR0_TDMD;
991
    HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, cr0);
992
 
993
#if DEBUG & 1
994
    HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, status);
995
    diag_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, status);
996
#endif
997
 
998
}
999
 
1000
static void
1001
rhine_TxEvent(struct eth_drv_sc *sc, int stat)
1002
{
1003
     struct rhine_priv_data *cpd =
1004
        (struct rhine_priv_data *)sc->driver_private;
1005
    int success = 1;
1006
    cyg_uint8 *txd;
1007
    cyg_uint8 status;
1008
 
1009
    DEBUG_FUNCTION();
1010
 
1011
    INCR_STAT( tx_complete );
1012
 
1013
    txd = cpd->tx_ring + cpd->tx_ring_alloc*RHINE_TD_SIZE;
1014
#if DEBUG & 4
1015
    diag_printf("##Tx packet %d freed %08x %08x!\n", cpd->tx_ring_alloc, txd, _SU32(txd, RHINE_TDES0) );
1016
#endif
1017
    if ((_SU32(txd, RHINE_TDES0) & RHINE_TDES0_OWN)) {
1018
#if DEBUG & 1
1019
        diag_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
1020
#endif
1021
        // first dirty ring entry not freed - wtf?
1022
    }
1023
    cpd->tx_ring_alloc++;
1024
    if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
1025
        cpd->tx_ring_alloc = 0;
1026
    cpd->tx_ring_owned--;
1027
 
1028
#ifdef KEEP_STATISTICS
1029
    {
1030
        cyg_uint32 reg = _SU32(txd, RHINE_TDES0);
1031
        int collisions;
1032
 
1033
        // Covering each bit in turn...
1034
        if ( reg & RHINE_TDES0_TXOK ) INCR_STAT( tx_good );
1035
        if ( reg & RHINE_TDES0_CRS ) INCR_STAT( tx_carrier_loss );
1036
        if ( reg & RHINE_TDES0_OWC ) INCR_STAT( tx_late_collisions );
1037
        if ( reg & RHINE_TDES0_ABT ) INCR_STAT( tx_max_collisions );
1038
 
1039
        if ( reg & RHINE_TDES0_DFR ) INCR_STAT( tx_deferred );
1040
 
1041
        collisions = ((reg & RHINE_TDES0_NCR_mask) >> RHINE_TDES0_NCR_shift);
1042
        if (1 == collisions)
1043
            INCR_STAT( tx_single_collisions );
1044
        else if (1 < collisions)
1045
            INCR_STAT( tx_mult_collisions );
1046
 
1047
        cpd->stats.tx_total_collisions =
1048
            cpd->stats.tx_late_collisions +
1049
            cpd->stats.tx_max_collisions +
1050
            cpd->stats.tx_mult_collisions +
1051
            cpd->stats.tx_single_collisions;
1052
    }
1053
#endif // KEEP_STATISTICS
1054
 
1055
    // We do not really care about Tx failure.  Ethernet is not a reliable
1056
    // medium.  But we do care about the TX engine stopping.
1057
    HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, status);
1058
    if ( 0 == (RHINE_CR0_STRT & status) ) {
1059
#if DEBUG & 1
1060
        diag_printf("%s: ENGINE RESTART: status %04x\n", __FUNCTION__, status);
1061
#endif
1062
        status &= ~RHINE_CR0_STOP;
1063
        status |= RHINE_CR0_STRT;
1064
        HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, status);
1065
        success = 0; // And treat this as an error...
1066
    }
1067
 
1068
    if ( cpd->txbusy ) {
1069
        cpd->txbusy = 0;
1070
        (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
1071
    }
1072
 
1073
    // Ack TX interrupt set
1074
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PTX);
1075
}
1076
 
1077
//
1078
// This function is called when a packet has been received.  Its job is
1079
// to prepare to unload the packet from the hardware.  Once the length of
1080
// the packet is known, the upper layer of the driver can be told.  When
1081
// the upper layer is ready to unload the packet, the internal function
1082
// 'rhine_recv' will be called to actually fetch it from the hardware.
1083
//
1084
static void
1085
rhine_RxEvent(struct eth_drv_sc *sc)
1086
{
1087
    struct rhine_priv_data *cpd =
1088
        (struct rhine_priv_data *)sc->driver_private;
1089
    cyg_uint8 *rxd;
1090
    cyg_uint32 rstat;
1091
    cyg_uint16 ints, len, mask;
1092
 
1093
    DEBUG_FUNCTION();
1094
 
1095
    HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, ints);
1096
#if DEBUG & 1
1097
    diag_printf("RxEvent - CSR: 0x%04x\n", ints);
1098
#endif
1099
    if ( 0 == (RHINE_ISR_PRX & ints) )
1100
        // Then there's no RX event pending
1101
        return;
1102
 
1103
    // Mask interrupt
1104
    HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
1105
    mask &= ~RHINE_IMR_PRX;
1106
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, mask);
1107
 
1108
    while (1) {
1109
        // Get state of next (supposedly) full ring entry
1110
        cpd->rxpacket = cpd->rx_ring_next;
1111
        rxd = cpd->rx_ring + cpd->rxpacket*RHINE_RD_SIZE;
1112
        rstat = _SU32(rxd, RHINE_RDES0);
1113
 
1114
        // Keep going until we hit an entry that is owned by the
1115
        // controller.
1116
        if (rstat & RHINE_RDES0_OWN) {
1117
#ifdef CYGDBG_USE_ASSERTS
1118
            // Sanity check of queue
1119
            int i;
1120
            for (i = 0; i < cpd->rx_ring_cnt; i++) {
1121
                rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
1122
                rstat = _SU32(rxd, RHINE_RDES0);
1123
 
1124
                if (!(rstat & RHINE_RDES0_OWN)) {
1125
                    int i;
1126
                    cyg_uint32 rstat;
1127
                    cyg_uint8* rxd;
1128
 
1129
                    diag_printf("####Rx %s Inconsistent RX state - next was %d\n",
1130
                                __FUNCTION__, cpd->rx_ring_next);
1131
                    for (i = 0; i < cpd->rx_ring_cnt; i++) {
1132
                        rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
1133
                        rstat = _SU32(rxd, RHINE_RDES0);
1134
                        diag_printf("#### %02d: 0x%08x\n", i, rstat);
1135
                    }
1136
                }
1137
                break;
1138
            }
1139
#endif
1140
            break;
1141
        }
1142
 
1143
#if DEBUG & 4
1144
        diag_printf("##Rx packet %d RDES %08x stat %08x\n",
1145
                    cpd->rxpacket, rxd, rstat);
1146
#endif
1147
 
1148
        // Increment counts
1149
        INCR_STAT( rx_count );
1150
        cpd->rx_ring_next++;
1151
        if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
1152
 
1153
        len = (rstat & RHINE_RDES0_FLNG_mask) >> RHINE_RDES0_FLNG_shift;
1154
 
1155
#ifdef KEEP_STATISTICS
1156
        if ( rstat & RHINE_RDES0_CRC ) INCR_STAT( rx_crc_errors );
1157
        if ( rstat & RHINE_RDES0_FAE ) INCR_STAT( rx_align_errors );
1158
        if ( rstat & RHINE_RDES0_LONG ) INCR_STAT( rx_too_long_frames );
1159
#endif // KEEP_STATISTICS
1160
 
1161
        if (RHINE_RDES0_RXOK & rstat) {
1162
            // It's OK
1163
            INCR_STAT( rx_good );
1164
 
1165
#if DEBUG & 1
1166
            diag_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
1167
            {
1168
                    unsigned char *buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
1169
 
1170
                    int i;
1171
                    diag_printf("RDES: %08x %08x %08x %08x\n",
1172
                                _SU32(rxd, RHINE_RDES0), _SU32(rxd, RHINE_RDES1),
1173
                                _SU32(rxd, RHINE_RDES2), _SU32(rxd, RHINE_RDES3));
1174
 
1175
                    diag_printf("Packet data at %p\n", buf);
1176
                    for (i=0;i<len;i++) diag_printf("%02x ", buf[i]);
1177
                    diag_printf("\n");
1178
            }
1179
#endif
1180
            // Check for bogusly short packets; can happen in promisc
1181
            // mode: Asserted against and checked by upper layer
1182
            // driver.
1183
#ifdef CYGPKG_NET
1184
            if ( len > sizeof( struct ether_header ) )
1185
                // then it is acceptable; offer the data to the network stack
1186
#endif
1187
                (sc->funs->eth_drv->recv)(sc, len);
1188
        } else {
1189
            // Not OK for one reason or another...
1190
#if DEBUG & 1
1191
            diag_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
1192
                        rstat, len);
1193
#endif
1194
        }
1195
 
1196
        // Free packet (clear all status flags, and set OWN)
1197
        _SU32(rxd, RHINE_RDES0) = RHINE_RDES0_OWN;
1198
    }
1199
 
1200
    // Ack RX int
1201
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PRX);
1202
    // And reenable the interrupt
1203
    HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
1204
    mask |= RHINE_IMR_PRX;
1205
    HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, mask);
1206
}
1207
 
1208
//
1209
// This function is called as a result of the "eth_drv_recv()" call above.
1210
// Its job is to actually fetch data for a packet from the hardware once
1211
// memory buffers have been allocated for the packet.  Note that the buffers
1212
// may come in pieces, using a scatter-gather list.  This allows for more
1213
// efficient processing in the upper layers of the stack.
1214
//
1215
static void
1216
rhine_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
1217
{
1218
    struct rhine_priv_data *cpd =
1219
        (struct rhine_priv_data *)sc->driver_private;
1220
    int i, mlen=0, plen;
1221
    cyg_uint8 *data, *rxd, *buf;
1222
 
1223
    DEBUG_FUNCTION();
1224
 
1225
    rxd = cpd->rx_ring + cpd->rxpacket*RHINE_RD_SIZE;
1226
    buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
1227
 
1228
    INCR_STAT( rx_deliver );
1229
 
1230
    plen = (_SU32(rxd, RHINE_RDES0) & RHINE_RDES0_FLNG_mask) >> RHINE_RDES0_FLNG_shift;
1231
 
1232
    for (i = 0;  i < sg_len;  i++) {
1233
        data = (cyg_uint8*)sg_list[i].buf;
1234
        mlen = sg_list[i].len;
1235
 
1236
#if DEBUG & 1
1237
        diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
1238
#endif
1239
        if (data) {
1240
            while (mlen > 0) {
1241
                *data++ = *buf++;
1242
                mlen--;
1243
                plen--;
1244
            }
1245
        }
1246
    }
1247
}
1248
 
1249
static void
1250
rhine_poll(struct eth_drv_sc *sc)
1251
{
1252
    struct rhine_priv_data *cpd =
1253
        (struct rhine_priv_data *)sc->driver_private;
1254
    cyg_uint16 event, mask;
1255
    static volatile bool locked = false;
1256
 
1257
//    DEBUG_FUNCTION();
1258
 
1259
    while (1) {
1260
        // Get the (unmasked) requests
1261
        HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, event);
1262
        HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
1263
 
1264
        event &= mask;
1265
 
1266
        if (0 == event)
1267
            break;
1268
 
1269
        if (event & RHINE_ISR_PRX) {
1270
            rhine_RxEvent(sc);
1271
        }
1272
        else if (event & RHINE_ISR_PTX) {
1273
            rhine_TxEvent(sc, event);
1274
        }
1275
        else if (event & RHINE_ISR_RU) {
1276
#if DEBUG & 1
1277
            int i;
1278
            cyg_uint32 rstat;
1279
            cyg_uint8* rxd;
1280
            struct rhine_priv_data *cpd =
1281
                (struct rhine_priv_data *)sc->driver_private;
1282
 
1283
            diag_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
1284
            for (i = 0; i < cpd->rx_ring_cnt; i++) {
1285
                rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
1286
 
1287
                rstat = _SU32(rxd, RHINE_RDES0);
1288
                diag_printf(" %02d: 0x%08x\n", i, rstat);
1289
            }
1290
#endif
1291
            HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_RU);
1292
        }
1293
        else {
1294
#if DEBUG & 1
1295
            diag_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
1296
#endif
1297
            // Clear unhandled interrupts and hope for the best
1298
            // This should never happen though, since we only enable
1299
            // the sources we handle.
1300
            HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, event);
1301
        }
1302
    }
1303
 
1304
    locked = false;
1305
}
1306
// EOF if_rhine.c

powered by: WebSVN 2.1.0

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