1 /*
2  * Copyright 2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include "fsl_enet_mdio.h"
9 
10 /*******************************************************************************
11  * Definitions
12  ******************************************************************************/
13 
14 /*******************************************************************************
15  * Prototypes
16  ******************************************************************************/
17 
18 static void ENET_MDIO_Init(mdio_handle_t *handle);
19 
20 static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data);
21 
22 static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr);
23 
24 /*******************************************************************************
25  * Variables
26  ******************************************************************************/
27 
28 const mdio_operations_t lpc_enet_ops = {.mdioInit     = ENET_MDIO_Init,
29                                         .mdioWrite    = ENET_MDIO_Write,
30                                         .mdioRead     = ENET_MDIO_Read,
31                                         .mdioWriteExt = NULL,
32                                         .mdioReadExt  = NULL};
33 
34 /*******************************************************************************
35  * Code
36  ******************************************************************************/
37 
ENET_MDIO_Init(mdio_handle_t * handle)38 static void ENET_MDIO_Init(mdio_handle_t *handle)
39 {
40     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
41     ENET_Type *base           = (ENET_Type *)resource->base;
42     uint32_t instance         = ENET_GetInstance(base);
43 
44 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
45     /* Set SMI first. */
46     (void)CLOCK_EnableClock(s_enetClock[instance]);
47 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
48     ENET_SetSMI(base);
49 }
50 
ENET_MDIO_Write(mdio_handle_t * handle,uint32_t phyAddr,uint32_t devAddr,uint32_t data)51 static status_t ENET_MDIO_Write(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t data)
52 {
53     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
54     ENET_Type *base           = (ENET_Type *)resource->base;
55     status_t result           = kStatus_Success;
56 #ifdef MDIO_TIMEOUT_COUNT
57     uint32_t counter;
58 #endif
59 
60     ENET_StartSMIWrite(base, phyAddr, devAddr, data);
61 #ifdef MDIO_TIMEOUT_COUNT
62     for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
63     {
64         if (!ENET_IsSMIBusy(base))
65         {
66             break;
67         }
68     }
69     /* Check for timeout. */
70     if (0U == counter)
71     {
72         result = kStatus_PHY_SMIVisitTimeout;
73     }
74 #else
75     while (ENET_IsSMIBusy(base))
76     {
77     }
78 #endif
79 
80     return result;
81 }
82 
ENET_MDIO_Read(mdio_handle_t * handle,uint32_t phyAddr,uint32_t devAddr,uint32_t * dataPtr)83 static status_t ENET_MDIO_Read(mdio_handle_t *handle, uint32_t phyAddr, uint32_t devAddr, uint32_t *dataPtr)
84 {
85     assert(dataPtr);
86 
87     mdio_resource_t *resource = (mdio_resource_t *)&handle->resource;
88     ENET_Type *base           = (ENET_Type *)resource->base;
89     status_t result           = kStatus_Success;
90 #ifdef MDIO_TIMEOUT_COUNT
91     uint32_t counter;
92 #endif
93 
94     ENET_StartSMIRead(base, phyAddr, devAddr);
95 #ifdef MDIO_TIMEOUT_COUNT
96     for (counter = MDIO_TIMEOUT_COUNT; counter > 0U; counter--)
97     {
98         if (!ENET_IsSMIBusy(base))
99         {
100             break;
101         }
102     }
103     /* Check for timeout. */
104     if (0U == counter)
105     {
106         result = kStatus_PHY_SMIVisitTimeout;
107     }
108 #else
109     while (ENET_IsSMIBusy(base))
110     {
111     }
112 #endif
113     *dataPtr = ENET_ReadSMIData(base);
114 
115     return result;
116 }
117