1 /*
2 * Copyright (c) 2024 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_jl1111_regs.h"
14 #include "hpm_jl1111.h"
15
16 /*---------------------------------------------------------------------
17 * Internal API
18 *---------------------------------------------------------------------
19 */
jl1111_check_id(ENET_Type * ptr)20 static bool jl1111_check_id(ENET_Type *ptr)
21 {
22 uint16_t id1, id2;
23
24 id1 = enet_read_phy(ptr, JL1111_ADDR, JL1111_PHYID1);
25 id2 = enet_read_phy(ptr, JL1111_ADDR, JL1111_PHYID2);
26
27 if (JL1111_PHYID1_OUI_MSB_GET(id1) == JL1111_ID1 && JL1111_PHYID2_OUI_LSB_GET(id2) == JL1111_ID2) {
28 return true;
29 } else {
30 return false;
31 }
32 }
33
34 /*---------------------------------------------------------------------
35 * API
36 *---------------------------------------------------------------------
37 */
jl1111_reset(ENET_Type * ptr)38 void jl1111_reset(ENET_Type *ptr)
39 {
40 uint16_t data;
41
42 /* PHY reset */
43 enet_write_phy(ptr, JL1111_ADDR, JL1111_BMCR, JL1111_BMCR_RESET_SET(1));
44
45 /* wait until the reset is completed */
46 do {
47 data = enet_read_phy(ptr, JL1111_ADDR, JL1111_BMCR);
48 } while (JL1111_BMCR_RESET_GET(data));
49 }
50
jl1111_basic_mode_default_config(ENET_Type * ptr,jl1111_config_t * config)51 void jl1111_basic_mode_default_config(ENET_Type *ptr, jl1111_config_t *config)
52 {
53 (void)ptr;
54
55 config->loopback = false; /* Disable PCS loopback mode */
56 #if defined(__DISABLE_AUTO_NEGO) && (__DISABLE_AUTO_NEGO)
57 config->auto_negotiation = false; /* Disable Auto-Negotiation */
58 config->speed = enet_phy_port_speed_100mbps;
59 config->duplex = enet_phy_duplex_full;
60 #else
61 config->auto_negotiation = true; /* Enable Auto-Negotiation */
62 #endif
63 }
64
jl1111_basic_mode_init(ENET_Type * ptr,jl1111_config_t * config)65 bool jl1111_basic_mode_init(ENET_Type *ptr, jl1111_config_t *config)
66 {
67 uint16_t data = 0;
68
69 data |= JL1111_BMCR_RESET_SET(0) /* Normal operation */
70 | JL1111_BMCR_LOOPBACK_SET(config->loopback) /* configure PCS loopback mode */
71 | JL1111_BMCR_ANE_SET(config->auto_negotiation) /* configure Auto-Negotiation */
72 | JL1111_BMCR_PWD_SET(0) /* Normal operation */
73 | JL1111_BMCR_ISOLATE_SET(0) /* Normal operation */
74 | JL1111_BMCR_RESTART_AN_SET(0) /* Normal operation (ignored when Auto-Negotiation is disabled) */
75 | JL1111_BMCR_COLLISION_TEST_SET(0); /* Normal operation */
76
77 if (config->auto_negotiation == 0) {
78 data |= JL1111_BMCR_SPEED0_SET(config->speed); /* Set port speed */
79 data |= JL1111_BMCR_DUPLEX_SET(config->duplex); /* Set duplex mode */
80 }
81
82 /* check the id of jl1111 */
83 if (jl1111_check_id(ptr) == false) {
84 return false;
85 }
86
87 enet_write_phy(ptr, JL1111_ADDR, JL1111_BMCR, data);
88
89 return true;
90 }
91
jl1111_get_phy_status(ENET_Type * ptr,enet_phy_status_t * status)92 void jl1111_get_phy_status(ENET_Type *ptr, enet_phy_status_t *status)
93 {
94 uint16_t data, anar, anlpar;
95
96 data = enet_read_phy(ptr, JL1111_ADDR, JL1111_BMSR);
97 status->enet_phy_link = JL1111_BMSR_LINK_STATUS_GET(data);
98
99 anar = enet_read_phy(ptr, JL1111_ADDR, JL1111_ANAR);
100 anlpar = enet_read_phy(ptr, JL1111_ADDR, JL1111_ANLPAR);
101 data = anar & anlpar;
102
103 if (JL1111_ANAR_100BASE_TX_GET(data)) {
104 if (JL1111_ANAR_100BASE_TX_FD_GET(data)) {
105 status->enet_phy_speed = enet_phy_port_speed_100mbps;
106 status->enet_phy_duplex = enet_phy_duplex_full;
107 } else {
108 status->enet_phy_speed = enet_phy_port_speed_100mbps;
109 status->enet_phy_duplex = enet_phy_duplex_half;
110 }
111 } else if (JL1111_ANAR_10BASE_T_GET(data)) {
112 if (JL1111_ANAR_10BASE_T_FD_GET(data)) {
113 status->enet_phy_speed = enet_phy_port_speed_10mbps;
114 status->enet_phy_duplex = enet_phy_duplex_full;
115 } else {
116 status->enet_phy_speed = enet_phy_port_speed_10mbps;
117 status->enet_phy_duplex = enet_phy_duplex_half;
118 }
119 } else {
120
121 }
122 }
123