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