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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /or1k/trunk/ecos-2.0/packages/devs/eth/powerpc
    from Rev 1254 to Rev 1765
    Reverse comparison

Rev 1254 → Rev 1765

/adder/v2_0/cdl/adder_eth_drivers.cdl
0,0 → 1,71
#====================================================================
#
# adder_eth_drivers.cdl
#
# Hardware specifics for A&M Adder ethernet
#
#====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002 Gary Thomas
##
## 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): gthomas, hmt
# Original data: gthomas
# Contributors: gthomas
# Date: 2001-02-14
#
#####DESCRIPTIONEND####
#
#====================================================================
 
cdl_package CYGPKG_DEVS_ETH_POWERPC_ADDER {
display "A&M Adder (MPC8xxT) ethernet support"
description "Hardware specifics for A&M Adder ethernet"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC
active_if CYGPKG_HAL_POWERPC_MPC8xx
active_if CYGPKG_HAL_POWERPC_ADDER
 
requires CYGPKG_DEVS_ETH_POWERPC_QUICC
 
compile adder_eth.c
 
include_dir cyg/io
define_proc {
puts $::cdl_system_header "#define CYGDAT_DEVS_QUICC_ETH_INL <cyg/io/adder_eth.inl>"
}
}
/adder/v2_0/include/adder_eth.inl
0,0 → 1,97
#ifndef CYGONCE_DEVS_ADDER_ETH_INL
#define CYGONCE_DEVS_ADDER_ETH_INL
//==========================================================================
//
// adder_eth.inl
//
// Hardware specifics for A&M Adder ethernet support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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): gthomas
// Contributors: gthomas
// Date: 2002-11-19
// Purpose:
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
 
extern int _adder_get_leds(void);
extern void _adder_set_leds(int);
extern bool _adder_reset_phy(void);
 
#define _get_led() _adder_get_leds()
#define _set_led(v) _adder_set_leds(v)
 
#define LED_TxACTIVE 2
#define LED_RxACTIVE 1
 
// Reset the PHY - analagous to hardware reset
#define QUICC_ETH_RESET_PHY() \
if (!_adder_reset_phy()) { \
diag_printf("Can't reset PHY or get link\n"); \
}
 
// Port layout - uses SCC2
#define QUICC_ETH_INT CYGNUM_HAL_INTERRUPT_CPM_SCC2
#define QUICC_ETH_SCC 1 // SCC2
#define QUICC_CPM_SCCx QUICC_CPM_SCC2
 
// Fixed bits
#define QUICC_ETH_PA_RXD 0x0004 // Rx Data on Port A
#define QUICC_ETH_PA_TXD 0x0008 // Tx Data on Port A
#define QUICC_ETH_PC_COLLISION 0x0040 // Collision detect
#define QUICC_ETH_PC_Rx_ENABLE 0x0080 // Rx Enable (RENA)
 
// These depend on how the PHY is wired to the CPU
#define QUICC_ETH_PA_Tx_CLOCK 0x0200 // Tx Clock = CLK2
#define QUICC_ETH_PA_Rx_CLOCK 0x0800 // Rx Clock = CLK4
#define QUICC_ETH_SICR_MASK 0xFF00 // SI Clock Route - important bits
#define QUICC_ETH_SICR_ENET (7<<11)|(5<<8) // Rx=CLK4, Tx=CLK2
#define QUICC_ETH_SICR_ENABLE 0x4000 // Enable SCC2 to use NMSI
 
// The TENA signal can appear on either port B or C
//#define QUICC_ETH_PC_Tx_ENABLE 0x0002 // Tx Enable (TENA)
#define QUICC_ETH_PB_Tx_ENABLE 0x2000 // Tx Enable (TENA)
 
 
#endif // CYGONCE_DEVS_ADDER_ETH_INL
// ------------------------------------------------------------------------
/adder/v2_0/ChangeLog
0,0 → 1,45
2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
 
* src/adder_eth.c:
* include/adder_eth.inl:
* cdl/adder_eth_drivers.cdl: New package - platform specifics for
Analogue & Micro Adder (PowerPC 850) ethernet, using SCC2.
 
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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####
//===========================================================================
 
/adder/v2_0/src/adder_eth.c
0,0 → 1,279
//==========================================================================
//
// adder_eth.c
//
// Ethernet device driver specifics for Analogue & Micro Adder (PPC850)
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD or other sources,
// and are covered by the appropriate copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas
// Date: 2002-11-25
// Purpose:
// Description: platform driver specifics for A&M Adder
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
// Ethernet device driver support for PHY on Adder/MPC850
 
#include <pkgconf/system.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/diag.h>
 
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_cache.h>
#include <cyg/hal/hal_if.h>
#include <cyg/hal/drv_api.h>
 
#include CYGDAT_DEVS_QUICC_ETH_INL // Platform specifics
#include <cyg/hal/quicc/ppc8xx.h> // QUICC structure definitions
 
// MII interface
#define MII_Start 0x40000000
#define MII_Read 0x20000000
#define MII_Write 0x10000000
#define MII_Cmd 0x30000000
#define MII_Phy(phy) (phy << 23)
#define MII_Reg(reg) (reg << 18)
#define MII_TA 0x00020000
 
// Transceiver mode
#define PHY_BMCR 0x00 // Register number
#define PHY_BMCR_RESET 0x8000
#define PHY_BMCR_LOOPBACK 0x4000
#define PHY_BMCR_100MB 0x2000
#define PHY_BMCR_AUTO_NEG 0x1000
#define PHY_BMCR_POWER_DOWN 0x0800
#define PHY_BMCR_ISOLATE 0x0400
#define PHY_BMCR_RESTART 0x0200
#define PHY_BMCR_FULL_DUPLEX 0x0100
#define PHY_BMCR_COLL_TEST 0x0080
 
#define PHY_BMSR 0x01 // Status register
#define PHY_BMSR_AUTO_NEG 0x0020
#define PHY_BMSR_LINK 0x0004
 
// Bits in port D - used for 2 wire MII interface
#define MII_DATA 0x1000
#define MII_CLOCK 0x0800
 
#define MII_SET_DATA(val) \
if (val) { \
eppc->pio_pddat |= MII_DATA; \
} else { \
eppc->pio_pddat &= ~MII_DATA; \
}
 
#define MII_GET_DATA() \
((eppc->pio_pddat & MII_DATA) != 0)
 
#define MII_SET_CLOCK(val) \
if (val) { \
eppc->pio_pddat |= MII_CLOCK; \
} else { \
eppc->pio_pddat &= ~MII_CLOCK; \
}
 
static cyg_uint32
phy_cmd(cyg_uint32 cmd)
{
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
cyg_uint32 retval;
int i, off;
bool is_read = ((cmd & MII_Cmd) == MII_Read);
 
// Set both bits as output
eppc->pio_pddir |= MII_DATA | MII_CLOCK;
 
// Preamble
for (i = 0; i < 32; i++) {
MII_SET_CLOCK(0);
MII_SET_DATA(1);
CYGACC_CALL_IF_DELAY_US(1);
MII_SET_CLOCK(1);
CYGACC_CALL_IF_DELAY_US(1);
}
 
// Command/data
for (i = 0, off = 31; i < (is_read ? 14 : 32); i++, --off) {
MII_SET_CLOCK(0);
MII_SET_DATA((cmd >> off) & 0x00000001);
CYGACC_CALL_IF_DELAY_US(1);
MII_SET_CLOCK(1);
CYGACC_CALL_IF_DELAY_US(1);
}
 
retval = cmd;
 
// If read, fetch data register
if (is_read) {
retval >>= 16;
 
MII_SET_CLOCK(0);
eppc->pio_pddir &= ~MII_DATA; // Data bit is now input
CYGACC_CALL_IF_DELAY_US(1);
MII_SET_CLOCK(1);
CYGACC_CALL_IF_DELAY_US(1);
MII_SET_CLOCK(0);
CYGACC_CALL_IF_DELAY_US(1);
 
for (i = 0, off = 15; i < 16; i++, off--) {
MII_SET_CLOCK(1);
retval <<= 1;
retval |= MII_GET_DATA();
CYGACC_CALL_IF_DELAY_US(1);
MII_SET_CLOCK(0);
CYGACC_CALL_IF_DELAY_US(1);
}
}
 
// Set both bits as output
eppc->pio_pddir |= MII_DATA | MII_CLOCK;
 
// Postamble
for (i = 0; i < 32; i++) {
MII_SET_CLOCK(0);
MII_SET_DATA(1);
CYGACC_CALL_IF_DELAY_US(1);
MII_SET_CLOCK(1);
CYGACC_CALL_IF_DELAY_US(1);
}
 
return retval;
}
 
//
// PHY unit access (via MII channel)
//
static void
phy_write(int reg, int addr, unsigned short data)
{
phy_cmd(MII_Start | MII_Write | MII_Phy(addr) | MII_Reg(reg) | MII_TA | data);
}
 
static bool
phy_read(int reg, int addr, unsigned short *val)
{
cyg_uint32 ret;
 
ret = phy_cmd(MII_Start | MII_Read | MII_Phy(addr) | MII_Reg(reg) | MII_TA);
*val = ret;
return true;
}
 
bool
_adder_reset_phy(void)
{
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
int phy_timeout = 5*1000; // Wait 5 seconds max for link to clear
bool phy_ok;
unsigned short phy_state = 0;
int phy_unit = -1;
int i;
 
// Reset PHY (transceiver)
eppc->pip_pbdat &= ~0x00004000; // Reset PHY chip
CYGACC_CALL_IF_DELAY_US(15000); // > 10ms
eppc->pip_pbdat |= 0x00004000; // Enable PHY chip
 
phy_ok = false;
// Try and discover how this PHY is wired
for (i = 0; i < 0x20; i++) {
phy_read(PHY_BMCR, i, &phy_state);
if ((phy_state & PHY_BMCR_RESET) == 0) {
phy_unit = i;
break;
}
}
if (phy_unit < 0) {
diag_printf("QUICC ETH - Can't locate PHY\n");
return false;
} else {
#if 0
diag_printf("QUICC ETH - using PHY %d\n", phy_unit);
#endif
}
if (phy_read(PHY_BMSR, phy_unit, &phy_state)) {
if ((phy_state & PHY_BMSR_LINK) != PHY_BMSR_LINK) {
unsigned short reset_mode;
phy_write(PHY_BMCR, phy_unit, PHY_BMCR_RESET);
for (i = 0; i < 10; i++) {
phy_ok = phy_read(PHY_BMCR, phy_unit, &phy_state);
if (!phy_ok) break;
if (!(phy_state & PHY_BMCR_RESET)) break;
}
if (!phy_ok || (phy_state & PHY_BMCR_RESET)) {
diag_printf("QUICC/ETH: Can't get PHY unit to soft reset: %x\n", phy_state);
return false;
}
reset_mode = PHY_BMCR_RESTART | PHY_BMCR_AUTO_NEG | PHY_BMCR_FULL_DUPLEX;
phy_write(PHY_BMCR, phy_unit, reset_mode);
while (phy_timeout-- >= 0) {
phy_ok = phy_read(PHY_BMSR, phy_unit, &phy_state);
if (phy_ok && (phy_state & PHY_BMSR_LINK)) {
break;
} else {
CYGACC_CALL_IF_DELAY_US(10000); // 10ms
}
}
if (phy_timeout <= 0) {
diag_printf("** QUICC/ETH Warning: PHY LINK UP failed\n");
}
}
else {
diag_printf("** QUICC/ETH Info: PHY LINK already UP \n");
}
}
 
return phy_ok;
}
 
/csb281/v2_0/cdl/csb281_eth_drivers.cdl
0,0 → 1,201
# ====================================================================
#
# csb281_eth_drivers.cdl
#
# Ethernet drivers - support for i82559 ethernet controller
# on the Cogent CSB281 (PowerPC 8245) board.
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002 Gary Thomas
##
## 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, hmt, gthomas
# Date: 2001-02-28
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_DEVS_ETH_CSB281 {
display "Cogent CSB281 ethernet driver"
description "
Ethernet driver for Cogent CSB281 with Intel
i82559 Ethernet controllers attached via the PCI"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC_CSB281
 
include_dir cyg/io
 
# FIXME: This really belongs in the INTEL_I82559 package
cdl_interface CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED {
display "Intel i82559 ethernet driver required"
}
 
define_proc {
puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_INL <cyg/io/devs_eth_csb281.inl>"
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_INTEL_I82559_CFG <pkgconf/devs_eth_csb281.h>"
puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
}
 
cdl_component CYGPKG_DEVS_ETH_CSB281_ETH0 {
display "CSB281 ethernet port 0 driver"
flavor bool
default_value 1
description "
This option includes the ethernet device driver on the
csb281 motherboard."
 
implements CYGHWR_NET_DRIVERS
implements CYGHWR_NET_DRIVER_ETH0
implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
 
cdl_option CYGDAT_DEVS_ETH_CSB281_ETH0_NAME {
display "Device name for the ethernet port 0 driver"
flavor data
default_value {"\"eth0\""}
description "
This option sets the name of the ethernet device for the
ethernet port 0."
}
 
cdl_component CYGSEM_DEVS_ETH_CSB281_ETH0_SET_ESA {
display "Set the ethernet station address"
flavor bool
default_value !CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
description "Enabling this option will allow the ethernet
station address to be forced to the value set by the
configuration. This may be required if the hardware does
not include a serial EEPROM for the ESA, and if RedBoot's
flash configuration support is not available."
cdl_option CYGDAT_DEVS_ETH_CSB281_ETH0_ESA {
display "The ethernet station address"
flavor data
default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x11}"}
description "The ethernet station address"
}
}
}
 
cdl_component CYGPKG_DEVS_ETH_CSB281_ETH1 {
display "CSB281 ethernet port 1 driver"
flavor bool
default_value 0
description "
This option includes the ethernet device driver for the
additional i82559 devices plugged into a PCI slot."
 
implements CYGHWR_NET_DRIVERS
implements CYGHWR_NET_DRIVER_ETH1
implements CYGINT_DEVS_ETH_INTEL_I82559_REQUIRED
 
cdl_option CYGDAT_DEVS_ETH_CSB281_ETH1_NAME {
display "Device name for the ethernet port 1 driver"
flavor data
default_value {"\"eth1\""}
description "
This option sets the name of the ethernet device for the
ethernet port 1."
}
 
cdl_component CYGSEM_DEVS_ETH_CSB281_ETH1_SET_ESA {
display "Set the ethernet station address"
flavor bool
default_value !CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
description "Enabling this option will allow the ethernet
station address to be forced to the value set by the
configuration. This may be required if the hardware does
not include a serial EEPROM for the ESA, and if RedBoot's
flash configuration support is not available."
cdl_option CYGDAT_DEVS_ETH_CSB281_ETH1_ESA {
display "The ethernet station address"
flavor data
default_value {"{0x00, 0xB5, 0xE0, 0xB5, 0xE0, 0x12}"}
description "The ethernet station address"
}
}
}
 
 
# note that this option's name is NOT csb281-specific, but i82559
# generic - other instantiations can set these also.
cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA {
display "RedBoot manages ESA initialization data"
flavor bool
default_value 1
 
active_if CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
 
description "Enabling this option will allow the ethernet
station address to be acquired from RedBoot's configuration data,
stored in flash memory. It can be overridden individually by the
'Set the ethernet station address' option for each interface."
 
cdl_component CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_VARS {
display "Build-in flash config fields for ESAs"
flavor bool
default_value 1
 
active_if CYGPKG_REDBOOT
active_if CYGPKG_REDBOOT_FLASH
active_if CYGSEM_REDBOOT_FLASH_CONFIG
active_if CYGPKG_REDBOOT_NETWORKING
 
description "
This option controls the presence of RedBoot flash
configuration fields for the ESAs of the interfaces when you
are building RedBoot. It is independent of whether RedBoot
itself uses the network or any particular interface; this
support is more for the application to use than for RedBoot
itself, though the application gets at the data by vector
calls; this option cannot be enabled outside of building
RedBoot."
cdl_option CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0 {
display "RedBoot manages ESA for eth0"
flavor bool
default_value 1
}
}
}
}
 
# EOF csb281_eth_drivers.cdl
/csb281/v2_0/include/devs_eth_csb281.inl
0,0 → 1,161
//==========================================================================
//
// devs/eth/powerpc/csb281/include/devs_eth_csb281.inl
//
// PCI i82559 ethernet I/O definitions.
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002, 2003 Gary Thomas
//
// 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, gthomas
// Date: 2001-01-25
// Purpose: PCI/i82559 ethernet defintions
//####DESCRIPTIONEND####
//==========================================================================
 
#include <cyg/hal/hal_intr.h> // CYGNUM_HAL_INTERRUPT_ETHR
 
#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
 
#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_BASE CYGMEM_SECTION_pci_window
#define CYGHWR_INTEL_I82559_PCI_MEM_MAP_SIZE CYGMEM_SECTION_pci_window_SIZE
#define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
#define CYGHWR_DEVS_ETH_INTEL_I82559_USE_MEMORY
 
static I82559 i82559_eth0_priv_data = {
#ifdef CYGSEM_DEVS_ETH_CSB281_ETH0_SET_ESA
hardwired_esa: 1,
mac_address: CYGDAT_DEVS_ETH_CSB281_ETH0_ESA
#else
hardwired_esa: 0,
#endif
};
 
ETH_DRV_SC(i82559_sc0,
&i82559_eth0_priv_data, // Driver specific data
CYGDAT_DEVS_ETH_CSB281_ETH0_NAME, // Name for device
i82559_start,
i82559_stop,
i82559_ioctl,
i82559_can_send,
i82559_send,
i82559_recv,
i82559_deliver,
i82559_poll,
i82559_int_vector
);
 
NETDEVTAB_ENTRY(i82559_netdev0,
"i82559_" CYGDAT_DEVS_ETH_CSB281_ETH0_NAME,
i82559_init,
&i82559_sc0);
 
#endif // CYGPKG_DEVS_ETH_CSB281_ETH0
 
 
// These arrays are used for sanity checking of pointers
I82559 *
i82559_priv_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
&i82559_eth0_priv_data,
#endif
};
 
#ifdef CYGDBG_USE_ASSERTS
// These are only used when assertions are enabled
cyg_netdevtab_entry_t *
i82559_netdev_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
&i82559_netdev0,
#endif
};
 
