]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/devs/eth/phy/v2_0/src/eth_phy.c
TX53 Release 2011-12-20
[karo-tx-redboot.git] / packages / devs / eth / phy / v2_0 / src / eth_phy.c
index d3943987018c4a5e5f82c5245a959ad6fbe257a7..d2b8acee082405f197e0da5822db7d39d8159281 100644 (file)
@@ -2,7 +2,7 @@
 //
 //      dev/eth_phy.c
 //
-//      Ethernet transciever (PHY) support 
+//      Ethernet transceiver (PHY) support
 //
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: 
+// Contributors:
 // Date:         2003-08-01
-// Purpose:      
+// Purpose:
 // Description:  API support for ethernet PHY
-//              
+//
 //
 //####DESCRIPTIONEND####
 //
@@ -70,13 +70,13 @@ CYG_HAL_TABLE_END( __ETH_PHY_TAB_END__, _eth_phy_devs );
 extern struct _eth_phy_dev_entry __ETH_PHY_TAB__[], __ETH_PHY_TAB_END__;
 
 // 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
+#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
 
 //
 // PHY unit access (via MII channel, using bit-level operations)
@@ -85,208 +85,208 @@ extern struct _eth_phy_dev_entry __ETH_PHY_TAB__[], __ETH_PHY_TAB_END__;
 static cyg_uint32
 phy_cmd(eth_phy_access_t *f, cyg_uint32 cmd)
 {
-    cyg_uint32  retval;
-    int         i, off;
-    bool        is_read = (cmd & MII_Cmd) == MII_Read;
+       cyg_uint32  retval;
+       int                     i, off;
+       bool            is_read = (cmd & MII_Cmd) == MII_Read;
 
-    // Set both bits as output
-    f->ops.bit_level_ops.set_dir(1);
+       // Set both bits as output
+       f->ops.bit_level_ops.set_dir(1);
 
-    // Preamble
-    for (i = 0; i < 32; i++) {
-        f->ops.bit_level_ops.set_clock(0);
-        f->ops.bit_level_ops.set_data(1);
-        CYGACC_CALL_IF_DELAY_US(1);
-        f->ops.bit_level_ops.set_clock(1);
-        CYGACC_CALL_IF_DELAY_US(1);
-    }
+       // Preamble
+       for (i = 0; i < 32; i++) {
+               f->ops.bit_level_ops.set_clock(0);
+               f->ops.bit_level_ops.set_data(1);
+               CYGACC_CALL_IF_DELAY_US(1);
+               f->ops.bit_level_ops.set_clock(1);
+               CYGACC_CALL_IF_DELAY_US(1);
+       }
 
-    // Command/data
-    for (i = 0, off = 31; i < (is_read ? 14 : 32); i++, --off) {
-        f->ops.bit_level_ops.set_clock(0);
-        f->ops.bit_level_ops.set_data((cmd >> off) & 0x00000001);
-        CYGACC_CALL_IF_DELAY_US(1);
-        f->ops.bit_level_ops.set_clock(1);
-        CYGACC_CALL_IF_DELAY_US(1);
-    }
+       // Command/data
+       for (i = 0, off = 31; i < (is_read ? 14 : 32); i++, --off) {
+               f->ops.bit_level_ops.set_clock(0);
+               f->ops.bit_level_ops.set_data((cmd >> off) & 0x00000001);
+               CYGACC_CALL_IF_DELAY_US(1);
+               f->ops.bit_level_ops.set_clock(1);
+               CYGACC_CALL_IF_DELAY_US(1);
+       }
 
-    retval = cmd;
+       retval = cmd;
 
-    // If read, fetch data register
-    if (is_read) {
-        retval >>= 16;
+       // If read, fetch data register
+       if (is_read) {
+               retval >>= 16;
 
-        f->ops.bit_level_ops.set_clock(0);
-        f->ops.bit_level_ops.set_dir(0);
-        CYGACC_CALL_IF_DELAY_US(1);
-        f->ops.bit_level_ops.set_clock(1);
-        CYGACC_CALL_IF_DELAY_US(1);
                f->ops.bit_level_ops.set_clock(0);
-        CYGACC_CALL_IF_DELAY_US(1);
+               f->ops.bit_level_ops.set_dir(0);
+               CYGACC_CALL_IF_DELAY_US(1);
+               f->ops.bit_level_ops.set_clock(1);
+               CYGACC_CALL_IF_DELAY_US(1);
+               f->ops.bit_level_ops.set_clock(0);
+               CYGACC_CALL_IF_DELAY_US(1);
 
-        for (i = 0, off = 15; i < 16; i++, off--) {
-            f->ops.bit_level_ops.set_clock(1);
-            retval <<= 1;
-            retval |= f->ops.bit_level_ops.get_data();
-            CYGACC_CALL_IF_DELAY_US(1);
-            f->ops.bit_level_ops.set_clock(0);
-            CYGACC_CALL_IF_DELAY_US(1);
-        }
-    }
+               for (i = 0, off = 15; i < 16; i++, off--) {
+                       f->ops.bit_level_ops.set_clock(1);
+                       retval <<= 1;
+                       retval |= f->ops.bit_level_ops.get_data();
+                       CYGACC_CALL_IF_DELAY_US(1);
+                       f->ops.bit_level_ops.set_clock(0);
+                       CYGACC_CALL_IF_DELAY_US(1);
+               }
+       }
 
-    // Set both bits as output
-    f->ops.bit_level_ops.set_dir(1);
+       // Set both bits as output
+       f->ops.bit_level_ops.set_dir(1);
 
-    // Postamble
-    for (i = 0; i < 32; i++) {
-        f->ops.bit_level_ops.set_clock(0);
-        f->ops.bit_level_ops.set_data(1);
-        CYGACC_CALL_IF_DELAY_US(1);
-        f->ops.bit_level_ops.set_clock(1);
-        CYGACC_CALL_IF_DELAY_US(1);
-    }
+       // Postamble
+       for (i = 0; i < 32; i++) {
+               f->ops.bit_level_ops.set_clock(0);
+               f->ops.bit_level_ops.set_data(1);
+               CYGACC_CALL_IF_DELAY_US(1);
+               f->ops.bit_level_ops.set_clock(1);
+               CYGACC_CALL_IF_DELAY_US(1);
+       }
 
-    return retval;
+       return retval;
 }
 
 externC bool
 _eth_phy_init(eth_phy_access_t *f)
 {
-    int addr;
-    unsigned short state;
-    unsigned long id = 0;
-    struct _eth_phy_dev_entry *dev;
+       int addr;
+       unsigned short state;
+       unsigned long id = 0;
+       struct _eth_phy_dev_entry *dev;
 
-    if (f->init_done) return true;
-    f->init();
-    // Scan to determine PHY address
-    f->init_done = true;
-    for (addr = 0;  addr < 0x20;  addr++) {
-        if (_eth_phy_read(f, PHY_ID1, addr, &state)) {
-            id = state << 16;
-            if (_eth_phy_read(f, PHY_ID2, addr, &state)) {
-                id |= state;
-                f->phy_addr = addr;
-                for (dev = __ETH_PHY_TAB__; dev != &__ETH_PHY_TAB_END__;  dev++) {
-                    if (dev->id == id) {
-                        eth_phy_printf("PHY: %s\n", dev->name);
-                        f->dev = dev;
-                        return true;
-                    }
-                }
-            }
-        }
-    }
-    if (addr >= 0x20) {
-        // Can't handle this PHY
-        eth_phy_printf("Unsupported PHY device - id: %lx\n", id);
-    }
-    f->init_done = false;
-    return false;
+       if (f->init_done) return true;
+       f->init();
+       // Scan to determine PHY address
+       f->init_done = true;
+       for (addr = 0;  addr < 0x20;  addr++) {
+               if (_eth_phy_read(f, PHY_ID1, addr, &state)) {
+                       id = state << 16;
+                       if (_eth_phy_read(f, PHY_ID2, addr, &state)) {
+                               id |= state;
+                               f->phy_addr = addr;
+                               for (dev = __ETH_PHY_TAB__; dev != &__ETH_PHY_TAB_END__;  dev++) {
+                                       if (dev->id == id) {
+                                               eth_phy_printf("PHY: %s\n", dev->name);
+                                               f->dev = dev;
+                                               return true;
+                                       }
+                               }
+                       }
+               }
+       }
+       if (addr >= 0x20) {
+               // Can't handle this PHY
+               eth_phy_printf("Unsupported PHY device - id: %lx\n", id);
+       }
+       f->init_done = false;
+       return false;
 }
 
 externC void
 _eth_phy_reset(eth_phy_access_t *f)
 {
-    if (!f->init_done) {
-        eth_phy_printf("PHY reset without init on PHY: %p\n", f);
-        return;
-    }
-    f->init();
+       if (!f->init_done) {
+               eth_phy_printf("PHY reset without init on PHY: %p\n", f);
+               return;
+       }
+       f->init();
 }
 
 externC void
 _eth_phy_write(eth_phy_access_t *f, int reg, int addr, unsigned short data)
 {
-    if (!f->init_done) {
-        eth_phy_printf("PHY write without init on PHY: %p\n", f);
-        return;
-    }
-    if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) {
-        phy_cmd(f, MII_Start | MII_Write | MII_Phy(addr) | MII_Reg(reg) | MII_TA | data);
-    } else {
-        f->ops.reg_level_ops.put_reg(reg, addr, data);
-    }
+       if (!f->init_done) {
+               eth_phy_printf("PHY write without init on PHY: %p\n", f);
+               return;
+       }
+       if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) {
+               phy_cmd(f, MII_Start | MII_Write | MII_Phy(addr) | MII_Reg(reg) | MII_TA | data);
+       } else {
+               f->ops.reg_level_ops.put_reg(reg, addr, data);
+       }
 }
 
 externC bool
 _eth_phy_read(eth_phy_access_t *f, int reg, int addr, unsigned short *val)
 {
-    cyg_uint32 ret;
+       cyg_uint32 ret;
 
-    if (!f->init_done) {
-        eth_phy_printf("PHY read without init on PHY: %p\n", f);
-        return false;
-    }
-    if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) {
-        ret = phy_cmd(f, MII_Start | MII_Read | MII_Phy(addr) | MII_Reg(reg) | MII_TA);
-        *val = ret;
-        return true;
-    } else {
-        return f->ops.reg_level_ops.get_reg(reg, addr, val);
-    }
+       if (!f->init_done) {
+               eth_phy_printf("PHY read without init on PHY: %p\n", f);
+               return false;
+       }
+       if (f->ops_type == PHY_BIT_LEVEL_ACCESS_TYPE) {
+               ret = phy_cmd(f, MII_Start | MII_Read | MII_Phy(addr) | MII_Reg(reg) | MII_TA);
+               *val = ret;
+               return true;
+       } else {
+               return f->ops.reg_level_ops.get_reg(reg, addr, val);
+       }
 }
 
 externC int
 _eth_phy_cfg(eth_phy_access_t *f, int mode)
 {
-    int phy_timeout = 5*1000;  // Wait 5 seconds max for link to clear
-    bool phy_ok;
-    unsigned short reset_mode, phy_state;
-    int i;
+       int phy_timeout = 5 * 1000;  // Wait 5 seconds max for link to clear
+       bool phy_ok;
+       unsigned short reset_mode, phy_state;
+       int i;
 
-    if (!f->init_done) {
-        eth_phy_printf("PHY config without init on PHY: %p\n", f);
-        return 0;
-    }
+       if (!f->init_done) {
+               eth_phy_printf("PHY config without init on PHY: %p\n", f);
+               return 0;
+       }
 
-    // Reset PHY (transceiver)
-    phy_ok = false;
-    _eth_phy_reset(f);
+       // Reset PHY (transceiver)
+       phy_ok = false;
+       _eth_phy_reset(f);
 
-    _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);            
-        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)) {
-        eth_phy_printf("PPC405: Can't get PHY unit to soft reset: %x\n", phy_state);
-        return 0;
-    }
+       _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);
+               eth_phy_printf("PHY: %04x\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)) {
+               eth_phy_printf("Can't get PHY unit to soft reset: %x\n", phy_state);
+               return 0;
+       }
 
