source: uKadecot/trunk/uip/target/if_rx62n/ether_phy.c@ 101

Last change on this file since 101 was 101, checked in by coas-nagasima, 8 years ago

TOPPERS/uKadecotのソースコードを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/plain
File size: 10.4 KB
Line 
1/*
2 * TINET (TCP/IP Protocol Stack)
3 *
4 * Copyright (C) 2001-2009 by Dep. of Computer Science and Engineering
5 * Tomakomai National College of Technology, JAPAN
6 * Copyright (C) 2014 Cores Co., Ltd. Japan
7 *
8 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
9 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
10 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
11 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
12 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
13 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
14 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
15 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
16ƒƒ“ƒgi—˜—p
17 * ŽÒƒ}ƒjƒ…
18ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
19 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
20 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
21 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
22 * ‚ƁD
23 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
24ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
25ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
26 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
27 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
28 * •ñ‚·‚邱‚ƁD
29 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
30 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
31 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
32 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
33 * –Ɛӂ·‚邱‚ƁD
34 *
35 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
36 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
37 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
38 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
39 * ‚̐ӔC‚𕉂í‚È‚¢D
40 *
41 * @(#) $Id: ether_phy.c 101 2015-06-02 15:37:23Z coas-nagasima $
42 */
43
44#include "ether_phy.h"
45#include <kernel.h>
46#include "uip.h"
47#include <sil.h>
48
49#define PHY_CONTROL_REGISTER 0x00
50
51#define PHY_CONTROL_RESET 0x8000
52#define PHY_CONTROL_LOOPBACK 0x4000
53#define PHY_CONTROL_SPEED_SELECT 0x2000
54#define PHY_CONTROL_A_N_ENABLE 0x1000
55#define PHY_CONTROL_POWER_DOWN 0x0800
56#define PHY_CONTROL_ISOLATE 0x0400
57#define PHY_CONTROL_RESTART_A_N 0x0200
58#define PHY_CONTROL_DUPLEX_MODE 0x0100
59#define PHY_CONTROL_COLLISION_TEST 0x0080
60
61#define PHY_STATUS_REGISTER 0x01
62
63#define PHY_STATUS_100BASE_T4 0x8000
64#define PHY_STATUS_100BASE_TX_FULL_DUPLEX 0x4000
65#define PHY_STATUS_100BASE_TX_HALF_DUPLEX 0x2000
66#define PHY_STATUS_10BASE_T_FULL_DUPLEX 0x1000
67#define PHY_STATUS_10BASE_T_HALF_DUPLEX 0x0800
68#define PHY_STATUS_A_N_COMPLETE 0x0020
69#define PHY_STATUS_REMOTE_FAULT 0x0010
70#define PHY_STATUS_A_N_ABILITY 0x0008
71#define PHY_STATUS_LINK_STATUS 0x0004
72#define PHY_STATUS_JABBER_DETECT 0x0002
73#define PHY_STATUS_EXTENDED_CAPABILITY 0x0001
74
75#define PHY_AN_ADVERTISEMENT_REGISTER 0x04
76
77#define PHY_AN_AD_100BASE_T4 0x0200
78#define PHY_AN_AD_100BASE_TX_FULL_DUPLEX 0x0100
79#define PHY_AN_AD_100BASE_TX_HALF_DUPLEX 0x0080
80#define PHY_AN_AD_10BASE_T_FULL_DUPLEX 0x0040
81#define PHY_AN_AD_10BASE_T_HALF_DUPLEX 0x0020
82#define PHY_AN_AD_SELECTOR_FIELD 0x0001
83
84#define PHY_AN_STATUS_REGISTER 0x05
85
86#define PHY_AN_STATUS_100BASE_T4 0x0200
87#define PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX 0x0100
88#define PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX 0x0080
89#define PHY_AN_STATUS_10BASE_T_FULL_DUPLEX 0x0040
90#define PHY_AN_STATUS_10BASE_T_HALF_DUPLEX 0x0020
91
92static void phy_write_bit(bool_t bit);
93static void phy_release_bus();
94static bool_t phy_read_bit();
95static void phy_single_rel_bus();
96
97PHY_STATE_T phy_reset(PHY_STATE_T state, uint8_t phy_addr)
98{
99 switch(state){
100 case PHY_STATE_UNINIT:
101 /* PHY‚̃ŠƒZƒbƒg */
102 phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_RESET);
103
104 /* 500ms‘Ò‚Â */
105 /* tslp_tsk(500); •s—vH */
106 /* continue; */
107 case PHY_STATE_RESETING:
108 /* ƒŠƒZƒbƒgŠ®—¹‚ÌŠm”F */
109 if((phy_read_reg(phy_addr, PHY_CONTROL_REGISTER) & PHY_CONTROL_RESET) != 0)
110 return PHY_STATE_RESETING;
111
112 return PHY_STATE_RESET;
113 default:
114 return state;
115 }
116}
117
118PHY_STATE_T phy_initialize(PHY_STATE_T state, uint8_t phy_addr, PHY_MODE_T *mode)
119{
120#ifndef __RX
121 static int reset = 0;
122#endif
123 uint16_t status;
124 *mode = (PHY_MODE_T)0;
125
126 switch(state){
127 case PHY_STATE_RESET:
128#ifndef __RX
129 reset++;
130 if(reset < 2){
131#endif
132 /* ƒŠƒ“ƒNŠ®—¹‚ÌŠm”F */
133 if(!phy_is_link(phy_addr))
134 return PHY_STATE_RESET;
135#ifndef __RX
136 }
137 reset = 0;
138#endif
139 /* ƒI[ƒgƒlƒSƒVƒG[ƒVƒ‡ƒ“‚Ì‚¨’m‚点‚ð—LŒø‚ɐݒè */
140 phy_write_reg(phy_addr, PHY_AN_ADVERTISEMENT_REGISTER,
141 PHY_AN_AD_100BASE_T4 | PHY_AN_AD_100BASE_TX_FULL_DUPLEX | PHY_AN_AD_100BASE_TX_HALF_DUPLEX
142 | PHY_AN_AD_10BASE_T_FULL_DUPLEX | PHY_AN_AD_10BASE_T_HALF_DUPLEX | PHY_AN_AD_SELECTOR_FIELD);
143
144 /* ƒI[ƒgƒlƒSƒVƒG[ƒVƒ‡ƒ“‚ð—LŒø‚ɐݒè */
145 phy_write_reg(phy_addr, PHY_CONTROL_REGISTER, PHY_CONTROL_SPEED_SELECT | PHY_CONTROL_A_N_ENABLE);
146
147 /* continue; */
148 case PHY_STATE_LINKED:
149#ifndef __RX
150 reset++;
151 if(reset < 2){
152#endif
153 /* ƒI[ƒgƒlƒSƒVƒG[ƒVƒ‡ƒ“Š®—¹‚ÌŠm”F */
154 if((phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_A_N_COMPLETE) == 0)
155 return PHY_STATE_LINKED;
156#ifndef __RX
157 }
158#endif
159 status = phy_read_reg(phy_addr, PHY_AN_STATUS_REGISTER);
160
161 if ((status & (PHY_AN_STATUS_100BASE_T4 | PHY_AN_STATUS_10BASE_T_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX)) != 0)
162 *mode = (PHY_MODE_T)(((int)*mode) | 0x01);
163
164 if ((status & (PHY_AN_STATUS_100BASE_T4 | PHY_AN_STATUS_100BASE_TX_FULL_DUPLEX | PHY_AN_STATUS_100BASE_TX_HALF_DUPLEX)) != 0)
165 *mode = (PHY_MODE_T)(((int)*mode) | 0x02);
166
167 return PHY_STATE_NEGOTIATED;
168 }
169
170 return state;
171}
172
173bool_t phy_is_link(uint8_t phy_addr)
174{
175#ifdef __RX
176 /* ƒŠƒ“ƒN‚ÌŠm”F */
177 return (phy_read_reg(phy_addr, PHY_STATUS_REGISTER) & PHY_STATUS_LINK_STATUS) != 0;
178#else
179 return true;
180#endif
181}
182
183uint16_t phy_read_reg(uint8_t phy_addr, uint8_t reg_addr)
184{
185 uint16_t result = 0, bit;
186 int i;
187
188 /* PRE F32ŒÂ‚̘A‘±‚µ‚½1b */
189 for (i = 0; i < 32; i++)
190 phy_write_bit(true);
191
192 /* ST FƒtƒŒ[ƒ€‚̐擪‚ðŽ¦‚·01b‚̃‰ƒCƒg */
193 phy_write_bit(false);
194 phy_write_bit(true);
195
196 /* OP FƒAƒNƒZƒXŽí•Ê‚ðŽ¦‚·ƒR[ƒh‚̃‰ƒCƒg */
197 phy_write_bit(true);
198 phy_write_bit(false);
199
200 /* PHYAD FPHY-LSI‚̃AƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB ‚©‚珇ŽŸƒ‰ƒCƒgjB */
201 phy_write_bit((phy_addr & 0x10) != 0);
202 phy_write_bit((phy_addr & 0x08) != 0);
203 phy_write_bit((phy_addr & 0x04) != 0);
204 phy_write_bit((phy_addr & 0x02) != 0);
205 phy_write_bit((phy_addr & 0x01) != 0);
206
207 /* REGAD FƒŒƒWƒXƒ^ƒAƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB‚©‚珇ŽŸƒ‰ƒCƒgjB */
208 phy_write_bit((reg_addr & 0x10) != 0);
209 phy_write_bit((reg_addr & 0x08) != 0);
210 phy_write_bit((reg_addr & 0x04) != 0);
211 phy_write_bit((reg_addr & 0x02) != 0);
212 phy_write_bit((reg_addr & 0x01) != 0);
213
214 /* TA FMII/RMIIƒCƒ“ƒ^ƒtƒF[ƒXã‚Ńf[ƒ^‚Ì‘—MŒ³‚ðØ‚è‘Ö‚¦‚鎞ŠÔ */
215 /* uƒoƒX‰ð•úviZ0‚Æ•\‹Lj‚ðs‚¤ */
216 phy_release_bus();
217
218 /* DATA F16ƒrƒbƒg‚̃f[ƒ^BMSB‚©‚珇ŽŸƒŠ[ƒh */
219 for (bit = 0x8000; bit != 0; bit >>= 1) {
220 if(phy_read_bit())
221 result |= bit;
222 }
223
224 /* IDLE FŽŸ‚ÌMIIŠÇ—ƒtƒH[ƒ}ƒbƒg“ü—Í‚Ü‚Å‚Ì‘Ò‹@ŽžŠÔ */
225 /* ‚·‚Å‚ÉTAŽž‚ɃoƒX‰ð•úÏ‚Ý‚Å‚ ‚萧Œä•s—v */
226 phy_release_bus();
227
228 return result;
229}
230
231void phy_write_reg(uint8_t phy_addr, uint8_t reg_addr, uint16_t reg_data)
232{
233 int i;
234 uint16_t bit;
235
236 /* PRE F32ŒÂ‚̘A‘±‚µ‚½1b */
237 for (i = 0; i < 32; i++)
238 phy_write_bit(true);
239
240 /* ST FƒtƒŒ[ƒ€‚̐擪‚ðŽ¦‚·01b‚̃‰ƒCƒg */
241 phy_write_bit(false);
242 phy_write_bit(true);
243
244 /* OP FƒAƒNƒZƒXŽí•Ê‚ðŽ¦‚·ƒR[ƒh‚̃‰ƒCƒg */
245 phy_write_bit(false);
246 phy_write_bit(true);
247
248 /* PHYAD FPHY-LSI‚̃AƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB ‚©‚珇ŽŸƒ‰ƒCƒgjB */
249 phy_write_bit((phy_addr & 0x10) != 0);
250 phy_write_bit((phy_addr & 0x08) != 0);
251 phy_write_bit((phy_addr & 0x04) != 0);
252 phy_write_bit((phy_addr & 0x02) != 0);
253 phy_write_bit((phy_addr & 0x01) != 0);
254
255 /* REGAD FƒŒƒWƒXƒ^ƒAƒhƒŒƒX‚ª1”Ԃ̏ꍇA00001b‚ðƒ‰ƒCƒgiMSB‚©‚珇ŽŸƒ‰ƒCƒgjB */
256 phy_write_bit((reg_addr & 0x10) != 0);
257 phy_write_bit((reg_addr & 0x08) != 0);
258 phy_write_bit((reg_addr & 0x04) != 0);
259 phy_write_bit((reg_addr & 0x02) != 0);
260 phy_write_bit((reg_addr & 0x01) != 0);
261
262 /* TA FMII/RMIIƒCƒ“ƒ^ƒtƒF[ƒXã‚Ńf[ƒ^‚Ì‘—MŒ³‚ðØ‚è‘Ö‚¦‚鎞ŠÔ */
263 /* 10b‚ðƒ‰ƒCƒg */
264 phy_write_bit(true);
265 phy_write_bit(false);
266
267 /* DATA F16ƒrƒbƒg‚̃f[ƒ^BMSB‚©‚珇ŽŸƒ‰ƒCƒg */
268 for (bit = 0x8000; bit != 0; bit >>= 1) {
269 phy_write_bit((reg_data & bit) != 0);
270 }
271
272 /* IDLE FŽŸ‚ÌMIIŠÇ—ƒtƒH[ƒ}ƒbƒg“ü—Í‚Ü‚Å‚Ì‘Ò‹@ŽžŠÔ */
273 /* u’P“ƃoƒX‰ð•úviX‚Æ•\‹Lj‚ðs‚¤ */
274 phy_single_rel_bus();
275}
276
277#define ETHERC_PIR_WAIT 4
278
279/*
280 * 1 ƒrƒbƒgƒf[ƒ^‚̃‰ƒCƒg
281 */
282static void phy_write_bit(bool_t bit)
283{
284 int i;
285 uint32_t data = bit ? ETHERC_PIR_MDO : 0;
286
287 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
288 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
289
290 for(i = ETHERC_PIR_WAIT; i > 0; i--);
291
292 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
293 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | ETHERC_PIR_MDC);
294
295 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
296
297 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
298 sil_wrw_mem(ETHERC_PIR, data | ETHERC_PIR_MMD | 0/*ETHERC_PIR_MDC*/);
299
300 for(i = ETHERC_PIR_WAIT; i > 0; i--);
301}
302
303/*
304 * ƒoƒX‰ð•ú
305 */
306static void phy_release_bus()
307{
308 int i;
309
310 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
311 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
312
313 for(i = ETHERC_PIR_WAIT; i > 0; i--);
314
315 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
316 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
317
318 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
319
320 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
321 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
322
323 for(i = ETHERC_PIR_WAIT; i > 0; i--);
324}
325
326/*
327 * 1 ƒrƒbƒgƒf[ƒ^‚̃Š[ƒh
328 */
329static bool_t phy_read_bit()
330{
331 bool_t bit;
332 int i;
333
334 for(i = ETHERC_PIR_WAIT; i > 0; i--);
335
336 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
337 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | ETHERC_PIR_MDC);
338
339 for(i = ETHERC_PIR_WAIT; i > 0; i--);
340
341 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
342 bit = (sil_rew_mem(ETHERC_PIR) & ETHERC_PIR_MDI) != 0;
343
344 for(i = ETHERC_PIR_WAIT; i > 0; i--);
345
346 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
347 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
348
349 for(i = ETHERC_PIR_WAIT; i > 0; i--);
350
351 return bit;
352}
353
354/*
355 * ’P“ƃoƒX‰ð•ú
356 */
357static void phy_single_rel_bus()
358{
359 int i;
360
361 for(i = ETHERC_PIR_WAIT; i > 0; i--);
362
363 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
364 sil_wrw_mem(ETHERC_PIR, ETHERC_PIR_MMD | ETHERC_PIR_MDC);
365
366 for(i = 2 * ETHERC_PIR_WAIT; i > 0; i--);
367
368 /* PHY•”ƒCƒ“ƒ^ƒtƒF[ƒXƒŒƒWƒXƒ^‚ւ̃‰ƒCƒg */
369 sil_wrw_mem(ETHERC_PIR, 0/*ETHERC_PIR_MMD*/ | 0/*ETHERC_PIR_MDC*/);
370
371 for(i = ETHERC_PIR_WAIT; i > 0; i--);
372}
Note: See TracBrowser for help on using the repository browser.