struct eth_drv_sc *
i82559_sc_array[CYGNUM_DEVS_ETH_INTEL_I82559_DEV_COUNT] = {
#ifdef CYGPKG_DEVS_ETH_CSB281_ETH0
&i82559_sc0,
#endif
};
#endif // CYGDBG_USE_ASSERTS
 
// --------------------------------------------------------------
// RedBoot configuration options for managing ESAs for us
 
// tell the driver there is no EEPROM on this board
#define CYGHWR_DEVS_ETH_INTEL_I82559_HAS_NO_EEPROM
 
// Decide whether to have redboot config vars for it...
#ifdef CYGPKG_REDBOOT
#include <pkgconf/redboot.h>
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#ifdef CYGPKG_REDBOOT_NETWORKING
#include <redboot.h>
#include <flash_config.h>
 
#ifdef CYGVAR_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA_ETH0
RedBoot_config_option("Network hardware address [MAC] for eth0",
eth0_esa,
ALWAYS_ENABLED, true,
CONFIG_ESA, 0
);
#endif
 
#endif
#endif
#endif
 
// and initialization code to read them
// - independent of whether we are building RedBoot right now:
#ifdef CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
 
#include <cyg/hal/hal_if.h>
 
#ifndef CONFIG_ESA
#define CONFIG_ESA (6)
#endif
 
#define CYGHWR_DEVS_ETH_INTEL_I82559_GET_ESA( p_i82559, mac_address, ok ) \
CYG_MACRO_START \
ok = false; \
ok = CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET, \
"eth0_esa", mac_address, CONFIG_ESA); \
CYG_MACRO_END
 
#endif // CYGPKG_DEVS_ETH_I82559_ETH_REDBOOT_HOLDS_ESA
 
// EOF devs_eth_csb281.inl
/csb281/v2_0/ChangeLog
0,0 → 1,50
2003-01-20 Gary Thomas <gary@mlbassoc.com>
 
* include/devs_eth_csb281.inl: Add RedBoot management of ESA.
 
2003-01-03 Gary Thomas <gary@mlbassoc.com>
 
* include/devs_eth_csb281.inl: PCI window is now in specially
mapped, uncacheable space.
 
2002-12-24 Gary Thomas <gary@mlbassoc.com>
 
* include/devs_eth_csb281.inl:
* cdl/csb281_eth_drivers.cdl: New package - ethernet support
via i82559 on PCI for Cogent CSB281 board.
 
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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####
//===========================================================================
/quicc/v2_0/cdl/quicc_eth_drivers.cdl
0,0 → 1,113
# ====================================================================
#
# quicc_eth_drivers.cdl
#
# Ethernet drivers - platform dependent support for PowerPC MPC8xx
#
# ====================================================================
#####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): gthomas
# Original data: gthomas
# Contributors:
# Date: 2000-01-25
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_DEVS_ETH_POWERPC_QUICC {
display "MPC8xx QUICC ethernet driver"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC
active_if CYGPKG_HAL_POWERPC_MPC8xx
 
implements CYGHWR_NET_DRIVERS
implements CYGHWR_NET_DRIVER_ETH0
include_dir .
include_files ; # none _exported_ whatsoever
 
description "Ethernet driver for PowerPC MPC8xx boards."
compile -library=libextras.a if_quicc.c
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE {
display "Buffer size"
flavor data
default_value 1520
description "
This option specifies the size of the internal buffers used
for the PowerPC QUICC/ethernet device."
}
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM {
display "Number of output buffers"
flavor data
legal_values 2 to 16
default_value 4
description "
This option specifies the number of output buffer packets
to be used for the PowerPC QUICC/ethernet device."
}
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM {
display "Number of input buffers"
flavor data
legal_values 2 to 16
default_value 4
description "
This option specifies the number of input buffer packets
to be used for the PowerPC QUICC/ethernet device."
}
 
cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC_OPTIONS {
display "MPC8xx QUICC ethernet driver build options"
flavor none
no_define
 
cdl_option CYGPKG_DEVS_ETH_POWERPC_QUICC_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 MPC8xx QUICC ethernet driver package. These flags are used in addition
to the set of global flags."
}
}
}
/quicc/v2_0/ChangeLog
0,0 → 1,214
2003-03-14 Nick Garnett <nickg@balti.calivar.com>
 
* src/if_quicc.c: Fixed several bugs, mostly dealing with getting
the device restarted after certain failures such as collisions.
 
* src/quicc_eth.h: Added some statistics gathering.
2003-03-06 Gary Thomas <gary@mlbassoc.com>
 
* src/if_quicc.c (quicc_eth_init): New name for CPM/DPRAM allocator.
 
2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
 
* src/quicc_eth.h:
* src/if_quicc.c: Split platform specifics into separate packages.
 
2002-08-08 Gary Thomas <gthomas@ecoscentric.com>
2002-08-08 Luoqi Chen <lchen@onetta.com>
 
* src/if_quicc.c (quicc_eth_send): Need to flush cache to force
out data, not invalidate it.
 
2002-06-14 Gary Thomas <gary@chez-thomas.org>
 
* src/if_quicc.c:
Need to include <pkgconf/io_eth_drivers.h> for proper configuration
of stand-alone (polled) vs. system (interrupt driven) mode.
 
2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
 
* src/if_quicc.c: Use CYGINT_IO_ETH_INT_SUPPORT_REQUIRED where
appropriate.
 
2001-08-22 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c:
printf() is no longer a part of RedBoot. Thus all programs
must use diag_printf() and related functions instead.
 
2001-05-07 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c (quicc_eth_init): Get ESA from RedBoot 'fconfig' data.
Improve interrupt interroperability when running with RedBoot and
sharing the network connection. Proper operation requires a new
RedBoot at least as new as this file.
 
2001-01-30 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c: New RedBoot config data layout.
 
2001-01-03 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c: Add support in RedBoot to keep ESA (since
the I2C interface is really broken).
 
2000-10-20 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c: Changes to compile in stand-alone mode.
 
2000-09-01 Hugo Tyson <hmt@cygnus.co.uk>
 
* src/if_quicc.c (quicc_eth_init): Work with new fast net
thread to do all the copying work instead of loading up DSR time.
In detail:
o New "deliver" function in the interface record.
o The DSR changed to be that new function; its arg is now the sc
pointer already, no cast needed.
o In creating the interrupt, use eth_drv_dsr (from the logical
driver) instead of quicc_eth_dsr (which is gone).
 
 
2000-08-23 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c: Add function to return interrupt vector used
by the interface.
 
2000-08-03 Gary Thomas <gthomas@redhat.com>
 
* cdl/quicc_eth_drivers.cdl: Ethernet driver package hierarchy changed.
 
2000-07-26 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c: Update for new eth_drv interfaces.
 
2000-06-22 Hugo Tyson <hmt@cygnus.co.uk>
 
* cdl/<yournamehere>.cdl: Remove the comment on the empty
include_files directive; the tools now support this correctly.
This keeps internal include files internal.
 
2000-04-07 Hugo Tyson <hmt@cygnus.co.uk>
 
* ecos.db: Re-organize device packages. This is a massive change
involving deleting all the sources for serial and ethernet drivers
from where they used to live in
packages/io/serial/current/src/ARCH/PLATFORM.[ch]
packages/net/drivers/eth/PLATFORM/current/src/...
and reinstating them in
packages/devs/serial/ARCH/PLATFORM/current/src/...
packages/devs/eth/ARCH/PLATFORM/current/src/...
 
All these new packages are properly defined in ecos.db, and are
all of type "hardware" so that a "target" can grab them.
This directory layout is descriptive of the devices we have right
now, arch and platform are separate levels just to make it easier
to navigate in the filesystem and similar to the HAL structure in
the filesystem.
 
It is *not* prescriptive of future work; for example, the mythical
common highly-portable 16550 serial driver which works on many
targets would be called "devs/serial/s16550/current", or a serial
device for a particular board (cogent springs to mind) that can
work with different CPUs fitted is "devs/serial/cogent/current".
 
Changelogs have been preserved and replicated over all the new
packages, so that no history is lost.
 
The contents of individual source files are unchanged; they build
in just the same emvironment except for a very few cases where the
config file name changed in this movement.
 
