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