1 //==========================================================================
5 // Driver for RTL8201 PHY
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
44 // Contributoris: rcassebohm, gthomas, jskov
45 // Grant Edwards <grante@visi.com>
50 //####DESCRIPTIONEND####
53 #include <pkgconf/system.h>
54 #include <pkgconf/hal.h>
55 #include <cyg/hal/hal_if.h>
57 #include <pkgconf/devs_eth_arm_ks32c5000.h>
59 #include <cyg/infra/diag.h>
64 // Set up the level of debug output
65 #if CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL > 0
66 #define debug1_printf(args...) diag_printf(args)
68 #define debug1_printf(args...) /* noop */
70 #if CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL > 1
71 #define debug2_printf(args...) diag_printf(args)
73 #define debug2_printf(args...) /* noop */
76 // address of the RTL8201 phy
77 #ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
78 #define RTL8201_ADDR CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
80 #error no Phy addr set
83 // RTL8201 register offsets
84 #define RTL8201_CNTL_REG 0x00
85 #define RTL8201_STATUS_REG 0x01
86 #define RTL8201_ID_REG1 0x02
87 #define RTL8201_ID_REG2 0x03
88 #define RTL8201_ANA_REG 0x04
89 #define RTL8201_ANLPA_REG 0x05
90 #define RTL8201_ANE_REG 0x06
91 #define RTL8201_NSR_REG 0x10
92 #define RTL8201_LBREMR_REG 0x11
93 #define RTL8201_RXER_REG 0x12
94 #define RTL8201_10M_NIC_REG 0x13
95 #define RTL8201_PHY1_1_REG 0x14
96 #define RTL8201_PHY1_2_REG 0x15
97 #define RTL8201_PHY2_REG 0x16
98 #define RTL8201_TWISTER1_REG 0x17
99 #define RTL8201_TWISTER2_REG 0x18
100 #define RTL8201_TEST_REG 0x19
102 // RTL8201 Control register bit defines
103 #define RTL8201_CNTL_RESET 0x8000
104 #define RTL8201_CNTL_LOOPBACK 0x4000
105 #define RTL8201_CNTL_SPEED 0x2000 // 1=100Meg, 0=10Meg
106 #define RTL8201_CNTL_AN 0x1000 // 1=Enable auto negotiation, 0=disable it
107 #define RTL8201_CNTL_PWRDN 0x0800 // 1=Enable power down
108 #define RTL8201_CNTL_RSTRT_AN 0x0200 // 1=Restart Auto Negotioation process
109 #define RTL8201_CNTL_FULL_DUP 0x0100 // 1=Enable full duplex mode, 0=half dup
111 #define Bit(n) (1<<(n))
113 #define RTL8201_STATUS_100T4 Bit(15)
114 #define RTL8201_STATUS_100TX_FULL Bit(14)
115 #define RTL8201_STATUS_100TX Bit(13)
116 #define RTL8201_STATUS_10T_FULL Bit(12)
117 #define RTL8201_STATUS_10T Bit(11)
118 #define RTL8201_STATUS_AN_COMLETE Bit(5)
119 #define RTL8201_STATUS_LINKUP Bit(2)
121 #define RTL8201_ANA_PAUSE_ENA Bit(10)
122 #define RTL8201_ANA_100T4 Bit(9)
123 #define RTL8201_ANA_100TX_FULL Bit(8)
124 #define RTL8201_ANA_100TX Bit(7)
125 #define RTL8201_ANA_10T_FULL Bit(6)
126 #define RTL8201_ANA_10T Bit(5)
127 #define RTL8201_ANA_SEL_802_3 Bit(0)
129 #define RTL8201_TEST_LINK_10 Bit(1)
130 #define RTL8201_TEST_LINK_100 Bit(0)
131 #define RTL8201_TEST_PHY_ADR (0x1f<<8)
135 static int init_done=0;
143 debug2_printf("Phy addr %d\n",RTL8201_ADDR);
144 // first software reset the RTL8201
145 MiiStationWrite(RTL8201_CNTL_REG, RTL8201_ADDR, RTL8201_CNTL_RESET);
146 MiiStationWrite(RTL8201_CNTL_REG, RTL8201_ADDR, 0);
148 // initialize auto-negotiation capabilities
149 MiiStationWrite(RTL8201_ANA_REG,RTL8201_ADDR,
150 RTL8201_ANA_100TX_FULL+
152 RTL8201_ANA_10T_FULL+
154 RTL8201_ANA_SEL_802_3);
155 // Now start an auto negotiation
156 debug1_printf("Start auto negotiation\n");
157 MiiStationWrite(RTL8201_CNTL_REG, RTL8201_ADDR,
159 RTL8201_CNTL_RSTRT_AN);
162 unsigned PhyStatus(void)
165 unsigned r = 0, count=0;
167 debug2_printf("Wait\n");
169 // Wait for auto negotiation to get completed
172 Status = MiiStationRead(RTL8201_STATUS_REG,RTL8201_ADDR);
173 CYGACC_CALL_IF_DELAY_US(10000);
176 while (!(Status&RTL8201_STATUS_AN_COMLETE) && count<500);
177 //If it takes longer then 5 sec stop waiting
179 debug2_printf("Wait finished\n");
181 debug1_printf("PhyStatus is ");
182 Status = MiiStationRead(RTL8201_STATUS_REG,RTL8201_ADDR);
183 if (Status & RTL8201_STATUS_LINKUP)
185 r |= PhyStatus_LinkUp;
186 debug1_printf("LINK ");
188 Status = MiiStationRead(RTL8201_CNTL_REG,RTL8201_ADDR);
189 if (Status & RTL8201_CNTL_FULL_DUP)
191 r |= PhyStatus_FullDuplex;
192 debug1_printf("FDX ");
194 Status = MiiStationRead(RTL8201_TEST_REG,RTL8201_ADDR);
195 if (Status & RTL8201_TEST_LINK_100)
197 r |= PhyStatus_100Mb;
198 debug1_printf("100MBit ");
200 else if (r & PhyStatus_LinkUp)
201 debug2_printf("10MBit ");
202 debug1_printf("(0x%x)\n",r);
207 void PhyInterruptAck(void)