-    reset_mode = PHY_BMCR_RESTART | PHY_BMCR_AUTO_NEG;
-    _eth_phy_write(f, PHY_BMCR, f->phy_addr, reset_mode);
-    while (phy_timeout-- >= 0) {
-        phy_ok = _eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state);
-        if (phy_ok && (phy_state & PHY_BMSR_AUTO_NEG)) {
-            break;
-        } else {
-            CYGACC_CALL_IF_DELAY_US(10000);   // 10ms
-        }
-    }
-    if (phy_timeout <= 0) {
-        eth_phy_printf("** PPC405 Warning: PHY LINK UP failed: %04x\n", phy_state);
-        return 0;
-    }
+       reset_mode = PHY_BMCR_RESTART | PHY_BMCR_AUTO_NEG;
+       _eth_phy_write(f, PHY_BMCR, f->phy_addr, reset_mode);
+       while (phy_timeout-- >= 0) {
+               phy_ok = _eth_phy_read(f, PHY_BMSR, f->phy_addr, &phy_state);
+               if (phy_ok && (phy_state & PHY_BMSR_AUTO_NEG)) {
+                       break;
+               } else {
+                       CYGACC_CALL_IF_DELAY_US(10000);   // 10ms
+               }
+       }
+       if (phy_timeout <= 0) {
+               eth_phy_printf("**Warning: PHY LINK UP failed: %04x\n", phy_state);
+               return 0;
+       }
 
-    return _eth_phy_state(f);
+       return _eth_phy_state(f);
 }
 
 externC int
 _eth_phy_state(eth_phy_access_t *f)
 {
-    int state = 0;
+       int state = 0;
 
-    if (!f->init_done) {
-        eth_phy_printf("PHY state without init on PHY: %p\n", f);
-        return 0;
-    }
-    if (f->dev->stat(f, &state)) {
-        return state;
-    } else {
-        return 0;
-    }
-    return state;
+       if (!f->init_done) {
+               eth_phy_printf("PHY state without init on PHY: %p\n", f);
+               return 0;
+       }
+       if (f->dev->stat(f, &state)) {
+               return state;
+       } else {
+               return 0;
+       }
+       return state;
 }