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