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