Skip to content

Commit b7627e8

Browse files
author
Mika Leppänen
committed
K64F, K66F: Update the ENET PHY driver
PHY init and autonegotation is split into own functions.
1 parent 5e8ed33 commit b7627e8

File tree

6 files changed

+119
-149
lines changed

6 files changed

+119
-149
lines changed

features/netsocket/emac-drivers/TARGET_Freescale_EMAC/kinetis_emac.cpp

Lines changed: 2 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,6 @@ uint32_t *rx_ptr[ENET_RX_RING_LEN];
6666
#define ENET_ALIGN(x,align) ((unsigned int)((x) + ((align)-1)) & (unsigned int)(~(unsigned int)((align)- 1)))
6767

6868
extern "C" void kinetis_init_eth_hardware(void);
69-
extern "C" uint32_t ENET_GetInstance(ENET_Type *base);
70-
extern "C" clock_ip_name_t s_enetClock[];
7169

7270
/* \brief Flags for worker thread */
7371
#define FLAG_TX 1
@@ -232,7 +230,7 @@ bool Kinetis_EMAC::low_level_init_successful()
232230

233231
ENET_GetDefaultConfig(&config);
234232

235-
if (init_enet_phy(ENET, phyAddr, sysClock) != kStatus_Success) {
233+
if (PHY_Init(ENET, phyAddr, sysClock) != kStatus_Success) {
236234
return false;
237235
}
238236

@@ -263,78 +261,6 @@ bool Kinetis_EMAC::low_level_init_successful()
263261
return true;
264262
}
265263

