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