1 /* -----------------------------------------------------------------------------
2  * Copyright (c) 2013-2015 ARM Ltd.
3  *
4  * This software is provided 'as-is', without any express or implied warranty.
5  * In no event will the authors be held liable for any damages arising from
6  * the use of this software. Permission is granted to anyone to use this
7  * software for any purpose, including commercial applications, and to alter
8  * it and redistribute it freely, subject to the following restrictions:
9  *
10  * 1. The origin of this software must not be misrepresented; you must not
11  *    claim that you wrote the original software. If you use this software in
12  *    a product, an acknowledgment in the product documentation would be
13  *    appreciated but is not required.
14  *
15  * 2. Altered source versions must be plainly marked as such, and must not be
16  *    misrepresented as being the original software.
17  *
18  * 3. This notice may not be removed or altered from any source distribution.
19  *
20  *
21  * $Date:        02. October 2015
22  * $Revision:    V2.5
23  *
24  * Driver:       Driver_ETH_MAC0
25  * Configured:   via RTE_Device.h configuration file
26  * Project:      Ethernet Media Access (MAC) Driver for NXP LPC18xx
27  * --------------------------------------------------------------------------
28  * Use the following configuration settings in the middleware component
29  * to connect to this driver.
30  *
31  *   Configuration Setting                     Value
32  *   ---------------------                     -----
33  *   Connect to hardware via Driver_ETH_MAC# = 0
34  * -------------------------------------------------------------------------- */
35 
36 /* History:
37  *  Version 2.5
38  *    Corrected return value of the ReadFrame function
39  *  Version 2.4
40  *    - Updated initialization, uninitialization and power procedures
41  *  Version 2.3
42  *    - Corrected return value of PHY_Read and PHY_Write functions on timeout
43  *  Version 2.2
44  *    - GetMacAddress function implemented in Ethernet driver
45  *  Version 2.1
46  *    - Added Sleep mode and Wake-up on Magic Packet
47  *    - Improved robustness and error control
48  *    - Added CLK0 pin option support
49  *  Version 2.0
50  *    - Based on API V2.00
51  *    - Added multicast MAC address filtering
52  *  Version 1.1
53  *    - Based on API V1.10 (namespace prefix ARM_ added)
54  *  Version 1.0
55  *    - Initial release
56  */
57 
58 /* IEEE 1588 time stamping enable (PTP) */
59 #ifndef EMAC_TIME_STAMP
60 #define EMAC_TIME_STAMP         0
61 #endif
62 
63 #include "EMAC_LPC18xx.h"
64 
65 #define ARM_ETH_MAC_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,5) /* driver version */
66 
67 /* Timeouts */
68 #define PHY_TIMEOUT         200         /* PHY Register access timeout in us  */
69 
70 /* EMAC Memory Buffer configuration */
71 #define NUM_RX_BUF          4           /* 0x1800 for Rx (4*1536=6K)          */
72 #define NUM_TX_BUF          2           /* 0x0C00 for Tx (2*1536=3K)          */
73 #define ETH_BUF_SIZE        1536        /* ETH Receive/Transmit buffer size   */
74 
75 /* EMAC core clock (system_LPC43xx.c) */
76 extern uint32_t GetClockFreq (uint32_t clk_src);
77 
78 /* Ethernet Pin definitions */
79 static const PIN_ID eth_pins[] = {
80   { RTE_ENET_MDI_MDC_PORT,     RTE_ENET_MDI_MDC_PIN,                   SCU_SFS_EZI | RTE_ENET_MDI_MDC_FUNC       },
81   { RTE_ENET_MDI_MDIO_PORT,    RTE_ENET_MDI_MDIO_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MDI_MDIO_FUNC      },
82 #if (RTE_ENET_RMII)
83   { RTE_ENET_RMII_TXD0_PORT,   RTE_ENET_RMII_TXD0_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_RMII_TXD0_FUNC     },
84   { RTE_ENET_RMII_TXD1_PORT,   RTE_ENET_RMII_TXD1_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_RMII_TXD1_FUNC     },
85   { RTE_ENET_RMII_TX_EN_PORT,  RTE_ENET_RMII_TX_EN_PIN,  SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_RMII_TX_EN_FUNC    },
86   { RTE_ENET_RMII_REF_CLK_PORT,RTE_ENET_RMII_REF_CLK_PIN,SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_RMII_REF_CLK_FUNC  },
87   { RTE_ENET_RMII_RXD0_PORT,   RTE_ENET_RMII_RXD0_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_RMII_RXD0_FUNC     },
88   { RTE_ENET_RMII_RXD1_PORT,   RTE_ENET_RMII_RXD1_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_RMII_RXD1_FUNC     },
89   { RTE_ENET_RMII_RX_DV_PORT,  RTE_ENET_RMII_RX_DV_PIN,  SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_RMII_RX_DV_FUNC    }
90 #endif
91 #if (RTE_ENET_MII)
92   { RTE_ENET_MII_TXD0_PORT,    RTE_ENET_MII_TXD0_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_TXD0_FUNC      },
93   { RTE_ENET_MII_TXD1_PORT,    RTE_ENET_MII_TXD1_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_TXD1_FUNC      },
94   { RTE_ENET_MII_TXD2_PORT,    RTE_ENET_MII_TXD2_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_TXD2_FUNC      },
95   { RTE_ENET_MII_TXD3_PORT,    RTE_ENET_MII_TXD3_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_TXD3_FUNC      },
96   { RTE_ENET_MII_TX_EN_PORT,   RTE_ENET_MII_TX_EN_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_TX_EN_FUNC     },
97   { RTE_ENET_MII_TX_CLK_PORT,  RTE_ENET_MII_TX_CLK_PIN,  SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_TX_CLK_FUNC    },
98 #if (RTE_ENET_MII_TX_ER_PIN_EN)
99   { RTE_ENET_MII_TX_ER_PORT,   RTE_ENET_MII_TX_ER_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_TX_ER_FUNC     },
100 #endif
101   { RTE_ENET_MII_RXD0_PORT,    RTE_ENET_MII_RXD0_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_RXD0_FUNC      },
102   { RTE_ENET_MII_RXD1_PORT,    RTE_ENET_MII_RXD1_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_RXD1_FUNC      },
103   { RTE_ENET_MII_RXD2_PORT,    RTE_ENET_MII_RXD2_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_RXD2_FUNC      },
104   { RTE_ENET_MII_RXD3_PORT,    RTE_ENET_MII_RXD3_PIN,    SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_RXD3_FUNC      },
105   { RTE_ENET_MII_RX_DV_PORT,   RTE_ENET_MII_RX_DV_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_RX_DV_FUNC     },
106   { RTE_ENET_MII_RX_CLK_PORT,  RTE_ENET_MII_RX_CLK_PIN,  SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_RX_CLK_FUNC    },
107   { RTE_ENET_MII_RX_ER_PORT,   RTE_ENET_MII_RX_ER_PIN,   SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_RX_ER_FUNC     },
108   { RTE_ENET_MII_COL_PORT,     RTE_ENET_MII_COL_PIN,     SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_COL_FUNC       },
109   { RTE_ENET_MII_CRS_PORT,     RTE_ENET_MII_CRS_PIN,     SCU_SFS_EHS | SCU_SFS_EZI | RTE_ENET_MII_CRS_FUNC       },
110 #endif
111 };
112 
113 /* Driver Version */
114 static const ARM_DRIVER_VERSION DriverVersion = {
115   ARM_ETH_MAC_API_VERSION,
116   ARM_ETH_MAC_DRV_VERSION
117 };
118 
119 /* Driver Capabilities */
120 static const ARM_ETH_MAC_CAPABILITIES DriverCapabilities = {
121   0,                                /* checksum_offload_rx_ip4  */
122   0,                                /* checksum_offload_rx_ip6  */
123   0,                                /* checksum_offload_rx_udp  */
124   0,                                /* checksum_offload_rx_tcp  */
125   0,                                /* checksum_offload_rx_icmp */
126   0,                                /* checksum_offload_tx_ip4  */
127   0,                                /* checksum_offload_tx_ip6  */
128   0,                                /* checksum_offload_tx_udp  */
129   0,                                /* checksum_offload_tx_tcp  */
130   0,                                /* checksum_offload_tx_icmp */
131   (RTE_ENET_RMII) ?
132   ARM_ETH_INTERFACE_RMII :
133   ARM_ETH_INTERFACE_MII,            /* media_interface          */
134   0,                                /* mac_address              */
135   1,                                /* event_rx_frame           */
136   1,                                /* event_tx_frame           */
137   1,                                /* event_wakeup             */
138   (EMAC_TIME_STAMP) ? 1 : 0         /* precision_timer          */
139 };
140 
141 /* Local variables */
142 static EMAC_CTRL  emac_control = { 0 };
143 #define emac     (emac_control)
144 static RX_Desc   rx_desc[NUM_RX_BUF];
145 static TX_Desc   tx_desc[NUM_TX_BUF];
146 static uint32_t  rx_buf [NUM_RX_BUF][ETH_BUF_SIZE>>2];
147 static uint32_t  tx_buf [NUM_TX_BUF][ETH_BUF_SIZE>>2];
148 
149 /* Local functions */
150 static void init_rx_desc (void);
151 static void init_tx_desc (void);
152 static uint32_t crc32_8bit_rev (uint32_t crc32, uint8_t val);
153 static uint32_t crc32_data (const uint8_t *data, uint32_t len);
154 
155 /**
156   \fn          void init_rx_desc (void)
157   \brief       Initialize Rx DMA descriptors.
158   \return      none.
159 */
init_rx_desc(void)160 static void init_rx_desc (void) {
161   uint32_t i,next;
162 
163   for (i = 0; i < NUM_RX_BUF; i++) {
164     rx_desc[i].Stat = EMAC_RDES0_OWN;
165     rx_desc[i].Ctrl = EMAC_RDES1_RCH | ETH_BUF_SIZE;
166     rx_desc[i].Addr = (uint8_t *)&rx_buf[i];
167     next = i + 1;
168     if (next == NUM_RX_BUF) next = 0;
169     rx_desc[i].Next = &rx_desc[next];
170   }
171   ENET->DMA_REC_DES_ADDR = (uint32_t)&rx_desc[0];
172   emac.rx_index = 0;
173 }
174 
175 /**
176   \fn          void init_tx_desc (void)
177   \brief       Initialize Tx DMA descriptors.
178   \return      none.
179 */
init_tx_desc(void)180 static void init_tx_desc (void) {
181   uint32_t i,next;
182 
183   for (i = 0; i < NUM_TX_BUF; i++) {
184     tx_desc[i].CtrlStat = EMAC_TDES0_TCH | EMAC_TDES0_LS | EMAC_TDES0_FS;
185     tx_desc[i].Addr     = (uint8_t *)&tx_buf[i];
186     next = i + 1;
187     if (next == NUM_TX_BUF) next = 0;
188     tx_desc[i].Next     = &tx_desc[next];
189   }
190   ENET->DMA_TRANS_DES_ADDR = (uint32_t)&tx_desc[0];
191   emac.tx_index = 0;
192 }
193 
194 /**
195   \fn          uint32_t crc32_8bit_rev (uint32_t crc32, uint8_t val)
196   \brief       Calculate 32-bit CRC (Polynom: 0x04C11DB7, data bit-reversed).
197   \param[in]   crc32  CRC initial value
198   \param[in]   val    Input value
199   \return      Calculated CRC value
200 */
crc32_8bit_rev(uint32_t crc32,uint8_t val)201 static uint32_t crc32_8bit_rev (uint32_t crc32, uint8_t val) {
202   uint32_t n;
203 
204   crc32 ^= __RBIT (val);
205   for (n = 8; n; n--) {
206     if (crc32 & 0x80000000) {
207       crc32 <<= 1;
208       crc32  ^= 0x04C11DB7;
209     } else {
210       crc32 <<= 1;
211     }
212   }
213   return (crc32);
214 }
215 
216 /**
217   \fn          uint32_t crc32_data (const uint8_t *data, uint32_t len)
218   \brief       Calculate standard 32-bit Ethernet CRC.
219   \param[in]   data  Pointer to buffer containing the data
220   \param[in]   len   Data length in bytes
221   \return      Calculated CRC value
222 */
crc32_data(const uint8_t * data,uint32_t len)223 static uint32_t crc32_data (const uint8_t *data, uint32_t len) {
224   uint32_t crc;
225 
226   for (crc = 0xFFFFFFFF; len; len--) {
227     crc = crc32_8bit_rev (crc, *data++);
228   }
229   return (crc ^ 0xFFFFFFFF);
230 }
231 
232 
233 /* Ethernet Driver functions */
234 
235 /**
236   \fn          ARM_DRIVER_VERSION GetVersion (void)
237   \brief       Get driver version.
238   \return      \ref ARM_DRIVER_VERSION
239 */
GetVersion(void)240 static ARM_DRIVER_VERSION GetVersion (void) {
241   return DriverVersion;
242 }
243 
244 
245 /**
246   \fn          ARM_ETH_MAC_CAPABILITIES GetCapabilities (void)
247   \brief       Get driver capabilities.
248   \return      \ref ARM_ETH_MAC_CAPABILITIES
249 */
GetCapabilities(void)250 static ARM_ETH_MAC_CAPABILITIES GetCapabilities (void) {
251   return DriverCapabilities;
252 }
253 
254 
255 /**
256   \fn          int32_t Initialize (ARM_ETH_MAC_SignalEvent_t cb_event)
257   \brief       Initialize Ethernet MAC Device.
258   \param[in]   cb_event  Pointer to \ref ARM_ETH_MAC_SignalEvent
259   \return      \ref execution_status
260 */
Initialize(ARM_ETH_MAC_SignalEvent_t cb_event)261 static int32_t Initialize (ARM_ETH_MAC_SignalEvent_t cb_event) {
262   const PIN_ID *pin;
263 
264   if (emac.flags & EMAC_FLAG_INIT) { return ARM_DRIVER_OK; }
265 
266   /* Configure EMAC pins */
267   for (pin = eth_pins; pin != &eth_pins[sizeof(eth_pins)/sizeof(PIN_ID)]; pin++) {
268     if (pin->port == 0x10) {
269       SCU_CLK_PinConfigure (pin->num, pin->config_val);
270       continue;
271     }
272     SCU_PinConfigure(pin->port, pin->num, pin->config_val);
273   }
274 
275   /* Clear control structure */
276   memset (&emac, 0, sizeof (EMAC_CTRL));
277 
278   emac.cb_event = cb_event;
279   emac.flags    = EMAC_FLAG_INIT;
280 
281   return ARM_DRIVER_OK;
282 }
283 
284 /**
285   \fn          int32_t Uninitialize (void)
286   \brief       De-initialize Ethernet MAC Device.
287   \return      \ref execution_status
288 */
Uninitialize(void)289 static int32_t Uninitialize (void) {
290   const PIN_ID *pin;
291 
292   emac.flags = 0;
293 
294   /* Unconfigure ethernet pins */
295   for (pin = eth_pins; pin != &eth_pins[sizeof(eth_pins)/sizeof(PIN_ID)]; pin++) {
296     if (pin->port == 0x10) {
297       SCU_CLK_PinConfigure (pin->num, 0);
298       continue;
299     }
300     SCU_PinConfigure(pin->port, pin->num, 0);
301   }
302 
303   return ARM_DRIVER_OK;
304 }
305 
306 /**
307   \fn          int32_t PowerControl (ARM_POWER_STATE state)
308   \brief       Control Ethernet MAC Device Power.
309   \param[in]   state  Power state
310   \return      \ref execution_status
311 */
PowerControl(ARM_POWER_STATE state)312 static int32_t PowerControl (ARM_POWER_STATE state) {
313   uint32_t clk;
314 
315   switch (state) {
316     case ARM_POWER_OFF:
317       /* Disable EMAC interrupts */
318       NVIC_DisableIRQ(ETHERNET_IRQn);
319 
320       ENET->DMA_INT_EN       = 0x00000000;
321       ENET->MAC_TIMESTP_CTRL = 0x00000000;
322 
323       /* Disable DMA Tx and Rx */
324       ENET->DMA_OP_MODE &= ~(EMAC_DOMR_ST | EMAC_DOMR_SR);
325 
326       /* Flush transmit FIFO */
327       ENET->DMA_OP_MODE |= EMAC_DOMR_FTF;
328       __NOP ();
329 
330       /* Disable EMAC Tx and Rx */
331       ENET->MAC_CONFIG  = 0x00000000;
332       ENET->DMA_OP_MODE = 0x00000000;
333 
334       /* Disable EMAC peripheral clock */
335       LPC_CCU1->CLK_M3_ETHERNET_CFG &= ~CCU_CLK_CFG_RUN;
336 
337       emac.flags = EMAC_FLAG_INIT;
338       break;
339 
340     case ARM_POWER_LOW:
341       return ARM_DRIVER_ERROR_UNSUPPORTED;
342 
343     case ARM_POWER_FULL:
344       if (emac.flags & EMAC_FLAG_POWER) {
345         /* Driver already powered */
346         break;
347       }
348 
349       /* Enable EMAC peripheral clock */
350       LPC_CCU1->CLK_M3_ETHERNET_CFG |=  CCU_CLK_CFG_AUTO | CCU_CLK_CFG_RUN;
351       while (!(LPC_CCU1->CLK_M3_ETHERNET_STAT & CCU_CLK_STAT_RUN));
352 
353       /* Configure Ethernet PHY interface mode (MII/RMII) */
354       /* EMAC must be reset after changing PHY interface! */
355       #if (RTE_ENET_RMII)
356         LPC_CREG->CREG6 = (LPC_CREG->CREG6 & ~EMAC_CREG6_ETH_MASK) | EMAC_CREG6_ETH_RMII;
357       #else
358         LPC_CREG->CREG6 = (LPC_CREG->CREG6 & ~EMAC_CREG6_ETH_MASK) | EMAC_CREG6_ETH_MII;
359       #endif
360 
361       /* Reset EMAC peripheral */
362       LPC_RGU->RESET_CTRL0 = RGU_RESET_EMAC;
363       while (!(LPC_RGU->RESET_ACTIVE_STATUS0 & RGU_RESET_EMAC));
364 
365       /* Soft reset EMAC DMA controller */
366       ENET->DMA_BUS_MODE |= EMAC_DBMR_SWR;
367       while (ENET->DMA_BUS_MODE & EMAC_DBMR_SWR);
368 
369       /* MDC clock range selection */
370       clk = GetClockFreq (CLK_SRC_PLL1);
371       if      (clk >= 150000000) emac.mmar_cr_val = EMAC_MMAR_CR_Div102;
372       else if (clk >= 100000000) emac.mmar_cr_val = EMAC_MMAR_CR_Div62;
373       else if (clk >= 60000000)  emac.mmar_cr_val = EMAC_MMAR_CR_Div42;
374       else if (clk >= 35000000)  emac.mmar_cr_val = EMAC_MMAR_CR_Div26;
375       else if (clk >= 25000000)  emac.mmar_cr_val = EMAC_MMAR_CR_Div16;
376       else                       return ARM_DRIVER_ERROR_UNSUPPORTED;
377       ENET->MAC_MII_ADDR = emac.mmar_cr_val;
378 
379       #if (EMAC_TIME_STAMP)
380         /* Enhanced DMA descriptor enable */
381         ENET->DMA_BUS_MODE |= EMAC_DBMR_ATDS;
382 
383         /* Set clock accuracy to 20ns (50MHz) or 50ns (20MHz) */
384         if (clk >= 51000000) {
385           ENET->SUBSECOND_INCR = 20;
386           ENET->ADDEND         = (50000000ull << 32) / clk;
387         }
388         else {
389           ENET->SUBSECOND_INCR = 50;
390           ENET->ADDEND         = (20000000ull << 32) / clk;
391         }
392 
393         /* Enable timestamp fine update */
394         ENET->MAC_TIMESTP_CTRL = EMAC_MTCR_TSIPV4E | EMAC_MTCR_TSIPV6E |
395                                  EMAC_MTCR_TSCTRL  | EMAC_MTCR_TSADDR  |
396                                  EMAC_MTCR_TSCFUP  | EMAC_MTCR_TSENA;
397         emac.tx_ts_index = 0;
398       #endif
399 
400       /* Initialize MAC configuration */
401       ENET->MAC_CONFIG = EMAC_MCR_DO | EMAC_MCR_PS;
402 
403       /* Initialize Filter registers */
404       ENET->MAC_FRAME_FILTER = EMAC_MFFR_DBF;
405       ENET->MAC_FLOW_CTRL    = EMAC_MFCR_DZPQ;
406 
407       /* Initialize Address register */
408       ENET->MAC_ADDR0_HIGH = 0x00000000;
409       ENET->MAC_ADDR0_LOW  = 0x00000000;
410 
411       /* Disable MAC interrupts */
412       ENET->MAC_INTR_MASK  = EMAC_MIMR_PMTIM | EMAC_MIMR_TSIM;
413 
414       /* Initialize DMA Descriptors */
415       init_rx_desc ();
416       init_tx_desc ();
417 
418       /* Enable DMA interrupts */
419       ENET->DMA_STAT   = 0xFFFFFFFF;
420       ENET->DMA_INT_EN = EMAC_DIER_NIE | EMAC_DIER_RIE | EMAC_DIER_TIE;
421 
422       /* Enable ethernet interrupts */
423       NVIC_ClearPendingIRQ(ETHERNET_IRQn);
424       NVIC_EnableIRQ(ETHERNET_IRQn);
425 
426       emac.frame_end = NULL;
427       emac.flags    |= EMAC_FLAG_POWER;
428       break;
429 
430     default:
431       return ARM_DRIVER_ERROR_UNSUPPORTED;
432   }
433 
434   return ARM_DRIVER_OK;
435 }
436 
437 /**
438   \fn          int32_t GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr)
439   \brief       Get Ethernet MAC Address.
440   \param[in]   ptr_addr  Pointer to address
441   \return      \ref execution_status
442 */
GetMacAddress(ARM_ETH_MAC_ADDR * ptr_addr)443 static int32_t GetMacAddress (ARM_ETH_MAC_ADDR *ptr_addr) {
444   uint32_t val;
445 
446   if (!ptr_addr) {
447     /* Invalid parameters */
448     return ARM_DRIVER_ERROR_PARAMETER;
449   }
450 
451   if (!(emac.flags & EMAC_FLAG_POWER)) {
452     /* Driver not yet powered */
453     return ARM_DRIVER_ERROR;
454   }
455 
456   val = ENET->MAC_ADDR0_HIGH;
457   ptr_addr->b[5] = (uint8_t)(val >> 8);
458   ptr_addr->b[4] = (uint8_t)(val);
459   val = ENET->MAC_ADDR0_LOW;
460   ptr_addr->b[3] = (uint8_t)(val >> 24);
461   ptr_addr->b[2] = (uint8_t)(val >> 16);
462   ptr_addr->b[1] = (uint8_t)(val >>  8);
463   ptr_addr->b[0] = (uint8_t)(val);
464 
465   return ARM_DRIVER_OK;
466 }
467 
468 /**
469   \fn          int32_t SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr)
470   \brief       Set Ethernet MAC Address.
471   \param[in]   ptr_addr  Pointer to address
472   \return      \ref execution_status
473 */
SetMacAddress(const ARM_ETH_MAC_ADDR * ptr_addr)474 static int32_t SetMacAddress (const ARM_ETH_MAC_ADDR *ptr_addr) {
475 
476   if (!ptr_addr) {
477     /* Invalid parameters */
478     return ARM_DRIVER_ERROR_PARAMETER;
479   }
480 
481   if (!(emac.flags & EMAC_FLAG_POWER)) {
482     /* Driver not yet powered */
483     return ARM_DRIVER_ERROR;
484   }
485 
486   /* Set Ethernet MAC Address registers */
487   ENET->MAC_ADDR0_HIGH = (ptr_addr->b[5] <<  8) |  ptr_addr->b[4];
488   ENET->MAC_ADDR0_LOW  = (ptr_addr->b[3] << 24) | (ptr_addr->b[2] << 16) |
489                          (ptr_addr->b[1] <<  8) |  ptr_addr->b[0];
490   return ARM_DRIVER_OK;
491 }
492 
493 /**
494   \fn          int32_t SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr,
495                                                uint32_t          num_addr)
496   \brief       Configure Address Filter.
497   \param[in]   ptr_addr  Pointer to addresses
498   \param[in]   num_addr  Number of addresses to configure
499   \return      \ref execution_status
500 */
SetAddressFilter(const ARM_ETH_MAC_ADDR * ptr_addr,uint32_t num_addr)501 static int32_t SetAddressFilter (const ARM_ETH_MAC_ADDR *ptr_addr, uint32_t num_addr) {
502   uint32_t crc;
503 
504   if (!ptr_addr && num_addr) {
505     /* Invalid parameters */
506     return ARM_DRIVER_ERROR_PARAMETER;
507   }
508 
509   if (!(emac.flags & EMAC_FLAG_POWER)) {
510     /* Driver not yet powered */
511     return ARM_DRIVER_ERROR;
512   }
513 
514   ENET->MAC_FRAME_FILTER &= ~(EMAC_MFFR_HPF | EMAC_MFFR_HMC);
515   ENET->MAC_HASHTABLE_HIGH = 0x00000000;
516   ENET->MAC_HASHTABLE_LOW  = 0x00000000;
517 
518   if (num_addr == 0) {
519     return ARM_DRIVER_OK;
520   }
521 
522   /* Calculate 64-bit Hash table for MAC addresses */
523   for ( ; num_addr; ptr_addr++, num_addr--) {
524     crc = crc32_data (&ptr_addr->b[0], 6) >> 26;
525     if (crc & 0x20) {
526       ENET->MAC_HASHTABLE_HIGH |= (1 << (crc & 0x1F));
527     }
528     else {
529       ENET->MAC_HASHTABLE_LOW  |= (1 << crc);
530     }
531   }
532   /* Enable both, unicast and hash address filtering */
533   ENET->MAC_FRAME_FILTER |= EMAC_MFFR_HPF | EMAC_MFFR_HMC;
534 
535   return ARM_DRIVER_OK;
536 }
537 
538 /**
539   \fn          int32_t SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags)
540   \brief       Send Ethernet frame.
541   \param[in]   frame  Pointer to frame buffer with data to send
542   \param[in]   len    Frame buffer length in bytes
543   \param[in]   flags  Frame transmit flags (see ARM_ETH_MAC_TX_FRAME_...)
544   \return      \ref execution_status
545 */
SendFrame(const uint8_t * frame,uint32_t len,uint32_t flags)546 static int32_t SendFrame (const uint8_t *frame, uint32_t len, uint32_t flags) {
547   uint8_t *dst;
548   uint32_t ctrl;
549 
550   if (!frame || !len) {
551     /* Invalid parameters */
552     return ARM_DRIVER_ERROR_PARAMETER;
553   }
554 
555   if (!(emac.flags & EMAC_FLAG_POWER)) {
556     /* Driver not yet powered */
557     return ARM_DRIVER_ERROR;
558   }
559 
560   dst = emac.frame_end;
561   if (dst == NULL) {
562     /* Start of a new transmit frame */
563     if (tx_desc[emac.tx_index].CtrlStat & EMAC_TDES0_OWN) {
564       /* Transmitter is busy, wait */
565       return ARM_DRIVER_ERROR_BUSY;
566     }
567     dst = tx_desc[emac.tx_index].Addr;
568     tx_desc[emac.tx_index].Size = len;
569   }
570   else {
571     /* Sending data fragments in progress */
572     tx_desc[emac.tx_index].Size += len;
573   }
574   /* Fast-copy data fragments to EMAC-DMA buffer */
575   for ( ; len > 7; dst += 8, frame += 8, len -= 8) {
576     ((__packed uint32_t *)dst)[0] = ((__packed uint32_t *)frame)[0];
577     ((__packed uint32_t *)dst)[1] = ((__packed uint32_t *)frame)[1];
578   }
579   /* Copy remaining 7 bytes */
580   for ( ; len > 1; dst += 2, frame += 2, len -= 2) {
581     ((__packed uint16_t *)dst)[0] = ((__packed uint16_t *)frame)[0];
582   }
583   if (len > 0) dst++[0] = frame++[0];
584 
585   if (flags & ARM_ETH_MAC_TX_FRAME_FRAGMENT) {
586     /* More data to come, remember current write position */
587     emac.frame_end = dst;
588     return ARM_DRIVER_OK;
589   }
590 
591   /* Frame is now ready, send it to DMA */
592   ctrl = tx_desc[emac.tx_index].CtrlStat & ~(EMAC_TDES0_IC | EMAC_TDES0_TTSE);
593   if (flags & ARM_ETH_MAC_TX_FRAME_EVENT)     ctrl |= EMAC_TDES0_IC;
594 #if (EMAC_TIME_STAMP)
595   if (flags & ARM_ETH_MAC_TX_FRAME_TIMESTAMP) ctrl |= EMAC_TDES0_TTSE;
596   emac.tx_ts_index = emac.tx_index;
597 #endif
598   tx_desc[emac.tx_index].CtrlStat = ctrl | EMAC_TDES0_OWN;
599 
600   if (++emac.tx_index == NUM_TX_BUF) emac.tx_index = 0;
601   emac.frame_end = NULL;
602 
603   /* Start frame transmission */
604   ENET->DMA_STAT = EMAC_DSR_TPS;
605   ENET->DMA_TRANS_POLL_DEMAND = 0;
606 
607   return ARM_DRIVER_OK;
608 }
609 
610 /**
611   \fn          int32_t ReadFrame (uint8_t *frame, uint32_t len)
612   \brief       Read data of received Ethernet frame.
613   \param[in]   frame  Pointer to frame buffer for data to read into
614   \param[in]   len    Frame buffer length in bytes
615   \return      number of data bytes read or execution status
616                  - value >= 0: number of data bytes read
617                  - value < 0: error occurred, value is execution status as defined with \ref execution_status
618 */
ReadFrame(uint8_t * frame,uint32_t len)619 static int32_t ReadFrame (uint8_t *frame, uint32_t len) {
620   uint8_t const *src;
621   int32_t cnt = (int32_t)len;
622 
623   if (!frame && len) {
624     /* Invalid parameters */
625     return ARM_DRIVER_ERROR_PARAMETER;
626   }
627 
628   if (!(emac.flags & EMAC_FLAG_POWER)) {
629     /* Driver not yet powered */
630     return ARM_DRIVER_ERROR;
631   }
632 
633   /* Fast-copy data to packet buffer */
634   src = rx_desc[emac.rx_index].Addr;
635   for ( ; len > 7; frame += 8, src += 8, len -= 8) {
636     ((__packed uint32_t *)frame)[0] = ((uint32_t *)src)[0];
637     ((__packed uint32_t *)frame)[1] = ((uint32_t *)src)[1];
638   }
639   /* Copy remaining 7 bytes */
640   for ( ; len > 1; frame += 2, src += 2, len -= 2) {
641     ((__packed uint16_t *)frame)[0] = ((uint16_t *)src)[0];
642   }
643   if (len > 0) frame[0] = src[0];
644 
645   /* Return this block back to EMAC-DMA */
646   rx_desc[emac.rx_index].Stat = EMAC_RDES0_OWN;
647 
648   if (++emac.rx_index == NUM_RX_BUF) emac.rx_index = 0;
649 
650   if (ENET->DMA_STAT & EMAC_DSR_RU) {
651     /* Receive buffer unavailable, resume DMA */
652     ENET->DMA_STAT = EMAC_DSR_RU;
653     ENET->DMA_REC_POLL_DEMAND = 0;
654   }
655   return (cnt);
656 }
657 
658 /**
659   \fn          uint32_t GetRxFrameSize (void)
660   \brief       Get size of received Ethernet frame.
661   \return      number of bytes in received frame
662 */
GetRxFrameSize(void)663 static uint32_t GetRxFrameSize (void) {
664   uint32_t stat;
665 
666   if (!(emac.flags & EMAC_FLAG_POWER)) {
667     /* Driver not yet powered */
668     return (0);
669   }
670 
671   stat = rx_desc[emac.rx_index].Stat;
672   if (stat & EMAC_RDES0_OWN) {
673     /* Owned by DMA */
674     return (0);
675   }
676 
677   if ((stat & EMAC_RDES0_ES) || !(stat & EMAC_RDES0_FS) || !(stat & EMAC_RDES0_LS)) {
678     /* Error, this block is invalid */
679     return (0xFFFFFFFF);
680   }
681   return (((stat & EMAC_RDES0_FL) >> 16) - 4);
682 }
683 
684 /**
685   \fn          int32_t GetRxFrameTime (ARM_ETH_MAC_TIME *time)
686   \brief       Get time of received Ethernet frame.
687   \param[in]   time  Pointer to time structure for data to read into
688   \return      \ref execution_status
689 */
GetRxFrameTime(ARM_ETH_MAC_TIME * time)690 static int32_t GetRxFrameTime (ARM_ETH_MAC_TIME *time) {
691 #if (EMAC_TIME_STAMP)
692   RX_Desc *rxd;
693 
694   if (!time) {
695     /* Invalid parameters */
696     return ARM_DRIVER_ERROR_PARAMETER;
697   }
698 
699   rxd = &rx_desc[emac.rx_index];
700   if (rxd->Stat & EMAC_RDES0_OWN) {
701     /* Owned by DMA */
702     return ARM_DRIVER_ERROR_BUSY;
703   }
704   time->ns  = rxd->TimeLo;
705   time->sec = rxd->TimeHi;
706 
707   return ARM_DRIVER_OK;
708 #else
709   return ARM_DRIVER_ERROR_UNSUPPORTED;
710 #endif
711 }
712 
713 /**
714   \fn          int32_t GetTxFrameTime (ARM_ETH_MAC_TIME *time)
715   \brief       Get time of transmitted Ethernet frame.
716   \param[in]   time  Pointer to time structure for data to read into
717   \return      \ref execution_status
718 */
GetTxFrameTime(ARM_ETH_MAC_TIME * time)719 static int32_t GetTxFrameTime (ARM_ETH_MAC_TIME *time) {
720 #if (EMAC_TIME_STAMP)
721   TX_Desc *txd;
722 
723   if (!time) {
724     /* Invalid parameters */
725     return ARM_DRIVER_ERROR_PARAMETER;
726   }
727 
728   txd = &tx_desc[emac.tx_ts_index];
729   if (txd->CtrlStat & EMAC_TDES0_OWN) {
730     /* Owned by DMA */
731     return ARM_DRIVER_ERROR_BUSY;
732   }
733   if (!(txd->CtrlStat & EMAC_TDES0_TTSS)) {
734     /* No transmit time stamp available */
735     return ARM_DRIVER_ERROR;
736   }
737   time->ns  = txd->TimeLo;
738   time->sec = txd->TimeHi;
739   return ARM_DRIVER_OK;
740 #else
741   return ARM_DRIVER_ERROR_UNSUPPORTED;
742 #endif
743 }
744 
745 /**
746   \fn          int32_t Control (uint32_t control, uint32_t arg)
747   \brief       Control Ethernet Interface.
748   \param[in]   control  Operation
749   \param[in]   arg      Argument of operation (optional)
750   \return      \ref execution_status
751 */
Control(uint32_t control,uint32_t arg)752 static int32_t Control (uint32_t control, uint32_t arg) {
753   uint32_t maccr;
754   uint32_t macffr;
755 
756   if (!(emac.flags & EMAC_FLAG_POWER)) {
757     /* Driver not powered */
758     return ARM_DRIVER_ERROR;
759   }
760 
761   switch (control) {
762     case ARM_ETH_MAC_CONFIGURE:
763       maccr = ENET->MAC_CONFIG & ~(EMAC_MCR_FES | EMAC_MCR_DM | EMAC_MCR_LM);
764 
765       /* Configure 100MBit/10MBit mode */
766       switch (arg & ARM_ETH_MAC_SPEED_Msk) {
767         case ARM_ETH_MAC_SPEED_10M:
768 #if (RTE_ENET_RMII)
769           /* RMII Half Duplex Collision detection does not work */
770           maccr |= EMAC_MCR_DM;
771 #endif
772           break;
773         case ARM_ETH_SPEED_100M:
774           maccr |= EMAC_MCR_FES;
775           break;
776         default:
777           return ARM_DRIVER_ERROR_UNSUPPORTED;
778       }
779 
780       /* Configure Half/Full duplex mode */
781       switch (arg & ARM_ETH_MAC_DUPLEX_Msk) {
782         case ARM_ETH_MAC_DUPLEX_FULL:
783           maccr |= EMAC_MCR_DM;
784           break;
785       }
786 
787       /* Configure loopback mode */
788       if (arg & ARM_ETH_MAC_LOOPBACK) {
789         maccr |= EMAC_MCR_LM;
790       }
791 
792       if ((arg & ARM_ETH_MAC_CHECKSUM_OFFLOAD_RX) ||
793           (arg & ARM_ETH_MAC_CHECKSUM_OFFLOAD_TX)) {
794         /* Checksum offload is disabled in the driver */
795         return ARM_DRIVER_ERROR_UNSUPPORTED;
796       }
797 
798       ENET->MAC_CONFIG = maccr;
799 
800       macffr = ENET->MAC_FRAME_FILTER & ~(EMAC_MFFR_PR | EMAC_MFFR_PAM | EMAC_MFFR_DBF);
801       /* Enable broadcast frame receive */
802       if (!(arg & ARM_ETH_MAC_ADDRESS_BROADCAST)) {
803         macffr |= EMAC_MFFR_DBF;
804       }
805 
806       /* Enable all multicast frame receive */
807       if (arg & ARM_ETH_MAC_ADDRESS_MULTICAST) {
808         macffr |= EMAC_MFFR_PAM;
809       }
810 
811       /* Enable promiscuous mode (no filtering) */
812       if (arg & ARM_ETH_MAC_ADDRESS_ALL) {
813         macffr |= EMAC_MFFR_PR;
814       }
815       ENET->MAC_FRAME_FILTER = macffr;
816 
817       break;
818 
819     case ARM_ETH_MAC_CONTROL_TX:
820       /* Enable/disable MAC transmitter */
821       if (arg != 0) {
822         ENET->MAC_CONFIG  |= EMAC_MCR_TE;
823         ENET->DMA_OP_MODE |= EMAC_DOMR_ST;
824       }
825       else {
826         ENET->DMA_OP_MODE &= ~EMAC_DOMR_ST;
827         ENET->MAC_CONFIG  &= ~EMAC_MCR_TE;
828       }
829       break;
830 
831     case ARM_ETH_MAC_CONTROL_RX:
832       /* Enable/disable MAC receiver */
833       if (arg != 0) {
834         ENET->MAC_CONFIG  |= EMAC_MCR_RE;
835         ENET->DMA_OP_MODE |= EMAC_DOMR_SR;
836       }
837       else {
838         ENET->DMA_OP_MODE &= ~EMAC_DOMR_SR;
839         ENET->MAC_CONFIG  &= ~EMAC_MCR_RE;
840       }
841       break;
842 
843     case ARM_ETH_MAC_FLUSH:
844       /* Flush Tx and Rx buffers */
845       if (arg & ARM_ETH_MAC_FLUSH_RX) {
846         /* Stop/Start DMA Receive */
847         uint32_t domr = ENET->DMA_OP_MODE;
848         ENET->DMA_OP_MODE &= ~EMAC_DOMR_SR;
849         init_rx_desc ();
850         ENET->DMA_OP_MODE = domr;
851       }
852       if (arg & ARM_ETH_MAC_FLUSH_TX) {
853         /* Stop/Start DMA Transmit */
854         uint32_t domr = ENET->DMA_OP_MODE;
855         ENET->DMA_OP_MODE &= ~EMAC_DOMR_ST;
856         /* Flush transmit FIFO */
857         ENET->DMA_OP_MODE |= EMAC_DOMR_FTF;
858         init_tx_desc ();
859         ENET->DMA_OP_MODE = domr;
860       }
861       break;
862 
863     case ARM_ETH_MAC_SLEEP:
864       /* Enable/disable Sleep mode */
865       if (arg != 0) {
866         /* Enable Power Management interrupts */
867         ENET->MAC_INTR_MASK    &= ~EMAC_MIMR_PMTIM;
868         /* Enter Power-down, Magic packet enable */
869         ENET->MAC_PMT_CTRL_STAT = EMAC_PMTR_MPE | EMAC_PMTR_PD;
870       }
871       else {
872         /* Disable Power Management interrupts */
873         ENET->MAC_INTR_MASK    |= EMAC_MIMR_PMTIM;
874         ENET->MAC_PMT_CTRL_STAT = 0x00000000;
875       }
876       break;
877 
878     case ARM_ETH_MAC_VLAN_FILTER:
879       /* Configure VLAN filter */
880       ENET->MAC_VLAN_TAG = arg;
881       break;
882 
883     default:
884       return ARM_DRIVER_ERROR_UNSUPPORTED;
885   }
886   return ARM_DRIVER_OK;
887 }
888 
889 /**
890   \fn          int32_t ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time)
891   \brief       Control Precision Timer.
892   \param[in]   control  Operation
893   \param[in]   time     Pointer to time structure
894   \return      \ref execution_status
895 */
ControlTimer(uint32_t control,ARM_ETH_MAC_TIME * time)896 static int32_t ControlTimer (uint32_t control, ARM_ETH_MAC_TIME *time) {
897 
898 #if (EMAC_TIME_STAMP)
899   if (!(emac.flags & EMAC_FLAG_POWER)) {
900     /* Driver not powered */
901     return ARM_DRIVER_ERROR;
902   }
903 
904   switch (control) {
905     case ARM_ETH_MAC_TIMER_GET_TIME:
906       /* Get current time */
907       time->sec = ENET->SECONDS;
908       time->ns  = ENET->NANOSECONDS;
909       break;
910 
911     case ARM_ETH_MAC_TIMER_SET_TIME:
912       /* Set new time */
913       ENET->SECONDSUPDATE     = time->sec;
914       ENET->NANOSECONDSUPDATE = time->ns;
915       /* Initialize precision timer */
916       ENET->MAC_TIMESTP_CTRL |= EMAC_MTCR_TSINIT;
917       break;
918 
919     case ARM_ETH_MAC_TIMER_INC_TIME:
920       /* Increment current time */
921       ENET->SECONDSUPDATE     = time->sec;
922       ENET->NANOSECONDSUPDATE = time->ns;
923       /* Update precision timer */
924       ENET->MAC_TIMESTP_CTRL |=  EMAC_MTCR_TSUPDT;
925       break;
926 
927     case ARM_ETH_MAC_TIMER_DEC_TIME:
928       /* Decrement current time */
929       ENET->SECONDSUPDATE     = time->sec;
930       ENET->NANOSECONDSUPDATE = time->ns | 0x80000000;
931       /* Update precision timer */
932       ENET->MAC_TIMESTP_CTRL |=  EMAC_MTCR_TSUPDT;
933       break;
934 
935     case ARM_ETH_MAC_TIMER_SET_ALARM:
936       /* Set alarm time */
937       ENET->TARGETSECONDS     = time->sec;
938       ENET->TARGETNANOSECONDS = time->ns;
939       /* Enable timestamp interrupt trigger */
940       ENET->MAC_TIMESTP_CTRL |= EMAC_MTCR_TSTRIG;
941       if (time->sec || time->ns) {
942         /* Enable timestamp interrupts */
943         ENET->MAC_INTR_MASK &= ~EMAC_MIMR_TSIM;
944         break;
945       }
946       /* Disable timestamp interrupts */
947       ENET->MAC_INTR_MASK |= EMAC_MIMR_TSIM;
948       break;
949 
950     case ARM_ETH_MAC_TIMER_ADJUST_CLOCK:
951       /* Adjust current time, fine correction */
952       /* Correction factor is Q31 (0x80000000 = 1.000000000) */
953       ENET->ADDEND = ((uint64_t)time->ns * ENET->ADDEND) >> 31;
954       /* Update addend register */
955       ENET->MAC_TIMESTP_CTRL |= EMAC_MTCR_TSADDR;
956       break;
957 
958     default:
959       return ARM_DRIVER_ERROR_UNSUPPORTED;
960   }
961   return ARM_DRIVER_OK;
962 #else
963   return ARM_DRIVER_ERROR_UNSUPPORTED;
964 #endif
965 }
966 
967 /**
968   \fn          int32_t PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
969   \brief       Read Ethernet PHY Register through Management Interface.
970   \param[in]   phy_addr  5-bit device address
971   \param[in]   reg_addr  5-bit register address
972   \param[out]  data      Pointer where the result is written to
973   \return      \ref execution_status
974 */
PHY_Read(uint8_t phy_addr,uint8_t reg_addr,uint16_t * data)975 static int32_t PHY_Read (uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) {
976   uint32_t tick;
977 
978   if (!data) {
979     /* Invalid parameter */
980     return ARM_DRIVER_ERROR_PARAMETER;
981   }
982 
983   if (!(emac.flags & EMAC_FLAG_POWER)) {
984     /* Driver not powered */
985     return ARM_DRIVER_ERROR;
986   }
987 
988   ENET->MAC_MII_ADDR  = emac.mmar_cr_val | EMAC_MMAR_GB |
989                         (phy_addr << 11) | (reg_addr << 6);
990 
991   /* Wait until operation completed */
992   tick = osKernelSysTick();
993   do {
994     if (!(ENET->MAC_MII_ADDR & EMAC_MMAR_GB)) {
995       *data = ENET->MAC_MII_DATA & EMAC_MMDR_GD;
996       return ARM_DRIVER_OK;
997     }
998   } while ((osKernelSysTick() - tick) < osKernelSysTickMicroSec(PHY_TIMEOUT));
999 
1000   if (!(ENET->MAC_MII_ADDR & EMAC_MMAR_GB)) {
1001     *data = ENET->MAC_MII_DATA & EMAC_MMDR_GD;
1002     return ARM_DRIVER_OK;
1003   }
1004   return ARM_DRIVER_ERROR_TIMEOUT;
1005 }
1006 
1007 /**
1008   \fn          int32_t PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
1009   \brief       Write Ethernet PHY Register through Management Interface.
1010   \param[in]   phy_addr  5-bit device address
1011   \param[in]   reg_addr  5-bit register address
1012   \param[in]   data      16-bit data to write
1013   \return      \ref execution_status
1014 */
PHY_Write(uint8_t phy_addr,uint8_t reg_addr,uint16_t data)1015 static int32_t PHY_Write (uint8_t phy_addr, uint8_t reg_addr, uint16_t data) {
1016   uint32_t tick;
1017 
1018   if (!(emac.flags & EMAC_FLAG_POWER)) {
1019     /* Driver not powered */
1020     return ARM_DRIVER_ERROR;
1021   }
1022 
1023   ENET->MAC_MII_DATA  = data;
1024   ENET->MAC_MII_ADDR  = emac.mmar_cr_val | EMAC_MMAR_GB | EMAC_MMAR_W |
1025                         (phy_addr << 11) | (reg_addr << 6);
1026 
1027   /* Wait until operation completed */
1028   tick = osKernelSysTick();
1029   do {
1030     if (!(ENET->MAC_MII_ADDR & EMAC_MMAR_GB)) {
1031       return ARM_DRIVER_OK;
1032     }
1033   } while ((osKernelSysTick() - tick) < osKernelSysTickMicroSec(PHY_TIMEOUT));
1034 
1035   if (!(ENET->MAC_MII_ADDR & EMAC_MMAR_GB)) {
1036     return ARM_DRIVER_OK;
1037   }
1038   return ARM_DRIVER_ERROR_TIMEOUT;
1039 }
1040 
1041 /**
1042   \fn          void ETH_IRQHandler (void)
1043   \brief       Ethernet Interrupt handler.
1044 */
ETH_IRQHandler(void)1045 void ETH_IRQHandler (void) {
1046   uint32_t stat,event = 0;
1047 
1048   stat = ENET->DMA_STAT;
1049   ENET->DMA_STAT = stat & (EMAC_DSR_NIS | EMAC_DSR_RI | EMAC_DSR_TI);
1050   if (stat & EMAC_DSR_TI) {
1051     /* Transmit interrupt */
1052     event |= ARM_ETH_MAC_EVENT_TX_FRAME;
1053   }
1054   if (stat & EMAC_DSR_RI) {
1055     /* Receive interrupt */
1056     event |= ARM_ETH_MAC_EVENT_RX_FRAME;
1057   }
1058   stat = ENET->MAC_INTR;
1059 #if (EMAC_TIME_STAMP)
1060   if (stat & EMAC_MISR_TS) {
1061     /* Timestamp interrupt */
1062     if (ENET->TIMESTAMPSTAT & EMAC_MTSR_TSTARGT) {
1063       /* Alarm trigger interrupt */
1064       event |= ARM_ETH_MAC_EVENT_TIMER_ALARM;
1065     }
1066   }
1067 #endif
1068   if (stat & EMAC_MISR_PMT) {
1069     /* Power management interrupt */
1070     if (ENET->MAC_PMT_CTRL_STAT & EMAC_PMTR_MPR) {
1071       /* Magic packet received */
1072       event |= ARM_ETH_MAC_EVENT_WAKEUP;
1073     }
1074   }
1075   /* Callback event notification */
1076   if (event && emac.cb_event) {
1077     emac.cb_event (event);
1078   }
1079 }
1080 
1081 /* MAC Driver Control Block */
1082 ARM_DRIVER_ETH_MAC Driver_ETH_MAC0 = {
1083   GetVersion,
1084   GetCapabilities,
1085   Initialize,
1086   Uninitialize,
1087   PowerControl,
1088   GetMacAddress,
1089   SetMacAddress,
1090   SetAddressFilter,
1091   SendFrame,
1092   ReadFrame,
1093   GetRxFrameSize,
1094   GetRxFrameTime,
1095   GetTxFrameTime,
1096   ControlTimer,
1097   Control,
1098   PHY_Read,
1099   PHY_Write
1100 };
1101