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