1 //==========================================================================
5 // Ethernet device driver for VIA RHINE compatible controllers
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.
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.
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
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.
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.
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.
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####
42 // -------------------------------------------
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.
47 // -------------------------------------------
49 //####BSDCOPYRIGHTEND####
50 //==========================================================================
51 //#####DESCRIPTIONBEGIN####
53 // Author(s): jskov, based on pcnet driver
54 // Contributors: gthomas, jskov, hmt
57 // Description: hardware driver for VIA Rhine ethernet
59 // FIXME: Make endian safe
60 // Make use of virtual addressing for memory shared over PCI
62 // Link failure not detected for some reason.
64 //####DESCRIPTIONEND####
66 //==========================================================================
68 #include <pkgconf/system.h>
69 #include <pkgconf/devs_eth_via_rhine.h>
70 #include <pkgconf/io_eth_drivers.h>
72 #include <cyg/infra/cyg_type.h>
73 #include <cyg/hal/hal_arch.h>
74 #include <cyg/hal/hal_intr.h>
75 #include <cyg/infra/cyg_ass.h>
76 #include <cyg/infra/diag.h>
77 #include <cyg/hal/drv_api.h>
78 #include <cyg/io/eth/netdev.h>
79 #include <cyg/io/eth/eth_drv.h>
81 #include <pkgconf/net.h>
82 #include <cyg/kernel/kapi.h>
83 #include <net/if.h> /* Needed for struct ifnet */
84 #include <pkgconf/io_eth_drivers.h>
86 #include CYGHWR_MEMORY_LAYOUT_H
89 #include <cyg/io/pci.h>
91 #error "Need PCI package here"
94 #define _BUF_SIZE 1544
96 #ifdef CYGPKG_INFRA_DEBUG
97 // Then we log, OOI, the number of times we get a bad packet number
98 // from the tx done fifo.
99 int rhine_txfifo_good = 0;
100 int rhine_txfifo_bad = 0;
103 #include "via_rhine.h"
106 #include CYGDAT_DEVS_ETH_VIA_RHINE_INL
109 static void rhine_poll(struct eth_drv_sc *sc);
111 // This ISR is called when the ethernet interrupt occurs
113 rhine_isr(cyg_vector_t vector, cyg_addrword_t data)
115 struct rhine_priv_data *cpd = (struct rhine_priv_data *)data;
119 INCR_STAT( interrupts );
121 cyg_drv_interrupt_mask(cpd->interrupt);
122 cyg_drv_interrupt_acknowledge(cpd->interrupt);
123 return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
127 rhine_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
129 // This conditioning out is necessary because of explicit calls to this
130 // DSR - which would not ever be called in the case of a polled mode
131 // usage ie. in RedBoot.
132 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
133 struct rhine_priv_data* cpd = (struct rhine_priv_data *)data;
134 struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp);
135 struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
137 // but here, it must be a *sc:
138 eth_drv_dsr( vector, count, (cyg_addrword_t)sc );
140 # ifndef CYGPKG_REDBOOT
141 # error Empty Rhine ethernet DSR is compiled. Is this what you want?
146 // The deliver function (ex-DSR) handles the ethernet [logical] processing
148 rhine_deliver(struct eth_drv_sc *sc)
150 struct rhine_priv_data *cpd = (struct rhine_priv_data *)sc->driver_private;
154 // Service the interrupt:
156 // Allow interrupts to happen again
157 cyg_drv_interrupt_unmask(cpd->interrupt);
161 rhine_int_vector(struct eth_drv_sc *sc)
163 struct rhine_priv_data *cpd =
164 (struct rhine_priv_data *)sc->driver_private;
166 return (cpd->interrupt);
169 // ------------------------------------------------------------------------
170 // Physical interface
171 #if 0 // fix warning since this isn't actually used
173 rhine_write_MII(struct rhine_priv_data *cpd, int id, int reg, cyg_uint16 value)
178 // Wait for a previous access to complete (within reason)
180 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
181 } while ((stat & (RHINE_MIICR_RCMD | RHINE_MIICR_WCMD)) && i-- > 0);
183 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, 0);
184 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PHYADR, id);
185 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIIAD, reg);
186 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_MIIDATA, value);
187 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, RHINE_MIICR_WCMD);
192 rhine_read_MII(struct rhine_priv_data *cpd, int id, int reg)
198 // Wait for a previous access to complete (within reason)
200 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
201 } while ((stat & (RHINE_MIICR_RCMD | RHINE_MIICR_WCMD)) && i-- > 0);
203 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, 0);
204 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PHYADR, id);
205 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIIAD, reg);
206 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_MIICR, RHINE_MIICR_RCMD);
210 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIICR, stat);
211 } while ((stat & RHINE_MIICR_RCMD) && i-- > 0);
213 HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_MIIDATA, val);
217 // ------------------------------------------------------------------------
220 // Simply carve off from the front of the PCI mapped window into real memory
221 static cyg_uint32 rhine_heap_size;
222 static cyg_uint8 *rhine_heap_base;
223 static cyg_uint8 *rhine_heap_free;
226 pciwindow_mem_alloc(int size)
232 (CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE <= (int)rhine_heap_free)
234 ((CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE +
235 CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE) > (int)rhine_heap_free)
237 (0 < rhine_heap_size)
239 (CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE >= rhine_heap_size)
241 (CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE == (int)rhine_heap_base),
242 "Heap variables corrupted" );
244 p_memory = (void *)0;
245 size = (size + 3) & ~3;
246 if ( (rhine_heap_free+size) < (rhine_heap_base+rhine_heap_size) ) {
248 p_memory = (void *)rhine_heap_free;
249 rhine_heap_free += size;
250 for ( p = (cyg_uint32 *)p_memory; _size > 0; _size -= 4 )
255 diag_printf("Allocated %d bytes at %08x\n", size, p_memory);
261 static cyg_pci_match_func find_rhine_match_func;
264 find_rhine_match_func( cyg_uint16 v, cyg_uint16 d, cyg_uint32 c, void *p )
267 diag_printf("PCI match vendor %04x device %04x\n", v, d);
270 (0x1106 == v) && // vendor: VIA
271 ((0x3065 == d) || // device: DL10030A
272 (0x3043 == d)); // device: VT86C100A
276 pci_init_find_rhines( void )
278 cyg_pci_device_id devid;
279 cyg_pci_device dev_info;
282 int found_devices = 0;
286 #ifdef CYGARC_UNCACHED_ADDRESS
287 CYG_ASSERT( CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) ==
288 CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE,
289 "PCI window configured does not match PCI memory section base" );
291 CYG_ASSERT( (CYG_ADDRWORD)CYGMEM_SECTION_pci_window ==
292 CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE,
293 "PCI window configured does not match PCI memory section base" );
295 CYG_ASSERT( CYGMEM_SECTION_pci_window_SIZE ==
296 CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE,
297 "PCI window configured does not match PCI memory section size" );
300 #ifdef CYGARC_UNCACHED_ADDRESS
301 CYGARC_UNCACHED_ADDRESS((CYG_ADDRWORD)CYGMEM_SECTION_pci_window) !=
303 (CYG_ADDRWORD)CYGMEM_SECTION_pci_window !=
305 CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE
307 CYGMEM_SECTION_pci_window_SIZE !=
308 CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE ) {
310 diag_printf("pci_init_find_rhines(): PCI window misconfigured\n");
315 // First initialize the heap in PCI window'd memory
316 rhine_heap_size = CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE;
317 rhine_heap_base = (cyg_uint8 *)CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE;
318 rhine_heap_free = rhine_heap_base;
322 diag_printf("Finished cyg_pci_init();\n");
325 devid = CYG_PCI_NULL_DEVID;
327 for (device_index = 0;
328 device_index < CYGNUM_DEVS_ETH_VIA_RHINE_DEV_COUNT;
330 struct rhine_priv_data* cpd = rhine_priv_array[device_index];
332 cpd->index = device_index;
334 // See above for find_rhine_match_func - it selects any of several
335 // variants. This is necessary in case we have multiple mixed-type
336 // devices on one board in arbitrary orders.
337 if (cyg_pci_find_matching( &find_rhine_match_func, NULL, &devid )) {
339 diag_printf("eth%d = rhine\n", device_index);
341 cyg_pci_get_device_info(devid, &dev_info);
343 cpd->interrupt_handle = 0; // Flag not attached.
344 if (cyg_pci_translate_interrupt(&dev_info, &cpd->interrupt)) {
346 diag_printf(" Wired to HAL vector %d\n", cpd->interrupt);
348 cyg_drv_interrupt_create(
350 1, // Priority - unused
351 (cyg_addrword_t)cpd,// Data item passed to ISR & DSR
354 &cpd->interrupt_handle, // handle to intr obj
355 &cpd->interrupt_object ); // space for int obj
357 cyg_drv_interrupt_attach(cpd->interrupt_handle);
359 // Don't unmask the interrupt yet, that could get us into a
365 diag_printf(" Does not generate interrupts.\n");
369 if (cyg_pci_configure_device(&dev_info)) {
372 diag_printf("Found device on bus %d, devfn 0x%02x:\n",
373 CYG_PCI_DEV_GET_BUS(devid),
374 CYG_PCI_DEV_GET_DEVFN(devid));
376 if (dev_info.command & CYG_PCI_CFG_COMMAND_ACTIVE) {
377 diag_printf(" Note that board is active. Probed"
378 " sizes and CPU addresses invalid!\n");
380 diag_printf(" Vendor 0x%04x", dev_info.vendor);
381 diag_printf("\n Device 0x%04x", dev_info.device);
382 diag_printf("\n Command 0x%04x, Status 0x%04x\n",
383 dev_info.command, dev_info.status);
385 diag_printf(" Class/Rev 0x%08x", dev_info.class_rev);
386 diag_printf("\n Header 0x%02x\n", dev_info.header_type);
388 diag_printf(" SubVendor 0x%04x, Sub ID 0x%04x\n",
389 dev_info.header.normal.sub_vendor,
390 dev_info.header.normal.sub_id);
392 for(i = 0; i < CYG_PCI_MAX_BAR; i++) {
393 diag_printf(" BAR[%d] 0x%08x /", i, dev_info.base_address[i]);
394 diag_printf(" probed size 0x%08x / CPU addr 0x%08x\n",
395 dev_info.base_size[i], dev_info.base_map[i]);
397 diag_printf(" eth%d configured\n", device_index);
403 cpd->base = (unsigned char*) dev_info.base_map[0];
405 diag_printf(" I/O address = 0x%08x\n", cpd->base);
408 // Don't use cyg_pci_set_device_info since it clears
409 // some of the fields we want to print out below.
410 cyg_pci_read_config_uint16(dev_info.devid,
411 CYG_PCI_CFG_COMMAND, &cmd);
412 cmd |= (CYG_PCI_CFG_COMMAND_IO // enable I/O space
413 | CYG_PCI_CFG_COMMAND_MEMORY // enable memory space
414 | CYG_PCI_CFG_COMMAND_MASTER); // enable bus master
415 cyg_pci_write_config_uint16(dev_info.devid,
416 CYG_PCI_CFG_COMMAND, cmd);
418 // Extra init code needed for D-Link controller. This
419 // is snuffed from the Linux driver and was provided
420 // by D-Link. I've been unable to find documentation
422 if (0x3065 == dev_info.device) {
426 diag_printf("Pre-reset init code for D-Link.\n");
428 HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_STICKYHW, tmp);
430 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_STICKYHW, tmp);
432 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_WOL_CG_CLR, 0x80);
433 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_WOL_CR_CLR, 0xff);
434 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_PWR_CSR_CLR, 0xff);
437 // Now the PCI part of the device is configured, reset
438 // it. This should make it safe to enable the
440 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR1, RHINE_CR1_SRST);
442 // Reload ESA from EEPROM
448 diag_printf("Reload ESA from EEPROM...");
450 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_EECSR, 0x20);
451 for (i = 0; i < 150; i++) {
452 HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_EECSR, tmp);
459 diag_printf("Timed out\n");
461 diag_printf("Done\n");
465 // This is the indicator for "uses an interrupt"
466 if (cpd->interrupt_handle != 0) {
467 cyg_drv_interrupt_acknowledge(cpd->interrupt);
468 cyg_drv_interrupt_unmask(cpd->interrupt);
470 diag_printf(" Enabled interrupt %d\n", cpd->interrupt);
474 diag_printf(" **** Device enabled for I/O and Memory "
482 diag_printf("Failed to configure device %d\n", device_index);
490 diag_printf("eth%d not found\n", device_index);
495 if (0 == found_devices)
502 via_rhine_init(struct cyg_netdevtab_entry *tab)
504 static int initialized = 0; // only probe PCI et al *once*
505 struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
506 struct rhine_priv_data *cpd =
507 (struct rhine_priv_data *)sc->driver_private;
508 cyg_uint8 *d, *p, *p_next;
514 if ( 0 == initialized++ ) {
515 // then this is the first time ever:
516 if ( ! pci_init_find_rhines() ) {
518 diag_printf( "pci_init_find_rhines failed" );
524 // If this device is not present, exit
529 diag_printf( "Rhine device SC %08x CPD %08x\n", sc, cpd);
532 // Look for physical MII device
533 for (i = 0; i < 32; i++) {
534 cyg_uint16 mii_status = rhine_read_MII(cpd, i, MII_BMSR);
535 if (mii_status != 0x0000 && mii_status != 0xffff) {
538 diag_printf("Found MII interface at id %d, status %04x, adv 0x%04x, link 0x%04x\n",
539 cpd->phys_id, mii_status, rhine_read_MII(cpd,i,4), rhine_read_MII(cpd,i,5));
546 diag_printf("No MII interface found!");
550 if (cpd->hardwired_esa) {
551 // Force the NIC to use the specified ESA
552 p = cpd->base + RHINE_PAR0;
553 for (i = 0; i < 6; i++)
556 // Use the address from the serial EEPROM
557 p = cpd->base + RHINE_PAR0;
558 for (i = 0; i < 6; i++)
562 diag_printf("RHINE - %s ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
563 (cpd->hardwired_esa) ? "static" : "eeprom",
572 // Prepare RX and TX rings
573 p = cpd->rx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc((1<<cpd->rx_ring_log_cnt)*RHINE_RD_SIZE));
574 d = cpd->rx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc(_BUF_SIZE*cpd->rx_ring_cnt));
575 for (i = 0; i < cpd->rx_ring_cnt; i++) {
576 p_next = p + RHINE_RD_SIZE;
577 HAL_PCI_CPU_TO_BUS((cyg_uint32)d, ba);
578 _SU32(p, RHINE_RDES2) = ba;
579 _SU32(p, RHINE_RDES1) = _BUF_SIZE;
580 HAL_PCI_CPU_TO_BUS((cyg_uint32)p_next, ba);
581 _SU32(p, RHINE_RDES3) = ba;
582 _SU32(p, RHINE_RDES0) = RHINE_RDES0_OWN;
584 diag_printf("Set RDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
586 _SU32(p, RHINE_RDES0), _SU32(p, RHINE_RDES1),
587 _SU32(p, RHINE_RDES2), _SU32(p, RHINE_RDES3));
592 // last entry wraps to the first
594 HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->rx_ring, ba);
595 _SU32(p, RHINE_RDES3) = ba;
597 diag_printf("Set RDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
599 _SU32(p, RHINE_RDES0), _SU32(p, RHINE_RDES1),
600 _SU32(p, RHINE_RDES2), _SU32(p, RHINE_RDES3));
602 cpd->rx_ring_next = 0;
603 // CPU to PCI space translation
604 HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->rx_ring, ba);
605 HAL_PCI_IO_WRITE_UINT32(cpd->base + RHINE_CUR_RX, ba);
607 p = cpd->tx_ring = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc((1<<cpd->tx_ring_log_cnt)*RHINE_TD_SIZE));
608 d = cpd->tx_buffers = (cyg_uint8*) CYGARC_UNCACHED_ADDRESS(pciwindow_mem_alloc(_BUF_SIZE*cpd->tx_ring_cnt));
609 for (i = 0; i < cpd->tx_ring_cnt; i++) {
611 _SU32(p, RHINE_TDES0) = 0;
612 _SU32(p, RHINE_TDES1) = (RHINE_TDES1_IC|RHINE_TDES1_EDP|RHINE_TDES1_STP|RHINE_TDES1_C);
613 HAL_PCI_CPU_TO_BUS((cyg_uint32)d, ba);
614 _SU32(p, RHINE_TDES2) = ba;
615 HAL_PCI_CPU_TO_BUS((cyg_uint32)(p + RHINE_TD_SIZE), ba);
616 _SU32(p, RHINE_TDES3) = ba;
618 diag_printf("Set TDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
620 _SU32(p, RHINE_TDES0), _SU32(p, RHINE_TDES1),
621 _SU32(p, RHINE_TDES2), _SU32(p, RHINE_TDES3));
627 // last entry wraps to the first
629 HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->tx_ring, ba);
630 _SU32(p, RHINE_TDES3) = ba;
632 diag_printf("Set TDES at 0x%08lx to 0x%08x 0x%08x 0x%08x 0x%08x\n",
634 _SU32(p, RHINE_TDES0), _SU32(p, RHINE_TDES1),
635 _SU32(p, RHINE_TDES2), _SU32(p, RHINE_TDES3));
637 cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0;
638 HAL_PCI_CPU_TO_BUS((cyg_uint32)cpd->tx_ring, ba);
639 HAL_PCI_IO_WRITE_UINT32(cpd->base + RHINE_CUR_TX, ba);
645 cyg_uint8 tmp1, tmp2;
646 HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_CR0, tmp1);
647 HAL_PCI_IO_READ_UINT8(cpd->base+RHINE_CR1, tmp2);
648 diag_printf("CR0: %02x CR1: %02x\n", tmp1, tmp2);
652 // and record the net dev pointer
653 cpd->ndp = (void *)tab;
655 // Initialize upper level driver
656 (sc->funs->eth_drv->init)(sc, cpd->esa);
659 diag_printf("Done\n");
665 rhine_stop(struct eth_drv_sc *sc)
667 struct rhine_priv_data *cpd =
668 (struct rhine_priv_data *)sc->driver_private;
673 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR0, RHINE_CR0_STOP);
677 // This function is called to "start up" the interface. It may be called
678 // multiple times, even when the hardware is already running. It will be
679 // called whenever something "hardware oriented" changes and should leave
680 // the hardware ready to send/receive packets.
683 rhine_start(struct eth_drv_sc *sc, unsigned char *esa, int flags)
686 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
688 struct rhine_priv_data *cpd =
689 (struct rhine_priv_data *)sc->driver_private;
693 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, RHINE_CR0_STOP);
694 // Ack old interrupts
695 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, 0xffff);
697 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, RHINE_IMR_INIT);
699 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_CR1, RHINE_CR1_DPOLL /* | RHINE_CR1_FDX*/);
700 // Accept broadcast, multicast and small packets
701 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_RCR, RHINE_RCR_AB | RHINE_RCR_AM | RHINE_RCR_AR);
702 // Tweak some magic (undocumented) parameters
703 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_BCR0, RHINE_BCR0_MAGIC_INIT);
704 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_BCR1, RHINE_BCR1_MAGIC_INIT);
707 HAL_PCI_IO_WRITE_UINT8(cpd->base+RHINE_TCR, 0x20);
712 #ifdef ETH_DRV_FLAGS_PROMISC_MODE
713 != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
715 ) || (ifp->if_flags & IFF_PROMISC)
717 // Then we select promiscuous mode.
719 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_RCR, rcr);
720 rcr |= RHINE_RCR_PRO;
721 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_RCR, rcr);
725 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, RHINE_CR0_STRT | RHINE_CR0_RXON | RHINE_CR0_TXON);
729 // This routine is called to perform special "control" opertions
732 rhine_control(struct eth_drv_sc *sc, unsigned long key,
733 void *data, int data_length)
735 cyg_uint8 *esa = (cyg_uint8 *)data;
737 cyg_uint8 reg, old_stat;
738 struct rhine_priv_data *cpd =
739 (struct rhine_priv_data *)sc->driver_private;
743 // Stop the controller while accessing (possibly altering) registers
744 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, old_stat);
746 reg |= RHINE_CR0_STOP;
747 reg &= ~RHINE_CR0_STRT;
748 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, reg);
750 res = 0; // expect success
752 case ETH_DRV_SET_MAC_ADDRESS:
754 diag_printf("RHINE - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
763 for ( i = 0; i < sizeof(cpd->esa); i++ ) {
764 cpd->esa[i] = esa[i];
765 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_PAR0 + i, esa[i]);
769 #ifdef ETH_DRV_GET_MAC_ADDRESS
770 case ETH_DRV_GET_MAC_ADDRESS:
771 // Extract the MAC address that is in the chip, and tell the
773 for (i = 0; i < sizeof(cpd->esa); i++) {
774 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_PAR0 + i, esa[i]);
779 #ifdef ETH_DRV_GET_IF_STATS_UD
780 case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
783 #ifdef ETH_DRV_GET_IF_STATS
784 case ETH_DRV_GET_IF_STATS:
787 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
790 struct ether_drv_stats *p = (struct ether_drv_stats *)data;
791 // Chipset entry is no longer supported; RFC1573.
792 for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
793 p->snmp_chipset[i] = 0;
795 // This perhaps should be a config opt, so you can make up your own
796 // description, or supply it from the instantiation.
797 strcpy( p->description, "VIA Rhine" );
798 // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
800 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIISR, reg);
801 if (reg & RHINE_MIISR_LNKFL) {
802 p->operational = 2; // LINK DOWN
803 p->duplex = 1; // UNKNOWN
807 p->operational = 3; // LINK UP
808 p->speed = (reg & RHINE_MIISR_SPEED) ? 10 * 1000000 : 100 * 1000000;
809 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR1, reg);
810 if (reg & RHINE_CR1_FDX)
811 p->duplex = 3; // 3 = DUPLEX
813 p->duplex = 2; // 2 = SIMPLEX
816 #ifdef KEEP_STATISTICS
818 struct via_rhine_stats *ps = &(cpd->stats);
821 p->supports_dot3 = true;
823 p->tx_good = ps->tx_good ;
824 p->tx_max_collisions = ps->tx_max_collisions ;
825 p->tx_late_collisions = ps->tx_late_collisions ;
826 p->tx_underrun = ps->tx_underrun ;
827 p->tx_carrier_loss = ps->tx_carrier_loss ;
828 p->tx_deferred = ps->tx_deferred ;
829 p->tx_sqetesterrors = ps->tx_sqetesterrors ;
830 p->tx_single_collisions = ps->tx_single_collisions;
831 p->tx_mult_collisions = ps->tx_mult_collisions ;
832 p->tx_total_collisions = ps->tx_total_collisions ;
833 p->rx_good = ps->rx_good ;
834 p->rx_crc_errors = ps->rx_crc_errors ;
835 p->rx_align_errors = ps->rx_align_errors ;
836 p->rx_resource_errors = ps->rx_resource_errors ;
837 p->rx_overrun_errors = ps->rx_overrun_errors ;
838 p->rx_collisions = ps->rx_collisions ;
839 p->rx_short_frames = ps->rx_short_frames ;
840 p->rx_too_long_frames = ps->rx_too_long_frames ;
841 p->rx_symbol_errors = ps->rx_symbol_errors ;
843 p->interrupts = ps->interrupts ;
844 p->rx_count = ps->rx_count ;
845 p->rx_deliver = ps->rx_deliver ;
846 p->rx_resource = ps->rx_resource ;
847 p->rx_restart = ps->rx_restart ;
848 p->tx_count = ps->tx_count ;
849 p->tx_complete = ps->tx_complete ;
850 p->tx_dropped = ps->tx_dropped ;
852 #endif // KEEP_STATISTICS
863 // Restore controller state
864 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, old_stat);
870 // This routine is called to see if it is possible to send another packet.
871 // It will return non-zero if a transmit is possible, zero otherwise.
874 rhine_can_send(struct eth_drv_sc *sc)
877 struct rhine_priv_data *cpd =
878 (struct rhine_priv_data *)sc->driver_private;
882 // This MII read forces the MIISR to get updated
883 (void) rhine_read_MII(cpd, cpd->phys_id, MII_BMSR);
884 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_MIISR, stat);
885 if (stat & RHINE_MIISR_LNKFL) {
887 diag_printf("*** Link failure\n");
889 return false; // Link not connected
892 return (cpd->txbusy == 0);
896 // This routine is called to send data to the hardware.
898 rhine_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
899 int total_len, unsigned long key)
901 struct rhine_priv_data *cpd =
902 (struct rhine_priv_data *)sc->driver_private;
903 int i, len, plen, ring_entry;
905 cyg_uint8* sdata = NULL;
906 cyg_uint8 *d, *buf, *txd;
912 INCR_STAT( tx_count );
914 // Worry about the engine stopping.
915 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, status);
916 if ( 0 == (RHINE_CR0_STRT & status) ) {
918 diag_printf("%s: ENGINE RESTART: status %04x\n", __FUNCTION__, status);
920 status &= ~RHINE_CR0_STOP;
921 status |= RHINE_CR0_STRT;
922 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, status);
928 // Find packet length
930 for (i = 0; i < sg_len; i++)
931 plen += sg_list[i].len;
933 CYG_ASSERT( plen == total_len, "sg data length mismatch" );
935 // Get next TX descriptor
936 ring_entry = cpd->tx_ring_free;
938 if (cpd->tx_ring_owned == cpd->tx_ring_cnt) {
939 // Is this a dead end? Probably is.
941 diag_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
947 cpd->tx_ring_owned++;
948 if (cpd->tx_ring_free == cpd->tx_ring_cnt)
949 cpd->tx_ring_free = 0;
952 txd = cpd->tx_ring + ring_entry*RHINE_TD_SIZE;
953 buf = cpd->tx_buffers + ring_entry*_BUF_SIZE;
954 CYG_ASSERT(0 == (_SU32(txd, RHINE_TDES0) & RHINE_TDES0_OWN),
955 "TX descriptor not free");
958 diag_printf("##Tx descriptor index %d TDES %08x buffer %08x\n",
959 ring_entry, txd, buf);
962 // Put data into buffer
964 for (i = 0; i < sg_len; i++) {
965 sdata = (cyg_uint8 *)sg_list[i].buf;
966 len = sg_list[i].len;
968 CYG_ASSERT( sdata, "No sg data pointer here" );
972 CYG_ASSERT( sdata, "No sg data pointer outside" );
974 // Annoyingly the chip doesn't pad to minimal packet size, so do
979 diag_printf("Padded %d bytes packet to 60 bytes\n", plen);
983 CYG_ASSERT( (plen & RHINE_TDES1_TLNG_mask) == plen, "packet too long");
984 CYG_ASSERT( (plen & RHINE_TDES1_TLNG_mask) >= 60, "packet too short");
985 _SU32(txd, RHINE_TDES1) &= ~RHINE_TDES1_TLNG_mask;
986 _SU32(txd, RHINE_TDES1) |= plen;
987 _SU32(txd, RHINE_TDES0) = RHINE_TDES0_OWN;
989 #if DEBUG & 1 // FIXME
990 diag_printf("Before TX: Desc (@0x%08lx) %08x %08x %08x %08x\n Next (@0x%08lx) %08x %08x %08x %08x\n",
992 _SU32(txd, RHINE_TDES0), _SU32(txd, RHINE_TDES1),
993 _SU32(txd, RHINE_TDES2), _SU32(txd, RHINE_TDES3),
994 ( (unsigned long)txd)+0x10,
995 _SU32(txd, (0x10+RHINE_TDES0)), _SU32(txd, (0x10+RHINE_TDES1)),
996 _SU32(txd,(0x10+ RHINE_TDES2)), _SU32(txd,(0x10+ RHINE_TDES3)));
1000 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PTX);
1001 // Set transmit demand
1002 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, cr0);
1003 cr0 |= RHINE_CR0_TDMD;
1004 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, cr0);
1007 HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, status);
1008 diag_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, status);
1014 rhine_TxEvent(struct eth_drv_sc *sc, int stat)
1016 struct rhine_priv_data *cpd =
1017 (struct rhine_priv_data *)sc->driver_private;
1024 INCR_STAT( tx_complete );
1026 txd = cpd->tx_ring + cpd->tx_ring_alloc*RHINE_TD_SIZE;
1028 diag_printf("##Tx packet %d freed %08x %08x!\n", cpd->tx_ring_alloc, txd, _SU32(txd, RHINE_TDES0) );
1030 if ((_SU32(txd, RHINE_TDES0) & RHINE_TDES0_OWN)) {
1032 diag_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__);
1034 // first dirty ring entry not freed - wtf?
1036 cpd->tx_ring_alloc++;
1037 if (cpd->tx_ring_alloc == cpd->tx_ring_cnt)
1038 cpd->tx_ring_alloc = 0;
1039 cpd->tx_ring_owned--;
1041 #ifdef KEEP_STATISTICS
1043 cyg_uint32 reg = _SU32(txd, RHINE_TDES0);
1046 // Covering each bit in turn...
1047 if ( reg & RHINE_TDES0_TXOK ) INCR_STAT( tx_good );
1048 if ( reg & RHINE_TDES0_CRS ) INCR_STAT( tx_carrier_loss );
1049 if ( reg & RHINE_TDES0_OWC ) INCR_STAT( tx_late_collisions );
1050 if ( reg & RHINE_TDES0_ABT ) INCR_STAT( tx_max_collisions );
1052 if ( reg & RHINE_TDES0_DFR ) INCR_STAT( tx_deferred );
1054 collisions = ((reg & RHINE_TDES0_NCR_mask) >> RHINE_TDES0_NCR_shift);
1055 if (1 == collisions)
1056 INCR_STAT( tx_single_collisions );
1057 else if (1 < collisions)
1058 INCR_STAT( tx_mult_collisions );
1060 cpd->stats.tx_total_collisions =
1061 cpd->stats.tx_late_collisions +
1062 cpd->stats.tx_max_collisions +
1063 cpd->stats.tx_mult_collisions +
1064 cpd->stats.tx_single_collisions;
1066 #endif // KEEP_STATISTICS
1068 // We do not really care about Tx failure. Ethernet is not a reliable
1069 // medium. But we do care about the TX engine stopping.
1070 HAL_PCI_IO_READ_UINT8(cpd->base + RHINE_CR0, status);
1071 if ( 0 == (RHINE_CR0_STRT & status) ) {
1073 diag_printf("%s: ENGINE RESTART: status %04x\n", __FUNCTION__, status);
1075 status &= ~RHINE_CR0_STOP;
1076 status |= RHINE_CR0_STRT;
1077 HAL_PCI_IO_WRITE_UINT8(cpd->base + RHINE_CR0, status);
1078 success = 0; // And treat this as an error...
1081 if ( cpd->txbusy ) {
1083 (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
1086 // Ack TX interrupt set
1087 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PTX);
1091 // This function is called when a packet has been received. Its job is
1092 // to prepare to unload the packet from the hardware. Once the length of
1093 // the packet is known, the upper layer of the driver can be told. When
1094 // the upper layer is ready to unload the packet, the internal function
1095 // 'rhine_recv' will be called to actually fetch it from the hardware.
1098 rhine_RxEvent(struct eth_drv_sc *sc)
1100 struct rhine_priv_data *cpd =
1101 (struct rhine_priv_data *)sc->driver_private;
1104 cyg_uint16 ints, len, mask;
1108 HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, ints);
1110 diag_printf("RxEvent - CSR: 0x%04x\n", ints);
1112 if ( 0 == (RHINE_ISR_PRX & ints) )
1113 // Then there's no RX event pending
1117 HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
1118 mask &= ~RHINE_IMR_PRX;
1119 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, mask);
1122 // Get state of next (supposedly) full ring entry
1123 cpd->rxpacket = cpd->rx_ring_next;
1124 rxd = cpd->rx_ring + cpd->rxpacket*RHINE_RD_SIZE;
1125 rstat = _SU32(rxd, RHINE_RDES0);
1127 // Keep going until we hit an entry that is owned by the
1129 if (rstat & RHINE_RDES0_OWN) {
1130 #ifdef CYGDBG_USE_ASSERTS
1131 // Sanity check of queue
1133 for (i = 0; i < cpd->rx_ring_cnt; i++) {
1134 rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
1135 rstat = _SU32(rxd, RHINE_RDES0);
1137 if (!(rstat & RHINE_RDES0_OWN)) {
1142 diag_printf("####Rx %s Inconsistent RX state - next was %d\n",
1143 __FUNCTION__, cpd->rx_ring_next);
1144 for (i = 0; i < cpd->rx_ring_cnt; i++) {
1145 rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
1146 rstat = _SU32(rxd, RHINE_RDES0);
1147 diag_printf("#### %02d: 0x%08x\n", i, rstat);
1157 diag_printf("##Rx packet %d RDES %08x stat %08x\n",
1158 cpd->rxpacket, rxd, rstat);
1162 INCR_STAT( rx_count );
1163 cpd->rx_ring_next++;
1164 if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0;
1166 len = (rstat & RHINE_RDES0_FLNG_mask) >> RHINE_RDES0_FLNG_shift;
1168 #ifdef KEEP_STATISTICS
1169 if ( rstat & RHINE_RDES0_CRC ) INCR_STAT( rx_crc_errors );
1170 if ( rstat & RHINE_RDES0_FAE ) INCR_STAT( rx_align_errors );
1171 if ( rstat & RHINE_RDES0_LONG ) INCR_STAT( rx_too_long_frames );
1172 #endif // KEEP_STATISTICS
1174 if (RHINE_RDES0_RXOK & rstat) {
1176 INCR_STAT( rx_good );
1179 diag_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len);
1181 unsigned char *buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
1184 diag_printf("RDES: %08x %08x %08x %08x\n",
1185 _SU32(rxd, RHINE_RDES0), _SU32(rxd, RHINE_RDES1),
1186 _SU32(rxd, RHINE_RDES2), _SU32(rxd, RHINE_RDES3));
1188 diag_printf("Packet data at %p\n", buf);
1189 for (i=0;i<len;i++) diag_printf("%02x ", buf[i]);
1193 // Check for bogusly short packets; can happen in promisc
1194 // mode: Asserted against and checked by upper layer
1197 if ( len > sizeof( struct ether_header ) )
1198 // then it is acceptable; offer the data to the network stack
1200 (sc->funs->eth_drv->recv)(sc, len);
1202 // Not OK for one reason or another...
1204 diag_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n",
1209 // Free packet (clear all status flags, and set OWN)
1210 _SU32(rxd, RHINE_RDES0) = RHINE_RDES0_OWN;
1214 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_PRX);
1215 // And reenable the interrupt
1216 HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
1217 mask |= RHINE_IMR_PRX;
1218 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_IMR, mask);
1222 // This function is called as a result of the "eth_drv_recv()" call above.
1223 // Its job is to actually fetch data for a packet from the hardware once
1224 // memory buffers have been allocated for the packet. Note that the buffers
1225 // may come in pieces, using a scatter-gather list. This allows for more
1226 // efficient processing in the upper layers of the stack.
1229 rhine_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
1231 struct rhine_priv_data *cpd =
1232 (struct rhine_priv_data *)sc->driver_private;
1233 int i, mlen=0, plen;
1234 cyg_uint8 *data, *rxd, *buf;
1238 rxd = cpd->rx_ring + cpd->rxpacket*RHINE_RD_SIZE;
1239 buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE;
1241 INCR_STAT( rx_deliver );
1243 plen = (_SU32(rxd, RHINE_RDES0) & RHINE_RDES0_FLNG_mask) >> RHINE_RDES0_FLNG_shift;
1245 for (i = 0; i < sg_len; i++) {
1246 data = (cyg_uint8*)sg_list[i].buf;
1247 mlen = sg_list[i].len;
1250 diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
1263 rhine_poll(struct eth_drv_sc *sc)
1265 struct rhine_priv_data *cpd =
1266 (struct rhine_priv_data *)sc->driver_private;
1267 cyg_uint16 event, mask;
1268 static volatile bool locked = false;
1270 // DEBUG_FUNCTION();
1273 // Get the (unmasked) requests
1274 HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_ISR, event);
1275 HAL_PCI_IO_READ_UINT16(cpd->base + RHINE_IMR, mask);
1282 if (event & RHINE_ISR_PRX) {
1285 else if (event & RHINE_ISR_PTX) {
1286 rhine_TxEvent(sc, event);
1288 else if (event & RHINE_ISR_RU) {
1293 struct rhine_priv_data *cpd =
1294 (struct rhine_priv_data *)sc->driver_private;
1296 diag_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event);
1297 for (i = 0; i < cpd->rx_ring_cnt; i++) {
1298 rxd = cpd->rx_ring + i*RHINE_RD_SIZE;
1300 rstat = _SU32(rxd, RHINE_RDES0);
1301 diag_printf(" %02d: 0x%08x\n", i, rstat);
1304 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, RHINE_ISR_RU);
1308 diag_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event);
1310 // Clear unhandled interrupts and hope for the best
1311 // This should never happen though, since we only enable
1312 // the sources we handle.
1313 HAL_PCI_IO_WRITE_UINT16(cpd->base + RHINE_ISR, event);