wdenk | affae2b | 2002-08-17 09:36:01 +0000 | [diff] [blame] | 1 | #include <common.h> |
| 2 | #include <mii_phy.h> |
| 3 | #include "rpxsuper.h" |
| 4 | |
| 5 | #define MII_MDIO 0x01 |
| 6 | #define MII_MDCK 0x02 |
| 7 | #define MII_MDIR 0x04 |
| 8 | |
| 9 | void |
| 10 | mii_discover_phy(void) |
| 11 | { |
| 12 | int known; |
| 13 | unsigned short phy_reg; |
| 14 | unsigned long phy_id; |
| 15 | |
| 16 | known = 0; |
| 17 | printf("Discovering phy @ 0: "); |
| 18 | phy_id = mii_phy_read(2) << 16; |
| 19 | phy_id |= mii_phy_read(3); |
| 20 | if ((phy_id & 0xFFFFFC00) == 0x00137800) { |
| 21 | printf("Level One "); |
| 22 | if ((phy_id & 0x000003F0) == 0xE0) { |
| 23 | printf("LXT971A Revision %d\n", (int)(phy_id & 0xF)); |
| 24 | known = 1; |
| 25 | } |
| 26 | else printf("unknown type\n"); |
| 27 | } |
| 28 | else printf("unknown OUI = 0x%08lX\n", phy_id); |
| 29 | |
| 30 | phy_reg = mii_phy_read(1); |
| 31 | if (!(phy_reg & 0x0004)) printf("Link is down\n"); |
| 32 | if (!(phy_reg & 0x0020)) printf("Auto-negotiation not complete\n"); |
| 33 | if (phy_reg & 0x0002) printf("Jabber condition detected\n"); |
| 34 | if (phy_reg & 0x0010) printf("Remote fault condition detected \n"); |
| 35 | |
| 36 | if (known) { |
| 37 | phy_reg = mii_phy_read(17); |
| 38 | if (phy_reg & 0x0400) |
| 39 | printf("Phy operating at %d MBit/s in %s-duplex mode\n", |
| 40 | phy_reg & 0x4000 ? 100 : 10, |
wdenk | 57b2d80 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 41 | phy_reg & 0x0200 ? "full" : "half"); |
wdenk | affae2b | 2002-08-17 09:36:01 +0000 | [diff] [blame] | 42 | else |
| 43 | printf("bad link!!\n"); |
| 44 | /* |
| 45 | left off: no link, green 100MBit, yellow 10MBit |
| 46 | right off: no activity, green full-duplex, yellow half-duplex |
| 47 | */ |
| 48 | mii_phy_write(20, 0x0452); |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | unsigned short |
| 53 | mii_phy_read(unsigned short reg) |
| 54 | { |
| 55 | int i; |
| 56 | unsigned short tmp, val = 0, adr = 0; |
| 57 | t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE; |
| 58 | |
| 59 | tmp = 0x6002 | (adr << 7) | (reg << 2); |
| 60 | regs->bcsr4 = 0xC3; |
| 61 | for (i = 0; i < 64; i++) { |
wdenk | 57b2d80 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 62 | regs->bcsr4 ^= MII_MDCK; |
wdenk | affae2b | 2002-08-17 09:36:01 +0000 | [diff] [blame] | 63 | } |
| 64 | for (i = 0; i < 16; i++) { |
| 65 | regs->bcsr4 &= ~MII_MDCK; |
| 66 | if (tmp & 0x8000) regs->bcsr4 |= MII_MDIO; |
| 67 | else regs->bcsr4 &= ~MII_MDIO; |
| 68 | regs->bcsr4 |= MII_MDCK; |
| 69 | tmp <<= 1; |
| 70 | } |
| 71 | regs->bcsr4 |= MII_MDIR; |
| 72 | for (i = 0; i < 16; i++) { |
| 73 | val <<= 1; |
| 74 | regs->bcsr4 = MII_MDIO | (regs->bcsr4 | MII_MDCK); |
| 75 | if (regs->bcsr4 & MII_MDIO) val |= 1; |
| 76 | regs->bcsr4 = MII_MDIO | (regs->bcsr4 &= ~MII_MDCK); |
| 77 | } |
| 78 | return val; |
| 79 | } |
| 80 | |
| 81 | void |
| 82 | mii_phy_write(unsigned short reg, unsigned short val) |
| 83 | { |
| 84 | int i; |
| 85 | unsigned short tmp, adr = 0; |
| 86 | t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE; |
| 87 | |
| 88 | tmp = 0x5002 | (adr << 7) | (reg << 2); |
| 89 | regs->bcsr4 = 0xC3; |
| 90 | for (i = 0; i < 64; i++) { |
| 91 | regs->bcsr4 ^= MII_MDCK; |
| 92 | } |
| 93 | for (i = 0; i < 16; i++) { |
| 94 | regs->bcsr4 &= ~MII_MDCK; |
wdenk | 57b2d80 | 2003-06-27 21:31:46 +0000 | [diff] [blame] | 95 | if (tmp & 0x8000) regs->bcsr4 |= MII_MDIO; |
wdenk | affae2b | 2002-08-17 09:36:01 +0000 | [diff] [blame] | 96 | else regs->bcsr4 &= ~MII_MDIO; |
| 97 | regs->bcsr4 |= MII_MDCK; |
| 98 | tmp <<= 1; |
| 99 | } |
| 100 | for (i = 0; i < 16; i++) { |
| 101 | regs->bcsr4 &= ~MII_MDCK; |
| 102 | if (val & 0x8000) regs->bcsr4 |= MII_MDIO; |
| 103 | else regs->bcsr4 &= ~MII_MDIO; |
| 104 | regs->bcsr4 |= MII_MDCK; |
| 105 | val <<= 1; |
| 106 | } |
| 107 | } |