Targets in ecos.db have been redefined to bring in all relevant
hardware packages including net and serial drivers (but the newly
included packages are only active if their desired parent is
available.)
The names of CDL options (and their #defines of course) stay the
same for the serial drivers, for backward compatibility.
 
* templates/*/current.ect: these have had CYGPKG_IO_SERIAL added
rather than it being in (almost) all target definitions.
2000-03-28 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c (quicc_eth_recv): Handle case where there were
no buffers (and thus the sg_list[] contains NULL pointers).
 
2000-03-06 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c: New driver API.
 
2000-03-05 Gary Thomas <gthomas@redhat.com>
 
* src/if_quicc.c: Cleanup to remove compiler warnings.
 
2000-03-03 Gary Thomas <gthomas@redhat.com>
 
* src/quicc_eth.h: Move standard CPM defines to common (ppc8xx.h).
 
* src/if_quicc.c: Fetch ethernet hardware address (MAC) from the
board EEPROM. Also remove a bunch of diagnostic prints which aren't
needed any longer, now that the device is properly running.
 
2000-03-01 Gary Thomas <gthomas@redhat.com>
 
* src/quicc_eth.h (MBX_CTL1):
* src/if_quicc.c (quicc_eth_init): Add intialization of board control
register which lets driver work when booted from eCos/GDB.
 
2000-03-01 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/if_quicc.c: Lots of fixes. Now works, but only if application
is booted via PPCbug (some initialization is still missing).
 
2000-02-29 Gary Thomas <gthomas@cygnus.co.uk>
 
* src/quicc_eth.h:
* src/if_quicc.c: Some improvements. Almost works when booted via
PPCbug, but not from eCos/GDB.
 
2000-02-21 Gary Thomas <gthomas@cygnus.co.uk>
 
* cdl/quicc_eth_drivers.cdl:
* src/quicc_eth.h
* src/if_quicc.c: New file(s).
 
//===========================================================================
//####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####
//===========================================================================
 
/quicc/v2_0/src/if_quicc.c
0,0 → 1,828
//==========================================================================
//
// dev/if_quicc.c
//
// Ethernet device driver for PowerPC QUICC (MPC8xx) boards
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting the copyright
// holders.
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD or other sources,
// and are covered by the appropriate copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas, nickg
// Date: 2000-01-10
// Purpose:
// Description: hardware driver for MPC8xx QUICC
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
// Ethernet device driver for MPC8xx QUICC
 
#include <pkgconf/system.h>
#include <pkgconf/devs_eth_powerpc_quicc.h>
#include <pkgconf/io_eth_drivers.h>
 
#ifdef CYGPKG_NET
#include <pkgconf/net.h>
#endif
 
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/diag.h>
 
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_cache.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/drv_api.h>
 
#include <cyg/io/eth/netdev.h>
#include <cyg/io/eth/eth_drv.h>
 
#include "quicc_eth.h"
 
static unsigned char quicc_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM]
[CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE];
static unsigned char quicc_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM]
[CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE];
 
static struct quicc_eth_info quicc_eth0_info;
static unsigned char _default_enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x79, 0xB8};
static unsigned char enaddr[6];
#ifdef CYGPKG_REDBOOT
#include <pkgconf/redboot.h>
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <redboot.h>
#include <flash_config.h>
RedBoot_config_option("Network hardware address [MAC]",
quicc_esa,
ALWAYS_ENABLED, true,
CONFIG_ESA, 0
);
#endif
#endif
 
// For fetching the ESA from RedBoot
#include <cyg/hal/hal_if.h>
#ifndef CONFIG_ESA
#define CONFIG_ESA 6
#endif
 
ETH_DRV_SC(quicc_eth0_sc,
&quicc_eth0_info, // Driver specific data
"eth0", // Name for this interface
quicc_eth_start,
quicc_eth_stop,
quicc_eth_control,
quicc_eth_can_send,
quicc_eth_send,
quicc_eth_recv,
quicc_eth_deliver,
quicc_eth_int,
quicc_eth_int_vector);
 
NETDEVTAB_ENTRY(quicc_netdev,
"quicc_eth",
quicc_eth_init,
&quicc_eth0_sc);
 
// LED activity [exclusive of hardware bits]
#ifndef _get_led
#define _get_led()
#define _set_led(v)
#endif
#ifndef LED_TxACTIVE
#define LED_TxACTIVE 7
#define LED_RxACTIVE 6
#define LED_IntACTIVE 5
#endif
 
static void
set_led(int bit)
{
_set_led(_get_led() | (1<<bit));
}
 
static void
clear_led(int bit)
{
_set_led(_get_led() & ~(1<<bit));
}
 
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
static cyg_interrupt quicc_eth_interrupt;
static cyg_handle_t quicc_eth_interrupt_handle;
#endif
static void quicc_eth_int(struct eth_drv_sc *data);
 
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
// This ISR is called when the ethernet interrupt occurs
static int
quicc_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
{
cyg_drv_interrupt_mask(QUICC_ETH_INT);
cyg_drv_interrupt_acknowledge(QUICC_ETH_INT);
return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
}
#endif
 
// Deliver function (ex-DSR) handles the ethernet [logical] processing
static void
quicc_eth_deliver(struct eth_drv_sc * sc)
{
quicc_eth_int(sc);
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
// Allow interrupts to happen again
cyg_drv_interrupt_unmask(QUICC_ETH_INT);
#endif
}
 
//
// Initialize the interface - performed at system startup
// This function must set up the interface, including arranging to
// handle interrupts, etc, so that it may be "started" cheaply later.
//
static bool
quicc_eth_init(struct cyg_netdevtab_entry *tab)
{
struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
struct cp_bufdesc *rxbd, *txbd;
unsigned char *RxBUF, *TxBUF, *ep, *ap;
volatile struct ethernet_pram *enet_pram;
volatile struct scc_regs *scc;
int TxBD, RxBD;
int cache_state;
int i;
bool esa_ok = false;
 
#ifdef QUICC_ETH_FETCH_ESA
QUICC_ETH_FETCH_ESA(esa_ok);
#endif
 
if (!esa_ok) {
#if defined(CYGPKG_REDBOOT) && \
defined(CYGSEM_REDBOOT_FLASH_CONFIG)
esa_ok = flash_get_config("quicc_esa", enaddr, CONFIG_ESA);
#else
esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
"quicc_esa", enaddr, CONFIG_ESA);
#endif
if (!esa_ok) {
// Can't figure out ESA
diag_printf("QUICC_ETH - Warning! ESA unknown\n");
memcpy(&enaddr, &_default_enaddr, sizeof(enaddr));
}
}
 
// Ensure consistent state between cache and what the QUICC sees
HAL_DCACHE_IS_ENABLED(cache_state);
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
 
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
// Set up to handle interrupts
cyg_drv_interrupt_create(QUICC_ETH_INT,
CYGARC_SIU_PRIORITY_HIGH,
(cyg_addrword_t)sc, // Data item passed to interrupt handler
(cyg_ISR_t *)quicc_eth_isr,
(cyg_DSR_t *)eth_drv_dsr,
&quicc_eth_interrupt_handle,
&quicc_eth_interrupt);
cyg_drv_interrupt_attach(quicc_eth_interrupt_handle);
cyg_drv_interrupt_acknowledge(QUICC_ETH_INT);
cyg_drv_interrupt_unmask(QUICC_ETH_INT);
#endif
 
qi->pram = enet_pram = &eppc->pram[QUICC_ETH_SCC].enet_scc;
qi->ctl = scc = &eppc->scc_regs[QUICC_ETH_SCC]; // Use SCCx
 
// Shut down ethernet, in case it is already running
scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT);
 
memset((void *)enet_pram, 0, sizeof(*enet_pram));
 
TxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM * sizeof(struct cp_bufdesc));
RxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM * sizeof(struct cp_bufdesc));
 
txbd = (struct cp_bufdesc *)((char *)eppc + TxBD);
rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD);
qi->tbase = txbd;
qi->txbd = txbd;
qi->tnext = txbd;
qi->rbase = rxbd;
qi->rxbd = rxbd;
qi->rnext = rxbd;
qi->txactive = 0;
 
RxBUF = &quicc_eth_rxbufs[0][0];
TxBUF = &quicc_eth_txbufs[0][0];
 
// setup buffer descriptors
for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM; i++) {
rxbd->length = 0;
rxbd->buffer = RxBUF;
rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
RxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
rxbd++;
}
rxbd--;
rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM; i++) {
txbd->length = 0;
txbd->buffer = TxBUF;
txbd->ctrl = 0;
TxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
txbd++;
}
txbd--;
txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
 
// Set up parallel ports for connection to ethernet tranceiver
eppc->pio_papar |= (QUICC_ETH_PA_RXD | QUICC_ETH_PA_TXD);
eppc->pio_padir &= ~(QUICC_ETH_PA_RXD | QUICC_ETH_PA_TXD);
eppc->pio_paodr &= ~QUICC_ETH_PA_TXD;
 
eppc->pio_pcpar &= ~(QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
eppc->pio_pcdir &= ~(QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
eppc->pio_pcso |= (QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
 
eppc->pio_papar |= (QUICC_ETH_PA_Tx_CLOCK | QUICC_ETH_PA_Rx_CLOCK);
eppc->pio_padir &= ~(QUICC_ETH_PA_Tx_CLOCK | QUICC_ETH_PA_Rx_CLOCK);
 
// Set up clock routing
eppc->si_sicr &= ~QUICC_ETH_SICR_MASK;
eppc->si_sicr |= QUICC_ETH_SICR_ENET;
eppc->si_sicr &= ~QUICC_ETH_SICR_ENABLE;
 
// Set up DMA mode
eppc->dma_sdcr = 0x0001;
 
// Initialize shared PRAM
enet_pram->rbase = RxBD;
enet_pram->tbase = TxBD;
 
// Set Big Endian mode
enet_pram->rfcr = QUICC_SCC_FCR_BE;
enet_pram->tfcr = QUICC_SCC_FCR_BE;
 
// Size of receive buffers
enet_pram->mrblr = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
 
// Initialize CRC calculations
enet_pram->c_pres = 0xFFFFFFFF;
enet_pram->c_mask = 0xDEBB20E3; // Actual CRC formula
enet_pram->crcec = 0;
enet_pram->alec = 0;
enet_pram->disfc = 0;
 
// Frame padding
enet_pram->pads = 0x8888;
enet_pram->pads = 0x0000;
 
// Retries
enet_pram->ret_lim = 15;
enet_pram->ret_cnt = 0;
 
// Frame sizes
enet_pram->mflr = IEEE_8023_MAX_FRAME;
enet_pram->minflr = IEEE_8023_MIN_FRAME;
enet_pram->maxd1 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
enet_pram->maxd2 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
 
// Group address hash
enet_pram->gaddr1 = 0;
enet_pram->gaddr2 = 0;
enet_pram->gaddr3 = 0;
enet_pram->gaddr4 = 0;
 
// Device physical address
ep = &enaddr[sizeof(enaddr)];
ap = (unsigned char *)&enet_pram->paddr_h;
for (i = 0; i < sizeof(enaddr); i++) {
*ap++ = *--ep;
}
 
// Persistence counter
enet_pram->p_per = 0;
 
// Individual address filter
enet_pram->iaddr1 = 0;
enet_pram->iaddr2 = 0;
enet_pram->iaddr3 = 0;
enet_pram->iaddr4 = 0;
 
// Temp address
enet_pram->taddr_h = 0;
enet_pram->taddr_m = 0;
enet_pram->taddr_l = 0;
 
// Initialize the CPM (set up buffer pointers, etc).
eppc->cp_cr = QUICC_CPM_SCCx | QUICC_CPM_CR_INIT_TXRX | QUICC_CPM_CR_BUSY;
while (eppc->cp_cr & QUICC_CPM_CR_BUSY) ;
 
// Clear any pending interrupt/exceptions
scc->scc_scce = 0xFFFF;
 
// Enable interrupts
scc->scc_sccm = QUICC_SCCE_INTS | QUICC_SCCE_GRC | QUICC_SCCE_BSY;
 
// Set up SCCx to run in ethernet mode
scc->scc_gsmr_h = 0;
scc->scc_gsmr_l = QUICC_SCC_GSML_TCI | QUICC_SCC_GSML_TPL_48 |
QUICC_SCC_GSML_TPP_01 | QUICC_SCC_GSML_MODE_ENET;
 
// Sync delimiters
scc->scc_dsr = 0xD555;
 
// Protocol specifics (as if GSML wasn't enough)
scc->scc_psmr = QUICC_PMSR_ENET_CRC | QUICC_PMSR_SEARCH_AFTER_22 |
QUICC_PMSR_RCV_SHORT_FRAMES;
 
#ifdef QUICC_ETH_ENABLE
QUICC_ETH_ENABLE();
#endif
 
#ifdef QUICC_ETH_RESET_PHY
QUICC_ETH_RESET_PHY();
#endif
 
// Enable ethernet interface
#ifdef QUICC_ETH_PC_Tx_ENABLE
eppc->pio_pcpar |= QUICC_ETH_PC_Tx_ENABLE;
eppc->pio_pcdir &= ~QUICC_ETH_PC_Tx_ENABLE;
#else
eppc->pip_pbpar |= QUICC_ETH_PB_Tx_ENABLE;
eppc->pip_pbdir |= QUICC_ETH_PB_Tx_ENABLE;
#endif
 
if (cache_state)
HAL_DCACHE_ENABLE();
 
// Initialize upper level driver
(sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
 
// Set LED state
clear_led(LED_TxACTIVE);
clear_led(LED_RxACTIVE);
 
return true;
}
 
//
// This function is called to shut down the interface.
//
static void
quicc_eth_stop(struct eth_drv_sc *sc)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
volatile struct scc_regs *scc = qi->ctl;
 
// Disable the device!
scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT);
}
 
//
// 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
quicc_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
volatile struct scc_regs *scc = qi->ctl;
 
// Enable the device!
scc->scc_gsmr_l |= QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT;
}
 
//
// This function is called for low level "control" operations
//
static int
quicc_eth_control(struct eth_drv_sc *sc, unsigned long key,
void *data, int length)
{
switch (key) {
case ETH_DRV_SET_MAC_ADDRESS:
return 0;
break;
 
#ifdef ETH_DRV_GET_IF_STATS
case ETH_DRV_GET_IF_STATS:
{
struct ether_drv_stats *p = (struct ether_drv_stats *)data;
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
 
strcpy( p->description, "QUICC (MPC8xx) SCC Ethernet" );
CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
 
// Really need to determine the following values properly, for
// now just assume the link is up, full duplex, unknown speed.
p->operational = 3; // LINK UP
p->duplex = 1;
p->speed = 0;
 
{
p->supports_dot3 = false;
 
// Those commented out are not available on this chip.
 
p->tx_good = qi->tx_good ;
//p->tx_max_collisions = qi->tx_max_collisions ;
p->tx_late_collisions = qi->tx_late_collisions ;
p->tx_underrun = qi->tx_underrun ;
p->tx_carrier_loss = qi->tx_carrier_loss ;
p->tx_deferred = qi->tx_deferred ;
//p->tx_sqetesterrors = qi->tx_sqetesterrors ;
//p->tx_single_collisions = qi->tx_single_collisions;
//p->tx_mult_collisions = qi->tx_mult_collisions ;
//p->tx_total_collisions = qi->tx_total_collisions ;
p->rx_good = qi->rx_good ;
p->rx_crc_errors = qi->rx_crc_errors ;
p->rx_align_errors = qi->rx_align_errors ;
p->rx_resource_errors = qi->rx_resource_errors ;
p->rx_overrun_errors = qi->rx_overrun_errors ;
p->rx_collisions = qi->rx_collisions ;
p->rx_short_frames = qi->rx_short_frames ;
p->rx_too_long_frames = qi->rx_long_frames ;
//p->rx_symbol_errors = qi->rx_symbol_errors ;
p->interrupts = qi->interrupts ;
p->rx_count = qi->rx_count ;
p->rx_deliver = qi->rx_deliver ;
p->rx_resource = qi->rx_resource ;
p->rx_restart = qi->rx_restart ;
p->tx_count = qi->tx_count ;
p->tx_complete = qi->tx_complete ;
p->tx_dropped = qi->tx_dropped ;
}
 
p->tx_queue_len = CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM;
 
return 0; // OK
}
#endif
 
default:
return 1;
break;
}
}
 
//
// This function is called to see if another packet can be sent.
// It should return the number of packets which can be handled.
// Zero should be returned if the interface is busy and can not send any more.
//
static int
quicc_eth_can_send(struct eth_drv_sc *sc)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
 
return (qi->txactive < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM);
}
 
//
// This routine is called to send data to the hardware.
static void
quicc_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
int total_len, unsigned long key)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
volatile struct cp_bufdesc *txbd, *txfirst;
volatile char *bp;
int i, txindex, cache_state;
unsigned int ctrl;
 
qi->tx_count++;
// Find a free buffer
txbd = txfirst = qi->txbd;
if ((txbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int )))
#ifdef CYGPKG_NET
panic ("No free xmit buffers");
#else
diag_printf("QUICC Ethernet: No free xmit buffers\n");
#endif
 
// Remember the next buffer to try
if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
qi->txbd = qi->tbase;
} else {
qi->txbd = txbd+1;
}
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
qi->txkey[txindex] = key;
// Set up buffer
txbd->length = total_len;
bp = txbd->buffer;
for (i = 0; i < sg_len; i++) {
memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
bp += sg_list[i].len;
}
// Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_FLUSH(txbd->buffer, txbd->length); // Make sure no stale data
}
// Send it on it's way
ctrl = txbd->ctrl & ~QUICC_BD_TX_PAD;
if (txbd->length < IEEE_8023_MIN_FRAME) {
ctrl |= QUICC_BD_TX_PAD;
}
txbd->ctrl = ctrl | QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int |
QUICC_BD_TX_LAST | QUICC_BD_TX_TC;
qi->txactive++;
set_led(LED_TxACTIVE);
}
 
//
// This function is called when a packet has been received. It's 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
// 'quicc_eth_recv' will be called to actually fetch it from the hardware.
//
static void
quicc_eth_RxEvent(struct eth_drv_sc *sc)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
volatile struct cp_bufdesc *rxbd;
 
rxbd = qi->rnext;
while ((rxbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
 
qi->rx_count++;
if( rxbd->ctrl & QUICC_BD_RX_MISS )
{
qi->rx_miss++;
}
if( rxbd->ctrl & QUICC_BD_RX_LG )
{
qi->rx_long_frames++;
}
if( rxbd->ctrl & QUICC_BD_RX_NO )
{
qi->rx_align_errors++;
}
if( rxbd->ctrl & QUICC_BD_RX_SH )
{
qi->rx_short_frames++;
}
if( rxbd->ctrl & QUICC_BD_RX_CR )
{
qi->rx_crc_errors++;
}
if( rxbd->ctrl & QUICC_BD_RX_OV )
{
qi->rx_overrun_errors++;
}
 
if( rxbd->ctrl & QUICC_BD_RX_CL )
{
qi->rx_collisions++;
}
 
if( (rxbd->ctrl & QUICC_BD_RX_ERRORS) == 0 )
{
qi->rx_good++;
// OK frame - Prepare for callback
qi->rxbd = rxbd; // Save for callback
set_led(LED_RxACTIVE);
(sc->funs->eth_drv->recv)(sc, rxbd->length);
clear_led(LED_RxACTIVE);
}
// Clear flags and wrap if needed else step up BD pointer
if (rxbd->ctrl & QUICC_BD_CTL_Wrap)
{
rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int | QUICC_BD_CTL_Wrap;
rxbd = qi->rbase;
}
else
{
rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
rxbd++;
}
}
// Remember where we left off
qi->rnext = (struct cp_bufdesc *)rxbd;
}
 
//
// This function is called as a result of the "eth_drv_recv()" call above.
// It's 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
quicc_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
unsigned char *bp;
int i, cache_state;
int sg_list_null_buffer = 0;
bp = (unsigned char *)qi->rxbd->buffer;
// Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data
}
for (i = 0; i < sg_len; i++) {
if (sg_list[i].buf != 0) {
memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
bp += sg_list[i].len;
}
else
sg_list_null_buffer = 1;
}
 
// A NULL sg_list buffer usually means no mbufs, so we don't count
// it as a delivery, instead we count it as a resource error.
if (!sg_list_null_buffer)
qi->rx_deliver++;
else
qi->rx_resource++;
 
}
 
 
static void
quicc_eth_command( struct eth_drv_sc *sc, unsigned long cmd)
{
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
eppc->cp_cr = QUICC_CPM_SCCx | cmd | QUICC_CPM_CR_BUSY;
 
while (eppc->cp_cr & QUICC_CPM_CR_BUSY )
continue;
}
 
static void
quicc_eth_TxEvent(struct eth_drv_sc *sc, int stat)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
volatile struct cp_bufdesc *txbd;
int txindex;
bool restart = false;
 
txbd = qi->tnext;
while ((txbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
 
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
 
qi->tx_complete++;
(sc->funs->eth_drv->tx_done)(sc, qi->txkey[txindex], 0);
txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset int pending bit
 
if (txbd->ctrl & QUICC_BD_TX_LC )
qi->tx_late_collisions++, restart = true;
if (txbd->ctrl & QUICC_BD_TX_RL )
qi->tx_retransmit_error++, restart = true;
if (txbd->ctrl & QUICC_BD_TX_UN )
qi->tx_underrun++, restart = true;
if (txbd->ctrl & QUICC_BD_TX_CSL )
qi->tx_carrier_loss++;
if (txbd->ctrl & QUICC_BD_TX_HB )
qi->tx_heartbeat_loss++;
if (txbd->ctrl & QUICC_BD_TX_DEF )
qi->tx_deferred++;
 
if( (txbd->ctrl & QUICC_BD_TX_ERRORS) == 0 )
qi->tx_good++;
 
if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
txbd->ctrl = QUICC_BD_CTL_Wrap;
txbd = qi->tbase;
} else {
txbd->ctrl = 0;
txbd++;
}
qi->txactive--;
}
 
if (qi->txactive == 0) {
clear_led(LED_TxACTIVE);
}
// Remember where we left off
qi->tnext = (struct cp_bufdesc *)txbd;
 
if (restart)
{
quicc_eth_command(sc,QUICC_CPM_CR_RESTART_TX);
qi->tx_restart++;
}
}
 
//
// Interrupt processing
//
static void
quicc_eth_int(struct eth_drv_sc *sc)
{
struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
volatile struct scc_regs *scc = qi->ctl;
unsigned short scce;
 
qi->interrupts++;
 
while ( (scce = scc->scc_scce) != 0 )
{
scc->scc_scce = scce;
if ( (scce & (QUICC_SCCE_TXE | QUICC_SCCE_TX)) != 0)
{
quicc_eth_TxEvent(sc, scce);
}
if ( (scce & ( QUICC_SCCE_RXF | QUICC_SCCE_RX )) != 0)
{
quicc_eth_RxEvent(sc);
}
if ( (scce & QUICC_SCCE_BSY) != 0)
{
qi->rx_resource_errors++;
}
if ( (scce & QUICC_SCCE_GRC) != 0 )
{
quicc_eth_command(sc, QUICC_CPM_CR_RESTART_TX);
qi->tx_restart++;
quicc_eth_command(sc, QUICC_CPM_CR_HUNT_MODE);
qi->rx_restart++;
}
}
}
 
//
// Interrupt vector
//
static int
quicc_eth_int_vector(struct eth_drv_sc *sc)
{
return (QUICC_ETH_INT);
}
/quicc/v2_0/src/quicc_eth.h
0,0 → 1,203
//==========================================================================
//
// quicc_eth.h
//
// PowerPC QUICC (MPC8xx) ethernet
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
// Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting the copyright
// holders.
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD or other sources,
// and are covered by the appropriate copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): gthomas
// Contributors: gthomas, nickg
// Date: 2000-01-10
// Purpose:
// Description:
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
// PowerPC QUICC (MPC8xx) Ethernet
 
#include <cyg/hal/quicc/ppc8xx.h> // QUICC structure definitions
 
struct quicc_eth_info {
volatile struct ethernet_pram *pram; // Parameter RAM pointer
volatile struct scc_regs *ctl; // SCC control registers
volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use
struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor
struct cp_bufdesc *tnext, *rnext; // Next descriptor to check for interrupt
int txsize, rxsize; // Length of individual buffers
int txactive; // Count of active Tx buffers
unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM];
 
// Keep some statistics
cyg_uint32 interrupts;
 
cyg_uint32 rx_count;
cyg_uint32 rx_deliver;
cyg_uint32 rx_resource;
cyg_uint32 rx_restart;
cyg_uint32 rx_good;
cyg_uint32 rx_crc_errors;
cyg_uint32 rx_align_errors;
cyg_uint32 rx_resource_errors;
cyg_uint32 rx_overrun_errors;
cyg_uint32 rx_collisions;
cyg_uint32 rx_short_frames;
cyg_uint32 rx_long_frames;
cyg_uint32 rx_miss;
 
cyg_uint32 tx_count;
cyg_uint32 tx_complete;
cyg_uint32 tx_restart;
cyg_uint32 tx_good;
cyg_uint32 tx_dropped;
cyg_uint32 tx_underrun;
cyg_uint32 tx_late_collisions;
cyg_uint32 tx_carrier_loss;
cyg_uint32 tx_retransmit_error;
cyg_uint32 tx_heartbeat_loss;
cyg_uint32 tx_deferred;
};
 
// SCC registers - ethernet mode
 
// General SCC mode register
#define QUICC_SCC_GSMH_IRP 0x00040000 // Infared polarity
#define QUICC_SCC_GSMH_GDE 0x00010000 // Glitch detect enable
#define QUICC_SCC_GSMH_TCRC 0x00008000 // Transparent CRC
#define QUICC_SCC_GSMH_REVD 0x00004000 // Reverse data (transparent)
#define QUICC_SCC_GSMH_TRX 0x00002000 // Transparent Rx
#define QUICC_SCC_GSMH_TTX 0x00001000 // Transparent Tx
 
#define QUICC_SCC_GSML_TCI 0x10000000 // Transmit clock invert
#define QUICC_SCC_GSML_TPL 0x00E00000 // Tx preamble bits
#define QUICC_SCC_GSML_TPL_8 0x00200000 // 8 bits
#define QUICC_SCC_GSML_TPL_16 0x00400000 // 16 bits
#define QUICC_SCC_GSML_TPL_32 0x00600000 // 32 bits
#define QUICC_SCC_GSML_TPL_48 0x00800000 // 48 bits (used for ethernet)
#define QUICC_SCC_GSML_TPL_64 0x00A00000 // 64 bits
#define QUICC_SCC_GSML_TPL_128 0x00C00000 // 128 bits
#define QUICC_SCC_GSML_TPP 0x00180000 // Tx preamble pattern
#define QUICC_SCC_GSML_TPP_00 0x00000000 // all zeroes
#define QUICC_SCC_GSML_TPP_01 0x00080000 // 10 repeats (ethernet)
#define QUICC_SCC_GSML_TPP_10 0x00100000 // 01 repeats
#define QUICC_SCC_GSML_TPP_11 0x00180000 // all ones (localtalk)
#define QUICC_SCC_GSML_ENR 0x00000020 // Enable receiver
#define QUICC_SCC_GSML_ENT 0x00000010 // Enable transmitter
#define QUICC_SCC_GSML_MODE 0x0000000F // Operating mode
#define QUICC_SCC_GSML_MODE_HDLC 0x00000000
#define QUICC_SCC_GSML_MODE_ATALK 0x00000002
#define QUICC_SCC_GSML_MODE_ENET 0x0000000C
 
// Function code
#define QUICC_SCC_FCR_BE 0x0010 // Big Endian operation
 
// Event register
#define QUICC_SCCE_GRC 0x0080 // Gracefull stop complete
#define QUICC_SCCE_TXE 0x0010 // Transmit error
#define QUICC_SCCE_RXF 0x0008 // Received full frame
#define QUICC_SCCE_BSY 0x0004 // No free receive buffers
#define QUICC_SCCE_TX 0x0002 // Buffer transmit complete
#define QUICC_SCCE_RX 0x0001 // Buffer received
#define QUICC_SCCE_INTS (QUICC_SCCE_TXE | QUICC_SCCE_RXF | QUICC_SCCE_TX)
 
// Protocol specific mode register
#define QUICC_PMSR_HEARTBEAT 0x8000 // Enable heartbeat
#define QUICC_PMSR_FORCE_COLLISION 0x4000 // Force a collision
#define QUICC_PMSR_RCV_SHORT_FRAMES 0x2000 // Accept short frames
#define QUICC_PMSR_INDIV_ADDR_MODE 0x1000 // Check individual address (hash)
#define QUICC_PMSR_ENET_CRC 0x0800 // Enable ethernet CRC mode
#define QUICC_PMSR_PROMISCUOUS 0x0200 // Enable promiscuous mode
#define QUICC_PMSR_BROADCAST 0x0100 // Accept broadcast packets
#define QUICC_PMSR_SPECIAL_BACKOFF 0x0080 // Enable special backoff timer
#define QUICC_PMSR_LOOPBACK 0x0040 // Enable loopback mode
#define QUICC_PMSR_SAMPLE_INPUTS 0x0020 // Discretely look at input pins
#define QUICC_PMSR_LATE_COLLISION 0x0010 // Enable late collision window
#define QUICC_PMSR_SEARCH_AFTER_22 0x000A // Start frame search after 22 bits
#define QUICC_PMSR_FULL_DUPLEX 0x0001 // Full duplex mode
 
// Receive buffer status
#define QUICC_BD_RX_LAST 0x0800 // Last buffer in chain
#define QUICC_BD_RX_FIRST 0x0400 // First buffer in chain
#define QUICC_BD_RX_MISS 0x0100 // Missed data
#define QUICC_BD_RX_LG 0x0020 // Rx frame too long
#define QUICC_BD_RX_NO 0x0010 // Rx frame not properly aligned
#define QUICC_BD_RX_SH 0x0008 // Rx frame too short
#define QUICC_BD_RX_CR 0x0004 // Bad CRC
#define QUICC_BD_RX_OV 0x0002 // Rx overrun
#define QUICC_BD_RX_CL 0x0001 // Collision during frame
 
#define QUICC_BD_RX_ERRORS ( QUICC_BD_RX_CL | QUICC_BD_RX_OV | \
QUICC_BD_RX_CR | QUICC_BD_RX_SH | \
QUICC_BD_RX_NO | QUICC_BD_RX_LG | \
QUICC_BD_RX_MISS )
 
// Transmit buffer status
#define QUICC_BD_TX_PAD 0x4000 // Pad short packets
#define QUICC_BD_TX_LAST 0x0800 // Last buffer in chain
#define QUICC_BD_TX_TC 0x0400 // Transmit CRC after buffer
#define QUICC_BD_TX_DEF 0x0200 // Transmission was deferred
#define QUICC_BD_TX_HB 0x0100 // Heartbeat detected
#define QUICC_BD_TX_LC 0x0080 // Late collision
#define QUICC_BD_TX_RL 0x0040 // Retransmit limit exceeded
#define QUICC_BD_TX_RC 0x003C // Retry count
#define QUICC_BD_TX_UN 0x0002 // Tx underrun
#define QUICC_BD_TX_CSL 0x0001 // Carrier lost
 
#define QUICC_BD_TX_ERRORS (QUICC_BD_TX_CSL | QUICC_BD_TX_UN | \
QUICC_BD_TX_RL | QUICC_BD_TX_LC | \
QUICC_BD_TX_HB | QUICC_BD_TX_DEF )
 
#include CYGDAT_DEVS_QUICC_ETH_INL // Platform specifics
 
#define IEEE_8023_MAX_FRAME 1518 // Largest possible ethernet frame
#define IEEE_8023_MIN_FRAME 64 // Smallest possible ethernet frame
 
/viper/v2_0/cdl/viper_eth_drivers.cdl
0,0 → 1,67
#====================================================================
#
# viper_eth_drivers.cdl
#
# Hardware specifics for A&M Viper ethernet
#
#====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002 Gary Thomas
##
## 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): gthomas, hmt
# Original data: gthomas
# Contributors: gthomas
# Date: 2001-02-14
#
#####DESCRIPTIONEND####
#
#====================================================================
 
cdl_package CYGPKG_DEVS_ETH_POWERPC_VIPER {
display "A&M Viper (MPC8xxT) ethernet support"
description "Hardware specifics for A&M Viper ethernet"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC
active_if CYGPKG_HAL_POWERPC_MPC8xx
 
include_dir cyg/io
 
define_proc {
puts $::cdl_system_header "#define CYGDAT_DEVS_FEC_ETH_INL <cyg/io/viper_eth.inl>"
}
}
/viper/v2_0/include/viper_eth.inl
0,0 → 1,79
#ifndef CYGONCE_DEVS_VIPER_ETH_INL
#define CYGONCE_DEVS_VIPER_ETH_INL
//==========================================================================
//
// viper_eth.inl
//
// Hardware specifics for A&M Viper ethernet support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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): gthomas
// Contributors: gthomas
// Date: 2002-09-03
// Purpose:
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
 
extern int hal_viper_get_led(void);
extern void hal_viper_set_led(int);
 
#define _get_led() hal_viper_get_led()
#define _set_led(v) hal_viper_set_led(v)
 
#define LED_TxACTIVE 7
#define LED_RxACTIVE 6
#define LED_IntACTIVE 5
 
// Interrupt generated by device
#define FEC_ETH_INT CYGNUM_HAL_INTERRUPT_SIU_LVL1
// Address of PHY (transceiver) device
#define FEC_ETH_PHY 0
 
// Reset the PHY - analagous to hardware reset
#define FEC_ETH_RESET_PHY() \
eppc->pip_pbdat &= ~0x00004000; /* Reset PHY chip */ \
CYGACC_CALL_IF_DELAY_US(10000); /* 10ms */ \
eppc->pip_pbdat |= 0x00004000; /* Enable PHY chip */
 
#endif // CYGONCE_DEVS_VIPER_ETH_INL
// ------------------------------------------------------------------------
/viper/v2_0/ChangeLog
0,0 → 1,43
2002-09-03 Gary Thomas <gary@mlbassoc.com>
 
* include/viper_eth.inl:
* cdl/viper_eth_drivers.cdl: New package - platform specifics for
PowerPC/FEC ethernet 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####
//===========================================================================
 
/mbx/v2_0/cdl/mbx_eth_drivers.cdl
0,0 → 1,69
#====================================================================
#
# mbx_eth_drivers.cdl
#
# Hardware specifics for Motorola MBX ethernet
#
#====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002 Gary Thomas
##
## 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): gthomas, hmt
# Original data: gthomas
# Contributors: gthomas
# Date: 2001-02-14
#
#####DESCRIPTIONEND####
#
#====================================================================
 
cdl_package CYGPKG_DEVS_ETH_POWERPC_MBX {
display "Motorola MBX (MPC8xxT) ethernet support"
description "Hardware specifics for Motorola MBX ethernet"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC
active_if CYGPKG_HAL_POWERPC_MPC8xx
active_if CYGPKG_HAL_POWERPC_MBX
 
requires CYGPKG_DEVS_ETH_POWERPC_QUICC
 
include_dir cyg/io
define_proc {
puts $::cdl_system_header "#define CYGDAT_DEVS_QUICC_ETH_INL <cyg/io/mbx_eth.inl>"
}
}
/mbx/v2_0/include/mbx_eth.inl
0,0 → 1,99
#ifndef CYGONCE_DEVS_MBX_ETH_INL
#define CYGONCE_DEVS_MBX_ETH_INL
//==========================================================================
//
// mbx_eth.inl
//
// Hardware specifics for Motorola MBX ethernet support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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): gthomas
// Contributors: gthomas
// Date: 2002-11-19
// Purpose:
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#define _get_led()
#define _set_led(v)
 
#define LED_TxACTIVE 7
#define LED_RxACTIVE 6
#define LED_IntACTIVE 5
 
#if 0
// Fetch ESA from on-board EEPROM
extern int _mbx_fetch_VPD(int, void *, int);
#define QUICC_ETH_FETCH_ESA(_ok_) \
_ok_ = _mbx_fetch_VPD(VPD_ETHERNET_ADDRESS, enaddr, sizeof(enaddr));
#endif
 
// Reset/enable any external hardware
#define QUICC_ETH_ENABLE() \
*MBX_CTL1 = MBX_CTL1_ETEN | MBX_CTL1_TPEN; /* Enable ethernet, TP mode */
 
 
// Port layout - uses SCC1
#define QUICC_ETH_PA_RXD 0x0001 // Rx Data on Port A
#define QUICC_ETH_PA_TXD 0x0002 // Tx Data on Port A
#define QUICC_ETH_PA_Tx_CLOCK 0x0200 // Tx Clock = CLK2
#define QUICC_ETH_PA_Rx_CLOCK 0x0800 // Rx Clock = CLK4
#define QUICC_ETH_PC_Tx_ENABLE 0x0001 // Tx Enable (TENA)
#define QUICC_ETH_PC_COLLISION 0x0010 // Collision detect
#define QUICC_ETH_PC_Rx_ENABLE 0x0020 // Rx Enable (RENA)
#define QUICC_ETH_SICR_MASK 0x00FF // SI Clock Route - important bits
#define QUICC_ETH_SICR_ENET (7<<3)|(5<<0) // Rx=CLK4, Tx=CLK2
#define QUICC_ETH_SICR_ENABLE 0x0040 // Enable SCC1 to use NMSI
#define QUICC_ETH_INT CYGNUM_HAL_INTERRUPT_CPM_SCC1
#define QUICC_ETH_SCC 0 // SCC1
#define QUICC_CPM_SCCx QUICC_CPM_SCC1
 
#define MBX_CTL1 (cyg_uint8 *)0xFA100000 // System control register
#define MBX_CTL1_ETEN 0x80 // 1 = Enable ethernet tranceiver
#define MBX_CTL1_ELEN 0x40 // 1 = Enable ethernet loopback
#define MBX_CTL1_EAEN 0x20 // 1 = Auto select ethernet interface
#define MBX_CTL1_TPEN 0x10 // 0 = AUI, 1 = TPI
#define MBX_CTL1_FDDIS 0x08 // 1 = Disable full duplex (if TP mode)
 
 
#endif // CYGONCE_DEVS_MBX_ETH_INL
// ------------------------------------------------------------------------
/mbx/v2_0/ChangeLog
0,0 → 1,44
2002-11-25 Gary Thomas <gthomas@ecoscentric.com>
 
* include/mbx_eth.inl:
* cdl/mbx_eth_drivers.cdl: New package - platform specifics for
Motorola MBX (PowerPC 860) board.
 
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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####
//===========================================================================
 
/quicc2/v2_0/cdl/quicc2_eth_drivers.cdl
0,0 → 1,115
# ====================================================================
#
# fec_eth_drivers.cdl
#
# Ethernet drivers - platform dependent support for PowerPC MPC8260
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002 Gary Thomas
##
## 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): mtek
# Original data: gthomas
# Contributors:
# Date: 2002-02-20
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_DEVS_ETH_POWERPC_QUICC2 {
display "MPC8260 FEC ethernet driver"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC
active_if CYGPKG_HAL_POWERPC_MPC8260
 
implements CYGHWR_NET_DRIVERS
implements CYGHWR_NET_DRIVER_ETH0
include_dir .
include_files ; # none _exported_ whatsoever
 
description "Fast ethernet driver for PowerPC MPC8260 boards."
compile -library=libextras.a if_fec.c EnetPHY.c
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE {
display "Buffer size"
flavor data
default_value 1540
description "
This option specifies the size of the internal buffers used
for the PowerPC FEC/ethernet device."
}
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM {
display "Number of output buffers"
flavor data
legal_values 2 to 16
default_value 4
description "
This option specifies the number of output buffer packets
to be used for the PowerPC FEC/ethernet device."
}
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM {
display "Number of input buffers"
flavor data
legal_values 2 to 16
default_value 4
description "
This option specifies the number of input buffer packets
to be used for the PowerPC FEC/ethernet device."
}
 
cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC2_OPTIONS {
display "MPC8260 FEC ethernet driver build options"
flavor none
no_define
 
cdl_option CYGPKG_DEVS_ETH_POWERPC_QUICC2_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 MPC8260 FEC ethernet driver package.
These flags are used in addition to the set of global
flags."
}
}
}
/quicc2/v2_0/ChangeLog
0,0 → 1,49
2002-12-12 Gary Thomas <gthomas@ecoscentric.com>
2002-12-12 Patrick Doyle <wpd@delcomsys.com>
 
