xref: /openbmc/u-boot/cmd/aspeed/nettest/phy.c (revision 67bb2848)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) ASPEED Technology Inc.
4  */
5 
6 #define PHY_C
7 //#define PHY_DEBUG
8 //#define PHY_DEBUG_SET_CLR
9 
10 #ifdef PHY_DEBUG
11 #undef DbgPrn_PHYRW
12 #define DbgPrn_PHYRW		1
13 #endif
14 
15 #ifdef PHY_DEBUG_SET_CLR
16 #undef DbgPrn_PHYRW
17 #define DbgPrn_PHYRW		1
18 #endif
19 
20 
21 #include "comminf.h"
22 #include "swfunc.h"
23 
24 #include <command.h>
25 #include <common.h>
26 
27 #include "phy.h"
28 
29 #include "phy_tbl.h"
30 #include "mem_io.h"
31 
32 //#define RTK_DEBUG
33 #define RTK_DBG_GPIO		BIT(22)
34 #ifdef RTK_DEBUG
35 #define RTK_DBG_PRINTF		printf
36 #else
37 #define RTK_DBG_PRINTF(...)
38 #endif
39 
40 static void rtk_dbg_gpio_set(void)
41 {
42 #ifdef RTK_DEBUG
43 	GPIO_WR(GPIO_RD(0x20) | RTK_DBG_GPIO, 0x20);
44 #endif
45 }
46 
47 static void rtk_dbg_gpio_clr(void)
48 {
49 #ifdef RTK_DEBUG
50 	GPIO_WR(GPIO_RD(0x20) & ~RTK_DBG_GPIO, 0x20);
51 #endif
52 }
53 
54 static void rtk_dbg_gpio_init(void)
55 {
56 #ifdef RTK_DEBUG
57 	GPIO_WR(GPIO_RD(0x24) | RTK_DBG_GPIO, 0x24);
58 
59 	rtk_dbg_gpio_set();
60 #endif
61 }
62 
63 //------------------------------------------------------------
64 // PHY R/W basic
65 //------------------------------------------------------------
66 void phy_write (MAC_ENGINE *eng, int index, uint32_t data)
67 {
68 	u32 wr_data;
69 	int timeout = 0;
70 
71 	if (eng->env.is_new_mdio_reg[eng->run.mdio_idx]) {
72 		wr_data = MDIO_WR_CODE | MDIO_SET_WR_DATA(data) |
73 			  MDIO_SET_PHY_ADDR(eng->phy.Adr) |
74 			  MDIO_SET_REG_ADDR(index);
75 		writel(wr_data, eng->run.mdio_base);
76 		/* check time-out */
77 		while (readl(eng->run.mdio_base) & MDIO_FIRE_BUSY) {
78 			if (++timeout > TIME_OUT_PHY_RW) {
79 				if (!eng->run.tm_tx_only)
80 					PRINTF(FP_LOG,
81 					       "[PHY-Write] Time out: %08x\n",
82 					       readl(eng->run.mdio_base));
83 
84 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
85 				break;
86 			}
87 		}
88 	} else {
89 		writel(data, eng->run.mdio_base + 0x4);
90 		writel(MDC_CYC_THLD | MDIO_WR_CODE_OLD |
91 			       MDIO_SET_PHY_ADDR_OLD(eng->phy.Adr) |
92 			       MDIO_SET_REG_ADDR_OLD(index),
93 		       eng->run.mdio_base);
94 
95 		while (readl(eng->run.mdio_base) & MDIO_WR_CODE_OLD) {
96 			if (++timeout > TIME_OUT_PHY_RW) {
97 				if (!eng->run.tm_tx_only)
98 					PRINTF(FP_LOG,
99 					       "[PHY-Write] Time out: %08x\n",
100 					       readl(eng->run.mdio_base));
101 
102 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
103 				break;
104 			}
105 		}
106 	} // End if (eng->env.new_mdio_reg)
107 
108 	if (DbgPrn_PHYRW) {
109 		printf("[Wr ]%02d: 0x%04x (%02d:%08x)\n", index, data,
110 		       eng->phy.Adr, eng->run.mdio_base);
111 		if (!eng->run.tm_tx_only)
112 			PRINTF(FP_LOG, "[Wr ]%02d: 0x%04x (%02d:%08x)\n", index,
113 			       data, eng->phy.Adr, eng->run.mdio_base);
114 	}
115 
116 } // End void phy_write (int adr, uint32_t data)
117 
118 //------------------------------------------------------------
119 uint16_t phy_read (MAC_ENGINE *eng, int index)
120 {
121 	uint32_t read_value;
122 	int timeout = 0;
123 
124 	if (index > 0x1f) {
125 		printf("invalid PHY register index: 0x%02x\n", index);
126 		FindErr(eng, Err_Flag_PHY_TimeOut_RW);
127 		return 0;
128 	}
129 
130 	if (eng->env.is_new_mdio_reg[eng->run.mdio_idx]) {
131 		writel(MDIO_RD_CODE | MDIO_SET_PHY_ADDR(eng->phy.Adr) |
132 			       MDIO_SET_REG_ADDR(index),
133 		       eng->run.mdio_base);
134 
135 		while (readl(eng->run.mdio_base) & MDIO_FIRE_BUSY) {
136 			if (++timeout > TIME_OUT_PHY_RW) {
137 				if (!eng->run.tm_tx_only)
138 					PRINTF(FP_LOG,
139 					       "[PHY-Read] Time out: %08x\n",
140 					       readl(eng->run.mdio_base));
141 
142 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
143 				break;
144 			}
145 		}
146 
147 #ifdef Delay_PHYRd
148 		DELAY(Delay_PHYRd);
149 #endif
150 		read_value = readl(eng->run.mdio_base + 0x4) & GENMASK(15, 0);
151 	} else {
152 		writel(MDC_CYC_THLD | MDIO_RD_CODE_OLD |
153 			       MDIO_SET_PHY_ADDR_OLD(eng->phy.Adr) |
154 			       MDIO_SET_REG_ADDR_OLD(index),
155 		       eng->run.mdio_base);
156 
157 		while (readl(eng->run.mdio_base) & MDIO_RD_CODE_OLD) {
158 			if (++timeout > TIME_OUT_PHY_RW) {
159 				if (!eng->run.tm_tx_only)
160 					PRINTF(FP_LOG,
161 					       "[PHY-Read] Time out: %08x\n",
162 					       readl(eng->run.mdio_base));
163 
164 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
165 				break;
166 			}
167 		}
168 
169 #ifdef Delay_PHYRd
170 		DELAY(Delay_PHYRd);
171 #endif
172 		read_value = readl(eng->run.mdio_base + 0x4) >> 16;
173 	}
174 
175 
176 	if (DbgPrn_PHYRW) {
177 		printf("[Rd ]%02d: 0x%04x (%02d:%08x)\n", index, read_value,
178 		       eng->phy.Adr, eng->run.mdio_base);
179 		if (!eng->run.tm_tx_only)
180 			PRINTF(FP_LOG, "[Rd ]%02d: 0x%04x (%02d:%08x)\n", index,
181 			       read_value, eng->phy.Adr, eng->run.mdio_base);
182 	}
183 
184 	return (read_value);
185 } // End uint16_t phy_read (MAC_ENGINE *eng, int adr)
186 
187 //------------------------------------------------------------
188 void phy_clrset(MAC_ENGINE *eng, int adr, uint32_t clr_mask, uint32_t set_mask)
189 {
190 	if (DbgPrn_PHYRW) {
191 		printf("[RW ]%02d: clr:0x%04x: set:0x%04x (%02d:%08x)\n", adr,
192 		       clr_mask, set_mask, eng->phy.Adr, eng->run.mdio_base);
193 		if (!eng->run.tm_tx_only)
194 			PRINTF(FP_LOG,
195 			       "[RW ]%02d: clr:0x%04x: set:0x%04x (%02d:%08x)\n",
196 			       adr, clr_mask, set_mask, eng->phy.Adr,
197 			       eng->run.mdio_base);
198 	}
199 	phy_write(eng, adr, ((phy_read(eng, adr) & (~clr_mask)) | set_mask));
200 }
201 
202 //------------------------------------------------------------
203 void phy_dump(MAC_ENGINE *eng)
204 {
205 	int index;
206 
207 	printf("[PHY%d][%d]----------------\n", eng->run.mac_idx + 1,
208 	       eng->phy.Adr);
209 	for (index = 0; index < 32; index++) {
210 		printf("%02d: %04x ", index, phy_read(eng, index));
211 
212 		if ((index % 8) == 7)
213 			printf("\n");
214 	}
215 }
216 
217 //------------------------------------------------------------
218 static void phy_scan_id(MAC_ENGINE *eng, uint8_t option)
219 {
220 	int8_t phy_addr_orig;
221 
222 	phy_addr_orig = eng->phy.Adr;
223 	for (eng->phy.Adr = 0; eng->phy.Adr < 32; eng->phy.Adr++) {
224 		PRINTF(option, "[%02d] ", eng->phy.Adr);
225 		PRINTF(option, "%d:%04x ", 2, phy_read(eng, 2));
226 		PRINTF(option, "%d:%04x ", 3, phy_read(eng, 3));
227 
228 		if ((eng->phy.Adr % 4) == 3)
229 			PRINTF(option, "\n");
230 	}
231 	eng->phy.Adr = phy_addr_orig;
232 }
233 
234 //------------------------------------------------------------
235 void phy_delay (int dt)
236 {
237 	rtk_dbg_gpio_clr();
238 
239 #ifdef PHY_DEBUG
240         printf("delay %d ms\n", dt);
241 #endif
242         DELAY(dt);
243 	rtk_dbg_gpio_set();
244 }
245 
246 //------------------------------------------------------------
247 // PHY IC basic
248 //------------------------------------------------------------
249 void phy_basic_setting(MAC_ENGINE *eng)
250 {
251 	uint32_t clr = GENMASK(14, 10) | BIT(6);
252 
253 	phy_clrset(eng, 0, clr, eng->phy.PHY_00h);
254 	if (DbgPrn_PHYRW) {
255 		printf("[Set]00: 0x%04x (%02d:%08x)\n",
256 		       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
257 		       eng->run.mdio_base);
258 		if (!eng->run.tm_tx_only)
259 			PRINTF(FP_LOG, "[Set]00: 0x%04x (%02d:%08x)\n",
260 			       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
261 			       eng->run.mdio_base);
262 	}
263 }
264 
265 //------------------------------------------------------------
266 void phy_wait_reset_done(MAC_ENGINE *eng)
267 {
268 	int timeout = 0;
269 
270 	while (phy_read(eng, PHY_REG_BMCR) & 0x8000) {
271 		if (++timeout > TIME_OUT_PHY_Rst) {
272 			if (!eng->run.tm_tx_only)
273 				PRINTF(FP_LOG, "[PHY-Reset] Time out: %08x\n",
274 				       readl(eng->run.mdio_base));
275 
276 			FindErr(eng, Err_Flag_PHY_TimeOut_Rst);
277 			break;
278 		}
279 	} //wait Rst Done
280 
281 	if (DbgPrn_PHYRW) {
282 		printf("[Clr]00: 0x%04x (%02d:%08x)\n",
283 		       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
284 		       eng->run.mdio_base);
285 		if (!eng->run.tm_tx_only)
286 			PRINTF(FP_LOG, "[Clr]00: 0x%04x (%02d:%08x)\n",
287 			       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
288 			       eng->run.mdio_base);
289 	}
290 #ifdef Delay_PHYRst
291 	DELAY(Delay_PHYRst);
292 #endif
293 }
294 
295 //------------------------------------------------------------
296 static void phy_reset(MAC_ENGINE *eng)
297 {
298 	phy_basic_setting(eng);
299 
300 	//phy_clrset(eng, 0, 0x0000, 0x8000 | eng->phy.PHY_00h);
301 	phy_clrset(eng, 0, 0x7140, 0x8000 | eng->phy.PHY_00h);
302 	//phy_write(eng, 0, 0x8000); //clr set//Rst PHY
303 	phy_wait_reset_done(eng);
304 
305 	phy_basic_setting(eng);
306 #ifdef Delay_PHYRst
307 	DELAY(Delay_PHYRst);
308 #endif
309 }
310 
311 //------------------------------------------------------------
312 void phy_check_register (MAC_ENGINE *eng, uint32_t adr, uint32_t check_mask, uint32_t check_value, uint32_t hit_number, char *runname) {
313         uint16_t     wait_phy_ready = 0;
314         uint16_t     hit_count = 0;
315 
316         while ( wait_phy_ready < 1000 ) {
317                 if ( (phy_read( eng, adr ) & check_mask) == check_value ) {
318                         if ( ++hit_count >= hit_number ) {
319                                 break;
320                         }
321                         else {
322                                 phy_delay(1);
323                         }
324                 } else {
325                         hit_count = 0;
326                         wait_phy_ready++;
327                         phy_delay(10);
328                 }
329         }
330         if ( hit_count < hit_number ) {
331                 printf("Timeout: %s\n", runname);
332         }
333 }
334 
335 //------------------------------------------------------------
336 // PHY IC
337 //------------------------------------------------------------
338 void recov_phy_marvell (MAC_ENGINE *eng) {//88E1111
339         if ( eng->run.tm_tx_only ) {
340         }
341         else if ( eng->phy.loopback ) {
342         }
343         else {
344 		if (eng->run.speed_sel[0]) {
345 			phy_write(eng, 9, eng->phy.PHY_09h);
346 
347 			phy_reset(eng);
348 
349 			phy_write(eng, 29, 0x0007);
350 			phy_clrset(eng, 30, 0x0008, 0x0000); //clr set
351 			phy_write(eng, 29, 0x0010);
352 			phy_clrset(eng, 30, 0x0002, 0x0000); //clr set
353 			phy_write(eng, 29, 0x0012);
354 			phy_clrset(eng, 30, 0x0001, 0x0000); //clr set
355 
356 			phy_write(eng, 18, eng->phy.PHY_12h);
357 		}
358 	}
359 }
360 
361 //------------------------------------------------------------
362 void phy_marvell (MAC_ENGINE *eng)
363 {//88E1111
364         if ( eng->run.tm_tx_only ) {
365                 phy_reset( eng );
366         }
367         else if ( eng->phy.loopback ) {
368                 phy_reset( eng );
369         }
370         else {
371                 if ( eng->run.speed_sel[ 0 ] ) {
372                         eng->phy.PHY_09h = phy_read( eng, PHY_GBCR );
373                         eng->phy.PHY_12h = phy_read( eng, PHY_INER );
374                         phy_write( eng, 18, 0x0000 );
375                         phy_clrset( eng,  9, 0x0000, 0x1800 );//clr set
376                 }
377 
378                 phy_reset( eng );
379 
380                 if ( eng->run.speed_sel[ 0 ] ) {
381                         phy_write( eng, 29, 0x0007 );
382                         phy_clrset( eng, 30, 0x0000, 0x0008 );//clr set
383                         phy_write( eng, 29, 0x0010 );
384                         phy_clrset( eng, 30, 0x0000, 0x0002 );//clr set
385                         phy_write( eng, 29, 0x0012 );
386                         phy_clrset( eng, 30, 0x0000, 0x0001 );//clr set
387                 }
388         }
389 
390         if ( !eng->phy.loopback )
391                 phy_check_register ( eng, 17, 0x0400, 0x0400, 1, "wait 88E1111 link-up");
392 //      Retry = 0;
393 //      do {
394 //              eng->phy.PHY_11h = phy_read( eng, PHY_SR );
395 //      } while ( !( ( eng->phy.PHY_11h & 0x0400 ) | eng->phy.loopback | ( Retry++ > 20 ) ) );
396 }
397 
398 //------------------------------------------------------------
399 void recov_phy_marvell0 (MAC_ENGINE *eng) {//88E1310
400         if ( eng->run.tm_tx_only ) {
401         }
402         else if ( eng->phy.loopback ) {
403         }
404         else {
405                 if ( eng->run.speed_sel[ 0 ] ) {
406                         phy_write( eng, 22, 0x0006 );
407                         phy_clrset( eng, 16, 0x0020, 0x0000 );//clr set
408                         phy_write( eng, 22, 0x0000 );
409                 }
410         }
411 }
412 
413 //------------------------------------------------------------
414 void phy_marvell0 (MAC_ENGINE *eng) {//88E1310
415 //      int        Retry;
416 
417         phy_write( eng, 22, 0x0002 );
418 
419         eng->phy.PHY_15h = phy_read( eng, 21 );
420         if ( eng->phy.PHY_15h & 0x0030 ) {
421                 printf("\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15_2:%04x]\n\n", eng->phy.PHY_15h);
422                 if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15_2:%04x]\n\n", eng->phy.PHY_15h );
423                 if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15_2:%04x]\n\n", eng->phy.PHY_15h );
424 
425                 phy_write( eng, 21, eng->phy.PHY_15h & 0xffcf ); // Set [5]Rx Dly, [4]Tx Dly to 0
426         }
427 phy_read( eng, 21 ); // v069
428         phy_write( eng, 22, 0x0000 );
429 
430         if ( eng->run.tm_tx_only ) {
431                 phy_reset( eng );
432         }
433         else if ( eng->phy.loopback ) {
434                 phy_write( eng, 22, 0x0002 );
435 
436                 if ( eng->run.speed_sel[ 0 ] ) {
437                         phy_clrset( eng, 21, 0x6040, 0x0040 );//clr set
438                 }
439                 else if ( eng->run.speed_sel[ 1 ] ) {
440                         phy_clrset( eng, 21, 0x6040, 0x2000 );//clr set
441                 }
442                 else {
443                         phy_clrset( eng, 21, 0x6040, 0x0000 );//clr set
444                 }
445                 phy_write( eng, 22, 0x0000 );
446                 phy_reset(  eng  );
447         }
448         else {
449                 if ( eng->run.speed_sel[ 0 ] ) {
450                         phy_write( eng, 22, 0x0006 );
451                         phy_clrset( eng, 16, 0x0000, 0x0020 );//clr set
452 phy_read( eng, 16 ); // v069
453                         phy_write( eng, 22, 0x0000 );
454                 }
455 
456                 phy_reset( eng );
457 phy_read( eng, 0 ); // v069
458         }
459 
460         if ( !eng->phy.loopback )
461                 phy_check_register ( eng, 17, 0x0400, 0x0400, 1, "wait 88E1310 link-up");
462 //      Retry = 0;
463 //      do {
464 //              eng->phy.PHY_11h = phy_read( eng, PHY_SR );
465 //      } while ( !( ( eng->phy.PHY_11h & 0x0400 ) | eng->phy.loopback | ( Retry++ > 20 ) ) );
466 }
467 
468 //------------------------------------------------------------
469 void recov_phy_marvell1 (MAC_ENGINE *eng) {//88E6176
470         int8_t       phy_addr_org;
471 
472         phy_addr_org = eng->phy.Adr;
473         for ( eng->phy.Adr = 16; eng->phy.Adr <= 22; eng->phy.Adr++ ) {
474                 if ( eng->run.tm_tx_only ) {
475                 }
476                 else {
477                         phy_write( eng,  6, eng->phy.PHY_06hA[eng->phy.Adr-16] );//06h[5]P5 loopback, 06h[6]P6 loopback
478                 }
479         }
480         for ( eng->phy.Adr = 21; eng->phy.Adr <= 22; eng->phy.Adr++ ) {
481                 phy_write( eng,  1, 0x0003 ); //01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
482         }
483         eng->phy.Adr = phy_addr_org;
484 }
485 
486 //------------------------------------------------------------
487 void phy_marvell1 (MAC_ENGINE *eng) {//88E6176
488 //      uint32_t      PHY_01h;
489         int8_t       phy_addr_org;
490 
491         if ( eng->run.tm_tx_only ) {
492                 printf("This mode doesn't support in 88E6176.\n");
493         } else {
494                 //The 88E6176 is switch with 7 Port(P0~P6) and the PHYAdr will be fixed at 0x10~0x16, and only P5/P6 can be connected to the MAC.
495                 //Therefor, the 88E6176 only can run the internal loopback.
496                 phy_addr_org = eng->phy.Adr;
497                 for ( eng->phy.Adr = 16; eng->phy.Adr <= 20; eng->phy.Adr++ ) {
498                         eng->phy.PHY_06hA[eng->phy.Adr-16] = phy_read( eng, PHY_ANER );
499                         phy_write( eng,  6, 0x0000 );//06h[5]P5 loopback, 06h[6]P6 loopback
500                 }
501 
502                 for ( eng->phy.Adr = 21; eng->phy.Adr <= 22; eng->phy.Adr++ ) {
503 //                      PHY_01h = phy_read( eng, PHY_REG_BMSR );
504 //                      if      ( eng->run.speed_sel[ 0 ] ) phy_write( eng,  1, (PHY_01h & 0xfffc) | 0x0002 );//[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
505 //                      else if ( eng->run.speed_sel[ 1 ] ) phy_write( eng,  1, (PHY_01h & 0xfffc) | 0x0001 );//[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
506 //                      else                              phy_write( eng,  1, (PHY_01h & 0xfffc)          );//[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
507                         if      ( eng->run.speed_sel[ 0 ] ) phy_write( eng,  1, 0x0002 );//01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
508                         else if ( eng->run.speed_sel[ 1 ] ) phy_write( eng,  1, 0x0001 );//01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
509                         else                                phy_write( eng,  1, 0x0000 );//01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
510 
511                         eng->phy.PHY_06hA[eng->phy.Adr-16] = phy_read( eng, PHY_ANER );
512                         if ( eng->phy.Adr == 21 ) phy_write( eng,  6, 0x0020 );//06h[5]P5 loopback, 06h[6]P6 loopback
513                         else                      phy_write( eng,  6, 0x0040 );//06h[5]P5 loopback, 06h[6]P6 loopback
514                 }
515                 eng->phy.Adr = phy_addr_org;
516         }
517 }
518 
519 //------------------------------------------------------------
520 void recov_phy_marvell2 (MAC_ENGINE *eng) {//88E1512//88E15 10/12/14/18
521         if ( eng->run.tm_tx_only ) {
522         }
523         else if ( eng->phy.loopback ) {
524         }
525         else {
526                 if ( eng->run.speed_sel[ 0 ] ) {
527                         // Enable Stub Test
528                         // switch page 6
529                         phy_write( eng, 22, 0x0006 );
530                         phy_clrset( eng, 18, 0x0008, 0x0000 );//clr set
531                         phy_write( eng, 22, 0x0000 );
532                 }
533         }
534 }
535 
536 //------------------------------------------------------------
537 //88E1512//88E15 10/12/14/18
538 void phy_marvell2 (MAC_ENGINE *eng)
539 {
540 	/* switch to page 2 */
541 	phy_write(eng, 22, 0x0002);
542 	eng->phy.PHY_15h = phy_read(eng, 21);
543 	eng->phy.PHY_15h &= ~GENMASK(5, 4);
544 	if (eng->arg.ctrl.b.phy_tx_delay_en)
545 		eng->phy.PHY_15h |= BIT(4);
546 	if (eng->arg.ctrl.b.phy_rx_delay_en)
547 		eng->phy.PHY_15h |= BIT(5);
548 
549 	phy_write(eng, 21, eng->phy.PHY_15h);
550 
551 	/* switch to page 0 */
552 	phy_write(eng, 22, 0x0000);
553 
554         if ( eng->run.tm_tx_only ) {
555                 phy_reset( eng );
556         }
557         else if ( eng->phy.loopback ) {
558                 // Internal loopback funciton only support in copper mode
559                 // switch page 18
560                 phy_write( eng, 22, 0x0012 );
561                 eng->phy.PHY_14h = phy_read( eng, 20 );
562                 // Change mode to Copper mode
563 //              if ( eng->phy.PHY_14h & 0x0020 ) {
564                 if ( ( eng->phy.PHY_14h & 0x003f ) != 0x0010 ) {
565                         printf("\n\n[Warning] Internal loopback funciton only support in copper mode[%04x]\n\n", eng->phy.PHY_14h);
566                         if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Internal loopback funciton only support in copper mode[%04x]\n\n", eng->phy.PHY_14h);
567                         if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Internal loopback funciton only support in copper mode[%04x]\n\n", eng->phy.PHY_14h);
568 
569                         phy_write( eng, 20, ( eng->phy.PHY_14h & 0xffc0 ) | 0x8010 );
570                         // do software reset
571                         phy_check_register ( eng, 20, 0x8000, 0x0000, 1, "wait 88E15 10/12/14/18 mode reset");
572 //                      do {
573 //                              temp_reg = phy_read( eng, 20 );
574 //                      } while ( ( (temp_reg & 0x8000) == 0x8000 ) & (Retry++ < 20) );
575                 }
576 
577                 // switch page 2
578                 phy_write( eng, 22, 0x0002 );
579                 if ( eng->run.speed_sel[ 0 ] ) {
580                         phy_clrset( eng, 21, 0x2040, 0x0040 );//clr set
581                 }
582                 else if ( eng->run.speed_sel[ 1 ] ) {
583                         phy_clrset( eng, 21, 0x2040, 0x2000 );//clr set
584                 }
585                 else {
586                         phy_clrset( eng, 21, 0x2040, 0x0000 );//clr set
587                 }
588                 phy_write( eng, 22, 0x0000 );
589 
590                 phy_reset( eng );
591 
592                 //Internal loopback at 100Mbps need delay 400~500 ms
593 //              DELAY( 400 );//Still fail at 100Mbps
594 //              DELAY( 500 );//All Pass
595                 if ( !eng->run.speed_sel[ 0 ] ) {
596                         phy_check_register ( eng, 17, 0x0040, 0x0040, 10, "wait 88E15 10/12/14/18 link-up");
597                         phy_check_register ( eng, 17, 0x0040, 0x0000, 10, "wait 88E15 10/12/14/18 link-up");
598                         phy_check_register ( eng, 17, 0x0040, 0x0040, 10, "wait 88E15 10/12/14/18 link-up");
599                 }
600         }
601         else {
602                 if ( eng->run.speed_sel[ 0 ] ) {
603                         // Enable Stub Test
604                         // switch page 6
605                         phy_write( eng, 22, 0x0006 );
606                         phy_clrset( eng, 18, 0x0000, 0x0008 );//clr set
607                         phy_write( eng, 22, 0x0000 );
608                 }
609 
610                 phy_reset( eng );
611                 phy_check_register ( eng, 17, 0x0400, 0x0400, 10, "wait 88E15 10/12/14/18 link-up");
612         }
613 
614 //      if ( !eng->phy.loopback )
615 ////    if ( !eng->run.tm_tx_only )
616 //              phy_check_register ( eng, 17, 0x0400, 0x0400, 10, "wait 88E15 10/12/14/18 link-up");
617 ////    Retry = 0;
618 ////    do {
619 ////            eng->phy.PHY_11h = phy_read( eng, PHY_SR );
620 ////    } while ( !( ( eng->phy.PHY_11h & 0x0400 ) | eng->phy.loopback | ( Retry++ > 20 ) ) );
621 }
622 
623 //------------------------------------------------------------
624 void phy_marvell3 (MAC_ENGINE *eng)
625 {//88E3019
626 
627         //Reg1ch[11:10]: MAC Interface Mode
628         // 00 => RGMII where receive clock trnasitions when data transitions
629         // 01 => RGMII where receive clock trnasitions when data is stable
630         // 10 => RMII
631         // 11 => MII
632         eng->phy.PHY_1ch = phy_read( eng, 28 );
633         if (eng->run.is_rgmii) {
634                 if ( ( eng->phy.PHY_1ch & 0x0c00 ) != 0x0000 ) {
635                         printf("\n\n[Warning] Register 28, bit 10~11 must be 0 (RGMIIRX Edge-align Mode)[Reg1ch:%04x]\n\n", eng->phy.PHY_1ch);
636                         eng->phy.PHY_1ch = ( eng->phy.PHY_1ch & 0xf3ff ) | 0x0000;
637                         phy_write( eng, 28, eng->phy.PHY_1ch );
638                 }
639         } else {
640                 if ( ( eng->phy.PHY_1ch & 0x0c00 ) != 0x0800 ) {
641                         printf("\n\n[Warning] Register 28, bit 10~11 must be 2 (RMII Mode)[Reg1ch:%04x]\n\n", eng->phy.PHY_1ch);
642                         eng->phy.PHY_1ch = ( eng->phy.PHY_1ch & 0xf3ff ) | 0x0800;
643                         phy_write( eng, 28, eng->phy.PHY_1ch );
644                 }
645         }
646 
647         if ( eng->run.tm_tx_only ) {
648                 phy_reset( eng );
649         }
650         else if ( eng->phy.loopback ) {
651                 phy_reset( eng );
652         }
653         else {
654                 phy_reset( eng );
655         }
656 
657         phy_check_register ( eng, 17, 0x0400, 0x0400, 1, "wait 88E3019 link-up");
658 }
659 
660 //------------------------------------------------------------
661 void phy_broadcom (MAC_ENGINE *eng)
662 {//BCM5221
663 	uint32_t      reg;
664 
665         phy_reset( eng );
666 
667         if ( eng->run.TM_IEEE ) {
668                 if ( eng->run.ieee_sel == 0 ) {
669                         phy_write( eng, 25, 0x1f01 );//Force MDI  //Measuring from channel A
670                 }
671                 else {
672                         phy_clrset( eng, 24, 0x0000, 0x4000 );//clr set//Force Link
673 //                      phy_write( eng,  0, eng->phy.PHY_00h );
674 //                      phy_write( eng, 30, 0x1000 );
675                 }
676         }
677         else
678         {
679                 // we can check link status from register 0x18
680                 if ( eng->run.speed_sel[ 1 ] ) {
681                         do {
682                                 reg = phy_read( eng, 0x18 ) & 0xF;
683                         } while ( reg != 0x7 );
684                 }
685                 else {
686                         do {
687                         reg = phy_read( eng, 0x18 ) & 0xF;
688                         } while ( reg != 0x1 );
689                 }
690         }
691 }
692 
693 //------------------------------------------------------------
694 void recov_phy_broadcom0 (MAC_ENGINE *eng) {//BCM54612
695         phy_write( eng,  0, eng->phy.PHY_00h );
696         phy_write( eng,  9, eng->phy.PHY_09h );
697 //      phy_write( eng, 24, eng->phy.PHY_18h | 0xf007 );//write reg 18h, shadow value 111
698 //      phy_write( eng, 28, eng->phy.PHY_1ch | 0x8c00 );//write reg 1Ch, shadow value 00011
699 
700         if ( eng->run.tm_tx_only ) {
701         }
702         else if ( eng->phy.loopback ) {
703                 phy_write( eng,  0, eng->phy.PHY_00h );
704         }
705         else {
706         }
707 }
708 
709 //------------------------------------------------------------
710 //internal loop 1G  : no  loopback stub
711 //internal loop 100M: Don't support(?)
712 //internal loop 10M : Don't support(?)
713 void phy_broadcom0 (MAC_ENGINE *eng)
714 {
715 	uint32_t PHY_new;
716 
717 	phy_reset(eng);
718 
719         eng->phy.PHY_00h = phy_read( eng, PHY_REG_BMCR );
720         eng->phy.PHY_09h = phy_read( eng, PHY_GBCR );
721 
722 	phy_write( eng, 0, eng->phy.PHY_00h & ~BIT(10));
723 
724 	/*
725 	 * RX interface delay: reg 0x18, shadow value b'0111: misc control
726 	 * bit[8] RGMII RXD to RXC skew
727 	 */
728 	phy_write(eng, 0x18, (0x7 << 12) | 0x7);
729 	eng->phy.PHY_18h = phy_read(eng, 0x18);
730 	PHY_new = eng->phy.PHY_18h & ~((0x7 << 12) | 0x7 | BIT(8));
731 	PHY_new |= (0x7 << 12) | 0x7 | BIT(15);
732 	if (eng->arg.ctrl.b.phy_rx_delay_en)
733 		PHY_new |= BIT(8);
734 	phy_write(eng, 0x18, PHY_new);
735 
736 	/*
737 	 * TX interface delay: reg 0x1c, shadow value b'0011: clock alignment
738 	 * control
739 	 * bit[9] GTXCLK clock delay enable
740 	 */
741 	phy_write(eng, 0x1c, 0x3 << 10);
742 	eng->phy.PHY_1ch = phy_read(eng, 0x1c);
743 	PHY_new = eng->phy.PHY_1ch & ~((0x1f << 10) | BIT(9));
744 	PHY_new |= (0x3 << 10) | BIT(15);
745 	if (eng->arg.ctrl.b.phy_tx_delay_en)
746 		PHY_new |= BIT(9);
747 	phy_write(eng, 0x1c, PHY_new);
748 
749         if ( eng->run.tm_tx_only ) {
750                 phy_basic_setting(eng);
751         } else if (eng->phy.loopback) {
752 		phy_basic_setting(eng);
753 		/* reg1E[12]: force-link */
754 		if (strncmp((char *)eng->phy.phy_name, "BCM5421x", strlen("BCM5421x")) == 0)
755 			phy_write(eng, 0x1e, BIT(12));
756 	} else {
757 		if (eng->run.speed_sel[0]) {
758 			phy_write(eng, 0x9, 0x1800);
759 			phy_write(eng, 0x0, 0x0140);
760 			phy_write(eng, 0x18, 0x8400);
761 		} else if (eng->run.speed_sel[1]) {
762 			phy_write(eng, 0x0, 0x2100);
763 			phy_write(eng, 0x18, 0x8400);
764 		} else {
765 			phy_write(eng, 0x0, 0x0100);
766 			phy_write(eng, 0x18, 0x8400);
767 		}
768 	}
769 	mdelay(100);
770 }
771 
772 //------------------------------------------------------------
773 void phy_realtek (MAC_ENGINE *eng)
774 {//RTL8201N
775 
776         phy_reset( eng );
777 }
778 
779 //------------------------------------------------------------
780 //internal loop 100M: Don't support
781 //internal loop 10M : no  loopback stub
782 void phy_realtek0 (MAC_ENGINE *eng)
783 {//RTL8201E
784 
785         eng->phy.RMIICK_IOMode |= PHY_Flag_RMIICK_IOMode_RTL8201E;
786 
787         phy_reset( eng );
788 
789         eng->phy.PHY_19h = phy_read( eng, 25 );
790         //Check RMII Mode
791         if ( ( eng->phy.PHY_19h & 0x0400 ) == 0x0 ) {
792                 phy_write( eng, 25, eng->phy.PHY_19h | 0x0400 );
793                 printf("\n\n[Warning] Register 25, bit 10 must be 1 [Reg19h:%04x]\n\n", eng->phy.PHY_19h);
794                 if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Register 25, bit 10 must be 1 [Reg19h:%04x]\n\n", eng->phy.PHY_19h );
795                 if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Register 25, bit 10 must be 1 [Reg19h:%04x]\n\n", eng->phy.PHY_19h );
796         }
797         //Check TXC Input/Output Direction
798         if ( eng->arg.ctrl.b.rmii_phy_in == 0 ) {
799                 if ( ( eng->phy.PHY_19h & 0x0800 ) == 0x0800 ) {
800                         phy_write( eng, 25, eng->phy.PHY_19h & 0xf7ff );
801                         printf("\n\n[Warning] Register 25, bit 11 must be 0 (TXC should be output mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h);
802                         if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Register 25, bit 11 must be 0 (TXC should be output mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h );
803                         if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Register 25, bit 11 must be 0 (TXC should be output mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h );
804                 }
805         } else {
806                 if ( ( eng->phy.PHY_19h & 0x0800 ) == 0x0000 ) {
807                         phy_write( eng, 25, eng->phy.PHY_19h | 0x0800 );
808                         printf("\n\n[Warning] Register 25, bit 11 must be 1 (TXC should be input mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h);
809                         if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Register 25, bit 11 must be 1 (TXC should be input mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h );
810                         if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Register 25, bit 11 must be 1 (TXC should be input mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h );
811                 }
812         }
813 
814         if ( eng->run.TM_IEEE ) {
815                 phy_write( eng, 31, 0x0001 );
816                 if ( eng->run.ieee_sel == 0 ) {
817                         phy_write( eng, 25, 0x1f01 );//Force MDI  //Measuring from channel A
818                 }
819                 else {
820                         phy_write( eng, 25, 0x1f00 );//Force MDIX //Measuring from channel B
821                 }
822                 phy_write( eng, 31, 0x0000 );
823         }
824 }
825 
826 //------------------------------------------------------------
827 void recov_phy_realtek1 (MAC_ENGINE *eng) {//RTL8211D
828         if ( eng->run.tm_tx_only ) {
829                 if ( eng->run.TM_IEEE ) {
830                         if ( eng->run.speed_sel[ 0 ] ) {
831                                 if ( eng->run.ieee_sel == 0 ) {//Test Mode 1
832                                         //Rev 1.2
833                                         phy_write( eng, 31, 0x0002 );
834                                         phy_write( eng,  2, 0xc203 );
835                                         phy_write( eng, 31, 0x0000 );
836                                         phy_write( eng,  9, 0x0000 );
837                                 }
838                                 else {//Test Mode 4
839                                         //Rev 1.2
840                                         phy_write( eng, 31, 0x0000 );
841                                         phy_write( eng,  9, 0x0000 );
842                                 }
843                         }
844                         else if ( eng->run.speed_sel[ 1 ] ) {
845                                 //Rev 1.2
846                                 phy_write( eng, 23, 0x2100 );
847                                 phy_write( eng, 16, 0x016e );
848                         }
849                         else {
850                                 //Rev 1.2
851                                 phy_write( eng, 31, 0x0006 );
852                                 phy_write( eng,  0, 0x5a00 );
853                                 phy_write( eng, 31, 0x0000 );
854                         }
855                 } else {
856                         phy_reset( eng );
857                 } // End if ( eng->run.TM_IEEE )
858         }
859         else if ( eng->phy.loopback ) {
860                 if ( eng->run.speed_sel[ 0 ] ) {
861                         phy_write( eng, 31, 0x0000 ); // new in Rev. 1.6
862                         phy_write( eng,  0, 0x1140 ); // new in Rev. 1.6
863                         phy_write( eng, 20, 0x8040 ); // new in Rev. 1.6
864                 }
865         }
866         else {
867                 if ( eng->run.speed_sel[ 0 ] ) {
868                         phy_write( eng, 31, 0x0001 );
869                         phy_write( eng,  3, 0xdf41 );
870                         phy_write( eng,  2, 0xdf20 );
871                         phy_write( eng,  1, 0x0140 );
872                         phy_write( eng,  0, 0x00bb );
873                         phy_write( eng,  4, 0xb800 );
874                         phy_write( eng,  4, 0xb000 );
875 
876                         phy_write( eng, 31, 0x0000 );
877 //                      phy_write( eng, 26, 0x0020 ); // Rev. 1.2
878                         phy_write( eng, 26, 0x0040 ); // new in Rev. 1.6
879                         phy_write( eng,  0, 0x1140 );
880 //                      phy_write( eng, 21, 0x0006 ); // Rev. 1.2
881                         phy_write( eng, 21, 0x1006 ); // new in Rev. 1.6
882                         phy_write( eng, 23, 0x2100 );
883 //              }
884 //              else if ( eng->run.speed_sel[ 1 ] ) {//option
885 //                      phy_write( eng, 31, 0x0000 );
886 //                      phy_write( eng,  9, 0x0200 );
887 //                      phy_write( eng,  0, 0x1200 );
888 //              }
889 //              else if ( eng->run.speed_sel[ 2 ] ) {//option
890 //                      phy_write( eng, 31, 0x0000 );
891 //                      phy_write( eng,  9, 0x0200 );
892 //                      phy_write( eng,  4, 0x05e1 );
893 //                      phy_write( eng,  0, 0x1200 );
894                 }
895                 phy_reset( eng );
896                 phy_delay(2000);
897         } // End if ( eng->run.tm_tx_only )
898 } // End void recov_phy_realtek1 (MAC_ENGINE *eng)
899 
900 //------------------------------------------------------------
901 //internal loop 1G  : no  loopback stub
902 //internal loop 100M: no  loopback stub
903 //internal loop 10M : no  loopback stub
904 void phy_realtek1 (MAC_ENGINE *eng)
905 {//RTL8211D
906 
907         if ( eng->run.tm_tx_only ) {
908                 if ( eng->run.TM_IEEE ) {
909                         if ( eng->run.speed_sel[ 0 ] ) {
910                                 if ( eng->run.ieee_sel == 0 ) {//Test Mode 1
911                                         //Rev 1.2
912                                         phy_write( eng, 31, 0x0002 );
913                                         phy_write( eng,  2, 0xc22b );
914                                         phy_write( eng, 31, 0x0000 );
915                                         phy_write( eng,  9, 0x2000 );
916                                 }
917                                 else {//Test Mode 4
918                                         //Rev 1.2
919                                         phy_write( eng, 31, 0x0000 );
920                                         phy_write( eng,  9, 0x8000 );
921                                 }
922                         }
923                         else if ( eng->run.speed_sel[ 1 ] ) {
924                                 if ( eng->run.ieee_sel == 0 ) {//From Channel A
925                                         //Rev 1.2
926                                         phy_write( eng, 23, 0xa102 );
927                                         phy_write( eng, 16, 0x01ae );//MDI
928                                 }
929                                 else {//From Channel B
930                                         //Rev 1.2
931                                         phy_clrset( eng, 17, 0x0008, 0x0000 ); // clr set
932                                         phy_write( eng, 23, 0xa102 );         // MDI
933                                         phy_write( eng, 16, 0x010e );
934                                 }
935                         }
936                         else {
937                                 if ( eng->run.ieee_sel == 0 ) {//Diff. Voltage/TP-IDL/Jitter: Pseudo-random pattern
938                                         phy_write( eng, 31, 0x0006 );
939                                         phy_write( eng,  0, 0x5a21 );
940                                         phy_write( eng, 31, 0x0000 );
941                                 }
942                                 else if ( eng->run.ieee_sel == 1 ) {//Harmonic: pattern
943                                         phy_write( eng, 31, 0x0006 );
944                                         phy_write( eng,  2, 0x05ee );
945                                         phy_write( eng,  0, 0xff21 );
946                                         phy_write( eng, 31, 0x0000 );
947                                 }
948                                 else {//Harmonic: �00� pattern
949                                         phy_write( eng, 31, 0x0006 );
950                                         phy_write( eng,  2, 0x05ee );
951                                         phy_write( eng,  0, 0x0021 );
952                                         phy_write( eng, 31, 0x0000 );
953                                 }
954                         }
955                 }
956                 else {
957                         phy_reset( eng );
958                 }
959         }
960         else if ( eng->phy.loopback ) {
961                 phy_reset( eng );
962 
963                 if ( eng->run.speed_sel[ 0 ] ) {
964                         phy_write( eng, 20, 0x0042 );//new in Rev. 1.6
965                 }
966         }
967         else {
968         // refer to RTL8211D Register for Manufacture Test_V1.6.pdf
969         // MDI loop back
970                 if ( eng->run.speed_sel[ 0 ] ) {
971                         phy_write( eng, 31, 0x0001 );
972                         phy_write( eng,  3, 0xff41 );
973                         phy_write( eng,  2, 0xd720 );
974                         phy_write( eng,  1, 0x0140 );
975                         phy_write( eng,  0, 0x00bb );
976                         phy_write( eng,  4, 0xb800 );
977                         phy_write( eng,  4, 0xb000 );
978 
979                         phy_write( eng, 31, 0x0007 );
980                         phy_write( eng, 30, 0x0040 );
981                         phy_write( eng, 24, 0x0008 );
982 
983                         phy_write( eng, 31, 0x0000 );
984                         phy_write( eng,  9, 0x0300 );
985                         phy_write( eng, 26, 0x0020 );
986                         phy_write( eng,  0, 0x0140 );
987                         phy_write( eng, 23, 0xa101 );
988                         phy_write( eng, 21, 0x0200 );
989                         phy_write( eng, 23, 0xa121 );
990                         phy_write( eng, 23, 0xa161 );
991                         phy_write( eng,  0, 0x8000 );
992                         phy_wait_reset_done( eng );
993 
994 //                      phy_delay(200); // new in Rev. 1.6
995                         phy_delay(5000); // 20150504
996 //              }
997 //              else if ( eng->run.speed_sel[ 1 ] ) {//option
998 //                      phy_write( eng, 31, 0x0000 );
999 //                      phy_write( eng,  9, 0x0000 );
1000 //                      phy_write( eng,  4, 0x0061 );
1001 //                      phy_write( eng,  0, 0x1200 );
1002 //                      phy_delay(5000);
1003 //              }
1004 //              else if ( eng->run.speed_sel[ 2 ] ) {//option
1005 //                      phy_write( eng, 31, 0x0000 );
1006 //                      phy_write( eng,  9, 0x0000 );
1007 //                      phy_write( eng,  4, 0x05e1 );
1008 //                      phy_write( eng,  0, 0x1200 );
1009 //                      phy_delay(5000);
1010                 }
1011                 else {
1012                         phy_reset( eng );
1013                 }
1014         }
1015 } // End void phy_realtek1 (MAC_ENGINE *eng)
1016 
1017 //------------------------------------------------------------
1018 void recov_phy_realtek2 (MAC_ENGINE *eng)
1019 {
1020 	RTK_DBG_PRINTF("\nClear RTL8211E [Start] =====>\n");
1021 
1022         if ( eng->run.tm_tx_only ) {
1023                 if ( eng->run.TM_IEEE ) {
1024                         if ( eng->run.speed_sel[ 0 ] ) {
1025                                 //Rev 1.2
1026                                 phy_write( eng, 31, 0x0000 );
1027                                 phy_write( eng,  9, 0x0000 );
1028                         }
1029                         else if ( eng->run.speed_sel[ 1 ] ) {
1030                                 //Rev 1.2
1031                                 phy_write( eng, 31, 0x0007 );
1032                                 phy_write( eng, 30, 0x002f );
1033                                 phy_write( eng, 23, 0xd88f );
1034                                 phy_write( eng, 30, 0x002d );
1035                                 phy_write( eng, 24, 0xf050 );
1036                                 phy_write( eng, 31, 0x0000 );
1037                                 phy_write( eng, 16, 0x006e );
1038                         }
1039                         else {
1040                                 //Rev 1.2
1041                                 phy_write( eng, 31, 0x0006 );
1042                                 phy_write( eng,  0, 0x5a00 );
1043                                 phy_write( eng, 31, 0x0000 );
1044                         }
1045                         //Rev 1.2
1046                         phy_write( eng, 31, 0x0005 );
1047                         phy_write( eng,  5, 0x8b86 );
1048                         phy_write( eng,  6, 0xe201 );
1049                         phy_write( eng, 31, 0x0007 );
1050                         phy_write( eng, 30, 0x0020 );
1051                         phy_write( eng, 21, 0x1108 );
1052                         phy_write( eng, 31, 0x0000 );
1053                 }
1054                 else {
1055                 }
1056         }
1057         else if ( eng->phy.loopback ) {
1058         }
1059         else {
1060                 if ( eng->run.speed_sel[ 0 ] ) {
1061                         //Rev 1.6
1062                         phy_write( eng, 31, 0x0000 );
1063                         phy_write( eng,  0, 0x8000 );
1064 #ifdef RTK_DEBUG
1065 #else
1066                         phy_wait_reset_done( eng );
1067                         phy_delay(30);
1068 #endif
1069 
1070                         phy_write( eng, 31, 0x0007 );
1071                         phy_write( eng, 30, 0x0042 );
1072                         phy_write( eng, 21, 0x0500 );
1073                         phy_write( eng, 31, 0x0000 );
1074                         phy_write( eng,  0, 0x1140 );
1075                         phy_write( eng, 26, 0x0040 );
1076                         phy_write( eng, 31, 0x0007 );
1077                         phy_write( eng, 30, 0x002f );
1078                         phy_write( eng, 23, 0xd88f );
1079                         phy_write( eng, 30, 0x0023 );
1080                         phy_write( eng, 22, 0x0300 );
1081                         phy_write( eng, 31, 0x0000 );
1082                         phy_write( eng, 21, 0x1006 );
1083                         phy_write( eng, 23, 0x2100 );
1084                 }
1085 //              else if ( eng->run.speed_sel[ 1 ] ) {//option
1086 //                      phy_write( eng, 31, 0x0000 );
1087 //                      phy_write( eng,  9, 0x0200 );
1088 //                      phy_write( eng,  0, 0x1200 );
1089 //              }
1090 //              else if ( eng->run.speed_sel[ 2 ] ) {//option
1091 //                      phy_write( eng, 31, 0x0000 );
1092 //                      phy_write( eng,  9, 0x0200 );
1093 //                      phy_write( eng,  4, 0x05e1 );
1094 //                      phy_write( eng,  0, 0x1200 );
1095 //              }
1096                 else {
1097                         phy_write( eng, 31, 0x0000 );
1098                         phy_write( eng,  0, 0x1140 );
1099                 }
1100 #ifdef RTK_DEBUG
1101 #else
1102                 // Check register 0x11 bit10 Link OK or not OK
1103                 phy_check_register ( eng, 17, 0x0c02, 0x0000, 10, "clear RTL8211E");
1104 #endif
1105         }
1106 
1107 	RTK_DBG_PRINTF("\nClear RTL8211E [End] =====>\n");
1108 } // End void recov_phy_realtek2 (MAC_ENGINE *eng)
1109 
1110 //------------------------------------------------------------
1111 //internal loop 1G  : no  loopback stub
1112 //internal loop 100M: no  loopback stub
1113 //internal loop 10M : no  loopback stub
1114 // for RTL8211E
1115 void phy_realtek2 (MAC_ENGINE *eng)
1116 {
1117         uint16_t     check_value;
1118 
1119 	RTK_DBG_PRINTF("\nSet RTL8211E [Start] =====>\n");
1120 
1121 	rtk_dbg_gpio_init();
1122 
1123 #ifdef RTK_DEBUG
1124 #else
1125         phy_write( eng, 31, 0x0000 );
1126         phy_clrset( eng,  0, 0x0000, 0x8000 | eng->phy.PHY_00h ); // clr set // Rst PHY
1127         phy_wait_reset_done( eng );
1128         phy_delay(30);
1129 #endif
1130 
1131         if ( eng->run.tm_tx_only ) {
1132                 if ( eng->run.TM_IEEE ) {
1133                         //Rev 1.2
1134                         phy_write( eng, 31, 0x0005 );
1135                         phy_write( eng,  5, 0x8b86 );
1136                         phy_write( eng,  6, 0xe200 );
1137                         phy_write( eng, 31, 0x0007 );
1138                         phy_write( eng, 30, 0x0020 );
1139                         phy_write( eng, 21, 0x0108 );
1140                         phy_write( eng, 31, 0x0000 );
1141 
1142                         if ( eng->run.speed_sel[ 0 ] ) {
1143                                 //Rev 1.2
1144                                 phy_write( eng, 31, 0x0000 );
1145 
1146                                 if ( eng->run.ieee_sel == 0 ) {
1147                                         phy_write( eng,  9, 0x2000 );//Test Mode 1
1148                                 }
1149                                 else {
1150                                         phy_write( eng,  9, 0x8000 );//Test Mode 4
1151                                 }
1152                         }
1153                         else if ( eng->run.speed_sel[ 1 ] ) {
1154                                 //Rev 1.2
1155                                 phy_write( eng, 31, 0x0007 );
1156                                 phy_write( eng, 30, 0x002f );
1157                                 phy_write( eng, 23, 0xd818 );
1158                                 phy_write( eng, 30, 0x002d );
1159                                 phy_write( eng, 24, 0xf060 );
1160                                 phy_write( eng, 31, 0x0000 );
1161 
1162                                 if ( eng->run.ieee_sel == 0 ) {
1163                                         phy_write( eng, 16, 0x00ae );//From Channel A
1164                                 }
1165                                 else {
1166                                         phy_write( eng, 16, 0x008e );//From Channel B
1167                                 }
1168                         }
1169                         else {
1170                                 //Rev 1.2
1171                                 phy_write( eng, 31, 0x0006 );
1172                                 if ( eng->run.ieee_sel == 0 ) {//Diff. Voltage/TP-IDL/Jitter
1173                                         phy_write( eng,  0, 0x5a21 );
1174                                 }
1175                                 else if ( eng->run.ieee_sel == 1 ) {//Harmonic: �FF� pattern
1176                                         phy_write( eng,  2, 0x05ee );
1177                                         phy_write( eng,  0, 0xff21 );
1178                                 }
1179                                 else {//Harmonic: �00� pattern
1180                                         phy_write( eng,  2, 0x05ee );
1181                                         phy_write( eng,  0, 0x0021 );
1182                                 }
1183                                 phy_write( eng, 31, 0x0000 );
1184                         }
1185                 }
1186                 else {
1187                         phy_basic_setting( eng );
1188                         phy_delay(30);
1189                 }
1190         }
1191         else if ( eng->phy.loopback ) {
1192 #ifdef RTK_DEBUG
1193                 phy_write( eng,  0, 0x0000 );
1194                 phy_write( eng,  0, 0x8000 );
1195                 phy_delay(60);
1196                 phy_write( eng,  0, eng->phy.PHY_00h );
1197                 phy_delay(60);
1198 #else
1199                 phy_basic_setting( eng );
1200 
1201                 phy_clrset( eng,  0, 0x0000, 0x8000 | eng->phy.PHY_00h );//clr set//Rst PHY
1202                 phy_wait_reset_done( eng );
1203                 phy_delay(30);
1204 
1205                 phy_basic_setting( eng );
1206                 phy_delay(30);
1207 #endif
1208         }
1209         else {
1210 #ifdef Enable_Dual_Mode
1211                 if ( eng->run.speed_sel[ 0 ] ) {
1212                         check_value = 0x0c02 | 0xa000;
1213                 }
1214                 else if ( eng->run.speed_sel[ 1 ] ) {
1215                         check_value = 0x0c02 | 0x6000;
1216                 }
1217                 else if ( eng->run.speed_sel[ 2 ] ) {
1218                         check_value = 0x0c02 | 0x2000;
1219                 }
1220 #else
1221                 if ( eng->run.speed_sel[ 0 ] ) {
1222                         check_value = 0x0c02 | 0xa000;
1223 #ifdef RTK_DEBUG
1224                         phy_write( eng, 31, 0x0000 );
1225                         phy_write( eng,  0, 0x8000 );
1226                         phy_delay(60);
1227   #endif
1228 
1229                         phy_write( eng, 31, 0x0007 );
1230                         phy_write( eng, 30, 0x0042 );
1231                         phy_write( eng, 21, 0x2500 );
1232                         phy_write( eng, 30, 0x0023 );
1233                         phy_write( eng, 22, 0x0006 );
1234                         phy_write( eng, 31, 0x0000 );
1235                         phy_write( eng,  0, 0x0140 );
1236                         phy_write( eng, 26, 0x0060 );
1237                         phy_write( eng, 31, 0x0007 );
1238                         phy_write( eng, 30, 0x002f );
1239                         phy_write( eng, 23, 0xd820 );
1240                         phy_write( eng, 31, 0x0000 );
1241                         phy_write( eng, 21, 0x0206 );
1242                         phy_write( eng, 23, 0x2120 );
1243                         phy_write( eng, 23, 0x2160 );
1244   #ifdef RTK_DEBUG
1245                         phy_delay(600);
1246   #else
1247                         phy_delay(300);
1248   #endif
1249                 }
1250 //              else if ( eng->run.speed_sel[ 1 ] ) {//option
1251 //                      check_value = 0x0c02 | 0x6000;
1252 //                      phy_write( eng, 31, 0x0000 );
1253 //                      phy_write( eng,  9, 0x0000 );
1254 //                      phy_write( eng,  4, 0x05e1 );
1255 //                      phy_write( eng,  0, 0x1200 );
1256 //                      phy_delay(6000);
1257 //              }
1258 //              else if ( eng->run.speed_sel[ 2 ] ) {//option
1259 //                      check_value = 0x0c02 | 0x2000;
1260 //                      phy_write( eng, 31, 0x0000 );
1261 //                      phy_write( eng,  9, 0x0000 );
1262 //                      phy_write( eng,  4, 0x0061 );
1263 //                      phy_write( eng,  0, 0x1200 );
1264 //                      phy_delay(6000);
1265 //              }
1266                 else {
1267                         if ( eng->run.speed_sel[ 1 ] )
1268                                 check_value = 0x0c02 | 0x6000;
1269                         else
1270                                 check_value = 0x0c02 | 0x2000;
1271                         phy_write( eng, 31, 0x0000 );
1272                         phy_write( eng,  0, eng->phy.PHY_00h );
1273   #ifdef RTK_DEBUG
1274                         phy_delay(300);
1275   #else
1276                         phy_delay(150);
1277   #endif
1278                 }
1279 #endif
1280 #ifdef RTK_DEBUG
1281 #else
1282                 // Check register 0x11 bit10 Link OK or not OK
1283                 phy_check_register ( eng, 17, 0x0c02 | 0xe000, check_value, 10, "set RTL8211E");
1284 #endif
1285         }
1286 
1287 	RTK_DBG_PRINTF("\nSet RTL8211E [End] =====>\n");
1288 } // End void phy_realtek2 (MAC_ENGINE *eng)
1289 
1290 //------------------------------------------------------------
1291 void recov_phy_realtek3 (MAC_ENGINE *eng) {//RTL8211C
1292         if ( eng->run.tm_tx_only ) {
1293                 if ( eng->run.TM_IEEE ) {
1294                         if ( eng->run.speed_sel[ 0 ] ) {
1295                                 phy_write( eng,  9, 0x0000 );
1296                         }
1297                         else if ( eng->run.speed_sel[ 1 ] ) {
1298                                 phy_write( eng, 17, eng->phy.PHY_11h );
1299                                 phy_write( eng, 14, 0x0000 );
1300                                 phy_write( eng, 16, 0x00a0 );
1301                         }
1302                         else {
1303 //                              phy_write( eng, 31, 0x0006 );
1304 //                              phy_write( eng,  0, 0x5a00 );
1305 //                              phy_write( eng, 31, 0x0000 );
1306                         }
1307                 }
1308                 else {
1309                 }
1310         }
1311         else if ( eng->phy.loopback ) {
1312                 if ( eng->run.speed_sel[ 0 ] ) {
1313                         phy_write( eng, 11, 0x0000 );
1314                 }
1315                 phy_write( eng, 12, 0x1006 );
1316         }
1317         else {
1318                 if ( eng->run.speed_sel[ 0 ] ) {
1319                         phy_write( eng, 31, 0x0001 );
1320                         phy_write( eng,  4, 0xb000 );
1321                         phy_write( eng,  3, 0xff41 );
1322                         phy_write( eng,  2, 0xdf20 );
1323                         phy_write( eng,  1, 0x0140 );
1324                         phy_write( eng,  0, 0x00bb );
1325                         phy_write( eng,  4, 0xb800 );
1326                         phy_write( eng,  4, 0xb000 );
1327 
1328                         phy_write( eng, 31, 0x0000 );
1329                         phy_write( eng, 25, 0x8c00 );
1330                         phy_write( eng, 26, 0x0040 );
1331                         phy_write( eng,  0, 0x1140 );
1332                         phy_write( eng, 14, 0x0000 );
1333                         phy_write( eng, 12, 0x1006 );
1334                         phy_write( eng, 23, 0x2109 );
1335                 }
1336         }
1337 }
1338 
1339 //------------------------------------------------------------
1340 void phy_realtek3 (MAC_ENGINE *eng)
1341 {//RTL8211C
1342 
1343         if ( eng->run.tm_tx_only ) {
1344                 if ( eng->run.TM_IEEE ) {
1345                         if ( eng->run.speed_sel[ 0 ] ) {
1346                                 if ( eng->run.ieee_sel == 0 ) {   //Test Mode 1
1347                                         phy_write( eng,  9, 0x2000 );
1348                                 }
1349                                 else if ( eng->run.ieee_sel == 1 ) {//Test Mode 2
1350                                         phy_write( eng,  9, 0x4000 );
1351                                 }
1352                                 else if ( eng->run.ieee_sel == 2 ) {//Test Mode 3
1353                                         phy_write( eng,  9, 0x6000 );
1354                                 }
1355                                 else {                           //Test Mode 4
1356                                         phy_write( eng,  9, 0x8000 );
1357                                 }
1358                         }
1359                         else if ( eng->run.speed_sel[ 1 ] ) {
1360                                 eng->phy.PHY_11h = phy_read( eng, PHY_SR );
1361                                 phy_write( eng, 17, eng->phy.PHY_11h & 0xfff7 );
1362                                 phy_write( eng, 14, 0x0660 );
1363 
1364                                 if ( eng->run.ieee_sel == 0 ) {
1365                                         phy_write( eng, 16, 0x00a0 );//MDI  //From Channel A
1366                                 }
1367                                 else {
1368                                         phy_write( eng, 16, 0x0080 );//MDIX //From Channel B
1369                                 }
1370                         }
1371                         else {
1372 //                              if ( eng->run.ieee_sel == 0 ) {//Pseudo-random pattern
1373 //                                      phy_write( eng, 31, 0x0006 );
1374 //                                      phy_write( eng,  0, 0x5a21 );
1375 //                                      phy_write( eng, 31, 0x0000 );
1376 //                              }
1377 //                              else if ( eng->run.ieee_sel == 1 ) {//�FF� pattern
1378 //                                      phy_write( eng, 31, 0x0006 );
1379 //                                      phy_write( eng,  2, 0x05ee );
1380 //                                      phy_write( eng,  0, 0xff21 );
1381 //                                      phy_write( eng, 31, 0x0000 );
1382 //                              }
1383 //                              else {//�00� pattern
1384 //                                      phy_write( eng, 31, 0x0006 );
1385 //                                      phy_write( eng,  2, 0x05ee );
1386 //                                      phy_write( eng,  0, 0x0021 );
1387 //                                      phy_write( eng, 31, 0x0000 );
1388 //                              }
1389                         }
1390                 }
1391                 else {
1392                         phy_reset( eng );
1393                 }
1394         }
1395         else if ( eng->phy.loopback ) {
1396                 phy_write( eng,  0, 0x9200 );
1397                 phy_wait_reset_done( eng );
1398                 phy_delay(30);
1399 
1400                 phy_write( eng, 17, 0x401c );
1401                 phy_write( eng, 12, 0x0006 );
1402 
1403                 if ( eng->run.speed_sel[ 0 ] ) {
1404                         phy_write( eng, 11, 0x0002 );
1405                 }
1406                 else {
1407                         phy_basic_setting( eng );
1408                 }
1409         }
1410         else {
1411                 if ( eng->run.speed_sel[ 0 ] ) {
1412                         phy_write( eng, 31, 0x0001 );
1413                         phy_write( eng,  4, 0xb000 );
1414                         phy_write( eng,  3, 0xff41 );
1415                         phy_write( eng,  2, 0xd720 );
1416                         phy_write( eng,  1, 0x0140 );
1417                         phy_write( eng,  0, 0x00bb );
1418                         phy_write( eng,  4, 0xb800 );
1419                         phy_write( eng,  4, 0xb000 );
1420 
1421                         phy_write( eng, 31, 0x0000 );
1422                         phy_write( eng, 25, 0x8400 );
1423                         phy_write( eng, 26, 0x0020 );
1424                         phy_write( eng,  0, 0x0140 );
1425                         phy_write( eng, 14, 0x0210 );
1426                         phy_write( eng, 12, 0x0200 );
1427                         phy_write( eng, 23, 0x2109 );
1428                         phy_write( eng, 23, 0x2139 );
1429                 }
1430                 else {
1431                         phy_reset( eng );
1432                 }
1433         }
1434 } // End void phy_realtek3 (MAC_ENGINE *eng)
1435 
1436 //------------------------------------------------------------
1437 //external loop 100M: OK
1438 //external loop 10M : OK
1439 //internal loop 100M: no  loopback stub
1440 //internal loop 10M : no  loopback stub
1441 void phy_realtek4 (MAC_ENGINE *eng) {//RTL8201F
1442 
1443         eng->phy.RMIICK_IOMode |= PHY_Flag_RMIICK_IOMode_RTL8201F;
1444 
1445         phy_write( eng, 31, 0x0007 );
1446         eng->phy.PHY_10h = phy_read( eng, 16 );
1447         //Check RMII Mode
1448         if ( ( eng->phy.PHY_10h & 0x0008 ) == 0x0 ) {
1449                 phy_write( eng, 16, eng->phy.PHY_10h | 0x0008 );
1450                 printf("\n\n[Warning] Page 7 Register 16, bit 3 must be 1 [Reg10h_7:%04x]\n\n", eng->phy.PHY_10h);
1451                 if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Page 7 Register 16, bit 3 must be 1 [Reg10h_7:%04x]\n\n", eng->phy.PHY_10h );
1452                 if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Page 7 Register 16, bit 3 must be 1 [Reg10h_7:%04x]\n\n", eng->phy.PHY_10h );
1453         }
1454         //Check TXC Input/Output Direction
1455         if ( eng->arg.ctrl.b.rmii_phy_in == 0 ) {
1456                 if ( ( eng->phy.PHY_10h & 0x1000 ) == 0x1000 ) {
1457                         phy_write( eng, 16, eng->phy.PHY_10h & 0xefff );
1458                         printf("\n\n[Warning] Page 7 Register 16, bit 12 must be 0 (TXC should be output mode)[Reg10h_7:%04x]\n\n", eng->phy.PHY_10h);
1459                         if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Page 7 Register 16, bit 12 must be 0 (TXC should be output mode)[Reg10h_7:%04x]\n\n", eng->phy.PHY_10h );
1460                         if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Page 7 Register 16, bit 12 must be 0 (TXC should be output mode)[Reg10h_7:%04x]\n\n", eng->phy.PHY_10h );
1461                 }
1462         } else {
1463                 if ( ( eng->phy.PHY_10h & 0x1000 ) == 0x0000 ) {
1464                         phy_write( eng, 16, eng->phy.PHY_10h | 0x1000 );
1465                         printf("\n\n[Warning] Page 7 Register 16, bit 12 must be 1 (TXC should be input mode)[Reg10h_7:%04x]\n\n", eng->phy.PHY_10h);
1466                         if ( eng->run.TM_IOTiming ) PRINTF( FP_IO, "\n\n[Warning] Page 7 Register 16, bit 12 must be 1 (TXC should be input mode)[Reg10h_7:%04x]\n\n", eng->phy.PHY_10h );
1467                         if ( !eng->run.tm_tx_only ) PRINTF( FP_LOG, "\n\n[Warning] Page 7 Register 16, bit 12 must be 1 (TXC should be input mode)[Reg10h_7:%04x]\n\n", eng->phy.PHY_10h );
1468                 }
1469         }
1470         phy_write( eng, 31, 0x0000 );
1471 
1472         if ( eng->run.tm_tx_only ) {
1473                 if ( eng->run.TM_IEEE ) {
1474                         //Rev 1.0
1475                         phy_write( eng, 31, 0x0004 );
1476                         phy_write( eng, 16, 0x4077 );
1477                         phy_write( eng, 21, 0xc5a0 );
1478                         phy_write( eng, 31, 0x0000 );
1479 
1480                         if ( eng->run.speed_sel[ 1 ] ) {
1481                                 phy_write( eng,  0, 0x8000 ); // Reset PHY
1482                                 phy_wait_reset_done( eng );
1483                                 phy_write( eng, 24, 0x0310 ); // Disable ALDPS
1484 
1485                                 if ( eng->run.ieee_sel == 0 ) {//From Channel A (RJ45 pair 1, 2)
1486                                         phy_write( eng, 28, 0x40c2 ); //Force MDI
1487                                 }
1488                                 else {//From Channel B (RJ45 pair 3, 6)
1489                                         phy_write( eng, 28, 0x40c0 ); //Force MDIX
1490                                 }
1491                                 phy_write( eng,  0, 0x2100 );       //Force 100M/Full Duplex)
1492                         } else {
1493                         }
1494                 }
1495                 else {
1496                         phy_reset( eng );
1497                 }
1498         }
1499         else if ( eng->phy.loopback ) {
1500                 // Internal loopback
1501                 if ( eng->run.speed_sel[ 1 ] ) {
1502                         // Enable 100M PCS loop back; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
1503                         phy_write( eng, 31, 0x0000 );
1504                         phy_write( eng,  0, 0x6100 );
1505                         phy_write( eng, 31, 0x0007 );
1506                         phy_write( eng, 16, 0x1FF8 );
1507                         phy_write( eng, 16, 0x0FF8 );
1508                         phy_write( eng, 31, 0x0000 );
1509                         phy_delay(20);
1510                 } else if ( eng->run.speed_sel[ 2 ] ) {
1511                         // Enable 10M PCS loop back; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
1512                         phy_write( eng, 31, 0x0000 );
1513                         phy_write( eng,  0, 0x4100 );
1514                         phy_write( eng, 31, 0x0007 );
1515                         phy_write( eng, 16, 0x1FF8 );
1516                         phy_write( eng, 16, 0x0FF8 );
1517                         phy_write( eng, 31, 0x0000 );
1518                         phy_delay(20);
1519                 }
1520         }
1521         else {
1522                 // External loopback
1523                 if ( eng->run.speed_sel[ 1 ] ) {
1524                         // Enable 100M MDI loop back Nway option; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
1525                         phy_write( eng, 31, 0x0000 );
1526                         phy_write( eng,  4, 0x01E1 );
1527                         phy_write( eng,  0, 0x1200 );
1528                 } else if ( eng->run.speed_sel[ 2 ] ) {
1529                         // Enable 10M MDI loop back Nway option; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
1530                         phy_write( eng, 31, 0x0000 );
1531                         phy_write( eng,  4, 0x0061 );
1532                         phy_write( eng,  0, 0x1200 );
1533                 }
1534 //              phy_write( eng,  0, 0x8000 );
1535 //              while ( phy_read( eng, 0 ) != 0x3100 ) {}
1536 //              while ( phy_read( eng, 0 ) != 0x3100 ) {}
1537 //              phy_write( eng,  0, eng->phy.PHY_00h );
1538 ////            phy_delay(100);
1539 //              phy_delay(400);
1540 
1541                 // Check register 0x1 bit2 Link OK or not OK
1542                 phy_check_register ( eng, 1, 0x0004, 0x0004, 10, "set RTL8201F");
1543                 phy_delay(300);
1544         }
1545 }
1546 
1547 //------------------------------------------------------------
1548 /* for RTL8211F */
1549 void recov_phy_realtek5 (MAC_ENGINE *eng)
1550 {
1551 	RTK_DBG_PRINTF("\nClear RTL8211F [Start] =====>\n");
1552         if ( eng->run.tm_tx_only ) {
1553                 if ( eng->run.TM_IEEE ) {
1554                         if ( eng->run.speed_sel[ 0 ] ) {
1555                                 //Rev 1.0
1556                                 phy_write( eng, 31, 0x0000 );
1557                                 phy_write( eng,  9, 0x0000 );
1558                         }
1559                         else if ( eng->run.speed_sel[ 1 ] ) {
1560                                 //Rev 1.0
1561                                 phy_write( eng, 31, 0x0000 );
1562                                 phy_write( eng, 24, 0x2118 );//RGMII
1563                                 phy_write( eng,  9, 0x0200 );
1564                                 phy_write( eng,  0, 0x9200 );
1565                                 phy_wait_reset_done( eng );
1566                         }
1567                         else {
1568                                 //Rev 1.0
1569                                 phy_write( eng, 31, 0x0c80 );
1570                                 phy_write( eng, 16, 0x5a00 );
1571                                 phy_write( eng, 31, 0x0000 );
1572                                 phy_write( eng,  4, 0x01e1 );
1573                                 phy_write( eng,  9, 0x0200 );
1574                                 phy_write( eng,  0, 0x9200 );
1575                                 phy_wait_reset_done( eng );
1576                         }
1577                 }
1578                 else {
1579                 }
1580         }
1581         else if ( eng->phy.loopback ) {
1582         }
1583         else {
1584                 if ( eng->run.speed_sel[ 0 ] ) {
1585                         //Rev 1.1
1586                         phy_write( eng, 31, 0x0a43 );
1587                         phy_write( eng, 24, 0x2118 );
1588                         phy_write( eng,  0, 0x1040 );
1589                 }
1590 //              else if ( eng->run.speed_sel[ 1 ] ) {//option
1591 //                      phy_write( eng, 31, 0x0000 );
1592 //                      phy_write( eng,  9, 0x0200 );
1593 //                      phy_write( eng,  0, 0x1200 );
1594 //              }
1595 //              else if ( eng->run.speed_sel[ 2 ] ) {//option
1596 //                      phy_write( eng, 31, 0x0000 );
1597 //                      phy_write( eng,  9, 0x0200 );
1598 //                      phy_write( eng,  4, 0x01e1 );
1599 //                      phy_write( eng,  0, 0x1200 );
1600 //              }
1601                 else {
1602                         phy_write( eng, 31, 0x0000 );
1603                         phy_write( eng,  0, 0x1040 );
1604                 }
1605 
1606 #ifdef RTK_DEBUG
1607 #else
1608                 // Check register 0x1A bit2 Link OK or not OK
1609                 phy_write( eng, 31, 0x0a43 );
1610                 phy_check_register ( eng, 26, 0x0004, 0x0000, 10, "clear RTL8211F");
1611                 phy_write( eng, 31, 0x0000 );
1612 #endif
1613         }
1614 
1615 	RTK_DBG_PRINTF("\nClear RTL8211F [End] =====>\n");
1616 }
1617 
1618 //------------------------------------------------------------
1619 void phy_realtek5 (MAC_ENGINE *eng) {//RTL8211F
1620 	uint16_t check_value;
1621 	uint16_t reg;
1622 
1623 	RTK_DBG_PRINTF("\nSet RTL8211F [Start] =====>\n");
1624 
1625 	/* select page 0xd08 to configure TX and RX delay */
1626 	phy_write(eng, 0x1f, 0xd08);
1627 
1628 	/* page 0xd08, reg 0x11[8] TX delay enable */
1629 	reg = phy_read(eng, 0x11);
1630 	if (eng->arg.ctrl.b.phy_tx_delay_en)
1631 		reg |= BIT(8);
1632 	else
1633 		reg &= ~BIT(8);
1634 	phy_write(eng, 0x11, reg);
1635 
1636 	/* page 0xd08, reg 0x15[3] RX delay enable */
1637 	reg = phy_read(eng, 0x15);
1638 	if (eng->arg.ctrl.b.phy_rx_delay_en)
1639 		reg |= BIT(3);
1640 	else
1641 		reg &= ~BIT(3);
1642 	phy_write(eng, 0x15, reg);
1643 
1644 	/* restore page 0 */
1645 	phy_write(eng, 0x1f, 0x0);
1646 
1647 	if (eng->run.tm_tx_only) {
1648 		if (eng->run.TM_IEEE) {
1649 			if (eng->run.speed_sel[0]) {
1650 				// Rev 1.0
1651 				phy_write(eng, 31, 0x0000);
1652 				if (eng->run.ieee_sel == 0) { // Test Mode 1
1653 					phy_write(eng, 9, 0x0200);
1654 				} else if (eng->run.ieee_sel ==
1655 					   1) { // Test Mode 2
1656 					phy_write(eng, 9, 0x0400);
1657 				} else { // Test Mode 4
1658 					phy_write(eng, 9, 0x0800);
1659 				}
1660 			} else if (eng->run.speed_sel[1]) { // option
1661 				// Rev 1.0
1662 				phy_write(eng, 31, 0x0000);
1663 				if (eng->run.ieee_sel ==
1664 				    0) { // Output MLT-3 from Channel A
1665 					phy_write(eng, 24, 0x2318);
1666 				} else { // Output MLT-3 from Channel B
1667 					phy_write(eng, 24, 0x2218);
1668 				}
1669 				phy_write(eng, 9, 0x0000);
1670 				phy_write(eng, 0, 0x2100);
1671 			} else {
1672 				// Rev 1.0
1673 				// 0: For Diff. Voltage/TP-IDL/Jitter with EEE
1674 				// 1: For Diff. Voltage/TP-IDL/Jitter without
1675 				// EEE 2: For Harmonic (all "1" patten) with EEE
1676 				// 3: For Harmonic (all "1" patten) without EEE
1677 				// 4: For Harmonic (all "0" patten) with EEE
1678 				// 5: For Harmonic (all "0" patten) without EEE
1679 				phy_write(eng, 31, 0x0000);
1680 				phy_write(eng, 9, 0x0000);
1681 				phy_write(eng, 4, 0x0061);
1682 				if ((eng->run.ieee_sel & 0x1) == 0) { // with
1683 								      // EEE
1684 					phy_write(eng, 25, 0x0853);
1685 				} else { // without EEE
1686 					phy_write(eng, 25, 0x0843);
1687 				}
1688 				phy_write(eng, 0, 0x9200);
1689 				phy_wait_reset_done(eng);
1690 
1691 				if ((eng->run.ieee_sel & 0x6) ==
1692 				    0) { // For Diff. Voltage/TP-IDL/Jitter
1693 					phy_write(eng, 31, 0x0c80);
1694 					phy_write(eng, 18, 0x0115);
1695 					phy_write(eng, 16, 0x5a21);
1696 				} else if ((eng->run.ieee_sel & 0x6) ==
1697 					   0x2) { // For Harmonic (all "1"
1698 						  // patten)
1699 					phy_write(eng, 31, 0x0c80);
1700 					phy_write(eng, 18, 0x0015);
1701 					phy_write(eng, 16, 0xff21);
1702 				} else { // For Harmonic (all "0" patten)
1703 					phy_write(eng, 31, 0x0c80);
1704 					phy_write(eng, 18, 0x0015);
1705 					phy_write(eng, 16, 0x0021);
1706 				}
1707 				phy_write(eng, 31, 0x0000);
1708 			}
1709 		} else {
1710 			phy_reset(eng);
1711 		}
1712 	} else if (eng->phy.loopback) {
1713 		phy_reset(eng);
1714 	} else {
1715 		if (eng->run.speed_sel[0]) {
1716 			check_value = 0x0004 | 0x0028;
1717 			// Rev 1.1
1718 			phy_write(eng, 31, 0x0a43);
1719 			phy_write(eng, 0, 0x8000);
1720 #ifdef RTK_DEBUG
1721 			phy_delay(60);
1722 #else
1723 			phy_wait_reset_done(eng);
1724 			phy_delay(30);
1725 #endif
1726 
1727 			phy_write(eng, 0, 0x0140);
1728 			phy_write(eng, 24, 0x2d18);
1729 #ifdef RTK_DEBUG
1730 			phy_delay(600);
1731 #else
1732 			phy_delay(300);
1733 #endif
1734 		} else {
1735 			if (eng->run.speed_sel[1])
1736 				check_value = 0x0004 | 0x0018;
1737 			else
1738 				check_value = 0x0004 | 0x0008;
1739 #ifdef RTK_DEBUG
1740 #else
1741 			phy_write(eng, 31, 0x0a43);
1742 			phy_write(eng, 0, 0x8000);
1743 			phy_wait_reset_done(eng);
1744 			phy_delay(30);
1745 #endif
1746 
1747 			phy_write(eng, 31, 0x0000);
1748 			phy_write(eng, 0, eng->phy.PHY_00h);
1749 #ifdef RTK_DEBUG
1750 			phy_delay(300);
1751 #else
1752 			phy_delay(150);
1753 #endif
1754 		}
1755 
1756 #ifdef RTK_DEBUG
1757 #else
1758 		// Check register 0x1A bit2 Link OK or not OK
1759 		phy_write(eng, 31, 0x0a43);
1760 		phy_check_register(eng, 26, 0x0004 | 0x0038, check_value, 10,
1761 				   "set RTL8211F");
1762 		phy_write(eng, 31, 0x0000);
1763 #endif
1764 	}
1765 
1766 	RTK_DBG_PRINTF("\nSet RTL8211F [End] =====>\n");
1767 }
1768 
1769 //------------------------------------------------------------
1770 //It is a LAN Switch, only support 1G internal loopback test.
1771 void phy_realtek6 (MAC_ENGINE *eng)
1772 {//RTL8363S
1773 
1774 	if (eng->run.tm_tx_only) {
1775 		printf("This mode doesn't support in RTL8363S.\n");
1776 	} else if (eng->phy.loopback) {
1777 
1778 		// RXDLY2 and TXDLY2 of RTL8363S should set to LOW
1779 		phy_basic_setting(eng);
1780 
1781 		phy_clrset(eng, 0, 0x0000,
1782 			       0x8000 | eng->phy.PHY_00h); // clr set//Rst PHY
1783 		phy_wait_reset_done(eng);
1784 		phy_delay(30);
1785 
1786 		phy_basic_setting(eng);
1787 		phy_delay(30);
1788 	} else {
1789 		printf("This mode doesn't support in RTL8363S\n");
1790 	}
1791 } // End void phy_realtek6 (MAC_ENGINE *eng)
1792 
1793 //------------------------------------------------------------
1794 void phy_smsc (MAC_ENGINE *eng)
1795 {//LAN8700
1796 	phy_reset(eng);
1797 }
1798 
1799 //------------------------------------------------------------
1800 void phy_micrel (MAC_ENGINE *eng)
1801 {//KSZ8041
1802 
1803         phy_reset( eng );
1804 
1805 //      phy_write( eng, 24, 0x0600 );
1806 }
1807 
1808 //------------------------------------------------------------
1809 void phy_micrel0 (MAC_ENGINE *eng)
1810 {//KSZ8031/KSZ8051
1811 
1812         //For KSZ8051RNL only
1813         //Reg1Fh[7] = 0(default): 25MHz Mode, XI, XO(pin 9, 8) is 25MHz(crystal/oscilator).
1814         //Reg1Fh[7] = 1         : 50MHz Mode, XI(pin 9) is 50MHz(oscilator).
1815         eng->phy.PHY_1fh = phy_read( eng, 31 );
1816         if ( eng->phy.PHY_1fh & 0x0080 ) sprintf((char *)eng->phy.phy_name, "%s-50MHz Mode", eng->phy.phy_name);
1817         else                             sprintf((char *)eng->phy.phy_name, "%s-25MHz Mode", eng->phy.phy_name);
1818 
1819         if ( eng->run.TM_IEEE ) {
1820                 phy_clrset( eng,  0, 0x0000, 0x8000 | eng->phy.PHY_00h );//clr set//Rst PHY
1821                 phy_wait_reset_done( eng );
1822 
1823                 phy_clrset( eng, 31, 0x0000, 0x2000 );//clr set//1Fh[13] = 1: Disable auto MDI/MDI-X
1824                 phy_basic_setting( eng );
1825                 phy_clrset( eng, 31, 0x0000, 0x0800 );//clr set//1Fh[11] = 1: Force link pass
1826 
1827 //              phy_delay(2500);//2.5 sec
1828         }
1829         else {
1830                 phy_reset( eng );
1831 
1832                 //Reg16h[6] = 1         : RMII B-to-B override
1833                 //Reg16h[1] = 1(default): RMII override
1834                 phy_clrset( eng, 22, 0x0000, 0x0042 );//clr set
1835         }
1836 
1837         if ( eng->phy.PHY_1fh & 0x0080 )
1838                 phy_clrset( eng, 31, 0x0000, 0x0080 );//clr set//Reset PHY will clear Reg1Fh[7]
1839 }
1840 
1841 //------------------------------------------------------------
1842 //external loop 1G  : NOT Support
1843 //external loop 100M: OK
1844 //external loop 10M : OK
1845 //internal loop 1G  : no  loopback stub
1846 //internal loop 100M: no  loopback stub
1847 //internal loop 10M : no  loopback stub
1848 void phy_micrel1 (MAC_ENGINE *eng)
1849 {//KSZ9031
1850 //      int        temp;
1851 
1852 /*
1853         phy_write( eng, 13, 0x0002 );
1854         phy_write( eng, 14, 0x0004 );
1855         phy_write( eng, 13, 0x4002 );
1856         temp = phy_read( eng, 14 );
1857         //Reg2.4[ 7: 4]: RXDV Pad Skew
1858         phy_write( eng, 14, temp & 0xff0f | 0x0000 );
1859 //      phy_write( eng, 14, temp & 0xff0f | 0x00f0 );
1860 printf("Reg2.4 = %04x -> %04x\n", temp, phy_read( eng, 14 ));
1861 
1862         phy_write( eng, 13, 0x0002 );
1863         phy_write( eng, 14, 0x0005 );
1864         phy_write( eng, 13, 0x4002 );
1865         temp = phy_read( eng, 14 );
1866         //Reg2.5[15:12]: RXD3 Pad Skew
1867         //Reg2.5[11: 8]: RXD2 Pad Skew
1868         //Reg2.5[ 7: 4]: RXD1 Pad Skew
1869         //Reg2.5[ 3: 0]: RXD0 Pad Skew
1870         phy_write( eng, 14, 0x0000 );
1871 //      phy_write( eng, 14, 0xffff );
1872 printf("Reg2.5 = %04x -> %04x\n", temp, phy_read( eng, 14 ));
1873 
1874         phy_write( eng, 13, 0x0002 );
1875         phy_write( eng, 14, 0x0008 );
1876         phy_write( eng, 13, 0x4002 );
1877         temp = phy_read( eng, 14 );
1878         //Reg2.8[9:5]: GTX_CLK Pad Skew
1879         //Reg2.8[4:0]: RX_CLK Pad Skew
1880 //      phy_write( eng, 14, temp & 0xffe0 | 0x0000 );
1881         phy_write( eng, 14, temp & 0xffe0 | 0x001f );
1882 printf("Reg2.8 = %04x -> %04x\n", temp, phy_read( eng, 14 ));
1883 */
1884 
1885         if ( eng->run.tm_tx_only ) {
1886                 if ( eng->run.TM_IEEE ) {
1887                         phy_reset( eng );
1888                 }
1889                 else {
1890                         phy_reset( eng );
1891                 }
1892         }
1893         else if ( eng->phy.loopback ) {
1894                 phy_reset( eng );
1895         }
1896         else {
1897                 if ( eng->run.speed_sel[ 0 ] ) {
1898                         phy_reset( eng );//DON'T support for 1G external loopback testing
1899                 }
1900                 else {
1901                         phy_reset( eng );
1902                 }
1903         }
1904 }
1905 
1906 //------------------------------------------------------------
1907 //external loop 100M: OK
1908 //external loop 10M : OK
1909 //internal loop 100M: no  loopback stub
1910 //internal loop 10M : no  loopback stub
1911 void phy_micrel2 (MAC_ENGINE *eng)
1912 {//KSZ8081
1913 
1914         if ( eng->run.tm_tx_only ) {
1915                 if ( eng->run.TM_IEEE ) {
1916                         phy_reset( eng );
1917                 }
1918                 else {
1919                         phy_reset( eng );
1920                 }
1921         }
1922         else if ( eng->phy.loopback ) {
1923                 phy_reset( eng );
1924         }
1925         else {
1926                 if ( eng->run.speed_sel[ 1 ] )
1927                         phy_reset( eng );
1928                 else
1929                         phy_reset( eng );
1930         }
1931 }
1932 
1933 //------------------------------------------------------------
1934 void recov_phy_vitesse (MAC_ENGINE *eng) {//VSC8601
1935         if ( eng->run.tm_tx_only ) {
1936 //              if ( eng->run.TM_IEEE ) {
1937 //              }
1938 //              else {
1939 //              }
1940         }
1941         else if ( eng->phy.loopback ) {
1942         }
1943         else {
1944                 if ( eng->run.speed_sel[ 0 ] ) {
1945                         phy_write( eng, 24, eng->phy.PHY_18h );
1946                         phy_write( eng, 18, eng->phy.PHY_12h );
1947                 }
1948         }
1949 }
1950 
1951 //------------------------------------------------------------
1952 void phy_vitesse (MAC_ENGINE *eng)
1953 {//VSC8601
1954 
1955         if ( eng->run.tm_tx_only ) {
1956                 if ( eng->run.TM_IEEE ) {
1957                         phy_reset( eng );
1958                 }
1959                 else {
1960                         phy_reset( eng );
1961                 }
1962         }
1963         else if ( eng->phy.loopback ) {
1964                 phy_reset( eng );
1965         }
1966         else {
1967                 if ( eng->run.speed_sel[ 0 ] ) {
1968                         eng->phy.PHY_18h = phy_read( eng, 24 );
1969                         eng->phy.PHY_12h = phy_read( eng, PHY_INER );
1970 
1971                         phy_reset( eng );
1972 
1973                         phy_write( eng, 24, eng->phy.PHY_18h | 0x0001 );
1974                         phy_write( eng, 18, eng->phy.PHY_12h | 0x0020 );
1975                 }
1976                 else {
1977                         phy_reset( eng );
1978                 }
1979         }
1980 }
1981 
1982 //------------------------------------------------------------
1983 void recov_phy_atheros (MAC_ENGINE *eng) {//AR8035
1984 	if (eng->run.tm_tx_only) {
1985 		if (eng->run.TM_IEEE) {
1986 		} else {
1987 		}
1988 	} else if (eng->phy.loopback) {
1989 	} else {
1990 		phy_clrset(
1991 		    eng, 11, 0x0000,
1992 		    0x8000); // clr set//Disable hibernate: Reg0Bh[15] = 0
1993 		phy_clrset(
1994 		    eng, 17, 0x0001,
1995 		    0x0000); // clr set//Enable external loopback: Reg11h[0] = 1
1996 	}
1997 }
1998 
1999 //------------------------------------------------------------
2000 void phy_atheros (MAC_ENGINE *eng)
2001 {
2002 	// Reg0b[15]: Power saving
2003 	phy_write(eng, 29, 0x000b);
2004 	eng->phy.PHY_1eh = phy_read(eng, 30);
2005 	if (eng->phy.PHY_1eh & 0x8000) {
2006 		printf("\n\n[Warning] Debug register offset = 11, bit 15 must "
2007 		       "be 0 [%04x]\n\n",
2008 		       eng->phy.PHY_1eh);
2009 		if (eng->run.TM_IOTiming)
2010 			PRINTF(FP_IO,
2011 			       "\n\n[Warning] Debug register offset = 11, bit "
2012 			       "15 must be 0 [%04x]\n\n",
2013 			       eng->phy.PHY_1eh);
2014 		if (!eng->run.tm_tx_only)
2015 			PRINTF(FP_LOG,
2016 			       "\n\n[Warning] Debug register offset = 11, bit "
2017 			       "15 must be 0 [%04x]\n\n",
2018 			       eng->phy.PHY_1eh);
2019 
2020 		phy_write(eng, 30, eng->phy.PHY_1eh & 0x7fff);
2021 	}
2022 	//      phy_write( eng, 30, (eng->phy.PHY_1eh & 0x7fff) | 0x8000 );
2023 
2024 	// Check RGMIIRXCK delay (Sel_clk125m_dsp)
2025 	phy_write(eng, 29, 0x0000);
2026 	eng->phy.PHY_1eh = phy_read(eng, 30);
2027 	if (eng->phy.PHY_1eh & 0x8000) {
2028 		printf("\n\n[Warning] Debug register offset = 0, bit 15 must "
2029 		       "be 0 [%04x]\n\n",
2030 		       eng->phy.PHY_1eh);
2031 		if (eng->run.TM_IOTiming)
2032 			PRINTF(FP_IO,
2033 			       "\n\n[Warning] Debug register offset = 0, bit "
2034 			       "15 must be 0 [%04x]\n\n",
2035 			       eng->phy.PHY_1eh);
2036 		if (!eng->run.tm_tx_only)
2037 			PRINTF(FP_LOG,
2038 			       "\n\n[Warning] Debug register offset = 0, bit "
2039 			       "15 must be 0 [%04x]\n\n",
2040 			       eng->phy.PHY_1eh);
2041 
2042 		phy_write(eng, 30, eng->phy.PHY_1eh & 0x7fff);
2043 	}
2044 	//      phy_write( eng, 30, (eng->phy.PHY_1eh & 0x7fff) | 0x8000 );
2045 
2046 	// Check RGMIITXCK delay (rgmii_tx_clk_dly)
2047 	phy_write(eng, 29, 0x0005);
2048 	eng->phy.PHY_1eh = phy_read(eng, 30);
2049 	if (eng->phy.PHY_1eh & 0x0100) {
2050 		printf("\n\n[Warning] Debug register offset = 5, bit 8 must be "
2051 		       "0 [%04x]\n\n",
2052 		       eng->phy.PHY_1eh);
2053 		if (eng->run.TM_IOTiming)
2054 			PRINTF(FP_IO,
2055 			       "\n\n[Warning] Debug register offset = 5, bit 8 "
2056 			       "must be 0 [%04x]\n\n",
2057 			       eng->phy.PHY_1eh);
2058 		if (!eng->run.tm_tx_only)
2059 			PRINTF(FP_LOG,
2060 			       "\n\n[Warning] Debug register offset = 5, bit 8 "
2061 			       "must be 0 [%04x]\n\n",
2062 			       eng->phy.PHY_1eh);
2063 
2064 		phy_write(eng, 30, eng->phy.PHY_1eh & 0xfeff);
2065 	}
2066 	//      phy_write( eng, 30, (eng->phy.PHY_1eh & 0xfeff) | 0x0100 );
2067 
2068 	// Check CLK_25M output (Select_clk125m)
2069 	phy_write(eng, 13, 0x0007);
2070 	phy_write(eng, 14, 0x8016);
2071 	phy_write(eng, 13, 0x4007);
2072 	eng->phy.PHY_0eh = phy_read(eng, 14);
2073 	if ((eng->phy.PHY_0eh & 0x0018) != 0x0018) {
2074 		printf("\n\n[Warning] Device addrress = 7, Addrress ofset = "
2075 		       "0x8016, bit 4~3 must be 3 [%04x]\n\n",
2076 		       eng->phy.PHY_0eh);
2077 		if (eng->run.TM_IOTiming)
2078 			PRINTF(FP_IO,
2079 			       "\n\n[Warning] Device addrress = 7, Addrress "
2080 			       "ofset = 0x8016, bit 4~3 must be 3 [%04x]\n\n",
2081 			       eng->phy.PHY_0eh);
2082 		if (!eng->run.tm_tx_only)
2083 			PRINTF(FP_LOG,
2084 			       "\n\n[Warning] Device addrress = 7, Addrress "
2085 			       "ofset = 0x8016, bit 4~3 must be 3 [%04x]\n\n",
2086 			       eng->phy.PHY_0eh);
2087 		printf("          The CLK_25M don't ouput 125MHz clock for the "
2088 		       "RGMIICK !!!\n\n");
2089 
2090 		phy_write(eng, 14, (eng->phy.PHY_0eh & 0xffe7) | 0x0018);
2091 	}
2092 
2093 	if (eng->run.tm_tx_only) {
2094 		if (eng->run.TM_IEEE) {
2095 			phy_write(eng, 0, eng->phy.PHY_00h);
2096 		} else {
2097 			phy_write(eng, 0, eng->phy.PHY_00h);
2098 		}
2099 	} else if (eng->phy.loopback) {
2100 		phy_write(eng, 0, eng->phy.PHY_00h);
2101 	} else {
2102 		phy_clrset(
2103 		    eng, 11, 0x8000,
2104 		    0x0000); // clr set//Disable hibernate: Reg0Bh[15] = 0
2105 		phy_clrset(
2106 		    eng, 17, 0x0000,
2107 		    0x0001); // clr set//Enable external loopback: Reg11h[0] = 1
2108 
2109 		phy_write(eng, 0, eng->phy.PHY_00h | 0x8000);
2110 #ifdef Delay_PHYRst
2111 		phy_delay(Delay_PHYRst);
2112 #endif
2113 	}
2114 }
2115 
2116 //------------------------------------------------------------
2117 void phy_default (MAC_ENGINE *eng)
2118 {
2119 	nt_log_func_name();
2120 
2121 	phy_reset(eng);
2122 }
2123 
2124 //------------------------------------------------------------
2125 // PHY Init
2126 //------------------------------------------------------------
2127 /**
2128  * @return	1->addr found,  0->else
2129 */
2130 uint32_t phy_find_addr(MAC_ENGINE *eng)
2131 {
2132 	uint32_t value;
2133 	uint32_t ret = 0;
2134 	int8_t phy_addr_org;
2135 
2136 	nt_log_func_name();
2137 
2138         phy_addr_org = eng->phy.Adr;
2139         value = phy_read(eng, PHY_REG_ID_1);
2140 
2141         ret = PHY_IS_VALID(value);
2142         if ((ret == 0) && (eng->arg.ctrl.b.skip_phy_id_check)) {
2143 		value = phy_read(eng, PHY_REG_BMCR);
2144 		if ((value & BIT(15)) && (0 == eng->arg.ctrl.b.skip_phy_init)) {
2145                         /* user wants to skip PHY init but PHY is in reset state
2146                          * this case should not be allowed.
2147                          */
2148 		} else {
2149 			ret = 1;
2150 		}
2151 	}
2152 
2153 	if (ret == 0) {
2154 		for (eng->phy.Adr = 0; eng->phy.Adr < 32; eng->phy.Adr++) {
2155 			value = phy_read(eng, PHY_REG_ID_1);
2156 			if (PHY_IS_VALID(value)) {
2157 				ret = 1;
2158 				break;
2159 			}
2160 		}
2161 	}
2162 
2163 	if (ret == 0)
2164 		eng->phy.Adr = eng->arg.phy_addr;
2165 
2166 	if (0 == eng->arg.ctrl.b.skip_phy_init) {
2167 		if (ret == 1) {
2168 			if (phy_addr_org != eng->phy.Adr) {
2169 				phy_scan_id(eng, STD_OUT);
2170 			}
2171 		} else {
2172 			phy_scan_id(eng, STD_OUT);
2173 			FindErr(eng, Err_Flag_PHY_Type);
2174 		}
2175 	}
2176 
2177 
2178 	eng->phy.id1 = phy_read(eng, PHY_REG_ID_1);
2179 	eng->phy.id2 = phy_read(eng, PHY_REG_ID_2);
2180         value = (eng->phy.id2 << 16) | eng->phy.id1;
2181 
2182 	if (0 == eng->arg.ctrl.b.skip_phy_id_check) {
2183                 if ((value == 0) || (value == 0xffffffff)) {
2184                         sprintf((char *)eng->phy.phy_name, "--");
2185                         if (0 == eng->arg.ctrl.b.skip_phy_init)
2186 			        FindErr(eng, Err_Flag_PHY_Type);
2187                 }
2188         }
2189 
2190         return ret;
2191 }
2192 
2193 //------------------------------------------------------------
2194 void phy_set00h (MAC_ENGINE *eng)
2195 {
2196 	nt_log_func_name();
2197 
2198 	eng->phy.PHY_00h = BIT(8);
2199 
2200 	if (eng->run.speed_sel[0])
2201 		eng->phy.PHY_00h |= BIT(6);
2202 	else if (eng->run.speed_sel[1])
2203 		eng->phy.PHY_00h |= BIT(13);
2204 
2205 	if (eng->phy.loopback)
2206 		eng->phy.PHY_00h |= BIT(14);
2207 }
2208 
2209 static uint32_t phy_check_id(MAC_ENGINE *p_eng, const struct phy_desc *p_phy)
2210 {
2211         uint32_t value, id;
2212 
2213         value  = (p_eng->phy.id1 << 16) | (p_eng->phy.id2 & p_phy->id2_mask);
2214         id  = (p_phy->id1 << 16) | (p_phy->id2 & p_phy->id2_mask);
2215         debug("%s:value %04x, id %04x\n", __func__, value, id);
2216 
2217         if (value == id)
2218                 return 1;
2219 
2220         return 0;
2221 }
2222 
2223 void phy_select(MAC_ENGINE *eng, PHY_ENGINE *phyeng)
2224 {
2225 	int i;
2226 	const struct phy_desc *p_phy;
2227 	nt_log_func_name();
2228 
2229 	/* set default before lookup */
2230 	sprintf((char *)eng->phy.phy_name, "default");
2231 	phyeng->fp_set = phy_default;
2232 	phyeng->fp_clr = NULL;
2233 
2234 	if (eng->phy.default_phy) {
2235 		debug("use default PHY\n");
2236 	} else {
2237 		for (i = 0; i < PHY_LOOKUP_N; i++) {
2238 			p_phy = &phy_lookup_tbl[i];
2239 			if (phy_check_id(eng, p_phy)) {
2240 				sprintf((char *)eng->phy.phy_name,
2241 					(char *)p_phy->name);
2242 				phyeng->fp_set = p_phy->cfg.fp_set;
2243 				phyeng->fp_clr = p_phy->cfg.fp_clr;
2244 				break;
2245 			}
2246 		}
2247 	}
2248 
2249 	if (eng->arg.ctrl.b.skip_phy_init) {
2250 		phyeng->fp_set = NULL;
2251 		phyeng->fp_clr = NULL;
2252 	} else if (eng->arg.ctrl.b.skip_phy_deinit) {
2253 		phyeng->fp_clr = NULL;
2254 	}
2255 }
2256 
2257 //------------------------------------------------------------
2258 void recov_phy (MAC_ENGINE *eng, PHY_ENGINE *phyeng)
2259 {
2260 	nt_log_func_name();
2261 
2262 	if (phyeng->fp_clr != NULL)
2263         	(*phyeng->fp_clr)( eng );
2264 }
2265 
2266 //------------------------------------------------------------
2267 void init_phy (MAC_ENGINE *eng, PHY_ENGINE *phyeng)
2268 {
2269 	nt_log_func_name();
2270 
2271 	if (DbgPrn_PHYInit)
2272 		phy_dump(eng);
2273 
2274 	phy_set00h(eng);
2275 	if (phyeng->fp_set != NULL)
2276 		(*phyeng->fp_set)(eng);
2277 
2278 	if (DbgPrn_PHYInit)
2279 		phy_dump(eng);
2280 }
2281