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