1 /*
2 * Copyright (c) 2021-2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 /*---------------------------------------------------------------------
9 * Includes
10 *---------------------------------------------------------------------
11 */
12 #include "hpm_enet_drv.h"
13 #include "hpm_rtl8211_regs.h"
14 #include "hpm_rtl8211.h"
15 #include "board.h"
16
17 /*---------------------------------------------------------------------
18 * Internal API
19 *---------------------------------------------------------------------
20 */
rtl8211_check_id(ENET_Type * ptr)21 static bool rtl8211_check_id(ENET_Type *ptr)
22 {
23 uint16_t id1, id2;
24
25 id1 = enet_read_phy(ptr, RTL8211_ADDR, RTL8211_PHYID1);
26 id2 = enet_read_phy(ptr, RTL8211_ADDR, RTL8211_PHYID2);
27
28 if (RTL8211_PHYID1_OUI_MSB_GET(id1) == RTL8211_ID1 && RTL8211_PHYID2_OUI_LSB_GET(id2) == RTL8211_ID2) {
29 return true;
30 } else {
31 return false;
32 }
33 }
34
35 /*---------------------------------------------------------------------
36 * API
37 *---------------------------------------------------------------------
38 */
rtl8211_reset(ENET_Type * ptr)39 void rtl8211_reset(ENET_Type *ptr)
40 {
41 uint16_t data;
42
43 /* PHY reset */
44 enet_write_phy(ptr, RTL8211_ADDR, RTL8211_BMCR, RTL8211_BMCR_RESET_SET(1));
45
46 /* wait until the reset is completed */
47 do {
48 data = enet_read_phy(ptr, RTL8211_ADDR, RTL8211_BMCR);
49 } while (RTL8211_BMCR_RESET_GET(data));
50 }
51
rtl8211_basic_mode_default_config(ENET_Type * ptr,rtl8211_config_t * config)52 void rtl8211_basic_mode_default_config(ENET_Type *ptr, rtl8211_config_t *config)
53 {
54 (void)ptr;
55
56 config->loopback = 0; /* Disable PCS loopback mode */
57 #if defined(__DISABLE_AUTO_NEGO) && (__DISABLE_AUTO_NEGO)
58 config->auto_negotiation = false; /* Disable Auto-Negotiation */
59 config->speed = enet_phy_port_speed_100mbps;
60 config->duplex = enet_phy_duplex_full;
61 #else
62 config->auto_negotiation = 1; /* Enable Auto-Negotiation */
63 #endif
64 }
65
rtl8211_basic_mode_init(ENET_Type * ptr,rtl8211_config_t * config)66 bool rtl8211_basic_mode_init(ENET_Type *ptr, rtl8211_config_t *config)
67 {
68 uint16_t data = 0;
69
70 data |= RTL8211_BMCR_RESET_SET(0) /* Normal operation */
71 | RTL8211_BMCR_LOOPBACK_SET(config->loopback) /* configure PCS loopback mode */
72 | RTL8211_BMCR_ANE_SET(config->auto_negotiation) /* configure Auto-Negotiation */
73 | RTL8211_BMCR_PWD_SET(0) /* Normal operation */
74 | RTL8211_BMCR_ISOLATE_SET(0) /* Normal operation */
75 | RTL8211_BMCR_RESTART_AN_SET(0) /* Normal operation (ignored when Auto-Negotiation is disabled) */
76 | RTL8211_BMCR_COLLISION_TEST_SET(0); /* Normal operation */
77
78 if (config->auto_negotiation == 0) {
79 data |= RTL8211_BMCR_SPEED0_SET(config->speed) | RTL8211_BMCR_SPEED1_SET(config->speed >> 1); /* Set port speed */
80 data |= RTL8211_BMCR_DUPLEX_SET(config->duplex); /* Set duplex mode */
81 }
82
83 enet_write_phy(ptr, RTL8211_ADDR, RTL8211_BMCR, data);
84
85 /* check the id of rtl8211 */
86 if (rtl8211_check_id(ptr) == false) {
87 return false;
88 }
89
90 return true;
91 }
92
93
rtl8211_get_phy_status(ENET_Type * ptr,enet_phy_status_t * status)94 void rtl8211_get_phy_status(ENET_Type *ptr, enet_phy_status_t *status)
95 {
96 uint16_t data;
97
98 data = enet_read_phy(ptr, RTL8211_ADDR, RTL8211_PHYSR);
99 status->enet_phy_link = RTL8211_PHYSR_LINK_REAL_TIME_GET(data);
100 status->enet_phy_speed = RTL8211_PHYSR_SPEED_GET(data) == 0 ? enet_phy_port_speed_10mbps : RTL8211_PHYSR_SPEED_GET(data) == 1 ? enet_phy_port_speed_100mbps : enet_phy_port_speed_1000mbps;
101 status->enet_phy_duplex = RTL8211_PHYSR_DUPLEX_GET(data);
102 }
103