mpc5777_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file mpc5777_eth_driver.c
3  * @brief NXP MPC5777 Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "device_registers.h"
36 #include "interrupt_manager.h"
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //TX buffer
46  __attribute__((aligned(64)));
47 //RX buffer
49  __attribute__((aligned(64)));
50 //TX buffer descriptors
51 static uint32_t txBufferDesc[MPC5777_ETH_TX_BUFFER_COUNT][2]
52  __attribute__((aligned(64)));
53 //RX buffer descriptors
54 static uint32_t rxBufferDesc[MPC5777_ETH_RX_BUFFER_COUNT][2]
55  __attribute__((aligned(64)));
56 
57 //TX buffer index
58 static uint_t txBufferIndex;
59 //RX buffer index
60 static uint_t rxBufferIndex;
61 
62 
63 /**
64  * @brief MPC5777 Ethernet MAC driver
65  **/
66 
68 {
70  ETH_MTU,
81  TRUE,
82  TRUE,
83  TRUE,
84  FALSE
85 };
86 
87 
88 /**
89  * @brief MPC5777 Ethernet MAC initialization
90  * @param[in] interface Underlying network interface
91  * @return Error code
92  **/
93 
95 {
96  error_t error;
97  uint32_t value;
98 
99  //Debug message
100  TRACE_INFO("Initializing MPC5777 Ethernet MAC...\r\n");
101 
102  //Save underlying network interface
103  nicDriverInterface = interface;
104 
105  //GPIO configuration
106  mpc5777EthInitGpio(interface);
107 
108  //Reset FEC module
109  FEC->ECR = FEC_ECR_RESET_MASK;
110  //Wait for the reset to complete
111  while((FEC->ECR & FEC_ECR_RESET_MASK) != 0)
112  {
113  }
114 
115  //Receive control register
116  FEC->RCR = FEC_RCR_MAX_FL(MPC5777_ETH_RX_BUFFER_SIZE) |
117  FEC_RCR_RMII_MODE_MASK | FEC_RCR_MII_MODE_MASK;
118 
119  //Transmit control register
120  FEC->TCR = 0;
121  //Configure MDC clock frequency
122  FEC->MSCR = FEC_MSCR_MII_SPEED(19);
123 
124  //Valid Ethernet PHY or switch driver?
125  if(interface->phyDriver != NULL)
126  {
127  //Ethernet PHY initialization
128  error = interface->phyDriver->init(interface);
129  }
130  else if(interface->switchDriver != NULL)
131  {
132  //Ethernet switch initialization
133  error = interface->switchDriver->init(interface);
134  }
135  else
136  {
137  //The interface is not properly configured
138  error = ERROR_FAILURE;
139  }
140 
141  //Any error to report?
142  if(error)
143  {
144  return error;
145  }
146 
147  //Set the MAC address of the station (upper 16 bits)
148  value = interface->macAddr.b[5];
149  value |= (interface->macAddr.b[4] << 8);
150  FEC->PAUR = FEC_PAUR_PADDR2(value) | FEC_PAUR_TYPE(0x8808);
151 
152  //Set the MAC address of the station (lower 32 bits)
153  value = interface->macAddr.b[3];
154  value |= (interface->macAddr.b[2] << 8);
155  value |= (interface->macAddr.b[1] << 16);
156  value |= (interface->macAddr.b[0] << 24);
157  FEC->PALR = FEC_PALR_PADDR1(value);
158 
159  //Hash table for unicast address filtering
160  FEC->IALR = 0;
161  FEC->IAUR = 0;
162  //Hash table for multicast address filtering
163  FEC->GALR = 0;
164  FEC->GAUR = 0;
165 
166  //Disable statistics counters
167  FEC->MIBC = FEC_MIBC_MIB_DIS_MASK;
168 
169  //Initialize buffer descriptors
170  mpc5777EthInitBufferDesc(interface);
171 
172  //Clear any pending interrupts
173  FEC->EIR = 0xFFFFFFFF;
174  //Enable desired interrupts
175  FEC->EIMR = FEC_EIMR_TXF_MASK | FEC_EIMR_RXF_MASK | FEC_EIMR_EBERR_MASK;
176 
177  //Configure FEC transmit interrupt priority
178  INT_SYS_SetPriority(FEC_TXF_IRQn, MPC5777_ETH_IRQ_PRIORITY);
179  //Configure FEC receive interrupt priority
180  INT_SYS_SetPriority(FEC_RXF_IRQn, MPC5777_ETH_IRQ_PRIORITY);
181  //Configure FEC error interrupt priority
182  INT_SYS_SetPriority(FEC_ERR_IRQn, MPC5777_ETH_IRQ_PRIORITY);
183 
184  //Enable Ethernet MAC
185  FEC->ECR |= FEC_ECR_ETHER_EN_MASK;
186  //Instruct the DMA to poll the receive descriptor list
187  FEC->RDAR = FEC_RDAR_RDAR_MASK;
188 
189  //Accept any packets from the upper layer
190  osSetEvent(&interface->nicTxEvent);
191 
192  //Successful initialization
193  return NO_ERROR;
194 }
195 
196 
197 /**
198  * @brief GPIO configuration
199  * @param[in] interface Underlying network interface
200  **/
201 
202 __weak_func void mpc5777EthInitGpio(NetInterface *interface)
203 {
204 }
205 
206 
207 /**
208  * @brief Initialize buffer descriptors
209  * @param[in] interface Underlying network interface
210  **/
211 
213 {
214  uint_t i;
215  uint32_t address;
216 
217  //Clear TX and RX buffer descriptors
218  osMemset(txBufferDesc, 0, sizeof(txBufferDesc));
219  osMemset(rxBufferDesc, 0, sizeof(rxBufferDesc));
220 
221  //Initialize TX buffer descriptors
222  for(i = 0; i < MPC5777_ETH_TX_BUFFER_COUNT; i++)
223  {
224  //Calculate the address of the current TX buffer
225  address = (uint32_t) txBuffer[i];
226  //Transmit buffer address
227  txBufferDesc[i][1] = address;
228  }
229 
230  //Mark the last descriptor entry with the wrap flag
231  txBufferDesc[i - 1][0] |= FEC_TBD0_W;
232  //Initialize TX buffer index
233  txBufferIndex = 0;
234 
235  //Initialize RX buffer descriptors
236  for(i = 0; i < MPC5777_ETH_RX_BUFFER_COUNT; i++)
237  {
238  //Calculate the address of the current RX buffer
239  address = (uint32_t) rxBuffer[i];
240  //The descriptor is initially owned by the DMA
241  rxBufferDesc[i][0] = FEC_RBD0_E;
242  //Receive buffer address
243  rxBufferDesc[i][1] = address;
244  }
245 
246  //Mark the last descriptor entry with the wrap flag
247  rxBufferDesc[i - 1][0] |= FEC_RBD0_W;
248  //Initialize RX buffer index
249  rxBufferIndex = 0;
250 
251  //Start location of the TX descriptor list
252  FEC->ETDSR = (uint32_t) txBufferDesc;
253  //Start location of the RX descriptor list
254  FEC->ERDSR = (uint32_t) rxBufferDesc;
255  //Maximum receive buffer size
256  FEC->EMRBR = MPC5777_ETH_RX_BUFFER_SIZE;
257 }
258 
259 
260 /**
261  * @brief MPC5777 Ethernet MAC timer handler
262  *
263  * This routine is periodically called by the TCP/IP stack to handle periodic
264  * operations such as polling the link state
265  *
266  * @param[in] interface Underlying network interface
267  **/
268 
269 void mpc5777EthTick(NetInterface *interface)
270 {
271  //Valid Ethernet PHY or switch driver?
272  if(interface->phyDriver != NULL)
273  {
274  //Handle periodic operations
275  interface->phyDriver->tick(interface);
276  }
277  else if(interface->switchDriver != NULL)
278  {
279  //Handle periodic operations
280  interface->switchDriver->tick(interface);
281  }
282  else
283  {
284  //Just for sanity
285  }
286 }
287 
288 
289 /**
290  * @brief Enable interrupts
291  * @param[in] interface Underlying network interface
292  **/
293 
295 {
296  //Enable Ethernet MAC interrupts
297  INT_SYS_EnableIRQ(FEC_TXF_IRQn);
298  INT_SYS_EnableIRQ(FEC_RXF_IRQn);
299  INT_SYS_EnableIRQ(FEC_ERR_IRQn);
300 
301  //Valid Ethernet PHY or switch driver?
302  if(interface->phyDriver != NULL)
303  {
304  //Enable Ethernet PHY interrupts
305  interface->phyDriver->enableIrq(interface);
306  }
307  else if(interface->switchDriver != NULL)
308  {
309  //Enable Ethernet switch interrupts
310  interface->switchDriver->enableIrq(interface);
311  }
312  else
313  {
314  //Just for sanity
315  }
316 }
317 
318 
319 /**
320  * @brief Disable interrupts
321  * @param[in] interface Underlying network interface
322  **/
323 
325 {
326  //Disable Ethernet MAC interrupts
327  INT_SYS_DisableIRQ(FEC_TXF_IRQn);
328  INT_SYS_DisableIRQ(FEC_RXF_IRQn);
329  INT_SYS_DisableIRQ(FEC_ERR_IRQn);
330 
331  //Valid Ethernet PHY or switch driver?
332  if(interface->phyDriver != NULL)
333  {
334  //Disable Ethernet PHY interrupts
335  interface->phyDriver->disableIrq(interface);
336  }
337  else if(interface->switchDriver != NULL)
338  {
339  //Disable Ethernet switch interrupts
340  interface->switchDriver->disableIrq(interface);
341  }
342  else
343  {
344  //Just for sanity
345  }
346 }
347 
348 
349 /**
350  * @brief Ethernet MAC transmit interrupt
351  **/
352 
354 {
355  bool_t flag;
356 
357  //Interrupt service routine prologue
358  osEnterIsr();
359 
360  //This flag will be set if a higher priority task must be woken
361  flag = FALSE;
362 
363  //Packet transmitted?
364  if((FEC->EIR & FEC_EIR_TXF_MASK) != 0)
365  {
366  //Clear TXF interrupt flag
367  FEC->EIR = FEC_EIR_TXF_MASK;
368 
369  //Check whether the TX buffer is available for writing
370  if((txBufferDesc[txBufferIndex][0] & FEC_TBD0_R) == 0)
371  {
372  //Notify the TCP/IP stack that the transmitter is ready to send
373  flag = osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
374  }
375 
376  //Instruct the DMA to poll the transmit descriptor list
377  FEC->TDAR = FEC_TDAR_TDAR_MASK;
378  }
379 
380  //Interrupt service routine epilogue
381  osExitIsr(flag);
382 }
383 
384 
385 /**
386  * @brief Ethernet MAC receive interrupt
387  **/
388 
390 {
391  bool_t flag;
392 
393  //Interrupt service routine prologue
394  osEnterIsr();
395 
396  //This flag will be set if a higher priority task must be woken
397  flag = FALSE;
398 
399  //Packet received?
400  if((FEC->EIR & FEC_EIR_RXF_MASK) != 0)
401  {
402  //Disable RXF interrupt
403  FEC->EIMR &= ~FEC_EIMR_RXF_MASK;
404 
405  //Set event flag
406  nicDriverInterface->nicEvent = TRUE;
407  //Notify the TCP/IP stack of the event
408  flag = osSetEventFromIsr(&netEvent);
409  }
410 
411  //Interrupt service routine epilogue
412  osExitIsr(flag);
413 }
414 
415 
416 /**
417  * @brief Ethernet MAC error interrupt
418  **/
419 
421 {
422  bool_t flag;
423 
424  //Interrupt service routine prologue
425  osEnterIsr();
426 
427  //This flag will be set if a higher priority task must be woken
428  flag = FALSE;
429 
430  //System bus error?
431  if((FEC->EIR & FEC_EIR_EBERR_MASK) != 0)
432  {
433  //Disable EBERR interrupt
434  FEC->EIMR &= ~FEC_EIMR_EBERR_MASK;
435 
436  //Set event flag
437  nicDriverInterface->nicEvent = TRUE;
438  //Notify the TCP/IP stack of the event
439  flag |= osSetEventFromIsr(&netEvent);
440  }
441 
442  //Interrupt service routine epilogue
443  osExitIsr(flag);
444 }
445 
446 
447 /**
448  * @brief MPC5777 Ethernet MAC event handler
449  * @param[in] interface Underlying network interface
450  **/
451 
453 {
454  error_t error;
455  uint32_t status;
456 
457  //Read interrupt event register
458  status = FEC->EIR;
459 
460  //Packet received?
461  if((status & FEC_EIR_RXF_MASK) != 0)
462  {
463  //Clear RXF interrupt flag
464  FEC->EIR = FEC_EIR_RXF_MASK;
465 
466  //Process all pending packets
467  do
468  {
469  //Read incoming packet
470  error = mpc5777EthReceivePacket(interface);
471 
472  //No more data in the receive buffer?
473  } while(error != ERROR_BUFFER_EMPTY);
474  }
475 
476  //System bus error?
477  if((status & FEC_EIR_EBERR_MASK) != 0)
478  {
479  //Clear EBERR interrupt flag
480  FEC->EIR = FEC_EIR_EBERR_MASK;
481 
482  //Disable Ethernet MAC
483  FEC->ECR &= ~FEC_ECR_ETHER_EN_MASK;
484  //Reset buffer descriptors
485  mpc5777EthInitBufferDesc(interface);
486  //Resume normal operation
487  FEC->ECR |= FEC_ECR_ETHER_EN_MASK;
488  //Instruct the DMA to poll the receive descriptor list
489  FEC->RDAR = FEC_RDAR_RDAR_MASK;
490  }
491 
492  //Re-enable Ethernet MAC interrupts
493  FEC->EIMR = FEC_EIMR_TXF_MASK | FEC_EIMR_RXF_MASK | FEC_EIMR_EBERR_MASK;
494 }
495 
496 
497 /**
498  * @brief Send a packet
499  * @param[in] interface Underlying network interface
500  * @param[in] buffer Multi-part buffer containing the data to send
501  * @param[in] offset Offset to the first data byte
502  * @param[in] ancillary Additional options passed to the stack along with
503  * the packet
504  * @return Error code
505  **/
506 
508  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
509 {
510  size_t length;
511 
512  //Retrieve the length of the packet
513  length = netBufferGetLength(buffer) - offset;
514 
515  //Check the frame length
517  {
518  //The transmitter can accept another packet
519  osSetEvent(&interface->nicTxEvent);
520  //Report an error
521  return ERROR_INVALID_LENGTH;
522  }
523 
524  //Make sure the current buffer is available for writing
525  if((txBufferDesc[txBufferIndex][0] & FEC_TBD0_R) != 0)
526  {
527  return ERROR_FAILURE;
528  }
529 
530  //Copy user data to the transmit buffer
531  netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
532 
533  //Clear BDU flag
534  txBufferDesc[txBufferIndex][4] = 0;
535 
536  //Check current index
537  if(txBufferIndex < (MPC5777_ETH_TX_BUFFER_COUNT - 1))
538  {
539  //Give the ownership of the descriptor to the DMA engine
540  txBufferDesc[txBufferIndex][0] = FEC_TBD0_R | FEC_TBD0_L |
542 
543  //Point to the next buffer
544  txBufferIndex++;
545  }
546  else
547  {
548  //Give the ownership of the descriptor to the DMA engine
549  txBufferDesc[txBufferIndex][0] = FEC_TBD0_R | FEC_TBD0_W |
551 
552  //Wrap around
553  txBufferIndex = 0;
554  }
555 
556  //Instruct the DMA to poll the transmit descriptor list
557  FEC->TDAR = FEC_TDAR_TDAR_MASK;
558 
559  //Check whether the next buffer is available for writing
560  if((txBufferDesc[txBufferIndex][0] & FEC_TBD0_R) == 0)
561  {
562  //The transmitter can accept another packet
563  osSetEvent(&interface->nicTxEvent);
564  }
565 
566  //Successful processing
567  return NO_ERROR;
568 }
569 
570 
571 /**
572  * @brief Receive a packet
573  * @param[in] interface Underlying network interface
574  * @return Error code
575  **/
576 
578 {
579  error_t error;
580  size_t n;
581  NetRxAncillary ancillary;
582 
583  //Current buffer available for reading?
584  if((rxBufferDesc[rxBufferIndex][0] & FEC_RBD0_E) == 0)
585  {
586  //The frame should not span multiple buffers
587  if((rxBufferDesc[rxBufferIndex][0] & FEC_RBD0_L) != 0)
588  {
589  //Check whether an error occurred
590  if((rxBufferDesc[rxBufferIndex][0] & (FEC_RBD0_LG | FEC_RBD0_NO |
592  {
593  //Retrieve the length of the frame
594  n = rxBufferDesc[rxBufferIndex][0] & FEC_RBD0_DATA_LENGTH;
595  //Limit the number of data to read
597 
598  //Additional options can be passed to the stack along with the packet
599  ancillary = NET_DEFAULT_RX_ANCILLARY;
600 
601  //Pass the packet to the upper layer
602  nicProcessPacket(interface, rxBuffer[rxBufferIndex], n, &ancillary);
603 
604  //Valid packet received
605  error = NO_ERROR;
606  }
607  else
608  {
609  //The received packet contains an error
610  error = ERROR_INVALID_PACKET;
611  }
612  }
613  else
614  {
615  //The packet is not valid
616  error = ERROR_INVALID_PACKET;
617  }
618 
619  //Clear BDU flag
620  rxBufferDesc[rxBufferIndex][4] = 0;
621 
622  //Check current index
623  if(rxBufferIndex < (MPC5777_ETH_RX_BUFFER_COUNT - 1))
624  {
625  //Give the ownership of the descriptor back to the DMA engine
626  rxBufferDesc[rxBufferIndex][0] = FEC_RBD0_E;
627  //Point to the next buffer
628  rxBufferIndex++;
629  }
630  else
631  {
632  //Give the ownership of the descriptor back to the DMA engine
633  rxBufferDesc[rxBufferIndex][0] = FEC_RBD0_E | FEC_RBD0_W;
634  //Wrap around
635  rxBufferIndex = 0;
636  }
637 
638  //Instruct the DMA to poll the receive descriptor list
639  FEC->RDAR = FEC_RDAR_RDAR_MASK;
640  }
641  else
642  {
643  //No more data in the receive buffer
644  error = ERROR_BUFFER_EMPTY;
645  }
646 
647  //Return status code
648  return error;
649 }
650 
651 
652 /**
653  * @brief Configure MAC address filtering
654  * @param[in] interface Underlying network interface
655  * @return Error code
656  **/
657 
659 {
660  uint_t i;
661  uint_t k;
662  uint32_t crc;
663  uint32_t value;
664  uint32_t unicastHashTable[2];
665  uint32_t multicastHashTable[2];
666  MacFilterEntry *entry;
667 
668  //Debug message
669  TRACE_DEBUG("Updating MAC filter...\r\n");
670 
671  //Set the MAC address of the station (upper 16 bits)
672  value = interface->macAddr.b[5];
673  value |= (interface->macAddr.b[4] << 8);
674  FEC->PAUR = FEC_PAUR_PADDR2(value) | FEC_PAUR_TYPE(0x8808);
675 
676  //Set the MAC address of the station (lower 32 bits)
677  value = interface->macAddr.b[3];
678  value |= (interface->macAddr.b[2] << 8);
679  value |= (interface->macAddr.b[1] << 16);
680  value |= (interface->macAddr.b[0] << 24);
681  FEC->PALR = FEC_PALR_PADDR1(value);
682 
683  //Clear hash table (unicast address filtering)
684  unicastHashTable[0] = 0;
685  unicastHashTable[1] = 0;
686 
687  //Clear hash table (multicast address filtering)
688  multicastHashTable[0] = 0;
689  multicastHashTable[1] = 0;
690 
691  //The MAC address filter contains the list of MAC addresses to accept
692  //when receiving an Ethernet frame
693  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
694  {
695  //Point to the current entry
696  entry = &interface->macAddrFilter[i];
697 
698  //Valid entry?
699  if(entry->refCount > 0)
700  {
701  //Compute CRC over the current MAC address
702  crc = mpc5777EthCalcCrc(&entry->addr, sizeof(MacAddr));
703 
704  //The upper 6 bits in the CRC register are used to index the
705  //contents of the hash table
706  k = (crc >> 26) & 0x3F;
707 
708  //Multicast address?
709  if(macIsMulticastAddr(&entry->addr))
710  {
711  //Update the multicast hash table
712  multicastHashTable[k / 32] |= (1 << (k % 32));
713  }
714  else
715  {
716  //Update the unicast hash table
717  unicastHashTable[k / 32] |= (1 << (k % 32));
718  }
719  }
720  }
721 
722  //Write the hash table (unicast address filtering)
723  FEC->IALR = unicastHashTable[0];
724  FEC->IAUR = unicastHashTable[1];
725 
726  //Write the hash table (multicast address filtering)
727  FEC->GALR = multicastHashTable[0];
728  FEC->GAUR = multicastHashTable[1];
729 
730  //Debug message
731  TRACE_DEBUG(" IALR = %08" PRIX32 "\r\n", FEC->IALR);
732  TRACE_DEBUG(" IAUR = %08" PRIX32 "\r\n", FEC->IAUR);
733  TRACE_DEBUG(" GALR = %08" PRIX32 "\r\n", FEC->GALR);
734  TRACE_DEBUG(" GAUR = %08" PRIX32 "\r\n", FEC->GAUR);
735 
736  //Successful processing
737  return NO_ERROR;
738 }
739 
740 
741 /**
742  * @brief Adjust MAC configuration parameters for proper operation
743  * @param[in] interface Underlying network interface
744  * @return Error code
745  **/
746 
748 {
749  //Disable Ethernet MAC while modifying configuration registers
750  FEC->ECR &= ~FEC_ECR_ETHER_EN_MASK;
751 
752  //10BASE-T or 100BASE-TX operation mode?
753  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
754  {
755  //100 Mbps operation
756  FEC->RCR &= ~FEC_RCR_RMII_10T_MASK;
757  }
758  else
759  {
760  //10 Mbps operation
761  FEC->RCR |= FEC_RCR_RMII_10T_MASK;
762  }
763 
764  //Half-duplex or full-duplex mode?
765  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
766  {
767  //Full-duplex mode
768  FEC->TCR |= FEC_TCR_FDEN_MASK;
769  //Receive path operates independently of transmit
770  FEC->RCR &= ~FEC_RCR_DRT_MASK;
771  }
772  else
773  {
774  //Half-duplex mode
775  FEC->TCR &= ~FEC_TCR_FDEN_MASK;
776  //Disable reception of frames while transmitting
777  FEC->RCR |= FEC_RCR_DRT_MASK;
778  }
779 
780  //Reset buffer descriptors
781  mpc5777EthInitBufferDesc(interface);
782 
783  //Re-enable Ethernet MAC
784  FEC->ECR |= FEC_ECR_ETHER_EN_MASK;
785  //Instruct the DMA to poll the receive descriptor list
786  FEC->RDAR = FEC_RDAR_RDAR_MASK;
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 mpc5777EthWritePhyReg(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 = FEC_MMFR_ST(1) | FEC_MMFR_OP(1) | FEC_MMFR_TA(2);
811  //PHY address
812  temp |= FEC_MMFR_PA(phyAddr);
813  //Register address
814  temp |= FEC_MMFR_RA(regAddr);
815  //Register value
816  temp |= FEC_MMFR_DATA(data);
817 
818  //Clear MII interrupt flag
819  FEC->EIR = FEC_EIR_MII_MASK;
820  //Start a write operation
821  FEC->MMFR = temp;
822 
823  //Wait for the write to complete
824  while((FEC->EIR & FEC_EIR_MII_MASK) == 0)
825  {
826  }
827  }
828  else
829  {
830  //The MAC peripheral only supports standard Clause 22 opcodes
831  }
832 }
833 
834 
835 /**
836  * @brief Read PHY register
837  * @param[in] opcode Access type (2 bits)
838  * @param[in] phyAddr PHY address (5 bits)
839  * @param[in] regAddr Register address (5 bits)
840  * @return Register value
841  **/
842 
843 uint16_t mpc5777EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
844  uint8_t regAddr)
845 {
846  uint16_t data;
847  uint32_t temp;
848 
849  //Valid opcode?
850  if(opcode == SMI_OPCODE_READ)
851  {
852  //Set up a read operation
853  temp = FEC_MMFR_ST(1) | FEC_MMFR_OP(2) | FEC_MMFR_TA(2);
854  //PHY address
855  temp |= FEC_MMFR_PA(phyAddr);
856  //Register address
857  temp |= FEC_MMFR_RA(regAddr);
858 
859  //Clear MII interrupt flag
860  FEC->EIR = FEC_EIR_MII_MASK;
861  //Start a read operation
862  FEC->MMFR = temp;
863 
864  //Wait for the read to complete
865  while((FEC->EIR & FEC_EIR_MII_MASK) == 0)
866  {
867  }
868 
869  //Get register value
870  data = FEC->MMFR & FEC_MMFR_DATA_MASK;
871  }
872  else
873  {
874  //The MAC peripheral only supports standard Clause 22 opcodes
875  data = 0;
876  }
877 
878  //Return the value of the PHY register
879  return data;
880 }
881 
882 
883 /**
884  * @brief CRC calculation
885  * @param[in] data Pointer to the data over which to calculate the CRC
886  * @param[in] length Number of bytes to process
887  * @return Resulting CRC value
888  **/
889 
890 uint32_t mpc5777EthCalcCrc(const void *data, size_t length)
891 {
892  uint_t i;
893  uint_t j;
894  uint32_t crc;
895  const uint8_t *p;
896 
897  //Point to the data over which to calculate the CRC
898  p = (uint8_t *) data;
899  //CRC preset value
900  crc = 0xFFFFFFFF;
901 
902  //Loop through data
903  for(i = 0; i < length; i++)
904  {
905  //Update CRC value
906  crc ^= p[i];
907 
908  //The message is processed bit by bit
909  for(j = 0; j < 8; j++)
910  {
911  if((crc & 0x01) != 0)
912  {
913  crc = (crc >> 1) ^ 0xEDB88320;
914  }
915  else
916  {
917  crc = crc >> 1;
918  }
919  }
920  }
921 
922  //Return CRC value
923  return crc;
924 }
#define rxBuffer
#define txBuffer
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
uint8_t opcode
Definition: dns_common.h:188
error_t
Error codes.
Definition: error.h:43
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PACKET
Definition: error.h:140
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:133
#define ETH_MTU
Definition: ethernet.h:116
uint8_t data[]
Definition: ethernet.h:222
MacAddr
Definition: ethernet.h:195
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
Ipv6Addr address[]
Definition: ipv6.h:316
uint16_t regAddr
error_t mpc5777EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
uint32_t mpc5777EthCalcCrc(const void *data, size_t length)
CRC calculation.
void FEC_RXF_IRQHandler(void)
Ethernet MAC receive interrupt.
error_t mpc5777EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
__weak_func void mpc5777EthInitGpio(NetInterface *interface)
GPIO configuration.
void mpc5777EthTick(NetInterface *interface)
MPC5777 Ethernet MAC timer handler.
uint16_t mpc5777EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
void mpc5777EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
error_t mpc5777EthReceivePacket(NetInterface *interface)
Receive a packet.
void mpc5777EthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
void FEC_TXF_IRQHandler(void)
Ethernet MAC transmit interrupt.
error_t mpc5777EthInit(NetInterface *interface)
MPC5777 Ethernet MAC initialization.
error_t mpc5777EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
const NicDriver mpc5777EthDriver
MPC5777 Ethernet MAC driver.
void mpc5777EthEnableIrq(NetInterface *interface)
Enable interrupts.
void mpc5777EthEventHandler(NetInterface *interface)
MPC5777 Ethernet MAC event handler.
void FEC_ERR_IRQHandler(void)
Ethernet MAC error interrupt.
void mpc5777EthDisableIrq(NetInterface *interface)
Disable interrupts.
NXP MPC5777 Ethernet MAC driver.
#define FEC_RBD0_LG
#define FEC_TBD0_TC
#define FEC_TBD0_L
#define FEC_RBD0_OV
#define FEC_RBD0_NO
#define FEC_RBD0_DATA_LENGTH
#define FEC_RBD0_W
#define FEC_TBD0_DATA_LENGTH
#define MPC5777_ETH_RX_BUFFER_COUNT
#define FEC_RBD0_L
#define FEC_RBD0_E
#define FEC_RBD0_CR
#define FEC_RBD0_TR
#define FEC_TBD0_R
#define MPC5777_ETH_TX_BUFFER_SIZE
#define MPC5777_ETH_RX_BUFFER_SIZE
#define FEC_TBD0_W
#define MPC5777_ETH_IRQ_PRIORITY
#define MPC5777_ETH_TX_BUFFER_COUNT
uint8_t p
Definition: ndp.h:300
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netEvent
Definition: net_legacy.h:196
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
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:674
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:101
#define NetRxAncillary
Definition: net_misc.h:40
#define NetTxAncillary
Definition: net_misc.h:36
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:391
#define SMI_OPCODE_WRITE
Definition: nic.h:66
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define SMI_OPCODE_READ
Definition: nic.h:67
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
#define osMemset(p, value, length)
Definition: os_port.h:135
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define osEnterIsr()
#define osExitIsr(flag)
MAC filter table entry.
Definition: ethernet.h:262
MacAddr addr
MAC address.
Definition: ethernet.h:263
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:264
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:283
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369