1 /*
2 * Copyright 2021-2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "fsl_netc_mdio.h"
8
9 /*! @brief MDC standard frequency. */
10 #define NETC_MDC_FREQUENCY (2500000U)
11
12 /*! @brief MDC frequency max clock divisor. */
13 #define NETC_MDIO_CLK_MAX_DIV_FIELD (0x1FFU)
14
15 /*! @brief MDIO hold time in nanosecond. */
16 #define NETC_MDIO_HOLD_TIME_NS_MIN (10U)
17
18 /*! @brief Pointers to netc function bases for each instance. */
19 static ENETC_PCI_TYPE0_Type *const s_netcFuncBases[] = ENETC_PCI_TYPE0_BASE_PTRS;
20
21 /*! @brief Pointers to eth link bases for each instance. */
22 static NETC_ETH_LINK_Type *const s_netcEthLinkBases[] = NETC_ETH_LINK_BASE_PTRS;
23
NETC_MDIOGetOpBase(netc_mdio_handle_t * handle)24 static netc_mdio_hw_t *NETC_MDIOGetOpBase(netc_mdio_handle_t *handle)
25 {
26 if (handle->mdio.type == kNETC_EMdio)
27 {
28 return (netc_mdio_hw_t *)(uintptr_t)&EMDIO_BASE->EMDIO_CFG;
29 }
30 else
31 {
32 return (netc_mdio_hw_t *)(uintptr_t)&s_netcEthLinkBases[handle->mdio.port]->PEMDIOCR;
33 }
34 }
35
36 /*
37 * Port external MDIO Access functions
38 */
39
NETC_PEMDIO_Init(netc_mdio_hw_t * base,netc_mdio_config_t * mdioConfig)40 static status_t NETC_PEMDIO_Init(netc_mdio_hw_t *base, netc_mdio_config_t *mdioConfig)
41 {
42 bool eHold = false;
43 uint32_t holdCycle;
44 uint32_t mdioHold;
45 uint32_t config;
46 uint32_t div;
47
48 /* Set the divisor MDC. */
49 div = mdioConfig->srcClockHz / NETC_MDC_FREQUENCY / 2U;
50 if (div > NETC_MDIO_CLK_MAX_DIV_FIELD)
51 {
52 return kStatus_Fail;
53 }
54
55 /* A hold time of 10ns is required. */
56 holdCycle = (NETC_MDIO_HOLD_TIME_NS_MIN + NETC_NANOSECOND_ONE_SECOND / mdioConfig->srcClockHz - 1U) /
57 (NETC_NANOSECOND_ONE_SECOND / mdioConfig->srcClockHz);
58
59 if ((holdCycle > 57U) || (holdCycle == 0U))
60 {
61 return kStatus_Fail;
62 }
63 else if (holdCycle > 15U)
64 {
65 eHold = true;
66 mdioHold = (holdCycle - 2U) / 8U + 1U;
67 }
68 else
69 {
70 mdioHold = holdCycle / 2U;
71 }
72
73 config = ENETC_PF_EMDIO_EMDIO_CFG_NEG(mdioConfig->isNegativeDriven) | ENETC_PF_EMDIO_EMDIO_CFG_MDIO_CLK_DIV(div) |
74 ENETC_PF_EMDIO_EMDIO_CFG_PRE_DIS(mdioConfig->isPreambleDisable) |
75 ENETC_PF_EMDIO_EMDIO_CFG_MDIO_HOLD(mdioHold) | ENETC_PF_EMDIO_EMDIO_CFG_EHOLD(eHold);
76 base->EMDIO_CFG = config;
77
78 return kStatus_Success;
79 }
80
NETC_PEMDIO_IsSMIBusy(netc_mdio_hw_t * base)81 static bool NETC_PEMDIO_IsSMIBusy(netc_mdio_hw_t *base)
82 {
83 return ((base->EMDIO_CFG & ENETC_PF_EMDIO_EMDIO_CFG_BSY1_MASK) != 0U) ? true : false;
84 }
85
NETC_PEMDIO_IsPhyAddrErr(netc_mdio_hw_t * base)86 static bool NETC_PEMDIO_IsPhyAddrErr(netc_mdio_hw_t *base)
87 {
88 return ((base->EMDIO_CFG & ENETC_PF_EMDIO_EMDIO_CFG_ADDR_ERR_MASK) != 0U);
89 }
90
NETC_PEMDIO_IsReadErr(netc_mdio_hw_t * base)91 static bool NETC_PEMDIO_IsReadErr(netc_mdio_hw_t *base)
92 {
93 return ((base->EMDIO_CFG & ENETC_PF_EMDIO_EMDIO_CFG_MDIO_RD_ER_MASK) != 0U);
94 }
95
NETC_PEMDIO_Write(netc_mdio_hw_t * base,uint8_t phyAddr,uint8_t regAddr,uint16_t data)96 static status_t NETC_PEMDIO_Write(netc_mdio_hw_t *base, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
97 {
98 status_t result = kStatus_Success;
99
100 base->EMDIO_CFG &= ~ENETC_PF_EMDIO_EMDIO_CFG_ENC45_MASK;
101 base->EMDIO_CTL = ENETC_PF_EMDIO_EMDIO_CTL_PORT_ADDR(phyAddr) | ENETC_PF_EMDIO_EMDIO_CTL_DEV_ADDR(regAddr);
102 base->EMDIO_DATA = data;
103
104 while (NETC_PEMDIO_IsSMIBusy(base))
105 {
106 }
107
108 if (NETC_PEMDIO_IsPhyAddrErr(base))
109 {
110 result = kStatus_Fail;
111 }
112
113 return result;
114 }
115
NETC_PEMDIO_Read(netc_mdio_hw_t * base,uint8_t phyAddr,uint8_t regAddr,uint16_t * pData)116 static status_t NETC_PEMDIO_Read(netc_mdio_hw_t *base, uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
117 {
118 status_t result = kStatus_Success;
119
120 base->EMDIO_CFG &= ~ENETC_PF_EMDIO_EMDIO_CFG_ENC45_MASK;
121 base->EMDIO_CTL = ENETC_PF_EMDIO_EMDIO_CTL_READ_MASK | ENETC_PF_EMDIO_EMDIO_CTL_PORT_ADDR(phyAddr) |
122 ENETC_PF_EMDIO_EMDIO_CTL_DEV_ADDR(regAddr);
123
124 while (NETC_PEMDIO_IsSMIBusy(base))
125 {
126 }
127
128 if (NETC_PEMDIO_IsReadErr(base) || NETC_PEMDIO_IsPhyAddrErr(base))
129 {
130 result = kStatus_Fail;
131 }
132 *pData = (uint16_t)base->EMDIO_DATA;
133
134 return result;
135 }
136
NETC_PEMDIO_C45Write(netc_mdio_hw_t * base,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t data)137 static status_t NETC_PEMDIO_C45Write(
138 netc_mdio_hw_t *base, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t data)
139 {
140 base->EMDIO_CFG |= ENETC_PF_EMDIO_EMDIO_CFG_ENC45_MASK;
141 base->EMDIO_CTL = ENETC_PF_EMDIO_EMDIO_CTL_PORT_ADDR(portAddr) | ENETC_PF_EMDIO_EMDIO_CTL_DEV_ADDR(devAddr);
142 base->EMDIO_ADDR = ENETC_PF_EMDIO_EMDIO_ADDR_REGADDR(regAddr);
143
144 while (NETC_PEMDIO_IsSMIBusy(base))
145 {
146 }
147
148 if (NETC_PEMDIO_IsPhyAddrErr(base))
149 {
150 return kStatus_Fail;
151 }
152
153 base->EMDIO_DATA = data;
154 while (NETC_PEMDIO_IsSMIBusy(base))
155 {
156 }
157
158 return kStatus_Success;
159 }
160
NETC_PEMDIO_C45Read(netc_mdio_hw_t * base,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t * pData)161 static status_t NETC_PEMDIO_C45Read(
162 netc_mdio_hw_t *base, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t *pData)
163 {
164 base->EMDIO_CFG |= ENETC_PF_EMDIO_EMDIO_CFG_ENC45_MASK;
165 base->EMDIO_CTL = ENETC_PF_EMDIO_EMDIO_CTL_PORT_ADDR(portAddr) | ENETC_PF_EMDIO_EMDIO_CTL_PORT_ADDR(devAddr);
166 base->EMDIO_ADDR = ENETC_PF_EMDIO_EMDIO_ADDR_REGADDR(regAddr);
167 while (NETC_PEMDIO_IsSMIBusy(base))
168 {
169 }
170
171 if (NETC_PEMDIO_IsPhyAddrErr(base))
172 {
173 return kStatus_Fail;
174 }
175
176 base->EMDIO_CTL = ENETC_PF_EMDIO_EMDIO_CTL_READ_MASK | ENETC_PF_EMDIO_EMDIO_CTL_PORT_ADDR(portAddr) |
177 ENETC_PF_EMDIO_EMDIO_CTL_DEV_ADDR(devAddr);
178 while (NETC_PEMDIO_IsSMIBusy(base))
179 {
180 }
181
182 if (NETC_PEMDIO_IsReadErr(base))
183 {
184 return kStatus_Fail;
185 }
186
187 *pData = (uint16_t)base->EMDIO_DATA;
188 return kStatus_Success;
189 }
190
191 /*
192 * Port internal MDIO Access functions
193 */
194
NETC_PIMDIO_Init(NETC_ETH_LINK_Type * base,netc_mdio_config_t * mdioConfig)195 static status_t NETC_PIMDIO_Init(NETC_ETH_LINK_Type *base, netc_mdio_config_t *mdioConfig)
196 {
197 uint32_t holdCycle;
198 uint32_t mdioHold;
199 uint32_t div;
200
201 /* Set the divisor MDC. */
202 div = mdioConfig->srcClockHz / NETC_MDC_FREQUENCY / 2U;
203 if (div > NETC_MDIO_CLK_MAX_DIV_FIELD)
204 {
205 return kStatus_Fail;
206 }
207
208 /* A hold time of 10ns is required. */
209 holdCycle = (NETC_MDIO_HOLD_TIME_NS_MIN + NETC_NANOSECOND_ONE_SECOND / mdioConfig->srcClockHz - 1U) /
210 (NETC_NANOSECOND_ONE_SECOND / mdioConfig->srcClockHz);
211
212 if ((holdCycle > 15U) || (holdCycle == 0U))
213 {
214 return kStatus_Fail;
215 }
216 else
217 {
218 mdioHold = holdCycle / 2U;
219 }
220
221 base->PM0_MDIO_CFG = NETC_ETH_LINK_PM0_MDIO_CFG_MDIO_CLK_DIV(div) |
222 NETC_ETH_LINK_PM0_MDIO_CFG_PRE_DIS(mdioConfig->isPreambleDisable) |
223 NETC_ETH_LINK_PM0_MDIO_CFG_MDIO_HOLD(mdioHold);
224
225 return kStatus_Success;
226 }
227
NETC_PIMDIO_IsSMIBusy(NETC_ETH_LINK_Type * base)228 static bool NETC_PIMDIO_IsSMIBusy(NETC_ETH_LINK_Type *base)
229 {
230 return ((base->PM0_MDIO_CTL & NETC_ETH_LINK_PM0_MDIO_CTL_BSY_MASK) != 0U) ? true : false;
231 }
232
NETC_PIMDIO_Write(NETC_ETH_LINK_Type * base,uint8_t phyAddr,uint8_t regAddr,uint16_t data)233 static void NETC_PIMDIO_Write(NETC_ETH_LINK_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
234 {
235 base->PM0_MDIO_CFG &= ~NETC_ETH_LINK_PM0_MDIO_CFG_ENC45_MASK;
236 base->PM0_MDIO_CTL = NETC_ETH_LINK_PM0_MDIO_CTL_PORT_ADDR(phyAddr) | NETC_ETH_LINK_PM0_MDIO_CTL_DEV_ADDR(regAddr);
237 base->PM0_MDIO_DATA = data;
238 while (NETC_PIMDIO_IsSMIBusy(base))
239 {
240 }
241 }
242
NETC_PIMDIO_Read(NETC_ETH_LINK_Type * base,uint8_t phyAddr,uint8_t regAddr,uint16_t * pData)243 static void NETC_PIMDIO_Read(NETC_ETH_LINK_Type *base, uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
244 {
245 base->PM0_MDIO_CFG &= ~NETC_ETH_LINK_PM0_MDIO_CFG_ENC45_MASK;
246 base->PM0_MDIO_CTL = NETC_ETH_LINK_PM0_MDIO_CTL_READ_MASK | NETC_ETH_LINK_PM0_MDIO_CTL_PORT_ADDR(phyAddr) |
247 NETC_ETH_LINK_PM0_MDIO_CTL_DEV_ADDR(regAddr);
248 while (NETC_PIMDIO_IsSMIBusy(base))
249 {
250 }
251
252 *pData = (uint16_t)base->PM0_MDIO_DATA;
253 }
254
255 /* Internal MDIO supports C45 */
256 #if defined(NETC_ETH_LINK_PM0_MDIO_ADDR_REGADDR_MASK)
NETC_PIMDIO_C45Write(NETC_ETH_LINK_Type * base,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t data)257 static void NETC_PIMDIO_C45Write(
258 NETC_ETH_LINK_Type *base, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t data)
259 {
260 base->PM0_MDIO_CFG |= NETC_ETH_LINK_PM0_MDIO_CFG_ENC45_MASK;
261 base->PM0_MDIO_CTL = NETC_ETH_LINK_PM0_MDIO_CTL_PORT_ADDR(portAddr) |
262 NETC_ETH_LINK_PM0_MDIO_CTL_DEV_ADDR(devAddr);
263 base->PM0_MDIO_ADDR = NETC_ETH_LINK_PM0_MDIO_ADDR_REGADDR(regAddr);
264
265 while (NETC_PIMDIO_IsSMIBusy(base))
266 {
267 }
268
269 base->PM0_MDIO_DATA = NETC_ETH_LINK_PM0_MDIO_DATA_MDIO_DATA(data);
270 while (NETC_PIMDIO_IsSMIBusy(base))
271 {
272 }
273 }
274
NETC_PIMDIO_C45Read(NETC_ETH_LINK_Type * base,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t * pData)275 static status_t NETC_PIMDIO_C45Read(
276 NETC_ETH_LINK_Type *base, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t *pData)
277 {
278 base->PM0_MDIO_CFG |= NETC_ETH_LINK_PM0_MDIO_CFG_ENC45_MASK;
279 base->PM0_MDIO_CTL = NETC_ETH_LINK_PM0_MDIO_CTL_PORT_ADDR(portAddr) |
280 NETC_ETH_LINK_PM0_MDIO_CTL_DEV_ADDR(devAddr);
281 base->PM0_MDIO_ADDR = NETC_ETH_LINK_PM0_MDIO_ADDR_REGADDR(regAddr);
282
283 while (NETC_PIMDIO_IsSMIBusy(base))
284 {
285 }
286
287 base->PM0_MDIO_CTL = NETC_ETH_LINK_PM0_MDIO_CTL_READ(1U) | NETC_ETH_LINK_PM0_MDIO_CTL_PORT_ADDR(portAddr) |
288 NETC_ETH_LINK_PM0_MDIO_CTL_DEV_ADDR(devAddr);
289
290 while (NETC_PIMDIO_IsSMIBusy(base))
291 {
292 }
293
294 if ((base->PM0_MDIO_CFG & 0x2U) != 0U)
295 {
296 return kStatus_Fail;
297 }
298
299 *pData = (uint16_t)base->PM0_MDIO_DATA;
300 return kStatus_Success;
301 }
302 #endif
303
304 /*
305 * MDIO API Layer MDIO Access functions
306 */
307
NETC_MDIOInit(netc_mdio_handle_t * handle,netc_mdio_config_t * config)308 status_t NETC_MDIOInit(netc_mdio_handle_t *handle, netc_mdio_config_t *config)
309 {
310 assert(config->srcClockHz != 0U);
311
312 uint32_t funcFlags = ENETC_PCI_TYPE0_PCI_CFH_CMD_MEM_ACCESS_MASK | ENETC_PCI_TYPE0_PCI_CFH_CMD_BUS_MASTER_EN_MASK;
313 netc_mdio_hw_t *mdioBase;
314 NETC_ETH_LINK_Type *base;
315 uint32_t instance;
316 status_t result;
317
318 handle->mdio = config->mdio;
319
320 /* Port MDIO needs EP/Switch to enable the register access permission. */
321 if (handle->mdio.type != kNETC_EMdio)
322 {
323 instance = NETC_SocGetFuncInstance(handle->mdio.port);
324 if ((s_netcFuncBases[instance]->PCI_CFH_CMD & funcFlags) != funcFlags)
325 {
326 return kStatus_Fail;
327 }
328 }
329
330 if (handle->mdio.type == kNETC_InternalMdio)
331 {
332 base = s_netcEthLinkBases[handle->mdio.port];
333 result = NETC_PIMDIO_Init(base, config);
334 }
335 else
336 {
337 if (handle->mdio.type == kNETC_EMdio)
338 {
339 mdioBase = (netc_mdio_hw_t *)(uintptr_t)&EMDIO_BASE->EMDIO_CFG;
340
341 /* Reset EMDIO submodule */
342 EMDIO_PCI_HDR_TYPE0->PCI_CFC_PCIE_DEV_CTL |= ENETC_PCI_TYPE0_PCI_CFC_PCIE_DEV_CTL_INIT_FLR_MASK;
343 while ((EMDIO_PCI_HDR_TYPE0->PCI_CFC_PCIE_DEV_CTL & ENETC_PCI_TYPE0_PCI_CFC_PCIE_DEV_CTL_INIT_FLR_MASK) !=
344 0U)
345 {
346 }
347
348 /* Enable master bus and memory access for PCIe and MSI-X */
349 EMDIO_PCI_HDR_TYPE0->PCI_CFH_CMD |=
350 (ENETC_PCI_TYPE0_PCI_CFH_CMD_MEM_ACCESS_MASK | ENETC_PCI_TYPE0_PCI_CFH_CMD_BUS_MASTER_EN_MASK);
351 }
352 else
353 {
354 base = s_netcEthLinkBases[handle->mdio.port];
355 mdioBase = (netc_mdio_hw_t *)(uintptr_t)&base->PEMDIOCR;
356 }
357 result = NETC_PEMDIO_Init(mdioBase, config);
358 }
359
360 return result;
361 }
362
NETC_MDIOWrite(netc_mdio_handle_t * handle,uint8_t phyAddr,uint8_t regAddr,uint16_t data)363 status_t NETC_MDIOWrite(netc_mdio_handle_t *handle, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
364 {
365 NETC_ETH_LINK_Type *base = s_netcEthLinkBases[handle->mdio.port];
366 status_t result;
367
368 if (handle->mdio.type == kNETC_InternalMdio)
369 {
370 NETC_PIMDIO_Write(base, phyAddr, regAddr, data);
371 result = kStatus_Success;
372 }
373 else
374 {
375 result = NETC_PEMDIO_Write(NETC_MDIOGetOpBase(handle), phyAddr, regAddr, data);
376 }
377
378 return result;
379 }
380
NETC_MDIORead(netc_mdio_handle_t * handle,uint8_t phyAddr,uint8_t regAddr,uint16_t * pData)381 status_t NETC_MDIORead(netc_mdio_handle_t *handle, uint8_t phyAddr, uint8_t regAddr, uint16_t *pData)
382 {
383 NETC_ETH_LINK_Type *base = s_netcEthLinkBases[handle->mdio.port];
384 status_t result;
385
386 if (handle->mdio.type == kNETC_InternalMdio)
387 {
388 NETC_PIMDIO_Read(base, phyAddr, regAddr, pData);
389 result = kStatus_Success;
390 }
391 else
392 {
393 result = NETC_PEMDIO_Read(NETC_MDIOGetOpBase(handle), phyAddr, regAddr, pData);
394 }
395
396 return result;
397 }
398
NETC_MDIOC45Write(netc_mdio_handle_t * handle,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t data)399 status_t NETC_MDIOC45Write(
400 netc_mdio_handle_t *handle, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t data)
401 {
402 status_t result;
403
404 if (handle->mdio.type == kNETC_InternalMdio)
405 {
406 #if defined(NETC_ETH_LINK_PM0_MDIO_ADDR_REGADDR_MASK)
407 NETC_PIMDIO_C45Write(s_netcEthLinkBases[handle->mdio.port], portAddr, devAddr, regAddr, data);
408 result = kStatus_Success;
409 #else
410 result = kStatus_NETC_Unsupported;
411 #endif
412 }
413 else
414 {
415 result = NETC_PEMDIO_C45Write(NETC_MDIOGetOpBase(handle), portAddr, devAddr, regAddr, data);
416 }
417
418 return result;
419 }
420
NETC_MDIOC45Read(netc_mdio_handle_t * handle,uint8_t portAddr,uint8_t devAddr,uint16_t regAddr,uint16_t * pData)421 status_t NETC_MDIOC45Read(
422 netc_mdio_handle_t *handle, uint8_t portAddr, uint8_t devAddr, uint16_t regAddr, uint16_t *pData)
423 {
424 status_t result;
425
426 if (handle->mdio.type == kNETC_InternalMdio)
427 {
428 #if defined(NETC_ETH_LINK_PM0_MDIO_ADDR_REGADDR_MASK)
429 result = NETC_PIMDIO_C45Read(s_netcEthLinkBases[handle->mdio.port], portAddr, devAddr, regAddr, pData);
430 #else
431 result = kStatus_NETC_Unsupported;
432 #endif
433 }
434 else
435 {
436 result = NETC_PEMDIO_C45Read(NETC_MDIOGetOpBase(handle), portAddr, devAddr, regAddr, pData);
437 }
438
439 return result;
440 }
441
NETC_MDIOSetPhyStatusCheck(netc_mdio_handle_t * handle,netc_mdio_phy_status_t * config)442 status_t NETC_MDIOSetPhyStatusCheck(netc_mdio_handle_t *handle, netc_mdio_phy_status_t *config)
443 {
444 status_t result = kStatus_Success;
445 netc_mdio_hw_t *mdioBase;
446
447 if (handle->mdio.type == kNETC_InternalMdio)
448 {
449 result = kStatus_NETC_Unsupported;
450 }
451 else
452 {
453 mdioBase = NETC_MDIOGetOpBase(handle);
454 mdioBase->PHY_STATUS_CFG = ENETC_PF_EMDIO_PHY_STATUS_CFG_STATUS_INTERVAL(config->interval);
455 mdioBase->PHY_STATUS_CTL = ENETC_PF_EMDIO_PHY_STATUS_CTL_PORT_ADDR(config->phyOrPortAddr) |
456 ENETC_PF_EMDIO_PHY_STATUS_CTL_DEV_ADDR(config->regiOrDevAddr);
457 mdioBase->PHY_STATUS_ADDR = ENETC_PF_EMDIO_PHY_STATUS_ADDR_REGADDR(config->c45RegiAddr);
458 mdioBase->PHY_STATUS_MASK = ((uint32_t)config->enableIntrLow2High << 16U) + config->enableIntrHigh2Low;
459 }
460
461 return result;
462 }
463
NETC_MDIOPhyStatusGetFlags(netc_mdio_handle_t * handle,uint16_t * low2HighMask,uint16_t * high2LowMask)464 void NETC_MDIOPhyStatusGetFlags(netc_mdio_handle_t *handle, uint16_t *low2HighMask, uint16_t *high2LowMask)
465 {
466 assert(handle->mdio.type != kNETC_InternalMdio);
467 assert(low2HighMask != NULL);
468 assert(high2LowMask != NULL);
469
470 netc_mdio_hw_t *mdioBase = NETC_MDIOGetOpBase(handle);
471 uint32_t event = mdioBase->PHY_STATUS_EVENT;
472
473 *low2HighMask = (uint16_t)((event >> 16U) & 0xFFFFU);
474 *high2LowMask = (uint16_t)(event & 0xFFFFU);
475 }
476
NETC_MDIOPhyStatusClearFlags(netc_mdio_handle_t * handle,uint16_t low2HighMask,uint16_t high2LowMask)477 void NETC_MDIOPhyStatusClearFlags(netc_mdio_handle_t *handle, uint16_t low2HighMask, uint16_t high2LowMask)
478 {
479 assert(handle->mdio.type != kNETC_InternalMdio);
480
481 NETC_ETH_LINK_Type *base = s_netcEthLinkBases[handle->mdio.port];
482 netc_mdio_hw_t *mdioBase;
483
484 if (handle->mdio.type == kNETC_EMdio)
485 {
486 mdioBase = (netc_mdio_hw_t *)(uintptr_t)&EMDIO_BASE->EMDIO_CFG;
487 }
488 else
489 {
490 base = s_netcEthLinkBases[handle->mdio.port];
491 mdioBase = (netc_mdio_hw_t *)(uintptr_t)&base->PEMDIOCR;
492 }
493 mdioBase->PHY_STATUS_EVENT = ((uint32_t)low2HighMask << 16U) + high2LowMask;
494 }
495