rza2_eth1_driver.c
Go to the documentation of this file.
1 /**
2  * @file rza2_eth1_driver.c
3  * @brief RZ/A2 Ethernet MAC driver (ETHERC0 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_ETH1_RAM_SECTION
55 //Receive buffer
56 #pragma data_alignment = 32
57 #pragma location = RZA2_ETH1_RAM_SECTION
59 //Transmit DMA descriptors
60 #pragma data_alignment = 32
61 #pragma location = RZA2_ETH1_RAM_SECTION
63 //Receive DMA descriptors
64 #pragma data_alignment = 32
65 #pragma location = RZA2_ETH1_RAM_SECTION
67 
68 //ARM or GCC compiler?
69 #else
70 
71 //Transmit buffer
73  __attribute__((aligned(32), section(RZA2_ETH1_RAM_SECTION)));
74 //Receive buffer
76  __attribute__((aligned(32), section(RZA2_ETH1_RAM_SECTION)));
77 //Transmit DMA descriptors
79  __attribute__((aligned(32), section(RZA2_ETH1_RAM_SECTION)));
80 //Receive DMA descriptors
82  __attribute__((aligned(32), section(RZA2_ETH1_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 (ETHERC0 instance)
94  **/
95 
97 {
99  ETH_MTU,
100  rza2Eth1Init,
101  rza2Eth1Tick,
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 (ETHERC0)...\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 0 Ethernet controller and channel 0 DMA controller
136  CPG.STBCR6.BYTE &= ~CPG_STBCR6_MSTP65;
137 
138  //GPIO configuration
139  rza2Eth1InitGpio(interface);
140 
141  //Reset EDMAC0 module
142  EDMAC0.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  rza2Eth1InitDmaDesc(interface);
171 
172  //Maximum frame length that can be accepted
173  ETHERC0.RFLR.LONG = RZA2_ETH1_RX_BUFFER_SIZE;
174  //Set default inter packet gap (96-bit time)
175  ETHERC0.IPGR.LONG = 0x14;
176 
177  //Set the upper 32 bits of the MAC address
178  ETHERC0.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  ETHERC0.MALR.LONG = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
183 
184  //Select little endian mode and set descriptor length (16 bytes)
185  EDMAC0.EDMR.LONG = EDMAC_EDMR_DE | EDMAC_EDMR_DL_16;
186  //Use store and forward mode
187  EDMAC0.TFTR.LONG = 0;
188  //Set transmit FIFO size (2048 bytes) and receive FIFO size (4096 bytes)
189  EDMAC0.FDR.LONG = EDMAC_FDR_TFD_2048 | EDMAC_FDR_RFD_4096;
190  //Enable continuous reception of multiple frames
191  EDMAC0.RMCR.LONG = EDMAC_RMCR_RNR;
192  //Select write-back complete interrupt mode and enable transmit interrupts
193  EDMAC0.TRIMD.LONG = EDMAC_TRIMD_TIM | EDMAC_TRIMD_TIS;
194 
195  //Disable all ETHERC interrupts
196  ETHERC0.ECSIPR.LONG = 0;
197  //Enable the desired EDMAC interrupts
198  EDMAC0.EESIPR.LONG = EDMAC_EESIPR_TWBIP | EDMAC_EESIPR_FRIP;
199 
200  //Register interrupt handler
201  R_INTC_RegistIntFunc(INTC_ID_ETHER_EINT1, rza2Eth1IrqHandler);
202  //Configure interrupt priority
203  R_INTC_SetPriority(INTC_ID_ETHER_EINT1, RZA2_ETH1_IRQ_PRIORITY);
204 
205  //Enable transmission and reception
206  ETHERC0.ECMR.LONG |= ETHERC_ECMR_TE | ETHERC_ECMR_RE;
207 
208  //Instruct the DMA to poll the receive descriptor list
209  EDMAC0.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 rza2Eth1InitGpio(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.PHYMODE0 = 0;
234 
235  //Configure RMII0_TXD_EN (P6_1)
236  GPIO.P61PFS.BIT.PSEL = 7;
237  PORT6.PMR.BIT.PMR1 = 1;
238  PORT6.DSCR.BIT.DSCR1 = 1;
239 
240  //Configure RMII0_TXD0 (P6_2)
241  GPIO.P62PFS.BIT.PSEL = 7;
242  PORT6.PMR.BIT.PMR2 = 1;
243  PORT6.DSCR.BIT.DSCR2 = 1;
244 
245  //Configure RMII0_TXD1 (P6_3)
246  GPIO.P63PFS.BIT.PSEL = 7;
247  PORT6.PMR.BIT.PMR3 = 1;
248  PORT6.DSCR.BIT.DSCR3 = 1;
249 
250  //Configure REF50CK0 (PE_0)
251  GPIO.PE0PFS.BIT.PSEL = 7;
252  PORTE.PMR.BIT.PMR0 = 1;
253  PORTE.DSCR.BIT.DSCR0 = 1;
254 
255  //Configure RMII0_RXD0 (PE_1)
256  GPIO.PE1PFS.BIT.PSEL = 7;
257  PORTE.PMR.BIT.PMR1 = 1;
258  PORTE.DSCR.BIT.DSCR1 = 1;
259 
260  //Configure RMII0_RXD1 (PE_2)
261  GPIO.PE2PFS.BIT.PSEL = 7;
262  PORTE.PMR.BIT.PMR2 = 1;
263  PORTE.DSCR.BIT.DSCR2 = 1;
264 
265  //Configure RMII0_RXER (PE_3)
266  GPIO.PE3PFS.BIT.PSEL = 7;
267  PORTE.PMR.BIT.PMR3 = 1;
268  PORTE.DSCR.BIT.DSCR3 = 1;
269 
270  //Configure RMII0_CRS_DV (PE_4)
271  GPIO.PE4PFS.BIT.PSEL = 7;
272  PORTE.PMR.BIT.PMR4 = 1;
273  PORTE.DSCR.BIT.DSCR4 = 1;
274 
275  //Configure ET0_MDC (PE_5)
276  GPIO.PE5PFS.BIT.PSEL = 1;
277  PORTE.PMR.BIT.PMR5 = 1;
278  PORTE.DSCR.BIT.DSCR5 = 1;
279 
280  //Configure ET0_MDIO (PE_6)
281  GPIO.PE6PFS.BIT.PSEL = 1;
282  PORTE.PMR.BIT.PMR6 = 1;
283  PORTE.DSCR.BIT.DSCR6 = 1;
284 
285  //Lock PFS registers
286  GPIO.PWPR.BIT.PFSWE = 0;
287  GPIO.PWPR.BIT.B0WI = 1;
288 #endif
289 }
290 
291 
292 /**
293  * @brief Initialize DMA descriptor lists
294  * @param[in] interface Underlying network interface
295  **/
296 
298 {
299  uint_t i;
300 
301  //Initialize TX descriptors
302  for(i = 0; i < RZA2_ETH1_TX_BUFFER_COUNT; i++)
303  {
304  //The descriptor is initially owned by the application
305  txDmaDesc[i].td0 = 0;
306  //Transmit buffer length
307  txDmaDesc[i].td1 = 0;
308  //Transmit buffer address
310  //Clear padding field
311  txDmaDesc[i].padding = 0;
312  }
313 
314  //Mark the last descriptor entry with the TDLE flag
315  txDmaDesc[i - 1].td0 |= EDMAC_TD0_TDLE;
316  //Initialize TX descriptor index
317  txIndex = 0;
318 
319  //Initialize RX descriptors
320  for(i = 0; i < RZA2_ETH1_RX_BUFFER_COUNT; i++)
321  {
322  //The descriptor is initially owned by the DMA
323  rxDmaDesc[i].rd0 = EDMAC_RD0_RACT;
324  //Receive buffer length
326  //Receive buffer address
328  //Clear padding field
329  rxDmaDesc[i].padding = 0;
330  }
331 
332  //Mark the last descriptor entry with the RDLE flag
333  rxDmaDesc[i - 1].rd0 |= EDMAC_RD0_RDLE;
334  //Initialize RX descriptor index
335  rxIndex = 0;
336 
337  //Start address of the TX descriptor list
338  EDMAC0.TDLAR.LONG = RZA2_ETH1_GET_PHYSICAL_ADDR(txDmaDesc);
339  //Start address of the RX descriptor list
340  EDMAC0.RDLAR.LONG = RZA2_ETH1_GET_PHYSICAL_ADDR(rxDmaDesc);
341 }
342 
343 
344 /**
345  * @brief RZ/A2 Ethernet MAC timer handler
346  *
347  * This routine is periodically called by the TCP/IP stack to handle periodic
348  * operations such as polling the link state
349  *
350  * @param[in] interface Underlying network interface
351  **/
352 
353 void rza2Eth1Tick(NetInterface *interface)
354 {
355  //Valid Ethernet PHY or switch driver?
356  if(interface->phyDriver != NULL)
357  {
358  //Handle periodic operations
359  interface->phyDriver->tick(interface);
360  }
361  else if(interface->switchDriver != NULL)
362  {
363  //Handle periodic operations
364  interface->switchDriver->tick(interface);
365  }
366  else
367  {
368  //Just for sanity
369  }
370 }
371 
372 
373 /**
374  * @brief Enable interrupts
375  * @param[in] interface Underlying network interface
376  **/
377 
379 {
380  //Enable Ethernet MAC interrupts
381  R_INTC_Enable(INTC_ID_ETHER_EINT1);
382 
383  //Valid Ethernet PHY or switch driver?
384  if(interface->phyDriver != NULL)
385  {
386  //Enable Ethernet PHY interrupts
387  interface->phyDriver->enableIrq(interface);
388  }
389  else if(interface->switchDriver != NULL)
390  {
391  //Enable Ethernet switch interrupts
392  interface->switchDriver->enableIrq(interface);
393  }
394  else
395  {
396  //Just for sanity
397  }
398 }
399 
400 
401 /**
402  * @brief Disable interrupts
403  * @param[in] interface Underlying network interface
404  **/
405 
407 {
408  //Disable Ethernet MAC interrupts
409  R_INTC_Disable(INTC_ID_ETHER_EINT1);
410 
411  //Valid Ethernet PHY or switch driver?
412  if(interface->phyDriver != NULL)
413  {
414  //Disable Ethernet PHY interrupts
415  interface->phyDriver->disableIrq(interface);
416  }
417  else if(interface->switchDriver != NULL)
418  {
419  //Disable Ethernet switch interrupts
420  interface->switchDriver->disableIrq(interface);
421  }
422  else
423  {
424  //Just for sanity
425  }
426 }
427 
428 
429 /**
430  * @brief RZ/A2 Ethernet MAC interrupt service routine
431  * @param[in] intSense Unused parameter
432  **/
433 
434 void rza2Eth1IrqHandler(uint32_t intSense)
435 {
436  bool_t flag;
437  uint32_t status;
438 
439  //Interrupt service routine prologue
440  osEnterIsr();
441 
442  //This flag will be set if a higher priority task must be woken
443  flag = FALSE;
444 
445  //Read interrupt status register
446  status = EDMAC0.EESR.LONG;
447 
448  //Packet transmitted?
449  if((status & EDMAC_EESR_TWB) != 0)
450  {
451  //Clear TWB interrupt flag
452  EDMAC0.EESR.LONG = EDMAC_EESR_TWB;
453 
454  //Check whether the TX buffer is available for writing
455  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
456  {
457  //Notify the TCP/IP stack that the transmitter is ready to send
458  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
459  }
460  }
461 
462  //Packet received?
463  if((status & EDMAC_EESR_FR) != 0)
464  {
465  //Clear FR interrupt flag
466  EDMAC0.EESR.LONG = EDMAC_EESR_FR;
467 
468  //Set event flag
469  nicDriverInterface->nicEvent = TRUE;
470  //Notify the TCP/IP stack of the event
471  flag |= osSetEventFromIsr(&netEvent);
472  }
473 
474  //Interrupt service routine epilogue
475  osExitIsr(flag);
476 }
477 
478 
479 /**
480  * @brief RZ/A2 Ethernet MAC event handler
481  * @param[in] interface Underlying network interface
482  **/
483 
485 {
486  error_t error;
487 
488  //Process all pending packets
489  do
490  {
491  //Read incoming packet
492  error = rza2Eth1ReceivePacket(interface);
493 
494  //No more data in the receive buffer?
495  } while(error != ERROR_BUFFER_EMPTY);
496 }
497 
498 
499 /**
500  * @brief Send a packet
501  * @param[in] interface Underlying network interface
502  * @param[in] buffer Multi-part buffer containing the data to send
503  * @param[in] offset Offset to the first data byte
504  * @param[in] ancillary Additional options passed to the stack along with
505  * the packet
506  * @return Error code
507  **/
508 
510  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
511 {
512  //Retrieve the length of the packet
513  size_t length = netBufferGetLength(buffer) - offset;
514 
515  //Check the frame length
517  {
518  //The transmitter can accept another packet
519  osSetEvent(&interface->nicTxEvent);
520  //Report an error
521  return ERROR_INVALID_LENGTH;
522  }
523 
524  //Make sure the current buffer is available for writing
525  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) != 0)
526  {
527  return ERROR_FAILURE;
528  }
529 
530  //Copy user data to the transmit buffer
531  netBufferRead(txBuffer[txIndex], buffer, offset, length);
532 
533  //Write the number of bytes to send
534  txDmaDesc[txIndex].td1 = (length << 16) & EDMAC_TD1_TBL;
535 
536  //Check current index
537  if(txIndex < (RZA2_ETH1_TX_BUFFER_COUNT - 1))
538  {
539  //Give the ownership of the descriptor to the DMA engine
540  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TFP_SOF |
542 
543  //Point to the next descriptor
544  txIndex++;
545  }
546  else
547  {
548  //Give the ownership of the descriptor to the DMA engine
549  txDmaDesc[txIndex].td0 = EDMAC_TD0_TACT | EDMAC_TD0_TDLE |
551 
552  //Wrap around
553  txIndex = 0;
554  }
555 
556  //Instruct the DMA to poll the transmit descriptor list
557  EDMAC0.EDTRR.LONG = EDMAC_EDTRR_TR;
558 
559  //Check whether the next buffer is available for writing
560  if((txDmaDesc[txIndex].td0 & EDMAC_TD0_TACT) == 0)
561  {
562  //The transmitter can accept another packet
563  osSetEvent(&interface->nicTxEvent);
564  }
565 
566  //Successful write operation
567  return NO_ERROR;
568 }
569 
570 
571 /**
572  * @brief Receive a packet
573  * @param[in] interface Underlying network interface
574  * @return Error code
575  **/
576 
578 {
579  static uint32_t temp[RZA2_ETH1_RX_BUFFER_SIZE / 4];
580  error_t error;
581  size_t n;
582  NetRxAncillary ancillary;
583 
584  //Current buffer available for reading?
585  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RACT) == 0)
586  {
587  //SOF and EOF flags should be set
588  if((rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_SOF) != 0 &&
589  (rxDmaDesc[rxIndex].rd0 & EDMAC_RD0_RFP_EOF) != 0)
590  {
591  //Make sure no error occurred
592  if((rxDmaDesc[rxIndex].rd0 & (EDMAC_RD0_RFS_MASK & ~EDMAC_RD0_RFS_RMAF)) == 0)
593  {
594  //Retrieve the length of the frame
595  n = rxDmaDesc[rxIndex].rd1 & EDMAC_RD1_RFL;
596  //Limit the number of data to read
598 
599  //Copy data from the receive buffer
600  osMemcpy(temp, rxBuffer[rxIndex], n);
601 
602  //Additional options can be passed to the stack along with the packet
603  ancillary = NET_DEFAULT_RX_ANCILLARY;
604 
605  //Pass the packet to the upper layer
606  nicProcessPacket(interface, (uint8_t *) temp, n, &ancillary);
607 
608  //Valid packet received
609  error = NO_ERROR;
610  }
611  else
612  {
613  //The received packet contains an error
614  error = ERROR_INVALID_PACKET;
615  }
616  }
617  else
618  {
619  //The packet is not valid
620  error = ERROR_INVALID_PACKET;
621  }
622 
623  //Check current index
624  if(rxIndex < (RZA2_ETH1_RX_BUFFER_COUNT - 1))
625  {
626  //Give the ownership of the descriptor back to the DMA
627  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT;
628  //Point to the next descriptor
629  rxIndex++;
630  }
631  else
632  {
633  //Give the ownership of the descriptor back to the DMA
634  rxDmaDesc[rxIndex].rd0 = EDMAC_RD0_RACT | EDMAC_RD0_RDLE;
635  //Wrap around
636  rxIndex = 0;
637  }
638 
639  //Instruct the DMA to poll the receive descriptor list
640  EDMAC0.EDRRR.LONG = EDMAC_EDRRR_RR;
641  }
642  else
643  {
644  //No more data in the receive buffer
645  error = ERROR_BUFFER_EMPTY;
646  }
647 
648  //Return status code
649  return error;
650 }
651 
652 
653 /**
654  * @brief Configure MAC address filtering
655  * @param[in] interface Underlying network interface
656  * @return Error code
657  **/
658 
660 {
661  uint_t i;
662  bool_t acceptMulticast;
663 
664  //Debug message
665  TRACE_DEBUG("Updating MAC filter...\r\n");
666 
667  //Promiscuous mode?
668  if(interface->promiscuous)
669  {
670  //Accept all frames regardless of their destination address
671  ETHERC0.ECMR.LONG |= ETHERC_ECMR_PRM;
672  }
673  else
674  {
675  //Disable promiscuous mode
676  ETHERC0.ECMR.LONG &= ~ETHERC_ECMR_PRM;
677 
678  //Set the upper 32 bits of the MAC address
679  ETHERC0.MAHR.LONG = (interface->macAddr.b[0] << 24) | (interface->macAddr.b[1] << 16) |
680  (interface->macAddr.b[2] << 8) | interface->macAddr.b[3];
681 
682  //Set the lower 16 bits of the MAC address
683  ETHERC0.MALR.LONG = (interface->macAddr.b[4] << 8) | interface->macAddr.b[5];
684 
685  //This flag will be set if multicast addresses should be accepted
686  acceptMulticast = FALSE;
687 
688  //The MAC address filter contains the list of MAC addresses to accept
689  //when receiving an Ethernet frame
690  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
691  {
692  //Valid entry?
693  if(interface->macAddrFilter[i].refCount > 0)
694  {
695  //Accept multicast addresses
696  acceptMulticast = TRUE;
697  //We are done
698  break;
699  }
700  }
701 
702  //Enable or disable the reception of multicast frames
703  if(acceptMulticast || interface->acceptAllMulticast)
704  {
705  EDMAC0.EESR.LONG |= EDMAC_EESR_RMAF;
706  }
707  else
708  {
709  EDMAC0.EESR.LONG &= ~EDMAC_EESR_RMAF;
710  }
711  }
712 
713  //Successful processing
714  return NO_ERROR;
715 }
716 
717 
718 /**
719  * @brief Adjust MAC configuration parameters for proper operation
720  * @param[in] interface Underlying network interface
721  * @return Error code
722  **/
723 
725 {
726  uint32_t mode;
727 
728  //Read ETHERC mode register
729  mode = ETHERC0.ECMR.LONG;
730 
731  //10BASE-T or 100BASE-TX operation mode?
732  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
733  {
734  mode |= ETHERC_ECMR_RTM;
735  }
736  else
737  {
738  mode &= ~ETHERC_ECMR_RTM;
739  }
740 
741  //Half-duplex or full-duplex mode?
742  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
743  {
744  mode |= ETHERC_ECMR_DM;
745  }
746  else
747  {
748  mode &= ~ETHERC_ECMR_DM;
749  }
750 
751  //Update ETHERC mode register
752  ETHERC0.ECMR.LONG = mode;
753 
754  //Successful processing
755  return NO_ERROR;
756 }
757 
758 
759 /**
760  * @brief Write PHY register
761  * @param[in] opcode Access type (2 bits)
762  * @param[in] phyAddr PHY address (5 bits)
763  * @param[in] regAddr Register address (5 bits)
764  * @param[in] data Register value
765  **/
766 
767 void rza2Eth1WritePhyReg(uint8_t opcode, uint8_t phyAddr,
768  uint8_t regAddr, uint16_t data)
769 {
770  //Synchronization pattern
772  //Start of frame
774  //Set up a write operation
776  //Write PHY address
777  rza2Eth1WriteSmi(phyAddr, 5);
778  //Write register address
780  //Turnaround
782  //Write register value
783  rza2Eth1WriteSmi(data, 16);
784  //Release MDIO
785  rza2Eth1ReadSmi(1);
786 }
787 
788 
789 /**
790  * @brief Read PHY register
791  * @param[in] opcode Access type (2 bits)
792  * @param[in] phyAddr PHY address (5 bits)
793  * @param[in] regAddr Register address (5 bits)
794  * @return Register value
795  **/
796 
797 uint16_t rza2Eth1ReadPhyReg(uint8_t opcode, uint8_t phyAddr,
798  uint8_t regAddr)
799 {
800  uint16_t data;
801 
802  //Synchronization pattern
804  //Start of frame
806  //Set up a read operation
808  //Write PHY address
809  rza2Eth1WriteSmi(phyAddr, 5);
810  //Write register address
812  //Turnaround to avoid contention
813  rza2Eth1ReadSmi(1);
814  //Read register value
815  data = rza2Eth1ReadSmi(16);
816  //Force the PHY to release the MDIO pin
817  rza2Eth1ReadSmi(1);
818 
819  //Return PHY register contents
820  return data;
821 }
822 
823 
824 /**
825  * @brief SMI write operation
826  * @param[in] data Raw data to be written
827  * @param[in] length Number of bits to be written
828  **/
829 
831 {
832  //Skip the most significant bits since they are meaningless
833  data <<= 32 - length;
834 
835  //Configure MDIO as an output
836  ETHERC0.PIR.LONG |= ETHERC_PIR_MMD;
837 
838  //Write the specified number of bits
839  while(length--)
840  {
841  //Write MDIO
842  if((data & 0x80000000) != 0)
843  {
844  ETHERC0.PIR.LONG |= ETHERC_PIR_MDO;
845  }
846  else
847  {
848  ETHERC0.PIR.LONG &= ~ETHERC_PIR_MDO;
849  }
850 
851  //Assert MDC
852  usleep(1);
853  ETHERC0.PIR.LONG |= ETHERC_PIR_MDC;
854  //Deassert MDC
855  usleep(1);
856  ETHERC0.PIR.LONG &= ~ETHERC_PIR_MDC;
857 
858  //Rotate data
859  data <<= 1;
860  }
861 }
862 
863 
864 /**
865  * @brief SMI read operation
866  * @param[in] length Number of bits to be read
867  * @return Data resulting from the MDIO read operation
868  **/
869 
871 {
872  uint32_t data = 0;
873 
874  //Configure MDIO as an input
875  ETHERC0.PIR.LONG &= ~ETHERC_PIR_MMD;
876 
877  //Read the specified number of bits
878  while(length--)
879  {
880  //Rotate data
881  data <<= 1;
882 
883  //Assert MDC
884  ETHERC0.PIR.LONG |= ETHERC_PIR_MDC;
885  usleep(1);
886  //Deassert MDC
887  ETHERC0.PIR.LONG &= ~ETHERC_PIR_MDC;
888  usleep(1);
889 
890  //Check MDIO state
891  if((ETHERC0.PIR.LONG & ETHERC_PIR_MDI) != 0)
892  {
893  data |= 0x01;
894  }
895  }
896 
897  //Return the received data
898  return data;
899 }
#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
__weak_func void rza2Eth1InitGpio(NetInterface *interface)
GPIO configuration.
void rza2Eth1Tick(NetInterface *interface)
RZ/A2 Ethernet MAC timer handler.
void rza2Eth1DisableIrq(NetInterface *interface)
Disable interrupts.
void rza2Eth1InitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
void rza2Eth1EnableIrq(NetInterface *interface)
Enable interrupts.
void rza2Eth1WritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
void rza2Eth1IrqHandler(uint32_t intSense)
RZ/A2 Ethernet MAC interrupt service routine.
uint32_t rza2Eth1ReadSmi(uint_t length)
SMI read operation.
error_t rza2Eth1UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
error_t rza2Eth1SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
void rza2Eth1EventHandler(NetInterface *interface)
RZ/A2 Ethernet MAC event handler.
error_t rza2Eth1UpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
uint16_t rza2Eth1ReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
error_t rza2Eth1Init(NetInterface *interface)
RZ/A2 Ethernet MAC initialization.
const NicDriver rza2Eth1Driver
RZ/A2 Ethernet MAC driver (ETHERC0 instance)
void rza2Eth1WriteSmi(uint32_t data, uint_t length)
SMI write operation.
error_t rza2Eth1ReceivePacket(NetInterface *interface)
Receive a packet.
RZ/A2 Ethernet MAC driver (ETHERC0 instance)
#define RZA2_ETH1_RX_BUFFER_COUNT
#define EDMAC_FDR_RFD_4096
#define RZA2_ETH1_TX_BUFFER_SIZE
#define EDMAC_EDMR_DL_16
#define RZA2_ETH1_RAM_SECTION
#define RZA2_ETH1_TX_BUFFER_COUNT
#define RZA2_ETH1_GET_PHYSICAL_ADDR(addr)
#define EDMAC_FDR_TFD_2048
#define RZA2_ETH1_RX_BUFFER_SIZE
#define RZA2_ETH1_IRQ_PRIORITY
#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