]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/arm/ks32c5000/v2_0/src/rtl8201.c
Initial revision
[karo-tx-redboot.git] / packages / devs / eth / arm / ks32c5000 / v2_0 / src / rtl8201.c
1 //==========================================================================
2 //
3 //      rtl8201.c
4 //
5 //      Driver for RTL8201 PHY
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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.
35 //
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####
42 //
43 // Author(s):    gthomas
44 // Contributoris: rcassebohm, gthomas, jskov
45 //               Grant Edwards <grante@visi.com>
46 // Date:         2001-07-31
47 // Purpose:
48 // Description:
49 //
50 //####DESCRIPTIONEND####
51 //
52
53 #include <pkgconf/system.h>
54 #include <pkgconf/hal.h>
55 #include <cyg/hal/hal_if.h>
56
57 #include <pkgconf/devs_eth_arm_ks32c5000.h>
58
59 #include <cyg/infra/diag.h>
60
61 #include "std.h"
62 #include "phy.h"
63
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)
67 #else
68 #define debug1_printf(args...) /* noop */
69 #endif
70 #if CYGPKG_DEVS_ETH_ARM_KS32C5000_DEBUG_LEVEL > 1
71 #define debug2_printf(args...) diag_printf(args)
72 #else
73 #define debug2_printf(args...) /* noop */
74 #endif
75
76 // address of the RTL8201 phy
77 #ifdef CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
78 #define RTL8201_ADDR  CYGPKG_DEVS_ETH_ARM_KS32C5000_PHYADDR
79 #else
80 #error no Phy addr set
81 #endif
82
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
101
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
110
111 #define Bit(n) (1<<(n))
112
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)
120
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)
128
129 #define RTL8201_TEST_LINK_10   Bit(1)
130 #define RTL8201_TEST_LINK_100  Bit(0)
131 #define RTL8201_TEST_PHY_ADR   (0x1f<<8)
132
133 void PhyReset(void)
134 {
135     static int init_done=0;
136     unsigned Status;
137
138     if (init_done)
139         return;
140
141     init_done=1;
142
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);
147
148     // initialize auto-negotiation capabilities
149     MiiStationWrite(RTL8201_ANA_REG,RTL8201_ADDR, 
150                     RTL8201_ANA_100TX_FULL+
151                     RTL8201_ANA_100TX+
152                     RTL8201_ANA_10T_FULL+
153                     RTL8201_ANA_10T+
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, 
158                     RTL8201_CNTL_AN+
159                     RTL8201_CNTL_RSTRT_AN);
160 }
161
162 unsigned PhyStatus(void)
163 {
164     unsigned Status;
165     unsigned r = 0, count=0;
166
167     debug2_printf("Wait\n");
168
169     // Wait for auto negotiation to get completed
170     do
171     {
172         Status = MiiStationRead(RTL8201_STATUS_REG,RTL8201_ADDR);
173         CYGACC_CALL_IF_DELAY_US(10000);
174         count++;
175     }
176     while (!(Status&RTL8201_STATUS_AN_COMLETE) && count<500);
177     //If it takes longer then 5 sec stop waiting
178    
179     debug2_printf("Wait finished\n");
180
181     debug1_printf("PhyStatus is ");
182     Status = MiiStationRead(RTL8201_STATUS_REG,RTL8201_ADDR);
183     if (Status & RTL8201_STATUS_LINKUP)
184     {
185         r |= PhyStatus_LinkUp;
186         debug1_printf("LINK ");
187     }
188     Status = MiiStationRead(RTL8201_CNTL_REG,RTL8201_ADDR);
189     if (Status & RTL8201_CNTL_FULL_DUP)
190     {
191         r |= PhyStatus_FullDuplex;
192         debug1_printf("FDX ");
193     }
194     Status = MiiStationRead(RTL8201_TEST_REG,RTL8201_ADDR);
195     if (Status & RTL8201_TEST_LINK_100)
196     {
197         r |=  PhyStatus_100Mb;
198         debug1_printf("100MBit ");
199     }
200     else if (r & PhyStatus_LinkUp)
201         debug2_printf("10MBit ");
202     debug1_printf("(0x%x)\n",r);
203
204     return r;
205 }
206
207 void PhyInterruptAck(void)
208 {
209 }