m5531_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file m5531_eth_driver.c
3  * @brief Nuvoton M5531 Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 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 2.6.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "NuMicro.h"
36 #include "core/net.h"
38 #include "debug.h"
39 
40 //Underlying network interface
41 static NetInterface *nicDriverInterface;
42 
43 //IAR EWARM compiler?
44 #if defined(__ICCARM__)
45 
46 //Transmit buffer
47 #pragma data_alignment = 4
48 #pragma location = M5531_ETH_RAM_SECTION
50 //Receive buffer
51 #pragma data_alignment = 4
52 #pragma location = M5531_ETH_RAM_SECTION
54 //Transmit DMA descriptors
55 #pragma data_alignment = 8
56 #pragma location = M5531_ETH_RAM_SECTION
58 //Receive DMA descriptors
59 #pragma data_alignment = 8
60 #pragma location = M5531_ETH_RAM_SECTION
62 
63 //Keil MDK-ARM or GCC compiler?
64 #else
65 
66 //Transmit buffer
68  __attribute__((aligned(4), __section__(M5531_ETH_RAM_SECTION)));
69 //Receive buffer
71  __attribute__((aligned(4), __section__(M5531_ETH_RAM_SECTION)));
72 //Transmit DMA descriptors
74  __attribute__((aligned(8), __section__(M5531_ETH_RAM_SECTION)));
75 //Receive DMA descriptors
77  __attribute__((aligned(8), __section__(M5531_ETH_RAM_SECTION)));
78 
79 #endif
80 
81 //Pointer to the current TX DMA descriptor
82 static M5531TxDmaDesc *txCurDmaDesc;
83 //Pointer to the current RX DMA descriptor
84 static M5531RxDmaDesc *rxCurDmaDesc;
85 
86 
87 /**
88  * @brief M5531 Ethernet MAC driver
89  **/
90 
92 {
94  ETH_MTU,
105  TRUE,
106  TRUE,
107  TRUE,
108  FALSE
109 };
110 
111 
112 /**
113  * @brief M5531 Ethernet MAC initialization
114  * @param[in] interface Underlying network interface
115  * @return Error code
116  **/
117 
119 {
120  error_t error;
121 
122  //Debug message
123  TRACE_INFO("Initializing M5531 Ethernet MAC...\r\n");
124 
125  //Save underlying network interface
126  nicDriverInterface = interface;
127 
128  //GPIO configuration
129  m5531EthInitGpio(interface);
130 
131  //Reset EMAC module
132  SYS_ResetModule(SYS_EMAC0RST);
133  //Enable EMAC clock
134  CLK_EnableModuleClock(EMAC0_MODULE);
135 
136  //Perform a software reset
138  //Wait for the reset to complete
139  while((EMAC_BUS_MODE & EMAC_BUS_MODE_SWR) != 0)
140  {
141  }
142 
143  //Adjust MDC clock range depending on CSR frequency
145 
146  //Valid Ethernet PHY or switch driver?
147  if(interface->phyDriver != NULL)
148  {
149  //Ethernet PHY initialization
150  error = interface->phyDriver->init(interface);
151  }
152  else if(interface->switchDriver != NULL)
153  {
154  //Ethernet switch initialization
155  error = interface->switchDriver->init(interface);
156  }
157  else
158  {
159  //The interface is not properly configured
160  error = ERROR_FAILURE;
161  }
162 
163  //Any error to report?
164  if(error)
165  {
166  return error;
167  }
168 
169  //Use default MAC configuration
171 
172  //Configure MAC address filtering
173  m5531EthUpdateMacAddrFilter(interface);
174 
175  //Disable flow control
176  EMAC_FLOW_CONTROL = 0;
177  //Enable store and forward mode
179 
180  //Configure DMA bus mode
183 
184  //Initialize DMA descriptor lists
185  m5531EthInitDmaDesc(interface);
186 
187  //Disable MAC interrupts
189  //Enable the desired DMA interrupts
192 
193  //Set priority grouping (3 bits for pre-emption priority, no bits for subpriority)
194  NVIC_SetPriorityGrouping(M5531_ETH_IRQ_PRIORITY_GROUPING);
195 
196  //Configure Ethernet interrupt priority
197  NVIC_SetPriority(EMAC0_IRQn, NVIC_EncodePriority(M5531_ETH_IRQ_PRIORITY_GROUPING,
199 
200  //Enable MAC transmission and reception
202  //Enable DMA transmission and reception
204 
205  //Accept any packets from the upper layer
206  osSetEvent(&interface->nicTxEvent);
207 
208  //Successful initialization
209  return NO_ERROR;
210 }
211 
212 
213 /**
214  * @brief GPIO configuration
215  * @param[in] interface Underlying network interface
216  **/
217 
218 __weak_func void m5531EthInitGpio(NetInterface *interface)
219 {
220 //NuMaker-X-M55M1D evaluation board?
221 #if defined(USE_NUMAKER_X_M55M1D)
222  //Enable GPIO clocks
223  CLK_EnableModuleClock(GPIOA_MODULE);
224  CLK_EnableModuleClock(GPIOC_MODULE);
225  CLK_EnableModuleClock(GPIOE_MODULE);
226 
227  //Configure EMAC_RMII_RXERR (PA.6)
228  SET_EMAC0_RMII_RXERR_PA6();
229  //Configure EMAC_RMII_CRSDV (PA.7)
230  SET_EMAC0_RMII_CRSDV_PA7();
231  //Configure EMAC_RMII_RXD1 (PC.6)
232  SET_EMAC0_RMII_RXD1_PC6();
233  //Configure EMAC_RMII_RXD0 (PC.7)
234  SET_EMAC0_RMII_RXD0_PC7();
235  //Configure EMAC_RMII_REFCLK (PC.8)
236  SET_EMAC0_RMII_REFCLK_PC8();
237  //Configure EMAC_RMII_MDC (PE.8)
238  SET_EMAC0_RMII_MDC_PE8();
239  //Configure EMAC_RMII_MDIO (PE.9)
240  SET_EMAC0_RMII_MDIO_PE9();
241  //Configure EMAC_RMII_TXD0 (PE.10)
242  SET_EMAC0_RMII_TXD0_PE10();
243  //Configure EMAC_RMII_TXD1 (PE.11)
244  SET_EMAC0_RMII_TXD1_PE11();
245  //Configure EMAC_RMII_TXEN (PE.12)
246  SET_EMAC0_RMII_TXEN_PE12();
247 
248  //Enable high slew rate on RMII output pins
249  GPIO_SetSlewCtl(PE, BIT10 | BIT11 | BIT12, GPIO_SLEWCTL_FAST1);
250 #endif
251 }
252 
253 
254 /**
255  * @brief Initialize DMA descriptor lists
256  * @param[in] interface Underlying network interface
257  **/
258 
260 {
261  uint_t i;
262 
263  //Initialize TX DMA descriptor list
264  for(i = 0; i < M5531_ETH_TX_BUFFER_COUNT; i++)
265  {
266  //Use chain structure rather than ring structure
268  //Initialize transmit buffer size
269  txDmaDesc[i].tdes1 = 0;
270  //Transmit buffer address
271  txDmaDesc[i].tdes2 = (uint32_t) txBuffer[i];
272  //Next descriptor address
273  txDmaDesc[i].tdes3 = (uint32_t) &txDmaDesc[i + 1];
274  //Reserved fields
275  txDmaDesc[i].tdes4 = 0;
276  txDmaDesc[i].tdes5 = 0;
277  //Transmit frame time stamp
278  txDmaDesc[i].tdes6 = 0;
279  txDmaDesc[i].tdes7 = 0;
280  }
281 
282  //The last descriptor is chained to the first entry
283  txDmaDesc[i - 1].tdes3 = (uint32_t) &txDmaDesc[0];
284  //Point to the very first descriptor
285  txCurDmaDesc = &txDmaDesc[0];
286 
287  //Initialize RX DMA descriptor list
288  for(i = 0; i < M5531_ETH_RX_BUFFER_COUNT; i++)
289  {
290  //The descriptor is initially owned by the DMA
291  rxDmaDesc[i].rdes0 = EMAC_RDES0_OWN;
292  //Use chain structure rather than ring structure
294  //Receive buffer address
295  rxDmaDesc[i].rdes2 = (uint32_t) rxBuffer[i];
296  //Next descriptor address
297  rxDmaDesc[i].rdes3 = (uint32_t) &rxDmaDesc[i + 1];
298  //Extended status
299  rxDmaDesc[i].rdes4 = 0;
300  //Reserved field
301  rxDmaDesc[i].rdes5 = 0;
302  //Receive frame time stamp
303  rxDmaDesc[i].rdes6 = 0;
304  rxDmaDesc[i].rdes7 = 0;
305  }
306 
307  //The last descriptor is chained to the first entry
308  rxDmaDesc[i - 1].rdes3 = (uint32_t) &rxDmaDesc[0];
309  //Point to the very first descriptor
310  rxCurDmaDesc = &rxDmaDesc[0];
311 
312  //Start location of the TX descriptor list
314  //Start location of the RX descriptor list
316 }
317 
318 
319 /**
320  * @brief M5531 Ethernet MAC timer handler
321  *
322  * This routine is periodically called by the TCP/IP stack to handle periodic
323  * operations such as polling the link state
324  *
325  * @param[in] interface Underlying network interface
326  **/
327 
328 void m5531EthTick(NetInterface *interface)
329 {
330  //Valid Ethernet PHY or switch driver?
331  if(interface->phyDriver != NULL)
332  {
333  //Handle periodic operations
334  interface->phyDriver->tick(interface);
335  }
336  else if(interface->switchDriver != NULL)
337  {
338  //Handle periodic operations
339  interface->switchDriver->tick(interface);
340  }
341  else
342  {
343  //Just for sanity
344  }
345 }
346 
347 
348 /**
349  * @brief Enable interrupts
350  * @param[in] interface Underlying network interface
351  **/
352 
354 {
355  //Enable Ethernet MAC interrupts
356  NVIC_EnableIRQ(EMAC0_IRQn);
357 
358  //Valid Ethernet PHY or switch driver?
359  if(interface->phyDriver != NULL)
360  {
361  //Enable Ethernet PHY interrupts
362  interface->phyDriver->enableIrq(interface);
363  }
364  else if(interface->switchDriver != NULL)
365  {
366  //Enable Ethernet switch interrupts
367  interface->switchDriver->enableIrq(interface);
368  }
369  else
370  {
371  //Just for sanity
372  }
373 }
374 
375 
376 /**
377  * @brief Disable interrupts
378  * @param[in] interface Underlying network interface
379  **/
380 
382 {
383  //Disable Ethernet MAC interrupts
384  NVIC_DisableIRQ(EMAC0_IRQn);
385 
386  //Valid Ethernet PHY or switch driver?
387  if(interface->phyDriver != NULL)
388  {
389  //Disable Ethernet PHY interrupts
390  interface->phyDriver->disableIrq(interface);
391  }
392  else if(interface->switchDriver != NULL)
393  {
394  //Disable Ethernet switch interrupts
395  interface->switchDriver->disableIrq(interface);
396  }
397  else
398  {
399  //Just for sanity
400  }
401 }
402 
403 
404 /**
405  * @brief M5531 Ethernet MAC interrupt service routine
406  **/
407 
409 {
410  bool_t flag;
411  uint32_t status;
412 
413  //Interrupt service routine prologue
414  osEnterIsr();
415 
416  //This flag will be set if a higher priority task must be woken
417  flag = FALSE;
418 
419  //Read DMA status register
420  status = EMAC_STATUS;
421 
422  //Packet transmitted?
423  if((status & EMAC_STATUS_TI) != 0)
424  {
425  //Clear TI interrupt flag
427 
428  //Check whether the TX buffer is available for writing
429  if((txCurDmaDesc->tdes0 & EMAC_TDES0_OWN) == 0)
430  {
431  //Notify the TCP/IP stack that the transmitter is ready to send
432  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
433  }
434  }
435 
436  //Packet received?
437  if((status & EMAC_STATUS_RI) != 0)
438  {
439  //Clear RI interrupt flag
441 
442  //Set event flag
443  nicDriverInterface->nicEvent = TRUE;
444  //Notify the TCP/IP stack of the event
445  flag |= osSetEventFromIsr(&nicDriverInterface->netContext->event);
446  }
447 
448  //Clear NIS interrupt flag
450 
451  //Interrupt service routine epilogue
452  osExitIsr(flag);
453 }
454 
455 
456 /**
457  * @brief M5531 Ethernet MAC event handler
458  * @param[in] interface Underlying network interface
459  **/
460 
462 {
463  error_t error;
464 
465  //Process all pending packets
466  do
467  {
468  //Read incoming packet
469  error = m5531EthReceivePacket(interface);
470 
471  //No more data in the receive buffer?
472  } while(error != ERROR_BUFFER_EMPTY);
473 }
474 
475 
476 /**
477  * @brief Send a packet
478  * @param[in] interface Underlying network interface
479  * @param[in] buffer Multi-part buffer containing the data to send
480  * @param[in] offset Offset to the first data byte
481  * @param[in] ancillary Additional options passed to the stack along with
482  * the packet
483  * @return Error code
484  **/
485 
487  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
488 {
489  size_t length;
490 
491  //Retrieve the length of the packet
492  length = netBufferGetLength(buffer) - offset;
493 
494  //Check the frame length
496  {
497  //The transmitter can accept another packet
498  osSetEvent(&interface->nicTxEvent);
499  //Report an error
500  return ERROR_INVALID_LENGTH;
501  }
502 
503  //Make sure the current buffer is available for writing
504  if((txCurDmaDesc->tdes0 & EMAC_TDES0_OWN) != 0)
505  {
506  return ERROR_FAILURE;
507  }
508 
509  //Copy user data to the transmit buffer
510  netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length);
511 
512  //Write the number of bytes to send
513  txCurDmaDesc->tdes1 = length & EMAC_TDES1_TBS1;
514  //Set LS and FS flags as the data fits in a single buffer
515  txCurDmaDesc->tdes0 |= EMAC_TDES0_LS | EMAC_TDES0_FS;
516  //Give the ownership of the descriptor to the DMA
517  txCurDmaDesc->tdes0 |= EMAC_TDES0_OWN;
518 
519  //Data synchronization barrier
520  __DSB();
521 
522  //Clear TU flag to resume processing
524  //Instruct the DMA to poll the transmit descriptor list
526 
527  //Point to the next descriptor in the list
528  txCurDmaDesc = (M5531TxDmaDesc *) txCurDmaDesc->tdes3;
529 
530  //Check whether the next buffer is available for writing
531  if((txCurDmaDesc->tdes0 & EMAC_TDES0_OWN) == 0)
532  {
533  //The transmitter can accept another packet
534  osSetEvent(&interface->nicTxEvent);
535  }
536 
537  //Data successfully written
538  return NO_ERROR;
539 }
540 
541 
542 /**
543  * @brief Receive a packet
544  * @param[in] interface Underlying network interface
545  * @return Error code
546  **/
547 
549 {
550  error_t error;
551  size_t n;
552  NetRxAncillary ancillary;
553 
554  //Current buffer available for reading?
555  if((rxCurDmaDesc->rdes0 & EMAC_RDES0_OWN) == 0)
556  {
557  //FS and LS flags should be set
558  if((rxCurDmaDesc->rdes0 & EMAC_RDES0_FS) != 0 &&
559  (rxCurDmaDesc->rdes0 & EMAC_RDES0_LS) != 0)
560  {
561  //Make sure no error occurred
562  if((rxCurDmaDesc->rdes0 & EMAC_RDES0_ES) == 0)
563  {
564  //Retrieve the length of the frame
565  n = (rxCurDmaDesc->rdes0 & EMAC_RDES0_FL) >> 16;
566  //Limit the number of data to read
568 
569  //Additional options can be passed to the stack along with the packet
570  ancillary = NET_DEFAULT_RX_ANCILLARY;
571 
572  //Pass the packet to the upper layer
573  nicProcessPacket(interface, (uint8_t *) rxCurDmaDesc->rdes2, n,
574  &ancillary);
575 
576  //Valid packet received
577  error = NO_ERROR;
578  }
579  else
580  {
581  //The received packet contains an error
582  error = ERROR_INVALID_PACKET;
583  }
584  }
585  else
586  {
587  //The packet is not valid
588  error = ERROR_INVALID_PACKET;
589  }
590 
591  //Give the ownership of the descriptor back to the DMA
592  rxCurDmaDesc->rdes0 = EMAC_RDES0_OWN;
593  //Point to the next descriptor in the list
594  rxCurDmaDesc = (M5531RxDmaDesc *) rxCurDmaDesc->rdes3;
595  }
596  else
597  {
598  //No more data in the receive buffer
599  error = ERROR_BUFFER_EMPTY;
600  }
601 
602  //Clear RU flag to resume processing
604  //Instruct the DMA to poll the receive descriptor list
606 
607  //Return status code
608  return error;
609 }
610 
611 
612 /**
613  * @brief Configure MAC address filtering
614  * @param[in] interface Underlying network interface
615  * @return Error code
616  **/
617 
619 {
620  uint_t i;
621  uint_t j;
622  bool_t acceptMulticast;
623  MacAddr unicastMacAddr[3];
624  MacFilterEntry *entry;
625 
626  //Debug message
627  TRACE_DEBUG("Updating MAC filter...\r\n");
628 
629  //Set the MAC address of the station
630  EMAC_MAC_ADDR0_HIGH = interface->macAddr.w[2];
631  EMAC_MAC_ADDR0_LOW = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
632 
633  //The MAC supports 3 additional addresses for unicast perfect filtering
634  unicastMacAddr[0] = MAC_UNSPECIFIED_ADDR;
635  unicastMacAddr[1] = MAC_UNSPECIFIED_ADDR;
636  unicastMacAddr[2] = MAC_UNSPECIFIED_ADDR;
637 
638  //This flag will be set if multicast addresses should be accepted
639  acceptMulticast = FALSE;
640 
641  //The MAC address filter contains the list of MAC addresses to accept
642  //when receiving an Ethernet frame
643  for(i = 0, j = 0; i < MAC_ADDR_FILTER_SIZE; i++)
644  {
645  //Point to the current entry
646  entry = &interface->macAddrFilter[i];
647 
648  //Valid entry?
649  if(entry->refCount > 0)
650  {
651  //Multicast address?
652  if(macIsMulticastAddr(&entry->addr))
653  {
654  //Accept multicast addresses
655  acceptMulticast = TRUE;
656  }
657  else
658  {
659  //Up to 3 additional MAC addresses can be specified
660  if(j < 3)
661  {
662  //Save the unicast address
663  unicastMacAddr[j++] = entry->addr;
664  }
665  }
666  }
667  }
668 
669  //Configure the first unicast address filter
670  if(j >= 1)
671  {
672  EMAC_MAC_ADDR1_HIGH = unicastMacAddr[0].w[2] | EMAC_MAC_ADDR1_HIGH_AE;
673  EMAC_MAC_ADDR1_LOW = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
674  }
675  else
676  {
678  EMAC_MAC_ADDR1_LOW = 0;
679  }
680 
681  //Configure the second unicast address filter
682  if(j >= 2)
683  {
684  EMAC_MAC_ADDR2_HIGH = unicastMacAddr[1].w[2] | EMAC_MAC_ADDR2_HIGH_AE;
685  EMAC_MAC_ADDR2_LOW = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
686  }
687  else
688  {
690  EMAC_MAC_ADDR2_LOW = 0;
691  }
692 
693  //Configure the third unicast address filter
694  if(j >= 3)
695  {
696  EMAC_MAC_ADDR3_HIGH = unicastMacAddr[2].w[2] | EMAC_MAC_ADDR3_HIGH_AE;
697  EMAC_MAC_ADDR3_LOW = unicastMacAddr[2].w[0] | (unicastMacAddr[0].w[2] << 16);
698  }
699  else
700  {
702  EMAC_MAC_ADDR3_LOW = 0;
703  }
704 
705  //Enable or disable the reception of multicast frames
706  if(acceptMulticast)
707  {
709  }
710  else
711  {
713  }
714 
715  //Successful processing
716  return NO_ERROR;
717 }
718 
719 
720 /**
721  * @brief Adjust MAC configuration parameters for proper operation
722  * @param[in] interface Underlying network interface
723  * @return Error code
724  **/
725 
727 {
728  uint32_t config;
729 
730  //Read current MAC configuration
731  config = EMAC_MAC_CONFIG;
732 
733  //10BASE-T or 100BASE-TX operation mode?
734  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
735  {
736  config |= EMAC_MAC_CONFIG_FES;
737  }
738  else
739  {
740  config &= ~EMAC_MAC_CONFIG_FES;
741  }
742 
743  //Half-duplex or full-duplex mode?
744  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
745  {
746  config |= EMAC_MAC_CONFIG_DM;
747  }
748  else
749  {
750  config &= ~EMAC_MAC_CONFIG_DM;
751  }
752 
753  //Update MAC configuration register
754  EMAC_MAC_CONFIG = config;
755 
756  //Successful processing
757  return NO_ERROR;
758 }
759 
760 
761 /**
762  * @brief Write PHY register
763  * @param[in] opcode Access type (2 bits)
764  * @param[in] phyAddr PHY address (5 bits)
765  * @param[in] regAddr Register address (5 bits)
766  * @param[in] data Register value
767  **/
768 
769 void m5531EthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
770  uint8_t regAddr, uint16_t data)
771 {
772  uint32_t temp;
773 
774  //Valid opcode?
775  if(opcode == SMI_OPCODE_WRITE)
776  {
777  //Take care not to alter MDC clock configuration
779  //Set up a write operation
781  //PHY address
782  temp |= (phyAddr << 11) & EMAC_GMII_ADDR_PA;
783  //Register address
784  temp |= (regAddr << 6) & EMAC_GMII_ADDR_GR;
785 
786  //Data to be written in the PHY register
788 
789  //Start a write operation
790  EMAC_GMII_ADDR = temp;
791  //Wait for the write to complete
792  while((EMAC_GMII_ADDR & EMAC_GMII_ADDR_GB) != 0)
793  {
794  }
795  }
796  else
797  {
798  //The MAC peripheral only supports standard Clause 22 opcodes
799  }
800 }
801 
802 
803 /**
804  * @brief Read PHY register
805  * @param[in] opcode Access type (2 bits)
806  * @param[in] phyAddr PHY address (5 bits)
807  * @param[in] regAddr Register address (5 bits)
808  * @return Register value
809  **/
810 
811 uint16_t m5531EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
812  uint8_t regAddr)
813 {
814  uint16_t data;
815  uint32_t temp;
816 
817  //Valid opcode?
818  if(opcode == SMI_OPCODE_READ)
819  {
820  //Take care not to alter MDC clock configuration
822  //Set up a read operation
823  temp |= EMAC_GMII_ADDR_GB;
824  //PHY address
825  temp |= (phyAddr << 11) & EMAC_GMII_ADDR_PA;
826  //Register address
827  temp |= (regAddr << 6) & EMAC_GMII_ADDR_GR;
828 
829  //Start a read operation
830  EMAC_GMII_ADDR = temp;
831  //Wait for the read to complete
832  while((EMAC_GMII_ADDR & EMAC_GMII_ADDR_GB) != 0)
833  {
834  }
835 
836  //Get register value
838  }
839  else
840  {
841  //The MAC peripheral only supports standard Clause 22 opcodes
842  data = 0;
843  }
844 
845  //Return the value of the PHY register
846  return data;
847 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define EMAC_RECEIVE_DESCRIPTOR_LIST_ADDR
#define EMAC_RDES1_RBS1
Enhanced TX DMA descriptor.
uint8_t opcode
Definition: dns_common.h:191
#define EMAC_BUS_MODE_AAB
int bool_t
Definition: compiler_port.h:63
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define EMAC_GMII_ADDR_GW
#define EMAC_MAC_ADDR3_HIGH
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:690
#define EMAC_TDES0_OWN
#define EMAC_RDES0_ES
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
#define EMAC_OPERATION_MODE_SR
#define TRUE
Definition: os_port.h:50
#define EMAC_MAC_ADDR3_HIGH_AE
uint8_t data[]
Definition: ethernet.h:224
#define EMAC_STATUS
#define EMAC_MAC_ADDR1_LOW
#define EMAC_GMII_ADDR_CR_DIV_102
#define EMAC_GMII_DATA
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:266
#define EMAC_TDES0_IC
error_t m5531EthInit(NetInterface *interface)
M5531 Ethernet MAC initialization.
Enhanced RX DMA descriptor.
#define EMAC_BUS_MODE_PBL_32
__weak_func void m5531EthInitGpio(NetInterface *interface)
GPIO configuration.
#define EMAC_MAC_CONFIG_RESERVED15
#define EMAC_INTERRUPT_ENABLE_RIE
#define EMAC_INTERRUPT_ENABLE_TIE
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:418
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:133
#define osExitIsr(flag)
#define SMI_OPCODE_WRITE
Definition: nic.h:66
#define M5531_ETH_TX_BUFFER_COUNT
#define EMAC_BUS_MODE_RPBL_32
#define M5531_ETH_IRQ_SUB_PRIORITY
#define EMAC_INTERRUPT_MASK
#define EMAC_MAC_CONFIG_FES
#define FALSE
Definition: os_port.h:46
#define EMAC_RDES1_RCH
#define EMAC_OPERATION_MODE_ST
#define EMAC_TDES1_TBS1
#define EMAC_FLOW_CONTROL
void m5531EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
#define EMAC_INTERRUPT_MASK_TSIM
#define EMAC_RDES0_LS
error_t m5531EthReceivePacket(NetInterface *interface)
Receive a packet.
error_t
Error codes.
Definition: error.h:43
#define EMAC_INTERRUPT_ENABLE_NIE
#define EMAC_STATUS_TI
#define EMAC_MAC_FRAME_FILTER_PM
#define M5531_ETH_IRQ_GROUP_PRIORITY
#define EMAC_GMII_DATA_GD
void m5531EthEventHandler(NetInterface *interface)
M5531 Ethernet MAC event handler.
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:103
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
void EMAC0_IRQHandler(void)
M5531 Ethernet MAC interrupt service routine.
#define txBuffer
#define NetRxAncillary
Definition: net_misc.h:40
@ ERROR_INVALID_PACKET
Definition: error.h:141
#define NetInterface
Definition: net.h:40
MacAddr addr
MAC address.
Definition: ethernet.h:265
#define EMAC_STATUS_TU
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_BUFFER_EMPTY
Definition: error.h:142
#define NetTxAncillary
Definition: net_misc.h:36
error_t m5531EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define SMI_OPCODE_READ
Definition: nic.h:67
#define EMAC_MAC_ADDR2_HIGH
#define EMAC_MAC_CONFIG_RE
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
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:63
#define EMAC_INTERRUPT_ENABLE
#define EMAC_GMII_ADDR_PA
#define EMAC_BUS_MODE
#define EMAC_TDES0_LS
#define rxBuffer
MacAddr
Definition: ethernet.h:197
#define EMAC_TDES0_TCH
void m5531EthDisableIrq(NetInterface *interface)
Disable interrupts.
#define EMAC_MAC_CONFIG_DO
#define EMAC_BUS_MODE_ATDS
#define EMAC_OPERATION_MODE_TSF
#define EMAC_MAC_ADDR2_LOW
#define EMAC_GMII_ADDR
#define EMAC_MAC_ADDR3_LOW
#define EMAC_RDES0_FL
#define TRACE_DEBUG(...)
Definition: debug.h:119
uint16_t regAddr
#define EMAC_GMII_ADDR_GR
#define EMAC_MAC_CONFIG_DM
#define EMAC_RECEIVE_POLL_DEMAND
#define ETH_MTU
Definition: ethernet.h:116
uint8_t n
#define EMAC_GMII_ADDR_GB
MAC filter table entry.
Definition: ethernet.h:264
#define EMAC_TRANSMIT_DESCRIPTOR_LIST_ADDR
#define EMAC_STATUS_RI
const NicDriver m5531EthDriver
M5531 Ethernet MAC driver.
#define EMAC_MAC_ADDR0_LOW
#define EMAC_STATUS_NIS
#define EMAC_GMII_ADDR_CR
#define M5531_ETH_IRQ_PRIORITY_GROUPING
#define osEnterIsr()
error_t m5531EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
#define EMAC_MAC_FRAME_FILTER
#define EMAC_MAC_ADDR1_HIGH_AE
#define EMAC_OPERATION_MODE_RSF
#define EMAC_TRANSMIT_POLL_DEMAND
#define EMAC_TDES0_FS
#define rxDmaDesc
#define EMAC_BUS_MODE_USP
#define EMAC_STATUS_RU
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define EMAC_MAC_CONFIG
#define EMAC_MAC_CONFIG_TE
#define txDmaDesc
#define M5531_ETH_RX_BUFFER_SIZE
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
Nuvoton M5531 Ethernet MAC driver.
void m5531EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
unsigned int uint_t
Definition: compiler_port.h:57
TCP/IP stack core.
#define EMAC_OPERATION_MODE
#define EMAC_BUS_MODE_SWR
#define M5531_ETH_RX_BUFFER_COUNT
NIC driver.
Definition: nic.h:286
#define EMAC_RDES0_OWN
void m5531EthTick(NetInterface *interface)
M5531 Ethernet MAC timer handler.
#define EMAC_INTERRUPT_MASK_PMTIM
#define M5531_ETH_TX_BUFFER_SIZE
#define EMAC_MAC_ADDR2_HIGH_AE
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:51
@ NO_ERROR
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
#define EMAC_MAC_ADDR1_HIGH
error_t m5531EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
uint16_t m5531EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
void m5531EthEnableIrq(NetInterface *interface)
Enable interrupts.
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define EMAC_RDES0_FS
#define EMAC_MAC_ADDR0_HIGH
#define M5531_ETH_RAM_SECTION