mpc57xx_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file mpc57xx_eth_driver.c
3  * @brief NXP MPC57xx Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2023 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.2.4
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 "core/net.h"
38 #include "debug.h"
39 
40 //Underlying network interface
41 static NetInterface *nicDriverInterface;
42 
43 //TX buffer
45  __attribute__((aligned(64)));
46 //RX buffer
48  __attribute__((aligned(64)));
49 //TX buffer descriptors
50 static uint32_t txBufferDesc[MPC57XX_ETH_TX_BUFFER_COUNT][8]
51  __attribute__((aligned(64)));
52 //RX buffer descriptors
53 static uint32_t rxBufferDesc[MPC57XX_ETH_RX_BUFFER_COUNT][8]
54  __attribute__((aligned(64)));
55 
56 
57 //TX buffer index
58 static uint_t txBufferIndex;
59 //RX buffer index
60 static uint_t rxBufferIndex;
61 
62 
63 /**
64  * @brief MPC57xx Ethernet MAC driver
65  **/
66 
68 {
70  ETH_MTU,
81  TRUE,
82  TRUE,
83  TRUE,
84  FALSE
85 };
86 
87 
88 /**
89  * @brief MPC57xx 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 MPC57xx Ethernet MAC...\r\n");
101 
102  //Save underlying network interface
103  nicDriverInterface = interface;
104 
105  //GPIO configuration
106  mpc57xxEthInitGpio(interface);
107 
108  //Reset ENET module
109  ENET_0->ECR = ENET_ECR_RESET_MASK;
110  //Wait for the reset to complete
111  while((ENET_0->ECR & ENET_ECR_RESET_MASK) != 0)
112  {
113  }
114 
115  //Receive control register
116  ENET_0->RCR = ENET_RCR_MAX_FL(MPC57XX_ETH_RX_BUFFER_SIZE) |
117  ENET_RCR_RMII_MODE_MASK | ENET_RCR_MII_MODE_MASK;
118 
119  //Transmit control register
120  ENET_0->TCR = 0;
121  //Configure MDC clock frequency
122  ENET_0->MSCR = ENET_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  ENET_0->PAUR = ENET_PAUR_PADDR2(value) | ENET_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  ENET_0->PALR = ENET_PALR_PADDR1(value);
158 
159  //Hash table for unicast address filtering
160  ENET_0->IALR = 0;
161  ENET_0->IAUR = 0;
162  //Hash table for multicast address filtering
163  ENET_0->GALR = 0;
164  ENET_0->GAUR = 0;
165 
166  //Disable transmit accelerator functions
167  ENET_0->TACC = 0;
168  //Disable receive accelerator functions
169  ENET_0->RACC = 0;
170 
171  //Use enhanced buffer descriptors
172  ENET_0->ECR = ENET_ECR_EN1588_MASK;
173 
174  //Reset statistics counters
175  ENET_0->MIBC = ENET_MIBC_MIB_CLEAR_MASK;
176  ENET_0->MIBC = 0;
177 
178  //Initialize buffer descriptors
179  mpc57xxEthInitBufferDesc(interface);
180 
181  //Clear any pending interrupts
182  ENET_0->EIR = 0xFFFFFFFF;
183  //Enable desired interrupts
184  ENET_0->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
185 
186  //Configure ENET transmit interrupt priority
187  INTC->PSR[ENET0_GROUP2_IRQn] = INTC_PSR_PRIN(MPC57XX_ETH_IRQ_PRIORITY);
188  //Configure ENET receive interrupt priority
189  INTC->PSR[ENET0_GROUP1_IRQn] = INTC_PSR_PRIN(MPC57XX_ETH_IRQ_PRIORITY);
190  //Configure ENET error interrupt priority
191  INTC->PSR[ENET0_GROUP0_IRQn] = INTC_PSR_PRIN(MPC57XX_ETH_IRQ_PRIORITY);
192 
193  //Enable Ethernet MAC
194  ENET_0->ECR |= ENET_ECR_ETHEREN_MASK;
195  //Instruct the DMA to poll the receive descriptor list
196  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
197 
198  //Accept any packets from the upper layer
199  osSetEvent(&interface->nicTxEvent);
200 
201  //Successful initialization
202  return NO_ERROR;
203 }
204 
205 
206 /**
207  * @brief GPIO configuration
208  * @param[in] interface Underlying network interface
209  **/
210 
211 __weak_func void mpc57xxEthInitGpio(NetInterface *interface)
212 {
213 //DEVKIT-MPC5748G evaluation board?
214 #if defined(USE_DEVKIT_MPC5748G)
215  //Configure MII_RMII_0_MDIO (PF14)
216  SIUL2->MSCR[94] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
217  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK | SIUL2_MSCR_PUS_MASK |
218  SIUL2_MSCR_PUE_MASK | SIUL2_MSCR_SSS(4);
219  SIUL2->IMCR[450] = SIUL2_IMCR_SSS(1);
220 
221  //Configure MII_RMII_0_MDC (PG0)
222  SIUL2->MSCR[96] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
223  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(3);
224 
225  //Configure MII_RMII_0_TXD0 (PH1)
226  SIUL2->MSCR[113] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
227  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(4);
228 
229  //Configure MII_RMII_0_TXD1 (PH0)
230  SIUL2->MSCR[112] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
231  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(3);
232 
233  //Configure MII_RMII_0_TX_EN (PH2)
234  SIUL2->MSCR[114] = SIUL2_MSCR_SRC(3) | SIUL2_MSCR_OBE_MASK |
235  SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_SSS(4);
236 
237  //Configure MII_RMII_0_TX_CLK (PG1)
238  SIUL2->MSCR[97] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
239  SIUL2->IMCR[449] = SIUL2_IMCR_SSS(1);
240 
241  //Configure MII_RMII_0_RXD0 (PA9)
242  SIUL2->MSCR[9] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
243  SIUL2->IMCR[451] = SIUL2_IMCR_SSS(1);
244 
245  //Configure MII_RMII_0_RXD1 (PA8)
246  SIUL2->MSCR[8] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
247  SIUL2->IMCR[452] = SIUL2_IMCR_SSS(1);
248 
249  //Configure MII_RMII_0_RX_ER (PA11)
250  SIUL2->MSCR[11] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
251  SIUL2->IMCR[455] = SIUL2_IMCR_SSS(1);
252 
253  //Configure MII_RMII_0_RX_DV (PF15)
254  SIUL2->MSCR[95] = SIUL2_MSCR_SMC_MASK | SIUL2_MSCR_IBE_MASK;
255  SIUL2->IMCR[457] = SIUL2_IMCR_SSS(1);
256 #endif
257 }
258 
259 
260 /**
261  * @brief Initialize buffer descriptors
262  * @param[in] interface Underlying network interface
263  **/
264 
266 {
267  uint_t i;
268  uint32_t address;
269 
270  //Clear TX and RX buffer descriptors
271  osMemset(txBufferDesc, 0, sizeof(txBufferDesc));
272  osMemset(rxBufferDesc, 0, sizeof(rxBufferDesc));
273 
274  //Initialize TX buffer descriptors
275  for(i = 0; i < MPC57XX_ETH_TX_BUFFER_COUNT; i++)
276  {
277  //Calculate the address of the current TX buffer
278  address = (uint32_t) txBuffer[i];
279  //Transmit buffer address
280  txBufferDesc[i][1] = address;
281  //Generate interrupts
282  txBufferDesc[i][2] = ENET_TBD2_INT;
283  }
284 
285  //Mark the last descriptor entry with the wrap flag
286  txBufferDesc[i - 1][0] |= ENET_TBD0_W;
287  //Initialize TX buffer index
288  txBufferIndex = 0;
289 
290  //Initialize RX buffer descriptors
291  for(i = 0; i < MPC57XX_ETH_RX_BUFFER_COUNT; i++)
292  {
293  //Calculate the address of the current RX buffer
294  address = (uint32_t) rxBuffer[i];
295  //The descriptor is initially owned by the DMA
296  rxBufferDesc[i][0] = ENET_RBD0_E;
297  //Receive buffer address
298  rxBufferDesc[i][1] = address;
299  //Generate interrupts
300  rxBufferDesc[i][2] = ENET_RBD2_INT;
301  }
302 
303  //Mark the last descriptor entry with the wrap flag
304  rxBufferDesc[i - 1][0] |= ENET_RBD0_W;
305  //Initialize RX buffer index
306  rxBufferIndex = 0;
307 
308  //Start location of the TX descriptor list
309  ENET_0->TDSR = (uint32_t) txBufferDesc;
310  //Start location of the RX descriptor list
311  ENET_0->RDSR = (uint32_t) rxBufferDesc;
312  //Maximum receive buffer size
313  ENET_0->MRBR = MPC57XX_ETH_RX_BUFFER_SIZE;
314 }
315 
316 
317 /**
318  * @brief MPC57xx Ethernet MAC timer handler
319  *
320  * This routine is periodically called by the TCP/IP stack to handle periodic
321  * operations such as polling the link state
322  *
323  * @param[in] interface Underlying network interface
324  **/
325 
326 void mpc57xxEthTick(NetInterface *interface)
327 {
328  //Valid Ethernet PHY or switch driver?
329  if(interface->phyDriver != NULL)
330  {
331  //Handle periodic operations
332  interface->phyDriver->tick(interface);
333  }
334  else if(interface->switchDriver != NULL)
335  {
336  //Handle periodic operations
337  interface->switchDriver->tick(interface);
338  }
339  else
340  {
341  //Just for sanity
342  }
343 }
344 
345 
346 /**
347  * @brief Enable interrupts
348  * @param[in] interface Underlying network interface
349  **/
350 
352 {
353  //Enable Ethernet MAC interrupts
354  INTC->PSR[ENET0_GROUP2_IRQn] |= INTC_PSR_PRC_SELN0_MASK;
355  INTC->PSR[ENET0_GROUP1_IRQn] |= INTC_PSR_PRC_SELN0_MASK;
356  INTC->PSR[ENET0_GROUP0_IRQn] |= INTC_PSR_PRC_SELN0_MASK;
357 
358  //Valid Ethernet PHY or switch driver?
359  if(interface->phyDriver != NULL)
360  {
361  //Enable Ethernet PHY interrupts
362  interface->phyDriver->enableIrq(interface);
363  }
364  else if(interface->switchDriver != NULL)
365  {
366  //Enable Ethernet switch interrupts
367  interface->switchDriver->enableIrq(interface);
368  }
369  else
370  {
371  //Just for sanity
372  }
373 }
374 
375 
376 /**
377  * @brief Disable interrupts
378  * @param[in] interface Underlying network interface
379  **/
380 
382 {
383  //Disable Ethernet MAC interrupts
384  INTC->PSR[ENET0_GROUP2_IRQn] &= ~INTC_PSR_PRC_SELN0_MASK;
385  INTC->PSR[ENET0_GROUP1_IRQn] &= ~INTC_PSR_PRC_SELN0_MASK;
386  INTC->PSR[ENET0_GROUP0_IRQn] &= ~INTC_PSR_PRC_SELN0_MASK;
387 
388  //Valid Ethernet PHY or switch driver?
389  if(interface->phyDriver != NULL)
390  {
391  //Disable Ethernet PHY interrupts
392  interface->phyDriver->disableIrq(interface);
393  }
394  else if(interface->switchDriver != NULL)
395  {
396  //Disable Ethernet switch interrupts
397  interface->switchDriver->disableIrq(interface);
398  }
399  else
400  {
401  //Just for sanity
402  }
403 }
404 
405 
406 /**
407  * @brief Ethernet MAC transmit interrupt
408  **/
409 
411 {
412  bool_t flag;
413 
414  //Interrupt service routine prologue
415  osEnterIsr();
416 
417  //This flag will be set if a higher priority task must be woken
418  flag = FALSE;
419 
420  //Packet transmitted?
421  if((ENET_0->EIR & ENET_EIR_TXF_MASK) != 0)
422  {
423  //Clear TXF interrupt flag
424  ENET_0->EIR = ENET_EIR_TXF_MASK;
425 
426  //Check whether the TX buffer is available for writing
427  if((txBufferDesc[txBufferIndex][0] & ENET_TBD0_R) == 0)
428  {
429  //Notify the TCP/IP stack that the transmitter is ready to send
430  flag = osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
431  }
432 
433  //Instruct the DMA to poll the transmit descriptor list
434  ENET_0->TDAR = ENET_TDAR_TDAR_MASK;
435  }
436 
437  //Interrupt service routine epilogue
438  osExitIsr(flag);
439 }
440 
441 
442 /**
443  * @brief Ethernet MAC receive interrupt
444  **/
445 
447 {
448  bool_t flag;
449 
450  //Interrupt service routine prologue
451  osEnterIsr();
452 
453  //This flag will be set if a higher priority task must be woken
454  flag = FALSE;
455 
456  //Packet received?
457  if((ENET_0->EIR & ENET_EIR_RXF_MASK) != 0)
458  {
459  //Disable RXF interrupt
460  ENET_0->EIMR &= ~ENET_EIMR_RXF_MASK;
461 
462  //Set event flag
463  nicDriverInterface->nicEvent = TRUE;
464  //Notify the TCP/IP stack of the event
465  flag = osSetEventFromIsr(&netEvent);
466  }
467 
468  //Interrupt service routine epilogue
469  osExitIsr(flag);
470 }
471 
472 
473 /**
474  * @brief Ethernet MAC error interrupt
475  **/
476 
478 {
479  bool_t flag;
480 
481  //Interrupt service routine prologue
482  osEnterIsr();
483 
484  //This flag will be set if a higher priority task must be woken
485  flag = FALSE;
486 
487  //System bus error?
488  if((ENET_0->EIR & ENET_EIR_EBERR_MASK) != 0)
489  {
490  //Disable EBERR interrupt
491  ENET_0->EIMR &= ~ENET_EIMR_EBERR_MASK;
492 
493  //Set event flag
494  nicDriverInterface->nicEvent = TRUE;
495  //Notify the TCP/IP stack of the event
496  flag |= osSetEventFromIsr(&netEvent);
497  }
498 
499  //Interrupt service routine epilogue
500  osExitIsr(flag);
501 }
502 
503 
504 /**
505  * @brief MPC57xx Ethernet MAC event handler
506  * @param[in] interface Underlying network interface
507  **/
508 
510 {
511  error_t error;
512  uint32_t status;
513 
514  //Read interrupt event register
515  status = ENET_0->EIR;
516 
517  //Packet received?
518  if((status & ENET_EIR_RXF_MASK) != 0)
519  {
520  //Clear RXF interrupt flag
521  ENET_0->EIR = ENET_EIR_RXF_MASK;
522 
523  //Process all pending packets
524  do
525  {
526  //Read incoming packet
527  error = mpc57xxEthReceivePacket(interface);
528 
529  //No more data in the receive buffer?
530  } while(error != ERROR_BUFFER_EMPTY);
531  }
532 
533  //System bus error?
534  if((status & ENET_EIR_EBERR_MASK) != 0)
535  {
536  //Clear EBERR interrupt flag
537  ENET_0->EIR = ENET_EIR_EBERR_MASK;
538 
539  //Disable Ethernet MAC
540  ENET_0->ECR &= ~ENET_ECR_ETHEREN_MASK;
541  //Reset buffer descriptors
542  mpc57xxEthInitBufferDesc(interface);
543  //Resume normal operation
544  ENET_0->ECR |= ENET_ECR_ETHEREN_MASK;
545  //Instruct the DMA to poll the receive descriptor list
546  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
547  }
548 
549  //Re-enable Ethernet MAC interrupts
550  ENET_0->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
551 }
552 
553 
554 /**
555  * @brief Send a packet
556  * @param[in] interface Underlying network interface
557  * @param[in] buffer Multi-part buffer containing the data to send
558  * @param[in] offset Offset to the first data byte
559  * @param[in] ancillary Additional options passed to the stack along with
560  * the packet
561  * @return Error code
562  **/
563 
565  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
566 {
567  size_t length;
568 
569  //Retrieve the length of the packet
570  length = netBufferGetLength(buffer) - offset;
571 
572  //Check the frame length
574  {
575  //The transmitter can accept another packet
576  osSetEvent(&interface->nicTxEvent);
577  //Report an error
578  return ERROR_INVALID_LENGTH;
579  }
580 
581  //Make sure the current buffer is available for writing
582  if((txBufferDesc[txBufferIndex][0] & ENET_TBD0_R) != 0)
583  {
584  return ERROR_FAILURE;
585  }
586 
587  //Copy user data to the transmit buffer
588  netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
589 
590  //Clear BDU flag
591  txBufferDesc[txBufferIndex][4] = 0;
592 
593  //Check current index
594  if(txBufferIndex < (MPC57XX_ETH_TX_BUFFER_COUNT - 1))
595  {
596  //Give the ownership of the descriptor to the DMA engine
597  txBufferDesc[txBufferIndex][0] = ENET_TBD0_R | ENET_TBD0_L |
599 
600  //Point to the next buffer
601  txBufferIndex++;
602  }
603  else
604  {
605  //Give the ownership of the descriptor to the DMA engine
606  txBufferDesc[txBufferIndex][0] = ENET_TBD0_R | ENET_TBD0_W |
608 
609  //Wrap around
610  txBufferIndex = 0;
611  }
612 
613  //Instruct the DMA to poll the transmit descriptor list
614  ENET_0->TDAR = ENET_TDAR_TDAR_MASK;
615 
616  //Check whether the next buffer is available for writing
617  if((txBufferDesc[txBufferIndex][0] & ENET_TBD0_R) == 0)
618  {
619  //The transmitter can accept another packet
620  osSetEvent(&interface->nicTxEvent);
621  }
622 
623  //Successful processing
624  return NO_ERROR;
625 }
626 
627 
628 /**
629  * @brief Receive a packet
630  * @param[in] interface Underlying network interface
631  * @return Error code
632  **/
633 
635 {
636  error_t error;
637  size_t n;
638  NetRxAncillary ancillary;
639 
640  //Current buffer available for reading?
641  if((rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_E) == 0)
642  {
643  //The frame should not span multiple buffers
644  if((rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_L) != 0)
645  {
646  //Check whether an error occurred
647  if((rxBufferDesc[rxBufferIndex][0] & (ENET_RBD0_LG | ENET_RBD0_NO |
649  {
650  //Retrieve the length of the frame
651  n = rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_DATA_LENGTH;
652  //Limit the number of data to read
654 
655  //Additional options can be passed to the stack along with the packet
656  ancillary = NET_DEFAULT_RX_ANCILLARY;
657 
658  //Pass the packet to the upper layer
659  nicProcessPacket(interface, rxBuffer[rxBufferIndex], n, &ancillary);
660 
661  //Valid packet received
662  error = NO_ERROR;
663  }
664  else
665  {
666  //The received packet contains an error
667  error = ERROR_INVALID_PACKET;
668  }
669  }
670  else
671  {
672  //The packet is not valid
673  error = ERROR_INVALID_PACKET;
674  }
675 
676  //Clear BDU flag
677  rxBufferDesc[rxBufferIndex][4] = 0;
678 
679  //Check current index
680  if(rxBufferIndex < (MPC57XX_ETH_RX_BUFFER_COUNT - 1))
681  {
682  //Give the ownership of the descriptor back to the DMA engine
683  rxBufferDesc[rxBufferIndex][0] = ENET_RBD0_E;
684  //Point to the next buffer
685  rxBufferIndex++;
686  }
687  else
688  {
689  //Give the ownership of the descriptor back to the DMA engine
690  rxBufferDesc[rxBufferIndex][0] = ENET_RBD0_E | ENET_RBD0_W;
691  //Wrap around
692  rxBufferIndex = 0;
693  }
694 
695  //Instruct the DMA to poll the receive descriptor list
696  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
697  }
698  else
699  {
700  //No more data in the receive buffer
701  error = ERROR_BUFFER_EMPTY;
702  }
703 
704  //Return status code
705  return error;
706 }
707 
708 
709 /**
710  * @brief Configure MAC address filtering
711  * @param[in] interface Underlying network interface
712  * @return Error code
713  **/
714 
716 {
717  uint_t i;
718  uint_t k;
719  uint32_t crc;
720  uint32_t value;
721  uint32_t unicastHashTable[2];
722  uint32_t multicastHashTable[2];
723  MacFilterEntry *entry;
724 
725  //Debug message
726  TRACE_DEBUG("Updating MAC filter...\r\n");
727 
728  //Set the MAC address of the station (upper 16 bits)
729  value = interface->macAddr.b[5];
730  value |= (interface->macAddr.b[4] << 8);
731  ENET_0->PAUR = ENET_PAUR_PADDR2(value) | ENET_PAUR_TYPE(0x8808);
732 
733  //Set the MAC address of the station (lower 32 bits)
734  value = interface->macAddr.b[3];
735  value |= (interface->macAddr.b[2] << 8);
736  value |= (interface->macAddr.b[1] << 16);
737  value |= (interface->macAddr.b[0] << 24);
738  ENET_0->PALR = ENET_PALR_PADDR1(value);
739 
740  //Clear hash table (unicast address filtering)
741  unicastHashTable[0] = 0;
742  unicastHashTable[1] = 0;
743 
744  //Clear hash table (multicast address filtering)
745  multicastHashTable[0] = 0;
746  multicastHashTable[1] = 0;
747 
748  //The MAC address filter contains the list of MAC addresses to accept
749  //when receiving an Ethernet frame
750  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
751  {
752  //Point to the current entry
753  entry = &interface->macAddrFilter[i];
754 
755  //Valid entry?
756  if(entry->refCount > 0)
757  {
758  //Compute CRC over the current MAC address
759  crc = mpc57xxEthCalcCrc(&entry->addr, sizeof(MacAddr));
760 
761  //The upper 6 bits in the CRC register are used to index the
762  //contents of the hash table
763  k = (crc >> 26) & 0x3F;
764 
765  //Multicast address?
766  if(macIsMulticastAddr(&entry->addr))
767  {
768  //Update the multicast hash table
769  multicastHashTable[k / 32] |= (1 << (k % 32));
770  }
771  else
772  {
773  //Update the unicast hash table
774  unicastHashTable[k / 32] |= (1 << (k % 32));
775  }
776  }
777  }
778 
779  //Write the hash table (unicast address filtering)
780  ENET_0->IALR = unicastHashTable[0];
781  ENET_0->IAUR = unicastHashTable[1];
782 
783  //Write the hash table (multicast address filtering)
784  ENET_0->GALR = multicastHashTable[0];
785  ENET_0->GAUR = multicastHashTable[1];
786 
787  //Debug message
788  TRACE_DEBUG(" IALR = %08" PRIX32 "\r\n", ENET_0->IALR);
789  TRACE_DEBUG(" IAUR = %08" PRIX32 "\r\n", ENET_0->IAUR);
790  TRACE_DEBUG(" GALR = %08" PRIX32 "\r\n", ENET_0->GALR);
791  TRACE_DEBUG(" GAUR = %08" PRIX32 "\r\n", ENET_0->GAUR);
792 
793  //Successful processing
794  return NO_ERROR;
795 }
796 
797 
798 /**
799  * @brief Adjust MAC configuration parameters for proper operation
800  * @param[in] interface Underlying network interface
801  * @return Error code
802  **/
803 
805 {
806  //Disable Ethernet MAC while modifying configuration registers
807  ENET_0->ECR &= ~ENET_ECR_ETHEREN_MASK;
808 
809  //10BASE-T or 100BASE-TX operation mode?
810  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
811  {
812  //100 Mbps operation
813  ENET_0->RCR &= ~ENET_RCR_RMII_10T_MASK;
814  }
815  else
816  {
817  //10 Mbps operation
818  ENET_0->RCR |= ENET_RCR_RMII_10T_MASK;
819  }
820 
821  //Half-duplex or full-duplex mode?
822  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
823  {
824  //Full-duplex mode
825  ENET_0->TCR |= ENET_TCR_FDEN_MASK;
826  //Receive path operates independently of transmit
827  ENET_0->RCR &= ~ENET_RCR_DRT_MASK;
828  }
829  else
830  {
831  //Half-duplex mode
832  ENET_0->TCR &= ~ENET_TCR_FDEN_MASK;
833  //Disable reception of frames while transmitting
834  ENET_0->RCR |= ENET_RCR_DRT_MASK;
835  }
836 
837  //Reset buffer descriptors
838  mpc57xxEthInitBufferDesc(interface);
839 
840  //Re-enable Ethernet MAC
841  ENET_0->ECR |= ENET_ECR_ETHEREN_MASK;
842  //Instruct the DMA to poll the receive descriptor list
843  ENET_0->RDAR = ENET_RDAR_RDAR_MASK;
844 
845  //Successful processing
846  return NO_ERROR;
847 }
848 
849 
850 /**
851  * @brief Write PHY register
852  * @param[in] opcode Access type (2 bits)
853  * @param[in] phyAddr PHY address (5 bits)
854  * @param[in] regAddr Register address (5 bits)
855  * @param[in] data Register value
856  **/
857 
858 void mpc57xxEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
859  uint8_t regAddr, uint16_t data)
860 {
861  uint32_t temp;
862 
863  //Valid opcode?
864  if(opcode == SMI_OPCODE_WRITE)
865  {
866  //Set up a write operation
867  temp = ENET_MMFR_ST(1) | ENET_MMFR_OP(1) | ENET_MMFR_TA(2);
868  //PHY address
869  temp |= ENET_MMFR_PA(phyAddr);
870  //Register address
871  temp |= ENET_MMFR_RA(regAddr);
872  //Register value
873  temp |= ENET_MMFR_DATA(data);
874 
875  //Clear MII interrupt flag
876  ENET_0->EIR = ENET_EIR_MII_MASK;
877  //Start a write operation
878  ENET_0->MMFR = temp;
879 
880  //Wait for the write to complete
881  while((ENET_0->EIR & ENET_EIR_MII_MASK) == 0)
882  {
883  }
884  }
885  else
886  {
887  //The MAC peripheral only supports standard Clause 22 opcodes
888  }
889 }
890 
891 
892 /**
893  * @brief Read PHY register
894  * @param[in] opcode Access type (2 bits)
895  * @param[in] phyAddr PHY address (5 bits)
896  * @param[in] regAddr Register address (5 bits)
897  * @return Register value
898  **/
899 
900 uint16_t mpc57xxEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
901  uint8_t regAddr)
902 {
903  uint16_t data;
904  uint32_t temp;
905 
906  //Valid opcode?
907  if(opcode == SMI_OPCODE_READ)
908  {
909  //Set up a read operation
910  temp = ENET_MMFR_ST(1) | ENET_MMFR_OP(2) | ENET_MMFR_TA(2);
911  //PHY address
912  temp |= ENET_MMFR_PA(phyAddr);
913  //Register address
914  temp |= ENET_MMFR_RA(regAddr);
915 
916  //Clear MII interrupt flag
917  ENET_0->EIR = ENET_EIR_MII_MASK;
918  //Start a read operation
919  ENET_0->MMFR = temp;
920 
921  //Wait for the read to complete
922  while((ENET_0->EIR & ENET_EIR_MII_MASK) == 0)
923  {
924  }
925 
926  //Get register value
927  data = ENET_0->MMFR & ENET_MMFR_DATA_MASK;
928  }
929  else
930  {
931  //The MAC peripheral only supports standard Clause 22 opcodes
932  data = 0;
933  }
934 
935  //Return the value of the PHY register
936  return data;
937 }
938 
939 
940 /**
941  * @brief CRC calculation
942  * @param[in] data Pointer to the data over which to calculate the CRC
943  * @param[in] length Number of bytes to process
944  * @return Resulting CRC value
945  **/
946 
947 uint32_t mpc57xxEthCalcCrc(const void *data, size_t length)
948 {
949  uint_t i;
950  uint_t j;
951  uint32_t crc;
952  const uint8_t *p;
953 
954  //Point to the data over which to calculate the CRC
955  p = (uint8_t *) data;
956  //CRC preset value
957  crc = 0xFFFFFFFF;
958 
959  //Loop through data
960  for(i = 0; i < length; i++)
961  {
962  //Update CRC value
963  crc ^= p[i];
964 
965  //The message is processed bit by bit
966  for(j = 0; j < 8; j++)
967  {
968  if((crc & 0x01) != 0)
969  {
970  crc = (crc >> 1) ^ 0xEDB88320;
971  }
972  else
973  {
974  crc = crc >> 1;
975  }
976  }
977  }
978 
979  //Return CRC value
980  return crc;
981 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
uint8_t length
Definition: coap_common.h:193
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:53
#define netEvent
Definition: net_legacy.h:196
uint8_t data[]
Definition: ethernet.h:220
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define ENET_TBD0_L
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
void mpc57xxEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define ENET_RBD0_DATA_LENGTH
uint8_t p
Definition: ndp.h:298
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
#define TRUE
Definition: os_port.h:52
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:260
void mpc57xxEthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
#define ENET_TBD0_DATA_LENGTH
#define MPC57XX_ETH_TX_BUFFER_SIZE
#define ENET_TBD0_W
#define ENET_TBD0_TC
uint16_t mpc57xxEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
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 macIsMulticastAddr(macAddr)
Definition: ethernet.h:133
#define osExitIsr(flag)
#define SMI_OPCODE_WRITE
Definition: nic.h:66
void ENET0_Rx_IRQHandler(void)
Ethernet MAC receive interrupt.
void ENET0_Err_IRQHandler(void)
Ethernet MAC error interrupt.
#define ENET_RBD0_L
void mpc57xxEthEnableIrq(NetInterface *interface)
Enable interrupts.
#define FALSE
Definition: os_port.h:48
__start_packed struct @0 MacAddr
MAC address.
uint32_t mpc57xxEthCalcCrc(const void *data, size_t length)
CRC calculation.
error_t
Error codes.
Definition: error.h:43
void mpc57xxEthDisableIrq(NetInterface *interface)
Disable interrupts.
__weak_func void mpc57xxEthInitGpio(NetInterface *interface)
GPIO configuration.
uint8_t value[]
Definition: tcp.h:367
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:102
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
NXP MPC57xx Ethernet MAC driver.
#define txBuffer
#define NetRxAncillary
Definition: net_misc.h:40
@ ERROR_INVALID_PACKET
Definition: error.h:140
#define MPC57XX_ETH_RX_BUFFER_SIZE
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:259
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define ENET_RBD0_W
error_t mpc57xxEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
#define ENET_RBD0_TR
#define NetTxAncillary
Definition: net_misc.h:36
#define SMI_OPCODE_READ
Definition: nic.h:67
#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:65
error_t mpc57xxEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define rxBuffer
#define ENET_RBD0_LG
void mpc57xxEthEventHandler(NetInterface *interface)
MPC57xx Ethernet MAC event handler.
#define TRACE_DEBUG(...)
Definition: debug.h:107
error_t mpc57xxEthReceivePacket(NetInterface *interface)
Receive a packet.
uint16_t regAddr
#define ENET_RBD0_CR
#define ENET_RBD0_OV
void mpc57xxEthTick(NetInterface *interface)
MPC57xx Ethernet MAC timer handler.
#define ETH_MTU
Definition: ethernet.h:116
uint8_t n
MAC filter table entry.
Definition: ethernet.h:258
#define MPC57XX_ETH_TX_BUFFER_COUNT
#define osEnterIsr()
#define ENET_TBD0_R
#define ENET_TBD2_INT
#define ENET_RBD0_E
#define MPC57XX_ETH_IRQ_PRIORITY
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t mpc57xxEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
const NicDriver mpc57xxEthDriver
MPC57xx Ethernet MAC driver.
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
void ENET0_Tx_IRQHandler(void)
Ethernet MAC transmit interrupt.
unsigned int uint_t
Definition: compiler_port.h:50
#define osMemset(p, value, length)
Definition: os_port.h:134
TCP/IP stack core.
NIC driver.
Definition: nic.h:283
error_t mpc57xxEthInit(NetInterface *interface)
MPC57xx Ethernet MAC initialization.
#define ENET_RBD0_NO
#define ENET_RBD2_INT
#define MPC57XX_ETH_RX_BUFFER_COUNT
@ NO_ERROR
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83