266-
status_t Kinetis_EMAC::init_enet_phy(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
267-
{
268-
status_t result = kStatus_Success;
269-
uint32_t instance = ENET_GetInstance(base);
270-
271-
#if TARGET_K66F
272-
uint32_t counter = 0xFFFFFU;
273-
uint32_t idReg = 0;
274-
275-
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
276-
/* Set SMI first. */
277-
CLOCK_EnableClock(s_enetClock[instance]);
278-
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
279-
ENET_SetSMI(base, srcClock_Hz, false);
280-
281-
/* Initialization after PHY stars to work. */
282-
while ((idReg != PHY_CONTROL_ID1) && (counter != 0)) {
283-
PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg);
284-
counter --;
285-
}
286-
287-
if (!counter) {
288-
return kStatus_Fail;
289-
}
290-
291-
counter = 0xFFFFFU;
292-
#elif TARGET_K64F
293-
/* Set SMI first. */
294-
CLOCK_EnableClock(s_enetClock[instance]);
295-
ENET_SetSMI(base, srcClock_Hz, false);
296-
#else
297-
#error invalid target!
298-
#endif
299-
300-
/* Reset PHY. */
301-
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
302-
return result;
303-
}
304-
305-
status_t Kinetis_EMAC::auto_negotiation(ENET_Type *base, uint32_t phyAddr)
306-
{
307-
uint32_t bssReg;
308-
status_t result;
309-
uint32_t counter = 0xFFFFFFU;
310-
311-
/* Set the negotiation. */
312-
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
313-
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
314-
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
315-
if (result == kStatus_Success) {
316-
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
317-
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
318-
if (result == kStatus_Success) {
319-
/* Check auto negotiation complete. */
320-
while (counter --) {
321-
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
322-
if (result == kStatus_Success) {
323-
if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0) {
324-
break;
325-
}
326-
}
327-
328-
if (!counter) {
329-
return kStatus_PHY_AutoNegotiateFail;
330-
}
331-
}
332-
}
333-
}
334-
335-
return result;
336-
}
337-
338264
/** \brief Allocates a emac_mem_buf_t and returns the data from the incoming packet.
339265
*
340266
* \param[in] idx index of packet to be read
@@ -544,7 +470,7 @@ void Kinetis_EMAC::phy_task()
544470

545471
if (crt_state.connected == STATE_LINK_UP) {
546472
if (prev_state.connected != STATE_LINK_UP) {
547-
auto_negotiation(ENET, phyAddr);
473+
PHY_AutoNegotiation(ENET, phyAddr);
548474
}
549475

550476
PHY_GetLinkSpeedDuplex(ENET, phyAddr, &crt_state.speed, &crt_state.duplex);

features/netsocket/emac-drivers/TARGET_Freescale_EMAC/kinetis_emac.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ class Kinetis_EMAC : public EMAC {
138138

139139
private:
140140
bool low_level_init_successful();
141-
status_t init_enet_phy(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
142-
status_t auto_negotiation(ENET_Type *base, uint32_t phyAddr);
143141
void rx_isr();
144142
void tx_isr();
145143
void packet_rx();

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.c

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
6464

6565
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
6666
{
67-
uint32_t bssReg;
6867
uint32_t counter = PHY_TIMEOUT_COUNT;
6968
uint32_t idReg = 0;
7069
status_t result = kStatus_Success;
@@ -89,36 +88,42 @@ status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
8988
}
9089

9190
/* Reset PHY. */
92-
counter = PHY_TIMEOUT_COUNT;
9391
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
92+
93+
return result;
94+
}
95+
96+
status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr)
97+
{
98+
status_t result = kStatus_Success;
99+
uint32_t bssReg;
100+
uint32_t counter = PHY_TIMEOUT_COUNT;
101+
102+
/* Set the negotiation. */
103+
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
104+
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
105+
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
94106
if (result == kStatus_Success)
95107
{
96-
/* Set the negotiation. */
97-
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
98-
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
99-
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
108+
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
109+
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
100110
if (result == kStatus_Success)
101111
{
102-
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
103-
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
104-
if (result == kStatus_Success)
112+
/* Check auto negotiation complete. */
113+
while (counter --)
105114
{
106-
/* Check auto negotiation complete. */
107-
while (counter --)
115+
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
116+
if ( result == kStatus_Success)
108117
{
109-
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
110-
if ( result == kStatus_Success)
118+
if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
111119
{
112-
if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
113-
{
114-
break;
115-
}
120+
break;
116121
}
122+
}
117123

118-
if (!counter)
119-
{
120-
return kStatus_PHY_AutoNegotiateFail;
121-
}
124+
if (!counter)
125+
{
126+
return kStatus_PHY_AutoNegotiateFail;
122127
}
123128
}
124129
}

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/fsl_phy.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,19 @@ extern "C" {
136136
* @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI.
137137
* @retval kStatus_Success PHY initialize success
138138
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
139-
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
140139
*/
141140
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
142141

142+
/*!
143+
* @brief Initiates auto negotiation.
144+
*
145+
* @param base ENET peripheral base address.
146+
* @param phyAddr The PHY address.
147+
* @retval kStatus_Success PHY auto negotiation success
148+
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
149+
*/
150+
status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr);
151+
143152
/*!
144153
* @brief PHY Write function. This function write data over the SMI to
145154
* the specified PHY register. This function is called by all PHY interfaces.

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_FRDM/fsl_phy.c

Lines changed: 71 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
/*
2-
* Copyright (c) 2015, Freescale Semiconductor, Inc.
3-
* All rights reserved.
4-
*
5-
* Redistribution and use in source and binary forms, with or without modification,
6-
* are permitted provided that the following conditions are met:
7-
*
8-
* o Redistributions of source code must retain the above copyright notice, this list
9-
* of conditions and the following disclaimer.
10-
*
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.
14-
*
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.
18-
*
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.
29-
*/
2+
* Copyright (c) 2015, Freescale Semiconductor, Inc.
3+
* Copyright 2016-2017 NXP
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification,
6+
* are permitted provided that the following conditions are met:
7+
*
8+
* o Redistributions of source code must retain the above copyright notice, this list
9+
* of conditions and the following disclaimer.
10+
*
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.
14+
*
15+
* o Neither the name of the copyright holder 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.
18+
*
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.
29+
*/
3030

3131
#include "fsl_phy.h"
3232

@@ -53,54 +53,77 @@ extern uint32_t ENET_GetInstance(ENET_Type *base);
5353
* Variables
5454
******************************************************************************/
5555

56+
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
5657
/*! @brief Pointers to enet clocks for each instance. */
5758
extern clock_ip_name_t s_enetClock[FSL_FEATURE_SOC_ENET_COUNT];
59+
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
5860

5961
/*******************************************************************************
6062
* Code
6163
******************************************************************************/
6264

6365
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz)
6466
{
65-
uint32_t bssReg;
6667
uint32_t counter = PHY_TIMEOUT_COUNT;
68+
uint32_t idReg = 0;
6769
status_t result = kStatus_Success;
6870
uint32_t instance = ENET_GetInstance(base);
6971

72+
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
7073
/* Set SMI first. */
7174
CLOCK_EnableClock(s_enetClock[instance]);
75+
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
7276
ENET_SetSMI(base, srcClock_Hz, false);
7377

78+
/* Initialization after PHY stars to work. */
79+
while ((idReg != PHY_CONTROL_ID1) && (counter != 0))
80+
{
81+
PHY_Read(base, phyAddr, PHY_ID1_REG, &idReg);
82+
counter --;
83+
}
84+
85+
if (!counter)
86+
{
87+
return kStatus_Fail;
88+
}
89+
7490
/* Reset PHY. */
7591
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG, PHY_BCTL_RESET_MASK);
92+
93+
return result;
94+
}
95+
96+
status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr)
97+
{
98+
status_t result = kStatus_Success;
99+
uint32_t bssReg;
100+
uint32_t counter = PHY_TIMEOUT_COUNT;
101+
102+
/* Set the negotiation. */
103+
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
104+
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
105+
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
76106
if (result == kStatus_Success)
77107
{
78-
/* Set the negotiation. */
79-
result = PHY_Write(base, phyAddr, PHY_AUTONEG_ADVERTISE_REG,
80-
(PHY_100BASETX_FULLDUPLEX_MASK | PHY_100BASETX_HALFDUPLEX_MASK |
81-
PHY_10BASETX_FULLDUPLEX_MASK | PHY_10BASETX_HALFDUPLEX_MASK | 0x1U));
108+
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
109+
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
82110
if (result == kStatus_Success)
83111
{
84-
result = PHY_Write(base, phyAddr, PHY_BASICCONTROL_REG,
85-
(PHY_BCTL_AUTONEG_MASK | PHY_BCTL_RESTART_AUTONEG_MASK));
86-
if (result == kStatus_Success)
112+
/* Check auto negotiation complete. */
113+
while (counter --)
87114
{
88-
/* Check auto negotiation complete. */
89-
while (counter --)
115+
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
116+
if ( result == kStatus_Success)
90117
{
91-
result = PHY_Read(base, phyAddr, PHY_BASICSTATUS_REG, &bssReg);
92-
if ( result == kStatus_Success)
118+
if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
93119
{
94-
if ((bssReg & PHY_BSTATUS_AUTONEGCOMP_MASK) != 0)
95-
{
96-
break;
97-
}
120+
break;
98121
}
122+
}
99123

100-
if (!counter)
101-
{
102-
return kStatus_PHY_AutoNegotiateFail;
103-
}
124+
if (!counter)
125+
{
126+
return kStatus_PHY_AutoNegotiateFail;
104127
}
105128
}
106129
}

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_FRDM/fsl_phy.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,19 @@ extern "C" {
136136
* @param srcClock_Hz The module clock frequency - system clock for MII management interface - SMI.
137137
* @retval kStatus_Success PHY initialize success
138138
* @retval kStatus_PHY_SMIVisitTimeout PHY SMI visit time out
139-
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
140139
*/
141140
status_t PHY_Init(ENET_Type *base, uint32_t phyAddr, uint32_t srcClock_Hz);
142141

142+
/*!
143+
* @brief Initiates auto negotiation.
144+
*
145+
* @param base ENET peripheral base address.
146+
* @param phyAddr The PHY address.
147+
* @retval kStatus_Success PHY auto negotiation success
148+
* @retval kStatus_PHY_AutoNegotiateFail PHY auto negotiate fail
149+
*/
150+
status_t PHY_AutoNegotiation(ENET_Type *base, uint32_t phyAddr);
151+
143152
/*!
144153
* @brief PHY Write function. This function write data over the SMI to
145154
* the specified PHY register. This function is called by all PHY interfaces.

0 commit comments

Comments
 (0)