changeset 2177:970f455a2397

Add support for ICS189X, better debug handling - from Jay Foster
author gthomas
date Fri, 07 Apr 2006 15:38:32 +0000
parents a70dd1fde406
children 9bb18751f4b7
files packages/devs/eth/phy/current/ChangeLog packages/devs/eth/phy/current/cdl/phy_eth_drivers.cdl packages/devs/eth/phy/current/include/eth_phy.h packages/devs/eth/phy/current/include/eth_phy_dev.h packages/devs/eth/phy/current/src/AM79C874.c packages/devs/eth/phy/current/src/DP83847.c packages/devs/eth/phy/current/src/INLXT972.c packages/devs/eth/phy/current/src/eth_phy.c packages/devs/eth/phy/current/src/ics189x.c
diffstat 9 files changed, 215 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/packages/devs/eth/phy/current/ChangeLog
+++ b/packages/devs/eth/phy/current/ChangeLog
@@ -2,6 +2,17 @@ 2006-04-07  Andrew Lunn  <andrew.lunn@as
 
 	* doc/eth_phy.sgml: Fixed a few typos
 
+2006-03-30  Jay Foster <jay@systech.com>
+	* 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 <marks@peppercon.de>
 
 	* src/INLXT972.c: 
--- 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"
+    }
+
 }
--- 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);
--- 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 <cyg/infra/diag.h>
+#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;
--- a/packages/devs/eth/phy/current/src/AM79C874.c
+++ b/packages/devs/eth/phy/current/src/AM79C874.c
@@ -55,7 +55,6 @@
 #include <pkgconf/devs_eth_phy.h>
 
 #include <cyg/infra/cyg_type.h>
-#include <cyg/infra/diag.h>
 
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/drv_api.h>
@@ -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;
--- a/packages/devs/eth/phy/current/src/DP83847.c
+++ b/packages/devs/eth/phy/current/src/DP83847.c
@@ -55,7 +55,6 @@
 #include <pkgconf/devs_eth_phy.h>
 
 #include <cyg/infra/cyg_type.h>
-#include <cyg/infra/diag.h>
 
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/drv_api.h>
@@ -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;
--- a/packages/devs/eth/phy/current/src/INLXT972.c
+++ b/packages/devs/eth/phy/current/src/INLXT972.c
@@ -55,7 +55,6 @@
 #include <pkgconf/devs_eth_phy.h>
 
 #include <cyg/infra/cyg_type.h>
-#include <cyg/infra/diag.h>
 
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/drv_api.h>
@@ -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;
--- 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 <pkgconf/system.h>
+#include <pkgconf/io_eth_drivers.h>
+#include <pkgconf/devs_eth_phy.h>
 #include <cyg/infra/cyg_type.h>
-#include <cyg/infra/diag.h>
 
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/drv_api.h>
@@ -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)) {
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 <pkgconf/system.h>
+#include <pkgconf/devs_eth_phy.h>
+
+#include <cyg/infra/cyg_type.h>
+
+#include <cyg/hal/hal_arch.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_tables.h>
+
+#include <cyg/io/eth_phy.h>
+#include <cyg/io/eth_phy_dev.h>
+
+#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
+