zynq7000_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file zynq7000_eth_driver.c
3  * @brief Zynq-7000 Ethernet MAC controller
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include <limits.h>
34 #include "xemacps_hw.h"
35 #include "xscugic.h"
36 #include "xil_misc_psreset_api.h"
37 #include "core/net.h"
39 #include "debug.h"
40 
41 //Underlying network interface
42 static NetInterface *nicDriverInterface;
43 
44 //GIC instance
45 extern XScuGic ZYNQ7000_ETH_GIC_INSTANCE;
46 
47 //IAR EWARM compiler?
48 #if defined(__ICCARM__)
49 
50 //TX buffer
51 #pragma data_alignment = 8
52 #pragma location = ".ram_no_cache"
54 //RX buffer
55 #pragma data_alignment = 8
56 #pragma location = ".ram_no_cache"
58 //TX buffer descriptors
59 #pragma data_alignment = 4
60 #pragma location = ".ram_no_cache"
62 //RX buffer descriptors
63 #pragma data_alignment = 4
64 #pragma location = ".ram_no_cache"
66 
67 //Keil MDK-ARM or GCC compiler?
68 #else
69 
70 //TX buffer
72  __attribute__((aligned(8), __section__(".ram_no_cache")));
73 //RX buffer
75  __attribute__((aligned(8), __section__(".ram_no_cache")));
76 //TX buffer descriptors
78  __attribute__((aligned(4), __section__(".ram_no_cache")));
79 //RX buffer descriptors
81  __attribute__((aligned(4), __section__(".ram_no_cache")));
82 
83 #endif
84 
85 //TX buffer index
86 static uint_t txBufferIndex;
87 //RX buffer index
88 static uint_t rxBufferIndex;
89 
90 
91 /**
92  * @brief Zynq-7000 Ethernet MAC driver
93  **/
94 
96 {
98  ETH_MTU,
109  TRUE,
110  TRUE,
111  TRUE,
112  FALSE
113 };
114 
115 
116 /**
117  * @brief Zynq-7000 Ethernet MAC initialization
118  * @param[in] interface Underlying network interface
119  * @return Error code
120  **/
121 
123 {
124  error_t error;
125  volatile uint32_t temp;
126 
127  //Debug message
128  TRACE_INFO("Initializing Zynq-7000 Ethernet MAC...\r\n");
129 
130  //Save underlying network interface
131  nicDriverInterface = interface;
132 
133  //Unlock SLCR
135 
136  //Configure Ethernet controller reference clock
138  temp |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1 << 20) & XSLCR_GEM0_CLK_CTRL_DIV1_MASK;
139  temp |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0 << 8) & XSLCR_GEM0_CLK_CTRL_DIV0_MASK;
140  XSLCR_GEM0_CLK_CTRL = temp;
141 
142  //Enable Ethernet controller RX clock
144 
145  //Lock SLCR
147 
148  //Clear network control register
149  XEMACPS_NWCTRL = 0;
150  //Clear statistics registers
151  XEMACPS_NWCTRL |= XEMACPS_NWCTRL_STATCLR_MASK;
152 
153  //Configure MDC clock speed
154  XEMACPS_NWCFG = (MDC_DIV_224 << XEMACPS_NWCFG_MDC_SHIFT_MASK) | XEMACPS_NWCFG_MDCCLKDIV_MASK;
155  //Enable management port (MDC and MDIO)
156  XEMACPS_NWCTRL |= XEMACPS_NWCTRL_MDEN_MASK;
157 
158  //PHY transceiver initialization
159  error = interface->phyDriver->init(interface);
160  //Failed to initialize PHY transceiver?
161  if(error)
162  return error;
163 
164  //Set the MAC address
165  XEMACPS_LADDR1L = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
166  XEMACPS_LADDR1H = interface->macAddr.w[2];
167 
168  //Configure the receive filter
169  XEMACPS_NWCFG |= XEMACPS_NWCFG_UCASTHASHEN_MASK | XEMACPS_NWCFG_MCASTHASHEN_MASK;
170 
171  //Initialize hash table
172  XEMACPS_HASHL = 0;
173  XEMACPS_HASHH = 0;
174 
175  //Initialize buffer descriptors
176  zynq7000EthInitBufferDesc(interface);
177 
178  //Set RX buffer size
179  temp = ((ZYNQ7000_ETH_RX_BUFFER_SIZE / 64) << XEMACPS_DMACR_RXBUF_SHIFT) &
180  XEMACPS_DMACR_RXBUF_MASK;
181 
182  //Use full configured addressable space for transmit and receive packet buffers
183  temp |= XEMACPS_DMACR_TXSIZE_MASK | XEMACPS_DMACR_RXSIZE_MASK;
184  //Select the burst length for DMA data operations
185  temp |= XEMACPS_DMACR_INCR16_AHB_BURST;
186  //Set DMA configuration register
187  XEMACPS_DMACR = temp;
188 
189  //Clear transmit status register
190  XEMACPS_TXSR = XEMACPS_TXSR_TXCOMPL_MASK | XEMACPS_TXSR_TXGO_MASK |
191  XEMACPS_TXSR_ERROR_MASK;
192 
193  //Clear receive status register
194  XEMACPS_RXSR = XEMACPS_RXSR_FRAMERX_MASK | XEMACPS_RXSR_ERROR_MASK;
195 
196  //First disable all interrupts
197  XEMACPS_IDR = 0xFFFFFFFF;
198 
199  //Only the desired ones are enabled
200  XEMACPS_IER = XEMACPS_IXR_HRESPNOK_MASK | XEMACPS_IXR_RXOVR_MASK |
201  XEMACPS_IXR_TXCOMPL_MASK | XEMACPS_IXR_TXEXH_MASK | XEMACPS_IXR_RETRY_MASK |
202  XEMACPS_IXR_URUN_MASK | XEMACPS_IXR_RXUSED_MASK | XEMACPS_IXR_FRAMERX_MASK;
203 
204  //Read interrupt status register to clear any pending interrupt
205  temp = XEMACPS_ISR;
206 
207  //Register interrupt handler
208  XScuGic_Connect(&ZYNQ7000_ETH_GIC_INSTANCE, XPS_GEM0_INT_ID,
209  (Xil_InterruptHandler) zynq7000EthIrqHandler, interface);
210 
211  //Configure interrupt priority
212  XScuGic_SetPriorityTriggerType(&ZYNQ7000_ETH_GIC_INSTANCE,
213  XPS_GEM0_INT_ID, ZYNQ7000_ETH_IRQ_PRIORITY, 1);
214 
215  //Enable the transmitter and the receiver
216  XEMACPS_NWCTRL |= XEMACPS_NWCTRL_TXEN_MASK | XEMACPS_NWCTRL_RXEN_MASK;
217 
218  //Accept any packets from the upper layer
219  osSetEvent(&interface->nicTxEvent);
220 
221  //Successful initialization
222  return NO_ERROR;
223 }
224 
225 
226 /**
227  * @brief Initialize buffer descriptors
228  * @param[in] interface Underlying network interface
229  **/
230 
232 {
233  uint_t i;
234  uint32_t address;
235 
236  //Initialize TX buffer descriptors
237  for(i = 0; i < ZYNQ7000_ETH_TX_BUFFER_COUNT; i++)
238  {
239  //Calculate the address of the current TX buffer
240  address = (uint32_t) txBuffer[i];
241  //Write the address to the descriptor entry
242  txBufferDesc[i].address = address;
243  //Initialize status field
244  txBufferDesc[i].status = XEMACPS_TX_USED;
245  }
246 
247  //Mark the last descriptor entry with the wrap flag
248  txBufferDesc[i - 1].status |= XEMACPS_TX_WRAP;
249  //Initialize TX buffer index
250  txBufferIndex = 0;
251 
252  //Initialize RX buffer descriptors
253  for(i = 0; i < ZYNQ7000_ETH_RX_BUFFER_COUNT; i++)
254  {
255  //Calculate the address of the current RX buffer
256  address = (uint32_t) rxBuffer[i];
257  //Write the address to the descriptor entry
258  rxBufferDesc[i].address = address & XEMACPS_RX_ADDRESS;
259  //Clear status field
260  rxBufferDesc[i].status = 0;
261  }
262 
263  //Mark the last descriptor entry with the wrap flag
264  rxBufferDesc[i - 1].address |= XEMACPS_RX_WRAP;
265  //Initialize RX buffer index
266  rxBufferIndex = 0;
267 
268  //Start location of the TX descriptor list
269  XEMACPS_TXQBASE = (uint32_t) txBufferDesc;
270  //Start location of the RX descriptor list
271  XEMACPS_RXQBASE = (uint32_t) rxBufferDesc;
272 }
273 
274 
275 /**
276  * @brief Zynq-7000 Ethernet MAC timer handler
277  *
278  * This routine is periodically called by the TCP/IP stack to
279  * handle periodic operations such as polling the link state
280  *
281  * @param[in] interface Underlying network interface
282  **/
283 
285 {
286  //Handle periodic operations
287  interface->phyDriver->tick(interface);
288 }
289 
290 
291 /**
292  * @brief Enable interrupts
293  * @param[in] interface Underlying network interface
294  **/
295 
297 {
298  //Enable Ethernet MAC interrupts
299  XScuGic_Enable(&ZYNQ7000_ETH_GIC_INSTANCE, XPS_GEM0_INT_ID);
300  //Enable Ethernet PHY interrupts
301  interface->phyDriver->enableIrq(interface);
302 }
303 
304 
305 /**
306  * @brief Disable interrupts
307  * @param[in] interface Underlying network interface
308  **/
309 
311 {
312  //Disable Ethernet MAC interrupts
313  XScuGic_Disable(&ZYNQ7000_ETH_GIC_INSTANCE, XPS_GEM0_INT_ID);
314  //Disable Ethernet PHY interrupts
315  interface->phyDriver->disableIrq(interface);
316 }
317 
318 
319 /**
320  * @brief Zynq-7000 Ethernet MAC interrupt service routine
321  * @param[in] interface Underlying network interface
322  **/
323 
325 {
326  bool_t flag;
327  volatile uint32_t isr;
328  volatile uint32_t tsr;
329  volatile uint32_t rsr;
330 
331  //Enter interrupt service routine
332  osEnterIsr();
333 
334  //This flag will be set if a higher priority task must be woken
335  flag = FALSE;
336 
337  //Each time the software reads XEMACPS_ISR, it has to check the
338  //contents of XEMACPS_TXSR, XEMACPS_RXSR
339  isr = XEMACPS_ISR;
340  tsr = XEMACPS_TXSR;
341  rsr = XEMACPS_RXSR;
342 
343  //Clear interrupt flags
344  XEMACPS_ISR = isr;
345 
346  //A packet has been transmitted?
347  if(tsr & (XEMACPS_TXSR_TXCOMPL_MASK | XEMACPS_TXSR_TXGO_MASK | XEMACPS_TXSR_ERROR_MASK))
348  {
349  //Only clear TSR flags that are currently set
350  XEMACPS_TXSR = tsr;
351 
352  //Check whether the TX buffer is available for writing
353  if(txBufferDesc[txBufferIndex].status & XEMACPS_TX_USED)
354  {
355  //Notify the TCP/IP stack that the transmitter is ready to send
356  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
357  }
358  }
359 
360  //A packet has been received?
361  if(rsr & (XEMACPS_RXSR_FRAMERX_MASK | XEMACPS_RXSR_ERROR_MASK))
362  {
363  //Set event flag
364  nicDriverInterface->nicEvent = TRUE;
365  //Notify the TCP/IP stack of the event
366  flag |= osSetEventFromIsr(&netEvent);
367  }
368 
369  //Flush packet if the receive buffer not available
370  if (isr & XEMACPS_IXR_RXUSED_MASK)
371  XEMACPS_NWCTRL |= XEMACPS_NWCTRL_FLUSH_DPRAM_MASK;
372 
373  //Leave interrupt service routine
374  osExitIsr(flag);
375 }
376 
377 
378 /**
379  * @brief Zynq-7000 Ethernet MAC event handler
380  * @param[in] interface Underlying network interface
381  **/
382 
384 {
385  error_t error;
386  uint32_t rsr;
387 
388  //Read receive status
389  rsr = XEMACPS_RXSR;
390 
391  //Packet received?
392  if(rsr & (XEMACPS_RXSR_FRAMERX_MASK | XEMACPS_RXSR_ERROR_MASK))
393  {
394  //Only clear RSR flags that are currently set
395  XEMACPS_RXSR = rsr;
396 
397  //Process all pending packets
398  do
399  {
400  //Read incoming packet
401  error = zynq7000EthReceivePacket(interface);
402 
403  //No more data in the receive buffer?
404  } while(error != ERROR_BUFFER_EMPTY);
405  }
406 }
407 
408 
409 /**
410  * @brief Send a packet
411  * @param[in] interface Underlying network interface
412  * @param[in] buffer Multi-part buffer containing the data to send
413  * @param[in] offset Offset to the first data byte
414  * @return Error code
415  **/
416 
418  const NetBuffer *buffer, size_t offset)
419 {
420  static uint8_t temp[ZYNQ7000_ETH_TX_BUFFER_SIZE];
421  size_t length;
422 
423  //Retrieve the length of the packet
424  length = netBufferGetLength(buffer) - offset;
425 
426  //Check the frame length
428  {
429  //The transmitter can accept another packet
430  osSetEvent(&interface->nicTxEvent);
431  //Report an error
432  return ERROR_INVALID_LENGTH;
433  }
434 
435  //Make sure the current buffer is available for writing
436  if(!(txBufferDesc[txBufferIndex].status & XEMACPS_TX_USED))
437  return ERROR_FAILURE;
438 
439  //Copy user data to the transmit buffer
440  netBufferRead(temp, buffer, offset, length);
441  memcpy(txBuffer[txBufferIndex], temp, length);
442 
443  //Set the necessary flags in the descriptor entry
444  if(txBufferIndex < (ZYNQ7000_ETH_TX_BUFFER_COUNT - 1))
445  {
446  //Write the status word
447  txBufferDesc[txBufferIndex].status =
449 
450  //Point to the next buffer
451  txBufferIndex++;
452  }
453  else
454  {
455  //Write the status word
456  txBufferDesc[txBufferIndex].status = XEMACPS_TX_WRAP |
458 
459  //Wrap around
460  txBufferIndex = 0;
461  }
462 
463  //Set the STARTTX bit to initiate transmission
464  XEMACPS_NWCTRL |= XEMACPS_NWCTRL_STARTTX_MASK;
465 
466  //Check whether the next buffer is available for writing
467  if(txBufferDesc[txBufferIndex].status & XEMACPS_TX_USED)
468  {
469  //The transmitter can accept another packet
470  osSetEvent(&interface->nicTxEvent);
471  }
472 
473  //Successful processing
474  return NO_ERROR;
475 }
476 
477 
478 /**
479  * @brief Receive a packet
480  * @param[in] interface Underlying network interface
481  * @return Error code
482  **/
483 
485 {
486  static uint8_t temp[ETH_MAX_FRAME_SIZE];
487  error_t error;
488  uint_t i;
489  uint_t j;
490  uint_t sofIndex;
491  uint_t eofIndex;
492  size_t n;
493  size_t size;
494  size_t length;
495 
496  //Initialize SOF and EOF indices
497  sofIndex = UINT_MAX;
498  eofIndex = UINT_MAX;
499 
500  //Search for SOF and EOF flags
501  for(i = 0; i < ZYNQ7000_ETH_RX_BUFFER_COUNT; i++)
502  {
503  //Point to the current entry
504  j = rxBufferIndex + i;
505 
506  //Wrap around to the beginning of the buffer if necessary
509 
510  //No more entries to process?
511  if(!(rxBufferDesc[j].address & XEMACPS_RX_OWNERSHIP))
512  {
513  //Stop processing
514  break;
515  }
516  //A valid SOF has been found?
517  if(rxBufferDesc[j].status & XEMACPS_RX_SOF)
518  {
519  //Save the position of the SOF
520  sofIndex = i;
521  }
522  //A valid EOF has been found?
523  if((rxBufferDesc[j].status & XEMACPS_RX_EOF) && sofIndex != UINT_MAX)
524  {
525  //Save the position of the EOF
526  eofIndex = i;
527  //Retrieve the length of the frame
528  size = rxBufferDesc[j].status & XEMACPS_RX_LENGTH;
529  //Limit the number of data to read
530  size = MIN(size, ETH_MAX_FRAME_SIZE);
531  //Stop processing since we have reached the end of the frame
532  break;
533  }
534  }
535 
536  //Determine the number of entries to process
537  if(eofIndex != UINT_MAX)
538  j = eofIndex + 1;
539  else if(sofIndex != UINT_MAX)
540  j = sofIndex;
541  else
542  j = i;
543 
544  //Total number of bytes that have been copied from the receive buffer
545  length = 0;
546 
547  //Process incoming frame
548  for(i = 0; i < j; i++)
549  {
550  //Any data to copy from current buffer?
551  if(eofIndex != UINT_MAX && i >= sofIndex && i <= eofIndex)
552  {
553  //Calculate the number of bytes to read at a time
555  //Copy data from receive buffer
556  memcpy(temp + length, rxBuffer[rxBufferIndex], n);
557  //Update byte counters
558  length += n;
559  size -= n;
560  }
561 
562  //Mark the current buffer as free
563  rxBufferDesc[rxBufferIndex].address &= ~XEMACPS_RX_OWNERSHIP;
564 
565  //Point to the following entry
566  rxBufferIndex++;
567 
568  //Wrap around to the beginning of the buffer if necessary
569  if(rxBufferIndex >= ZYNQ7000_ETH_RX_BUFFER_COUNT)
570  rxBufferIndex = 0;
571  }
572 
573  //Any packet to process?
574  if(length > 0)
575  {
576  //Pass the packet to the upper layer
577  nicProcessPacket(interface, temp, length);
578  //Valid packet received
579  error = NO_ERROR;
580  }
581  else
582  {
583  //No more data in the receive buffer
584  error = ERROR_BUFFER_EMPTY;
585  }
586 
587  //Return status code
588  return error;
589 }
590 
591 
592 /**
593  * @brief Configure MAC address filtering
594  * @param[in] interface Underlying network interface
595  * @return Error code
596  **/
597 
599 {
600  uint_t i;
601  uint_t k;
602  uint8_t *p;
603  uint32_t hashTable[2];
604  MacFilterEntry *entry;
605 
606  //Debug message
607  TRACE_DEBUG("Updating Zynq-7000 hash table...\r\n");
608 
609  //Clear hash table
610  hashTable[0] = 0;
611  hashTable[1] = 0;
612 
613  //The MAC address filter contains the list of MAC addresses to accept
614  //to accept when receiving an Ethernet frame
615  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
616  {
617  //Point to the current entry
618  entry = &interface->macAddrFilter[i];
619 
620  //Valid entry?
621  if(entry->refCount > 0)
622  {
623  //Point to the MAC address
624  p = entry->addr.b;
625 
626  //Apply the hash function
627  k = (p[0] >> 6) ^ p[0];
628  k ^= (p[1] >> 4) ^ (p[1] << 2);
629  k ^= (p[2] >> 2) ^ (p[2] << 4);
630  k ^= (p[3] >> 6) ^ p[3];
631  k ^= (p[4] >> 4) ^ (p[4] << 2);
632  k ^= (p[5] >> 2) ^ (p[5] << 4);
633 
634  //The hash value is reduced to a 6-bit index
635  k &= 0x3F;
636 
637  //Update hash table contents
638  hashTable[k / 32] |= (1 << (k % 32));
639  }
640  }
641 
642  //Write the hash table
643  XEMACPS_HASHL = hashTable[0];
644  XEMACPS_HASHH = hashTable[1];
645 
646  //Debug message
647  TRACE_DEBUG(" HASHL = %08" PRIX32 "\r\n", XEMACPS_HASHL);
648  TRACE_DEBUG(" HASHH = %08" PRIX32 "\r\n", XEMACPS_HASHH);
649 
650  //Successful processing
651  return NO_ERROR;
652 }
653 
654 
655 /**
656  * @brief Adjust MAC configuration parameters for proper operation
657  * @param[in] interface Underlying network interface
658  * @return Error code
659  **/
660 
662 {
663  uint32_t config;
664  uint32_t clockCtrl;
665 
666  //Read network configuration register
667  config = XEMACPS_NWCFG;
668 
669  //Read clock control register
670  clockCtrl = XSLCR_GEM0_CLK_CTRL;
672 
673  //1000BASE-T operation mode?
674  if(interface->linkSpeed == NIC_LINK_SPEED_1GBPS)
675  {
676  //Update network configuration
677  config |= XEMACPS_NWCFG_1000_MASK;
678  config &= ~XEMACPS_NWCFG_100_MASK;
679 
680  //Update clock configuration
681  clockCtrl |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1 << 20) & XSLCR_GEM0_CLK_CTRL_DIV1_MASK;
682  clockCtrl |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0 << 8) & XSLCR_GEM0_CLK_CTRL_DIV0_MASK;
683  }
684  //100BASE-TX operation mode?
685  else if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
686  {
687  //Update network configuration
688  config &= ~XEMACPS_NWCFG_1000_MASK;
689  config |= XEMACPS_NWCFG_100_MASK;
690 
691  //Update clock configuration
692  clockCtrl |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1 << 20) & XSLCR_GEM0_CLK_CTRL_DIV1_MASK;
693  clockCtrl |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0 << 8) & XSLCR_GEM0_CLK_CTRL_DIV0_MASK;
694  }
695  //10BASE-T operation mode?
696  else
697  {
698  //Update network configuration
699  config &= ~XEMACPS_NWCFG_1000_MASK;
700  config &= ~XEMACPS_NWCFG_100_MASK;
701 
702  //Update clock configuration
703  clockCtrl |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1 << 20) & XSLCR_GEM0_CLK_CTRL_DIV1_MASK;
704  clockCtrl |= (XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0 << 8) & XSLCR_GEM0_CLK_CTRL_DIV0_MASK;
705  }
706 
707  //Half-duplex or full-duplex mode?
708  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
709  config |= XEMACPS_NWCFG_FDEN_MASK;
710  else
711  config &= ~XEMACPS_NWCFG_FDEN_MASK;
712 
713  //Write network configuration register
714  XEMACPS_NWCFG = config;
715 
716  //Unlock SLCR
718  //Write clock control register
719  XSLCR_GEM0_CLK_CTRL = clockCtrl;
720  //Lock SLCR
722 
723  //Successful processing
724  return NO_ERROR;
725 }
726 
727 
728 /**
729  * @brief Write PHY register
730  * @param[in] phyAddr PHY address
731  * @param[in] regAddr Register address
732  * @param[in] data Register value
733  **/
734 
735 void zynq7000EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
736 {
737  uint32_t value;
738 
739  //Set up a write operation
740  value = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_W_MASK;
741  //PHY address
742  value |= (phyAddr << 23) & XEMACPS_PHYMNTNC_ADDR_MASK;
743  //Register address
744  value |= (regAddr << 18) & XEMACPS_PHYMNTNC_REG_MASK;
745  //Register value
746  value |= data & XEMACPS_PHYMNTNC_DATA_MASK;
747 
748  //Start a write operation
750  //Wait for the write to complete
751  while(!(XEMACPS_NWSR & XEMACPS_NWSR_MDIOIDLE_MASK));
752 }
753 
754 
755 /**
756  * @brief Read PHY register
757  * @param[in] phyAddr PHY address
758  * @param[in] regAddr Register address
759  * @return Register value
760  **/
761 
762 uint16_t zynq7000EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
763 {
764  uint32_t value;
765 
766  //Set up a read operation
767  value = XEMACPS_PHYMNTNC_OP_MASK | XEMACPS_PHYMNTNC_OP_R_MASK;
768  //PHY address
769  value |= (phyAddr << 23) & XEMACPS_PHYMNTNC_ADDR_MASK;
770  //Register address
771  value |= (regAddr << 18) & XEMACPS_PHYMNTNC_REG_MASK;
772 
773  //Start a read operation
775  //Wait for the read to complete
776  while(!(XEMACPS_NWSR & XEMACPS_NWSR_MDIOIDLE_MASK));
777 
778  //Return PHY register contents
779  return XEMACPS_PHYMNTNC & XEMACPS_PHYMNTNC_DATA_MASK;
780 }
#define XEMACPS_TX_USED
#define XEMACPS_HASHL
#define XEMACPS_RXSR
MacAddr addr
MAC address.
Definition: ethernet.h:210
#define XSLCR_LOCK
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:80
#define XEMACPS_RX_EOF
#define XSLCR_GEM0_RCLK_CTRL
TCP/IP stack core.
void zynq7000EthIrqHandler(NetInterface *interface)
Zynq-7000 Ethernet MAC interrupt service routine.
Debugging facilities.
uint8_t p
Definition: ndp.h:295
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
Generic error code.
Definition: error.h:43
#define ZYNQ7000_ETH_RX_BUFFER_SIZE
#define txBuffer
error_t zynq7000EthReceivePacket(NetInterface *interface)
Receive a packet.
#define XEMACPS_NWCTRL
#define XEMACPS_TX_LENGTH
#define ZYNQ7000_ETH_TX_BUFFER_COUNT
#define XEMACPS_RX_WRAP
Zynq-7000 Ethernet MAC controller.
XScuGic ZYNQ7000_ETH_GIC_INSTANCE
#define XEMACPS_ISR
#define XEMACPS_LADDR1L
void zynq7000EthInitBufferDesc(NetInterface *interface)
Initialize buffer descriptors.
#define XSLCR_GEM0_CLK_CTRL_DIV0_MASK
#define XEMACPS_DMACR
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
#define XEMACPS_RX_ADDRESS
#define XEMACPS_RX_LENGTH
#define XSLCR_LOCK_KEY_VALUE
#define XSLCR_UNLOCK_KEY_VALUE
error_t zynq7000EthInit(NetInterface *interface)
Zynq-7000 Ethernet MAC initialization.
const NicDriver zynq7000EthDriver
Zynq-7000 Ethernet MAC driver.
#define XEMACPS_PHYMNTNC
#define XSLCR_GEM0_RCLK_CTRL_CLKACT_MASK
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:670
error_t zynq7000EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define XEMACPS_RXQBASE
void zynq7000EthTick(NetInterface *interface)
Zynq-7000 Ethernet MAC timer handler.
NIC driver.
Definition: nic.h:161
#define XSLCR_GEM0_CLK_CTRL_CLKACT_MASK
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define ZYNQ7000_ETH_TX_BUFFER_SIZE
#define MIN(a, b)
Definition: os_port.h:60
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define ZYNQ7000_ETH_IRQ_PRIORITY
void zynq7000EthEventHandler(NetInterface *interface)
Zynq-7000 Ethernet MAC event handler.
#define XSLCR_UNLOCK
#define XEMACPS_IDR
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ZYNQ7000_ETH_RX_BUFFER_COUNT
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
#define XEMACPS_RX_OWNERSHIP
#define rxBuffer
void zynq7000EthEnableIrq(NetInterface *interface)
Enable interrupts.
Ipv6Addr address
void zynq7000EthDisableIrq(NetInterface *interface)
Disable interrupts.
OsEvent netEvent
Definition: net.c:72
void nicProcessPacket(NetInterface *interface, void *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:239
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:211
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
Transmit buffer descriptor.
unsigned int uint_t
Definition: compiler_port.h:43
#define XEMACPS_RX_SOF
#define XSLCR_GEM0_CLK_CTRL_DIV1_MASK
#define XEMACPS_HASHH
error_t zynq7000EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define XEMACPS_TXSR
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
#define XEMACPS_TXQBASE
uint8_t value[]
Definition: dtls_misc.h:141
#define XEMACPS_NWCFG
uint16_t zynq7000EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Receive buffer descriptor.
error_t zynq7000EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define XEMACPS_TX_WRAP
#define XEMACPS_IER
#define osExitIsr(flag)
#define XEMACPS_TX_LAST
#define osEnterIsr()
#define XEMACPS_NWSR
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define XSLCR_GEM0_CLK_CTRL
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
void zynq7000EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define XEMACPS_LADDR1H
MAC filter table entry.
Definition: ethernet.h:208
#define TRACE_DEBUG(...)
Definition: debug.h:98