ksz8851_driver.c
Go to the documentation of this file.
1 /**
2  * @file ksz8851_driver.c
3  * @brief KSZ8851 Ethernet controller
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 "core/net.h"
37 #include "debug.h"
38 
39 
40 /**
41  * @brief KSZ8851 driver
42  **/
43 
45 {
47  ETH_MTU,
55  NULL,
56  NULL,
57  NULL,
58  TRUE,
59  TRUE,
60  TRUE,
61  FALSE
62 };
63 
64 
65 /**
66  * @brief KSZ8851 controller initialization
67  * @param[in] interface Underlying network interface
68  * @return Error code
69  **/
70 
72 {
73  Ksz8851Context *context;
74 
75  //Point to the driver context
76  context = (Ksz8851Context *) interface->nicContext;
77 
78  //Debug message
79  TRACE_INFO("Initializing KSZ8851 Ethernet controller...\r\n");
80 
81 #if (KSZ8851_SPI_SUPPORT == ENABLED)
82  //Initialize SPI interface
83  interface->spiDriver->init();
84 #endif
85 
86  //Initialize external interrupt line driver
87  if(interface->extIntDriver != NULL)
88  {
89  interface->extIntDriver->init();
90  }
91 
92  //Debug message
93  TRACE_DEBUG("CIDER=0x%04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_CIDER));
94  TRACE_DEBUG("PHY1ILR=0x%04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_PHY1ILR));
95  TRACE_DEBUG("PHY1IHR=0x%04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_PHY1IHR));
96 
97  //Check device ID and revision ID
100  {
101  return ERROR_WRONG_IDENTIFIER;
102  }
103 
104  //Dump registers for debugging purpose
105  ksz8851DumpReg(interface);
106 
107  //Initialize driver specific variables
108  context->frameId = 0;
109 
110  //Initialize MAC address
111  ksz8851WriteReg(interface, KSZ8851_MARH, htons(interface->macAddr.w[0]));
112  ksz8851WriteReg(interface, KSZ8851_MARM, htons(interface->macAddr.w[1]));
113  ksz8851WriteReg(interface, KSZ8851_MARL, htons(interface->macAddr.w[2]));
114 
115  //Packets shorter than 64 bytes are padded and the CRC is automatically
116  //generated
119 
120  //Automatically increment TX data pointer
122 
123  //Configure address filtering
127 
128  //No checksum verification
131 
132  //Enable automatic RXQ frame buffer dequeue
135 
136  //Automatically increment RX data pointer
138  //Configure receive frame count threshold
139  ksz8851WriteReg(interface, KSZ8851_RXFCTR, 1);
140 
141  //Force link in half-duplex if auto-negotiation failed
143  //Restart auto-negotiation
145 
146  //Clear interrupt flags
152 
153  //Configure interrupts as desired
156 
157  //Enable TX operation
159  //Enable RX operation
161 
162  //Perform custom configuration
163  ksz8851InitHook(interface);
164 
165  //Accept any packets from the upper layer
166  osSetEvent(&interface->nicTxEvent);
167 
168  //Force the TCP/IP stack to poll the link state at startup
169  interface->nicEvent = TRUE;
170  //Notify the TCP/IP stack of the event
172 
173  //Successful initialization
174  return NO_ERROR;
175 }
176 
177 
178 /**
179  * @brief KSZ8851 custom configuration
180  * @param[in] interface Underlying network interface
181  **/
182 
183 __weak_func void ksz8851InitHook(NetInterface *interface)
184 {
185 }
186 
187 
188 /**
189  * @brief KSZ8851 timer handler
190  * @param[in] interface Underlying network interface
191  **/
192 
193 void ksz8851Tick(NetInterface *interface)
194 {
195 }
196 
197 
198 /**
199  * @brief Enable interrupts
200  * @param[in] interface Underlying network interface
201  **/
202 
204 {
205  //Enable interrupts
206  if(interface->extIntDriver != NULL)
207  {
208  interface->extIntDriver->enableIrq();
209  }
210 }
211 
212 
213 /**
214  * @brief Disable interrupts
215  * @param[in] interface Underlying network interface
216  **/
217 
219 {
220  //Disable interrupts
221  if(interface->extIntDriver != NULL)
222  {
223  interface->extIntDriver->disableIrq();
224  }
225 }
226 
227 
228 /**
229  * @brief KSZ8851 interrupt service routine
230  * @param[in] interface Underlying network interface
231  * @return TRUE if a higher priority task must be woken. Else FALSE is returned
232  **/
233 
235 {
236  bool_t flag;
237  size_t n;
238  uint16_t ier;
239  uint16_t isr;
240 
241  //This flag will be set if a higher priority task must be woken
242  flag = FALSE;
243 
244  //Save IER register value
245  ier = ksz8851ReadReg(interface, KSZ8851_IER);
246  //Disable interrupts to release the interrupt line
247  ksz8851WriteReg(interface, KSZ8851_IER, 0);
248 
249  //Read interrupt status register
250  isr = ksz8851ReadReg(interface, KSZ8851_ISR);
251 
252  //Link status change?
253  if((isr & KSZ8851_ISR_LCIS) != 0)
254  {
255  //Disable LCIE interrupt
256  ier &= ~KSZ8851_IER_LCIE;
257 
258  //Set event flag
259  interface->nicEvent = TRUE;
260  //Notify the TCP/IP stack of the event
261  flag |= osSetEventFromIsr(&netEvent);
262  }
263 
264  //Packet transmission complete?
265  if((isr & KSZ8851_ISR_TXIS) != 0)
266  {
267  //Clear interrupt flag
269 
270  //Get the amount of free memory available in the TX FIFO
272 
273  //Check whether the TX FIFO is available for writing
274  if(n >= (KSZ8851_ETH_TX_BUFFER_SIZE + 8))
275  {
276  //Notify the TCP/IP stack that the transmitter is ready to send
277  flag |= osSetEventFromIsr(&interface->nicTxEvent);
278  }
279  }
280 
281  //Packet received?
282  if((isr & KSZ8851_ISR_RXIS) != 0)
283  {
284  //Disable RXIE interrupt
285  ier &= ~KSZ8851_IER_RXIE;
286 
287  //Set event flag
288  interface->nicEvent = TRUE;
289  //Notify the TCP/IP stack of the event
290  flag |= osSetEventFromIsr(&netEvent);
291  }
292 
293  //Re-enable interrupts once the interrupt has been serviced
294  ksz8851WriteReg(interface, KSZ8851_IER, ier);
295 
296  //A higher priority task must be woken?
297  return flag;
298 }
299 
300 
301 /**
302  * @brief KSZ8851 event handler
303  * @param[in] interface Underlying network interface
304  **/
305 
307 {
308  uint16_t isr;
309  uint16_t psr;
310  uint_t frameCount;
311 
312  //Read interrupt status register
313  isr = ksz8851ReadReg(interface, KSZ8851_ISR);
314 
315  //Link status change?
316  if((isr & KSZ8851_ISR_LCIS) != 0)
317  {
318  //Clear interrupt flag
320  //Read PHY status register
321  psr = ksz8851ReadReg(interface, KSZ8851_P1SR);
322 
323  //Check link state
324  if((psr & KSZ8851_P1SR_LINK_GOOD) != 0)
325  {
326  //Get current speed
327  if((psr & KSZ8851_P1SR_OPERATION_SPEED) != 0)
328  {
329  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
330  }
331  else
332  {
333  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
334  }
335 
336  //Determine the new duplex mode
337  if((psr & KSZ8851_P1SR_OPERATION_DUPLEX) != 0)
338  {
339  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
340  }
341  else
342  {
343  interface->duplexMode = NIC_HALF_DUPLEX_MODE;
344  }
345 
346  //Link is up
347  interface->linkState = TRUE;
348  }
349  else
350  {
351  //Link is down
352  interface->linkState = FALSE;
353  }
354 
355  //Process link state change event
356  nicNotifyLinkChange(interface);
357  }
358 
359  //Packet received?
360  if((isr & KSZ8851_ISR_RXIS) != 0)
361  {
362  //Clear interrupt flag
364  //Get the total number of frames that are pending in the buffer
365  frameCount = MSB(ksz8851ReadReg(interface, KSZ8851_RXFCTR));
366 
367  //Process all pending packets
368  while(frameCount > 0)
369  {
370  //Read incoming packet
371  ksz8851ReceivePacket(interface);
372  //Decrement frame counter
373  frameCount--;
374  }
375  }
376 
377  //Re-enable LCIE and RXIE interrupts
379 }
380 
381 
382 /**
383  * @brief Send a packet
384  * @param[in] interface Underlying network interface
385  * @param[in] buffer Multi-part buffer containing the data to send
386  * @param[in] offset Offset to the first data byte
387  * @param[in] ancillary Additional options passed to the stack along with
388  * the packet
389  * @return Error code
390  **/
391 
393  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
394 {
395  static uint8_t temp[KSZ8851_ETH_TX_BUFFER_SIZE];
396  size_t n;
397  size_t length;
398  Ksz8851TxHeader header;
399  Ksz8851Context *context;
400 
401  //Point to the driver context
402  context = (Ksz8851Context *) interface->nicContext;
403 
404  //Retrieve the length of the packet
405  length = netBufferGetLength(buffer) - offset;
406 
407  //Check the frame length
409  {
410  //The transmitter can accept another packet
411  osSetEvent(&interface->nicTxEvent);
412  //Report an error
413  return ERROR_INVALID_LENGTH;
414  }
415 
416  //Get the amount of free memory available in the TX FIFO
418 
419  //Make sure the TX FIFO is available for writing
420  if(n < (length + 8))
421  {
422  return ERROR_FAILURE;
423  }
424 
425  //Copy user data
426  netBufferRead(temp, buffer, offset, length);
427 
428  //Format control word
429  header.controlWord = htole16(KSZ8851_TX_CTRL_TXIC |
430  (context->frameId++ & KSZ8851_TX_CTRL_TXFID));
431 
432  //Total number of bytes to be transmitted
433  header.byteCount = htole16(length);
434 
435  //Enable TXQ write access
437  //Write TX packet header
438  ksz8851WriteFifo(interface, (uint8_t *) &header, sizeof(Ksz8851TxHeader));
439  //Write data
440  ksz8851WriteFifo(interface, temp, length);
441  //End TXQ write access
443 
444  //Start transmission
446 
447  //Get the amount of free memory available in the TX FIFO
449 
450  //Check whether the TX FIFO is available for writing
451  if(n >= (KSZ8851_ETH_TX_BUFFER_SIZE + 8))
452  {
453  //The transmitter can accept another packet
454  osSetEvent(&interface->nicTxEvent);
455  }
456 
457  //Successful processing
458  return NO_ERROR;
459 }
460 
461 
462 /**
463  * @brief Receive a packet
464  * @param[in] interface Underlying network interface
465  * @return Error code
466  **/
467 
469 {
470  static uint8_t temp[KSZ8851_ETH_RX_BUFFER_SIZE];
471  error_t error;
472  size_t length;
473  uint16_t status;
474 
475  //Read received frame status from RXFHSR
476  status = ksz8851ReadReg(interface, KSZ8851_RXFHSR);
477 
478  //Make sure the frame is valid
479  if((status & KSZ8851_RXFHSR_RXFV) != 0)
480  {
481  //Check error flags
482  if((status & (KSZ8851_RXFHSR_RXMR | KSZ8851_RXFHSR_RXFTL |
484  {
485  //Read received frame byte size from RXFHBCR
487 
488  //Check packet length
490  {
491  //Reset QMU RXQ frame pointer to zero
493  //Enable RXQ read access
495  //Read packet data
496  ksz8851ReadFifo(interface, temp, length);
497  //End RXQ read access
499 
500  //Valid packet received
501  error = NO_ERROR;
502  }
503  else
504  {
505  //The packet length is not acceptable
506  error = ERROR_INVALID_LENGTH;
507  }
508  }
509  else
510  {
511  //The received packet contains an error
512  error = ERROR_INVALID_PACKET;
513  }
514  }
515  else
516  {
517  //The received packet is not valid
518  error = ERROR_INVALID_PACKET;
519  }
520 
521  //Check whether a valid packet has been received
522  if(!error)
523  {
524  NetRxAncillary ancillary;
525 
526  //Additional options can be passed to the stack along with the packet
527  ancillary = NET_DEFAULT_RX_ANCILLARY;
528 
529  //Pass the packet to the upper layer
530  nicProcessPacket(interface, temp, length, &ancillary);
531  }
532  else
533  {
534  //Release the current error frame from RXQ
536  }
537 
538  //Return status code
539  return error;
540 }
541 
542 
543 /**
544  * @brief Configure MAC address filtering
545  * @param[in] interface Underlying network interface
546  * @return Error code
547  **/
548 
550 {
551  uint_t i;
552  uint_t k;
553  uint32_t crc;
554  uint16_t hashTable[4];
555  MacFilterEntry *entry;
556 
557  //Debug message
558  TRACE_DEBUG("Updating MAC filter...\r\n");
559 
560  //Clear hash table
561  osMemset(hashTable, 0, sizeof(hashTable));
562 
563  //The MAC address filter contains the list of MAC addresses to accept
564  //when receiving an Ethernet frame
565  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
566  {
567  //Point to the current entry
568  entry = &interface->macAddrFilter[i];
569 
570  //Valid entry?
571  if(entry->refCount > 0)
572  {
573  //Compute CRC over the current MAC address
574  crc = ksz8851CalcCrc(&entry->addr, sizeof(MacAddr));
575  //Calculate the corresponding index in the table
576  k = (crc >> 26) & 0x3F;
577  //Update hash table contents
578  hashTable[k / 16] |= (1 << (k % 16));
579  }
580  }
581 
582  //Write the hash table to the KSZ8851 controller
583  ksz8851WriteReg(interface, KSZ8851_MAHTR0, hashTable[0]);
584  ksz8851WriteReg(interface, KSZ8851_MAHTR1, hashTable[1]);
585  ksz8851WriteReg(interface, KSZ8851_MAHTR2, hashTable[2]);
586  ksz8851WriteReg(interface, KSZ8851_MAHTR3, hashTable[3]);
587 
588  //Debug message
589  TRACE_DEBUG(" MAHTR0 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_MAHTR0));
590  TRACE_DEBUG(" MAHTR1 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_MAHTR1));
591  TRACE_DEBUG(" MAHTR2 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_MAHTR2));
592  TRACE_DEBUG(" MAHTR3 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_MAHTR3));
593 
594  //Successful processing
595  return NO_ERROR;
596 }
597 
598 
599 /**
600  * @brief Write KSZ8851 register
601  * @param[in] interface Underlying network interface
602  * @param[in] address Register address
603  * @param[in] data Register value
604  **/
605 
606 void ksz8851WriteReg(NetInterface *interface, uint8_t address, uint16_t data)
607 {
608 #if (KSZ8851_SPI_SUPPORT == ENABLED)
609  uint8_t command;
610 
611  //Form the write command
612  if((address & 0x02) != 0)
613  {
615  }
616  else
617  {
619  }
620 
621  //Pull the CS pin low
622  interface->spiDriver->assertCs();
623 
624  //Command phase
625  interface->spiDriver->transfer(command | (address >> 6));
626  interface->spiDriver->transfer(address << 2);
627 
628  //Data phase
629  interface->spiDriver->transfer(LSB(data));
630  interface->spiDriver->transfer(MSB(data));
631 
632  //Terminate the operation by raising the CS pin
633  interface->spiDriver->deassertCs();
634 #else
635  //Set register address
636  if((address & 0x02) != 0)
637  {
639  }
640  else
641  {
643  }
644 
645  //Write register value
647 #endif
648 }
649 
650 
651 /**
652  * @brief Read KSZ8851 register
653  * @param[in] interface Underlying network interface
654  * @param[in] address Register address
655  * @return Register value
656  **/
657 
658 uint16_t ksz8851ReadReg(NetInterface *interface, uint8_t address)
659 {
660 #if (KSZ8851_SPI_SUPPORT == ENABLED)
661  uint8_t command;
662  uint16_t data;
663 
664  //Form the read command
665  if((address & 0x02) != 0)
666  {
668  }
669  else
670  {
672  }
673 
674  //Pull the CS pin low
675  interface->spiDriver->assertCs();
676 
677  //Command phase
678  interface->spiDriver->transfer(command | (address >> 6));
679  interface->spiDriver->transfer(address << 2);
680 
681  //Data phase (lower 8 bits)
682  data = interface->spiDriver->transfer(0x00);
683  //Data phase (upper 8 bits)
684  data |= interface->spiDriver->transfer(0x00) << 8;
685 
686  //Terminate the operation by raising the CS pin
687  interface->spiDriver->deassertCs();
688 
689  //Return register value
690  return data;
691 #else
692  //Set register address
693  if((address & 0x02) != 0)
694  {
696  }
697  else
698  {
700  }
701 
702  //Return register value
703  return KSZ8851_DATA_REG;
704 #endif
705 }
706 
707 
708 /**
709  * @brief Write TX FIFO
710  * @param[in] interface Underlying network interface
711  * @param[in] data Pointer to the data being written
712  * @param[in] length Number of data to write
713  **/
714 
715 void ksz8851WriteFifo(NetInterface *interface, const uint8_t *data,
716  size_t length)
717 {
718 #if (KSZ8851_SPI_SUPPORT == ENABLED)
719  size_t i;
720 
721  //Pull the CS pin low
722  interface->spiDriver->assertCs();
723 
724  //Command phase
725  interface->spiDriver->transfer(KSZ8851_CMD_WR_FIFO);
726 
727  //Data phase
728  for(i = 0; i < length; i++)
729  {
730  interface->spiDriver->transfer(data[i]);
731  }
732 
733  //Maintain alignment to 4-byte boundaries
734  for(; (i % 4) != 0; i++)
735  {
736  interface->spiDriver->transfer(0x00);
737  }
738 
739  //Terminate the operation by raising the CS pin
740  interface->spiDriver->deassertCs();
741 #else
742  size_t i;
743 
744  //Data phase
745  for(i = 0; i < length; i += 2)
746  {
747  KSZ8851_DATA_REG = data[i] | data[i + 1] << 8;
748  }
749 
750  //Maintain alignment to 4-byte boundaries
751  for(; (i % 4) != 0; i += 2)
752  {
753  KSZ8851_DATA_REG = 0x0000;
754  }
755 #endif
756 }
757 
758 
759 /**
760  * @brief Read RX FIFO
761  * @param[in] interface Underlying network interface
762  * @param[out] data Buffer where to store the incoming data
763  * @param[in] length Number of data to read
764  **/
765 
766 void ksz8851ReadFifo(NetInterface *interface, uint8_t *data, size_t length)
767 {
768 #if (KSZ8851_SPI_SUPPORT == ENABLED)
769  size_t i;
770 
771  //Pull the CS pin low
772  interface->spiDriver->assertCs();
773 
774  //Command phase
775  interface->spiDriver->transfer(KSZ8851_CMD_RD_FIFO);
776 
777  //The first 4 bytes are dummy data and must be discarded
778  for(i = 0; i < 4; i++)
779  {
780  interface->spiDriver->transfer(0x00);
781  }
782 
783  //Ignore RX packet header
784  for(i = 0; i < 4; i++)
785  {
786  interface->spiDriver->transfer(0x00);
787  }
788 
789  //Data phase
790  for(i = 0; i < length; i++)
791  {
792  data[i] = interface->spiDriver->transfer(0x00);
793  }
794 
795  //Maintain alignment to 4-byte boundaries
796  for(; (i % 4) != 0; i++)
797  {
798  interface->spiDriver->transfer(0x00);
799  }
800 
801  //Terminate the operation by raising the CS pin
802  interface->spiDriver->deassertCs();
803 #else
804  size_t i;
805  uint16_t temp;
806 
807  //The first 2 bytes are dummy data and must be discarded
808  temp = KSZ8851_DATA_REG;
809 
810  //Ignore RX packet header
811  temp = KSZ8851_DATA_REG;
812  temp = KSZ8851_DATA_REG;
813 
814  //Data phase
815  for(i = 0; i < length; i += 2)
816  {
817  temp = KSZ8851_DATA_REG;
818  data [i] = temp & 0xFF;
819  data [i + 1] = (temp >> 8) & 0xFF;
820  }
821 
822  //Maintain alignment to 4-byte boundaries
823  for(; (i % 4) != 0; i += 2)
824  {
825  temp = KSZ8851_DATA_REG;
826  }
827 #endif
828 }
829 
830 
831 /**
832  * @brief Set bit field
833  * @param[in] interface Underlying network interface
834  * @param[in] address Register address
835  * @param[in] mask Bits to set in the target register
836  **/
837 
838 void ksz8851SetBit(NetInterface *interface, uint8_t address, uint16_t mask)
839 {
840  uint16_t value;
841 
842  //Read current register value
843  value = ksz8851ReadReg(interface, address);
844  //Set specified bits
845  ksz8851WriteReg(interface, address, value | mask);
846 }
847 
848 
849 /**
850  * @brief Clear bit field
851  * @param[in] interface Underlying network interface
852  * @param[in] address Register address
853  * @param[in] mask Bits to clear in the target register
854  **/
855 
856 void ksz8851ClearBit(NetInterface *interface, uint8_t address, uint16_t mask)
857 {
858  uint16_t value;
859 
860  //Read current register value
861  value = ksz8851ReadReg(interface, address);
862  //Clear specified bits
863  ksz8851WriteReg(interface, address, value & ~mask);
864 }
865 
866 
867 /**
868  * @brief CRC calculation
869  * @param[in] data Pointer to the data over which to calculate the CRC
870  * @param[in] length Number of bytes to process
871  * @return Resulting CRC value
872  **/
873 
874 uint32_t ksz8851CalcCrc(const void *data, size_t length)
875 {
876  uint_t i;
877  uint_t j;
878  uint32_t crc;
879  const uint8_t *p;
880 
881  //Point to the data over which to calculate the CRC
882  p = (uint8_t *) data;
883  //CRC preset value
884  crc = 0xFFFFFFFF;
885 
886  //Loop through data
887  for(i = 0; i < length; i++)
888  {
889  //The message is processed bit by bit
890  for(j = 0; j < 8; j++)
891  {
892  //Update CRC value
893  if((((crc >> 31) ^ (p[i] >> j)) & 0x01) != 0)
894  {
895  crc = (crc << 1) ^ 0x04C11DB7;
896  }
897  else
898  {
899  crc = crc << 1;
900  }
901  }
902  }
903 
904  //Return CRC value
905  return crc;
906 }
907 
908 
909 /**
910  * @brief Dump registers for debugging purpose
911  * @param[in] interface Underlying network interface
912  **/
913 
914 void ksz8851DumpReg(NetInterface *interface)
915 {
916 #if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
917  uint_t i;
918  uint_t j;
919  uint_t address;
920 
921  //Loop through register addresses
922  for(i = 0; i < 256; i += 16)
923  {
924  //Display register address
925  TRACE_DEBUG("%02" PRIu8 ": ", i);
926 
927  //Display 8 registers at a time
928  for(j = 0; j < 16; j += 2)
929  {
930  //Format register address
931  address = i + j;
932  //Display register contents
933  TRACE_DEBUG("0x%04" PRIX16 " ", ksz8851ReadReg(interface, address));
934  }
935 
936  //Jump to the following line
937  TRACE_DEBUG("\r\n");
938  }
939 
940  //Terminate with a line feed
941  TRACE_DEBUG("\r\n");
942 #endif
943 }
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
#define htons(value)
Definition: cpu_endian.h:413
#define htole16(value)
Definition: cpu_endian.h:429
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ 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
MacAddr
Definition: ethernet.h:195
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
Ipv6Addr address[]
Definition: ipv6.h:316
error_t ksz8851UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void ksz8851WriteReg(NetInterface *interface, uint8_t address, uint16_t data)
Write KSZ8851 register.
error_t ksz8851Init(NetInterface *interface)
KSZ8851 controller initialization.
void ksz8851DumpReg(NetInterface *interface)
Dump registers for debugging purpose.
void ksz8851Tick(NetInterface *interface)
KSZ8851 timer handler.
void ksz8851EnableIrq(NetInterface *interface)
Enable interrupts.
const NicDriver ksz8851Driver
KSZ8851 driver.
error_t ksz8851SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
uint32_t ksz8851CalcCrc(const void *data, size_t length)
CRC calculation.
void ksz8851SetBit(NetInterface *interface, uint8_t address, uint16_t mask)
Set bit field.
void ksz8851ReadFifo(NetInterface *interface, uint8_t *data, size_t length)
Read RX FIFO.
error_t ksz8851ReceivePacket(NetInterface *interface)
Receive a packet.
void ksz8851EventHandler(NetInterface *interface)
KSZ8851 event handler.
void ksz8851WriteFifo(NetInterface *interface, const uint8_t *data, size_t length)
Write TX FIFO.
void ksz8851ClearBit(NetInterface *interface, uint8_t address, uint16_t mask)
Clear bit field.
__weak_func void ksz8851InitHook(NetInterface *interface)
KSZ8851 custom configuration.
void ksz8851DisableIrq(NetInterface *interface)
Disable interrupts.
bool_t ksz8851IrqHandler(NetInterface *interface)
KSZ8851 interrupt service routine.
uint16_t ksz8851ReadReg(NetInterface *interface, uint8_t address)
Read KSZ8851 register.
KSZ8851 Ethernet controller.
#define KSZ8851_RXFHSR_RXFTL
#define KSZ8851_TX_CTRL_TXFID
#define KSZ8851_TXCR
#define KSZ8851_TX_CTRL_TXIC
#define KSZ8851_RXCR1_RXPAFMA
#define KSZ8851_ISR_EDIS
#define KSZ8851_CMD_B2
#define KSZ8851_CMD_RD_FIFO
#define KSZ8851_P1CR_RESTART_AN
#define KSZ8851_MAHTR1
#define KSZ8851_ISR_TXSAIS
#define KSZ8851_RXFHSR_RXRF
Ksz8851TxHeader
#define KSZ8851_RXQCR_RXFCTE
#define KSZ8851_TXCR_TXFCE
#define KSZ8851_PHY1ILR
#define KSZ8851_ISR_SPIBEIS
#define KSZ8851_CMD_WR_REG
#define KSZ8851_CIDER
#define KSZ8851_TXCR_TXCE
#define KSZ8851_P1SR_OPERATION_DUPLEX
#define KSZ8851_RXFHSR_RXCE
#define KSZ8851_TXMIR_TXMA
#define KSZ8851_TXCR_TXE
#define KSZ8851_MAHTR2
#define KSZ8851_RXFDPR_RXFPAI
#define KSZ8851_TXMIR
#define KSZ8851_RXCR1
#define KSZ8851_PHY1IHR
#define KSZ8851_TXFDPR_TXFPAI
#define KSZ8851_P1SR_LINK_GOOD
#define KSZ8851_IER_RXIE
#define KSZ8851_ISR_RXOIS
#define KSZ8851_RXCR1_RXUE
#define KSZ8851_RXCR1_RXBE
#define KSZ8851_RXFHSR_RXFV
#define KSZ8851_CMD_B1
#define KSZ8851_RXFCTR
#define KSZ8851_P1CR_FORCE_DUPLEX
#define KSZ8851_RXFHBCR
#define KSZ8851_RXCR1_RXE
#define KSZ8851_RXQCR_RRXEF
#define KSZ8851_RXQCR_ADRFE
#define KSZ8851_CMD_B3
#define KSZ8851_RXCR1_RXME
#define KSZ8851_TXFDPR
#define KSZ8851_P1SR_OPERATION_SPEED
#define KSZ8851_RXFHBCR_RXBC
#define KSZ8851_RXFDPR
#define KSZ8851_IER_LCIE
#define KSZ8851_ISR_LDIS
#define KSZ8851_RXCR2
#define KSZ8851_TXQCR
#define KSZ8851_P1SR
#define KSZ8851_IER
#define KSZ8851_DATA_REG
#define KSZ8851_RXCR2_IUFFP
#define KSZ8851_MAHTR0
#define KSZ8851_ETH_RX_BUFFER_SIZE
#define KSZ8851_MAHTR3
#define KSZ8851_RXCR2_RXIUFCEZ
#define KSZ8851_ISR
#define KSZ8851_CMD_RD_REG
#define KSZ8851_TXQCR_METFE
#define KSZ8851_CIDER_FAMILY_ID_DEFAULT
#define KSZ8851_ISR_RXIS
#define KSZ8851_ISR_RXWFDIS
#define KSZ8851_CMD_WR_FIFO
#define KSZ8851_ISR_RXPSIS
#define KSZ8851_RXCR2_SRDBL_SINGLE_FRAME
#define KSZ8851_ISR_TXPSIS
#define KSZ8851_TXCR_TXPE
#define KSZ8851_ISR_RXMPDIS
#define KSZ8851_MARL
#define KSZ8851_CMD_REG
#define KSZ8851_MARH
#define KSZ8851_ISR_TXIS
#define KSZ8851_RXCR1_RXFCE
#define KSZ8851_CIDER_CHIP_ID_DEFAULT
#define KSZ8851_ISR_LCIS
#define KSZ8851_P1CR
#define KSZ8851_RXQCR
#define KSZ8851_MARM
#define KSZ8851_RXFHSR_RXMR
#define KSZ8851_CIDER_REV_ID_A3
#define KSZ8851_RXQCR_SDA
#define KSZ8851_IER_TXIE
#define KSZ8851_RXFHSR
#define KSZ8851_ETH_TX_BUFFER_SIZE
#define KSZ8851_CMD_B0
uint8_t p
Definition: ndp.h:300
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
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:548
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
@ NIC_HALF_DUPLEX_MODE
Definition: nic.h:124
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:112
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:111
#define osMemset(p, value, length)
Definition: os_port.h:135
#define LSB(x)
Definition: os_port.h:55
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define MSB(x)
Definition: os_port.h:59
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.
KSZ8851 driver context.
uint16_t frameId
Identify a frame and its associated status.
MAC filter table entry.
Definition: ethernet.h:262
MacAddr addr
MAC address.
Definition: ethernet.h:263
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:264
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:283
uint8_t length
Definition: tcp.h:368
uint8_t value[]
Definition: tcp.h:369
uint8_t mask
Definition: web_socket.h:319