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