sam4e_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file sam4e_eth_driver.c
3  * @brief SAM4E Ethernet MAC controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include <limits.h>
36 #include "sam4e.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
55 static Sam4eTxBufferDesc txBufferDesc[SAM4E_ETH_TX_BUFFER_COUNT];
56 //RX buffer descriptors
57 #pragma data_alignment = 4
58 static Sam4eRxBufferDesc rxBufferDesc[SAM4E_ETH_RX_BUFFER_COUNT];
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 SAM4E Ethernet MAC driver
86  **/
87 
89 {
91  ETH_MTU,
102  TRUE,
103  TRUE,
104  TRUE,
105  FALSE
106 };
107 
108 
109 /**
110  * @brief SAM4E 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 SAM4E Ethernet MAC...\r\n");
122 
123  //Save underlying network interface
124  nicDriverInterface = interface;
125 
126  //Enable GMAC peripheral clock
127  PMC->PMC_PCER1 = (1 << (ID_GMAC - 32));
128 
129  //Disable transmit and receive circuits
130  GMAC->GMAC_NCR = 0;
131 
132  //GPIO configuration
133  sam4eEthInitGpio(interface);
134 
135  //Configure MDC clock speed
136  GMAC->GMAC_NCFGR = GMAC_NCFGR_CLK_MCK_96;
137  //Enable management port (MDC and MDIO)
138  GMAC->GMAC_NCR |= GMAC_NCR_MPE;
139 
140  //PHY transceiver initialization
141  error = interface->phyDriver->init(interface);
142  //Failed to initialize PHY transceiver?
143  if(error)
144  return error;
145 
146  //Set the MAC address of the station
147  GMAC->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
148  GMAC->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
149 
150  //The MAC supports 3 additional addresses for unicast perfect filtering
151  GMAC->GMAC_SA[1].GMAC_SAB = 0;
152  GMAC->GMAC_SA[2].GMAC_SAB = 0;
153  GMAC->GMAC_SA[3].GMAC_SAB = 0;
154 
155  //Initialize hash table
156  GMAC->GMAC_HRB = 0;
157  GMAC->GMAC_HRT = 0;
158 
159  //Configure the receive filter
160  GMAC->GMAC_NCFGR |= GMAC_NCFGR_MAXFS | GMAC_NCFGR_MTIHEN;
161 
162  //Initialize buffer descriptors
163  sam4eEthInitBufferDesc(interface);
164 
165  //Clear transmit status register
166  GMAC->GMAC_TSR = GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
167  GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR;
168  //Clear receive status register
169  GMAC->GMAC_RSR = GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA;
170 
171  //First disable all GMAC interrupts
172  GMAC->GMAC_IDR = 0xFFFFFFFF;
173  //Only the desired ones are enabled
174  GMAC->GMAC_IER = GMAC_IER_HRESP | GMAC_IER_ROVR | GMAC_IER_TCOMP | GMAC_IER_TFC |
175  GMAC_IER_RLEX | GMAC_IER_TUR | GMAC_IER_RXUBR | GMAC_IER_RCOMP;
176 
177  //Read GMAC ISR register to clear any pending interrupt
178  status = GMAC->GMAC_ISR;
179 
180  //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
181  NVIC_SetPriorityGrouping(SAM4E_ETH_IRQ_PRIORITY_GROUPING);
182 
183  //Configure GMAC interrupt priority
184  NVIC_SetPriority(GMAC_IRQn, NVIC_EncodePriority(SAM4E_ETH_IRQ_PRIORITY_GROUPING,
186 
187  //Enable the GMAC to transmit and receive data
188  GMAC->GMAC_NCR |= GMAC_NCR_TXEN | GMAC_NCR_RXEN;
189 
190  //Accept any packets from the upper layer
191  osSetEvent(&interface->nicTxEvent);
192 
193  //Successful initialization
194  return NO_ERROR;
195 }
196 
197 
198 //SAM4E-EK or SAM4E-Xplained-Pro evaluation board?
199 #if defined(USE_SAM4E_EK) || defined(USE_SAM4E_XPLAINED_PRO)
200 
201 /**
202  * @brief GPIO configuration
203  * @param[in] interface Underlying network interface
204  **/
205 
206 void sam4eEthInitGpio(NetInterface *interface)
207 {
208  //Enable PIO peripheral clock
209  PMC->PMC_PCER0 = (1 << ID_PIOD);
210 
211  //Disable pull-up resistors on MII pins
212  PIOD->PIO_PUDR = GMAC_MII_MASK;
213  //Disable interrupts-on-change
214  PIOD->PIO_IDR = GMAC_MII_MASK;
215  //Assign MII pins to peripheral A function
216  PIOD->PIO_ABCDSR[0] &= ~GMAC_MII_MASK;
217  PIOD->PIO_ABCDSR[1] &= ~GMAC_MII_MASK;
218  //Disable the PIO from controlling the corresponding pins
219  PIOD->PIO_PDR = GMAC_MII_MASK;
220 
221  //Select MII operation mode
222  GMAC->GMAC_UR = GMAC_UR_RMIIMII;
223 }
224 
225 #endif
226 
227 
228 /**
229  * @brief Initialize buffer descriptors
230  * @param[in] interface Underlying network interface
231  **/
232 
234 {
235  uint_t i;
236  uint32_t address;
237 
238  //Initialize TX buffer descriptors
239  for(i = 0; i < SAM4E_ETH_TX_BUFFER_COUNT; i++)
240  {
241  //Calculate the address of the current TX buffer
242  address = (uint32_t) txBuffer[i];
243  //Write the address to the descriptor entry
244  txBufferDesc[i].address = address;
245  //Initialize status field
246  txBufferDesc[i].status = GMAC_TX_USED;
247  }
248 
249  //Mark the last descriptor entry with the wrap flag
250  txBufferDesc[i - 1].status |= GMAC_TX_WRAP;
251  //Initialize TX buffer index
252  txBufferIndex = 0;
253 
254  //Initialize RX buffer descriptors
255  for(i = 0; i < SAM4E_ETH_RX_BUFFER_COUNT; i++)
256  {
257  //Calculate the address of the current RX buffer
258  address = (uint32_t) rxBuffer[i];
259  //Write the address to the descriptor entry
260  rxBufferDesc[i].address = address & GMAC_RX_ADDRESS;
261  //Clear status field
262  rxBufferDesc[i].status = 0;
263  }
264 
265  //Mark the last descriptor entry with the wrap flag
266  rxBufferDesc[i - 1].address |= GMAC_RX_WRAP;
267  //Initialize RX buffer index
268  rxBufferIndex = 0;
269 
270  //Start location of the TX descriptor list
271  GMAC->GMAC_TBQB = (uint32_t) txBufferDesc;
272  //Start location of the RX descriptor list
273  GMAC->GMAC_RBQB = (uint32_t) rxBufferDesc;
274 }
275 
276 
277 /**
278  * @brief SAM4E Ethernet MAC timer handler
279  *
280  * This routine is periodically called by the TCP/IP stack to
281  * handle periodic operations such as polling the link state
282  *
283  * @param[in] interface Underlying network interface
284  **/
285 
286 void sam4eEthTick(NetInterface *interface)
287 {
288  //Handle periodic operations
289  interface->phyDriver->tick(interface);
290 }
291 
292 
293 /**
294  * @brief Enable interrupts
295  * @param[in] interface Underlying network interface
296  **/
297 
299 {
300  //Enable Ethernet MAC interrupts
301  NVIC_EnableIRQ(GMAC_IRQn);
302  //Enable Ethernet PHY interrupts
303  interface->phyDriver->enableIrq(interface);
304 }
305 
306 
307 /**
308  * @brief Disable interrupts
309  * @param[in] interface Underlying network interface
310  **/
311 
313 {
314  //Disable Ethernet MAC interrupts
315  NVIC_DisableIRQ(GMAC_IRQn);
316  //Disable Ethernet PHY interrupts
317  interface->phyDriver->disableIrq(interface);
318 }
319 
320 
321 /**
322  * @brief SAM4E Ethernet MAC interrupt service routine
323  **/
324 
325 void GMAC_Handler(void)
326 {
327  bool_t flag;
328  volatile uint32_t isr;
329  volatile uint32_t tsr;
330  volatile uint32_t rsr;
331 
332  //Interrupt service routine prologue
333  osEnterIsr();
334 
335  //This flag will be set if a higher priority task must be woken
336  flag = FALSE;
337 
338  //Each time the software reads GMAC_ISR, it has to check the
339  //contents of GMAC_TSR, GMAC_RSR and GMAC_NSR
340  isr = GMAC->GMAC_ISR;
341  tsr = GMAC->GMAC_TSR;
342  rsr = GMAC->GMAC_RSR;
343 
344  //A packet has been transmitted?
345  if(tsr & (GMAC_TSR_HRESP | GMAC_TSR_UND | GMAC_TSR_TXCOMP | GMAC_TSR_TFC |
346  GMAC_TSR_TXGO | GMAC_TSR_RLE | GMAC_TSR_COL | GMAC_TSR_UBR))
347  {
348  //Only clear TSR flags that are currently set
349  GMAC->GMAC_TSR = tsr;
350 
351  //Check whether the TX buffer is available for writing
352  if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED)
353  {
354  //Notify the TCP/IP stack that the transmitter is ready to send
355  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
356  }
357  }
358 
359  //A packet has been received?
360  if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA))
361  {
362  //Set event flag
363  nicDriverInterface->nicEvent = TRUE;
364  //Notify the TCP/IP stack of the event
365  flag |= osSetEventFromIsr(&netEvent);
366  }
367 
368  //Interrupt service routine epilogue
369  osExitIsr(flag);
370 }
371 
372 
373 /**
374  * @brief SAM4E Ethernet MAC event handler
375  * @param[in] interface Underlying network interface
376  **/
377 
379 {
380  error_t error;
381  uint32_t rsr;
382 
383  //Read receive status
384  rsr = GMAC->GMAC_RSR;
385 
386  //Packet received?
387  if(rsr & (GMAC_RSR_HNO | GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA))
388  {
389  //Only clear RSR flags that are currently set
390  GMAC->GMAC_RSR = rsr;
391 
392  //Process all pending packets
393  do
394  {
395  //Read incoming packet
396  error = sam4eEthReceivePacket(interface);
397 
398  //No more data in the receive buffer?
399  } while(error != ERROR_BUFFER_EMPTY);
400  }
401 }
402 
403 
404 /**
405  * @brief Send a packet
406  * @param[in] interface Underlying network interface
407  * @param[in] buffer Multi-part buffer containing the data to send
408  * @param[in] offset Offset to the first data byte
409  * @return Error code
410  **/
411 
413  const NetBuffer *buffer, size_t offset)
414 {
415  size_t length;
416 
417  //Retrieve the length of the packet
418  length = netBufferGetLength(buffer) - offset;
419 
420  //Check the frame length
422  {
423  //The transmitter can accept another packet
424  osSetEvent(&interface->nicTxEvent);
425  //Report an error
426  return ERROR_INVALID_LENGTH;
427  }
428 
429  //Make sure the current buffer is available for writing
430  if(!(txBufferDesc[txBufferIndex].status & GMAC_TX_USED))
431  return ERROR_FAILURE;
432 
433  //Copy user data to the transmit buffer
434  netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
435 
436  //Set the necessary flags in the descriptor entry
437  if(txBufferIndex < (SAM4E_ETH_TX_BUFFER_COUNT - 1))
438  {
439  //Write the status word
440  txBufferDesc[txBufferIndex].status =
442 
443  //Point to the next buffer
444  txBufferIndex++;
445  }
446  else
447  {
448  //Write the status word
449  txBufferDesc[txBufferIndex].status = GMAC_TX_WRAP |
451 
452  //Wrap around
453  txBufferIndex = 0;
454  }
455 
456  //Set the TSTART bit to initiate transmission
457  GMAC->GMAC_NCR |= GMAC_NCR_TSTART;
458 
459  //Check whether the next buffer is available for writing
460  if(txBufferDesc[txBufferIndex].status & GMAC_TX_USED)
461  {
462  //The transmitter can accept another packet
463  osSetEvent(&interface->nicTxEvent);
464  }
465 
466  //Successful processing
467  return NO_ERROR;
468 }
469 
470 
471 /**
472  * @brief Receive a packet
473  * @param[in] interface Underlying network interface
474  * @return Error code
475  **/
476 
478 {
479  static uint8_t temp[ETH_MAX_FRAME_SIZE];
480  error_t error;
481  uint_t i;
482  uint_t j;
483  uint_t sofIndex;
484  uint_t eofIndex;
485  size_t n;
486  size_t size;
487  size_t length;
488 
489  //Initialize SOF and EOF indices
490  sofIndex = UINT_MAX;
491  eofIndex = UINT_MAX;
492 
493  //Search for SOF and EOF flags
494  for(i = 0; i < SAM4E_ETH_RX_BUFFER_COUNT; i++)
495  {
496  //Point to the current entry
497  j = rxBufferIndex + i;
498 
499  //Wrap around to the beginning of the buffer if necessary
502 
503  //No more entries to process?
504  if(!(rxBufferDesc[j].address & GMAC_RX_OWNERSHIP))
505  {
506  //Stop processing
507  break;
508  }
509  //A valid SOF has been found?
510  if(rxBufferDesc[j].status & GMAC_RX_SOF)
511  {
512  //Save the position of the SOF
513  sofIndex = i;
514  }
515  //A valid EOF has been found?
516  if((rxBufferDesc[j].status & GMAC_RX_EOF) && sofIndex != UINT_MAX)
517  {
518  //Save the position of the EOF
519  eofIndex = i;
520  //Retrieve the length of the frame
521  size = rxBufferDesc[j].status & GMAC_RX_LENGTH;
522  //Limit the number of data to read
523  size = MIN(size, ETH_MAX_FRAME_SIZE);
524  //Stop processing since we have reached the end of the frame
525  break;
526  }
527  }
528 
529  //Determine the number of entries to process
530  if(eofIndex != UINT_MAX)
531  j = eofIndex + 1;
532  else if(sofIndex != UINT_MAX)
533  j = sofIndex;
534  else
535  j = i;
536 
537  //Total number of bytes that have been copied from the receive buffer
538  length = 0;
539 
540  //Process incoming frame
541  for(i = 0; i < j; i++)
542  {
543  //Any data to copy from current buffer?
544  if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
545  {
546  //Calculate the number of bytes to read at a time
547  n = MIN(size, SAM4E_ETH_RX_BUFFER_SIZE);
548  //Copy data from receive buffer
549  memcpy(temp + length, rxBuffer[rxBufferIndex], n);
550  //Update byte counters
551  length += n;
552  size -= n;
553  }
554 
555  //Mark the current buffer as free
556  rxBufferDesc[rxBufferIndex].address &= ~GMAC_RX_OWNERSHIP;
557 
558  //Point to the following entry
559  rxBufferIndex++;
560 
561  //Wrap around to the beginning of the buffer if necessary
562  if(rxBufferIndex >= SAM4E_ETH_RX_BUFFER_COUNT)
563  rxBufferIndex = 0;
564  }
565 
566  //Any packet to process?
567  if(length > 0)
568  {
569  //Pass the packet to the upper layer
570  nicProcessPacket(interface, temp, length);
571  //Valid packet received
572  error = NO_ERROR;
573  }
574  else
575  {
576  //No more data in the receive buffer
577  error = ERROR_BUFFER_EMPTY;
578  }
579 
580  //Return status code
581  return error;
582 }
583 
584 
585 /**
586  * @brief Configure MAC address filtering
587  * @param[in] interface Underlying network interface
588  * @return Error code
589  **/
590 
592 {
593  uint_t i;
594  uint_t j;
595  uint_t k;
596  uint8_t *p;
597  uint32_t hashTable[2];
598  MacAddr unicastMacAddr[3];
599  MacFilterEntry *entry;
600 
601  //Debug message
602  TRACE_DEBUG("Updating MAC filter...\r\n");
603 
604  //Set the MAC address of the station
605  GMAC->GMAC_SA[0].GMAC_SAB = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
606  GMAC->GMAC_SA[0].GMAC_SAT = interface->macAddr.w[2];
607 
608  //The MAC supports 3 additional addresses for unicast perfect filtering
609  unicastMacAddr[0] = MAC_UNSPECIFIED_ADDR;
610  unicastMacAddr[1] = MAC_UNSPECIFIED_ADDR;
611  unicastMacAddr[2] = MAC_UNSPECIFIED_ADDR;
612 
613  //The hash table is used for multicast address filtering
614  hashTable[0] = 0;
615  hashTable[1] = 0;
616 
617  //The MAC address filter contains the list of MAC addresses to accept
618  //when receiving an Ethernet frame
619  for(i = 0, j = 0; i < MAC_ADDR_FILTER_SIZE; i++)
620  {
621  //Point to the current entry
622  entry = &interface->macAddrFilter[i];
623 
624  //Valid entry?
625  if(entry->refCount > 0)
626  {
627  //Multicast address?
628  if(macIsMulticastAddr(&entry->addr))
629  {
630  //Point to the MAC address
631  p = entry->addr.b;
632 
633  //Apply the hash function
634  k = (p[0] >> 6) ^ p[0];
635  k ^= (p[1] >> 4) ^ (p[1] << 2);
636  k ^= (p[2] >> 2) ^ (p[2] << 4);
637  k ^= (p[3] >> 6) ^ p[3];
638  k ^= (p[4] >> 4) ^ (p[4] << 2);
639  k ^= (p[5] >> 2) ^ (p[5] << 4);
640 
641  //The hash value is reduced to a 6-bit index
642  k &= 0x3F;
643 
644  //Update hash table contents
645  hashTable[k / 32] |= (1 << (k % 32));
646  }
647  else
648  {
649  //Up to 3 additional MAC addresses can be specified
650  if(j < 3)
651  {
652  //Save the unicast address
653  unicastMacAddr[j++] = entry->addr;
654  }
655  }
656  }
657  }
658 
659  //Configure the first unicast address filter
660  if(j >= 1)
661  {
662  //The address is activated when SAT register is written
663  GMAC->GMAC_SA[1].GMAC_SAB = unicastMacAddr[0].w[0] | (unicastMacAddr[0].w[1] << 16);
664  GMAC->GMAC_SA[1].GMAC_SAT = unicastMacAddr[0].w[2];
665  }
666  else
667  {
668  //The address is deactivated when SAB register is written
669  GMAC->GMAC_SA[1].GMAC_SAB = 0;
670  }
671 
672  //Configure the second unicast address filter
673  if(j >= 2)
674  {
675  //The address is activated when SAT register is written
676  GMAC->GMAC_SA[2].GMAC_SAB = unicastMacAddr[1].w[0] | (unicastMacAddr[1].w[1] << 16);
677  GMAC->GMAC_SA[2].GMAC_SAT = unicastMacAddr[1].w[2];
678  }
679  else
680  {
681  //The address is deactivated when SAB register is written
682  GMAC->GMAC_SA[2].GMAC_SAB = 0;
683  }
684 
685  //Configure the third unicast address filter
686  if(j >= 3)
687  {
688  //The address is activated when SAT register is written
689  GMAC->GMAC_SA[3].GMAC_SAB = unicastMacAddr[2].w[0] | (unicastMacAddr[2].w[1] << 16);
690  GMAC->GMAC_SA[3].GMAC_SAT = unicastMacAddr[2].w[2];
691  }
692  else
693  {
694  //The address is deactivated when SAB register is written
695  GMAC->GMAC_SA[3].GMAC_SAB = 0;
696  }
697 
698  //Configure the multicast address filter
699  GMAC->GMAC_HRB = hashTable[0];
700  GMAC->GMAC_HRT = hashTable[1];
701 
702  //Debug message
703  TRACE_DEBUG(" HRB = %08" PRIX32 "\r\n", GMAC->GMAC_HRB);
704  TRACE_DEBUG(" HRT = %08" PRIX32 "\r\n", GMAC->GMAC_HRT);
705 
706  //Successful processing
707  return NO_ERROR;
708 }
709 
710 
711 /**
712  * @brief Adjust MAC configuration parameters for proper operation
713  * @param[in] interface Underlying network interface
714  * @return Error code
715  **/
716 
718 {
719  uint32_t config;
720 
721  //Read network configuration register
722  config = GMAC->GMAC_NCFGR;
723 
724  //10BASE-T or 100BASE-TX operation mode?
725  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
726  config |= GMAC_NCFGR_SPD;
727  else
728  config &= ~GMAC_NCFGR_SPD;
729 
730  //Half-duplex or full-duplex mode?
731  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
732  config |= GMAC_NCFGR_FD;
733  else
734  config &= ~GMAC_NCFGR_FD;
735 
736  //Write configuration value back to NCFGR register
737  GMAC->GMAC_NCFGR = config;
738 
739  //Successful processing
740  return NO_ERROR;
741 }
742 
743 
744 /**
745  * @brief Write PHY register
746  * @param[in] opcode Access type (2 bits)
747  * @param[in] phyAddr PHY address (5 bits)
748  * @param[in] regAddr Register address (5 bits)
749  * @param[in] data Register value
750  **/
751 
752 void sam4eEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
753  uint8_t regAddr, uint16_t data)
754 {
755  uint32_t temp;
756 
757  //Valid opcode?
758  if(opcode == SMI_OPCODE_WRITE)
759  {
760  //Set up a write operation
761  temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(1) | GMAC_MAN_WTN(2);
762  //PHY address
763  temp |= GMAC_MAN_PHYA(phyAddr);
764  //Register address
765  temp |= GMAC_MAN_REGA(regAddr);
766  //Register value
767  temp |= GMAC_MAN_DATA(data);
768 
769  //Start a write operation
770  GMAC->GMAC_MAN = temp;
771  //Wait for the write to complete
772  while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE))
773  {
774  }
775  }
776  else
777  {
778  //The MAC peripheral only supports standard Clause 22 opcodes
779  }
780 }
781 
782 
783 /**
784  * @brief Read PHY register
785  * @param[in] opcode Access type (2 bits)
786  * @param[in] phyAddr PHY address (5 bits)
787  * @param[in] regAddr Register address (5 bits)
788  * @return Register value
789  **/
790 
791 uint16_t sam4eEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
792  uint8_t regAddr)
793 {
794  uint16_t data;
795  uint32_t temp;
796 
797  //Valid opcode?
798  if(opcode == SMI_OPCODE_READ)
799  {
800  //Set up a read operation
801  temp = GMAC_MAN_CLTTO | GMAC_MAN_OP(2) | GMAC_MAN_WTN(2);
802  //PHY address
803  temp |= GMAC_MAN_PHYA(phyAddr);
804  //Register address
805  temp |= GMAC_MAN_REGA(regAddr);
806 
807  //Start a read operation
808  GMAC->GMAC_MAN = temp;
809  //Wait for the read to complete
810  while(!(GMAC->GMAC_NSR & GMAC_NSR_IDLE))
811  {
812  }
813 
814  //Get register value
815  data = GMAC->GMAC_MAN & GMAC_MAN_DATA_Msk;
816  }
817  else
818  {
819  //The MAC peripheral only supports standard Clause 22 opcodes
820  data = 0;
821  }
822 
823  //Return the value of the PHY register
824  return data;
825 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
error_t sam4eEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
uint8_t length
Definition: dtls_misc.h:149
SAM4E Ethernet MAC controller.
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:49
uint16_t sam4eEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define GMAC_TX_WRAP
#define GMAC_MII_MASK
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:672
uint8_t p
Definition: ndp.h:298
#define SAM4E_ETH_RX_BUFFER_SIZE
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:383
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
#define TRUE
Definition: os_port.h:50
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:89
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:223
#define GMAC_TX_LENGTH
void sam4eEthInitGpio(NetInterface *interface)
#define GMAC_TX_LAST
Transmit buffer descriptor.
error_t sam4eEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define GMAC_RX_WRAP
#define GMAC_RX_OWNERSHIP
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:110
#define osExitIsr(flag)
error_t sam4eEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define SMI_OPCODE_WRITE
Definition: nic.h:62
void sam4eEthTick(NetInterface *interface)
SAM4E Ethernet MAC timer handler.
Receive buffer descriptor.
#define FALSE
Definition: os_port.h:46
error_t
Error codes.
Definition: error.h:42
#define GMAC_RX_SOF
#define SAM4E_ETH_IRQ_PRIORITY_GROUPING
Generic error code.
Definition: error.h:45
#define SAM4E_ETH_IRQ_SUB_PRIORITY
#define txBuffer
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:222
#define SAM4E_ETH_RX_BUFFER_COUNT
#define GMAC_RX_EOF
OsEvent netEvent
Definition: net.c:77
#define SMI_OPCODE_READ
Definition: nic.h:63
#define TRACE_INFO(...)
Definition: debug.h:94
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
error_t sam4eEthInit(NetInterface *interface)
SAM4E Ethernet MAC initialization.
#define MIN(a, b)
Definition: os_port.h:62
#define rxBuffer
#define GMAC_RX_LENGTH
#define TRACE_DEBUG(...)
Definition: debug.h:106
void sam4eEthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
void sam4eEthEventHandler(NetInterface *interface)
SAM4E Ethernet MAC event handler.
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:91
uint8_t n
MAC filter table entry.
Definition: ethernet.h:220
#define SAM4E_ETH_TX_BUFFER_SIZE
#define osEnterIsr()
error_t sam4eEthReceivePacket(NetInterface *interface)
Receive a packet.
const NicDriver sam4eEthDriver
SAM4E Ethernet MAC driver.
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
void sam4eEthDisableIrq(NetInterface *interface)
Disable interrupts.
#define GMAC_TX_USED
void sam4eEthEnableIrq(NetInterface *interface)
Enable interrupts.
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
NIC driver.
Definition: nic.h:179
#define SAM4E_ETH_TX_BUFFER_COUNT
#define SAM4E_ETH_IRQ_GROUP_PRIORITY
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:56
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
void sam4eEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
void GMAC_Handler(void)
SAM4E Ethernet MAC interrupt service routine.
#define GMAC_RX_ADDRESS
__start_packed struct @108 MacAddr
MAC address.
Ethernet interface.
Definition: nic.h:79