2 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "fsl_phy_driver.h"
35 /*******************************************************************************
37 ******************************************************************************/
39 /*! @brief Define Phy API structure for MAC application*/
40 const enet_phy_api_t g_enetPhyApi =
48 /*******************************************************************************
50 ******************************************************************************/
51 /*FUNCTION****************************************************************
53 * Function Name: phy_init
54 * Return Value: The execution status.
55 * Description: Initialize Phy.
56 * This interface provides initialize functions for Phy, This is called by enet
57 * initialize function. Phy is usually deault auto-negotiation. so there is no
58 * need to do the intialize about this. we just need to check the loop mode.
59 *END*********************************************************************/
60 uint32_t phy_init(enet_dev_if_t * enetIfPtr)
66 /* Check input parameters*/
69 return kStatus_PHY_InvaildInput;
73 if ((result = (enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
74 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhySR,&data))) == kStatus_PHY_Success)
76 if ((data & kEnetPhyAutoNegAble) != 0)
78 /* Set Autonegotiation*/
79 enetIfPtr->macApiPtr->enet_mii_write(enetIfPtr->deviceNumber,
80 enetIfPtr->phyCfgPtr->phyAddr, kEnetPhyCR, kEnetPhyAutoNeg);
81 for (counter = 0; counter < kPhyTimeout; counter++)
83 if (enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
84 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhySR,&data)== kStatus_PHY_Success)
86 if ((data & kEnetPhyAutoNegComplete) != 0)
93 if (counter == kPhyTimeout)
95 return kStatus_PHY_TimeOut;
100 if (enetIfPtr->phyCfgPtr->isLoopEnabled)
102 /* First read the current status in control register*/
103 if (enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
104 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhyCR,&data))
106 result = enetIfPtr->macApiPtr->enet_mii_write(enetIfPtr->deviceNumber,
107 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhyCR,(data|kEnetPhyLoop));
114 /*FUNCTION****************************************************************
116 * Function Name: phy_auto_discover
117 * Return Value: The execution status.
118 * Description: Phy address auto discover.
119 * This function provides a interface to get phy address using phy address auto
120 * discovering, this interface is used when the phy address is unknown.
121 *END*********************************************************************/
122 uint32_t phy_auto_discover(enet_dev_if_t * enetIfPtr)
124 uint32_t addrIdx,data;
125 uint32_t result = kStatus_PHY_Fail;
127 /* Check input parameters*/
130 return kStatus_PHY_InvaildInput;
133 for (addrIdx = 0; addrIdx < 32; addrIdx++)
135 enetIfPtr->phyCfgPtr->phyAddr = addrIdx;
136 result = enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
137 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhyId1,&data);
138 if ((result == kStatus_PHY_Success) && (data != 0) && (data != 0xffff) )
140 return kStatus_PHY_Success;
147 /*FUNCTION****************************************************************
149 * Function Name: phy_get_link_speed
150 * Return Value: The execution status.
151 * Description: Get phy link speed.
152 * This function provides a interface to get link speed.
153 *END*********************************************************************/
154 uint32_t phy_get_link_speed(enet_dev_if_t * enetIfPtr, enet_phy_speed_t *status)
156 uint32_t result = kStatus_PHY_Success;
159 /* Check input parameters*/
160 if ((!enetIfPtr) || (!status))
162 return kStatus_PHY_InvaildInput;
165 result = enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
166 enetIfPtr->phyCfgPtr->phyAddr, kEnetPhyCt2,&data);
167 if (result == kStatus_PHY_Success)
169 data &= kEnetPhySpeedDulpexMask;
170 if ((kEnetPhy100HalfDuplex == data) || (kEnetPhy100FullDuplex == data))
172 *status = kEnetSpeed100M;
176 *status = kEnetSpeed10M;
183 /*FUNCTION****************************************************************
185 * Function Name: phy_get_link_status
186 * Return Value: The execution status.
187 * Description: Get phy link status.
188 * This function provides a interface to get link status to see if the link
189 * status is on or off.
190 *END*********************************************************************/
191 uint32_t phy_get_link_status(enet_dev_if_t * enetIfPtr, bool *status)
193 uint32_t result = kStatus_PHY_Success;
196 /* Check input parameters*/
197 if ((!enetIfPtr) || (!status))
199 return kStatus_PHY_InvaildInput;
202 result = enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
203 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhyCR,&data);
204 if ((result == kStatus_PHY_Success) && (!(data & kEnetPhyReset)))
207 result = enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
208 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhySR, &data);
209 if (result == kStatus_PHY_Success)
211 if (!(kEnetPhyLinkStatus & data))
225 /*FUNCTION****************************************************************
227 * Function Name: phy_get_link_duplex
228 * Return Value: The execution status.
229 * Description: Get phy link duplex.
230 * This function provides a interface to get link duplex to see if the link
231 * duplex is full or half.
232 *END*********************************************************************/
233 uint32_t phy_get_link_duplex(enet_dev_if_t * enetIfPtr, enet_phy_duplex_t *status)
235 uint32_t result = kStatus_PHY_Success;
238 /* Check input parameters*/
239 if ((!enetIfPtr) || (!status))
241 return kStatus_PHY_InvaildInput;
244 result = enetIfPtr->macApiPtr->enet_mii_read(enetIfPtr->deviceNumber,
245 enetIfPtr->phyCfgPtr->phyAddr,kEnetPhyCt2,&data);
246 if (result == kStatus_PHY_Success)
248 data &= kEnetPhySpeedDulpexMask;
249 if ((kEnetPhy10FullDuplex == data) || (kEnetPhy100FullDuplex == data))
251 *status = kEnetFullDuplex;
255 *status = kEnetHalfDuplex;
264 /*******************************************************************************
266 ******************************************************************************/