1 /**
2  * @file    emac.h
3  * @brief   EMAC driver function prototypes and data types.
4  */
5 
6 /******************************************************************************
7  *
8  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
9  * Analog Devices, Inc.),
10  * Copyright (C) 2023-2024 Analog Devices, Inc.
11  *
12  * Licensed under the Apache License, Version 2.0 (the "License");
13  * you may not use this file except in compliance with the License.
14  * You may obtain a copy of the License at
15  *
16  *     http://www.apache.org/licenses/LICENSE-2.0
17  *
18  * Unless required by applicable law or agreed to in writing, software
19  * distributed under the License is distributed on an "AS IS" BASIS,
20  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  * See the License for the specific language governing permissions and
22  * limitations under the License.
23  *
24  ******************************************************************************/
25 
26 #ifndef LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_EMAC_H_
27 #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_EMAC_H_
28 
29 /* **** Includes **** */
30 #include "mxc_device.h"
31 #include "emac_regs.h"
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 /**
38  * @defgroup emac Ethernet Media Access Controller (EMAC)
39  * @ingroup periphlibs
40  * @{
41  */
42 
43 /* **** Definitions **** */
44 /** @brief   Enumeration for the EMAC interrupt events */
45 typedef enum {
46     MXC_EMAC_EVENT_MPS =
47         MXC_F_EMAC_INT_EN_MPS, /**! Management Packet Sent Interrupt                   */
48     MXC_EMAC_EVENT_RXCMPL =
49         MXC_F_EMAC_INT_EN_RXCMPL, /**! Receive Complete Interrupt                         */
50     MXC_EMAC_EVENT_RXUBR =
51         MXC_F_EMAC_INT_EN_RXUBR, /**! RX Used Bit Read Interrupt                         */
52     MXC_EMAC_EVENT_TXUBR =
53         MXC_F_EMAC_INT_EN_TXUBR, /**! TX Used Bit Read Interrupt                         */
54     MXC_EMAC_EVENT_TXUR =
55         MXC_F_EMAC_INT_EN_TXUR, /**! Ethernet Transmit Underrun Interrupt               */
56     MXC_EMAC_EVENT_RLE =
57         MXC_F_EMAC_INT_EN_RLE, /**! Retry Limit Exceeded Interrupt                     */
58     MXC_EMAC_EVENT_TXERR =
59         MXC_F_EMAC_INT_EN_TXERR, /**! Transmit Buffers Exhausted In Mid-Frame Interrupt  */
60     MXC_EMAC_EVENT_TXCMPL =
61         MXC_F_EMAC_INT_EN_TXCMPL, /**! Transmit Complete Interrupt                        */
62     MXC_EMAC_EVENT_LC =
63         MXC_F_EMAC_INT_EN_LC, /**! Link Change Interrupt                              */
64     MXC_EMAC_EVENT_RXOR =
65         MXC_F_EMAC_INT_EN_RXOR, /**! Receive Overrun Interrupt                          */
66     MXC_EMAC_EVENT_HRESPNO =
67         MXC_F_EMAC_INT_EN_HRESPNO, /**! HRESP Not OK Interrupt                             */
68     MXC_EMAC_EVENT_PPR =
69         MXC_F_EMAC_INT_EN_PPR, /**! Pause Packet Received Interrupt                    */
70     MXC_EMAC_EVENT_PTZ =
71         MXC_F_EMAC_INT_EN_PTZ /**! Pause Time Zero Interrupt                          */
72 } mxc_emac_events_t;
73 
74 /* **** Structures **** */
75 /**
76  * @brief   The callback called on EMAC interrupt event
77  *
78  */
79 typedef void (*mxc_emac_cb_func_t)(void);
80 
81 /**
82  * @brief   The microsecond delay function used by the driver
83  *
84  */
85 typedef int (*mxc_emac_delay_func_t)(uint32_t);
86 
87 /**
88  * @brief   The table of callback functions for EMAC interrupt events
89  *
90  */
91 typedef struct {
92     mxc_emac_cb_func_t mps_handler;
93     mxc_emac_cb_func_t rxcmpl_handler;
94     mxc_emac_cb_func_t rxubr_handler;
95     mxc_emac_cb_func_t txubr_handler;
96     mxc_emac_cb_func_t txur_handler;
97     mxc_emac_cb_func_t rle_handler;
98     mxc_emac_cb_func_t txerr_handler;
99     mxc_emac_cb_func_t txcmpl_handler;
100     mxc_emac_cb_func_t lc_handler;
101     mxc_emac_cb_func_t rxor_handler;
102     mxc_emac_cb_func_t hrespno_handler;
103     mxc_emac_cb_func_t ppr_handler;
104     mxc_emac_cb_func_t ptz_handler;
105 } mxc_emac_cb_funcs_tbl_t;
106 
107 /**
108  * @brief   The information needed for an EMAC buffer descriptor
109  *
110  */
111 typedef struct {
112     unsigned int addr;
113     unsigned int ctrl;
114 } mxc_emac_dma_desc_t;
115 
116 /**
117  * @brief   The information needed by the EMAC driver to operate
118  *
119  */
120 typedef struct {
121     mxc_emac_regs_t *regs;
122     unsigned int rx_tail;
123     unsigned int tx_head;
124     unsigned int tx_tail;
125     void *rx_buffer;
126     void *tx_buffer;
127     mxc_emac_dma_desc_t *rx_ring;
128     mxc_emac_dma_desc_t *tx_ring;
129     unsigned int rx_buffer_dma;
130     unsigned int rx_ring_dma;
131     unsigned int tx_ring_dma;
132     uint16_t phy_addr;
133 
134     unsigned int first_init;
135     unsigned int rx_buffer_size;
136     unsigned int rx_ring_size;
137     unsigned int tx_ring_size;
138     mxc_emac_delay_func_t delay_us;
139     mxc_emac_cb_funcs_tbl_t cb_funcs;
140 } mxc_emac_device_t;
141 
142 /**
143  * @brief   The basic configuration information to set up EMAC module
144  *
145  */
146 typedef struct {
147     unsigned char *rx_buff;
148     unsigned char *rx_ring_buff;
149     unsigned char *tx_ring_buff;
150     unsigned int rx_buff_size;
151     unsigned int rx_ring_buff_size;
152     unsigned int tx_ring_buff_size;
153     uint16_t phy_addr;
154     unsigned int interrupt_mode;
155     unsigned int interrupt_events;
156     mxc_emac_delay_func_t delay_us;
157     mxc_emac_cb_funcs_tbl_t conf_cb_funcs;
158 } mxc_emac_config_t;
159 
160 /* **** Function Prototypes **** */
161 /* ************************************************************************* */
162 /* Control/Configuration Functions                                           */
163 /* ************************************************************************* */
164 /**
165  * @brief      Initialize EMAC device structure
166  *
167  * @param      config             EMAC configuration parameters
168  *
169  * @return     #E_NO_ERROR        if successful
170  * @return     #E_NULL_PTR        if pointer is null
171  * @return     #E_INVALID         if parameter is invalid
172  */
173 int MXC_EMAC_Init(mxc_emac_config_t *config);
174 
175 /**
176  * @brief      Set configuration for EMAC device
177  *
178  * @param      config             EMAC configuration parameters
179  *
180  * @return     #E_NO_ERROR        if successful
181  * @return     #E_NULL_PTR        if pointer is null
182  * @return     #E_INVALID         if parameter is invalid
183  * @return     #E_UNINITIALIZED   if device is uninitialized
184  */
185 int MXC_EMAC_SetConfiguration(mxc_emac_config_t *config);
186 
187 /**
188  * @brief      Set EMAC hardware address
189  *
190  * @param      enetaddr           MAC address
191  *
192  * @return     #E_NO_ERROR        if successful
193  * @return     #E_NULL_PTR        if pointer is null
194  */
195 int MXC_EMAC_SetHwAddr(unsigned char *enetaddr);
196 
197 /**
198  * @brief      Enable interrupt events
199  *
200  * @param      events             interrupt events to be enabled
201  *
202  * @return     #E_NO_ERROR        if successful
203  * @return     #E_UNINITIALIZED   if device is uninitialized
204  */
205 int MXC_EMAC_EnableInterruptEvents(unsigned int events);
206 
207 /**
208  * @brief      Disable interrupt events
209  *
210  * @param      events             interrupt events to be disabled
211  *
212  * @return     #E_NO_ERROR        if successful
213  * @return     #E_UNINITIALIZED   if device is uninitialized
214  */
215 int MXC_EMAC_DisableInterruptEvents(unsigned int events);
216 
217 /* ************************************************************************* */
218 /* Low-Level Functions                                                       */
219 /* ************************************************************************* */
220 /**
221  * @brief      Start EMAC device
222  *
223  * @return     #E_NO_ERROR        if successful
224  * @return     #E_UNINITIALIZED   if device is uninitialized
225  * @return     #E_NO_DEVICE       if no phy device
226  * @return     #E_NO_RESPONSE     if link down
227  */
228 int MXC_EMAC_Start(void);
229 
230 /**
231  * @brief      Stop EMAC device
232  *
233  * @return     #E_NO_ERROR        if successful
234  */
235 int MXC_EMAC_Stop(void);
236 
237 /**
238  * @brief      Read link status
239  *
240  * @return     #E_NO_ERROR        link up
241  * @return     #E_NO_DEVICE       link down
242  */
243 int MXC_EMAC_ReadLinkStatus(void);
244 
245 /* ************************************************************************* */
246 /* Transaction-Level Functions                                               */
247 /* ************************************************************************* */
248 /**
249  * @brief      Send Ethernet packet in sync mode
250  *
251  * @param      packet             pointer to the transmission buffer
252  * @param      length             length of the packet to be transmitted
253  *
254  * @return     #E_NO_ERROR        if successful
255  * @return     #E_NULL_PTR        if pointer is null
256  * @return     #E_UNINITIALIZED   if device is uninitialized
257  * @return     #E_UNDERFLOW       if transmission is underrun
258  * @return     #E_OVERFLOW        if transmission is exhausted
259  * @return     #E_TIME_OUT        if transmission timeout occurs
260  */
261 int MXC_EMAC_SendSync(const void *packet, unsigned int length);
262 
263 /**
264  * @brief      Send Ethernet packet in async mode
265  *
266  * @param      packet             pointer to the transmission buffer
267  * @param      length             length of the packet to be transmitted
268  *
269  * @return     #E_NO_ERROR        if successful
270  * @return     #E_NULL_PTR        if pointer is null
271  */
272 int MXC_EMAC_SendAsync(const void *packet, unsigned int length);
273 
274 /**
275  * @brief      Receive Ethernet packet
276  *
277  * @param      rx_buff            pointer to the receive buffer
278  * @param      max_len            max length to be stored into the receive buffer
279  *
280  * @return     0 - 1514           length of the received packet
281  * @return     #E_UNINITIALIZED   if device is uninitialized
282  * @return     #E_NULL_PTR        if pointer is null
283  * @return     #E_NONE_AVAIL      if received packet does not fit into the receive buffer
284  */
285 int MXC_EMAC_Recv(void *rx_buff, unsigned int max_len);
286 
287 /**
288  * @brief      Used for interrupt handling
289  * @details    In order to handle EMAC interrupt events, the application must call this
290  *             function periodically. This can be done from within the EMAC interrupt
291  *             handler or periodically by the application if EMAC interrupts are disabled.
292  *
293  */
294 void MXC_EMAC_IrqHandler(void);
295 
296 /**@} end of group emac */
297 
298 #ifdef __cplusplus
299 }
300 #endif
301 
302 #endif // LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_EMAC_H_
303