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 |