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