* src/types.h:
* src/if_fec.c:
* src/fec.h:
* src/EnetPHY.h:
* src/EnetPHY.c:
* cdl/quicc2_eth_drivers.cdl: New package; ethernet drivers for
PowerPC/QUICC2 based systems (like MPC8260).
 
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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####
//===========================================================================
 
/quicc2/v2_0/src/EnetPHY.h
0,0 → 1,111
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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####
/*------------------------------------------------------------------
*
* FILE: EnetPHY.c
*
* DESCRIPTION: LXT970a driver header file
*
*
* Modified for MPC8260 VADS board
*-------------------------------------------------------------------*/
 
#ifndef _EnetPHY_H
#define _EnetPHY_H
 
#include "types.h"
 
// Board control and status registers
typedef struct bcsr {
UINT32 bcsr0;
UINT32 bcsr1;
UINT32 bcsr2;
UINT32 bcsr3;
} t_BCSR;
 
// Fast ethernet enable/reset pins on bcsr
#define FETHIEN_ 0x08000000
#define FETHRST_ 0x04000000
 
 
/**************************/
/* The API for PHY Device */
/**************************/
 
void EnableResetPHY(volatile t_BCSR *pBCSR);
UINT16 InitEthernetPHY(VUINT32* pdir, VUINT32* pdat, UINT16 link);
UINT16 EthernetPHYInterruptHandler(void);
void EnablePHYinterrupt(UINT8 enable);
UINT16 LinkTestPHY(void);
 
 
typedef enum MDIORW {READ, WRITE} MDIORW;
 
 
#define LINKERROR 0xFFFF
#define NOTLINKED 0x0000
#define TEN_HD 0x0020
#define TEN_FD 0x0040
#define HUNDRED_HD 0x0080
#define HUNDRED_FD 0x0100
 
#define MD_TEST_FRAME 0xDEAD
 
//8260 VADS Pin Connections
#define MDIO_PIN_MASK 0x00400000 //PC9 for 8260 VADS
#define MDC_PIN_MASK 0x00200000 //PC10 for 8260 VADS
 
//#define MDIO_PIN_MASK 0x00000200 //PC9 for 8260 VADS
//#define MDC_PIN_MASK 0x00000400 //PC10 for 8260 VADS
 
//IEEE 802.3 PHY Register Definitions
#define CONTROL_REG 0
#define STATUS_REG 1
#define PHY_ID_REG_A 2
#define PHY_ID_REG_B 3
#define AUTONEG_AD_REG 4
#define AUTONEG_LINKPARTNER_REG 5
#define AUTONEG_EXP_REG 6
 
//LXT970a Specific Register Definitions
#define MIRROR_REG 16
#define INT_EN_REG 17
#define INT_STAT_REG 18
#define CONFIG_REG 19
#define CHIP_STAT_REG 20
 
//Clock Timing Control
#define MDC_HOLD_TIME 50
 
#endif
/quicc2/v2_0/src/fec.h
0,0 → 1,173
//==========================================================================
//
// fec.h
//
// PowerPC MPC8260 fast ethernet (FEC)
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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): mtek
// Contributors: pfine
// Date: 2002-02-20
// Purpose:
// Description:
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
// The port connected to the ethernet
#define QUICC2_VADS_IMM_BASE 0x04700000
#define FCC2 1
 
/* ------------------------ */
/* FCC REGISTER CONSTANTS */
/* ------------------------ */
 
// GFMR masks (RESET: 0x00000000)
#define FEC_GFMR_EN_Rx 0x00000020 // Receive enable
#define FEC_GFMR_EN_Tx 0x00000010 // Transmit enable
#define FEC_GFMR_INIT 0x0000000C // mode=ethernet
#define FEC_GFMR_OFFSET 0x11320
 
//PSMR masks (RESET: 0x00000000)
#define FEC_PSMR_INIT 0x00000080 // 32-bit CRC
#define FEC_PSMR_OFFSET 0x11324
 
//TODR masks (RESET: 0x0000)
#define FEC_TOD_INIT 0x0000
#define FEC_TOD_SET 0x8000
#define FEC_TOD_OFFSET 0x11328
 
//DSR masks (RESET: 0x7E7E)
#define FEC_DSR_INIT 0xD555
#define FEC_DSR_OFFSET 0x1132C
 
//FCCE & FCCM (RESET: 0x0000)
#define FEC_EV_GRA 0x00800000 // Graceful stop
#define FEC_EV_RXC 0x00400000 // A control frame has been received
#define FEC_EV_TXC 0x00200000 // Out of sequence frame sent
#define FEC_EV_TXE 0x00100000 // Error in transmission channel
#define FEC_EV_RXF 0x00080000 // A complete frame received
#define FEC_EV_BSY 0x00040000 // A received frame discarded due to lack
// of buffers
#define FEC_EV_TXB 0x00020000 // A buffer sent to ethernet
#define FEC_EV_RXB 0x00010000 // A buffer that is a non-complete frame
// is received
#define FEC_FCCE_OFFSET 0x11330
#define FEC_FCCM_OFFSET 0x11334
 
/* ------------------------------ */
/* FCC PARAMETER RAM CONSTANTS */
/* ------------------------------ */
 
#define FEC_PRAM_RIPTR 0x3000 // 32 byte buffer in dual port RAM
#define FEC_PRAM_TIPTR 0xB000 // 32 byte buffer in dual port RAM
#define FEC_FCR_INIT 0x00000000 // Clear the reserved bits
#define FEC_FCR_MOT_BO 0x10000000 // Motorola byte ordering
#define FEC_PRAM_C_MASK 0xDEBB20E3 // Constant MASK for CRC
#define FEC_PRAM_C_PRES 0xFFFFFFFF // CRC Preset
#define FEC_PRAM_RETLIM 15 // Retry limit
#define FEC_PRAM_PER_LO 5 // Persistance
#define FEC_PRAM_PER_HI 0
#define FEC_PRAM_MRBLR 1536
#define FEC_MAX_FLR 1518 // Max frame length
#define FEC_MIN_FLR 64 // Min frame length
#define FEC_PRAM_PAD_CH 0x8888
#define FEC_PRAM_MAXD 1520
#define FEC_PRAM_OFFSET 0x8500 // Offset of t_Fcc_Pram in 82xx
 
