s32k148_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file s32k148_eth_driver.c
3  * @brief NXP S32K148 Ethernet MAC controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "s32k148.h"
36 #include "core/net.h"
38 #include "debug.h"
39 
40 //Underlying network interface
41 static NetInterface *nicDriverInterface;
42 
43 //IAR EWARM compiler?
44 #if defined(__ICCARM__)
45 
46 //TX buffer
47 #pragma data_alignment = 16
49 //RX buffer
50 #pragma data_alignment = 16
52 //TX buffer descriptors
53 #pragma data_alignment = 16
54 static uint32_t txBufferDesc[S32K148_ETH_TX_BUFFER_COUNT][8];
55 //RX buffer descriptors
56 #pragma data_alignment = 16
57 static uint32_t rxBufferDesc[S32K148_ETH_RX_BUFFER_COUNT][8];
58 
59 //ARM or GCC compiler?
60 #else
61 
62 //TX buffer
64  __attribute__((aligned(16)));
65 //RX buffer
67  __attribute__((aligned(16)));
68 //TX buffer descriptors
69 static uint32_t txBufferDesc[S32K148_ETH_TX_BUFFER_COUNT][8]
70  __attribute__((aligned(16)));
71 //RX buffer descriptors
72 static uint32_t rxBufferDesc[S32K148_ETH_RX_BUFFER_COUNT][8]
73  __attribute__((aligned(16)));
74 
75 #endif
76 
77 //TX buffer index
78 static uint_t txBufferIndex;
79 //RX buffer index
80 static uint_t rxBufferIndex;
81 
82 
83 /**
84  * @brief S32K148 Ethernet MAC driver
85  **/
86 
88 {
90  ETH_MTU,
101  TRUE,
102  TRUE,
103  TRUE,
104  FALSE
105 };
106 
107 
108 /**
109  * @brief S32K148 Ethernet MAC initialization
110  * @param[in] interface Underlying network interface
111  * @return Error code
112  **/
113 
115 {
116  error_t error;
117  uint32_t value;
118 
119  //Debug message
120  TRACE_INFO("Initializing S32K148 Ethernet MAC...\r\n");
121 
122  //Save underlying network interface
123  nicDriverInterface = interface;
124 
125  //Disable MPU
126  MPU->CESR &= ~MPU_CESR_VLD_MASK;
127 
128  //Enable external reference clock
129  SIM->MISCTRL0 &= ~(SIM_MISCTRL0_RMII_CLK_SEL_MASK |
130  SIM_MISCTRL0_RMII_CLK_OBE_MASK);
131 
132  //Enable ENET peripheral clock
133  PCC->PCCn[PCC_ENET_INDEX] |= PCC_PCCn_CGC_MASK;
134 
135  //GPIO configuration
136  s32k148EthInitGpio(interface);
137 
138  //Reset ENET module
139  ENET->ECR = ENET_ECR_RESET_MASK;
140  //Wait for the reset to complete
141  while(ENET->ECR & ENET_ECR_RESET_MASK)
142  {
143  }
144 
145  //Receive control register
146  ENET->RCR = ENET_RCR_MAX_FL(S32K148_ETH_RX_BUFFER_SIZE) |
147  ENET_RCR_RMII_MODE_MASK | ENET_RCR_MII_MODE_MASK;
148 
149  //Transmit control register
150  ENET->TCR = 0;
151  //Configure MDC clock frequency
152  ENET->MSCR = ENET_MSCR_MII_SPEED(23);
153 
154  //PHY transceiver initialization
155  error = interface->phyDriver->init(interface);
156  //Failed to initialize PHY transceiver?
157  if(error)
158  return error;
159 
160  //Set the MAC address of the station (upper 16 bits)
161  value = interface->macAddr.b[5];
162  value |= (interface->macAddr.b[4] << 8);
163  ENET->PAUR = ENET_PAUR_PADDR2(value) | ENET_PAUR_TYPE(0x8808);
164 
165  //Set the MAC address of the station (lower 32 bits)
166  value = interface->macAddr.b[3];
167  value |= (interface->macAddr.b[2] << 8);
168  value |= (interface->macAddr.b[1] << 16);
169  value |= (interface->macAddr.b[0] << 24);
170  ENET->PALR = ENET_PALR_PADDR1(value);
171 
172  //Hash table for unicast address filtering
173  ENET->IALR = 0;
174  ENET->IAUR = 0;
175  //Hash table for multicast address filtering
176  ENET->GALR = 0;
177  ENET->GAUR = 0;
178 
179  //Disable transmit accelerator functions
180  ENET->TACC = 0;
181  //Disable receive accelerator functions
182  ENET->RACC = 0;
183 
184  //Use enhanced buffer descriptors
185  ENET->ECR = ENET_ECR_DBSWP_MASK | ENET_ECR_EN1588_MASK;
186 
187  //Reset statistics counters
188  ENET->MIBC = ENET_MIBC_MIB_CLEAR_MASK;
189  ENET->MIBC = 0;
190 
191  //Initialize buffer descriptors
192  s32k148EthInitBufferDesc(interface);
193 
194  //Clear any pending interrupts
195  ENET->EIR = 0xFFFFFFFF;
196  //Enable desired interrupts
197  ENET->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
198 
199  //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
200  NVIC_SetPriorityGrouping(S32K148_ETH_IRQ_PRIORITY_GROUPING);
201 
202  //Configure ENET transmit interrupt priority
203  NVIC_SetPriority(ENET_TX_IRQn, NVIC_EncodePriority(S32K148_ETH_IRQ_PRIORITY_GROUPING,
205 
206  //Configure ENET receive interrupt priority
207  NVIC_SetPriority(ENET_RX_IRQn, NVIC_EncodePriority(S32K148_ETH_IRQ_PRIORITY_GROUPING,
209 
210  //Configure ENET error interrupt priority
211  NVIC_SetPriority(ENET_ERR_IRQn, NVIC_EncodePriority(S32K148_ETH_IRQ_PRIORITY_GROUPING,
213 
214  //Enable Ethernet MAC
215  ENET->ECR |= ENET_ECR_ETHEREN_MASK;
216  //Instruct the DMA to poll the receive descriptor list
217  ENET->RDAR = ENET_RDAR_RDAR_MASK;
218 
219  //Accept any packets from the upper layer
220  osSetEvent(&interface->nicTxEvent);
221 
222  //Successful initialization
223  return NO_ERROR;
224 }
225 
226 
227 //S32K148-EVB evaluation board?
228 #if defined(USE_S32K148_EVB)
229 
230 /**
231  * @brief GPIO configuration
232  * @param[in] interface Underlying network interface
233  **/
234 
235 void s32k148EthInitGpio(NetInterface *interface)
236 {
237  //Enable PARTA, PORTB, PORTC and PORTD peripheral clocks
238  PCC->PCCn[PCC_PORTA_INDEX] = PCC_PCCn_CGC_MASK;
239  PCC->PCCn[PCC_PORTB_INDEX] = PCC_PCCn_CGC_MASK;
240  PCC->PCCn[PCC_PORTC_INDEX] = PCC_PCCn_CGC_MASK;
241  PCC->PCCn[PCC_PORTD_INDEX] = PCC_PCCn_CGC_MASK;
242 
243  //Configure RMII_RXD1 (PTC0)
244  PORTC->PCR[0] = PORT_PCR_MUX(4);
245  //Configure RMII_RXD0 (PTC1)
246  PORTC->PCR[1] = PORT_PCR_MUX(5);
247  //Configure RMII_TXD0 (PTC2)
248  PORTC->PCR[2] = PORT_PCR_MUX(5);
249  //Configure RMII_RXER (PTC16)
250  //PORTC->PCR[16] = PORT_PCR_MUX(5) | PORT_PCR_PE_MASK;
251  //Configure RMII_CRS_DV (PTC17)
252  PORTC->PCR[17] = PORT_PCR_MUX(5);
253  //Configure RMII_TXD1 (PTD7)
254  PORTD->PCR[7] = PORT_PCR_MUX(5);
255  //Configure RMII_REF_CLK (PTD11)
256  PORTD->PCR[11] = PORT_PCR_MUX(5);
257  //Configure RMII_TXEN (PTD12)
258  PORTD->PCR[12] = PORT_PCR_MUX(5);
259 
260  //Configure RMII_MDIO (PTB4)
261  PORTB->PCR[4] = PORT_PCR_MUX(5) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK;
262  //Configure RMII_MDC (PTB5)
263  PORTB->PCR[5] = PORT_PCR_MUX(7);
264 
265  //Configure ENET_RESET (PTA17) as an output
266  PORTA->PCR[17] = PORT_PCR_MUX(1);
267  PTA->PDDR |= (1 << 17);
268 
269  //Reset PHY transceiver
270  PTA->PCOR |= (1 << 17);
271  sleep(10);
272  PTA->PSOR |= (1 << 17);
273  sleep(10);
274 }
275 
276 #endif
277 
278 
279 /**
280  * @brief Initialize buffer descriptors
281  * @param[in] interface Underlying network interface
282  **/
283 
285 {
286  uint_t i;
287  uint32_t address;
288 
289  //Clear TX and RX buffer descriptors
290  memset(txBufferDesc, 0, sizeof(txBufferDesc));
291  memset(rxBufferDesc, 0, sizeof(rxBufferDesc));
292 
293  //Initialize TX buffer descriptors
294  for(i = 0; i < S32K148_ETH_TX_BUFFER_COUNT; i++)
295  {
296  //Calculate the address of the current TX buffer
297  address = (uint32_t) txBuffer[i];
298  //Transmit buffer address
299  txBufferDesc[i][1] = address;
300  //Generate interrupts
301  txBufferDesc[i][2] = ENET_TBD2_INT;
302  }
303 
304  //Mark the last descriptor entry with the wrap flag
305  txBufferDesc[i - 1][0] |= ENET_TBD0_W;
306  //Initialize TX buffer index
307  txBufferIndex = 0;
308 
309  //Initialize RX buffer descriptors
310  for(i = 0; i < S32K148_ETH_RX_BUFFER_COUNT; i++)
311  {
312  //Calculate the address of the current RX buffer
313  address = (uint32_t) rxBuffer[i];
314  //The descriptor is initially owned by the DMA
315  rxBufferDesc[i][0] = ENET_RBD0_E;
316  //Receive buffer address
317  rxBufferDesc[i][1] = address;
318  //Generate interrupts
319  rxBufferDesc[i][2] = ENET_RBD2_INT;
320  }
321 
322  //Mark the last descriptor entry with the wrap flag
323  rxBufferDesc[i - 1][0] |= ENET_RBD0_W;
324  //Initialize RX buffer index
325  rxBufferIndex = 0;
326 
327  //Start location of the TX descriptor list
328  ENET->TDSR = (uint32_t) txBufferDesc;
329  //Start location of the RX descriptor list
330  ENET->RDSR = (uint32_t) rxBufferDesc;
331  //Maximum receive buffer size
332  ENET->MRBR = S32K148_ETH_RX_BUFFER_SIZE;
333 }
334 
335 
336 /**
337  * @brief S32K148 Ethernet MAC timer handler
338  *
339  * This routine is periodically called by the TCP/IP stack to
340  * handle periodic operations such as polling the link state
341  *
342  * @param[in] interface Underlying network interface
343  **/
344 
345 void s32k148EthTick(NetInterface *interface)
346 {
347  //Handle periodic operations
348  interface->phyDriver->tick(interface);
349 }
350 
351 
352 /**
353  * @brief Enable interrupts
354  * @param[in] interface Underlying network interface
355  **/
356 
358 {
359  //Enable Ethernet MAC interrupts
360  NVIC_EnableIRQ(ENET_TX_IRQn);
361  NVIC_EnableIRQ(ENET_RX_IRQn);
362  NVIC_EnableIRQ(ENET_ERR_IRQn);
363 
364  //Enable Ethernet PHY interrupts
365  interface->phyDriver->enableIrq(interface);
366 }
367 
368 
369 /**
370  * @brief Disable interrupts
371  * @param[in] interface Underlying network interface
372  **/
373 
375 {
376  //Disable Ethernet MAC interrupts
377  NVIC_DisableIRQ(ENET_TX_IRQn);
378  NVIC_DisableIRQ(ENET_RX_IRQn);
379  NVIC_DisableIRQ(ENET_ERR_IRQn);
380 
381  //Disable Ethernet PHY interrupts
382  interface->phyDriver->disableIrq(interface);
383 }
384 
385 
386 /**
387  * @brief Ethernet MAC transmit interrupt
388  **/
389 
391 {
392  bool_t flag;
393 
394  //Interrupt service routine prologue
395  osEnterIsr();
396 
397  //This flag will be set if a higher priority task must be woken
398  flag = FALSE;
399 
400  //A packet has been transmitted?
401  if(ENET->EIR & ENET_EIR_TXF_MASK)
402  {
403  //Clear TXF interrupt flag
404  ENET->EIR = ENET_EIR_TXF_MASK;
405 
406  //Check whether the TX buffer is available for writing
407  if(!(txBufferDesc[txBufferIndex][0] & ENET_TBD0_R))
408  {
409  //Notify the TCP/IP stack that the transmitter is ready to send
410  flag = osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
411  }
412 
413  //Instruct the DMA to poll the transmit descriptor list
414  ENET->TDAR = ENET_TDAR_TDAR_MASK;
415  }
416 
417  //Interrupt service routine epilogue
418  osExitIsr(flag);
419 }
420 
421 
422 /**
423  * @brief Ethernet MAC receive interrupt
424  **/
425 
427 {
428  bool_t flag;
429 
430  //Interrupt service routine prologue
431  osEnterIsr();
432 
433  //This flag will be set if a higher priority task must be woken
434  flag = FALSE;
435 
436  //A packet has been received?
437  if(ENET->EIR & ENET_EIR_RXF_MASK)
438  {
439  //Disable RXF interrupt
440  ENET->EIMR &= ~ENET_EIMR_RXF_MASK;
441 
442  //Set event flag
443  nicDriverInterface->nicEvent = TRUE;
444  //Notify the TCP/IP stack of the event
445  flag = osSetEventFromIsr(&netEvent);
446  }
447 
448  //Interrupt service routine epilogue
449  osExitIsr(flag);
450 }
451 
452 
453 /**
454  * @brief Ethernet MAC error interrupt
455  **/
456 
458 {
459  bool_t flag;
460 
461  //Interrupt service routine prologue
462  osEnterIsr();
463 
464  //This flag will be set if a higher priority task must be woken
465  flag = FALSE;
466 
467  //System bus error?
468  if(ENET->EIR & ENET_EIR_EBERR_MASK)
469  {
470  //Disable EBERR interrupt
471  ENET->EIMR &= ~ENET_EIMR_EBERR_MASK;
472 
473  //Set event flag
474  nicDriverInterface->nicEvent = TRUE;
475  //Notify the TCP/IP stack of the event
476  flag |= osSetEventFromIsr(&netEvent);
477  }
478 
479  //Interrupt service routine epilogue
480  osExitIsr(flag);
481 }
482 
483 
484 /**
485  * @brief S32K148 Ethernet MAC event handler
486  * @param[in] interface Underlying network interface
487  **/
488 
490 {
491  error_t error;
492  uint32_t status;
493 
494  //Read interrupt event register
495  status = ENET->EIR;
496 
497  //Packet received?
498  if(status & ENET_EIR_RXF_MASK)
499  {
500  //Clear RXF interrupt flag
501  ENET->EIR = ENET_EIR_RXF_MASK;
502 
503  //Process all pending packets
504  do
505  {
506  //Read incoming packet
507  error = s32k148EthReceivePacket(interface);
508 
509  //No more data in the receive buffer?
510  } while(error != ERROR_BUFFER_EMPTY);
511  }
512 
513  //System bus error?
514  if(status & ENET_EIR_EBERR_MASK)
515  {
516  //Clear EBERR interrupt flag
517  ENET->EIR = ENET_EIR_EBERR_MASK;
518 
519  //Disable Ethernet MAC
520  ENET->ECR &= ~ENET_ECR_ETHEREN_MASK;
521  //Reset buffer descriptors
522  s32k148EthInitBufferDesc(interface);
523  //Resume normal operation
524  ENET->ECR |= ENET_ECR_ETHEREN_MASK;
525  //Instruct the DMA to poll the receive descriptor list
526  ENET->RDAR = ENET_RDAR_RDAR_MASK;
527  }
528 
529  //Re-enable Ethernet MAC interrupts
530  ENET->EIMR = ENET_EIMR_TXF_MASK | ENET_EIMR_RXF_MASK | ENET_EIMR_EBERR_MASK;
531 }
532 
533 
534 /**
535  * @brief Send a packet
536  * @param[in] interface Underlying network interface
537  * @param[in] buffer Multi-part buffer containing the data to send
538  * @param[in] offset Offset to the first data byte
539  * @return Error code
540  **/
541 
543  const NetBuffer *buffer, size_t offset)
544 {
545  size_t length;
546 
547  //Retrieve the length of the packet
548  length = netBufferGetLength(buffer) - offset;
549 
550  //Check the frame length
552  {
553  //The transmitter can accept another packet
554  osSetEvent(&interface->nicTxEvent);
555  //Report an error
556  return ERROR_INVALID_LENGTH;
557  }
558 
559  //Make sure the current buffer is available for writing
560  if(txBufferDesc[txBufferIndex][0] & ENET_TBD0_R)
561  return ERROR_FAILURE;
562 
563  //Copy user data to the transmit buffer
564  netBufferRead(txBuffer[txBufferIndex], buffer, offset, length);
565 
566  //Clear BDU flag
567  txBufferDesc[txBufferIndex][4] = 0;
568 
569  //Check current index
570  if(txBufferIndex < (S32K148_ETH_TX_BUFFER_COUNT - 1))
571  {
572  //Give the ownership of the descriptor to the DMA engine
573  txBufferDesc[txBufferIndex][0] = ENET_TBD0_R | ENET_TBD0_L |
575 
576  //Point to the next buffer
577  txBufferIndex++;
578  }
579  else
580  {
581  //Give the ownership of the descriptor to the DMA engine
582  txBufferDesc[txBufferIndex][0] = ENET_TBD0_R | ENET_TBD0_W |
584 
585  //Wrap around
586  txBufferIndex = 0;
587  }
588 
589  //Instruct the DMA to poll the transmit descriptor list
590  ENET->TDAR = ENET_TDAR_TDAR_MASK;
591 
592  //Check whether the next buffer is available for writing
593  if(!(txBufferDesc[txBufferIndex][0] & ENET_TBD0_R))
594  {
595  //The transmitter can accept another packet
596  osSetEvent(&interface->nicTxEvent);
597  }
598 
599  //Successful processing
600  return NO_ERROR;
601 }
602 
603 
604 /**
605  * @brief Receive a packet
606  * @param[in] interface Underlying network interface
607  * @return Error code
608  **/
609 
611 {
612  error_t error;
613  size_t n;
614 
615  //Make sure the current buffer is available for reading
616  if(!(rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_E))
617  {
618  //The frame should not span multiple buffers
619  if(rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_L)
620  {
621  //Check whether an error occurred
622  if(!(rxBufferDesc[rxBufferIndex][0] & (ENET_RBD0_LG |
624  {
625  //Retrieve the length of the frame
626  n = rxBufferDesc[rxBufferIndex][0] & ENET_RBD0_DATA_LENGTH;
627  //Limit the number of data to read
629 
630  //Pass the packet to the upper layer
631  nicProcessPacket(interface, rxBuffer[rxBufferIndex], n);
632 
633  //Valid packet received
634  error = NO_ERROR;
635  }
636  else
637  {
638  //The received packet contains an error
639  error = ERROR_INVALID_PACKET;
640  }
641  }
642  else
643  {
644  //The packet is not valid
645  error = ERROR_INVALID_PACKET;
646  }
647 
648  //Clear BDU flag
649  rxBufferDesc[rxBufferIndex][4] = 0;
650 
651  //Check current index
652  if(rxBufferIndex < (S32K148_ETH_RX_BUFFER_COUNT - 1))
653  {
654  //Give the ownership of the descriptor back to the DMA engine
655  rxBufferDesc[rxBufferIndex][0] = ENET_RBD0_E;
656  //Point to the next buffer
657  rxBufferIndex++;
658  }
659  else
660  {
661  //Give the ownership of the descriptor back to the DMA engine
662  rxBufferDesc[rxBufferIndex][0] = ENET_RBD0_E | ENET_RBD0_W;
663  //Wrap around
664  rxBufferIndex = 0;
665  }
666 
667  //Instruct the DMA to poll the receive descriptor list
668  ENET->RDAR = ENET_RDAR_RDAR_MASK;
669  }
670  else
671  {
672  //No more data in the receive buffer
673  error = ERROR_BUFFER_EMPTY;
674  }
675 
676  //Return status code
677  return error;
678 }
679 
680 
681 /**
682  * @brief Configure MAC address filtering
683  * @param[in] interface Underlying network interface
684  * @return Error code
685  **/
686 
688 {
689  uint_t i;
690  uint_t k;
691  uint32_t crc;
692  uint32_t value;
693  uint32_t unicastHashTable[2];
694  uint32_t multicastHashTable[2];
695  MacFilterEntry *entry;
696 
697  //Debug message
698  TRACE_DEBUG("Updating MAC filter...\r\n");
699 
700  //Set the MAC address of the station (upper 16 bits)
701  value = interface->macAddr.b[5];
702  value |= (interface->macAddr.b[4] << 8);
703  ENET->PAUR = ENET_PAUR_PADDR2(value) | ENET_PAUR_TYPE(0x8808);
704 
705  //Set the MAC address of the station (lower 32 bits)
706  value = interface->macAddr.b[3];
707  value |= (interface->macAddr.b[2] << 8);
708  value |= (interface->macAddr.b[1] << 16);
709  value |= (interface->macAddr.b[0] << 24);
710  ENET->PALR = ENET_PALR_PADDR1(value);
711 
712  //Clear hash table (unicast address filtering)
713  unicastHashTable[0] = 0;
714  unicastHashTable[1] = 0;
715 
716  //Clear hash table (multicast address filtering)
717  multicastHashTable[0] = 0;
718  multicastHashTable[1] = 0;
719 
720  //The MAC address filter contains the list of MAC addresses to accept
721  //when receiving an Ethernet frame
722  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
723  {
724  //Point to the current entry
725  entry = &interface->macAddrFilter[i];
726 
727  //Valid entry?
728  if(entry->refCount > 0)
729  {
730  //Compute CRC over the current MAC address
731  crc = s32k148EthCalcCrc(&entry->addr, sizeof(MacAddr));
732 
733  //The upper 6 bits in the CRC register are used to index the
734  //contents of the hash table
735  k = (crc >> 26) & 0x3F;
736 
737  //Multicast address?
738  if(macIsMulticastAddr(&entry->addr))
739  {
740  //Update the multicast hash table
741  multicastHashTable[k / 32] |= (1 << (k % 32));
742  }
743  else
744  {
745  //Update the unicast hash table
746  unicastHashTable[k / 32] |= (1 << (k % 32));
747  }
748  }
749  }
750 
751  //Write the hash table (unicast address filtering)
752  ENET->IALR = unicastHashTable[0];
753  ENET->IAUR = unicastHashTable[1];
754 
755  //Write the hash table (multicast address filtering)
756  ENET->GALR = multicastHashTable[0];
757  ENET->GAUR = multicastHashTable[1];
758 
759  //Debug message
760  TRACE_DEBUG(" IALR = %08" PRIX32 "\r\n", ENET->IALR);
761  TRACE_DEBUG(" IAUR = %08" PRIX32 "\r\n", ENET->IAUR);
762  TRACE_DEBUG(" GALR = %08" PRIX32 "\r\n", ENET->GALR);
763  TRACE_DEBUG(" GAUR = %08" PRIX32 "\r\n", ENET->GAUR);
764 
765  //Successful processing
766  return NO_ERROR;
767 }
768 
769 
770 /**
771  * @brief Adjust MAC configuration parameters for proper operation
772  * @param[in] interface Underlying network interface
773  * @return Error code
774  **/
775 
777 {
778  //Disable Ethernet MAC while modifying configuration registers
779  ENET->ECR &= ~ENET_ECR_ETHEREN_MASK;
780 
781  //10BASE-T or 100BASE-TX operation mode?
782  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
783  {
784  //100 Mbps operation
785  ENET->RCR &= ~ENET_RCR_RMII_10T_MASK;
786  }
787  else
788  {
789  //10 Mbps operation
790  ENET->RCR |= ENET_RCR_RMII_10T_MASK;
791  }
792 
793  //Half-duplex or full-duplex mode?
794  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
795  {
796  //Full-duplex mode
797  ENET->TCR |= ENET_TCR_FDEN_MASK;
798  //Receive path operates independently of transmit
799  ENET->RCR &= ~ENET_RCR_DRT_MASK;
800  }
801  else
802  {
803  //Half-duplex mode
804  ENET->TCR &= ~ENET_TCR_FDEN_MASK;
805  //Disable reception of frames while transmitting
806  ENET->RCR |= ENET_RCR_DRT_MASK;
807  }
808 
809  //Reset buffer descriptors
810  s32k148EthInitBufferDesc(interface);
811 
812  //Re-enable Ethernet MAC
813  ENET->ECR |= ENET_ECR_ETHEREN_MASK;
814  //Instruct the DMA to poll the receive descriptor list
815  ENET->RDAR = ENET_RDAR_RDAR_MASK;
816 
817  //Successful processing
818  return NO_ERROR;
819 }
820 
821 
822 /**
823  * @brief Write PHY register
824  * @param[in] opcode Access type (2 bits)
825  * @param[in] phyAddr PHY address (5 bits)
826  * @param[in] regAddr Register address (5 bits)
827  * @param[in] data Register value
828  **/
829 
830 void s32k148EthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
831  uint8_t regAddr, uint16_t data)
832 {
833  uint32_t temp;
834 
835  //Valid opcode?
836  if(opcode == SMI_OPCODE_WRITE)
837  {
838  //Set up a write operation
839  temp = ENET_MMFR_ST(1) | ENET_MMFR_OP(1) | ENET_MMFR_TA(2);
840  //PHY address
841  temp |= ENET_MMFR_PA(phyAddr);
842  //Register address
843  temp |= ENET_MMFR_RA(regAddr);
844  //Register value
845  temp |= ENET_MMFR_DATA(data);
846 
847  //Clear MII interrupt flag
848  ENET->EIR = ENET_EIR_MII_MASK;
849  //Start a write operation
850  ENET->MMFR = temp;
851 
852  //Wait for the write to complete
853  while(!(ENET->EIR & ENET_EIR_MII_MASK))
854  {
855  }
856  }
857  else
858  {
859  //The MAC peripheral only supports standard Clause 22 opcodes
860  }
861 }
862 
863 
864 /**
865  * @brief Read PHY register
866  * @param[in] opcode Access type (2 bits)
867  * @param[in] phyAddr PHY address (5 bits)
868  * @param[in] regAddr Register address (5 bits)
869  * @return Register value
870  **/
871 
872 uint16_t s32k148EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
873  uint8_t regAddr)
874 {
875  uint16_t data;
876  uint32_t temp;
877 
878  //Valid opcode?
879  if(opcode == SMI_OPCODE_READ)
880  {
881  //Set up a read operation
882  temp = ENET_MMFR_ST(1) | ENET_MMFR_OP(2) | ENET_MMFR_TA(2);
883  //PHY address
884  temp |= ENET_MMFR_PA(phyAddr);
885  //Register address
886  temp |= ENET_MMFR_RA(regAddr);
887 
888  //Clear MII interrupt flag
889  ENET->EIR = ENET_EIR_MII_MASK;
890  //Start a read operation
891  ENET->MMFR = temp;
892 
893  //Wait for the read to complete
894  while(!(ENET->EIR & ENET_EIR_MII_MASK))
895  {
896  }
897 
898  //Get register value
899  data = ENET->MMFR & ENET_MMFR_DATA_MASK;
900  }
901  else
902  {
903  //The MAC peripheral only supports standard Clause 22 opcodes
904  data = 0;
905  }
906 
907  //Return the value of the PHY register
908  return data;
909 }
910 
911 
912 /**
913  * @brief CRC calculation
914  * @param[in] data Pointer to the data over which to calculate the CRC
915  * @param[in] length Number of bytes to process
916  * @return Resulting CRC value
917  **/
918 
919 uint32_t s32k148EthCalcCrc(const void *data, size_t length)
920 {
921  uint_t i;
922  uint_t j;
923 
924  //Point to the data over which to calculate the CRC
925  const uint8_t *p = (uint8_t *) data;
926  //CRC preset value
927  uint32_t crc = 0xFFFFFFFF;
928 
929  //Loop through data
930  for(i = 0; i < length; i++)
931  {
932  //Update CRC value
933  crc ^= p[i];
934  //The message is processed bit by bit
935  for(j = 0; j < 8; j++)
936  {
937  if(crc & 0x00000001)
938  crc = (crc >> 1) ^ 0xEDB88320;
939  else
940  crc = crc >> 1;
941  }
942  }
943 
944  //Return CRC value
945  return crc;
946 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
uint8_t length
Definition: dtls_misc.h:149
void s32k148EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:49
#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
#define ENET_RBD0_DATA_LENGTH
uint8_t p
Definition: ndp.h:298
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:383
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
#define TRUE
Definition: os_port.h:50
#define sleep(delay)
Definition: os_port.h:131
#define S32K148_ETH_TX_BUFFER_SIZE
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:223
void ENET_ERR_IRQHandler(void)
Ethernet MAC error interrupt.
error_t s32k148EthInit(NetInterface *interface)
S32K148 Ethernet MAC initialization.
#define ENET_TBD0_DATA_LENGTH
#define ENET_TBD0_W
#define ENET_TBD0_TC
void s32k148EthEventHandler(NetInterface *interface)
S32K148 Ethernet MAC event handler.
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:110
#define S32K148_ETH_TX_BUFFER_COUNT
#define osExitIsr(flag)
NXP S32K148 Ethernet MAC controller.
#define SMI_OPCODE_WRITE
Definition: nic.h:62
#define ENET_RBD0_L
#define FALSE
Definition: os_port.h:46
void s32k148EthTick(NetInterface *interface)
S32K148 Ethernet MAC timer handler.
uint16_t s32k148EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define MPU_CESR_VLD_MASK
error_t
Error codes.
Definition: error.h:42
#define S32K148_ETH_IRQ_SUB_PRIORITY
Generic error code.
Definition: error.h:45
#define txBuffer
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:222
#define ENET_RBD0_W
#define ENET_RBD0_TR
OsEvent netEvent
Definition: net.c:77
#define SMI_OPCODE_READ
Definition: nic.h:63
error_t s32k148EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define TRACE_INFO(...)
Definition: debug.h:94
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define MIN(a, b)
Definition: os_port.h:62
error_t s32k148EthReceivePacket(NetInterface *interface)
Receive a packet.
void s32k148EthInitGpio(NetInterface *interface)
#define S32K148_ETH_IRQ_GROUP_PRIORITY
const NicDriver s32k148EthDriver
S32K148 Ethernet MAC driver.
#define rxBuffer
void s32k148EthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
#define ENET_RBD0_LG
uint32_t s32k148EthCalcCrc(const void *data, size_t length)
CRC calculation.
void ENET_RX_IRQHandler(void)
Ethernet MAC receive interrupt.
void s32k148EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define TRACE_DEBUG(...)
Definition: debug.h:106
uint16_t regAddr
#define ENET_RBD0_CR
#define ENET_RBD0_OV
#define ETH_MTU
Definition: ethernet.h:91
uint8_t n
MAC filter table entry.
Definition: ethernet.h:220
#define osEnterIsr()
#define MPU
#define ENET_TBD0_R
#define ENET_TBD2_INT
#define S32K148_ETH_RX_BUFFER_SIZE
#define ENET_RBD0_E
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define S32K148_ETH_RX_BUFFER_COUNT
#define S32K148_ETH_IRQ_PRIORITY_GROUPING
void s32k148EthDisableIrq(NetInterface *interface)
Disable interrupts.
error_t s32k148EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
uint8_t value[]
Definition: dtls_misc.h:150
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
void ENET_TX_IRQHandler(void)
Ethernet MAC transmit interrupt.
NIC driver.
Definition: nic.h:179
#define ENET_RBD0_NO
#define ENET_RBD2_INT
error_t s32k148EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
__start_packed struct @108 MacAddr
MAC address.
Ethernet interface.
Definition: nic.h:79