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 #include <string.h>
11 #include "r_ether.h"
12 #include "r_ether_phy.h"
13
14 /***********************************************************************************************************************
15 * Macro definitions
16 ***********************************************************************************************************************/
17 #ifndef ETHER_ERROR_RETURN
18
19 #define ETHER_ERROR_RETURN(a, err) FSP_ERROR_RETURN((a), (err))
20 #endif
21
22 #define ETHER_ETHERC_REG_SIZE (0x400UL)
23 #define ETHER_ETHERC_EDMAC_REG_SIZE (0x100UL)
24
25 #define ETHER_ETHERC_INITIALIZATION_WAIT_CYCLE (0x64UL)
26
27 /** "ETHE" in ASCII. Used to determine if the control block is open. */
28 #define ETHER_OPEN (0x45544845U)
29
30 /* Definition of the maximum / minimum number of data that can be sent at one time in the Ethernet */
31 #define ETHER_MAXIMUM_FRAME_SIZE (1514U) /* Maximum number of transmitted data */
32 #define ETHER_MINIMUM_FRAME_SIZE (60U) /* Minimum number of transmitted data */
33
34 /* Definition of the maximum padding offset */
35 #define ETHER_MAXIMUM_PADDING_OFFSET (63U)
36
37 /* Bit definition of Ethernet interrupt factor*/
38 #define ETHER_ETHERC_INTERRUPT_FACTOR_ALL (0x00000037UL)
39
40 #define ETHER_ETHERC_INTERRUPT_FACTOR_LCHNG (1UL << 2)
41 #define ETHER_ETHERC_INTERRUPT_FACTOR_MPD (1UL << 1)
42
43 #define ETHER_EDMAC_INTERRUPT_FACTOR_ALL (0x47FF0F9FUL)
44
45 #define ETHER_EDMAC_INTERRUPT_FACTOR_RFCOF (1UL << 24)
46 #define ETHER_EDMAC_INTERRUPT_FACTOR_ECI (1UL << 22)
47 #define ETHER_EDMAC_INTERRUPT_FACTOR_TC (1UL << 21)
48 #define ETHER_EDMAC_INTERRUPT_FACTOR_FR (1UL << 18)
49 #define ETHER_EDMAC_INTERRUPT_FACTOR_RDE (1UL << 17)
50 #define ETHER_EDMAC_INTERRUPT_FACTOR_RFOF (1UL << 16)
51
52 /* Bit definition of Ethernet interrupt enable */
53 #define ETHER_ETHERC_INTERRUPT_ENABLE_LCHNG (1UL << 2)
54 #define ETHER_ETHERC_INTERRUPT_ENABLE_MPD (1UL << 1)
55
56 /* Bit definitions of status member of DescriptorS */
57
58 #define ETHER_TD0_TACT (0x80000000UL)
59 #define ETHER_TD0_TDLE (0x40000000UL)
60 #define ETHER_TD0_TFP1 (0x20000000UL)
61 #define ETHER_TD0_TFP0 (0x10000000UL)
62 #define ETHER_TD0_TFE (0x08000000UL)
63
64 #define ETHER_TD0_TWBI (0x04000000UL)
65 #define ETHER_TD0_TFS8_TAD (0x00000100UL)
66 #define ETHER_TD0_TFS3_CND (0x00000008UL)
67 #define ETHER_TD0_TFS2_DLC (0x00000004UL)
68 #define ETHER_TD0_TFS1_CD (0x00000002UL)
69 #define ETHER_TD0_TFS0_TRO (0x00000001UL)
70
71 #define ETHER_RD0_RACT (0x80000000UL)
72 #define ETHER_RD0_RDLE (0x40000000UL)
73 #define ETHER_RD0_RFP1 (0x20000000UL)
74 #define ETHER_RD0_RFP0 (0x10000000UL)
75 #define ETHER_RD0_RFE (0x08000000UL)
76
77 #define ETHER_RD0_RFS9_RFOVER (0x00000200UL)
78 #define ETHER_RD0_RFS8_RAD (0x00000100UL)
79 #define ETHER_RD0_RFS7_RMAF (0x00000080UL)
80 #define ETHER_RD0_RFS4_RRF (0x00000010UL)
81 #define ETHER_RD0_RFS3_RTLF (0x00000008UL)
82 #define ETHER_RD0_RFS2_RTSF (0x00000004UL)
83 #define ETHER_RD0_RFS1_PRE (0x00000002UL)
84 #define ETHER_RD0_RFS0_CERF (0x00000001UL)
85
86 /* Macro definitions of ETHERC/EDMAC configurations */
87 #define ETHER_ETHERC_ECMR_MODE_CLEAR (0x00000000UL)
88 #define ETHER_ETHERC_RFLR_DEFAULT_VALUE (1518U)
89 #define ETHER_ETHERC_IPGR_DEFAULT_VALUE (0x00000014UL)
90 #define ETHER_ETHERC_APR_MAXIMUM_VALUE (0x0000FFFFUL)
91 #define ETHER_ETHERC_FCFTR_MINIMUM_VALUE (0x00000000UL)
92
93 #define ETHER_EDMAC_TRSCER_MULTICAST_DISABLE (0x00000000UL)
94 #define ETHER_EDMAC_TRSCER_MULTICAST_ENABLE (0x00000080UL)
95 #define ETHER_EDMAC_RMCR_MULTIPLE_FRAMES_ENABLE (0x00000001UL)
96 #define ETHER_EDMAC_TFTR_STORE_AND_FORWARD_MODE (0x00000000UL)
97
98 /* Macro definitions of EDMAC requests */
99 #define ETHER_EDMAC_EDRRR_RECEIVE_REQUEST (0x00000001UL)
100 #define ETHER_EDMAC_EDTRR_TRANSMIT_REQUEST (0x00000001UL)
101
102 /* Number of entries in PAUSE resolution table */
103 #define ETHER_PAUSE_TABLE_ENTRIES (8)
104
105 /* Local device and link partner PAUSE settings */
106 #define ETHER_PAUSE_XMIT_OFF (0) /* The pause frame transmission is prohibited. */
107 #define ETHER_PAUSE_RECV_OFF (0) /* The pause frame reception is prohibited. */
108 #define ETHER_PAUSE_XMIT_ON (1) /* The pause frame transmission is permitted. */
109 #define ETHER_PAUSE_RECV_ON (1) /* The pause frame reception is permitted. */
110
111 /* Macro definition for buffer alignment adjustment */
112 #define ETHER_BUFFER_32BYTE_ALIGNMENT_MASK (0x1FUL) /* Mask for checking whether or not 32-bit alignment. */
113
114 /* PAUSE link mask and shift values */
115
116 /*
117 * The mask value and shift value which are for that shift the bits form a line and
118 * for comparing the bit information of PAUSE function which support the local device and
119 * Link partner with the assorted table(pause_resolution) which enable or disable the PAUSE frame.
120 */
121 #define ETHER_LINK_RESOLUTION_ABILITY_MASK (3)
122 #define ETHER_LINK_RESOLUTION_LOCAL_ABILITY_BITSHIFT (2)
123
124 /* Etherc mode */
125 #define ETHER_NO_USE_MAGIC_PACKET_DETECT (0)
126 #define ETHER_USE_MAGIC_PACKET_DETECT (1)
127
128 /* ETHER_NO_DATA is the return value that indicates that no received data. */
129 #define ETHER_NO_DATA (0)
130
131 /* PAUSE link mask and shift values */
132
133 /***********************************************************************************************************************
134 * Typedef definitions
135 ***********************************************************************************************************************/
136 #if defined(__ARMCC_VERSION) || defined(__ICCARM__)
137 typedef void (BSP_CMSE_NONSECURE_CALL * ether_prv_ns_callback)(ether_callback_args_t * p_args);
138 #elif defined(__GNUC__)
139 typedef BSP_CMSE_NONSECURE_CALL void (*volatile ether_prv_ns_callback)(ether_callback_args_t * p_args);
140 #endif
141
142 /***********************************************************************************************************************
143 * Exported global functions (to be accessed by other files)
144 ***********************************************************************************************************************/
145 void ether_eint_isr(void);
146
147 /***********************************************************************************************************************
148 * Exported global variables (to be accessed by other files)
149 ***********************************************************************************************************************/
150
151 /***********************************************************************************************************************
152 * Private function prototypes
153 **********************************************************************************************************************/
154 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
155 static fsp_err_t ether_open_param_check(ether_instance_ctrl_t const * const p_instance_ctrl,
156 ether_cfg_t const * const p_cfg);
157
158 #endif
159
160 static void ether_enable_icu(ether_instance_ctrl_t * const p_instance_ctrl);
161 static void ether_disable_icu(ether_instance_ctrl_t * const p_instance_ctrl);
162 static void ether_reset_mac(R_ETHERC_EDMAC_Type * const p_reg);
163 static void ether_init_descriptors(ether_instance_ctrl_t * const p_instance_ctrl);
164 void ether_init_buffers(ether_instance_ctrl_t * const p_instance_ctrl);
165 static fsp_err_t ether_buffer_get(ether_instance_ctrl_t * const p_instance_ctrl,
166 void ** const p_buffer,
167 uint32_t * p_buffer_size);
168 static void ether_config_ethernet(ether_instance_ctrl_t const * const p_instance_ctrl, const uint8_t mode);
169 static void ether_pause_resolution(uint32_t const local_ability,
170 uint32_t const partner_ability,
171 uint32_t * ptx_pause,
172 uint32_t * prx_pause);
173 void ether_configure_mac(ether_instance_ctrl_t * const p_instance_ctrl,
174 const uint8_t mac_addr[],
175 const uint8_t mode);
176 fsp_err_t ether_do_link(ether_instance_ctrl_t * const p_instance_ctrl, const uint8_t mode);
177 static fsp_err_t ether_link_status_check(ether_instance_ctrl_t const * const p_instance_ctrl);
178 static uint8_t ether_check_magic_packet_detection_bit(ether_instance_ctrl_t const * const p_instance_ctrl);
179 static void ether_configure_padding(ether_instance_ctrl_t * const p_instance_ctrl);
180 static void ether_call_callback(ether_instance_ctrl_t * p_instance_ctrl, ether_callback_args_t * p_callback_args);
181
182 /***********************************************************************************************************************
183 * Private global variables
184 **********************************************************************************************************************/
185
186 /** Name of module used by error logger macro */
187 #if BSP_CFG_ERROR_LOG != 0
188 static const char g_module_name[] = "ether";
189 #endif
190
191 #if defined(__GNUC__)
192
193 /* This structure is affected by warnings from a GCC compiler bug. This pragma suppresses the warnings in this
194 * structure only.*/
195
196 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
197 #endif
198
199 /** ETHER HAL API mapping for Ethernet Controller interface. */
200 const ether_api_t g_ether_on_ether =
201 {
202 .open = R_ETHER_Open,
203 .close = R_ETHER_Close,
204 .read = R_ETHER_Read,
205 .bufferRelease = R_ETHER_BufferRelease,
206 .rxBufferUpdate = R_ETHER_RxBufferUpdate,
207 .write = R_ETHER_Write,
208 .linkProcess = R_ETHER_LinkProcess,
209 .wakeOnLANEnable = R_ETHER_WakeOnLANEnable,
210 .txStatusGet = R_ETHER_TxStatusGet,
211 .callbackSet = R_ETHER_CallbackSet,
212 };
213
214 /*
215 * PAUSE Resolution as documented in IEEE 802.3-2008_section2 Annex
216 * 28B, Table 28B-3. The following table codify logic that
217 * determines how the PAUSE is configured for local transmitter
218 * and receiver and partner transmitter and receiver.
219 */
220 static const ether_pause_resolution_t pause_resolution[ETHER_PAUSE_TABLE_ENTRIES] =
221 {
222 {ETHER_PAUSE_MASKC, ETHER_PAUSE_VAL0, ETHER_PAUSE_XMIT_OFF, ETHER_PAUSE_RECV_OFF },
223 {ETHER_PAUSE_MASKE, ETHER_PAUSE_VAL4, ETHER_PAUSE_XMIT_OFF, ETHER_PAUSE_RECV_OFF },
224 {ETHER_PAUSE_MASKF, ETHER_PAUSE_VAL6, ETHER_PAUSE_XMIT_OFF, ETHER_PAUSE_RECV_OFF },
225 {ETHER_PAUSE_MASKF, ETHER_PAUSE_VAL7, ETHER_PAUSE_XMIT_ON, ETHER_PAUSE_RECV_OFF },
226 {ETHER_PAUSE_MASKE, ETHER_PAUSE_VAL8, ETHER_PAUSE_XMIT_OFF, ETHER_PAUSE_RECV_OFF },
227 {ETHER_PAUSE_MASKA, ETHER_PAUSE_VALA, ETHER_PAUSE_XMIT_ON, ETHER_PAUSE_RECV_ON },
228 {ETHER_PAUSE_MASKF, ETHER_PAUSE_VALC, ETHER_PAUSE_XMIT_OFF, ETHER_PAUSE_RECV_OFF },
229 {ETHER_PAUSE_MASKF, ETHER_PAUSE_VALD, ETHER_PAUSE_XMIT_OFF, ETHER_PAUSE_RECV_ON }
230 };
231
232 /*******************************************************************************************************************//**
233 * @addtogroup ETHER
234 * @{
235 **********************************************************************************************************************/
236
237 /***********************************************************************************************************************
238 * Functions
239 **********************************************************************************************************************/
240
241 /********************************************************************************************************************//**
242 * @brief After ETHERC, EDMAC and PHY-LSI are reset in software, an auto negotiation of PHY-LSI is begun.
243 * Afterwards, the link signal change interrupt is permitted. Implements @ref ether_api_t::open.
244 *
245 * @retval FSP_SUCCESS Channel opened successfully.
246 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block or configuration structure is NULL.
247 * @retval FSP_ERR_ALREADY_OPEN Control block has already been opened or channel is being used by another
248 * instance. Call close() then open() to reconfigure.
249 * @retval FSP_ERR_ETHER_ERROR_PHY_COMMUNICATION Initialization of PHY-LSI failed.
250 * @retval FSP_ERR_INVALID_CHANNEL Invalid channel number is given.
251 * @retval FSP_ERR_INVALID_POINTER Pointer to extend config structure or MAC address is NULL.
252 * @retval FSP_ERR_INVALID_ARGUMENT Interrupt is not enabled.
253 * @retval FSP_ERR_ETHER_PHY_ERROR_LINK Initialization of PHY-LSI failed.
254 ***********************************************************************************************************************/
R_ETHER_Open(ether_ctrl_t * const p_ctrl,ether_cfg_t const * const p_cfg)255 fsp_err_t R_ETHER_Open (ether_ctrl_t * const p_ctrl, ether_cfg_t const * const p_cfg)
256 {
257 fsp_err_t err = FSP_SUCCESS;
258 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
259 ether_extended_cfg_t * p_ether_extended_cfg;
260 R_ETHERC0_Type * p_reg_etherc;
261 R_ETHERC_EDMAC_Type * p_reg_edmac;
262
263 fsp_err_t phy_ret;
264
265 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
266
267 /** Check parameters. */
268 err = ether_open_param_check(p_instance_ctrl, p_cfg); /** check arguments */
269 ETHER_ERROR_RETURN((FSP_SUCCESS == err), err);
270 #endif
271 ETHER_ERROR_RETURN((ETHER_OPEN != p_instance_ctrl->open), FSP_ERR_ALREADY_OPEN);
272
273 p_ether_extended_cfg = (ether_extended_cfg_t *) p_cfg->p_extend;
274
275 /** Make sure this channel exists. */
276 p_instance_ctrl->p_reg_etherc = ((R_ETHERC0_Type *) (R_ETHERC0_BASE + (ETHER_ETHERC_REG_SIZE * p_cfg->channel)));
277 p_instance_ctrl->p_reg_edmac =
278 ((R_ETHERC_EDMAC_Type *) (R_ETHERC_EDMAC_BASE + (ETHER_ETHERC_EDMAC_REG_SIZE * p_cfg->channel)));
279
280 p_reg_etherc = p_instance_ctrl->p_reg_etherc;
281 p_reg_edmac = p_instance_ctrl->p_reg_edmac;
282
283 /* Initialize configuration of Ethernet module. */
284 p_instance_ctrl->p_ether_cfg = p_cfg;
285
286 /* Initialize the flags */
287 p_instance_ctrl->link_establish_status = ETHER_LINK_ESTABLISH_STATUS_DOWN;
288 p_instance_ctrl->magic_packet = ETHER_MAGIC_PACKET_NOT_DETECTED;
289 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_NO_CHANGE;
290 p_instance_ctrl->previous_link_status = ETHER_PREVIOUS_LINK_STATUS_DOWN;
291
292 /* Initialize the transmit and receive descriptor */
293 memset(p_ether_extended_cfg->p_rx_descriptors,
294 0x00,
295 sizeof(ether_instance_descriptor_t) *
296 p_instance_ctrl->p_ether_cfg->num_rx_descriptors);
297 memset(p_ether_extended_cfg->p_tx_descriptors,
298 0x00,
299 sizeof(ether_instance_descriptor_t) *
300 p_instance_ctrl->p_ether_cfg->num_tx_descriptors);
301
302 /* Initialize the Ethernet buffer */
303 ether_init_buffers(p_instance_ctrl);
304
305 /* Set callback and context pointers, if configured */
306 p_instance_ctrl->p_callback = p_cfg->p_callback;
307 p_instance_ctrl->p_context = p_cfg->p_context;
308 p_instance_ctrl->p_callback_memory = NULL;
309
310
311 /* Software reset */
312 ether_reset_mac(p_instance_ctrl->p_reg_edmac);
313
314 /* Setting the padding function */
315 ether_configure_padding(p_instance_ctrl);
316
317 #if !ETHER_CFG_USE_CUSTOM_PHY_DRIVER
318 /* Software reset the PHY */
319 phy_ret = p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_api->open(
320 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_ctrl,
321 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_cfg);
322
323 #if !ETHER_PHY_CFG_INIT_PHY_LSI_AUTOMATIC
324
325 /* Initialize the PHY */
326 if (FSP_SUCCESS == phy_ret)
327 {
328 phy_ret = p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_api->chipInit(
329 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_ctrl,
330 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_cfg);
331 }
332 #endif
333 #else
334 phy_ret = FSP_SUCCESS;
335 #endif
336
337 if (FSP_SUCCESS == phy_ret)
338 {
339 #if !ETHER_CFG_USE_CUSTOM_PHY_DRIVER
340 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_api->startAutoNegotiate(
341 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_ctrl);
342 #endif
343
344 /* Clear all ETHERC status BFR, PSRTO, LCHNG, MPD, ICD */
345 p_reg_etherc->ECSR = ETHER_ETHERC_INTERRUPT_FACTOR_ALL;
346
347 /* Clear all EDMAC status bits */
348 p_reg_edmac->EESR = ETHER_EDMAC_INTERRUPT_FACTOR_ALL;
349
350 #if (ETHER_CFG_USE_LINKSTA == 1)
351
352 /* Enable interrupts of interest only. */
353 p_reg_etherc->ECSIPR_b.LCHNGIP = 1;
354 #endif
355
356 p_reg_edmac->EESIPR_b.ECIIP = 1;
357
358 /* Set Ethernet interrupt level and enable */
359 ether_enable_icu(p_instance_ctrl);
360
361 p_instance_ctrl->open = ETHER_OPEN;
362
363 err = FSP_SUCCESS;
364 }
365 else
366 {
367 if (FSP_ERR_ETHER_PHY_ERROR_LINK == phy_ret)
368 {
369 err = FSP_ERR_ETHER_ERROR_PHY_COMMUNICATION;
370 }
371 else
372 {
373 err = phy_ret;
374 }
375 }
376
377 return err;
378 } /* End of function R_ETHER_Open() */
379
380 /********************************************************************************************************************//**
381 * @brief Disables interrupts. Removes power and releases hardware lock. Implements @ref ether_api_t::close.
382 *
383 * @retval FSP_SUCCESS Channel successfully closed.
384 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block is NULL.
385 * @retval FSP_ERR_NOT_OPEN The control block has not been opened
386 *
387 ***********************************************************************************************************************/
R_ETHER_Close(ether_ctrl_t * const p_ctrl)388 fsp_err_t R_ETHER_Close (ether_ctrl_t * const p_ctrl)
389 {
390 fsp_err_t err = FSP_SUCCESS;
391 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
392 R_ETHERC0_Type * p_reg_etherc;
393 R_ETHERC_EDMAC_Type * p_reg_edmac;
394
395 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
396 FSP_ASSERT(p_instance_ctrl);
397 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
398 #endif
399
400 p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
401 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
402
403 /* Disable Ethernet interrupt. */
404 ether_disable_icu(p_instance_ctrl);
405
406 #if !ETHER_CFG_USE_CUSTOM_PHY_DRIVER
407 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_api->close(
408 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_ctrl);
409 #endif
410
411 p_reg_etherc->ECSIPR_b.LCHNGIP = 0;
412 p_reg_edmac->EESIPR_b.ECIIP = 0;
413
414 /* Disable TE and RE */
415 p_reg_etherc->ECMR = ETHER_ETHERC_ECMR_MODE_CLEAR;
416
417 /* Initialize the flags */
418 p_instance_ctrl->link_establish_status = ETHER_LINK_ESTABLISH_STATUS_DOWN;
419 p_instance_ctrl->magic_packet = ETHER_MAGIC_PACKET_NOT_DETECTED;
420 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_NO_CHANGE;
421 #if (ETHER_CFG_USE_LINKSTA == 0)
422 p_instance_ctrl->previous_link_status = ETHER_PREVIOUS_LINK_STATUS_DOWN;
423 #endif
424
425 /** Remove power to the channel. */
426 R_BSP_MODULE_STOP(FSP_IP_ETHER, p_instance_ctrl->p_ether_cfg->channel);
427
428 /** Clear configure block parameters. */
429 p_instance_ctrl->p_ether_cfg = NULL;
430
431 /** Mark the channel not open so other APIs cannot use it. */
432 p_instance_ctrl->open = 0U;
433
434 return err;
435 } /* End of function R_ETHER_Close() */
436
437 /********************************************************************************************************************//**
438 * @brief Move to the next buffer in the circular receive buffer list. Implements @ref ether_api_t::bufferRelease.
439 *
440 * @retval FSP_SUCCESS Processing completed successfully.
441 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block is NULL.
442 * @retval FSP_ERR_NOT_OPEN The control block has not been opened
443 * @retval FSP_ERR_ETHER_ERROR_LINK Auto-negotiation is not completed, and reception is not enabled.
444 * @retval FSP_ERR_ETHER_ERROR_MAGIC_PACKET_MODE As a Magic Packet is being detected, transmission and reception is
445 * not enabled.
446 ***********************************************************************************************************************/
R_ETHER_BufferRelease(ether_ctrl_t * const p_ctrl)447 fsp_err_t R_ETHER_BufferRelease (ether_ctrl_t * const p_ctrl)
448 {
449 fsp_err_t err = FSP_SUCCESS;
450 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
451 R_ETHERC_EDMAC_Type * p_reg_edmac;
452
453 uint32_t status;
454
455 /* Check argument */
456 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
457 FSP_ASSERT(p_instance_ctrl);
458 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
459 #endif
460
461 /* When the Link up processing is not completed, return error */
462 ETHER_ERROR_RETURN(ETHER_LINK_ESTABLISH_STATUS_UP == p_instance_ctrl->link_establish_status,
463 FSP_ERR_ETHER_ERROR_LINK);
464
465 /* In case of detection mode of magic packet, return error. */
466 ETHER_ERROR_RETURN(0 == ether_check_magic_packet_detection_bit(p_instance_ctrl),
467 FSP_ERR_ETHER_ERROR_MAGIC_PACKET_MODE);
468
469 /* When receive data exists */
470 if (ETHER_RD0_RACT != (p_instance_ctrl->p_rx_descriptor->status & ETHER_RD0_RACT))
471 {
472 /* Reset current descriptor */
473 status = ETHER_RD0_RFP1;
474 status |= ETHER_RD0_RFP0;
475 status |= ETHER_RD0_RFE;
476 status |= ETHER_RD0_RFS9_RFOVER;
477 status |= ETHER_RD0_RFS8_RAD;
478 status |= ETHER_RD0_RFS7_RMAF;
479 status |= ETHER_RD0_RFS4_RRF;
480 status |= ETHER_RD0_RFS3_RTLF;
481 status |= ETHER_RD0_RFS2_RTSF;
482 status |= ETHER_RD0_RFS1_PRE;
483 status |= ETHER_RD0_RFS0_CERF;
484
485 p_instance_ctrl->p_rx_descriptor->status &= (~status);
486
487 /* Enable current descriptor */
488 p_instance_ctrl->p_rx_descriptor->status |= ETHER_RD0_RACT;
489
490 /* Move to next descriptor */
491 p_instance_ctrl->p_rx_descriptor = p_instance_ctrl->p_rx_descriptor->p_next;
492 }
493
494 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
495
496 if (ETHER_EDMAC_EDRRR_RECEIVE_REQUEST != p_reg_edmac->EDRRR)
497 {
498 /* Restart if stopped */
499 p_reg_edmac->EDRRR = ETHER_EDMAC_EDRRR_RECEIVE_REQUEST;
500 }
501
502 err = FSP_SUCCESS;
503
504 return err;
505 } /* End of function R_ETHER_BufferRelease() */
506
507 /********************************************************************************************************************//**
508 * @brief Change the buffer pointer of the current rx buffer descriptor. Implements @ref ether_api_t::rxBufferUpdate.
509 *
510 * @retval FSP_SUCCESS Processing completed successfully.
511 * @retval FSP_ERR_ASSERTION A pointer argument is NULL.
512 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
513 * @retval FSP_ERR_INVALID_POINTER The pointer of buffer is NULL or not aligned on a 32-bit boundary.
514 * @retval FSP_ERR_INVALID_MODE Driver is configured to non zero copy mode.
515 * @retval FSP_ERR_ETHER_RECEIVE_BUFFER_ACTIVE All descriptor is active.
516 ***********************************************************************************************************************/
R_ETHER_RxBufferUpdate(ether_ctrl_t * const p_ctrl,void * const p_buffer)517 fsp_err_t R_ETHER_RxBufferUpdate (ether_ctrl_t * const p_ctrl, void * const p_buffer)
518 {
519 fsp_err_t err = FSP_SUCCESS;
520 R_ETHERC_EDMAC_Type * p_reg_edmac;
521 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
522 uint32_t status;
523
524 /* Check argument */
525 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
526 FSP_ASSERT(p_instance_ctrl);
527 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
528 ETHER_ERROR_RETURN(NULL != p_buffer, FSP_ERR_INVALID_POINTER);
529 ETHER_ERROR_RETURN(0 == ((uint32_t) p_buffer & (uint32_t) ETHER_BUFFER_32BYTE_ALIGNMENT_MASK),
530 FSP_ERR_INVALID_POINTER);
531 ETHER_ERROR_RETURN(ETHER_ZEROCOPY_ENABLE == p_instance_ctrl->p_ether_cfg->zerocopy, FSP_ERR_INVALID_MODE);
532 #endif
533
534 if (ETHER_RD0_RACT != (p_instance_ctrl->p_rx_descriptor->status & ETHER_RD0_RACT))
535 {
536 p_instance_ctrl->p_rx_descriptor->p_buffer = p_buffer;
537
538 /* Reset current descriptor */
539 status = ETHER_RD0_RFP1;
540 status |= ETHER_RD0_RFP0;
541 status |= ETHER_RD0_RFE;
542 status |= ETHER_RD0_RFS9_RFOVER;
543 status |= ETHER_RD0_RFS8_RAD;
544 status |= ETHER_RD0_RFS7_RMAF;
545 status |= ETHER_RD0_RFS4_RRF;
546 status |= ETHER_RD0_RFS3_RTLF;
547 status |= ETHER_RD0_RFS2_RTSF;
548 status |= ETHER_RD0_RFS1_PRE;
549 status |= ETHER_RD0_RFS0_CERF;
550
551 p_instance_ctrl->p_rx_descriptor->status &= (~status);
552
553 /* Enable current descriptor */
554 p_instance_ctrl->p_rx_descriptor->status |= ETHER_RD0_RACT;
555
556 /* Move to next descriptor */
557 p_instance_ctrl->p_rx_descriptor = p_instance_ctrl->p_rx_descriptor->p_next;
558
559 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
560
561 if (ETHER_EDMAC_EDRRR_RECEIVE_REQUEST != p_reg_edmac->EDRRR)
562 {
563 /* Restart if stopped */
564 p_reg_edmac->EDRRR = ETHER_EDMAC_EDRRR_RECEIVE_REQUEST;
565 }
566 }
567 else
568 {
569 err = FSP_ERR_ETHER_RECEIVE_BUFFER_ACTIVE;
570 }
571
572 return err;
573 }
574
575 /********************************************************************************************************************//**
576 * @brief The Link up processing, the Link down processing, and the magic packet detection processing are executed.
577 * Implements @ref ether_api_t::linkProcess.
578 *
579 * @retval FSP_SUCCESS Link is up.
580 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block is NULL.
581 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
582 * @retval FSP_ERR_ETHER_ERROR_LINK Link is down.
583 * @retval FSP_ERR_ETHER_ERROR_PHY_COMMUNICATION When reopening the PHY interface initialization of the PHY-LSI failed.
584 * @retval FSP_ERR_ALREADY_OPEN When reopening the PHY interface it was already opened.
585 * @retval FSP_ERR_INVALID_CHANNEL When reopening the PHY interface an invalid channel was passed.
586 * @retval FSP_ERR_INVALID_POINTER When reopening the PHY interface the MAC address pointer was NULL.
587 * @retval FSP_ERR_INVALID_ARGUMENT When reopening the PHY interface the interrupt was not enabled.
588 * @retval FSP_ERR_ETHER_PHY_ERROR_LINK Initialization of the PHY-LSI failed.
589 ***********************************************************************************************************************/
R_ETHER_LinkProcess(ether_ctrl_t * const p_ctrl)590 fsp_err_t R_ETHER_LinkProcess (ether_ctrl_t * const p_ctrl)
591 {
592 fsp_err_t err = FSP_SUCCESS;
593 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
594 R_ETHERC0_Type * p_reg_etherc;
595
596 ether_callback_args_t callback_arg;
597 ether_cfg_t const * p_ether_cfg;
598 volatile ether_previous_link_status_t previous_link_status;
599 ether_extended_cfg_t * p_ether_extended_cfg;
600
601 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
602 FSP_ASSERT(p_instance_ctrl);
603 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
604 #endif
605 p_ether_extended_cfg = (ether_extended_cfg_t *) p_instance_ctrl->p_ether_cfg->p_extend;
606
607 /* When the magic packet is detected. */
608 if (ETHER_MAGIC_PACKET_DETECTED == p_instance_ctrl->magic_packet)
609 {
610 p_instance_ctrl->magic_packet = ETHER_MAGIC_PACKET_NOT_DETECTED;
611
612 /* If a callback is provided, then call it with callback argument. */
613 if (NULL != p_instance_ctrl->p_callback)
614 {
615 callback_arg.channel = p_instance_ctrl->p_ether_cfg->channel;
616 callback_arg.event = ETHER_EVENT_WAKEON_LAN;
617 callback_arg.status_ecsr = 0;
618 callback_arg.status_eesr = 0;
619 callback_arg.p_context = p_instance_ctrl->p_ether_cfg->p_context;
620 ether_call_callback(p_instance_ctrl, &callback_arg);
621 }
622
623 /*
624 * After the close function is called, the open function is called
625 * to have to set ETHERC to a usual operational mode
626 * to usually communicate after magic packet is detected.
627 *//* back up previous_link_status */
628 previous_link_status = p_instance_ctrl->previous_link_status;
629
630 p_ether_cfg = p_instance_ctrl->p_ether_cfg;
631
632 err = R_ETHER_Close((ether_ctrl_t *) p_instance_ctrl);
633 ETHER_ERROR_RETURN(FSP_SUCCESS == err, err);
634
635 err = R_ETHER_Open((ether_ctrl_t *) p_instance_ctrl, (ether_cfg_t *) p_ether_cfg);
636 ETHER_ERROR_RETURN(FSP_SUCCESS == err, err);
637
638 /* restore previous_link_status */
639 p_instance_ctrl->previous_link_status = previous_link_status;
640 }
641
642 #if (ETHER_CFG_USE_LINKSTA == 0)
643 err = ether_link_status_check(p_instance_ctrl);
644
645 /* The state of the link status in PHY-LSI is confirmed and Link Up/Down is judged. */
646 if (FSP_SUCCESS == err)
647 {
648 /* When becoming Link up */
649 if (ETHER_PREVIOUS_LINK_STATUS_DOWN == p_instance_ctrl->previous_link_status)
650 {
651 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_LINK_UP;
652
653 /* Update Link status */
654 p_instance_ctrl->previous_link_status = ETHER_PREVIOUS_LINK_STATUS_UP;
655 }
656 }
657 else
658 {
659 /* When becoming Link down */
660 if (ETHER_PREVIOUS_LINK_STATUS_UP == p_instance_ctrl->previous_link_status)
661 {
662 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_LINK_DOWN;
663
664 /* Update Link status */
665 p_instance_ctrl->previous_link_status = ETHER_PREVIOUS_LINK_STATUS_DOWN;
666 }
667 }
668 #endif
669
670 /* When the link is up */
671 if (ETHER_LINK_CHANGE_LINK_UP == p_instance_ctrl->link_change)
672 {
673 #if (ETHER_CFG_USE_LINKSTA == 1)
674
675 /*
676 * The Link Up/Down is confirmed by the Link Status bit of PHY register1,
677 * because the LINK signal of PHY-LSI is used for LED indicator, and
678 * isn't used for notifing the Link Up/Down to external device.
679 */
680 err = ether_link_status_check(p_instance_ctrl);
681
682 if (FSP_SUCCESS == err)
683 {
684 #endif
685
686 /*
687 * The status of the LINK signal became "link-up" even if PHY-LSI did not detect "link-up"
688 * after a reset. To avoid this wrong detection, processing in R_ETHER_LinkProcess has been modified to
689 * clear the flag after link-up is confirmed in R_ETHER_CheckLink_ZC.
690 */
691 #if (ETHER_CFG_USE_LINKSTA == 1)
692 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_LINK_DOWN;
693 #elif (ETHER_CFG_USE_LINKSTA == 0)
694 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_NO_CHANGE;
695 #endif
696
697 /* Initialize the transmit and receive descriptor */
698 memset(p_ether_extended_cfg->p_rx_descriptors,
699 0x00,
700 sizeof(ether_instance_descriptor_t) * p_instance_ctrl->p_ether_cfg->num_rx_descriptors);
701 memset(p_ether_extended_cfg->p_tx_descriptors,
702 0x00,
703 sizeof(ether_instance_descriptor_t) * p_instance_ctrl->p_ether_cfg->num_tx_descriptors);
704
705 /* Initialize the Ethernet buffer */
706 ether_init_buffers(p_instance_ctrl);
707
708 p_instance_ctrl->link_establish_status = ETHER_LINK_ESTABLISH_STATUS_UP;
709
710 /*
711 * ETHERC and EDMAC are set after ETHERC and EDMAC are reset in software
712 * and sending and receiving is permitted.
713 */
714 ether_configure_mac(p_instance_ctrl,
715 p_instance_ctrl->p_ether_cfg->p_mac_address,
716 ETHER_NO_USE_MAGIC_PACKET_DETECT);
717 err = ether_do_link(p_instance_ctrl, ETHER_NO_USE_MAGIC_PACKET_DETECT);
718
719 if (FSP_SUCCESS == err)
720 {
721 /* If a callback is provided, then call it with callback argument. */
722 if (NULL != p_instance_ctrl->p_callback)
723 {
724 callback_arg.channel = p_instance_ctrl->p_ether_cfg->channel;
725 callback_arg.event = ETHER_EVENT_LINK_ON;
726 callback_arg.status_ecsr = 0;
727 callback_arg.status_eesr = 0;
728 callback_arg.p_context = p_instance_ctrl->p_ether_cfg->p_context;
729 ether_call_callback(p_instance_ctrl, &callback_arg);
730 }
731 }
732 else
733 {
734 /* When PHY auto-negotiation is not completed */
735 p_instance_ctrl->link_establish_status = ETHER_LINK_ESTABLISH_STATUS_DOWN;
736 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_LINK_UP;
737 }
738
739 #if (ETHER_CFG_USE_LINKSTA == 1)
740 }
741 else
742 {
743 /* no process */
744 }
745 #endif
746 }
747 /* When the link is down */
748 else if (ETHER_LINK_CHANGE_LINK_DOWN == p_instance_ctrl->link_change)
749 {
750 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_NO_CHANGE;
751
752 #if (ETHER_CFG_USE_LINKSTA == 1)
753
754 /*
755 * The Link Up/Down is confirmed by the Link Status bit of PHY register1,
756 * because the LINK signal of PHY-LSI is used for LED indicator, and
757 * isn't used for notifying the Link Up/Down to external device.
758 */
759 err = ether_link_status_check(p_instance_ctrl);
760 if (FSP_ERR_ETHER_ERROR_LINK == err)
761 {
762 #endif
763
764 p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
765
766 /* Disable receive and transmit. */
767 p_reg_etherc->ECMR_b.RE = 0;
768 p_reg_etherc->ECMR_b.TE = 0;
769
770 p_instance_ctrl->link_establish_status = ETHER_LINK_ESTABLISH_STATUS_DOWN;
771
772 /* If a callback is provided, then call it with callback argument. */
773 if (NULL != p_instance_ctrl->p_callback)
774 {
775 callback_arg.channel = p_instance_ctrl->p_ether_cfg->channel;
776 callback_arg.event = ETHER_EVENT_LINK_OFF;
777 callback_arg.status_ecsr = 0;
778 callback_arg.status_eesr = 0;
779 callback_arg.p_context = p_instance_ctrl->p_ether_cfg->p_context;
780 ether_call_callback(p_instance_ctrl, &callback_arg);
781 }
782
783 #if (ETHER_CFG_USE_LINKSTA == 1)
784 }
785 else
786 {
787 ; /* no operation */
788 }
789 #endif
790 }
791 else
792 {
793 ; /* no operation */
794 }
795
796 return err;
797 } /* End of function R_ETHER_LinkProcess() */
798
799 /********************************************************************************************************************//**
800 * @brief The setting of ETHERC is changed from normal sending and receiving mode to magic packet detection mode.
801 * Implements @ref ether_api_t::wakeOnLANEnable.
802 *
803 * @retval FSP_SUCCESS Processing completed successfully.
804 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block is NULL.
805 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
806 * @retval FSP_ERR_ETHER_ERROR_LINK Auto-negotiation is not completed, and reception is not enabled.
807 * @retval FSP_ERR_ETHER_PHY_ERROR_LINK Initialization of PHY-LSI failed.
808 ***********************************************************************************************************************/
R_ETHER_WakeOnLANEnable(ether_ctrl_t * const p_ctrl)809 fsp_err_t R_ETHER_WakeOnLANEnable (ether_ctrl_t * const p_ctrl)
810 {
811 fsp_err_t err = FSP_SUCCESS;
812 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
813
814 #if (ETHER_CFG_USE_LINKSTA == 1)
815 R_ETHERC0_Type * p_reg_etherc;
816 #endif
817
818 /* Check argument */
819 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
820 FSP_ASSERT(p_instance_ctrl);
821 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
822 #endif
823
824 /* When the Link up processing is not completed, return error */
825 ETHER_ERROR_RETURN(ETHER_LINK_ESTABLISH_STATUS_UP == p_instance_ctrl->link_establish_status,
826 FSP_ERR_ETHER_ERROR_LINK);
827
828 /* When the Link up processing is completed */
829 /* Change to the magic packet detection mode. */
830 ether_configure_mac(p_instance_ctrl, p_instance_ctrl->p_ether_cfg->p_mac_address, ETHER_USE_MAGIC_PACKET_DETECT);
831 err = ether_do_link(p_instance_ctrl, ETHER_USE_MAGIC_PACKET_DETECT);
832 if (FSP_SUCCESS == err)
833 {
834 #if (ETHER_CFG_USE_LINKSTA == 1)
835 p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
836
837 /* It is confirmed not to become Link down while changing the setting. */
838 if (ETHER_CFG_LINK_PRESENT == p_reg_etherc->PSR_b.LMON)
839 {
840 err = FSP_SUCCESS;
841 }
842 else
843 {
844 err = FSP_ERR_ETHER_ERROR_LINK;
845 }
846
847 #else
848
849 /* It is confirmed not to become Link down while changing the setting. */
850 err = ether_link_status_check(p_instance_ctrl);
851 #endif
852 }
853 else
854 {
855 err = FSP_ERR_ETHER_ERROR_LINK;
856 }
857
858 return err;
859 } /* End of function R_ETHER_WakeOnLANEnable() */
860
861 /********************************************************************************************************************//**
862 * @brief Receive Ethernet frame. Receives data to the location specified by the pointer to the receive buffer.
863 * In zero copy mode, the address of the receive buffer is returned.
864 * In non zero copy mode, the received data in the internal buffer is copied to the pointer passed by the argument.
865 * Implements @ref ether_api_t::read.
866 *
867 * @retval FSP_SUCCESS Processing completed successfully.
868 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block is NULL.
869 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
870 * @retval FSP_ERR_ETHER_ERROR_NO_DATA There is no data in receive buffer.
871 * @retval FSP_ERR_ETHER_ERROR_LINK Auto-negotiation is not completed, and reception is not enabled.
872 * @retval FSP_ERR_ETHER_ERROR_MAGIC_PACKET_MODE As a Magic Packet is being detected, transmission and reception
873 * is not enabled.
874 * @retval FSP_ERR_ETHER_ERROR_FILTERING Multicast Frame filter is enable, and Multicast Address Frame is
875 * received.
876 * @retval FSP_ERR_INVALID_POINTER Value of the pointer is NULL.
877 *
878 ***********************************************************************************************************************/
R_ETHER_Read(ether_ctrl_t * const p_ctrl,void * const p_buffer,uint32_t * const length_bytes)879 fsp_err_t R_ETHER_Read (ether_ctrl_t * const p_ctrl, void * const p_buffer, uint32_t * const length_bytes)
880 {
881 fsp_err_t err = FSP_SUCCESS;
882 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
883 uint8_t * p_read_buffer = NULL; /* Buffer location controlled by the Ethernet driver */
884 uint32_t received_size = ETHER_NO_DATA;
885 uint8_t ** pp_read_buffer = (uint8_t **) p_buffer;
886
887 /* Check argument */
888 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
889 FSP_ASSERT(p_instance_ctrl);
890 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
891 ETHER_ERROR_RETURN(NULL != p_buffer, FSP_ERR_INVALID_POINTER);
892 ETHER_ERROR_RETURN(NULL != length_bytes, FSP_ERR_INVALID_POINTER);
893 #endif
894
895 /* (1) Retrieve the receive buffer location controlled by the descriptor. */
896 /* When the Link up processing is not completed, return error */
897 ETHER_ERROR_RETURN(ETHER_LINK_ESTABLISH_STATUS_UP == p_instance_ctrl->link_establish_status,
898 FSP_ERR_ETHER_ERROR_LINK);
899
900 /* In case of detection mode of magic packet, return error. */
901 ETHER_ERROR_RETURN(0 == ether_check_magic_packet_detection_bit(p_instance_ctrl),
902 FSP_ERR_ETHER_ERROR_MAGIC_PACKET_MODE);
903
904 while (FSP_SUCCESS == err)
905 {
906 /* When receive data exists. */
907
908 if (ETHER_RD0_RACT != (p_instance_ctrl->p_rx_descriptor->status & ETHER_RD0_RACT))
909 {
910 /* Check multicast is detected when multicast frame filter is enabled */
911
912 if (ETHER_MULTICAST_DISABLE == p_instance_ctrl->p_ether_cfg->multicast)
913 {
914 if (ETHER_RD0_RFS7_RMAF == (p_instance_ctrl->p_rx_descriptor->status & ETHER_RD0_RFS7_RMAF))
915 {
916 /* The buffer is released at the multicast frame detect. */
917
918 err = R_ETHER_BufferRelease((ether_ctrl_t *) p_instance_ctrl);
919
920 if (FSP_SUCCESS == err)
921 {
922 err = FSP_ERR_ETHER_ERROR_FILTERING;
923 }
924
925 break;
926 }
927 }
928
929 if (ETHER_RD0_RFE == (p_instance_ctrl->p_rx_descriptor->status & ETHER_RD0_RFE))
930 {
931 /* The buffer is released at the error. */
932 err = R_ETHER_BufferRelease((ether_ctrl_t *) p_instance_ctrl);
933 }
934 else
935 {
936 /**
937 * Pass the pointer to received data to application. This is
938 * zero-copy operation.
939 */
940 p_read_buffer = p_instance_ctrl->p_rx_descriptor->p_buffer;
941
942 /* Get bytes received */
943 received_size =
944 (uint32_t) (p_instance_ctrl->p_rx_descriptor->size +
945 (uint16_t) p_instance_ctrl->p_ether_cfg->padding);
946 break;
947 }
948 }
949 else
950 {
951 break;
952 }
953 }
954
955 if (FSP_SUCCESS == err)
956 {
957 /* When there is data to receive */
958 if (received_size > ETHER_NO_DATA)
959 {
960 if (ETHER_ZEROCOPY_DISABLE == p_instance_ctrl->p_ether_cfg->zerocopy)
961 {
962 /* (2) Copy the data read from the receive buffer which is controlled
963 * by the descriptor to the buffer which is specified by the user (up to 1024 bytes). */
964 memcpy(p_buffer, p_read_buffer, received_size);
965
966 /* (3) Read the receive data from the receive buffer controlled by the descriptor,
967 * and then release the receive buffer. */
968 err = R_ETHER_BufferRelease((ether_ctrl_t *) p_instance_ctrl);
969 }
970 else
971 {
972 *pp_read_buffer = p_read_buffer;
973 }
974
975 *length_bytes = received_size;
976 }
977 /* When there is no data to receive */
978 else
979 {
980 err = FSP_ERR_ETHER_ERROR_NO_DATA;
981 }
982 }
983
984 return err;
985 } /* End of function R_ETHER_Read() */
986
987 /********************************************************************************************************************//**
988 * @brief Transmit Ethernet frame. Transmits data from the location specified by the pointer to the transmit
989 * buffer, with the data size equal to the specified frame length.
990 * In the non zero copy mode, transmits data after being copied to the internal buffer.
991 * Implements @ref ether_api_t::write.
992 *
993 * @retval FSP_SUCCESS Processing completed successfully.
994 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block is NULL.
995 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
996 * @retval FSP_ERR_ETHER_ERROR_LINK Auto-negotiation is not completed, and reception is not enabled.
997 * @retval FSP_ERR_ETHER_ERROR_MAGIC_PACKET_MODE As a Magic Packet is being detected, transmission and reception
998 * is not enabled.
999 * @retval FSP_ERR_ETHER_ERROR_TRANSMIT_BUFFER_FULL Transmit buffer is not empty.
1000 * @retval FSP_ERR_INVALID_POINTER Value of the pointer is NULL.
1001 * @retval FSP_ERR_INVALID_ARGUMENT Value of the send frame size is out of range.
1002 *
1003 ***********************************************************************************************************************/
R_ETHER_Write(ether_ctrl_t * const p_ctrl,void * const p_buffer,uint32_t const frame_length)1004 fsp_err_t R_ETHER_Write (ether_ctrl_t * const p_ctrl, void * const p_buffer, uint32_t const frame_length)
1005 {
1006 fsp_err_t err = FSP_SUCCESS;
1007 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
1008 R_ETHERC_EDMAC_Type * p_reg_edmac;
1009
1010 uint8_t * p_write_buffer;
1011 uint32_t write_buffer_size;
1012
1013 /* Check argument */
1014 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
1015 FSP_ASSERT(p_instance_ctrl);
1016 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
1017 ETHER_ERROR_RETURN(NULL != p_buffer, FSP_ERR_INVALID_POINTER);
1018 ETHER_ERROR_RETURN((ETHER_MINIMUM_FRAME_SIZE <= frame_length) && (ETHER_MAXIMUM_FRAME_SIZE >= frame_length),
1019 FSP_ERR_INVALID_ARGUMENT);
1020 #endif
1021
1022 /* When the Link up processing is not completed, return error */
1023 ETHER_ERROR_RETURN(ETHER_LINK_ESTABLISH_STATUS_UP == p_instance_ctrl->link_establish_status,
1024 FSP_ERR_ETHER_ERROR_LINK);
1025
1026 /* In case of detection mode of magic packet, return error. */
1027 ETHER_ERROR_RETURN(0 == ether_check_magic_packet_detection_bit(p_instance_ctrl),
1028 FSP_ERR_ETHER_ERROR_MAGIC_PACKET_MODE);
1029
1030 if (ETHER_ZEROCOPY_DISABLE == p_instance_ctrl->p_ether_cfg->zerocopy)
1031 {
1032 /* (1) Retrieve the transmit buffer location controlled by the descriptor. */
1033 err = ether_buffer_get(p_instance_ctrl, (void **) &p_write_buffer, &write_buffer_size);
1034
1035 /* Writing to the transmit buffer (buf) is enabled. */
1036 if (FSP_SUCCESS == err)
1037 {
1038 if (write_buffer_size < frame_length)
1039 {
1040 err = FSP_ERR_ETHER_ERROR_TRANSMIT_BUFFER_FULL; /* Transmit buffer overflow */
1041 }
1042 else
1043 {
1044 /* Write the transmit data to the transmit buffer. */
1045
1046 /* (2) Write the data to the transmit buffer controlled by the descriptor. */
1047 memcpy(p_write_buffer, p_buffer, frame_length);
1048 }
1049 }
1050 }
1051
1052 /* Writing to the transmit buffer (buf) is enabled. */
1053 if (FSP_SUCCESS == err)
1054 {
1055 /* (3) Enable the EDMAC to transmit data in the transmit buffer. */
1056 /* When the Link up processing is not completed, return error */
1057
1058 /* The data of the buffer is made active. */
1059 if (ETHER_ZEROCOPY_ENABLE == p_instance_ctrl->p_ether_cfg->zerocopy)
1060 {
1061 p_instance_ctrl->p_tx_descriptor->p_buffer = (uint8_t *) p_buffer;
1062 }
1063
1064 p_instance_ctrl->p_tx_descriptor->buffer_size = (uint16_t) frame_length;
1065 p_instance_ctrl->p_tx_descriptor->status &= (~(ETHER_TD0_TFP1 | ETHER_TD0_TFP0));
1066 p_instance_ctrl->p_tx_descriptor->status |= ((ETHER_TD0_TFP1 | ETHER_TD0_TFP0) | ETHER_TD0_TACT);
1067 p_instance_ctrl->p_tx_descriptor = p_instance_ctrl->p_tx_descriptor->p_next;
1068
1069 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
1070
1071 if (ETHER_EDMAC_EDTRR_TRANSMIT_REQUEST != p_reg_edmac->EDTRR)
1072 {
1073 /* Restart if stopped */
1074 p_reg_edmac->EDTRR = ETHER_EDMAC_EDTRR_TRANSMIT_REQUEST;
1075 }
1076 }
1077
1078 return err;
1079 } /* End of function R_ETHER_Write() */
1080
1081 /**********************************************************************************************************************//**
1082 * Provides status of Ethernet driver in the user provided pointer. Implements @ref ether_api_t::txStatusGet.
1083 *
1084 * @retval FSP_SUCCESS Transmit buffer address is stored in provided p_buffer_address.
1085 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block is NULL.
1086 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
1087 * @retval FSP_ERR_INVALID_POINTER p_status is NULL.
1088 * @retval FSP_ERR_NOT_FOUND Transmit buffer address has been overwritten in transmit descriptor.
1089 ***********************************************************************************************************************/
R_ETHER_TxStatusGet(ether_ctrl_t * const p_ctrl,void * const p_buffer_address)1090 fsp_err_t R_ETHER_TxStatusGet (ether_ctrl_t * const p_ctrl, void * const p_buffer_address)
1091 {
1092 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) p_ctrl;
1093 ether_extended_cfg_t * p_ether_extended_cfg;
1094 R_ETHERC_EDMAC_Type * p_reg_edmac;
1095 ether_instance_descriptor_t * p_descriptor;
1096 uint8_t ** p_sent_buffer_address = (uint8_t **) p_buffer_address;
1097 fsp_err_t err = FSP_ERR_NOT_FOUND;
1098
1099 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
1100 FSP_ASSERT(p_instance_ctrl);
1101 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
1102 ETHER_ERROR_RETURN(NULL != p_buffer_address, FSP_ERR_INVALID_POINTER);
1103 #endif
1104 p_ether_extended_cfg = (ether_extended_cfg_t *) p_instance_ctrl->p_ether_cfg->p_extend;
1105
1106 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
1107
1108 p_descriptor = (ether_instance_descriptor_t *) p_reg_edmac->TDFAR;
1109
1110 /* Descriptor is NULL, when no packet transmitted. */
1111 if (NULL != p_descriptor)
1112 {
1113 uint32_t num_tx_descriptors = p_instance_ctrl->p_ether_cfg->num_tx_descriptors;
1114 ether_instance_descriptor_t * p_tx_descriptors = p_ether_extended_cfg->p_tx_descriptors;
1115
1116 p_descriptor = (ether_instance_descriptor_t *) ((uint8_t *) p_descriptor - sizeof(ether_instance_descriptor_t));
1117
1118 if (p_descriptor < p_tx_descriptors)
1119 {
1120 p_descriptor = &p_tx_descriptors[num_tx_descriptors - 1];
1121 }
1122
1123 /* Check that the descriptor is not overridden. */
1124 if ((NULL != p_descriptor->p_buffer) && (ETHER_TD0_TACT != (p_descriptor->status & ETHER_TD0_TACT)))
1125 {
1126 *p_sent_buffer_address = p_descriptor->p_buffer;
1127 err = FSP_SUCCESS;
1128 }
1129 else
1130 {
1131 ;
1132 }
1133 }
1134
1135 return err;
1136 } /* End of function R_ETHER_VersionGet() */
1137
1138 /*******************************************************************************************************************//**
1139 * Updates the user callback with the option to provide memory for the callback argument structure.
1140 * Implements @ref ether_api_t::callbackSet.
1141 *
1142 * @retval FSP_SUCCESS Callback updated successfully.
1143 * @retval FSP_ERR_ASSERTION A required pointer is NULL.
1144 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
1145 * @retval FSP_ERR_NO_CALLBACK_MEMORY p_callback is non-secure and p_callback_memory is either secure or NULL.
1146 **********************************************************************************************************************/
R_ETHER_CallbackSet(ether_ctrl_t * const p_api_ctrl,void (* p_callback)(ether_callback_args_t *),void const * const p_context,ether_callback_args_t * const p_callback_memory)1147 fsp_err_t R_ETHER_CallbackSet (ether_ctrl_t * const p_api_ctrl,
1148 void ( * p_callback)(ether_callback_args_t *),
1149 void const * const p_context,
1150 ether_callback_args_t * const p_callback_memory)
1151 {
1152 ether_instance_ctrl_t * p_ctrl = (ether_instance_ctrl_t *) p_api_ctrl;
1153
1154 #if ETHER_CFG_PARAM_CHECKING_ENABLE
1155 FSP_ASSERT(p_ctrl);
1156 FSP_ASSERT(p_callback);
1157 FSP_ERROR_RETURN(ETHER_OPEN == p_ctrl->open, FSP_ERR_NOT_OPEN);
1158 #endif
1159
1160 #if BSP_TZ_SECURE_BUILD && BSP_FEATURE_ETHER_SUPPORTS_TZ_SECURE
1161
1162 /* Get security state of p_callback */
1163 bool callback_is_secure =
1164 (NULL == cmse_check_address_range((void *) p_callback, sizeof(void *), CMSE_AU_NONSECURE));
1165
1166 #if ETHER_CFG_PARAM_CHECKING_ENABLE
1167
1168 /* In secure projects, p_callback_memory must be provided in non-secure space if p_callback is non-secure */
1169 ether_callback_args_t * const p_callback_memory_checked = cmse_check_pointed_object(p_callback_memory,
1170 CMSE_AU_NONSECURE);
1171 FSP_ERROR_RETURN(callback_is_secure || (NULL != p_callback_memory_checked), FSP_ERR_NO_CALLBACK_MEMORY);
1172 #endif
1173 #endif
1174
1175 /* Store callback and context */
1176 #if BSP_TZ_SECURE_BUILD && BSP_FEATURE_ETHER_SUPPORTS_TZ_SECURE
1177 p_ctrl->p_callback = callback_is_secure ? p_callback :
1178 (void (*)(ether_callback_args_t *))cmse_nsfptr_create(p_callback);
1179 #else
1180 p_ctrl->p_callback = p_callback;
1181 #endif
1182 p_ctrl->p_context = p_context;
1183 p_ctrl->p_callback_memory = p_callback_memory;
1184
1185 return FSP_SUCCESS;
1186 }
1187
1188 /*******************************************************************************************************************//**
1189 * @} (end addtogroup ETHER)
1190 **********************************************************************************************************************/
1191
1192 /***********************************************************************************************************************
1193 * Private Functions
1194 **********************************************************************************************************************/
1195
1196 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
1197
1198 /*******************************************************************************************************************//**
1199 * @brief Parameter error check function for open.
1200 *
1201 * @param[in] p_instance_ctrl Pointer to the control block for the channel
1202 * @param[in] p_cfg Pointer to the configuration structure specific to UART mode
1203 *
1204 * @retval FSP_SUCCESS No parameter error found
1205 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block or configuration structure is NULL
1206 * @retval FSP_ERR_INVALID_CHANNEL Invalid channel number is given.
1207 * @retval FSP_ERR_INVALID_POINTER Pointer to MAC address is NULL.
1208 * @retval FSP_ERR_INVALID_ARGUMENT Irq number lower then 0.
1209 **********************************************************************************************************************/
ether_open_param_check(ether_instance_ctrl_t const * const p_instance_ctrl,ether_cfg_t const * const p_cfg)1210 static fsp_err_t ether_open_param_check (ether_instance_ctrl_t const * const p_instance_ctrl,
1211 ether_cfg_t const * const p_cfg)
1212 {
1213 FSP_ASSERT(p_instance_ctrl);
1214 ETHER_ERROR_RETURN((NULL != p_cfg), FSP_ERR_INVALID_POINTER);
1215 ETHER_ERROR_RETURN((NULL != p_cfg->p_mac_address), FSP_ERR_INVALID_POINTER);
1216 ETHER_ERROR_RETURN((NULL != p_cfg->p_extend), FSP_ERR_INVALID_POINTER);
1217 ETHER_ERROR_RETURN((BSP_FEATURE_ETHER_MAX_CHANNELS > p_cfg->channel), FSP_ERR_INVALID_CHANNEL);
1218 ETHER_ERROR_RETURN((0 <= p_cfg->irq), FSP_ERR_INVALID_ARGUMENT);
1219 ETHER_ERROR_RETURN((p_cfg->padding <= ETHER_PADDING_3BYTE), FSP_ERR_INVALID_ARGUMENT);
1220
1221 if (p_cfg->padding != ETHER_PADDING_DISABLE)
1222 {
1223 ETHER_ERROR_RETURN((p_cfg->padding_offset <= ETHER_MAXIMUM_PADDING_OFFSET), FSP_ERR_INVALID_ARGUMENT);
1224 }
1225
1226 if (p_cfg->zerocopy == ETHER_ZEROCOPY_DISABLE)
1227 {
1228 ETHER_ERROR_RETURN((p_cfg->pp_ether_buffers != NULL), FSP_ERR_INVALID_ARGUMENT);
1229 }
1230
1231 return FSP_SUCCESS;
1232 }
1233
1234 #endif
1235
1236 /***********************************************************************************************************************
1237 * Function Name: ether_reset_mac
1238 * Description : The EDMAC and EtherC are reset through the software reset.
1239 * Arguments : channel -
1240 * ETHERC channel number
1241 * Return Value : none
1242 ***********************************************************************************************************************/
ether_reset_mac(R_ETHERC_EDMAC_Type * const p_reg)1243 static void ether_reset_mac (R_ETHERC_EDMAC_Type * const p_reg)
1244 {
1245 p_reg->EDMR_b.SWR = 1;
1246
1247 /*
1248 * Waiting time until the initialization of ETHERC and EDMAC is completed is 64 cycles
1249 * in the clock conversion of an internal bus of EDMAC.
1250 */
1251 R_BSP_SoftwareDelay(ETHER_ETHERC_INITIALIZATION_WAIT_CYCLE * BSP_DELAY_UNITS_SECONDS / SystemCoreClock + 1,
1252 BSP_DELAY_UNITS_MICROSECONDS);
1253 } /* End of function ether_reset_mac() */
1254
1255 /***********************************************************************************************************************
1256 * Function Name: ether_init_descriptors
1257 * Description : The EDMAC descriptors and the driver buffers are initialized.
1258 * Arguments : channel -
1259 * ETHERC channel number
1260 * Return Value : none
1261 ***********************************************************************************************************************/
ether_init_descriptors(ether_instance_ctrl_t * const p_instance_ctrl)1262 static void ether_init_descriptors (ether_instance_ctrl_t * const p_instance_ctrl)
1263 {
1264 ether_instance_descriptor_t * p_descriptor = NULL;
1265 uint32_t i;
1266 ether_extended_cfg_t * p_ether_extended_cfg = (ether_extended_cfg_t *) p_instance_ctrl->p_ether_cfg->p_extend;
1267
1268 /* Initialize the receive descriptors */
1269 for (i = 0; i < p_instance_ctrl->p_ether_cfg->num_rx_descriptors; i++)
1270 {
1271 p_descriptor = &p_ether_extended_cfg->p_rx_descriptors[i];
1272 p_descriptor->buffer_size = (uint16_t) p_instance_ctrl->p_ether_cfg->ether_buffer_size;
1273 p_descriptor->size = 0;
1274 p_descriptor->p_next = &p_ether_extended_cfg->p_rx_descriptors[(i + 1)];
1275
1276 if (NULL != p_instance_ctrl->p_ether_cfg->pp_ether_buffers)
1277 {
1278 p_descriptor->p_buffer = p_instance_ctrl->p_ether_cfg->pp_ether_buffers[i];
1279 p_descriptor->status = ETHER_RD0_RACT;
1280 }
1281 else
1282 {
1283 p_descriptor->p_buffer = NULL;
1284 }
1285 }
1286
1287 if (NULL != p_descriptor)
1288 {
1289 /* The last descriptor points back to the start */
1290 p_descriptor->status |= ETHER_RD0_RDLE;
1291 p_descriptor->p_next = &p_ether_extended_cfg->p_rx_descriptors[0];
1292
1293 /* Initialize application receive descriptor pointer */
1294 p_instance_ctrl->p_rx_descriptor = &p_ether_extended_cfg->p_rx_descriptors[0];
1295 }
1296
1297 /* Initialize the transmit descriptors */
1298 for (i = 0; i < p_instance_ctrl->p_ether_cfg->num_tx_descriptors; i++)
1299 {
1300 p_descriptor = &p_ether_extended_cfg->p_tx_descriptors[i];
1301 p_descriptor->buffer_size = 1; /* Set a value equal to or greater than 1. (reference to UMH)
1302 * When transmitting data, the value of size is set to the function argument
1303 * R_ETHER_Write. */
1304 p_descriptor->size = 0; /* Reserved : The write value should be 0. (reference to UMH) */
1305 p_descriptor->status = 0;
1306 p_descriptor->p_next = &p_ether_extended_cfg->p_tx_descriptors[(i + 1)];
1307
1308 if ((ETHER_ZEROCOPY_DISABLE == p_instance_ctrl->p_ether_cfg->zerocopy) &&
1309 (NULL != p_instance_ctrl->p_ether_cfg->pp_ether_buffers))
1310 {
1311 p_descriptor->p_buffer =
1312 p_instance_ctrl->p_ether_cfg->pp_ether_buffers[(p_instance_ctrl->p_ether_cfg->num_rx_descriptors + i)];
1313 }
1314 else
1315 {
1316 p_descriptor->p_buffer = NULL;
1317 }
1318 }
1319
1320 if (NULL != p_descriptor)
1321 {
1322 /* The last descriptor points back to the start */
1323 p_descriptor->status |= ETHER_TD0_TDLE;
1324 p_descriptor->p_next = &p_ether_extended_cfg->p_tx_descriptors[0];
1325
1326 /* Initialize application transmit descriptor pointer */
1327 p_instance_ctrl->p_tx_descriptor = &p_ether_extended_cfg->p_tx_descriptors[0];
1328 }
1329 } /* End of function ether_init_descriptors() */
1330
1331 /***********************************************************************************************************************
1332 * Function Name: ether_init_buffers
1333 * Description : The driver buffers are initialized.
1334 * Arguments : p_instance_ctrl -
1335 * ETHERC control block.
1336 * Return Value : none
1337 ***********************************************************************************************************************/
ether_init_buffers(ether_instance_ctrl_t * const p_instance_ctrl)1338 void ether_init_buffers (ether_instance_ctrl_t * const p_instance_ctrl)
1339 {
1340 uint32_t i;
1341 uint32_t buffer_num;
1342
1343 if (NULL != p_instance_ctrl->p_ether_cfg->pp_ether_buffers)
1344 {
1345 if (ETHER_ZEROCOPY_DISABLE == p_instance_ctrl->p_ether_cfg->zerocopy)
1346 {
1347 buffer_num =
1348 (uint32_t) (p_instance_ctrl->p_ether_cfg->num_tx_descriptors +
1349 p_instance_ctrl->p_ether_cfg->num_rx_descriptors);
1350 }
1351 else
1352 {
1353 buffer_num = (uint32_t) p_instance_ctrl->p_ether_cfg->num_rx_descriptors;
1354 }
1355
1356 for (i = 0; i < buffer_num; i++)
1357 {
1358 memset(p_instance_ctrl->p_ether_cfg->pp_ether_buffers[i],
1359 0x00,
1360 p_instance_ctrl->p_ether_cfg->ether_buffer_size);
1361 }
1362 }
1363 } /* End of function ether_init_buffers() */
1364
1365 /********************************************************************************************************************//**
1366 * @brief Get Points to the buffer pointer used by the stack.
1367 * @param[in] p_instance_ctrl Ethernet driver control block.
1368 * @param[out] p_buffer Pointer to location to store the buffer pointer
1369 * @param[out] p_buffer_size Pointer to location to store the buffer size
1370 * @retval FSP_SUCCESS Processing completed successfully.
1371 * @retval FSP_ERR_ETHER_ERROR_TRANSMIT_BUFFER_FULL Transmit buffer is not empty.
1372 *
1373 ***********************************************************************************************************************/
ether_buffer_get(ether_instance_ctrl_t * const p_instance_ctrl,void ** const p_buffer,uint32_t * p_buffer_size)1374 static fsp_err_t ether_buffer_get (ether_instance_ctrl_t * const p_instance_ctrl,
1375 void ** const p_buffer,
1376 uint32_t * p_buffer_size)
1377 {
1378 fsp_err_t err = FSP_SUCCESS;
1379
1380 /* When the Link up processing is completed */
1381 /* All transmit buffers are full */
1382 if (ETHER_TD0_TACT == (p_instance_ctrl->p_tx_descriptor->status & ETHER_TD0_TACT))
1383 {
1384 err = FSP_ERR_ETHER_ERROR_TRANSMIT_BUFFER_FULL;
1385 }
1386 else
1387 {
1388 /* Give application another buffer to work with */
1389 (*p_buffer) = p_instance_ctrl->p_tx_descriptor->p_buffer;
1390 (*p_buffer_size) = p_instance_ctrl->p_ether_cfg->ether_buffer_size;
1391 err = FSP_SUCCESS;
1392 }
1393
1394 return err;
1395 } /* End of function ether_buffer_get() */
1396
1397 /***********************************************************************************************************************
1398 * Function Name: ether_config_ethernet
1399 * Description : Configure the Ethernet Controller (EtherC) and the Ethernet
1400 * Direct Memory Access controller (EDMAC).
1401 * Arguments : channel -
1402 * ETHERC channel number
1403 * mode -
1404 * The operational mode is specified.
1405 * NO_USE_MAGIC_PACKET_DETECT (0) - Communicate mode usually
1406 * USE_MAGIC_PACKET_DETECT (1) - Magic packet detection mode
1407 * Return Value : none
1408 ***********************************************************************************************************************/
ether_config_ethernet(ether_instance_ctrl_t const * const p_instance_ctrl,const uint8_t mode)1409 static void ether_config_ethernet (ether_instance_ctrl_t const * const p_instance_ctrl, const uint8_t mode)
1410 {
1411 R_ETHERC0_Type * p_reg_etherc;
1412 R_ETHERC_EDMAC_Type * p_reg_edmac;
1413
1414 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
1415
1416 /* Check argument */
1417 if ((NULL == p_instance_ctrl) || (ETHER_OPEN != p_instance_ctrl->open))
1418 {
1419 return;
1420 }
1421 #endif
1422
1423 p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
1424 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
1425
1426 /* Magic packet detection mode */
1427 if (ETHER_USE_MAGIC_PACKET_DETECT == mode)
1428 {
1429 #if (ETHER_CFG_USE_LINKSTA == 1)
1430 p_reg_etherc->ECSIPR = (ETHER_ETHERC_INTERRUPT_ENABLE_LCHNG | ETHER_ETHERC_INTERRUPT_ENABLE_MPD);
1431 #elif (ETHER_CFG_USE_LINKSTA == 0)
1432 p_reg_etherc->ECSIPR_b.MPDIP = 1;
1433 #endif
1434 p_reg_edmac->EESIPR_b.ECIIP = 1;
1435 }
1436 /* Normal mode */
1437 else
1438 {
1439 #if (ETHER_CFG_USE_LINKSTA == 1)
1440
1441 /* LINK Signal Change Interrupt Enable */
1442 p_reg_etherc->ECSR_b.LCHNG = 1;
1443 p_reg_etherc->ECSIPR_b.LCHNGIP = 1;
1444 #endif
1445 p_reg_edmac->EESIPR_b.ECIIP = 1;
1446
1447 /* Frame receive interrupt and frame transmit end interrupt */
1448 p_reg_edmac->EESIPR_b.FRIP = 1; /* Enable the frame receive interrupt. */
1449 p_reg_edmac->EESIPR_b.TCIP = 1; /* Enable the frame transmit end interrupt. */
1450 }
1451
1452 /* Ethernet length 1514bytes + CRC and intergap is 96-bit time */
1453 p_reg_etherc->RFLR = ETHER_ETHERC_RFLR_DEFAULT_VALUE; /* Ethernet length (1514bytes) + CRC(4byte) */
1454 p_reg_etherc->IPGR = ETHER_ETHERC_IPGR_DEFAULT_VALUE; /* Interpacket Gap is 96-bit time */
1455
1456 /* Continuous reception number of Broadcast frame */
1457 p_reg_etherc->BCFRR = p_instance_ctrl->p_ether_cfg->broadcast_filter;
1458
1459 #if ((defined(__GNUC__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || (defined(__ARMCC_VERSION) && \
1460 !defined(__ARM_BIG_ENDIAN)) || (defined(__ICCARM__) && (__LITTLE_ENDIAN__)))
1461
1462 /* Set little endian mode */
1463 p_reg_edmac->EDMR_b.DE = 1;
1464 #endif
1465
1466 /* Initialize Rx descriptor list address */
1467 /* Casting the pointer to a uint32_t type is valid because the Renesas Compiler uses 4 bytes per pointer. */
1468 p_reg_edmac->RDLAR = (uint32_t) p_instance_ctrl->p_rx_descriptor;
1469
1470 /* Initialize Tx descriptor list address */
1471 /* Casting the pointer to a uint32_t type is valid because the Renesas Compiler uses 4 bytes per pointer. */
1472 p_reg_edmac->TDLAR = (uint32_t) p_instance_ctrl->p_tx_descriptor;
1473
1474 if (ETHER_MULTICAST_DISABLE == p_instance_ctrl->p_ether_cfg->multicast)
1475 {
1476 /* Reflect the EESR.RMAF bit status in the RD0.RFS bit in the receive descriptor */
1477 p_reg_edmac->TRSCER = ETHER_EDMAC_TRSCER_MULTICAST_DISABLE;
1478 }
1479 else
1480 {
1481 /* Don't reflect the EESR.RMAF bit status in the RD0.RFS bit in the receive descriptor */
1482 p_reg_edmac->TRSCER = ETHER_EDMAC_TRSCER_MULTICAST_ENABLE;
1483 }
1484
1485 /* Threshold of Tx_FIFO */
1486 /* To prevent a transmit underflow, setting the initial value (store and forward modes) is recommended. */
1487 p_reg_edmac->TFTR = ETHER_EDMAC_TFTR_STORE_AND_FORWARD_MODE;
1488
1489 p_reg_edmac->FDR = BSP_FEATURE_ETHER_FIFO_DEPTH;
1490
1491 /* Configure receiving method
1492 * b0 RNR - Receive Request Bit Reset - Continuous reception of multiple frames is possible.
1493 * b31:b1 Reserved set to 0
1494 */
1495 p_reg_edmac->RMCR = ETHER_EDMAC_RMCR_MULTIPLE_FRAMES_ENABLE;
1496 } /* End of function ether_config_ethernet() */
1497
1498 /***********************************************************************************************************************
1499 * Function Name: ether_pause_resolution
1500 * Description : Determines PAUSE frame generation and handling. Uses
1501 * the resolution Table 28B-3 of IEEE 802.3-2008.
1502 * Arguments : local_ability -
1503 * local PAUSE capability (2 least significant bits)
1504 * partner_ability -
1505 * link partner PAUSE capability (2 least significant bits)
1506 * *ptx_pause -
1507 * pointer to location to store the result of the table lookup for transmit
1508 * PAUSE. 1 is enable, 0 is disable.
1509 * *prx_pause -
1510 * pointer to location to store the result of the table lookup for receive
1511 * PAUSE. 1 is enable, 0 is disable.
1512 * Return Value : none
1513 ***********************************************************************************************************************/
ether_pause_resolution(uint32_t const local_ability,uint32_t const partner_ability,uint32_t * ptx_pause,uint32_t * prx_pause)1514 static void ether_pause_resolution (uint32_t const local_ability,
1515 uint32_t const partner_ability,
1516 uint32_t * ptx_pause,
1517 uint32_t * prx_pause)
1518 {
1519 uint32_t i;
1520 uint32_t ability_compare;
1521
1522 /*
1523 * Arrange the bits so that they correspond to the Table 28B-3
1524 * of the IEEE 802.3 values.
1525 */
1526 ability_compare =
1527 (uint32_t) (((local_ability & ETHER_LINK_RESOLUTION_ABILITY_MASK) <<
1528 ETHER_LINK_RESOLUTION_LOCAL_ABILITY_BITSHIFT) |
1529 (partner_ability & ETHER_LINK_RESOLUTION_ABILITY_MASK));
1530
1531 /* Walk through the look up table */
1532 for (i = 0; i < ETHER_PAUSE_TABLE_ENTRIES; i++)
1533 {
1534 if ((ability_compare & pause_resolution[i].mask) == pause_resolution[i].value)
1535 {
1536 (*ptx_pause) = pause_resolution[i].transmit;
1537 (*prx_pause) = pause_resolution[i].receive;
1538
1539 return;
1540 }
1541 }
1542 } /* End of function ether_pause_resolution() */
1543
1544 /***********************************************************************************************************************
1545 * Function Name: ether_configure_mac
1546 * Description : Software reset is executed, and ETHERC and EDMAC are configured.
1547 * Arguments : channel -
1548 * ETHERC channel number
1549 * mac_addr -
1550 * The MAC address of ETHERC
1551 * mode -
1552 * The operational mode is specified.
1553 * NO_USE_MAGIC_PACKET_DETECT (0) - Communicate mode usually
1554 * USE_MAGIC_PACKET_DETECT (1) - Magic packet detection mode
1555 * Return Value : none
1556 ***********************************************************************************************************************/
ether_configure_mac(ether_instance_ctrl_t * const p_instance_ctrl,const uint8_t mac_addr[],const uint8_t mode)1557 void ether_configure_mac (ether_instance_ctrl_t * const p_instance_ctrl,
1558 const uint8_t mac_addr[],
1559 const uint8_t mode)
1560 {
1561 R_ETHERC0_Type * p_reg_etherc;
1562 uint32_t mac_h;
1563 uint32_t mac_l;
1564
1565 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
1566
1567 /* Check argument */
1568 if ((NULL == p_instance_ctrl) || (ETHER_OPEN != p_instance_ctrl->open))
1569 {
1570 return;
1571 }
1572 #endif
1573
1574 p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
1575
1576 /* Software reset */
1577 ether_reset_mac(p_instance_ctrl->p_reg_edmac);
1578
1579 /* Setting the padding function */
1580 ether_configure_padding(p_instance_ctrl);
1581
1582 /* Set MAC address */
1583 mac_h = (((((uint32_t) mac_addr[0] << 24) | ((uint32_t) mac_addr[1] << 16)) | ((uint32_t) mac_addr[2] << 8)) |
1584 (uint32_t) mac_addr[3]);
1585
1586 mac_l = (((uint32_t) mac_addr[4] << 8) | (uint32_t) mac_addr[5]);
1587
1588 p_reg_etherc->MAHR = mac_h;
1589 p_reg_etherc->MALR = mac_l;
1590
1591 /* Initialize receive and transmit descriptors */
1592 ether_init_descriptors(p_instance_ctrl);
1593
1594 /* Perform reset of hardware interface configuration */
1595 ether_config_ethernet(p_instance_ctrl, mode);
1596 } /* End of function ether_configure_mac() */
1597
1598 /********************************************************************************************************************//**
1599 * @brief Determines the partner PHY capability through auto-negotiation process. The link abilities
1600 * are handled to determine duplex, speed and flow control (PAUSE frames).
1601 *
1602 * @param[in] p_instance_ctrl Pointer to the control block for the channel
1603 * @param[in] mode The operational mode is specified.
1604 * NO_USE_MAGIC_PACKET_DETECT (0) - Communicate mode usually
1605 * USE_MAGIC_PACKET_DETECT (1) - Magic packet detection mode
1606 * @retval FSP_SUCCESS Processing completed successfully.
1607 * @retval FSP_ERR_ASSERTION Pointer to ETHER control block or configuration structure is NULL.
1608 * @retval FSP_ERR_NOT_OPEN The control block has not been opened.
1609 * @retval FSP_ERR_ETHER_ERROR_LINK Auto-negotiation of PHY-LSI is not completed
1610 * or result of Auto-negotiation is abnormal.
1611 *
1612 ***********************************************************************************************************************/
ether_do_link(ether_instance_ctrl_t * const p_instance_ctrl,const uint8_t mode)1613 fsp_err_t ether_do_link (ether_instance_ctrl_t * const p_instance_ctrl, const uint8_t mode)
1614 {
1615 fsp_err_t err;
1616 R_ETHERC0_Type * p_reg_etherc;
1617 R_ETHERC_EDMAC_Type * p_reg_edmac;
1618
1619 uint32_t link_speed_duplex = 0;
1620 uint32_t local_pause_bits = 0;
1621 uint32_t partner_pause_bits = 0;
1622 uint32_t transmit_pause_set = 0;
1623 uint32_t receive_pause_set = 0;
1624 uint32_t full_duplex = 0;
1625 fsp_err_t link_result;
1626
1627 #if (ETHER_CFG_PARAM_CHECKING_ENABLE)
1628 FSP_ASSERT(p_instance_ctrl);
1629 ETHER_ERROR_RETURN(ETHER_OPEN == p_instance_ctrl->open, FSP_ERR_NOT_OPEN);
1630 #endif
1631
1632 p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
1633 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
1634
1635 #if !ETHER_CFG_USE_CUSTOM_PHY_DRIVER
1636 /* Set the link status */
1637 link_result = p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_api->linkPartnerAbilityGet(
1638 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_ctrl,
1639 &link_speed_duplex,
1640 &local_pause_bits,
1641 &partner_pause_bits);
1642 #else
1643 link_result = FSP_SUCCESS;
1644 link_speed_duplex = p_instance_ctrl->link_speed_duplex;
1645 #endif
1646
1647 if (FSP_SUCCESS == link_result)
1648 {
1649 switch (link_speed_duplex)
1650 {
1651 /* Half duplex link */
1652 case ETHER_PHY_LINK_SPEED_100H:
1653 {
1654 p_reg_etherc->ECMR_b.DM = 0;
1655 p_reg_etherc->ECMR_b.RTM = 1;
1656 err = FSP_SUCCESS;
1657 break;
1658 }
1659
1660 case ETHER_PHY_LINK_SPEED_10H:
1661 {
1662 p_reg_etherc->ECMR_b.DM = 0;
1663 p_reg_etherc->ECMR_b.RTM = 0;
1664 err = FSP_SUCCESS;
1665 break;
1666 }
1667
1668 /* Full duplex link */
1669 case ETHER_PHY_LINK_SPEED_100F:
1670 {
1671 p_reg_etherc->ECMR_b.DM = 1;
1672 p_reg_etherc->ECMR_b.RTM = 1;
1673 full_duplex = 1;
1674 err = FSP_SUCCESS;
1675 break;
1676 }
1677
1678 case ETHER_PHY_LINK_SPEED_10F:
1679 {
1680 p_reg_etherc->ECMR_b.DM = 1;
1681 p_reg_etherc->ECMR_b.RTM = 0;
1682 full_duplex = 1;
1683 err = FSP_SUCCESS;
1684 break;
1685 }
1686
1687 default:
1688 {
1689 err = FSP_ERR_ETHER_ERROR_LINK;
1690 break;
1691 }
1692 }
1693
1694 /* At the communicate mode usually */
1695 if (FSP_SUCCESS == err)
1696 {
1697 if (ETHER_NO_USE_MAGIC_PACKET_DETECT == mode)
1698 {
1699 /* When pause frame is used */
1700 if ((full_duplex) && (ETHER_FLOW_CONTROL_ENABLE == p_instance_ctrl->p_ether_cfg->flow_control))
1701 {
1702 /* Set automatic PAUSE for 512 bit-time */
1703 p_reg_etherc->APR = ETHER_ETHERC_APR_MAXIMUM_VALUE;
1704
1705 /* Set unlimited retransmit of PAUSE frames */
1706 p_reg_etherc->TPAUSER = 0;
1707
1708 /* PAUSE flow control FIFO settings. */
1709 p_reg_edmac->FCFTR = ETHER_ETHERC_FCFTR_MINIMUM_VALUE;
1710
1711 /* Control of a PAUSE frame whose TIME parameter value is 0 is enabled. */
1712 p_reg_etherc->ECMR_b.ZPF = 1;
1713
1714 /**
1715 * Enable PAUSE for full duplex link depending on
1716 * the pause resolution results
1717 */
1718 ether_pause_resolution(local_pause_bits, partner_pause_bits, &transmit_pause_set,
1719 &receive_pause_set);
1720
1721 if (ETHER_PAUSE_XMIT_ON == transmit_pause_set)
1722 {
1723 /* Enable automatic PAUSE frame transmission */
1724 p_reg_etherc->ECMR_b.TXF = 1;
1725 }
1726 else
1727 {
1728 /* Disable automatic PAUSE frame transmission */
1729 p_reg_etherc->ECMR_b.TXF = 0;
1730 }
1731
1732 if (ETHER_PAUSE_RECV_ON == receive_pause_set)
1733 {
1734 /* Enable reception of PAUSE frames */
1735 p_reg_etherc->ECMR_b.RXF = 1;
1736 }
1737 else
1738 {
1739 /* Disable reception of PAUSE frames */
1740 p_reg_etherc->ECMR_b.RXF = 0;
1741 }
1742 }
1743 /* When pause frame is not used */
1744 else
1745 {
1746 /* Disable PAUSE for half duplex link */
1747 p_reg_etherc->ECMR_b.TXF = 0;
1748 p_reg_etherc->ECMR_b.RXF = 0;
1749 }
1750
1751 /* Set the promiscuous mode bit */
1752 p_reg_etherc->ECMR_b.PRM = p_instance_ctrl->p_ether_cfg->promiscuous;
1753
1754 /* Enable receive and transmit. */
1755 p_reg_etherc->ECMR_b.RE = 1;
1756 p_reg_etherc->ECMR_b.TE = 1;
1757
1758 /* Enable EDMAC receive */
1759 p_reg_edmac->EDRRR = 0x1;
1760 }
1761 /* At the magic packet detection mode */
1762 else
1763 {
1764 /* The magic packet detection is permitted. */
1765 p_reg_etherc->ECMR_b.MPDE = 1;
1766
1767 /* Because data is not transmitted for the magic packet detection waiting,
1768 * only the reception is permitted. */
1769 p_reg_etherc->ECMR_b.RE = 1;
1770
1771 /*
1772 * The reception function of EDMAC keep invalidity
1773 * because the receive data don't need to be read when the magic packet detection mode.
1774 */
1775 }
1776 }
1777 }
1778 else
1779 {
1780 err = FSP_ERR_ETHER_ERROR_LINK;
1781 }
1782
1783 return err;
1784 } /* End of function ether_do_link() */
1785
1786 /***********************************************************************************************************************
1787 * Function Name: ether_check_magic_packet_detection_bit
1788 * Description :
1789 * Arguments : ether_instance_ctrl_t const * const p_instance_ctrl
1790 * Return Value : 1: Magic Packet detection is enabled.
1791 * 0: Magic Packet detection is disabled.
1792 ***********************************************************************************************************************/
ether_check_magic_packet_detection_bit(ether_instance_ctrl_t const * const p_instance_ctrl)1793 static uint8_t ether_check_magic_packet_detection_bit (ether_instance_ctrl_t const * const p_instance_ctrl)
1794 {
1795 R_ETHERC0_Type * p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
1796 uint8_t ret = 0;
1797
1798 /* The MPDE bit can be referred to only when ETHERC operates. */
1799 if ((1 == p_reg_etherc->ECMR_b.MPDE))
1800 {
1801 ret = 1;
1802 }
1803 else
1804 {
1805 ret = 0;
1806 }
1807
1808 return ret;
1809 } /* End of function ether_check_magic_packet_detection_bit() */
1810
1811 /*******************************************************************************************************************//**
1812 * @brief Verifies the Etherent link is up or not.
1813 *
1814 * @param[in] p_instance_ctrl Pointer to the control block for the channel
1815 *
1816 * @retval FSP_SUCCESS: Link is up
1817 * @retval FSP_ERR_ETHER_ERROR_LINK: Link is down
1818 * @retval FSP_ERR_ETHER_PHY_ERROR_LINK Initialization of PHY-LSI failed.
1819 **********************************************************************************************************************/
ether_link_status_check(ether_instance_ctrl_t const * const p_instance_ctrl)1820 static fsp_err_t ether_link_status_check (ether_instance_ctrl_t const * const p_instance_ctrl)
1821 {
1822 fsp_err_t err;
1823 fsp_err_t link_status;
1824
1825 #if !ETHER_CFG_USE_CUSTOM_PHY_DRIVER
1826 link_status = p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_api->linkStatusGet(
1827 p_instance_ctrl->p_ether_cfg->p_ether_phy_instance->p_ctrl);
1828 #else
1829 link_status = FSP_SUCCESS;
1830 #endif
1831
1832 if (FSP_ERR_ETHER_PHY_ERROR_LINK == link_status)
1833 {
1834 /* Link is down */
1835 err = FSP_ERR_ETHER_ERROR_LINK;
1836 }
1837 else
1838 {
1839 /* Link is up */
1840 err = FSP_SUCCESS;
1841 }
1842
1843 return err;
1844 } /* End of function ether_link_status_check() */
1845
1846 /*******************************************************************************************************************//**
1847 * Calls user callback.
1848 *
1849 * @param[in] p_instance_ctrl Pointer to ether instance control block
1850 * @param[in] p_callback_args Pointer to callback args
1851 **********************************************************************************************************************/
ether_call_callback(ether_instance_ctrl_t * p_instance_ctrl,ether_callback_args_t * p_callback_args)1852 static void ether_call_callback (ether_instance_ctrl_t * p_instance_ctrl, ether_callback_args_t * p_callback_args)
1853 {
1854 ether_callback_args_t args;
1855
1856 /* Store callback arguments in memory provided by user if available. This allows callback arguments to be
1857 * stored in non-secure memory so they can be accessed by a non-secure callback function. */
1858 ether_callback_args_t * p_args = p_instance_ctrl->p_callback_memory;
1859 if (NULL == p_args)
1860 {
1861 /* Store on stack */
1862 p_args = &args;
1863 }
1864 else
1865 {
1866 /* Save current arguments on the stack in case this is a nested interrupt. */
1867 args = *p_args;
1868 }
1869
1870 p_args->event = p_callback_args->event;
1871 p_args->status_ecsr = p_callback_args->status_ecsr;
1872 p_args->status_eesr = p_callback_args->status_eesr;
1873 p_args->channel = p_instance_ctrl->p_ether_cfg->channel;
1874 p_args->p_context = p_instance_ctrl->p_context;
1875
1876 #if BSP_TZ_SECURE_BUILD && BSP_FEATURE_ETHER_SUPPORTS_TZ_SECURE
1877
1878 /* p_callback can point to a secure function or a non-secure function. */
1879 if (!cmse_is_nsfptr(p_instance_ctrl->p_callback))
1880 {
1881 /* If p_callback is secure, then the project does not need to change security state. */
1882 p_instance_ctrl->p_callback(p_args);
1883 }
1884 else
1885 {
1886 /* If p_callback is Non-secure, then the project must change to Non-secure state in order to call the callback. */
1887 ether_prv_ns_callback p_callback = (ether_prv_ns_callback) (p_instance_ctrl->p_callback);
1888 p_callback(p_args);
1889 }
1890
1891 #else
1892
1893 /* If the project is not Trustzone Secure, then it will never need to change security state in order to call the callback. */
1894 p_instance_ctrl->p_callback(p_args);
1895 #endif
1896
1897 if (NULL != p_instance_ctrl->p_callback_memory)
1898 {
1899 /* Restore callback memory in case this is a nested interrupt. */
1900 *p_instance_ctrl->p_callback_memory = args;
1901 }
1902 }
1903
1904 /***********************************************************************************************************************
1905 * Function Name: ether_eint_isr
1906 * Description : Interrupt handler for Ethernet receive and transmit interrupts.
1907 * Arguments : none
1908 * Return Value : none
1909 ***********************************************************************************************************************/
ether_eint_isr(void)1910 void ether_eint_isr (void)
1911 {
1912 /* Save context if RTOS is used */
1913 FSP_CONTEXT_SAVE
1914
1915 uint32_t status_ecsr;
1916 uint32_t status_eesr;
1917
1918 ether_callback_args_t callback_arg;
1919 R_ETHERC0_Type * p_reg_etherc;
1920 R_ETHERC_EDMAC_Type * p_reg_edmac;
1921
1922 IRQn_Type irq = R_FSP_CurrentIrqGet();
1923 ether_instance_ctrl_t * p_instance_ctrl = (ether_instance_ctrl_t *) R_FSP_IsrContextGet(irq);
1924
1925 p_reg_etherc = (R_ETHERC0_Type *) p_instance_ctrl->p_reg_etherc;
1926 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
1927
1928 status_ecsr = p_reg_etherc->ECSR;
1929 status_eesr = p_reg_edmac->EESR;
1930
1931 /* When the ETHERC status interrupt is generated */
1932 if (status_eesr & ETHER_EDMAC_INTERRUPT_FACTOR_ECI)
1933 {
1934 #if (ETHER_CFG_USE_LINKSTA == 1)
1935
1936 /* When the link signal change interrupt is generated */
1937 if (ETHER_ETHERC_INTERRUPT_FACTOR_LCHNG == (status_ecsr & ETHER_ETHERC_INTERRUPT_FACTOR_LCHNG))
1938 {
1939 /* The state of the link signal is confirmed and Link Up/Down is judged. */
1940 /* When becoming Link up */
1941 if (ETHER_CFG_LINK_PRESENT == p_reg_etherc->PSR_b.LMON)
1942 {
1943 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_LINK_UP;
1944 }
1945 /* When Link becomes down */
1946 else
1947 {
1948 p_instance_ctrl->link_change = ETHER_LINK_CHANGE_LINK_DOWN;
1949 }
1950 }
1951 #endif
1952
1953 /* When the Magic Packet detection interrupt is generated */
1954 if (ETHER_ETHERC_INTERRUPT_FACTOR_MPD == (status_ecsr & ETHER_ETHERC_INTERRUPT_FACTOR_MPD))
1955 {
1956 p_instance_ctrl->magic_packet = ETHER_MAGIC_PACKET_DETECTED;
1957 }
1958
1959 /*
1960 * Because each bit of the ECSR register is cleared when one is written,
1961 * the value read from the register is written and the bit is cleared.
1962 */
1963 p_reg_etherc->ECSR = status_ecsr; /* Clear all ETHERC status BFR, PSRTO, LCHNG, MPD, ICD */
1964 }
1965
1966 /*
1967 * Because each bit of the EESR register is cleared when one is written,
1968 * the value read from the register is written and the bit is cleared.
1969 */
1970 p_reg_edmac->EESR = status_eesr; /* Clear EDMAC status bits */
1971
1972 /* If a callback is provided, then call it with callback argument. */
1973 if (NULL != p_instance_ctrl->p_callback)
1974 {
1975 callback_arg.channel = p_instance_ctrl->p_ether_cfg->channel;
1976 callback_arg.event = ETHER_EVENT_INTERRUPT;
1977 callback_arg.status_ecsr = status_ecsr;
1978 callback_arg.status_eesr = status_eesr;
1979 callback_arg.p_context = p_instance_ctrl->p_ether_cfg->p_context;
1980 ether_call_callback(p_instance_ctrl, &callback_arg);
1981 }
1982
1983 /* Clear pending interrupt flag to make sure it doesn't fire again
1984 * after exiting. */
1985 R_BSP_IrqStatusClear(R_FSP_CurrentIrqGet());
1986
1987 /* Restore context if RTOS is used */
1988 FSP_CONTEXT_RESTORE
1989 } /* End of function ether_eint_isr() */
1990
1991 /***********************************************************************************************************************
1992 * Function Name: ether_enable_icu
1993 * Description :
1994 * Arguments : channel -
1995 * Ethernet channel number
1996 * Return Value : none
1997 ***********************************************************************************************************************/
ether_enable_icu(ether_instance_ctrl_t * const p_instance_ctrl)1998 static void ether_enable_icu (ether_instance_ctrl_t * const p_instance_ctrl)
1999 {
2000 /** Configure the Ethernet interrupt. */
2001 R_BSP_IrqCfgEnable(p_instance_ctrl->p_ether_cfg->irq,
2002 p_instance_ctrl->p_ether_cfg->interrupt_priority,
2003 p_instance_ctrl);
2004 } /* End of function ether_enable_icu() */
2005
2006 /***********************************************************************************************************************
2007 * Function Name: ether_disable_icu
2008 * Description :
2009 * Arguments : channel -
2010 * Ethernet channel number
2011 * Return Value : none
2012 ***********************************************************************************************************************/
ether_disable_icu(ether_instance_ctrl_t * const p_instance_ctrl)2013 static void ether_disable_icu (ether_instance_ctrl_t * const p_instance_ctrl)
2014 {
2015 /* Get IRQ number for EDMAC_EINT interrupt. */
2016 NVIC_DisableIRQ(p_instance_ctrl->p_ether_cfg->irq);
2017 R_FSP_IsrContextSet(p_instance_ctrl->p_ether_cfg->irq, NULL);
2018 } /* End of function ether_disable_icu() */
2019
2020 /***********************************************************************************************************************
2021 * Function Name: ether_configure_padding
2022 * Description :
2023 * Arguments : channel -
2024 * Ethernet channel number
2025 * Return Value : none
2026 ***********************************************************************************************************************/
ether_configure_padding(ether_instance_ctrl_t * const p_instance_ctrl)2027 static void ether_configure_padding (ether_instance_ctrl_t * const p_instance_ctrl)
2028 {
2029 R_ETHERC_EDMAC_Type * p_reg_edmac;
2030 p_reg_edmac = (R_ETHERC_EDMAC_Type *) p_instance_ctrl->p_reg_edmac;
2031 p_reg_edmac->RPADIR_b.PADR = (unsigned) p_instance_ctrl->p_ether_cfg->padding_offset & ETHER_MAXIMUM_PADDING_OFFSET;
2032 p_reg_edmac->RPADIR_b.PADS = p_instance_ctrl->p_ether_cfg->padding;
2033 }
2034