/* ------------------------------ */
/* BUFFER DESCRIPTOR CONSTANTS */
/* ------------------------------ */
#define FEC_PRAM_RxBD_Base (FEC_PRAM_RIPTR + 0x400)
#define FEC_BD_Rx_Empty 0x8000 // Buffer is empty, FEC can fill
#define FEC_BD_Rx_Wrap 0x2000 // Wrap: Last buffer in ring
#define FEC_BD_Rx_Int 0x1000 // Interrupt
#define FEC_BD_Rx_Last 0x0800 // Last buffer in frame
#define FEC_BD_Rx_Miss 0x0100 // Miss: promiscious mode
#define FEC_BD_Rx_BC 0x0080 // Broadcast address
#define FEC_BD_Rx_MC 0x0040 // Multicast address
#define FEC_BD_Rx_LG 0x0020 // Frame length violation
#define FEC_BD_Rx_NO 0x0010 // Non-octet aligned frame
#define FEC_BD_Rx_SH 0x0008 // Short frame
#define FEC_BD_Rx_CR 0x0004 // CRC error
#define FEC_BD_Rx_OV 0x0002 // Overrun
#define FEC_BD_Rx_TR 0x0001 // Frame truncated. late collision
 
#define FEC_PRAM_TxBD_Base (FEC_PRAM_TIPTR + 0x400)
#define FEC_BD_Tx_Ready 0x8000 // Frame ready
#define FEC_BD_Tx_Pad 0x4000 // Pad short frames
#define FEC_BD_Tx_Wrap 0x2000 // Wrap: Last buffer in ring
#define FEC_BD_Tx_Int 0x1000 // Interrupt
#define FEC_BD_Tx_Last 0x0800 // Last buffer in frame
#define FEC_BD_Tx_TC 0x0400 // Send CRC after data
#define FEC_BD_Tx_DEF 0x0200 // Defer indication
#define FEC_BD_Tx_HB 0x0100 // Heartbeat
#define FEC_BD_Tx_LC 0x0080 // Late collision
#define FEC_BD_Tx_RL 0x0040 // Retransmission limit
#define FEC_BD_Tx_RC 0x003C // Retry count
#define FEC_BD_Tx_UN 0x0002 // Underrun
#define FEC_BD_Tx_CSL 0x0001 // Carrier sense lost
 
 
// Buffer descriptor
struct fec_bd {
volatile unsigned short ctrl;
volatile unsigned short length;
volatile unsigned char *buffer;
};
 
 
struct fec_eth_info {
volatile struct fcc_regs *fcc_reg; // See "mpc8260.h"
struct fec_bd *txbd, *rxbd; // Next Tx,Rx descriptor to use
struct fec_bd *tbase, *rbase; // First Tx,Rx descriptor
struct fec_bd *tnext, *rnext; // Next descriptor to check for interrupt
int txsize, rxsize; // Length of individual buffers
unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM];
};
 
// CPM_CPCR masks
#define CPCR_FLG 0x00010000
#define CPCR_FCC2_CH 0x16200000
#define CPCR_GRSTOP_TX 0x00000005
#define CPCR_INIT_TX_RX_PARAMS 0x00000000
#define CPCR_MCN_FEC 0x00000300
#define CPCR_READY_TO_RX_CMD 0 /* Ready to receive a command */
/quicc2/v2_0/src/types.h
0,0 → 1,100
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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####
/**********************************************************************
* Copyright (c) 1999 Delphi Communication Systems
* Maynard, MA. ALL RIGHTS RESERVED
***********************************************************************/
/**********************************************************************
* File:
* $RCSfile: types.h,v $
* $Revision: 1.1.1.1 $
* $Date: 2004-02-14 13:33:31 $
*
* Purpose:
* This file defines basic types used in the ITU-T G.729A Speech
* codec. These are defined here so that we may control
* how many bits of precision a type has on a particular
* platform.
*
* Operation:
* We define the following in this file:
*
* typedef ... INT16
* This type definition defines the data type used for
* variables that must hold exactly 16 bits (signed).
*
* typedef ... INT32
* This type definition defines the data type used for
* variables that must hold exactly 32 bits (signed).
*
* Notes/Issues:
* This file is correct for the following platforms (so far):
*
* GNUWIN32 compiled with GCC
*
* $Log: not supported by cvs2svn $
* Revision 1.1.1.2 2002/03/14 17:54:24 pfine
* Fixed CR/LF Problem
*
* Revision 1.1.1.1 2002/03/13 18:20:24 pfine
* DCS Ecos with Device Drivers
*
*
***********************************************************************/
#ifndef TYPES_H
#define TYPES_H
 
typedef char INT8;
typedef unsigned char UINT8;
typedef short INT16;
typedef unsigned short UINT16;
typedef long INT32;
typedef unsigned long UINT32;
 
typedef volatile char VINT8;
typedef volatile unsigned char VUINT8;
typedef volatile short VINT16;
typedef volatile unsigned short VUINT16;
typedef volatile long VINT32;
typedef volatile unsigned long VUINT32;
 
typedef char OCTET;
typedef int INT_NATIVE;
typedef unsigned int UINT_NATIVE;
 
#endif /* TYPES_H */
 
 
 
 
/quicc2/v2_0/src/if_fec.c
0,0 → 1,721
//==========================================================================
//
// dev/if_fec.c
//
// Fast ethernet device driver for PowerPC MPC8260 boards
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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): mtek
// Contributors: pfine
// Date: 2002-02-20
// Purpose:
// Description: hardware driver for MPC8260 FEC
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/devs_eth_powerpc_quicc2.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/diag.h>
 
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_cache.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/var_intr.h>
#include <cyg/hal/drv_api.h>
#include <cyg/hal/hal_if.h>
#include <cyg/hal/mpc8260.h>
 
#include <cyg/io/eth/netdev.h>
#include <cyg/io/eth/eth_drv.h>
 
#ifdef CYGPKG_NET
#include <pkgconf/net.h>
#endif
 
#include "fec.h"
#include "EnetPHY.h"
 
#define ALIGN_TO_CACHE_LINES(x) ( (long)((x) + 31) & 0xffffffe0 )
 
static unsigned char fec_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM *
(CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE + 32)];
static unsigned char fec_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM *
(CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE + 32)];
 
// Buffer descriptors are in dual ported RAM, which is marked non-cached
#define FEC_BDs_NONCACHED
static struct fec_bd *const fec_eth_rxring = (struct fec_bd *)
(QUICC2_VADS_IMM_BASE + FEC_PRAM_RxBD_Base);
static struct fec_bd *const fec_eth_txring = (struct fec_bd *)
(QUICC2_VADS_IMM_BASE + FEC_PRAM_TxBD_Base);
 
static struct fec_eth_info fec_eth0_info;
 
static unsigned short _default_enaddr[] = {0x1234, 0x5678, 0x90a1};
static unsigned char enaddr[6];
 
#ifdef CYGPKG_REDBOOT
#include <pkgconf/redboot.h>
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <redboot.h>
#include <flash_config.h>
RedBoot_config_option("Network hardware address [MAC]",
fec_esa,
ALWAYS_ENABLED, true,
CONFIG_ESA, 0
);
RedBoot_config_option("Attempt to find 100 Mbps Ethernet",
fec_100,
ALWAYS_ENABLED, true,
CONFIG_BOOL, 0
);
#endif
#endif
 
#define os_printf diag_printf
 
// CONFIG_ESA and CONFIG_BOOL are defined in redboot/include/flash_config.h
#ifndef CONFIG_ESA
#define CONFIG_ESA 6 // ethernet address length ...
#endif
 
#ifndef CONFIG_BOOL
#define CONFIG_BOOL 1
#endif
 
ETH_DRV_SC(fec_eth0_sc,
&fec_eth0_info, // Driver specific data
"eth0", // Name for this interface
fec_eth_start,
fec_eth_stop,
fec_eth_control,
fec_eth_can_send,
fec_eth_send,
fec_eth_recv,
fec_eth_deliver,
fec_eth_int,
fec_eth_int_vector);
 
NETDEVTAB_ENTRY(fec_netdev,
"fec_eth",
fec_eth_init,
&fec_eth0_sc);
 
#ifdef CYGPKG_NET
static cyg_interrupt fec_eth_interrupt;
static cyg_handle_t fec_eth_interrupt_handle;
#endif
static void fec_eth_int(struct eth_drv_sc *data);
 
#define FEC_ETH_INT CYGNUM_HAL_INTERRUPT_FCC2
 
// This ISR is called when the ethernet interrupt occurs
#ifdef CYGPKG_NET
static int
fec_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
{
cyg_drv_interrupt_mask(FEC_ETH_INT);
return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
}
#endif
 
// Deliver function (ex-DSR) handles the ethernet [logical] processing
static void
fec_eth_deliver(struct eth_drv_sc * sc)
{
fec_eth_int(sc);
#ifdef CYGPKG_NET
// Clearing the event register acknowledges FCC2 interrupt ...
// cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
cyg_drv_interrupt_unmask(FEC_ETH_INT);
#endif
 
}
 
 
// Initialize the interface - performed at system startup
// This function must set up the interface, including arranging to
// handle interrupts, etc, so that it may be "started" cheaply later.
static bool
fec_eth_init(struct cyg_netdevtab_entry *tab)
{
struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
 
volatile t_PQ2IMM *IMM = (volatile t_PQ2IMM *) QUICC2_VADS_IMM_BASE;
volatile t_Fcc_Pram *fcc = (volatile t_Fcc_Pram *) (QUICC2_VADS_IMM_BASE + FEC_PRAM_OFFSET);
volatile t_EnetFcc_Pram *E_fcc = &(fcc->SpecificProtocol.e);
#ifdef CYGPKG_HAL_POWERPC_VADS
volatile t_BCSR *CSR = (t_BCSR *) 0x04500000;
#endif
 
int cache_state;
int i;
bool esa_ok;
bool fec_100;
unsigned char *c_ptr;
UINT16 link_speed;
 
// Ensure consistent state between cache and what the FEC sees
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_DISABLE();
HAL_DCACHE_INVALIDATE_ALL();
}
 
// Link the memory to the driver control memory
qi->fcc_reg = & (IMM->fcc_regs[FCC2]);
 
// just in case : disable Transmit and Receive
qi->fcc_reg->fcc_gfmr &= ~(FEC_GFMR_EN_Rx | FEC_GFMR_EN_Tx);
// Via BCSR, (re)start LXT970
#ifdef CYGPKG_HAL_POWERPC_VADS
EnableResetPHY(CSR);
#endif
 
// Try to read the ethernet address of the transciever ...
#ifdef CYGPKG_REDBOOT
esa_ok = flash_get_config("fec_100", &fec_100, CONFIG_BOOL);
#else
esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
"fec_100", &fec_100, CONFIG_BOOL);
#endif
link_speed = NOTLINKED;
if(esa_ok && fec_100){
// Via MII Management pins, tell LXT970 to initialize
os_printf("Attempting to acquire 100 Mbps half_duplex link ...");
InitEthernetPHY((VUINT32 *) &(IMM->io_regs[PORT_C].pdir),
(VUINT32 *) &(IMM->io_regs[PORT_C].pdat),
HUNDRED_HD);
 
link_speed = LinkTestPHY();
os_printf("\n");
if(link_speed == NOTLINKED){
os_printf("Failed to get 100 Mbps half_duplex link.\n");
}
}
if(link_speed == NOTLINKED){
os_printf("Attempting to acquire 10 Mbps half_duplex link ...");
InitEthernetPHY((VUINT32 *) &(IMM->io_regs[PORT_C].pdir),
(VUINT32 *) &(IMM->io_regs[PORT_C].pdat),
TEN_HD);
link_speed = LinkTestPHY();
os_printf("\n");
if(link_speed == NOTLINKED){
link_speed = LinkTestPHY();
os_printf("Failed to get 10 Mbps half_duplex link.\n");
}
}
switch ( link_speed ) {
case HUNDRED_FD:
os_printf("100 MB full-duplex ethernet link \n");
break;
case HUNDRED_HD:
os_printf("100 MB half-duplex ethernet link \n");
break;
case TEN_FD:
os_printf("10 MB full-duplex ethernet link \n");
break;
case TEN_HD:
os_printf("10 MB half-duplex ethernet link \n");
break;
default:
os_printf("NO ethernet link \n");
}
 
// Connect PORTC pins: (C19) to clk13, (C18) to clk 14
IMM->io_regs[PORT_C].ppar |= 0x00003000;
IMM->io_regs[PORT_C].podr &= ~(0x00003000);
IMM->io_regs[PORT_C].psor &= ~(0x00003000);
IMM->io_regs[PORT_C].pdir &= ~(0x00003000);
 
// Connect clk13 to RxClk and clk14 to TxClk on FCC2
IMM->cpm_mux_cmxfcr &= 0x7f007f00; // clear fcc2 clocks
IMM->cpm_mux_cmxfcr |= 0x00250000; // set fcc2 clocks (see 15-14)
IMM->cpm_mux_cmxuar = 0x0000; // Utopia address reg, just clear
 
// Initialize parallel port registers to connect FCC2 to MII
IMM->io_regs[PORT_B].podr &= 0xffffc000; // clear bits 18-31
IMM->io_regs[PORT_B].psor &= 0xffffc000;
IMM->io_regs[PORT_B].pdir &= 0xffffc000;
 
IMM->io_regs[PORT_B].psor |= 0x00000004;
IMM->io_regs[PORT_B].pdir |= 0x000003c5;
IMM->io_regs[PORT_B].ppar |= 0x00003fff;
 
// Initialize Receive Buffer Descriptors
qi->rbase = fec_eth_rxring;
qi->rxbd = fec_eth_rxring;
qi->rnext = fec_eth_rxring;
c_ptr = fec_eth_rxbufs;
 
for(i=0; i<CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM; i++) {
fec_eth_rxring[i].ctrl = (FEC_BD_Rx_Empty | FEC_BD_Rx_Int);
fec_eth_rxring[i].length = 0; // reset
c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr);
fec_eth_rxring[i].buffer = (volatile unsigned char *)c_ptr;
c_ptr += CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE;
}
fec_eth_rxring[CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM-1].ctrl |= FEC_BD_Rx_Wrap;
 
// Initialize Transmit Buffer Descriptors
qi->tbase = fec_eth_txring;
qi->txbd = fec_eth_txring;
qi->tnext = fec_eth_txring;
c_ptr = fec_eth_txbufs;
 
for(i=0; i<CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM; i++) {
fec_eth_txring[i].ctrl = (FEC_BD_Tx_Pad | FEC_BD_Tx_Int);
fec_eth_txring[i].length = 0; // reset : Write before send
c_ptr = (unsigned char *) ALIGN_TO_CACHE_LINES(c_ptr);
fec_eth_txring[i].buffer = (volatile unsigned char *)c_ptr;
c_ptr += CYGNUM_DEVS_ETH_POWERPC_QUICC2_BUFSIZE;
}
 
fec_eth_txring[CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM-1].ctrl |= FEC_BD_Tx_Wrap;
// Common FCC Parameter RAM initialization
fcc->riptr = FEC_PRAM_RIPTR; // in dual port RAM (see 28-11)
fcc->tiptr = FEC_PRAM_TIPTR; // in dual port RAM (see 28-11)
fcc->mrblr = FEC_PRAM_MRBLR; // ?? FROM 8101 code ...
fcc->rstate &= FEC_FCR_INIT;
fcc->rstate |= FEC_FCR_MOT_BO;
fcc->rbase = (long) fec_eth_rxring;
fcc->tstate &= FEC_FCR_INIT;
fcc->tstate |= FEC_FCR_MOT_BO;
fcc->tbase = (long) fec_eth_txring;
 
// Ethernet Specific FCC Parameter RAM Initialization
E_fcc->c_mask = FEC_PRAM_C_MASK; // (see 30-9)
E_fcc->c_pres = FEC_PRAM_C_PRES;
E_fcc->crcec = 0;
E_fcc->alec = 0;
E_fcc->disfc = 0;
E_fcc->ret_lim = FEC_PRAM_RETLIM;
E_fcc->p_per = FEC_PRAM_PER_LO;
E_fcc->gaddr_h = 0;
E_fcc->gaddr_l = 0;
E_fcc->tfcstat = 0;
E_fcc->mflr = FEC_MAX_FLR;
 
// Try to read the ethernet address of the transciever ...
#ifdef CYGPKG_REDBOOT
esa_ok = flash_get_config("fec_esa", enaddr, CONFIG_ESA);
#else
esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
"fec_esa", enaddr, CONFIG_ESA);
#endif
if (!esa_ok) {
// If can't use the default ...
os_printf("FEC_ETH - Warning! ESA unknown\n");
memcpy(enaddr, _default_enaddr, sizeof(enaddr));
}
 
E_fcc->paddr1_h = ((short)enaddr[5] << 8) | enaddr[4]; // enaddr[2];
E_fcc->paddr1_m = ((short)enaddr[3] << 8) | enaddr[2]; // enaddr[1];
E_fcc->paddr1_l = ((short)enaddr[1] << 8) | enaddr[0]; // enaddr[0];
 
E_fcc->iaddr_h = 0;
E_fcc->iaddr_l = 0;
E_fcc->minflr = FEC_MIN_FLR;
E_fcc->taddr_h = 0;
E_fcc->taddr_m = 0;
E_fcc->taddr_l = 0;
E_fcc->pad_ptr = FEC_PRAM_TIPTR; // No special padding char ...
E_fcc->cf_type = 0;
E_fcc->maxd1 = FEC_PRAM_MAXD;
E_fcc->maxd2 = FEC_PRAM_MAXD;
 
// FCC register initialization
IMM->fcc_regs[FCC2].fcc_gfmr = FEC_GFMR_INIT;
IMM->fcc_regs[FCC2].fcc_psmr = FEC_PSMR_INIT;
IMM->fcc_regs[FCC2].fcc_dsr = FEC_DSR_INIT;
 
#ifdef CYGPKG_NET
// clear the events of FCC2
IMM->fcc_regs[FCC2].fcc_fcce = 0xFFFF0000;
IMM->fcc_regs[FCC2].fcc_fccm = FEC_EV_TXE | FEC_EV_TXB | FEC_EV_RXF;
 
// Set up to handle interrupts
cyg_drv_interrupt_create(FEC_ETH_INT,
0, // Highest //CYGARC_SIU_PRIORITY_HIGH,
(cyg_addrword_t)sc, // Data passed to ISR
(cyg_ISR_t *)fec_eth_isr,
(cyg_DSR_t *)eth_drv_dsr,
&fec_eth_interrupt_handle,
&fec_eth_interrupt);
cyg_drv_interrupt_attach(fec_eth_interrupt_handle);
cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
cyg_drv_interrupt_unmask(FEC_ETH_INT);
#else
 
// Mask the interrupts
IMM->fcc_regs[FCC2].fcc_fccm = 0;
#endif
 
