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