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