# HG changeset patch # User gthomas # Date 1144424312 0 # Node ID 970f455a23974a0ce7c5e490a9885e682cc3d913 # Parent a70dd1fde4061e2208ff91b112d551c11b27df67 Add support for ICS189X, better debug handling - from Jay Foster diff --git a/packages/devs/eth/phy/current/ChangeLog b/packages/devs/eth/phy/current/ChangeLog --- a/packages/devs/eth/phy/current/ChangeLog +++ b/packages/devs/eth/phy/current/ChangeLog @@ -2,6 +2,17 @@ 2006-04-07 Andrew Lunn + * include/eth_phy.h: Add default mode value for _eth_phy_cfg(). + * cdl/phy_eth_drivers.cdl: Add support for ICS189x. + * include/eth_phy_dev.h: + * src/AM79C874.c: + * src/DP83847.c: + * src/INLXT972.c: Make debug output CDL configurable. + * src/eth_phy.c: Fix bug in _eth_phy_init() that prevented using + a PHY MII address other than 0. + * src/ics189x.c: New + 2005-08-25 Markus Schade * src/INLXT972.c: diff --git a/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl b/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl --- a/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl +++ b/packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl @@ -61,6 +61,14 @@ cdl_package CYGPKG_DEVS_ETH_PHY { compile eth_phy.c + cdl_option CYGDBG_DEVS_ETH_PHY { + display "Enable driver debugging" + flavor bool + default_value 0 + description "Enables the diagnostic debug messages on the + console device." + } + cdl_option CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME { display "Time period (seconds) to wait for auto-negotiation" flavor data @@ -96,4 +104,32 @@ cdl_package CYGPKG_DEVS_ETH_PHY { description " Include support for Intel LXT972xxx PHY" } + + cdl_option CYGHWR_DEVS_ETH_PHY_ICS1890 { + display "ICS 1890" + flavor bool + default_value 0 + compile -library=libextras.a ics189x.c + description " + Include support for ICS 1890 PHY" + } + + cdl_option CYGHWR_DEVS_ETH_PHY_ICS1892 { + display "ICS 1892" + flavor bool + default_value 0 + compile -library=libextras.a ics189x.c + description " + Include support for ICS 1892 PHY" + } + + cdl_option CYGHWR_DEVS_ETH_PHY_ICS1893 { + display "ICS 1893" + flavor bool + default_value 0 + compile -library=libextras.a ics189x.c + description " + Include support for ICS 1893 and 1893AF PHY" + } + } diff --git a/packages/devs/eth/phy/current/include/eth_phy.h b/packages/devs/eth/phy/current/include/eth_phy.h --- a/packages/devs/eth/phy/current/include/eth_phy.h +++ b/packages/devs/eth/phy/current/include/eth_phy.h @@ -93,6 +93,8 @@ externC bool _eth_phy_init(eth_phy_acces externC void _eth_phy_reset(eth_phy_access_t *f); externC int _eth_phy_state(eth_phy_access_t *f); externC int _eth_phy_cfg(eth_phy_access_t *f, int mode); +#define ETH_PHY_MODE_DEFAULT 0 + // Internal routines externC void _eth_phy_write(eth_phy_access_t *f, int reg, int unit, unsigned short data); externC bool _eth_phy_read(eth_phy_access_t *f, int reg, int unit, unsigned short *val); diff --git a/packages/devs/eth/phy/current/include/eth_phy_dev.h b/packages/devs/eth/phy/current/include/eth_phy_dev.h --- a/packages/devs/eth/phy/current/include/eth_phy_dev.h +++ b/packages/devs/eth/phy/current/include/eth_phy_dev.h @@ -52,6 +52,13 @@ // //========================================================================== +#ifdef CYGDBG_DEVS_ETH_PHY +#include +#define eth_phy_printf(args...) diag_printf(args) +#else +#define eth_phy_printf(args...) /* NOOP */ +#endif + // Transceiver mode #define PHY_BMCR 0x00 // Register number #define PHY_BMCR_RESET 0x8000 @@ -76,6 +83,20 @@ #define PHY_ID1 0x02 // Chip ID register (high 16 bits) #define PHY_ID2 0x03 // Chip ID register (low 16 bits) +#define PHY_AN_ADV 0x04 // Auto negotiation advertisement register +#define PHY_AN_ADV_10HDX 0x0020 +#define PHY_AN_ADV_10FDX 0x0040 +#define PHY_AN_ADV_100HDX 0x0080 +#define PHY_AN_ADV_100FDX 0x0100 +#define PHY_AN_ADV_100_T4 0x0200 + +#define PHY_AN_PAR 0x05 // Auto negotiation link partner ability +#define PHY_AN_PAR_10HDX 0x0020 +#define PHY_AN_PAR_10FDX 0x0040 +#define PHY_AN_PAR_100HDX 0x0080 +#define PHY_AN_PAR_100FDX 0x0100 +#define PHY_AN_PAR_100_T4 0x0200 + struct _eth_phy_dev_entry { char *name; unsigned long id; diff --git a/packages/devs/eth/phy/current/src/AM79C874.c b/packages/devs/eth/phy/current/src/AM79C874.c --- a/packages/devs/eth/phy/current/src/AM79C874.c +++ b/packages/devs/eth/phy/current/src/AM79C874.c @@ -55,7 +55,6 @@ #include #include -#include #include #include @@ -73,7 +72,7 @@ static bool am79c874_stat(eth_phy_access // Read negotiated state if (_eth_phy_read(f, 0x1, f->phy_addr, &phy_state)) { if ((phy_state & 0x20) == 0) { - diag_printf("... waiting for auto-negotiation"); + eth_phy_printf("... waiting for auto-negotiation"); for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) { if (_eth_phy_read(f, 0x1, f->phy_addr, &phy_state)) { if ((phy_state & 0x20) != 0) { @@ -81,9 +80,9 @@ static bool am79c874_stat(eth_phy_access } } CYGACC_CALL_IF_DELAY_US(1000000); // 1 second - diag_printf("."); + eth_phy_printf("."); } - diag_printf("\n"); + eth_phy_printf("\n"); } if ((phy_state & 0x20) != 0) { *state = 0; diff --git a/packages/devs/eth/phy/current/src/DP83847.c b/packages/devs/eth/phy/current/src/DP83847.c --- a/packages/devs/eth/phy/current/src/DP83847.c +++ b/packages/devs/eth/phy/current/src/DP83847.c @@ -55,7 +55,6 @@ #include #include -#include #include #include @@ -73,7 +72,7 @@ static bool dp83847_stat(eth_phy_access_ // Read negotiated state if (_eth_phy_read(f, 0x10, f->phy_addr, &phy_state)) { if ((phy_state & 0x10) == 0) { - diag_printf("... waiting for auto-negotiation"); + eth_phy_printf("... waiting for auto-negotiation"); for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) { if (_eth_phy_read(f, 0x10, f->phy_addr, &phy_state)) { if ((phy_state & 0x10) != 0) { @@ -81,9 +80,9 @@ static bool dp83847_stat(eth_phy_access_ } } CYGACC_CALL_IF_DELAY_US(1000000); // 1 second - diag_printf("."); + eth_phy_printf("."); } - diag_printf("\n"); + eth_phy_printf("\n"); } if ((phy_state & 0x10) != 0) { *state = 0; diff --git a/packages/devs/eth/phy/current/src/INLXT972.c b/packages/devs/eth/phy/current/src/INLXT972.c --- a/packages/devs/eth/phy/current/src/INLXT972.c +++ b/packages/devs/eth/phy/current/src/INLXT972.c @@ -55,7 +55,6 @@ #include #include -#include #include #include @@ -73,7 +72,7 @@ static bool inlxt972_stat(eth_phy_access // Read negotiated state if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state)) { if ((phy_state & PHY_BMSR_AUTO_NEG) == 0) { - diag_printf("... waiting for auto-negotiation"); + eth_phy_printf("... waiting for auto-negotiation"); for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) { if (_eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state)) { if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) { @@ -81,9 +80,9 @@ static bool inlxt972_stat(eth_phy_access } } CYGACC_CALL_IF_DELAY_US(1000000); // 1 second - diag_printf("."); + eth_phy_printf("."); } - diag_printf("\n"); + eth_phy_printf("\n"); } if ((phy_state & PHY_BMSR_AUTO_NEG) != 0) { *state = 0; diff --git a/packages/devs/eth/phy/current/src/eth_phy.c b/packages/devs/eth/phy/current/src/eth_phy.c --- a/packages/devs/eth/phy/current/src/eth_phy.c +++ b/packages/devs/eth/phy/current/src/eth_phy.c @@ -52,8 +52,9 @@ //========================================================================== #include +#include +#include #include -#include #include #include @@ -153,7 +154,7 @@ externC bool { int addr; unsigned short state; - unsigned long id; + unsigned long id = 0; struct _eth_phy_dev_entry *dev; if (f->init_done) return true; @@ -168,16 +169,19 @@ externC bool f->phy_addr = addr; for (dev = __ETH_PHY_TAB__; dev != &__ETH_PHY_TAB_END__; dev++) { if (dev->id == id) { - diag_printf("PHY: %s\n", dev->name); + eth_phy_printf("PHY: %s\n", dev->name); f->dev = dev; return true; } } - diag_printf("Unsupported PHY device - id: %x\n", id); - break; // Can't handle this PHY } } } + if (addr >= 0x20) + { + // Can't handle this PHY + eth_phy_printf("Unsupported PHY device - id: %x\n", id); + } f->init_done = false; return false; } @@ -186,7 +190,7 @@ externC void _eth_phy_reset(eth_phy_access_t *f) { if (!f->init_done) { - diag_printf("PHY reset without init on PHY: %x\n", f); + eth_phy_printf("PHY reset without init on PHY: %x\n", f); return; } (f->init)(); @@ -196,7 +200,7 @@ externC void _eth_phy_write(eth_phy_access_t *f, int reg, int addr, unsigned short data) { if (!f->init_done) { - diag_printf("PHY write without init on PHY: %x\n", f); + eth_phy_printf("PHY write without init on PHY: %x\n", f); return; } if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) { @@ -212,7 +216,7 @@ externC bool cyg_uint32 ret; if (!f->init_done) { - diag_printf("PHY read without init on PHY: %x\n", f); + eth_phy_printf("PHY read without init on PHY: %x\n", f); return false; } if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) { @@ -233,7 +237,7 @@ externC int int i; if (!f->init_done) { - diag_printf("PHY config without init on PHY: %x\n", f); + eth_phy_printf("PHY config without init on PHY: %x\n", f); return 0; } @@ -244,12 +248,12 @@ externC int _eth_phy_write(f, PHY_BMCR, f->phy_addr, PHY_BMCR_RESET); for (i = 0; i < 5*100; i++) { phy_ok = _eth_phy_read(f, PHY_BMCR, f->phy_addr, &phy_state); - diag_printf("PHY: %x\n", phy_state); + eth_phy_printf("PHY: %x\n", phy_state); if (phy_ok && !(phy_state & PHY_BMCR_RESET)) break; CYGACC_CALL_IF_DELAY_US(10000); // 10ms } if (!phy_ok || (phy_state & PHY_BMCR_RESET)) { - diag_printf("PPC405: Can't get PHY unit to soft reset: %x\n", phy_state); + eth_phy_printf("PPC405: Can't get PHY unit to soft reset: %x\n", phy_state); return 0; } @@ -264,7 +268,7 @@ externC int } } if (phy_timeout <= 0) { - diag_printf("** PPC405 Warning: PHY LINK UP failed: %04x\n", phy_state); + eth_phy_printf("** PPC405 Warning: PHY LINK UP failed: %04x\n", phy_state); return 0; } @@ -277,7 +281,7 @@ externC int int state = 0; if (!f->init_done) { - diag_printf("PHY state without init on PHY: %x\n", f); + eth_phy_printf("PHY state without init on PHY: %x\n", f); return 0; } if ((f->dev->stat)(f, &state)) { diff --git a/packages/devs/eth/phy/current/src/ics189x.c b/packages/devs/eth/phy/current/src/ics189x.c new file mode 100644 --- /dev/null +++ b/packages/devs/eth/phy/current/src/ics189x.c @@ -0,0 +1,119 @@ +//========================================================================== +// +// ics189x.c +// +// Ethernet transceiver (PHY) support +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2005 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: Jay Foster +// Date: 2006-03-17 +// Purpose: +// Description: Support for ethernet ICS 189x PHYs +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#define Bit(n) (1<<(n)) + +static bool ics189x_stat(eth_phy_access_t *f, int *state) +{ + unsigned short phy_state; + int tries; + + // Read negotiated state from the Quick Poll Detailed Status Register + if (_eth_phy_read(f, 17, f->phy_addr, &phy_state)) + { + if ((phy_state & Bit(4)) == 0) + { + eth_phy_printf("... waiting for auto-negotiation"); + for (tries = 0; tries < CYGINT_DEVS_ETH_PHY_AUTO_NEGOTIATION_TIME; tries++) + { + if (_eth_phy_read(f, 17, f->phy_addr, &phy_state)) + { + if ((phy_state & Bit(4)) != 0) + { + break; + } + } + CYGACC_CALL_IF_DELAY_US(1000000); // 1 second + eth_phy_printf("."); + } + eth_phy_printf("\n"); + } + if ((phy_state & Bit(4)) != 0) + { + *state = 0; + if (phy_state & Bit(0)) + *state |= ETH_PHY_STAT_LINK; + if (phy_state & Bit(14)) + *state |= ETH_PHY_STAT_FDX; + if (phy_state & Bit(15)) + *state |= ETH_PHY_STAT_100MB; + return true; + } + } + return false; +} + +#ifdef CYGHWR_DEVS_ETH_PHY_ICS1890 +_eth_phy_dev("ICS 1890", 0x0015F422, ics189x_stat) // 1st general release +_eth_phy_dev("ICS 1890", 0x0015F423, ics189x_stat) // 1890 "J" release +#endif +#ifdef CYGHWR_DEVS_ETH_PHY_ICS1892 +_eth_phy_dev("ICS 1892", 0x0015F430, ics189x_stat) +#endif +#ifdef CYGHWR_DEVS_ETH_PHY_ICS1893 +_eth_phy_dev("ICS 1893", 0x0015F441, ics189x_stat) +#endif +