rx63n_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file rx63n_eth_driver.c
3  * @brief Renesas RX63N 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.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include <iorx63n.h>
36 #include <intrinsics.h>
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //IAR EWRX compiler?
45 #if defined(__ICCRX__)
46 
47 //Transmit buffer
48 #pragma data_alignment = 32
50 //Receive buffer
51 #pragma data_alignment = 32
53 //Transmit DMA descriptors
54 #pragma data_alignment = 32
56 //Receive DMA descriptors
57 #pragma data_alignment = 32
59 
60 //GCC compiler?
61 #else
62 
63 //Transmit buffer
65  __attribute__((aligned(32)));
66 //Receive buffer
68  __attribute__((aligned(32)));
69 //Transmit DMA descriptors
71  __attribute__((aligned(32)));
72 //Receive DMA descriptors
74  __attribute__((aligned(32)));
75 
76 #endif
77 
78 //Current transmit descriptor
79 static uint_t txIndex;
80 //Current receive descriptor
81 static uint_t rxIndex;
82 
83 
84 /**
85  * @brief RX63N Ethernet MAC driver
86  **/
87 
89 {
91  ETH_MTU,
102  TRUE,
103  TRUE,
104  TRUE,
105  TRUE
106 };
107 
108 
109 /**
110  * @brief RX63N Ethernet MAC initialization
111  * @param[in] interface Underlying network interface
112  * @return Error code
113  **/
114 
116 {
117  error_t error;
118 
119  //Debug message
120  TRACE_INFO("Initializing RX63N Ethernet MAC...\r\n");
121 
122  //Save underlying network interface
123  nicDriverInterface = interface;
124 
125  //Disable protection
126  SYSTEM.PRCR.WORD = 0xA50B;
127  //Cancel EDMAC module stop state
128  MSTP(EDMAC) = 0;
129  //Enable protection
130  SYSTEM.PRCR.WORD = 0xA500;
131 
132  //GPIO configuration
133  rx63nEthInitGpio(interface);
134 
135  //Reset EDMAC module
136  EDMAC.EDMR.BIT.SWR = 1;
137  //Wait for the reset to complete
138  sleep(10);
139 
140  //Valid Ethernet PHY or switch driver?
141  if(interface->phyDriver != NULL)
142  {
143  //Ethernet PHY initialization
144  error = interface->phyDriver->init(interface);
145  }
146  else if(interface->switchDriver != NULL)
147  {
148  //Ethernet switch initialization
149  error = interface->switchDriver->init(interface);
150  }
151  else
152  {
153  //The interface is not properly configured
154  error = ERROR_FAILURE;
155  }
156 
157  //Any error to report?
158  if(error)
159  {
160  return error;
161  }
162 
163  //Initialize DMA descriptor lists
164  rx63nEthInitDmaDesc(interface);
165 
166  //Maximum frame length that can be accepted
167  ETHERC.RFLR.LONG = RX63N_ETH_RX_BUFFER_SIZE;
168  //Set default inter packet gap (96-bit time)
169  ETHERC.IPGR.LONG = 0x14;
170 
171  //Set the upper 32 bits of the MAC address
172  ETHERC.MAHR = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
173  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
174 
175  //Set the lower 16 bits of the MAC address
176  ETHERC.MALR.BIT.MA = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
177 
178  //Set descriptor length (16 bytes)
179  EDMAC.EDMR.BIT.DL = 0;
180 
181 #ifdef _CPU_BIG_ENDIAN
182  //Select big endian mode
183  EDMAC.EDMR.BIT.DE = 0;
184 #else
185  //Select little endian mode
186  EDMAC.EDMR.BIT.DE = 1;
187 #endif
188 
189  //Use store and forward mode
190  EDMAC.TFTR.BIT.TFT = 0;
191 
192  //Set transmit FIFO size (2048 bytes)
193  EDMAC.FDR.BIT.TFD = 7;
194  //Set receive FIFO size (2048 bytes)
195  EDMAC.FDR.BIT.RFD = 7;
196 
197  //Enable continuous reception of multiple frames
198  EDMAC.RMCR.BIT.RNR = 1;
199 
200  //Accept transmit interrupt notifications
201  EDMAC.TRIMD.BIT.TIM = 0;
202  EDMAC.TRIMD.BIT.TIS = 1;
203 
204  //Disable all EDMAC interrupts
205  EDMAC.EESIPR.LONG = 0;
206  //Enable only the desired EDMAC interrupts
207  EDMAC.EESIPR.BIT.TWBIP = 1;
208  EDMAC.EESIPR.BIT.FRIP = 1;
209 
210  //Configure EDMAC interrupt priority
211  IPR(ETHER, EINT) = RX63N_ETH_IRQ_PRIORITY;
212 
213  //Enable transmission and reception
214  ETHERC.ECMR.BIT.TE = 1;
215  ETHERC.ECMR.BIT.RE = 1;
216 
217  //Instruct the DMA to poll the receive descriptor list
218  EDMAC.EDRRR.BIT.RR = 1;
219 
220  //Accept any packets from the upper layer
221  osSetEvent(&interface->nicTxEvent);
222 
223  //Successful initialization
224  return NO_ERROR;
225 }
226 
227 
228 /**
229  * @brief GPIO configuration
230  * @param[in] interface Underlying network interface
231  **/
232 
233 __weak_func void rx63nEthInitGpio(NetInterface *interface)
234 {
235 #if defined(USE_RDK_RX63N)
236  //Unlock MPC registers
237  MPC.PWPR.BIT.B0WI = 0;
238  MPC.PWPR.BIT.PFSWE = 1;
239 
240  //Select RMII interface mode
241  MPC.PFENET.BIT.PHYMODE = 0;
242 
243  //Configure ET_MDIO (PA3)
244  PORTA.PMR.BIT.B3 = 1;
245  MPC.PA3PFS.BYTE = 0x11;
246 
247  //Configure ET_MDC (PA4)
248  PORTA.PMR.BIT.B4 = 1;
249  MPC.PA4PFS.BYTE = 0x11;
250 
251  //Configure ET_LINKSTA (PA5)
252  PORTA.PMR.BIT.B5 = 1;
253  MPC.PA5PFS.BYTE = 0x11;
254 
255  //Configure RMII_RXD1 (PB0)
256  PORTB.PMR.BIT.B0 = 1;
257  MPC.PB0PFS.BYTE = 0x12;
258 
259  //Configure RMII_RXD0 (PB1)
260  PORTB.PMR.BIT.B1 = 1;
261  MPC.PB1PFS.BYTE = 0x12;
262 
263  //Configure REF50CK (PB2)
264  PORTB.PMR.BIT.B2 = 1;
265  MPC.PB2PFS.BYTE = 0x12;
266 
267  //Configure RMII_RX_ER (PB3)
268  PORTB.PMR.BIT.B3 = 1;
269  MPC.PB3PFS.BYTE = 0x12;
270 
271  //Configure RMII_TXD_EN (PB4)
272  PORTB.PMR.BIT.B4 = 1;
273  MPC.PB4PFS.BYTE = 0x12;
274 
275  //Configure RMII_TXD0 (PB5)
276  PORTB.PMR.BIT.B5 = 1;
277  MPC.PB5PFS.BYTE = 0x12;
278 
279  //Configure RMII_TXD1 (PB6)
280  PORTB.PMR.BIT.B6 = 1;
281  MPC.PB6PFS.BYTE = 0x12;
282 
283  //Configure RMII_CRS_DV (PB7)
284  PORTB.PMR.BIT.B7 = 1;
285  MPC.PB7PFS.BYTE = 0x12;
286 
287  //Lock MPC registers
288  MPC.PWPR.BIT.PFSWE = 0;
289  MPC.PWPR.BIT.B0WI = 0;
290 
291 #elif defined(USE_RSK_RX63N) || defined(USE_RSK_RX63N_256K)
292  //Unlock MPC registers
293  MPC.PWPR.BIT.B0WI = 0;
294  MPC.PWPR.BIT.PFSWE = 1;
295 
296  //Select MII interface mode
297  MPC.PFENET.BIT.PHYMODE = 1;
298 
299  //Configure ET_MDIO (P71)
300  PORT7.PMR.BIT.B1 = 1;
301  MPC.P71PFS.BYTE = 0x11;
302 
303  //Configure ET_MDC (P72)
304  PORT7.PMR.BIT.B2 = 1;
305  MPC.P72PFS.BYTE = 0x11;
306 
307  //Configure ET_ERXD1 (P74)
308  PORT7.PMR.BIT.B4 = 1;
309  MPC.P74PFS.BYTE = 0x11;
310 
311  //Configure ET_ERXD0 P75)
312  PORT7.PMR.BIT.B5 = 1;
313  MPC.P75PFS.BYTE = 0x11;
314 
315  //Configure ET_RX_CLK (P76)
316  PORT7.PMR.BIT.B6 = 1;
317  MPC.P76PFS.BYTE = 0x11;
318 
319  //Configure ET_RX_ER (P77)
320  PORT7.PMR.BIT.B7 = 1;
321  MPC.P77PFS.BYTE = 0x11;
322 
323  //Configure ET_TX_EN (P80)
324  PORT8.PMR.BIT.B0 = 1;
325  MPC.P80PFS.BYTE = 0x11;
326 
327  //Configure ET_ETXD0 (P81)
328  PORT8.PMR.BIT.B1 = 1;
329  MPC.P81PFS.BYTE = 0x11;
330 
331  //Configure ET_ETXD1 (P82)
332  PORT8.PMR.BIT.B2 = 1;
333  MPC.P82PFS.BYTE = 0x11;
334 
335  //Configure ET_CRS (P83)
336  PORT8.PMR.BIT.B3 = 1;
337  MPC.P83PFS.BYTE = 0x11;
338 
339  //Configure ET_ERXD3 (PC0)
340  PORTC.PMR.BIT.B0 = 1;
341  MPC.PC0PFS.BYTE = 0x11;
342 
343  //Configure ET_ERXD2 (PC1)
344  PORTC.PMR.BIT.B1 = 1;
345  MPC.PC1PFS.BYTE = 0x11;
346 
347  //Configure ET_RX_DV (PC2)
348  PORTC.PMR.BIT.B2 = 1;
349  MPC.PC2PFS.BYTE = 0x11;
350 
351  //Configure ET_TX_ER (PC3)
352  PORTC.PMR.BIT.B3 = 1;
353  MPC.PC3PFS.BYTE = 0x11;
354 
355  //Configure ET_TX_CLK (PC4)
356  PORTC.PMR.BIT.B4 = 1;
357  MPC.PC4PFS.BYTE = 0x11;
358 
359  //Configure ET_ETXD2 (PC5)
360  PORTC.PMR.BIT.B5 = 1;
361  MPC.PC5PFS.BYTE = 0x11;
362 
363  //Configure ET_ETXD3 (PC6)
364  PORTC.PMR.BIT.B6 = 1;
365  MPC.PC6PFS.BYTE = 0x11;
366 
367  //Configure ET_COL (PC7)
368  PORTC.PMR.BIT.B7 = 1;
369  MPC.PC7PFS.BYTE = 0x11;
370 
371  //Lock MPC registers
372  MPC.PWPR.BIT.PFSWE = 0;
373  MPC.PWPR.BIT.B0WI = 0;
374 #endif
375 }
376 
377 
378 /**
379  * @brief Initialize DMA descriptor lists
380  * @param[in] interface Underlying network interface
381  **/
382 
384 {
385  uint_t i;
386 
387  //Initialize TX descriptors
388  for(i = 0; i < RX63N_ETH_TX_BUFFER_COUNT; i++)
389  {
390  //The descriptor is initially owned by the application
391  txDmaDesc[i].td0 = 0;
392  //Transmit buffer length
393  txDmaDesc[i].td1 = 0;
394  //Transmit buffer address
395  txDmaDesc[i].td2 = (uint32_t) txBuffer[i];
396  //Clear padding field
397  txDmaDesc[i].padding = 0;
398  }
399 
400  //Mark the last descriptor entry with the TDLE flag
401  txDmaDesc[i - 1].td0 |= EDMAC_TD0_TDLE;
402  //Initialize TX descriptor index
403  txIndex = 0;
404 
405  //Initialize RX descriptors
406  for(i = 0; i < RX63N_ETH_RX_BUFFER_COUNT; i++)
407  {
408  //The descriptor is initially owned by the DMA
409  rxDmaDesc[i].rd0 = EDMAC_RD0_RACT;
410  //Receive buffer length
412  //Receive buffer address
413  rxDmaDesc[i].rd2 = (uint32_t) rxBuffer[i];
414  //Clear padding field
415  rxDmaDesc[i].padding = 0;
416  }
417 
418  //Mark the last descriptor entry with the RDLE flag
419  rxDmaDesc[i - 1].rd0 |= EDMAC_RD0_RDLE;
420  //Initialize RX descriptor index
421  rxIndex = 0;
422 
423  //Start address of the TX descriptor list
424  EDMAC.TDLAR = txDmaDesc;
425  //Start address of the RX descriptor list
426  EDMAC.RDLAR = rxDmaDesc;
427 }
428 
429 
430 /**
431  * @brief RX63N Ethernet MAC timer handler
432  *
433  * This routine is periodically called by the TCP/IP stack to handle periodic
434  * operations such as polling the link state
435  *
436  * @param[in] interface Underlying network interface
437  **/
438 
439 void rx63nEthTick(NetInterface *interface)
440 {
441  //Valid Ethernet PHY or switch driver?
442  if(interface->phyDriver != NULL)
443  {
444  //Handle periodic operations
445  interface->phyDriver->tick(interface);
446  }
447  else if(interface->switchDriver != NULL)
448  {
449  //Handle periodic operations
450  interface->switchDriver->tick(interface);
451  }
452  else
453  {
454  //Just for sanity
455  }
456 }
457 
458 
459 /**
460  * @brief Enable interrupts
461  * @param[in] interface Underlying network interface
462  **/
463 
465 {
466  //Enable Ethernet MAC interrupts
467  IEN(ETHER, EINT) = 1;
468 
469  //Valid Ethernet PHY or switch driver?
470  if(interface->phyDriver != NULL)
471  {
472  //Enable Ethernet PHY interrupts
473  interface->phyDriver->enableIrq(interface);
474  }
475  else if(interface->switchDriver != NULL)
476  {
477  //Enable Ethernet switch interrupts
478  interface->switchDriver->enableIrq(interface);
479  }
480  else
481  {
482  //Just for sanity
483  }
484 }
485 
486 
487 /**
488  * @brief Disable interrupts
489  * @param[in] interface Underlying network interface
490  **/
491 
493 {
494  //Disable Ethernet MAC interrupts
495  IEN(ETHER, EINT) = 0;
496 
497  //Valid Ethernet PHY or switch driver?
498  if(interface->phyDriver != NULL)
499  {
500  //Disable Ethernet PHY interrupts
501  interface->phyDriver->disableIrq(interface);
502  }
503  else if(interface->switchDriver != NULL)
504  {
505  //Disable Ethernet switch interrupts
506  interface->switchDriver->disableIrq(interface);
507  }
508  else
509  {
510  //Just for sanity
511  }
512 }
513 
514 
515 /**
516  * @brief RX63N Ethernet MAC interrupt service routine
517  **/
518 
519 #pragma vector = VECT_ETHER_EINT
520 __interrupt void rx63nEthIrqHandler(void)
521 {
522  bool_t flag;
523  uint32_t status;
524 
525  //Allow nested interrupts
526  __enable_interrupt();
527 
528  //This flag will be set if a higher priority task must be woken
529  flag = FALSE;
530 
531  //Read interrupt status register
532  status = EDMAC.EESR.LONG;
533 
534  //Packet transmitted?
535  if((status & EDMAC_EESR_TWB) != 0)
536  {
537  //Clear TWB interrupt flag
538  EDMAC.EESR.LONG = EDMAC_EESR_TWB;
539 
540  //Check whether the TX buffer is available for writing
541  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
542  {
543  //Notify the TCP/IP stack that the transmitter is ready to send
544  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
545  }
546  }
547 
548  //Packet received?
549  if((status & EDMAC_EESR_FR) != 0)
550  {
551  //Disable FR interrupts
552  EDMAC.EESIPR.BIT.FRIP = 0;
553 
554  //Set event flag
555  nicDriverInterface->nicEvent = TRUE;
556  //Notify the TCP/IP stack of the event
557  flag |= osSetEventFromIsr(&netEvent);
558  }
559 
560  //Interrupt service routine epilogue
561  osExitIsr(flag);
562 }
563 
564 
565 /**
566  * @brief RX63N Ethernet MAC event handler
567  * @param[in] interface Underlying network interface
568  **/
569 
571 {
572  error_t error;
573 
574  //Packet received?
575  if((EDMAC.EESR.LONG & EDMAC_EESR_FR) != 0)
576  {
577  //Clear FR interrupt flag
578  EDMAC.EESR.LONG = EDMAC_EESR_FR;
579 
580  //Process all pending packets
581  do
582  {
583  //Read incoming packet
584  error = rx63nEthReceivePacket(interface);
585 
586  //No more data in the receive buffer?
587  } while(error != ERROR_BUFFER_EMPTY);
588  }
589 
590  //Re-enable EDMAC interrupts
591  EDMAC.EESIPR.BIT.TWBIP = 1;
592  EDMAC.EESIPR.BIT.FRIP = 1;
593 }
594 
595 
596 /**
597  * @brief Send a packet
598  * @param[in] interface Underlying network interface
599  * @param[in] buffer Multi-part buffer containing the data to send
600  * @param[in] offset Offset to the first data byte
601  * @param[in] ancillary Additional options passed to the stack along with
602  * the packet
603  * @return Error code
604  **/
605 
607  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
608 {
609  //Retrieve the length of the packet
610  size_t length = netBufferGetLength(buffer) - offset;
611 
612  //Check the frame length
614  {
615  //The transmitter can accept another packet
616  osSetEvent(&interface->nicTxEvent);
617  //Report an error
618  return ERROR_INVALID_LENGTH;
619  }
620 
621  //Make sure the current buffer is available for writing
622  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) != 0)
623  {
624  return ERROR_FAILURE;
625  }
626 
627  //Copy user data to the transmit buffer
628  netBufferRead(txBuffer[txIndex], buffer, offset, length);
629 
630  //Write the number of bytes to send
631  txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL;
632 
633  //Check current index
634  if(txIndex < (RX63N_ETH_TX_BUFFER_COUNT - 1))
635  {
636  //Give the ownership of the descriptor to the DMA engine
637  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF |
639 
640  //Point to the next descriptor
641  txIndex++;
642  }
643  else
644  {
645  //Give the ownership of the descriptor to the DMA engine
646  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE |
648 
649  //Wrap around
650  txIndex = 0;
651  }
652 
653  //Instruct the DMA to poll the transmit descriptor list
654  EDMAC.EDTRR.BIT.TR = 1;
655 
656  //Check whether the next buffer is available for writing
657  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
658  {
659  //The transmitter can accept another packet
660  osSetEvent(&interface->nicTxEvent);
661  }
662 
663  //Successful write operation
664  return NO_ERROR;
665 }
666 
667 
668 /**
669  * @brief Receive a packet
670  * @param[in] interface Underlying network interface
671  * @return Error code
672  **/
673 
675 {
676  error_t error;
677  size_t n;
678  NetRxAncillary ancillary;
679 
680  //Current buffer available for reading?
681  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT) == 0)
682  {
683  //SOF and EOF flags should be set
684  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) != 0 &&
685  (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF) != 0)
686  {
687  //Make sure no error occurred
688  if((rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF)) == 0)
689  {
690  //Retrieve the length of the frame
691  n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL;
692  //Limit the number of data to read
694 
695  //Additional options can be passed to the stack along with the packet
696  ancillary = NET_DEFAULT_RX_ANCILLARY;
697 
698  //Pass the packet to the upper layer
699  nicProcessPacket(interface, rxBuffer[rxIndex], n, &ancillary);
700 
701  //Valid packet received
702  error = NO_ERROR;
703  }
704  else
705  {
706  //The received packet contains an error
707  error = ERROR_INVALID_PACKET;
708  }
709  }
710  else
711  {
712  //The packet is not valid
713  error = ERROR_INVALID_PACKET;
714  }
715 
716  //Check current index
717  if(rxIndex < (RX63N_ETH_RX_BUFFER_COUNT - 1))
718  {
719  //Give the ownership of the descriptor back to the DMA
720  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT;
721  //Point to the next descriptor
722  rxIndex++;
723  }
724  else
725  {
726  //Give the ownership of the descriptor back to the DMA
727  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE;
728  //Wrap around
729  rxIndex = 0;
730  }
731 
732  //Instruct the DMA to poll the receive descriptor list
733  EDMAC.EDRRR.BIT.RR = 1;
734  }
735  else
736  {
737  //No more data in the receive buffer
738  error = ERROR_BUFFER_EMPTY;
739  }
740 
741  //Return status code
742  return error;
743 }
744 
745 
746 /**
747  * @brief Configure MAC address filtering
748  * @param[in] interface Underlying network interface
749  * @return Error code
750  **/
751 
753 {
754  uint_t i;
755  bool_t acceptMulticast;
756 
757  //Debug message
758  TRACE_DEBUG("Updating MAC filter...\r\n");
759 
760  //Set the upper 32 bits of the MAC address
761  ETHERC.MAHR = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
762  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
763 
764  //Set the lower 16 bits of the MAC address
765  ETHERC.MALR.BIT.MA = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
766 
767  //This flag will be set if multicast addresses should be accepted
768  acceptMulticast = FALSE;
769 
770  //The MAC address filter contains the list of MAC addresses to accept
771  //when receiving an Ethernet frame
772  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
773  {
774  //Valid entry?
775  if(interface->macAddrFilter[i].refCount > 0)
776  {
777  //Accept multicast addresses
778  acceptMulticast = TRUE;
779  //We are done
780  break;
781  }
782  }
783 
784  //Enable or disable the reception of multicast frames
785  if(acceptMulticast)
786  {
787  EDMAC.EESR.BIT.RMAF = 1;
788  }
789  else
790  {
791  EDMAC.EESR.BIT.RMAF = 0;
792  }
793 
794  //Successful processing
795  return NO_ERROR;
796 }
797 
798 
799 /**
800  * @brief Adjust MAC configuration parameters for proper operation
801  * @param[in] interface Underlying network interface
802  * @return Error code
803  **/
804 
806 {
807  //10BASE-T or 100BASE-TX operation mode?
808  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
809  {
810  ETHERC.ECMR.BIT.RTM = 1;
811  }
812  else
813  {
814  ETHERC.ECMR.BIT.RTM = 0;
815  }
816 
817  //Half-duplex or full-duplex mode?
818  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
819  {
820  ETHERC.ECMR.BIT.DM = 1;
821  }
822  else
823  {
824  ETHERC.ECMR.BIT.DM = 0;
825  }
826 
827  //Successful processing
828  return NO_ERROR;
829 }
830 
831 
832 /**
833  * @brief Write 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  * @param[in] data Register value
838  **/
839 
840 void rx63nEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
841  uint8_t regAddr, uint16_t data)
842 {
843  //Synchronization pattern
845  //Start of frame
847  //Set up a write operation
849  //Write PHY address
850  rx63nEthWriteSmi(phyAddr, 5);
851  //Write register address
853  //Turnaround
855  //Write register value
856  rx63nEthWriteSmi(data, 16);
857  //Release MDIO
858  rx63nEthReadSmi(1);
859 }
860 
861 
862 /**
863  * @brief Read PHY register
864  * @param[in] opcode Access type (2 bits)
865  * @param[in] phyAddr PHY address (5 bits)
866  * @param[in] regAddr Register address (5 bits)
867  * @return Register value
868  **/
869 
870 uint16_t rx63nEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
871  uint8_t regAddr)
872 {
873  uint16_t data;
874 
875  //Synchronization pattern
877  //Start of frame
879  //Set up a read operation
881  //Write PHY address
882  rx63nEthWriteSmi(phyAddr, 5);
883  //Write register address
885  //Turnaround to avoid contention
886  rx63nEthReadSmi(1);
887  //Read register value
888  data = rx63nEthReadSmi(16);
889  //Force the PHY to release the MDIO pin
890  rx63nEthReadSmi(1);
891 
892  //Return PHY register contents
893  return data;
894 }
895 
896 
897 /**
898  * @brief SMI write operation
899  * @param[in] data Raw data to be written
900  * @param[in] length Number of bits to be written
901  **/
902 
904 {
905  //Skip the most significant bits since they are meaningless
906  data <<= 32 - length;
907 
908  //Configure MDIO as an output
909  ETHERC.PIR.BIT.MMD = 1;
910 
911  //Write the specified number of bits
912  while(length--)
913  {
914  //Write MDIO
915  if((data & 0x80000000) != 0)
916  {
917  ETHERC.PIR.BIT.MDO = 1;
918  }
919  else
920  {
921  ETHERC.PIR.BIT.MDO = 0;
922  }
923 
924  //Assert MDC
925  usleep(1);
926  ETHERC.PIR.BIT.MDC = 1;
927  //Deassert MDC
928  usleep(1);
929  ETHERC.PIR.BIT.MDC = 0;
930 
931  //Rotate data
932  data <<= 1;
933  }
934 }
935 
936 
937 /**
938  * @brief SMI read operation
939  * @param[in] length Number of bits to be read
940  * @return Data resulting from the MDIO read operation
941  **/
942 
944 {
945  uint32_t data = 0;
946 
947  //Configure MDIO as an input
948  ETHERC.PIR.BIT.MMD = 0;
949 
950  //Read the specified number of bits
951  while(length--)
952  {
953  //Rotate data
954  data <<= 1;
955 
956  //Assert MDC
957  ETHERC.PIR.BIT.MDC = 1;
958  usleep(1);
959  //Deassert MDC
960  ETHERC.PIR.BIT.MDC = 0;
961  usleep(1);
962 
963  //Check MDIO state
964  if(ETHERC.PIR.BIT.MDI != 0)
965  {
966  data |= 0x01;
967  }
968  }
969 
970  //Return the received data
971  return data;
972 }
#define txDmaDesc
#define rxBuffer
#define txBuffer
#define rxDmaDesc
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
uint8_t opcode
Definition: dns_common.h:188
error_t
Error codes.
Definition: error.h:43
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PACKET
Definition: error.h:140
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define ETH_MTU
Definition: ethernet.h:116
uint8_t data[]
Definition: ethernet.h:222
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
uint16_t regAddr
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netEvent
Definition: net_legacy.h:196
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
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:674
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:101
#define NetRxAncillary
Definition: net_misc.h:40
#define NetTxAncillary
Definition: net_misc.h:36
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:391
#define SMI_SYNC
Definition: nic.h:63
#define SMI_START
Definition: nic.h:64
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define SMI_TA
Definition: nic.h:68
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define usleep(delay)
Definition: os_port.h:297
#define sleep(delay)
Definition: os_port.h:301
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define osExitIsr(flag)
#define EDMAC_TD1_TBL
#define EDMAC_RD0_RFS_MASK
#define EDMAC_RD0_RDLE
#define EDMAC_RD0_RFS_RMAF
#define EDMAC_RD1_RFL
#define EDMAC_TD0_TWBI
#define EDMAC_TD0_TACT
#define EDMAC_RD1_RBL
#define EDMAC_TD0_TDLE
#define EDMAC_TD0_TFP_EOF
#define EDMAC_RD0_RACT
#define EDMAC_RD0_RFP_EOF
#define EDMAC_RD0_RFP_SOF
#define EDMAC_TD0_TFP_SOF
#define EDMAC_EESR_TWB
#define EDMAC_EESR_FR
const NicDriver rx63nEthDriver
RX63N Ethernet MAC driver.
void rx63nEthEnableIrq(NetInterface *interface)
Enable interrupts.
error_t rx63nEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
uint32_t rx63nEthReadSmi(uint_t length)
SMI read operation.
__weak_func void rx63nEthInitGpio(NetInterface *interface)
GPIO configuration.
void rx63nEthEventHandler(NetInterface *interface)
RX63N Ethernet MAC event handler.
error_t rx63nEthInit(NetInterface *interface)
RX63N Ethernet MAC initialization.
void rx63nEthDisableIrq(NetInterface *interface)
Disable interrupts.
uint16_t rx63nEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
error_t rx63nEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
__interrupt void rx63nEthIrqHandler(void)
RX63N Ethernet MAC interrupt service routine.
error_t rx63nEthReceivePacket(NetInterface *interface)
Receive a packet.
void rx63nEthWriteSmi(uint32_t data, uint_t length)
SMI write operation.
error_t rx63nEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
void rx63nEthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
void rx63nEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
void rx63nEthTick(NetInterface *interface)
RX63N Ethernet MAC timer handler.
Renesas RX63N Ethernet MAC driver.
#define RX63N_ETH_TX_BUFFER_COUNT
#define RX63N_ETH_RX_BUFFER_COUNT
#define RX63N_ETH_IRQ_PRIORITY
#define RX63N_ETH_RX_BUFFER_SIZE
#define RX63N_ETH_TX_BUFFER_SIZE
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:283
Receive DMA descriptor.
Transmit DMA descriptor.
uint8_t length
Definition: tcp.h:368