URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/rtos/ecos-2.0/packages/devs/eth/mips
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/atlas/v2_0/cdl/atlas_eth_drivers.cdl
0,0 → 1,102
# ==================================================================== |
# |
# atlas_eth_drivers.cdl |
# |
# Ethernet drivers - platform dependent support for MIPS Atlas |
# board using a Philips SAA9730 IO chip. |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): msalter |
# Original data: msalter |
# Contributors: |
# Date: 2000-12-04 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_MIPS_ATLAS { |
display "MIPS Atlas ethernet driver" |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_MIPS_ATLAS |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH0 |
include_dir . |
include_files ; # none _exported_ whatsoever |
description "Ethernet driver for MIPS Atlas boards w/ SAA9730." |
compile -library=libextras.a if_atlas.c if_buffers.S |
|
cdl_component CYGSEM_MIPS_ATLAS_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
default_value 0 |
description "Enabling this option will allow the ethernet |
station address to be forced to the value set by the |
configuration. This may be required if the hardware does |
not include a serial EEPROM for the ESA." |
|
cdl_option CYGDAT_MIPS_ATLAS_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x00, 0xd0, 0xa0, 0x00, 0x00, 0x10}"} |
description "The ethernet station address" |
} |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_ATLAS_OPTIONS { |
display "MIPS Atlas ethernet driver build options" |
flavor none |
no_define |
|
cdl_option CYGPKG_DEVS_ETH_MIPS_ATLAS_CFLAGS_ADD { |
display "Additional compiler flags" |
flavor data |
no_define |
default_value { "-D_KERNEL -D__ECOS" } |
description " |
This option modifies the set of compiler flags for |
building the MIPS Atlas ethernet driver package. |
These flags are used in addition |
to the set of global flags." |
} |
} |
} |
|
/atlas/v2_0/ChangeLog
0,0 → 1,82
2003-03-21 Nick Garnett <nickg@balti.calivar.com> |
|
* src/saa9730.h: |
* src/if_atlas.c: |
Many small changes to make this driver work correctly in eCos. |
|
2003-03-13 Nick Garnett <nickg@balti.calivar.com> |
|
* cdl/atlas_eth_drivers.cdl: |
Changed CYGPKG_DEVS_ETH_ARM_ATLAS_OPTIONS to |
CYGPKG_DEVS_ETH_MIPS_ATLAS_OPTIONS. |
|
* src/if_atlas.c (atlas_saa9730_init): ifdeffed out bogus code to |
set MAC address in non-redboot configuration just to make it |
compile. Note that there are other problems with this driver in |
eCos. |
|
2002-06-14 Gary Thomas <gary@chez-thomas.org> |
|
* src/if_atlas.c: |
Need to include <pkgconf/io_eth_drivers.h> for proper configuration |
of stand-alone (polled) vs. system (interrupt driven) mode. |
|
2001-10-18 Jonathan Larmour <jlarmour@redhat.com> |
|
* src/if_atlas.c: net_debug is no longer used. |
|
2001-10-05 Jesper Skov <jskov@redhat.com> |
|
* src/if_atlas.c: Use new HAL endian conversion macros. |
|
* src/saa9730.h: Deleted endian conversion macros. |
|
2001-02-15 Nick Garnett <nickg@cygnus.co.uk> |
|
* src/saa9730.h: |
* src/if_atlas.c: |
Added support for getting RX interrupts. This is solely for the |
purposes of doing Ctrl-C processing in RedBoot, more work would be |
needed to get full eCos driver support going. |
|
2001-01-30 Gary Thomas <gthomas@redhat.com> |
|
* src/if_atlas.c: New RedBoot config data layout. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |
|
|
|
/atlas/v2_0/src/if_atlas.c
0,0 → 1,1054
//========================================================================== |
// |
// dev/if_atlas.c |
// |
// Ethernet device driver for MIPS Atlas using Philips SAA9730 |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// Copyright (C) 2003 Nick Garnett <nickg@calivar.com> |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting the copyright |
// holders. |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//####BSDCOPYRIGHTBEGIN#### |
// |
// ------------------------------------------- |
// |
// Portions of this software may have been derived from OpenBSD or other sources, |
// and are covered by the appropriate copyright disclaimers included herein. |
// |
// ------------------------------------------- |
// |
//####BSDCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): msalter |
// Contributors: msalter, nickg |
// Date: 2000-12-06 |
// Purpose: |
// Description: hardware driver for SAA9730 ethernet |
// |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
// Ethernet device driver for MIPS Atlas |
// Based on SAA9730 |
|
#include <pkgconf/system.h> |
#include <pkgconf/devs_eth_mips_atlas.h> |
#include <pkgconf/io_eth_drivers.h> |
|
#ifdef CYGPKG_NET |
#include <pkgconf/net.h> |
#include <cyg/kernel/kapi.h> |
#endif |
#include <cyg/infra/cyg_type.h> |
#include <cyg/hal/hal_arch.h> |
#include <cyg/hal/hal_endian.h> |
#include <cyg/hal/hal_intr.h> |
#include <cyg/hal/hal_cache.h> |
#include <cyg/hal/hal_if.h> |
#include <cyg/infra/diag.h> |
#include <cyg/hal/drv_api.h> |
#include <cyg/io/eth/netdev.h> |
#include <cyg/io/eth/eth_drv.h> |
|
#ifdef CYGPKG_IO_PCI |
#include <cyg/io/pci.h> |
// So we can check the validity of the PCI window against the MLTs opinion, |
// and thereby what the malloc heap consumes willy-nilly: |
#include CYGHWR_MEMORY_LAYOUT_H |
#else |
#error "Need PCI package here" |
#endif |
|
#ifndef CYGSEM_MIPS_ATLAS_SET_ESA |
#ifdef CYGPKG_REDBOOT |
#include <pkgconf/redboot.h> |
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
#include <redboot.h> |
#include <flash_config.h> |
RedBoot_config_option("Network hardware address [MAC]", |
atlas_esa, |
ALWAYS_ENABLED, true, |
CONFIG_ESA, 0 |
); |
#endif |
#endif |
#endif |
|
// SAA9730 LAN definitions |
#include "saa9730.h" |
|
// Exported statistics and the like |
#include <cyg/io/eth/eth_drv_stats.h> |
|
#ifndef CYGPKG_REDBOOT |
//#define DEBUG |
#endif |
#define db_printf diag_printf |
|
#define ETHER_ADDR_LEN 6 |
|
static unsigned poll_count = 0; // for bug workaround |
static void __tx_poll(struct eth_drv_sc *sc); |
|
struct saa9730_priv_data { |
int active; |
cyg_uint32 vector; |
cyg_handle_t interrupt_handle; |
cyg_interrupt interrupt_object; |
cyg_uint32 devid; // PCI device id |
cyg_uint32 base; // PCI memory map base |
void *ndp; |
|
// index of next RX buffer |
cyg_uint8 next_rx_bindex; |
|
// index of next packet within RX buffer |
cyg_uint8 next_rx_pindex; |
|
// index of next TX buffer |
cyg_uint8 next_tx_bindex; |
|
// index of next packet within TX buffer |
cyg_uint8 next_tx_pindex; |
|
cyg_uint32 *tx_buffer[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER]; |
cyg_uint32 *rx_buffer[SAA9730_BUFFERS][SAA9730_RXPKTS_PER_BUFFER]; |
|
int tx_busy; |
unsigned long tx_key[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER]; |
int tx_used[SAA9730_BUFFERS]; |
|
} saa9730_priv_data; |
|
ETH_DRV_SC(atlas_sc, |
&saa9730_priv_data, // Driver specific data |
"eth0", // Name for this interface |
saa9730_start, |
saa9730_stop, |
saa9730_control, |
saa9730_can_send, |
saa9730_send, |
saa9730_recv, |
saa9730_deliver, // "pseudoDSR" called from fast net thread |
saa9730_poll, |
saa9730_int_vector); |
|
NETDEVTAB_ENTRY(atlas_netdev, |
"atlas", |
atlas_saa9730_init, |
&atlas_sc); |
|
#ifdef CYGSEM_MIPS_ATLAS_SET_ESA |
static unsigned char enaddr[] = CYGDAT_MIPS_ATLAS_ESA; |
#else |
static unsigned char enaddr[ETHER_ADDR_LEN]; |
#endif |
|
static void saa9730_poll(struct eth_drv_sc *sc); |
|
// This ISR is called when the ethernet interrupt occurs |
static int |
saa9730_isr(cyg_vector_t vector, cyg_addrword_t data) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data; |
unsigned long __base = spd->base; |
|
#ifndef CYGPKG_REDBOOT |
SAA9730_EVM_IER_SW &= ~(SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER); |
SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT; |
cyg_drv_interrupt_mask(vector); |
#endif |
#ifdef DEBUG |
db_printf("saa9730_isr\n"); |
#endif |
return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR |
} |
|
#ifndef CYGPKG_REDBOOT |
static |
void saa9730_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data; |
struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(spd->ndp); |
struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance); |
#ifdef DEBUG |
db_printf("saa9730_dsr\n"); |
#endif |
|
eth_drv_dsr(vector, count, (cyg_addrword_t)sc); |
} |
#endif |
|
static int |
saa9730_int_vector(struct eth_drv_sc *sc) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
|
return spd->vector; |
} |
|
static void |
__init_buffers(struct saa9730_priv_data *spd) |
{ |
extern char cyg_io_atlas_2kbuffers[]; |
cyg_uint32 *bufp = (cyg_uint32 *)CYGARC_UNCACHED_ADDRESS((unsigned)cyg_io_atlas_2kbuffers); |
int i, j; |
|
for (i = 0; i < SAA9730_BUFFERS; i++) { |
for (j = 0; j < SAA9730_RXPKTS_PER_BUFFER; j++) { |
memset(bufp, 0, 2048); |
spd->rx_buffer[i][j] = bufp; |
bufp += SAA9730_PACKET_SIZE/sizeof(*bufp); |
} |
} |
for (i = 0; i < SAA9730_BUFFERS; i++) { |
for (j = 0; j < SAA9730_TXPKTS_PER_BUFFER; j++) { |
memset(bufp, 0, 2048); |
*bufp = CYG_CPU_TO_LE32(TX_EMPTY); |
spd->tx_buffer[i][j] = bufp; |
bufp += SAA9730_PACKET_SIZE/sizeof(*bufp); |
} |
} |
|
spd->next_rx_pindex = 0; |
spd->next_rx_bindex = 0; |
spd->next_tx_pindex = 0; |
spd->next_tx_bindex = 0; |
} |
|
static void |
__select_buffer(struct saa9730_priv_data *spd, int buf_nr) |
{ |
unsigned long __base = spd->base; |
cyg_uint32 *p; |
int i; |
|
// Enable RX buffer |
for (i = 0; i < SAA9730_RXPKTS_PER_BUFFER; i++) { |
p = spd->rx_buffer[buf_nr][i]; |
*p = CYG_CPU_TO_LE32(RX_READY); |
} |
|
if (buf_nr) |
SAA9730_OK2USE |= SAA9730_OK2USE_RXB; |
else |
SAA9730_OK2USE |= SAA9730_OK2USE_RXA; |
|
} |
|
static void |
__init_cam(struct saa9730_priv_data *spd) |
{ |
unsigned long __base = spd->base; |
cyg_uint32 abuf[3]; // room for 2 copies of mac address |
int i,j,cam_offset; |
|
// make 2 contiguous copies of mac addr |
memcpy((char *)abuf, enaddr, 6); |
memcpy((char *)abuf + 6, enaddr, 6); |
|
// Setting up the address compare regs is weird because you have |
// to access by word addresses even though addresses don't have |
// an integral number of words. |
cam_offset = 0; |
for (i = 0; i < SAA9730_CAM_ENTRIES; i++) { |
for (j = 0; j < 3; j++, cam_offset++) { |
SAA9730_CAMADR = cam_offset; |
SAA9730_CAMDAT = CYG_CPU_TO_BE32(abuf[j]); |
} |
} |
} |
|
static void |
__stop_dma(struct saa9730_priv_data *spd) |
{ |
unsigned long __base = spd->base; |
|
// Stop DMA |
SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX); |
|
// Stop tx/rx |
SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX; |
SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX; |
|
// Set DMA and MAC reset bits |
SAA9730_DMATST |= SAA9730_DMATST_RESET; |
SAA9730_MACCTL |= SAA9730_MACCTL_RESET; |
} |
|
|
static void |
__init_dma(struct saa9730_priv_data *spd) |
{ |
unsigned long __base = spd->base; |
|
__stop_dma(spd); |
|
// reset DMA engine |
SAA9730_DMATST |= SAA9730_DMATST_RESET; |
|
// setup buffers |
SAA9730_TXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[0][0]); |
SAA9730_TXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[1][0]); |
SAA9730_RXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[0][0]); |
SAA9730_RXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[1][0]); |
|
SAA9730_PKTCNT = ((SAA9730_TXPKTS_PER_BUFFER << 24) | |
(SAA9730_TXPKTS_PER_BUFFER << 16) | |
(SAA9730_RXPKTS_PER_BUFFER << 8) | |
(SAA9730_RXPKTS_PER_BUFFER << 0)); |
|
SAA9730_OK2USE = 0; |
|
__select_buffer(spd, 0); |
|
// initialize DMA control register |
SAA9730_DMACTL = SAA9730_DMACTL_BLKINT | |
SAA9730_DMACTL_MAXXFER_ANY | |
SAA9730_DMACTL_ENDIAN_LITTLE; |
|
SAA9730_DMACTL |= SAA9730_DMACTL_RXINT; |
SAA9730_DMACTL |= (1<<SAA9730_DMACTL_RXINTCNT_SHIFT); |
SAA9730_DMACTL &= ~SAA9730_DMACTL_BLKINT; |
|
#ifndef CYGPKG_REDBOOT |
SAA9730_DMACTL |= SAA9730_DMACTL_TXINT; |
#endif |
|
SAA9730_TIMOUT = 200; |
|
// accept broadcast packets */ |
SAA9730_CAMCTL = SAA9730_CAMCTL_BROADCAST | |
SAA9730_CAMCTL_COMPARE; |
|
SAA9730_TXCTL = 0; |
SAA9730_RXCTL |= SAA9730_RXCTL_STRIPCRC; |
|
SAA9730_CAMENA = 1; |
|
} |
|
static void |
__check_mii(struct saa9730_priv_data *spd) |
{ |
unsigned long __base = spd->base; |
cyg_uint32 opmode; |
|
#ifdef DEBUG |
db_printf("__check_mii\n"); |
#endif |
|
// spin till station is not busy |
while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY) |
; |
|
// set PHY address = 'STATUS' |
SAA9730_MDCTL = SAA9730_MDCTL_BUSY | |
(PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT) | |
PHY_STATUS; |
|
// spin till station is not busy |
while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY) |
; |
|
hal_delay_us(1000); |
|
// check the link status |
if (SAA9730_MDDATA & PHY_STATUS_LINK_UP) { |
|
SAA9730_MDCTL = SAA9730_MDCTL_BUSY | |
(PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT) | |
PHY_REG31; |
|
// spin till station is not busy |
while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY) |
; |
|
hal_delay_us(1000); |
|
opmode = (SAA9730_MDDATA & PHY_REG31_OPMODE_MSK) >> PHY_REG31_OPMODE_SHIFT; |
|
#ifdef DEBUG |
db_printf("MII mode %d\n", opmode); |
#endif |
|
if ((opmode == OPMODE_10BASET_FULLDUPLEX) || |
(opmode == OPMODE_100BASEX_FULLDUPLEX)) |
SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII | SAA9730_MACCTL_FULLDUP; |
else |
SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII; |
} |
#ifdef DEBUG |
else |
db_printf("Link is down\n"); |
#endif |
} |
|
|
static void |
saa9730_reset(struct saa9730_priv_data *spd) |
{ |
unsigned long __base = spd->base; |
|
__init_buffers(spd); |
|
__base = spd->base; |
|
// Stop DMA |
SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX); |
|
// Stop tx/rx |
SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX; |
SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX; |
|
// Set DMA and MAC reset bits |
SAA9730_DMATST |= SAA9730_DMATST_RESET; |
SAA9730_MACCTL |= SAA9730_MACCTL_RESET; |
|
__init_cam(spd); |
__init_dma(spd); |
__check_mii(spd); |
|
spd->tx_busy = 0; |
} |
|
|
static bool |
atlas_saa9730_init(struct cyg_netdevtab_entry *tab) |
{ |
static int initialized = 0; // only probe PCI et al *once* |
struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
|
#ifdef DEBUG |
db_printf("atlas_saa9730_init\n"); |
#endif |
|
if (0 == initialized) { |
cyg_pci_device_id devid; |
cyg_pci_device dev_info; |
|
cyg_pci_init(); |
|
devid = CYG_PCI_NULL_DEVID; |
|
if (cyg_pci_find_device(CYG_PCI_VENDOR_PHILIPS, 0x9730, &devid) ) { |
|
spd->devid = devid; |
|
cyg_pci_get_device_info(devid, &dev_info); |
|
if (!cyg_pci_configure_device(&dev_info)) { |
#ifdef DEBUG |
db_printf("Failed to configure eth device\n"); |
#endif |
return false; |
} |
|
// Philips SAA9730 implements only one function memory mapped |
// into a single contigous memory region. |
// |
// According to spec. the BAR#1 is to be used for memory mapped IO. |
spd->base = dev_info.base_map[1]; |
|
// FIXME! All IO units share an interrupt |
spd->vector = CYGNUM_HAL_INTERRUPT_INTB; |
|
// Setup timing stuff |
cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid), |
CYG_PCI_DEV_GET_DEVFN(devid), |
CYG_PCI_CFG_LATENCY_TIMER, 0x20); |
cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid), |
CYG_PCI_DEV_GET_DEVFN(devid), |
CYG_PCI_CFG_MIN_GNT, 9); |
cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid), |
CYG_PCI_DEV_GET_DEVFN(devid), |
CYG_PCI_CFG_MAX_LAT, 24); |
|
#ifdef DEBUG |
db_printf("eth0 found: bus[%d] dev[%d] base[%x] vector[%d]\n", |
CYG_PCI_DEV_GET_BUS(devid), |
CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)), |
spd->base, spd->vector); |
#endif |
|
spd->ndp = tab; |
|
#ifndef CYGPKG_REDBOOT |
cyg_drv_interrupt_create( |
spd->vector, |
0, // Priority - unused |
(CYG_ADDRWORD)spd, // Data item passed to ISR & DSR |
saa9730_isr, // ISR |
saa9730_dsr, // DSR |
&spd->interrupt_handle, // handle to intr obj |
&spd->interrupt_object ); // space for int obj |
|
cyg_drv_interrupt_attach(spd->interrupt_handle); |
cyg_drv_interrupt_acknowledge(spd->vector); |
cyg_drv_interrupt_unmask(spd->vector); |
#endif |
{ |
// When in Redboot we want to get RX interrupts. These |
// will be picked up by the default interrupt handler and |
// checked for ^C. |
unsigned long __base = spd->base; |
SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER); |
SAA9730_EVM_IER |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER); |
SAA9730_EVM_ISR |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER); |
} |
|
#ifdef DEBUG |
db_printf(" **** Device enabled for I/O and Memory and Bus Master\n"); |
#endif |
|
} else { |
#ifdef DEBUG |
db_printf("eth0 not found\n"); |
#endif |
} |
|
saa9730_stop(sc); |
|
spd->active = 0; |
|
initialized = 1; |
} |
|
// Fetch hardware address |
#if defined(CYGPKG_REDBOOT) && \ |
defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \ |
!defined(CYGSEM_MIPS_ATLAS_SET_ESA) |
flash_get_config("atlas_esa", enaddr, CONFIG_ESA); |
#else |
#define CONFIG_ESA 6 |
CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, |
"atlas_esa", enaddr, CONFIG_ESA ); |
#ifdef DEBUG |
db_printf("ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", |
enaddr[0],enaddr[1],enaddr[2],enaddr[3],enaddr[4],enaddr[5]); |
#endif |
#endif |
|
saa9730_reset(spd); |
|
// Initialize upper level driver |
(sc->funs->eth_drv->init)(sc, enaddr); |
|
return true; |
} |
|
static void |
saa9730_stop(struct eth_drv_sc *sc) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
unsigned long __base = spd->base; |
|
// Stop DMA |
SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX); |
|
// Stop tx/rx |
SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX; |
SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX; |
|
// Set DMA and MAC reset bits |
SAA9730_DMATST |= SAA9730_DMATST_RESET; |
SAA9730_MACCTL |= SAA9730_MACCTL_RESET; |
|
spd->active = 0; |
} |
|
static void |
__do_start(struct saa9730_priv_data *spd) |
{ |
unsigned long __base = spd->base; |
int i; |
|
spd->active = 1; |
spd->tx_busy = 0; |
|
for (i = 0; i < SAA9730_BUFFERS; i++) |
spd->tx_used[i] = 0; |
|
// for tx, turn on MAC first |
SAA9730_TXCTL |= SAA9730_TXCTL_ENTX; |
SAA9730_DMACTL |= SAA9730_DMACTL_ENTX; |
|
// for rx, turn on DMA first |
SAA9730_DMACTL |= SAA9730_DMACTL_ENRX; |
SAA9730_RXCTL |= SAA9730_RXCTL_ENRX; |
|
__select_buffer(spd, spd->next_rx_bindex); |
} |
|
// |
// This function is called to "start up" the interface. It may be called |
// multiple times, even when the hardware is already running. It will be |
// called whenever something "hardware oriented" changes and should leave |
// the hardware ready to send/receive packets. |
// |
static void |
saa9730_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
|
if (spd->active) |
saa9730_stop(sc); |
|
__do_start(spd); |
} |
|
// |
// This routine is called to perform special "control" opertions |
// |
static int |
saa9730_control(struct eth_drv_sc *sc, unsigned long key, |
void *data, int data_length) |
{ |
switch (key) { |
case ETH_DRV_SET_MAC_ADDRESS: |
return 0; |
break; |
default: |
return 1; |
break; |
} |
} |
|
// |
// This routine is called to see if it is possible to send another packet. |
// It will return non-zero if a transmit is possible, zero otherwise. |
// |
static int |
saa9730_can_send(struct eth_drv_sc *sc) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
unsigned long __base = spd->base; |
|
__tx_poll(sc); |
|
if (spd->next_tx_bindex == 0 && (SAA9730_OK2USE & SAA9730_OK2USE_TXA)) |
return 0; |
|
if (spd->next_tx_bindex == 1 && (SAA9730_OK2USE & SAA9730_OK2USE_TXB)) |
return 0; |
|
return 1; |
} |
|
|
static int tx_poll_count; |
|
// |
// This routine is called to send data to the hardware. |
static void |
saa9730_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, |
int total_len, unsigned long key) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
unsigned long __base = spd->base; |
int bindex, pindex; |
cyg_uint32 pktlen = total_len; |
cyg_uint8 *pktdata, *to_p; |
volatile cyg_uint32 *pktstat ; |
struct eth_drv_sg *last_sg; |
|
#ifdef DEBUG |
db_printf("saa9730_send: %d sg's, %d bytes, KEY %x\n", |
sg_len, total_len, key ); |
#endif |
|
if (!spd->active) |
return; |
|
bindex = spd->next_tx_bindex; |
pindex = spd->next_tx_pindex; |
|
spd->next_tx_pindex++; |
if (spd->next_tx_pindex >= SAA9730_TXPKTS_PER_BUFFER) { |
spd->next_tx_pindex = 0; |
spd->next_tx_bindex ^= 1; |
} |
|
pktstat = spd->tx_buffer[bindex][pindex]; |
|
if (bindex == 0 && (SAA9730_OK2USE & SAA9730_OK2USE_TXA)) |
return; |
|
if (bindex == 1 && (SAA9730_OK2USE & SAA9730_OK2USE_TXB)) |
return; |
|
spd->tx_key[bindex][pindex] = key; |
spd->tx_used[bindex] += 1; |
|
pktdata = (cyg_uint8 *)((unsigned)pktstat + 4); |
|
// Copy from the sglist into the tx buffer |
to_p = pktdata; |
|
for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) { |
cyg_uint8 *from_p; |
int l; |
|
from_p = (cyg_uint8 *)(sg_list->buf); |
l = sg_list->len; |
|
if (l > total_len) |
l = total_len; |
|
memcpy((unsigned char *)to_p, from_p, l); |
to_p += l; |
total_len -= l; |
|
if (total_len < 0) |
break; // Should exit via sg_last normally |
} |
|
// pad to minimum size |
if (pktlen < SAA9730_MIN_PACKET_SIZE) { |
memset(to_p, 0, SAA9730_MIN_PACKET_SIZE-pktlen); |
pktlen = SAA9730_MIN_PACKET_SIZE; |
} |
|
// Set transmit status WORD for hardware (LAN-DMA-ENGINE) |
*pktstat = CYG_CPU_TO_LE32(TX_READY | pktlen); |
|
// start hardware |
if (bindex == 0) |
SAA9730_OK2USE |= SAA9730_OK2USE_TXA; |
else |
SAA9730_OK2USE |= SAA9730_OK2USE_TXB; |
|
if (!spd->tx_busy) { |
tx_poll_count = 0; |
spd->tx_busy = bindex + 1; |
} |
} |
|
|
static void |
__check_rxstate(struct saa9730_priv_data *spd) |
{ |
unsigned long __base = spd->base; |
cyg_uint32 status, flag, size; |
cyg_uint32 *pkt; |
int i, j; |
|
#ifdef DEBUG |
db_printf("__check_rxstate\n"); |
#endif |
|
#ifdef CYGPKG_REDBOOT |
// Clear SAA9730 LAN interrupt and re-enable interrupts. |
SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT; |
SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER); |
#endif |
|
if ((SAA9730_DBGRXS & SAA9730_DBGRXS_RXDII_MASK) == SAA9730_DBGRXS_RXDII_ERROR) { |
// re-init driver and controller |
#ifdef DEBUG |
db_printf("DBGRXS: reset\n"); |
#endif |
saa9730_reset(spd); |
__do_start(spd); |
return; |
} |
|
// Check RX packet status |
for (i = 0; i < SAA9730_BUFFERS; i++) { |
for (j = 1; j < SAA9730_RXPKTS_PER_BUFFER; j++) { |
pkt = spd->rx_buffer[i][j]; |
status = CYG_LE32_TO_CPU(*pkt); |
size = status & RXPACKET_STATUS_SIZE_MASK; |
flag = status & RXPACKET_STATUS_FLAG_MASK; |
if (flag == RX_INVALID_STAT || size > 1514 || *(pkt - 1)) { |
// re-init driver and controller |
#ifdef DEBUG |
db_printf("rxpkt: reset\n"); |
#endif |
saa9730_reset(spd); |
__do_start(spd); |
return; |
} |
} |
} |
} |
|
|
static void |
__tx_poll(struct eth_drv_sc *sc) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
int bindex, pindex; |
volatile cyg_uint32 *pktstat; |
cyg_uint32 status; |
|
if (!spd->tx_busy) |
return; |
|
bindex = spd->tx_busy - 1; |
pindex = spd->tx_used[bindex] - 1; // watch last pkt in buffer |
|
pktstat = spd->tx_buffer[bindex][pindex]; |
|
status = CYG_LE32_TO_CPU(*pktstat); |
if ((status & TXPACKET_STATUS_FLAG_MASK) != TX_HWDONE) { |
|
hal_delay_us(1000); |
|
if (++tx_poll_count > 1000) { |
// reset |
|
for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++) |
(sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1); |
|
bindex ^= 1; |
|
for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++) |
(sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1); |
|
saa9730_reset(spd); |
__do_start(spd); |
} |
return; |
} |
|
for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++) { |
/* Check for error. */ |
pktstat = spd->tx_buffer[bindex][pindex]; |
status = CYG_LE32_TO_CPU(*pktstat); |
|
if (status & TXPACKET_STATUS_ERROR) { |
if (status & TXPACKET_STATUS_EXDEFER) |
db_printf("tx deferred\n"); |
|
if (status & TXPACKET_STATUS_LATECOLLERR) |
db_printf("tx late collision\n"); |
|
if (status & TXPACKET_STATUS_LOSTCARRIER) |
db_printf("tx no carrier\n"); |
|
if (status & TXPACKET_STATUS_UNDERRUN) |
db_printf("tx underrun\n"); |
|
if (status & TXPACKET_STATUS_SQERR) |
db_printf("tx sq\n"); |
} |
/* free the space */ |
*pktstat = CYG_CPU_TO_LE32(TX_EMPTY); |
|
(sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1 /* status */); |
} |
|
tx_poll_count = 0; |
spd->tx_used[bindex] = 0; |
|
bindex ^= 1; |
if (spd->tx_used[bindex]) |
spd->tx_busy = bindex + 1; |
else |
spd->tx_busy = 0; |
} |
|
|
static void |
__rx_poll(struct eth_drv_sc *sc) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
int bindex, pindex, done; |
volatile cyg_uint32 *pkt; |
cyg_uint32 status, pktlen; |
|
#ifdef DEBUG |
db_printf("__rx_poll\n"); |
#endif |
if (!spd->active) |
return; |
|
done = 0; |
while (!done) { |
// index of next packet buffer |
bindex = spd->next_rx_bindex; |
|
// index of next packet within buffer |
pindex = spd->next_rx_pindex; |
|
pkt = spd->rx_buffer[bindex][pindex]; |
|
// stop now if no more packets |
if (((status = CYG_LE32_TO_CPU(*pkt)) & RXPACKET_STATUS_FLAG_MASK) == RX_READY) |
break; |
#ifdef DEBUG |
db_printf("__rx_poll pkt %08x status %08x\n",pkt,status); |
#endif |
// if this is the first packet in a buffer, switch the SAA9730 to |
// use the next buffer for subsequent incoming packets. |
if (pindex == 0) |
__select_buffer(spd, bindex == 0); |
|
// check for good packet |
if (status & RXPACKET_STATUS_GOOD) { |
|
pktlen = status & RXPACKET_STATUS_SIZE_MASK ; |
|
if (pktlen > 0) { |
(sc->funs->eth_drv->recv)(sc, pktlen); |
// done = 1; |
} |
} |
#ifdef DEBUG |
else |
db_printf("rx bad: %08x %08x\n",pkt,status); |
#endif |
|
/* go to next packet in sequence */ |
spd->next_rx_pindex++; |
if (spd->next_rx_pindex >= SAA9730_RXPKTS_PER_BUFFER) { |
spd->next_rx_pindex = 0; |
spd->next_rx_bindex++; |
if (spd->next_rx_bindex >= SAA9730_BUFFERS) |
spd->next_rx_bindex = 0; |
} |
} |
|
if (((poll_count++) % 100) == 0) |
__check_rxstate(spd); |
} |
|
|
static void |
saa9730_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
volatile cyg_uint32 *pkt; |
cyg_uint32 pktlen, status; |
struct eth_drv_sg *last_sg; |
|
if (!spd->active) |
return; |
|
pkt = spd->rx_buffer[spd->next_rx_bindex][spd->next_rx_pindex]; |
|
status = CYG_LE32_TO_CPU(*pkt); |
if (status & RXPACKET_STATUS_GOOD) { |
// packet is good |
pktlen = status & RXPACKET_STATUS_SIZE_MASK; |
|
if (pktlen > 0) { |
int total_len; |
cyg_uint8 *from_p; |
|
// check we have memory to copy into; we would be called even if |
// caller was out of memory in order to maintain our state. |
if (0 == sg_len || 0 == sg_list) |
return; // caller was out of mbufs |
|
total_len = pktlen; |
from_p = (cyg_uint8 *)((unsigned)pkt + 4); |
|
for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) { |
cyg_uint8 *to_p; |
int l; |
|
to_p = (cyg_uint8 *)(sg_list->buf); |
l = sg_list->len; |
|
if (0 >= l || 0 == to_p) |
return; // caller was out of mbufs |
|
if (l > total_len) |
l = total_len; |
|
memcpy(to_p, (unsigned char *)from_p, l); |
from_p += l; |
total_len -= l; |
} |
} |
} |
} |
|
static inline void |
__do_deliver(struct eth_drv_sc *sc) |
{ |
// First pass any rx data up the stack |
__rx_poll(sc); |
|
// Then scan for completed Txen and inform the stack |
__tx_poll(sc); |
} |
|
static void |
saa9730_poll(struct eth_drv_sc *sc) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
|
#ifndef CYGPKG_REDBOOT |
cyg_drv_interrupt_mask(spd->vector); |
#endif |
|
(void)saa9730_isr(spd->vector, (cyg_addrword_t)spd); |
|
__do_deliver(sc); |
|
cyg_drv_interrupt_acknowledge(spd->vector); |
|
#ifndef CYGPKG_REDBOOT |
cyg_drv_interrupt_unmask(spd->vector); |
#endif |
} |
|
|
// The deliver function (ex-DSR) handles the ethernet [logical] processing |
static void |
saa9730_deliver(struct eth_drv_sc *sc) |
{ |
struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private; |
unsigned long __base = spd->base; |
|
if (spd->active) |
__do_deliver(sc); |
|
cyg_drv_interrupt_acknowledge(spd->vector); |
|
#ifndef CYGPKG_REDBOOT |
// Clear SAA9730 LAN interrupt and re-enable interrupts. |
SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER); |
cyg_drv_interrupt_unmask(spd->vector); |
#endif |
} |
|
|
/atlas/v2_0/src/if_buffers.S
0,0 → 1,64
// #======================================================================== |
// # |
// # if_buffers.S |
// # |
// # Declare a chunk of 4Kbyte aligned memory for use by bus-mastering |
// # PCI ethernet device. |
// # |
// #======================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
// #======================================================================== |
// ######DESCRIPTIONBEGIN#### |
// # |
// # Author(s): msalter |
// # Contributors: msalter |
// # Date: 2000-11-03 |
// # Purpose: |
// # Description: This file defines a chunk of 2Kbyte aligned memory for use |
// # by bus-mastering PCI ethernet device. |
// # |
// #####DESCRIPTIONEND#### |
// # |
// #======================================================================== |
|
#include "saa9730.h" |
|
.bss |
.p2align(11) |
.globl cyg_io_atlas_2kbuffers |
cyg_io_atlas_2kbuffers: |
.rept (SAA9730_RXPKTS_PER_BUFFER + SAA9730_TXPKTS_PER_BUFFER) \ |
* SAA9730_BUFFERS * SAA9730_PACKET_SIZE |
.byte 0 |
.endr |
/atlas/v2_0/src/saa9730.h
0,0 → 1,364
#ifndef CYGONCE_DEVS_ETH_MIPS_ATLAS_SAA9730_H |
#define CYGONCE_DEVS_ETH_MIPS_ATLAS_SAA9730_H |
/*========================================================================== |
// |
// saa9730.h |
// Philips SAA9730 IO Chip Ethernet Interface |
// |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// Copyright (C) 2003 Nick Garnett <nickg@calivar.com> |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting the copyright |
// holders. |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): msalter |
// Contributors: msalter, nickg |
// Date: 2000-12-09 |
// Description: Definitions for Philips SAA9730 Ethernet module. |
// |
//####DESCRIPTIONEND#### |
*/ |
|
// QS6612 PHY definitions |
|
#define PHY_CONTROL 0 |
#define PHY_STATUS 1 |
#define PHY_REG31 31 |
|
#define PHY_CONTROL_RESET (1 << 15) |
#define PHY_CONTROL_AUTO_NEG (1 << 12) |
#define PHY_CONTROL_RESTART_AUTO_NEG (1 << 9) |
|
#define PHY_STATUS_LINK_UP (1 << 2) |
|
#define PHY_REG31_OPMODE_SHIFT 2 |
#define PHY_REG31_OPMODE_MSK (7 << PHY_REG31_OPMODE_SHIFT) |
|
#define OPMODE_AUTONEGOTIATE 0 |
#define OPMODE_10BASET_HALFDUPLEX 1 |
#define OPMODE_100BASEX_HALFDUPLEX 2 |
#define OPMODE_REPEATER_MODE 3 |
#define OPMODE_UNDEFINED 4 |
#define OPMODE_10BASET_FULLDUPLEX 5 |
#define OPMODE_100BASEX_FULLDUPLEX 6 |
#define OPMODE_ISOLATE 7 |
|
#define QS6612_PHY_ADDRESS 0 |
#define PHY_ADDRESS QS6612_PHY_ADDRESS |
|
// Number of 6-byte entries in the CAM |
#define SAA9730_CAM_ENTRIES 10 |
|
// TX and RX packet size fixed at 2k bytes by hw |
#define SAA9730_PACKET_SIZE 2048 |
|
// Number of TX buffers = number of RX buffers = 2, |
// which is fixed according to HW requirements |
#define SAA9730_BUFFERS 2 |
|
// Number of RX packets per RX buffer |
#define SAA9730_RXPKTS_PER_BUFFER 2 |
|
// Number of TX packets per TX buffer |
#define SAA9730_TXPKTS_PER_BUFFER 1 |
|
// Minimum packet size |
#define SAA9730_MIN_PACKET_SIZE 60 |
|
// owner ship bit |
#define SAA9730_BLOCK_OWNED_BY_SYSTEM 0 |
#define SAA9730_BLOCK_OWNED_BY_HARDWARE 1 |
|
// Default Rcv interrupt count |
#define SAA9730_DEFAULT_RCV_INTERRUPT_CNT 4 |
|
// Default maxium transmit retry |
#define SAA9730_DEFAULT_MAX_TXM_RETRY 16 |
|
// Default time out value |
#define SAA9730_DEFAULT_TIME_OUT_CNT 200 |
|
// MAX map registers |
#define SAA9730__MAX_MAP_REGISTERS 64 |
|
// Defines used by Interrupt code |
#define SAA9730_DMA_PACKET_SIZE 2048 |
#define SAA9730_VALID_PACKET 0xC0000000 |
#define SAA9730_FRAME_TYPELEN_OFFSET 12 |
#define SAA9730_ETH_MIN_FRAME_SIZE 60 |
#define SAA9730_DEST_ADDR_SIZE 6 |
#define SAA9730_SRC_ADDR_SIZE 6 |
#define SAA9730_TYPE_LEN_SIZE 2 |
|
// MAC receive error |
#define SAA9730_MAC_GOOD_RX (0x00004000) << 11 |
#define SAA9730_MAC_RCV_ALIGN_ERROR (0x00000100) << 11 |
#define SAA9730_MAC_RCV_CRC_ERROR (0x00000200) << 11 |
#define SAA9730_MAC_RCV_OVERFLOW (0x00000400) << 11 |
|
// This number is arbitrary and can be increased if needed |
#define SAA9730_MAX_MULTICAST_ADDRESSES 20 |
|
// SAA9730 Event Manager Registers |
#define SAA9730_EVM_ISR *((volatile unsigned *)(__base + 0x02000)) |
#define SAA9730_EVM_IER *((volatile unsigned *)(__base + 0x02004)) |
#define SAA9730_EVM_IMR *((volatile unsigned *)(__base + 0x02008)) |
|
#define SAA9730_EVM_IER_SW *((volatile unsigned *)(__base + 0x0202c)) |
|
#define SAA9730_EVM_LAN_INT (1<<16) // LAN interrupt bit |
#define SAA9730_EVM_MASTER (1<<0) // Master interrupt bit |
|
// SAA9730 LAN Registers |
#define SAA9730_TXBUFA *((volatile unsigned *)(__base + 0x20400)) // TX buffer A |
|
#define SAA9730_TXBUFB *((volatile unsigned *)(__base + 0x20404)) // TX buffer B |
|
#define SAA9730_RXBUFA *((volatile unsigned *)(__base + 0x20408)) // RX buffer A |
|
#define SAA9730_RXBUFB *((volatile unsigned *)(__base + 0x2040C)) // RX buffer B |
|
#define SAA9730_PKTCNT *((volatile unsigned *)(__base + 0x20410)) // Packet count |
|
#define SAA9730_OK2USE *((volatile unsigned *)(__base + 0x20414)) // OK-to-use |
# define SAA9730_OK2USE_TXA 8 |
# define SAA9730_OK2USE_TXB 4 |
# define SAA9730_OK2USE_RXA 2 |
# define SAA9730_OK2USE_RXB 1 |
|
#define SAA9730_DMACTL *((volatile unsigned *)(__base + 0x20418)) // DMA control |
# define SAA9730_DMACTL_BLKINT (1 << 31) |
# define SAA9730_DMACTL_MAXXFER_ANY (0 << 18) |
# define SAA9730_DMACTL_MAXXFER_8 (1 << 18) |
# define SAA9730_DMACTL_MAXXFER_32 (2 << 18) |
# define SAA9730_DMACTL_MAXXFER_64 (3 << 18) |
# define SAA9730_DMACTL_ENDIAN_LITTLE (0 << 16) |
# define SAA9730_DMACTL_ENDIAN_2143 (1 << 16) |
# define SAA9730_DMACTL_ENDIAN_4321 (2 << 16) |
# define SAA9730_DMACTL_RXINTCNT_SHIFT 8 |
# define SAA9730_DMACTL_RXINTCNT_MSK (0xff << SAA9730_DMACTL_RXINTCNT_SHIFT) |
# define SAA9730_DMACTL_ENTX (1 << 7) |
# define SAA9730_DMACTL_ENRX (1 << 6) |
# define SAA9730_DMACTL_RXFULL (1 << 5) |
# define SAA9730_DMACTL_RXTOINT (1 << 4) |
# define SAA9730_DMACTL_RXINT (1 << 3) |
# define SAA9730_DMACTL_TXINT (1 << 2) |
# define SAA9730_DMACTL_MACTXINT (1 << 1) |
# define SAA9730_DMACTL_MACRXINT (1 << 0) |
|
#define SAA9730_TIMOUT *((volatile unsigned *)(__base + 0x2041C)) // Time out |
|
#define SAA9730_DMASTA *((volatile unsigned *)(__base + 0x20420)) // DMA status |
# define SAA9730_DMASTA_TXABADR_MSK (1 << 19) |
# define SAA9730_DMASTA_TXBBADR_MSK (1 << 18) |
# define SAA9730_DMASTA_RXABADR_MSK (1 << 17) |
# define SAA9730_DMASTA_RXBBADR_MSK (1 << 16) |
# define SAA9730_DMASTA_RXBBADR_SHIFT 8 |
# define SAA9730_DMASTA_RXPCKCNT_MASK (0xff << SAA9730_DMASTA_RXPCKCNT_SHIFT) |
# define SAA9730_DMASTA_TXMACBUSY_MSK (1 << 7) |
# define SAA9730_DMASTA_RXAFULL_MSK (1 << 6) |
# define SAA9730_DMASTA_RXBFULL_MSK (1 << 5) |
# define SAA9730_DMASTA_RXTOINT_MSK (1 << 4) |
# define SAA9730_DMASTA_RXINT_MSK (1 << 3) |
# define SAA9730_DMASTA_TXINT_MSK (1 << 2) |
# define SAA9730_DMASTA_MACTXINT_MSK (1 << 1) |
# define SAA9730_DMASTA_MACRXINT_MSK (1 << 0) |
|
#define SAA9730_DMATST *((volatile unsigned *)(__base + 0x20424)) // DMA loop back |
# define SAA9730_DMATST_LPBACK (1 << 24) |
# define SAA9730_DMATST_RESET 1 |
|
#define SAA9730_PAUSE *((volatile unsigned *)(__base + 0x20430)) // Pause count |
|
#define SAA9730_REMPAUSE *((volatile unsigned *)(__base + 0x20434)) // Remote Pause count |
|
#define SAA9730_MACCTL *((volatile unsigned *)(__base + 0x20440)) // MAC control |
# define SAA9730_MACCTL_MISSRINT (1 << 13) |
# define SAA9730_MACCTL_MISSROLL (1 << 10) |
# define SAA9730_MACCTL_LOOP10 (1 << 7) |
# define SAA9730_MACCTL_CONMODE_AUTOMATIC (0 << 5) |
# define SAA9730_MACCTL_CONMODE_FORCE_10MB (1 << 5) |
# define SAA9730_MACCTL_CONMODE_FORCE_MII (2 << 5) |
# define SAA9730_MACCTL_LPBACK (1 << 4) |
# define SAA9730_MACCTL_FULLDUP (1 << 3) |
# define SAA9730_MACCTL_RESET (1 << 2) |
# define SAA9730_MACCTL_HALTNOW (1 << 1) |
# define SAA9730_MACCTL_HALTREQ (1 << 0) |
|
#define SAA9730_CAMCTL *((volatile unsigned *)(__base + 0x20444)) // CAM control |
# define SAA9730_CAMCTL_COMPARE (1 << 4) |
# define SAA9730_CAMCTL_NEGATE (1 << 3) |
# define SAA9730_CAMCTL_BROADCAST (1 << 2) |
# define SAA9730_CAMCTL_MULTICAST (1 << 1) |
# define SAA9730_CAMCTL_UNICAST (1 << 0) |
|
#define SAA9730_TXCTL *((volatile unsigned *)(__base + 0x20448)) // TX control |
# define SAA9730_TXCTL_COMPLINT (1 << 14) |
# define SAA9730_TXCTL_TXPARINT (1 << 13) |
# define SAA9730_TXCTL_LATECOLLINT (1 << 12) |
# define SAA9730_TXCTL_EXCOLLINT (1 << 11) |
# define SAA9730_TXCTL_CARRIERINT (1 << 10) |
# define SAA9730_TXCTL_DEFERINT (1 << 9) |
# define SAA9730_TXCTL_UNDERINT (1 << 8) |
# define SAA9730_TXCTL_MII10 (1 << 7) |
# define SAA9730_TXCTL_SDPAUSE (1 << 6) |
# define SAA9730_TXCTL_NOEXDEF (1 << 5) |
# define SAA9730_TXCTL_FBACK (1 << 4) |
# define SAA9730_TXCTL_NOCRC (1 << 3) |
# define SAA9730_TXCTL_NOPAD (1 << 2) |
# define SAA9730_TXCTL_TXHALT (1 << 1) |
# define SAA9730_TXCTL_ENTX (1 << 0) |
|
#define SAA9730_TXSTA *((volatile unsigned *)(__base + 0x2044C)) // TX status |
# define SAA9730_TXSTA_SQERR (1 << 16) |
# define SAA9730_TXSTA_TXHALTED (1 << 15) |
# define SAA9730_TXSTA_COMPLETION (1 << 14) |
# define SAA9730_TXSTA_PARITYERR (1 << 13) |
# define SAA9730_TXSTA_LATECOLLERR (1 << 12) |
# define SAA9730_TXSTA_WAS10MB (1 << 11) |
# define SAA9730_TXSTA_LOSTCARRIER (1 << 10) |
# define SAA9730_TXSTA_EXDEFER (1 << 9) |
# define SAA9730_TXSTA_UNDERRUN (1 << 8) |
# define SAA9730_TXSTA_INTERRUPT (1 << 7) |
# define SAA9730_TXSTA_PAUSED (1 << 6) |
# define SAA9730_TXSTA_DEFERRED (1 << 5) |
# define SAA9730_TXSTA_EXCOLL (1 << 4) |
# define SAA9730_TXSTA_COLLISIONS_MASK 0xf |
|
#define SAA9730_RXCTL *((volatile unsigned *)(__base + 0x20450)) // RX control |
# define SAA9730_RXCTL_ENGOOD (1 << 14) |
# define SAA9730_RXCTL_ENPARITY (1 << 13) |
# define SAA9730_RXCTL_ENLONGERR (1 << 11) |
# define SAA9730_RXCTL_ENOVER (1 << 10) |
# define SAA9730_RXCTL_ENCRCERR (1 << 9) |
# define SAA9730_RXCTL_ENALIGN (1 << 8) |
# define SAA9730_RXCTL_IGNORECRC (1 << 6) |
# define SAA9730_RXCTL_PASSCTL (1 << 5) |
# define SAA9730_RXCTL_STRIPCRC (1 << 4) |
# define SAA9730_RXCTL_SHORTEN (1 << 3) |
# define SAA9730_RXCTL_LONGEN (1 << 2) |
# define SAA9730_RXCTL_RXHALT (1 << 1) |
# define SAA9730_RXCTL_ENRX (1 << 0) |
|
#define SAA9730_RXSTA *((volatile unsigned *)(__base + 0x20454)) // RX status |
# define SAA9730_RXSTA_HALTED (1 << 15) |
# define SAA9730_RXSTA_GOOD (1 << 14) |
# define SAA9730_RXSTA_PARITY (1 << 13) |
# define SAA9730_RXSTA_LONGERR (1 << 11) |
# define SAA9730_RXSTA_OVERFLOW (1 << 10) |
# define SAA9730_RXSTA_CRCERR (1 << 9) |
# define SAA9730_RXSTA_ALIGNERR (1 << 8) |
# define SAA9730_RXSTA_WAS10MB (1 << 7) |
# define SAA9730_RXSTA_INTERRUPT (1 << 6) |
# define SAA9730_RXSTA_CONTROLRCV (1 << 5) |
|
#define SAA9730_MDDATA *((volatile unsigned *)(__base + 0x20458)) // PHY mgmt data |
# define SAA9730_MDDATA_DATA_MASK (0xffff << SAA9730_MDDATA_DATA_SHIFT) |
|
#define SAA9730_MDCTL *((volatile unsigned *)(__base + 0x2045C)) // PHY mgmt control |
# define SAA9730_MDCTL_PRESUP (1 << 12) |
# define SAA9730_MDCTL_BUSY (1 << 11) |
# define SAA9730_MDCTL_WRITE (1 << 10) |
# define SAA9730_MDCTL_PHY_SHIFT 5 |
# define SAA9730_MDCTL_PHY_MASK (0x1f << SAA9730_MDCTL_PHY_SHIFT) |
# define SAA9730_MDCTL_ADDR_MASK 0x1f |
|
#define SAA9730_CAMADR *((volatile unsigned *)(__base + 0x20460)) // CAM address |
# define SAA9730_CAMADR_ADDRESS_MASK (0x1ff << SAA9730_CAMADR_ADDRESS_SHIFT) |
|
#define SAA9730_CAMDAT *((volatile unsigned *)(__base + 0x20464)) // CAM data |
|
#define SAA9730_CAMENA *((volatile unsigned *)(__base + 0x20468)) // CAM enable |
# define SAA9730_CAMENA_ENABLE_MASK (0x3fffff << SAA9730_CAMENA_ENABLE_SHIFT) |
|
#define SAA9730_DBGRXS *((volatile unsigned *)(__base + 0x20508)) // DEBUG |
# define SAA9730_DBGRXS_RXPI_MASK (0x3ff << 16) |
# define SAA9730_DBGRXS_RXPI_ERROR (0x001 << 16) |
# define SAA9730_DBGRXS_RXDII_MASK 0x1ff |
# define SAA9730_DBGRXS_RXDII_ERROR 8 |
|
|
#define SAA9730_DBGRXFIFO *((volatile unsigned *)(__base + 0x20510)) // DEBUG |
|
#define SAA9730_DBGLANSTA *((volatile unsigned *)(__base + 0x20514)) // DEBUG |
|
// ******** Packet control/status ********** |
|
#define TXPACKET_CTL_FLAG_MASK (0x3 << 30) |
# define TX_EMPTY (0 << 30) |
# define TX_READY (2 << 30) |
# define TX_HWDONE (3 << 30) |
|
# define TXPACKET_CTL_IRQ_MASK (1 << 29) |
# define TXPACKET_CTL_NOCRC_MASK (1 << 28) |
# define TXPACKET_CTL_NOPAD_MASK (1 << 27) |
# define TXPACKET_CTL_SIZE_MASK 0x7ff |
|
#define TXPACKET_STATUS_FLAG_MASK (0x3 << 30) |
# define TXPACKET_STATUS_SQERR (1 << 27) |
# define TXPACKET_STATUS_TXHALTED (1 << 26) |
# define TXPACKET_STATUS_COMPLETION (1 << 25) |
# define TXPACKET_STATUS_PARITYERR (1 << 24) |
# define TXPACKET_STATUS_LATECOLLERR (1 << 23) |
# define TXPACKET_STATUS_WAS10MB (1 << 22) |
# define TXPACKET_STATUS_LOSTCARRIER (1 << 21) |
# define TXPACKET_STATUS_EXDEFER (1 << 20) |
# define TXPACKET_STATUS_UNDERRUN (1 << 19) |
# define TXPACKET_STATUS_COLLISIONS_SHIFT 11 |
# define TXPACKET_STATUS_COLLISIONS_MASK (0x1f << TXPACKET_STATUS_COLLISIONS_SHIFT) |
# define TXPACKET_STATUS_SIZE_MASK 0x7ff |
|
# define TXPACKET_STATUS_ERROR (TXPACKET_STATUS_EXDEFER | \ |
TXPACKET_STATUS_LATECOLLERR | \ |
TXPACKET_STATUS_LOSTCARRIER | \ |
TXPACKET_STATUS_UNDERRUN | \ |
TXPACKET_STATUS_SQERR) |
|
# define RXPACKET_STATUS_FLAG_MASK (0x3 << 30) |
# define RX_NDIS (0 << 30) |
# define RX_INVALID_STAT (1 << 30) |
# define RX_READY (2 << 30) |
# define RX_HWDONE (3 << 30) |
|
# define RXPACKET_STATUS_GOOD (1 << 25) |
# define RXPACKET_STATUS_PARITY (1 << 24) |
# define RXPACKET_STATUS_LONGERR (1 << 22) |
# define RXPACKET_STATUS_OVERFLOW (1 << 21) |
# define RXPACKET_STATUS_CRCERR (1 << 20) |
# define RXPACKET_STATUS_ALIGNERR (1 << 19) |
# define RXPACKET_STATUS_WAS10MB (1 << 18) |
# define RXPACKET_STATUS_SIZE_MASK 0x7ff |
|
#endif // CYGONCE_DEVS_ETH_MIPS_ATLAS_SAA9730_H |
/ocelot/v2_0/cdl/mips_rm7000_ocelot_eth_drivers.cdl
0,0 → 1,113
# ==================================================================== |
# |
# ocelot_eth_drivers.cdl |
# |
# Ethernet drivers - support for i82559 ethernet controller |
# on the PMC-Sierra Ocelot board. |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): jskov |
# Contributors: jskov |
# Date: 2001-01-25 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT { |
display "PMC-Sierra Ocelot board ethernet driver" |
description "Ethernet driver for PMC-Sierra Ocelot board." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_MIPS_RM7000_OCELOT |
|
include_dir cyg/io |
|
# FIXME: This really belongs in the INTEL_I82559 package |
cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED { |
display "Intel i82559 ethernet driver required" |
} |
|
define_proc { |
puts $::cdl_system_header "/***** ethernet driver proc output start *****/" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_mips_rm7000_ocelot.inl>" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_mips_rm7000_ocelot.h>" |
puts $::cdl_system_header "/***** ethernet driver proc output end *****/" |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0 { |
display "Ocelot ethernet port 0 driver" |
flavor bool |
default_value 1 |
description " |
This option includes the ethernet device driver for the |
Ocelot port 0 - that is the connector on the front of |
the board." |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH0 |
implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_NAME { |
display "Device name for the ETH0 ethernet port 0 driver" |
flavor data |
default_value {"\"eth0\""} |
description " |
This option sets the name of the ethernet device for the |
Ocelot port 0." |
} |
|
cdl_component CYGSEM_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
default_value 0 |
description "Enabling this option will allow the ethernet |
station address to be forced to the value set by the |
configuration. This may be required if the hardware does |
not include a serial EEPROM for the ESA." |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"} |
description "The ethernet station address" |
} |
} |
} |
} |
/ocelot/v2_0/include/devs_eth_mips_rm7000_ocelot.inl
0,0 → 1,118
//========================================================================== |
// |
// devs/eth/mips/ocelot/include/devs_eth_mips_rm7000_ocelot.inl |
// |
// Ocelot ethernet I/O definitions. |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): jskov |
// Contributors:jskov |
// Date: 2001-01-25 |
// Purpose: Ocelot ethernet defintions |
//####DESCRIPTIONEND#### |
//========================================================================== |
|
#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR |
|
#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0 |
|
#ifndef CYGSEM_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_SET_ESA |
# define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM 0 |
# define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_ONE_EEPROM_WITHOUT_CRC |
#endif |
|
#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(0x0ff00000)) |
#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE 0x00100000 |
|
static I82559 i82559_eth0_priv_data = { |
#ifdef CYGSEM_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_SET_ESA |
hardwired_esa: 1, |
mac_address: CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_ESA |
#else |
hardwired_esa: 0, |
#endif |
}; |
|
ETH_DRV_SC(i82559_sc0, |
&i82559_eth0_priv_data, // Driver specific data |
CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_NAME, // Name for device |
i82559_start, |
i82559_stop, |
i82559_ioctl, |
i82559_can_send, |
i82559_send, |
i82559_recv, |
i82559_deliver, |
i82559_poll, |
i82559_int_vector |
); |
|
NETDEVTAB_ENTRY(i82559_netdev0, |
"i82559_" CYGDAT_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0_NAME, |
i82559_init, |
&i82559_sc0); |
|
#endif // CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0 |
|
|
// These arrays are used for sanity checking of pointers |
I82559 * |
i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0 |
&i82559_eth0_priv_data, |
#endif |
}; |
|
#ifdef CYGDBG_USE_ASSERTS |
// These are only used when assertions are enabled |
cyg_netdevtab_entry_t * |
i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0 |
&i82559_netdev0, |
#endif |
}; |
|
struct eth_drv_sc * |
i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_RM7000_OCELOT_ETH0 |
&i82559_sc0, |
#endif |
}; |
#endif // CYGDBG_USE_ASSERTS |
|
// EOF devs_eth_mips_rm7000_ocelot.inl |
/ocelot/v2_0/ChangeLog
0,0 → 1,54
2001-06-22 Jesper Skov <jskov@redhat.com> |
|
* cdl/mips_rm7000_ocelot_eth_drivers.cdl: Default to getting ESA |
from EEPROM. |
|
* include/devs_eth_mips_rm7000_ocelot.inl: Tell driver to expect |
EEPROM without CRC. |
|
2001-03-02 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_mips_rm7000_ocelot.inl: Define controller PCI |
details. |
|
2001-11-29 Jesper Skov <jskov@redhat.com> |
|
* cdl/mips_rm7000_ocelot_eth_drivers.cdl: Platform specific |
information required to use the generic i82559 driver for the |
Ocelot platform. |
* include/devs_eth_mips_rm7000_ocelot.inl: Same. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |
/vrc4375/v2_0/cdl/vrc4375_eth_drivers.cdl
0,0 → 1,116
# ==================================================================== |
# |
# vrc4375_eth_drivers.cdl |
# |
# Ethernet drivers - support for i21143 ethernet controller |
# on the NEC VRC4375 "Blue Nile" board. |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): hmt |
# Contributors: |
# Date: 2001-09-17 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_MIPS_VRC4375 { |
display "NEC vrc4375 ethernet driver" |
description " |
Ethernet driver for vrc4375 'Blue Nile' board with one Intel |
i21143 Ethernet controller attached via the PCI bus." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_MIPS_VR4300_VRC4375 |
|
include_dir cyg/io |
|
cdl_interface CYGINT_DEVS_ETH_INTEL_I21143_REQUIRED { |
display "Intel i21143 ethernet driver required" |
} |
|
define_proc { |
puts $::cdl_system_header "/***** ethernet driver proc output start *****/" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I21143_INL <cyg/io/devs_eth_vrc4375.inl>" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I21143_CFG <pkgconf/devs_eth_mips_vrc4375.h>" |
puts $::cdl_system_header "/***** ethernet driver proc output end *****/" |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0 { |
display "Vrc4375 ethernet port 0 driver" |
flavor bool |
default_value 1 |
description " |
This option includes the ethernet device driver for the |
vrc4375Engine or vrc4375Bridge port 0 - that is the connector one |
slot in from the corner of the board, or the only connector |
depending on your particular hardware." |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH0 |
implements CYGINT_DEVS_ETH_INTEL_I21143_REQUIRED |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_NAME { |
display "Device name for the ethernet port 0 driver" |
flavor data |
default_value {"\"eth0\""} |
description " |
This option sets the name of the ethernet device for the |
ethernet port 0." |
} |
|
cdl_component CYGSEM_DEVS_ETH_MIPS_VRC4375_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
description "Enabling this option will allow the ethernet |
station address to be forced to the value set by the |
configuration. This may be required if the hardware does |
not include a serial EEPROM for the ESA." |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x00, 0x12, 0x34, 0x55, 0x55, 0x66}"} |
description "The ethernet station address" |
} |
} |
} |
} |
|
# EOF vrc4375_eth_drivers.cdl |
/vrc4375/v2_0/include/devs_eth_vrc4375.inl
0,0 → 1,127
//========================================================================== |
// |
// devs/eth/mips/vrc4375/..../include/devs_eth_vrc4375.inl |
// |
// vrc4375 ethernet I/O definitions. |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): hmt |
// Contributors: |
// Date: 2001-09-17 |
// Purpose: vrc4375 ethernet defintions |
//####DESCRIPTIONEND#### |
//========================================================================== |
|
// -------------------------------------------------------------- |
// Construct the interface |
|
#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0 |
|
static I21143 i21143_eth0_priv_data = { |
#ifdef CYGSEM_DEVS_ETH_MIPS_VRC4375_ETH0_SET_ESA |
hardwired_esa: 1, |
mac_address: CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_ESA |
#else |
hardwired_esa: 0, |
#endif |
}; |
|
ETH_DRV_SC(i21143_sc0, |
&i21143_eth0_priv_data, // Driver specific data |
CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_NAME, // Name for device |
i21143_start, |
i21143_stop, |
i21143_ioctl, |
i21143_can_send, |
i21143_send, |
i21143_recv, |
i21143_deliver, |
i21143_poll, |
i21143_int_vector |
); |
|
NETDEVTAB_ENTRY(i21143_netdev0, |
"i21143_" CYGDAT_DEVS_ETH_MIPS_VRC4375_ETH0_NAME, |
i21143_init, |
&i21143_sc0); |
|
#endif // CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0 |
|
// -------------------------------------------------------------- |
// These arrays are used for sanity checking of pointers |
I21143 * |
i21143_priv_array[CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0 |
&i21143_eth0_priv_data, |
#endif |
#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH1 |
&i21143_eth1_priv_data, |
#endif |
}; |
|
#ifdef CYGDBG_USE_ASSERTS |
// These are only used when assertions are enabled |
cyg_netdevtab_entry_t * |
i21143_netdev_array[CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0 |
&i21143_netdev0, |
#endif |
#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH1 |
&i21143_netdev1, |
#endif |
}; |
|
struct eth_drv_sc * |
i21143_sc_array[CYGNUM_DEVS_ETH_INTEL_I21143_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH0 |
&i21143_sc0, |
#endif |
#ifdef CYGPKG_DEVS_ETH_MIPS_VRC4375_ETH1 |
&i21143_sc1, |
#endif |
}; |
#endif // CYGDBG_USE_ASSERTS |
|
// -------------------------------------------------------------- |
// Debugging |
|
//#define CYGDBG_DEVS_ETH_INTEL_I21143_CHATTER 1 |
|
// -------------------------------------------------------------- |
|
// EOF devs_eth_vrc4375.inl |
/vrc4375/v2_0/ChangeLog
0,0 → 1,41
2001-09-27 Hugo Tyson <hmt@redhat.com> |
|
* cdl/vrc4375_eth_drivers.cdl: New file. |
* include/devs_eth_vrc4375.inl: New file. |
Instantiation data for the Intel 21143 Ethernet Device driver, |
as used in the NEC MIPS vrc4375 'Blue Nile' board. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |
/idt79s334a/v2_0/cdl/refidt334_eth_drivers.cdl
0,0 → 1,149
# ==================================================================== |
# |
# refidt334_eth_drivers.cdl |
# |
# Ethernet drivers |
# Intel PRO/100+ platform specific support for IDT MIPS 334 |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): Tim Michals |
# Original data: hmt |
# Contributors: |
# Date: 2003-02-13 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_MIPS_REFIDT334 { |
display "MIPS IDT 79RC32334 reference platform ethernet driver" |
description "Ethernet driver for MIPS IDT 79RC32334 reference platform." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_MIPS_IDT32334_REFIDT334 |
|
include_dir cyg/io |
|
# FIXME: This really belongs in the INTEL_I82559 package |
cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED { |
display "Intel i82559 ethernet driver required" |
} |
|
define_proc { |
puts $::cdl_system_header "/***** ethernet driver proc output start *****/" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_refidt334.inl>" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_mips_refidt334.h>" |
puts $::cdl_system_header "/***** ethernet driver proc output end *****/" |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0 { |
display "IDT 79RC32334 ethernet port 0 driver" |
flavor bool |
default_value 1 |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH0 |
implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_NAME { |
display "Device name for the ETH0 ethernet port 0 driver" |
flavor data |
default_value {"\"eth0\""} |
description " |
This option sets the name of the ethernet device for the |
i82559 ethernet port 0." |
} |
|
cdl_component CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
default_value 0 |
description "Enabling this option will allow the ethernet |
station address to be forced to the value set by the |
configuration. This may be required if the hardware does |
not include a serial EEPROM for the ESA." |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x01}"} |
description "The ethernet station address" |
} |
} |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1 { |
display "IDT 79RC32334 ethernet port 1 driver" |
flavor bool |
default_value 1 |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH1 |
implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_NAME { |
display "Device name for the ETH0 ethernet port 1 driver" |
flavor data |
default_value {"\"eth1\""} |
description " |
This option sets the name of the ethernet device for the |
i82559 ethernet port 1." |
} |
|
cdl_component CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
default_value 0 |
description "Enabling this option will allow the ethernet |
station address to be forced to the value set by the |
configuration. This may be required if the hardware does |
not include a serial EEPROM for the ESA." |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x08, 0x00, 0x00, 0x00, 0x00, 0x02}"} |
description "The ethernet station address" |
} |
} |
} |
|
} |
|
# EOF refidt334_eth_drivers.cdl |
/idt79s334a/v2_0/include/devs_eth_refidt334.inl
0,0 → 1,173
//========================================================================== |
// |
// devs_eth_refidt334.inl |
// |
// IDT79S334a i82559 ethernet I/O definitions. |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): Tim Michals |
// Contributors:jskov |
// Date: 2003-02-13 |
// Purpose: IDT79s334A i82559 ethernet defintions |
//####DESCRIPTIONEND#### |
//========================================================================== |
|
#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR |
|
#if 1 < CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT |
#define CYGHWR_DEVS_ETH_INTEL_I82559_DEMUX_ALL |
#endif // multiple devs, so demux_all needed |
|
|
#if defined(CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0) || defined(CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1) |
|
#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE 0xa0100000 |
#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE 0x100000 //CYGMEM_SECTION_pci_window_SIZE |
|
#define CYGHWR_INTEL_I82559_PCI_VIRT_TO_BUS( _x_ ) (((cyg_uint32)(_x_))|0) |
#define CYGHWR_INTEL_I82559_PCI_BUS_TO_VIRT( _x_ ) (((cyg_uint32)(_x_))&~0) |
#endif |
|
|
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0 |
|
static I82559 i82559_eth0_priv_data = { |
#ifdef CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_SET_ESA |
hardwired_esa: 1, |
mac_address: CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_SET_ESA |
#else |
hardwired_esa: 0, |
#endif |
}; |
|
ETH_DRV_SC(i82559_sc0, |
&i82559_eth0_priv_data, // Driver specific data |
CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_NAME, // Name for device |
i82559_start, |
i82559_stop, |
i82559_ioctl, |
i82559_can_send, |
i82559_send, |
i82559_recv, |
i82559_deliver, |
i82559_poll, |
i82559_int_vector |
); |
|
NETDEVTAB_ENTRY(i82559_netdev0, |
"i82559_" CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0_NAME, |
i82559_init, |
&i82559_sc0); |
|
#endif // CYGPKG_DEVS_ETH_XXX_ETH0 |
|
|
|
|
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1 |
|
static I82559 i82559_eth1_priv_data = { |
#ifdef CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_SET_ESA |
hardwired_esa:2, |
mac_address: CYGSEM_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_SET_ESA |
#else |
hardwired_esa: 0, |
#endif |
}; |
|
ETH_DRV_SC(i82559_sc1, |
&i82559_eth1_priv_data, // Driver specific data |
CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_NAME, // Name for device |
i82559_start, |
i82559_stop, |
i82559_ioctl, |
i82559_can_send, |
i82559_send, |
i82559_recv, |
i82559_deliver, |
i82559_poll, |
i82559_int_vector |
); |
|
NETDEVTAB_ENTRY(i82559_netdev1, |
"i82559_" CYGDAT_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1_NAME, |
i82559_init, |
&i82559_sc1); |
|
#endif // CYGPKG_DEVS_ETH_XXX_ETH1 |
|
|
|
|
// These arrays are used for sanity checking of pointers |
I82559 * |
i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0 |
&i82559_eth0_priv_data, |
#endif |
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1 |
&i82559_eth1_priv_data, |
#endif |
}; |
|
#ifdef CYGDBG_USE_ASSERTS |
// These are only used when assertions are enabled |
cyg_netdevtab_entry_t * |
i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0 |
&i82559_netdev0, |
#endif |
|
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1 |
&i82559_netdev1, |
#endif |
|
}; |
|
struct eth_drv_sc * |
i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH0 |
&i82559_sc0, |
#endif |
#ifdef CYGPKG_DEVS_ETH_MIPS_REFIDT334_I82559_ETH1 |
&i82559_sc1, |
#endif |
}; |
#endif |
|
// EOF devs_eth_refidt334.inl |
/idt79s334a/v2_0/ChangeLog
0,0 → 1,39
2003-02-13 Tim Michals <t.michals@attbi.com> |
2003-02-13 Jonathan Larmour <jifl@eCosCentric.com> |
|
* New package - support for MIPS IDT 79s334a board. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |
/malta/v2_0/cdl/mips_mips32_malta_eth_drivers.cdl
0,0 → 1,130
# ==================================================================== |
# |
# malta_eth_drivers.cdl |
# |
# Ethernet drivers - support for AMD PCnet ethernet controller |
# on the MIPS MALTA board. |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): jskov |
# Contributors: jskov |
# Date: 2001-04-02 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA { |
display "MIPS MALTA board ethernet driver" |
description "Ethernet driver for MIPS MALTA board." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_MIPS_MALTA |
|
include_dir cyg/io |
|
# FIXME: This really belongs in the AMD_PCNET package |
cdl_interface CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED { |
display "AMD PCNET ethernet driver required" |
} |
|
define_proc { |
puts $::cdl_system_header "/***** ethernet driver proc output start *****/" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_INL <cyg/io/devs_eth_mips_mips32_malta.inl>" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_CFG <pkgconf/devs_eth_mips_mips32_malta.h>" |
puts $::cdl_system_header "/***** ethernet driver proc output end *****/" |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0 { |
display "MALTA ethernet port 0 driver" |
flavor bool |
default_value 1 |
description " |
This option includes the ethernet device driver for the |
MALTA port 0." |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH0 |
implements CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED |
|
cdl_option CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_RX_RING_SIZE { |
display "Size of RX ring for ETH0" |
flavor data |
default_value 4 |
legal_values { 4 8 16 32 64 128 } |
description " |
This option sets the size of the RX ring." |
} |
|
cdl_option CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_TX_RING_SIZE { |
display "Size of TX ring for ETH0" |
flavor data |
default_value 16 |
legal_values { 4 8 16 32 64 128 } |
description " |
This option sets the size of the TX ring." |
} |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_NAME { |
display "Device name for the ETH0 ethernet port 0 driver" |
flavor data |
default_value {"\"eth0\""} |
description " |
This option sets the name of the ethernet device for the |
MALTA port 0." |
} |
|
cdl_component CYGSEM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
default_value 0 |
description "Enabling this option will allow the ethernet |
station address to be forced to the value set by the |
configuration. This may be required if the hardware does |
not include a serial EEPROM for the ESA." |
|
cdl_option CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"} |
description "The ethernet station address" |
} |
} |
} |
} |
/malta/v2_0/include/devs_eth_mips_mips32_malta.inl
0,0 → 1,109
//========================================================================== |
// |
// devs/eth/mips/malta/include/devs_eth_mips_mips32_malta.inl |
// |
// Malta ethernet I/O definitions. |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): jskov |
// Contributors:jskov |
// Date: 2001-04-02 |
// Purpose: Malta ethernet defintions |
//####DESCRIPTIONEND#### |
//========================================================================== |
|
#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR |
|
#ifdef __WANT_CONFIG |
|
#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_BASE CYGARC_UNCACHED_ADDRESS((cyg_uint32)(&CYGMEM_SECTION_pci_window[0])) |
#define CYGHWR_AMD_PCNET_PCI_MEM_MAP_SIZE ((cyg_uint32)(CYGMEM_SECTION_pci_window_SIZE)) |
|
#endif // __WANT_CONFIG |
|
|
#ifdef __WANT_DEVS |
|
#ifdef CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0 |
|
static pcnet_priv_data amd_pcnet_eth0_priv_data = { |
#ifdef CYGSEM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_SET_ESA |
esa : CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_ESA, |
hardwired_esa : true, |
#else |
hardwired_esa : false, |
#endif |
config_esa : NULL, |
rx_ring : NULL, |
rx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_RX_RING_SIZE*/, |
rx_ring_log_cnt : 2, |
tx_ring : NULL, |
tx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_TX_RING_SIZE*/, |
tx_ring_log_cnt : 2, |
}; |
|
ETH_DRV_SC(amd_pcnet_sc, |
&amd_pcnet_eth0_priv_data, // Driver specific data |
CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_NAME, |
pcnet_start, |
pcnet_stop, |
pcnet_control, |
pcnet_can_send, |
pcnet_send, |
pcnet_recv, |
pcnet_deliver, // "pseudoDSR" called from fast net thread |
pcnet_poll, // poll function, encapsulates ISR and DSR |
pcnet_int_vector); |
|
NETDEVTAB_ENTRY(pcnet_netdev, |
"pcnet_" CYGDAT_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0_NAME, |
amd_pcnet_init, |
&amd_pcnet_sc); |
#endif // CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0 |
|
// These arrays are used for sanity checking of pointers |
struct pcnet_priv_data * |
pcnet_priv_array[CYGNUM_DEVS_ETH_AMD_PCNET_DEV_COUNT] = { |
#ifdef CYGPKG_DEVS_ETH_MIPS_MIPS32_MALTA_ETH0 |
&amd_pcnet_eth0_priv_data, |
#endif |
}; |
|
#endif // __WANT_DEVS |
|
// EOF devs_eth_mips_mips32_malta.inl |
/malta/v2_0/ChangeLog
0,0 → 1,70
2001-07-26 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_mips_mips32_malta.inl: Removed ESA init |
definition again now driver has been fixed. |
|
2001-07-24 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_mips_mips32_malta.inl |
(CYGHWR_AMD_PCNET_BROKEN_ESA_INIT): Defined. |
|
2001-07-18 Jesper Skov <jskov@redhat.com> |
|
* cdl/mips_mips32_malta_eth_drivers.cdl: Default to use eeprom ESA. |
|
2001-07-12 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_mips_mips32_malta.inl: Let driver find base and |
interrupt details. Updated esa options. |
|
2001-06-27 Jesper Skov <jskov@redhat.com> |
|
* cdl/mips_mips32_malta_eth_drivers.cdl: Implements net drivers. |
|
2001-04-23 Mark Salter <msalter@redhat.com> |
|
* include/devs_eth_mips_mips32_malta.inl: Adjust base address to |
match changed PCI allocation base. This should really be gotten |
at runtime from the PCI interface, not from a build time constant. |
|
2001-04-03 Jesper Skov <jskov@redhat.com> |
|
* cdl/mips_mips32_malta_eth_drivers.cdl: Platform specific |
information required to use the generic AMD PCNet driver for the |
Malta platform. |
* include/devs_eth_mips_mips32_malta.inl: Same. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |
/upd985xx/v2_0/cdl/upd985xx_eth_drivers.cdl
0,0 → 1,205
# ==================================================================== |
# |
# upd985xx_eth_drivers.cdl |
# |
# Ethernet drivers |
# NEC uPD985xx device specific support |
# |
# ==================================================================== |
#####ECOSGPLCOPYRIGHTBEGIN#### |
## ------------------------------------------- |
## This file is part of eCos, the Embedded Configurable Operating System. |
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
## |
## eCos is free software; you can redistribute it and/or modify it under |
## the terms of the GNU General Public License as published by the Free |
## Software Foundation; either version 2 or (at your option) any later version. |
## |
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
## WARRANTY; without even the implied warranty of MERCHANTABILITY or |
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
## for more details. |
## |
## You should have received a copy of the GNU General Public License along |
## with eCos; if not, write to the Free Software Foundation, Inc., |
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
## |
## As a special exception, if other files instantiate templates or use macros |
## or inline functions from this file, or you compile this file and link it |
## with other works to produce a work based on this file, this file does not |
## by itself cause the resulting work to be covered by the GNU General Public |
## License. However the source code for this file must still be made available |
## in accordance with section (3) of the GNU General Public License. |
## |
## This exception does not invalidate any other reasons why a work based on |
## this file might be covered by the GNU General Public License. |
## |
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
## at http://sources.redhat.com/ecos/ecos-license/ |
## ------------------------------------------- |
#####ECOSGPLCOPYRIGHTEND#### |
# ==================================================================== |
######DESCRIPTIONBEGIN#### |
# |
# Author(s): hmt |
# Original data: hmt |
# Contributors: gthomas |
# Date: 2001-06-28 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_MIPS_UPD985XX { |
display "NEC uPD985xx ethernet driver" |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_MIPS_UPD985XX |
|
implements CYGHWR_NET_DRIVER_ETH0 |
|
implements CYGHWR_NET_DRIVERS |
include_dir cyg/devs/eth |
|
description "Ethernet driver for NEC uPD985xx devices." |
compile -library=libextras.a if_upd985xx.c |
|
cdl_option CYGDBG_DEVS_ETH_MIPS_UPD985XX_CHATTER { |
display "Prints ethernet device status info during startup" |
default_value 0 |
description " |
The ethernet device initialization code can print lots of info |
to confirm that it has booted correctly." |
} |
|
cdl_option CYGNUM_DEVS_ETH_MIPS_UPD985XX_DEV_COUNT { |
display "Number of supported interfaces." |
#legal_values 1 |
#default_value 1 |
calculated 1 |
flavor data |
description " |
This option selects the number of ethernet interfaces to |
be supported by the driver." |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_UPD985XX_ETH0 { |
display "Ethernet port 0 driver" |
flavor bool |
calculated 1 |
description " |
This option includes the ethernet device driver for |
port 0 - that is the only connector |
depending on your particular hardware." |
|
|
cdl_option CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME { |
display "Device name for the ethernet port 0 driver" |
flavor data |
default_value {"\"eth0\""} |
description " |
This option sets the name of the ethernet device for the |
ethernet port 0." |
} |
|
cdl_component CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
default_value false |
requires !CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA |
description "Enabling this option will allow the ethernet |
station address to be forced to the value set by the |
configuration. This may be required if the hardware does |
not include a serial EEPROM for the ESA." |
|
cdl_option CYGDAT_DEVS_ETH_UPD985XX_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x00, 0xBA, 0xCA, 0xDD, 0x1E, 0xDD}"} |
description "The ethernet station address" |
} |
} |
|
cdl_option CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA { |
display "Get the ethernet station address from EEPROM" |
flavor bool |
default_value !CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA |
requires !CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA |
description "Enabling this option will allow the ethernet |
station address to be read from a serial EEPROM (such as 93C06, |
93C46...). If this is not valid, your application must set the |
ESA manually via an ioctl() call or similar." |
} |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_UPD985XX_OPTIONS { |
display "NEC uPD985xx ethernet driver build options" |
flavor none |
no_define |
|
cdl_option CYGPKG_DEVS_ETH_MIPS_UPD985XX_CFLAGS_ADD { |
display "Additional compiler flags" |
flavor data |
no_define |
default_value { "-D_KERNEL -D__ECOS" } |
description " |
This option modifies the set of compiler flags for |
building the NEC uPD985xx ethernet driver |
package. These flags are used in addition to the set of |
global flags." |
} |
} |
|
cdl_component CYGPKG_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS { |
display "Workarounds for Ethernet Hardware bugs " |
flavor bool |
default_value 1 |
description " |
This component controls whether code workarounds for the numerous |
hardware bugs in the uPD98503 Ethernet device are included. |
These might not all be necessary depending on the speed and mode in |
which the interface is used. Please refer to the manufacturer's |
Behaviour Analysis Report to make your decision about which of |
these options to enable or disable. |
The default is to enable all workarounds for best reliability." |
|
cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_S1 { |
display "S1 - CPU to IBUS write restriction" |
flavor bool |
default_value 1 |
description "Enable a workaround for hardware bug S1" |
} |
cdl_component CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 { |
display "E1,E2 - Status queue corruption and MAC filtering" |
flavor bool |
default_value 1 |
description "Enable a workaround for hardware bugs E1 and/or E2." |
|
cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY { |
display "Do not set device in promisc mode - solve E2 only" |
flavor bool |
default_value 1 |
description "Work around bug E2 only - do not set the device |
in promiscuous mode by default. |
Setting this option prevents the work around |
for bug E1." |
} |
} |
cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3 { |
display "E3 - Transmit descriptor error" |
flavor bool |
default_value 1 |
description "Enable a workaround for hardware bug E3" |
|
} |
cdl_option CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E8 { |
display "E8 - Transmission error under abnormal conditions" |
flavor bool |
default_value 1 |
description "Enable a workaround for hardware bug E8" |
} |
} |
} |
|
# EOF upd985xx_eth_drivers.cdl |
/upd985xx/v2_0/include/upd985xx_eth.h
0,0 → 1,465
#ifndef CYGONCE_HAL_UPD985XX_ETH_H |
#define CYGONCE_HAL_UPD985XX_ETH_H |
//========================================================================== |
// |
// upd985xx_eth.h |
// |
// Architecture specific abstractions for the on-chip ethernet |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): hmt, nickg |
// Contributors: nickg |
// Date: 2001-06-28 |
// Purpose: Define architecture abstractions |
// Description: This file contains any extra or modified definitions for |
// this variant of the architecture's ethernet controller. |
// Usage: #include <cyg/io/upd985xx_eth.h> |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <cyg/hal/var_arch.h> |
|
// -------------------------------------------------------------------------- |
// By default we use the definition of UPD985XX_SYSETH_REG( n ) from |
// var_arch.h - if we port to a KORVA with multiple ethernet controllers we |
// will have to vary this to account for the different base addresses. |
|
// (the noise at the end of these lines is the default value) |
// |
// Table 5-2. MAC Control Register Map |
// |
#define ETH_MACC1 UPD985XX_SYSETH_REG( 0x000) // MAC configuration register 1 R/W 0000_0000H |
#define ETH_MACC2 UPD985XX_SYSETH_REG( 0x004) // MAC configuration register 2 R/W 0000_0000H |
#define ETH_IPGT UPD985XX_SYSETH_REG( 0x008) // Back-to-Back IPG register R/W 0000_0013H |
#define ETH_IPGR UPD985XX_SYSETH_REG( 0x00C) // Non Back-to-Back IPG register R/W 0000_0E13H |
#define ETH_CLRT UPD985XX_SYSETH_REG( 0x010) // Collision register R/W 0000_370FH |
#define ETH_LMAX UPD985XX_SYSETH_REG( 0x014) // Max packet length register R/W 0000_0600H |
// N/A UPD985XX_SYSETH_REG( 0x018) // Reserved for future use - - |
#define ETH_RETX UPD985XX_SYSETH_REG( 0x020) // Retry count register R/W 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x024) // Reserved for future use - - |
#define ETH_LSA2 UPD985XX_SYSETH_REG( 0x054) // Station Address register 2 R/W 0000_0000H |
#define ETH_LSA1 UPD985XX_SYSETH_REG( 0x058) // Station Address register 1 R/W 0000_0000H |
#define ETH_PTVR UPD985XX_SYSETH_REG( 0x05C) // Pause timer value read register R 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x060) // Reserved for future use - - |
#define ETH_VLTP UPD985XX_SYSETH_REG( 0x064) // VLAN type register R/W 0000_0000H |
#define ETH_MIIC UPD985XX_SYSETH_REG( 0x080) // MII configuration register R/W 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x084) // Reserved for future use - - |
#define ETH_MCMD UPD985XX_SYSETH_REG( 0x094) // MII command register W 0000_0000H |
#define ETH_MADR UPD985XX_SYSETH_REG( 0x098) // MII address register R/W 0000_0000H |
#define ETH_MWTD UPD985XX_SYSETH_REG( 0x09C) // MII write data register R/W 0000_0000H |
#define ETH_MRDD UPD985XX_SYSETH_REG( 0x0A0) // MII read data register R 0000_0000H |
#define ETH_MIND UPD985XX_SYSETH_REG( 0x0A4) // MII indicator register R 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x0A8) // Reserved for future use - - |
#define ETH_AFR UPD985XX_SYSETH_REG( 0x0C8) // Address Filtering register R/W 0000_0000H |
#define ETH_HT1 UPD985XX_SYSETH_REG( 0x0CC) // Hash table register 1 R/W 0000_0000H |
#define ETH_HT2 UPD985XX_SYSETH_REG( 0x0D0) // Hash table register 2 R/W 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x0D4) // Reserved for future use - - |
#define ETH_CAR1 UPD985XX_SYSETH_REG( 0x0DC) // Carry register 1 R/W 0000_0000H |
#define ETH_CAR2 UPD985XX_SYSETH_REG( 0x0E0) // Carry register 2 R/W 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x0E4) // Reserved for future use - - |
#define ETH_CAM1 UPD985XX_SYSETH_REG( 0x130) // Carry mask register 1 R/W 0000_0000H |
#define ETH_CAM2 UPD985XX_SYSETH_REG( 0x134) // Carry mask register 2 R/W 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x138) // Reserved for future use - - |
// |
// Table 5-3. Statistics Counter Register Map |
// |
#define ETH_RBYT UPD985XX_SYSETH_REG( 0x140) // Receive Byte Counter R/W |
#define ETH_RPKT UPD985XX_SYSETH_REG( 0x144) // Receive Packet Counter R/W |
#define ETH_RFCS UPD985XX_SYSETH_REG( 0x148) // Receive FCS Error Counter R/W |
#define ETH_RMCA UPD985XX_SYSETH_REG( 0x14C) // Receive Multicast Packet Counter R/W |
#define ETH_RBCA UPD985XX_SYSETH_REG( 0x150) // Receive Broadcast Packet Counter R/W |
#define ETH_RXCF UPD985XX_SYSETH_REG( 0x154) // Receive Control Frame Packet Counter R/W |
#define ETH_RXPF UPD985XX_SYSETH_REG( 0x158) // Receive PAUSE Frame Packet Counter R/W |
#define ETH_RXUO UPD985XX_SYSETH_REG( 0x15C) // Receive Unknown OP code Counter R/W |
#define ETH_RALN UPD985XX_SYSETH_REG( 0x160) // Receive Alignment Error Counter R/W |
#define ETH_RFLR UPD985XX_SYSETH_REG( 0x164) // Receive Frame Length Out of Range Counter R/W |
#define ETH_RCDE UPD985XX_SYSETH_REG( 0x168) // Receive Code Error Counter R/W |
#define ETH_RFCR UPD985XX_SYSETH_REG( 0x16C) // Receive False Carrier Counter R/W |
#define ETH_RUND UPD985XX_SYSETH_REG( 0x170) // Receive Undersize Packet Counter R/W |
#define ETH_ROVR UPD985XX_SYSETH_REG( 0x174) // Receive Oversize Packet Counter R/W |
#define ETH_RFRG UPD985XX_SYSETH_REG( 0x178) // Receive Error Undersize Packet Counter R/W |
#define ETH_RJBR UPD985XX_SYSETH_REG( 0x17C) // Receive Error Oversize Packet Counter R/W |
#define ETH_R64 UPD985XX_SYSETH_REG( 0x180) // Receive 64 Byte Frame Counter R/W |
#define ETH_R127 UPD985XX_SYSETH_REG( 0x184) // Receive 65 to 127 Byte Frame Counter R/W |
#define ETH_R255 UPD985XX_SYSETH_REG( 0x188) // Receive 128 to 255 Byte Frame Counter R/W |
#define ETH_R511 UPD985XX_SYSETH_REG( 0x18C) // Receive 256 to 511 Byte Frame Counter R/W |
#define ETH_R1K UPD985XX_SYSETH_REG( 0x190) // Receive 512 to 1023 Byte Frame Counter R/W |
#define ETH_RMAX UPD985XX_SYSETH_REG( 0x194) // Receive Over 1023 Byte Frame Counter R/W |
#define ETH_RVBT UPD985XX_SYSETH_REG( 0x198) // Receive Valid Byte Counter R/W |
#define ETH_TBYT UPD985XX_SYSETH_REG( 0x1C0) // Transmit Byte Counter R/W |
#define ETH_TPCT UPD985XX_SYSETH_REG( 0x1C4) // Transmit Packet Counter R/W |
#define ETH_TFCS UPD985XX_SYSETH_REG( 0x1C8) // Transmit CRC Error Packet Counter R/W |
#define ETH_TMCA UPD985XX_SYSETH_REG( 0x1CC) // Transmit Multicast Packet Counter R/W |
#define ETH_TBCA UPD985XX_SYSETH_REG( 0x1D0) // Transmit Broadcast Packet Counter R/W |
#define ETH_TUCA UPD985XX_SYSETH_REG( 0x1D4) // Transmit Unicast Packet Counter R/W |
#define ETH_TXPF UPD985XX_SYSETH_REG( 0x1D8) // Transmit PAUSE control Frame Counter R/W |
#define ETH_TDFR UPD985XX_SYSETH_REG( 0x1DC) // Transmit Single Deferral Packet Counter R/W |
#define ETH_TXDF UPD985XX_SYSETH_REG( 0x1E0) // Transmit Excessive Deferral Packet Counter R/W |
#define ETH_TSCL UPD985XX_SYSETH_REG( 0x1E4) // Transmit Single Collision Packet Counter R/W |
#define ETH_TMCL UPD985XX_SYSETH_REG( 0x1E8) // Transmit Multiple collision Packet Counter R/W |
#define ETH_TLCL UPD985XX_SYSETH_REG( 0x1EC) // Transmit Late Collision Packet Counter R/W |
#define ETH_TXCL UPD985XX_SYSETH_REG( 0x1F0) // Transmit Excessive Collision Packet Counter R/W |
#define ETH_TNCL UPD985XX_SYSETH_REG( 0x1F4) // Transmit Total Collision Counter R/W |
#define ETH_TCSE UPD985XX_SYSETH_REG( 0x1F8) // Transmit Carrier Sense Error Counter R/W |
#define ETH_TIME UPD985XX_SYSETH_REG( 0x1FC) // Transmit Internal MAC Error Counter R/W |
// |
// Table 5-4. DMA and FIFO Management Registers Map |
// |
#define ETH_TXCR UPD985XX_SYSETH_REG( 0x200) // Transmit Configuration Register R/W 0000_0000H |
#define ETH_TXFCR UPD985XX_SYSETH_REG( 0x204) // Transmit FIFO Control Register R/W FFFF_40C0H |
#define ETH_TXDTR UPD985XX_SYSETH_REG( 0x208) // Transmit Data Register W 0000_0000H |
#define ETH_TXSR UPD985XX_SYSETH_REG( 0x20C) // Transmit Status Register R 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x210) // Reserved for future use - - |
#define ETH_TXDPR UPD985XX_SYSETH_REG( 0x214) // Transmit Descriptor Pointer R/W 0000_0000H |
#define ETH_RXCR UPD985XX_SYSETH_REG( 0x218) // Receive Configuration Register R/W 0000_0000H |
#define ETH_RXFCR UPD985XX_SYSETH_REG( 0x21C) // Receive FIFO Control Register R/W C040_0040H |
#define ETH_RXDTR UPD985XX_SYSETH_REG( 0x220) // Receive Data Register R 0000_0000H |
#define ETH_RXSR UPD985XX_SYSETH_REG( 0x224) // Receive Status Register R 0000_0000H |
// N/A UPD985XX_SYSETH_REG( 0x228) // Reserved for future use - - |
#define ETH_RXDPR UPD985XX_SYSETH_REG( 0x22C) // Receive Descriptor Pointer R/W 0000_0000H |
#define ETH_RXPDR UPD985XX_SYSETH_REG( 0x230) // Receive Pool Descriptor Register R/W 0000_0000H |
// |
// Table 5-5. Interrupt and Configuration Registers Map |
// |
#define ETH_CCR UPD985XX_SYSETH_REG( 0x234) // Configuration Register R/W 0000_0000H |
#define ETH_ISR UPD985XX_SYSETH_REG( 0x238) // Interrupt Service Register R 0000_0000H |
#define ETH_MSR UPD985XX_SYSETH_REG( 0x23C) // Mask Serves Register R/W 0000_0000H |
|
// -------------------------------------------------------------------------- |
// Now the fields within all those registers... |
// |
// Table 5-2. MAC Control Register Map |
// |
// ETH_MACC1 0x000 MAC configuration register 1 R/W 0000_0000H |
#define ETH_MACC1_MACLB (1<<14) // MAC loopback: 0 |
#define ETH_MACC1_TXFC (1<<11) // Transmit flow control enable: 0 |
#define ETH_MACC1_RXFC (1<<10) // Receive flow control enable: 0 |
#define ETH_MACC1_SRXEN (1<< 9) // Receive enable: 0 |
#define ETH_MACC1_PARF (1<< 8) // Control packet pass: 0 |
#define ETH_MACC1_PUREP (1<< 7) // Pure preamble: 0 |
#define ETH_MACC1_FLCHT (1<< 6) // Length field check: 0 |
#define ETH_MACC1_NOBO (1<< 5) // No Back Off: 0 |
#define ETH_MACC1_CRCEN (1<< 3) // CRC append enable: 0 |
#define ETH_MACC1_PADEN (1<< 2) // PAD append enable: 0 |
#define ETH_MACC1_FDX (1<< 1) // Full duplex enable: 0 |
#define ETH_MACC1_HUGEN (1<< 0) // Large packet enable: 0 |
// ETH_MACC2 0x004 MAC configuration register 2 R/W 0000_0000H |
#define ETH_MACC2_MCRST (1<<10) // MAC Control Block software reset: 0 |
#define ETH_MACC2_RFRST (1<< 9) // Receive Function Block software reset: 0 |
#define ETH_MACC2_TFRST (1<< 8) // Transmit Function Block software reset: 0 |
#define ETH_MACC2_BPNB (1<< 6) // Back Pressure No Back Off: 0 |
#define ETH_MACC2_APD (1<< 5) // Auto VLAN PAD: 0 |
#define ETH_MACC2_VPD (1<< 4) // VLAN PAD mode: 0 |
|
// ETH_IPGT 0x008 Back-to-Back IPG register R/W 0000_0013H |
// ETH_IPGR 0x00C Non Back-to-Back IPG register R/W 0000_0E13H |
// ETH_CLRT 0x010 Collision register R/W 0000_370FH |
// ETH_LMAX 0x014 Max packet length register R/W 0000_0600H |
// N/A 0x018 Reserved for future use - - |
// ETH_RETX 0x020 Retry count register R/W 0000_0000H |
// N/A 0x024 Reserved for future use - - |
// ETH_LSA2 0x054 Station Address register 2 R/W 0000_0000H |
// ETH_LSA1 0x058 Station Address register 1 R/W 0000_0000H |
// ETH_PTVR 0x05C Pause timer value read register R 0000_0000H |
// N/A 0x060 Reserved for future use - - |
// ETH_VLTP 0x064 VLAN type register R/W 0000_0000H |
#define ETH_VLTP_VLTP (0x00008100) // magic number from example |
// ETH_MIIC 0x080 MII configuration register R/W 0000_0000H |
#define ETH_MIIC_MIRST (1<<15) // MII Management Interface Block software reset |
#define ETH_MIIC_CLKS (0x0C) // 3:2 CLKS Select frequency range: |
#define ETH_MIIC_25 (0x00) // 00: HCLK is equal to 25 MHz |
#define ETH_MIIC_33 (0x04) // 01: HCLK is less than or equal to 33 MHz |
#define ETH_MIIC_50 (0x08) // 10: HCLK is less than or equal to 50 MHz |
#define ETH_MIIC_66 (0x0C) // 11: HCLK is less than or equal to 66 MHz |
// ETH_MCMD 0x094 MII command register W 0000_0000H |
#define ETH_MCMD_SCANC (1<< 1) // SCAN command: 0 |
#define ETH_MCMD_RSTAT (1<< 0) // MII management read: 0 |
// ETH_MADR 0x098 MII address register R/W 0000_0000H |
#define ETH_MADR_PHY_ADDR_SHIFT (8) |
// ETH_MWTD 0x09C MII write data register R/W 0000_0000H |
// ETH_MRDD 0x0A0 MII read data register R 0000_0000H |
// ETH_MIND 0x0A4 MII indicator register R 0000_0000H |
#define ETH_MIND_NVALID (1<< 2) // SCAN command start status: 0 |
#define ETH_MIND_SCANA (1<< 1) // SCAN command active: 0 |
#define ETH_MIND_BUSY (1<< 0) // BUSY: 0 |
// ETH_AFR 0x0C8 Address Filtering register R/W 0000_0000H |
#define ETH_AFR_PRO (1<< 3) // Promiscuous mode: 0 |
#define ETH_AFR_PRM (1<< 2) // Accept Multicast: 0 |
#define ETH_AFR_AMC (1<< 1) // Accept Multicast ( qualified ): 0 |
#define ETH_AFR_ABC (1<< 0) // Accept Broadcast: 0 |
// ETH_HT1 0x0CC Hash table register 1 R/W 0000_0000H |
// ETH_HT2 0x0D0 Hash table register 2 R/W 0000_0000H |
// ETH_CAR1 0x0DC Carry register 1 R/W 0000_0000H |
// ETH_CAR2 0x0E0 Carry register 2 R/W 0000_0000H |
// ETH_CAM1 0x130 Carry mask register 1 R/W 0000_0000H |
// ETH_CAM2 0x134 Carry mask register 2 R/W 0000_0000H |
// |
// Table 5-3. Statistics Counter Register Map |
// <snip> |
// |
// Table 5-4. DMA and FIFO Management Registers Map |
// |
// ETH_TXCR 0x200 Transmit Configuration Register R/W 0000_0000H |
#define ETH_TXCR_TXE (1<<31) // Transmit Enable: |
#define ETH_TXCR_DTBS_SHIFT (16) // 18:16 DMA Transmit Burst Size: |
#define ETH_TXCR_DTBS (0x70000) // 18:16 DMA Transmit Burst Size: |
#define ETH_TXCR_DTBS_1 (0x00000) // 000: 1 Word (4 bytes) |
#define ETH_TXCR_DTBS_2 (0x10000) // 001: 2 Word (8 bytes) |
#define ETH_TXCR_DTBS_4 (0x20000) // 010: 4 Word (16 bytes) |
#define ETH_TXCR_DTBS_8 (0x30000) // 011: 8 Word (32 bytes) |
#define ETH_TXCR_DTBS_16 (0x40000) // 100: 16 Word (64 bytes) |
#define ETH_TXCR_DTBS_32 (0x50000) // 101: 32 Word (128 bytes) |
#define ETH_TXCR_DTBS_64 (0x60000) // 110: 64 Word (256 bytes) |
#define ETH_TXCR_AFCE (1<< 0) // Auto Flow Control Enable: |
// ETH_TXFCR 0x204 Transmit FIFO Control Register R/W FFFF_40C0H |
#define ETH_TXFCR_TPTV_SHIFT (16) // 31:16 Transmit Pause Timer Value: FFFFH |
#define ETH_TXFCR_TPTV (0xffff0000) // 31:16 Transmit Pause Timer Value: FFFFH |
#define ETH_TXFCR_TX_DRTH_SHIFT (10) // 15:10 Transmit Drain Threshold Level: 10H |
#define ETH_TXFCR_TX_DRTH (0x0000fc00) // 15:10 Transmit Drain Threshold Level: 10H |
#define ETH_TXFCR_TX_FLTH_SHIFT (2) // 7:2 Transmit Fill Threshold Level: 03H |
#define ETH_TXFCR_TX_FLTH (0x000000fc) // 7:2 Transmit Fill Threshold Level: 03H |
#define ETH_TXFCR_TPTV_DEFAULT (0x10000000) // default 0x1000 slot time (1slot:512bit) |
#define ETH_TXFCR_TX_DRTH_DEFAULT (0x00002000) // 001000b (8long, 32byte) |
#define ETH_TXFCR_TX_FLTH_DEFAULT (0x000000c0) // default 110000b (48word, 192byte) |
// ETH_TXDTR 0x208 Transmit Data Register W 0000_0000H |
// ETH_TXSR 0x20C Transmit Status Register R 0000_0000H |
#define ETH_TXSR_CSE (1<<31) // Carrier lost was detected during the transmission 0 |
#define ETH_TXSR_TBP (1<<30) // Back pressure occurred when the packet was received 0 |
#define ETH_TXSR_TPP (1<<29) // A packet request during the PAUSE operation was transmitted 0 |
#define ETH_TXSR_TPCF (1<<28) // A PAUSE control frame was transmitted 0 |
#define ETH_TXSR_TCFR (1<<27) // A control frame was transmitted 0 |
#define ETH_TXSR_TUDR (1<<26) // The TPUR pin was set high and aborted. Note 2 0 |
#define ETH_TXSR_TGNT (1<<25) // A huge packet was transmitted and aborted. 0 |
#define ETH_TXSR_LCOL (1<<24) // Collision occurred |
#define ETH_TXSR_ECOL (1<<23) // Excess collisions |
#define ETH_TXSR_TEDFR (1<<22) // Excess deferred |
#define ETH_TXSR_TDFR (1<<21) // Transmission deferral occurred |
#define ETH_TXSR_TBRO (1<<20) // A broadcast packet was transmitted. 0 |
#define ETH_TXSR_TMUL (1<<19) // A multicast packet was transmitted. 0 |
#define ETH_TXSR_TDONE (1<<18) // Transmission was completed. 0 |
#define ETH_TXSR_TFLOR (1<<17) // Value of the length field was huge |
#define ETH_TXSR_TFLER (1<<16) // Value of the length field didn~t match the actual data count |
#define ETH_TXSR_TCRCE (1<<15) // Attached CRC didn~t match the internal generated CRC |
|
#define ETH_TXSR_TCBC_SHIFT (11) // 14:11 collisions for the previous transmission |
#define ETH_TXSR_TCBC (0x7800) // 14:11 collisions for the previous transmission |
#define ETH_TXSR_TBYT_SHIFT (0) // 10:0 transmitted bytes not including collided bytes |
#define ETH_TXSR_TBYT (0x07FF) // 10:0 transmitted bytes not including collided bytes |
|
// ETH_RXCR UPD985XX_SYSETH_REG( 0x218) // Receive Configuration Register R/W 0000_0000H |
#define ETH_RXCR_RXE (1<<31) // Receive Enable: |
#define ETH_RXCR_DRBS_SHIFT (16) // 18:16 DRBS DMA Transmit Burst Size: 0 |
#define ETH_RXCR_DRBS (0x70000) // |
#define ETH_RXCR_DRBS_1 (0x00000) // 000: 1 Word (4 bytes) |
#define ETH_RXCR_DRBS_2 (0x10000) // 001: 2 Word (8 bytes) |
#define ETH_RXCR_DRBS_4 (0x20000) // 010: 4 Word (16 bytes) |
#define ETH_RXCR_DRBS_8 (0x30000) // 011: 8 Word (32 bytes) |
#define ETH_RXCR_DRBS_16 (0x40000) // 100: 16 Word (64 bytes) |
#define ETH_RXCR_DRBS_32 (0x50000) // 101: 32 Word (128 bytes) |
#define ETH_RXCR_DRBS_64 (0x60000) // 110: 64 Word (256 bytes) |
|
// ETH_RXFCR 0x21C Receive FIFO Control Register R/W C040_0040H |
#define ETH_RXFCR_UWM (0xfc000000) // 31:26 Upper Water Mark: 30H |
#define ETH_RXFCR_UWM_SHIFT (26) // 31:26 Upper Water Mark: 30H |
#define ETH_RXFCR_LWM (0x00fc0000) // 23:18 Lower Water Mark: 10H |
#define ETH_RXFCR_LWM_SHIFT (18) // 23:18 Lower Water Mark: 10H |
#define ETH_RXFCR_RX_DRTH (0x000000fc) // 7: 2 Receive Drain Threshold Level 10H |
#define ETH_RXFCR_RX_DRTH_SHIFT (2) // 7: 2 Receive Drain Threshold Level 10H |
#define ETH_RXFCR_UWM_DEFAULT (0xE0000000) // default 110000b ( 48word, 192byte ) |
#define ETH_RXFCR_LWM_DEFAULT (0x00400000) // default 010000b (16word, 64byte) |
#define ETH_RXFCR_DRTH16W (0x00000040) // default 010000b (16word, 64byte) |
|
// ETH_RXDTR 0x220 Receive Data Register R 0000_0000H |
// ETH_RXSR 0x224 Receive Status Register R 0000_0000H |
#define ETH_RXSR_RLENE (1<<31) // A toosmall or toolarge packet was received. |
#define ETH_RXSR_VLAN (1<<30) // A VLAN was received. |
#define ETH_RXSR_USOP (1<<29) // A control frame containing an unknown OP code was received. |
#define ETH_RXSR_PRCF (1<<28) // A control frame containing the PAUSE OP code was received. |
#define ETH_RXSR_RCFR (1<<27) // A control frame was received. |
#define ETH_RXSR_DBNB (1<<26) // An alignment error occurred. |
#define ETH_RXSR_RBRO (1<<25) // A broadcast packet was received. 0 |
#define ETH_RXSR_RMUL (1<<24) // A multicast packet was received. 0 |
#define ETH_RXSR_RXOK (1<<23) // A good packet was received. |
#define ETH_RXSR_RLOR (1<<22) // The value of the length field was huge |
#define ETH_RXSR_RLER (1<<21) // The value of the length field didn~t match |
#define ETH_RXSR_RCRCE (1<<20) // A CRC error occurred. 0 |
#define ETH_RXSR_RCV (1<<19) // RXER was detected. 0 |
#define ETH_RXSR_CEPS (1<<18) // A False Carrier was detected. 0 |
#define ETH_RXSR_REPS (1<<17) // A packet which had a preamble and SFD only or one data nibble |
#define ETH_RXSR_PAIG (1<<16) // |
#define ETH_RXSR_RBYT (0xffff) // 15:0 The received byte count 0 |
#define ETH_RXSR_RBYT_SHIFT (0) // 15:0 The received byte count 0 |
// ETH_RXDPR 0x22C Receive Descriptor Register R/W 0000_0000H |
// ETH_RXPDR 0x230 Receive Pool Descriptor Register R/W 0000_0000H |
#define ETH_RXPDR_AL (0x70000000) // 30:28 AL[2:0] Alert Level 0H |
#define ETH_RXPDR_AL_SHIFT (28) |
#define ETH_RXPDR_RNOD (0xffff) // 15:0 Remaining Number of Descriptor 0H |
#define ETH_RXPDR_RNOD_SHIFT (0) |
// |
// Table 5-5. Interrupt and Configuration Registers Map |
// |
// ETH_CCR 0x234 Configuration Register R/W 0000_0000H |
#define ETH_CCR_SRT (1) // Software Reset (cleared automatically to '0') |
// ETH_ISR 0x238 Interrupt Service Register R 0000_0000H |
#define ETH_ISR_XMTDN (1<<15) // Transmit Done |
#define ETH_ISR_TBDR (1<<14) // Transmit Buffer Descriptor Request at Null |
#define ETH_ISR_TFLE (1<<13) // Transmit Frame Length Exceed |
#define ETH_ISR_UR (1<<12) // Underrun |
#define ETH_ISR_TABR (1<<11) // Transmit Aborted |
#define ETH_ISR_TCFRI (1<<10) // Control Frame Transmit |
#define ETH_ISR_RCVDN (1<<7 ) // Receive Done |
#define ETH_ISR_RBDRS (1<<6 ) // Receive Buffer Descriptor Request at alert level |
#define ETH_ISR_RBDRU (1<<5 ) // Receive Buffer Descriptor Request at zero |
#define ETH_ISR_OF (1<<4 ) // Overflow |
#define ETH_ISR_LFAL (1<<3 ) // Link Failed |
#define ETH_ISR_CARRY (1<<0 ) // Carry Flag: |
// ETH_MSR 0x23C Mask Serves Register R/W 0000_0000H |
// As above |
|
// -------------------------------------------------------------------------- |
// And the "buffer descriptor" control structures in RAM... |
|
|
#define ETH_BUF_LAST (1<<31) // Last Descriptor |
#define ETH_BUF_D_L (1<<30) // Data Buffer / Link Pointer |
#define ETH_BUF_D_L_DATA (1<<30) // Data Buffer / Link Pointer |
#define ETH_BUF_D_L_LINK (0<<30) // Data Buffer / Link Pointer |
#define ETH_BUF_OWN (1<<29) // Owner 1:Ethernet Controller 0: VR4120A |
#define ETH_BUF_OWN_ETH (1<<29) |
#define ETH_BUF_OWN_CPU (0<<29) |
|
#define ETH_BUF_DBRWE (1<<28) // Buffer Access Error |
#define ETH_BUF_OK (1<<16) // Tx or Rx OK |
#define ETH_BUF_SIZE (0xffff) // Byte Count |
|
#define ETH_BUF_TX_TUDR (1<<27) // Transmit Underrun Error |
#define ETH_BUF_TX_CSE (1<<26) // Carrier Sense Lost Error |
#define ETH_BUF_TX_LCOL (1<<25) // Late Collision |
#define ETH_BUF_TX_ECOL (1<<24) // Excessive Collision |
#define ETH_BUF_TX_EDFR (1<<23) // Excessive Deferral |
#define ETH_BUF_TX_TGNT (1<<18) // Transmit Giant Frame |
#define ETH_BUF_TX_HBF (1<<17) // Heart Beat Fail for ENDEC mode |
|
#define ETH_BUF_RX_OVRN (1<<24) // Overrun Error |
#define ETH_BUF_RX_RUNT (1<<23) // Runt packet |
#define ETH_BUF_RX_FRGE (1<<22) // Fragment Error |
#define ETH_BUF_RX_RCV (1<<21) // Detects RXER |
#define ETH_BUF_RX_FC (1<<20) // False Carrier |
#define ETH_BUF_RX_CRCE (1<<19) // CRC Error |
#define ETH_BUF_RX_FAE (1<<18) // Frame Alignment Error |
#define ETH_BUF_RX_RFLE (1<<17) // Receive Frame Length Error |
|
#define ETH_BUF_RX_FTYP (0x0e000000) // 27:25 Frame Type[2:0] |
#define ETH_BUF_RX_FTYP_SHIFT (25) // 27:25 Frame Type[2:0] |
// I don't think we need to know these... |
// 000 Broadcast Frame |
// 001 Multicast Frame |
// 010 Unicast Frame |
// 011 VLAN Frame |
// 100 PAUSE control frame |
// 101 Control Frame (except pause) |
// 11x Reserved for future use |
|
|
// -------------------------------------------------------------------------- |
// MII stuff for talking to the separate PHY |
// Initially this was a SEEQ NQ80225 but now it is a LU3X31T-T64. |
|
//#define SEEQ_DEVICE_PHYS_ADDRESS (1) // this from the board documentation |
#define LU3X31T_DEVICE_PHYS_ADDRESS (2) |
|
#define ETH_MADR_PHY_DEVICE_PHYS_ADDRESS \ |
(LU3X31T_DEVICE_PHYS_ADDRESS << ETH_MADR_PHY_ADDR_SHIFT) |
|
// I don't know how much they have in common, but I think MII is pretty |
// standard, and the "mandated" registers ought to be common. |
|
#define PHY_CONTROL_REG (0) |
#define PHY_STATUS_REG (1) |
#define PHY_ID_ONE (2) |
#define PHY_ID_TWO (3) |
#define PHY_AUTONEG_ADVERT (4) |
#define PHY_AUTONEG_REMOTE (5) |
#define PHY_STATUS_DETECT_REG (18) |
|
#define PHY_CONTROL_RESET (1<<15) |
#define PHY_CONTROL_LOOPBACK (1<<14) |
#define PHY_CONTROL_SPEED100 (1<<13) |
#define PHY_CONTROL_AUTONEG_EN (1<<12) |
#define PHY_CONTROL_POWERDOWN (1<<11) |
#define PHY_CONTROL_MII_DIS (1<<10) |
#define PHY_CONTROL_AUTONEG_RST (1<< 9) |
#define PHY_CONTROL_DPLX_FULL (1<< 8) |
#define PHY_CONTROL_COLLTEST (1<< 7) |
|
#define PHY_STATUS_CAP_T4 (1<<15) |
#define PHY_STATUS_CAP_100TXF (1<<14) |
#define PHY_STATUS_CAP_100TXH (1<<13) |
#define PHY_STATUS_CAP_10TF (1<<12) |
#define PHY_STATUS_CAP_10TH (1<<11) |
#define PHY_STATUS_CAP_SUPR (1<< 6) |
#define PHY_STATUS_AUTONEG_ACK (1<< 5) |
#define PHY_STATUS_REMOTEFAULT (1<< 4) |
#define PHY_STATUS_CAP_AUTONEG (1<< 3) |
#define PHY_STATUS_LINK_OK (1<< 2) |
#define PHY_STATUS_JABBER (1<< 1) |
#define PHY_STATUS_EXTREGS (1<< 0) |
|
// These are the same for both AUTONEG registers |
#define PHY_AUTONEG_NEXT (1<<15) |
#define PHY_AUTONEG_ACK (1<<14) |
#define PHY_AUTONEG_REMOTEFAULT (1<<13) |
#define PHY_AUTONEG_100BASET4 (1<< 9) |
#define PHY_AUTONEG_100BASETX_FDX (1<< 8) |
#define PHY_AUTONEG_100BASETX_HDX (1<< 7) |
#define PHY_AUTONEG_10BASET_FDX (1<< 6) |
#define PHY_AUTONEG_10BASET_HDX (1<< 5) |
#define PHY_AUTONEG_CSMA_802_3 (1<< 0) |
|
#if 0 |
// Others are undocumented |
#define PHY_STATUS_DETECT_SPEED100 (1<< 7) |
#define PHY_STATUS_DETECT_DPLX_FULL (1<< 6) |
#endif |
|
// Phew! |
// -------------------------------------------------------------------------- |
#endif // CYGONCE_HAL_UPD985XX_ETH_H |
// End of upd985xx_eth.h |
/upd985xx/v2_0/ChangeLog
0,0 → 1,265
2002-06-14 Gary Thomas <gary@chez-thomas.org> |
|
* src/if_upd985xx.c: |
Need to include <pkgconf/io_eth_drivers.h> for proper configuration |
of stand-alone (polled) vs. system (interrupt driven) mode. |
|
2001-09-13 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (upd985xx_eth_upd985xx_init): Fake an ESA if |
we see all ones from the EEPROM as well as all zeros. |
|
2001-08-30 Hugo Tyson <hmt@redhat.com> |
|
* cdl/upd985xx_eth_drivers.cdl: Make the "..._E2ONLY" workaround |
option on by default since this is how it will be used - the CPU |
load does suffer somewhat if promisc mode is set in the hardware. |
This should be unset to allow the workaround for E1 at 100Mbit. |
|
2001-08-30 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (PacketRxReady): Re-write the manual |
implementation of ESA matching for workaround E1E2 when the device |
is in promiscuous mode. It was having problems with the previous |
version; this works better. |
|
2001-08-24 Hugo Tyson <hmt@redhat.com> |
|
* cdl/upd985xx_eth_drivers.cdl: Configury for an alternate case |
where we workaround hardware bug E2 only, as a subset of the E1E2 |
complete fix. Added more description to the options too. |
|
* src/if_upd985xx.c (eth_upd985xx_configure): Handle an alternate |
case where we workaround hardware bug E2 only. This means leaving |
the device in normal mode (unless set to promisc) and doing MAC |
address filtering by hand anyway. |
|
2001-08-20 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c: Guard all entrypoints that can mess with |
hardware state by "active" check. If the net is included in an |
app, but not used, it is init'd but not started - this can leave a |
pending interrupt from RedBoot's use of the network to take us |
completely by surprise. So init() acks and masks the interrupt, |
can_send(), recv() and deliver() now demur if not active. |
Also some additional STATIC's on entrypoint functions. |
|
2001-08-16 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (upd985xx_eth_upd985xx_init): If the EEPROM |
contains nothing (or isn't fitted?) fake an ESA so we can get |
RedBoot going on the board without special configury. |
|
2001-08-16 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (eth_upd985xx_configure): Use smaller numbers |
for the Tx Fill Threshold [TX_FLTH] and DMA Tx Burst Size [DTBS] |
because the hardware is even more broken than first throught - |
this is new information on fault E4. I also tagged this with the |
name of the option we would use if this were cdl controlled - but |
since it's just setup I see no need to change it, so no CDL. |
|
2001-08-16 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (TxDone): Since it still wedged occasionally, |
with an "out of rx buffers" status but nothing else, this is a |
much simplified workaround for bug E8. If we see the suspect |
transmit status, simply reset the whole subsystem there and then. |
This leaves it in far more of a known state. It's neater anyway. |
|
2001-08-15 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (eth_upd985xx_send): Small hacks to recover |
from various wedged states with bogus or unexpected ETH_ISR |
values... 0x80000000: We detect this in the deliver routine and |
totally reset the system. "out of rx buffers" with no "good rx": |
we unmask and check for all these RX interrupts, not just "good |
rx". Also PacketRxReady() shortcuts to resetting the receive |
engine when it sees the problem. I suspect these might be caused |
by the E8 workaround below, perhaps introducing some race |
condition with turning off the receiver just when it rx'd - and of |
course E1E2 means it receives far more packets. |
|
2001-08-07 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c: Workaround various bugs in the hardware; |
these workarounds are conditionally compiled via CDL options named |
CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_xxx in general; 'xxx' |
is the reference for the mis-feature. All are enabled by default. |
|
To summarize: |
(eth_upd985xx_reset): xxx=S1: insert reads between writes to the |
device to avoid a possible deadlock; macro FLUSH_WRITES(). |
(PacketRxReady): xxx=E1E2: we set the device in promiscuous mode |
always, and implement ESA matching in code. The cost is small. |
If promisc mode is set by the stack, we pass all packets. |
(eth_upd985xx_send): xxx=E3: we copy any transmit that uses 3 or |
more SGs into a static contiguous buffer and transmit from that |
thus using only one buffer descriptor. |
(eth_upd985xx_send): |
(TxDone): xxx=E8: we make a note that a tx ended badly and when |
starting the next tx, we disable and reset the transmitter. |
|
* cdl/upd985xx_eth_drivers.cdl: New subcomponent for controlling |
these workarounds: CYGPKG_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS. |
"Workarounds for Ethernet Hardware bugs" |
|
2001-07-16 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (PacketRxReady): Test for, rather than assert, |
packet size in range. The hardware can report a tiny packet as |
AOK, with no bad in the status, despite the doc's reassurances. |
|
2001-07-13 Hugo Tyson <hmt@redhat.com> |
|
* cdl/upd985xx_eth_drivers.cdl: Turn off the startup chatter. |
|
2001-07-13 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (TxDone): Test a few more bits for tx |
complete; it turns out you can get tx underruns when the CPU us |
heavily loaded, as in the tcp_echo tests with high load. |
|
2001-07-13 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (eth_upd985xx_send): Use HAL_DCACHE_STORE() |
rather than syncing the whole of cache every sglist entry(=mbuf). |
Turns out the cache op must be cache line aligned to work on the |
4120, boo, unlike other MIPS and unlike the doc, even. |
|
2001-07-12 Hugo Tyson <hmt@redhat.com> |
|
* cdl/upd985xx_eth_drivers.cdl (CYGPKG_DEVS_ETH_MIPS_UPD985XX_ETH0): |
Whole new section to address configuring the source of the MAC |
address. Also allows configury of the device's name ("eth0") for |
cohabitation with additional devices. |
|
* src/if_upd985xx.c (upd985xx_eth_upd985xx_init): Pick up the ESA |
from EEPROM if it's available, also support a fixed ESA from CDL |
configuration land. A few minor changes to the structure |
initialization to accommodate this; also pick up the interrupt |
vector from struct init. |
(eth_set_mac_address): New routine available via the ioctl() |
entry, for use when neither a fixed nor EEPROM address is |
available. |
|
2001-07-12 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (NUM_RXBUFS): Reduce NUM_RXBUFS to 8; IME |
fewer results in lost rx's in typical systems. Enlarge rx buffers |
slightly, to accommodate oversize VLAN packets. 128 bytes extra |
should be enough. Implemented eth_upd985xx_configure() selection |
of promiscuous mode and allow oversize packets - up to the allowed |
oversize. Otherwise we would get confused if a packet ate more |
than 1 rx buffer. |
|
2001-07-12 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c: Tidy up debug print defaults; make functions |
static; add a few extra statistics to the device object; pass a |
p_eth_upd985xx around more consistently for if we switch to |
multiple devices in future; comment out mii_write(); handle |
stopping the device with a tx pending; remove some commented-out |
templates copied from another driver; and fill in SNMP statistics. |
In other words, many minor changes. |
|
2001-07-11 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c (PacketRxReady): Recover from running out of |
receive buffers. All very dodgy, but it seems to work. |
Additional efforts are also made to reset the device, having |
realized how hard it is to re-initialize the receive engine once |
it has been awakened. |
|
2001-07-11 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c: Efficient Rx now essentially working, with a |
simple circular buffer, always linked into a ring, and one entry |
of which is always NULL,NULL to bring the rx machinery to a halt. |
If it reaches thus far the rx mechanism seems to jam; will deal |
with that next. |
|
2001-07-09 Hugo Tyson <hmt@redhat.com> |
|
* src/if_upd985xx.c: Rejigged version of the rx buffer system; |
still not working properly, still not a good match for the |
hardware's elusive semantics. Committed anyway, to keep it around |
for reference. |
(eth_upd985xx_status): Also removed all the cruft about |
renegotiating line status; it's not needed. |
|
2001-07-06 Hugo Tyson <hmt@redhat.com> |
|
* include/upd985xx_eth.h (ETH_MADR_PHY_DEVICE_PHYS_ADDRESS): |
Change name of PHY address symbol to generic not SEEQ. |
Comment out the non-standard symbols for useful bits that the |
previous PHY device supported. |
|
* src/if_upd985xx.c (eth_upd985xx_reset): If there is a valid ESA |
in the MAC already, run with it - it would have come from the |
not-fitted serial EEPROM, via some different registers. |
(upd985xx_eth_upd985xx_init): Moved the call to reset about to |
accommodate this. |
(eth_upd985xx_status): Omit renegotiation of link properties and |
use the intersection of the capabilities bits to report what |
speed, duplex, we are running at. More portable. |
(mii_write): |
(mii_read): Change name of PHY address symbol to generic not SEEQ |
'cos the board has changed. |
|
2001-07-06 Hugo Tyson <hmt@redhat.com> |
|
* ChangeLog: |
* cdl/upd985xx_eth_drivers.cdl: |
* include/upd985xx_eth.h: |
* src/if_upd985xx.c: |
New files. Initial checkin of limping along version of |
NEC upd985xx ethernet driver. |
|
Limitations: |
ESA is hard coded. |
It talks to the PHY just to make sure - helped with debug anyway. |
No SNMP data exported. |
No ioctl() for promiscuous mode or VLAN mode. |
Only one TX at once. |
Only one RX buffer, so no RX until serviced. |
It seems to loose interrupts - inevitably, for an eth device - and |
there's no "catchup" defense against this yet. |
|
It's oriented to the "old" (already) board - so the particular PHY |
and GPIO layout. |
|
//=========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//=========================================================================== |
/upd985xx/v2_0/src/if_upd985xx.c
0,0 → 1,1621
//========================================================================== |
// |
// if_upd985xx.c |
// |
// Ethernet drivers |
// NEC UPD985XX device ethernet specific support |
// |
//========================================================================== |
//####ECOSGPLCOPYRIGHTBEGIN#### |
// ------------------------------------------- |
// This file is part of eCos, the Embedded Configurable Operating System. |
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. |
// |
// eCos is free software; you can redistribute it and/or modify it under |
// the terms of the GNU General Public License as published by the Free |
// Software Foundation; either version 2 or (at your option) any later version. |
// |
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY |
// WARRANTY; without even the implied warranty of MERCHANTABILITY or |
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
// for more details. |
// |
// You should have received a copy of the GNU General Public License along |
// with eCos; if not, write to the Free Software Foundation, Inc., |
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. |
// |
// As a special exception, if other files instantiate templates or use macros |
// or inline functions from this file, or you compile this file and link it |
// with other works to produce a work based on this file, this file does not |
// by itself cause the resulting work to be covered by the GNU General Public |
// License. However the source code for this file must still be made available |
// in accordance with section (3) of the GNU General Public License. |
// |
// This exception does not invalidate any other reasons why a work based on |
// this file might be covered by the GNU General Public License. |
// |
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. |
// at http://sources.redhat.com/ecos/ecos-license/ |
// ------------------------------------------- |
//####ECOSGPLCOPYRIGHTEND#### |
//####BSDCOPYRIGHTBEGIN#### |
// |
// ------------------------------------------- |
// |
// Portions of this software may have been derived from OpenBSD or other sources, |
// and are covered by the appropriate copyright disclaimers included herein. |
// |
// ------------------------------------------- |
// |
//####BSDCOPYRIGHTEND#### |
//========================================================================== |
//#####DESCRIPTIONBEGIN#### |
// |
// Author(s): hmt, gthomas |
// Contributors: |
// Date: 2001-06-28 |
// Purpose: |
// Description: hardware driver for uPD985xx ethernet devices |
// |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <pkgconf/system.h> |
#include <pkgconf/devs_eth_mips_upd985xx.h> |
#include <pkgconf/io_eth_drivers.h> |
|
#include <cyg/infra/cyg_type.h> |
#include <cyg/infra/cyg_ass.h> |
#include <cyg/hal/hal_arch.h> |
#include <cyg/hal/hal_intr.h> |
#include <cyg/hal/hal_cache.h> |
#include <cyg/infra/diag.h> |
#include <cyg/hal/drv_api.h> |
#include <cyg/io/eth/netdev.h> |
#include <cyg/io/eth/eth_drv.h> |
|
#ifdef CYGPKG_NET |
#include <pkgconf/net.h> |
#include <net/if.h> /* Needed for struct ifnet */ |
#else |
#include <cyg/hal/hal_if.h> |
#endif |
|
#include <cyg/devs/eth/upd985xx_eth.h> |
|
#include <cyg/io/eth/eth_drv_stats.h> |
|
// ------------------------------------------------------------------------ |
|
#ifdef CYGDBG_DEVS_ETH_MIPS_UPD985XX_CHATTER |
#define nDEBUG_TRAFFIC // This one prints stuff as packets come and go |
#define nDEBUG_IOCTL // ioctl() call printing |
#define DEBUG // Startup printing mainly |
#endif |
|
#define os_printf diag_printf |
#define db_printf diag_printf |
|
#define STATIC static |
|
// ------------------------------------------------------------------------ |
// I/O access macros as inlines for later changes to >1 device? |
// |
// (If we need to do this, then these macros would *assume* the |
// presence of a valid p_eth_upd985xx just like we always have) |
|
static inline void OUTL( volatile cyg_uint32 *io_address, cyg_uint32 value ) |
{ *io_address = value; } |
|
static inline cyg_uint32 INL( volatile cyg_uint32 *io_address ) |
{ return *io_address; } |
|
// These map cachable addresses to uncachable ones and vice versa. |
// This is all fixed on MIPS. 8-9xxxxxxx uncachable, A-Bxxxxxxx cachable. |
#define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_)) |
static inline cyg_uint8 *virt_to_bus(cyg_uint32 p_memory) |
{ |
return (cyg_uint8 *)(0xa0000000u + (p_memory & ~0xe0000000u)); |
} |
#define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_)) |
static inline cyg_uint8 *bus_to_virt(cyg_uint32 p_memory) |
{ |
return (cyg_uint8 *)(0x80000000u + (p_memory & ~0xe0000000u)); |
} |
|
|
// ------------------------------------------------------------------------ |
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_S1 |
#define FLUSH_WRITES() CYG_MACRO_START \ |
(void) INL( ETH_RXSR ); \ |
CYG_MACRO_END |
#else |
#define FLUSH_WRITES() CYG_EMPTY_STATEMENT |
#endif |
|
// ------------------------------------------------------------------------ |
// |
// DEVICES AND PACKET QUEUES |
// |
// ------------------------------------------------------------------------ |
|
// 128 bytes extra for VLAN packets should be enough; AFAICT usually the |
// encapsulation is only 4 or 10 bytes extra. |
#define MAX_ETHERNET_PACKET_SIZE 1536 // Ethernet Rx packet size |
#define MAX_OVERSIZE_PACKET_SIZE 1664 // VLAN Rx packet size |
#define MAX_RX_PACKET_SIZE MAX_OVERSIZE_PACKET_SIZE |
|
#define NUM_RXBUFS (8) |
|
// This one is the hardware definition. |
struct bufdesc { |
volatile cyg_uint32 attr; |
cyg_uint8 *ptr; |
}; |
|
// Rx databuffer. |
STATIC cyg_uint8 rx_databuf[ NUM_RXBUFS ] [ MAX_RX_PACKET_SIZE ]; |
|
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3 |
// Tx databuffer |
STATIC cyg_uint8 tx_databuf[ MAX_RX_PACKET_SIZE ]; |
#endif |
|
struct eth_upd985xx { |
cyg_uint8 active, index, tx_busy, mac_addr_ok; |
cyg_uint8 vector; // interrupt numbers are small |
cyg_uint8 phy_status; // from PHY_STATUS_ flags below |
cyg_uint8 hardwired_esa; |
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 |
cyg_uint8 promisc; |
#endif |
cyg_uint8 mac_address[6]; |
|
cyg_handle_t interrupt_handle; |
cyg_interrupt interrupt_object; |
|
struct cyg_netdevtab_entry *ndp; |
|
// these shall hold uncached addresses of the structures following... |
volatile struct bufdesc *txring; |
volatile struct bufdesc *rxring_active; |
volatile struct bufdesc *rxring_next; |
int rxring_active_index; |
int rxring_next_index; |
cyg_uint32 intrs; |
cyg_uint32 tx_keys[1]; |
|
// ----------------------------------------------------------------- |
// Statistics counters |
cyg_uint32 count_rx_resource; |
cyg_uint32 count_rx_restart; |
cyg_uint32 count_interrupts; |
cyg_uint32 count_bad_isr_restarts; |
cyg_uint32 count_bad_tx_completion; |
|
// ----------------------------------------------------------------- |
// DO NOT ACCESS THESE DIRECTLY - THE DEVICE HAS TO SEE THEM UNCACHED |
|
// Initially, enough for one whole transmission to be described in one go, |
// plus a null link on the end. |
struct bufdesc tx_bufdesc[ MAX_ETH_DRV_SG + 2 ]; |
|
// Pending rx buffers, of full size. |
struct bufdesc rx_bufdesc[ NUM_RXBUFS+1 ]; |
|
// ----------------------------------------------------------------- |
}; |
|
struct eth_upd985xx eth_upd985xx[CYGNUM_DEVS_ETH_MIPS_UPD985XX_DEV_COUNT] = { |
{ |
index: 0, |
vector: CYGNUM_HAL_INTERRUPT_ETHER, |
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 |
promisc: 0, |
#endif |
#ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA |
hardwired_esa: 1, |
mac_address: CYGDAT_DEVS_ETH_UPD985XX_ETH0_ESA, |
mac_addr_ok: 1, |
#else |
hardwired_esa: 0, |
mac_addr_ok: 0, |
#endif |
} |
}; |
|
// eth0 |
|
ETH_DRV_SC(upd985xx_sc0, |
ð_upd985xx[0], // Driver specific data |
CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME, // name for this interface |
eth_upd985xx_start, |
eth_upd985xx_stop, |
eth_upd985xx_ioctl, |
eth_upd985xx_can_send, |
eth_upd985xx_send, |
eth_upd985xx_recv, |
eth_upd985xx_deliver, |
eth_upd985xx_poll, |
eth_upd985xx_int_vector |
); |
|
NETDEVTAB_ENTRY(upd985xx_netdev0, |
"upd985xx-" CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME, |
upd985xx_eth_upd985xx_init, |
&upd985xx_sc0); |
|
|
// This is in a macro so that if more devices arrive it can easily be changed |
#define CHECK_NDP_SC_LINK() CYG_MACRO_START \ |
CYG_ASSERT( ((void *)ndp == (void *)&upd985xx_netdev0), "Bad ndp" ); \ |
CYG_ASSERT( ((void *)sc == (void *)&upd985xx_sc0), "Bad sc" ); \ |
CYG_ASSERT( (void *)p_eth_upd985xx == sc->driver_private, \ |
"sc pointer bad" ); \ |
CYG_ASSERT( (void *)p_eth_upd985xx == (void *)ð_upd985xx[0], \ |
"bad p_eth_upd985x" ); \ |
CYG_MACRO_END |
|
#define NUM_ELEMENTS( _x_ ) (sizeof( (_x_) ) / sizeof( (_x_[0]) ) ) |
|
// ------------------------------------------------------------------------ |
// |
// FUNCTION PROTOTYPES |
// |
// ------------------------------------------------------------------------ |
STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx); |
STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx); |
STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx); |
STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx); |
|
#ifdef CYGPKG_NET |
STATIC int eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx, |
int promisc, int oversized); |
#endif |
|
STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx); |
STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx); |
|
#define PHY_STATUS_LINK (1) |
#define PHY_STATUS_FDX (2) |
#define PHY_STATUS_100MBPS (4) |
STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx ); |
STATIC int eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data ); |
|
// ------------------------------------------------------------------------ |
// |
// MII ACCESS TO PHY DEVICE |
// |
// ------------------------------------------------------------------------ |
|
STATIC cyg_bool mii_read( cyg_uint32 reg, cyg_uint32 *pvalue, |
struct eth_upd985xx *p_eth_upd985xx ) |
{ |
int i = 1000; |
// wait a bit for it to be idle |
while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY) |
& INL(ETH_MIND)) ) |
if ( --i < 0 ) |
return false; |
// Tell it the register address and PHY address |
OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg ); |
OUTL( ETH_MCMD, ETH_MCMD_RSTAT ); // "do a read" |
// wait for the read to complete |
while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY) |
& INL(ETH_MIND)) ) |
if ( --i < 0 ) |
return false; |
// so get the data |
*pvalue = INL( ETH_MRDD ); |
return true; |
} |
|
#if 0 |
STATIC cyg_bool mii_write( cyg_uint32 reg, cyg_uint32 value, |
struct eth_upd985xx *p_eth_upd985xx ) |
{ |
int i = 1000; |
// wait a bit for it to be idle |
while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY) |
& INL(ETH_MIND)) ) |
if ( --i < 0 ) |
return false; |
// Tell it the register address and PHY address |
OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg ); |
// And write the data: |
OUTL( ETH_MWTD, value ); |
// wait a bit for it to be idle |
while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY) |
& INL(ETH_MIND)) ) |
if ( --i < 0 ) |
return false; |
return true; |
} |
#endif |
|
// ------------------------------------------------------------------------ |
// |
// INTERRUPT HANDLERS |
// |
// ------------------------------------------------------------------------ |
|
STATIC cyg_uint32 eth_isr(cyg_vector_t vector, cyg_addrword_t data) |
{ |
cyg_drv_interrupt_mask( vector ); |
|
return CYG_ISR_CALL_DSR; // schedule DSR |
} |
|
// ------------------------------------------------------------------------ |
// This is a callback from the higher level thread in consequence of the DSR |
STATIC void |
eth_upd985xx_deliver(struct eth_drv_sc *sc) |
{ |
register int intrs; |
struct eth_upd985xx *p_eth_upd985xx; |
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
p_eth_upd985xx->count_interrupts++; |
|
intrs = INL( ETH_ISR ); // Read-clear |
// Acknowledge once at the start anyway to prevent an interrupt loop in |
// case of a transient - interrupts latch in the interrupt controller |
// as well as in the ethernet device. |
cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector); |
|
#ifdef DEBUG_TRAFFIC |
os_printf("\n[[[[[[[ Deliver intrs = %x\n", intrs ); |
#endif |
|
// Guard possible external entry points |
if ( ! p_eth_upd985xx->active ) |
return; // without unmasking the interrupt |
|
while ( intrs ) { |
if ( 0xffff0000 & intrs ) { |
// Then something very bad has happened |
p_eth_upd985xx->count_bad_isr_restarts++; |
CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" ); |
eth_upd985xx_stop( sc ); |
eth_upd985xx_start( sc, NULL, 0 ); |
intrs = INL( ETH_ISR ); // Read-clear |
} |
p_eth_upd985xx->intrs = intrs; |
if ( ( ETH_ISR_XMTDN | ETH_ISR_TABR ) & intrs ) { |
// Scan for completed Txen and inform the stack |
TxDone(p_eth_upd985xx); |
} |
if ( ( ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU ) & intrs ) { |
// Pass any rx data up the stack |
PacketRxReady(p_eth_upd985xx); |
} |
// Now we have made the interrupt causes go away, acknowledge and |
// *then* read the ISR again. That way the race can result in a |
// spurious interrupt rather than a lost interrupt. |
cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector); |
intrs = INL( ETH_ISR ); // Read-clear |
#ifdef DEBUG_TRAFFIC |
if ( intrs ) |
os_printf("------- Again intrs = %x\n", intrs ); |
#endif |
} |
#ifdef DEBUG_TRAFFIC |
os_printf("]]]]]]]] Done intrs = %x\n\n", intrs ); |
#endif |
|
cyg_drv_interrupt_unmask(p_eth_upd985xx->vector); |
} |
|
// ------------------------------------------------------------------------ |
// Device table entry to operate the chip in a polled mode. |
// Only diddle the interface we were asked to! |
|
STATIC void |
eth_upd985xx_poll(struct eth_drv_sc *sc) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
|
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
// As it happens, this driver always requests the DSR to be called: |
(void)eth_isr( p_eth_upd985xx->vector, (cyg_addrword_t)sc ); |
eth_upd985xx_deliver( sc ); |
} |
|
// ------------------------------------------------------------------------ |
// Determine interrupt vector used by a device - for attaching GDB stubs |
// packet handler. |
STATIC int |
eth_upd985xx_int_vector(struct eth_drv_sc *sc) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
return (p_eth_upd985xx->vector); |
} |
|
// ------------------------------------------------------------------------ |
|
STATIC int |
eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data ) |
{ |
cyg_uint8 *p = (cyg_uint8 *)data; |
cyg_uint8 *mac_address; |
|
mac_address = &p_eth_upd985xx->mac_address[0]; |
|
mac_address[5] = p[5]; |
mac_address[4] = p[4]; |
mac_address[3] = p[3]; |
mac_address[2] = p[2]; |
mac_address[1] = p[1]; |
mac_address[0] = p[0]; |
|
p_eth_upd985xx->mac_addr_ok = 1; |
|
// Set the ESA in the device regs |
OUTL( ETH_LSA2, |
(p_eth_upd985xx->mac_address[1]) | |
(p_eth_upd985xx->mac_address[0] << 8 ) ); |
OUTL( ETH_LSA1, |
(p_eth_upd985xx->mac_address[5]) | |
(p_eth_upd985xx->mac_address[4] << 8 ) | |
(p_eth_upd985xx->mac_address[3] << 16 ) | |
(p_eth_upd985xx->mac_address[2] << 24) ); |
|
return 0; // OK |
} |
|
// ------------------------------------------------------------------------ |
|
STATIC void |
eth_upd985xx_reset( struct eth_upd985xx *p_eth_upd985xx ) |
{ |
int i; |
|
// Reset whole device: Software Reset (clears automatically) |
OUTL( ETH_CCR, ETH_CCR_SRT ); |
for ( i = 0; i < 10000; i++ ) /* nothing */; |
// Reset internal units |
OUTL( ETH_MACC2, ETH_MACC2_MCRST | ETH_MACC2_RFRST | ETH_MACC2_TFRST ); |
for ( i = 0; i < 10000; i++ ) /* nothing */; |
FLUSH_WRITES(); |
OUTL( ETH_MACC2, 0 ); // (and release reset) |
// Enable CRC adding, padding |
FLUSH_WRITES(); |
OUTL( ETH_MACC1, |
ETH_MACC1_CRCEN | ETH_MACC1_PADEN | |
ETH_MACC1_TXFC | ETH_MACC1_RXFC | ETH_MACC1_PARF ); |
FLUSH_WRITES(); |
OUTL( ETH_MACC2, ETH_MACC2_APD ); // Auto VLAN pad |
FLUSH_WRITES(); |
OUTL( ETH_HT1, 0 ); |
FLUSH_WRITES(); |
OUTL( ETH_HT2, 0 ); |
|
// Enable rx of broadcasts, multicasts, but not promiscuous... |
FLUSH_WRITES(); |
#if defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 ) && \ |
!defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY ) |
// Unless we are faking it. |
OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM | ETH_AFR_PRO ); |
#else |
OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM ); |
#endif |
|
FLUSH_WRITES(); |
OUTL( ETH_IPGT, 0x00000013 ); |
FLUSH_WRITES(); |
OUTL( ETH_IPGR, 0x00000e13 ); |
FLUSH_WRITES(); |
OUTL( ETH_CLRT, 0x0000380f ); |
FLUSH_WRITES(); |
OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE ); |
|
// Select a clock for the MII |
FLUSH_WRITES(); |
OUTL( ETH_MIIC, ETH_MIIC_66 ); // Example code sets to 66. |
// Set VLAN type reg |
FLUSH_WRITES(); |
OUTL( ETH_VLTP, ETH_VLTP_VLTP ); |
|
// Set the ESA in the device regs |
if ( p_eth_upd985xx->mac_addr_ok ) { |
FLUSH_WRITES(); |
OUTL( ETH_LSA2, |
(p_eth_upd985xx->mac_address[1]) | |
(p_eth_upd985xx->mac_address[0] << 8 ) ); |
FLUSH_WRITES(); |
OUTL( ETH_LSA1, |
(p_eth_upd985xx->mac_address[5]) | |
(p_eth_upd985xx->mac_address[4] << 8 ) | |
(p_eth_upd985xx->mac_address[3] << 16 ) | |
(p_eth_upd985xx->mac_address[2] << 24) ); |
} |
|
FLUSH_WRITES(); |
OUTL( ETH_RXFCR, ETH_RXFCR_UWM_DEFAULT | |
ETH_RXFCR_LWM_DEFAULT | ETH_RXFCR_DRTH16W ); |
|
FLUSH_WRITES(); |
// Fault E4 - use only 32 for FLTH, not the previously recommended 48 (words) |
// Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4 |
// but no config opt is provided. |
OUTL( ETH_TXFCR, ETH_TXFCR_TPTV_DEFAULT | |
ETH_TXFCR_TX_DRTH_DEFAULT | (32 << ETH_TXFCR_TX_FLTH_SHIFT) ); |
|
// Transmit and receive config regs we hit when enabling those |
// functions separately, and the wet string end of the receiver |
// which is controlled by MACC1 |= ETH_MACC1_SRXEN; |
|
// Tx and Rx interrupts enabled internally; |
// Tx done/aborted, and rx OK. |
FLUSH_WRITES(); |
OUTL( ETH_MSR, ETH_ISR_XMTDN | ETH_ISR_TABR | |
ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU ); |
FLUSH_WRITES(); |
} |
|
// ------------------------------------------------------------------------ |
// |
// NETWORK INTERFACE INITIALIZATION |
// |
// ------------------------------------------------------------------------ |
STATIC bool |
upd985xx_eth_upd985xx_init(struct cyg_netdevtab_entry * ndp) |
{ |
struct eth_drv_sc *sc; |
cyg_uint8 *mac_address; |
struct eth_upd985xx *p_eth_upd985xx; |
|
#ifdef DEBUG |
db_printf("upd985xx_eth_upd985xx_init\n"); |
#endif |
|
sc = (struct eth_drv_sc *)(ndp->device_instance); |
p_eth_upd985xx = (struct eth_upd985xx *)(sc->driver_private); |
|
CHECK_NDP_SC_LINK(); |
|
p_eth_upd985xx->tx_busy = 0; |
|
// record the net dev pointer |
p_eth_upd985xx->ndp = (void *)ndp; |
|
mac_address = &p_eth_upd985xx->mac_address[0]; |
|
#ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA |
if ( ! p_eth_upd985xx->hardwired_esa ) { |
cyg_uint8 *p; |
union macar { |
struct { |
cyg_uint32 macar1, macar2, macar3; |
} integers; |
cyg_uint8 bytes[12]; |
} eeprom; |
|
eeprom.integers.macar1 = INL( MACAR1 ); // MAC Address Register 1 |
eeprom.integers.macar2 = INL( MACAR2 ); // MAC Address Register 2 |
eeprom.integers.macar3 = INL( MACAR3 ); // MAC Address Register 3 |
|
if ( (0 != eeprom.integers.macar1 || |
0 != eeprom.integers.macar2 || |
0 != eeprom.integers.macar3 ) |
&& |
(0xffffffff != eeprom.integers.macar1 || |
0xffffffff != eeprom.integers.macar2 || |
0xffffffff != eeprom.integers.macar3 ) ) { |
// Then we have good data in the EEPROM |
#ifdef DEBUG |
os_printf( "EEPROM data %08x %08x %08x\n", |
eeprom.integers.macar1, |
eeprom.integers.macar2, |
eeprom.integers.macar3 ); |
#endif |
p = &eeprom.bytes[0]; // pick up either set of ESA info |
if ( 1 == p_eth_upd985xx->index ) |
p += 6; |
|
mac_address[5] = p[5]; |
mac_address[4] = p[4]; |
mac_address[3] = p[3]; |
mac_address[2] = p[2]; |
mac_address[1] = p[1]; |
mac_address[0] = p[0]; |
p_eth_upd985xx->mac_addr_ok = 1; |
} |
else { |
// Fake it so we can get RedBoot going on a board with no EEPROM |
mac_address[0] = 0; |
mac_address[1] = 0xBA; |
mac_address[2] = 0xD0; |
mac_address[3] = 0xEE; |
mac_address[4] = 0x00; |
mac_address[5] = p_eth_upd985xx->index; |
p_eth_upd985xx->mac_addr_ok = 1; |
} |
} |
#endif // CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA |
|
// Init the underlying hardware and insert the ESA: |
eth_upd985xx_reset(p_eth_upd985xx); |
|
#ifdef DEBUG |
os_printf("MAC Address %s, ESA = %02X %02X %02X %02X %02X %02X\n", |
p_eth_upd985xx->mac_addr_ok ? "OK" : "**BAD**", |
mac_address[0], mac_address[1], mac_address[2], mac_address[3], |
mac_address[4], mac_address[5]); |
#endif |
|
// Set up the pointers to data structures |
InitTxRing(p_eth_upd985xx); |
|
// Construct the interrupt handler |
p_eth_upd985xx->active = 0; |
cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector); |
cyg_drv_interrupt_mask(p_eth_upd985xx->vector); |
cyg_drv_interrupt_create( |
p_eth_upd985xx->vector, |
0, // Priority - unused |
(CYG_ADDRWORD)sc, // Data item passed to ISR & DSR |
eth_isr, // ISR |
eth_drv_dsr, // DSR (generic) |
&p_eth_upd985xx->interrupt_handle, // handle to intr obj |
&p_eth_upd985xx->interrupt_object ); // space for int obj |
|
cyg_drv_interrupt_attach(p_eth_upd985xx->interrupt_handle); |
|
// Initialize upper level driver |
if ( p_eth_upd985xx->mac_addr_ok ) |
(sc->funs->eth_drv->init)(sc, &(p_eth_upd985xx->mac_address[0]) ); |
else |
(sc->funs->eth_drv->init)(sc, 0 ); |
|
return (1); |
} |
|
// ------------------------------------------------------------------------ |
// |
// Function : eth_upd985xx_start |
// |
// ------------------------------------------------------------------------ |
STATIC void |
eth_upd985xx_start( struct eth_drv_sc *sc, |
unsigned char *enaddr, int flags ) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
cyg_uint32 ss; |
#ifdef CYGPKG_NET |
struct ifnet *ifp = &sc->sc_arpcom.ac_if; |
#endif |
|
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
#ifdef DEBUG |
os_printf("eth_upd985xx_start %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx ); |
#endif |
|
if ( p_eth_upd985xx->active ) |
eth_upd985xx_stop( sc ); |
|
p_eth_upd985xx->active = 1; |
|
#ifdef CYGPKG_NET |
/* Enable promiscuous mode if requested, reception of oversized frames always. |
* The latter is needed for VLAN support and shouldn't hurt even if we're not |
* using VLANs. |
*/ |
eth_upd985xx_configure(p_eth_upd985xx, !!(ifp->if_flags & IFF_PROMISC), 1); |
#endif |
|
// renegotiate link status |
p_eth_upd985xx->phy_status = eth_upd985xx_status( p_eth_upd985xx ); |
|
if ( p_eth_upd985xx->phy_status & PHY_STATUS_FDX ) { |
cyg_uint32 ss; |
// then enable full duplex in the MAC |
ss = INL( ETH_MACC1 ); |
ss |= ETH_MACC1_FDX; |
OUTL( ETH_MACC1, ss ); |
} |
|
#ifdef DEBUG |
{ |
int status = p_eth_upd985xx->phy_status; |
os_printf("eth_upd985xx_start %d Link = %s, %s Mbps, %s Duplex\n", |
p_eth_upd985xx->index, |
status & PHY_STATUS_LINK ? "Up" : "Down", |
status & PHY_STATUS_100MBPS ? "100" : "10", |
status & PHY_STATUS_FDX ? "Full" : "Half" |
); |
} |
#endif |
|
|
// Start the receive engine |
p_eth_upd985xx->count_rx_restart++; |
// Initialize all but one buffer: [B0,B1,B2,...Bx,NULL,LINK] |
InitRxRing( p_eth_upd985xx ); |
// Point the hardware at the list of buffers |
OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active ); |
// Tell it about the buffers via the rx descriptor count |
OUTL( ETH_RXPDR, ETH_RXPDR_AL | (NUM_RXBUFS-1) ); |
// Ack any pending interrupts from the system |
p_eth_upd985xx->intrs = INL( ETH_ISR ); // Read-clear |
// Start the rx. |
OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 ); |
|
// Enable the wet string end of the receiver |
ss = INL( ETH_MACC1 ); |
ss |= ETH_MACC1_SRXEN; |
OUTL( ETH_MACC1, ss ); |
|
// And unmask the interrupt |
cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector); |
cyg_drv_interrupt_unmask(p_eth_upd985xx->vector); |
} |
|
// ------------------------------------------------------------------------ |
// |
// Function : eth_upd985xx_status; 10/100 and Full/Half Duplex (FDX/HDX) |
// |
// ------------------------------------------------------------------------ |
STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx ) |
{ |
int status; |
int i, j; |
// Some of these bits latch and only reflect "the truth" on a 2nd reading. |
// So read and discard. |
mii_read( PHY_CONTROL_REG, &i, p_eth_upd985xx ); |
mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx ); |
// Use the "and" of the local and remote capabilities words to infer |
// what is selected: |
status = 0; |
if ( mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx ) ) { |
if ( PHY_STATUS_LINK_OK & i ) |
status |= PHY_STATUS_LINK; |
} |
if ( mii_read( PHY_AUTONEG_ADVERT, &j, p_eth_upd985xx ) && |
mii_read( PHY_AUTONEG_REMOTE, &i, p_eth_upd985xx ) ) { |
#if defined( DEBUG_TRAFFIC ) || defined( DEBUG_IOCTL ) |
os_printf( "MII: capabilities are %04x, %04x; common %04x\n", |
i, j, i & j ); |
#endif |
j &= i; // select only common capabilities |
|
if ( (PHY_AUTONEG_100BASET4 | |
PHY_AUTONEG_100BASETX_FDX | |
PHY_AUTONEG_100BASETX_HDX) & j ) |
status |= PHY_STATUS_100MBPS; |
if ( (PHY_AUTONEG_100BASETX_FDX | PHY_AUTONEG_10BASET_FDX) & j ) |
status |= PHY_STATUS_FDX; |
} |
return status; |
} |
|
// ------------------------------------------------------------------------ |
// |
// Function : eth_upd985xx_stop |
// |
// ------------------------------------------------------------------------ |
|
STATIC void eth_upd985xx_stop( struct eth_drv_sc *sc ) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
|
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
// No more interrupts |
cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector); |
cyg_drv_interrupt_mask(p_eth_upd985xx->vector); |
|
#ifdef DEBUG |
os_printf("eth_upd985xx_stop %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx ); |
#endif |
|
p_eth_upd985xx->active = 0; // stop people tormenting it |
|
if ( p_eth_upd985xx->tx_busy ) { |
// Then it is finshed now, by force: |
cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ]; |
// Turn off the transmitter (before the callback to the stack). |
OUTL( ETH_TXCR, 0 ); |
#ifdef DEBUG_TRAFFIC |
os_printf("Stop: tidying up TX, KEY %x\n", key ); |
#endif |
// Leave tx_busy true so no recursion can occur here. |
// Then tell the stack we are done: |
if ( key ) { |
(sc->funs->eth_drv->tx_done)( sc, key, 0 ); |
} |
} |
p_eth_upd985xx->tx_keys[ 0 ] = 0; |
p_eth_upd985xx->tx_busy = p_eth_upd985xx->active = 0; |
|
eth_upd985xx_reset(p_eth_upd985xx); |
|
ResetTxRing( p_eth_upd985xx ); |
} |
|
|
// ------------------------------------------------------------------------ |
// |
// Function : InitRxRing |
// |
// ------------------------------------------------------------------------ |
STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx) |
{ |
int i; |
struct bufdesc *bp; |
|
// first just blat the various flags and addresses: the first N |
// bufdescs point to data buffers, the last one is NULL. |
bp = (struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[0] ); |
// Record the initial active buffer: |
p_eth_upd985xx->rxring_active = bp; |
p_eth_upd985xx->rxring_active_index = 0; |
for ( i = 0; i < NUM_RXBUFS - 1; i++, bp++ ) { |
bp->ptr = VIRT_TO_BUS( &rx_databuf[i][0] ); |
bp->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU |
| (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) ); |
} |
CYG_ASSERT( i == NUM_RXBUFS-1, "Penultimate rx buffer index mismatch" ); |
CYG_ASSERT( (cyg_uint8 *)bp == |
VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS-1] ), |
"Penultimate rx buffer address mismatch" ); |
|
// NULL out the penultimate one |
bp->ptr = NULL; |
bp->attr = 0; |
// And record it as next one to use |
p_eth_upd985xx->rxring_next = bp; |
p_eth_upd985xx->rxring_next_index = NUM_RXBUFS-1; |
|
// Step on to the extra entry at the end which makes a ring: |
bp++; |
CYG_ASSERT( (cyg_uint8 *)bp == |
VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS] ), |
"Ultimate rx buffer address mismatch" ); |
|
// Link the Ultimate back to the start |
bp->ptr = (cyg_uint8 *)p_eth_upd985xx->rxring_active; // Zeroth entry |
bp->attr = ETH_BUF_D_L_LINK; |
|
// All done. |
} |
|
|
// ------------------------------------------------------------------------ |
// |
// Function : NextRxRing |
// |
// ------------------------------------------------------------------------ |
|
STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx ) |
{ |
volatile struct bufdesc *next, *dead; |
int iactive; |
int inext; |
|
iactive = p_eth_upd985xx->rxring_active_index; |
inext = p_eth_upd985xx->rxring_next_index; |
|
// Preconditions: |
CYG_ASSERT( 0 <= inext && inext < NUM_RXBUFS, "Bad inext" ); |
CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" ); |
CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] ) |
== (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" ); |
CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] ) |
== (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" ); |
CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" ); |
CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" ); |
CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" ); |
CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) == |
p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" ); |
CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext), |
"Chasing pointers mismatch" ); |
|
// Select the new bufdesc to be active - ie. next to scan for reception: |
if ( ++iactive >= NUM_RXBUFS ) |
iactive = 0; |
dead = p_eth_upd985xx->rxring_active; // the one that just died |
// Step ahead the new active buffer: |
p_eth_upd985xx->rxring_active = (volatile struct bufdesc *) |
VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] ); |
p_eth_upd985xx->rxring_active_index = iactive; |
|
// Blow away the currently active entry; we have dealt with it already |
// and it is needed for an end stop to the ring: |
dead->ptr = NULL; |
dead->attr = 0; |
|
// Select the next bufdesc to enliven |
next = p_eth_upd985xx->rxring_next; |
next->ptr = VIRT_TO_BUS( &rx_databuf[inext][0] ); |
next->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU |
| (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) ); |
|
// And update the external info to reflect this: |
if ( ++inext >= NUM_RXBUFS ) |
inext = 0; |
next = (volatile struct bufdesc *) |
VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] ); |
|
p_eth_upd985xx->rxring_next = next; |
p_eth_upd985xx->rxring_next_index = inext; |
|
// Postconditions: |
CYG_ASSERT( 0 <= inext && inext < NUM_RXBUFS, "Bad inext" ); |
CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" ); |
CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] ) |
== (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" ); |
CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] ) |
== (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" ); |
CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" ); |
CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" ); |
CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" ); |
CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) == |
p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" ); |
CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext), |
"Chasing pointers mismatch" ); |
} |
|
// ------------------------------------------------------------------------ |
// |
// Function : PacketRxReady (Called from delivery thread) |
// |
// ------------------------------------------------------------------------ |
STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx) |
{ |
struct cyg_netdevtab_entry *ndp; |
struct eth_drv_sc *sc; |
cyg_uint32 ss, length; |
cyg_bool reset_required = 0; |
|
ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp); |
sc = (struct eth_drv_sc *)(ndp->device_instance); |
|
CHECK_NDP_SC_LINK(); |
|
#ifdef DEBUG_TRAFFIC |
ss = INL( ETH_RXSR ); |
os_printf("PacketRxReady: RXSR %x\n", ss ); |
#endif |
|
if ( ETH_ISR_RBDRU & p_eth_upd985xx->intrs ) |
reset_required = 1; // Out of buffers |
if ( ! ETH_ISR_RCVDN & p_eth_upd985xx->intrs ) |
reset_required = 1; // or if no reception completed, reset anyway |
|
// For all ready rx blocks... |
do { |
volatile struct bufdesc *bp; |
|
bp = p_eth_upd985xx->rxring_active; // Current rx candidate |
|
ss = bp->attr; |
#ifdef DEBUG_TRAFFIC |
os_printf("PacketRxReady attr %x at %x\n", ss, bp ); |
#endif |
if ( ETH_BUF_OWN_CPU == (ETH_BUF_OWN & ss) ) { |
// Then the packet is untouched... |
break; |
} |
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 |
// Perform address recognition by hand, hardware is in promisc mode |
// (we have settable "software" promisc mode too of course) |
if ( ETH_BUF_OK & ss ) { |
cyg_uint8 *esa = (cyg_uint8 *)bp->ptr; // (this is a non-cachable address) |
int ok = 0; |
if ( p_eth_upd985xx->promisc ) |
ok = 1; // accept the packet |
else |
if ( p_eth_upd985xx->mac_address[0] == esa[0] && |
p_eth_upd985xx->mac_address[1] == esa[1] && |
p_eth_upd985xx->mac_address[2] == esa[2] && |
p_eth_upd985xx->mac_address[3] == esa[3] && |
p_eth_upd985xx->mac_address[4] == esa[4] && |
p_eth_upd985xx->mac_address[5] == esa[5] ) |
ok = 1; // Then they are equal - accept |
else |
if ( 0xff == esa[0] && |
0xff == esa[1] && |
0xff == esa[2] && |
0xff == esa[3] && |
0xff == esa[4] && |
0xff == esa[5] ) |
ok = 1; // Then they are equal - accept |
|
if ( !ok ) |
ss = 0; // Easiest way... |
} |
#endif |
if ( ETH_BUF_OK & ss ) { |
length = ETH_BUF_SIZE & ss; |
#ifdef DEBUG_TRAFFIC |
os_printf("PacketRxReady found a packet size %d attr %x\n", length, ss ); |
#endif |
// Asserts for the length in-range can fire, with good status |
// in the block, so be defensive here instead. Belt and braces. |
if ( 63 < length && length <= MAX_RX_PACKET_SIZE ) { |
CYG_ASSERT( ETH_BUF_D_L_DATA == (ETH_BUF_D_L & ss), "Not data buffer" ); |
CYG_ASSERT( length > 63, "Tiny packet" ); |
CYG_ASSERT( length <= MAX_RX_PACKET_SIZE, "Too big packet" ); |
CYG_ASSERT( ETH_BUF_LAST & ss, "Not last buffer" ); |
(sc->funs->eth_drv->recv)( sc, length ); |
} // Else drop it on the floor. |
} |
|
// Step along to the next buffer descriptor... |
NextRxRing( p_eth_upd985xx ); |
if ( ! reset_required ) { |
// And tell the device it can have a biscuit: |
OUTL( ETH_RXPDR, ETH_RXPDR_AL | 1 ); |
|
// Now, before moving on to the next packet, find out if receptions |
// had caught up with us before adding that new buffer: |
ss = INL( ETH_RXPDR ); |
ss &= ETH_RXPDR_RNOD; |
ss >>= ETH_RXPDR_RNOD_SHIFT; |
if ( 1 >= ss ) { |
// Then it was zero before. So the rx engine is stopped. |
#ifdef DEBUG_TRAFFIC |
os_printf( "***ZERO rx buffers were left\n" ); |
#endif |
reset_required = 1; |
} |
// Otherwise we carry on as usual. |
} |
} while ( 1 ); |
|
if ( reset_required ) { |
p_eth_upd985xx->count_rx_resource++; |
// Disable the wet string end of the receiver |
ss = INL( ETH_MACC1 ); |
ss &=~ETH_MACC1_SRXEN; |
OUTL( ETH_MACC1, ss ); |
// Disable the DMA engine |
OUTL( ETH_RXCR, 0 ); |
// Reset the RxRing from scratch |
InitRxRing( p_eth_upd985xx ); |
// Point the hardware at the list of buffers |
OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active ); |
// Tell it about the buffers via the rx descriptor count: |
ss = INL( ETH_RXPDR ); |
ss &= ETH_RXPDR_RNOD; |
ss >>= ETH_RXPDR_RNOD_SHIFT; |
// This awful register *increments* by what you write, even if the |
// machinery is halted. Vile filthy evil rubbish. |
OUTL( ETH_RXPDR, ETH_RXPDR_AL | ((NUM_RXBUFS-1) - ss) ); |
ss = INL( ETH_RXPDR ); |
CYG_ASSERT( (ETH_RXPDR_AL | (NUM_RXBUFS-1)) == ss, "RXPDR not right" ); |
// Start the rx. |
OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 ); |
// Enable the wet string end of the receiver |
ss = INL( ETH_MACC1 ); |
ss |= ETH_MACC1_SRXEN; |
OUTL( ETH_MACC1, ss ); |
// All done. |
#ifdef DEBUG_TRAFFIC |
os_printf( "***Rx Machine restarted\n" ); |
#endif |
} |
} |
|
// and the callback function |
|
STATIC void |
eth_upd985xx_recv( struct eth_drv_sc *sc, |
struct eth_drv_sg *sg_list, int sg_len ) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
int total_len; |
struct eth_drv_sg *last_sg; |
cyg_uint8 *from_p; |
volatile struct bufdesc *bp; |
|
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
// Guard possible external entry points |
if ( ! p_eth_upd985xx->active ) |
return; |
|
bp = p_eth_upd985xx->rxring_active; // Current rx candidate |
|
#ifdef DEBUG_TRAFFIC |
os_printf("Rx status %x\n", bp->attr ); |
#endif |
|
if ( 0 == (ETH_BUF_OK & bp->attr) ) |
return; |
|
total_len = ETH_BUF_SIZE & bp->attr; |
|
#ifdef DEBUG_TRAFFIC |
os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n", |
p_eth_upd985xx->index, (int)p_eth_upd985xx, |
bp->attr, |
sg_len, total_len); |
#endif |
|
// Copy the data to the network stack |
from_p = bp->ptr; // (this is a non-cachable address) |
|
// check we have memory to copy into; we would be called even if |
// caller was out of memory in order to maintain our state. |
if ( 0 == sg_len || 0 == sg_list ) |
return; // caller was out of mbufs |
|
CYG_ASSERT( 0 < sg_len, "sg_len underflow" ); |
CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" ); |
|
for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) { |
cyg_uint8 *to_p; |
int l; |
|
to_p = (cyg_uint8 *)(sg_list->buf); |
l = sg_list->len; |
|
CYG_ASSERT( 0 <= l, "sg length -ve" ); |
|
if ( 0 >= l || 0 == to_p ) |
return; // caller was out of mbufs |
|
if ( l > total_len ) |
l = total_len; |
|
memcpy( to_p, from_p, l ); |
from_p += l; |
total_len -= l; |
} |
|
CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" ); |
CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" ); |
CYG_ASSERT( bp->ptr < from_p, "from_p wild in rx" ); |
CYG_ASSERT( bp->ptr + MAX_RX_PACKET_SIZE >= from_p, |
"from_p overflow in rx" ); |
} |
|
|
// ------------------------------------------------------------------------ |
// |
// Function : InitTxRing |
// |
// ------------------------------------------------------------------------ |
STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx) |
{ |
int i; |
volatile struct bufdesc *bp; |
|
p_eth_upd985xx->txring = |
(struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->tx_bufdesc[0] ); |
|
bp = p_eth_upd985xx->txring; |
|
for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ); i++, bp++ ) { |
bp->ptr = NULL; |
bp->attr = 0; |
} |
// Last one is a NULL link |
bp--; |
bp->ptr = NULL; |
bp->attr = ETH_BUF_D_L_LINK; |
|
ResetTxRing(p_eth_upd985xx); |
} |
|
// ------------------------------------------------------------------------ |
// |
// Function : ResetTxRing |
// |
// ------------------------------------------------------------------------ |
STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx) |
{ |
int i; |
volatile struct bufdesc *bp; |
bp = p_eth_upd985xx->txring; |
for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ) - 1; i++, bp++ ) { |
bp->attr = |
ETH_BUF_LAST | |
ETH_BUF_D_L_DATA | |
ETH_BUF_OWN_CPU | |
(ETH_BUF_SIZE & 0); |
} |
} |
|
// ------------------------------------------------------------------------ |
// |
// Function : TxDone (Called from delivery thread) |
// |
// This returns Tx's from the Tx Machine to the stack (ie. reports |
// completion) - allowing for missed interrupts, and so on. |
// ------------------------------------------------------------------------ |
|
STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx) |
{ |
struct cyg_netdevtab_entry *ndp; |
struct eth_drv_sc *sc; |
|
ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp); |
sc = (struct eth_drv_sc *)(ndp->device_instance); |
|
CHECK_NDP_SC_LINK(); |
|
if ( p_eth_upd985xx->tx_busy ) { |
cyg_uint32 ss; |
|
ss = INL( ETH_TXSR ); // Get tx status |
if ( ss & (ETH_TXSR_CSE | |
ETH_TXSR_TUDR | |
ETH_TXSR_TGNT | |
ETH_TXSR_LCOL | |
ETH_TXSR_ECOL | |
ETH_TXSR_TEDFR | |
ETH_TXSR_TDFR | |
ETH_TXSR_TBRO | |
ETH_TXSR_TMUL | |
ETH_TXSR_TDONE ) ) { |
// Then it finished; somehow... |
cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ]; |
|
// Turn off the transmitter (before the callback to the stack). |
OUTL( ETH_TXCR, 0 ); |
|
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E8 |
// Must take action after certain types of tx failure: |
if ( ss & (ETH_TXSR_TUDR | |
ETH_TXSR_LCOL | |
ETH_TXSR_ECOL) ) { |
p_eth_upd985xx->count_bad_tx_completion++; |
CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" ); |
eth_upd985xx_stop( sc ); |
eth_upd985xx_start( sc, NULL, 0 ); |
key = 0; // Important! Stop above already fed it back. |
} |
#endif |
|
#ifdef DEBUG_TRAFFIC |
os_printf("TxDone %d %x: KEY %x\n", |
p_eth_upd985xx->index, (int)p_eth_upd985xx, key ); |
#endif |
// Finished, ready for the next one |
p_eth_upd985xx->tx_keys[ 0 ] = 0; |
p_eth_upd985xx->tx_busy = 0; |
// Then tell the stack we are done: |
if (key) { |
(sc->funs->eth_drv->tx_done)( sc, key, |
0 == (p_eth_upd985xx->intrs & ETH_ISR_TABR) ); |
} |
} |
} |
} |
|
|
// ------------------------------------------------------------------------ |
// |
// Function : eth_upd985xx_can_send |
// |
// ------------------------------------------------------------------------ |
|
STATIC int |
eth_upd985xx_can_send(struct eth_drv_sc *sc) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
|
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
// Guard possible external entry points |
if ( ! p_eth_upd985xx->active ) |
return 0; |
|
return ! p_eth_upd985xx->tx_busy; |
} |
|
// ------------------------------------------------------------------------ |
// |
// Function : eth_upd985xx_send |
// |
// ------------------------------------------------------------------------ |
|
STATIC void |
eth_upd985xx_send(struct eth_drv_sc *sc, |
struct eth_drv_sg *sg_list, int sg_len, int total_len, |
unsigned long key) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
struct eth_drv_sg *last_sg; |
volatile struct bufdesc *bp; |
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3 |
struct eth_drv_sg local_sg[2]; |
#endif |
|
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
#ifdef DEBUG_TRAFFIC |
os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x\n", |
p_eth_upd985xx->index, (int)p_eth_upd985xx, sg_len, total_len, key ); |
#endif |
|
if ( ! p_eth_upd985xx->active ) |
return; // device inactive, no return |
|
CYG_ASSERT( ! p_eth_upd985xx->tx_busy, "Can't send when busy!" ); |
|
p_eth_upd985xx->tx_busy++; |
|
p_eth_upd985xx->tx_keys[0] = key; |
bp = &p_eth_upd985xx->txring[0]; // Current free tx |
CYG_ASSERT( 0 < sg_len, "sg_len underflow" ); |
CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" ); |
|
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3 |
// We must copy any Tx that is more than two SGs into just one buffer. |
if ( sg_len > 2 ) { |
cyg_uint8 *from_p, *to_p; |
to_p = &tx_databuf[0]; // normal cached address |
if ( sizeof( tx_databuf ) < total_len ) |
total_len = sizeof( tx_databuf ); |
for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) { |
int l; |
|
from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address |
l = sg_list->len; |
|
if ( l > total_len ) |
l = total_len; |
|
memcpy( to_p, from_p, l ); // All in cached memory |
to_p += l; |
total_len -= l; |
|
if ( 0 > total_len ) |
break; // Should exit via sg_last normally |
} |
|
// Set up SGs describing the single tx buffer |
total_len = to_p - &tx_databuf[0]; |
local_sg[0].buf = (CYG_ADDRESS)&tx_databuf[0]; |
local_sg[0].len = (CYG_ADDRWORD)total_len; |
local_sg[1].buf = (CYG_ADDRESS)0; |
local_sg[1].len = (CYG_ADDRWORD)0; |
|
// And make the subsequent code use it. |
sg_len = 1; |
sg_list = &local_sg[0]; |
} |
#endif |
|
for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) { |
cyg_uint8 *from_p; |
int l; |
|
from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address |
l = sg_list->len; |
|
if ( l > total_len ) |
l = total_len; |
|
// Ensure the mbuf contents really is in RAM where DMA can see it. |
// (Must round to cache lines apparantly for 4120) |
HAL_DCACHE_STORE( ((CYG_ADDRESS)from_p) &~(HAL_DCACHE_LINE_SIZE-1), |
l + HAL_DCACHE_LINE_SIZE ); |
|
bp->ptr = VIRT_TO_BUS( from_p ); // uncached real RAM address |
bp->attr &=~(ETH_BUF_LAST | ETH_BUF_SIZE); |
bp->attr |= ETH_BUF_SIZE & l; |
bp->attr |= ETH_BUF_D_L_DATA; |
|
total_len -= l; |
bp++; |
|
if ( 0 > total_len ) |
break; // Should exit via sg_last normally |
} |
|
CYG_ASSERT( bp > &p_eth_upd985xx->txring[0], "bp underflow" ); |
CYG_ASSERT( bp < &p_eth_upd985xx->txring[ |
NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc) |
], "bp underflow" ); |
|
bp--; |
bp->attr |= ETH_BUF_LAST; |
|
// Make the rest be null links |
for ( bp++; bp < |
&p_eth_upd985xx->txring[NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc)]; |
bp++ ) { |
bp->attr = ETH_BUF_D_L_LINK; |
bp->ptr = NULL; |
} |
|
CYG_ASSERT( 0 == total_len, "length mismatch in tx" ); |
CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" ); |
|
// And start off the tx system |
|
// Point the hardware at the list of buffers |
OUTL( ETH_TXDPR, (cyg_uint32)p_eth_upd985xx->txring ); |
// and start the tx. |
|
// Fault E4 - use only 8 for DTBS, not the previously recommended 16. |
// Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4 |
// but no config opt is provided. |
|
// Fault E7: ETH_TXCR_AFCE must not be used. |
// Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E7 |
// but no config opt is provided. |
|
OUTL( ETH_TXCR, ETH_TXCR_TXE | ETH_TXCR_DTBS_8 /* | ETH_TXCR_AFCE */ ); |
} |
|
#ifdef CYGPKG_NET |
// ------------------------------------------------------------------------ |
// |
// Function : eth_upd985xx_configure |
// |
// Return : 0 = It worked. |
// non0 = It failed. |
// ------------------------------------------------------------------------ |
|
STATIC int |
eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx, int promisc, int oversized) |
{ |
int ss; |
|
// We implement permission of oversize packets by changing LMAX (rather |
// than enabling HUGEN in ETH_MACC1) because we rely on only one |
// reception per rx descriptor. General oversize packets could eat |
// many rx descriptors and we would become ...confused. |
|
// Sanity check the numbers we're about to use. |
CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_OVERSIZE_PACKET_SIZE, |
"Oversize packet would overflow rx buffer" ); |
CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_ETHERNET_PACKET_SIZE, |
"Ethernet packet would overflow rx buffer" ); |
if ( oversized ) |
OUTL( ETH_LMAX, MAX_OVERSIZE_PACKET_SIZE ); |
else |
OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE ); |
|
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 |
ss = promisc ? 1 : 0; // avoid unused var warning |
p_eth_upd985xx->promisc = ss; |
#ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY |
// Then we must also set the mode in the chip |
ss = INL( ETH_AFR ); |
if ( promisc ) |
ss |= ETH_AFR_PRO; |
else |
ss &=~ETH_AFR_PRO; |
OUTL( ETH_AFR, ss ); |
#endif // CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY |
#else |
ss = INL( ETH_AFR ); |
if ( promisc ) |
ss |= ETH_AFR_PRO; |
else |
ss &=~ETH_AFR_PRO; |
OUTL( ETH_AFR, ss ); |
#endif |
return 0; // OK |
} |
#endif |
|
// ------------------------------------------------------------------------ |
// |
// Function : eth_upd985xx_ioctl |
// |
// ------------------------------------------------------------------------ |
STATIC int |
eth_upd985xx_ioctl(struct eth_drv_sc *sc, unsigned long key, |
void *data, int data_length) |
{ |
struct eth_upd985xx *p_eth_upd985xx; |
|
p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private; |
|
#ifdef DEBUG_IOCTL |
db_printf( "eth_upd985xx_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n", |
p_eth_upd985xx->index, p_eth_upd985xx, key, data, data_length ); |
#endif |
|
// DO NOT guard possible external entry points - want to be able eg. to |
// set a mac address of a down interface before bringing it up! |
|
switch ( key ) { |
|
#ifdef ETH_DRV_SET_MAC_ADDRESS |
case ETH_DRV_SET_MAC_ADDRESS: |
if ( 6 != data_length ) |
return -2; |
return eth_set_mac_address( p_eth_upd985xx, data ); |
#endif |
|
#ifdef ETH_DRV_GET_IF_STATS_UD |
case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE |
#endif |
// drop through |
#ifdef ETH_DRV_GET_IF_STATS |
case ETH_DRV_GET_IF_STATS: |
#endif |
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD) |
{ |
struct ether_drv_stats *p = (struct ether_drv_stats *)data; |
int i; |
|
// Chipset entry is no longer supported; RFC1573. |
for ( i = 0; i < SNMP_CHIPSET_LEN; i++ ) |
p->snmp_chipset[i] = 0; |
|
// This perhaps should be a config opt, so you can make up your own |
// description, or supply it from the instantiation. |
strcpy( p->description, "NEC uPD985xx on-chip ethernet (CANDY)" ); |
// CYG_ASSERT( 48 > strlen(p->description), "Description too long" ); |
|
i = eth_upd985xx_status( p_eth_upd985xx ); |
|
if ( !( i & PHY_STATUS_LINK) ) { |
p->operational = 2; // LINK DOWN |
p->duplex = 1; // UNKNOWN |
p->speed = 0; |
} |
else { |
p->operational = 3; // LINK UP |
p->duplex = (i & PHY_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX |
p->speed = ((i & PHY_STATUS_100MBPS) ? 100 : 10) * 1000000; |
} |
|
// Admit to it... |
p->supports_dot3 = true; |
|
// Those commented out are not available on this chip. |
p->tx_good = INL( ETH_TPCT ) ; |
p->tx_max_collisions = INL( ETH_TXCL ) ; |
p->tx_late_collisions = INL( ETH_TLCL ) ; |
//p->tx_underrun = INL( ) ; |
p->tx_carrier_loss = INL( ETH_TCSE ) ; |
p->tx_deferred = INL( ETH_TDFR ) + |
INL( ETH_TXDF ) ; |
//p->tx_sqetesterrors = INL( ) ; |
p->tx_single_collisions = INL( ETH_TSCL ) ; |
p->tx_mult_collisions = INL( ETH_TMCL ) ; |
p->tx_total_collisions = INL( ETH_TSCL ) + |
INL( ETH_TMCL ) + |
INL( ETH_TLCL ) + |
INL( ETH_TXCL ) ; |
p->rx_good = INL( ETH_RPKT ) ; |
p->rx_crc_errors = INL( ETH_RFCS ) ; |
p->rx_align_errors = INL( ETH_RALN ) ; |
p->rx_resource_errors = p_eth_upd985xx->count_rx_resource; |
//p->rx_overrun_errors = INL( ) ; |
//p->rx_collisions = INL( ) ; |
p->rx_short_frames = INL( ETH_RUND ) ; |
p->rx_too_long_frames = INL( ETH_ROVR ) ; |
p->rx_symbol_errors = INL( ETH_RXUO ) ; |
|
p->interrupts = p_eth_upd985xx->count_interrupts; |
p->rx_count = INL( ETH_RBYT ) ; |
p->rx_deliver = INL( ETH_RPKT ) ; |
p->rx_resource = p_eth_upd985xx->count_rx_resource; |
p->rx_restart = p_eth_upd985xx->count_rx_resource + |
p_eth_upd985xx->count_rx_restart; |
p->tx_count = INL( ETH_TBYT ) ; |
p->tx_complete = INL( ETH_TPCT ) ; |
p->tx_dropped = INL( ETH_TNCL ) ; |
|
p->tx_queue_len = 1; |
|
return 0; // OK |
} |
#endif |
|
default: |
break; |
} |
return -1; |
} |
|
// ------------------------------------------------------------------------ |
|
// EOF if_upd985xx.c |