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