xref: /openbmc/u-boot/cmd/aspeed/nettest/phy.c (revision 20b0d70ca252fd7b83b28486921fe0721d44c7ed)
1d82a9689SDylan Hung // SPDX-License-Identifier: GPL-2.0+
25c8f9400Sryan_chen /*
3d82a9689SDylan Hung  * Copyright (C) ASPEED Technology Inc.
45c8f9400Sryan_chen  */
55c8f9400Sryan_chen 
65c8f9400Sryan_chen #define PHY_C
75c8f9400Sryan_chen //#define PHY_DEBUG
85c8f9400Sryan_chen //#define PHY_DEBUG_SET_CLR
95c8f9400Sryan_chen 
105c8f9400Sryan_chen #ifdef PHY_DEBUG
115c8f9400Sryan_chen #undef DbgPrn_PHYRW
125c8f9400Sryan_chen #define DbgPrn_PHYRW		1
135c8f9400Sryan_chen #endif
145c8f9400Sryan_chen 
155c8f9400Sryan_chen #ifdef PHY_DEBUG_SET_CLR
165c8f9400Sryan_chen #undef DbgPrn_PHYRW
175c8f9400Sryan_chen #define DbgPrn_PHYRW		1
185c8f9400Sryan_chen #endif
195c8f9400Sryan_chen 
205c8f9400Sryan_chen 
215c8f9400Sryan_chen #include "comminf.h"
225c8f9400Sryan_chen #include "swfunc.h"
235c8f9400Sryan_chen 
245c8f9400Sryan_chen #include <command.h>
255c8f9400Sryan_chen #include <common.h>
265c8f9400Sryan_chen 
275c8f9400Sryan_chen #include "phy.h"
285c8f9400Sryan_chen 
295c8f9400Sryan_chen #include "phy_tbl.h"
305c8f9400Sryan_chen #include "mem_io.h"
315c8f9400Sryan_chen 
325c8f9400Sryan_chen //#define RTK_DEBUG
335c8f9400Sryan_chen #define RTK_DBG_GPIO		BIT(22)
345c8f9400Sryan_chen #ifdef RTK_DEBUG
355c8f9400Sryan_chen #define RTK_DBG_PRINTF		printf
365c8f9400Sryan_chen #else
375c8f9400Sryan_chen #define RTK_DBG_PRINTF(...)
385c8f9400Sryan_chen #endif
395c8f9400Sryan_chen 
rtk_dbg_gpio_set(void)405c8f9400Sryan_chen static void rtk_dbg_gpio_set(void)
415c8f9400Sryan_chen {
425c8f9400Sryan_chen #ifdef RTK_DEBUG
435c8f9400Sryan_chen 	GPIO_WR(GPIO_RD(0x20) | RTK_DBG_GPIO, 0x20);
445c8f9400Sryan_chen #endif
455c8f9400Sryan_chen }
465c8f9400Sryan_chen 
rtk_dbg_gpio_clr(void)475c8f9400Sryan_chen static void rtk_dbg_gpio_clr(void)
485c8f9400Sryan_chen {
495c8f9400Sryan_chen #ifdef RTK_DEBUG
505c8f9400Sryan_chen 	GPIO_WR(GPIO_RD(0x20) & ~RTK_DBG_GPIO, 0x20);
515c8f9400Sryan_chen #endif
525c8f9400Sryan_chen }
535c8f9400Sryan_chen 
rtk_dbg_gpio_init(void)545c8f9400Sryan_chen static void rtk_dbg_gpio_init(void)
555c8f9400Sryan_chen {
565c8f9400Sryan_chen #ifdef RTK_DEBUG
575c8f9400Sryan_chen 	GPIO_WR(GPIO_RD(0x24) | RTK_DBG_GPIO, 0x24);
585c8f9400Sryan_chen 
595c8f9400Sryan_chen 	rtk_dbg_gpio_set();
605c8f9400Sryan_chen #endif
615c8f9400Sryan_chen }
625c8f9400Sryan_chen 
635c8f9400Sryan_chen //------------------------------------------------------------
645c8f9400Sryan_chen // PHY R/W basic
655c8f9400Sryan_chen //------------------------------------------------------------
phy_write(MAC_ENGINE * eng,int index,uint32_t data)665c8f9400Sryan_chen void phy_write (MAC_ENGINE *eng, int index, uint32_t data)
675c8f9400Sryan_chen {
6867e8dc79SDylan Hung 	u32 wr_data;
695c8f9400Sryan_chen 	int timeout = 0;
705c8f9400Sryan_chen 
715c8f9400Sryan_chen 	if (eng->env.is_new_mdio_reg[eng->run.mdio_idx]) {
7267e8dc79SDylan Hung 		wr_data = MDIO_WR_CODE | MDIO_SET_WR_DATA(data) |
7367e8dc79SDylan Hung 			  MDIO_SET_PHY_ADDR(eng->phy.Adr) |
7467e8dc79SDylan Hung 			  MDIO_SET_REG_ADDR(index);
7567e8dc79SDylan Hung 		writel(wr_data, eng->run.mdio_base);
765c8f9400Sryan_chen 		/* check time-out */
7767e8dc79SDylan Hung 		while (readl(eng->run.mdio_base) & MDIO_FIRE_BUSY) {
785c8f9400Sryan_chen 			if (++timeout > TIME_OUT_PHY_RW) {
795c8f9400Sryan_chen 				if (!eng->run.tm_tx_only)
805c8f9400Sryan_chen 					PRINTF(FP_LOG,
815c8f9400Sryan_chen 					       "[PHY-Write] Time out: %08x\n",
825c8f9400Sryan_chen 					       readl(eng->run.mdio_base));
835c8f9400Sryan_chen 
845c8f9400Sryan_chen 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
855c8f9400Sryan_chen 				break;
865c8f9400Sryan_chen 			}
875c8f9400Sryan_chen 		}
885c8f9400Sryan_chen 	} else {
895c8f9400Sryan_chen 		writel(data, eng->run.mdio_base + 0x4);
9067e8dc79SDylan Hung 		writel(MDC_CYC_THLD | MDIO_WR_CODE_OLD |
9167e8dc79SDylan Hung 			       MDIO_SET_PHY_ADDR_OLD(eng->phy.Adr) |
9267e8dc79SDylan Hung 			       MDIO_SET_REG_ADDR_OLD(index),
9367e8dc79SDylan Hung 		       eng->run.mdio_base);
945c8f9400Sryan_chen 
9567e8dc79SDylan Hung 		while (readl(eng->run.mdio_base) & MDIO_WR_CODE_OLD) {
965c8f9400Sryan_chen 			if (++timeout > TIME_OUT_PHY_RW) {
975c8f9400Sryan_chen 				if (!eng->run.tm_tx_only)
985c8f9400Sryan_chen 					PRINTF(FP_LOG,
995c8f9400Sryan_chen 					       "[PHY-Write] Time out: %08x\n",
1005c8f9400Sryan_chen 					       readl(eng->run.mdio_base));
1015c8f9400Sryan_chen 
1025c8f9400Sryan_chen 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
1035c8f9400Sryan_chen 				break;
1045c8f9400Sryan_chen 			}
1055c8f9400Sryan_chen 		}
1065c8f9400Sryan_chen 	} // End if (eng->env.new_mdio_reg)
1075c8f9400Sryan_chen 
1085c8f9400Sryan_chen 	if (DbgPrn_PHYRW) {
1095c8f9400Sryan_chen 		printf("[Wr ]%02d: 0x%04x (%02d:%08x)\n", index, data,
1105c8f9400Sryan_chen 		       eng->phy.Adr, eng->run.mdio_base);
1115c8f9400Sryan_chen 		if (!eng->run.tm_tx_only)
1125c8f9400Sryan_chen 			PRINTF(FP_LOG, "[Wr ]%02d: 0x%04x (%02d:%08x)\n", index,
1135c8f9400Sryan_chen 			       data, eng->phy.Adr, eng->run.mdio_base);
1145c8f9400Sryan_chen 	}
1155c8f9400Sryan_chen 
1165c8f9400Sryan_chen } // End void phy_write (int adr, uint32_t data)
1175c8f9400Sryan_chen 
1185c8f9400Sryan_chen //------------------------------------------------------------
phy_read(MAC_ENGINE * eng,int index)119daba96f3SDylan Hung uint16_t phy_read (MAC_ENGINE *eng, int index)
1205c8f9400Sryan_chen {
1215c8f9400Sryan_chen 	uint32_t read_value;
1225c8f9400Sryan_chen 	int timeout = 0;
1235c8f9400Sryan_chen 
1245c8f9400Sryan_chen 	if (index > 0x1f) {
1255c8f9400Sryan_chen 		printf("invalid PHY register index: 0x%02x\n", index);
1265c8f9400Sryan_chen 		FindErr(eng, Err_Flag_PHY_TimeOut_RW);
1275c8f9400Sryan_chen 		return 0;
1285c8f9400Sryan_chen 	}
1295c8f9400Sryan_chen 
1305c8f9400Sryan_chen 	if (eng->env.is_new_mdio_reg[eng->run.mdio_idx]) {
131fbcd0575SDylan Hung 		writel(MDIO_RD_CODE | MDIO_SET_PHY_ADDR(eng->phy.Adr) |
13267e8dc79SDylan Hung 			       MDIO_SET_REG_ADDR(index),
1335c8f9400Sryan_chen 		       eng->run.mdio_base);
1345c8f9400Sryan_chen 
13567e8dc79SDylan Hung 		while (readl(eng->run.mdio_base) & MDIO_FIRE_BUSY) {
1365c8f9400Sryan_chen 			if (++timeout > TIME_OUT_PHY_RW) {
1375c8f9400Sryan_chen 				if (!eng->run.tm_tx_only)
1385c8f9400Sryan_chen 					PRINTF(FP_LOG,
1395c8f9400Sryan_chen 					       "[PHY-Read] Time out: %08x\n",
1405c8f9400Sryan_chen 					       readl(eng->run.mdio_base));
1415c8f9400Sryan_chen 
1425c8f9400Sryan_chen 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
1435c8f9400Sryan_chen 				break;
1445c8f9400Sryan_chen 			}
1455c8f9400Sryan_chen 		}
1465c8f9400Sryan_chen 
1475c8f9400Sryan_chen #ifdef Delay_PHYRd
1485c8f9400Sryan_chen 		DELAY(Delay_PHYRd);
1495c8f9400Sryan_chen #endif
1505c8f9400Sryan_chen 		read_value = readl(eng->run.mdio_base + 0x4) & GENMASK(15, 0);
1515c8f9400Sryan_chen 	} else {
15267e8dc79SDylan Hung 		writel(MDC_CYC_THLD | MDIO_RD_CODE_OLD |
15367e8dc79SDylan Hung 			       MDIO_SET_PHY_ADDR_OLD(eng->phy.Adr) |
15467e8dc79SDylan Hung 			       MDIO_SET_REG_ADDR_OLD(index),
1555c8f9400Sryan_chen 		       eng->run.mdio_base);
1565c8f9400Sryan_chen 
15767e8dc79SDylan Hung 		while (readl(eng->run.mdio_base) & MDIO_RD_CODE_OLD) {
1585c8f9400Sryan_chen 			if (++timeout > TIME_OUT_PHY_RW) {
1595c8f9400Sryan_chen 				if (!eng->run.tm_tx_only)
1605c8f9400Sryan_chen 					PRINTF(FP_LOG,
1615c8f9400Sryan_chen 					       "[PHY-Read] Time out: %08x\n",
1625c8f9400Sryan_chen 					       readl(eng->run.mdio_base));
1635c8f9400Sryan_chen 
1645c8f9400Sryan_chen 				FindErr(eng, Err_Flag_PHY_TimeOut_RW);
1655c8f9400Sryan_chen 				break;
1665c8f9400Sryan_chen 			}
1675c8f9400Sryan_chen 		}
1685c8f9400Sryan_chen 
1695c8f9400Sryan_chen #ifdef Delay_PHYRd
1705c8f9400Sryan_chen 		DELAY(Delay_PHYRd);
1715c8f9400Sryan_chen #endif
1725c8f9400Sryan_chen 		read_value = readl(eng->run.mdio_base + 0x4) >> 16;
1735c8f9400Sryan_chen 	}
1745c8f9400Sryan_chen 
1755c8f9400Sryan_chen 
1765c8f9400Sryan_chen 	if (DbgPrn_PHYRW) {
1775c8f9400Sryan_chen 		printf("[Rd ]%02d: 0x%04x (%02d:%08x)\n", index, read_value,
1785c8f9400Sryan_chen 		       eng->phy.Adr, eng->run.mdio_base);
1795c8f9400Sryan_chen 		if (!eng->run.tm_tx_only)
1805c8f9400Sryan_chen 			PRINTF(FP_LOG, "[Rd ]%02d: 0x%04x (%02d:%08x)\n", index,
1815c8f9400Sryan_chen 			       read_value, eng->phy.Adr, eng->run.mdio_base);
1825c8f9400Sryan_chen 	}
1835c8f9400Sryan_chen 
1845c8f9400Sryan_chen 	return (read_value);
185daba96f3SDylan Hung } // End uint16_t phy_read (MAC_ENGINE *eng, int adr)
1865c8f9400Sryan_chen 
1875c8f9400Sryan_chen //------------------------------------------------------------
phy_clrset(MAC_ENGINE * eng,int adr,uint32_t clr_mask,uint32_t set_mask)188ff33b245SDylan Hung void phy_clrset(MAC_ENGINE *eng, int adr, uint32_t clr_mask, uint32_t set_mask)
1895c8f9400Sryan_chen {
1905c8f9400Sryan_chen 	if (DbgPrn_PHYRW) {
1915c8f9400Sryan_chen 		printf("[RW ]%02d: clr:0x%04x: set:0x%04x (%02d:%08x)\n", adr,
1925c8f9400Sryan_chen 		       clr_mask, set_mask, eng->phy.Adr, eng->run.mdio_base);
1935c8f9400Sryan_chen 		if (!eng->run.tm_tx_only)
194ff33b245SDylan Hung 			PRINTF(FP_LOG,
1955c8f9400Sryan_chen 			       "[RW ]%02d: clr:0x%04x: set:0x%04x (%02d:%08x)\n",
1965c8f9400Sryan_chen 			       adr, clr_mask, set_mask, eng->phy.Adr,
1975c8f9400Sryan_chen 			       eng->run.mdio_base);
1985c8f9400Sryan_chen 	}
1995c8f9400Sryan_chen 	phy_write(eng, adr, ((phy_read(eng, adr) & (~clr_mask)) | set_mask));
2005c8f9400Sryan_chen }
2015c8f9400Sryan_chen 
2025c8f9400Sryan_chen //------------------------------------------------------------
phy_dump(MAC_ENGINE * eng)2033f472ca7SDylan Hung void phy_dump(MAC_ENGINE *eng)
2043f472ca7SDylan Hung {
2055c8f9400Sryan_chen 	int index;
2065c8f9400Sryan_chen 
2073f472ca7SDylan Hung 	printf("[PHY%d][%d]----------------\n", eng->run.mac_idx + 1,
2083f472ca7SDylan Hung 	       eng->phy.Adr);
2095c8f9400Sryan_chen 	for (index = 0; index < 32; index++) {
2105c8f9400Sryan_chen 		printf("%02d: %04x ", index, phy_read(eng, index));
2115c8f9400Sryan_chen 
2125c8f9400Sryan_chen 		if ((index % 8) == 7)
2135c8f9400Sryan_chen 			printf("\n");
2145c8f9400Sryan_chen 	}
2155c8f9400Sryan_chen }
2165c8f9400Sryan_chen 
2175c8f9400Sryan_chen //------------------------------------------------------------
phy_scan_id(MAC_ENGINE * eng,uint8_t option)218daba96f3SDylan Hung static void phy_scan_id(MAC_ENGINE *eng, uint8_t option)
2195c8f9400Sryan_chen {
220ff33b245SDylan Hung 	int8_t phy_addr_orig;
2215c8f9400Sryan_chen 
222ff33b245SDylan Hung 	phy_addr_orig = eng->phy.Adr;
2235c8f9400Sryan_chen 	for (eng->phy.Adr = 0; eng->phy.Adr < 32; eng->phy.Adr++) {
2245c8f9400Sryan_chen 		PRINTF(option, "[%02d] ", eng->phy.Adr);
225ff33b245SDylan Hung 		PRINTF(option, "%d:%04x ", 2, phy_read(eng, 2));
226ff33b245SDylan Hung 		PRINTF(option, "%d:%04x ", 3, phy_read(eng, 3));
2275c8f9400Sryan_chen 
228ff33b245SDylan Hung 		if ((eng->phy.Adr % 4) == 3)
2295c8f9400Sryan_chen 			PRINTF(option, "\n");
2305c8f9400Sryan_chen 	}
231ff33b245SDylan Hung 	eng->phy.Adr = phy_addr_orig;
2325c8f9400Sryan_chen }
2335c8f9400Sryan_chen 
2345c8f9400Sryan_chen //------------------------------------------------------------
phy_delay(int dt)2355c8f9400Sryan_chen void phy_delay (int dt)
2365c8f9400Sryan_chen {
2375c8f9400Sryan_chen 	rtk_dbg_gpio_clr();
2385c8f9400Sryan_chen 
2395c8f9400Sryan_chen #ifdef PHY_DEBUG
2405c8f9400Sryan_chen         printf("delay %d ms\n", dt);
2415c8f9400Sryan_chen #endif
2425c8f9400Sryan_chen         DELAY(dt);
2435c8f9400Sryan_chen 	rtk_dbg_gpio_set();
2445c8f9400Sryan_chen }
2455c8f9400Sryan_chen 
2465c8f9400Sryan_chen //------------------------------------------------------------
2475c8f9400Sryan_chen // PHY IC basic
2485c8f9400Sryan_chen //------------------------------------------------------------
phy_basic_setting(MAC_ENGINE * eng)2493f472ca7SDylan Hung void phy_basic_setting(MAC_ENGINE *eng)
2503f472ca7SDylan Hung {
251e1be0065SDylan Hung 	uint32_t clr = GENMASK(14, 10) | BIT(6);
2525c8f9400Sryan_chen 
253e1be0065SDylan Hung 	phy_clrset(eng, 0, clr, eng->phy.PHY_00h);
2545c8f9400Sryan_chen 	if (DbgPrn_PHYRW) {
2553f472ca7SDylan Hung 		printf("[Set]00: 0x%04x (%02d:%08x)\n",
2563f472ca7SDylan Hung 		       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
2573f472ca7SDylan Hung 		       eng->run.mdio_base);
2583f472ca7SDylan Hung 		if (!eng->run.tm_tx_only)
2593f472ca7SDylan Hung 			PRINTF(FP_LOG, "[Set]00: 0x%04x (%02d:%08x)\n",
2603f472ca7SDylan Hung 			       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
2613f472ca7SDylan Hung 			       eng->run.mdio_base);
2625c8f9400Sryan_chen 	}
2635c8f9400Sryan_chen }
2645c8f9400Sryan_chen 
2655c8f9400Sryan_chen //------------------------------------------------------------
phy_wait_reset_done(MAC_ENGINE * eng)2663f472ca7SDylan Hung void phy_wait_reset_done(MAC_ENGINE *eng)
2673f472ca7SDylan Hung {
2685c8f9400Sryan_chen 	int timeout = 0;
2695c8f9400Sryan_chen 
2705c8f9400Sryan_chen 	while (phy_read(eng, PHY_REG_BMCR) & 0x8000) {
2715c8f9400Sryan_chen 		if (++timeout > TIME_OUT_PHY_Rst) {
2725c8f9400Sryan_chen 			if (!eng->run.tm_tx_only)
2733f472ca7SDylan Hung 				PRINTF(FP_LOG, "[PHY-Reset] Time out: %08x\n",
2743f472ca7SDylan Hung 				       readl(eng->run.mdio_base));
2755c8f9400Sryan_chen 
2765c8f9400Sryan_chen 			FindErr(eng, Err_Flag_PHY_TimeOut_Rst);
2775c8f9400Sryan_chen 			break;
2785c8f9400Sryan_chen 		}
2795c8f9400Sryan_chen 	} //wait Rst Done
2805c8f9400Sryan_chen 
2815c8f9400Sryan_chen 	if (DbgPrn_PHYRW) {
2823f472ca7SDylan Hung 		printf("[Clr]00: 0x%04x (%02d:%08x)\n",
2833f472ca7SDylan Hung 		       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
2843f472ca7SDylan Hung 		       eng->run.mdio_base);
2853f472ca7SDylan Hung 		if (!eng->run.tm_tx_only)
2863f472ca7SDylan Hung 			PRINTF(FP_LOG, "[Clr]00: 0x%04x (%02d:%08x)\n",
2873f472ca7SDylan Hung 			       phy_read(eng, PHY_REG_BMCR), eng->phy.Adr,
2883f472ca7SDylan Hung 			       eng->run.mdio_base);
2895c8f9400Sryan_chen 	}
2905c8f9400Sryan_chen #ifdef Delay_PHYRst
2915c8f9400Sryan_chen 	DELAY(Delay_PHYRst);
2925c8f9400Sryan_chen #endif
2935c8f9400Sryan_chen }
2945c8f9400Sryan_chen 
2955c8f9400Sryan_chen //------------------------------------------------------------
phy_reset(MAC_ENGINE * eng)2966a6965c4SDylan Hung static void phy_reset(MAC_ENGINE *eng)
2973f472ca7SDylan Hung {
2985c8f9400Sryan_chen 	phy_basic_setting(eng);
2995c8f9400Sryan_chen 
3003f472ca7SDylan Hung 	//phy_clrset(eng, 0, 0x0000, 0x8000 | eng->phy.PHY_00h);
3013f472ca7SDylan Hung 	phy_clrset(eng, 0, 0x7140, 0x8000 | eng->phy.PHY_00h);
3025c8f9400Sryan_chen 	//phy_write(eng, 0, 0x8000); //clr set//Rst PHY
3033f472ca7SDylan Hung 	phy_wait_reset_done(eng);
3045c8f9400Sryan_chen 
3055c8f9400Sryan_chen 	phy_basic_setting(eng);
3065c8f9400Sryan_chen #ifdef Delay_PHYRst
3075c8f9400Sryan_chen 	DELAY(Delay_PHYRst);
3085c8f9400Sryan_chen #endif
3095c8f9400Sryan_chen }
3105c8f9400Sryan_chen 
3115c8f9400Sryan_chen //------------------------------------------------------------
phy_check_register(MAC_ENGINE * eng,uint32_t adr,uint32_t check_mask,uint32_t check_value,uint32_t hit_number,char * runname)3125c8f9400Sryan_chen void phy_check_register (MAC_ENGINE *eng, uint32_t adr, uint32_t check_mask, uint32_t check_value, uint32_t hit_number, char *runname) {
3135c8f9400Sryan_chen         uint16_t     wait_phy_ready = 0;
3145c8f9400Sryan_chen         uint16_t     hit_count = 0;
3155c8f9400Sryan_chen 
3165c8f9400Sryan_chen         while ( wait_phy_ready < 1000 ) {
3175c8f9400Sryan_chen                 if ( (phy_read( eng, adr ) & check_mask) == check_value ) {
3185c8f9400Sryan_chen                         if ( ++hit_count >= hit_number ) {
3195c8f9400Sryan_chen                                 break;
3205c8f9400Sryan_chen                         }
3215c8f9400Sryan_chen                         else {
3225c8f9400Sryan_chen                                 phy_delay(1);
3235c8f9400Sryan_chen                         }
3245c8f9400Sryan_chen                 } else {
3255c8f9400Sryan_chen                         hit_count = 0;
3265c8f9400Sryan_chen                         wait_phy_ready++;
3275c8f9400Sryan_chen                         phy_delay(10);
3285c8f9400Sryan_chen                 }
3295c8f9400Sryan_chen         }
3305c8f9400Sryan_chen         if ( hit_count < hit_number ) {
3315c8f9400Sryan_chen                 printf("Timeout: %s\n", runname);
3325c8f9400Sryan_chen         }
3335c8f9400Sryan_chen }
3345c8f9400Sryan_chen 
3355c8f9400Sryan_chen //------------------------------------------------------------
3365c8f9400Sryan_chen // PHY IC
3375c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_marvell(MAC_ENGINE * eng)3385c8f9400Sryan_chen void recov_phy_marvell (MAC_ENGINE *eng) {//88E1111
3395c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
3405c8f9400Sryan_chen         }
3415c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
3425c8f9400Sryan_chen         }
3435c8f9400Sryan_chen         else {
3445c8f9400Sryan_chen 		if (eng->run.speed_sel[0]) {
3455c8f9400Sryan_chen 			phy_write(eng, 9, eng->phy.PHY_09h);
3465c8f9400Sryan_chen 
347ee3c59a9SDylan Hung 			phy_reset(eng);
3485c8f9400Sryan_chen 
3495c8f9400Sryan_chen 			phy_write(eng, 29, 0x0007);
350ff33b245SDylan Hung 			phy_clrset(eng, 30, 0x0008, 0x0000); //clr set
3515c8f9400Sryan_chen 			phy_write(eng, 29, 0x0010);
352ff33b245SDylan Hung 			phy_clrset(eng, 30, 0x0002, 0x0000); //clr set
3535c8f9400Sryan_chen 			phy_write(eng, 29, 0x0012);
354ff33b245SDylan Hung 			phy_clrset(eng, 30, 0x0001, 0x0000); //clr set
3555c8f9400Sryan_chen 
3565c8f9400Sryan_chen 			phy_write(eng, 18, eng->phy.PHY_12h);
3575c8f9400Sryan_chen 		}
3585c8f9400Sryan_chen 	}
3595c8f9400Sryan_chen }
3605c8f9400Sryan_chen 
3615c8f9400Sryan_chen //------------------------------------------------------------
phy_marvell(MAC_ENGINE * eng)362daba96f3SDylan Hung void phy_marvell (MAC_ENGINE *eng)
363daba96f3SDylan Hung {//88E1111
3645c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
365ee3c59a9SDylan Hung                 phy_reset( eng );
3665c8f9400Sryan_chen         }
3675c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
368ee3c59a9SDylan Hung                 phy_reset( eng );
3695c8f9400Sryan_chen         }
3705c8f9400Sryan_chen         else {
3715c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
3725c8f9400Sryan_chen                         eng->phy.PHY_09h = phy_read( eng, PHY_GBCR );
3735c8f9400Sryan_chen                         eng->phy.PHY_12h = phy_read( eng, PHY_INER );
3745c8f9400Sryan_chen                         phy_write( eng, 18, 0x0000 );
375ff33b245SDylan Hung                         phy_clrset( eng,  9, 0x0000, 0x1800 );//clr set
3765c8f9400Sryan_chen                 }
3775c8f9400Sryan_chen 
378ee3c59a9SDylan Hung                 phy_reset( eng );
3795c8f9400Sryan_chen 
3805c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
3815c8f9400Sryan_chen                         phy_write( eng, 29, 0x0007 );
382ff33b245SDylan Hung                         phy_clrset( eng, 30, 0x0000, 0x0008 );//clr set
3835c8f9400Sryan_chen                         phy_write( eng, 29, 0x0010 );
384ff33b245SDylan Hung                         phy_clrset( eng, 30, 0x0000, 0x0002 );//clr set
3855c8f9400Sryan_chen                         phy_write( eng, 29, 0x0012 );
386ff33b245SDylan Hung                         phy_clrset( eng, 30, 0x0000, 0x0001 );//clr set
3875c8f9400Sryan_chen                 }
3885c8f9400Sryan_chen         }
3895c8f9400Sryan_chen 
3905c8f9400Sryan_chen         if ( !eng->phy.loopback )
3915c8f9400Sryan_chen                 phy_check_register ( eng, 17, 0x0400, 0x0400, 1, "wait 88E1111 link-up");
3925c8f9400Sryan_chen //      Retry = 0;
3935c8f9400Sryan_chen //      do {
3945c8f9400Sryan_chen //              eng->phy.PHY_11h = phy_read( eng, PHY_SR );
3955c8f9400Sryan_chen //      } while ( !( ( eng->phy.PHY_11h & 0x0400 ) | eng->phy.loopback | ( Retry++ > 20 ) ) );
3965c8f9400Sryan_chen }
3975c8f9400Sryan_chen 
3985c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_marvell0(MAC_ENGINE * eng)3995c8f9400Sryan_chen void recov_phy_marvell0 (MAC_ENGINE *eng) {//88E1310
4005c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
4015c8f9400Sryan_chen         }
4025c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
4035c8f9400Sryan_chen         }
4045c8f9400Sryan_chen         else {
4055c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
4065c8f9400Sryan_chen                         phy_write( eng, 22, 0x0006 );
407ff33b245SDylan Hung                         phy_clrset( eng, 16, 0x0020, 0x0000 );//clr set
4085c8f9400Sryan_chen                         phy_write( eng, 22, 0x0000 );
4095c8f9400Sryan_chen                 }
4105c8f9400Sryan_chen         }
4115c8f9400Sryan_chen }
4125c8f9400Sryan_chen 
4135c8f9400Sryan_chen //------------------------------------------------------------
phy_marvell0(MAC_ENGINE * eng)4145c8f9400Sryan_chen void phy_marvell0 (MAC_ENGINE *eng) {//88E1310
4155c8f9400Sryan_chen //      int        Retry;
4165c8f9400Sryan_chen 
4175c8f9400Sryan_chen         phy_write( eng, 22, 0x0002 );
4185c8f9400Sryan_chen 
4195c8f9400Sryan_chen         eng->phy.PHY_15h = phy_read( eng, 21 );
4205c8f9400Sryan_chen         if ( eng->phy.PHY_15h & 0x0030 ) {
4215c8f9400Sryan_chen                 printf("\n\n[Warning] Page2, Register 21, bit 4~5 must be 0 [Reg15_2:%04x]\n\n", eng->phy.PHY_15h);
4225c8f9400Sryan_chen                 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 );
4235c8f9400Sryan_chen                 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 );
4245c8f9400Sryan_chen 
4255c8f9400Sryan_chen                 phy_write( eng, 21, eng->phy.PHY_15h & 0xffcf ); // Set [5]Rx Dly, [4]Tx Dly to 0
4265c8f9400Sryan_chen         }
4275c8f9400Sryan_chen phy_read( eng, 21 ); // v069
4285c8f9400Sryan_chen         phy_write( eng, 22, 0x0000 );
4295c8f9400Sryan_chen 
4305c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
431ee3c59a9SDylan Hung                 phy_reset( eng );
4325c8f9400Sryan_chen         }
4335c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
4345c8f9400Sryan_chen                 phy_write( eng, 22, 0x0002 );
4355c8f9400Sryan_chen 
4365c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
437ff33b245SDylan Hung                         phy_clrset( eng, 21, 0x6040, 0x0040 );//clr set
4385c8f9400Sryan_chen                 }
4395c8f9400Sryan_chen                 else if ( eng->run.speed_sel[ 1 ] ) {
440ff33b245SDylan Hung                         phy_clrset( eng, 21, 0x6040, 0x2000 );//clr set
4415c8f9400Sryan_chen                 }
4425c8f9400Sryan_chen                 else {
443ff33b245SDylan Hung                         phy_clrset( eng, 21, 0x6040, 0x0000 );//clr set
4445c8f9400Sryan_chen                 }
4455c8f9400Sryan_chen                 phy_write( eng, 22, 0x0000 );
446ee3c59a9SDylan Hung                 phy_reset(  eng  );
4475c8f9400Sryan_chen         }
4485c8f9400Sryan_chen         else {
4495c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
4505c8f9400Sryan_chen                         phy_write( eng, 22, 0x0006 );
451ff33b245SDylan Hung                         phy_clrset( eng, 16, 0x0000, 0x0020 );//clr set
4525c8f9400Sryan_chen phy_read( eng, 16 ); // v069
4535c8f9400Sryan_chen                         phy_write( eng, 22, 0x0000 );
4545c8f9400Sryan_chen                 }
4555c8f9400Sryan_chen 
456ee3c59a9SDylan Hung                 phy_reset( eng );
4575c8f9400Sryan_chen phy_read( eng, 0 ); // v069
4585c8f9400Sryan_chen         }
4595c8f9400Sryan_chen 
4605c8f9400Sryan_chen         if ( !eng->phy.loopback )
4615c8f9400Sryan_chen                 phy_check_register ( eng, 17, 0x0400, 0x0400, 1, "wait 88E1310 link-up");
4625c8f9400Sryan_chen //      Retry = 0;
4635c8f9400Sryan_chen //      do {
4645c8f9400Sryan_chen //              eng->phy.PHY_11h = phy_read( eng, PHY_SR );
4655c8f9400Sryan_chen //      } while ( !( ( eng->phy.PHY_11h & 0x0400 ) | eng->phy.loopback | ( Retry++ > 20 ) ) );
4665c8f9400Sryan_chen }
4675c8f9400Sryan_chen 
4685c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_marvell1(MAC_ENGINE * eng)4695c8f9400Sryan_chen void recov_phy_marvell1 (MAC_ENGINE *eng) {//88E6176
470daba96f3SDylan Hung         int8_t       phy_addr_org;
4715c8f9400Sryan_chen 
472daba96f3SDylan Hung         phy_addr_org = eng->phy.Adr;
4735c8f9400Sryan_chen         for ( eng->phy.Adr = 16; eng->phy.Adr <= 22; eng->phy.Adr++ ) {
4745c8f9400Sryan_chen                 if ( eng->run.tm_tx_only ) {
4755c8f9400Sryan_chen                 }
4765c8f9400Sryan_chen                 else {
4775c8f9400Sryan_chen                         phy_write( eng,  6, eng->phy.PHY_06hA[eng->phy.Adr-16] );//06h[5]P5 loopback, 06h[6]P6 loopback
4785c8f9400Sryan_chen                 }
4795c8f9400Sryan_chen         }
4805c8f9400Sryan_chen         for ( eng->phy.Adr = 21; eng->phy.Adr <= 22; eng->phy.Adr++ ) {
4815c8f9400Sryan_chen                 phy_write( eng,  1, 0x0003 ); //01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
4825c8f9400Sryan_chen         }
483daba96f3SDylan Hung         eng->phy.Adr = phy_addr_org;
4845c8f9400Sryan_chen }
4855c8f9400Sryan_chen 
4865c8f9400Sryan_chen //------------------------------------------------------------
phy_marvell1(MAC_ENGINE * eng)4875c8f9400Sryan_chen void phy_marvell1 (MAC_ENGINE *eng) {//88E6176
4885c8f9400Sryan_chen //      uint32_t      PHY_01h;
489daba96f3SDylan Hung         int8_t       phy_addr_org;
4905c8f9400Sryan_chen 
4915c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
4925c8f9400Sryan_chen                 printf("This mode doesn't support in 88E6176.\n");
4935c8f9400Sryan_chen         } else {
4945c8f9400Sryan_chen                 //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.
4955c8f9400Sryan_chen                 //Therefor, the 88E6176 only can run the internal loopback.
496daba96f3SDylan Hung                 phy_addr_org = eng->phy.Adr;
4975c8f9400Sryan_chen                 for ( eng->phy.Adr = 16; eng->phy.Adr <= 20; eng->phy.Adr++ ) {
4985c8f9400Sryan_chen                         eng->phy.PHY_06hA[eng->phy.Adr-16] = phy_read( eng, PHY_ANER );
4995c8f9400Sryan_chen                         phy_write( eng,  6, 0x0000 );//06h[5]P5 loopback, 06h[6]P6 loopback
5005c8f9400Sryan_chen                 }
5015c8f9400Sryan_chen 
5025c8f9400Sryan_chen                 for ( eng->phy.Adr = 21; eng->phy.Adr <= 22; eng->phy.Adr++ ) {
5035c8f9400Sryan_chen //                      PHY_01h = phy_read( eng, PHY_REG_BMSR );
5045c8f9400Sryan_chen //                      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.
5055c8f9400Sryan_chen //                      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.
5065c8f9400Sryan_chen //                      else                              phy_write( eng,  1, (PHY_01h & 0xfffc)          );//[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
5075c8f9400Sryan_chen                         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.
5085c8f9400Sryan_chen                         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.
5095c8f9400Sryan_chen                         else                                phy_write( eng,  1, 0x0000 );//01h[1:0]00 = 10 Mbps, 01 = 100 Mbps, 10 = 1000 Mbps, 11 = Speed is not forced.
5105c8f9400Sryan_chen 
5115c8f9400Sryan_chen                         eng->phy.PHY_06hA[eng->phy.Adr-16] = phy_read( eng, PHY_ANER );
5125c8f9400Sryan_chen                         if ( eng->phy.Adr == 21 ) phy_write( eng,  6, 0x0020 );//06h[5]P5 loopback, 06h[6]P6 loopback
5135c8f9400Sryan_chen                         else                      phy_write( eng,  6, 0x0040 );//06h[5]P5 loopback, 06h[6]P6 loopback
5145c8f9400Sryan_chen                 }
515daba96f3SDylan Hung                 eng->phy.Adr = phy_addr_org;
5165c8f9400Sryan_chen         }
5175c8f9400Sryan_chen }
5185c8f9400Sryan_chen 
5195c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_marvell2(MAC_ENGINE * eng)5205c8f9400Sryan_chen void recov_phy_marvell2 (MAC_ENGINE *eng) {//88E1512//88E15 10/12/14/18
5215c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
5225c8f9400Sryan_chen         }
5235c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
5245c8f9400Sryan_chen         }
5255c8f9400Sryan_chen         else {
5265c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
5275c8f9400Sryan_chen                         // Enable Stub Test
5285c8f9400Sryan_chen                         // switch page 6
5295c8f9400Sryan_chen                         phy_write( eng, 22, 0x0006 );
530ff33b245SDylan Hung                         phy_clrset( eng, 18, 0x0008, 0x0000 );//clr set
5315c8f9400Sryan_chen                         phy_write( eng, 22, 0x0000 );
5325c8f9400Sryan_chen                 }
5335c8f9400Sryan_chen         }
5345c8f9400Sryan_chen }
5355c8f9400Sryan_chen 
5365c8f9400Sryan_chen //------------------------------------------------------------
537414917c6SDylan Hung //88E1512//88E15 10/12/14/18
phy_marvell2(MAC_ENGINE * eng)538414917c6SDylan Hung void phy_marvell2 (MAC_ENGINE *eng)
539414917c6SDylan Hung {
540414917c6SDylan Hung 	/* switch to page 2 */
5415c8f9400Sryan_chen 	phy_write(eng, 22, 0x0002);
5425c8f9400Sryan_chen 	eng->phy.PHY_15h = phy_read(eng, 21);
543414917c6SDylan Hung 	eng->phy.PHY_15h &= ~GENMASK(5, 4);
544414917c6SDylan Hung 	if (eng->arg.ctrl.b.phy_tx_delay_en)
545414917c6SDylan Hung 		eng->phy.PHY_15h |= BIT(4);
546414917c6SDylan Hung 	if (eng->arg.ctrl.b.phy_rx_delay_en)
547414917c6SDylan Hung 		eng->phy.PHY_15h |= BIT(5);
5485c8f9400Sryan_chen 
549414917c6SDylan Hung 	phy_write(eng, 21, eng->phy.PHY_15h);
550414917c6SDylan Hung 
551414917c6SDylan Hung 	/* switch to page 0 */
5525c8f9400Sryan_chen 	phy_write(eng, 22, 0x0000);
5535c8f9400Sryan_chen 
5545c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
555ee3c59a9SDylan Hung                 phy_reset( eng );
5565c8f9400Sryan_chen         }
5575c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
5585c8f9400Sryan_chen                 // Internal loopback funciton only support in copper mode
5595c8f9400Sryan_chen                 // switch page 18
5605c8f9400Sryan_chen                 phy_write( eng, 22, 0x0012 );
5615c8f9400Sryan_chen                 eng->phy.PHY_14h = phy_read( eng, 20 );
5625c8f9400Sryan_chen                 // Change mode to Copper mode
5635c8f9400Sryan_chen //              if ( eng->phy.PHY_14h & 0x0020 ) {
5645c8f9400Sryan_chen                 if ( ( eng->phy.PHY_14h & 0x003f ) != 0x0010 ) {
5655c8f9400Sryan_chen                         printf("\n\n[Warning] Internal loopback funciton only support in copper mode[%04x]\n\n", eng->phy.PHY_14h);
5665c8f9400Sryan_chen                         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);
5675c8f9400Sryan_chen                         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);
5685c8f9400Sryan_chen 
5695c8f9400Sryan_chen                         phy_write( eng, 20, ( eng->phy.PHY_14h & 0xffc0 ) | 0x8010 );
5705c8f9400Sryan_chen                         // do software reset
5715c8f9400Sryan_chen                         phy_check_register ( eng, 20, 0x8000, 0x0000, 1, "wait 88E15 10/12/14/18 mode reset");
5725c8f9400Sryan_chen //                      do {
5735c8f9400Sryan_chen //                              temp_reg = phy_read( eng, 20 );
5745c8f9400Sryan_chen //                      } while ( ( (temp_reg & 0x8000) == 0x8000 ) & (Retry++ < 20) );
5755c8f9400Sryan_chen                 }
5765c8f9400Sryan_chen 
5775c8f9400Sryan_chen                 // switch page 2
5785c8f9400Sryan_chen                 phy_write( eng, 22, 0x0002 );
5795c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
580ff33b245SDylan Hung                         phy_clrset( eng, 21, 0x2040, 0x0040 );//clr set
5815c8f9400Sryan_chen                 }
5825c8f9400Sryan_chen                 else if ( eng->run.speed_sel[ 1 ] ) {
583ff33b245SDylan Hung                         phy_clrset( eng, 21, 0x2040, 0x2000 );//clr set
5845c8f9400Sryan_chen                 }
5855c8f9400Sryan_chen                 else {
586ff33b245SDylan Hung                         phy_clrset( eng, 21, 0x2040, 0x0000 );//clr set
5875c8f9400Sryan_chen                 }
5885c8f9400Sryan_chen                 phy_write( eng, 22, 0x0000 );
5895c8f9400Sryan_chen 
590ee3c59a9SDylan Hung                 phy_reset( eng );
5915c8f9400Sryan_chen 
5925c8f9400Sryan_chen                 //Internal loopback at 100Mbps need delay 400~500 ms
5935c8f9400Sryan_chen //              DELAY( 400 );//Still fail at 100Mbps
5945c8f9400Sryan_chen //              DELAY( 500 );//All Pass
5955c8f9400Sryan_chen                 if ( !eng->run.speed_sel[ 0 ] ) {
5965c8f9400Sryan_chen                         phy_check_register ( eng, 17, 0x0040, 0x0040, 10, "wait 88E15 10/12/14/18 link-up");
5975c8f9400Sryan_chen                         phy_check_register ( eng, 17, 0x0040, 0x0000, 10, "wait 88E15 10/12/14/18 link-up");
5985c8f9400Sryan_chen                         phy_check_register ( eng, 17, 0x0040, 0x0040, 10, "wait 88E15 10/12/14/18 link-up");
5995c8f9400Sryan_chen                 }
6005c8f9400Sryan_chen         }
6015c8f9400Sryan_chen         else {
6025c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
6035c8f9400Sryan_chen                         // Enable Stub Test
6045c8f9400Sryan_chen                         // switch page 6
6055c8f9400Sryan_chen                         phy_write( eng, 22, 0x0006 );
606ff33b245SDylan Hung                         phy_clrset( eng, 18, 0x0000, 0x0008 );//clr set
6075c8f9400Sryan_chen                         phy_write( eng, 22, 0x0000 );
6085c8f9400Sryan_chen                 }
6095c8f9400Sryan_chen 
610ee3c59a9SDylan Hung                 phy_reset( eng );
6115c8f9400Sryan_chen                 phy_check_register ( eng, 17, 0x0400, 0x0400, 10, "wait 88E15 10/12/14/18 link-up");
6125c8f9400Sryan_chen         }
6135c8f9400Sryan_chen 
6145c8f9400Sryan_chen //      if ( !eng->phy.loopback )
6155c8f9400Sryan_chen ////    if ( !eng->run.tm_tx_only )
6165c8f9400Sryan_chen //              phy_check_register ( eng, 17, 0x0400, 0x0400, 10, "wait 88E15 10/12/14/18 link-up");
6175c8f9400Sryan_chen ////    Retry = 0;
6185c8f9400Sryan_chen ////    do {
6195c8f9400Sryan_chen ////            eng->phy.PHY_11h = phy_read( eng, PHY_SR );
6205c8f9400Sryan_chen ////    } while ( !( ( eng->phy.PHY_11h & 0x0400 ) | eng->phy.loopback | ( Retry++ > 20 ) ) );
6215c8f9400Sryan_chen }
6225c8f9400Sryan_chen 
6235c8f9400Sryan_chen //------------------------------------------------------------
phy_marvell3(MAC_ENGINE * eng)6245c8f9400Sryan_chen void phy_marvell3 (MAC_ENGINE *eng)
6255c8f9400Sryan_chen {//88E3019
6265c8f9400Sryan_chen 
6275c8f9400Sryan_chen         //Reg1ch[11:10]: MAC Interface Mode
6285c8f9400Sryan_chen         // 00 => RGMII where receive clock trnasitions when data transitions
6295c8f9400Sryan_chen         // 01 => RGMII where receive clock trnasitions when data is stable
6305c8f9400Sryan_chen         // 10 => RMII
6315c8f9400Sryan_chen         // 11 => MII
6325c8f9400Sryan_chen         eng->phy.PHY_1ch = phy_read( eng, 28 );
6335c8f9400Sryan_chen         if (eng->run.is_rgmii) {
6345c8f9400Sryan_chen                 if ( ( eng->phy.PHY_1ch & 0x0c00 ) != 0x0000 ) {
6355c8f9400Sryan_chen                         printf("\n\n[Warning] Register 28, bit 10~11 must be 0 (RGMIIRX Edge-align Mode)[Reg1ch:%04x]\n\n", eng->phy.PHY_1ch);
6365c8f9400Sryan_chen                         eng->phy.PHY_1ch = ( eng->phy.PHY_1ch & 0xf3ff ) | 0x0000;
6375c8f9400Sryan_chen                         phy_write( eng, 28, eng->phy.PHY_1ch );
6385c8f9400Sryan_chen                 }
6395c8f9400Sryan_chen         } else {
6405c8f9400Sryan_chen                 if ( ( eng->phy.PHY_1ch & 0x0c00 ) != 0x0800 ) {
6415c8f9400Sryan_chen                         printf("\n\n[Warning] Register 28, bit 10~11 must be 2 (RMII Mode)[Reg1ch:%04x]\n\n", eng->phy.PHY_1ch);
6425c8f9400Sryan_chen                         eng->phy.PHY_1ch = ( eng->phy.PHY_1ch & 0xf3ff ) | 0x0800;
6435c8f9400Sryan_chen                         phy_write( eng, 28, eng->phy.PHY_1ch );
6445c8f9400Sryan_chen                 }
6455c8f9400Sryan_chen         }
6465c8f9400Sryan_chen 
6475c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
648ee3c59a9SDylan Hung                 phy_reset( eng );
6495c8f9400Sryan_chen         }
6505c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
651ee3c59a9SDylan Hung                 phy_reset( eng );
6525c8f9400Sryan_chen         }
6535c8f9400Sryan_chen         else {
654ee3c59a9SDylan Hung                 phy_reset( eng );
6555c8f9400Sryan_chen         }
6565c8f9400Sryan_chen 
6575c8f9400Sryan_chen         phy_check_register ( eng, 17, 0x0400, 0x0400, 1, "wait 88E3019 link-up");
6585c8f9400Sryan_chen }
6595c8f9400Sryan_chen 
6605c8f9400Sryan_chen //------------------------------------------------------------
phy_broadcom(MAC_ENGINE * eng)6615b4262ddSDylan Hung void phy_broadcom (MAC_ENGINE *eng)
6625b4262ddSDylan Hung {//BCM5221
6635c8f9400Sryan_chen 	uint32_t      reg;
6645c8f9400Sryan_chen 
665ee3c59a9SDylan Hung         phy_reset( eng );
6665c8f9400Sryan_chen 
6675c8f9400Sryan_chen         if ( eng->run.TM_IEEE ) {
6685c8f9400Sryan_chen                 if ( eng->run.ieee_sel == 0 ) {
6695c8f9400Sryan_chen                         phy_write( eng, 25, 0x1f01 );//Force MDI  //Measuring from channel A
6705c8f9400Sryan_chen                 }
6715c8f9400Sryan_chen                 else {
672ff33b245SDylan Hung                         phy_clrset( eng, 24, 0x0000, 0x4000 );//clr set//Force Link
6735c8f9400Sryan_chen //                      phy_write( eng,  0, eng->phy.PHY_00h );
6745c8f9400Sryan_chen //                      phy_write( eng, 30, 0x1000 );
6755c8f9400Sryan_chen                 }
6765c8f9400Sryan_chen         }
6775c8f9400Sryan_chen         else
6785c8f9400Sryan_chen         {
6795c8f9400Sryan_chen                 // we can check link status from register 0x18
6805c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 1 ] ) {
6815c8f9400Sryan_chen                         do {
6825c8f9400Sryan_chen                                 reg = phy_read( eng, 0x18 ) & 0xF;
6835c8f9400Sryan_chen                         } while ( reg != 0x7 );
6845c8f9400Sryan_chen                 }
6855c8f9400Sryan_chen                 else {
6865c8f9400Sryan_chen                         do {
6875c8f9400Sryan_chen                         reg = phy_read( eng, 0x18 ) & 0xF;
6885c8f9400Sryan_chen                         } while ( reg != 0x1 );
6895c8f9400Sryan_chen                 }
6905c8f9400Sryan_chen         }
6915c8f9400Sryan_chen }
6925c8f9400Sryan_chen 
6935c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_broadcom0(MAC_ENGINE * eng)6945c8f9400Sryan_chen void recov_phy_broadcom0 (MAC_ENGINE *eng) {//BCM54612
6955c8f9400Sryan_chen         phy_write( eng,  0, eng->phy.PHY_00h );
6965c8f9400Sryan_chen         phy_write( eng,  9, eng->phy.PHY_09h );
6975c8f9400Sryan_chen //      phy_write( eng, 24, eng->phy.PHY_18h | 0xf007 );//write reg 18h, shadow value 111
6985c8f9400Sryan_chen //      phy_write( eng, 28, eng->phy.PHY_1ch | 0x8c00 );//write reg 1Ch, shadow value 00011
6995c8f9400Sryan_chen 
7005c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
7015c8f9400Sryan_chen         }
7025c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
7035c8f9400Sryan_chen                 phy_write( eng,  0, eng->phy.PHY_00h );
7045c8f9400Sryan_chen         }
7055c8f9400Sryan_chen         else {
7065c8f9400Sryan_chen         }
7075c8f9400Sryan_chen }
7085c8f9400Sryan_chen 
7095c8f9400Sryan_chen //------------------------------------------------------------
7105c8f9400Sryan_chen //internal loop 1G  : no  loopback stub
7115c8f9400Sryan_chen //internal loop 100M: Don't support(?)
7125c8f9400Sryan_chen //internal loop 10M : Don't support(?)
phy_broadcom0(MAC_ENGINE * eng)7135b4262ddSDylan Hung void phy_broadcom0 (MAC_ENGINE *eng)
7145b4262ddSDylan Hung {
7155c8f9400Sryan_chen 	uint32_t PHY_new;
7165c8f9400Sryan_chen 
717ee3c59a9SDylan Hung 	phy_reset(eng);
7185c8f9400Sryan_chen 
7195c8f9400Sryan_chen         eng->phy.PHY_00h = phy_read( eng, PHY_REG_BMCR );
7205c8f9400Sryan_chen         eng->phy.PHY_09h = phy_read( eng, PHY_GBCR );
7215c8f9400Sryan_chen 
7225c8f9400Sryan_chen 	phy_write( eng, 0, eng->phy.PHY_00h & ~BIT(10));
7235c8f9400Sryan_chen 
724414917c6SDylan Hung 	/*
725414917c6SDylan Hung 	 * RX interface delay: reg 0x18, shadow value b'0111: misc control
726414917c6SDylan Hung 	 * bit[8] RGMII RXD to RXC skew
727414917c6SDylan Hung 	 */
728414917c6SDylan Hung 	phy_write(eng, 0x18, (0x7 << 12) | 0x7);
729414917c6SDylan Hung 	eng->phy.PHY_18h = phy_read(eng, 0x18);
730414917c6SDylan Hung 	PHY_new = eng->phy.PHY_18h & ~((0x7 << 12) | 0x7 | BIT(8));
731414917c6SDylan Hung 	PHY_new |= (0x7 << 12) | 0x7 | BIT(15);
732414917c6SDylan Hung 	if (eng->arg.ctrl.b.phy_rx_delay_en)
733414917c6SDylan Hung 		PHY_new |= BIT(8);
734414917c6SDylan Hung 	phy_write(eng, 0x18, PHY_new);
7355b4262ddSDylan Hung 
736414917c6SDylan Hung 	/*
737414917c6SDylan Hung 	 * TX interface delay: reg 0x1c, shadow value b'0011: clock alignment
738414917c6SDylan Hung 	 * control
739414917c6SDylan Hung 	 * bit[9] GTXCLK clock delay enable
740414917c6SDylan Hung 	 */
741414917c6SDylan Hung 	phy_write(eng, 0x1c, 0x3 << 10);
742414917c6SDylan Hung 	eng->phy.PHY_1ch = phy_read(eng, 0x1c);
743414917c6SDylan Hung 	PHY_new = eng->phy.PHY_1ch & ~((0x1f << 10) | BIT(9));
744414917c6SDylan Hung 	PHY_new |= (0x3 << 10) | BIT(15);
745414917c6SDylan Hung 	if (eng->arg.ctrl.b.phy_tx_delay_en)
746414917c6SDylan Hung 		PHY_new |= BIT(9);
747414917c6SDylan Hung 	phy_write(eng, 0x1c, PHY_new);
7485c8f9400Sryan_chen 
7495c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
7505c8f9400Sryan_chen                 phy_basic_setting(eng);
751579a4c36SDylan Hung         } else if (eng->phy.loopback) {
752e1be0065SDylan Hung 		phy_basic_setting(eng);
753579a4c36SDylan Hung 		/* reg1E[12]: force-link */
75491907bc5SDylan Hung 		if (strncmp((char *)eng->phy.phy_name, "BCM5421x", strlen("BCM5421x")) == 0)
755579a4c36SDylan Hung 			phy_write(eng, 0x1e, BIT(12));
756579a4c36SDylan Hung 	} else {
7575c8f9400Sryan_chen 		if (eng->run.speed_sel[0]) {
758579a4c36SDylan Hung 			phy_write(eng, 0x9, 0x1800);
759579a4c36SDylan Hung 			phy_write(eng, 0x0, 0x0140);
760579a4c36SDylan Hung 			phy_write(eng, 0x18, 0x8400);
761579a4c36SDylan Hung 		} else if (eng->run.speed_sel[1]) {
762579a4c36SDylan Hung 			phy_write(eng, 0x0, 0x2100);
763579a4c36SDylan Hung 			phy_write(eng, 0x18, 0x8400);
764579a4c36SDylan Hung 		} else {
765579a4c36SDylan Hung 			phy_write(eng, 0x0, 0x0100);
766579a4c36SDylan Hung 			phy_write(eng, 0x18, 0x8400);
7675c8f9400Sryan_chen 		}
7685c8f9400Sryan_chen 	}
769b265bb8cSDylan Hung 	mdelay(100);
7705c8f9400Sryan_chen }
7715c8f9400Sryan_chen 
7725c8f9400Sryan_chen //------------------------------------------------------------
phy_realtek(MAC_ENGINE * eng)7735b4262ddSDylan Hung void phy_realtek (MAC_ENGINE *eng)
7745b4262ddSDylan Hung {//RTL8201N
7755c8f9400Sryan_chen 
776ee3c59a9SDylan Hung         phy_reset( eng );
7775c8f9400Sryan_chen }
7785c8f9400Sryan_chen 
7795c8f9400Sryan_chen //------------------------------------------------------------
7805c8f9400Sryan_chen //internal loop 100M: Don't support
7815c8f9400Sryan_chen //internal loop 10M : no  loopback stub
phy_realtek0(MAC_ENGINE * eng)7825b4262ddSDylan Hung void phy_realtek0 (MAC_ENGINE *eng)
7835b4262ddSDylan Hung {//RTL8201E
7845c8f9400Sryan_chen 
7855c8f9400Sryan_chen         eng->phy.RMIICK_IOMode |= PHY_Flag_RMIICK_IOMode_RTL8201E;
7865c8f9400Sryan_chen 
787ee3c59a9SDylan Hung         phy_reset( eng );
7885c8f9400Sryan_chen 
7895c8f9400Sryan_chen         eng->phy.PHY_19h = phy_read( eng, 25 );
7905c8f9400Sryan_chen         //Check RMII Mode
7915c8f9400Sryan_chen         if ( ( eng->phy.PHY_19h & 0x0400 ) == 0x0 ) {
7925c8f9400Sryan_chen                 phy_write( eng, 25, eng->phy.PHY_19h | 0x0400 );
7935c8f9400Sryan_chen                 printf("\n\n[Warning] Register 25, bit 10 must be 1 [Reg19h:%04x]\n\n", eng->phy.PHY_19h);
7945c8f9400Sryan_chen                 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 );
7955c8f9400Sryan_chen                 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 );
7965c8f9400Sryan_chen         }
7975c8f9400Sryan_chen         //Check TXC Input/Output Direction
7985c8f9400Sryan_chen         if ( eng->arg.ctrl.b.rmii_phy_in == 0 ) {
7995c8f9400Sryan_chen                 if ( ( eng->phy.PHY_19h & 0x0800 ) == 0x0800 ) {
8005c8f9400Sryan_chen                         phy_write( eng, 25, eng->phy.PHY_19h & 0xf7ff );
8015c8f9400Sryan_chen                         printf("\n\n[Warning] Register 25, bit 11 must be 0 (TXC should be output mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h);
8025c8f9400Sryan_chen                         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 );
8035c8f9400Sryan_chen                         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 );
8045c8f9400Sryan_chen                 }
8055c8f9400Sryan_chen         } else {
8065c8f9400Sryan_chen                 if ( ( eng->phy.PHY_19h & 0x0800 ) == 0x0000 ) {
8075c8f9400Sryan_chen                         phy_write( eng, 25, eng->phy.PHY_19h | 0x0800 );
8085c8f9400Sryan_chen                         printf("\n\n[Warning] Register 25, bit 11 must be 1 (TXC should be input mode)[Reg19h:%04x]\n\n", eng->phy.PHY_19h);
8095c8f9400Sryan_chen                         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 );
8105c8f9400Sryan_chen                         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 );
8115c8f9400Sryan_chen                 }
8125c8f9400Sryan_chen         }
8135c8f9400Sryan_chen 
8145c8f9400Sryan_chen         if ( eng->run.TM_IEEE ) {
8155c8f9400Sryan_chen                 phy_write( eng, 31, 0x0001 );
8165c8f9400Sryan_chen                 if ( eng->run.ieee_sel == 0 ) {
8175c8f9400Sryan_chen                         phy_write( eng, 25, 0x1f01 );//Force MDI  //Measuring from channel A
8185c8f9400Sryan_chen                 }
8195c8f9400Sryan_chen                 else {
8205c8f9400Sryan_chen                         phy_write( eng, 25, 0x1f00 );//Force MDIX //Measuring from channel B
8215c8f9400Sryan_chen                 }
8225c8f9400Sryan_chen                 phy_write( eng, 31, 0x0000 );
8235c8f9400Sryan_chen         }
8245c8f9400Sryan_chen }
8255c8f9400Sryan_chen 
8265c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_realtek1(MAC_ENGINE * eng)8275c8f9400Sryan_chen void recov_phy_realtek1 (MAC_ENGINE *eng) {//RTL8211D
8285c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
8295c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
8305c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 0 ] ) {
8315c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {//Test Mode 1
8325c8f9400Sryan_chen                                         //Rev 1.2
8335c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0002 );
8345c8f9400Sryan_chen                                         phy_write( eng,  2, 0xc203 );
8355c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0000 );
8365c8f9400Sryan_chen                                         phy_write( eng,  9, 0x0000 );
8375c8f9400Sryan_chen                                 }
8385c8f9400Sryan_chen                                 else {//Test Mode 4
8395c8f9400Sryan_chen                                         //Rev 1.2
8405c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0000 );
8415c8f9400Sryan_chen                                         phy_write( eng,  9, 0x0000 );
8425c8f9400Sryan_chen                                 }
8435c8f9400Sryan_chen                         }
8445c8f9400Sryan_chen                         else if ( eng->run.speed_sel[ 1 ] ) {
8455c8f9400Sryan_chen                                 //Rev 1.2
8465c8f9400Sryan_chen                                 phy_write( eng, 23, 0x2100 );
8475c8f9400Sryan_chen                                 phy_write( eng, 16, 0x016e );
8485c8f9400Sryan_chen                         }
8495c8f9400Sryan_chen                         else {
8505c8f9400Sryan_chen                                 //Rev 1.2
8515c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0006 );
8525c8f9400Sryan_chen                                 phy_write( eng,  0, 0x5a00 );
8535c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
8545c8f9400Sryan_chen                         }
8555c8f9400Sryan_chen                 } else {
856ee3c59a9SDylan Hung                         phy_reset( eng );
8575c8f9400Sryan_chen                 } // End if ( eng->run.TM_IEEE )
8585c8f9400Sryan_chen         }
8595c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
8605c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
8615c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 ); // new in Rev. 1.6
8625c8f9400Sryan_chen                         phy_write( eng,  0, 0x1140 ); // new in Rev. 1.6
8635c8f9400Sryan_chen                         phy_write( eng, 20, 0x8040 ); // new in Rev. 1.6
8645c8f9400Sryan_chen                 }
8655c8f9400Sryan_chen         }
8665c8f9400Sryan_chen         else {
8675c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
8685c8f9400Sryan_chen                         phy_write( eng, 31, 0x0001 );
8695c8f9400Sryan_chen                         phy_write( eng,  3, 0xdf41 );
8705c8f9400Sryan_chen                         phy_write( eng,  2, 0xdf20 );
8715c8f9400Sryan_chen                         phy_write( eng,  1, 0x0140 );
8725c8f9400Sryan_chen                         phy_write( eng,  0, 0x00bb );
8735c8f9400Sryan_chen                         phy_write( eng,  4, 0xb800 );
8745c8f9400Sryan_chen                         phy_write( eng,  4, 0xb000 );
8755c8f9400Sryan_chen 
8765c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
8775c8f9400Sryan_chen //                      phy_write( eng, 26, 0x0020 ); // Rev. 1.2
8785c8f9400Sryan_chen                         phy_write( eng, 26, 0x0040 ); // new in Rev. 1.6
8795c8f9400Sryan_chen                         phy_write( eng,  0, 0x1140 );
8805c8f9400Sryan_chen //                      phy_write( eng, 21, 0x0006 ); // Rev. 1.2
8815c8f9400Sryan_chen                         phy_write( eng, 21, 0x1006 ); // new in Rev. 1.6
8825c8f9400Sryan_chen                         phy_write( eng, 23, 0x2100 );
8835c8f9400Sryan_chen //              }
8845c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 1 ] ) {//option
8855c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
8865c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0200 );
8875c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
8885c8f9400Sryan_chen //              }
8895c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 2 ] ) {//option
8905c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
8915c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0200 );
8925c8f9400Sryan_chen //                      phy_write( eng,  4, 0x05e1 );
8935c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
8945c8f9400Sryan_chen                 }
895ee3c59a9SDylan Hung                 phy_reset( eng );
8965c8f9400Sryan_chen                 phy_delay(2000);
8975c8f9400Sryan_chen         } // End if ( eng->run.tm_tx_only )
8985c8f9400Sryan_chen } // End void recov_phy_realtek1 (MAC_ENGINE *eng)
8995c8f9400Sryan_chen 
9005c8f9400Sryan_chen //------------------------------------------------------------
9015c8f9400Sryan_chen //internal loop 1G  : no  loopback stub
9025c8f9400Sryan_chen //internal loop 100M: no  loopback stub
9035c8f9400Sryan_chen //internal loop 10M : no  loopback stub
phy_realtek1(MAC_ENGINE * eng)9045b4262ddSDylan Hung void phy_realtek1 (MAC_ENGINE *eng)
9055b4262ddSDylan Hung {//RTL8211D
9065c8f9400Sryan_chen 
9075c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
9085c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
9095c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 0 ] ) {
9105c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {//Test Mode 1
9115c8f9400Sryan_chen                                         //Rev 1.2
9125c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0002 );
9135c8f9400Sryan_chen                                         phy_write( eng,  2, 0xc22b );
9145c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0000 );
9155c8f9400Sryan_chen                                         phy_write( eng,  9, 0x2000 );
9165c8f9400Sryan_chen                                 }
9175c8f9400Sryan_chen                                 else {//Test Mode 4
9185c8f9400Sryan_chen                                         //Rev 1.2
9195c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0000 );
9205c8f9400Sryan_chen                                         phy_write( eng,  9, 0x8000 );
9215c8f9400Sryan_chen                                 }
9225c8f9400Sryan_chen                         }
9235c8f9400Sryan_chen                         else if ( eng->run.speed_sel[ 1 ] ) {
9245c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {//From Channel A
9255c8f9400Sryan_chen                                         //Rev 1.2
9265c8f9400Sryan_chen                                         phy_write( eng, 23, 0xa102 );
9275c8f9400Sryan_chen                                         phy_write( eng, 16, 0x01ae );//MDI
9285c8f9400Sryan_chen                                 }
9295c8f9400Sryan_chen                                 else {//From Channel B
9305c8f9400Sryan_chen                                         //Rev 1.2
931ff33b245SDylan Hung                                         phy_clrset( eng, 17, 0x0008, 0x0000 ); // clr set
9325c8f9400Sryan_chen                                         phy_write( eng, 23, 0xa102 );         // MDI
9335c8f9400Sryan_chen                                         phy_write( eng, 16, 0x010e );
9345c8f9400Sryan_chen                                 }
9355c8f9400Sryan_chen                         }
9365c8f9400Sryan_chen                         else {
9375c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {//Diff. Voltage/TP-IDL/Jitter: Pseudo-random pattern
9385c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0006 );
9395c8f9400Sryan_chen                                         phy_write( eng,  0, 0x5a21 );
9405c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0000 );
9415c8f9400Sryan_chen                                 }
9425c8f9400Sryan_chen                                 else if ( eng->run.ieee_sel == 1 ) {//Harmonic: pattern
9435c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0006 );
9445c8f9400Sryan_chen                                         phy_write( eng,  2, 0x05ee );
9455c8f9400Sryan_chen                                         phy_write( eng,  0, 0xff21 );
9465c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0000 );
9475c8f9400Sryan_chen                                 }
9485c8f9400Sryan_chen                                 else {//Harmonic: �00� pattern
9495c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0006 );
9505c8f9400Sryan_chen                                         phy_write( eng,  2, 0x05ee );
9515c8f9400Sryan_chen                                         phy_write( eng,  0, 0x0021 );
9525c8f9400Sryan_chen                                         phy_write( eng, 31, 0x0000 );
9535c8f9400Sryan_chen                                 }
9545c8f9400Sryan_chen                         }
9555c8f9400Sryan_chen                 }
9565c8f9400Sryan_chen                 else {
957ee3c59a9SDylan Hung                         phy_reset( eng );
9585c8f9400Sryan_chen                 }
9595c8f9400Sryan_chen         }
9605c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
961ee3c59a9SDylan Hung                 phy_reset( eng );
9625c8f9400Sryan_chen 
9635c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
9645c8f9400Sryan_chen                         phy_write( eng, 20, 0x0042 );//new in Rev. 1.6
9655c8f9400Sryan_chen                 }
9665c8f9400Sryan_chen         }
9675c8f9400Sryan_chen         else {
9685c8f9400Sryan_chen         // refer to RTL8211D Register for Manufacture Test_V1.6.pdf
9695c8f9400Sryan_chen         // MDI loop back
9705c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
9715c8f9400Sryan_chen                         phy_write( eng, 31, 0x0001 );
9725c8f9400Sryan_chen                         phy_write( eng,  3, 0xff41 );
9735c8f9400Sryan_chen                         phy_write( eng,  2, 0xd720 );
9745c8f9400Sryan_chen                         phy_write( eng,  1, 0x0140 );
9755c8f9400Sryan_chen                         phy_write( eng,  0, 0x00bb );
9765c8f9400Sryan_chen                         phy_write( eng,  4, 0xb800 );
9775c8f9400Sryan_chen                         phy_write( eng,  4, 0xb000 );
9785c8f9400Sryan_chen 
9795c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
9805c8f9400Sryan_chen                         phy_write( eng, 30, 0x0040 );
9815c8f9400Sryan_chen                         phy_write( eng, 24, 0x0008 );
9825c8f9400Sryan_chen 
9835c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
9845c8f9400Sryan_chen                         phy_write( eng,  9, 0x0300 );
9855c8f9400Sryan_chen                         phy_write( eng, 26, 0x0020 );
9865c8f9400Sryan_chen                         phy_write( eng,  0, 0x0140 );
9875c8f9400Sryan_chen                         phy_write( eng, 23, 0xa101 );
9885c8f9400Sryan_chen                         phy_write( eng, 21, 0x0200 );
9895c8f9400Sryan_chen                         phy_write( eng, 23, 0xa121 );
9905c8f9400Sryan_chen                         phy_write( eng, 23, 0xa161 );
9915c8f9400Sryan_chen                         phy_write( eng,  0, 0x8000 );
9923f472ca7SDylan Hung                         phy_wait_reset_done( eng );
9935c8f9400Sryan_chen 
9945c8f9400Sryan_chen //                      phy_delay(200); // new in Rev. 1.6
9955c8f9400Sryan_chen                         phy_delay(5000); // 20150504
9965c8f9400Sryan_chen //              }
9975c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 1 ] ) {//option
9985c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
9995c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0000 );
10005c8f9400Sryan_chen //                      phy_write( eng,  4, 0x0061 );
10015c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
10025c8f9400Sryan_chen //                      phy_delay(5000);
10035c8f9400Sryan_chen //              }
10045c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 2 ] ) {//option
10055c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
10065c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0000 );
10075c8f9400Sryan_chen //                      phy_write( eng,  4, 0x05e1 );
10085c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
10095c8f9400Sryan_chen //                      phy_delay(5000);
10105c8f9400Sryan_chen                 }
10115c8f9400Sryan_chen                 else {
1012ee3c59a9SDylan Hung                         phy_reset( eng );
10135c8f9400Sryan_chen                 }
10145c8f9400Sryan_chen         }
10155c8f9400Sryan_chen } // End void phy_realtek1 (MAC_ENGINE *eng)
10165c8f9400Sryan_chen 
10175c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_realtek2(MAC_ENGINE * eng)10185c8f9400Sryan_chen void recov_phy_realtek2 (MAC_ENGINE *eng)
10195c8f9400Sryan_chen {
10205c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nClear RTL8211E [Start] =====>\n");
10215c8f9400Sryan_chen 
10225c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
10235c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
10245c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 0 ] ) {
10255c8f9400Sryan_chen                                 //Rev 1.2
10265c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
10275c8f9400Sryan_chen                                 phy_write( eng,  9, 0x0000 );
10285c8f9400Sryan_chen                         }
10295c8f9400Sryan_chen                         else if ( eng->run.speed_sel[ 1 ] ) {
10305c8f9400Sryan_chen                                 //Rev 1.2
10315c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0007 );
10325c8f9400Sryan_chen                                 phy_write( eng, 30, 0x002f );
10335c8f9400Sryan_chen                                 phy_write( eng, 23, 0xd88f );
10345c8f9400Sryan_chen                                 phy_write( eng, 30, 0x002d );
10355c8f9400Sryan_chen                                 phy_write( eng, 24, 0xf050 );
10365c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
10375c8f9400Sryan_chen                                 phy_write( eng, 16, 0x006e );
10385c8f9400Sryan_chen                         }
10395c8f9400Sryan_chen                         else {
10405c8f9400Sryan_chen                                 //Rev 1.2
10415c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0006 );
10425c8f9400Sryan_chen                                 phy_write( eng,  0, 0x5a00 );
10435c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
10445c8f9400Sryan_chen                         }
10455c8f9400Sryan_chen                         //Rev 1.2
10465c8f9400Sryan_chen                         phy_write( eng, 31, 0x0005 );
10475c8f9400Sryan_chen                         phy_write( eng,  5, 0x8b86 );
10485c8f9400Sryan_chen                         phy_write( eng,  6, 0xe201 );
10495c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
10505c8f9400Sryan_chen                         phy_write( eng, 30, 0x0020 );
10515c8f9400Sryan_chen                         phy_write( eng, 21, 0x1108 );
10525c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
10535c8f9400Sryan_chen                 }
10545c8f9400Sryan_chen                 else {
10555c8f9400Sryan_chen                 }
10565c8f9400Sryan_chen         }
10575c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
10585c8f9400Sryan_chen         }
10595c8f9400Sryan_chen         else {
10605c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
10615c8f9400Sryan_chen                         //Rev 1.6
10625c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
10635c8f9400Sryan_chen                         phy_write( eng,  0, 0x8000 );
10645c8f9400Sryan_chen #ifdef RTK_DEBUG
10655c8f9400Sryan_chen #else
10663f472ca7SDylan Hung                         phy_wait_reset_done( eng );
10675c8f9400Sryan_chen                         phy_delay(30);
10685c8f9400Sryan_chen #endif
10695c8f9400Sryan_chen 
10705c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
10715c8f9400Sryan_chen                         phy_write( eng, 30, 0x0042 );
10725c8f9400Sryan_chen                         phy_write( eng, 21, 0x0500 );
10735c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
10745c8f9400Sryan_chen                         phy_write( eng,  0, 0x1140 );
10755c8f9400Sryan_chen                         phy_write( eng, 26, 0x0040 );
10765c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
10775c8f9400Sryan_chen                         phy_write( eng, 30, 0x002f );
10785c8f9400Sryan_chen                         phy_write( eng, 23, 0xd88f );
10795c8f9400Sryan_chen                         phy_write( eng, 30, 0x0023 );
10805c8f9400Sryan_chen                         phy_write( eng, 22, 0x0300 );
10815c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
10825c8f9400Sryan_chen                         phy_write( eng, 21, 0x1006 );
10835c8f9400Sryan_chen                         phy_write( eng, 23, 0x2100 );
10845c8f9400Sryan_chen                 }
10855c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 1 ] ) {//option
10865c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
10875c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0200 );
10885c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
10895c8f9400Sryan_chen //              }
10905c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 2 ] ) {//option
10915c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
10925c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0200 );
10935c8f9400Sryan_chen //                      phy_write( eng,  4, 0x05e1 );
10945c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
10955c8f9400Sryan_chen //              }
10965c8f9400Sryan_chen                 else {
10975c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
10985c8f9400Sryan_chen                         phy_write( eng,  0, 0x1140 );
10995c8f9400Sryan_chen                 }
11005c8f9400Sryan_chen #ifdef RTK_DEBUG
11015c8f9400Sryan_chen #else
11025c8f9400Sryan_chen                 // Check register 0x11 bit10 Link OK or not OK
11035c8f9400Sryan_chen                 phy_check_register ( eng, 17, 0x0c02, 0x0000, 10, "clear RTL8211E");
11045c8f9400Sryan_chen #endif
11055c8f9400Sryan_chen         }
11065c8f9400Sryan_chen 
11075c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nClear RTL8211E [End] =====>\n");
11085c8f9400Sryan_chen } // End void recov_phy_realtek2 (MAC_ENGINE *eng)
11095c8f9400Sryan_chen 
11105c8f9400Sryan_chen //------------------------------------------------------------
11115c8f9400Sryan_chen //internal loop 1G  : no  loopback stub
11125c8f9400Sryan_chen //internal loop 100M: no  loopback stub
11135c8f9400Sryan_chen //internal loop 10M : no  loopback stub
11145c8f9400Sryan_chen // for RTL8211E
phy_realtek2(MAC_ENGINE * eng)11155c8f9400Sryan_chen void phy_realtek2 (MAC_ENGINE *eng)
11165c8f9400Sryan_chen {
11175c8f9400Sryan_chen         uint16_t     check_value;
11185c8f9400Sryan_chen 
11195c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nSet RTL8211E [Start] =====>\n");
11205c8f9400Sryan_chen 
11215c8f9400Sryan_chen 	rtk_dbg_gpio_init();
11225c8f9400Sryan_chen 
11235c8f9400Sryan_chen #ifdef RTK_DEBUG
11245c8f9400Sryan_chen #else
11255c8f9400Sryan_chen         phy_write( eng, 31, 0x0000 );
1126ff33b245SDylan Hung         phy_clrset( eng,  0, 0x0000, 0x8000 | eng->phy.PHY_00h ); // clr set // Rst PHY
11273f472ca7SDylan Hung         phy_wait_reset_done( eng );
11285c8f9400Sryan_chen         phy_delay(30);
11295c8f9400Sryan_chen #endif
11305c8f9400Sryan_chen 
11315c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
11325c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
11335c8f9400Sryan_chen                         //Rev 1.2
11345c8f9400Sryan_chen                         phy_write( eng, 31, 0x0005 );
11355c8f9400Sryan_chen                         phy_write( eng,  5, 0x8b86 );
11365c8f9400Sryan_chen                         phy_write( eng,  6, 0xe200 );
11375c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
11385c8f9400Sryan_chen                         phy_write( eng, 30, 0x0020 );
11395c8f9400Sryan_chen                         phy_write( eng, 21, 0x0108 );
11405c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
11415c8f9400Sryan_chen 
11425c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 0 ] ) {
11435c8f9400Sryan_chen                                 //Rev 1.2
11445c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
11455c8f9400Sryan_chen 
11465c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {
11475c8f9400Sryan_chen                                         phy_write( eng,  9, 0x2000 );//Test Mode 1
11485c8f9400Sryan_chen                                 }
11495c8f9400Sryan_chen                                 else {
11505c8f9400Sryan_chen                                         phy_write( eng,  9, 0x8000 );//Test Mode 4
11515c8f9400Sryan_chen                                 }
11525c8f9400Sryan_chen                         }
11535c8f9400Sryan_chen                         else if ( eng->run.speed_sel[ 1 ] ) {
11545c8f9400Sryan_chen                                 //Rev 1.2
11555c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0007 );
11565c8f9400Sryan_chen                                 phy_write( eng, 30, 0x002f );
11575c8f9400Sryan_chen                                 phy_write( eng, 23, 0xd818 );
11585c8f9400Sryan_chen                                 phy_write( eng, 30, 0x002d );
11595c8f9400Sryan_chen                                 phy_write( eng, 24, 0xf060 );
11605c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
11615c8f9400Sryan_chen 
11625c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {
11635c8f9400Sryan_chen                                         phy_write( eng, 16, 0x00ae );//From Channel A
11645c8f9400Sryan_chen                                 }
11655c8f9400Sryan_chen                                 else {
11665c8f9400Sryan_chen                                         phy_write( eng, 16, 0x008e );//From Channel B
11675c8f9400Sryan_chen                                 }
11685c8f9400Sryan_chen                         }
11695c8f9400Sryan_chen                         else {
11705c8f9400Sryan_chen                                 //Rev 1.2
11715c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0006 );
11725c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {//Diff. Voltage/TP-IDL/Jitter
11735c8f9400Sryan_chen                                         phy_write( eng,  0, 0x5a21 );
11745c8f9400Sryan_chen                                 }
11755c8f9400Sryan_chen                                 else if ( eng->run.ieee_sel == 1 ) {//Harmonic: �FF� pattern
11765c8f9400Sryan_chen                                         phy_write( eng,  2, 0x05ee );
11775c8f9400Sryan_chen                                         phy_write( eng,  0, 0xff21 );
11785c8f9400Sryan_chen                                 }
11795c8f9400Sryan_chen                                 else {//Harmonic: �00� pattern
11805c8f9400Sryan_chen                                         phy_write( eng,  2, 0x05ee );
11815c8f9400Sryan_chen                                         phy_write( eng,  0, 0x0021 );
11825c8f9400Sryan_chen                                 }
11835c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
11845c8f9400Sryan_chen                         }
11855c8f9400Sryan_chen                 }
11865c8f9400Sryan_chen                 else {
11875c8f9400Sryan_chen                         phy_basic_setting( eng );
11885c8f9400Sryan_chen                         phy_delay(30);
11895c8f9400Sryan_chen                 }
11905c8f9400Sryan_chen         }
11915c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
11925c8f9400Sryan_chen #ifdef RTK_DEBUG
11935c8f9400Sryan_chen                 phy_write( eng,  0, 0x0000 );
11945c8f9400Sryan_chen                 phy_write( eng,  0, 0x8000 );
11955c8f9400Sryan_chen                 phy_delay(60);
11965c8f9400Sryan_chen                 phy_write( eng,  0, eng->phy.PHY_00h );
11975c8f9400Sryan_chen                 phy_delay(60);
11985c8f9400Sryan_chen #else
11995c8f9400Sryan_chen                 phy_basic_setting( eng );
12005c8f9400Sryan_chen 
1201ff33b245SDylan Hung                 phy_clrset( eng,  0, 0x0000, 0x8000 | eng->phy.PHY_00h );//clr set//Rst PHY
12023f472ca7SDylan Hung                 phy_wait_reset_done( eng );
12035c8f9400Sryan_chen                 phy_delay(30);
12045c8f9400Sryan_chen 
12055c8f9400Sryan_chen                 phy_basic_setting( eng );
12065c8f9400Sryan_chen                 phy_delay(30);
12075c8f9400Sryan_chen #endif
12085c8f9400Sryan_chen         }
12095c8f9400Sryan_chen         else {
12105c8f9400Sryan_chen #ifdef Enable_Dual_Mode
12115c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
12125c8f9400Sryan_chen                         check_value = 0x0c02 | 0xa000;
12135c8f9400Sryan_chen                 }
12145c8f9400Sryan_chen                 else if ( eng->run.speed_sel[ 1 ] ) {
12155c8f9400Sryan_chen                         check_value = 0x0c02 | 0x6000;
12165c8f9400Sryan_chen                 }
12175c8f9400Sryan_chen                 else if ( eng->run.speed_sel[ 2 ] ) {
12185c8f9400Sryan_chen                         check_value = 0x0c02 | 0x2000;
12195c8f9400Sryan_chen                 }
12205c8f9400Sryan_chen #else
12215c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
12225c8f9400Sryan_chen                         check_value = 0x0c02 | 0xa000;
12235c8f9400Sryan_chen #ifdef RTK_DEBUG
12245c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
12255c8f9400Sryan_chen                         phy_write( eng,  0, 0x8000 );
12265c8f9400Sryan_chen                         phy_delay(60);
12275c8f9400Sryan_chen   #endif
12285c8f9400Sryan_chen 
12295c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
12305c8f9400Sryan_chen                         phy_write( eng, 30, 0x0042 );
12315c8f9400Sryan_chen                         phy_write( eng, 21, 0x2500 );
12325c8f9400Sryan_chen                         phy_write( eng, 30, 0x0023 );
12335c8f9400Sryan_chen                         phy_write( eng, 22, 0x0006 );
12345c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
12355c8f9400Sryan_chen                         phy_write( eng,  0, 0x0140 );
12365c8f9400Sryan_chen                         phy_write( eng, 26, 0x0060 );
12375c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
12385c8f9400Sryan_chen                         phy_write( eng, 30, 0x002f );
12395c8f9400Sryan_chen                         phy_write( eng, 23, 0xd820 );
12405c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
12415c8f9400Sryan_chen                         phy_write( eng, 21, 0x0206 );
12425c8f9400Sryan_chen                         phy_write( eng, 23, 0x2120 );
12435c8f9400Sryan_chen                         phy_write( eng, 23, 0x2160 );
12445c8f9400Sryan_chen   #ifdef RTK_DEBUG
12455c8f9400Sryan_chen                         phy_delay(600);
12465c8f9400Sryan_chen   #else
12475c8f9400Sryan_chen                         phy_delay(300);
12485c8f9400Sryan_chen   #endif
12495c8f9400Sryan_chen                 }
12505c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 1 ] ) {//option
12515c8f9400Sryan_chen //                      check_value = 0x0c02 | 0x6000;
12525c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
12535c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0000 );
12545c8f9400Sryan_chen //                      phy_write( eng,  4, 0x05e1 );
12555c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
12565c8f9400Sryan_chen //                      phy_delay(6000);
12575c8f9400Sryan_chen //              }
12585c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 2 ] ) {//option
12595c8f9400Sryan_chen //                      check_value = 0x0c02 | 0x2000;
12605c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
12615c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0000 );
12625c8f9400Sryan_chen //                      phy_write( eng,  4, 0x0061 );
12635c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
12645c8f9400Sryan_chen //                      phy_delay(6000);
12655c8f9400Sryan_chen //              }
12665c8f9400Sryan_chen                 else {
12675c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 1 ] )
12685c8f9400Sryan_chen                                 check_value = 0x0c02 | 0x6000;
12695c8f9400Sryan_chen                         else
12705c8f9400Sryan_chen                                 check_value = 0x0c02 | 0x2000;
12715c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
12725c8f9400Sryan_chen                         phy_write( eng,  0, eng->phy.PHY_00h );
12735c8f9400Sryan_chen   #ifdef RTK_DEBUG
12745c8f9400Sryan_chen                         phy_delay(300);
12755c8f9400Sryan_chen   #else
12765c8f9400Sryan_chen                         phy_delay(150);
12775c8f9400Sryan_chen   #endif
12785c8f9400Sryan_chen                 }
12795c8f9400Sryan_chen #endif
12805c8f9400Sryan_chen #ifdef RTK_DEBUG
12815c8f9400Sryan_chen #else
12825c8f9400Sryan_chen                 // Check register 0x11 bit10 Link OK or not OK
12835c8f9400Sryan_chen                 phy_check_register ( eng, 17, 0x0c02 | 0xe000, check_value, 10, "set RTL8211E");
12845c8f9400Sryan_chen #endif
12855c8f9400Sryan_chen         }
12865c8f9400Sryan_chen 
12875c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nSet RTL8211E [End] =====>\n");
12885c8f9400Sryan_chen } // End void phy_realtek2 (MAC_ENGINE *eng)
12895c8f9400Sryan_chen 
12905c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_realtek3(MAC_ENGINE * eng)12915c8f9400Sryan_chen void recov_phy_realtek3 (MAC_ENGINE *eng) {//RTL8211C
12925c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
12935c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
12945c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 0 ] ) {
12955c8f9400Sryan_chen                                 phy_write( eng,  9, 0x0000 );
12965c8f9400Sryan_chen                         }
12975c8f9400Sryan_chen                         else if ( eng->run.speed_sel[ 1 ] ) {
12985c8f9400Sryan_chen                                 phy_write( eng, 17, eng->phy.PHY_11h );
12995c8f9400Sryan_chen                                 phy_write( eng, 14, 0x0000 );
13005c8f9400Sryan_chen                                 phy_write( eng, 16, 0x00a0 );
13015c8f9400Sryan_chen                         }
13025c8f9400Sryan_chen                         else {
13035c8f9400Sryan_chen //                              phy_write( eng, 31, 0x0006 );
13045c8f9400Sryan_chen //                              phy_write( eng,  0, 0x5a00 );
13055c8f9400Sryan_chen //                              phy_write( eng, 31, 0x0000 );
13065c8f9400Sryan_chen                         }
13075c8f9400Sryan_chen                 }
13085c8f9400Sryan_chen                 else {
13095c8f9400Sryan_chen                 }
13105c8f9400Sryan_chen         }
13115c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
13125c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
13135c8f9400Sryan_chen                         phy_write( eng, 11, 0x0000 );
13145c8f9400Sryan_chen                 }
13155c8f9400Sryan_chen                 phy_write( eng, 12, 0x1006 );
13165c8f9400Sryan_chen         }
13175c8f9400Sryan_chen         else {
13185c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
13195c8f9400Sryan_chen                         phy_write( eng, 31, 0x0001 );
13205c8f9400Sryan_chen                         phy_write( eng,  4, 0xb000 );
13215c8f9400Sryan_chen                         phy_write( eng,  3, 0xff41 );
13225c8f9400Sryan_chen                         phy_write( eng,  2, 0xdf20 );
13235c8f9400Sryan_chen                         phy_write( eng,  1, 0x0140 );
13245c8f9400Sryan_chen                         phy_write( eng,  0, 0x00bb );
13255c8f9400Sryan_chen                         phy_write( eng,  4, 0xb800 );
13265c8f9400Sryan_chen                         phy_write( eng,  4, 0xb000 );
13275c8f9400Sryan_chen 
13285c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
13295c8f9400Sryan_chen                         phy_write( eng, 25, 0x8c00 );
13305c8f9400Sryan_chen                         phy_write( eng, 26, 0x0040 );
13315c8f9400Sryan_chen                         phy_write( eng,  0, 0x1140 );
13325c8f9400Sryan_chen                         phy_write( eng, 14, 0x0000 );
13335c8f9400Sryan_chen                         phy_write( eng, 12, 0x1006 );
13345c8f9400Sryan_chen                         phy_write( eng, 23, 0x2109 );
13355c8f9400Sryan_chen                 }
13365c8f9400Sryan_chen         }
13375c8f9400Sryan_chen }
13385c8f9400Sryan_chen 
13395c8f9400Sryan_chen //------------------------------------------------------------
phy_realtek3(MAC_ENGINE * eng)13405b4262ddSDylan Hung void phy_realtek3 (MAC_ENGINE *eng)
13415b4262ddSDylan Hung {//RTL8211C
13425c8f9400Sryan_chen 
13435c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
13445c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
13455c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 0 ] ) {
13465c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {   //Test Mode 1
13475c8f9400Sryan_chen                                         phy_write( eng,  9, 0x2000 );
13485c8f9400Sryan_chen                                 }
13495c8f9400Sryan_chen                                 else if ( eng->run.ieee_sel == 1 ) {//Test Mode 2
13505c8f9400Sryan_chen                                         phy_write( eng,  9, 0x4000 );
13515c8f9400Sryan_chen                                 }
13525c8f9400Sryan_chen                                 else if ( eng->run.ieee_sel == 2 ) {//Test Mode 3
13535c8f9400Sryan_chen                                         phy_write( eng,  9, 0x6000 );
13545c8f9400Sryan_chen                                 }
13555c8f9400Sryan_chen                                 else {                           //Test Mode 4
13565c8f9400Sryan_chen                                         phy_write( eng,  9, 0x8000 );
13575c8f9400Sryan_chen                                 }
13585c8f9400Sryan_chen                         }
13595c8f9400Sryan_chen                         else if ( eng->run.speed_sel[ 1 ] ) {
13605c8f9400Sryan_chen                                 eng->phy.PHY_11h = phy_read( eng, PHY_SR );
13615c8f9400Sryan_chen                                 phy_write( eng, 17, eng->phy.PHY_11h & 0xfff7 );
13625c8f9400Sryan_chen                                 phy_write( eng, 14, 0x0660 );
13635c8f9400Sryan_chen 
13645c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {
13655c8f9400Sryan_chen                                         phy_write( eng, 16, 0x00a0 );//MDI  //From Channel A
13665c8f9400Sryan_chen                                 }
13675c8f9400Sryan_chen                                 else {
13685c8f9400Sryan_chen                                         phy_write( eng, 16, 0x0080 );//MDIX //From Channel B
13695c8f9400Sryan_chen                                 }
13705c8f9400Sryan_chen                         }
13715c8f9400Sryan_chen                         else {
13725c8f9400Sryan_chen //                              if ( eng->run.ieee_sel == 0 ) {//Pseudo-random pattern
13735c8f9400Sryan_chen //                                      phy_write( eng, 31, 0x0006 );
13745c8f9400Sryan_chen //                                      phy_write( eng,  0, 0x5a21 );
13755c8f9400Sryan_chen //                                      phy_write( eng, 31, 0x0000 );
13765c8f9400Sryan_chen //                              }
13775c8f9400Sryan_chen //                              else if ( eng->run.ieee_sel == 1 ) {//�FF� pattern
13785c8f9400Sryan_chen //                                      phy_write( eng, 31, 0x0006 );
13795c8f9400Sryan_chen //                                      phy_write( eng,  2, 0x05ee );
13805c8f9400Sryan_chen //                                      phy_write( eng,  0, 0xff21 );
13815c8f9400Sryan_chen //                                      phy_write( eng, 31, 0x0000 );
13825c8f9400Sryan_chen //                              }
13835c8f9400Sryan_chen //                              else {//�00� pattern
13845c8f9400Sryan_chen //                                      phy_write( eng, 31, 0x0006 );
13855c8f9400Sryan_chen //                                      phy_write( eng,  2, 0x05ee );
13865c8f9400Sryan_chen //                                      phy_write( eng,  0, 0x0021 );
13875c8f9400Sryan_chen //                                      phy_write( eng, 31, 0x0000 );
13885c8f9400Sryan_chen //                              }
13895c8f9400Sryan_chen                         }
13905c8f9400Sryan_chen                 }
13915c8f9400Sryan_chen                 else {
1392ee3c59a9SDylan Hung                         phy_reset( eng );
13935c8f9400Sryan_chen                 }
13945c8f9400Sryan_chen         }
13955c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
13965c8f9400Sryan_chen                 phy_write( eng,  0, 0x9200 );
13973f472ca7SDylan Hung                 phy_wait_reset_done( eng );
13985c8f9400Sryan_chen                 phy_delay(30);
13995c8f9400Sryan_chen 
14005c8f9400Sryan_chen                 phy_write( eng, 17, 0x401c );
14015c8f9400Sryan_chen                 phy_write( eng, 12, 0x0006 );
14025c8f9400Sryan_chen 
14035c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
14045c8f9400Sryan_chen                         phy_write( eng, 11, 0x0002 );
14055c8f9400Sryan_chen                 }
14065c8f9400Sryan_chen                 else {
14075c8f9400Sryan_chen                         phy_basic_setting( eng );
14085c8f9400Sryan_chen                 }
14095c8f9400Sryan_chen         }
14105c8f9400Sryan_chen         else {
14115c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
14125c8f9400Sryan_chen                         phy_write( eng, 31, 0x0001 );
14135c8f9400Sryan_chen                         phy_write( eng,  4, 0xb000 );
14145c8f9400Sryan_chen                         phy_write( eng,  3, 0xff41 );
14155c8f9400Sryan_chen                         phy_write( eng,  2, 0xd720 );
14165c8f9400Sryan_chen                         phy_write( eng,  1, 0x0140 );
14175c8f9400Sryan_chen                         phy_write( eng,  0, 0x00bb );
14185c8f9400Sryan_chen                         phy_write( eng,  4, 0xb800 );
14195c8f9400Sryan_chen                         phy_write( eng,  4, 0xb000 );
14205c8f9400Sryan_chen 
14215c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
14225c8f9400Sryan_chen                         phy_write( eng, 25, 0x8400 );
14235c8f9400Sryan_chen                         phy_write( eng, 26, 0x0020 );
14245c8f9400Sryan_chen                         phy_write( eng,  0, 0x0140 );
14255c8f9400Sryan_chen                         phy_write( eng, 14, 0x0210 );
14265c8f9400Sryan_chen                         phy_write( eng, 12, 0x0200 );
14275c8f9400Sryan_chen                         phy_write( eng, 23, 0x2109 );
14285c8f9400Sryan_chen                         phy_write( eng, 23, 0x2139 );
14295c8f9400Sryan_chen                 }
14305c8f9400Sryan_chen                 else {
1431ee3c59a9SDylan Hung                         phy_reset( eng );
14325c8f9400Sryan_chen                 }
14335c8f9400Sryan_chen         }
14345c8f9400Sryan_chen } // End void phy_realtek3 (MAC_ENGINE *eng)
14355c8f9400Sryan_chen 
14365c8f9400Sryan_chen //------------------------------------------------------------
14375c8f9400Sryan_chen //external loop 100M: OK
14385c8f9400Sryan_chen //external loop 10M : OK
14395c8f9400Sryan_chen //internal loop 100M: no  loopback stub
14405c8f9400Sryan_chen //internal loop 10M : no  loopback stub
phy_realtek4(MAC_ENGINE * eng)14415c8f9400Sryan_chen void phy_realtek4 (MAC_ENGINE *eng) {//RTL8201F
14425c8f9400Sryan_chen 
14435c8f9400Sryan_chen         eng->phy.RMIICK_IOMode |= PHY_Flag_RMIICK_IOMode_RTL8201F;
14445c8f9400Sryan_chen 
14455c8f9400Sryan_chen         phy_write( eng, 31, 0x0007 );
14465c8f9400Sryan_chen         eng->phy.PHY_10h = phy_read( eng, 16 );
14475c8f9400Sryan_chen         //Check RMII Mode
14485c8f9400Sryan_chen         if ( ( eng->phy.PHY_10h & 0x0008 ) == 0x0 ) {
14495c8f9400Sryan_chen                 phy_write( eng, 16, eng->phy.PHY_10h | 0x0008 );
14505c8f9400Sryan_chen                 printf("\n\n[Warning] Page 7 Register 16, bit 3 must be 1 [Reg10h_7:%04x]\n\n", eng->phy.PHY_10h);
14515c8f9400Sryan_chen                 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 );
14525c8f9400Sryan_chen                 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 );
14535c8f9400Sryan_chen         }
14545c8f9400Sryan_chen         //Check TXC Input/Output Direction
14555c8f9400Sryan_chen         if ( eng->arg.ctrl.b.rmii_phy_in == 0 ) {
14565c8f9400Sryan_chen                 if ( ( eng->phy.PHY_10h & 0x1000 ) == 0x1000 ) {
14575c8f9400Sryan_chen                         phy_write( eng, 16, eng->phy.PHY_10h & 0xefff );
14585c8f9400Sryan_chen                         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);
14595c8f9400Sryan_chen                         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 );
14605c8f9400Sryan_chen                         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 );
14615c8f9400Sryan_chen                 }
14625c8f9400Sryan_chen         } else {
14635c8f9400Sryan_chen                 if ( ( eng->phy.PHY_10h & 0x1000 ) == 0x0000 ) {
14645c8f9400Sryan_chen                         phy_write( eng, 16, eng->phy.PHY_10h | 0x1000 );
14655c8f9400Sryan_chen                         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);
14665c8f9400Sryan_chen                         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 );
14675c8f9400Sryan_chen                         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 );
14685c8f9400Sryan_chen                 }
14695c8f9400Sryan_chen         }
14705c8f9400Sryan_chen         phy_write( eng, 31, 0x0000 );
14715c8f9400Sryan_chen 
14725c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
14735c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
14745c8f9400Sryan_chen                         //Rev 1.0
14755c8f9400Sryan_chen                         phy_write( eng, 31, 0x0004 );
14765c8f9400Sryan_chen                         phy_write( eng, 16, 0x4077 );
14775c8f9400Sryan_chen                         phy_write( eng, 21, 0xc5a0 );
14785c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
14795c8f9400Sryan_chen 
14805c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 1 ] ) {
14815c8f9400Sryan_chen                                 phy_write( eng,  0, 0x8000 ); // Reset PHY
14823f472ca7SDylan Hung                                 phy_wait_reset_done( eng );
14835c8f9400Sryan_chen                                 phy_write( eng, 24, 0x0310 ); // Disable ALDPS
14845c8f9400Sryan_chen 
14855c8f9400Sryan_chen                                 if ( eng->run.ieee_sel == 0 ) {//From Channel A (RJ45 pair 1, 2)
14865c8f9400Sryan_chen                                         phy_write( eng, 28, 0x40c2 ); //Force MDI
14875c8f9400Sryan_chen                                 }
14885c8f9400Sryan_chen                                 else {//From Channel B (RJ45 pair 3, 6)
14895c8f9400Sryan_chen                                         phy_write( eng, 28, 0x40c0 ); //Force MDIX
14905c8f9400Sryan_chen                                 }
14915c8f9400Sryan_chen                                 phy_write( eng,  0, 0x2100 );       //Force 100M/Full Duplex)
14925c8f9400Sryan_chen                         } else {
14935c8f9400Sryan_chen                         }
14945c8f9400Sryan_chen                 }
14955c8f9400Sryan_chen                 else {
1496ee3c59a9SDylan Hung                         phy_reset( eng );
14975c8f9400Sryan_chen                 }
14985c8f9400Sryan_chen         }
14995c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
15005c8f9400Sryan_chen                 // Internal loopback
15015c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 1 ] ) {
15025c8f9400Sryan_chen                         // Enable 100M PCS loop back; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
15035c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
15045c8f9400Sryan_chen                         phy_write( eng,  0, 0x6100 );
15055c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
15065c8f9400Sryan_chen                         phy_write( eng, 16, 0x1FF8 );
15075c8f9400Sryan_chen                         phy_write( eng, 16, 0x0FF8 );
15085c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
15095c8f9400Sryan_chen                         phy_delay(20);
15105c8f9400Sryan_chen                 } else if ( eng->run.speed_sel[ 2 ] ) {
15115c8f9400Sryan_chen                         // Enable 10M PCS loop back; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
15125c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
15135c8f9400Sryan_chen                         phy_write( eng,  0, 0x4100 );
15145c8f9400Sryan_chen                         phy_write( eng, 31, 0x0007 );
15155c8f9400Sryan_chen                         phy_write( eng, 16, 0x1FF8 );
15165c8f9400Sryan_chen                         phy_write( eng, 16, 0x0FF8 );
15175c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
15185c8f9400Sryan_chen                         phy_delay(20);
15195c8f9400Sryan_chen                 }
15205c8f9400Sryan_chen         }
15215c8f9400Sryan_chen         else {
15225c8f9400Sryan_chen                 // External loopback
15235c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 1 ] ) {
15245c8f9400Sryan_chen                         // Enable 100M MDI loop back Nway option; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
15255c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
15265c8f9400Sryan_chen                         phy_write( eng,  4, 0x01E1 );
15275c8f9400Sryan_chen                         phy_write( eng,  0, 0x1200 );
15285c8f9400Sryan_chen                 } else if ( eng->run.speed_sel[ 2 ] ) {
15295c8f9400Sryan_chen                         // Enable 10M MDI loop back Nway option; RTL8201(F_FL_FN)-VB-CG_DataSheet_1.6.pdf
15305c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
15315c8f9400Sryan_chen                         phy_write( eng,  4, 0x0061 );
15325c8f9400Sryan_chen                         phy_write( eng,  0, 0x1200 );
15335c8f9400Sryan_chen                 }
15345c8f9400Sryan_chen //              phy_write( eng,  0, 0x8000 );
15355c8f9400Sryan_chen //              while ( phy_read( eng, 0 ) != 0x3100 ) {}
15365c8f9400Sryan_chen //              while ( phy_read( eng, 0 ) != 0x3100 ) {}
15375c8f9400Sryan_chen //              phy_write( eng,  0, eng->phy.PHY_00h );
15385c8f9400Sryan_chen ////            phy_delay(100);
15395c8f9400Sryan_chen //              phy_delay(400);
15405c8f9400Sryan_chen 
15415c8f9400Sryan_chen                 // Check register 0x1 bit2 Link OK or not OK
15425c8f9400Sryan_chen                 phy_check_register ( eng, 1, 0x0004, 0x0004, 10, "set RTL8201F");
15435c8f9400Sryan_chen                 phy_delay(300);
15445c8f9400Sryan_chen         }
15455c8f9400Sryan_chen }
15465c8f9400Sryan_chen 
15475c8f9400Sryan_chen //------------------------------------------------------------
15485c8f9400Sryan_chen /* for RTL8211F */
recov_phy_realtek5(MAC_ENGINE * eng)15495c8f9400Sryan_chen void recov_phy_realtek5 (MAC_ENGINE *eng)
15505c8f9400Sryan_chen {
15515c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nClear RTL8211F [Start] =====>\n");
15525c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
15535c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
15545c8f9400Sryan_chen                         if ( eng->run.speed_sel[ 0 ] ) {
15555c8f9400Sryan_chen                                 //Rev 1.0
15565c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
15575c8f9400Sryan_chen                                 phy_write( eng,  9, 0x0000 );
15585c8f9400Sryan_chen                         }
15595c8f9400Sryan_chen                         else if ( eng->run.speed_sel[ 1 ] ) {
15605c8f9400Sryan_chen                                 //Rev 1.0
15615c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
15625c8f9400Sryan_chen                                 phy_write( eng, 24, 0x2118 );//RGMII
15635c8f9400Sryan_chen                                 phy_write( eng,  9, 0x0200 );
15645c8f9400Sryan_chen                                 phy_write( eng,  0, 0x9200 );
15653f472ca7SDylan Hung                                 phy_wait_reset_done( eng );
15665c8f9400Sryan_chen                         }
15675c8f9400Sryan_chen                         else {
15685c8f9400Sryan_chen                                 //Rev 1.0
15695c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0c80 );
15705c8f9400Sryan_chen                                 phy_write( eng, 16, 0x5a00 );
15715c8f9400Sryan_chen                                 phy_write( eng, 31, 0x0000 );
15725c8f9400Sryan_chen                                 phy_write( eng,  4, 0x01e1 );
15735c8f9400Sryan_chen                                 phy_write( eng,  9, 0x0200 );
15745c8f9400Sryan_chen                                 phy_write( eng,  0, 0x9200 );
15753f472ca7SDylan Hung                                 phy_wait_reset_done( eng );
15765c8f9400Sryan_chen                         }
15775c8f9400Sryan_chen                 }
15785c8f9400Sryan_chen                 else {
15795c8f9400Sryan_chen                 }
15805c8f9400Sryan_chen         }
15815c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
15825c8f9400Sryan_chen         }
15835c8f9400Sryan_chen         else {
15845c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
15855c8f9400Sryan_chen                         //Rev 1.1
15865c8f9400Sryan_chen                         phy_write( eng, 31, 0x0a43 );
15875c8f9400Sryan_chen                         phy_write( eng, 24, 0x2118 );
15885c8f9400Sryan_chen                         phy_write( eng,  0, 0x1040 );
15895c8f9400Sryan_chen                 }
15905c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 1 ] ) {//option
15915c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
15925c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0200 );
15935c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
15945c8f9400Sryan_chen //              }
15955c8f9400Sryan_chen //              else if ( eng->run.speed_sel[ 2 ] ) {//option
15965c8f9400Sryan_chen //                      phy_write( eng, 31, 0x0000 );
15975c8f9400Sryan_chen //                      phy_write( eng,  9, 0x0200 );
15985c8f9400Sryan_chen //                      phy_write( eng,  4, 0x01e1 );
15995c8f9400Sryan_chen //                      phy_write( eng,  0, 0x1200 );
16005c8f9400Sryan_chen //              }
16015c8f9400Sryan_chen                 else {
16025c8f9400Sryan_chen                         phy_write( eng, 31, 0x0000 );
16035c8f9400Sryan_chen                         phy_write( eng,  0, 0x1040 );
16045c8f9400Sryan_chen                 }
16055c8f9400Sryan_chen 
16065c8f9400Sryan_chen #ifdef RTK_DEBUG
16075c8f9400Sryan_chen #else
16085c8f9400Sryan_chen                 // Check register 0x1A bit2 Link OK or not OK
16095c8f9400Sryan_chen                 phy_write( eng, 31, 0x0a43 );
16105c8f9400Sryan_chen                 phy_check_register ( eng, 26, 0x0004, 0x0000, 10, "clear RTL8211F");
16115c8f9400Sryan_chen                 phy_write( eng, 31, 0x0000 );
16125c8f9400Sryan_chen #endif
16135c8f9400Sryan_chen         }
16145c8f9400Sryan_chen 
16155c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nClear RTL8211F [End] =====>\n");
16165c8f9400Sryan_chen }
16175c8f9400Sryan_chen 
16185c8f9400Sryan_chen //------------------------------------------------------------
phy_realtek5(MAC_ENGINE * eng)16195c8f9400Sryan_chen void phy_realtek5 (MAC_ENGINE *eng) {//RTL8211F
16205c8f9400Sryan_chen 	uint16_t check_value;
1621414917c6SDylan Hung 	uint16_t reg;
16225c8f9400Sryan_chen 
16235c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nSet RTL8211F [Start] =====>\n");
16245c8f9400Sryan_chen 
1625414917c6SDylan Hung 	/* select page 0xd08 to configure TX and RX delay */
1626414917c6SDylan Hung 	phy_write(eng, 0x1f, 0xd08);
1627414917c6SDylan Hung 
1628414917c6SDylan Hung 	/* page 0xd08, reg 0x11[8] TX delay enable */
1629414917c6SDylan Hung 	reg = phy_read(eng, 0x11);
1630414917c6SDylan Hung 	if (eng->arg.ctrl.b.phy_tx_delay_en)
1631414917c6SDylan Hung 		reg |= BIT(8);
1632414917c6SDylan Hung 	else
1633414917c6SDylan Hung 		reg &= ~BIT(8);
1634414917c6SDylan Hung 	phy_write(eng, 0x11, reg);
1635414917c6SDylan Hung 
1636414917c6SDylan Hung 	/* page 0xd08, reg 0x15[3] RX delay enable */
1637414917c6SDylan Hung 	reg = phy_read(eng, 0x15);
1638414917c6SDylan Hung 	if (eng->arg.ctrl.b.phy_rx_delay_en)
1639414917c6SDylan Hung 		reg |= BIT(3);
1640414917c6SDylan Hung 	else
1641414917c6SDylan Hung 		reg &= ~BIT(3);
1642414917c6SDylan Hung 	phy_write(eng, 0x15, reg);
1643414917c6SDylan Hung 
1644b875452fSDylan Hung 	/* restore page 0 */
1645b875452fSDylan Hung 	phy_write(eng, 0x1f, 0x0);
1646b875452fSDylan Hung 
16475c8f9400Sryan_chen 	if (eng->run.tm_tx_only) {
16485c8f9400Sryan_chen 		if (eng->run.TM_IEEE) {
16495c8f9400Sryan_chen 			if (eng->run.speed_sel[0]) {
16505c8f9400Sryan_chen 				// Rev 1.0
16515c8f9400Sryan_chen 				phy_write(eng, 31, 0x0000);
16525c8f9400Sryan_chen 				if (eng->run.ieee_sel == 0) { // Test Mode 1
16535c8f9400Sryan_chen 					phy_write(eng, 9, 0x0200);
16545c8f9400Sryan_chen 				} else if (eng->run.ieee_sel ==
16555c8f9400Sryan_chen 					   1) { // Test Mode 2
16565c8f9400Sryan_chen 					phy_write(eng, 9, 0x0400);
16575c8f9400Sryan_chen 				} else { // Test Mode 4
16585c8f9400Sryan_chen 					phy_write(eng, 9, 0x0800);
16595c8f9400Sryan_chen 				}
16605c8f9400Sryan_chen 			} else if (eng->run.speed_sel[1]) { // option
16615c8f9400Sryan_chen 				// Rev 1.0
16625c8f9400Sryan_chen 				phy_write(eng, 31, 0x0000);
16635c8f9400Sryan_chen 				if (eng->run.ieee_sel ==
16645c8f9400Sryan_chen 				    0) { // Output MLT-3 from Channel A
16655c8f9400Sryan_chen 					phy_write(eng, 24, 0x2318);
16665c8f9400Sryan_chen 				} else { // Output MLT-3 from Channel B
16675c8f9400Sryan_chen 					phy_write(eng, 24, 0x2218);
16685c8f9400Sryan_chen 				}
16695c8f9400Sryan_chen 				phy_write(eng, 9, 0x0000);
16705c8f9400Sryan_chen 				phy_write(eng, 0, 0x2100);
16715c8f9400Sryan_chen 			} else {
16725c8f9400Sryan_chen 				// Rev 1.0
16735c8f9400Sryan_chen 				// 0: For Diff. Voltage/TP-IDL/Jitter with EEE
16745c8f9400Sryan_chen 				// 1: For Diff. Voltage/TP-IDL/Jitter without
16755c8f9400Sryan_chen 				// EEE 2: For Harmonic (all "1" patten) with EEE
16765c8f9400Sryan_chen 				// 3: For Harmonic (all "1" patten) without EEE
16775c8f9400Sryan_chen 				// 4: For Harmonic (all "0" patten) with EEE
16785c8f9400Sryan_chen 				// 5: For Harmonic (all "0" patten) without EEE
16795c8f9400Sryan_chen 				phy_write(eng, 31, 0x0000);
16805c8f9400Sryan_chen 				phy_write(eng, 9, 0x0000);
16815c8f9400Sryan_chen 				phy_write(eng, 4, 0x0061);
16825c8f9400Sryan_chen 				if ((eng->run.ieee_sel & 0x1) == 0) { // with
16835c8f9400Sryan_chen 								      // EEE
16845c8f9400Sryan_chen 					phy_write(eng, 25, 0x0853);
16855c8f9400Sryan_chen 				} else { // without EEE
16865c8f9400Sryan_chen 					phy_write(eng, 25, 0x0843);
16875c8f9400Sryan_chen 				}
16885c8f9400Sryan_chen 				phy_write(eng, 0, 0x9200);
16893f472ca7SDylan Hung 				phy_wait_reset_done(eng);
16905c8f9400Sryan_chen 
16915c8f9400Sryan_chen 				if ((eng->run.ieee_sel & 0x6) ==
16925c8f9400Sryan_chen 				    0) { // For Diff. Voltage/TP-IDL/Jitter
16935c8f9400Sryan_chen 					phy_write(eng, 31, 0x0c80);
16945c8f9400Sryan_chen 					phy_write(eng, 18, 0x0115);
16955c8f9400Sryan_chen 					phy_write(eng, 16, 0x5a21);
16965c8f9400Sryan_chen 				} else if ((eng->run.ieee_sel & 0x6) ==
16975c8f9400Sryan_chen 					   0x2) { // For Harmonic (all "1"
16985c8f9400Sryan_chen 						  // patten)
16995c8f9400Sryan_chen 					phy_write(eng, 31, 0x0c80);
17005c8f9400Sryan_chen 					phy_write(eng, 18, 0x0015);
17015c8f9400Sryan_chen 					phy_write(eng, 16, 0xff21);
17025c8f9400Sryan_chen 				} else { // For Harmonic (all "0" patten)
17035c8f9400Sryan_chen 					phy_write(eng, 31, 0x0c80);
17045c8f9400Sryan_chen 					phy_write(eng, 18, 0x0015);
17055c8f9400Sryan_chen 					phy_write(eng, 16, 0x0021);
17065c8f9400Sryan_chen 				}
17075c8f9400Sryan_chen 				phy_write(eng, 31, 0x0000);
17085c8f9400Sryan_chen 			}
17095c8f9400Sryan_chen 		} else {
1710ee3c59a9SDylan Hung 			phy_reset(eng);
17115c8f9400Sryan_chen 		}
17125c8f9400Sryan_chen 	} else if (eng->phy.loopback) {
1713ee3c59a9SDylan Hung 		phy_reset(eng);
17145c8f9400Sryan_chen 	} else {
17155c8f9400Sryan_chen 		if (eng->run.speed_sel[0]) {
17165c8f9400Sryan_chen 			check_value = 0x0004 | 0x0028;
17175c8f9400Sryan_chen 			// Rev 1.1
17185c8f9400Sryan_chen 			phy_write(eng, 31, 0x0a43);
17195c8f9400Sryan_chen 			phy_write(eng, 0, 0x8000);
17205c8f9400Sryan_chen #ifdef RTK_DEBUG
17215c8f9400Sryan_chen 			phy_delay(60);
17225c8f9400Sryan_chen #else
17233f472ca7SDylan Hung 			phy_wait_reset_done(eng);
17245c8f9400Sryan_chen 			phy_delay(30);
17255c8f9400Sryan_chen #endif
17265c8f9400Sryan_chen 
17275c8f9400Sryan_chen 			phy_write(eng, 0, 0x0140);
17285c8f9400Sryan_chen 			phy_write(eng, 24, 0x2d18);
17295c8f9400Sryan_chen #ifdef RTK_DEBUG
17305c8f9400Sryan_chen 			phy_delay(600);
17315c8f9400Sryan_chen #else
17325c8f9400Sryan_chen 			phy_delay(300);
17335c8f9400Sryan_chen #endif
17345c8f9400Sryan_chen 		} else {
17355c8f9400Sryan_chen 			if (eng->run.speed_sel[1])
17365c8f9400Sryan_chen 				check_value = 0x0004 | 0x0018;
17375c8f9400Sryan_chen 			else
17385c8f9400Sryan_chen 				check_value = 0x0004 | 0x0008;
17395c8f9400Sryan_chen #ifdef RTK_DEBUG
17405c8f9400Sryan_chen #else
17415c8f9400Sryan_chen 			phy_write(eng, 31, 0x0a43);
17425c8f9400Sryan_chen 			phy_write(eng, 0, 0x8000);
17433f472ca7SDylan Hung 			phy_wait_reset_done(eng);
17445c8f9400Sryan_chen 			phy_delay(30);
17455c8f9400Sryan_chen #endif
17465c8f9400Sryan_chen 
17475c8f9400Sryan_chen 			phy_write(eng, 31, 0x0000);
17485c8f9400Sryan_chen 			phy_write(eng, 0, eng->phy.PHY_00h);
17495c8f9400Sryan_chen #ifdef RTK_DEBUG
17505c8f9400Sryan_chen 			phy_delay(300);
17515c8f9400Sryan_chen #else
17525c8f9400Sryan_chen 			phy_delay(150);
17535c8f9400Sryan_chen #endif
17545c8f9400Sryan_chen 		}
17555c8f9400Sryan_chen 
17565c8f9400Sryan_chen #ifdef RTK_DEBUG
17575c8f9400Sryan_chen #else
17585c8f9400Sryan_chen 		// Check register 0x1A bit2 Link OK or not OK
17595c8f9400Sryan_chen 		phy_write(eng, 31, 0x0a43);
17605c8f9400Sryan_chen 		phy_check_register(eng, 26, 0x0004 | 0x0038, check_value, 10,
17615c8f9400Sryan_chen 				   "set RTL8211F");
17625c8f9400Sryan_chen 		phy_write(eng, 31, 0x0000);
17635c8f9400Sryan_chen #endif
17645c8f9400Sryan_chen 	}
17655c8f9400Sryan_chen 
1766*20b0d70cSDylan Hung 	/* additional delay for PHY PCS loopback mode */
1767*20b0d70cSDylan Hung 	phy_delay(500);
17685c8f9400Sryan_chen 	RTK_DBG_PRINTF("\nSet RTL8211F [End] =====>\n");
17695c8f9400Sryan_chen }
17705c8f9400Sryan_chen 
17715c8f9400Sryan_chen //------------------------------------------------------------
17725c8f9400Sryan_chen //It is a LAN Switch, only support 1G internal loopback test.
phy_realtek6(MAC_ENGINE * eng)17735c8f9400Sryan_chen void phy_realtek6 (MAC_ENGINE *eng)
17745c8f9400Sryan_chen {//RTL8363S
17755c8f9400Sryan_chen 
17765c8f9400Sryan_chen 	if (eng->run.tm_tx_only) {
17775c8f9400Sryan_chen 		printf("This mode doesn't support in RTL8363S.\n");
17785c8f9400Sryan_chen 	} else if (eng->phy.loopback) {
17795c8f9400Sryan_chen 
17805c8f9400Sryan_chen 		// RXDLY2 and TXDLY2 of RTL8363S should set to LOW
17815c8f9400Sryan_chen 		phy_basic_setting(eng);
17825c8f9400Sryan_chen 
1783ff33b245SDylan Hung 		phy_clrset(eng, 0, 0x0000,
17845c8f9400Sryan_chen 			       0x8000 | eng->phy.PHY_00h); // clr set//Rst PHY
17853f472ca7SDylan Hung 		phy_wait_reset_done(eng);
17865c8f9400Sryan_chen 		phy_delay(30);
17875c8f9400Sryan_chen 
17885c8f9400Sryan_chen 		phy_basic_setting(eng);
17895c8f9400Sryan_chen 		phy_delay(30);
17905c8f9400Sryan_chen 	} else {
17915c8f9400Sryan_chen 		printf("This mode doesn't support in RTL8363S\n");
17925c8f9400Sryan_chen 	}
17935c8f9400Sryan_chen } // End void phy_realtek6 (MAC_ENGINE *eng)
17945c8f9400Sryan_chen 
17955c8f9400Sryan_chen //------------------------------------------------------------
phy_smsc(MAC_ENGINE * eng)17965c8f9400Sryan_chen void phy_smsc (MAC_ENGINE *eng)
17975c8f9400Sryan_chen {//LAN8700
1798ee3c59a9SDylan Hung 	phy_reset(eng);
17995c8f9400Sryan_chen }
18005c8f9400Sryan_chen 
18015c8f9400Sryan_chen //------------------------------------------------------------
phy_micrel(MAC_ENGINE * eng)18025c8f9400Sryan_chen void phy_micrel (MAC_ENGINE *eng)
18035c8f9400Sryan_chen {//KSZ8041
18045c8f9400Sryan_chen 
1805ee3c59a9SDylan Hung         phy_reset( eng );
18065c8f9400Sryan_chen 
18075c8f9400Sryan_chen //      phy_write( eng, 24, 0x0600 );
18085c8f9400Sryan_chen }
18095c8f9400Sryan_chen 
18105c8f9400Sryan_chen //------------------------------------------------------------
phy_micrel0(MAC_ENGINE * eng)18115b4262ddSDylan Hung void phy_micrel0 (MAC_ENGINE *eng)
18125b4262ddSDylan Hung {//KSZ8031/KSZ8051
18135c8f9400Sryan_chen 
18145c8f9400Sryan_chen         //For KSZ8051RNL only
18155c8f9400Sryan_chen         //Reg1Fh[7] = 0(default): 25MHz Mode, XI, XO(pin 9, 8) is 25MHz(crystal/oscilator).
18165c8f9400Sryan_chen         //Reg1Fh[7] = 1         : 50MHz Mode, XI(pin 9) is 50MHz(oscilator).
18175c8f9400Sryan_chen         eng->phy.PHY_1fh = phy_read( eng, 31 );
18185c8f9400Sryan_chen         if ( eng->phy.PHY_1fh & 0x0080 ) sprintf((char *)eng->phy.phy_name, "%s-50MHz Mode", eng->phy.phy_name);
18195c8f9400Sryan_chen         else                             sprintf((char *)eng->phy.phy_name, "%s-25MHz Mode", eng->phy.phy_name);
18205c8f9400Sryan_chen 
18215c8f9400Sryan_chen         if ( eng->run.TM_IEEE ) {
1822ff33b245SDylan Hung                 phy_clrset( eng,  0, 0x0000, 0x8000 | eng->phy.PHY_00h );//clr set//Rst PHY
18233f472ca7SDylan Hung                 phy_wait_reset_done( eng );
18245c8f9400Sryan_chen 
1825ff33b245SDylan Hung                 phy_clrset( eng, 31, 0x0000, 0x2000 );//clr set//1Fh[13] = 1: Disable auto MDI/MDI-X
18265c8f9400Sryan_chen                 phy_basic_setting( eng );
1827ff33b245SDylan Hung                 phy_clrset( eng, 31, 0x0000, 0x0800 );//clr set//1Fh[11] = 1: Force link pass
18285c8f9400Sryan_chen 
18295c8f9400Sryan_chen //              phy_delay(2500);//2.5 sec
18305c8f9400Sryan_chen         }
18315c8f9400Sryan_chen         else {
1832ee3c59a9SDylan Hung                 phy_reset( eng );
18335c8f9400Sryan_chen 
18345c8f9400Sryan_chen                 //Reg16h[6] = 1         : RMII B-to-B override
18355c8f9400Sryan_chen                 //Reg16h[1] = 1(default): RMII override
1836ff33b245SDylan Hung                 phy_clrset( eng, 22, 0x0000, 0x0042 );//clr set
18375c8f9400Sryan_chen         }
18385c8f9400Sryan_chen 
18395c8f9400Sryan_chen         if ( eng->phy.PHY_1fh & 0x0080 )
1840ff33b245SDylan Hung                 phy_clrset( eng, 31, 0x0000, 0x0080 );//clr set//Reset PHY will clear Reg1Fh[7]
18415c8f9400Sryan_chen }
18425c8f9400Sryan_chen 
18435c8f9400Sryan_chen //------------------------------------------------------------
18445c8f9400Sryan_chen //external loop 1G  : NOT Support
18455c8f9400Sryan_chen //external loop 100M: OK
18465c8f9400Sryan_chen //external loop 10M : OK
18475c8f9400Sryan_chen //internal loop 1G  : no  loopback stub
18485c8f9400Sryan_chen //internal loop 100M: no  loopback stub
18495c8f9400Sryan_chen //internal loop 10M : no  loopback stub
phy_micrel1(MAC_ENGINE * eng)18505c8f9400Sryan_chen void phy_micrel1 (MAC_ENGINE *eng)
18515c8f9400Sryan_chen {//KSZ9031
18525c8f9400Sryan_chen //      int        temp;
18535c8f9400Sryan_chen 
18545c8f9400Sryan_chen /*
18555c8f9400Sryan_chen         phy_write( eng, 13, 0x0002 );
18565c8f9400Sryan_chen         phy_write( eng, 14, 0x0004 );
18575c8f9400Sryan_chen         phy_write( eng, 13, 0x4002 );
18585c8f9400Sryan_chen         temp = phy_read( eng, 14 );
18595c8f9400Sryan_chen         //Reg2.4[ 7: 4]: RXDV Pad Skew
18605c8f9400Sryan_chen         phy_write( eng, 14, temp & 0xff0f | 0x0000 );
18615c8f9400Sryan_chen //      phy_write( eng, 14, temp & 0xff0f | 0x00f0 );
18625c8f9400Sryan_chen printf("Reg2.4 = %04x -> %04x\n", temp, phy_read( eng, 14 ));
18635c8f9400Sryan_chen 
18645c8f9400Sryan_chen         phy_write( eng, 13, 0x0002 );
18655c8f9400Sryan_chen         phy_write( eng, 14, 0x0005 );
18665c8f9400Sryan_chen         phy_write( eng, 13, 0x4002 );
18675c8f9400Sryan_chen         temp = phy_read( eng, 14 );
18685c8f9400Sryan_chen         //Reg2.5[15:12]: RXD3 Pad Skew
18695c8f9400Sryan_chen         //Reg2.5[11: 8]: RXD2 Pad Skew
18705c8f9400Sryan_chen         //Reg2.5[ 7: 4]: RXD1 Pad Skew
18715c8f9400Sryan_chen         //Reg2.5[ 3: 0]: RXD0 Pad Skew
18725c8f9400Sryan_chen         phy_write( eng, 14, 0x0000 );
18735c8f9400Sryan_chen //      phy_write( eng, 14, 0xffff );
18745c8f9400Sryan_chen printf("Reg2.5 = %04x -> %04x\n", temp, phy_read( eng, 14 ));
18755c8f9400Sryan_chen 
18765c8f9400Sryan_chen         phy_write( eng, 13, 0x0002 );
18775c8f9400Sryan_chen         phy_write( eng, 14, 0x0008 );
18785c8f9400Sryan_chen         phy_write( eng, 13, 0x4002 );
18795c8f9400Sryan_chen         temp = phy_read( eng, 14 );
18805c8f9400Sryan_chen         //Reg2.8[9:5]: GTX_CLK Pad Skew
18815c8f9400Sryan_chen         //Reg2.8[4:0]: RX_CLK Pad Skew
18825c8f9400Sryan_chen //      phy_write( eng, 14, temp & 0xffe0 | 0x0000 );
18835c8f9400Sryan_chen         phy_write( eng, 14, temp & 0xffe0 | 0x001f );
18845c8f9400Sryan_chen printf("Reg2.8 = %04x -> %04x\n", temp, phy_read( eng, 14 ));
18855c8f9400Sryan_chen */
18865c8f9400Sryan_chen 
18875c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
18885c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
1889ee3c59a9SDylan Hung                         phy_reset( eng );
18905c8f9400Sryan_chen                 }
18915c8f9400Sryan_chen                 else {
1892ee3c59a9SDylan Hung                         phy_reset( eng );
18935c8f9400Sryan_chen                 }
18945c8f9400Sryan_chen         }
18955c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
1896ee3c59a9SDylan Hung                 phy_reset( eng );
18975c8f9400Sryan_chen         }
18985c8f9400Sryan_chen         else {
18995c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
1900ee3c59a9SDylan Hung                         phy_reset( eng );//DON'T support for 1G external loopback testing
19015c8f9400Sryan_chen                 }
19025c8f9400Sryan_chen                 else {
1903ee3c59a9SDylan Hung                         phy_reset( eng );
19045c8f9400Sryan_chen                 }
19055c8f9400Sryan_chen         }
19065c8f9400Sryan_chen }
19075c8f9400Sryan_chen 
19085c8f9400Sryan_chen //------------------------------------------------------------
19095c8f9400Sryan_chen //external loop 100M: OK
19105c8f9400Sryan_chen //external loop 10M : OK
19115c8f9400Sryan_chen //internal loop 100M: no  loopback stub
19125c8f9400Sryan_chen //internal loop 10M : no  loopback stub
phy_micrel2(MAC_ENGINE * eng)19135c8f9400Sryan_chen void phy_micrel2 (MAC_ENGINE *eng)
19145c8f9400Sryan_chen {//KSZ8081
19155c8f9400Sryan_chen 
19165c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
19175c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
1918ee3c59a9SDylan Hung                         phy_reset( eng );
19195c8f9400Sryan_chen                 }
19205c8f9400Sryan_chen                 else {
1921ee3c59a9SDylan Hung                         phy_reset( eng );
19225c8f9400Sryan_chen                 }
19235c8f9400Sryan_chen         }
19245c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
1925ee3c59a9SDylan Hung                 phy_reset( eng );
19265c8f9400Sryan_chen         }
19275c8f9400Sryan_chen         else {
19285c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 1 ] )
1929ee3c59a9SDylan Hung                         phy_reset( eng );
19305c8f9400Sryan_chen                 else
1931ee3c59a9SDylan Hung                         phy_reset( eng );
19325c8f9400Sryan_chen         }
19335c8f9400Sryan_chen }
19345c8f9400Sryan_chen 
19355c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_vitesse(MAC_ENGINE * eng)19365c8f9400Sryan_chen void recov_phy_vitesse (MAC_ENGINE *eng) {//VSC8601
19375c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
19385c8f9400Sryan_chen //              if ( eng->run.TM_IEEE ) {
19395c8f9400Sryan_chen //              }
19405c8f9400Sryan_chen //              else {
19415c8f9400Sryan_chen //              }
19425c8f9400Sryan_chen         }
19435c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
19445c8f9400Sryan_chen         }
19455c8f9400Sryan_chen         else {
19465c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
19475c8f9400Sryan_chen                         phy_write( eng, 24, eng->phy.PHY_18h );
19485c8f9400Sryan_chen                         phy_write( eng, 18, eng->phy.PHY_12h );
19495c8f9400Sryan_chen                 }
19505c8f9400Sryan_chen         }
19515c8f9400Sryan_chen }
19525c8f9400Sryan_chen 
19535c8f9400Sryan_chen //------------------------------------------------------------
phy_vitesse(MAC_ENGINE * eng)19545b4262ddSDylan Hung void phy_vitesse (MAC_ENGINE *eng)
19555b4262ddSDylan Hung {//VSC8601
19565c8f9400Sryan_chen 
19575c8f9400Sryan_chen         if ( eng->run.tm_tx_only ) {
19585c8f9400Sryan_chen                 if ( eng->run.TM_IEEE ) {
1959ee3c59a9SDylan Hung                         phy_reset( eng );
19605c8f9400Sryan_chen                 }
19615c8f9400Sryan_chen                 else {
1962ee3c59a9SDylan Hung                         phy_reset( eng );
19635c8f9400Sryan_chen                 }
19645c8f9400Sryan_chen         }
19655c8f9400Sryan_chen         else if ( eng->phy.loopback ) {
1966ee3c59a9SDylan Hung                 phy_reset( eng );
19675c8f9400Sryan_chen         }
19685c8f9400Sryan_chen         else {
19695c8f9400Sryan_chen                 if ( eng->run.speed_sel[ 0 ] ) {
19705c8f9400Sryan_chen                         eng->phy.PHY_18h = phy_read( eng, 24 );
19715c8f9400Sryan_chen                         eng->phy.PHY_12h = phy_read( eng, PHY_INER );
19725c8f9400Sryan_chen 
1973ee3c59a9SDylan Hung                         phy_reset( eng );
19745c8f9400Sryan_chen 
19755c8f9400Sryan_chen                         phy_write( eng, 24, eng->phy.PHY_18h | 0x0001 );
19765c8f9400Sryan_chen                         phy_write( eng, 18, eng->phy.PHY_12h | 0x0020 );
19775c8f9400Sryan_chen                 }
19785c8f9400Sryan_chen                 else {
1979ee3c59a9SDylan Hung                         phy_reset( eng );
19805c8f9400Sryan_chen                 }
19815c8f9400Sryan_chen         }
19825c8f9400Sryan_chen }
19835c8f9400Sryan_chen 
19845c8f9400Sryan_chen //------------------------------------------------------------
recov_phy_atheros(MAC_ENGINE * eng)19855c8f9400Sryan_chen void recov_phy_atheros (MAC_ENGINE *eng) {//AR8035
19865c8f9400Sryan_chen 	if (eng->run.tm_tx_only) {
19875c8f9400Sryan_chen 		if (eng->run.TM_IEEE) {
19885c8f9400Sryan_chen 		} else {
19895c8f9400Sryan_chen 		}
19905c8f9400Sryan_chen 	} else if (eng->phy.loopback) {
19915c8f9400Sryan_chen 	} else {
1992ff33b245SDylan Hung 		phy_clrset(
19935c8f9400Sryan_chen 		    eng, 11, 0x0000,
19945c8f9400Sryan_chen 		    0x8000); // clr set//Disable hibernate: Reg0Bh[15] = 0
1995ff33b245SDylan Hung 		phy_clrset(
19965c8f9400Sryan_chen 		    eng, 17, 0x0001,
19975c8f9400Sryan_chen 		    0x0000); // clr set//Enable external loopback: Reg11h[0] = 1
19985c8f9400Sryan_chen 	}
19995c8f9400Sryan_chen }
20005c8f9400Sryan_chen 
20015c8f9400Sryan_chen //------------------------------------------------------------
phy_atheros(MAC_ENGINE * eng)20025c8f9400Sryan_chen void phy_atheros (MAC_ENGINE *eng)
20035c8f9400Sryan_chen {
20045c8f9400Sryan_chen 	// Reg0b[15]: Power saving
20055c8f9400Sryan_chen 	phy_write(eng, 29, 0x000b);
20065c8f9400Sryan_chen 	eng->phy.PHY_1eh = phy_read(eng, 30);
20075c8f9400Sryan_chen 	if (eng->phy.PHY_1eh & 0x8000) {
20085c8f9400Sryan_chen 		printf("\n\n[Warning] Debug register offset = 11, bit 15 must "
20095c8f9400Sryan_chen 		       "be 0 [%04x]\n\n",
20105c8f9400Sryan_chen 		       eng->phy.PHY_1eh);
20115c8f9400Sryan_chen 		if (eng->run.TM_IOTiming)
20125c8f9400Sryan_chen 			PRINTF(FP_IO,
20135c8f9400Sryan_chen 			       "\n\n[Warning] Debug register offset = 11, bit "
20145c8f9400Sryan_chen 			       "15 must be 0 [%04x]\n\n",
20155c8f9400Sryan_chen 			       eng->phy.PHY_1eh);
20165c8f9400Sryan_chen 		if (!eng->run.tm_tx_only)
20175c8f9400Sryan_chen 			PRINTF(FP_LOG,
20185c8f9400Sryan_chen 			       "\n\n[Warning] Debug register offset = 11, bit "
20195c8f9400Sryan_chen 			       "15 must be 0 [%04x]\n\n",
20205c8f9400Sryan_chen 			       eng->phy.PHY_1eh);
20215c8f9400Sryan_chen 
20225c8f9400Sryan_chen 		phy_write(eng, 30, eng->phy.PHY_1eh & 0x7fff);
20235c8f9400Sryan_chen 	}
20245c8f9400Sryan_chen 	//      phy_write( eng, 30, (eng->phy.PHY_1eh & 0x7fff) | 0x8000 );
20255c8f9400Sryan_chen 
20265c8f9400Sryan_chen 	// Check RGMIIRXCK delay (Sel_clk125m_dsp)
20275c8f9400Sryan_chen 	phy_write(eng, 29, 0x0000);
20285c8f9400Sryan_chen 	eng->phy.PHY_1eh = phy_read(eng, 30);
20295c8f9400Sryan_chen 	if (eng->phy.PHY_1eh & 0x8000) {
20305c8f9400Sryan_chen 		printf("\n\n[Warning] Debug register offset = 0, bit 15 must "
20315c8f9400Sryan_chen 		       "be 0 [%04x]\n\n",
20325c8f9400Sryan_chen 		       eng->phy.PHY_1eh);
20335c8f9400Sryan_chen 		if (eng->run.TM_IOTiming)
20345c8f9400Sryan_chen 			PRINTF(FP_IO,
20355c8f9400Sryan_chen 			       "\n\n[Warning] Debug register offset = 0, bit "
20365c8f9400Sryan_chen 			       "15 must be 0 [%04x]\n\n",
20375c8f9400Sryan_chen 			       eng->phy.PHY_1eh);
20385c8f9400Sryan_chen 		if (!eng->run.tm_tx_only)
20395c8f9400Sryan_chen 			PRINTF(FP_LOG,
20405c8f9400Sryan_chen 			       "\n\n[Warning] Debug register offset = 0, bit "
20415c8f9400Sryan_chen 			       "15 must be 0 [%04x]\n\n",
20425c8f9400Sryan_chen 			       eng->phy.PHY_1eh);
20435c8f9400Sryan_chen 
20445c8f9400Sryan_chen 		phy_write(eng, 30, eng->phy.PHY_1eh & 0x7fff);
20455c8f9400Sryan_chen 	}
20465c8f9400Sryan_chen 	//      phy_write( eng, 30, (eng->phy.PHY_1eh & 0x7fff) | 0x8000 );
20475c8f9400Sryan_chen 
20485c8f9400Sryan_chen 	// Check RGMIITXCK delay (rgmii_tx_clk_dly)
20495c8f9400Sryan_chen 	phy_write(eng, 29, 0x0005);
20505c8f9400Sryan_chen 	eng->phy.PHY_1eh = phy_read(eng, 30);
20515c8f9400Sryan_chen 	if (eng->phy.PHY_1eh & 0x0100) {
20525c8f9400Sryan_chen 		printf("\n\n[Warning] Debug register offset = 5, bit 8 must be "
20535c8f9400Sryan_chen 		       "0 [%04x]\n\n",
20545c8f9400Sryan_chen 		       eng->phy.PHY_1eh);
20555c8f9400Sryan_chen 		if (eng->run.TM_IOTiming)
20565c8f9400Sryan_chen 			PRINTF(FP_IO,
20575c8f9400Sryan_chen 			       "\n\n[Warning] Debug register offset = 5, bit 8 "
20585c8f9400Sryan_chen 			       "must be 0 [%04x]\n\n",
20595c8f9400Sryan_chen 			       eng->phy.PHY_1eh);
20605c8f9400Sryan_chen 		if (!eng->run.tm_tx_only)
20615c8f9400Sryan_chen 			PRINTF(FP_LOG,
20625c8f9400Sryan_chen 			       "\n\n[Warning] Debug register offset = 5, bit 8 "
20635c8f9400Sryan_chen 			       "must be 0 [%04x]\n\n",
20645c8f9400Sryan_chen 			       eng->phy.PHY_1eh);
20655c8f9400Sryan_chen 
20665c8f9400Sryan_chen 		phy_write(eng, 30, eng->phy.PHY_1eh & 0xfeff);
20675c8f9400Sryan_chen 	}
20685c8f9400Sryan_chen 	//      phy_write( eng, 30, (eng->phy.PHY_1eh & 0xfeff) | 0x0100 );
20695c8f9400Sryan_chen 
20705c8f9400Sryan_chen 	// Check CLK_25M output (Select_clk125m)
20715c8f9400Sryan_chen 	phy_write(eng, 13, 0x0007);
20725c8f9400Sryan_chen 	phy_write(eng, 14, 0x8016);
20735c8f9400Sryan_chen 	phy_write(eng, 13, 0x4007);
20745c8f9400Sryan_chen 	eng->phy.PHY_0eh = phy_read(eng, 14);
20755c8f9400Sryan_chen 	if ((eng->phy.PHY_0eh & 0x0018) != 0x0018) {
20765c8f9400Sryan_chen 		printf("\n\n[Warning] Device addrress = 7, Addrress ofset = "
20775c8f9400Sryan_chen 		       "0x8016, bit 4~3 must be 3 [%04x]\n\n",
20785c8f9400Sryan_chen 		       eng->phy.PHY_0eh);
20795c8f9400Sryan_chen 		if (eng->run.TM_IOTiming)
20805c8f9400Sryan_chen 			PRINTF(FP_IO,
20815c8f9400Sryan_chen 			       "\n\n[Warning] Device addrress = 7, Addrress "
20825c8f9400Sryan_chen 			       "ofset = 0x8016, bit 4~3 must be 3 [%04x]\n\n",
20835c8f9400Sryan_chen 			       eng->phy.PHY_0eh);
20845c8f9400Sryan_chen 		if (!eng->run.tm_tx_only)
20855c8f9400Sryan_chen 			PRINTF(FP_LOG,
20865c8f9400Sryan_chen 			       "\n\n[Warning] Device addrress = 7, Addrress "
20875c8f9400Sryan_chen 			       "ofset = 0x8016, bit 4~3 must be 3 [%04x]\n\n",
20885c8f9400Sryan_chen 			       eng->phy.PHY_0eh);
20895c8f9400Sryan_chen 		printf("          The CLK_25M don't ouput 125MHz clock for the "
20905c8f9400Sryan_chen 		       "RGMIICK !!!\n\n");
20915c8f9400Sryan_chen 
20925c8f9400Sryan_chen 		phy_write(eng, 14, (eng->phy.PHY_0eh & 0xffe7) | 0x0018);
20935c8f9400Sryan_chen 	}
20945c8f9400Sryan_chen 
20955c8f9400Sryan_chen 	if (eng->run.tm_tx_only) {
20965c8f9400Sryan_chen 		if (eng->run.TM_IEEE) {
20975c8f9400Sryan_chen 			phy_write(eng, 0, eng->phy.PHY_00h);
20985c8f9400Sryan_chen 		} else {
20995c8f9400Sryan_chen 			phy_write(eng, 0, eng->phy.PHY_00h);
21005c8f9400Sryan_chen 		}
21015c8f9400Sryan_chen 	} else if (eng->phy.loopback) {
21025c8f9400Sryan_chen 		phy_write(eng, 0, eng->phy.PHY_00h);
21035c8f9400Sryan_chen 	} else {
2104ff33b245SDylan Hung 		phy_clrset(
21055c8f9400Sryan_chen 		    eng, 11, 0x8000,
21065c8f9400Sryan_chen 		    0x0000); // clr set//Disable hibernate: Reg0Bh[15] = 0
2107ff33b245SDylan Hung 		phy_clrset(
21085c8f9400Sryan_chen 		    eng, 17, 0x0000,
21095c8f9400Sryan_chen 		    0x0001); // clr set//Enable external loopback: Reg11h[0] = 1
21105c8f9400Sryan_chen 
21115c8f9400Sryan_chen 		phy_write(eng, 0, eng->phy.PHY_00h | 0x8000);
21125c8f9400Sryan_chen #ifdef Delay_PHYRst
21135c8f9400Sryan_chen 		phy_delay(Delay_PHYRst);
21145c8f9400Sryan_chen #endif
21155c8f9400Sryan_chen 	}
21165c8f9400Sryan_chen }
21175c8f9400Sryan_chen 
21185c8f9400Sryan_chen //------------------------------------------------------------
phy_default(MAC_ENGINE * eng)21195c8f9400Sryan_chen void phy_default (MAC_ENGINE *eng)
21205c8f9400Sryan_chen {
21215c8f9400Sryan_chen 	nt_log_func_name();
21225c8f9400Sryan_chen 
2123ee3c59a9SDylan Hung 	phy_reset(eng);
21245c8f9400Sryan_chen }
21255c8f9400Sryan_chen 
21265c8f9400Sryan_chen //------------------------------------------------------------
21275c8f9400Sryan_chen // PHY Init
21285c8f9400Sryan_chen //------------------------------------------------------------
21295c8f9400Sryan_chen /**
21305c8f9400Sryan_chen  * @return	1->addr found,  0->else
21315c8f9400Sryan_chen */
phy_find_addr(MAC_ENGINE * eng)21325c8f9400Sryan_chen uint32_t phy_find_addr(MAC_ENGINE *eng)
21335c8f9400Sryan_chen {
2134daba96f3SDylan Hung 	uint32_t value;
21355c8f9400Sryan_chen 	uint32_t ret = 0;
2136daba96f3SDylan Hung 	int8_t phy_addr_org;
21375c8f9400Sryan_chen 
21385c8f9400Sryan_chen 	nt_log_func_name();
21395c8f9400Sryan_chen 
2140daba96f3SDylan Hung         phy_addr_org = eng->phy.Adr;
2141daba96f3SDylan Hung         value = phy_read(eng, PHY_REG_ID_1);
21425c8f9400Sryan_chen 
2143daba96f3SDylan Hung         ret = PHY_IS_VALID(value);
2144337226aaSDylan Hung         if ((ret == 0) && (eng->arg.ctrl.b.skip_phy_id_check)) {
2145daba96f3SDylan Hung 		value = phy_read(eng, PHY_REG_BMCR);
2146daba96f3SDylan Hung 		if ((value & BIT(15)) && (0 == eng->arg.ctrl.b.skip_phy_init)) {
2147daba96f3SDylan Hung                         /* user wants to skip PHY init but PHY is in reset state
2148daba96f3SDylan Hung                          * this case should not be allowed.
2149daba96f3SDylan Hung                          */
21505c8f9400Sryan_chen 		} else {
21515c8f9400Sryan_chen 			ret = 1;
21525c8f9400Sryan_chen 		}
21535c8f9400Sryan_chen 	}
21545c8f9400Sryan_chen 
21555c8f9400Sryan_chen 	if (ret == 0) {
21565c8f9400Sryan_chen 		for (eng->phy.Adr = 0; eng->phy.Adr < 32; eng->phy.Adr++) {
2157daba96f3SDylan Hung 			value = phy_read(eng, PHY_REG_ID_1);
2158daba96f3SDylan Hung 			if (PHY_IS_VALID(value)) {
21595c8f9400Sryan_chen 				ret = 1;
21605c8f9400Sryan_chen 				break;
21615c8f9400Sryan_chen 			}
21625c8f9400Sryan_chen 		}
21635c8f9400Sryan_chen 	}
2164daba96f3SDylan Hung 
21655c8f9400Sryan_chen 	if (ret == 0)
21665c8f9400Sryan_chen 		eng->phy.Adr = eng->arg.phy_addr;
21675c8f9400Sryan_chen 
2168daba96f3SDylan Hung 	if (0 == eng->arg.ctrl.b.skip_phy_init) {
21695c8f9400Sryan_chen 		if (ret == 1) {
2170daba96f3SDylan Hung 			if (phy_addr_org != eng->phy.Adr) {
2171daba96f3SDylan Hung 				phy_scan_id(eng, STD_OUT);
21725c8f9400Sryan_chen 			}
21735c8f9400Sryan_chen 		} else {
2174daba96f3SDylan Hung 			phy_scan_id(eng, STD_OUT);
21755c8f9400Sryan_chen 			FindErr(eng, Err_Flag_PHY_Type);
21765c8f9400Sryan_chen 		}
21775c8f9400Sryan_chen 	}
21785c8f9400Sryan_chen 
21795c8f9400Sryan_chen 
2180daba96f3SDylan Hung 	eng->phy.id1 = phy_read(eng, PHY_REG_ID_1);
2181daba96f3SDylan Hung 	eng->phy.id2 = phy_read(eng, PHY_REG_ID_2);
2182daba96f3SDylan Hung         value = (eng->phy.id2 << 16) | eng->phy.id1;
2183daba96f3SDylan Hung 
2184337226aaSDylan Hung 	if (0 == eng->arg.ctrl.b.skip_phy_id_check) {
2185daba96f3SDylan Hung                 if ((value == 0) || (value == 0xffffffff)) {
21865c8f9400Sryan_chen                         sprintf((char *)eng->phy.phy_name, "--");
2187daba96f3SDylan Hung                         if (0 == eng->arg.ctrl.b.skip_phy_init)
21885c8f9400Sryan_chen 			        FindErr(eng, Err_Flag_PHY_Type);
21895c8f9400Sryan_chen                 }
21905c8f9400Sryan_chen         }
21915c8f9400Sryan_chen 
21925c8f9400Sryan_chen         return ret;
21935c8f9400Sryan_chen }
21945c8f9400Sryan_chen 
21955c8f9400Sryan_chen //------------------------------------------------------------
phy_set00h(MAC_ENGINE * eng)21965c8f9400Sryan_chen void phy_set00h (MAC_ENGINE *eng)
21975c8f9400Sryan_chen {
21985c8f9400Sryan_chen 	nt_log_func_name();
2199e1be0065SDylan Hung 
2200e1be0065SDylan Hung 	eng->phy.PHY_00h = BIT(8);
2201e1be0065SDylan Hung 
22025c8f9400Sryan_chen 	if (eng->run.speed_sel[0])
2203e1be0065SDylan Hung 		eng->phy.PHY_00h |= BIT(6);
22045c8f9400Sryan_chen 	else if (eng->run.speed_sel[1])
2205e1be0065SDylan Hung 		eng->phy.PHY_00h |= BIT(13);
2206e1be0065SDylan Hung 
2207e1be0065SDylan Hung 	if (eng->phy.loopback)
2208e1be0065SDylan Hung 		eng->phy.PHY_00h |= BIT(14);
22095c8f9400Sryan_chen }
22105c8f9400Sryan_chen 
phy_check_id(MAC_ENGINE * p_eng,const struct phy_desc * p_phy)2211daba96f3SDylan Hung static uint32_t phy_check_id(MAC_ENGINE *p_eng, const struct phy_desc *p_phy)
22125c8f9400Sryan_chen {
2213daba96f3SDylan Hung         uint32_t value, id;
22145c8f9400Sryan_chen 
2215daba96f3SDylan Hung         value  = (p_eng->phy.id1 << 16) | (p_eng->phy.id2 & p_phy->id2_mask);
2216daba96f3SDylan Hung         id  = (p_phy->id1 << 16) | (p_phy->id2 & p_phy->id2_mask);
2217daba96f3SDylan Hung         debug("%s:value %04x, id %04x\n", __func__, value, id);
2218daba96f3SDylan Hung 
2219daba96f3SDylan Hung         if (value == id)
2220daba96f3SDylan Hung                 return 1;
2221daba96f3SDylan Hung 
2222daba96f3SDylan Hung         return 0;
22235c8f9400Sryan_chen }
22245c8f9400Sryan_chen 
phy_select(MAC_ENGINE * eng,PHY_ENGINE * phyeng)2225daba96f3SDylan Hung void phy_select(MAC_ENGINE *eng, PHY_ENGINE *phyeng)
22265c8f9400Sryan_chen {
22275c8f9400Sryan_chen 	int i;
22285c8f9400Sryan_chen 	const struct phy_desc *p_phy;
22295c8f9400Sryan_chen 	nt_log_func_name();
22305c8f9400Sryan_chen 
22315c8f9400Sryan_chen 	/* set default before lookup */
22325c8f9400Sryan_chen 	sprintf((char *)eng->phy.phy_name, "default");
22335c8f9400Sryan_chen 	phyeng->fp_set = phy_default;
22345c8f9400Sryan_chen 	phyeng->fp_clr = NULL;
22355c8f9400Sryan_chen 
22365c8f9400Sryan_chen 	if (eng->phy.default_phy) {
22375c8f9400Sryan_chen 		debug("use default PHY\n");
22385c8f9400Sryan_chen 	} else {
22395c8f9400Sryan_chen 		for (i = 0; i < PHY_LOOKUP_N; i++) {
22405c8f9400Sryan_chen 			p_phy = &phy_lookup_tbl[i];
2241daba96f3SDylan Hung 			if (phy_check_id(eng, p_phy)) {
22425c8f9400Sryan_chen 				sprintf((char *)eng->phy.phy_name,
22435c8f9400Sryan_chen 					(char *)p_phy->name);
22445c8f9400Sryan_chen 				phyeng->fp_set = p_phy->cfg.fp_set;
22455c8f9400Sryan_chen 				phyeng->fp_clr = p_phy->cfg.fp_clr;
22465c8f9400Sryan_chen 				break;
22475c8f9400Sryan_chen 			}
22485c8f9400Sryan_chen 		}
22495c8f9400Sryan_chen 	}
22505c8f9400Sryan_chen 
2251daba96f3SDylan Hung 	if (eng->arg.ctrl.b.skip_phy_init) {
22525c8f9400Sryan_chen 		phyeng->fp_set = NULL;
22535c8f9400Sryan_chen 		phyeng->fp_clr = NULL;
2254337226aaSDylan Hung 	} else if (eng->arg.ctrl.b.skip_phy_deinit) {
22555c8f9400Sryan_chen 		phyeng->fp_clr = NULL;
22565c8f9400Sryan_chen 	}
22575c8f9400Sryan_chen }
22585c8f9400Sryan_chen 
22595c8f9400Sryan_chen //------------------------------------------------------------
recov_phy(MAC_ENGINE * eng,PHY_ENGINE * phyeng)22605c8f9400Sryan_chen void recov_phy (MAC_ENGINE *eng, PHY_ENGINE *phyeng)
22615c8f9400Sryan_chen {
22625c8f9400Sryan_chen 	nt_log_func_name();
22635c8f9400Sryan_chen 
22645c8f9400Sryan_chen 	if (phyeng->fp_clr != NULL)
22655c8f9400Sryan_chen         	(*phyeng->fp_clr)( eng );
22665c8f9400Sryan_chen }
22675c8f9400Sryan_chen 
22685c8f9400Sryan_chen //------------------------------------------------------------
init_phy(MAC_ENGINE * eng,PHY_ENGINE * phyeng)22695c8f9400Sryan_chen void init_phy (MAC_ENGINE *eng, PHY_ENGINE *phyeng)
22705c8f9400Sryan_chen {
22715c8f9400Sryan_chen 	nt_log_func_name();
22725c8f9400Sryan_chen 
22735c8f9400Sryan_chen 	if (DbgPrn_PHYInit)
22745c8f9400Sryan_chen 		phy_dump(eng);
22755c8f9400Sryan_chen 
22765c8f9400Sryan_chen 	phy_set00h(eng);
22775c8f9400Sryan_chen 	if (phyeng->fp_set != NULL)
22785c8f9400Sryan_chen 		(*phyeng->fp_set)(eng);
22795c8f9400Sryan_chen 
22805c8f9400Sryan_chen 	if (DbgPrn_PHYInit)
22815c8f9400Sryan_chen 		phy_dump(eng);
22825c8f9400Sryan_chen }
2283