rza2_eth2_driver.c
Go to the documentation of this file.
1 /**
2  * @file rza2_eth2_driver.c
3  * @brief RZ/A2 Ethernet MAC driver (ETHERC1 instance)
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 "iodefine.h"
36 #include "cpg_iobitmask.h"
37 #include "gpio_iobitmask.h"
38 #include "etherc_iobitmask.h"
39 #include "edmac_iobitmask.h"
40 #include "r_intc_lld_rza2m.h"
41 #include "core/net.h"
43 #include "debug.h"
44 
45 //Underlying network interface
46 static NetInterface *nicDriverInterface;
47 
48 //IAR EWARM compiler?
49 #if defined(__ICCARM__)
50 
51 //Transmit buffer
52 #pragma data_alignment = 32
53 #pragma location = RZA2_ETH2_RAM_SECTION
55 //Receive buffer
56 #pragma data_alignment = 32
57 #pragma location = RZA2_ETH2_RAM_SECTION
59 //Transmit DMA descriptors
60 #pragma data_alignment = 32
61 #pragma location = RZA2_ETH2_RAM_SECTION
63 //Receive DMA descriptors
64 #pragma data_alignment = 32
65 #pragma location = RZA2_ETH2_RAM_SECTION
67 
68 //ARM or GCC compiler?
69 #else
70 
71 //Transmit buffer
73  __attribute__((aligned(32), section(RZA2_ETH2_RAM_SECTION)));
74 //Receive buffer
76  __attribute__((aligned(32), section(RZA2_ETH2_RAM_SECTION)));
77 //Transmit DMA descriptors
79  __attribute__((aligned(32), section(RZA2_ETH2_RAM_SECTION)));
80 //Receive DMA descriptors
82  __attribute__((aligned(32), section(RZA2_ETH2_RAM_SECTION)));
83 
84 #endif
85 
86 //Current transmit descriptor
87 static uint_t txIndex;
88 //Current receive descriptor
89 static uint_t rxIndex;
90 
91 
92 /**
93  * @brief RZ/A2 Ethernet MAC driver (ETHERC1 instance)
94  **/
95 
97 {
99  ETH_MTU,
100  rza2Eth2Init,
101  rza2Eth2Tick,
110  TRUE,
111  TRUE,
112  TRUE,
113  TRUE
114 };
115 
116 
117 /**
118  * @brief RZ/A2 Ethernet MAC initialization
119  * @param[in] interface Underlying network interface
120  * @return Error code
121  **/
122 
124 {
125  error_t error;
126 
127  //Debug message
128  TRACE_INFO("Initializing RZ/A2 Ethernet MAC (ETHERC1)...\r\n");
129 
130  //Save underlying network interface
131  nicDriverInterface = interface;
132 
133  //Enable the circuits shared by the Ethernet controllers and DMA controllers
134  CPG.STBCR6.BYTE &= ~CPG_STBCR6_MSTP62;
135  //Enable channel 1 Ethernet controller and channel 1 DMA controller
136  CPG.STBCR6.BYTE &= ~CPG_STBCR6_MSTP64;
137 
138  //GPIO configuration
139  rza2Eth2InitGpio(interface);
140 
141  //Reset EDMAC1 module
142  EDMAC1.EDMR.LONG |= EDMAC_EDMR_SWR;
143  //Wait for the reset to complete
144  sleep(10);
145 
146  //Valid Ethernet PHY or switch driver?
147  if(interface->phyDriver != NULL)
148  {
149  //Ethernet PHY initialization
150  error = interface->phyDriver->init(interface);
151  }
152  else if(interface->switchDriver != NULL)
153  {
154  //Ethernet switch initialization
155  error = interface->switchDriver->init(interface);
156  }
157  else
158  {
159  //The interface is not properly configured
160  error = ERROR_FAILURE;
161  }
162 
163  //Any error to report?
164  if(error)
165  {
166  return error;
167  }
168 
169  //Initialize DMA descriptor lists
170  rza2Eth2InitDmaDesc(interface);
171 
172  //Maximum frame length that can be accepted
173  ETHERC1.RFLR.LONG = RZA2_ETH2_RX_BUFFER_SIZE;
174  //Set default inter packet gap (96-bit time)
175  ETHERC1.IPGR.LONG = 0x14;
176 
177  //Set the upper 32 bits of the MAC address
178  ETHERC1.MAHR.LONG = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
179  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
180 
181  //Set the lower 16 bits of the MAC address
182  ETHERC1.MALR.LONG = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
183 
184  //Select little endian mode and set descriptor length (16 bytes)
185  EDMAC1.EDMR.LONG = EDMAC_EDMR_DE | EDMAC_EDMR_DL_16;
186  //Use store and forward mode
187  EDMAC1.TFTR.LONG = 0;
188  //Set transmit FIFO size (2048 bytes) and receive FIFO size (4096 bytes)
189  EDMAC1.FDR.LONG = EDMAC_FDR_TFD_2048 | EDMAC_FDR_RFD_4096;
190  //Enable continuous reception of multiple frames
191  EDMAC1.RMCR.LONG = EDMAC_RMCR_RNR;
192  //Select write-back complete interrupt mode and enable transmit interrupts
193  EDMAC1.TRIMD.LONG = EDMAC_TRIMD_TIM | EDMAC_TRIMD_TIS;
194 
195  //Disable all ETHERC interrupts
196  ETHERC1.ECSIPR.LONG = 0;
197  //Enable the desired EDMAC interrupts
198  EDMAC1.EESIPR.LONG = EDMAC_EESIPR_TWBIP | EDMAC_EESIPR_FRIP;
199 
200  //Register interrupt handler
201  R_INTC_RegistIntFunc(INTC_ID_ETHER_EINT1, rza2Eth2IrqHandler);
202  //Configure interrupt priority
203  R_INTC_SetPriority(INTC_ID_ETHER_EINT1, RZA2_ETH2_IRQ_PRIORITY);
204 
205  //Enable transmission and reception
206  ETHERC1.ECMR.LONG |= ETHERC_ECMR_TE | ETHERC_ECMR_RE;
207 
208  //Instruct the DMA to poll the receive descriptor list
209  EDMAC1.EDRRR.LONG = EDMAC_EDRRR_RR;
210 
211  //Accept any packets from the upper layer
212  osSetEvent(&interface->nicTxEvent);
213 
214  //Successful initialization
215  return NO_ERROR;
216 }
217 
218 
219 /**
220  * @brief GPIO configuration
221  * @param[in] interface Underlying network interface
222  **/
223 
224 __weak_func void rza2Eth2InitGpio(NetInterface *interface)
225 {
226 //RZ/A2-EVK evaluation board?
227 #if defined(USE_RZA2_EVK)
228  //Unlock PFS registers
229  GPIO.PWPR.BIT.B0WI = 0;
230  GPIO.PWPR.BIT.PFSWE = 1;
231 
232  //Select RMII interface mode
233  GPIO.PFENET.BIT.PHYMODE1 = 0;
234 
235  //Configure RMII1_RXER (P3_1)
236  GPIO.P31PFS.BIT.PSEL = 7;
237  PORT3.PMR.BIT.PMR1 = 1;
238  PORT3.DSCR.BIT.DSCR1 = 1;
239 
240  //Configure RMII1_CRS_DV (P3_2)
241  GPIO.P32PFS.BIT.PSEL = 7;
242  PORT3.PMR.BIT.PMR2 = 1;
243  PORT3.DSCR.BIT.DSCR2 = 1;
244 
245  //Configure ET1_MDC (P3_3)
246  GPIO.P33PFS.BIT.PSEL = 1;
247  PORT3.PMR.BIT.PMR3 = 1;
248  PORT3.DSCR.BIT.DSCR3 = 1;
249 
250  //Configure ET1_MDIO (P3_4)
251  GPIO.P34PFS.BIT.PSEL = 1;
252  PORT3.PMR.BIT.PMR4 = 1;
253  PORT3.DSCR.BIT.DSCR4 = 1;
254 
255  //Configure RMII1_RXD1 (P3_5)
256  GPIO.P35PFS.BIT.PSEL = 7;
257  PORT3.PMR.BIT.PMR5 = 1;
258  PORT3.DSCR.BIT.DSCR5 = 1;
259 
260  //Configure RMII1_TXD_EN (PK_0)
261  GPIO.PK0PFS.BIT.PSEL = 7;
262  PORTK.PMR.BIT.PMR0 = 1;
263  PORTK.DSCR.BIT.DSCR0 = 1;
264 
265  //Configure RMII1_TXD0 (PK_1)
266  GPIO.PK1PFS.BIT.PSEL = 7;
267  PORTK.PMR.BIT.PMR1 = 1;
268  PORTK.DSCR.BIT.DSCR1 = 1;
269 
270  //Configure RMII1_TXD1 (PK_2)
271  GPIO.PK2PFS.BIT.PSEL = 7;
272  PORTK.PMR.BIT.PMR2 = 1;
273  PORTK.DSCR.BIT.DSCR2 = 1;
274 
275  //Configure REF50CK1 (PK_3)
276  GPIO.PK3PFS.BIT.PSEL = 7;
277  PORTK.PMR.BIT.PMR3 = 1;
278  PORTK.DSCR.BIT.DSCR3 = 1;
279 
280  //Configure RMII1_RXD0 (PK_4)
281  GPIO.PK4PFS.BIT.PSEL = 7;
282  PORTK.PMR.BIT.PMR4 = 1;
283  PORTK.DSCR.BIT.DSCR4 = 1;
284 
285  //Lock PFS registers
286  GPIO.PWPR.BIT.PFSWE = 0;
287  GPIO.PWPR.BIT.B0WI = 1;
288 
289 //M13-RZ/A2-EK evaluation board?
290 #elif defined(USE_M13_RZA2_EK)
291  //Unlock PFS registers
292  GPIO.PWPR.BIT.B0WI = 0;
293  GPIO.PWPR.BIT.PFSWE = 1;
294 
295  //Select RMII interface mode
296  GPIO.PFENET.BIT.PHYMODE1 = 0;
297 
298  //Configure RMII1_CRS_DV (P3_2)
299  GPIO.P32PFS.BIT.PSEL = 7;
300  PORT3.PMR.BIT.PMR2 = 1;
301  PORT3.DSCR.BIT.DSCR2 = 1;
302 
303  //Configure ET1_MDC (P3_3)
304  GPIO.P33PFS.BIT.PSEL = 1;
305  PORT3.PMR.BIT.PMR3 = 1;
306  PORT3.DSCR.BIT.DSCR3 = 1;
307 
308  //Configure ET1_MDIO (P3_4)
309  GPIO.P34PFS.BIT.PSEL = 1;
310  PORT3.PMR.BIT.PMR4 = 1;
311  PORT3.DSCR.BIT.DSCR4 = 1;
312 
313  //Configure RMII1_RXD1 (P3_5)
314  GPIO.P35PFS.BIT.PSEL = 7;
315  PORT3.PMR.BIT.PMR5 = 1;
316  PORT3.DSCR.BIT.DSCR5 = 1;
317 
318  //Configure RMII1_TXD_EN (PK_0)
319  GPIO.PK0PFS.BIT.PSEL = 7;
320  PORTK.PMR.BIT.PMR0 = 1;
321  PORTK.DSCR.BIT.DSCR0 = 1;
322 
323  //Configure RMII1_TXD0 (PK_1)
324  GPIO.PK1PFS.BIT.PSEL = 7;
325  PORTK.PMR.BIT.PMR1 = 1;
326  PORTK.DSCR.BIT.DSCR1 = 1;
327 
328  //Configure RMII1_TXD1 (PK_2)
329  GPIO.PK2PFS.BIT.PSEL = 7;
330  PORTK.PMR.BIT.PMR2 = 1;
331  PORTK.DSCR.BIT.DSCR2 = 1;
332 
333  //Configure REF50CK1 (PK_3)
334  GPIO.PK3PFS.BIT.PSEL = 7;
335  PORTK.PMR.BIT.PMR3 = 1;
336  PORTK.DSCR.BIT.DSCR3 = 1;
337 
338  //Configure RMII1_RXD0 (PK_4)
339  GPIO.PK4PFS.BIT.PSEL = 7;
340  PORTK.PMR.BIT.PMR4 = 1;
341  PORTK.DSCR.BIT.DSCR4 = 1;
342 
343  //Lock PFS registers
344  GPIO.PWPR.BIT.PFSWE = 0;
345  GPIO.PWPR.BIT.B0WI = 1;
346 #endif
347 }
348 
349 
350 /**
351  * @brief Initialize DMA descriptor lists
352  * @param[in] interface Underlying network interface
353  **/
354 
356 {
357  uint_t i;
358 
359  //Initialize TX descriptors
360  for(i = 0; i < RZA2_ETH2_TX_BUFFER_COUNT; i++)
361  {
362  //The descriptor is initially owned by the application
363  txDmaDesc[i].td0 = 0;
364  //Transmit buffer length
365  txDmaDesc[i].td1 = 0;
366  //Transmit buffer address
368  //Clear padding field
369  txDmaDesc[i].padding = 0;
370  }
371 
372  //Mark the last descriptor entry with the TDLE flag
373  txDmaDesc[i - 1].td0 |= EDMAC_TD0_TDLE;
374  //Initialize TX descriptor index
375  txIndex = 0;
376 
377  //Initialize RX descriptors
378  for(i = 0; i < RZA2_ETH2_RX_BUFFER_COUNT; i++)
379  {
380  //The descriptor is initially owned by the DMA
381  rxDmaDesc[i].rd0 = EDMAC_RD0_RACT;
382  //Receive buffer length
384  //Receive buffer address
386  //Clear padding field
387  rxDmaDesc[i].padding = 0;
388  }
389 
390  //Mark the last descriptor entry with the RDLE flag
391  rxDmaDesc[i - 1].rd0 |= EDMAC_RD0_RDLE;
392  //Initialize RX descriptor index
393  rxIndex = 0;
394 
395  //Start address of the TX descriptor list
396  EDMAC1.TDLAR.LONG = RZA2_ETH2_GET_PHYSICAL_ADDR(txDmaDesc);
397  //Start address of the RX descriptor list
398  EDMAC1.RDLAR.LONG = RZA2_ETH2_GET_PHYSICAL_ADDR(rxDmaDesc);
399 }
400 
401 
402 /**
403  * @brief RZ/A2 Ethernet MAC timer handler
404  *
405  * This routine is periodically called by the TCP/IP stack to handle periodic
406  * operations such as polling the link state
407  *
408  * @param[in] interface Underlying network interface
409  **/
410 
411 void rza2Eth2Tick(NetInterface *interface)
412 {
413  //Valid Ethernet PHY or switch driver?
414  if(interface->phyDriver != NULL)
415  {
416  //Handle periodic operations
417  interface->phyDriver->tick(interface);
418  }
419  else if(interface->switchDriver != NULL)
420  {
421  //Handle periodic operations
422  interface->switchDriver->tick(interface);
423  }
424  else
425  {
426  //Just for sanity
427  }
428 }
429 
430 
431 /**
432  * @brief Enable interrupts
433  * @param[in] interface Underlying network interface
434  **/
435 
437 {
438  //Enable Ethernet MAC interrupts
439  R_INTC_Enable(INTC_ID_ETHER_EINT1);
440 
441  //Valid Ethernet PHY or switch driver?
442  if(interface->phyDriver != NULL)
443  {
444  //Enable Ethernet PHY interrupts
445  interface->phyDriver->enableIrq(interface);
446  }
447  else if(interface->switchDriver != NULL)
448  {
449  //Enable Ethernet switch interrupts
450  interface->switchDriver->enableIrq(interface);
451  }
452  else
453  {
454  //Just for sanity
455  }
456 }
457 
458 
459 /**
460  * @brief Disable interrupts
461  * @param[in] interface Underlying network interface
462  **/
463 
465 {
466  //Disable Ethernet MAC interrupts
467  R_INTC_Disable(INTC_ID_ETHER_EINT1);
468 
469  //Valid Ethernet PHY or switch driver?
470  if(interface->phyDriver != NULL)
471  {
472  //Disable Ethernet PHY interrupts
473  interface->phyDriver->disableIrq(interface);
474  }
475  else if(interface->switchDriver != NULL)
476  {
477  //Disable Ethernet switch interrupts
478  interface->switchDriver->disableIrq(interface);
479  }
480  else
481  {
482  //Just for sanity
483  }
484 }
485 
486 
487 /**
488  * @brief RZ/A2 Ethernet MAC interrupt service routine
489  * @param[in] intSense Unused parameter
490  **/
491 
492 void rza2Eth2IrqHandler(uint32_t intSense)
493 {
494  bool_t flag;
495  uint32_t status;
496 
497  //Interrupt service routine prologue
498  osEnterIsr();
499 
500  //This flag will be set if a higher priority task must be woken
501  flag = FALSE;
502 
503  //Read interrupt status register
504  status = EDMAC1.EESR.LONG;
505 
506  //Packet transmitted?
507  if((status & EDMAC_EESR_TWB) != 0)
508  {
509  //Clear TWB interrupt flag
510  EDMAC1.EESR.LONG = EDMAC_EESR_TWB;
511 
512  //Check whether the TX buffer is available for writing
513  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
514  {
515  //Notify the TCP/IP stack that the transmitter is ready to send
516  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
517  }
518  }
519 
520  //Packet received?
521  if((status & EDMAC_EESR_FR) != 0)
522  {
523  //Clear FR interrupt flag
524  EDMAC1.EESR.LONG = EDMAC_EESR_FR;
525 
526  //Set event flag
527  nicDriverInterface->nicEvent = TRUE;
528  //Notify the TCP/IP stack of the event
529  flag |= osSetEventFromIsr(&netEvent);
530  }
531 
532  //Interrupt service routine epilogue
533  osExitIsr(flag);
534 }
535 
536 
537 /**
538  * @brief RZ/A2 Ethernet MAC event handler
539  * @param[in] interface Underlying network interface
540  **/
541 
543 {
544  error_t error;
545 
546  //Process all pending packets
547  do
548  {
549  //Read incoming packet
550  error = rza2Eth2ReceivePacket(interface);
551 
552  //No more data in the receive buffer?
553  } while(error != ERROR_BUFFER_EMPTY);
554 }
555 
556 
557 /**
558  * @brief Send a packet
559  * @param[in] interface Underlying network interface
560  * @param[in] buffer Multi-part buffer containing the data to send
561  * @param[in] offset Offset to the first data byte
562  * @param[in] ancillary Additional options passed to the stack along with
563  * the packet
564  * @return Error code
565  **/
566 
568  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
569 {
570  //Retrieve the length of the packet
571  size_t length = netBufferGetLength(buffer) - offset;
572 
573  //Check the frame length
575  {
576  //The transmitter can accept another packet
577  osSetEvent(&interface->nicTxEvent);
578  //Report an error
579  return ERROR_INVALID_LENGTH;
580  }
581 
582  //Make sure the current buffer is available for writing
583  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) != 0)
584  {
585  return ERROR_FAILURE;
586  }
587 
588  //Copy user data to the transmit buffer
589  netBufferRead(txBuffer[txIndex], buffer, offset, length);
590 
591  //Write the number of bytes to send
592  txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL;
593 
594  //Check current index
595  if(txIndex < (RZA2_ETH2_TX_BUFFER_COUNT - 1))
596  {
597  //Give the ownership of the descriptor to the DMA engine
598  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF |
600 
601  //Point to the next descriptor
602  txIndex++;
603  }
604  else
605  {
606  //Give the ownership of the descriptor to the DMA engine
607  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE |
609 
610  //Wrap around
611  txIndex = 0;
612  }
613 
614  //Instruct the DMA to poll the transmit descriptor list
615  EDMAC1.EDTRR.LONG = EDMAC_EDTRR_TR;
616 
617  //Check whether the next buffer is available for writing
618  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
619  {
620  //The transmitter can accept another packet
621  osSetEvent(&interface->nicTxEvent);
622  }
623 
624  //Successful write operation
625  return NO_ERROR;
626 }
627 
628 
629 /**
630  * @brief Receive a packet
631  * @param[in] interface Underlying network interface
632  * @return Error code
633  **/
634 
636 {
637  static uint32_t temp[RZA2_ETH2_RX_BUFFER_SIZE / 4];
638  error_t error;
639  size_t n;
640  NetRxAncillary ancillary;
641 
642  //Current buffer available for reading?
643  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT) == 0)
644  {
645  //SOF and EOF flags should be set
646  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) != 0 &&
647  (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF) != 0)
648  {
649  //Make sure no error occurred
650  if((rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF)) == 0)
651  {
652  //Retrieve the length of the frame
653  n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL;
654  //Limit the number of data to read
656 
657  //Copy data from the receive buffer
658  osMemcpy(temp, rxBuffer[rxIndex], n);
659 
660  //Additional options can be passed to the stack along with the packet
661  ancillary = NET_DEFAULT_RX_ANCILLARY;
662 
663  //Pass the packet to the upper layer
664  nicProcessPacket(interface, (uint8_t *) temp, n, &ancillary);
665 
666  //Valid packet received
667  error = NO_ERROR;
668  }
669  else
670  {
671  //The received packet contains an error
672  error = ERROR_INVALID_PACKET;
673  }
674  }
675  else
676  {
677  //The packet is not valid
678  error = ERROR_INVALID_PACKET;
679  }
680 
681  //Check current index
682  if(rxIndex < (RZA2_ETH2_RX_BUFFER_COUNT - 1))
683  {
684  //Give the ownership of the descriptor back to the DMA
685  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT;
686  //Point to the next descriptor
687  rxIndex++;
688  }
689  else
690  {
691  //Give the ownership of the descriptor back to the DMA
692  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE;
693  //Wrap around
694  rxIndex = 0;
695  }
696 
697  //Instruct the DMA to poll the receive descriptor list
698  EDMAC1.EDRRR.LONG = EDMAC_EDRRR_RR;
699  }
700  else
701  {
702  //No more data in the receive buffer
703  error = ERROR_BUFFER_EMPTY;
704  }
705 
706  //Return status code
707  return error;
708 }
709 
710 
711 /**
712  * @brief Configure MAC address filtering
713  * @param[in] interface Underlying network interface
714  * @return Error code
715  **/
716 
718 {
719  uint_t i;
720  bool_t acceptMulticast;
721 
722  //Debug message
723  TRACE_DEBUG("Updating MAC filter...\r\n");
724 
725  //Promiscuous mode?
726  if(interface->promiscuous)
727  {
728  //Accept all frames regardless of their destination address
729  ETHERC1.ECMR.LONG |= ETHERC_ECMR_PRM;
730  }
731  else
732  {
733  //Disable promiscuous mode
734  ETHERC1.ECMR.LONG &= ~ETHERC_ECMR_PRM;
735 
736  //Set the upper 32 bits of the MAC address
737  ETHERC1.MAHR.LONG = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
738  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
739 
740  //Set the lower 16 bits of the MAC address
741  ETHERC1.MALR.LONG = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
742 
743  //This flag will be set if multicast addresses should be accepted
744  acceptMulticast = FALSE;
745 
746  //The MAC address filter contains the list of MAC addresses to accept
747  //when receiving an Ethernet frame
748  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
749  {
750  //Valid entry?
751  if(interface->macAddrFilter[i].refCount > 0)
752  {
753  //Accept multicast addresses
754  acceptMulticast = TRUE;
755  //We are done
756  break;
757  }
758  }
759 
760  //Enable or disable the reception of multicast frames
761  if(acceptMulticast || interface->acceptAllMulticast)
762  {
763  EDMAC1.EESR.LONG |= EDMAC_EESR_RMAF;
764  }
765  else
766  {
767  EDMAC1.EESR.LONG &= ~EDMAC_EESR_RMAF;
768  }
769  }
770 
771  //Successful processing
772  return NO_ERROR;
773 }
774 
775 
776 /**
777  * @brief Adjust MAC configuration parameters for proper operation
778  * @param[in] interface Underlying network interface
779  * @return Error code
780  **/
781 
783 {
784  uint32_t mode;
785 
786  //Read ETHERC mode register
787  mode = ETHERC1.ECMR.LONG;
788 
789  //10BASE-T or 100BASE-TX operation mode?
790  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
791  {
792  mode |= ETHERC_ECMR_RTM;
793  }
794  else
795  {
796  mode &= ~ETHERC_ECMR_RTM;
797  }
798 
799  //Half-duplex or full-duplex mode?
800  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
801  {
802  mode |= ETHERC_ECMR_DM;
803  }
804  else
805  {
806  mode &= ~ETHERC_ECMR_DM;
807  }
808 
809  //Update ETHERC mode register
810  ETHERC1.ECMR.LONG = mode;
811 
812  //Successful processing
813  return NO_ERROR;
814 }
815 
816 
817 /**
818  * @brief Write PHY register
819  * @param[in] opcode Access type (2 bits)
820  * @param[in] phyAddr PHY address (5 bits)
821  * @param[in] regAddr Register address (5 bits)
822  * @param[in] data Register value
823  **/
824 
825 void rza2Eth2WritePhyReg(uint8_t opcode, uint8_t phyAddr,
826  uint8_t regAddr, uint16_t data)
827 {
828  //Synchronization pattern
830  //Start of frame
832  //Set up a write operation
834  //Write PHY address
835  rza2Eth2WriteSmi(phyAddr, 5);
836  //Write register address
838  //Turnaround
840  //Write register value
841  rza2Eth2WriteSmi(data, 16);
842  //Release MDIO
843  rza2Eth2ReadSmi(1);
844 }
845 
846 
847 /**
848  * @brief Read PHY register
849  * @param[in] opcode Access type (2 bits)
850  * @param[in] phyAddr PHY address (5 bits)
851  * @param[in] regAddr Register address (5 bits)
852  * @return Register value
853  **/
854 
855 uint16_t rza2Eth2ReadPhyReg(uint8_t opcode, uint8_t phyAddr,
856  uint8_t regAddr)
857 {
858  uint16_t data;
859 
860  //Synchronization pattern
862  //Start of frame
864  //Set up a read operation
866  //Write PHY address
867  rza2Eth2WriteSmi(phyAddr, 5);
868  //Write register address
870  //Turnaround to avoid contention
871  rza2Eth2ReadSmi(1);
872  //Read register value
873  data = rza2Eth2ReadSmi(16);
874  //Force the PHY to release the MDIO pin
875  rza2Eth2ReadSmi(1);
876 
877  //Return PHY register contents
878  return data;
879 }
880 
881 
882 /**
883  * @brief SMI write operation
884  * @param[in] data Raw data to be written
885  * @param[in] length Number of bits to be written
886  **/
887 
889 {
890  //Skip the most significant bits since they are meaningless
891  data <<= 32 - length;
892 
893  //Configure MDIO as an output
894  ETHERC1.PIR.LONG |= ETHERC_PIR_MMD;
895 
896  //Write the specified number of bits
897  while(length--)
898  {
899  //Write MDIO
900  if((data & 0x80000000) != 0)
901  {
902  ETHERC1.PIR.LONG |= ETHERC_PIR_MDO;
903  }
904  else
905  {
906  ETHERC1.PIR.LONG &= ~ETHERC_PIR_MDO;
907  }
908 
909  //Assert MDC
910  usleep(1);
911  ETHERC1.PIR.LONG |= ETHERC_PIR_MDC;
912  //Deassert MDC
913  usleep(1);
914  ETHERC1.PIR.LONG &= ~ETHERC_PIR_MDC;
915 
916  //Rotate data
917  data <<= 1;
918  }
919 }
920 
921 
922 /**
923  * @brief SMI read operation
924  * @param[in] length Number of bits to be read
925  * @return Data resulting from the MDIO read operation
926  **/
927 
929 {
930  uint32_t data = 0;
931 
932  //Configure MDIO as an input
933  ETHERC1.PIR.LONG &= ~ETHERC_PIR_MMD;
934 
935  //Read the specified number of bits
936  while(length--)
937  {
938  //Rotate data
939  data <<= 1;
940 
941  //Assert MDC
942  ETHERC1.PIR.LONG |= ETHERC_PIR_MDC;
943  usleep(1);
944  //Deassert MDC
945  ETHERC1.PIR.LONG &= ~ETHERC_PIR_MDC;
946  usleep(1);
947 
948  //Check MDIO state
949  if((ETHERC1.PIR.LONG & ETHERC_PIR_MDI) != 0)
950  {
951  data |= 0x01;
952  }
953  }
954 
955  //Return the received data
956  return data;
957 }
#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 osMemcpy(dest, src, length)
Definition: os_port.h:141
#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 osEnterIsr()
#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_RMAF
#define EDMAC_EESR_FR
#define EDMAC_FDR_RFD_4096
#define EDMAC_EDMR_DL_16
#define EDMAC_FDR_TFD_2048
error_t rza2Eth2ReceivePacket(NetInterface *interface)
Receive a packet.
error_t rza2Eth2Init(NetInterface *interface)
RZ/A2 Ethernet MAC initialization.
void rza2Eth2WritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
error_t rza2Eth2UpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
void rza2Eth2WriteSmi(uint32_t data, uint_t length)
SMI write operation.
uint32_t rza2Eth2ReadSmi(uint_t length)
SMI read operation.
error_t rza2Eth2UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
uint16_t rza2Eth2ReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
void rza2Eth2Tick(NetInterface *interface)
RZ/A2 Ethernet MAC timer handler.
void rza2Eth2EnableIrq(NetInterface *interface)
Enable interrupts.
__weak_func void rza2Eth2InitGpio(NetInterface *interface)
GPIO configuration.
void rza2Eth2DisableIrq(NetInterface *interface)
Disable interrupts.
void rza2Eth2EventHandler(NetInterface *interface)
RZ/A2 Ethernet MAC event handler.
void rza2Eth2IrqHandler(uint32_t intSense)
RZ/A2 Ethernet MAC interrupt service routine.
error_t rza2Eth2SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
void rza2Eth2InitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
const NicDriver rza2Eth2Driver
RZ/A2 Ethernet MAC driver (ETHERC1 instance)
RZ/A2 Ethernet MAC driver (ETHERC1 instance)
#define RZA2_ETH2_IRQ_PRIORITY
#define RZA2_ETH2_RX_BUFFER_SIZE
#define RZA2_ETH2_TX_BUFFER_SIZE
#define RZA2_ETH2_TX_BUFFER_COUNT
#define RZA2_ETH2_RX_BUFFER_COUNT
#define RZA2_ETH2_GET_PHYSICAL_ADDR(addr)
#define RZA2_ETH2_RAM_SECTION
#define ETHERC_ECMR_DM
#define EDMAC_TRIMD_TIS
#define ETHERC_PIR_MMD
#define ETHERC_ECMR_TE
#define EDMAC_EDTRR_TR
#define ETHERC_ECMR_RTM
#define ETHERC_PIR_MDI
#define EDMAC_RMCR_RNR
#define EDMAC_EDMR_SWR
#define EDMAC_EDMR_DE
#define EDMAC_EDRRR_RR
#define ETHERC_PIR_MDO
#define ETHERC_PIR_MDC
#define EDMAC_EESIPR_FRIP
#define EDMAC_TRIMD_TIM
#define ETHERC_ECMR_RE
#define ETHERC_ECMR_PRM
#define EDMAC_EESIPR_TWBIP
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