same54_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file same54_eth_driver.c
3  * @brief SAME54 Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2020 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.8
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 "same54.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
50 //RX buffer
51 #pragma data_alignment = 8
53 //TX buffer descriptors
54 #pragma data_alignment = 4
56 //RX buffer descriptors
57 #pragma data_alignment = 4
59 
60 //Keil MDK-ARM or GCC compiler?
61 #else
62 
63 //TX buffer
65  __attribute__((aligned(8)));
66 //RX buffer
68  __attribute__((aligned(8)));
69 //TX buffer descriptors
71  __attribute__((aligned(4)));
72 //RX buffer descriptors
74  __attribute__((aligned(4)));
75 
76 #endif
77 
78 //TX buffer index
79 static uint_t txBufferIndex;
80 //RX buffer index
81 static uint_t rxBufferIndex;
82 
83 
84 /**
85  * @brief SAME54 Ethernet MAC driver
86  **/
87 
89 {
91  ETH_MTU,
102  TRUE,
103  TRUE,
104  TRUE,
105  FALSE
106 };
107 
108 
109 /**
110  * @brief SAME54 Ethernet MAC initialization
111  * @param[in] interface Underlying network interface
112  * @return Error code
113  **/
114 
116 {
117  error_t error;
118  volatile uint32_t status;
119 
120  //Debug message
121  TRACE_INFO("Initializing SAME54 Ethernet MAC...\r\n");
122 
123  //Save underlying network interface
124  nicDriverInterface = interface;
125 
126  //Enable GMAC bus clocks (CLK_GMAC_APB and CLK_GMAC_AHB)
127  MCLK->APBCMASK.bit.GMAC_ = 1;
128  MCLK->AHBMASK.bit.GMAC_ = 1;
129 
130  //Disable transmit and receive circuits
131  GMAC->NCR.reg = 0;
132 
133  //GPIO configuration
134  same54EthInitGpio(interface);
135 
136  //Configure MDC clock speed
137  GMAC->NCFGR.reg = GMAC_NCFGR_CLK(5);
138  //Enable management port (MDC and MDIO)
139  GMAC->NCR.reg |= GMAC_NCR_MPE;
140 
141  //Valid Ethernet PHY or switch driver?
142  if(interface->phyDriver != NULL)
143  {
144  //Ethernet PHY initialization
145  error = interface->phyDriver->init(interface);
146  }
147  else if(interface->switchDriver != NULL)
148  {
149  //Ethernet switch initialization
150  error = interface->switchDriver->init(interface);
151  }
152  else
153  {
154  //The interface is not properly configured
155  error = ERROR_FAILURE;
156  }
157 
158  //Any error to report?
159  if(error)
160  {
161  return error;
162  }
163 
164  //Set the MAC address of the station
165  GMAC->Sa[0].SAB.reg = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
166  GMAC->Sa[0].SAT.reg = interface->macAddr.w[2];
167 
168  //The MAC supports 3 additional addresses for unicast perfect filtering
169  GMAC->Sa[1].SAB.reg = 0;
170  GMAC->Sa[2].SAB.reg = 0;
171  GMAC->Sa[3].SAB.reg = 0;
172 
173  //Initialize hash table
174  GMAC->HRB.reg = 0;
175  GMAC->HRT.reg = 0;
176 
177  //Configure the receive filter
178  GMAC->NCFGR.reg |= GMAC_NCFGR_MAXFS | GMAC_NCFGR_MTIHEN;
179 
180  //Initialize buffer descriptors
181  same54EthInitBufferDesc(interface);
182 
183  //Clear transmit status register
184  GMAC->TSR.reg = GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
185  GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR;
186  //Clear receive status register
187  GMAC->RSR.reg = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA;
188 
189  //First disable all GMAC interrupts
190  GMAC->IDR.reg = 0xFFFFFFFF;
191  //Only the desired ones are enabled
192  GMAC->IER.reg = GMAC_IER_HRESP | GMAC_IER_ROVR | GMAC_IER_TCOMP | GMAC_IER_TFC |
193  GMAC_IER_RLEX | GMAC_IER_TUR | GMAC_IER_RXUBR | GMAC_IER_RCOMP;
194 
195  //Read GMAC ISR register to clear any pending interrupt
196  status = GMAC->ISR.reg;
197 
198  //Set priority grouping (3 bits for pre-emption priority, no bits for subpriority)
199  NVIC_SetPriorityGrouping(SAME54_ETH_IRQ_PRIORITY_GROUPING);
200 
201  //Configure GMAC interrupt priority
202  NVIC_SetPriority(GMAC_IRQn, NVIC_EncodePriority(SAME54_ETH_IRQ_PRIORITY_GROUPING,
204 
205  //Enable the GMAC to transmit and receive data
206  GMAC->NCR.reg |= GMAC_NCR_TXEN | GMAC_NCR_RXEN;
207 
208  //Accept any packets from the upper layer
209  osSetEvent(&interface->nicTxEvent);
210 
211  //Successful initialization
212  return NO_ERROR;
213 }
214 
215 
216 //SAME54-Xplained-Pro or SAME54-Curiosity-Ultra evaluation board?
217 #if defined(USE_SAME54_XPLAINED_PRO) || defined(USE_SAME54_CURIOSITY_ULTRA)
218 
219 /**
220  * @brief GPIO configuration
221  * @param[in] interface Underlying network interface
222  **/
223 
224 void same54EthInitGpio(NetInterface *interface)
225 {
226 //SAME54-Xplained-Pro evaluation board?
227 #if defined(USE_SAME54_XPLAINED_PRO)
228  //Enable PORT bus clock (CLK_PORT_APB)
229  MCLK->APBBMASK.bit.PORT_ = 1;
230 
231  //Configure GRX1 (PA12)
232  PORT->Group[0].PINCFG[12].bit.PMUXEN = 1;
233  PORT->Group[0].PMUX[6].bit.PMUXE = MUX_PA12L_GMAC_GRX1;
234 
235  //Configure GRX0 (PA13)
236  PORT->Group[0].PINCFG[13].bit.PMUXEN = 1;
237  PORT->Group[0].PMUX[6].bit.PMUXO = MUX_PA13L_GMAC_GRX0;
238 
239  //Configure GTXCK (PA14)
240  PORT->Group[0].PINCFG[14].bit.PMUXEN = 1;
241  PORT->Group[0].PMUX[7].bit.PMUXE = MUX_PA14L_GMAC_GTXCK;
242 
243  //Configure GRXER (PA15)
244  PORT->Group[0].PINCFG[15].bit.PMUXEN = 1;
245  PORT->Group[0].PMUX[7].bit.PMUXO = MUX_PA15L_GMAC_GRXER;
246 
247  //Configure GTXEN (PA17)
248  PORT->Group[0].PINCFG[17].bit.DRVSTR = 1;
249  PORT->Group[0].PINCFG[17].bit.PMUXEN = 1;
250  PORT->Group[0].PMUX[8].bit.PMUXO = MUX_PA17L_GMAC_GTXEN;
251 
252  //Configure GTX0 (PA18)
253  PORT->Group[0].PINCFG[18].bit.DRVSTR = 1;
254  PORT->Group[0].PINCFG[18].bit.PMUXEN = 1;
255  PORT->Group[0].PMUX[9].bit.PMUXE = MUX_PA18L_GMAC_GTX0;
256 
257  //Configure GTX1 (PA19)
258  PORT->Group[0].PINCFG[19].bit.DRVSTR = 1;
259  PORT->Group[0].PINCFG[19].bit.PMUXEN = 1;
260  PORT->Group[0].PMUX[9].bit.PMUXO = MUX_PA19L_GMAC_GTX1;
261 
262  //Configure GMDC (PC11)
263  PORT->Group[2].PINCFG[11].bit.PMUXEN = 1;
264  PORT->Group[2].PMUX[5].bit.PMUXO = MUX_PC11L_GMAC_GMDC;
265 
266  //Configure GMDIO (PC12)
267  PORT->Group[2].PINCFG[12].bit.PMUXEN = 1;
268  PORT->Group[2].PMUX[6].bit.PMUXE = MUX_PC12L_GMAC_GMDIO;
269 
270  //Configure GRXDV (PC20)
271  PORT->Group[2].PINCFG[20].bit.PMUXEN = 1;
272  PORT->Group[2].PMUX[10].bit.PMUXE = MUX_PC20L_GMAC_GRXDV;
273 
274  //Select RMII operation mode
275  GMAC->UR.bit.MII = 0;
276 
277  //Configure PHY_RESET (PC21) as an output
278  PORT->Group[2].DIRSET.reg = PORT_PC21;
279 
280  //Reset PHY transceiver
281  PORT->Group[2].OUTCLR.reg = PORT_PC21;
282  sleep(10);
283  PORT->Group[2].OUTSET.reg = PORT_PC21;
284  sleep(10);
285 
286 //SAME54-Curiosity-Ultra evaluation board?
287 #elif defined(USE_SAME54_CURIOSITY_ULTRA)
288  //Enable PORT bus clock (CLK_PORT_APB)
289  MCLK->APBBMASK.bit.PORT_ = 1;
290 
291  //Configure GRX1 (PA12)
292  PORT->Group[0].PINCFG[12].bit.PMUXEN = 1;
293  PORT->Group[0].PMUX[6].bit.PMUXE = MUX_PA12L_GMAC_GRX1;
294 
295  //Configure GRX0 (PA13)
296  PORT->Group[0].PINCFG[13].bit.PMUXEN = 1;
297  PORT->Group[0].PMUX[6].bit.PMUXO = MUX_PA13L_GMAC_GRX0;
298 
299  //Configure GTXCK (PA14)
300  PORT->Group[0].PINCFG[14].bit.PMUXEN = 1;
301  PORT->Group[0].PMUX[7].bit.PMUXE = MUX_PA14L_GMAC_GTXCK;
302 
303  //Configure GRXER (PA15)
304  PORT->Group[0].PINCFG[15].bit.PMUXEN = 1;
305  PORT->Group[0].PMUX[7].bit.PMUXO = MUX_PA15L_GMAC_GRXER;
306 
307  //Configure GTXEN (PA17)
308  PORT->Group[0].PINCFG[17].bit.DRVSTR = 1;
309  PORT->Group[0].PINCFG[17].bit.PMUXEN = 1;
310  PORT->Group[0].PMUX[8].bit.PMUXO = MUX_PA17L_GMAC_GTXEN;
311 
312  //Configure GTX0 (PA18)
313  PORT->Group[0].PINCFG[18].bit.DRVSTR = 1;
314  PORT->Group[0].PINCFG[18].bit.PMUXEN = 1;
315  PORT->Group[0].PMUX[9].bit.PMUXE = MUX_PA18L_GMAC_GTX0;
316 
317  //Configure GTX1 (PA19)
318  PORT->Group[0].PINCFG[19].bit.DRVSTR = 1;
319  PORT->Group[0].PINCFG[19].bit.PMUXEN = 1;
320  PORT->Group[0].PMUX[9].bit.PMUXO = MUX_PA19L_GMAC_GTX1;
321 
322  //Configure GRXDV (PC20)
323  PORT->Group[2].PINCFG[20].bit.PMUXEN = 1;
324  PORT->Group[2].PMUX[10].bit.PMUXE = MUX_PC20L_GMAC_GRXDV;
325 
326  //Configure GMDC (PC22)
327  PORT->Group[2].PINCFG[22].bit.PMUXEN = 1;
328  PORT->Group[2].PMUX[11].bit.PMUXE = MUX_PC22L_GMAC_GMDC;
329 
330  //Configure GMDIO (PC23)
331  PORT->Group[2].PINCFG[23].bit.PMUXEN = 1;
332  PORT->Group[2].PMUX[11].bit.PMUXO = MUX_PC23L_GMAC_GMDIO;
333 
334  //Select RMII operation mode
335  GMAC->UR.bit.MII = 0;
336 
337  //Configure PHY_RESET (PC18) as an output
338  PORT->Group[2].DIRSET.reg = PORT_PC18;
339 
340  //Reset PHY transceiver
341  PORT->Group[2].OUTCLR.reg = PORT_PC18;
342  sleep(10);
343  PORT->Group[2].OUTSET.reg = PORT_PC18;
344  sleep(10);
345 #endif
346 }
347 
348 #endif
349 
350 
351 /**
352  * @brief Initialize buffer descriptors
353  * @param[in] interface Underlying network interface
354  **/
355 
357 {
358  uint_t i;
359  uint32_t address;
360 
361  //Initialize TX buffer descriptors
362  for(i = 0; i < SAME54_ETH_TX_BUFFER_COUNT; i++)
363  {
364  //Calculate the address of the current TX buffer
365  address = (uint32_t) txBuffer[i];
366  //Write the address to the descriptor entry
367  txBufferDesc[i].address = address;
368  //Initialize status field
369  txBufferDesc[i].status = GMAC_TX_USED;
370  }
371 
372  //Mark the last descriptor entry with the wrap flag
373  txBufferDesc[i - 1].status |= GMAC_TX_WRAP;
374  //Initialize TX buffer index
375  txBufferIndex = 0;
376 
377  //Initialize RX buffer descriptors
378  for(i = 0; i < SAME54_ETH_RX_BUFFER_COUNT; i++)
379  {
380  //Calculate the address of the current RX buffer
381  address = (uint32_t) rxBuffer[i];
382  //Write the address to the descriptor entry
383  rxBufferDesc[i].address = address & GMAC_RX_ADDRESS;
384  //Clear status field
385  rxBufferDesc[i].status = 0;
386  }
387 
388  //Mark the last descriptor entry with the wrap flag
389  rxBufferDesc[i - 1].address |= GMAC_RX_WRAP;
390  //Initialize RX buffer index
391  rxBufferIndex = 0;
392 
393  //Start location of the TX descriptor list
394  GMAC->TBQB.reg = (uint32_t) txBufferDesc;
395  //Start location of the RX descriptor list
396  GMAC->RBQB.reg = (uint32_t) rxBufferDesc;
397 }
398 
399 
400 /**
401  * @brief SAME54 Ethernet MAC timer handler
402  *
403  * This routine is periodically called by the TCP/IP stack to handle periodic
404  * operations such as polling the link state
405  *
406  * @param[in] interface Underlying network interface
407  **/
408 
409 void same54EthTick(NetInterface *interface)
410 {
411  //Valid Ethernet PHY or switch driver?
412  if(interface->phyDriver != NULL)
413  {
414  //Handle periodic operations
415  interface->phyDriver->tick(interface);
416  }
417  else if(interface->switchDriver != NULL)
418  {
419  //Handle periodic operations
420  interface->switchDriver->tick(interface);
421  }
422  else
423  {
424  //Just for sanity
425  }
426 }
427 
428 
429 /**
430  * @brief Enable interrupts
431  * @param[in] interface Underlying network interface
432  **/
433 
435 {
436  //Enable Ethernet MAC interrupts
437  NVIC_EnableIRQ(GMAC_IRQn);
438 
439  //Valid Ethernet PHY or switch driver?
440  if(interface->phyDriver != NULL)
441  {
442  //Enable Ethernet PHY interrupts
443  interface->phyDriver->enableIrq(interface);
444  }
445  else if(interface->switchDriver != NULL)
446  {
447  //Enable Ethernet switch interrupts
448  interface->switchDriver->enableIrq(interface);
449  }
450  else
451  {
452  //Just for sanity
453  }
454 }
455 
456 
457 /**
458  * @brief Disable interrupts
459  * @param[in] interface Underlying network interface
460  **/
461 
463 {
464  //Disable Ethernet MAC interrupts
465  NVIC_DisableIRQ(GMAC_IRQn);
466 
467  //Valid Ethernet PHY or switch driver?
468  if(interface->phyDriver != NULL)
469  {
470  //Disable Ethernet PHY interrupts
471  interface->phyDriver->disableIrq(interface);
472  }
473  else if(interface->switchDriver != NULL)
474  {
475  //Disable Ethernet switch interrupts
476  interface->switchDriver->disableIrq(interface);
477  }
478  else
479  {
480  //Just for sanity
481  }
482 }
483 
484 
485 /**
486  * @brief SAME54 Ethernet MAC interrupt service routine
487  **/
488 
489 void GMAC_Handler(void)
490 {
491  bool_t flag;
492  volatile uint32_t isr;
493  volatile uint32_t tsr;
494  volatile uint32_t rsr;
495 
496  //Interrupt service routine prologue
497  osEnterIsr();
498 
499  //This flag will be set if a higher priority task must be woken
500  flag = FALSE;
501 
502  //Each time the software reads GMAC_ISR, it has to check the
503  //contents of GMAC_TSR, GMAC_RSR and GMAC_NSR
504  isr = GMAC->ISR.reg;
505  tsr = GMAC->TSR.reg;
506  rsr = GMAC->RSR.reg;
507 
508  //Packet transmitted?
509  if((tsr & (GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
510  GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR)) != 0)
511  {
512  //Only clear TSR flags that are currently set
513  GMAC->TSR.reg = tsr;
514 
515  //Check whether the TX buffer is available for writing
516  if((txBufferDesc[txBufferIndex].status & GMAC_TX_USED) != 0)
517  {
518  //Notify the TCP/IP stack that the transmitter is ready to send
519  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
520  }
521  }
522 
523  //Packet received?
524  if((rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) != 0)
525  {
526  //Set event flag
527  nicDriverInterface->nicEvent = TRUE;
528  //Notify the TCP/IP stack of the event
529  flag |= osSetEventFromIsr(&netEvent);
530  }
531 
532  //Interrupt service routine epilogue
533  osExitIsr(flag);
534 }
535 
536 
537 /**
538  * @brief SAME54 Ethernet MAC event handler
539  * @param[in] interface Underlying network interface
540  **/
541 
543 {
544  error_t error;
545  uint32_t rsr;
546 
547  //Read receive status
548  rsr = GMAC->RSR.reg;
549 
550  //Packet received?
551  if((rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA)) != 0)
552  {
553  //Only clear RSR flags that are currently set
554  GMAC->RSR.reg = rsr;
555 
556  //Process all pending packets
557  do
558  {
559  //Read incoming packet
560  error = same54EthReceivePacket(interface);
561 
562  //No more data in the receive buffer?
563  } while(error != ERROR_BUFFER_EMPTY);
564  }
565 }
566 
567 
568 /**
569  * @brief Send a packet
570  * @param[in] interface Underlying network interface
571  * @param[in] buffer Multi-part buffer containing the data to send
572  * @param[in] offset Offset to the first data byte
573  * @param[in] ancillary Additional options passed to the stack along with
574  * the packet
575  * @return Error code
576  **/
577 
579  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
580 {
581  size_t length;
582 
583  //Retrieve the length of the packet
584  length = netBufferGetLength(buffer) - offset;
585 
586  //Check the frame length
588  {
589  //The transmitter can accept another packet
590  osSetEvent(&interface->nicTxEvent);
591  //Report an error
592  return ERROR_INVALID_LENGTH;
593  }
594 
595  //Make sure the current buffer is available for writing
596  if((txBufferDesc[txBufferIndex].status & GMAC_TX_USED) == 0)
597  {
598  return ERROR_FAILURE;
599  }
600 
601  //Copy user data to the transmit buffer
602  netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
603 
604  //Set the necessary flags in the descriptor entry
605  if(txBufferIndex < (SAME54_ETH_TX_BUFFER_COUNT - 1))
606  {
607  //Write the status word
608  txBufferDesc[txBufferIndex].status = GMAC_TX_LAST |
610 
611  //Point to the next buffer
612  txBufferIndex++;
613  }
614  else
615  {
616  //Write the status word
617  txBufferDesc[txBufferIndex].status = GMAC_TX_WRAP | GMAC_TX_LAST |
619 
620  //Wrap around
621  txBufferIndex = 0;
622  }
623 
624  //Data synchronization barrier
625  __DSB();
626 
627  //Set the TSTART bit to initiate transmission
628  GMAC->NCR.reg |= GMAC_NCR_TSTART;
629 
630  //Check whether the next buffer is available for writing
631  if((txBufferDesc[txBufferIndex].status & GMAC_TX_USED) != 0)
632  {
633  //The transmitter can accept another packet
634  osSetEvent(&interface->nicTxEvent);
635  }
636 
637  //Successful processing
638  return NO_ERROR;
639 }
640 
641 
642 /**
643  * @brief Receive a packet
644  * @param[in] interface Underlying network interface
645  * @return Error code
646  **/
647 
649 {
650  static uint8_t temp[ETH_MAX_FRAME_SIZE];
651  error_t error;
652  uint_t i;
653  uint_t j;
654  uint_t sofIndex;
655  uint_t eofIndex;
656  size_t n;
657  size_t size;
658  size_t length;
659 
660  //Initialize SOF and EOF indices
661  sofIndex = UINT_MAX;
662  eofIndex = UINT_MAX;
663 
664  //Search for SOF and EOF flags
665  for(i = 0; i < SAME54_ETH_RX_BUFFER_COUNT; i++)
666  {
667  //Point to the current entry
668  j = rxBufferIndex + i;
669 
670  //Wrap around to the beginning of the buffer if necessary
672  {
674  }
675 
676  //No more entries to process?
677  if((rxBufferDesc[j].address & GMAC_RX_OWNERSHIP) == 0)
678  {
679  //Stop processing
680  break;
681  }
682 
683  //A valid SOF has been found?
684  if((rxBufferDesc[j].status & GMAC_RX_SOF) != 0)
685  {
686  //Save the position of the SOF
687  sofIndex = i;
688  }
689 
690  //A valid EOF has been found?
691  if((rxBufferDesc[j].status & GMAC_RX_EOF) != 0 && sofIndex != UINT_MAX)
692  {
693  //Save the position of the EOF
694  eofIndex = i;
695  //Retrieve the length of the frame
696  size = rxBufferDesc[j].status & GMAC_RX_LENGTH;
697  //Limit the number of data to read
698  size = MIN(size, ETH_MAX_FRAME_SIZE);
699  //Stop processing since we have reached the end of the frame
700  break;
701  }
702  }
703 
704  //Determine the number of entries to process
705  if(eofIndex != UINT_MAX)
706  {
707  j = eofIndex + 1;
708  }
709  else if(sofIndex != UINT_MAX)
710  {
711  j = sofIndex;
712  }
713  else
714  {
715  j = i;
716  }
717 
718  //Total number of bytes that have been copied from the receive buffer
719  length = 0;
720 
721  //Process incoming frame
722  for(i = 0; i < j; i++)
723  {
724  //Any data to copy from current buffer?
725  if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
726  {
727  //Calculate the number of bytes to read at a time
729  //Copy data from receive buffer
730  osMemcpy(temp + length, rxBuffer[rxBufferIndex], n);
731  //Update byte counters
732  length += n;
733  size -= n;
734  }
735 
736  //Mark the current buffer as free
737  rxBufferDesc[rxBufferIndex].address &= ~GMAC_RX_OWNERSHIP;
738 
739  //Point to the following entry
740  rxBufferIndex++;
741 
742  //Wrap around to the beginning of the buffer if necessary
743  if(rxBufferIndex >= SAME54_ETH_RX_BUFFER_COUNT)
744  {
745  rxBufferIndex = 0;
746  }
747  }
748 
749  //Any packet to process?
750  if(length > 0)
751  {
752  NetRxAncillary ancillary;
753 
754  //Additional options can be passed to the stack along with the packet
755  ancillary = NET_DEFAULT_RX_ANCILLARY;
756 
757  //Pass the packet to the upper layer
758  nicProcessPacket(interface, temp, length, &ancillary);
759  //Valid packet received
760  error = NO_ERROR;
761  }
762  else
763  {
764  //No more data in the receive buffer
765  error = ERROR_BUFFER_EMPTY;
766  }
767 
768  //Return status code
769  return error;
770 }
771 
772 
773 /**
774  * @brief Configure MAC address filtering
775  * @param[in] interface Underlying network interface
776  * @return Error code
777  **/
778 
780 {
781  uint_t i;
782  uint_t j;
783  uint_t k;
784  uint8_t *p;
785  uint32_t hashTable[2];
786  MacAddr unicastMacAddr[3];
787  MacFilterEntry *entry;
788 
789  //Debug message
790  TRACE_DEBUG("Updating MAC filter...\r\n");
791 
792  //Set the MAC address of the station
793  GMAC->Sa[0].SAB.reg = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
794  GMAC->Sa[0].SAT.reg = interface->macAddr.w[2];
795 
796  //The MAC supports 3 additional addresses for unicast perfect filtering
797  unicastMacAddr[0] = MAC_UNSPECIFIED_ADDR;
798  unicastMacAddr[1] = MAC_UNSPECIFIED_ADDR;
799  unicastMacAddr[2] = MAC_UNSPECIFIED_ADDR;
800 
801  //The hash table is used for multicast address filtering
802  hashTable[0] = 0;
803  hashTable[1] = 0;
804 
805  //The MAC address filter contains the list of MAC addresses to accept
806  //when receiving an Ethernet frame
807  for(i = 0, j = 0; i < MAC_ADDR_FILTER_SIZE; i++)
808  {
809  //Point to the current entry
810  entry = &interface->macAddrFilter[i];
811 
812  //Valid entry?
813  if(entry->refCount > 0)
814  {
815  //Multicast address?
816  if(macIsMulticastAddr(&entry->addr))
817  {
818  //Point to the MAC address
819  p = entry->addr.b;
820 
821  //Apply the hash function
822  k = (p[0] >> 6) ^ p[0];
823  k ^= (p[1] >> 4) ^ (p[1] << 2);
824  k ^= (p[2] >> 2) ^ (p[2] << 4);
825  k ^= (p[3] >> 6) ^ p[3];
826  k ^= (p[4] >> 4) ^ (p[4] << 2);
827  k ^= (p[5] >> 2) ^ (p[5] << 4);
828 
829  //The hash value is reduced to a 6-bit index
830  k &= 0x3F;
831 
832  //Update hash table contents
833  hashTable[k / 32] |= (1 << (k % 32));
834  }
835  else
836  {
837  //Up to 3 additional MAC addresses can be specified
838  if(j < 3)
839  {
840  //Save the unicast address
841  unicastMacAddr[j++] = entry->addr;
842  }
843  }
844  }
845  }
846 
847  //Configure the first unicast address filter
848  if(j >= 1)
849  {
850  //The address is activated when SAT register is written
851  GMAC->Sa[1].SAB.reg = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
852  GMAC->Sa[1].SAT.reg = unicastMacAddr[0].w[2];
853  }
854  else
855  {
856  //The address is deactivated when SAB register is written
857  GMAC->Sa[1].SAB.reg = 0;
858  }
859 
860  //Configure the second unicast address filter
861  if(j >= 2)
862  {
863  //The address is activated when SAT register is written
864  GMAC->Sa[2].SAB.reg = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
865  GMAC->Sa[2].SAT.reg = unicastMacAddr[1].w[2];
866  }
867  else
868  {
869  //The address is deactivated when SAB register is written
870  GMAC->Sa[2].SAB.reg = 0;
871  }
872 
873  //Configure the third unicast address filter
874  if(j >= 3)
875  {
876  //The address is activated when SAT register is written
877  GMAC->Sa[3].SAB.reg = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
878  GMAC->Sa[3].SAT.reg = unicastMacAddr[2].w[2];
879  }
880  else
881  {
882  //The address is deactivated when SAB register is written
883  GMAC->Sa[3].SAB.reg = 0;
884  }
885 
886  //Configure the multicast address filter
887  GMAC->HRB.reg = hashTable[0];
888  GMAC->HRT.reg = hashTable[1];
889 
890  //Debug message
891  TRACE_DEBUG(" HRB = %08" PRIX32 "\r\n", GMAC->HRB.reg);
892  TRACE_DEBUG(" HRT = %08" PRIX32 "\r\n", GMAC->HRT.reg);
893 
894  //Successful processing
895  return NO_ERROR;
896 }
897 
898 
899 /**
900  * @brief Adjust MAC configuration parameters for proper operation
901  * @param[in] interface Underlying network interface
902  * @return Error code
903  **/
904 
906 {
907  uint32_t config;
908 
909  //Read network configuration register
910  config = GMAC->NCFGR.reg;
911 
912  //10BASE-T or 100BASE-TX operation mode?
913  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
914  {
915  config |= GMAC_NCFGR_SPD;
916  }
917  else
918  {
919  config &= ~GMAC_NCFGR_SPD;
920  }
921 
922  //Half-duplex or full-duplex mode?
923  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
924  {
925  config |= GMAC_NCFGR_FD;
926  }
927  else
928  {
929  config &= ~GMAC_NCFGR_FD;
930  }
931 
932  //Write configuration value back to NCFGR register
933  GMAC->NCFGR.reg = config;
934 
935  //Successful processing
936  return NO_ERROR;
937 }
938 
939 
940 /**
941  * @brief Write PHY register
942  * @param[in] opcode Access type (2 bits)
943  * @param[in] phyAddr PHY address (5 bits)
944  * @param[in] regAddr Register address (5 bits)
945  * @param[in] data Register value
946  **/
947 
948 void same54EthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
949  uint8_t regAddr, uint16_t data)
950 {
951  uint32_t temp;
952 
953  //Valid opcode?
954  if(opcode == SMI_OPCODE_WRITE)
955  {
956  //Set up a write operation
957  temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2);
958  //PHY address
959  temp |= GMAC_MAN_PHYA(phyAddr);
960  //Register address
961  temp |= GMAC_MAN_REGA(regAddr);
962  //Register value
963  temp |= GMAC_MAN_DATA(data);
964 
965  //Start a write operation
966  GMAC->MAN.reg = temp;
967  //Wait for the write to complete
968  while((GMAC->NSR.reg & GMAC_NSR_IDLE) == 0)
969  {
970  }
971  }
972  else
973  {
974  //The MAC peripheral only supports standard Clause 22 opcodes
975  }
976 }
977 
978 
979 /**
980  * @brief Read PHY register
981  * @param[in] opcode Access type (2 bits)
982  * @param[in] phyAddr PHY address (5 bits)
983  * @param[in] regAddr Register address (5 bits)
984  * @return Register value
985  **/
986 
987 uint16_t same54EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
988  uint8_t regAddr)
989 {
990  uint16_t data;
991  uint32_t temp;
992 
993  //Valid opcode?
994  if(opcode == SMI_OPCODE_READ)
995  {
996  //Set up a read operation
997  temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2);
998  //PHY address
999  temp |= GMAC_MAN_PHYA(phyAddr);
1000  //Register address
1001  temp |= GMAC_MAN_REGA(regAddr);
1002 
1003  //Start a read operation
1004  GMAC->MAN.reg = temp;
1005  //Wait for the read to complete
1006  while((GMAC->NSR.reg & GMAC_NSR_IDLE) == 0)
1007  {
1008  }
1009 
1010  //Get register value
1011  data = GMAC->MAN.reg & GMAC_MAN_DATA_Msk;
1012  }
1013  else
1014  {
1015  //The MAC peripheral only supports standard Clause 22 opcodes
1016  data = 0;
1017  }
1018 
1019  //Return the value of the PHY register
1020  return data;
1021 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define SAME54_ETH_RX_BUFFER_SIZE
uint8_t length
Definition: coap_common.h:190
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:49
Transmit buffer descriptor.
error_t same54EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
#define netEvent
Definition: net_legacy.h:267
#define GMAC_TX_WRAP
uint8_t data[]
Definition: ethernet.h:209
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
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:88
#define SAME54_ETH_TX_BUFFER_SIZE
#define TRUE
Definition: os_port.h:50
Receive buffer descriptor.
#define sleep(delay)
Definition: os_port.h:251
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:103
__start_packed struct @5 MacAddr
MAC address.
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:249
#define GMAC_TX_LENGTH
#define GMAC_TX_LAST
uint16_t same54EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define SAME54_ETH_IRQ_SUB_PRIORITY
#define GMAC_RX_WRAP
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:388
#define GMAC_RX_OWNERSHIP
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:124
#define osExitIsr(flag)
void same54EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define SMI_OPCODE_WRITE
Definition: nic.h:65
#define SAME54_ETH_IRQ_GROUP_PRIORITY
void same54EthTick(NetInterface *interface)
SAME54 Ethernet MAC timer handler.
#define FALSE
Definition: os_port.h:46
#define osMemcpy(dest, src, length)
Definition: os_port.h:134
error_t
Error codes.
Definition: error.h:42
void same54EthDisableIrq(NetInterface *interface)
Disable interrupts.
#define GMAC_RX_SOF
const NicDriver same54EthDriver
SAME54 Ethernet MAC driver.
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:96
Generic error code.
Definition: error.h:45
error_t same54EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define SAME54_ETH_RX_BUFFER_COUNT
#define txBuffer
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:248
void same54EthInitGpio(NetInterface *interface)
#define GMAC_RX_EOF
void GMAC_Handler(void)
SAME54 Ethernet MAC interrupt service routine.
#define NetTxAncillary
Definition: net_misc.h:36
#define SMI_OPCODE_READ
Definition: nic.h:66
#define TRACE_INFO(...)
Definition: debug.h:95
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
#define rxBuffer
#define GMAC_RX_LENGTH
#define TRACE_DEBUG(...)
Definition: debug.h:107
uint16_t regAddr
void same54EthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
#define ETH_MTU
Definition: ethernet.h:105
uint8_t n
MAC filter table entry.
Definition: ethernet.h:246
#define osEnterIsr()
void same54EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
error_t same54EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
SAME54 Ethernet MAC driver.
#define GMAC_TX_USED
error_t same54EthInit(NetInterface *interface)
SAME54 Ethernet MAC initialization.
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
void same54EthEventHandler(NetInterface *interface)
SAME54 Ethernet MAC event handler.
NIC driver.
Definition: nic.h:257
error_t same54EthReceivePacket(NetInterface *interface)
Receive a packet.
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:56
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
#define SAME54_ETH_IRQ_PRIORITY_GROUPING
#define GMAC_RX_ADDRESS
#define SAME54_ETH_TX_BUFFER_COUNT
Ethernet interface.
Definition: nic.h:82