// Issue Init RX & TX Parameters Command for FCC2
while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD);
IMM->cpm_cpcr = CPCR_INIT_TX_RX_PARAMS |
CPCR_FCC2_CH |
CPCR_MCN_FEC |
CPCR_FLG; /* ISSUE COMMAND */
while ((IMM->cpm_cpcr & CPCR_FLG) != CPCR_READY_TO_RX_CMD);
 
if (cache_state)
HAL_DCACHE_ENABLE();
 
// Initialize upper level driver for ecos
(sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
 
return true;
}
//
// 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
fec_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
// Enable the device :
// Set the ENT/ENR bits in the GFMR -- Enable Transmit/Receive
qi->fcc_reg->fcc_gfmr |= (FEC_GFMR_EN_Rx | FEC_GFMR_EN_Tx);
}
 
//
// This function is called to shut down the interface.
//
static void
fec_eth_stop(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
// Disable the device :
// Clear the ENT/ENR bits in the GFMR -- Disable Transmit/Receive
qi->fcc_reg->fcc_gfmr &= ~(FEC_GFMR_EN_Rx | FEC_GFMR_EN_Tx);
}
 
 
//
// This function is called for low level "control" operations
//
static int
fec_eth_control(struct eth_drv_sc *sc, unsigned long key,
void *data, int length)
{
switch (key) {
case ETH_DRV_SET_MAC_ADDRESS:
return 0;
break;
default:
return 1;
break;
}
}
 
 
//
// This function is called to see if another packet can be sent.
// It should return the number of packets which can be handled.
// Zero should be returned if the interface is busy and can not send any more.
//
static int
fec_eth_can_send(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile struct fec_bd *txbd = qi->txbd;
int cache_state;
 
HAL_DCACHE_IS_ENABLED(cache_state);
#ifndef FEC_BDs_NONCACHED
if (cache_state) {
HAL_DCACHE_INVALIDATE(fec_eth_txring,
8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
}
#endif
 
return ((txbd->ctrl & FEC_BD_Tx_Ready) == 0);
}
 
//
// This routine is called to send data to the hardware.
static void
fec_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
int total_len, unsigned long key)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
struct fec_bd *txbd, *txfirst;
volatile char *bp;
int i, txindex, cache_state;
 
HAL_DCACHE_IS_ENABLED(cache_state);
#ifndef FEC_BDs_NONCACHED
if (cache_state) {
HAL_DCACHE_INVALIDATE(fec_eth_txring,
8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
}
#endif
// Find a free buffer
txbd = txfirst = qi->txbd;
while (txbd->ctrl & FEC_BD_Tx_Ready) {
// This buffer is busy, move to next one
if (txbd->ctrl & FEC_BD_Tx_Wrap) {
txbd = qi->tbase;
} else {
txbd++;
}
if (txbd == txfirst) {
#ifdef CYGPKG_NET
panic ("No free xmit buffers");
#else
os_printf("FEC Ethernet: No free xmit buffers\n");
#endif
}
}
 
// Remember the next buffer to try
if (txbd->ctrl & FEC_BD_Tx_Wrap) {
qi->txbd = qi->tbase;
} else {
qi->txbd = txbd+1;
}
 
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
qi->txkey[txindex] = key;
 
// Set up buffer
txbd->length = total_len;
bp = txbd->buffer;
for (i = 0; i < sg_len; i++) {
memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
bp += sg_list[i].len;
}
 
// Make sure no stale data buffer ...
if (cache_state) {
HAL_DCACHE_FLUSH(txbd->buffer, txbd->length);
}
// Send it on it's way
txbd->ctrl |= FEC_BD_Tx_Ready | FEC_BD_Tx_Last | FEC_BD_Tx_TC;
#ifndef FEC_BDs_NONCACHED
if (cache_state) {
HAL_DCACHE_FLUSH(fec_eth_txring,
8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
}
#endif
 
}
 
//
// This function is called when a packet has been received. It's 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
// 'fec_eth_recv' will be called to actually fetch it from the hardware.
//
static void
fec_eth_RxEvent(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
struct fec_bd *rxbd;
int cache_state;
 
HAL_DCACHE_IS_ENABLED(cache_state);
#ifndef FEC_BDs_NONCACHED
if (cache_state) {
HAL_DCACHE_INVALIDATE(fec_eth_rxring,
8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM);
}
#endif
 
rxbd = qi->rnext;
while ((rxbd->ctrl & FEC_BD_Rx_Empty) == 0) {
qi->rxbd = rxbd; // Save for callback
 
// This is the right way of doing it, but dcbi has a bug ...
// if (cache_state) {
// HAL_DCACHE_INVALIDATE(rxbd->buffer, rxbd->length);
// }
(sc->funs->eth_drv->recv)(sc, rxbd->length);
if (cache_state) {
HAL_DCACHE_FLUSH(rxbd->buffer, rxbd->length);
}
 
rxbd->ctrl |= FEC_BD_Rx_Empty;
if (rxbd->ctrl & FEC_BD_Rx_Wrap) {
rxbd = qi->rbase;
} else {
rxbd++;
}
}
// Remember where we left off
qi->rnext = (struct fec_bd *)rxbd;
 
// Make sure no stale data
#ifndef FEC_BDs_NONCACHED
if (cache_state) {
HAL_DCACHE_FLUSH(fec_eth_rxring,
8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_RxNUM);
}
#endif
 
}
 
//
// This function is called as a result of the "eth_drv_recv()" call above.
// It's 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
fec_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
unsigned char *bp;
int i;
bp = (unsigned char *)qi->rxbd->buffer;
 
for (i = 0; i < sg_len; i++) {
if (sg_list[i].buf != 0) {
memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
bp += sg_list[i].len;
}
}
 
}
 
static void
fec_eth_TxEvent(struct eth_drv_sc *sc, int stat)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
struct fec_bd *txbd;
int txindex, cache_state;
 
// Make sure no stale data
HAL_DCACHE_IS_ENABLED(cache_state);
#ifndef FEC_BDs_NONCACHED
if (cache_state) {
HAL_DCACHE_INVALIDATE(fec_eth_txring,
8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
}
#endif
 
txbd = qi->tnext;
// Note: TC field is used to indicate the buffer has/had data in it
while ( (txbd->ctrl & (FEC_BD_Tx_TC | FEC_BD_Tx_Ready)) == FEC_BD_Tx_TC ) {
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
(sc->funs->eth_drv->tx_done)(sc, qi->txkey[txindex], 0);
txbd->ctrl &= ~FEC_BD_Tx_TC;
if (txbd->ctrl & FEC_BD_Tx_Wrap) {
txbd = qi->tbase;
} else {
txbd++;
}
}
// Remember where we left off
qi->tnext = (struct fec_bd *)txbd;
 
// Make sure no stale data
#ifndef FEC_BDs_NONCACHED
if (cache_state) {
HAL_DCACHE_FLUSH(fec_eth_txring,
8*CYGNUM_DEVS_ETH_POWERPC_QUICC2_TxNUM);
}
#endif
 
}
 
//
// Interrupt processing
//
static void
fec_eth_int(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
unsigned long iEvent;
 
while ((iEvent = qi->fcc_reg->fcc_fcce) != 0){
 
// Writing 1's clear fcce, Writing 0's have no effect
qi->fcc_reg->fcc_fcce = iEvent;
 
// Tx Done or Tx Error
if ( iEvent & (FEC_EV_TXB | FEC_EV_TXE) ) {
fec_eth_TxEvent(sc, iEvent);
}
// Complete or non-complete frame receive
if (iEvent & (FEC_EV_RXF | FEC_EV_RXB) ) {
fec_eth_RxEvent(sc);
}
 
}
 
}
 
//
// Interrupt vector
//
static int
fec_eth_int_vector(struct eth_drv_sc *sc)
{
return (FEC_ETH_INT);
}
 
/quicc2/v2_0/src/EnetPHY.c
0,0 → 1,362
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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####
/*-------------------------------------------------------------------
*
* FILE: enetPHY.c
*
* DESCRIPTION: GPIO Management Pins driver for the LXT970a
*
*
* Modified for the mpc8260 VADS board
*--------------------------------------------------------------------*/
#include "types.h"
#include "EnetPHY.h"
 
/* Internal functions */
void MdioSend(UINT32, UINT16);
UINT16 MdioReceive(UINT16);
UINT16 MdioFrame(MDIORW, UINT16, UINT16, UINT32);
 
VUINT32 * pPortDir;
VUINT32 * pPortData;
 
/*-------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION:
*
* EXTERNAL EFFECT: Turns on the LXT970 transciever
*
* PARAMETERS:
*
* RETURNS: None
*
* ASSUMPTIONS:
*
*-------------------------------------------------------------------*/
void
EnableResetPHY(volatile t_BCSR *pBCSR)
{
// active low FETHIEN on BSCR1, assert reset low
pBCSR->bcsr1 &= ~(FETHIEN_ | FETHRST_);
// de-assert reset
pBCSR->bcsr1 |= FETHRST_;
}
 
 
/*-------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION: Writes parameters to the control registers of LXT970
*
* EXTERNAL EFFECT:
*
* PARAMETERS:
*
* RETURNS: None
*
* ASSUMPTIONS:
*
*-------------------------------------------------------------------*/
UINT16
InitEthernetPHY(VUINT32* pdir, VUINT32* pdat, UINT16 link)
{
 
VUINT16 FrameValue;
/* 8101 Ethernet Management Pin Assignments */
pPortDir = pdir;
pPortData = pdat;
(*pPortDir) |= MDC_PIN_MASK; /* MD_Clock will always be output only */
/* Test MDC & MDIO Pin Connection to PHY */
MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame
MdioFrame(WRITE, 0, MIRROR_REG, MD_TEST_FRAME); //send test frame
FrameValue = MdioFrame(READ, 0, MIRROR_REG, 0); //read test frame
 
if (FrameValue != MD_TEST_FRAME)
return LINKERROR; //test data integrity
/* General Configuration */
MdioFrame(WRITE, 0, CONFIG_REG, 0x0000);
 
if(link == HUNDRED_HD)
MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0081); //100 Mbps Half, 802.3
else
MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0021); //10 Mbps Half, 802.3
 
// 100 Mbps full duplex not supported
// MdioFrame(WRITE, 0, AUTONEG_AD_REG, 0x0101); //100 Mbps Full, 802.3
 
MdioFrame(WRITE, 0, CONTROL_REG, 0x1300);
 
return 0;
}
 
/*-------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION:
*
* EXTERNAL EFFECT:
*
* PARAMETERS:
*
* RETURNS: None
*
* ASSUMPTIONS:
*
*-------------------------------------------------------------------*/
UINT16
EthernetPHYInterruptHandler()
{
// Reading registers 1 and 18 in sequence
// clears the transceiver interrupt
 
MdioFrame(READ, 0, STATUS_REG, 0);
MdioFrame(READ, 0, INT_STAT_REG, 0);
return LinkTestPHY();
} /* end EthernetPHYInterruptHandler */
 
/*-------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION:
*
* EXTERNAL EFFECT:
*
* PARAMETERS:
*
* RETURNS: None
*
* ASSUMPTIONS:
*
*-------------------------------------------------------------------*/
UINT16
LinkTestPHY()
{
UINT32 j, cnt;
UINT16 FrameValue;
 
//for (j = 0; j < 10; j++) {
for (j = 0; j < 5; j++) {
 
for (cnt = 0; cnt < 1000000; cnt ++) {
asm("nop");
asm("nop");
asm("nop");
}
FrameValue = MdioFrame(READ,0,CHIP_STAT_REG,0);
if ( (FrameValue & 0x0200) != 0 )
break;
}
 
FrameValue &= 0x3800;
 
switch (FrameValue) {
case 0x3800: return HUNDRED_FD;
case 0x2800: return HUNDRED_HD;
case 0x3000: return TEN_FD;
case 0x2000: return TEN_HD;
default: return NOTLINKED;
}
 
}
 
/*-------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION:
*
* EXTERNAL EFFECT:
*
* PARAMETERS:
*
* RETURNS: None
*
* ASSUMPTIONS:
*
*-------------------------------------------------------------------*/
void EnablePHYinterrupt(UINT8 enable)
{
MdioFrame(WRITE, 0, INT_EN_REG, enable?0x2:0x0);
}
 
/*----------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION: generic READ/WRITE function of LXT970
* through the MDC/MDIO interface.
*
* EXTERNAL EFFECT:
*
* PARAMETERS:
*
* RETURNS: None
*
* ASSUMPTIONS:
*
*---------------------------------------------------------------------*/
UINT16
MdioFrame(MDIORW R_W, UINT16 PhyAddr, UINT16 RegAddr, UINT32 PutData) {
 
UINT16 GetData;
 
*pPortDir |= MDIO_PIN_MASK; //set to output mode
MdioSend(0xFFFFFFFF,32); //PreAmble
MdioSend(0x1,2); //Start Frame Delimiter
if (R_W==READ)
MdioSend(0x2,2); //Read OpCode
else
MdioSend(0x1,2); //Write OpCode
MdioSend(PhyAddr,5); //Send PHY transciever Address
MdioSend(RegAddr,5); //Send Register Address
 
if (R_W==READ) {
*pPortDir &= ~MDIO_PIN_MASK; //set to input mode
GetData = MdioReceive(17); //Drive TurnAround and Data
MdioReceive(2);
}
else {
MdioSend(0x2,2); //Drive TurnAround
MdioSend(PutData, 16); //Send Data
GetData = 0;
*pPortDir &= ~MDIO_PIN_MASK; //set to input mode
}
 
return GetData;
 
}
/*----------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION: Shift out bits of data
*
* EXTERNAL EFFECT:
*
* PARAMETERS:
*
* RETURNS: None
*
* ASSUMPTIONS:
*
*----------------------------------------------------------------------*/
void
MdioSend(UINT32 txF, UINT16 size) {
 
UINT32 dmask;
INT_NATIVE i, j;
 
dmask = 1 << (size-1); // msbit out first
 
for (i = 0; i < size; i++) { // for "size" bits
if ( txF & dmask ) //output data bit high
*pPortData |= MDIO_PIN_MASK;
else //output data bit low > 400ns
*pPortData &= ~MDIO_PIN_MASK;
// >10ns
*pPortData |= MDC_PIN_MASK; // clock rise
txF = (UINT32)(txF << 1); // >160ns
for (j=0; j<MDC_HOLD_TIME; j++);
 
*pPortData &= ~MDC_PIN_MASK; // clock fall
 
for (j=0; j<MDC_HOLD_TIME; j++);
 
}
return;
}
 
/*---------------------------------------------------------------------
*
* FUNCTION NAME:
*
* DESCRIPTION: Shifts in bits of data
*
* EXTERNAL EFFECT:
*
* PARAMETERS:
*
* RETURNS:
*
* ASSUMPTIONS:
*
*---------------------------------------------------------------------*/
UINT16
MdioReceive(UINT16 size) {
 
UINT16 i,j, rxF = 0;
 
for (i = 0; i < size; i++) { // 16 bits
*pPortData |= MDC_PIN_MASK; // clock rise
 
if ( *pPortData & MDIO_PIN_MASK ) // if read in a high bit
rxF = ( (UINT16)(rxF << 1) | 1 ); // shift in a one
else // if read in a low bit
rxF = ( (UINT16)(rxF << 1) & ~(UINT16)1 ); // shift in a zero
 
for (j=0; j<MDC_HOLD_TIME; j++);
 
*pPortData &= ~MDC_PIN_MASK; // clock fall
 
for (j=0; j<MDC_HOLD_TIME; j++);
 
}
return rxF;
}
 
/ts1000/v2_0/cdl/ts1000_eth_drivers.cdl
0,0 → 1,67
#====================================================================
#
# ts1000_eth_drivers.cdl
#
# Hardware specifics for Allied Telesyn Ts1000 ethernet
#
#====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002 Gary Thomas
##
## 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): gthomas
# Original data: gthomas
# Contributors: gthomas
# Date: 2002-09-03
#
#####DESCRIPTIONEND####
#
#====================================================================
 
cdl_package CYGPKG_DEVS_ETH_POWERPC_TS1000 {
display "Allied Telesyn TS1000 (MPC855T) ethernet support"
description "Hardware specifics for Allied Telesyn TS1000 ethernet"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC
active_if CYGPKG_HAL_POWERPC_MPC8xx
 
include_dir cyg/io
 
define_proc {
puts $::cdl_system_header "#define CYGDAT_DEVS_FEC_ETH_INL <cyg/io/ts1000_eth.inl>"
}
}
/ts1000/v2_0/include/ts1000_eth.inl
0,0 → 1,79
#ifndef CYGONCE_DEVS_TS1000_ETH_INL
#define CYGONCE_DEVS_TS1000_ETH_INL
//==========================================================================
//
// ts1000_eth.inl
//
// Hardware specifics for Allied Telesyn TS1000 ethernet support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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): gthomas
// Contributors: gthomas
// Date: 2002-09-03
// Purpose:
// Description:
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
 
extern int hal_ts1000_get_led(void);
extern void hal_ts1000_set_led(int);
 
#define _get_led()
#define _set_led(v)
 
#define LED_TxACTIVE 2
#define LED_RxACTIVE 1
#define LED_IntACTIVE 0
 
// Interrupt generated by device
#define FEC_ETH_INT CYGNUM_HAL_INTERRUPT_SIU_LVL1
// Address of PHY (transceiver) device
#define FEC_ETH_PHY 1
 
// Reset the PHY - analagous to hardware reset
#define FEC_ETH_RESET_PHY() \
eppc->pio_padat |= 0x00008000; /* Reset PHY chip */ \
CYGACC_CALL_IF_DELAY_US(10000); /* 10ms */ \
eppc->pio_padat &= ~0x00008000; /* Enable PHY chip */
 
#endif // CYGONCE_DEVS_TS1000_ETH_INL
// ------------------------------------------------------------------------
/ts1000/v2_0/ChangeLog
0,0 → 1,42
2002-09-03 Gary Thomas <gary@mlbassoc.com>
 
* include/ts1000_eth.inl:
* cdl/ts1000_eth_drivers.cdl: New package - platform ethernet specifics.
 
//===========================================================================
//####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####
//===========================================================================
 
