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 != ð_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 != ð_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