mcf5225x_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file mcf5225x_eth_driver.c
3  * @brief Coldfire V2 MCF5225x Ethernet MAC controller
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include "mcf52259.h"
34 #include "core/net.h"
36 #include "debug.h"
37 
38 //Underlying network interface
39 static NetInterface *nicDriverInterface;
40 
41 //TX buffer
43 //RX buffer
45 //TX buffer descriptors
47 //RX buffer descriptors
49 
50 //TX buffer index
51 static uint_t txBufferIndex;
52 //RX buffer index
53 static uint_t rxBufferIndex;
54 
55 
56 /**
57  * @brief MCF5225x Ethernet MAC driver
58  **/
59 
61 {
63  ETH_MTU,
74  TRUE,
75  TRUE,
76  TRUE,
77  FALSE
78 };
79 
80 
81 /**
82  * @brief MCF5225x Ethernet MAC initialization
83  * @param[in] interface Underlying network interface
84  * @return Error code
85  **/
86 
88 {
89  error_t error;
90  uint_t i;
91  uint32_t value;
92 
93  //Debug message
94  TRACE_INFO("Initializing MCF5225x Ethernet MAC...\r\n");
95 
96  //Save underlying network interface
97  nicDriverInterface = interface;
98 
99  //GPIO configuration
100  mcf5225xEthInitGpio(interface);
101 
102  //Reset FEC module
103  MCF_FEC_ECR = MCF_FEC_ECR_RESET;
104  //Wait for the reset to complete
105  while(MCF_FEC_ECR & MCF_FEC_ECR_RESET);
106 
107  //Receive control register
108  MCF_FEC_RCR = MCF_FEC_RCR_MAX_FL(1518) | MCF_FEC_RCR_MII_MODE;
109  //Transmit control register
110  MCF_FEC_TCR = 0;
111  //Configure MDC clock frequency
112  MCF_FEC_MSCR = MCF_FEC_MSCR_MII_SPEED(19);
113 
114  //PHY transceiver initialization
115  error = interface->phyDriver->init(interface);
116  //Failed to initialize PHY transceiver?
117  if(error)
118  return error;
119 
120  //Set the MAC address (upper 16 bits)
121  value = interface->macAddr.b[5];
122  value |= (interface->macAddr.b[4] << 8);
123  MCF_FEC_PAUR = MCF_FEC_PAUR_PADDR2(value) | MCF_FEC_PAUR_TYPE(0x8808);
124 
125  //Set the MAC address (lower 32 bits)
126  value = interface->macAddr.b[3];
127  value |= (interface->macAddr.b[2] << 8);
128  value |= (interface->macAddr.b[1] << 16);
129  value |= (interface->macAddr.b[0] << 24);
130  MCF_FEC_PALR = MCF_FEC_PALR_PADDR1(value);
131 
132  //Hash table for unicast address filtering
133  MCF_FEC_IALR = 0;
134  MCF_FEC_IAUR = 0;
135  //Hash table for multicast address filtering
136  MCF_FEC_GALR = 0;
137  MCF_FEC_GAUR = 0;
138 
139  //Initialize buffer descriptors
140  mcf5225xEthInitBufferDesc(interface);
141 
142  //Clear any pending interrupts
143  MCF_FEC_EIR = MCF_FEC_EIR_CLEAR_ALL;
144 
145  //Enable desired interrupts
146  MCF_FEC_EIMR = MCF_FEC_EIMR_TXF | MCF_FEC_EIMR_TXB |
147  MCF_FEC_EIMR_RXF | MCF_FEC_EIMR_RXB | MCF_FEC_EIMR_EBERR;
148 
149  //Set the priority of FEC interrupts
150  for(i = 23; i <= 35; i++)
151  {
152  MCF_INTC0_ICR(i) = MCF_INTC_ICR_IL(MCF5225X_ETH_IRQ_LEVEL) |
153  MCF_INTC_ICR_IP(MCF5225X_ETH_IRQ_PRIORITY);
154  }
155 
156  //Enable Ethernet MAC
157  MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
158  //Instruct the DMA to poll the receive descriptor list
159  MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
160 
161  //Accept any packets from the upper layer
162  osSetEvent(&interface->nicTxEvent);
163 
164  //Successful initialization
165  return NO_ERROR;
166 }
167 
168 
169 //TWR-MCF5225X evaluation board?
170 #if defined(USE_TWR_MCF5225X)
171 
172 /**
173  * @brief GPIO configuration
174  * @param[in] interface Underlying network interface
175  **/
176 
177 void mcf5225xEthInitGpio(NetInterface *interface)
178 {
179  uint8_t temp;
180 
181  //Configure FEC_COL (PTI0), FEC_CRS (PTI1), FEC_RXCLK (PTI2), FEC_RXD0 (PTI3),
182  //FEC_RXD1 (PTI4), FEC_RXD2 (PTI5), FEC_RXD3 (PTI6) and FEC_RXDV (PTI7)
183  MCF_GPIO_PTIPAR |= MCF_GPIO_PTIPAR_FEC_COL_FEC_COL | MCF_GPIO_PTIPAR_FEC_CRS_FEC_CRS |
184  MCF_GPIO_PTIPAR_FEC_RXCLK_FEC_RXCLK | MCF_GPIO_PTIPAR_FEC_RXD0_FEC_RXD0 |
185  MCF_GPIO_PTIPAR_FEC_RXD1_FEC_RXD1 | MCF_GPIO_PTIPAR_FEC_RXD2_FEC_RXD2 |
186  MCF_GPIO_PTIPAR_FEC_RXD3_FEC_RXD3 | MCF_GPIO_PTIPAR_FEC_RXDV_FEC_RXDV;
187 
188  //Configure FEC_RXER (PTJ0), FEC_TXCLK (PTJ1), FEC_TXD0 (PTJ2), FEC_TXD1 (PTJ3)
189  //FEC_TXD2 (PTJ4), FEC_TXD3 (PTJ5), FEC_TXEN (PTJ6) and FEC_TXER (PTJ7)
190  MCF_GPIO_PTJPAR |= MCF_GPIO_PTJPAR_FEC_RXER_FEC_RXER | MCF_GPIO_PTJPAR_FEC_TXCLK_FEC_TXCLK |
191  MCF_GPIO_PTJPAR_FEC_TXD0_FEC_TXD0 | MCF_GPIO_PTJPAR_FEC_TXD1_FEC_TXD1 |
192  MCF_GPIO_PTJPAR_FEC_TXD2_FEC_TXD2 | MCF_GPIO_PTJPAR_FEC_TXD3_FEC_TXD3 |
193  MCF_GPIO_PTJPAR_FEC_TXEN_FEC_TXEN | MCF_GPIO_PTJPAR_FEC_TXER_FEC_TXER;
194 
195  //Configure FEC_MDIO (PNQ3)
196  temp = MCF_GPIO_PNQPAR & ~MCF_GPIO_PNQPAR_PNQPAR3(3);
197  MCF_GPIO_PNQPAR = temp | MCF_GPIO_PNQPAR_IRQ3_FEC_MDIO;
198 
199  //Configure FEC_MDC (PNQ5)
200  temp = MCF_GPIO_PNQPAR & ~MCF_GPIO_PNQPAR_PNQPAR5(3);
201  MCF_GPIO_PNQPAR = temp | MCF_GPIO_PNQPAR_IRQ5_FEC_MDC;
202 
203  //Reset PHY transceiver
204  MCF_RCM_RCR |= MCF_RCM_RCR_FRCRSTOUT;
205  sleep(10);
206 
207  //Take the PHY transceiver out of reset
208  MCF_RCM_RCR &= ~MCF_RCM_RCR_FRCRSTOUT;
209  sleep(10);
210 }
211 
212 #endif
213 
214 
215 /**
216  * @brief Initialize buffer descriptors
217  * @param[in] interface Underlying network interface
218  **/
219 
221 {
222  uint_t i;
223 
224  //Initialize TX buffer descriptors
225  for(i = 0; i < MCF5225X_ETH_TX_BUFFER_COUNT; i++)
226  {
227  //The descriptor is initially owned by the software
228  txBufferDesc[i].status = 0;
229  //Transmit buffer length
230  txBufferDesc[i].length = 0;
231  //Transmit buffer address
232  txBufferDesc[i].address = (uint32_t) FEC_ALIGN16(txBuffer[i]);
233  }
234 
235  //Mark the last descriptor entry with the wrap flag
236  txBufferDesc[i - 1].status |= FEC_TX_BD_W;
237  //Initialize TX buffer index
238  txBufferIndex = 0;
239 
240  //Initialize RX buffer descriptors
241  for(i = 0; i < MCF5225X_ETH_RX_BUFFER_COUNT; i++)
242  {
243  //The descriptor is initially owned by the DMA
244  rxBufferDesc[i].status = FEC_RX_BD_E;
245  //Receive buffer length
246  rxBufferDesc[i].length = 0;
247  //Receive buffer address
248  rxBufferDesc[i].address = (uint32_t) FEC_ALIGN16(rxBuffer[i]);
249  }
250 
251  //Mark the last descriptor entry with the wrap flag
252  rxBufferDesc[i - 1].status |= FEC_RX_BD_W;
253  //Initialize RX buffer index
254  rxBufferIndex = 0;
255 
256  //Start location of the TX descriptor list
257  MCF_FEC_ETSDR = (uint32_t) txBufferDesc;
258  //Start location of the RX descriptor list
259  MCF_FEC_ERDSR = (uint32_t) rxBufferDesc;
260  //Maximum receive buffer size
261  MCF_FEC_EMRBR = MCF5225X_ETH_RX_BUFFER_SIZE;
262 }
263 
264 
265 /**
266  * @brief MCF5225x Ethernet MAC timer handler
267  *
268  * This routine is periodically called by the TCP/IP stack to
269  * handle periodic operations such as polling the link state
270  *
271  * @param[in] interface Underlying network interface
272  **/
273 
275 {
276  //Handle periodic operations
277  interface->phyDriver->tick(interface);
278 }
279 
280 
281 /**
282  * @brief Enable interrupts
283  * @param[in] interface Underlying network interface
284  **/
285 
287 {
288  //Enable Ethernet MAC interrupts
289  MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK23 |
290  MCF_INTC_IMRL_INT_MASK24 | MCF_INTC_IMRL_INT_MASK25 |
291  MCF_INTC_IMRL_INT_MASK26 | MCF_INTC_IMRL_INT_MASK27 |
292  MCF_INTC_IMRL_INT_MASK28 | MCF_INTC_IMRL_INT_MASK29 |
293  MCF_INTC_IMRL_INT_MASK30 | MCF_INTC_IMRL_INT_MASK31);
294 
295  MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK33 |
296  MCF_INTC_IMRH_INT_MASK34| MCF_INTC_IMRH_INT_MASK35);
297 
298  //Enable Ethernet PHY interrupts
299  interface->phyDriver->enableIrq(interface);
300 }
301 
302 
303 /**
304  * @brief Disable interrupts
305  * @param[in] interface Underlying network interface
306  **/
307 
309 {
310  //Disable Ethernet MAC interrupts
311  MCF_INTC0_IMRL |= MCF_INTC_IMRL_INT_MASK23 |
312  MCF_INTC_IMRL_INT_MASK24 | MCF_INTC_IMRL_INT_MASK25 |
313  MCF_INTC_IMRL_INT_MASK26 | MCF_INTC_IMRL_INT_MASK27 |
314  MCF_INTC_IMRL_INT_MASK28 | MCF_INTC_IMRL_INT_MASK29 |
315  MCF_INTC_IMRL_INT_MASK30 | MCF_INTC_IMRL_INT_MASK31;
316 
317  MCF_INTC0_IMRH |= MCF_INTC_IMRH_INT_MASK33 |
318  MCF_INTC_IMRH_INT_MASK34| MCF_INTC_IMRH_INT_MASK35;
319 
320  //Disable Ethernet PHY interrupts
321  interface->phyDriver->disableIrq(interface);
322 }
323 
324 
325 /**
326  * @brief Ethernet MAC interrupt
327  **/
328 
329 __declspec(interrupt) void mcf5225xEthIrqHandler(void)
330 {
331  bool_t flag;
332  uint32_t events;
333 
334  //Enter interrupt service routine
335  osEnterIsr();
336 
337  //This flag will be set if a higher priority task must be woken
338  flag = FALSE;
339  //Read interrupt event register
340  events = MCF_FEC_EIR;
341 
342  //A packet has been transmitted?
343  if(events & (MCF_FEC_EIR_TXF | MCF_FEC_EIR_TXB))
344  {
345  //Clear TXF and TXB interrupt flags
346  MCF_FEC_EIR = MCF_FEC_EIR_TXF | MCF_FEC_EIR_TXB;
347 
348  //Check whether the TX buffer is available for writing
349  if(!(txBufferDesc[txBufferIndex].status & FEC_TX_BD_R))
350  {
351  //Notify the TCP/IP stack that the transmitter is ready to send
352  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
353  }
354 
355  //Instruct the DMA to poll the transmit descriptor list
356  MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
357  }
358 
359  //A packet has been received?
360  if(events & (MCF_FEC_EIR_RXF | MCF_FEC_EIR_RXB))
361  {
362  //Disable RXF and RXB interrupts
363  MCF_FEC_EIMR &= ~(MCF_FEC_EIMR_RXF | MCF_FEC_EIMR_RXB);
364 
365  //Set event flag
366  nicDriverInterface->nicEvent = TRUE;
367  //Notify the TCP/IP stack of the event
368  flag |= osSetEventFromIsr(&netEvent);
369  }
370 
371  //System bus error?
372  if(events & MCF_FEC_EIR_EBERR)
373  {
374  //Disable EBERR interrupt
375  MCF_FEC_EIMR &= ~MCF_FEC_EIMR_EBERR;
376 
377  //Set event flag
378  nicDriverInterface->nicEvent = TRUE;
379  //Notify the TCP/IP stack of the event
380  flag |= osSetEventFromIsr(&netEvent);
381  }
382 
383  //Any other event?
384  if(events & (MCF_FEC_EIR_HBERR | MCF_FEC_EIR_BABR | MCF_FEC_EIR_BABT | MCF_FEC_EIR_GRA |
385  MCF_FEC_EIR_MII | MCF_FEC_EIR_LC | MCF_FEC_EIR_RL | MCF_FEC_EIR_UN))
386  {
387  //Clear interrupt flags
388  MCF_FEC_EIR = MCF_FEC_EIR_HBERR | MCF_FEC_EIR_BABR | MCF_FEC_EIR_BABT | MCF_FEC_EIR_GRA |
389  MCF_FEC_EIR_MII | MCF_FEC_EIR_LC | MCF_FEC_EIR_RL | MCF_FEC_EIR_UN;
390  }
391 
392  //Leave interrupt service routine
393  osExitIsr(flag);
394 }
395 
396 
397 /**
398  * @brief MCF5225x Ethernet MAC event handler
399  * @param[in] interface Underlying network interface
400  **/
401 
403 {
404  error_t error;
405  uint32_t status;
406 
407  //Read interrupt event register
408  status = MCF_FEC_EIR;
409 
410  //Packet received?
411  if(status & (MCF_FEC_EIR_RXF | MCF_FEC_EIR_RXB))
412  {
413  //Clear RXF and RXB interrupt flag
414  MCF_FEC_EIR = MCF_FEC_EIR_RXF | MCF_FEC_EIR_RXB;
415 
416  //Process all pending packets
417  do
418  {
419  //Read incoming packet
420  error = mcf5225xEthReceivePacket(interface);
421 
422  //No more data in the receive buffer?
423  } while(error != ERROR_BUFFER_EMPTY);
424  }
425 
426  //System bus error?
427  if(status & MCF_FEC_EIR_EBERR)
428  {
429  //Clear EBERR interrupt flag
430  MCF_FEC_EIR = MCF_FEC_EIR_EBERR;
431 
432  //Disable Ethernet MAC
433  MCF_FEC_ECR &= ~MCF_FEC_ECR_ETHER_EN;
434  //Reset buffer descriptors
435  mcf5225xEthInitBufferDesc(interface);
436  //Resume normal operation
437  MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
438  //Instruct the DMA to poll the receive descriptor list
439  MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
440  }
441 
442  //Re-enable Ethernet MAC interrupts
443  MCF_FEC_EIMR = MCF_FEC_EIMR_TXF | MCF_FEC_EIMR_TXB |
444  MCF_FEC_EIMR_RXF | MCF_FEC_EIMR_RXB | MCF_FEC_EIMR_EBERR;
445 }
446 
447 
448 /**
449  * @brief Send a packet
450  * @param[in] interface Underlying network interface
451  * @param[in] buffer Multi-part buffer containing the data to send
452  * @param[in] offset Offset to the first data byte
453  * @return Error code
454  **/
455 
457  const NetBuffer *buffer, size_t offset)
458 {
459  size_t length;
460 
461  //Retrieve the length of the packet
462  length = netBufferGetLength(buffer) - offset;
463 
464  //Check the frame length
466  {
467  //The transmitter can accept another packet
468  osSetEvent(&interface->nicTxEvent);
469  //Report an error
470  return ERROR_INVALID_LENGTH;
471  }
472 
473  //Make sure the current buffer is available for writing
474  if(txBufferDesc[txBufferIndex].status & FEC_TX_BD_R)
475  return ERROR_FAILURE;
476 
477  //Copy user data to the transmit buffer
478  netBufferRead(FEC_ALIGN16(txBuffer[txBufferIndex]), buffer, offset, length);
479 
480  //Set frame length
481  txBufferDesc[txBufferIndex].length = length;
482 
483  //Check current index
484  if(txBufferIndex < (MCF5225X_ETH_TX_BUFFER_COUNT - 1))
485  {
486  //Give the ownership of the descriptor to the DMA engine
487  txBufferDesc[txBufferIndex].status = FEC_TX_BD_R |
489 
490  //Point to the next buffer
491  txBufferIndex++;
492  }
493  else
494  {
495  //Give the ownership of the descriptor to the DMA engine
496  txBufferDesc[txBufferIndex].status = FEC_TX_BD_R |
498 
499  //Wrap around
500  txBufferIndex = 0;
501  }
502 
503  //Instruct the DMA to poll the transmit descriptor list
504  MCF_FEC_TDAR = MCF_FEC_TDAR_X_DES_ACTIVE;
505 
506  //Check whether the next buffer is available for writing
507  if(!(txBufferDesc[txBufferIndex].status & FEC_TX_BD_R))
508  {
509  //The transmitter can accept another packet
510  osSetEvent(&interface->nicTxEvent);
511  }
512 
513  //Successful processing
514  return NO_ERROR;
515 }
516 
517 
518 /**
519  * @brief Receive a packet
520  * @param[in] interface Underlying network interface
521  * @return Error code
522  **/
523 
525 {
526  error_t error;
527  size_t n;
528 
529  //Make sure the current buffer is available for reading
530  if(!(rxBufferDesc[rxBufferIndex].status & FEC_RX_BD_E))
531  {
532  //The frame should not span multiple buffers
533  if(rxBufferDesc[rxBufferIndex].status & FEC_RX_BD_L)
534  {
535  //Check whether an error occurred
536  if(!(rxBufferDesc[rxBufferIndex].status & (FEC_RX_BD_LG |
538  {
539  //Retrieve the length of the frame
540  n = rxBufferDesc[rxBufferIndex].length;
541  //Limit the number of data to read
543 
544  //Pass the packet to the upper layer
545  nicProcessPacket(interface, FEC_ALIGN16(rxBuffer[rxBufferIndex]), n);
546 
547  //Valid packet received
548  error = NO_ERROR;
549  }
550  else
551  {
552  //The received packet contains an error
553  error = ERROR_INVALID_PACKET;
554  }
555  }
556  else
557  {
558  //The packet is not valid
559  error = ERROR_INVALID_PACKET;
560  }
561 
562  //Check current index
563  if(rxBufferIndex < (MCF5225X_ETH_RX_BUFFER_COUNT - 1))
564  {
565  //Give the ownership of the descriptor back to the DMA engine
566  rxBufferDesc[rxBufferIndex].status = FEC_RX_BD_E;
567  //Point to the next buffer
568  rxBufferIndex++;
569  }
570  else
571  {
572  //Give the ownership of the descriptor back to the DMA engine
573  rxBufferDesc[rxBufferIndex].status = FEC_RX_BD_E | FEC_RX_BD_W;
574  //Wrap around
575  rxBufferIndex = 0;
576  }
577 
578  //Instruct the DMA to poll the receive descriptor list
579  MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
580  }
581  else
582  {
583  //No more data in the receive buffer
584  error = ERROR_BUFFER_EMPTY;
585  }
586 
587  //Return status code
588  return error;
589 }
590 
591 
592 /**
593  * @brief Configure MAC address filtering
594  * @param[in] interface Underlying network interface
595  * @return Error code
596  **/
597 
599 {
600  uint_t i;
601  uint_t k;
602  uint32_t crc;
603  uint32_t unicastHashTable[2];
604  uint32_t multicastHashTable[2];
605  MacFilterEntry *entry;
606 
607  //Debug message
608  TRACE_DEBUG("Updating MCF5225x hash table...\r\n");
609 
610  //Clear hash table (unicast address filtering)
611  unicastHashTable[0] = 0;
612  unicastHashTable[1] = 0;
613 
614  //Clear hash table (multicast address filtering)
615  multicastHashTable[0] = 0;
616  multicastHashTable[1] = 0;
617 
618  //The MAC address filter contains the list of MAC addresses to accept
619  //when receiving an Ethernet frame
620  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
621  {
622  //Point to the current entry
623  entry = &interface->macAddrFilter[i];
624 
625  //Valid entry?
626  if(entry->refCount > 0)
627  {
628  //Compute CRC over the current MAC address
629  crc = mcf5225xEthCalcCrc(&entry->addr, sizeof(MacAddr));
630 
631  //The upper 6 bits in the CRC register are used to index the
632  //contents of the hash table
633  k = (crc >> 26) & 0x3F;
634 
635  //Multicast address?
636  if(macIsMulticastAddr(&entry->addr))
637  {
638  //Update the multicast hash table
639  multicastHashTable[k / 32] |= (1 << (k % 32));
640  }
641  else
642  {
643  //Update the unicast hash table
644  unicastHashTable[k / 32] |= (1 << (k % 32));
645  }
646  }
647  }
648 
649  //Write the hash table (unicast address filtering)
650  MCF_FEC_IALR = unicastHashTable[0];
651  MCF_FEC_IAUR = unicastHashTable[1];
652 
653  //Write the hash table (multicast address filtering)
654  MCF_FEC_GALR = multicastHashTable[0];
655  MCF_FEC_GAUR = multicastHashTable[1];
656 
657  //Debug message
658  TRACE_DEBUG(" IALR = %08" PRIX32 "\r\n", MCF_FEC_IALR);
659  TRACE_DEBUG(" IAUR = %08" PRIX32 "\r\n", MCF_FEC_IAUR);
660  TRACE_DEBUG(" GALR = %08" PRIX32 "\r\n", MCF_FEC_GALR);
661  TRACE_DEBUG(" GAUR = %08" PRIX32 "\r\n", MCF_FEC_GAUR);
662 
663  //Successful processing
664  return NO_ERROR;
665 }
666 
667 
668 /**
669  * @brief Adjust MAC configuration parameters for proper operation
670  * @param[in] interface Underlying network interface
671  * @return Error code
672  **/
673 
675 {
676  //Disable Ethernet MAC while modifying configuration registers
677  MCF_FEC_ECR &= ~MCF_FEC_ECR_ETHER_EN;
678 
679  //Half-duplex or full-duplex mode?
680  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
681  {
682  //Full-duplex mode
683  MCF_FEC_TCR |= MCF_FEC_TCR_FDEN;
684  //Receive path operates independently of transmit
685  MCF_FEC_RCR &= ~MCF_FEC_RCR_DRT;
686  }
687  else
688  {
689  //Half-duplex mode
690  MCF_FEC_TCR &= ~MCF_FEC_TCR_FDEN;
691  //Disable reception of frames while transmitting
692  MCF_FEC_RCR |= MCF_FEC_RCR_DRT;
693  }
694 
695  //Reset buffer descriptors
696  mcf5225xEthInitBufferDesc(interface);
697 
698  //Re-enable Ethernet MAC
699  MCF_FEC_ECR |= MCF_FEC_ECR_ETHER_EN;
700  //Instruct the DMA to poll the receive descriptor list
701  MCF_FEC_RDAR = MCF_FEC_RDAR_R_DES_ACTIVE;
702 
703  //Successful processing
704  return NO_ERROR;
705 }
706 
707 
708 /**
709  * @brief Write PHY register
710  * @param[in] phyAddr PHY address
711  * @param[in] regAddr Register address
712  * @param[in] data Register value
713  **/
714 
715 void mcf5225xEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
716 {
717  uint32_t value;
718 
719  //Set up a write operation
720  value = MCF_FEC_MMFR_ST(1) | MCF_FEC_MMFR_OP(1) | MCF_FEC_MMFR_TA(2);
721  //PHY address
722  value |= MCF_FEC_MMFR_PA(phyAddr);
723  //Register address
724  value |= MCF_FEC_MMFR_RA(regAddr);
725  //Register value
726  value |= MCF_FEC_MMFR_DATA(data);
727 
728  //Clear MII interrupt flag
729  MCF_FEC_EIR = MCF_FEC_EIR_MII;
730  //Start a write operation
731  MCF_FEC_MMFR = value;
732  //Wait for the write to complete
733  while(!(MCF_FEC_EIR & MCF_FEC_EIR_MII));
734 }
735 
736 
737 /**
738  * @brief Read PHY register
739  * @param[in] phyAddr PHY address
740  * @param[in] regAddr Register address
741  * @return Register value
742  **/
743 
744 uint16_t mcf5225xEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
745 {
746  uint32_t value;
747 
748  //Set up a read operation
749  value = MCF_FEC_MMFR_ST(1) | MCF_FEC_MMFR_OP(2) | MCF_FEC_MMFR_TA(2);
750  //PHY address
751  value |= MCF_FEC_MMFR_PA(phyAddr);
752  //Register address
753  value |= MCF_FEC_MMFR_RA(regAddr);
754 
755  //Clear MII interrupt flag
756  MCF_FEC_EIR = MCF_FEC_EIR_MII;
757  //Start a read operation
758  MCF_FEC_MMFR = value;
759  //Wait for the read to complete
760  while(!(MCF_FEC_EIR & MCF_FEC_EIR_MII));
761 
762  //Return PHY register contents
763  return MCF_FEC_MMFR;
764 }
765 
766 
767 /**
768  * @brief CRC calculation
769  * @param[in] data Pointer to the data over which to calculate the CRC
770  * @param[in] length Number of bytes to process
771  * @return Resulting CRC value
772  **/
773 
774 uint32_t mcf5225xEthCalcCrc(const void *data, size_t length)
775 {
776  uint_t i;
777  uint_t j;
778 
779  //Point to the data over which to calculate the CRC
780  const uint8_t *p = (uint8_t *) data;
781  //CRC preset value
782  uint32_t crc = 0xFFFFFFFF;
783 
784  //Loop through data
785  for(i = 0; i < length; i++)
786  {
787  //Update CRC value
788  crc ^= p[i];
789  //The message is processed bit by bit
790  for(j = 0; j < 8; j++)
791  {
792  if(crc & 0x00000001)
793  crc = (crc >> 1) ^ 0xEDB88320;
794  else
795  crc = crc >> 1;
796  }
797  }
798 
799  //Return CRC value
800  return crc;
801 }
#define FEC_RX_BD_NO
#define FEC_RX_BD_L
#define FEC_TX_BD_L
MacAddr addr
MAC address.
Definition: ethernet.h:210
#define MCF5225X_ETH_IRQ_LEVEL
error_t mcf5225xEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
TCP/IP stack core.
#define MCF5225X_ETH_IRQ_PRIORITY
void mcf5225xEthDisableIrq(NetInterface *interface)
Disable interrupts.
Debugging facilities.
uint8_t p
Definition: ndp.h:295
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
Generic error code.
Definition: error.h:43
#define FEC_RX_BD_W
#define macIsMulticastAddr(macAddr)
Definition: ethernet.h:98
#define txBuffer
void mcf5225xEthEnableIrq(NetInterface *interface)
Enable interrupts.
#define sleep(delay)
Definition: os_port.h:126
Transmit buffer descriptor.
#define FEC_RX_BD_CR
__declspec(interrupt)
Ethernet MAC interrupt.
#define FEC_ALIGN16(p)
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
#define FEC_RX_BD_OV
error_t mcf5225xEthInit(NetInterface *interface)
MCF5225x Ethernet MAC initialization.
uint16_t mcf5225xEthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
Receive buffer descriptor.
#define FEC_RX_BD_LG
Coldfire V2 MCF5225x Ethernet MAC controller.
#define MCF5225X_ETH_RX_BUFFER_SIZE
#define MCF5225X_ETH_TX_BUFFER_COUNT
const NicDriver mcf5225xEthDriver
MCF5225x Ethernet MAC driver.
#define FEC_TX_BD_W
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:670
void mcf5225xEthEventHandler(NetInterface *interface)
MCF5225x Ethernet MAC event handler.
NIC driver.
Definition: nic.h:161
error_t mcf5225xEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define FEC_RX_BD_TR
#define MCF5225X_ETH_TX_BUFFER_SIZE
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
#define rxBuffer
#define MCF5225X_ETH_RX_BUFFER_COUNT
OsEvent netEvent
Definition: net.c:72
void nicProcessPacket(NetInterface *interface, void *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:239
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:211
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
unsigned int uint_t
Definition: compiler_port.h:43
__start_packed struct @112 MacAddr
MAC address.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
void mcf5225xEthInitGpio(NetInterface *interface)
uint8_t value[]
Definition: dtls_misc.h:141
#define FEC_TX_BD_TC
#define FEC_TX_BD_R
#define osExitIsr(flag)
void mcf5225xEthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
error_t mcf5225xEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define osEnterIsr()
void mcf5225xEthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
#define FEC_RX_BD_E
uint32_t mcf5225xEthCalcCrc(const void *data, size_t length)
CRC calculation.
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
void mcf5225xEthTick(NetInterface *interface)
MCF5225x Ethernet MAC timer handler.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
error_t mcf5225xEthReceivePacket(NetInterface *interface)
Receive a packet.
MAC filter table entry.
Definition: ethernet.h:208
#define TRACE_DEBUG(...)
Definition: debug.h:98