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/sh
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/hs7729pci/v2_0/cdl/sh_hs7729pci_eth_drivers.cdl
0,0 → 1,130
# ==================================================================== |
# |
# sh_hs7729pci_eth_drivers.cdl |
# |
# Ethernet drivers - support for VIA Rhine ethernet controller |
# on the Hitachi HS7729PCI 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-05-31 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_SH_HS7729PCI { |
display "SH HS7729PCI board ethernet driver" |
description "Ethernet driver for SH HS7729PCI board." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_SH_SH7729_HS7729PCI |
|
include_dir cyg/io |
|
# FIXME: This really belongs in the VIA_RHINE package |
cdl_interface CYGINT_DEVS_ETH_VIA_RHINE_REQUIRED { |
display "VIA Rhine ethernet driver required" |
} |
|
define_proc { |
puts $::cdl_system_header "/***** ethernet driver proc output start *****/" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_VIA_RHINE_INL <cyg/io/devs_eth_sh_hs7729pci.inl>" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_VIA_RHINE_CFG <pkgconf/devs_eth_sh_hs7729pci.h>" |
puts $::cdl_system_header "/***** ethernet driver proc output end *****/" |
} |
|
cdl_component CYGPKG_DEVS_ETH_SH_HS7729PCI_ETH0 { |
display "HS7729PCI ethernet port 0 driver" |
flavor bool |
default_value 1 |
description " |
This option includes the ethernet device driver for the |
HS7729PCI port 0." |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH0 |
implements CYGINT_DEVS_ETH_VIA_RHINE_REQUIRED |
|
cdl_option CYGNUM_DEVS_ETH_SH_HS7729PCI_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_SH_HS7729PCI_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_SH_HS7729PCI_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 |
HS7729PCI port 0." |
} |
|
cdl_component CYGSEM_DEVS_ETH_SH_HS7729PCI_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
calculated 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_SH_HS7729PCI_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"} |
description "The ethernet station address" |
} |
} |
} |
} |
/hs7729pci/v2_0/include/devs_eth_sh_hs7729pci.inl
0,0 → 1,100
//========================================================================== |
// |
// devs_eth_sh_hs7729pci.inl |
// |
// HS7729PCI 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-05-31 |
// Purpose: HS7729PCI ethernet defintions |
//####DESCRIPTIONEND#### |
//========================================================================== |
|
#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR |
|
#ifdef __WANT_CONFIG |
|
#define CYGHWR_VIA_RHINE_PCI_MEM_MAP_BASE (CYGARC_UNCACHED_ADDRESS(&CYGMEM_SECTION_pci_window[0])) |
#define CYGHWR_VIA_RHINE_PCI_MEM_MAP_SIZE (CYGMEM_SECTION_pci_window_SIZE) |
|
#endif // __WANT_CONFIG |
|
|
#ifdef __WANT_DEVS |
|
#ifdef CYGPKG_DEVS_ETH_SH_HS7729PCI_ETH0 |
|
static rhine_priv_data via_rhine_eth0_priv_data = { |
#ifdef CYGSEM_DEVS_ETH_SH_HS7729PCI_ETH0_SET_ESA |
enaddr : CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_ESA, |
#endif |
config_esa : NULL, // rely on the hardwired address for now |
rx_ring : NULL, |
rx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_SH_HS7729PCI_ETH0_RX_RING_SIZE*/, |
rx_ring_log_cnt : 2, |
tx_ring : NULL, |
tx_ring_cnt : (1<<2) /*CYGNUM_DEVS_ETH_SH_HS7729PCI_ETH0_TX_RING_SIZE*/, |
tx_ring_log_cnt : 2, |
}; |
|
static rhine_priv_data *rhine_priv_array[1] = {&via_rhine_eth0_priv_data}; |
|
ETH_DRV_SC(via_rhine_sc, |
&via_rhine_eth0_priv_data, // Driver specific data |
CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_NAME, |
rhine_start, |
rhine_stop, |
rhine_control, |
rhine_can_send, |
rhine_send, |
rhine_recv, |
rhine_deliver, // "pseudoDSR" called from fast net thread |
rhine_poll, // poll function, encapsulates ISR and DSR |
rhine_int_vector); |
|
NETDEVTAB_ENTRY(rhine_netdev, |
"rhine_" CYGDAT_DEVS_ETH_SH_HS7729PCI_ETH0_NAME, |
via_rhine_init, |
&via_rhine_sc); |
#endif // CYGPKG_DEVS_ETH_SH_HS7729PCI_ETH0 |
|
#endif // __WANT_DEVS |
|
// EOF devs_eth_sh_hs7729pci.inl |
/hs7729pci/v2_0/ChangeLog
0,0 → 1,58
2001-06-27 Jesper Skov <jskov@redhat.com> |
|
* cdl/sh_hs7729pci_eth_drivers.cdl: Implements net drivers. |
|
* include/devs_eth_sh_hs7729pci.inl: Use uncached addresses for |
shared mem. Removed fix me. |
|
2001-06-26 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_hs7729pci.inl: Leave PCI definitions to |
platform HAL. |
|
2001-06-25 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_hs7729pci.inl: Split in config and driver |
parts, fix some buglets. |
|
2001-05-31 Jesper Skov <jskov@redhat.com> |
|
* cdl/sh_hs7729pci_eth_drivers.cdl: Platform specific |
information required to use the generic VIA Rhine driver for the |
HS7729PCI platform. |
* include/devs_eth_sh_hs7729pci.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#### |
//=========================================================================== |
/se77x9/v2_0/cdl/sh_se77x9_eth_drivers.cdl
0,0 → 1,109
# ==================================================================== |
# |
# sh_se77x9_eth_drivers.cdl |
# |
# Ethernet drivers - support for NS DP83902A ethernet controller |
# on the Hitachi SE77X9 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-06-13 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_SH_SE77X9 { |
display "SH SE77X9 board ethernet driver" |
description "Ethernet driver for SH SE77X9 board." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_SH_SH77X9_SE77X9 |
|
include_dir cyg/io |
|
# FIXME: This really belongs in the NS DP83902A package |
cdl_interface CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED { |
display "NS DP83902A ethernet driver required" |
} |
|
define_proc { |
puts $::cdl_system_header "/***** ethernet driver proc output start *****/" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_INL <cyg/io/devs_eth_sh_se77x9.inl>" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NS_DP83902A_CFG <pkgconf/devs_eth_sh_se77x9.h>" |
puts $::cdl_system_header "/***** ethernet driver proc output end *****/" |
} |
|
cdl_component CYGPKG_DEVS_ETH_SH_SE77X9_ETH0 { |
display "SE77X9 ethernet port driver" |
flavor bool |
default_value 1 |
description " |
This option includes the ethernet device driver for the |
SE77X9 port." |
|
implements CYGINT_DEVS_ETH_NS_DP83902A_REQUIRED |
|
cdl_option CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_NAME { |
display "Device name for the ETH0 ethernet driver" |
flavor data |
default_value {"\"eth0\""} |
description " |
This option sets the name of the ethernet device." |
} |
|
cdl_component CYGSEM_DEVS_ETH_SH_SE77X9_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
calculated 1 |
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_SH_SE77X9_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"} |
description "The ethernet station address" |
} |
} |
} |
} |
/se77x9/v2_0/include/devs_eth_sh_se77x9.inl
0,0 → 1,143
//========================================================================== |
// |
// devs_eth_sh_se77x9.inl |
// |
// SE77X9 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-06-13 |
// Purpose: SE77X9 ethernet defintions |
// |
// FIXME: M17 contains an EPROM. May contain the ESA, but don't |
// know how to access it. |
// |
//####DESCRIPTIONEND#### |
//========================================================================== |
|
#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR |
#include <cyg/hal/hal_if.h> |
|
#ifdef __WANT_CONFIG |
|
|
|
#define CYGHWR_NS_DP83902A_PLF_RESET(_dp_) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT16(_dp_->reset, 0x0000); \ |
CYGACC_CALL_IF_DELAY_US(10); \ |
HAL_WRITE_UINT16(_dp_->reset, 0x0100); \ |
CYG_MACRO_END |
|
#define DP_IN(_b_, _o_, _d_) \ |
CYG_MACRO_START \ |
cyg_uint16 _t; \ |
HAL_READ_UINT16 ((cyg_addrword_t)(_b_)+2*(_o_), _t); \ |
(_d_) = (_t >> 8) & 0xff; \ |
CYG_MACRO_END |
|
#define DP_OUT(_b_, _o_, _d_) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT16((cyg_addrword_t)(_b_)+2*(_o_), (_d_)<<8); \ |
CYG_MACRO_END |
|
#define DP_IN_DATA(_b_, _d_) \ |
CYG_MACRO_START \ |
cyg_uint16 _t; \ |
HAL_READ_UINT16 ((cyg_addrword_t)(_b_), _t); \ |
(_d_) = ((_t >> 8) & 0xff) | ((_t & 0xff) << 8); \ |
CYG_MACRO_END |
|
#define DP_OUT_DATA(_b_, _d_) \ |
CYG_MACRO_START \ |
cyg_uint16 _t; \ |
_t = (_d_); \ |
(_t) = (((_t) >> 8) & 0xff) | ((_t & 0xff) << 8); \ |
HAL_WRITE_UINT16((cyg_addrword_t)(_b_), _t); \ |
CYG_MACRO_END |
|
#define CYGHWR_NS_DP83902A_PLF_16BIT_DATA |
#define CYGHWR_NS_DP83902A_PLF_BROKEN_TX_DMA |
|
#endif // __WANT_CONFIG |
|
|
#ifdef __WANT_DEVS |
|
#ifdef CYGPKG_DEVS_ETH_SH_SE77X9_ETH0 |
|
static dp83902a_priv_data_t dp83902a_eth0_priv_data = { |
base : (cyg_uint8*) 0xb0000000, |
data : (cyg_uint8*) 0xb0040000, |
reset: (cyg_uint8*) 0xb0080000, |
interrupt: CYGNUM_HAL_INTERRUPT_LAN, |
tx_buf1: 0x80, |
tx_buf2: 0x88, |
rx_buf_start: 0x90, |
rx_buf_end: 0xff, |
#ifdef CYGSEM_DEVS_ETH_SH_SE77X9_ETH0_SET_ESA |
esa : CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_ESA, |
hardwired_esa : true, |
#else |
hardwired_esa : false, |
#endif |
}; |
|
ETH_DRV_SC(dp83902a_sc, |
&dp83902a_eth0_priv_data, // Driver specific data |
CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_NAME, |
dp83902a_start, |
dp83902a_stop, |
dp83902a_control, |
dp83902a_can_send, |
dp83902a_send, |
dp83902a_recv, |
dp83902a_deliver, // "pseudoDSR" called from fast net thread |
dp83902a_poll, // poll function, encapsulates ISR and DSR |
dp83902a_int_vector); |
|
NETDEVTAB_ENTRY(dp83902a_netdev, |
"dp83902a_" CYGDAT_DEVS_ETH_SH_SE77X9_ETH0_NAME, |
dp83902a_init, |
&dp83902a_sc); |
#endif // CYGPKG_DEVS_ETH_SH_SE77X9_ETH0 |
|
#endif // __WANT_DEVS |
|
// EOF devs_eth_sh_se77x9.inl |
/se77x9/v2_0/ChangeLog
0,0 → 1,76
2001-10-16 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_se77x9.inl: Added buffer parameters. |
|
2001-10-10 Gary Thomas <gthomas@redhat.com> |
|
* include/devs_eth_sh_se77x9.inl (CYGHWR_NS_DP83902A_PLF_RESET): |
Change in calling convention - now uses soft "reset" address from |
device specific data. |
|
2001-07-12 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_se77x9.inl: Fix typo. |
|
2001-06-16 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_se77x9.inl: Use proper interrupt vector name. |
|
2001-06-15 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_se77x9.inl: Split in devs/config parts. Use |
proper delay in reset code. |
Removed unused delays. Tell driver DMA HW is broken (I suspect the |
FPGA - and yes, this took a very long time indeed to track down!). |
|
* cdl/sh_se77x9_eth_drivers.cdl: Removed ring size options. Force |
use of ESA until I figure out how to read the EPROM. |
|
2001-06-14 Jesper Skov <jskov@redhat.com> |
|
* cdl/sh_se77x9_eth_drivers.cdl: Made _SET_ESA option configurable. |
|
* include/devs_eth_sh_se77x9.inl: Added DATA I/O macros since the |
platform needs to be treated like it was BE when accessing the |
external devices. |
|
2001-06-13 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_se77x9.inl: Remove debug hack. |
|
* Created. |
|
//=========================================================================== |
//####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#### |
//=========================================================================== |
/etherc/v2_0/cdl/sh_etherc_eth_drivers.cdl
0,0 → 1,105
# ==================================================================== |
# |
# sh_etherc_eth_drivers.cdl |
# |
# Ethernet drivers - support for SH EtherC ethernet controllers |
# |
# ==================================================================== |
#####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: 2002-01-30 |
# |
#####DESCRIPTIONEND#### |
# |
# ==================================================================== |
|
cdl_package CYGPKG_DEVS_ETH_SH_ETHERC { |
display "SH EtherC CPU module ethernet driver" |
description "Ethernet driver for SH EtherC CPU module controller." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
|
active_if CYGINT_DEVS_ETH_SH_ETHERC_REQUIRED |
|
include_dir . |
include_files ; # none _exported_ whatsoever |
compile -library=libextras.a if_etherc.c |
|
define_proc { |
puts $::cdl_header "#include <pkgconf/system.h>"; |
puts $::cdl_header "#include CYGDAT_DEVS_ETH_SH_ETHERC_CFG"; |
} |
|
cdl_option CYGNUM_DEVS_ETH_SH_ETHERC_DEV_COUNT { |
display "Number of supported interfaces." |
calculated { CYGINT_DEVS_ETH_SH_ETHERC_REQUIRED } |
flavor data |
description " |
This option selects the number of ethernet interfaces to |
be supported by the driver." |
} |
|
cdl_option CYGSEM_DEVS_ETH_SH_ETHERC_FORCE_10MBPS { |
display "Force negotiation of a 10Mbps link" |
flavor bool |
default_value 0 |
description " |
If this option is enabled then the driver will force the chipset |
to negotiate only for a 10Mbps link (rather than a 100Mbps |
link)." |
} |
|
cdl_component CYGPKG_DEVS_ETH_SH_ETHERC_OPTIONS { |
display "ETHERC ethernet driver build options" |
flavor none |
no_define |
|
cdl_option CYGPKG_DEVS_ETH_SH_ETHERC_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 EtherC ethernet driver package. |
These flags are used in addition |
to the set of global flags." |
} |
} |
} |
/etherc/v2_0/ChangeLog
0,0 → 1,112
2002-06-14 Gary Thomas <gary@chez-thomas.org> |
|
* src/if_etherc.c: |
Need to include <pkgconf/io_eth_drivers.h> for proper configuration |
of stand-alone (polled) vs. system (interrupt driven) mode. |
|
2002-03-18 Jonathan Larmour <jlarmour@redhat.com> |
|
* src/if_etherc.c (etherc_RxEvent): ensure Receive Request is always |
enabled. |
|
2002-03-18 Jesper Skov <jskov@redhat.com> |
|
* src/sh_etherc.h: Removed some unused definitions. |
|
* src/if_etherc.c (etherc_poll): Move the bit of code that ensures RX |
enabling down to the exit of the function so it is always executed. |
|
2002-03-07 Jesper Skov <jskov@redhat.com> |
|
* src/if_etherc.c: Initialize interrupt field. Skip tests for |
suspended device - they are wrong. |
|
* src/phyter.inl (_MII_RENEGOTIATE): split delay out in new |
_MII_RENEGOTIATION_WAIT macro. |
(_MII_SPEED_FORCE_10MB): Added. |
|
* src/if_etherc.c (sh_etherc_init): Added forced-10Mbit |
option. Cleaned up some fix mes. |
|
2002-03-06 Jesper Skov <jskov@redhat.com> |
|
* src/if_etherc.c: Disabled PHY errata workaround. Make sure |
promisuous mode is disabled per default. Don't clear the wrap-bit |
of the RD table. |
|
* src/sh_etherc.h: Added a definition. |
|
2002-02-21 Jesper Skov <jskov@redhat.com> |
|
* src/if_etherc.c (_MII_HAS_EXTENDED): define. |
|
2002-02-20 Jesper Skov <jskov@redhat.com> |
|
* src/if_etherc.c: Pad packets to minimum ethernet frame |
length. Added PHY erratum workaround. |
|
* src/sh_etherc.h: Remove debug setting. |
|
* src/phyter.inl: Added here for now. |
|
* src/if_etherc.c: Include phyter.inl. |
(sh_etherc_init): Fix ring initialization. Set to continuous |
reception. |
(etherc_start): Tell FIFO to dump data in memory. |
(etherc_control): Use _MII functions to gather necessary |
information. |
(etherc_can_send): Same. |
Added _MII accessor macros and some extra debug code. |
|
2002-02-19 Jesper Skov <jskov@redhat.com> |
|
* src/sh_etherc.h: Moved debug print code here. Tweak debug |
functions. |
* src/if_etherc.c: Tweaked the init and TX code some. Don't check |
for CYGARC_REG_EESR_ECI in the poll function as it does not appear |
to get set when other requests are. Moved debug print code to |
header file. |
|
* src/sh_etherc.h: More definitions. |
|
* src/if_etherc.c: Fix typos. Add interrupt attach code. Update |
remaining functions to support this controller. |
|
2002-01-30 Jesper Skov <jskov@redhat.com> |
|
* File structure cloned from PCNet driver. |
|
//=========================================================================== |
//####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#### |
//=========================================================================== |
/etherc/v2_0/src/if_etherc.c
0,0 → 1,1127
//========================================================================== |
// |
// dev/if_etherc.c |
// |
// Ethernet device driver for SH EtherC CPU module controller |
// |
//========================================================================== |
//####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: 2002-01-30 |
// Purpose: |
// Description: Hardware driver for SH EtherC CPU module controller |
// |
// Notes: The KEEP_STATISTICS code is not implemented yet. Look |
// for FIXME macro. |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <pkgconf/system.h> |
#include <pkgconf/devs_eth_sh_etherc.h> |
#include <pkgconf/io_eth_drivers.h> |
|
#include <cyg/infra/cyg_type.h> |
#include <cyg/hal/hal_arch.h> |
#include <cyg/hal/hal_intr.h> |
#include <cyg/infra/cyg_ass.h> |
#include <cyg/infra/diag.h> |
#include <cyg/hal/drv_api.h> |
#include <cyg/hal/hal_if.h> // delays |
#include <string.h> |
#include <cyg/io/eth/netdev.h> |
#include <cyg/io/eth/eth_drv.h> |
#ifdef CYGPKG_NET |
#include <pkgconf/net.h> |
#include <cyg/kernel/kapi.h> |
#include <net/if.h> /* Needed for struct ifnet */ |
#include <pkgconf/io_eth_drivers.h> |
#endif |
#include CYGHWR_MEMORY_LAYOUT_H |
|
#define FIXME 0 |
|
// Set size so it is 16-byte aligned |
#define _BUF_SIZE (1544+8) |
|
#define IEEE_8023_MIN_FRAME 64 // Smallest possible ethernet frame |
|
#ifdef CYGPKG_INFRA_DEBUG |
// Then we log, OOI, the number of times we get a bad packet number |
// from the tx done fifo. |
int etherc_txfifo_good = 0; |
int etherc_txfifo_bad = 0; |
#endif |
|
#include "sh_etherc.h" |
#define __WANT_DEVS |
#include CYGDAT_DEVS_ETH_SH_ETHERC_INL |
#undef __WANT_DEVS |
|
static void etherc_poll(struct eth_drv_sc *sc); |
|
static cyg_uint16 etherc_read_MII(struct etherc_priv_data *cpd, int id, int reg); |
static void etherc_write_MII(struct etherc_priv_data *cpd, int id, int reg, cyg_uint16 value); |
#define _MII_READ(_priv_, _id_, _reg_) etherc_read_MII(_priv_, _id_, _reg_) |
#define _MII_WRITE(_priv_, _id_, _reg_, _val_) etherc_write_MII(_priv_, _id_, _reg_, _val_) |
#define _MII_HAS_EXTENDED |
#include "phyter.inl" |
|
#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE |
// This ISR is called when the ethernet interrupt occurs |
static cyg_uint32 |
etherc_isr(cyg_vector_t vector, cyg_addrword_t data) |
{ |
struct etherc_priv_data *cpd = (struct etherc_priv_data *)data; |
|
DEBUG_FUNCTION(); |
|
INCR_STAT( interrupts ); |
|
cyg_drv_interrupt_mask(cpd->interrupt); |
cyg_drv_interrupt_acknowledge(cpd->interrupt); |
return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR |
} |
|
static void |
etherc_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data) |
{ |
// This conditioning out is necessary because of explicit calls to this |
// DSR - which would not ever be called in the case of a polled mode |
// usage ie. in RedBoot. |
#ifdef CYGPKG_IO_ETH_DRIVERS_NET |
struct etherc_priv_data* cpd = (struct etherc_priv_data *)data; |
struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(cpd->ndp); |
struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance); |
|
// but here, it must be a *sc: |
eth_drv_dsr( vector, count, (cyg_addrword_t)sc ); |
#else |
# ifndef CYGPKG_REDBOOT |
# error Empty Etherc ethernet DSR is compiled. Is this what you want? |
# endif |
#endif |
} |
#endif // CYGPKG_IO_ETH_DRIVERS_STAND_ALONE |
|
|
// The deliver function (ex-DSR) handles the ethernet [logical] processing |
static void |
etherc_deliver(struct eth_drv_sc *sc) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
|
DEBUG_FUNCTION(); |
|
// Service the interrupt: |
etherc_poll(sc); |
// Allow interrupts to happen again |
cyg_drv_interrupt_unmask(cpd->interrupt); |
} |
|
static int |
etherc_int_vector(struct eth_drv_sc *sc) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
|
return (cpd->interrupt); |
} |
|
|
static bool |
sh_etherc_init(struct cyg_netdevtab_entry *tab) |
{ |
struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance; |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
cyg_uint8 *p, *d; |
cyg_uint32 reg; |
int i; |
bool esa_configured = true; |
|
DEBUG_FUNCTION(); |
|
cpd->txbusy = 0; |
|
// Ensure that addresses of ring descriptors and buffers are properly aligned |
// and in uncached memory. |
cpd->rx_buffers = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->rx_buffers+16-1) & ~(16-1)); |
cpd->rx_ring = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->rx_ring+16-1) & ~(16-1)); |
cpd->tx_buffers = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->tx_buffers+16-1) & ~(16-1)); |
cpd->tx_ring = (cyg_uint8*)CYGARC_UNCACHED_ADDRESS(((cyg_uint32)cpd->tx_ring+16-1) & ~(16-1)); |
|
#if DEBUG & 8 |
db_printf("Etherc at base 0x%08x\n", cpd->base); |
#endif |
|
// Find ESA - check possible sources in sequence and stop when |
// one provides the ESA: |
// RedBoot option (via provide_esa) |
// Compile-time configuration |
// EEPROM |
// <fail configuration of device> |
if (NULL != cpd->provide_esa) { |
esa_configured = cpd->provide_esa(cpd); |
# if DEBUG & 8 |
if (esa_configured) |
diag_printf("Got ESA from RedBoot option\n"); |
# endif |
} |
if (!esa_configured && cpd->hardwired_esa) { |
// ESA is already set in cpd->esa[] |
esa_configured = true; |
} |
if (!esa_configured) { |
# if DEBUG & 8 |
diag_printf("EtherC - no EEPROM, static ESA or RedBoot config option.\n"); |
# endif |
return false; |
} |
|
#if DEBUG & 9 |
db_printf("ETHERC ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", |
cpd->esa[0], cpd->esa[1], cpd->esa[2], |
cpd->esa[3], cpd->esa[4], cpd->esa[5] ); |
#endif |
|
// Prepare RX and TX rings |
p = cpd->rx_ring; |
d = cpd->rx_buffers; |
for (i = 0; i < cpd->rx_ring_cnt; i++) { |
_SU32(p, ETHERC_RD_STAT) = ETHERC_RD_STAT_RACT | ETHERC_RD_STAT_RFP_OTO; |
_SU16(p, ETHERC_RD_RBL) = _BUF_SIZE; |
_SU16(p, ETHERC_RD_RDL) = 0; |
_SU32(p, ETHERC_RD_RBA) = (cyg_uint32)d; |
_SU32(p, ETHERC_RD_PAD) = 0; |
p += ETHERC_RD_SIZE; |
d += _BUF_SIZE; |
} |
// Set ring-end marker |
p -= ETHERC_RD_SIZE; |
_SU32(p, ETHERC_RD_STAT) |= ETHERC_RD_STAT_RDLE; |
cpd->rx_ring_next = 0; |
|
p = cpd->tx_ring; |
d = cpd->tx_buffers; |
for (i = 0; i < cpd->tx_ring_cnt; i++) { |
_SU32(p, ETHERC_TD_STAT) = ETHERC_TD_STAT_TFP_OTO; |
_SU16(p, ETHERC_TD_TDL) = 0; |
_SU16(p, ETHERC_TD_PAD0) = 0; |
_SU32(p, ETHERC_TD_TBA) = (cyg_uint32)d; |
_SU32(p, ETHERC_TD_PAD1) = 0; |
p += ETHERC_TD_SIZE; |
d += _BUF_SIZE; |
} |
// Set ring-end marker |
p -= ETHERC_RD_SIZE; |
_SU32(p, ETHERC_TD_STAT) |= ETHERC_TD_STAT_TDLE; |
cpd->tx_ring_free = cpd->tx_ring_alloc = cpd->tx_ring_owned = 0; |
|
// Reset ethernet module, then wait for (at least) 16 clocks. |
put_reg(cpd, _REG_EDMR, CYGARC_REG_EDMR_SWR | CYGARC_REG_EDMR_DL16); |
for (i = 0; i < 16; i++); |
put_reg(cpd, _REG_EDMR, CYGARC_REG_EDMR_DL16); |
|
// Program ring data into controller |
put_reg(cpd, _REG_RDLAR, (cyg_uint32)cpd->rx_ring); |
put_reg(cpd, _REG_TDLAR, (cyg_uint32)cpd->tx_ring); |
|
// Set ESA |
put_reg(cpd, _REG_MAHR, (cpd->esa[0] << 24) | (cpd->esa[1] << 16) | (cpd->esa[2] << 8) | cpd->esa[3]); |
put_reg(cpd, _REG_MALR, (cpd->esa[4] << 8) | cpd->esa[5]); |
|
// Set receive mode: receive continuously |
put_reg(cpd, _REG_RCR, CYGARC_REG_RCR_RNC); |
|
// Stop controller, set duplex mode |
put_reg(cpd, _REG_ECMR, CYGARC_REG_ECMR_DM); |
cpd->active = 0; |
|
// Clear pending interrupt flags |
reg = get_reg(cpd, _REG_EESR); |
put_reg(cpd, _REG_EESR, reg); |
|
#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE |
// Attach ISR/DSRs. |
cpd->interrupt = CYGNUM_HAL_INTERRUPT_EDMAC_EINT; |
cyg_drv_interrupt_create(cpd->interrupt, |
1, // Priority |
(cyg_addrword_t)cpd, // Data item passed to ISR & DSR |
etherc_isr, // ISR |
etherc_dsr, // DSR |
&cpd->interrupt_handle, // handle to intr obj |
&cpd->interrupt_object ); // space for int obj |
|
cyg_drv_interrupt_attach(cpd->interrupt_handle); |
cyg_drv_interrupt_unmask(cpd->interrupt); |
put_reg(cpd, _REG_EESIPR, CYGARC_REG_EESIPR_TCIP|CYGARC_REG_EESIPR_FRIP); |
#if DEBUG & 8 |
db_printf("Attached interrupt on vector %d\n", cpd->interrupt); |
#endif |
#endif |
|
// Record the net dev pointer |
cpd->ndp = (void *)tab; |
|
|
// Initialize the PHY |
#ifdef CYGSEM_DEVS_ETH_SH_ETHERC_FORCE_10MBPS |
#if DEBUG & 8 |
db_printf("Forcing 10Mb link\n"); |
#endif |
_MII_SPEED_FORCE_10MB(cpd, 1); |
_MII_RENEGOTIATE(cpd, 1); |
#else |
// Wait for automatic negotiation to complete |
_MII_RENEGOTIATION_WAIT(cpd, 1); |
#endif |
|
// Initialize upper level driver |
(sc->funs->eth_drv->init)(sc, cpd->esa); |
|
#if DEBUG & 9 |
db_printf("Done\n"); |
#endif |
return true; |
} |
|
static void |
etherc_suspend(struct etherc_priv_data *cpd) |
{ |
cyg_uint32 reg; |
#if 0 |
bool still_active; |
#endif |
|
reg = get_reg(cpd, _REG_ECMR); |
reg &= ~(CYGARC_REG_ECMR_TE | CYGARC_REG_ECMR_RE); |
put_reg(cpd, _REG_ECMR, reg); |
|
#if 0 // |
// Try to find out if controller stopped. Supposedly, it should |
// communicate this by clearing the active signal of the active |
// RX/TX descriptors. |
|
// Check RX |
do { |
still_active = false; |
reg = get_reg(cpd, _REG_RDFAR); |
#if 1 |
{ |
int i; |
cyg_uint8* p; |
p = cpd->rx_ring; |
for (i = 0; i < cpd->rx_ring_cnt; i++) { |
if ((cyg_uint32)p == reg) { |
if (_SU32(reg, ETHERC_RD_STAT) & ETHERC_RD_STAT_RACT) { |
still_active = true; |
break; |
} |
} |
} |
} |
#else |
if (_SU32(reg, ETHERC_RD_STAT) & ETHERC_RD_STAT_RACT) |
still_active = true; |
#endif |
} while (still_active); |
|
// Check TX |
do { |
still_active = false; |
reg = get_reg(cpd, _REG_TDFAR); |
#if 1 |
{ |
int i; |
cyg_uint8* p; |
p = cpd->tx_ring; |
for (i = 0; i < cpd->tx_ring_cnt; i++) { |
if ((cyg_uint32)p == reg) { |
if (_SU32(reg, ETHERC_TD_STAT) & ETHERC_TD_STAT_TACT) { |
still_active = true; |
break; |
} |
} |
} |
} |
#else |
if (_SU32(reg, ETHERC_TD_STAT) & ETHERC_TD_STAT_TACT) |
still_active = true; |
#endif |
} while (still_active); |
|
db_printf("all done\n"); |
#endif |
cpd->active = 0; |
} |
|
static void |
etherc_stop(struct eth_drv_sc *sc) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
|
DEBUG_FUNCTION(); |
|
etherc_suspend(cpd); |
} |
|
// |
// 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 |
etherc_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags) |
{ |
cyg_uint32 reg, prm_mode = 0; |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
#ifdef CYGPKG_NET |
struct ifnet *ifp = &sc->sc_arpcom.ac_if; |
#endif |
DEBUG_FUNCTION(); |
|
// If device is already active, suspend it |
if (cpd->active) { |
etherc_suspend(cpd); |
} |
|
#ifdef CYGPKG_NET |
if (( 0 |
#ifdef ETH_DRV_FLAGS_PROMISC_MODE |
!= (flags & ETH_DRV_FLAGS_PROMISC_MODE) |
#endif |
) || (ifp->if_flags & IFF_PROMISC) |
) { |
// Then we select promiscuous mode. |
prm_mode = CYGARC_REG_ECMR_PRM; |
} |
#endif |
|
// Unsuspend the device |
reg = get_reg(cpd, _REG_ECMR); |
reg |= CYGARC_REG_ECMR_TE | CYGARC_REG_ECMR_RE; |
reg &= ~CYGARC_REG_ECMR_PRM; |
reg |= prm_mode; |
put_reg(cpd, _REG_ECMR, reg); |
|
put_reg(cpd, _REG_EDRRR, CYGARC_REG_EDRRR_RR); |
|
cpd->active = 1; |
} |
|
// |
// This routine is called to perform special "control" opertions |
// |
static int |
etherc_control(struct eth_drv_sc *sc, unsigned long key, |
void *data, int data_length) |
{ |
cyg_uint8 *esa = (cyg_uint8 *)data; |
int i, res; |
cyg_uint16 reg; |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
cyg_bool was_active = cpd->active; |
|
DEBUG_FUNCTION(); |
|
// If device is already active, suspend it |
if (cpd->active) { |
etherc_suspend(cpd); |
} |
|
res = 0; // expect success |
switch (key) { |
case ETH_DRV_SET_MAC_ADDRESS: |
#if 9 & DEBUG |
db_printf("ETHERC - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n", |
esa[0], esa[1], esa[2], esa[3], esa[4], esa[5] ); |
#endif // DEBUG |
|
for ( i = 0; i < sizeof(cpd->esa); i++ ) |
cpd->esa[i] = esa[i]; |
put_reg(cpd, _REG_MAHR,(cpd->esa[0] << 24) | (cpd->esa[1] << 16) | (cpd->esa[2] << 8) | cpd->esa[3]); |
put_reg(cpd, _REG_MALR, (cpd->esa[4] << 8) | cpd->esa[5]); |
break; |
|
#ifdef ETH_DRV_GET_MAC_ADDRESS |
case ETH_DRV_GET_MAC_ADDRESS: |
// Extract the MAC address that is in the chip, and tell the |
// system about it. |
cyg_uint32 reg; |
reg = get_reg(cpd, _REG_MAHR); |
cpd->esa[0] = (reg >> 24) & 0xff; |
cpd->esa[1] = (reg >> 16) & 0xff; |
cpd->esa[2] = (reg >> 08) & 0xff; |
cpd->esa[3] = (reg >> 00) & 0xff; |
reg = get_reg(cpd, _REG_MALR); |
cpd->esa[4] = (reg >> 08) & 0xff; |
cpd->esa[5] = (reg >> 00) & 0xff; |
break; |
#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; |
// 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, "SH Etherc" ); |
// CYG_ASSERT( 48 > strlen(p->description), "Description too long" ); |
|
if (_MII_LINK_STATE(cpd, 1)) { |
// Link is up |
p->operational = 3; // LINK UP |
if (_MII_DUPLEX_STATE(cpd, 1)) |
p->duplex = 3; // 3 = DUPLEX |
else |
p->duplex = 2; // 2 = SIMPLEX |
if (_MII_SPEED_STATE(cpd, 1)) |
p->speed = 100 * 1000000; |
else |
p->speed = 10 * 1000000; |
} else { |
// Link is down |
p->operational = 2; // LINK DOWN |
p->duplex = 1; // UNKNOWN |
p->speed = 0; |
} |
#if FIXME |
#ifdef KEEP_STATISTICS |
{ |
struct sh_etherc_stats *ps = &(cpd->stats); |
|
// Admit to it... |
p->supports_dot3 = true; |
|
p->tx_good = ps->tx_good ; |
p->tx_max_collisions = ps->tx_max_collisions ; |
p->tx_late_collisions = ps->tx_late_collisions ; |
p->tx_underrun = ps->tx_underrun ; |
p->tx_carrier_loss = ps->tx_carrier_loss ; |
p->tx_deferred = ps->tx_deferred ; |
p->tx_sqetesterrors = ps->tx_sqetesterrors ; |
p->tx_single_collisions = ps->tx_single_collisions; |
p->tx_mult_collisions = ps->tx_mult_collisions ; |
p->tx_total_collisions = ps->tx_total_collisions ; |
p->rx_good = ps->rx_good ; |
p->rx_crc_errors = ps->rx_crc_errors ; |
p->rx_align_errors = ps->rx_align_errors ; |
p->rx_resource_errors = ps->rx_resource_errors ; |
p->rx_overrun_errors = ps->rx_overrun_errors ; |
p->rx_collisions = ps->rx_collisions ; |
p->rx_short_frames = ps->rx_short_frames ; |
p->rx_too_long_frames = ps->rx_too_long_frames ; |
p->rx_symbol_errors = ps->rx_symbol_errors ; |
|
p->interrupts = ps->interrupts ; |
p->rx_count = ps->rx_count ; |
p->rx_deliver = ps->rx_deliver ; |
p->rx_resource = ps->rx_resource ; |
p->rx_restart = ps->rx_restart ; |
p->tx_count = ps->tx_count ; |
p->tx_complete = ps->tx_complete ; |
p->tx_dropped = ps->tx_dropped ; |
} |
#endif // KEEP_STATISTICS |
#endif // FIXME |
|
p->tx_queue_len = 1; |
break; |
} |
#endif |
default: |
res = 1; |
break; |
} |
|
// Restore controller state |
if (was_active) { |
// Unsuspend the device |
reg = get_reg(cpd, _REG_ECMR); |
reg |= CYGARC_REG_ECMR_RE | CYGARC_REG_ECMR_TE; |
put_reg(cpd, _REG_ECMR, reg); |
} |
|
return res; |
} |
|
// |
// 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 |
etherc_can_send(struct eth_drv_sc *sc) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
|
DEBUG_FUNCTION(); |
|
if (!_MII_LINK_STATE(cpd, 1)) |
return 0; // Link not connected |
|
return (0 == cpd->txbusy); |
} |
|
// |
// This routine is called to send data to the hardware. |
static void |
etherc_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, |
int total_len, unsigned long key) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
int i, len, plen, ring_entry; |
|
cyg_uint8* sdata = NULL; |
cyg_uint8 *d, *buf, *txd; |
|
DEBUG_FUNCTION(); |
|
INCR_STAT( tx_count ); |
|
cpd->txbusy = 1; |
cpd->txkey = key; |
|
// Find packet length |
plen = 0; |
for (i = 0; i < sg_len; i++) |
plen += sg_list[i].len; |
|
CYG_ASSERT( plen == total_len, "sg data length mismatch" ); |
|
// Get next TX descriptor |
ring_entry = cpd->tx_ring_free; |
do { |
if (cpd->tx_ring_owned == cpd->tx_ring_cnt) { |
// Is this a dead end? Probably is. |
#if DEBUG & 1 |
db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ ); |
#endif |
continue; |
} |
|
cpd->tx_ring_free++; |
cpd->tx_ring_owned++; |
if (cpd->tx_ring_free == cpd->tx_ring_cnt) |
cpd->tx_ring_free = 0; |
} while (0); |
|
txd = cpd->tx_ring + ring_entry*ETHERC_TD_SIZE; |
buf = cpd->tx_buffers + ring_entry*_BUF_SIZE; |
CYG_ASSERT(0 == (_SU32(txd, ETHERC_TD_STAT) & ETHERC_TD_STAT_TACT), |
"TX descriptor not free"); |
|
#if DEBUG & 4 |
db_printf("#####Tx descriptor 0x%08x buffer 0x%08x\n", |
txd, buf); |
#endif |
|
// Put data into buffer |
d = buf; |
for (i = 0; i < sg_len; i++) { |
sdata = (cyg_uint8 *)sg_list[i].buf; |
len = sg_list[i].len; |
|
CYG_ASSERT( sdata, "No sg data pointer here" ); |
while(len--) |
*d++ = *sdata++; |
} |
CYG_ASSERT( sdata, "No sg data pointer outside" ); |
|
if (plen < IEEE_8023_MIN_FRAME) { |
#if DEBUG & 1 |
db_printf("Packet too short (%d) - padding to %d bytes.\n", plen, IEEE_8023_MIN_FRAME); |
#endif |
for (i = plen; i < IEEE_8023_MIN_FRAME; i++) |
*d++ = 0; |
plen = IEEE_8023_MIN_FRAME; |
} |
|
_SU16(txd, ETHERC_TD_TDL) = plen; |
_SU32(txd, ETHERC_TD_STAT) |= ETHERC_TD_STAT_TACT; |
|
#if DEBUG & 1 |
db_printf("Last TX: LEN %04x STAT %08x PTR %08x\n", |
_SU16(txd, ETHERC_TD_TDL), |
_SU32(txd, ETHERC_TD_STAT), |
_SU32(txd, ETHERC_TD_TBA)); |
#endif |
|
// Set transmit demand |
put_reg(cpd, _REG_EDTRR, CYGARC_REG_EDTRR_TR); |
|
#if DEBUG & 1 |
{ |
cyg_uint32 reg; |
reg = get_reg(cpd, _REG_EESR); |
db_printf("%s:END: EESR at TX: 0x%08x\n", __FUNCTION__, reg); |
} |
#endif |
} |
|
static void |
etherc_TxEvent(struct eth_drv_sc *sc, int stat) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
int success = 1; |
cyg_uint8 *txd; |
cyg_uint32 pkt_stat; |
|
DEBUG_FUNCTION(); |
|
if (0 == cpd->tx_ring_owned) { |
#if DEBUG & 1 |
db_printf("%s: got TX completion when no outstanding packets\n", __FUNCTION__); |
#endif |
// Ack the TX int |
put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_TC); |
return; |
} |
|
|
INCR_STAT( tx_complete ); |
|
txd = cpd->tx_ring + cpd->tx_ring_alloc*ETHERC_TD_SIZE; |
pkt_stat = _SU32(txd, ETHERC_TD_STAT); |
if (pkt_stat & ETHERC_TD_STAT_TACT) { |
#if DEBUG & 1 |
db_printf("%s: got TX completion when buffer is still owned\n", __FUNCTION__); |
#endif |
// first dirty ring entry not freed - wtf? |
} |
|
if (pkt_stat & ETHERC_TD_STAT_TDFE) { |
// We had an error. Tell the stack. |
success = 0; |
#if DEBUG & 1 |
db_printf("%s: TX failure, retrying...\n", __FUNCTION__); |
#endif |
} |
|
cpd->tx_ring_alloc++; |
if (cpd->tx_ring_alloc == cpd->tx_ring_cnt) |
cpd->tx_ring_alloc = 0; |
cpd->tx_ring_owned--; |
|
#if FIXME |
#ifdef KEEP_STATISTICS |
{ |
cyg_uint16 reg; |
|
reg = get_reg( sc, ETHERC_CSR_CSCR ); |
|
// Covering each bit in turn... |
if ( reg & ETHERC_STATUS_TX_UNRN ) INCR_STAT( tx_underrun ); |
//if ( reg & ETHERC_STATUS_LINK_OK ) INCR_STAT( ); |
//if ( reg & ETHERC_STATUS_CTR_ROL ) INCR_STAT( ); |
//if ( reg & ETHERC_STATUS_EXC_DEF ) INCR_STAT( ); |
if ( reg & ETHERC_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss ); |
if ( reg & ETHERC_STATUS_LATCOL ) INCR_STAT( tx_late_collisions ); |
//if ( reg & ETHERC_STATUS_WAKEUP ) INCR_STAT( ); |
if ( reg & ETHERC_STATUS_TX_DEFR ) INCR_STAT( tx_deferred ); |
//if ( reg & ETHERC_STATUS_LTX_BRD ) INCR_STAT( ); |
if ( reg & ETHERC_STATUS_SQET ) INCR_STAT( tx_sqetesterrors ); |
if ( reg & ETHERC_STATUS_16COL ) INCR_STAT( tx_max_collisions ); |
//if ( reg & ETHERC_STATUS_LTX_MULT) INCR_STAT( ); |
if ( reg & ETHERC_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions ); |
if ( reg & ETHERC_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions ); |
if ( reg & ETHERC_STATUS_TX_SUC ) INCR_STAT( tx_good ); |
|
cpd->stats.tx_total_collisions = |
cpd->stats.tx_late_collisions + |
cpd->stats.tx_max_collisions + |
cpd->stats.tx_mult_collisions + |
cpd->stats.tx_single_collisions; |
|
// We do not need to look in the Counter Register (ETHERC_COUNTER) |
// because it just mimics the info we already have above. |
} |
#endif // KEEP_STATISTICS |
#endif // FIXME |
|
// Ack the TX int |
put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_TC); |
|
#if DEBUG & 4 |
db_printf("#####Tx packet freed 0x%08x\n", txd ); |
#endif |
|
if ( cpd->txbusy ) { |
cpd->txbusy = 0; |
(sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success); |
} |
} |
|
|
// |
// This function is called when a packet has been received. Its job is |
// to prepare to unload the packet from the hardware. Once the length of |
// the packet is known, the upper layer of the driver can be told. When |
// the upper layer is ready to unload the packet, the internal function |
// 'etherc_recv' will be called to actually fetch it from the hardware. |
// |
static void |
etherc_RxEvent(struct eth_drv_sc *sc) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
cyg_uint8 *rxd; |
cyg_uint32 rstat; |
cyg_uint32 ints; |
cyg_uint16 len; |
|
DEBUG_FUNCTION(); |
|
ints = get_reg(cpd, _REG_EESR); |
#if DEBUG & 1 |
db_printf("RxEvent - ESSR: 0x%08x\n", ints); |
#endif |
|
while (1) { |
// Get state of next (supposedly) full ring entry |
cpd->rxpacket = cpd->rx_ring_next; |
rxd = cpd->rx_ring + cpd->rxpacket*ETHERC_RD_SIZE; |
rstat = _SU32(rxd, ETHERC_RD_STAT); |
|
// Keep going until we hit an entry that is owned by the |
// controller. |
if (rstat & ETHERC_RD_STAT_RACT) { |
#if DEBUG & 1 |
int i; |
for (i = 0; i < cpd->rx_ring_cnt; i++) { |
rxd = cpd->rx_ring + i*ETHERC_RD_SIZE; |
rstat = _SU32(rxd, ETHERC_RD_STAT); |
|
if (!(rstat & ETHERC_RD_STAT_RACT)) { |
int i; |
cyg_uint32 rstat; |
cyg_uint16 mlen, blen; |
cyg_uint8* rxd; |
|
db_printf("%s: Inconsistent RX state for %d\n", __FUNCTION__, cpd->rxpacket); |
for (i = 0; i < cpd->rx_ring_cnt; i++) { |
rxd = cpd->rx_ring + i*ETHERC_RD_SIZE; |
|
rstat = _SU32(rxd, ETHERC_RD_STAT); |
blen = _SU16(rxd, ETHERC_RD_RBL); |
mlen = _SU16(rxd, ETHERC_RD_RDL); |
db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen); |
} |
} |
} |
#endif |
break; |
} |
|
#if DEBUG & 4 |
db_printf("#####Rx packet at index %d\n", cpd->rxpacket); |
#endif |
|
// Increment counts |
INCR_STAT( rx_count ); |
cpd->rx_ring_next++; |
if (cpd->rx_ring_next == cpd->rx_ring_cnt) cpd->rx_ring_next = 0; |
|
len = _SU16(rxd, ETHERC_RD_RDL); |
|
#ifdef KEEP_STATISTICS |
//if ( rstat & ETHERC_RD_PTR_FRAM ) INCR_STAT( rx_frame_errors ); |
//if ( rstat & ETHERC_RD_PTR_OFLO ) INCR_STAT( ); |
if ( rstat & ETHERC_RD_STAT_RFOF ) INCR_STAT( rx_crc_errors ); |
//if ( rstat & ETHERC_RD_PTR_BUFF ) INCR_STAT( ); |
#endif // KEEP_STATISTICS |
|
if (0 == (rstat & ETHERC_RD_STAT_RFE)) { |
// It's OK |
INCR_STAT( rx_good ); |
|
#if DEBUG & 1 |
db_printf("RxEvent good rx - stat: 0x%08x, len: 0x%04x\n", rstat, len); |
#endif |
// Check for bogusly short packets; can happen in promisc |
// mode: Asserted against and checked by upper layer |
// driver. |
#ifdef CYGPKG_NET |
if ( len > sizeof( struct ether_header ) ) |
// then it is acceptable; offer the data to the network stack |
#endif |
(sc->funs->eth_drv->recv)(sc, len); |
} else { |
// Not OK for one reason or another... |
#if DEBUG & 1 |
db_printf("RxEvent - No RX bit: stat: 0x%08x, len: 0x%04x\n", |
rstat, len); |
#endif |
} |
|
// Free packet (clear all status flags, and set RACT) |
_SU32(rxd, ETHERC_RD_STAT) &= ETHERC_RD_STAT_CLEAR; |
_SU32(rxd, ETHERC_RD_STAT) |= ETHERC_RD_STAT_RACT; |
} |
|
// Ack RX interrupt set |
put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_FR); |
// ensure Receive Request is enabled |
put_reg(cpd, _REG_EDRRR, CYGARC_REG_EDRRR_RR); |
#if DEBUG & 1 |
ints = get_reg(cpd, _REG_EESR); |
db_printf("RxEvent exit - ESSR: 0x%08x\n", ints); |
#endif |
} |
|
// |
// This function is called as a result of the "eth_drv_recv()" call above. |
// Its job is to actually fetch data for a packet from the hardware once |
// memory buffers have been allocated for the packet. Note that the buffers |
// may come in pieces, using a scatter-gather list. This allows for more |
// efficient processing in the upper layers of the stack. |
// |
static void |
etherc_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len) |
{ |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
int i, mlen=0, plen; |
cyg_uint8 *data, *rxd, *buf; |
|
DEBUG_FUNCTION(); |
|
rxd = cpd->rx_ring + cpd->rxpacket*ETHERC_TD_SIZE; |
buf = cpd->rx_buffers + cpd->rxpacket*_BUF_SIZE; |
|
INCR_STAT( rx_deliver ); |
|
plen = _SU16(rxd, ETHERC_RD_RDL); |
|
for (i = 0; i < sg_len; i++) { |
data = (cyg_uint8*)sg_list[i].buf; |
mlen = sg_list[i].len; |
|
#if DEBUG & 1 |
db_printf("%s : mlen %04x, plen %04x\n", __FUNCTION__, mlen, plen); |
#endif |
if (data) { |
while (mlen > 0) { |
*data++ = *buf++; |
mlen--; |
plen--; |
} |
} |
} |
} |
|
static void |
etherc_poll(struct eth_drv_sc *sc) |
{ |
cyg_uint32 event; |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
|
// DEBUG_FUNCTION(); |
|
while (1) { |
// Get the (unmasked) requests |
event = get_reg(cpd, _REG_EESR); |
if (0 == event) |
break; |
|
if (event & CYGARC_REG_EESR_FR) { |
etherc_RxEvent(sc); |
} |
else if (event & CYGARC_REG_EESR_TC) { |
etherc_TxEvent(sc, event); |
} |
else if (event & CYGARC_REG_EESR_RDE) { |
#if DEBUG & 1 |
int i; |
cyg_uint32 rstat; |
cyg_uint16 mlen, blen; |
cyg_uint8* rxd; |
struct etherc_priv_data *cpd = |
(struct etherc_priv_data *)sc->driver_private; |
|
db_printf("%s: Ran out of RX buffers (%04x)\n", __FUNCTION__, event); |
for (i = 0; i < cpd->rx_ring_cnt; i++) { |
rxd = cpd->rx_ring + i*ETHERC_RD_SIZE; |
|
rstat = _SU32(rxd, ETHERC_RD_STAT); |
blen = _SU16(rxd, ETHERC_RD_RBL); |
mlen = _SU16(rxd, ETHERC_RD_RDL); |
db_printf(" %02d: 0x%08x:0x%04x:0x%04x\n", i, rstat, blen, mlen); |
} |
#endif |
// Just clear the flag - RF is handled earlier in the loop |
// so a new RX block should be ready when this code |
// executes. |
put_reg(cpd, _REG_EESR, CYGARC_REG_EESR_RDE); |
} |
else { |
#if DEBUG & 1 |
db_printf("%s: Unknown interrupt: 0x%04x\n", __FUNCTION__, event); |
#endif |
put_reg(cpd, _REG_EESR, event); |
} |
} |
|
// Make sure RX is enabled |
if (cpd->active) { |
cyg_uint32 reg; |
reg = get_reg(cpd, _REG_ECMR); |
reg |= CYGARC_REG_ECMR_RE; |
put_reg(cpd, _REG_ECMR, reg); |
} |
} |
|
//---------------------------------------------------------------------------- |
// MII accessors |
|
#define _MII_WRITE_BIT(_cpd_, _b_) \ |
CYG_MACRO_START \ |
cyg_uint32 _d_ = (_b_) ? CYGARC_REG_PIR_MDO : 0; \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_WRITE | _d_); \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_WRITE | _d_ | CYGARC_REG_PIR_MDC); \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_WRITE | _d_); \ |
CYG_MACRO_END |
|
#define _MII_READ_BIT(_cpd_, _b_) \ |
CYG_MACRO_START \ |
cyg_uint32 _d_; \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ | CYGARC_REG_PIR_MDC); \ |
HAL_READ_UINT32(_cpd_->base+_REG_PIR, _d_); \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \ |
(_b_) = (_d_ & CYGARC_REG_PIR_MDI) ? 1 : 0; \ |
CYG_MACRO_END |
|
#define _MII_RELEASE(_cpd_) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ | CYGARC_REG_PIR_MDC); \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \ |
CYG_MACRO_END |
|
#define _MII_RELEASE_INDEP(_cpd_) \ |
CYG_MACRO_START \ |
HAL_WRITE_UINT32(_cpd_->base+_REG_PIR, CYGARC_REG_PIR_MMD_READ); \ |
CYG_MACRO_END |
|
|
static void |
etherc_write_MII(struct etherc_priv_data *cpd, int id, int reg, cyg_uint16 value) |
{ |
int i; |
|
// Pre |
for(i = 0; i < 32; i++) |
_MII_WRITE_BIT(cpd, 1); |
// Start of frame |
_MII_WRITE_BIT(cpd, 0); |
_MII_WRITE_BIT(cpd, 1); |
// Operation (write) |
_MII_WRITE_BIT(cpd, 0); |
_MII_WRITE_BIT(cpd, 1); |
// Phy address |
for (i = 4; i >= 0; i--) |
_MII_WRITE_BIT(cpd, (id & (1<<i)) ? 1: 0); |
// Register address |
for (i = 4; i >= 0; i--) |
_MII_WRITE_BIT(cpd, (reg & (1<<i)) ? 1: 0); |
// TA |
_MII_WRITE_BIT(cpd, 1); |
_MII_WRITE_BIT(cpd, 0); |
// Data |
for (i = 15; i >= 0; i--) |
_MII_WRITE_BIT(cpd, (value & (1<<i)) ? 1: 0); |
// Release bus |
_MII_RELEASE_INDEP(cpd); |
} |
|
static cyg_uint16 |
etherc_read_MII(struct etherc_priv_data *cpd, int id, int reg) |
{ |
bool b; |
int i; |
cyg_uint16 val = 0; |
|
// Pre |
for(i = 0; i < 32; i++) |
_MII_WRITE_BIT(cpd, 1); |
// Start of frame |
_MII_WRITE_BIT(cpd, 0); |
_MII_WRITE_BIT(cpd, 1); |
// Operation (read) |
_MII_WRITE_BIT(cpd, 1); |
_MII_WRITE_BIT(cpd, 0); |
// Phy address |
for (i = 4; i >= 0; i--) |
_MII_WRITE_BIT(cpd, (id & (1<<i)) ? 1: 0); |
// Register address |
for (i = 4; i >= 0; i--) |
_MII_WRITE_BIT(cpd, (reg & (1<<i)) ? 1: 0); |
// TA |
_MII_RELEASE(cpd); |
// Data |
for (i = 15; i >= 0; i--) { |
_MII_READ_BIT(cpd, b); |
val = val << 1; |
if (b) val |= 1; |
} |
|
return val; |
} |
|
// EOF if_etherc.c |
/etherc/v2_0/src/sh_etherc.h
0,0 → 1,344
#ifndef CYGONCE_DEVS_ETH_SH_ETHERC_H |
#define CYGONCE_DEVS_ETH_SH_ETHERC_H |
//========================================================================== |
// |
// sh_etherc.h |
// |
// SH EtherC Ethernet CPU module controller |
// |
//========================================================================== |
//####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: 2002-01-30 |
// Purpose: Hardware description of SH EtherC controller. |
// Description: |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
#include <cyg/hal/hal_io.h> |
|
//------------------------------------------------------------------------ |
// Get macros from platform header |
#define __WANT_CONFIG |
#include CYGDAT_DEVS_ETH_SH_ETHERC_INL |
#undef __WANT_CONFIG |
|
//------------------------------------------------------------------------ |
// Set to perms of: |
// 0 disables all debug output |
// 1 for process debug output |
// 2 for added data IO output: get_reg, put_reg |
// 4 for packet allocation/free output |
// 8 for only startup status, so we can tell we're installed OK |
#define DEBUG 0x0 |
|
#if DEBUG & 1 |
#define DEBUG_FUNCTION() do { db_printf("%s\n", __FUNCTION__); } while (0) |
#else |
#define DEBUG_FUNCTION() do {} while(0) |
#endif |
|
// ------------------------------------------------------------------------ |
// Debug print function |
#if defined(CYGPKG_REDBOOT) && DEBUG |
|
static void db_printf( char *fmt, ... ) |
{ |
extern int start_console(void); |
extern void end_console(int); |
va_list a; |
int old_console; |
va_start( a, fmt ); |
old_console = start_console(); |
diag_vprintf( fmt, a ); |
end_console(old_console); |
va_end( a ); |
} |
|
#else |
|
#define db_printf diag_printf |
|
#endif |
|
// ------------------------------------------------------------------------ |
// Macros for keeping track of statistics |
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD) |
# define KEEP_STATISTICS |
#endif |
|
#ifdef KEEP_STATISTICS |
# define INCR_STAT( _x_ ) (cpd->stats. _x_ ++) |
#else |
# define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT |
#endif |
|
//------------------------------------------------------------------------ |
// Cache translation |
#ifndef CYGARC_UNCACHED_ADDRESS |
# define CYGARC_UNCACHED_ADDRESS(x) (x) |
#endif |
|
// ------------------------------------------------------------------------ |
// Macros for accessing structure elements |
|
#define _SU8( _base_, _offset_) \ |
*((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_))) |
#define _SU16( _base_, _offset_) \ |
*((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_))) |
#define _SU32( _base_, _offset_) \ |
*((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_))) |
|
#define _SI8( _base_, _offset_) \ |
*((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_))) |
#define _SI16( _base_, _offset_) \ |
*((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_))) |
#define _SI32( _base_, _offset_) \ |
*((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_))) |
|
// ------------------------------------------------------------------------ |
// Controller registers in offset form |
#define _REG_EDMR 0x00 |
#define _REG_EDTRR 0x04 |
#define _REG_EDRRR 0x08 |
#define _REG_TDLAR 0x0c |
#define _REG_RDLAR 0x10 |
#define _REG_EESR 0x14 |
#define _REG_EESIPR 0x18 |
#define _REG_TRSCER 0x1c |
#define _REG_RMFCR 0x20 |
#define _REG_TFTR 0x24 |
#define _REG_FDR 0x28 |
#define _REG_RCR 0x2c |
#define _REG_EDOCR 0x30 |
#define _REG_RBWAR 0x40 |
#define _REG_RDFAR 0x44 |
#define _REG_TBRAR 0x4c |
#define _REG_TDFAR 0x50 |
|
#define _REG_ECMR 0x60 |
#define _REG_ECSR 0x64 |
#define _REG_ECSIPR 0x68 |
#define _REG_PIR 0x6c |
#define _REG_MAHR 0x70 |
#define _REG_MALR 0x74 |
#define _REG_RFLR 0x78 |
#define _REG_PSR 0x7c |
#define _REG_TROCR 0x80 |
#define _REG_CDCR 0x84 |
#define _REG_LCCR 0x88 |
#define _REG_CNDCR 0x8c |
#define _REG_IFLCR 0x90 |
#define _REG_CECFR 0x94 |
#define _REG_FRECR 0x98 |
#define _REG_TSFRCR 0x9c |
#define _REG_TLFRCR 0xa0 |
#define _REG_RFCR 0xa4 |
#define _REG_MAFCR 0xa8 |
|
//---------------------------------------------------------------------------- |
// Receive buffer Descriptor |
#define ETHERC_RD_STAT 0x00 // 32 bit |
#define ETHERC_RD_RBL 0x04 // 16 bit - receive buffer length |
#define ETHERC_RD_RDL 0x06 // 16 bit - receive data length (-CRC) |
#define ETHERC_RD_RBA 0x08 // 32 bit - receive buffer address |
#define ETHERC_RD_PAD 0x0c // 32 bit |
#define ETHERC_RD_SIZE 0x10 |
|
#define ETHERC_RD_STAT_RACT 0x80000000 |
#define ETHERC_RD_STAT_RDLE 0x40000000 |
#define ETHERC_RD_STAT_RFP_OTO 0x30000000 // one buffer to one frame |
#define ETHERC_RD_STAT_RFE 0x08000000 |
#define ETHERC_RD_STAT_RFOF 0x00000200 |
#define ETHERC_RD_STAT_RMAF 0x00000080 |
#define ETHERC_RD_STAT_RRF 0x00000010 |
#define ETHERC_RD_STAT_RTLF 0x00000008 |
#define ETHERC_RD_STAT_RTSF 0x00000004 |
#define ETHERC_RD_STAT_PRE 0x00000002 |
#define ETHERC_RD_STAT_CERF 0x00000001 |
|
#define ETHERC_RD_STAT_CLEAR 0x70000000 |
|
// Transmit buffer Descriptor |
#define ETHERC_TD_STAT 0x00 // 32 bit |
#define ETHERC_TD_TDL 0x04 // 16 bit - transmit data length |
#define ETHERC_TD_PAD0 0x06 // 16 bit |
#define ETHERC_TD_TBA 0x08 // 32 bit - transmit buffer address |
#define ETHERC_TD_PAD1 0x0c // 32 bit |
#define ETHERC_TD_SIZE 0x10 |
|
#define ETHERC_TD_STAT_TACT 0x80000000 |
#define ETHERC_TD_STAT_TDLE 0x40000000 |
#define ETHERC_TD_STAT_TFP_OTO 0x30000000 // one buffer to one frame |
#define ETHERC_TD_STAT_TDFE 0x08000000 |
#define ETHERC_TD_STAT_ITF 0x00000010 |
#define ETHERC_TD_STAT_CND 0x00000008 |
#define ETHERC_TD_STAT_DLC 0x00000004 |
#define ETHERC_TD_STAT_CD 0x00000002 |
#define ETHERC_TD_STAT_TRO 0x00000001 |
|
|
// Initialization Buffer |
#define ETHERC_IB_MODE 0 |
#define ETHERC_IB_PADR0 2 |
#define ETHERC_IB_PADR1 4 |
#define ETHERC_IB_PADR2 6 |
#define ETHERC_IB_LADRF0 8 |
#define ETHERC_IB_LADRF1 10 |
#define ETHERC_IB_LADRF2 12 |
#define ETHERC_IB_LADRF3 14 |
#define ETHERC_IB_RDRA 16 |
#define ETHERC_IB_TDRA 20 |
#define ETHERC_IB_SIZE 24 |
|
#define ETHERC_IB_TDRA_CNT_shift 29 |
#define ETHERC_IB_TDRA_PTR_mask 0x00ffffff |
#define ETHERC_IB_RDRA_CNT_shift 29 |
#define ETHERC_IB_RDRA_PTR_mask 0x00ffffff |
|
// ------------------------------------------------------------------------ |
|
#ifdef KEEP_STATISTICS |
struct sh_etherc_stats { |
unsigned int tx_good ; |
unsigned int tx_max_collisions ; |
unsigned int tx_late_collisions ; |
unsigned int tx_underrun ; |
unsigned int tx_carrier_loss ; |
unsigned int tx_deferred ; |
unsigned int tx_sqetesterrors ; |
unsigned int tx_single_collisions; |
unsigned int tx_mult_collisions ; |
unsigned int tx_total_collisions ; |
unsigned int rx_good ; |
unsigned int rx_crc_errors ; |
unsigned int rx_align_errors ; |
unsigned int rx_resource_errors ; |
unsigned int rx_overrun_errors ; |
unsigned int rx_collisions ; |
unsigned int rx_short_frames ; |
unsigned int rx_too_long_frames ; |
unsigned int rx_symbol_errors ; |
unsigned int interrupts ; |
unsigned int rx_count ; |
unsigned int rx_deliver ; |
unsigned int rx_resource ; |
unsigned int rx_restart ; |
unsigned int tx_count ; |
unsigned int tx_complete ; |
unsigned int tx_dropped ; |
}; |
#endif |
|
struct etherc_priv_data; |
typedef cyg_bool (*provide_esa_t)(struct etherc_priv_data* cpd); |
|
typedef struct etherc_priv_data { |
int index; |
cyg_uint8 // (split up for atomic byte access) |
mac_addr_ok:1, // can we bring up? |
active:1, // has this if been brung up? |
hardwired_esa:1, // set if ESA is hardwired via CDL |
txbusy:1, // A packet has been sent |
spare1:3; |
|
unsigned long txkey; // Used to ack when packet sent |
unsigned char* base; // Base address of controller EPROM region |
int interrupt; // Interrupt vector used by controller |
unsigned char esa[6]; // Controller ESA |
// Function to configure the ESA - may fetch ESA from EPROM or |
// RedBoot config option. |
void (*config_esa)(struct etherc_priv_data* cpd); |
void *ndp; // Network Device Pointer |
provide_esa_t provide_esa; |
|
cyg_handle_t interrupt_handle; |
cyg_interrupt interrupt_object; |
int devid; |
|
cyg_uint8* rx_buffers; // ptr to base of buffer mem |
cyg_uint8* rx_ring; // ptr to base of rx ring memory |
int rx_ring_cnt; // number of entries in ring |
int rx_ring_next; // index of next full ring entry |
|
cyg_uint8* tx_buffers; |
cyg_uint8* tx_ring; |
int tx_ring_cnt; |
int tx_ring_free; // index of next free ring entry |
int tx_ring_alloc; // index of first controller owned ring |
int tx_ring_owned; // number of controller owned ring entries |
|
int rxpacket; |
#ifdef KEEP_STATISTICS |
struct sh_etherc_stats stats; |
#endif |
#if DEBUG & 1 |
cyg_uint32 txd; |
#endif |
} etherc_priv_data; |
|
// ------------------------------------------------------------------------ |
|
static __inline__ cyg_uint32 |
get_reg(struct etherc_priv_data *cpd, int regno) |
{ |
cyg_int32 val; |
|
HAL_READ_UINT32(cpd->base+regno, val); |
|
#if DEBUG & 2 |
db_printf("read reg %d val 0x%08x\n", regno, val); |
#endif |
return val; |
} |
|
static __inline__ void |
put_reg(struct etherc_priv_data *cpd, int regno, cyg_uint32 val) |
{ |
HAL_WRITE_UINT32(cpd->base+regno, val); |
|
#if DEBUG & 2 |
db_printf("write reg %d val 0x%08x\n", regno, val); |
#endif |
} |
|
// ------------------------------------------------------------------------ |
#endif // CYGONCE_DEVS_ETH_SH_ETHERC_H |
// EOF sh_etherc.h |
/etherc/v2_0/src/phyter.inl
0,0 → 1,186
#ifndef CYGONCE_DEVS_ETH_PHYTER_PHYTER_INL |
#define CYGONCE_DEVS_ETH_PHYTER_PHYTER_INL |
//========================================================================== |
// |
// phyther.inl |
// |
// Generic Phyter definitions and helpers |
// |
//========================================================================== |
//####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: 2002-02-19 |
// Purpose: phy/MII definitions |
// Description: |
// |
//####DESCRIPTIONEND#### |
// |
//========================================================================== |
|
// Caller must define _MII_WRITE and _MII_READ macros |
#ifndef _MII_WRITE |
# error "_MII_WRITE(_priv_, _id_, _reg_, _val_) and _MII_READ(_priv_, _id_, _reg_) must be defined" |
#endif |
|
// Caller can define _MII_HAS_EXTENDED to add support for extended registers |
|
//----------------------------------------------------------------------------- |
// Helpers |
|
// Renegotiate link |
// This function will delay for up to 2 seconds waiting for a renegotiation |
// of the link. |
#define _MII_RENEGOTIATE(_priv_, _id_) \ |
CYG_MACRO_START \ |
_MII_WRITE(_priv_, _id_, CYGARC_REG_MII_BMCR, CYGARC_REG_MII_BMCR_RENEGOTIATE); \ |
_MII_RENEGOTIATION_WAIT(_priv_, _id_); \ |
CYG_MACRO_END |
|
// Wait for renegotiation to complete |
// This function will delay for up to 2 seconds waiting for a renegotiation |
// of the link. |
#define _MII_RENEGOTIATION_WAIT(_priv_, _id_) \ |
CYG_MACRO_START \ |
int _i; \ |
cyg_uint16 _r; \ |
for (_i = 0; _i < 2000; _i++) { \ |
HAL_DELAY_US(1000); \ |
_r = _MII_READ(_priv_, _id_, CYGARC_REG_MII_BMSR); \ |
if (_r & CYGARC_REG_MII_BMSR_AN_COMPLETE) break; \ |
} \ |
CYG_MACRO_END |
|
// Link state query |
#define _MII_LINK_STATE(_priv_, _id_) \ |
({ int _i; \ |
if (_MII_READ(_priv_, _id_, CYGARC_REG_MII_BMSR) & CYGARC_REG_MII_BMSR_LINK) \ |
(_i) = 1; \ |
else \ |
(_i) = 0; \ |
_i; }) |
|
// Clear 100MB capability advertisement bits |
// Caller has to start a new renegoatiation |
#define _MII_SPEED_FORCE_10MB(_priv_, _id_) \ |
CYG_MACRO_START \ |
cyg_uint16 _d; \ |
_d = _MII_READ(_priv_, _id_, CYGARC_REG_MII_ANAR); \ |
_d &= ~(CYGARC_REG_MII_ANAR_T4|CYGARC_REG_MII_ANAR_TX_FD|CYGARC_REG_MII_ANAR_TX); \ |
_MII_WRITE(_priv_, _id_, CYGARC_REG_MII_ANAR, _d); \ |
CYG_MACRO_END |
|
#ifdef _MII_HAS_EXTENDED |
|
// Speed state query |
// 0 = 10Mb, 1 = 100Mb |
#define _MII_SPEED_STATE(_priv_, _id_) \ |
({ int _i; \ |
if (_MII_READ(_priv_, _id_, CYGARC_REG_MII_PHYSTS) & CYGARC_REG_MII_PHYSTS_SPEED) \ |
(_i) = 0; \ |
else \ |
(_i) = 1; \ |
_i; }) |
|
// Duplex state query |
// 0 = simplex, 1 = duplex |
#define _MII_DUPLEX_STATE(_priv_, _id_) \ |
({ int _i; \ |
if (_MII_READ(_priv_, _id_, CYGARC_REG_MII_PHYSTS) & CYGARC_REG_MII_PHYSTS_DUPLEX) \ |
(_i) = 1; \ |
else \ |
(_i) = 0; \ |
_i; }) |
|
#endif // _MII_HAS_EXTENDED |
|
// Dump registers |
// Useful for debugging |
#define _MII_DUMP_REGS(_priv_, _id_) \ |
CYG_MACRO_START \ |
int _i; \ |
diag_printf("PHY registers:\n"); \ |
for(_i = 0; _i <= CYGARC_REG_MII_LAST; _i++) \ |
diag_printf(" %02d %04x\n", _i, _MII_READ(_priv_, _id_, _i)); \ |
CYG_MACRO_END |
|
//----------------------------------------------------------------------------- |
// Phyter Registers |
|
// Generic |
#define CYGARC_REG_MII_BMCR 0x00 |
#define CYGARC_REG_MII_BMSR 0x01 |
#define CYGARC_REG_MII_PHYIDR1 0x02 |
#define CYGARC_REG_MII_PHYIDR2 0x03 |
#define CYGARC_REG_MII_ANAR 0x04 |
#define CYGARC_REG_MII_ANLPAR 0x05 |
#define CYGARC_REG_MII_ANER 0x06 |
#define CYGARC_REG_MII_ANNPTR 0x07 |
|
#define CYGARC_REG_MII_BMCR_RESET 0x8000 |
#define CYGARC_REG_MII_BMCR_LOOPBACK 0x4000 |
#define CYGARC_REG_MII_BMCR_RENEGOTIATE 0x3300 |
|
#define CYGARC_REG_MII_BMSR_AN_COMPLETE 0x0020 |
#define CYGARC_REG_MII_BMSR_LINK 0x0004 |
|
#define CYGARC_REG_MII_ANAR_T4 0x0200 |
#define CYGARC_REG_MII_ANAR_TX_FD 0x0100 |
#define CYGARC_REG_MII_ANAR_TX 0x0080 |
#define CYGARC_REG_MII_ANAR_10_FD 0x0040 |
#define CYGARC_REG_MII_ANAR_10 0x0020 |
|
// Extended registers |
#ifndef _MII_HAS_EXTENDED |
# define CYGARC_REG_MII_LAST 0x0f |
#else |
# define CYGARC_REG_MII_PHYSTS 0x10 |
# define CYGARC_REG_MII_FCSCR 0x14 |
# define CYGARC_REG_MII_RECR 0x15 |
# define CYGARC_REG_MII_PCSR 0x16 |
# define CYGARC_REG_MII_PHYCTRL 0x19 |
# define CYGARC_REG_MII_10BTSCR 0x1a |
# define CYGARC_REG_MII_CDCTRL 0x1b |
# define CYGARC_REG_MII_LAST 0x1f |
|
|
# define CYGARC_REG_MII_PHYSTS_SPEED 0x00000002 |
# define CYGARC_REG_MII_PHYSTS_DUPLEX 0x00000004 |
|
#endif |
|
#endif // CYGONCE_DEVS_ETH_PHYTER_PHYTER_INL |
/se7751/v2_0/cdl/sh_se7751_eth_drivers.cdl
0,0 → 1,130
# ==================================================================== |
# |
# se7751_eth_drivers.cdl |
# |
# Ethernet drivers - support for AMD PCnet ethernet controller |
# on the Hitachi SE7751 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_SH_SE7751 { |
display "Hitachi SE7751 board ethernet driver" |
description "Ethernet driver for Hitachi SE7751 board." |
|
parent CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_IO_ETH_DRIVERS |
active_if CYGPKG_HAL_SH_SH7751_SE7751 |
|
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_sh_se7751.inl>" |
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_AMD_PCNET_CFG <pkgconf/devs_eth_sh_se7751.h>" |
puts $::cdl_system_header "/***** ethernet driver proc output end *****/" |
} |
|
cdl_component CYGPKG_DEVS_ETH_SH_SE7751_ETH0 { |
display "SE7751 ethernet port 0 driver" |
flavor bool |
default_value 1 |
description " |
This option includes the ethernet device driver for the |
SE7751 port 0." |
|
implements CYGHWR_NET_DRIVERS |
implements CYGHWR_NET_DRIVER_ETH0 |
implements CYGINT_DEVS_ETH_AMD_PCNET_REQUIRED |
|
cdl_option CYGNUM_DEVS_ETH_SH_SE7751_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_SH_SE7751_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_SH_SE7751_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 |
SE7751 port 0." |
} |
|
cdl_component CYGSEM_DEVS_ETH_SH_SE7751_ETH0_SET_ESA { |
display "Set the ethernet station address" |
flavor bool |
calculated 1 |
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_SH_SE7751_ETH0_ESA { |
display "The ethernet station address" |
flavor data |
default_value {"{0x08, 0x88, 0x12, 0x34, 0x56, 0x78}"} |
description "The ethernet station address" |
} |
} |
} |
} |
/se7751/v2_0/include/devs_eth_sh_se7751.inl
0,0 → 1,110
//========================================================================== |
// |
// devs/eth/sh/se7751/include/devs_eth_sh_se7751.inl |
// |
// SE7751 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-07-10 |
// Purpose: SE7751 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(&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_SH_SE7751_ETH0 |
|
// FIXME: find locations via PCI |
static pcnet_priv_data amd_pcnet_eth0_priv_data = { |
#ifdef CYGSEM_DEVS_ETH_SH_SE7751_ETH0_SET_ESA |
esa : CYGDAT_DEVS_ETH_SH_SE7751_ETH0_ESA, |
hardwired_esa : true, |
#else |
hardwired_esa : false, |
#endif |
config_esa : NULL, // rely on the hardwired address for now |
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_SH_SE7751_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_SH_SE7751_ETH0_NAME, |
amd_pcnet_init, |
&amd_pcnet_sc); |
#endif // CYGPKG_DEVS_ETH_SH_SE7751_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_SH_SE7751_ETH0 |
&amd_pcnet_eth0_priv_data, |
#endif |
}; |
|
#endif // __WANT_DEVS |
|
// EOF devs_eth_sh_se7751.inl |
/se7751/v2_0/ChangeLog
0,0 → 1,50
2002-02-18 Jesper Skov <jskov@redhat.com> |
|
* cdl/sh_se7751_eth_drivers.cdl: Fix typos. |
|
2001-07-12 Jesper Skov <jskov@redhat.com> |
|
* include/devs_eth_sh_se7751.inl: Driver finds the controller data |
via PCI library. |
|
2001-07-10 Jesper Skov <jskov@redhat.com> |
|
* cdl/sh_se7751_eth_drivers.cdl: Platform specific |
information required to use the generic AMD PCNet driver for the |
SE7751 platform. |
* include/devs_eth_sh_se7751.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#### |
//=========================================================================== |