1 /*
2  * Copyright 2021-2022 NXP
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef FSL_NETC_MDIO_H_
8 #define FSL_NETC_MDIO_H_
9 
10 #include "fsl_netc.h"
11 #include "fsl_netc_soc.h"
12 #include "netc_hw/fsl_netc_hw.h"
13 
14 #if !(defined(__GNUC__) || defined(__ICCARM__))
15 #pragma region api_mdio
16 #endif
17 //////////////////////////////////////
18 // Group for the MDIO Driver
19 //////////////////////////////////////
20 /*!
21  * @defgroup netc_mdio NETC MDIO Driver
22  * @details Group for MDIO API and data structure.
23  * API starts with NETC_MDIO.
24  * Parameter starts with netc_mdio_handle_t.
25  * Driver supports to access external actual PHY for normal ethernet transmission and internel virtual PHY for RevMII
26  * mode. For each MAC port, initialization should be done to bound a handle to specified MDIO port. Use handle to
27  * indicate specific MAC port to do MDIO read/write. All Clause 22/45 MDIO read/write functions will send command and
28  * wait transmission over through polling busy bit. PHY status automatical check is used to polling the register status
29  * of PHY with hardware at regular intervals.
30  * @ingroup netc_api
31  */
32 
33 /*!
34  * @defgroup netc_mdio_init MDIO initialization module
35  * @details Configurate specified MAC port MDIO
36  * @ingroup netc_mdio
37  */
38 /*!
39  * @defgroup netc_mdio_xfer MDIO write/read module
40  * @details IEEE Clause 22/45 MDIO access for PHY
41  *
42  * @ingroup netc_mdio
43  */
44 /*!
45  * @defgroup netc_mdio_phy_status MDIO PHY status module
46  * @details Automatically polling to read PHY register with hardware
47  *
48  * @ingroup netc_mdio
49  */
50 
51 #if !(defined(__GNUC__) || defined(__ICCARM__))
52 #pragma endregion api_mdio
53 #endif
54 
55 /*******************************************************************************
56  * Definitions
57  ******************************************************************************/
58 
59 #if !(defined(__GNUC__) || defined(__ICCARM__))
60 #pragma region netc_mdio_init
61 #endif
62 /*! @addtogroup netc_mdio_init
63  * @{
64  */
65 
66 /*!
67  * @brief Enumeration for the MAC port MDIO type
68  */
69 typedef enum _netc_mdio_type
70 {
71     kNETC_EMdio,        /*!< Bound handle to EMDIO access, submodule of NETC. */
72     kNETC_InternalMdio, /*!< Bound handle to MAC port internal MDIO access, submodule of EP/Switch. */
73     kNETC_ExternalMdio, /*!< Bound handle to MAC port external MDIO access, submodule of EP/Switch. */
74 } netc_mdio_type_t;
75 
76 /*!
77  * @brief Structure to choose MDIO entity(Internal/external MDIO for specified EP/Switch port)
78  */
79 typedef struct _netc_mdio
80 {
81     netc_mdio_type_t type;       /*!< Internal or external MAC port MDIO. */
82     netc_hw_eth_port_idx_t port; /*!< MDIO port index, only meaningful when port MDIO type is used. */
83 } netc_mdio_t;
84 
85 /*!
86  * @brief MDIO handle
87  */
88 typedef struct _netc_mdio_handle
89 {
90     netc_mdio_t mdio; /*!< MDIO identificator. */
91 } netc_mdio_handle_t;
92 
93 /*!
94  * @brief MDIO configuration structure
95  */
96 typedef struct _netc_mdio_config
97 {
98     netc_mdio_t mdio;       /*!< MDIO identificator. */
99     uint32_t srcClockHz;    /*!< MDIO reference clock for MDC frequency calculation. */
100     bool isNegativeDriven;  /*!< MDIO driven at positive(false)/negative(true) of MDC edge. */
101     bool isPreambleDisable; /*!< Enable/Disable generation of MDIO preamble. */
102 } netc_mdio_config_t;
103 
104 /*! @} */ // end of netc_mdio_init
105 #if !(defined(__GNUC__) || defined(__ICCARM__))
106 #pragma endregion netc_mdio_init
107 #endif
108 
109 #if !(defined(__GNUC__) || defined(__ICCARM__))
110 #pragma region netc_mdio_phy_status
111 #endif
112 /*! @addtogroup netc_mdio_phy_status
113  * @{
114  */
115 
116 /*!
117  * @brief PHY auto status check configuration structure
118  */
119 typedef struct _netc_mdio_phy_status
120 {
121     uint16_t interval;           /*!< PHY status read interval in units of 1-2 ms. A value of 0 indicates disable. */
122     bool isC45Used;              /*!< PHY status read with Clause 22/45 MDIO access. */
123     uint8_t phyOrPortAddr;       /*!< MDIO PHY address(Clause 22) / port address(Clause 45). */
124     uint8_t regiOrDevAddr;       /*!< MDIO register address(Clause 22) / device address(Clause 45). */
125     uint16_t c45RegiAddr;        /*!< MDIO register address(Clause 45). */
126     uint16_t enableIntrHigh2Low; /*!< Bit high-to-low event interrupt enable. */
127     uint16_t enableIntrLow2High; /*!< Bit low-to-high event interrupt enable. */
128 } netc_mdio_phy_status_t;
129 
130 /*! @} */ // end of netc_mdio_phy_status
131 #if !(defined(__GNUC__) || defined(__ICCARM__))
132 #pragma endregion netc_mdio_phy_status
133 #endif
134 
135 #if defined(__cplusplus)
136 extern "C" {
137 #endif
138 
139 /*******************************************************************************
140  * API
141  ******************************************************************************/
142 
143 #if !(defined(__GNUC__) || defined(__ICCARM__))
144 #pragma region netc_mdio_init
145 #endif
146 /*! @addtogroup netc_mdio_init
147  * @{
148  */
149 
150 /*!
151  * @brief Initialize the MDIO
152  * @note The EMDIO can be used independently. The port internal/external MDIO is a part of EP/Switch,
153  * should be initialized and used after EP/Switch is enabled.
154  *
155  * @param handle MDIO handle.
156  * @param config MDIO configuration.
157  * @return status_t
158  */
159 status_t NETC_MDIOInit(netc_mdio_handle_t *handle, netc_mdio_config_t *config);
160 
161 /*! @} */ // end of netc_mdio_init
162 #if !(defined(__GNUC__) || defined(__ICCARM__))
163 #pragma endregion netc_mdio_init
164 #endif
165 
166 #if !(defined(__GNUC__) || defined(__ICCARM__))
167 #pragma region netc_mdio_xfer
168 #endif
169 /*! @addtogroup netc_mdio_xfer
170  * @{
171  */
172 
173 /*!
174  * @brief IEEE802.3 Clause 22 MDIO write data
175  *
176  * @param handle MDIO handle.
177  * @param phyAddr The PHY address.
178  * @param regAddr The PHY register address.
179  * @param data The data written to PHY.
180  * @return status_t
181  */
182 status_t NETC_MDIOWrite(netc_mdio_handle_t *handle, uint8_t phyAddr, uint8_t regAddr, uint16_t data);
183 
184 /*!
185  * @brief IEEE802.3 Clause 22 MDIO read data
186  *
187  * @param handle MDIO handle.
188  * @param phyAddr The PHY address.
189  * @param regAddr The PHY register address.
190  * @param pData The received data from PHY.
191  * @return status_t
192  */
193 status_t NETC_MDIORead(netc_mdio_handle_t *handle, uint8_t phyAddr, uint8_t regAddr, uint16_t *pData);
194 
195 /*!
196  * @brief IEEE802.3 Clause 45 MDIO write data
197  *
198  * @param handle MDIO handle.
199  * @param portAddr The MDIO port address(PHY address).
200  * @param devAddr The device address.
201  * @param regAddr The PHY register address.
202  * @param data The data written to PHY.
203  * @return status_t
204  */
205 status_t NETC_MDIOC45Write(
206     netc_mdio_handle_t *handle, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t data);
207 
208 /*!
209  * @brief IEEE802.3 Clause 45 MDIO read data
210  *
211  * @param handle MDIO handle.
212  * @param portAddr The MDIO port address(PHY address).
213  * @param devAddr The device address.
214  * @param regAddr The PHY register address.
215  * @param pData The received data from PHY.
216  * @return status_t
217  */
218 status_t NETC_MDIOC45Read(
219     netc_mdio_handle_t *handle, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t *pData);
220 
221 /*! @} */ // end of netc_mdio_xfer
222 #if !(defined(__GNUC__) || defined(__ICCARM__))
223 #pragma endregion netc_mdio_xfer
224 #endif
225 
226 #if !(defined(__GNUC__) || defined(__ICCARM__))
227 #pragma region netc_mdio_phy_status
228 #endif
229 /*! @addtogroup netc_mdio_phy_status
230  * @{
231  */
232 
233 /*!
234  * @brief Setup the mechanism to check PHY status automatically
235  * This is a hardware mechanism to read specified PHY register in a configured time interval
236  * instead of polling the PHY in software.
237  *
238  * @param handle  MDIO handle.
239  * @param config  The configuration of the PHY status automatical check.
240  * @return status_t
241  */
242 status_t NETC_MDIOSetPhyStatusCheck(netc_mdio_handle_t *handle, netc_mdio_phy_status_t *config);
243 
244 /*!
245  * @brief Get the PHY register bit status transition interrupt flag(s).
246  *
247  * @param handle  MDIO handle.
248  * @param low2HighMask  The interrupt flag of a 0->1 transition on a corresponding bit of PHY register.
249  * @param high2LowMask  The interrupt flag of a 1->0 transition on a corresponding bit of PHY register.
250  */
251 void NETC_MDIOPhyStatusGetFlags(netc_mdio_handle_t *handle, uint16_t *low2HighMask, uint16_t *high2LowMask);
252 
253 /*!
254  * @brief Clear the PHY register bit status transition interrupt flag(s).
255  *
256  * @param handle  MDIO handle.
257  * @param low2HighMask  Clear the interrupt flag of a 0->1 transition on a corresponding bit of PHY register.
258  * @param high2LowMask  Clear the interrupt flag of a 1->0 transition on a corresponding bit of PHY register.
259  */
260 void NETC_MDIOPhyStatusClearFlags(netc_mdio_handle_t *handle, uint16_t low2HighMask, uint16_t high2LowMask);
261 
262 /*! @} */ // end of netc_mdio_phy_status
263 #if !(defined(__GNUC__) || defined(__ICCARM__))
264 #pragma endregion netc_mdio_phy_status
265 #endif
266 
267 #if defined(__cplusplus)
268 }
269 #endif
270 #endif /* FSL_NETC_MDIO_H_ */
271