mpc57xx_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file mpc57xx_eth_driver.c
3  * @brief Freescale MPC57xx Ethernet MAC controller
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include "device_registers.h"
34 #include "core/net.h"
36 #include "debug.h"
37 
38 //Underlying network interface
39 static NetInterface *nicDriverInterface;
40 
41 //TX buffer
43  __attribute__((aligned(64)));
44 //RX buffer
46  __attribute__((aligned(64)));
47 //TX buffer descriptors
48 static uint32_t txBufferDesc[MPC57XX_ETH_TX_BUFFER_COUNT][8]
49  __attribute__((aligned(64)));
50 //RX buffer descriptors
51 static uint32_t rxBufferDesc[MPC57XX_ETH_RX_BUFFER_COUNT][8]
52  __attribute__((aligned(64)));
53 
54 
55 //TX buffer index
56 static uint_t txBufferIndex;
57 //RX buffer index
58 static uint_t rxBufferIndex;
59 
60 
61 /**
62  * @brief MPC57xx Ethernet MAC driver
63  **/
64 
66 {
68  ETH_MTU,
79  TRUE,
80  TRUE,
81  TRUE,
82  FALSE
83 };
84 
85 
86 /**
87  * @brief MPC57xx Ethernet MAC initialization
88  * @param[in] interface Underlying network interface
89  * @return Error code
90  **/
91 
93 {
94  error_t error;
95  uint32_t value;
96 
97  //Debug message
98  TRACE_INFO("Initializing MPC57xx Ethernet MAC...\r\n");
99 
100  //Save underlying network interface
101  nicDriverInterface = interface;
102 
103  //GPIO configuration
104  mpc57xxEthInitGpio(interface);
105 
106  //Reset ENET module
107  ENET_0->ECR = ENET_ECR_RESET_MASK;
108  //Wait for the reset to complete
109  while(ENET_0->ECR & ENET_ECR_RESET_MASK);
110 
111  //Receive control register
112  ENET_0->RCR = ENET_RCR_MAX_FL(1518) | ENET_RCR_RMII_MODE_MASK |
113  ENET_RCR_MII_MODE_MASK;
114 
115  //Transmit control register
116  ENET_0->TCR = 0;
117  //Configure MDC clock frequency
118  ENET_0->MSCR = ENET_MSCR_MII_SPEED(19);
119 
120  //PHY transceiver initialization
121  error = interface->phyDriver->init(interface);
122  //Failed to initialize PHY transceiver?
123  if(error)
124  return error;
125 
126  //Set the MAC address (upper 16 bits)
127  value = interface->macAddr.b[5];
128  value |= (interface->macAddr.b[4] << 8);
129  ENET_0->PAUR = ENET_PAUR_PADDR2(value) | ENET_PAUR_TYPE(0x8808);
130 
131  //Set the MAC address (lower 32 bits)
132  value = interface->macAddr.b[3];
133  value |= (interface->macAddr.b[2] << 8);
134  value |= (interface->macAddr.b[1] << 16);
135  value |= (interface->macAddr.b[0] << 24);
136  ENET_0->PALR = ENET_PALR_PADDR1(value);
137 
138  //Hash table for unicast address filtering
139  ENET_0->IALR = 0;
140  ENET_0->IAUR = 0;
141  //Hash table for multicast address filtering
142  ENET_0->GALR = 0;
143  ENET_0->GAUR = 0;
144 
145  //Disable transmit accelerator functions
146  ENET_0->TACC = 0;
147  //Disable receive accelerator functions
148  ENET_0->RACC = 0;
149 
150  //Use enhanced buffer descriptors
151  ENET_0->ECR = ENET_ECR_EN1588_MASK;
152  //Clear MIC counters
153  ENET_0->MIBC = ENET_MIBC_MIB_CLEAR_MASK;
154 
155  //Initialize buffer descriptors
156  mpc57xxEthInitBufferDesc(interface);
157 
158  //Clear any pending interrupts
159  ENET_0->EIR = 0xFFFFFFFF;
160  //Enable desired interrupts
161  ENET_0->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
162 
163  //Configure ENET transmit interrupt priority
164  INTC->PSR[ENET0_GROUP2_IRQn] = INTC_PSR_PRIN(MPC57XX_ETH_IRQ_PRIORITY);
165  //Configure ENET receive interrupt priority
166  INTC->PSR[ENET0_GROUP1_IRQn] = INTC_PSR_PRIN(MPC57XX_ETH_IRQ_PRIORITY);
167  //Configure ENET error interrupt priority
168  INTC->PSR[ENET0_GROUP0_IRQn] = INTC_PSR_PRIN(MPC57XX_ETH_IRQ_PRIORITY);
169 
170  //Enable Ethernet MAC
171  ENET_0->ECR |= ENET_ECR_ETHEREN_MASK;
172  //Instruct the DMA to poll the receive descriptor list
173  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
174 
175  //Accept any packets from the upper layer
176  osSetEvent(&interface->nicTxEvent);
177 
178  //Successful initialization
179  return NO_ERROR;
180 }
181 
182 
183 //DEVKIT-MPC5748G evaluation board?
184 #if defined(USE_DEVKIT_MPC5748G)
185 
186 /**
187  * @brief GPIO configuration
188  * @param[in] interface Underlying network interface
189  **/
190 
191 void mpc57xxEthInitGpio(NetInterface *interface)
192 {
193  //Configure MII_RMII_0_MDIO (PF14)
194  SIUL2->MSCR[94] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
195  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK | SIUL2_MSCR_PUS_MASK |
196  SIUL2_MSCR_PUE_MASK | SIUL2_MSCR_SSS(4);
197  SIUL2->IMCR[450] = SIUL2_IMCR_SSS(1);
198 
199  //Configure MII_RMII_0_MDC (PG0)
200  SIUL2->MSCR[96] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
201  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(3);
202 
203  //Configure MII_RMII_0_TXD0 (PH1)
204  SIUL2->MSCR[113] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
205  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(4);
206 
207  //Configure MII_RMII_0_TXD1 (PH0)
208  SIUL2->MSCR[112] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
209  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(3);
210 
211  //Configure MII_RMII_0_TX_EN (PH2)
212  SIUL2->MSCR[114] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
213  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(4);
214 
215  //Configure MII_RMII_0_TX_CLK (PG1)
216  SIUL2->MSCR[97] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
217  SIUL2->IMCR[449] = SIUL2_IMCR_SSS(1);
218 
219  //Configure MII_RMII_0_RXD0 (PA9)
220  SIUL2->MSCR[9] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
221  SIUL2->IMCR[451] = SIUL2_IMCR_SSS(1);
222 
223  //Configure MII_RMII_0_RXD1 (PA8)
224  SIUL2->MSCR[8] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
225  SIUL2->IMCR[452] = SIUL2_IMCR_SSS(1);
226 
227  //Configure MII_RMII_0_RX_ER (PA11)
228  SIUL2->MSCR[11] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
229  SIUL2->IMCR[455] = SIUL2_IMCR_SSS(1);
230 
231  //Configure MII_RMII_0_RX_DV (PF15)
232  SIUL2->MSCR[95] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
233  SIUL2->IMCR[457] = SIUL2_IMCR_SSS(1);
234 }
235 
236 #endif
237 
238 
239 /**
240  * @brief Initialize buffer descriptors
241  * @param[in] interface Underlying network interface
242  **/
243 
245 {
246  uint_t i;
247  uint32_t address;
248 
249  //Clear TX and RX buffer descriptors
250  memset(txBufferDesc, 0, sizeof(txBufferDesc));
251  memset(rxBufferDesc, 0, sizeof(rxBufferDesc));
252 
253  //Initialize TX buffer descriptors
254  for(i = 0; i < MPC57XX_ETH_TX_BUFFER_COUNT; i++)
255  {
256  //Calculate the address of the current TX buffer
257  address = (uint32_t) txBuffer[i];
258  //Transmit buffer address
259  txBufferDesc[i][1] = address;
260  //Generate interrupts
261  txBufferDesc[i][2] = ENET_TBD2_INT;
262  }
263 
264  //Mark the last descriptor entry with the wrap flag
265  txBufferDesc[i - 1][0] |= ENET_TBD0_W;
266  //Initialize TX buffer index
267  txBufferIndex = 0;
268 
269  //Initialize RX buffer descriptors
270  for(i = 0; i < MPC57XX_ETH_RX_BUFFER_COUNT; i++)
271  {
272  //Calculate the address of the current RX buffer
273  address = (uint32_t) rxBuffer[i];
274  //The descriptor is initially owned by the DMA
275  rxBufferDesc[i][0] = ENET_RBD0_E;
276  //Receive buffer address
277  rxBufferDesc[i][1] = address;
278  //Generate interrupts
279  rxBufferDesc[i][2] = ENET_RBD2_INT;
280  }
281 
282  //Mark the last descriptor entry with the wrap flag
283  rxBufferDesc[i - 1][0] |= ENET_RBD0_W;
284  //Initialize RX buffer index
285  rxBufferIndex = 0;
286 
287  //Start location of the TX descriptor list
288  ENET_0->TDSR = (uint32_t) txBufferDesc;
289  //Start location of the RX descriptor list
290  ENET_0->RDSR = (uint32_t) rxBufferDesc;
291  //Maximum receive buffer size
292  ENET_0->MRBR = MPC57XX_ETH_RX_BUFFER_SIZE;
293 }
294 
295 
296 /**
297  * @brief MPC57xx Ethernet MAC timer handler
298  *
299  * This routine is periodically called by the TCP/IP stack to
300  * handle periodic operations such as polling the link state
301  *
302  * @param[in] interface Underlying network interface
303  **/
304 
305 void mpc57xxEthTick(NetInterface *interface)
306 {
307  //Handle periodic operations
308  interface->phyDriver->tick(interface);
309 }
310 
311 
312 /**
313  * @brief Enable interrupts
314  * @param[in] interface Underlying network interface
315  **/
316 
318 {
319  //Enable Ethernet MAC interrupts
320  INTC->PSR[ENET0_GROUP2_IRQn] |= INTC_PSR_PRC_SELN0_MASK;
321  INTC->PSR[ENET0_GROUP1_IRQn] |= INTC_PSR_PRC_SELN0_MASK;
322  INTC->PSR[ENET0_GROUP0_IRQn] |= INTC_PSR_PRC_SELN0_MASK;
323 
324  //Enable Ethernet PHY interrupts
325  interface->phyDriver->enableIrq(interface);
326 }
327 
328 
329 /**
330  * @brief Disable interrupts
331  * @param[in] interface Underlying network interface
332  **/
333 
335 {
336  //Disable Ethernet MAC interrupts
337  INTC->PSR[ENET0_GROUP2_IRQn] &= ~INTC_PSR_PRC_SELN0_MASK;
338  INTC->PSR[ENET0_GROUP1_IRQn] &= ~INTC_PSR_PRC_SELN0_MASK;
339  INTC->PSR[ENET0_GROUP0_IRQn] &= ~INTC_PSR_PRC_SELN0_MASK;
340 
341  //Disable Ethernet PHY interrupts
342  interface->phyDriver->disableIrq(interface);
343 }
344 
345 
346 /**
347  * @brief Ethernet MAC transmit interrupt
348  **/
349 
351 {
352  bool_t flag;
353 
354  //Enter interrupt service routine
355  osEnterIsr();
356 
357  //This flag will be set if a higher priority task must be woken
358  flag = FALSE;
359 
360  //A packet has been transmitted?
361  if(ENET_0->EIR & ENET_EIR_TXF_MASK)
362  {
363  //Clear TXF interrupt flag
364  ENET_0->EIR = ENET_EIR_TXF_MASK;
365 
366  //Check whether the TX buffer is available for writing
367  if(!(txBufferDesc[txBufferIndex][0] & ENET_TBD0_R))
368  {
369  //Notify the TCP/IP stack that the transmitter is ready to send
370  flag = osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
371  }
372 
373  //Instruct the DMA to poll the transmit descriptor list
374  ENET_0->TDAR = ENET_TDAR_TDAR_MASK;
375  }
376 
377  //Leave interrupt service routine
378  osExitIsr(flag);
379 }
380 
381 
382 /**
383  * @brief Ethernet MAC receive interrupt
384  **/
385 
387 {
388  bool_t flag;
389 
390  //Enter interrupt service routine
391  osEnterIsr();
392 
393  //This flag will be set if a higher priority task must be woken
394  flag = FALSE;
395 
396  //A packet has been received?
397  if(ENET_0->EIR & ENET_EIR_RXF_MASK)
398  {
399  //Disable RXF interrupt
400  ENET_0->EIMR &= ~ENET_EIMR_RXF_MASK;
401 
402  //Set event flag
403  nicDriverInterface->nicEvent = TRUE;
404  //Notify the TCP/IP stack of the event
405  flag = osSetEventFromIsr(&netEvent);
406  }
407 
408  //Leave interrupt service routine
409  osExitIsr(flag);
410 }
411 
412 
413 /**
414  * @brief Ethernet MAC error interrupt
415  **/
416 
418 {
419  bool_t flag;
420 
421  //Enter interrupt service routine
422  osEnterIsr();
423 
424  //This flag will be set if a higher priority task must be woken
425  flag = FALSE;
426 
427  //System bus error?
428  if(ENET_0->EIR & ENET_EIR_EBERR_MASK)
429  {
430  //Disable EBERR interrupt
431  ENET_0->EIMR &= ~ENET_EIMR_EBERR_MASK;
432 
433  //Set event flag
434  nicDriverInterface->nicEvent = TRUE;
435  //Notify the TCP/IP stack of the event
436  flag |= osSetEventFromIsr(&netEvent);
437  }
438 
439  //Leave interrupt service routine
440  osExitIsr(flag);
441 }
442 
443 
444 /**
445  * @brief MPC57xx Ethernet MAC event handler
446  * @param[in] interface Underlying network interface
447  **/
448 
450 {
451  error_t error;
452  uint32_t status;
453 
454  //Read interrupt event register
455  status = ENET_0->EIR;
456 
457  //Packet received?
458  if(status & ENET_EIR_RXF_MASK)
459  {
460  //Clear RXF interrupt flag
461  ENET_0->EIR = ENET_EIR_RXF_MASK;
462 
463  //Process all pending packets
464  do
465  {
466  //Read incoming packet
467  error = mpc57xxEthReceivePacket(interface);
468 
469  //No more data in the receive buffer?
470  } while(error != ERROR_BUFFER_EMPTY);
471  }
472 
473  //System bus error?
474  if(status & ENET_EIR_EBERR_MASK)
475  {
476  //Clear EBERR interrupt flag
477  ENET_0->EIR = ENET_EIR_EBERR_MASK;
478 
479  //Disable Ethernet MAC
480  ENET_0->ECR &= ~ENET_ECR_ETHEREN_MASK;
481  //Reset buffer descriptors
482  mpc57xxEthInitBufferDesc(interface);
483  //Resume normal operation
484  ENET_0->ECR |= ENET_ECR_ETHEREN_MASK;
485  //Instruct the DMA to poll the receive descriptor list
486  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
487  }
488 
489  //Re-enable Ethernet MAC interrupts
490  ENET_0->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
491 }
492 
493 
494 /**
495  * @brief Send a packet
496  * @param[in] interface Underlying network interface
497  * @param[in] buffer Multi-part buffer containing the data to send
498  * @param[in] offset Offset to the first data byte
499  * @return Error code
500  **/
501 
503  const NetBuffer *buffer, size_t offset)
504 {
505  size_t length;
506 
507  //Retrieve the length of the packet
508  length = netBufferGetLength(buffer) - offset;
509 
510  //Check the frame length
512  {
513  //The transmitter can accept another packet
514  osSetEvent(&interface->nicTxEvent);
515  //Report an error
516  return ERROR_INVALID_LENGTH;
517  }
518 
519  //Make sure the current buffer is available for writing
520  if(txBufferDesc[txBufferIndex][0] & ENET_TBD0_R)
521  return ERROR_FAILURE;
522 
523  //Copy user data to the transmit buffer
524  netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
525 
526  //Clear BDU flag
527  txBufferDesc[txBufferIndex][4] = 0;
528 
529  //Check current index
530  if(txBufferIndex < (MPC57XX_ETH_TX_BUFFER_COUNT - 1))
531  {
532  //Give the ownership of the descriptor to the DMA engine
533  txBufferDesc[txBufferIndex][0] = ENET_TBD0_R | ENET_TBD0_L |
535 
536  //Point to the next buffer
537  txBufferIndex++;
538  }
539  else
540  {
541  //Give the ownership of the descriptor to the DMA engine
542  txBufferDesc[txBufferIndex][0] = ENET_TBD0_R | ENET_TBD0_W |
544 
545  //Wrap around
546  txBufferIndex = 0;
547  }
548 
549  //Instruct the DMA to poll the transmit descriptor list
550  ENET_0->TDAR = ENET_TDAR_TDAR_MASK;
551 
552  //Check whether the next buffer is available for writing
553  if(!(txBufferDesc[txBufferIndex][0] & ENET_TBD0_R))
554  {
555  //The transmitter can accept another packet
556  osSetEvent(&interface->nicTxEvent);
557  }
558 
559  //Successful processing
560  return NO_ERROR;
561 }
562 
563 
564 /**
565  * @brief Receive a packet
566  * @param[in] interface Underlying network interface
567  * @return Error code
568  **/
569 
571 {
572  error_t error;
573  size_t n;
574 
575  //Make sure the current buffer is available for reading
576  if(!(rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_E))
577  {
578  //The frame should not span multiple buffers
579  if(rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_L)
580  {
581  //Check whether an error occurred
582  if(!(rxBufferDesc[rxBufferIndex][0] & (ENET_RBD0_LG |
584  {
585  //Retrieve the length of the frame
586  n = rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_DATA_LENGTH;
587  //Limit the number of data to read
589 
590  //Pass the packet to the upper layer
591  nicProcessPacket(interface, rxBuffer[rxBufferIndex], n);
592 
593  //Valid packet received
594  error = NO_ERROR;
595  }
596  else
597  {
598  //The received packet contains an error
599  error = ERROR_INVALID_PACKET;
600  }
601  }
602  else
603  {
604  //The packet is not valid
605  error = ERROR_INVALID_PACKET;
606  }
607 
608  //Clear BDU flag
609  rxBufferDesc[rxBufferIndex][4] = 0;
610 
611  //Check current index
612  if(rxBufferIndex < (MPC57XX_ETH_RX_BUFFER_COUNT - 1))
613  {
614  //Give the ownership of the descriptor back to the DMA engine
615  rxBufferDesc[rxBufferIndex][0] = ENET_RBD0_E;
616  //Point to the next buffer
617  rxBufferIndex++;
618  }
619  else
620  {
621  //Give the ownership of the descriptor back to the DMA engine
622  rxBufferDesc[rxBufferIndex][0] = ENET_RBD0_E | ENET_RBD0_W;
623  //Wrap around
624  rxBufferIndex = 0;
625  }
626 
627  //Instruct the DMA to poll the receive descriptor list
628  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
629  }
630  else
631  {
632  //No more data in the receive buffer
633  error = ERROR_BUFFER_EMPTY;
634  }
635 
636  //Return status code
637  return error;
638 }
639 
640 
641 /**
642  * @brief Configure MAC address filtering
643  * @param[in] interface Underlying network interface
644  * @return Error code
645  **/
646 
648 {
649  uint_t i;
650  uint_t k;
651  uint32_t crc;
652  uint32_t unicastHashTable[2];
653  uint32_t multicastHashTable[2];
654  MacFilterEntry *entry;
655 
656  //Debug message
657  TRACE_DEBUG("Updating MPC57xx hash table...\r\n");
658 
659  //Clear hash table (unicast address filtering)
660  unicastHashTable[0] = 0;
661  unicastHashTable[1] = 0;
662 
663  //Clear hash table (multicast address filtering)
664  multicastHashTable[0] = 0;
665  multicastHashTable[1] = 0;
666 
667  //The MAC address filter contains the list of MAC addresses to accept
668  //when receiving an Ethernet frame
669  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
670  {
671  //Point to the current entry
672  entry = &interface->macAddrFilter[i];
673 
674  //Valid entry?
675  if(entry->refCount > 0)
676  {
677  //Compute CRC over the current MAC address
678  crc = mpc57xxEthCalcCrc(&entry->addr, sizeof(MacAddr));
679 
680  //The upper 6 bits in the CRC register are used to index the
681  //contents of the hash table
682  k = (crc >> 26) & 0x3F;
683 
684  //Multicast address?
685  if(macIsMulticastAddr(&entry->addr))
686  {
687  //Update the multicast hash table
688  multicastHashTable[k / 32] |= (1 << (k % 32));
689  }
690  else
691  {
692  //Update the unicast hash table
693  unicastHashTable[k / 32] |= (1 << (k % 32));
694  }
695  }
696  }
697 
698  //Write the hash table (unicast address filtering)
699  ENET_0->IALR = unicastHashTable[0];
700  ENET_0->IAUR = unicastHashTable[1];
701 
702  //Write the hash table (multicast address filtering)
703  ENET_0->GALR = multicastHashTable[0];
704  ENET_0->GAUR = multicastHashTable[1];
705 
706  //Debug message
707  TRACE_DEBUG(" IALR = %08" PRIX32 "\r\n", ENET_0->IALR);
708  TRACE_DEBUG(" IAUR = %08" PRIX32 "\r\n", ENET_0->IAUR);
709  TRACE_DEBUG(" GALR = %08" PRIX32 "\r\n", ENET_0->GALR);
710  TRACE_DEBUG(" GAUR = %08" PRIX32 "\r\n", ENET_0->GAUR);
711 
712  //Successful processing
713  return NO_ERROR;
714 }
715 
716 
717 /**
718  * @brief Adjust MAC configuration parameters for proper operation
719  * @param[in] interface Underlying network interface
720  * @return Error code
721  **/
722 
724 {
725  //Disable Ethernet MAC while modifying configuration registers
726  ENET_0->ECR &= ~ENET_ECR_ETHEREN_MASK;
727 
728  //10BASE-T or 100BASE-TX operation mode?
729  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
730  {
731  //100 Mbps operation
732  ENET_0->RCR &= ~ENET_RCR_RMII_10T_MASK;
733  }
734  else
735  {
736  //10 Mbps operation
737  ENET_0->RCR |= ENET_RCR_RMII_10T_MASK;
738  }
739 
740  //Half-duplex or full-duplex mode?
741  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
742  {
743  //Full-duplex mode
744  ENET_0->TCR |= ENET_TCR_FDEN_MASK;
745  //Receive path operates independently of transmit
746  ENET_0->RCR &= ~ENET_RCR_DRT_MASK;
747  }
748  else
749  {
750  //Half-duplex mode
751  ENET_0->TCR &= ~ENET_TCR_FDEN_MASK;
752  //Disable reception of frames while transmitting
753  ENET_0->RCR |= ENET_RCR_DRT_MASK;
754  }
755 
756  //Reset buffer descriptors
757  mpc57xxEthInitBufferDesc(interface);
758 
759  //Re-enable Ethernet MAC
760  ENET_0->ECR |= ENET_ECR_ETHEREN_MASK;
761  //Instruct the DMA to poll the receive descriptor list
762  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
763 
764  //Successful processing
765  return NO_ERROR;
766 }
767 
768 
769 /**
770  * @brief Write PHY register
771  * @param[in] phyAddr PHY address
772  * @param[in] regAddr Register address
773  * @param[in] data Register value
774  **/
775 
776 void mpc57xxEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
777 {
778  uint32_t value;
779 
780  //Set up a write operation
781  value = ENET_MMFR_ST(1) | ENET_MMFR_OP(1) | ENET_MMFR_TA(2);
782  //PHY address
783  value |= ENET_MMFR_PA(phyAddr);
784  //Register address
785  value |= ENET_MMFR_RA(regAddr);
786  //Register value
787  value |= ENET_MMFR_DATA(data);
788 
789  //Clear MII interrupt flag
790  ENET_0->EIR = ENET_EIR_MII_MASK;
791  //Start a write operation
792  ENET_0->MMFR = value;
793  //Wait for the write to complete
794  while(!(ENET_0->EIR & ENET_EIR_MII_MASK));
795 }
796 
797 
798 /**
799  * @brief Read PHY register
800  * @param[in] phyAddr PHY address
801  * @param[in] regAddr Register address
802  * @return Register value
803  **/
804 
805 uint16_t mpc57xxEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
806 {
807  uint32_t value;
808 
809  //Set up a read operation
810  value = ENET_MMFR_ST(1) | ENET_MMFR_OP(2) | ENET_MMFR_TA(2);
811  //PHY address
812  value |= ENET_MMFR_PA(phyAddr);
813  //Register address
814  value |= ENET_MMFR_RA(regAddr);
815 
816  //Clear MII interrupt flag
817  ENET_0->EIR = ENET_EIR_MII_MASK;
818  //Start a read operation
819  ENET_0->MMFR = value;
820  //Wait for the read to complete
821  while(!(ENET_0->EIR & ENET_EIR_MII_MASK));
822 
823  //Return PHY register contents
824  return ENET_0->MMFR & ENET_MMFR_DATA_MASK;
825 }
826 
827 
828 /**
829  * @brief CRC calculation
830  * @param[in] data Pointer to the data over which to calculate the CRC
831  * @param[in] length Number of bytes to process
832  * @return Resulting CRC value
833  **/
834 
835 uint32_t mpc57xxEthCalcCrc(const void *data, size_t length)
836 {
837  uint_t i;
838  uint_t j;
839 
840  //Point to the data over which to calculate the CRC
841  const uint8_t *p = (uint8_t *) data;
842  //CRC preset value
843  uint32_t crc = 0xFFFFFFFF;
844 
845  //Loop through data
846  for(i = 0; i < length; i++)
847  {
848  //Update CRC value
849  crc ^= p[i];
850  //The message is processed bit by bit
851  for(j = 0; j < 8; j++)
852  {
853  if(crc & 0x00000001)
854  crc = (crc >> 1) ^ 0xEDB88320;
855  else
856  crc = crc >> 1;
857  }
858  }
859 
860  //Return CRC value
861  return crc;
862 }
MacAddr addr
MAC address.
Definition: ethernet.h:210
void mpc57xxEthEnableIrq(NetInterface *interface)
Enable interrupts.
void mpc57xxEthEventHandler(NetInterface *interface)
MPC57xx Ethernet MAC event handler.
TCP/IP stack core.
Debugging facilities.
uint8_t p
Definition: ndp.h:295
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
Generic error code.
Definition: error.h:43
#define ENET_RBD0_DATA_LENGTH
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:98
void mpc57xxEthTick(NetInterface *interface)
MPC57xx Ethernet MAC timer handler.
#define txBuffer
#define ENET_TBD0_TC
#define ENET_RBD0_TR
#define ENET_TBD2_INT
void mpc57xxEthDisableIrq(NetInterface *interface)
Disable interrupts.
error_t mpc57xxEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void ENET0_Tx_IRQHandler(void)
Ethernet MAC transmit interrupt.
#define ENET_TBD0_L
uint16_t mpc57xxEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
#define ENET_RBD0_W
#define MPC57XX_ETH_RX_BUFFER_SIZE
#define ENET_TBD0_R
#define ENET_RBD0_CR
#define ENET_RBD0_NO
void mpc57xxEthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
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:670
void mpc57xxEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define MPC57XX_ETH_TX_BUFFER_SIZE
#define ENET_RBD0_E
NIC driver.
Definition: nic.h:161
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
error_t mpc57xxEthInit(NetInterface *interface)
MPC57xx Ethernet MAC initialization.
#define ENET_RBD0_LG
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
#define ENET_TBD0_W
void ENET0_Err_IRQHandler(void)
Ethernet MAC error interrupt.
Success.
Definition: error.h:42
#define rxBuffer
Ipv6Addr address
OsEvent netEvent
Definition: net.c:72
void nicProcessPacket(NetInterface *interface, void *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:239
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:211
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
#define ENET_RBD2_INT
unsigned int uint_t
Definition: compiler_port.h:43
error_t mpc57xxEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
__start_packed struct @112 MacAddr
MAC address.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
error_t mpc57xxEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
uint8_t value[]
Definition: dtls_misc.h:141
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
void ENET0_Rx_IRQHandler(void)
Ethernet MAC receive interrupt.
#define osExitIsr(flag)
#define ENET_TBD0_DATA_LENGTH
Freescale MPC57xx Ethernet MAC controller.
#define osEnterIsr()
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define FALSE
Definition: os_port.h:44
void mpc57xxEthInitGpio(NetInterface *interface)
int bool_t
Definition: compiler_port.h:47
#define MPC57XX_ETH_IRQ_PRIORITY
const NicDriver mpc57xxEthDriver
MPC57xx Ethernet MAC driver.
#define MPC57XX_ETH_TX_BUFFER_COUNT
#define ENET_RBD0_OV
error_t mpc57xxEthReceivePacket(NetInterface *interface)
Receive a packet.
#define ENET_RBD0_L
MAC filter table entry.
Definition: ethernet.h:208
#define TRACE_DEBUG(...)
Definition: debug.h:98
#define MPC57XX_ETH_RX_BUFFER_COUNT
uint32_t mpc57xxEthCalcCrc(const void *data, size_t length)
CRC calculation.