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