str912_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file str912_eth_driver.c
3  * @brief STR9 Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "91x_lib.h"
36 #include "core/net.h"
38 #include "debug.h"
39 
40 //Underlying network interface
41 static NetInterface *nicDriverInterface;
42 
43 //IAR EWARM compiler?
44 #if defined(__ICCARM__)
45 
46 //Transmit buffer
47 #pragma data_alignment = 4
49 //Receive buffer
50 #pragma data_alignment = 4
52 //Transmit DMA descriptors
53 #pragma data_alignment = 4
55 //Receive DMA descriptors
56 #pragma data_alignment = 4
58 
59 //Keil MDK-ARM or GCC compiler?
60 #else
61 
62 //Transmit buffer
64  __attribute__((aligned(4)));
65 //Receive buffer
67  __attribute__((aligned(4)));
68 //Transmit DMA descriptors
70  __attribute__((aligned(4)));
71 //Receive DMA descriptors
73  __attribute__((aligned(4)));
74 
75 #endif
76 
77 //Pointer to the current TX DMA descriptor
78 static Str912TxDmaDesc *txCurDmaDesc;
79 //Pointer to the current RX DMA descriptor
80 static Str912RxDmaDesc *rxCurDmaDesc;
81 
82 
83 /**
84  * @brief STR912 Ethernet MAC driver
85  **/
86 
88 {
90  ETH_MTU,
101  TRUE,
102  TRUE,
103  TRUE,
104  FALSE
105 };
106 
107 
108 /**
109  * @brief STR912 Ethernet MAC initialization
110  * @param[in] interface Underlying network interface
111  * @return Error code
112  **/
113 
115 {
116  error_t error;
117 
118  //Debug message
119  TRACE_INFO("Initializing STR912 Ethernet MAC...\r\n");
120 
121  //Save underlying network interface
122  nicDriverInterface = interface;
123 
124  //GPIO configuration
125  str912EthInitGpio(interface);
126 
127  //Enable Ethernet MAC clock
128  SCU_AHBPeriphClockConfig(__ENET, ENABLE);
129 
130  //Reset Ethernet MAC peripheral
131  SCU_AHBPeriphReset(__ENET, ENABLE);
132  SCU_AHBPeriphReset(__ENET, DISABLE);
133 
134  //MAC DMA software reset
135  ENET_DMA->SCR |= ENET_SCR_SRESET;
136  ENET_DMA->SCR &= ~ENET_SCR_SRESET;
137 
138  //Use default MAC configuration
139  ENET_MAC->MCR = ENET_MCR_AFM_1 | ENET_MCR_RVFF | ENET_MCR_BL_1 |
141 
142  //Adjust HCLK divider depending on system clock frequency
143  if(SCU_GetHCLKFreqValue() > 50000)
144  {
145  ENET_MAC->MCR |= ENET_MCR_PS_1;
146  }
147 
148  //Valid Ethernet PHY or switch driver?
149  if(interface->phyDriver != NULL)
150  {
151  //Ethernet PHY initialization
152  error = interface->phyDriver->init(interface);
153  }
154  else if(interface->switchDriver != NULL)
155  {
156  //Ethernet switch initialization
157  error = interface->switchDriver->init(interface);
158  }
159  else
160  {
161  //The interface is not properly configured
162  error = ERROR_FAILURE;
163  }
164 
165  //Any error to report?
166  if(error)
167  {
168  return error;
169  }
170 
171  //Set the MAC address of the station
172  ENET_MAC->MAL = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
173  ENET_MAC->MAH = interface->macAddr.w[2];
174 
175  //Initialize hash table
176  ENET_MAC->MCLA = 0;
177  ENET_MAC->MCHA = 0;
178 
179  //DMA configuration
180  //ENET_DMA->SCR = 0;
181 
182  //Force a DMA abort
183  ENET_DMA->TXSTR |= ENET_TXSTR_DMA_EN;
184  ENET_DMA->RXSTR |= ENET_RXSTR_DMA_EN;
185 
186  //Set descriptor fetch delay
188  ENET_DMA->RXSTR = ENET_RXSTR_DFETCH_DLY_DEFAULT;
189 
190  //Initialize DMA descriptor lists
191  str912EthInitDmaDesc(interface);
192 
193  //Clear interrupt flags
195  //Configure DMA interrupts as desired
197 
198  //Configure Ethernet interrupt priority
199  VIC_Config(ENET_ITLine, VIC_IRQ, STR912_ETH_IRQ_PRIORITY);
200 
201  //Enable MAC transmission and reception
202  ENET_MAC->MCR |= ENET_MCR_TE | ENET_MCR_RE;
203  //Instruct the DMA to poll the receive descriptor list
204  ENET_DMA->RXSTR |= ENET_RXSTR_START_FETCH;
205 
206  //Accept any packets from the upper layer
207  osSetEvent(&interface->nicTxEvent);
208 
209  //Successful initialization
210  return NO_ERROR;
211 }
212 
213 
214 /**
215  * @brief GPIO configuration
216  * @param[in] interface Underlying network interface
217  **/
218 
219 __weak_func void str912EthInitGpio(NetInterface *interface)
220 {
221 //STR-E912 evaluation board?
222 #if defined(USE_STR_E912)
223  GPIO_InitTypeDef GPIO_InitStructure;
224 
225  //Enable GPIO clocks
226  SCU_APBPeriphClockConfig(__GPIO0, ENABLE);
227  SCU_APBPeriphClockConfig(__GPIO1, ENABLE);
228  SCU_APBPeriphClockConfig(__GPIO5, ENABLE);
229 
230  //Enable MII_PHYCLK clock
231  SCU_PHYCLKConfig(ENABLE);
232 
233  //Configure MII_TX_CLK (P0.0), MII_RXD0 (P0.2), MII_RXD1 (P0.3), MII_RXD2 (P0.4),
234  //MII_RXD3 (P0.5), MII_RX_CLK (P0.6) and MII_RX_DV (P0.7)
235  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3 |
236  GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
237 
238  GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
239  GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Disable;
240  GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
241  GPIO_Init(GPIO0, &GPIO_InitStructure);
242 
243  //Configure MII_RX_ER (P1.0), MII_COL (P1.5) and MII_CRS (P1.6)
244  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_5 | GPIO_Pin_6;
245  GPIO_InitStructure.GPIO_Direction = GPIO_PinInput;
246  GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Disable;
247  GPIO_InitStructure.GPIO_Alternate = GPIO_InputAlt1;
248  GPIO_Init(GPIO1, &GPIO_InitStructure);
249 
250  //Configure MII_TXD0 (P1.1), MII_TXD1 (P1.2), MII_TXD2 (P1.3),
251  //MII_TXD3 (P1.4) and MII_MDC (P1.7)
252  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 |
253  GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_7;
254 
255  GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
256  GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
257  GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Disable;
258  GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2;
259  GPIO_Init(GPIO1, &GPIO_InitStructure);
260 
261  //Configure MII_PHYCLK (P5.2) and MII_TX_EN (P5.3)
262  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
263  GPIO_InitStructure.GPIO_Direction = GPIO_PinOutput;
264  GPIO_InitStructure.GPIO_Type = GPIO_Type_PushPull;
265  GPIO_InitStructure.GPIO_IPInputConnected = GPIO_IPInputConnected_Disable;
266  GPIO_InitStructure.GPIO_Alternate = GPIO_OutputAlt2;
267  GPIO_Init(GPIO5, &GPIO_InitStructure);
268 #endif
269 }
270 
271 
272 /**
273  * @brief Initialize DMA descriptor lists
274  * @param[in] interface Underlying network interface
275  **/
276 
278 {
279  uint_t i;
280 
281  //Initialize TX DMA descriptor list
282  for(i = 0; i < STR912_ETH_TX_BUFFER_COUNT; i++)
283  {
284  //Control word
286  //Transmit buffer address
287  txDmaDesc[i].start = (uint32_t) txBuffer[i];
288  //Next descriptor address
289  txDmaDesc[i].next = (uint32_t) &txDmaDesc[i + 1] | ENET_TDES_NEXT_NPOL_EN;
290  //Status word
291  txDmaDesc[i].status = 0;
292  }
293 
294  //The last descriptor is chained to the first entry
295  txDmaDesc[i - 1].next = (uint32_t) &txDmaDesc[0] | ENET_TDES_NEXT_NPOL_EN;
296  //Point to the very first descriptor
297  txCurDmaDesc = &txDmaDesc[0];
298 
299  //Initialize RX DMA descriptor list
300  for(i = 0; i < STR912_ETH_RX_BUFFER_COUNT; i++)
301  {
302  //Control word
304  //Receive buffer address
305  rxDmaDesc[i].start = (uint32_t) rxBuffer[i];
306  //Next descriptor address
307  rxDmaDesc[i].next = (uint32_t) &rxDmaDesc[i + 1] | ENET_RDES_NEXT_NPOL_EN;
308  //Status word
309  rxDmaDesc[i].status = ENET_RDES_STATUS_VALID;
310  }
311 
312  //The last descriptor is chained to the first entry
313  rxDmaDesc[i - 1].next = (uint32_t) &rxDmaDesc[0] | ENET_RDES_NEXT_NPOL_EN;
314  //Point to the very first descriptor
315  rxCurDmaDesc = &rxDmaDesc[0];
316 
317  //Start location of the TX descriptor list
318  ENET_DMA->TXNDAR = (uint32_t) txDmaDesc | ENET_TDES_NEXT_NPOL_EN;
319  //Start location of the RX descriptor list
320  ENET_DMA->RXNDAR = (uint32_t) rxDmaDesc | ENET_RDES_NEXT_NPOL_EN;
321 }
322 
323 
324 /**
325  * @brief STR912 Ethernet MAC timer handler
326  *
327  * This routine is periodically called by the TCP/IP stack to handle periodic
328  * operations such as polling the link state
329  *
330  * @param[in] interface Underlying network interface
331  **/
332 
333 void str912EthTick(NetInterface *interface)
334 {
335  //Valid Ethernet PHY or switch driver?
336  if(interface->phyDriver != NULL)
337  {
338  //Handle periodic operations
339  interface->phyDriver->tick(interface);
340  }
341  else if(interface->switchDriver != NULL)
342  {
343  //Handle periodic operations
344  interface->switchDriver->tick(interface);
345  }
346  else
347  {
348  //Just for sanity
349  }
350 }
351 
352 
353 /**
354  * @brief Enable interrupts
355  * @param[in] interface Underlying network interface
356  **/
357 
359 {
360  //Enable Ethernet MAC interrupts
361  VIC_ITCmd(ENET_ITLine, ENABLE);
362 
363  //Valid Ethernet PHY or switch driver?
364  if(interface->phyDriver != NULL)
365  {
366  //Enable Ethernet PHY interrupts
367  interface->phyDriver->enableIrq(interface);
368  }
369  else if(interface->switchDriver != NULL)
370  {
371  //Enable Ethernet switch interrupts
372  interface->switchDriver->enableIrq(interface);
373  }
374  else
375  {
376  //Just for sanity
377  }
378 }
379 
380 
381 /**
382  * @brief Disable interrupts
383  * @param[in] interface Underlying network interface
384  **/
385 
387 {
388  //Disable Ethernet MAC interrupts
389  VIC_ITCmd(ENET_ITLine, DISABLE);
390 
391  //Valid Ethernet PHY or switch driver?
392  if(interface->phyDriver != NULL)
393  {
394  //Disable Ethernet PHY interrupts
395  interface->phyDriver->disableIrq(interface);
396  }
397  else if(interface->switchDriver != NULL)
398  {
399  //Disable Ethernet switch interrupts
400  interface->switchDriver->disableIrq(interface);
401  }
402  else
403  {
404  //Just for sanity
405  }
406 }
407 
408 
409 /**
410  * @brief STR912 Ethernet MAC interrupt service routine
411  **/
412 
413 void ENET_IRQHandler(void)
414 {
415  bool_t flag;
416  uint32_t status;
417 
418  //Interrupt service routine prologue
419  osEnterIsr();
420 
421  //This flag will be set if a higher priority task must be woken
422  flag = FALSE;
423 
424  //Read DMA status register
425  status = ENET_DMA->ISR;
426 
427  //Packet transmitted?
428  if((status & ENET_ISR_TX_CURR_DONE) != 0)
429  {
430  //Clear TX_CURR_DONE interrupt flag
431  ENET_DMA->ISR = ENET_ISR_TX_CURR_DONE;
432 
433  //Check whether the TX buffer is available for writing
434  if((txCurDmaDesc->status & ENET_TDES_STATUS_VALID) == 0)
435  {
436  //Notify the TCP/IP stack that the transmitter is ready to send
437  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
438  }
439  }
440 
441  //Packet received?
442  if((status & ENET_ISR_RX_CURR_DONE) != 0)
443  {
444  //Disable RX_CURR_DONE interrupt
445  ENET_DMA->IER &= ~ENET_IER_RX_CURR_DONE_EN;
446 
447  //Set event flag
448  nicDriverInterface->nicEvent = TRUE;
449  //Notify the TCP/IP stack of the event
450  flag |= osSetEventFromIsr(&netEvent);
451  }
452 
453  //Interrupt service routine epilogue
454  osExitIsr(flag);
455 }
456 
457 
458 /**
459  * @brief STR912 Ethernet MAC event handler
460  * @param[in] interface Underlying network interface
461  **/
462 
464 {
465  error_t error;
466 
467  //Packet received?
468  if((ENET_DMA->ISR & ENET_ISR_RX_CURR_DONE) != 0)
469  {
470  //Clear interrupt flag
471  ENET_DMA->ISR = ENET_ISR_RX_CURR_DONE;
472 
473  //Process all pending packets
474  do
475  {
476  //Read incoming packet
477  error = str912EthReceivePacket(interface);
478 
479  //No more data in the receive buffer?
480  } while(error != ERROR_BUFFER_EMPTY);
481  }
482 
483  //Re-enable DMA interrupts
485 }
486 
487 
488 /**
489  * @brief Send a packet
490  * @param[in] interface Underlying network interface
491  * @param[in] buffer Multi-part buffer containing the data to send
492  * @param[in] offset Offset to the first data byte
493  * @param[in] ancillary Additional options passed to the stack along with
494  * the packet
495  * @return Error code
496  **/
497 
499  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
500 {
501  size_t length;
502 
503  //Retrieve the length of the packet
504  length = netBufferGetLength(buffer) - offset;
505 
506  //Check the frame length
508  {
509  //The transmitter can accept another packet
510  osSetEvent(&interface->nicTxEvent);
511  //Report an error
512  return ERROR_INVALID_LENGTH;
513  }
514 
515  //Make sure the current buffer is available for writing
516  if((txCurDmaDesc->status & ENET_TDES_STATUS_VALID) != 0)
517  {
518  return ERROR_FAILURE;
519  }
520 
521  //Copy user data to the transmit buffer
522  netBufferRead((uint8_t *) (txCurDmaDesc->start & ENET_TDES_START_ADDR),
523  buffer, offset, length);
524 
525  //Write the number of bytes to send
526  txCurDmaDesc->ctrl = ENET_TDES_CTRL_NXT_EN | length;
527  //Give the ownership of the descriptor to the DMA
528  txCurDmaDesc->status = ENET_TDES_STATUS_VALID;
529 
530  //Instruct the DMA to poll the transmit descriptor list
531  ENET_DMA->TXSTR |= ENET_TXSTR_START_FETCH;
532 
533  //Point to the next descriptor in the list
534  txCurDmaDesc = (Str912TxDmaDesc *) (txCurDmaDesc->next & ENET_TDES_NEXT_ADDR);
535 
536  //Check whether the next buffer is available for writing
537  if((txCurDmaDesc->status & ENET_TDES_STATUS_VALID) == 0)
538  {
539  //The transmitter can accept another packet
540  osSetEvent(&interface->nicTxEvent);
541  }
542 
543  //Data successfully written
544  return NO_ERROR;
545 }
546 
547 
548 /**
549  * @brief Receive a packet
550  * @param[in] interface Underlying network interface
551  * @return Error code
552  **/
553 
555 {
556  error_t error;
557  size_t n;
558  uint8_t *p;
559  NetRxAncillary ancillary;
560 
561  //Current buffer available for reading?
562  if((rxCurDmaDesc->status & ENET_RDES_STATUS_VALID) == 0)
563  {
564  //Make sure no error occurred
565  if((rxCurDmaDesc->status & ENET_RDES_STATUS_ERROR) == 0)
566  {
567  //Point to the received frame
568  p = (uint8_t *) (rxCurDmaDesc->start & ENET_RDES_START_ADDR);
569 
570  //Retrieve the length of the frame
571  n = rxCurDmaDesc->status & ENET_RDES_STATUS_FL;
572  //Limit the number of data to read
574 
575  //Additional options can be passed to the stack along with the packet
576  ancillary = NET_DEFAULT_RX_ANCILLARY;
577 
578  //Pass the packet to the upper layer
579  nicProcessPacket(interface, p, n, &ancillary);
580 
581  //Valid packet received
582  error = NO_ERROR;
583  }
584  else
585  {
586  //The received packet contains an error
587  error = ERROR_INVALID_PACKET;
588  }
589 
590  //Give the ownership of the descriptor back to the DMA
591  rxCurDmaDesc->status = ENET_RDES_STATUS_VALID;
592  //Point to the next descriptor in the list
593  rxCurDmaDesc = (Str912RxDmaDesc *) (rxCurDmaDesc->next & ENET_RDES_NEXT_ADDR);
594  }
595  else
596  {
597  //No more data in the receive buffer
598  error = ERROR_BUFFER_EMPTY;
599  }
600 
601  //Instruct the DMA to poll the receive descriptor list
602  ENET_DMA->RXSTR |= ENET_RXSTR_START_FETCH;
603 
604  //Return status code
605  return error;
606 }
607 
608 
609 /**
610  * @brief Configure MAC address filtering
611  * @param[in] interface Underlying network interface
612  * @return Error code
613  **/
614 
616 {
617  uint_t i;
618  uint_t k;
619  uint32_t crc;
620  uint32_t hashTable[2];
621  MacFilterEntry *entry;
622 
623  //Debug message
624  TRACE_DEBUG("Updating MAC filter...\r\n");
625 
626  //Set the MAC address of the station
627  ENET_MAC->MAL = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
628  ENET_MAC->MAH = interface->macAddr.w[2];
629 
630  //Clear hash table
631  hashTable[0] = 0;
632  hashTable[1] = 0;
633 
634  //The MAC address filter contains the list of MAC addresses to accept
635  //when receiving an Ethernet frame
636  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
637  {
638  //Point to the current entry
639  entry = &interface->macAddrFilter[i];
640 
641  //Valid entry?
642  if(entry->refCount > 0)
643  {
644  //Compute CRC over the current MAC address
645  crc = str912EthCalcCrc(&entry->addr, sizeof(MacAddr));
646 
647  //The upper 6 bits in the CRC register are used to index the
648  //contents of the hash table
649  k = (crc >> 26) & 0x3F;
650 
651  //Update hash table contents
652  hashTable[k / 32] |= (1 << (k % 32));
653  }
654  }
655 
656  //Write the hash table
657  ENET_MAC->MCLA = hashTable[0];
658  ENET_MAC->MCHA = hashTable[1];
659 
660  //Debug message
661  TRACE_DEBUG(" ENET_MCLA = %08" PRIX32 "\r\n", ENET_MAC->MCLA);
662  TRACE_DEBUG(" ENET_MCHA = %08" PRIX32 "\r\n", ENET_MAC->MCHA);
663 
664  //Successful processing
665  return NO_ERROR;
666 }
667 
668 
669 /**
670  * @brief Adjust MAC configuration parameters for proper operation
671  * @param[in] interface Underlying network interface
672  * @return Error code
673  **/
674 
676 {
677  uint32_t config;
678 
679  //Read current MAC configuration
680  config = ENET_MAC->MCR;
681 
682  //Half-duplex or full-duplex mode?
683  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
684  {
685  //Full-duplex mode
686  config |= ENET_MCR_FDM;
687  //Enable the reception path during transmission
688  config &= ~ENET_MCR_DRO;
689  }
690  else
691  {
692  //Half-duplex mode
693  config &= ~ENET_MCR_FDM;
694  //Disable the reception path during transmission
695  config |= ENET_MCR_DRO;
696  }
697 
698  //Update MAC configuration register
699  ENET_MAC->MCR = config;
700 
701  //Successful processing
702  return NO_ERROR;
703 }
704 
705 
706 /**
707  * @brief Write PHY register
708  * @param[in] opcode Access type (2 bits)
709  * @param[in] phyAddr PHY address (5 bits)
710  * @param[in] regAddr Register address (5 bits)
711  * @param[in] data Register value
712  **/
713 
714 void str912EthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
715  uint8_t regAddr, uint16_t data)
716 {
717  uint32_t temp;
718 
719  //Valid opcode?
720  if(opcode == SMI_OPCODE_WRITE)
721  {
722  //Set up a write operation
723  temp = ENET_MIIA_WR | ENET_MIIA_BUSY;
724  //PHY address
725  temp |= (phyAddr << 11) & ENET_MIIA_PADDR;
726  //Register address
727  temp |= (regAddr << 6) & ENET_MIIA_RADDR;
728 
729  //Data to be written in the PHY register
730  ENET_MAC->MIID = data & ENET_MIID_RDATA;
731 
732  //Start a write operation
733  ENET_MAC->MIIA = temp;
734  //Wait for the write to complete
735  while((ENET_MAC->MIIA & ENET_MIIA_BUSY) != 0)
736  {
737  }
738  }
739  else
740  {
741  //The MAC peripheral only supports standard Clause 22 opcodes
742  }
743 }
744 
745 
746 /**
747  * @brief Read PHY register
748  * @param[in] opcode Access type (2 bits)
749  * @param[in] phyAddr PHY address (5 bits)
750  * @param[in] regAddr Register address (5 bits)
751  * @return Register value
752  **/
753 
754 uint16_t str912EthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
755  uint8_t regAddr)
756 {
757  uint16_t data;
758  uint32_t temp;
759 
760  //Valid opcode?
761  if(opcode == SMI_OPCODE_READ)
762  {
763  //Set up a read operation
764  temp = ENET_MIIA_BUSY;
765  //PHY address
766  temp |= (phyAddr << 11) & ENET_MIIA_PADDR;
767  //Register address
768  temp |= (regAddr << 6) & ENET_MIIA_RADDR;
769 
770  //Start a read operation
771  ENET_MAC->MIIA = temp;
772  //Wait for the read to complete
773  while((ENET_MAC->MIIA & ENET_MIIA_BUSY) != 0)
774  {
775  }
776 
777  //Get register value
778  data = ENET_MAC->MIID & ENET_MIID_RDATA;
779  }
780  else
781  {
782  //The MAC peripheral only supports standard Clause 22 opcodes
783  data = 0;
784  }
785 
786  //Return the value of the PHY register
787  return data;
788 }
789 
790 
791 /**
792  * @brief CRC calculation
793  * @param[in] data Pointer to the data over which to calculate the CRC
794  * @param[in] length Number of bytes to process
795  * @return Resulting CRC value
796  **/
797 
798 uint32_t str912EthCalcCrc(const void *data, size_t length)
799 {
800  uint_t i;
801  uint_t j;
802  uint32_t crc;
803  const uint8_t *p;
804 
805  //Point to the data over which to calculate the CRC
806  p = (uint8_t *) data;
807  //CRC preset value
808  crc = 0xFFFFFFFF;
809 
810  //Loop through data
811  for(i = 0; i < length; i++)
812  {
813  //The message is processed bit by bit
814  for(j = 0; j < 8; j++)
815  {
816  //Update CRC value
817  if((((crc >> 31) ^ (p[i] >> j)) & 0x01) != 0)
818  {
819  crc = (crc << 1) ^ 0x04C11DB7;
820  }
821  else
822  {
823  crc = crc << 1;
824  }
825  }
826  }
827 
828  //Return CRC value
829  return crc;
830 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define ENET_MCR_RVFF
error_t str912EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define ENET_MIIA_BUSY
#define ENET_MCR_TE
error_t str912EthInit(NetInterface *interface)
STR912 Ethernet MAC initialization.
uint8_t opcode
Definition: dns_common.h:188
#define STR912_ETH_IRQ_PRIORITY
int bool_t
Definition: compiler_port.h:53
#define ENET_MCR_PS_1
#define netEvent
Definition: net_legacy.h:196
uint16_t str912EthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define ENET_RDES_START_ADDR
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define ENET_TXSTR_UNDER_RUN
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:690
uint8_t p
Definition: ndp.h:300
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
#define ENET_SCR_SRESET
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
#define TRUE
Definition: os_port.h:50
uint32_t str912EthCalcCrc(const void *data, size_t length)
CRC calculation.
uint8_t data[]
Definition: ethernet.h:222
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:264
void str912EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define STR912_ETH_RX_BUFFER_SIZE
#define ENET_TXSTR_DFETCH_DLY_DEFAULT
#define ENET_RDES_NEXT_ADDR
#define ENET_TDES_START_ADDR
__weak_func void str912EthInitGpio(NetInterface *interface)
GPIO configuration.
#define STR912_ETH_TX_BUFFER_SIZE
#define ENET_RDES_STATUS_ERROR
#define ENET_ISR_TX_CURR_DONE
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:392
#define osExitIsr(flag)
#define ENET_MCR_BL_1
void str912EthDisableIrq(NetInterface *interface)
Disable interrupts.
#define SMI_OPCODE_WRITE
Definition: nic.h:66
#define ENET_TDES_CTRL_NXT_EN
#define ENET_MIIA_RADDR
#define FALSE
Definition: os_port.h:46
#define ENET_IER_RX_CURR_DONE_EN
#define STR912_ETH_RX_BUFFER_COUNT
error_t
Error codes.
Definition: error.h:43
#define STR912_ETH_TX_BUFFER_COUNT
error_t str912EthReceivePacket(NetInterface *interface)
Receive a packet.
#define ENET_RDES_CTRL_NXT_EN
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:104
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define txBuffer
#define NetRxAncillary
Definition: net_misc.h:40
@ ERROR_INVALID_PACKET
Definition: error.h:140
#define NetInterface
Definition: net.h:36
void ENET_IRQHandler(void)
STR912 Ethernet MAC interrupt service routine.
MacAddr addr
MAC address.
Definition: ethernet.h:263
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define ENET_RDES_STATUS_VALID
void str912EthEventHandler(NetInterface *interface)
STR912 Ethernet MAC event handler.
error_t str912EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
#define NetTxAncillary
Definition: net_misc.h:36
#define SMI_OPCODE_READ
Definition: nic.h:67
#define ENET_RDES_STATUS_FL
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t length
Definition: tcp.h:368
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define MIN(a, b)
Definition: os_port.h:63
#define ENET_RDES_NEXT_NPOL_EN
#define rxBuffer
MacAddr
Definition: ethernet.h:195
#define ENET_MCR_FDM
#define ENET_MIIA_WR
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define ENET_ISR_RX_CURR_DONE
error_t str912EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define ENET_RXSTR_START_FETCH
uint16_t regAddr
Transmit DMA descriptor.
#define ETH_MTU
Definition: ethernet.h:116
uint8_t n
MAC filter table entry.
Definition: ethernet.h:262
#define osEnterIsr()
#define ENET_MIID_RDATA
#define ENET_TXSTR_DMA_EN
#define ENET_RXSTR_DMA_EN
#define rxDmaDesc
void str912EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
#define ENET_TXSTR_START_FETCH
void str912EthTick(NetInterface *interface)
STR912 Ethernet MAC timer handler.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define ENET_TDES_NEXT_ADDR
#define txDmaDesc
#define ENET_MCR_DRO
#define ENET_IER_TX_CURR_DONE_EN
#define ENET_TDES_STATUS_VALID
const NicDriver str912EthDriver
STR912 Ethernet MAC driver.
Receive DMA descriptor.
#define ENET_RXSTR_DFETCH_DLY_DEFAULT
STR9 Ethernet MAC driver.
void str912EthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define ENET_MIIA_PADDR
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
#define ENET_TDES_NEXT_NPOL_EN
NIC driver.
Definition: nic.h:286
#define ENET_MCR_RVBE
#define ENET_MCR_AFM_1
#define ENET_MCR_DCE
@ NO_ERROR
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
#define ENET_MCR_RE
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83