aps3_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file aps3_eth_driver.c
3  * @brief Cortus APS3 Ethernet MAC controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include <machine/sfradr.h>
36 #include <machine/sfradr_eth.h>
37 #include <machine/ethernet.h>
38 #include <machine/ic.h>
39 #undef _ETHERNET_H
40 #include "core/net.h"
42 #include "debug.h"
43 
44 //Transmit buffer
45 #define txBuffer ((uint8_t *) SFRADR_ETH_TX_MEM_BOTTOM_AD)
46 //Receive buffer
47 #define rxBuffer ((uint8_t *) SFRADR_ETH_RX_MEM_BOTTOM_AD)
48 
49 //Transmit DMA descriptors
50 #define txDmaDesc ((Aps3TxDmaDesc *) (SFRADR_ETH_TX_MEM_BOTTOM_AD + \
51  APS3_ETH_TX_BUFFER_COUNT * APS3_ETH_TX_BUFFER_SIZE))
52 
53 //Receive DMA descriptors
54 #define rxDmaDesc ((Aps3RxDmaDesc *) (SFRADR_ETH_RX_MEM_BOTTOM_AD + \
55  APS3_ETH_RX_BUFFER_COUNT * APS3_ETH_RX_BUFFER_SIZE))
56 
57 //Underlying network interface
58 static NetInterface *nicDriverInterface;
59 
60 
61 /**
62  * @brief Cortus APS3 Ethernet MAC driver
63  **/
64 
66 {
68  ETH_MTU,
79  TRUE,
80  TRUE,
81  TRUE,
82  FALSE
83 };
84 
85 
86 /**
87  * @brief Cortus APS3 Ethernet MAC initialization
88  * @param[in] interface Underlying network interface
89  * @return Error code
90  **/
91 
93 {
94  error_t error;
95 
96  //Debug message
97  TRACE_INFO("Initializing Cortus APS3 Ethernet MAC...\r\n");
98 
99  //Save underlying network interface
100  nicDriverInterface = interface;
101 
102  //Adjust MDC clock range
103  eth_miim->miim_clock_divider = 32;
104 
105  //PHY transceiver initialization
106  error = interface->phyDriver->init(interface);
107  //Failed to initialize PHY transceiver?
108  if(error)
109  return error;
110 
111  //Reset Ethernet MAC peripheral
112  eth_mac->sw_reset = 1;
113 
114  //Set the MAC address of the station
115  eth_mac->addr_low = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
116  eth_mac->addr_high = interface->macAddr.w[2];
117 
118  //Initialize hash table
119  eth_mac->hash_filter_low = 0;
120  eth_mac->hash_filter_high = 0;
121 
122  //Configure the receive filter
123  eth_mac->unicast = 1;
124  eth_mac->multicast = 0;
125  eth_mac->broadcast = 1;
126  eth_mac->hash = 1;
127  eth_mac->exact_addr = 1;
128 
129  //Default duplex mode
130  eth_mac->full_duplex = 0;
131 
132  //Automatic padding and CRC generation
133  eth_mac->no_padding = 0;
134  eth_mac->crc_disable = 0;
135 
136  //Set the maximum frame length
137  eth_mac->max_frame_size = APS3_ETH_RX_BUFFER_SIZE;
138 
139  //Set transmit and receive thresholds
140  eth_tx->tx_threshold = 0;
141  eth_rx->rx_threshold = 0;
142 
143  //Disable indefinite deferral
144  eth_mac->indefinite_deferral = 0;
145  //Number of attempts to transmit a frame before aborting
146  eth_mac->max_deferral = 15;
147 
148  //Use default collision window (112 half-octets)
149  eth_mac->collision_window = 111;
150  //Maximum Number of Collisions
151  eth_mac->max_collision = 15;
152 
153  //Automatic backoff on collision
154  eth_mac->no_backoff = 0;
155 
156  //Use the default interframe gap (24 half-octets or 96 bits)
157  eth_mac->interframe_gap = 23;
158 
159  //Initialize DMA descriptor lists
160  aps3EthInitDmaDesc(interface);
161 
162  //Configure TX interrupts
163  eth_tx->tx_irq_mask = TX_IRQ_MASK_MEMORY_AVAILABLE;
164  //Configure RX interrupts
165  eth_rx->rx_irq_mask = RX_IRQ_MASK_FRAME_READY;
166 
167  //Configure TX interrupt priority
168  irq[IRQ_ETH_TX].ipl = APS3_ETH_IRQ_PRIORITY;
169  //Configure RX interrupt priority
170  irq[IRQ_ETH_RX].ipl = APS3_ETH_IRQ_PRIORITY;
171 
172  //Enable transmission and reception
173  eth_tx->tx_enable = 1;
174  eth_rx->rx_enable = 1;
175 
176  //Accept any packets from the upper layer
177  osSetEvent(&interface->nicTxEvent);
178 
179  //Successful initialization
180  return NO_ERROR;
181 }
182 
183 
184 /**
185  * @brief Initialize DMA descriptor lists
186  * @param[in] interface Underlying network interface
187  **/
188 
190 {
191  uint_t i;
192 
193  //Initialize TX DMA descriptor list
194  for(i = 0; i < APS3_ETH_TX_BUFFER_COUNT; i++)
195  {
196  //Transmit buffer address
197  txDmaDesc[i].addr = (uint32_t) txBuffer + (APS3_ETH_TX_BUFFER_SIZE * i);
198  //Transmit buffer size
199  txDmaDesc[i].size = 0;
200  //Transmit status
201  txDmaDesc[i].status = 0;
202  }
203 
204  //Initialize RX DMA descriptor list
205  for(i = 0; i < APS3_ETH_RX_BUFFER_COUNT; i++)
206  {
207  //Receive buffer address
208  rxDmaDesc[i].addr = (uint32_t) rxBuffer + (APS3_ETH_RX_BUFFER_SIZE * i);
209  //Receive buffer size
210  rxDmaDesc[i].size = 0;
211  //Receive status
212  rxDmaDesc[i].status = 0;
213  }
214 
215  //Start location of the TX descriptor list
216  eth_tx->tx_desc_base_addr = (uint32_t) txDmaDesc;
217  //Number of TX descriptors
218  eth_tx->tx_desc_number = APS3_ETH_TX_BUFFER_COUNT - 1;
219 
220  //Start location of the RX descriptor list
221  eth_rx->rx_desc_base_addr = (uint32_t) rxDmaDesc;
222  //Number of RX descriptors
223  eth_rx->rx_desc_number = APS3_ETH_RX_BUFFER_COUNT - 1;
224 }
225 
226 
227 /**
228  * @brief Cortus APS3 Ethernet MAC timer handler
229  *
230  * This routine is periodically called by the TCP/IP stack to
231  * handle periodic operations such as polling the link state
232  *
233  * @param[in] interface Underlying network interface
234  **/
235 
236 void aps3EthTick(NetInterface *interface)
237 {
238  //Handle periodic operations
239  interface->phyDriver->tick(interface);
240 }
241 
242 
243 /**
244  * @brief Enable interrupts
245  * @param[in] interface Underlying network interface
246  **/
247 
249 {
250  //Enable Ethernet MAC interrupts
251  irq[IRQ_ETH_TX].ien = 1;
252  irq[IRQ_ETH_RX].ien = 1;
253 
254  //Enable Ethernet PHY interrupts
255  interface->phyDriver->enableIrq(interface);
256 }
257 
258 
259 /**
260  * @brief Disable interrupts
261  * @param[in] interface Underlying network interface
262  **/
263 
265 {
266  //Disable Ethernet MAC interrupts
267  irq[IRQ_ETH_TX].ien = 0;
268  irq[IRQ_ETH_RX].ien = 0;
269 
270  //Disable Ethernet PHY interrupts
271  interface->phyDriver->disableIrq(interface);
272 }
273 
274 
275 /**
276  * @brief Ethernet MAC transmit interrupt service routine
277  **/
278 
280 {
281  bool_t flag;
282 
283  //Interrupt service routine prologue
284  osEnterIsr();
285 
286  //This flag will be set if a higher priority task must be woken
287  flag = FALSE;
288 
289  //Check interrupt flag
290  if(eth_tx->tx_status & TX_IRQ_MASK_MEMORY_AVAILABLE)
291  {
292  //Disable TX interrupts
293  eth_tx->tx_irq_mask = 0;
294 
295  //Check whether the TX buffer is available for writing
296  if(!(eth_tx->tx_desc_status))
297  {
298  //Notify the TCP/IP stack that the transmitter is ready to send
299  flag = osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
300  }
301  }
302 
303  //Interrupt service routine epilogue
304  osExitIsr(flag);
305 }
306 
307 
308 /**
309  * @brief Ethernet MAC receive interrupt service routine
310  **/
311 
313 {
314  bool_t flag;
315 
316  //Interrupt service routine prologue
317  osEnterIsr();
318 
319  //This flag will be set if a higher priority task must be woken
320  flag = FALSE;
321 
322  //Disable RX interrupts
323  eth_rx->rx_irq_mask = 0;
324 
325  //Set event flag
326  nicDriverInterface->nicEvent = TRUE;
327  //Notify the TCP/IP stack of the event
328  flag = osSetEventFromIsr(&netEvent);
329 
330  //Interrupt service routine epilogue
331  osExitIsr(flag);
332 }
333 
334 
335 /**
336  * @brief Cortus APS3 Ethernet MAC event handler
337  * @param[in] interface Underlying network interface
338  **/
339 
341 {
342  error_t error;
343 
344  //A packet has been received?
345  if(eth_rx->rx_status & RX_IRQ_MASK_FRAME_READY)
346  {
347  //Process all pending packets
348  do
349  {
350  //Read incoming packet
351  error = aps3EthReceivePacket(interface);
352 
353  //No more data in the receive buffer?
354  } while(error != ERROR_BUFFER_EMPTY);
355  }
356 
357  //Re-enable RX interrupts
358  eth_rx->rx_irq_mask = RX_IRQ_MASK_FRAME_READY;
359 }
360 
361 
362 /**
363  * @brief Send a packet
364  * @param[in] interface Underlying network interface
365  * @param[in] buffer Multi-part buffer containing the data to send
366  * @param[in] offset Offset to the first data byte
367  * @return Error code
368  **/
369 
371  const NetBuffer *buffer, size_t offset)
372 {
373  uint_t i;
374  size_t length;
375 
376  //Retrieve the length of the packet
377  length = netBufferGetLength(buffer) - offset;
378 
379  //Check the frame length
381  {
382  //The transmitter can accept another packet
383  osSetEvent(&interface->nicTxEvent);
384  //Report an error
385  return ERROR_INVALID_LENGTH;
386  }
387 
388  //Make sure the current buffer is available for writing
389  if(eth_tx->tx_desc_status)
390  {
391  //Re-enable TX interrupts
392  eth_tx->tx_irq_mask = TX_IRQ_MASK_MEMORY_AVAILABLE;
393  //Report an error
394  return ERROR_FAILURE;
395  }
396 
397  //Get the index of the current descriptor
398  i = eth_tx->tx_desc_produce;
399 
400  //Copy user data to the transmit buffer
401  netBufferRead((uint8_t *) txDmaDesc[i].addr, buffer, offset, length);
402  //Write the number of bytes to send
403  txDmaDesc[i].size = length;
404 
405  //Start transmission
406  eth_tx->tx_sw_done = 1;
407 
408  //Check whether the next buffer is available for writing
409  if(!eth_tx->tx_desc_status)
410  {
411  //The transmitter can accept another packet
412  osSetEvent(&interface->nicTxEvent);
413  }
414  else
415  {
416  //Re-enable TX interrupts
417  eth_tx->tx_irq_mask = TX_IRQ_MASK_MEMORY_AVAILABLE;
418  }
419 
420  //Data successfully written
421  return NO_ERROR;
422 }
423 
424 
425 /**
426  * @brief Receive a packet
427  * @param[in] interface Underlying network interface
428  * @return Error code
429  **/
430 
432 {
433  error_t error;
434  uint_t i;
435  size_t n;
436 
437  //The current buffer is available for reading?
438  if(!(eth_rx->rx_desc_status))
439  {
440  //Point to the current descriptor
441  i = eth_rx->rx_desc_consume;
442 
443  //Make sure no error occurred
444  if(!(rxDmaDesc[i].status & RX_DESC_RECEIVE_ERROR))
445  {
446  //Retrieve the length of the frame
447  n = rxDmaDesc[i].size;
448  //Limit the number of data to read
450 
451  //Pass the packet to the upper layer
452  nicProcessPacket(interface, (uint8_t *) rxDmaDesc[i].addr, n);
453 
454  //Valid packet received
455  error = NO_ERROR;
456  }
457  else
458  {
459  //The received packet contains an error
460  error = ERROR_INVALID_PACKET;
461  }
462 
463  //The frame has been has been processed by the software
464  //and is no longer needed
465  eth_rx->rx_sw_done = 1;
466  }
467  else
468  {
469  //No more data in the receive buffer
470  error = ERROR_BUFFER_EMPTY;
471  }
472 
473  //Return status code
474  return error;
475 }
476 
477 
478 /**
479  * @brief Configure MAC address filtering
480  * @param[in] interface Underlying network interface
481  * @return Error code
482  **/
483 
485 {
486  uint_t i;
487  uint_t k;
488  uint32_t crc;
489  uint32_t hashTable[2];
490  MacFilterEntry *entry;
491 
492  //Debug message
493  TRACE_DEBUG("Updating MAC filter...\r\n");
494 
495  //Set the MAC address of the station
496  eth_mac->addr_low = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
497  eth_mac->addr_high = interface->macAddr.w[2];
498 
499  //Clear hash table
500  hashTable[0] = 0;
501  hashTable[1] = 0;
502 
503  //The MAC address filter contains the list of MAC addresses to accept
504  //when receiving an Ethernet frame
505  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
506  {
507  //Point to the current entry
508  entry = &interface->macAddrFilter[i];
509 
510  //Valid entry?
511  if(entry->refCount > 0)
512  {
513  //Compute CRC over the current MAC address
514  crc = aps3EthCalcCrc(&entry->addr, sizeof(MacAddr));
515  //Calculate the corresponding index in the table
516  k = (crc >> 23) & 0x3F;
517  //Update hash table contents
518  hashTable[k / 32] |= (1 << (k % 32));
519  }
520  }
521 
522  //Disable transmission and reception
523  eth_tx->tx_enable = 0;
524  eth_rx->rx_enable = 0;
525 
526  //Write the hash table
527  eth_mac->hash_filter_low = hashTable[0];
528  eth_mac->hash_filter_high = hashTable[1];
529 
530  //Debug message
531  TRACE_DEBUG(" hash_filter_low = %08" PRIX32 "\r\n", hashTable[0]);
532  TRACE_DEBUG(" hash_filter_high = %08" PRIX32 "\r\n", hashTable[1]);
533 
534  //Re-enable transmission and reception
535  eth_tx->tx_enable = 1;
536  eth_rx->rx_enable = 1;
537 
538  //Successful processing
539  return NO_ERROR;
540 }
541 
542 
543 /**
544  * @brief Adjust MAC configuration parameters for proper operation
545  * @param[in] interface Underlying network interface
546  * @return Error code
547  **/
548 
550 {
551  //Disable transmission and reception
552  eth_tx->tx_enable = 0;
553  eth_rx->rx_enable = 0;
554 
555  //Half-duplex or full-duplex mode?
556  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
557  eth_mac->full_duplex = 1;
558  else
559  eth_mac->full_duplex = 0;
560 
561  //Re-enable transmission and reception
562  eth_tx->tx_enable = 1;
563  eth_rx->rx_enable = 1;
564 
565  //Successful processing
566  return NO_ERROR;
567 }
568 
569 
570 /**
571  * @brief Write PHY register
572  * @param[in] opcode Access type (2 bits)
573  * @param[in] phyAddr PHY address (5 bits)
574  * @param[in] regAddr Register address (5 bits)
575  * @param[in] data Register value
576  **/
577 
578 void aps3EthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
579  uint8_t regAddr, uint16_t data)
580 {
581  //Valid opcode?
582  if(opcode == SMI_OPCODE_WRITE)
583  {
584  //Wait for the MII management module to be ready
585  while(!eth_miim->miim_status)
586  {
587  }
588 
589  //PHY address
590  eth_miim->miim_phy_addr = phyAddr;
591  //Register address
592  eth_miim->miim_phy_register_addr = regAddr;
593  //Data to be written in the PHY register
594  eth_miim->miim_data = data;
595 
596  //Start a write operation
597  eth_miim->miim_read_write = 0;
598  //Wait for the write to complete
599  while(!eth_miim->miim_status)
600  {
601  }
602  }
603  else
604  {
605  //The MAC peripheral only supports standard Clause 22 opcodes
606  }
607 }
608 
609 
610 /**
611  * @brief Read PHY register
612  * @param[in] opcode Access type (2 bits)
613  * @param[in] phyAddr PHY address (5 bits)
614  * @param[in] regAddr Register address (5 bits)
615  * @return Register value
616  **/
617 
618 uint16_t aps3EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
619  uint8_t regAddr)
620 {
621  uint16_t data;
622 
623  //Valid opcode?
624  if(opcode == SMI_OPCODE_READ)
625  {
626  //Wait for the MII management module to be ready
627  while(!eth_miim->miim_status)
628  {
629  }
630 
631  //PHY address
632  eth_miim->miim_phy_addr = phyAddr;
633  //Register address
634  eth_miim->miim_phy_register_addr = regAddr;
635 
636  //Start a read operation
637  eth_miim->miim_read_write = 1;
638  //Wait for the read to complete
639  while(!eth_miim->miim_status)
640  {
641  }
642 
643  //Get register value
644  data = eth_miim->miim_data;
645  }
646  else
647  {
648  //The MAC peripheral only supports standard Clause 22 opcodes
649  data = 0;
650  }
651 
652  //Return the value of the PHY register
653  return data;
654 }
655 
656 
657 /**
658  * @brief CRC calculation
659  * @param[in] data Pointer to the data over which to calculate the CRC
660  * @param[in] length Number of bytes to process
661  * @return Resulting CRC value
662  **/
663 
664 uint32_t aps3EthCalcCrc(const void *data, size_t length)
665 {
666  uint_t i;
667  uint_t j;
668 
669  //Point to the data over which to calculate the CRC
670  const uint8_t *p = (uint8_t *) data;
671  //CRC preset value
672  uint32_t crc = 0xFFFFFFFF;
673 
674  //Loop through data
675  for(i = 0; i < length; i++)
676  {
677  //Update CRC value
678  crc ^= p[i];
679 
680  //The message is processed bit by bit
681  for(j = 0; j < 8; j++)
682  {
683  //Update CRC value
684  if(crc & 0x00000001)
685  crc = (crc >> 1) ^ 0xEDB88320;
686  else
687  crc = crc >> 1;
688  }
689  }
690 
691  //Return CRC value
692  return ~crc;
693 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define APS3_ETH_RX_BUFFER_COUNT
uint8_t length
Definition: dtls_misc.h:149
#define TX_IRQ_MASK_MEMORY_AVAILABLE
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:49
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:119
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:672
uint8_t p
Definition: ndp.h:298
#define APS3_ETH_IRQ_PRIORITY
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:383
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
#define TRUE
Definition: os_port.h:50
#define RX_IRQ_MASK_FRAME_READY
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:223
void aps3EthEventHandler(NetInterface *interface)
Cortus APS3 Ethernet MAC event handler.
void aps3EthDisableIrq(NetInterface *interface)
Disable interrupts.
uint16_t aps3EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
uint32_t aps3EthCalcCrc(const void *data, size_t length)
CRC calculation.
#define osExitIsr(flag)
#define SMI_OPCODE_WRITE
Definition: nic.h:62
#define FALSE
Definition: os_port.h:46
void aps3EthTxIrqHandler(void)
Ethernet MAC transmit interrupt service routine.
error_t
Error codes.
Definition: error.h:42
error_t aps3EthReceivePacket(NetInterface *interface)
Receive a packet.
error_t aps3EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define RX_DESC_RECEIVE_ERROR
#define txBuffer
@ ERROR_INVALID_PACKET
Definition: error.h:138
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:222
@ ERROR_INVALID_LENGTH
Definition: error.h:109
#define APS3_ETH_TX_BUFFER_COUNT
@ ERROR_BUFFER_EMPTY
Definition: error.h:139
void aps3EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
OsEvent netEvent
Definition: net.c:77
#define SMI_OPCODE_READ
Definition: nic.h:63
#define TRACE_INFO(...)
Definition: debug.h:94
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define MIN(a, b)
Definition: os_port.h:62
error_t aps3EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define rxBuffer
#define TRACE_DEBUG(...)
Definition: debug.h:106
void aps3EthEnableIrq(NetInterface *interface)
Enable interrupts.
const NicDriver aps3EthDriver
Cortus APS3 Ethernet MAC driver.
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:91
uint8_t n
MAC filter table entry.
Definition: ethernet.h:220
Cortus APS3 Ethernet MAC controller.
#define osEnterIsr()
void aps3EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
error_t aps3EthInit(NetInterface *interface)
Cortus APS3 Ethernet MAC initialization.
void aps3EthTick(NetInterface *interface)
Cortus APS3 Ethernet MAC timer handler.
#define rxDmaDesc
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define txDmaDesc
Ipv4Addr addr
Definition: nbns_common.h:121
#define APS3_ETH_TX_BUFFER_SIZE
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
#define APS3_ETH_RX_BUFFER_SIZE
NIC driver.
Definition: nic.h:179
error_t aps3EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
__start_packed struct @108 MacAddr
MAC address.
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:79
void aps3EthRxIrqHandler(void)
Ethernet MAC receive interrupt service routine.