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