sama5d3_geth_driver.c
Go to the documentation of this file.
1 /**
2  * @file sama5d3_geth_driver.c
3  * @brief SAMA5D3 Gigabit 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.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include <limits.h>
36 #include "sama5d3x.h"
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //IAR EWARM compiler?
45 #if defined(__ICCARM__)
46 
47 //TX buffer
48 #pragma data_alignment = 8
49 #pragma location = ".ram_no_cache"
51 //RX buffer
52 #pragma data_alignment = 8
53 #pragma location = ".ram_no_cache"
55 //TX buffer descriptors
56 #pragma data_alignment = 8
57 #pragma location = ".ram_no_cache"
59 //RX buffer descriptors
60 #pragma data_alignment = 8
61 #pragma location = ".ram_no_cache"
63 
64 //GCC compiler?
65 #else
66 
67 //TX buffer
69  __attribute__((aligned(8), __section__(".ram_no_cache")));
70 //RX buffer
72  __attribute__((aligned(8), __section__(".ram_no_cache")));
73 //TX buffer descriptors
75  __attribute__((aligned(8), __section__(".ram_no_cache")));
76 //RX buffer descriptors
78  __attribute__((aligned(8), __section__(".ram_no_cache")));
79 
80 #endif
81 
82 //TX buffer index
83 static uint_t txBufferIndex;
84 //RX buffer index
85 static uint_t rxBufferIndex;
86 
87 
88 /**
89  * @brief SAMA5D3 Gigabit Ethernet MAC driver
90  **/
91 
93 {
95  ETH_MTU,
106  TRUE,
107  TRUE,
108  TRUE,
109  FALSE
110 };
111 
112 
113 /**
114  * @brief SAMA5D3 Gigabit Ethernet MAC initialization
115  * @param[in] interface Underlying network interface
116  * @return Error code
117  **/
118 
120 {
121  error_t error;
122  volatile uint32_t status;
123 
124  //Debug message
125  TRACE_INFO("Initializing SAMA5D3 Gigabit Ethernet MAC...\r\n");
126 
127  //Save underlying network interface
128  nicDriverInterface = interface;
129 
130  //Enable GMAC peripheral clock
131  PMC->PMC_PCER1 = (1 << (ID_GMAC - 32));
132  //Enable IRQ controller peripheral clock
133  PMC->PMC_PCER1 = (1 << (ID_IRQ - 32));
134 
135  //GPIO configuration
136  sama5d3GigabitEthInitGpio(interface);
137 
138  //Configure MDC clock speed
139  GMAC->GMAC_NCFGR = GMAC_NCFGR_DBW_DBW64 | GMAC_NCFGR_CLK_MCK_224;
140  //Enable management port (MDC and MDIO)
141  GMAC->GMAC_NCR |= GMAC_NCR_MPE;
142 
143  //PHY transceiver initialization
144  error = interface->phyDriver->init(interface);
145  //Failed to initialize PHY transceiver?
146  if(error)
147  return error;
148 
149  //Set the MAC address of the station
150  GMAC->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
151  GMAC->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
152 
153  //The MAC supports 3 additional addresses for unicast perfect filtering
154  GMAC->GMAC_SA[1].GMAC_SAB = 0;
155  GMAC->GMAC_SA[2].GMAC_SAB = 0;
156  GMAC->GMAC_SA[3].GMAC_SAB = 0;
157 
158  //Initialize hash table
159  GMAC->GMAC_HRB = 0;
160  GMAC->GMAC_HRT = 0;
161 
162  //Configure the receive filter
163  GMAC->GMAC_NCFGR |= GMAC_NCFGR_MAXFS | GMAC_NCFGR_MTIHEN;
164 
165  //Initialize buffer descriptors
167 
168  //Clear transmit status register
169  GMAC->GMAC_TSR = GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
170  GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR;
171  //Clear receive status register
172  GMAC->GMAC_RSR = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA;
173 
174  //First disable all GMAC interrupts
175  GMAC->GMAC_IDR = 0xFFFFFFFF;
176  //Only the desired ones are enabled
177  GMAC->GMAC_IER = GMAC_IER_HRESP | GMAC_IER_ROVR | GMAC_IER_TCOMP | GMAC_IER_TFC |
178  GMAC_IER_RLEX | GMAC_IER_TUR | GMAC_IER_RXUBR | GMAC_IER_RCOMP;
179 
180  //Read GMAC ISR register to clear any pending interrupt
181  status = GMAC->GMAC_ISR;
182 
183  //Configure interrupt controller
184  AIC->AIC_SSR = ID_GMAC;
185  AIC->AIC_SMR = AIC_SMR_SRCTYPE_INT_LEVEL_SENSITIVE | AIC_SMR_PRIOR(SAMA5D3_GIGABIT_ETH_IRQ_PRIORITY);
186  AIC->AIC_SVR = (uint32_t) sama5d3GigabitEthIrqHandler;
187 
188  //Enable the GMAC to transmit and receive data
189  GMAC->GMAC_NCR |= GMAC_NCR_TXEN | GMAC_NCR_RXEN;
190 
191  //Accept any packets from the upper layer
192  osSetEvent(&interface->nicTxEvent);
193 
194  //Successful initialization
195  return NO_ERROR;
196 }
197 
198 
199 //SAMA5D3-Xplained evaluation board?
200 #if defined(USE_SAMA5D3_XPLAINED)
201 
202 /**
203  * @brief GPIO configuration
204  * @param[in] interface Underlying network interface
205  **/
206 
208 {
209  //Enable PIO peripheral clock
210  PMC->PMC_PCER0 = (1 << ID_PIOB);
211 
212  //Disable pull-up resistors on RGMII pins
213  PIOB->PIO_PUDR = GMAC_RGMII_MASK;
214  //Disable interrupts-on-change
215  PIOB->PIO_IDR = GMAC_RGMII_MASK;
216  //Assign MII pins to peripheral A function
217  PIOB->PIO_ABCDSR[0] &= ~GMAC_RGMII_MASK;
218  PIOB->PIO_ABCDSR[1] &= ~GMAC_RGMII_MASK;
219  //Disable the PIO from controlling the corresponding pins
220  PIOB->PIO_PDR = GMAC_RGMII_MASK;
221 
222  //Select RGMII operation mode
223  GMAC->GMAC_UR = GMAC_UR_RGMII;
224 }
225 
226 #endif
227 
228 
229 /**
230  * @brief Initialize buffer descriptors
231  * @param[in] interface Underlying network interface
232  **/
233 
235 {
236  uint_t i;
237  uint32_t address;
238 
239  //Initialize TX buffer descriptors
240  for(i = 0; i < SAMA5D3_GIGABIT_ETH_TX_BUFFER_COUNT; i++)
241  {
242  //Calculate the address of the current TX buffer
243  address = (uint32_t) txBuffer[i];
244  //Write the address to the descriptor entry
245  txBufferDesc[i].address = address;
246  //Initialize status field
247  txBufferDesc[i].status = GMAC_TX_USED;
248  }
249 
250  //Mark the last descriptor entry with the wrap flag
251  txBufferDesc[i - 1].status |= GMAC_TX_WRAP;
252  //Initialize TX buffer index
253  txBufferIndex = 0;
254 
255  //Initialize RX buffer descriptors
256  for(i = 0; i < SAMA5D3_GIGABIT_ETH_RX_BUFFER_COUNT; i++)
257  {
258  //Calculate the address of the current RX buffer
259  address = (uint32_t) rxBuffer[i];
260  //Write the address to the descriptor entry
261  rxBufferDesc[i].address = address & GMAC_RX_ADDRESS;
262  //Clear status field
263  rxBufferDesc[i].status = 0;
264  }
265 
266  //Mark the last descriptor entry with the wrap flag
267  rxBufferDesc[i - 1].address |= GMAC_RX_WRAP;
268  //Initialize RX buffer index
269  rxBufferIndex = 0;
270 
271  //Start location of the TX descriptor list
272  GMAC->GMAC_TBQB = (uint32_t) txBufferDesc;
273  //Start location of the RX descriptor list
274  GMAC->GMAC_RBQB = (uint32_t) rxBufferDesc;
275 }
276 
277 
278 /**
279  * @brief SAMA5D3 Gigabit Ethernet MAC timer handler
280  *
281  * This routine is periodically called by the TCP/IP stack to
282  * handle periodic operations such as polling the link state
283  *
284  * @param[in] interface Underlying network interface
285  **/
286 
288 {
289  //Handle periodic operations
290  interface->phyDriver->tick(interface);
291 }
292 
293 
294 /**
295  * @brief Enable interrupts
296  * @param[in] interface Underlying network interface
297  **/
298 
300 {
301  //Enable Ethernet MAC interrupts
302  AIC->AIC_SSR = ID_GMAC;
303  AIC->AIC_IECR = AIC_IECR_INTEN;
304 
305  //Enable Ethernet PHY interrupts
306  interface->phyDriver->enableIrq(interface);
307 }
308 
309 
310 /**
311  * @brief Disable interrupts
312  * @param[in] interface Underlying network interface
313  **/
314 
316 {
317  //Disable Ethernet MAC interrupts
318  AIC->AIC_SSR = ID_GMAC;
319  AIC->AIC_IDCR = AIC_IDCR_INTD;
320 
321  //Disable Ethernet PHY interrupts
322  interface->phyDriver->disableIrq(interface);
323 }
324 
325 
326 /**
327  * @brief SAMA5D3 Gigabit Ethernet MAC interrupt service routine
328  **/
329 
331 {
332  bool_t flag;
333  volatile uint32_t isr;
334  volatile uint32_t tsr;
335  volatile uint32_t rsr;
336 
337  //Enter interrupt service routine
338  osEnterIsr();
339 
340  //This flag will be set if a higher priority task must be woken
341  flag = FALSE;
342 
343  //Each time the software reads GMAC_ISR, it has to check the
344  //contents of GMAC_TSR, GMAC_RSR and GMAC_NSR
345  isr = GMAC->GMAC_ISR;
346  tsr = GMAC->GMAC_TSR;
347  rsr = GMAC->GMAC_RSR;
348 
349  //A packet has been transmitted?
350  if(tsr & (GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
351  GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR))
352  {
353  //Only clear TSR flags that are currently set
354  GMAC->GMAC_TSR = tsr;
355 
356  //Avoid DMA lockup by sending only one frame at a time (see errata 57.5.1)
357  if((txBufferDesc[0].status & GMAC_TX_USED) &&
358  (txBufferDesc[1].status & GMAC_TX_USED))
359  {
360  //Notify the TCP/IP stack that the transmitter is ready to send
361  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
362  }
363  }
364 
365  //A packet has been received?
366  if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA))
367  {
368  //Set event flag
369  nicDriverInterface->nicEvent = TRUE;
370  //Notify the TCP/IP stack of the event
371  flag |= osSetEventFromIsr(&netEvent);
372  }
373 
374  //Write AIC_EOICR register before exiting
375  AIC->AIC_EOICR = 0;
376 
377  //Leave interrupt service routine
378  osExitIsr(flag);
379 }
380 
381 
382 /**
383  * @brief SAMA5D3 Gigabit Ethernet MAC event handler
384  * @param[in] interface Underlying network interface
385  **/
386 
388 {
389  error_t error;
390  uint32_t rsr;
391 
392  //Read receive status
393  rsr = GMAC->GMAC_RSR;
394 
395  //Packet received?
396  if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA))
397  {
398  //Only clear RSR flags that are currently set
399  GMAC->GMAC_RSR = rsr;
400 
401  //Process all pending packets
402  do
403  {
404  //Read incoming packet
405  error = sama5d3GigabitEthReceivePacket(interface);
406 
407  //No more data in the receive buffer?
408  } while(error != ERROR_BUFFER_EMPTY);
409  }
410 }
411 
412 
413 /**
414  * @brief Send a packet
415  * @param[in] interface Underlying network interface
416  * @param[in] buffer Multi-part buffer containing the data to send
417  * @param[in] offset Offset to the first data byte
418  * @return Error code
419  **/
420 
422  const NetBuffer *buffer, size_t offset)
423 {
424  size_t length;
425 
426  //Retrieve the length of the packet
427  length = netBufferGetLength(buffer) - offset;
428 
429  //Check the frame length
431  {
432  //The transmitter can accept another packet
433  osSetEvent(&interface->nicTxEvent);
434  //Report an error
435  return ERROR_INVALID_LENGTH;
436  }
437 
438  //Make sure the current buffer is available for writing
439  if(!(txBufferDesc[txBufferIndex].status & GMAC_TX_USED))
440  return ERROR_FAILURE;
441 
442  //Copy user data to the transmit buffer
443  netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
444 
445  //Set the necessary flags in the descriptor entry
446  if(txBufferIndex < (SAMA5D3_GIGABIT_ETH_TX_BUFFER_COUNT - 1))
447  {
448  //Write the status word
449  txBufferDesc[txBufferIndex].status =
451 
452  //Point to the next buffer
453  txBufferIndex++;
454  }
455  else
456  {
457  //Write the status word
458  txBufferDesc[txBufferIndex].status = GMAC_TX_WRAP |
460 
461  //Wrap around
462  txBufferIndex = 0;
463  }
464 
465  //Set the TSTART bit to initiate transmission
466  GMAC->GMAC_NCR |= GMAC_NCR_TSTART;
467 
468  //Check whether the next buffer is available for writing
469  if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED)
470  {
471  //The transmitter can accept another packet
472  osSetEvent(&interface->nicTxEvent);
473  }
474 
475  //Successful processing
476  return NO_ERROR;
477 }
478 
479 
480 /**
481  * @brief Receive a packet
482  * @param[in] interface Underlying network interface
483  * @return Error code
484  **/
485 
487 {
488  static uint8_t temp[ETH_MAX_FRAME_SIZE];
489  error_t error;
490  uint_t i;
491  uint_t j;
492  uint_t sofIndex;
493  uint_t eofIndex;
494  size_t n;
495  size_t size;
496  size_t length;
497 
498  //Initialize SOF and EOF indices
499  sofIndex = UINT_MAX;
500  eofIndex = UINT_MAX;
501 
502  //Search for SOF and EOF flags
503  for(i = 0; i < SAMA5D3_GIGABIT_ETH_RX_BUFFER_COUNT; i++)
504  {
505  //Point to the current entry
506  j = rxBufferIndex + i;
507 
508  //Wrap around to the beginning of the buffer if necessary
511 
512  //No more entries to process?
513  if(!(rxBufferDesc[j].address & GMAC_RX_OWNERSHIP))
514  {
515  //Stop processing
516  break;
517  }
518  //A valid SOF has been found?
519  if(rxBufferDesc[j].status & GMAC_RX_SOF)
520  {
521  //Save the position of the SOF
522  sofIndex = i;
523  }
524  //A valid EOF has been found?
525  if((rxBufferDesc[j].status & GMAC_RX_EOF) && sofIndex != UINT_MAX)
526  {
527  //Save the position of the EOF
528  eofIndex = i;
529  //Retrieve the length of the frame
530  size = rxBufferDesc[j].status & GMAC_RX_LENGTH;
531  //Limit the number of data to read
532  size = MIN(size, ETH_MAX_FRAME_SIZE);
533  //Stop processing since we have reached the end of the frame
534  break;
535  }
536  }
537 
538  //Determine the number of entries to process
539  if(eofIndex != UINT_MAX)
540  j = eofIndex + 1;
541  else if(sofIndex != UINT_MAX)
542  j = sofIndex;
543  else
544  j = i;
545 
546  //Total number of bytes that have been copied from the receive buffer
547  length = 0;
548 
549  //Process incoming frame
550  for(i = 0; i < j; i++)
551  {
552  //Any data to copy from current buffer?
553  if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
554  {
555  //Calculate the number of bytes to read at a time
557  //Copy data from receive buffer
558  memcpy(temp + length, rxBuffer[rxBufferIndex], n);
559  //Update byte counters
560  length += n;
561  size -= n;
562  }
563 
564  //Mark the current buffer as free
565  rxBufferDesc[rxBufferIndex].address &= ~GMAC_RX_OWNERSHIP;
566 
567  //Point to the following entry
568  rxBufferIndex++;
569 
570  //Wrap around to the beginning of the buffer if necessary
571  if(rxBufferIndex >= SAMA5D3_GIGABIT_ETH_RX_BUFFER_COUNT)
572  rxBufferIndex = 0;
573  }
574 
575  //Any packet to process?
576  if(length > 0)
577  {
578  //Pass the packet to the upper layer
579  nicProcessPacket(interface, temp, length);
580  //Valid packet received
581  error = NO_ERROR;
582  }
583  else
584  {
585  //No more data in the receive buffer
586  error = ERROR_BUFFER_EMPTY;
587  }
588 
589  //Return status code
590  return error;
591 }
592 
593 
594 /**
595  * @brief Configure MAC address filtering
596  * @param[in] interface Underlying network interface
597  * @return Error code
598  **/
599 
601 {
602  uint_t i;
603  uint_t j;
604  uint_t k;
605  uint8_t *p;
606  uint32_t hashTable[2];
607  MacAddr unicastMacAddr[3];
608  MacFilterEntry *entry;
609 
610  //Debug message
611  TRACE_DEBUG("Updating MAC filter...\r\n");
612 
613  //The MAC supports 3 additional addresses for unicast perfect filtering
614  unicastMacAddr[0] = MAC_UNSPECIFIED_ADDR;
615  unicastMacAddr[1] = MAC_UNSPECIFIED_ADDR;
616  unicastMacAddr[2] = MAC_UNSPECIFIED_ADDR;
617 
618  //The hash table is used for multicast address filtering
619  hashTable[0] = 0;
620  hashTable[1] = 0;
621 
622  //The MAC address filter contains the list of MAC addresses to accept
623  //when receiving an Ethernet frame
624  for(i = 0, j = 0; i < MAC_ADDR_FILTER_SIZE; i++)
625  {
626  //Point to the current entry
627  entry = &interface->macAddrFilter[i];
628 
629  //Valid entry?
630  if(entry->refCount > 0)
631  {
632  //Multicast address?
633  if(macIsMulticastAddr(&entry->addr))
634  {
635  //Point to the MAC address
636  p = entry->addr.b;
637 
638  //Apply the hash function
639  k = (p[0] >> 6) ^ p[0];
640  k ^= (p[1] >> 4) ^ (p[1] << 2);
641  k ^= (p[2] >> 2) ^ (p[2] << 4);
642  k ^= (p[3] >> 6) ^ p[3];
643  k ^= (p[4] >> 4) ^ (p[4] << 2);
644  k ^= (p[5] >> 2) ^ (p[5] << 4);
645 
646  //The hash value is reduced to a 6-bit index
647  k &= 0x3F;
648 
649  //Update hash table contents
650  hashTable[k / 32] |= (1 << (k % 32));
651  }
652  else
653  {
654  //Up to 3 additional MAC addresses can be specified
655  if(j < 3)
656  {
657  //Save the unicast address
658  unicastMacAddr[j++] = entry->addr;
659  }
660  }
661  }
662  }
663 
664  //Configure the first unicast address filter
665  if(j >= 1)
666  {
667  //The addresse is activated when SAT register is written
668  GMAC->GMAC_SA[1].GMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
669  GMAC->GMAC_SA[1].GMAC_SAT = unicastMacAddr[0].w[2];
670  }
671  else
672  {
673  //The addresse is activated when SAB register is written
674  GMAC->GMAC_SA[1].GMAC_SAB = 0;
675  }
676 
677  //Configure the second unicast address filter
678  if(j >= 2)
679  {
680  //The addresse is activated when SAT register is written
681  GMAC->GMAC_SA[2].GMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
682  GMAC->GMAC_SA[2].GMAC_SAT = unicastMacAddr[1].w[2];
683  }
684  else
685  {
686  //The addresse is activated when SAB register is written
687  GMAC->GMAC_SA[2].GMAC_SAB = 0;
688  }
689 
690  //Configure the third unicast address filter
691  if(j >= 3)
692  {
693  //The addresse is activated when SAT register is written
694  GMAC->GMAC_SA[3].GMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
695  GMAC->GMAC_SA[3].GMAC_SAT = unicastMacAddr[2].w[2];
696  }
697  else
698  {
699  //The addresse is activated when SAB register is written
700  GMAC->GMAC_SA[3].GMAC_SAB = 0;
701  }
702 
703  //Configure the multicast address filter
704  GMAC->GMAC_HRB = hashTable[0];
705  GMAC->GMAC_HRT = hashTable[1];
706 
707  //Debug message
708  TRACE_DEBUG(" HRB = %08" PRIX32 "\r\n", GMAC->GMAC_HRB);
709  TRACE_DEBUG(" HRT = %08" PRIX32 "\r\n", GMAC->GMAC_HRT);
710 
711  //Successful processing
712  return NO_ERROR;
713 }
714 
715 
716 /**
717  * @brief Adjust MAC configuration parameters for proper operation
718  * @param[in] interface Underlying network interface
719  * @return Error code
720  **/
721 
723 {
724  uint32_t config;
725 
726  //Read network configuration register
727  config = GMAC->GMAC_NCFGR;
728 
729  //1000BASE-T operation mode?
730  if(interface->linkSpeed == NIC_LINK_SPEED_1GBPS)
731  {
732  config |= GMAC_NCFGR_GBE;
733  config &= ~GMAC_NCFGR_SPD;
734  }
735  //100BASE-TX operation mode?
736  else if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
737  {
738  config &= ~GMAC_NCFGR_GBE;
739  config |= GMAC_NCFGR_SPD;
740  }
741  //10BASE-T operation mode?
742  else
743  {
744  config &= ~GMAC_NCFGR_GBE;
745  config &= ~GMAC_NCFGR_SPD;
746  }
747 
748  //Half-duplex or full-duplex mode?
749  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
750  config |= GMAC_NCFGR_FD;
751  else
752  config &= ~GMAC_NCFGR_FD;
753 
754  //Write configuration value back to NCFGR register
755  GMAC->GMAC_NCFGR = config;
756 
757  //Successful processing
758  return NO_ERROR;
759 }
760 
761 
762 /**
763  * @brief Write PHY register
764  * @param[in] phyAddr PHY address
765  * @param[in] regAddr Register address
766  * @param[in] data Register value
767  **/
768 
769 void sama5d3GigabitEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
770 {
771  uint32_t value;
772 
773  //Set up a write operation
774  value = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2);
775  //PHY address
776  value |= GMAC_MAN_PHYA(phyAddr);
777  //Register address
778  value |= GMAC_MAN_REGA(regAddr);
779  //Register value
780  value |= GMAC_MAN_DATA(data);
781 
782  //Start a write operation
783  GMAC->GMAC_MAN = value;
784  //Wait for the write to complete
785  while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE));
786 }
787 
788 
789 /**
790  * @brief Read PHY register
791  * @param[in] phyAddr PHY address
792  * @param[in] regAddr Register address
793  * @return Register value
794  **/
795 
796 uint16_t sama5d3GigabitEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
797 {
798  uint32_t value;
799 
800  //Set up a read operation
801  value = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2);
802  //PHY address
803  value |= GMAC_MAN_PHYA(phyAddr);
804  //Register address
805  value |= GMAC_MAN_REGA(regAddr);
806 
807  //Start a read operation
808  GMAC->GMAC_MAN = value;
809  //Wait for the read to complete
810  while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE));
811 
812  //Return PHY register contents
813  return GMAC->GMAC_MAN & GMAC_MAN_DATA_Msk;
814 }
#define GMAC_RX_SOF
MacAddr addr
MAC address.
Definition: ethernet.h:219
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:89
Transmit buffer descriptor.
error_t sama5d3GigabitEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
TCP/IP stack core.
Debugging facilities.
uint8_t p
Definition: ndp.h:297
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define GMAC_RX_EOF
Receive buffer descriptor.
Generic error code.
Definition: error.h:45
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:107
#define txBuffer
SAMA5D3 Gigabit Ethernet MAC controller.
#define SAMA5D3_GIGABIT_ETH_TX_BUFFER_SIZE
#define GMAC_TX_USED
#define GMAC_TX_WRAP
void sama5d3GigabitEthEventHandler(NetInterface *interface)
SAMA5D3 Gigabit Ethernet MAC event handler.
#define TRUE
Definition: os_port.h:50
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
void sama5d3GigabitEthIrqHandler(void)
SAMA5D3 Gigabit Ethernet MAC interrupt service routine.
void sama5d3GigabitEthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
error_t sama5d3GigabitEthInit(NetInterface *interface)
SAMA5D3 Gigabit Ethernet MAC initialization.
#define GMAC_TX_LAST
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
NIC driver.
Definition: nic.h:164
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define MIN(a, b)
Definition: os_port.h:62
#define GMAC_RX_OWNERSHIP
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:56
#define GMAC_RX_ADDRESS
#define TRACE_INFO(...)
Definition: debug.h:94
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:91
Ethernet interface.
Definition: nic.h:71
Success.
Definition: error.h:44
#define GMAC_RX_WRAP
#define rxBuffer
void sama5d3GigabitEthTick(NetInterface *interface)
SAMA5D3 Gigabit Ethernet MAC timer handler.
Ipv6Addr address
error_t sama5d3GigabitEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
OsEvent netEvent
Definition: net.c:73
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:220
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:42
error_t sama5d3GigabitEthReceivePacket(NetInterface *interface)
Receive a packet.
uint16_t sama5d3GigabitEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
unsigned int uint_t
Definition: compiler_port.h:45
void sama5d3GigabitEthDisableIrq(NetInterface *interface)
Disable interrupts.
__start_packed struct @112 MacAddr
MAC address.
void sama5d3GigabitEthEnableIrq(NetInterface *interface)
Enable interrupts.
uint8_t data[]
Definition: dtls_misc.h:169
#define NetInterface
Definition: net.h:36
uint8_t value[]
Definition: dtls_misc.h:143
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:395
#define GMAC_RGMII_MASK
void sama5d3GigabitEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define osExitIsr(flag)
#define SAMA5D3_GIGABIT_ETH_IRQ_PRIORITY
error_t sama5d3GigabitEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define SAMA5D3_GIGABIT_ETH_RX_BUFFER_COUNT
#define osEnterIsr()
#define GMAC_RX_LENGTH
#define GMAC_TX_LENGTH
#define SAMA5D3_GIGABIT_ETH_RX_BUFFER_SIZE
uint8_t length
Definition: dtls_misc.h:142
uint8_t n
const NicDriver sama5d3GigabitEthDriver
SAMA5D3 Gigabit Ethernet MAC driver.
#define FALSE
Definition: os_port.h:46
int bool_t
Definition: compiler_port.h:49
#define SAMA5D3_GIGABIT_ETH_TX_BUFFER_COUNT
void sama5d3GigabitEthInitGpio(NetInterface *interface)
MAC filter table entry.
Definition: ethernet.h:217
#define TRACE_DEBUG(...)
Definition: debug.h:106