/fec/v2_0/cdl/fec_eth_drivers.cdl
0,0 → 1,142
# ====================================================================
#
# fec_eth_drivers.cdl
#
# Ethernet drivers - platform dependent support for PowerPC MPC8xx
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
## Copyright (C) 2002, 2003 Gary Thomas
##
## 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): gthomas
# Original data: gthomas
# Contributors:
# Date: 2001-01-21
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_DEVS_ETH_POWERPC_FEC {
display "MPC8xx FEC ethernet driver"
 
parent CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_IO_ETH_DRIVERS
active_if CYGPKG_HAL_POWERPC
active_if CYGPKG_HAL_POWERPC_MPC8xx
 
implements CYGHWR_NET_DRIVERS
implements CYGHWR_NET_DRIVER_ETH0
implements CYGINT_IO_ETH_MULTICAST
include_dir .
include_files ; # none _exported_ whatsoever
 
description "Fast ethernet driver for PowerPC MPC8xxT boards."
compile -library=libextras.a if_fec.c
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_BD_OFFSET {
display "Buffer descriptors offset in PRAM"
flavor data
default_value 0x2C00
description "
This option specifies the address of the buffer descriptors
used by the PowerPC FEC/ethernet device."
}
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE {
display "Buffer size"
flavor data
default_value 1520
description "
This option specifies the size of the internal buffers used
for the PowerPC FEC/ethernet device."
}
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM {
display "Number of output buffers"
flavor data
legal_values 2 to 64
default_value 16
description "
This option specifies the number of output buffer packets
to be used for the PowerPC FEC/ethernet device."
}
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM {
display "Number of input buffers"
flavor data
legal_values 2 to 64
default_value 16
description "
This option specifies the number of input buffer packets
to be used for the PowerPC FEC/ethernet device."
}
 
cdl_component CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY {
display "Reset and reconfigure PHY"
flavor bool
default_value { CYG_HAL_STARTUP != "RAM" }
description "
This option allows control over the physical transceiver"
 
cdl_option CYGNUM_DEVS_ETH_POWERPC_FEC_LINK_MODE {
display "Initial link mode"
flavor data
legal_values { "10Mb" "100Mb" "Auto" }
default_value { "Auto" }
description "
This option specifies initial mode for the physical
link. The PHY will be reset and then set to this mode."
}
}
 
cdl_component CYGPKG_DEVS_ETH_POWERPC_FEC_OPTIONS {
display "MPC8xx FEC ethernet driver build options"
flavor none
no_define
 
cdl_option CYGPKG_DEVS_ETH_POWERPC_FEC_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 MPC8xx FEC ethernet driver package. These flags are used in addition
to the set of global flags."
}
}
}
/fec/v2_0/ChangeLog
0,0 → 1,188
2003-01-20 Gary Thomas <gary@mlbassoc.com>
 
* cdl/fec_eth_drivers.cdl: Increase number of allowed buffers.
 
2002-11-14 Gary Thomas <gthomas@ecoscentric.com>
 
* cdl/fec_eth_drivers.cdl: Increase default number of buffers (to a
more reasonable amount).
 
2002-10-18 Gary Thomas <gthomas@ecoscentric.com>
 
* src/if_fec.c: Reduce warnings when PHY code is not used.
 
2002-10-11 Gary Thomas <gthomas@ecoscentric.com> [inspired by]
2002-10-11 Wolfgang Heppner <hep@iis.fhg.de>
 
* src/if_fec.c:
* cdl/fec_eth_drivers.cdl: Make buffer descriptor use configurable.
Also, fix some issues where cache state wasn't being honored.
 
2002-10-11 Gary Thomas <gary@mlbassoc.com>
 
* src/if_fec.c:
* cdl/fec_eth_drivers.cdl: Add control over PHY - when to reset
and how to configure the link.
 
2002-09-19 Gary Thomas <gary@mlbassoc.com>
 
* src/if_fec.c (fec_eth_init): Check for availability of RedBoot
FLASH support.
 
2002-09-03 Gary Thomas <gary@mlbassoc.com>
 
* src/if_fec.c: Make driver more generic - platform specifics are
now contained in an include file CYGDAT_DEVS_FEC_ETH_INL.
 
2002-08-15 Gary Thomas <gthomas@ecoscentric.com>
 
* src/if_fec.c (fec_eth_send):
Clean up: remove unused variable _fec_eth_tx_count.
 
2002-08-08 Gary Thomas <gthomas@ecoscentric.com>
 
* src/if_fec.c (fec_eth_RxEvent): Cache needs to be invalidated
to avoid any possible corruption.
 
2002-06-14 Gary Thomas <gary@chez-thomas.org>
 
* src/if_fec.c:
Need to include <pkgconf/io_eth_drivers.h> for proper configuration
of stand-alone (polled) vs. system (interrupt driven) mode.
 
2002-05-30 Jonathan Larmour <jlarmour@redhat.com>
 
* src/if_fec.c: Use CYGINT_IO_ETH_INT_SUPPORT_REQUIRED where
appropriate.
 
2002-05-30 Jesper Skov <jskov@redhat.com>
 
* src/if_fec.c: Initialized a variable and removed an unused
variable. Also made one volatile. All to remove warnings.
* src/fec.h: Made more pointers volatile to avoid compiler
warnings.
 
2002-04-30 Nick Garnett <nickg@redhat.com>
 
* src/if_fec.c: Changed order of initialization and made code more
robust against hangups. Changed initialization of ESA from memcpy
to 32 bit assignments, since 855 seems fussy about this where 860
is not.
 
2002-04-22 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c (fec_eth_control): Fix compile error (multicast).
 
2002-04-19 Gary Thomas <gthomas@redhat.com>
 
* cdl/fec_eth_drivers.cdl: Add [minimal] multicast support.
 
* src/if_fec.c: Cleaned out debug code.
 
2002-04-18 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c: Finally working! Problem was that resetting the
interface is much more involved than simply set/reset the "enable".
 
2002-04-17 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c:
* src/fec.h: Add code to poll PHY for link status on startup.
Still trying to get reliable results in general operation.
 
2002-04-12 Gary Thomas <gthomas@redhat.com>
 
* src/fec.h:
* src/if_fec.c: Lots of tinkering since this driver is somewhat
unreliable with the generic eCos stack (the RedBoot code seems
to work oddly enough).
 
2002-02-19 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c (fec_eth_init): Args were backwards(!) getting
processor revision.
 
2001-08-22 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c:
printf() is no longer a part of RedBoot. Thus all programs
must use diag_printf() and related functions instead.
 
2001-06-26 Jonathan Larmour <jlarmour@redhat.com>
 
* src/if_fec.c (fec_eth_init): Use correct version register.
 
2001-05-07 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c (fec_eth_init): Use RedBoot/fconfig data for ethernet
station address (ESA).
 
2001-05-04 Gary Thomas <gthomas@redhat.com>
 
* src/fec.h (iEvent_all):
* src/if_fec.c (fec_eth_init): Enable interrupts.
 
2001-05-01 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c (fec_eth_init): Force buffers to 32 byte boundary.
 
2001-02-21 Gary Thomas <gthomas@redhat.com>
 
* src/if_fec.c: Finally working! Lots of little changes
to get the setup just right.
(fec_eth_init): Need to set Tx high water mark high for proper
operation when code is run from FLASH. Also misc cleanups, removing
old debug code, etc.
(fec_eth_recv):
(fec_eth_TxEvent):
(fec_eth_RxEvent):
(fec_eth_send): Need to flush data cache - not snooped?
 
* src/fec.h: Add new defines for rev D of chip.
 
* cdl/fec_eth_drivers.cdl: Remove CDL for chip revision,
now handled automatically by driver.
 
2001-01-22 Gary Thomas <gthomas@redhat.com>
 
* src/fec.h:
* src/if_fec.c:
* cdl/fec_eth_drivers.cdl: New package/file(s).
 
//===========================================================================
//####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####
//===========================================================================
 
/fec/v2_0/src/fec.h
0,0 → 1,189
//==========================================================================
//
// fec.h
//
// PowerPC MPC8xxT fast ethernet (FEC)
//
//==========================================================================
//####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): gthomas
// Contributors: gthomas
// Date: 2001-01-21
// Purpose:
// Description:
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
// PowerPC FEC (MPC8xxT) Fast Ethernet
 
// Buffer descriptor
struct fec_bd {
unsigned short ctrl;
unsigned short length;
unsigned char *buffer;
};
 
// control flags differ for Rx and Tx buffers
#define FEC_BD_Rx_Empty 0x8000 // Buffer is empty [FEC can fill it]
#define FEC_BD_Rx_Wrap 0x2000 // Last buffer in ring [wrap]
#define FEC_BD_Rx_Last 0x0800 // Last buffer in frame
#define FEC_BD_Rx_Miss 0x0100 //
#define FEC_BD_Rx_BC 0x0080
#define FEC_BD_Rx_MC 0x0040
#define FEC_BD_Rx_LG 0x0020
#define FEC_BD_Rx_NO 0x0010
#define FEC_BD_Rx_SH 0x0008 // Short frame
#define FEC_BD_Rx_CR 0x0004 // CRC error
#define FEC_BD_Rx_OV 0x0002 // Overrun
#define FEC_BD_Rx_TR 0x0001 // Frame truncated
 
#define FEC_BD_Tx_Ready 0x8000 // Frame ready
#define FEC_BD_Tx_Wrap 0x2000 // Last buffer in ring
#define FEC_BD_Tx_Intr 0x1000 // Generate interrupt
#define FEC_BD_Tx_Last 0x0800 // Last buffer in frame
#define FEC_BD_Tx_TC 0x0400 // Send CRC after data
#define FEC_BD_Tx_DEF 0x0200
#define FEC_BD_Tx_HB 0x0100
#define FEC_BD_Tx_LC 0x0080
#define FEC_BD_Tx_RL 0x0040
#define FEC_BD_Tx_RC 0x003C
#define FEC_BD_Tx_UN 0x0002 // Underrun
#define FEC_BD_Tx_CSL 0x0001 // Carrier sense lost
 
#define FEC_BD_Tx_STATS 0x03FF // Status mask
 
struct fec_eth_info {
volatile struct fec *fec;
volatile struct fec_bd *txbd, *rxbd; // Next Tx,Rx descriptor to use
volatile struct fec_bd *tbase, *rbase; // First Tx,Rx descriptor
volatile struct fec_bd *tnext, *rnext; // Next descriptor to check for interrupt
int txsize, rxsize; // Length of individual buffers
int txactive; // Count of active Tx buffers
unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM];
};
 
// Fast Ethernet Controller [in PPC8xxT parameter RAM space]
 
struct fec {
unsigned long addr[2]; // ESA
unsigned long hash[2]; // Address hash mask
volatile struct fec_bd *RxRing;
volatile struct fec_bd *TxRing;
unsigned long RxBufSize;
unsigned char _fill0[0x40-0x1C];
unsigned long eControl; // Master control register
unsigned long iEvent; // Interrupt event
unsigned long iMask; // Interrupt mask
unsigned long iVector; // Interrupt vector
unsigned long RxUpdate; // RxRing updated
unsigned long TxUpdate; // TxRing updated
unsigned char _fill1[0x80-0x58];
unsigned long MiiData;
unsigned long MiiSpeed;
unsigned char _fill2[0xCC-0x88];
unsigned long RxBound; // End of FIFO RAM
unsigned long RxStart; // Start of FIFO RAM
unsigned char _fill3[0xE4-0xD4];
unsigned long TxWater; // Transmit watermark
unsigned char _fill4[0xEC-0xE8];
unsigned long TxStart; // Start of Tx FIFO
unsigned char _fill5[0x134-0xF0];
unsigned long FunCode; // DMA function codes
unsigned char _fill6[0x144-0x138];
unsigned long RxControl; // Receiver control
unsigned long RxHash; // Receive hash
unsigned char _fill7[0x184-0x14C];
unsigned long TxControl; // Transmitter control
};
 
#define FEC_OFFSET 0x0E00 // Offset in 8xx parameter RAM
 
// Master control register (eControl)
#define eControl_MUX 0x0004 // Select proper pin MUX functions
#define eControl_EN 0x0002 // Enable ethernet controller
#define eControl_RESET 0x0001 // Reset controller
 
// Receiver control register (RxControl)
#define RxControl_BC_REJ 0x0010 // Reject broadcast frames
#define RxControl_PROM 0x0008 // Promiscuous mode
#define RxControl_MII 0x0004 // MII (1) or 7 wire (0) mode
#define RxControl_DRT 0x0002 // Disable receive on transmit
#define RxControl_LOOP 0x0001 // Internal loopback
 
// Interrupt events
#define iEvent_HBERR 0x80000000 // No heartbeat error
#define iEvent_BABR 0x40000000 // Babling receiver
#define iEvent_BABT 0x20000000 // Babling transmitter
#define iEvent_GRA 0x10000000 // Graceful shutdown
#define iEvent_TFINT 0x08000000 // Transmit frame interrupt
#define iEvent_TXB 0x04000000 // Transmit buffer
#define iEvent_RFINT 0x02000000 // Receive frame
#define iEvent_RXB 0x01000000 // Receive buffer
#define iEvent_MII 0x00800000 // MII complete
#define iEvent_EBERR 0x00400000 // Ethernet BUS error
#define iEvent_all 0xFFC00000 // Any interrupt
 
// MII interface
#define MII_Start 0x40000000
#define MII_Read 0x20000000
#define MII_Write 0x10000000
#define MII_Phy(phy) (phy << 23)
#define MII_Reg(reg) (reg << 18)
#define MII_TA 0x00020000
 
// Transceiver mode
#define PHY_BMCR 0x00 // Register number
#define PHY_BMCR_RESET 0x8000
#define PHY_BMCR_LOOPBACK 0x4000
#define PHY_BMCR_100MB 0x2000
#define PHY_BMCR_AUTO_NEG 0x1000
#define PHY_BMCR_POWER_DOWN 0x0800
#define PHY_BMCR_ISOLATE 0x0400
#define PHY_BMCR_RESTART 0x0200
#define PHY_BMCR_FULL_DUPLEX 0x0100
#define PHY_BMCR_COLL_TEST 0x0080
 
#define PHY_BMSR 0x01 // Status register
#define PHY_BMSR_AUTO_NEG 0x0020
#define PHY_BMSR_LINK 0x0004
 
#define IEEE_8023_MAX_FRAME 1518 // Largest possible ethernet frame
#define IEEE_8023_MIN_FRAME 60 // Smallest possible ethernet frame
 
/fec/v2_0/src/if_fec.c
0,0 → 1,830
//==========================================================================
//
// dev/if_fec.c
//
// Fast ethernet device driver for PowerPC MPC8xxT boards
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Gary Thomas
//
// 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): gthomas
// Contributors: gthomas
// Date: 2001-01-21
// Purpose:
// Description: hardware driver for MPC8xxT FEC
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
// Ethernet device driver for MPC8xx FEC
 
#include <pkgconf/system.h>
#include <pkgconf/devs_eth_powerpc_fec.h>
#include <pkgconf/io_eth_drivers.h>
#include CYGDAT_DEVS_FEC_ETH_INL
 
#ifdef CYGPKG_NET
#include <pkgconf/net.h>
#endif
 
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/diag.h>
 
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_cache.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/drv_api.h>
#include <cyg/hal/hal_if.h>
#include <cyg/hal/ppc_regs.h>
 
#include <cyg/io/eth/netdev.h>
#include <cyg/io/eth/eth_drv.h>
 
#include "fec.h"
 
// Define this to force the buffer descriptors into the EPPC memory
#define FEC_USE_EPPC_BD
 
#ifndef FEC_USE_EPPC_BD
static struct fec_bd fec_eth_rxring[CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM];
static struct fec_bd fec_eth_txring[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM];
#endif
static unsigned char fec_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM+1]
[CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE];
static unsigned char fec_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM+1]
[CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE];
 
static struct fec_eth_info fec_eth0_info;
static unsigned char _default_enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x7A, 0xBA};
static unsigned char enaddr[6];
#ifdef CYGPKG_REDBOOT
#include <pkgconf/redboot.h>
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <redboot.h>
#include <flash_config.h>
RedBoot_config_option("Network hardware address [MAC]",
fec_esa,
ALWAYS_ENABLED, true,
CONFIG_ESA, 0
);
#endif
#endif
 
#define os_printf diag_printf
 
// For fetching the ESA from RedBoot
#include <cyg/hal/hal_if.h>
#ifndef CONFIG_ESA
#define CONFIG_ESA 6
#endif
 
ETH_DRV_SC(fec_eth0_sc,
&fec_eth0_info, // Driver specific data
"eth0", // Name for this interface
fec_eth_start,
fec_eth_stop,
fec_eth_control,
fec_eth_can_send,
fec_eth_send,
fec_eth_recv,
fec_eth_deliver,
fec_eth_int,
fec_eth_int_vector);
 
NETDEVTAB_ENTRY(fec_netdev,
"fec_eth",
fec_eth_init,
&fec_eth0_sc);
 
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
#define _FEC_USE_INTS
#ifdef _FEC_USE_INTS
static cyg_interrupt fec_eth_interrupt;
static cyg_handle_t fec_eth_interrupt_handle;
#else
#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
static char fec_fake_int_stack[STACK_SIZE];
static cyg_thread fec_fake_int_thread_data;
static cyg_handle_t fec_fake_int_thread_handle;
static void fec_fake_int(cyg_addrword_t);
#endif // _FEC_USE_INTS
#endif // CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
static void fec_eth_int(struct eth_drv_sc *data);
 
#ifndef FEC_ETH_INT
#error FEC_ETH_INT must be defined
#endif
 
#ifndef FEC_ETH_PHY
#error FEC_ETH_PHY must be defined
#endif
 
#ifndef FEC_ETH_RESET_PHY
#define FEC_ETH_RESET_PHY()
#endif
 
#ifndef FEC_EPPC_BD_OFFSET
#define FEC_EPPC_BD_OFFSET CYGNUM_DEVS_ETH_POWERPC_FEC_BD_OFFSET
#endif
 
// LED activity [exclusive of hardware bits]
#ifndef _get_led
#define _get_led()
#define _set_led(v)
#endif
#ifndef LED_TxACTIVE
#define LED_TxACTIVE 7
#define LED_RxACTIVE 6
#define LED_IntACTIVE 5
#endif
 
static void
set_led(int bit)
{
_set_led(_get_led() | (1<<bit));
}
 
static void
clear_led(int bit)
{
_set_led(_get_led() & ~(1<<bit));
}
 
#ifdef _FEC_USE_INTS
// This ISR is called when the ethernet interrupt occurs
static int
fec_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
{
cyg_drv_interrupt_mask(FEC_ETH_INT);
return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
}
#endif
 
