1 /*
2 * Copyright (c) 2020 - 2024 Renesas Electronics Corporation and/or its affiliates
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /***********************************************************************************************************************
8 * Includes <System Includes> , "Project Includes"
9 ***********************************************************************************************************************/
10
11 /* Access to peripherals and board defines. */
12 #include "bsp_api.h"
13 #include "r_ether_phy.h"
14
15 /***********************************************************************************************************************
16 * Macro definitions
17 ***********************************************************************************************************************/
18
19 #ifndef ETHER_PHY_ERROR_RETURN
20
21 #define ETHER_PHY_ERROR_RETURN(a, err) FSP_ERROR_RETURN((a), (err))
22 #endif
23
24 #define ETHERC_REG_SIZE (0x400UL)
25
26 /** "RPHY" in ASCII. Used to determine if the control block is open. */
27 #define ETHER_PHY_OPEN (0x52504859U)
28
29 /* Media Independent Interface */
30 #define ETHER_PHY_MII_ST (1)
31 #define ETHER_PHY_MII_READ (2)
32 #define ETHER_PHY_MII_WRITE (1)
33
34 /* Standard PHY Registers */
35 #define ETHER_PHY_REG_CONTROL (0)
36 #define ETHER_PHY_REG_STATUS (1)
37 #define ETHER_PHY_REG_IDENTIFIER1 (2)
38 #define ETHER_PHY_REG_IDENTIFIER2 (3)
39 #define ETHER_PHY_REG_AN_ADVERTISEMENT (4)
40 #define ETHER_PHY_REG_AN_LINK_PARTNER (5)
41 #define ETHER_PHY_REG_AN_EXPANSION (6)
42
43 /* Basic Mode Control Register Bit Definitions */
44 #define ETHER_PHY_CONTROL_RESET (1 << 15)
45 #define ETHER_PHY_CONTROL_LOOPBACK (1 << 14)
46 #define ETHER_PHY_CONTROL_100_MBPS (1 << 13)
47 #define ETHER_PHY_CONTROL_AN_ENABLE (1 << 12)
48 #define ETHER_PHY_CONTROL_POWER_DOWN (1 << 11)
49 #define ETHER_PHY_CONTROL_ISOLATE (1 << 10)
50 #define ETHER_PHY_CONTROL_AN_RESTART (1 << 9)
51 #define ETHER_PHY_CONTROL_FULL_DUPLEX (1 << 8)
52 #define ETHER_PHY_CONTROL_COLLISION (1 << 7)
53
54 /* Basic Mode Status Register Bit Definitions */
55 #define ETHER_PHY_STATUS_100_T4 (1 << 15)
56 #define ETHER_PHY_STATUS_100F (1 << 14)
57 #define ETHER_PHY_STATUS_100H (1 << 13)
58 #define ETHER_PHY_STATUS_10F (1 << 12)
59 #define ETHER_PHY_STATUS_10H (1 << 11)
60 #define ETHER_PHY_STATUS_AN_COMPLETE (1 << 5)
61 #define ETHER_PHY_STATUS_RM_FAULT (1 << 4)
62 #define ETHER_PHY_STATUS_AN_ABILITY (1 << 3)
63 #define ETHER_PHY_STATUS_LINK_UP (1 << 2)
64 #define ETHER_PHY_STATUS_JABBER (1 << 1)
65 #define ETHER_PHY_STATUS_EX_CAPABILITY (1 << 0)
66
67 /* Auto Negotiation Advertisement Bit Definitions */
68 #define ETHER_PHY_AN_ADVERTISEMENT_NEXT_PAGE (1 << 15)
69 #define ETHER_PHY_AN_ADVERTISEMENT_RM_FAULT (1 << 13)
70 #define ETHER_PHY_AN_ADVERTISEMENT_ASM_DIR (1 << 11)
71 #define ETHER_PHY_AN_ADVERTISEMENT_PAUSE (1 << 10)
72 #define ETHER_PHY_AN_ADVERTISEMENT_100_T4 (1 << 9)
73 #define ETHER_PHY_AN_ADVERTISEMENT_100F (1 << 8)
74 #define ETHER_PHY_AN_ADVERTISEMENT_100H (1 << 7)
75 #define ETHER_PHY_AN_ADVERTISEMENT_10F (1 << 6)
76 #define ETHER_PHY_AN_ADVERTISEMENT_10H (1 << 5)
77 #define ETHER_PHY_AN_ADVERTISEMENT_SELECTOR (1 << 0)
78
79 /* Auto Negotiate Link Partner Ability Bit Definitions */
80 #define ETHER_PHY_AN_LINK_PARTNER_NEXT_PAGE (1 << 15)
81 #define ETHER_PHY_AN_LINK_PARTNER_ACK (1 << 14)
82 #define ETHER_PHY_AN_LINK_PARTNER_RM_FAULT (1 << 13)
83 #define ETHER_PHY_AN_LINK_PARTNER_ASM_DIR (1 << 11)
84 #define ETHER_PHY_AN_LINK_PARTNER_PAUSE (1 << 10)
85 #define ETHER_PHY_AN_LINK_PARTNER_100_T4 (1 << 9)
86 #define ETHER_PHY_AN_LINK_PARTNER_100F (1 << 8)
87 #define ETHER_PHY_AN_LINK_PARTNER_100H (1 << 7)
88 #define ETHER_PHY_AN_LINK_PARTNER_10F (1 << 6)
89 #define ETHER_PHY_AN_LINK_PARTNER_10H (1 << 5)
90 #define ETHER_PHY_AN_LINK_PARTNER_SELECTOR (1 << 0)
91
92 #define ETHER_PHY_PIR_MDI_MASK (1 << 3)
93 #define ETHER_PHY_PIR_MDO_HIGH (0x04)
94 #define ETHER_PHY_PIR_MDO_LOW (0x00)
95 #define ETHER_PHY_PIR_MMD_WRITE (0x02)
96 #define ETHER_PHY_PIR_MMD_READ (0x00)
97 #define ETHER_PHY_PIR_MDC_HIGH (0x01)
98 #define ETHER_PHY_PIR_MDC_LOW (0x00)
99
100 #define ETHER_PHY_ADDRESS_SIZE (0x1fU)
101 #define ETHER_PHY_REGISTER_DATA_SIZE (0xffffU)
102
103 #define ETHER_PHY_PREAMBLE_LENGTH (32U)
104 #define ETHER_PHY_WRITE_DATA_BIT_MASK (0x8000)
105
106 /***********************************************************************************************************************
107 * Typedef definitions
108 ***********************************************************************************************************************/
109
110 /***********************************************************************************************************************
111 * Exported global variables (to be accessed by other files)
112 ***********************************************************************************************************************/
113
114 /***********************************************************************************************************************
115 * Exported global function
116 ***********************************************************************************************************************/
117 #if (ETHER_PHY_CFG_TARGET_KSZ8091RNB_ENABLE)
118 extern void ether_phy_target_ksz8091rnb_initialize(ether_phy_instance_ctrl_t * p_instance_ctrl);
119 extern bool ether_phy_target_ksz8091rnb_is_support_link_partner_ability(ether_phy_instance_ctrl_t * p_instance_ctrl,
120 uint32_t line_speed_duplex);
121
122 #endif
123 #if (ETHER_PHY_CFG_TARGET_KSZ8041_ENABLE)
124 extern void ether_phy_target_ksz8041_initialize(ether_phy_instance_ctrl_t * p_instance_ctrl);
125 extern bool ether_phy_target_ksz8041_is_support_link_partner_ability(ether_phy_instance_ctrl_t * p_instance_ctrl,
126 uint32_t line_speed_duplex);
127
128 #endif
129 #if (ETHER_PHY_CFG_TARGET_DP83620_ENABLE)
130 extern void ether_phy_target_dp83620_initialize(ether_phy_instance_ctrl_t * p_instance_ctrl);
131 extern bool ether_phy_target_dp83620_is_support_link_partner_ability(ether_phy_instance_ctrl_t * p_instance_ctrl,
132 uint32_t line_speed_duplex);
133
134 #endif
135 #if (ETHER_PHY_CFG_TARGET_ICS1894_ENABLE)
136 extern void ether_phy_target_ics1894_initialize(ether_phy_instance_ctrl_t * p_instance_ctrl);
137 extern bool ether_phy_target_ics1894_is_support_link_partner_ability(ether_phy_instance_ctrl_t * p_instance_ctrl,
138 uint32_t line_speed_duplex);
139
140 #endif
141
142 /***********************************************************************************************************************
143 * Private global variables and functions
144 ***********************************************************************************************************************/
145 static void ether_phy_preamble(ether_phy_instance_ctrl_t * p_instance_ctrl);
146 static void ether_phy_reg_set(ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t reg_addr, int32_t option);
147 static void ether_phy_reg_read(ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t * pdata);
148 static void ether_phy_reg_write(ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t data);
149 static void ether_phy_trans_zto0(ether_phy_instance_ctrl_t * p_instance_ctrl);
150 static void ether_phy_trans_1to0(ether_phy_instance_ctrl_t * p_instance_ctrl);
151 static void ether_phy_trans_idle(ether_phy_instance_ctrl_t * p_instance_ctrl);
152 static void ether_phy_mii_write1(ether_phy_instance_ctrl_t * p_instance_ctrl);
153 static void ether_phy_mii_write0(ether_phy_instance_ctrl_t * p_instance_ctrl);
154 static void ether_phy_mii_writez(ether_phy_instance_ctrl_t * p_instance_ctrl);
155 static void ether_phy_targets_initialize(ether_phy_instance_ctrl_t * p_instance_ctrl);
156 static bool ether_phy_targets_is_support_link_partner_ability(ether_phy_instance_ctrl_t * p_instance_ctrl,
157 uint32_t line_speed_duplex);
158
159 /** ETHER_PHY HAL API mapping for Ethernet PHY Controller interface */
160 /*LDRA_INSPECTED 27 D This structure must be accessible in user code. It cannot be static. */
161 const ether_phy_api_t g_ether_phy_on_ether_phy =
162 {
163 .open = R_ETHER_PHY_Open,
164 .close = R_ETHER_PHY_Close,
165 .startAutoNegotiate = R_ETHER_PHY_StartAutoNegotiate,
166 .linkPartnerAbilityGet = R_ETHER_PHY_LinkPartnerAbilityGet,
167 .linkStatusGet = R_ETHER_PHY_LinkStatusGet,
168 .chipInit = R_ETHER_PHY_ChipInit,
169 .read = R_ETHER_PHY_Read,
170 .write = R_ETHER_PHY_Write
171 };
172
173 /*******************************************************************************************************************//**
174 * @addtogroup ETHER_PHY
175 * @{
176 **********************************************************************************************************************/
177
178 /***********************************************************************************************************************
179 * Functions
180 **********************************************************************************************************************/
181
182 /********************************************************************************************************************//**
183 * @brief Resets Ethernet PHY device. Implements @ref ether_phy_api_t::open.
184 *
185 * @retval FSP_SUCCESS Channel opened successfully.
186 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block or configuration structure is NULL.
187 * @retval FSP_ERR_ALREADY_OPEN Control block has already been opened or channel is being used by another
188 * instance. Call close() then open() to reconfigure.
189 * @retval FSP_ERR_INVALID_CHANNEL Invalid channel number is given.
190 * @retval FSP_ERR_INVALID_POINTER Pointer to p_cfg is NULL.
191 * @retval FSP_ERR_TIMEOUT PHY-LSI Reset wait timeout.
192 * @retval FSP_ERR_INVALID_ARGUMENT Register address is incorrect
193 * @retval FSP_ERR_NOT_INITIALIZED The control block has not been initialized.
194 ***********************************************************************************************************************/
R_ETHER_PHY_Open(ether_phy_ctrl_t * const p_ctrl,ether_phy_cfg_t const * const p_cfg)195 fsp_err_t R_ETHER_PHY_Open (ether_phy_ctrl_t * const p_ctrl, ether_phy_cfg_t const * const p_cfg)
196 {
197 fsp_err_t err = FSP_SUCCESS;
198 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
199 R_ETHERC0_Type * p_reg_etherc;
200
201 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
202 FSP_ASSERT(p_instance_ctrl);
203 ETHER_PHY_ERROR_RETURN(NULL != p_cfg, FSP_ERR_INVALID_POINTER);
204 ETHER_PHY_ERROR_RETURN((ETHER_PHY_OPEN != p_instance_ctrl->open), FSP_ERR_ALREADY_OPEN);
205 ETHER_PHY_ERROR_RETURN((BSP_FEATURE_ETHER_MAX_CHANNELS > p_cfg->channel), FSP_ERR_INVALID_CHANNEL);
206 #endif
207
208 /** Make sure this channel exists. */
209 p_reg_etherc = ((R_ETHERC0_Type *) (R_ETHERC0_BASE + (ETHERC_REG_SIZE * p_cfg->channel)));
210 p_instance_ctrl->p_reg_pir = (uint32_t *) &p_reg_etherc->PIR;
211 p_instance_ctrl->local_advertise = 0;
212
213 /* Initialize configuration of ethernet phy module. */
214 p_instance_ctrl->p_ether_phy_cfg = p_cfg;
215
216 R_BSP_MODULE_START(FSP_IP_ETHER, p_instance_ctrl->p_ether_phy_cfg->channel);
217
218 #if ETHER_PHY_CFG_INIT_PHY_LSI_AUTOMATIC
219 uint32_t reg = 0;
220 uint32_t count = 0;
221
222 p_instance_ctrl->interface_status = ETHER_PHY_INTERFACE_STATUS_INITIALIZED;
223
224 /* Reset PHY */
225 R_ETHER_PHY_Write(p_instance_ctrl, ETHER_PHY_REG_CONTROL, ETHER_PHY_CONTROL_RESET);
226
227 /* Reset completion waiting */
228 do
229 {
230 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_CONTROL, ®);
231 count++;
232 } while ((reg & ETHER_PHY_CONTROL_RESET) && (count < p_cfg->phy_reset_wait_time));
233
234 if (count < p_cfg->phy_reset_wait_time)
235 {
236 ether_phy_targets_initialize(p_instance_ctrl);
237
238 p_instance_ctrl->open = ETHER_PHY_OPEN;
239
240 err = FSP_SUCCESS;
241 }
242 else
243 {
244 err = FSP_ERR_TIMEOUT;
245 }
246
247 #else
248 p_instance_ctrl->open = ETHER_PHY_OPEN;
249
250 err = FSP_SUCCESS;
251 #endif
252
253 return err;
254 } /* End of function R_ETHER_PHY_Open() */
255
256 /********************************************************************************************************************//**
257 * @brief Close Ethernet PHY device. Implements @ref ether_phy_api_t::close.
258 *
259 * @retval FSP_SUCCESS Channel successfully closed.
260 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block is NULL.
261 * @retval FSP_ERR_NOT_OPEN The control block has not been opened
262 *
263 ***********************************************************************************************************************/
R_ETHER_PHY_Close(ether_phy_ctrl_t * const p_ctrl)264 fsp_err_t R_ETHER_PHY_Close (ether_phy_ctrl_t * const p_ctrl)
265 {
266 fsp_err_t err = FSP_SUCCESS;
267 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
268
269 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
270 FSP_ASSERT(p_instance_ctrl);
271 ETHER_PHY_ERROR_RETURN(ETHER_PHY_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
272 #endif
273
274 /** Clear configure block parameters. */
275 p_instance_ctrl->p_ether_phy_cfg = NULL;
276 p_instance_ctrl->local_advertise = 0;
277 p_instance_ctrl->p_reg_pir = NULL;
278
279 p_instance_ctrl->interface_status = ETHER_PHY_INTERFACE_STATUS_UNINITIALIZED;
280 p_instance_ctrl->open = 0;
281
282 return err;
283 } /* End of function R_ETHER_PHY_Close() */
284
285 /********************************************************************************************************************//**
286 * @brief Starts auto-negotiate. Implements @ref ether_phy_api_t::startAutoNegotiate.
287 *
288 * @retval FSP_SUCCESS ETHER_PHY successfully starts auto-negotiate.
289 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block is NULL.
290 * @retval FSP_ERR_NOT_OPEN The control block has not been opened
291 * @retval FSP_ERR_INVALID_ARGUMENT Register address is incorrect
292 * @retval FSP_ERR_INVALID_POINTER Pointer to read buffer is NULL.
293 * @retval FSP_ERR_NOT_INITIALIZED The control block has not been initialized
294 ***********************************************************************************************************************/
R_ETHER_PHY_StartAutoNegotiate(ether_phy_ctrl_t * const p_ctrl)295 fsp_err_t R_ETHER_PHY_StartAutoNegotiate (ether_phy_ctrl_t * const p_ctrl)
296 {
297 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
298 uint32_t reg = 0;
299
300 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
301 FSP_ASSERT(p_instance_ctrl);
302 ETHER_PHY_ERROR_RETURN(ETHER_PHY_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
303 ETHER_PHY_ERROR_RETURN(ETHER_PHY_INTERFACE_STATUS_INITIALIZED == p_instance_ctrl->interface_status,
304 FSP_ERR_NOT_INITIALIZED);
305 #endif
306
307 /* Set local ability */
308 /* When pause frame is not used */
309 if (ETHER_PHY_FLOW_CONTROL_DISABLE == p_instance_ctrl->p_ether_phy_cfg->flow_control)
310 {
311 p_instance_ctrl->local_advertise = ((((ETHER_PHY_AN_ADVERTISEMENT_100F |
312 ETHER_PHY_AN_ADVERTISEMENT_100H) |
313 ETHER_PHY_AN_ADVERTISEMENT_10F) |
314 ETHER_PHY_AN_ADVERTISEMENT_10H) |
315 ETHER_PHY_AN_ADVERTISEMENT_SELECTOR);
316 }
317 /* When pause frame is used */
318 else
319 {
320 p_instance_ctrl->local_advertise = ((((((ETHER_PHY_AN_ADVERTISEMENT_ASM_DIR |
321 ETHER_PHY_AN_ADVERTISEMENT_PAUSE) |
322 ETHER_PHY_AN_ADVERTISEMENT_100F) |
323 ETHER_PHY_AN_ADVERTISEMENT_100H) |
324 ETHER_PHY_AN_ADVERTISEMENT_10F) |
325 ETHER_PHY_AN_ADVERTISEMENT_10H) |
326 ETHER_PHY_AN_ADVERTISEMENT_SELECTOR);
327 }
328
329 /* Configure what the PHY and the Ethernet controller on this board supports */
330 R_ETHER_PHY_Write(p_instance_ctrl, ETHER_PHY_REG_AN_ADVERTISEMENT, p_instance_ctrl->local_advertise);
331 R_ETHER_PHY_Write(p_instance_ctrl,
332 ETHER_PHY_REG_CONTROL,
333 (ETHER_PHY_CONTROL_AN_ENABLE |
334 ETHER_PHY_CONTROL_AN_RESTART));
335
336 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_AN_ADVERTISEMENT, ®);
337
338 return FSP_SUCCESS;
339 } /* End of function R_ETHER_PHY_StartAutoNegotiate() */
340
341 /********************************************************************************************************************//**
342 * @brief Reports the other side's physical capability. Implements @ref ether_phy_api_t::linkPartnerAbilityGet.
343 *
344 * @retval FSP_SUCCESS ETHER_PHY successfully get link partner ability.
345 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block is NULL.
346 * @retval FSP_ERR_INVALID_POINTER Pointer to arguments are NULL.
347 * @retval FSP_ERR_NOT_OPEN The control block has not been opened
348 * @retval FSP_ERR_ETHER_PHY_ERROR_LINK PHY-LSI is not link up.
349 * @retval FSP_ERR_ETHER_PHY_NOT_READY The auto-negotiation isn't completed
350 * @retval FSP_ERR_INVALID_ARGUMENT Status register address is incorrect
351 * @retval FSP_ERR_NOT_INITIALIZED The control block has not been initialized
352 ***********************************************************************************************************************/
R_ETHER_PHY_LinkPartnerAbilityGet(ether_phy_ctrl_t * const p_ctrl,uint32_t * const p_line_speed_duplex,uint32_t * const p_local_pause,uint32_t * const p_partner_pause)353 fsp_err_t R_ETHER_PHY_LinkPartnerAbilityGet (ether_phy_ctrl_t * const p_ctrl,
354 uint32_t * const p_line_speed_duplex,
355 uint32_t * const p_local_pause,
356 uint32_t * const p_partner_pause)
357 {
358 fsp_err_t err = FSP_SUCCESS;
359 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
360 uint32_t reg = 0;
361 uint32_t line_speed_duplex = ETHER_PHY_LINK_SPEED_NO_LINK;
362
363 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
364 FSP_ASSERT(p_instance_ctrl);
365 ETHER_PHY_ERROR_RETURN(ETHER_PHY_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
366 ETHER_PHY_ERROR_RETURN(NULL != p_line_speed_duplex, FSP_ERR_INVALID_POINTER);
367 ETHER_PHY_ERROR_RETURN(NULL != p_local_pause, FSP_ERR_INVALID_POINTER);
368 ETHER_PHY_ERROR_RETURN(NULL != p_partner_pause, FSP_ERR_INVALID_POINTER);
369 ETHER_PHY_ERROR_RETURN(ETHER_PHY_INTERFACE_STATUS_INITIALIZED == p_instance_ctrl->interface_status,
370 FSP_ERR_NOT_INITIALIZED);
371 #endif
372
373 /* Because reading the first time shows the previous state, the Link status bit is read twice. */
374 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_STATUS, ®);
375 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_STATUS, ®);
376
377 /* When the link isn't up, return error */
378 ETHER_PHY_ERROR_RETURN(ETHER_PHY_STATUS_LINK_UP == (reg & ETHER_PHY_STATUS_LINK_UP), FSP_ERR_ETHER_PHY_ERROR_LINK);
379
380 /* Establish local pause capability */
381 if (ETHER_PHY_AN_ADVERTISEMENT_PAUSE == (p_instance_ctrl->local_advertise & ETHER_PHY_AN_ADVERTISEMENT_PAUSE))
382 {
383 (*p_local_pause) |= (1 << 1);
384 }
385
386 if (ETHER_PHY_AN_ADVERTISEMENT_ASM_DIR == (p_instance_ctrl->local_advertise & ETHER_PHY_AN_ADVERTISEMENT_ASM_DIR))
387 {
388 (*p_local_pause) |= 1;
389 }
390
391 /* When the auto-negotiation isn't completed, return error */
392 ETHER_PHY_ERROR_RETURN(ETHER_PHY_STATUS_AN_COMPLETE == (reg & ETHER_PHY_STATUS_AN_COMPLETE),
393 FSP_ERR_ETHER_PHY_NOT_READY);
394
395 /* Get the link partner response */
396 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_AN_LINK_PARTNER, ®);
397
398 /* Establish partner pause capability */
399 if (ETHER_PHY_AN_LINK_PARTNER_PAUSE == (reg & ETHER_PHY_AN_LINK_PARTNER_PAUSE))
400 {
401 (*p_partner_pause) = (1 << 1);
402 }
403
404 if (ETHER_PHY_AN_LINK_PARTNER_ASM_DIR == (reg & ETHER_PHY_AN_LINK_PARTNER_ASM_DIR))
405 {
406 (*p_partner_pause) |= 1;
407 }
408
409 /* Establish the line speed and the duplex */
410 if ((ETHER_PHY_AN_LINK_PARTNER_10H == (reg & ETHER_PHY_AN_LINK_PARTNER_10H)) &&
411 ether_phy_targets_is_support_link_partner_ability(p_instance_ctrl, ETHER_PHY_LINK_SPEED_10H))
412 {
413 line_speed_duplex = ETHER_PHY_LINK_SPEED_10H;
414 }
415
416 if ((ETHER_PHY_AN_LINK_PARTNER_10F == (reg & ETHER_PHY_AN_LINK_PARTNER_10F)) &&
417 ether_phy_targets_is_support_link_partner_ability(p_instance_ctrl, ETHER_PHY_LINK_SPEED_10F))
418 {
419 line_speed_duplex = ETHER_PHY_LINK_SPEED_10F;
420 }
421
422 if ((ETHER_PHY_AN_LINK_PARTNER_100H == (reg & ETHER_PHY_AN_LINK_PARTNER_100H)) &&
423 ether_phy_targets_is_support_link_partner_ability(p_instance_ctrl, ETHER_PHY_LINK_SPEED_100H))
424 {
425 line_speed_duplex = ETHER_PHY_LINK_SPEED_100H;
426 }
427
428 if ((ETHER_PHY_AN_LINK_PARTNER_100F == (reg & ETHER_PHY_AN_LINK_PARTNER_100F)) &&
429 ether_phy_targets_is_support_link_partner_ability(p_instance_ctrl, ETHER_PHY_LINK_SPEED_100F))
430 {
431 line_speed_duplex = ETHER_PHY_LINK_SPEED_100F;
432 }
433
434 if (ETHER_PHY_LINK_SPEED_NO_LINK == line_speed_duplex)
435 {
436 err = FSP_ERR_ETHER_PHY_ERROR_LINK;
437 }
438 else
439 {
440 (*p_line_speed_duplex) = line_speed_duplex;
441 }
442
443 return err;
444 } /* End of function R_ETHER_PHY_LinkPartnerAbilityGet() */
445
446 /********************************************************************************************************************//**
447 * @brief Returns the status of the physical link. Implements @ref ether_phy_api_t::linkStatusGet.
448 *
449 * @retval FSP_SUCCESS ETHER_PHY successfully get link partner ability.
450 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block is NULL.
451 * @retval FSP_ERR_NOT_OPEN The control block has not been opened
452 * @retval FSP_ERR_ETHER_PHY_ERROR_LINK PHY-LSI is not link up.
453 * @retval FSP_ERR_INVALID_ARGUMENT Status register address is incorrect
454 * @retval FSP_ERR_INVALID_POINTER Pointer to read buffer is NULL.
455 * @retval FSP_ERR_NOT_INITIALIZED The control block has not been initialized
456 ***********************************************************************************************************************/
R_ETHER_PHY_LinkStatusGet(ether_phy_ctrl_t * const p_ctrl)457 fsp_err_t R_ETHER_PHY_LinkStatusGet (ether_phy_ctrl_t * const p_ctrl)
458 {
459 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
460 uint32_t reg;
461 fsp_err_t err = FSP_SUCCESS;
462
463 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
464 FSP_ASSERT(p_instance_ctrl);
465 ETHER_PHY_ERROR_RETURN(ETHER_PHY_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
466 ETHER_PHY_ERROR_RETURN(ETHER_PHY_INTERFACE_STATUS_INITIALIZED == p_instance_ctrl->interface_status,
467 FSP_ERR_NOT_INITIALIZED);
468 #endif
469
470 /* Because reading the first time shows the previous state, the Link status bit is read twice. */
471 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_STATUS, ®);
472 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_STATUS, ®);
473
474 /* When the link isn't up, return error */
475 if (ETHER_PHY_STATUS_LINK_UP != (reg & ETHER_PHY_STATUS_LINK_UP))
476 {
477 /* Link is down */
478 err = FSP_ERR_ETHER_PHY_ERROR_LINK;
479 }
480 else
481 {
482 /* Link is up */
483 err = FSP_SUCCESS;
484 }
485
486 return err;
487 } /* End of function R_ETHER_PHY_LinkStatusGet() */
488
489 /********************************************************************************************************************//**
490 * @brief Initialize Ethernet PHY device. Implements @ref ether_phy_api_t::chipInit.
491 *
492 * @retval FSP_SUCCESS PHY device initialized successfully.
493 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block or configuration structure is NULL.
494 * @retval FSP_ERR_INVALID_ARGUMENT Address or data is not a valid size.
495 * @retval FSP_ERR_INVALID_POINTER Pointer to p_cfg is NULL.
496 * @retval FSP_ERR_NOT_INITIALIZED The control block has not been initialized.
497 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
498 * @retval FSP_ERR_TIMEOUT PHY-LSI Reset wait timeout.
499 ***********************************************************************************************************************/
R_ETHER_PHY_ChipInit(ether_phy_ctrl_t * const p_ctrl,ether_phy_cfg_t const * const p_cfg)500 fsp_err_t R_ETHER_PHY_ChipInit (ether_phy_ctrl_t * const p_ctrl, ether_phy_cfg_t const * const p_cfg)
501 {
502 fsp_err_t err = FSP_SUCCESS;
503 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
504 uint32_t reg = 0;
505 uint32_t count = 0;
506
507 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
508 FSP_ASSERT(p_instance_ctrl);
509 ETHER_PHY_ERROR_RETURN(NULL != p_cfg, FSP_ERR_INVALID_POINTER);
510 ETHER_PHY_ERROR_RETURN(ETHER_PHY_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
511 #endif
512
513 p_instance_ctrl->interface_status = ETHER_PHY_INTERFACE_STATUS_INITIALIZED;
514
515 /* Reset PHY */
516 R_ETHER_PHY_Write(p_instance_ctrl, ETHER_PHY_REG_CONTROL, ETHER_PHY_CONTROL_RESET);
517
518 /* Reset completion waiting */
519 do
520 {
521 R_ETHER_PHY_Read(p_instance_ctrl, ETHER_PHY_REG_CONTROL, ®);
522 count++;
523 } while ((reg & ETHER_PHY_CONTROL_RESET) && (count < p_cfg->phy_reset_wait_time));
524
525 if (count < p_cfg->phy_reset_wait_time)
526 {
527 ether_phy_targets_initialize(p_instance_ctrl);
528
529 err = FSP_SUCCESS;
530 }
531 else
532 {
533 err = FSP_ERR_TIMEOUT;
534 }
535
536 return err;
537 } /* End of function R_ETHER_PHY_ChipInit() */
538
539 /********************************************************************************************************************//**
540 * @brief Read data from register of PHY-LSI . Implements @ref ether_phy_api_t::read.
541 *
542 * @retval FSP_SUCCESS ETHER_PHY successfully read data.
543 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block is NULL.
544 * @retval FSP_ERR_INVALID_POINTER Pointer to read buffer is NULL.
545 * @retval FSP_ERR_INVALID_ARGUMENT Address is not a valid size
546 * @retval FSP_ERR_NOT_INITIALIZED The control block has not been initialized
547 ***********************************************************************************************************************/
R_ETHER_PHY_Read(ether_phy_ctrl_t * const p_ctrl,uint32_t reg_addr,uint32_t * const p_data)548 fsp_err_t R_ETHER_PHY_Read (ether_phy_ctrl_t * const p_ctrl, uint32_t reg_addr, uint32_t * const p_data)
549 {
550 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
551 uint32_t data;
552 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
553 FSP_ASSERT(p_instance_ctrl);
554 ETHER_PHY_ERROR_RETURN(NULL != p_data, FSP_ERR_INVALID_POINTER);
555 ETHER_PHY_ERROR_RETURN(ETHER_PHY_ADDRESS_SIZE >= reg_addr, FSP_ERR_INVALID_ARGUMENT);
556 ETHER_PHY_ERROR_RETURN(ETHER_PHY_INTERFACE_STATUS_INITIALIZED == p_instance_ctrl->interface_status,
557 FSP_ERR_NOT_INITIALIZED);
558 #endif
559
560 /*
561 * The value is read from the PHY register by the frame format of MII Management Interface provided
562 * for by Table 22-12 of 22.2.4.5 of IEEE 802.3-2008_section2.
563 */
564 ether_phy_preamble(p_instance_ctrl);
565 ether_phy_reg_set(p_instance_ctrl, reg_addr, ETHER_PHY_MII_READ);
566 ether_phy_trans_zto0(p_instance_ctrl);
567 ether_phy_reg_read(p_instance_ctrl, &data);
568 ether_phy_trans_idle(p_instance_ctrl);
569
570 (*p_data) = data;
571
572 return FSP_SUCCESS;
573 } /* End of function R_ETHER_PHY_Read() */
574
575 /********************************************************************************************************************//**
576 * @brief Write data to register of PHY-LSI . Implements @ref ether_phy_api_t::write.
577 *
578 * @retval FSP_SUCCESS ETHER_PHY successfully write data.
579 * @retval FSP_ERR_ASSERTION Pointer to ETHER_PHY control block is NULL.
580 * @retval FSP_ERR_INVALID_ARGUMENT Address or data is not a valid size
581 * @retval FSP_ERR_NOT_INITIALIZED The control block has not been initialized
582 ***********************************************************************************************************************/
R_ETHER_PHY_Write(ether_phy_ctrl_t * const p_ctrl,uint32_t reg_addr,uint32_t data)583 fsp_err_t R_ETHER_PHY_Write (ether_phy_ctrl_t * const p_ctrl, uint32_t reg_addr, uint32_t data)
584 {
585 ether_phy_instance_ctrl_t * p_instance_ctrl = (ether_phy_instance_ctrl_t *) p_ctrl;
586
587 #if (ETHER_PHY_CFG_PARAM_CHECKING_ENABLE)
588 FSP_ASSERT(p_instance_ctrl);
589 ETHER_PHY_ERROR_RETURN(ETHER_PHY_ADDRESS_SIZE >= reg_addr, FSP_ERR_INVALID_ARGUMENT);
590 ETHER_PHY_ERROR_RETURN(ETHER_PHY_REGISTER_DATA_SIZE >= data, FSP_ERR_INVALID_ARGUMENT);
591 ETHER_PHY_ERROR_RETURN(ETHER_PHY_INTERFACE_STATUS_INITIALIZED == p_instance_ctrl->interface_status,
592 FSP_ERR_NOT_INITIALIZED);
593 #endif
594
595 /*
596 * The value is read from the PHY register by the frame format of MII Management Interface provided
597 * for by Table 22-12 of 22.2.4.5 of IEEE 802.3-2008_section2.
598 */
599 ether_phy_preamble(p_instance_ctrl);
600 ether_phy_reg_set(p_instance_ctrl, reg_addr, ETHER_PHY_MII_WRITE);
601 ether_phy_trans_1to0(p_instance_ctrl);
602 ether_phy_reg_write(p_instance_ctrl, data);
603 ether_phy_trans_idle(p_instance_ctrl);
604
605 return FSP_SUCCESS;
606 } /* End of function R_ETHER_PHY_Write() */
607
608 /*******************************************************************************************************************//**
609 * @} (end addtogroup ETHER_PHY)
610 **********************************************************************************************************************/
611
612 /**
613 * Private functions
614 */
615
616 /***********************************************************************************************************************
617 * Function Name: phy_preamble
618 * Description : As preliminary preparation for access to the PHY module register,
619 * "1" is output via the MII management interface.
620 * Arguments : ether_channel -
621 * Ethernet channel number
622 * Return Value : none
623 ***********************************************************************************************************************/
ether_phy_preamble(ether_phy_instance_ctrl_t * p_instance_ctrl)624 static void ether_phy_preamble (ether_phy_instance_ctrl_t * p_instance_ctrl)
625 {
626 int16_t i;
627
628 /*
629 * The processing of PRE (preamble) about the frame format of MII Management Interface which is
630 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
631 */
632 i = ETHER_PHY_PREAMBLE_LENGTH;
633 while (i > 0)
634 {
635 ether_phy_mii_write1(p_instance_ctrl);
636 i--;
637 }
638 } /* End of function ether_phy_preamble() */
639
640 /***********************************************************************************************************************
641 * Function Name: ether_phy_reg_set
642 * Description : Sets a PHY device to read or write mode
643 * Arguments : ether_channel -
644 * Ethernet channel number
645 * reg_addr -
646 * address of the PHY register
647 * option -
648 * mode
649 * Return Value : none
650 ***********************************************************************************************************************/
ether_phy_reg_set(ether_phy_instance_ctrl_t * p_instance_ctrl,uint32_t reg_addr,int32_t option)651 static void ether_phy_reg_set (ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t reg_addr, int32_t option)
652 {
653 int32_t i;
654 uint32_t data = 0;
655
656 /*
657 * The processing of ST (start of frame),OP (operation code), PHYAD (PHY Address), and
658 * REGAD (Register Address) about the frame format of MII Management Interface which is
659 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
660 */
661 data = (ETHER_PHY_MII_ST << 14); /* ST code */
662
663 if (ETHER_PHY_MII_READ == option)
664 {
665 data |= (ETHER_PHY_MII_READ << 12); /* OP code(RD) */
666 }
667 else
668 {
669 data |= (ETHER_PHY_MII_WRITE << 12); /* OP code(WT) */
670 }
671
672 data |= (uint32_t) (p_instance_ctrl->phy_lsi_address << 7); /* PHY Address */
673
674 data |= (reg_addr << 2); /* Reg Address */
675
676 i = 14;
677 while (i > 0)
678 {
679 if (0 == (data & ETHER_PHY_WRITE_DATA_BIT_MASK))
680 {
681 ether_phy_mii_write0(p_instance_ctrl);
682 }
683 else
684 {
685 ether_phy_mii_write1(p_instance_ctrl);
686 }
687
688 data = (data << 1);
689 i--;
690 }
691 } /* End of function ether_phy_reg_set() */
692
693 /***********************************************************************************************************************
694 * Function Name: ether_phy_reg_read
695 * Description : Reads PHY register through MII interface
696 * Arguments : p_instance_ctrl -
697 * Ethernet channel number
698 * pdata -
699 * pointer to store the data read
700 * Return Value : none
701 ***********************************************************************************************************************/
ether_phy_reg_read(ether_phy_instance_ctrl_t * p_instance_ctrl,uint32_t * pdata)702 static void ether_phy_reg_read (ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t * pdata)
703 {
704 int32_t i;
705 int32_t j;
706 uint32_t reg_data;
707
708 volatile uint32_t * petherc_pir;
709
710 petherc_pir = p_instance_ctrl->p_reg_pir;
711
712 /*
713 * The processing of DATA (data) about reading of the frame format of MII Management Interface which is
714 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
715 */
716 reg_data = 0;
717 i = 16;
718 while (i > 0)
719 {
720 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
721 {
722 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_LOW);
723 }
724
725 reg_data = (reg_data << 1);
726 reg_data |= (uint32_t) (((*petherc_pir) & ETHER_PHY_PIR_MDI_MASK) >> 3); /* MDI read */
727
728 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
729 {
730 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_HIGH);
731 }
732
733 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
734 {
735 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_HIGH);
736 }
737
738 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
739 {
740 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_LOW);
741 }
742
743 i--;
744 }
745
746 (*pdata) = reg_data;
747 } /* End of function ether_phy_reg_read() */
748
749 /***********************************************************************************************************************
750 * Function Name: ether_phy_reg_write
751 * Description : Writes to PHY register through MII interface
752 * Arguments : ether_channel -
753 * Ethernet channel number
754 * data -
755 * value to write
756 * Return Value : none
757 ***********************************************************************************************************************/
ether_phy_reg_write(ether_phy_instance_ctrl_t * p_instance_ctrl,uint32_t data)758 static void ether_phy_reg_write (ether_phy_instance_ctrl_t * p_instance_ctrl, uint32_t data)
759 {
760 int32_t i;
761
762 /*
763 * The processing of DATA (data) about writing of the frame format of MII Management Interface which is
764 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
765 */
766 i = 16;
767 while (i > 0)
768 {
769 if (0 == (data & ETHER_PHY_WRITE_DATA_BIT_MASK))
770 {
771 ether_phy_mii_write0(p_instance_ctrl);
772 }
773 else
774 {
775 ether_phy_mii_write1(p_instance_ctrl);
776 }
777
778 i--;
779 data = (data << 1);
780 }
781 } /* End of function ether_phy_reg_write() */
782
783 /***********************************************************************************************************************
784 * Function Name: ether_phy_trans_zto0
785 * Description : Performs bus release so that PHY can drive data
786 * : for read operation
787 * Arguments : ether_channel -
788 * Ethernet channel number
789 * Return Value : none
790 ***********************************************************************************************************************/
ether_phy_trans_zto0(ether_phy_instance_ctrl_t * p_instance_ctrl)791 static void ether_phy_trans_zto0 (ether_phy_instance_ctrl_t * p_instance_ctrl)
792 {
793 /* Release the bus by writing z. */
794 ether_phy_mii_writez(p_instance_ctrl);
795
796 /* The PHY will drive the bus to 0. */
797 ether_phy_mii_writez(p_instance_ctrl);
798 } /* End of function ether_phy_trans_zto0() */
799
800 /***********************************************************************************************************************
801 * Function Name: phy_trans_1to0
802 * Description : Switches data bus so MII interface can drive data
803 * : for write operation
804 * Arguments : ether_channel -
805 * Ethernet channel number
806 * Return Value : none
807 ***********************************************************************************************************************/
ether_phy_trans_1to0(ether_phy_instance_ctrl_t * p_instance_ctrl)808 static void ether_phy_trans_1to0 (ether_phy_instance_ctrl_t * p_instance_ctrl)
809 {
810 /*
811 * The processing of TA (turnaround) about writing of the frame format of MII Management Interface which is
812 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
813 */
814 ether_phy_mii_write1(p_instance_ctrl);
815 ether_phy_mii_write0(p_instance_ctrl);
816 } /* End of function ether_phy_trans_1to0() */
817
818 /***********************************************************************************************************************
819 * Function Name: ether_phy_trans_idle
820 * Description : Switches data bus to IDLE state to prepare for the next transfer.
821 * Arguments : ether_channel -
822 * Ethernet channel number
823 * Return Value : none
824 ***********************************************************************************************************************/
ether_phy_trans_idle(ether_phy_instance_ctrl_t * p_instance_ctrl)825 static void ether_phy_trans_idle (ether_phy_instance_ctrl_t * p_instance_ctrl)
826 {
827 volatile uint32_t * petherc_pir;
828
829 petherc_pir = p_instance_ctrl->p_reg_pir;
830
831 int64_t count = (int64_t) p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time * 4;
832
833 /* Release the bus for one MDC period. */
834 for (int64_t j = count; j > 0; j--)
835 {
836 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_LOW);
837 }
838 }
839
840 /***********************************************************************************************************************
841 * Function Name: ether_phy_mii_write1
842 * Description : Outputs 1 to the MII interface
843 * Arguments : ether_channel -
844 * Ethernet channel number
845 * Return Value : none
846 ***********************************************************************************************************************/
ether_phy_mii_write1(ether_phy_instance_ctrl_t * p_instance_ctrl)847 static void ether_phy_mii_write1 (ether_phy_instance_ctrl_t * p_instance_ctrl)
848 {
849 int32_t j;
850 volatile uint32_t * petherc_pir;
851
852 petherc_pir = p_instance_ctrl->p_reg_pir;
853
854 /*
855 * The processing of one bit about frame format of MII Management Interface which is
856 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
857 * The data that 1 is output.
858 */
859 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
860 {
861 (*petherc_pir) = (ETHER_PHY_PIR_MDO_HIGH | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_LOW);
862 }
863
864 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
865 {
866 (*petherc_pir) = (ETHER_PHY_PIR_MDO_HIGH | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_HIGH);
867 }
868
869 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
870 {
871 (*petherc_pir) = (ETHER_PHY_PIR_MDO_HIGH | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_HIGH);
872 }
873
874 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
875 {
876 (*petherc_pir) = (ETHER_PHY_PIR_MDO_HIGH | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_LOW);
877 }
878 } /* End of function ether_phy_mii_write1() */
879
880 /***********************************************************************************************************************
881 * Function Name: ether_phy_mii_write0
882 * Description : Outputs 0 to the MII interface
883 * Arguments : ether_channel -
884 * Ethernet channel number
885 * Return Value : none
886 ***********************************************************************************************************************/
ether_phy_mii_write0(ether_phy_instance_ctrl_t * p_instance_ctrl)887 static void ether_phy_mii_write0 (ether_phy_instance_ctrl_t * p_instance_ctrl)
888 {
889 int32_t j;
890 volatile uint32_t * petherc_pir;
891
892 petherc_pir = p_instance_ctrl->p_reg_pir;
893
894 /*
895 * The processing of one bit about frame format of MII Management Interface which is
896 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
897 * The data that 0 is output.
898 */
899 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
900 {
901 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_LOW);
902 }
903
904 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
905 {
906 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_HIGH);
907 }
908
909 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
910 {
911 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_HIGH);
912 }
913
914 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
915 {
916 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_WRITE | ETHER_PHY_PIR_MDC_LOW);
917 }
918 } /* End of function ether_phy_mii_write0() */
919
920 /***********************************************************************************************************************
921 * Function Name: ether_phy_mii_writez
922 * Description : Outputs z to the MII interface
923 * Arguments : ether_channel -
924 * Ethernet channel number
925 * Return Value : none
926 ***********************************************************************************************************************/
ether_phy_mii_writez(ether_phy_instance_ctrl_t * p_instance_ctrl)927 static void ether_phy_mii_writez (ether_phy_instance_ctrl_t * p_instance_ctrl)
928 {
929 int32_t j;
930
931 volatile uint32_t * petherc_pir;
932
933 petherc_pir = p_instance_ctrl->p_reg_pir;
934
935 /*
936 * The processing of one bit about frame format of MII Management Interface which is
937 * provided by "Table 22-12" of "22.2.4.5" of "IEEE 802.3-2008_section2".
938 * The data that z is output.
939 */
940 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
941 {
942 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_LOW);
943 }
944
945 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
946 {
947 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_HIGH);
948 }
949
950 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
951 {
952 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_HIGH);
953 }
954
955 for (j = p_instance_ctrl->p_ether_phy_cfg->mii_bit_access_wait_time; j > 0; j--)
956 {
957 (*petherc_pir) = (ETHER_PHY_PIR_MDO_LOW | ETHER_PHY_PIR_MMD_READ | ETHER_PHY_PIR_MDC_LOW);
958 }
959 }
960
961 /***********************************************************************************************************************
962 * Function Name: ether_phy_targets_initialize
963 * Description : PHY-LSI specific initialization processing
964 * Arguments : p_instance_ctrl -
965 * Ethernet control block
966 * Return Value : none
967 ***********************************************************************************************************************/
ether_phy_targets_initialize(ether_phy_instance_ctrl_t * p_instance_ctrl)968 static void ether_phy_targets_initialize (ether_phy_instance_ctrl_t * p_instance_ctrl)
969 {
970 switch (p_instance_ctrl->p_ether_phy_cfg->phy_lsi_type)
971 {
972 /* Use KSZ8091RNB */
973 #if (ETHER_PHY_CFG_TARGET_KSZ8091RNB_ENABLE)
974 case ETHER_PHY_LSI_TYPE_KSZ8091RNB:
975 {
976 ether_phy_target_ksz8091rnb_initialize(p_instance_ctrl);
977 break;
978 }
979 #endif
980
981 /* Use KSZ8041 */
982 #if (ETHER_PHY_CFG_TARGET_KSZ8041_ENABLE)
983 case ETHER_PHY_LSI_TYPE_KSZ8041:
984 {
985 ether_phy_target_ksz8041_initialize(p_instance_ctrl);
986 break;
987 }
988 #endif
989
990 /* Use DP83620 */
991 #if (ETHER_PHY_CFG_TARGET_DP83620_ENABLE)
992 case ETHER_PHY_LSI_TYPE_DP83620:
993 {
994 ether_phy_target_dp83620_initialize(p_instance_ctrl);
995 break;
996 }
997 #endif
998
999 /* Use ICS1894 */
1000 #if (ETHER_PHY_CFG_TARGET_ICS1894_ENABLE)
1001 case ETHER_PHY_LSI_TYPE_ICS1894:
1002 {
1003 ether_phy_target_ics1894_initialize(p_instance_ctrl);
1004 break;
1005 }
1006 #endif
1007
1008 /* User custom */
1009 #if (ETHER_PHY_CFG_USE_CUSTOM_PHY_LSI_ENABLE)
1010 case ETHER_PHY_LSI_TYPE_CUSTOM:
1011 {
1012 if (NULL != p_instance_ctrl->p_ether_phy_cfg->p_extend)
1013 {
1014 ether_phy_extended_cfg_t const * p_callback = p_instance_ctrl->p_ether_phy_cfg->p_extend;
1015 if (NULL != p_callback->p_target_init)
1016 {
1017 p_callback->p_target_init(p_instance_ctrl);
1018 }
1019 }
1020
1021 break;
1022 }
1023 #endif
1024
1025 /* If module is configured for default LSI */
1026 default:
1027 {
1028 break;
1029 }
1030 }
1031 } /* End of function ether_phy_targets_initialize() */
1032
1033 /***********************************************************************************************************************
1034 * Function Name: ether_phy_targets_is_support_link_partner_ability
1035 * Description : Check if the PHY-LSI connected Ethernet controller supports link ability
1036 * Arguments : p_instance_ctrl -
1037 * Ethernet control block
1038 * line_speed_duplex -
1039 * Line speed duplex of link partner PHY-LSI
1040 * Return Value : bool
1041 ***********************************************************************************************************************/
ether_phy_targets_is_support_link_partner_ability(ether_phy_instance_ctrl_t * p_instance_ctrl,uint32_t line_speed_duplex)1042 static bool ether_phy_targets_is_support_link_partner_ability (ether_phy_instance_ctrl_t * p_instance_ctrl,
1043 uint32_t line_speed_duplex)
1044 {
1045 bool result = false;
1046 FSP_PARAMETER_NOT_USED(line_speed_duplex);
1047 switch (p_instance_ctrl->p_ether_phy_cfg->phy_lsi_type)
1048 {
1049 /* Use KSZ8091RNB */
1050 #if (ETHER_PHY_CFG_TARGET_KSZ8091RNB_ENABLE)
1051 case ETHER_PHY_LSI_TYPE_KSZ8091RNB:
1052 {
1053 result = ether_phy_target_ksz8091rnb_is_support_link_partner_ability(p_instance_ctrl, line_speed_duplex);
1054 break;
1055 }
1056 #endif
1057
1058 /* Use KSZ8041 */
1059 #if (ETHER_PHY_CFG_TARGET_KSZ8041_ENABLE)
1060 case ETHER_PHY_LSI_TYPE_KSZ8041:
1061 {
1062 result = ether_phy_target_ksz8041_is_support_link_partner_ability(p_instance_ctrl, line_speed_duplex);
1063 break;
1064 }
1065 #endif
1066
1067 /* Use DP83620 */
1068 #if (ETHER_PHY_CFG_TARGET_DP83620_ENABLE)
1069 case ETHER_PHY_LSI_TYPE_DP83620:
1070 {
1071 result = ether_phy_target_dp83620_is_support_link_partner_ability(p_instance_ctrl, line_speed_duplex);
1072 break;
1073 }
1074 #endif
1075
1076 /* Use ICS1894 */
1077 #if (ETHER_PHY_CFG_TARGET_ICS1894_ENABLE)
1078 case ETHER_PHY_LSI_TYPE_ICS1894:
1079 {
1080 result = ether_phy_target_ics1894_is_support_link_partner_ability(p_instance_ctrl, line_speed_duplex);
1081 break;
1082 }
1083 #endif
1084
1085 /* User custom */
1086 #if (ETHER_PHY_CFG_USE_CUSTOM_PHY_LSI_ENABLE)
1087 case ETHER_PHY_LSI_TYPE_CUSTOM:
1088 {
1089 if (NULL != p_instance_ctrl->p_ether_phy_cfg->p_extend)
1090 {
1091 ether_phy_extended_cfg_t const * p_callback = p_instance_ctrl->p_ether_phy_cfg->p_extend;
1092 if (NULL != p_callback->p_target_link_partner_ability_get)
1093 {
1094 result = p_callback->p_target_link_partner_ability_get(p_instance_ctrl, line_speed_duplex);
1095 }
1096 }
1097
1098 break;
1099 }
1100 #endif
1101
1102 /* If module is configured for default LSI, always return true */
1103 default:
1104 {
1105 result = true;
1106 break;
1107 }
1108 }
1109
1110 return result;
1111 } /* End of function ether_phy_targets_is_support_link_partner_ability() */
1112