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