// Deliver function (ex-DSR) handles the ethernet [logical] processing
static void
fec_eth_deliver(struct eth_drv_sc * sc)
{
fec_eth_int(sc);
#ifdef _FEC_USE_INTS
// Allow interrupts to happen again
cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
cyg_drv_interrupt_unmask(FEC_ETH_INT);
#endif
}
 
#ifdef CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
//
// PHY unit access (via MII channel)
//
static void
phy_write(int reg, int addr, unsigned short data)
{
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
int timeout = 0x100000;
 
fec->iEvent = iEvent_MII;
fec->MiiData = MII_Start | MII_Write | MII_Phy(addr) | MII_Reg(reg) | MII_TA | data;
while (!(fec->iEvent & iEvent_MII) && (--timeout > 0)) ;
}
 
static bool
phy_read(int reg, int addr, unsigned short *val)
{
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
int timeout = 0x100000;
 
fec->iEvent = iEvent_MII;
fec->MiiData = MII_Start | MII_Read | MII_Phy(addr) | MII_Reg(reg) | MII_TA;
while (!(fec->iEvent & iEvent_MII)) {
if (--timeout <= 0) {
return false;
}
}
*val = fec->MiiData & 0x0000FFFF;
return true;
}
#endif // CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
 
//
// [re]Initialize the ethernet controller
// Done separately since shutting down the device requires a
// full reconfiguration when re-enabling.
// when
static bool
fec_eth_reset(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
volatile struct fec_bd *rxbd, *txbd;
unsigned char *RxBUF, *TxBUF;
int cache_state, int_state;
int i;
 
// Ignore unless device is idle/stopped
if ((qi->fec->eControl & eControl_EN) != 0) {
return true;
}
 
// Make sure interrupts are off while we mess with the device
HAL_DISABLE_INTERRUPTS(int_state);
 
// Ensure consistent state between cache and what the FEC sees
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state)
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
 
// Shut down ethernet controller, in case it is already running
fec->eControl = eControl_RESET;
i = 0;
while ((fec->eControl & eControl_RESET) != 0) {
if (++i >= 500000) {
os_printf("FEC Ethernet does not reset\n");
if (cache_state)
HAL_DCACHE_ENABLE();
HAL_RESTORE_INTERRUPTS(int_state);
return false;
}
}
 
fec->iMask = 0x0000000; // Disables all interrupts
fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
fec->iVector = (1<<29); // Caution - must match FEC_ETH_INT above
 
#define ROUNDUP(b,s) (((unsigned long)(b) + (s-1)) & ~(s-1))
#ifdef FEC_USE_EPPC_BD
txbd = (struct fec_bd *)(FEC_EPPC_BD_OFFSET + (cyg_uint32)eppc);
rxbd = &txbd[CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM];
#else
txbd = fec_eth_txring;
rxbd = fec_eth_rxring;
#endif
qi->tbase = qi->txbd = qi->tnext = txbd;
qi->rbase = qi->rxbd = qi->rnext = rxbd;
qi->txactive = 0;
 
RxBUF = (unsigned char *)ROUNDUP(&fec_eth_rxbufs[0][0], 32);
TxBUF = (unsigned char *)ROUNDUP(&fec_eth_txbufs[0][0], 32);
 
// setup buffer descriptors
for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_FEC_RxNUM; i++) {
rxbd->length = 0;
rxbd->buffer = RxBUF;
rxbd->ctrl = FEC_BD_Rx_Empty;
RxBUF += CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE;
rxbd++;
}
rxbd--;
rxbd->ctrl |= FEC_BD_Rx_Wrap; // Last buffer
for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM; i++) {
txbd->length = 0;
txbd->buffer = TxBUF;
txbd->ctrl = 0;
TxBUF += CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE;
txbd++;
}
txbd--;
txbd->ctrl |= FEC_BD_Tx_Wrap; // Last buffer
 
// Reset interrupts
fec->iMask = 0x00000000; // No interrupts enabled
fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
 
// Initialize shared PRAM
fec->RxRing = qi->rbase;
fec->TxRing = qi->tbase;
 
// Size of receive buffers
fec->RxBufSize = CYGNUM_DEVS_ETH_POWERPC_FEC_BUFSIZE;
 
// Receiver control
fec->RxControl = RxControl_MII | RxControl_DRT;
// fec->RxControl = RxControl_MII | RxControl_LOOP | RxControl_PROM;
fec->RxHash = IEEE_8023_MAX_FRAME; // Largest possible ethernet frame
 
// Transmit control
fec->TxControl = 4+0;
 
// Use largest possible Tx FIFO
fec->TxWater = 3;
 
// DMA control
fec->FunCode = ((2<<29) | (2<<27) | (0<<24));
 
// MII speed control (50MHz)
fec->MiiSpeed = 0x14;
 
// Group address hash
fec->hash[0] = 0;
fec->hash[1] = 0;
 
// Device physical address
fec->addr[0] = *(unsigned long *)&enaddr[0];
fec->addr[1] = *(unsigned long *)&enaddr[4];
// os_printf("FEC ESA = %08x/%08x\n", fec->addr[0], fec->addr[1]);
 
// Enable device
fec->eControl = eControl_EN | eControl_MUX;
fec->RxUpdate = 0x0F0F0F0F; // Any write tells machine to look for work
 
#ifdef _FEC_USE_INTS
// Set up for interrupts
fec->iMask = iEvent_TFINT | iEvent_TXB |
iEvent_RFINT | iEvent_RXB;
fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
#endif
 
if (cache_state)
HAL_DCACHE_ENABLE();
 
// Set LED state
clear_led(LED_TxACTIVE);
clear_led(LED_RxACTIVE);
 
HAL_RESTORE_INTERRUPTS(int_state);
return true;
}
 
//
// Initialize the interface - performed at system startup
// This function must set up the interface, including arranging to
// handle interrupts, etc, so that it may be "started" cheaply later.
//
static bool
fec_eth_init(struct cyg_netdevtab_entry *tab)
{
struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile EPPC *eppc = (volatile EPPC *)eppc_base();
volatile struct fec *fec = (volatile struct fec *)((unsigned char *)eppc + FEC_OFFSET);
int cache_state;
unsigned long proc_rev;
bool esa_ok;
#ifdef CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
int phy_timeout = 5*1000; // Wait 5 seconds max for link to clear
bool phy_ok;
unsigned short phy_state = 0;
#endif
 
// Ensure consistent state between cache and what the FEC sees
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state)
HAL_DCACHE_SYNC();
HAL_DCACHE_DISABLE();
 
qi->fec = fec;
fec_eth_stop(sc); // Make sure it's not running yet
 
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
#ifdef _FEC_USE_INTS
// Set up to handle interrupts
cyg_drv_interrupt_create(FEC_ETH_INT,
CYGARC_SIU_PRIORITY_HIGH,
(cyg_addrword_t)sc, // Data item passed to interrupt handler
(cyg_ISR_t *)fec_eth_isr,
(cyg_DSR_t *)eth_drv_dsr,
&fec_eth_interrupt_handle,
&fec_eth_interrupt);
cyg_drv_interrupt_attach(fec_eth_interrupt_handle);
cyg_drv_interrupt_acknowledge(FEC_ETH_INT);
cyg_drv_interrupt_unmask(FEC_ETH_INT);
#else // _FEC_USE_INTS
// Hack - use a thread to simulate interrupts
cyg_thread_create(1, // Priority
fec_fake_int, // entry
(cyg_addrword_t)sc, // entry parameter
"CS8900 int", // Name
&fec_fake_int_stack[0], // Stack
STACK_SIZE, // Size
&fec_fake_int_thread_handle, // Handle
&fec_fake_int_thread_data // Thread data structure
);
cyg_thread_resume(fec_fake_int_thread_handle); // Start it
#endif
#endif
 
// Set up parallel port for connection to ethernet tranceiver
eppc->pio_pdpar = 0x1FFF;
CYGARC_MFSPR( CYGARC_REG_PVR, proc_rev );
#define PROC_REVB 0x0020
if ((proc_rev & 0x0000FFFF) == PROC_REVB) {
eppc->pio_pddir = 0x1C58;
} else {
eppc->pio_pddir = 0x1FFF;
}
 
// Get physical device address
#ifdef CYGPKG_REDBOOT
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
esa_ok = flash_get_config("fec_esa", enaddr, CONFIG_ESA);
#else
esa_ok = false;
#endif
#else
esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
"fec_esa", enaddr, CONFIG_ESA);
#endif
if (!esa_ok) {
// Can't figure out ESA
os_printf("FEC_ETH - Warning! ESA unknown\n");
memcpy(&enaddr, &_default_enaddr, sizeof(enaddr));
}
 
// Configure the device
if (!fec_eth_reset(sc, enaddr, 0)) {
return false;
}
 
fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
 
#ifdef CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
// Reset PHY (transceiver)
FEC_ETH_RESET_PHY();
 
phy_ok = 0;
if (phy_read(PHY_BMSR, FEC_ETH_PHY, &phy_state)) {
if ((phy_state & PHY_BMSR_LINK) != PHY_BMSR_LINK) {
unsigned short reset_mode;
int i;
phy_write(PHY_BMCR, FEC_ETH_PHY, PHY_BMCR_RESET);
for (i = 0; i < 10; i++) {
phy_ok = phy_read(PHY_BMCR, FEC_ETH_PHY, &phy_state);
if (!phy_ok) break;
if (!(phy_state & PHY_BMCR_RESET)) break;
}
if (!phy_ok || (phy_state & PHY_BMCR_RESET)) {
os_printf("FEC: Can't get PHY unit to soft reset: %x\n", phy_state);
return false;
}
 
fec->iEvent = 0xFFFFFFFF; // Clear all interrupts
reset_mode = PHY_BMCR_RESTART;
#ifdef CYGNUM_DEVS_ETH_POWERPC_FEC_LINK_MODE_Auto
reset_mode |= PHY_BMCR_AUTO_NEG;
#endif
#ifdef CYGNUM_DEVS_ETH_POWERPC_FEC_LINK_MODE_100Mb
reset_mode |= PHY_BMCR_100MB;
#endif
phy_write(PHY_BMCR, FEC_ETH_PHY, reset_mode);
while (phy_timeout-- >= 0) {
int ev = fec->iEvent;
unsigned short state;
fec->iEvent = ev;
if (ev & iEvent_MII) {
phy_ok = phy_read(PHY_BMSR, FEC_ETH_PHY, &state);
if (phy_ok && (state & PHY_BMSR_LINK)) {
break;
} else {
CYGACC_CALL_IF_DELAY_US(10000); // 10ms
}
}
}
if (phy_timeout <= 0) {
os_printf("** FEC Warning: PHY LINK UP failed\n");
}
}
else {
os_printf("** FEC Info: PHY LINK already UP \n");
}
}
#endif // CYGSEM_DEVS_ETH_POWERPC_FEC_RESET_PHY
 
// Initialize upper level driver
(sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
if (cache_state)
HAL_DCACHE_ENABLE();
 
return true;
}
//
// This function is called to shut down the interface.
//
static void
fec_eth_stop(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
 
// Disable the device!
qi->fec->eControl &= ~eControl_EN;
}
 
//
// 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
fec_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
{
// Enable the device!
fec_eth_reset(sc, enaddr, flags);
}
 
//
// This function is called for low level "control" operations
//
static int
fec_eth_control(struct eth_drv_sc *sc, unsigned long key,
void *data, int length)
{
#ifdef ETH_DRV_SET_MC_ALL
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile struct fec *fec = qi->fec;
#endif
 
switch (key) {
case ETH_DRV_SET_MAC_ADDRESS:
return 0;
break;
#ifdef ETH_DRV_SET_MC_ALL
case ETH_DRV_SET_MC_ALL:
case ETH_DRV_SET_MC_LIST:
fec->RxControl &= ~RxControl_PROM;
fec->hash[0] = 0xFFFFFFFF;
fec->hash[1] = 0xFFFFFFFF;
return 0;
break;
#endif
default:
return 1;
break;
}
}
 
//
// This function is called to see if another packet can be sent.
// It should return the number of packets which can be handled.
// Zero should be returned if the interface is busy and can not send any more.
//
static int
fec_eth_can_send(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
 
return (qi->txactive < CYGNUM_DEVS_ETH_POWERPC_FEC_TxNUM);
}
 
//
// This routine is called to send data to the hardware.
 
static void
fec_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
int total_len, unsigned long key)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile struct fec_bd *txbd, *txfirst;
volatile char *bp;
int i, txindex, cache_state;
 
// Find a free buffer
txbd = txfirst = qi->txbd;
while (txbd->ctrl & FEC_BD_Tx_Ready) {
// This buffer is busy, move to next one
if (txbd->ctrl & FEC_BD_Tx_Wrap) {
txbd = qi->tbase;
} else {
txbd++;
}
if (txbd == txfirst) {
#ifdef CYGPKG_NET
panic ("No free xmit buffers");
#else
os_printf("FEC Ethernet: No free xmit buffers\n");
#endif
}
}
// Set up buffer
bp = txbd->buffer;
for (i = 0; i < sg_len; i++) {
memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
bp += sg_list[i].len;
}
txbd->length = total_len;
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
qi->txkey[txindex] = key;
// Note: the MPC860 does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_FLUSH(txbd->buffer, txbd->length); // Make sure no stale data
}
// Send it on it's way
txbd->ctrl |= FEC_BD_Tx_Ready | FEC_BD_Tx_Last | FEC_BD_Tx_TC;
#ifndef FEC_USE_EPPC_BD
if (cache_state) {
HAL_DCACHE_FLUSH(fec_eth_txring, sizeof(fec_eth_txring)); // Make sure no stale data
}
#endif
qi->txactive++;
qi->fec->TxUpdate = 0x01000000; // Any write tells machine to look for work
set_led(LED_TxACTIVE);
// Remember the next buffer to try
if (txbd->ctrl & FEC_BD_Tx_Wrap) {
qi->txbd = qi->tbase;
} else {
qi->txbd = txbd+1;
}
}
 
//
// This function is called when a packet has been received. It's 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
// 'fec_eth_recv' will be called to actually fetch it from the hardware.
//
static void
fec_eth_RxEvent(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile struct fec_bd *rxbd, *rxfirst;
int cache_state;
 
// Note: the MPC860 does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
#ifndef FEC_USE_EPPC_BD
if (cache_state) {
HAL_DCACHE_INVALIDATE(fec_eth_rxring, sizeof(fec_eth_rxring)); // Make sure no stale data
}
#endif
rxbd = rxfirst = qi->rnext;
while (true) {
if ((rxbd->ctrl & FEC_BD_Rx_Empty) == 0) {
qi->rxbd = rxbd; // Save for callback
set_led(LED_RxACTIVE);
(sc->funs->eth_drv->recv)(sc, rxbd->length);
}
if (rxbd->ctrl & FEC_BD_Rx_Wrap) {
rxbd = qi->rbase;
} else {
rxbd++;
}
if (rxbd == rxfirst) {
break;
}
}
// Remember where we left off
qi->rnext = (struct fec_bd *)rxbd;
#ifndef FEC_USE_EPPC_BD
if (cache_state) {
HAL_DCACHE_INVALIDATE(fec_eth_rxring, sizeof(fec_eth_rxring)); // Make sure no stale data
}
#endif
qi->fec->RxUpdate = 0x0F0F0F0F; // Any write tells machine to look for work
}
 
//
// This function is called as a result of the "eth_drv_recv()" call above.
// It's 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
fec_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
unsigned char *bp;
int i, cache_state;
 
bp = (unsigned char *)qi->rxbd->buffer;
// Note: the MPC860 does not seem to snoop/invalidate the data cache properly!
HAL_DCACHE_IS_ENABLED(cache_state);
if (cache_state) {
HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data
}
for (i = 0; i < sg_len; i++) {
if (sg_list[i].buf != 0) {
memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
bp += sg_list[i].len;
}
}
qi->rxbd->ctrl |= FEC_BD_Rx_Empty;
clear_led(LED_RxACTIVE);
}
 
static void
fec_eth_TxEvent(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
volatile struct fec_bd *txbd;
int key, txindex, cache_state;
 
HAL_DCACHE_IS_ENABLED(cache_state);
#ifndef FEC_USE_EPPC_BD
if (cache_state) {
HAL_DCACHE_FLUSH(fec_eth_txring, sizeof(fec_eth_txring)); // Make sure no stale data
}
#endif
txbd = qi->tnext;
// Note: TC field is used to indicate the buffer has/had data in it
while ((txbd->ctrl & (FEC_BD_Tx_Ready|FEC_BD_Tx_TC)) == FEC_BD_Tx_TC) {
txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
if ((key = qi->txkey[txindex]) != 0) {
qi->txkey[txindex] = 0;
(sc->funs->eth_drv->tx_done)(sc, key, 0);
}
if (--qi->txactive == 0) {
clear_led(LED_TxACTIVE);
}
txbd->ctrl &= ~FEC_BD_Tx_TC;
if (txbd->ctrl & FEC_BD_Tx_Wrap) {
txbd = qi->tbase;
} else {
txbd++;
}
}
// Remember where we left off
qi->tnext = (struct fec_bd *)txbd;
#ifndef FEC_USE_EPPC_BD
if (cache_state) {
HAL_DCACHE_FLUSH(fec_eth_txring, sizeof(fec_eth_txring)); // Make sure no stale data
}
#endif
}
 
//
// Interrupt processing
//
static void
fec_eth_int(struct eth_drv_sc *sc)
{
struct fec_eth_info *qi = (struct fec_eth_info *)sc->driver_private;
unsigned long event;
 
while ((event = qi->fec->iEvent) != 0) {
if ((event & iEvent_TFINT) != 0) {
fec_eth_TxEvent(sc);
}
if ((event & iEvent_RFINT) != 0) {
fec_eth_RxEvent(sc);
}
qi->fec->iEvent = event; // Reset the bits we handled
}
}
 
//
// Interrupt vector
//
static int
fec_eth_int_vector(struct eth_drv_sc *sc)
{
return (FEC_ETH_INT);
}
 
#if defined(CYGINT_IO_ETH_INT_SUPPORT_REQUIRED) && ~defined(_FEC_USE_INTS)
void
fec_fake_int(cyg_addrword_t param)
{
struct eth_drv_sc *sc = (struct eth_drv_sc *) param;
int int_state;
 
while (true) {
cyg_thread_delay(1); // 10ms
HAL_DISABLE_INTERRUPTS(int_state);
fec_eth_int(sc);
HAL_RESTORE_INTERRUPTS(int_state);
}
}
#endif

powered by: WebSVN 2.1.0

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