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-2019 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 1.9.6
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  //Point to the driver context
74  Ksz8851Context *context = (Ksz8851Context *) interface->nicContext;
75 
76  //Debug message
77  TRACE_INFO("Initializing KSZ8851 Ethernet controller...\r\n");
78 
79 #if (KSZ8851_SPI_SUPPORT == ENABLED)
80  //Initialize SPI
81  interface->spiDriver->init();
82 #endif
83 
84  //Initialize external interrupt line
85  interface->extIntDriver->init();
86 
87  //Debug message
88  TRACE_DEBUG("CIDER=0x%04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_REG_CIDER));
89  TRACE_DEBUG("PHY1ILR=0x%04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_REG_PHY1ILR));
90  TRACE_DEBUG("PHY1IHR=0x%04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_REG_PHY1IHR));
91 
92  //Check device ID and revision ID
95 
96  //Dump registers for debugging purpose
97  ksz8851DumpReg(interface);
98 
99  //Initialize driver specific variables
100  context->frameId = 0;
101 
102  //Allocate TX and RX buffers
105 
106  //Failed to allocate memory?
107  if(context->txBuffer == NULL || context->rxBuffer == NULL)
108  {
109  //Clean up side effects
110  memPoolFree(context->txBuffer);
111  memPoolFree(context->rxBuffer);
112 
113  //Report an error
114  return ERROR_OUT_OF_MEMORY;
115  }
116 
117  //Initialize MAC address
118  ksz8851WriteReg(interface, KSZ8851_REG_MARH, htons(interface->macAddr.w[0]));
119  ksz8851WriteReg(interface, KSZ8851_REG_MARM, htons(interface->macAddr.w[1]));
120  ksz8851WriteReg(interface, KSZ8851_REG_MARL, htons(interface->macAddr.w[2]));
121 
122  //Packets shorter than 64 bytes are padded and the CRC is automatically generated
124  //Automatically increment TX data pointer
126 
127  //Configure address filtering
130 
131  //No checksum verification
134 
135  //Enable automatic RXQ frame buffer dequeue
137  //Automatically increment RX data pointer
139  //Configure receive frame count threshold
140  ksz8851WriteReg(interface, KSZ8851_REG_RXFCTR, 1);
141 
142  //Force link in half-duplex if auto-negotiation failed
144  //Restart auto-negotiation
146 
147  //Clear interrupt flags
151 
152  //Configure interrupts as desired
154 
155  //Enable TX operation
157  //Enable RX operation
159 
160  //Accept any packets from the upper layer
161  osSetEvent(&interface->nicTxEvent);
162 
163  //Force the TCP/IP stack to poll the link state at startup
164  interface->nicEvent = TRUE;
165  //Notify the TCP/IP stack of the event
167 
168  //Successful initialization
169  return NO_ERROR;
170 }
171 
172 
173 /**
174  * @brief KSZ8851 timer handler
175  * @param[in] interface Underlying network interface
176  **/
177 
178 void ksz8851Tick(NetInterface *interface)
179 {
180 }
181 
182 
183 /**
184  * @brief Enable interrupts
185  * @param[in] interface Underlying network interface
186  **/
187 
189 {
190  //Enable interrupts
191  interface->extIntDriver->enableIrq();
192 }
193 
194 
195 /**
196  * @brief Disable interrupts
197  * @param[in] interface Underlying network interface
198  **/
199 
201 {
202  //Disable interrupts
203  interface->extIntDriver->disableIrq();
204 }
205 
206 
207 /**
208  * @brief KSZ8851 interrupt service routine
209  * @param[in] interface Underlying network interface
210  * @return TRUE if a higher priority task must be woken. Else FALSE is returned
211  **/
212 
214 {
215  bool_t flag;
216  size_t n;
217  uint16_t ier;
218  uint16_t isr;
219 
220  //This flag will be set if a higher priority task must be woken
221  flag = FALSE;
222 
223  //Save IER register value
224  ier = ksz8851ReadReg(interface, KSZ8851_REG_IER);
225  //Disable interrupts to release the interrupt line
226  ksz8851WriteReg(interface, KSZ8851_REG_IER, 0);
227 
228  //Read interrupt status register
229  isr = ksz8851ReadReg(interface, KSZ8851_REG_ISR);
230 
231  //Link status change?
232  if(isr & ISR_LCIS)
233  {
234  //Disable LCIE interrupt
235  ier &= ~IER_LCIE;
236 
237  //Set event flag
238  interface->nicEvent = TRUE;
239  //Notify the TCP/IP stack of the event
240  flag |= osSetEventFromIsr(&netEvent);
241  }
242 
243  //Packet transmission complete?
244  if(isr & ISR_TXIS)
245  {
246  //Clear interrupt flag
248 
249  //Get the amount of free memory available in the TX FIFO
251 
252  //Check whether the TX FIFO is available for writing
253  if(n >= (ETH_MAX_FRAME_SIZE + 8))
254  {
255  //Notify the TCP/IP stack that the transmitter is ready to send
256  flag |= osSetEventFromIsr(&interface->nicTxEvent);
257  }
258  }
259 
260  //Packet received?
261  if(isr & ISR_RXIS)
262  {
263  //Disable RXIE interrupt
264  ier &= ~IER_RXIE;
265 
266  //Set event flag
267  interface->nicEvent = TRUE;
268  //Notify the TCP/IP stack of the event
269  flag |= osSetEventFromIsr(&netEvent);
270  }
271 
272  //Re-enable interrupts once the interrupt has been serviced
273  ksz8851WriteReg(interface, KSZ8851_REG_IER, ier);
274 
275  //A higher priority task must be woken?
276  return flag;
277 }
278 
279 
280 /**
281  * @brief KSZ8851 event handler
282  * @param[in] interface Underlying network interface
283  **/
284 
286 {
287  uint16_t status;
288  uint_t frameCount;
289 
290  //Read interrupt status register
291  status = ksz8851ReadReg(interface, KSZ8851_REG_ISR);
292 
293  //Check whether the link status has changed?
294  if(status & ISR_LCIS)
295  {
296  //Clear interrupt flag
298  //Read PHY status register
299  status = ksz8851ReadReg(interface, KSZ8851_REG_P1SR);
300 
301  //Check link state
302  if(status & P1SR_LINK_GOOD)
303  {
304  //Get current speed
305  if(status & P1SR_OPERATION_SPEED)
306  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
307  else
308  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
309 
310  //Determine the new duplex mode
311  if(status & P1SR_OPERATION_DUPLEX)
312  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
313  else
314  interface->duplexMode = NIC_HALF_DUPLEX_MODE;
315 
316  //Link is up
317  interface->linkState = TRUE;
318  }
319  else
320  {
321  //Link is down
322  interface->linkState = FALSE;
323  }
324 
325  //Process link state change event
326  nicNotifyLinkChange(interface);
327  }
328 
329  //Check whether a packet has been received?
330  if(status & ISR_RXIS)
331  {
332  //Clear interrupt flag
334  //Get the total number of frames that are pending in the buffer
335  frameCount = MSB(ksz8851ReadReg(interface, KSZ8851_REG_RXFCTR));
336 
337  //Process all pending packets
338  while(frameCount > 0)
339  {
340  //Read incoming packet
341  ksz8851ReceivePacket(interface);
342  //Decrement frame counter
343  frameCount--;
344  }
345  }
346 
347  //Re-enable LCIE and RXIE interrupts
349 }
350 
351 
352 /**
353  * @brief Send a packet
354  * @param[in] interface Underlying network interface
355  * @param[in] buffer Multi-part buffer containing the data to send
356  * @param[in] offset Offset to the first data byte
357  * @return Error code
358  **/
359 
361  const NetBuffer *buffer, size_t offset)
362 {
363  size_t n;
364  size_t length;
365  Ksz8851TxHeader header;
366  Ksz8851Context *context;
367 
368  //Point to the driver context
369  context = (Ksz8851Context *) interface->nicContext;
370 
371  //Retrieve the length of the packet
372  length = netBufferGetLength(buffer) - offset;
373 
374  //Check the frame length
376  {
377  //The transmitter can accept another packet
378  osSetEvent(&interface->nicTxEvent);
379  //Report an error
380  return ERROR_INVALID_LENGTH;
381  }
382 
383  //Get the amount of free memory available in the TX FIFO
385 
386  //Make sure the TX FIFO is available for writing
387  if(n < (length + 8))
388  return ERROR_FAILURE;
389 
390  //Copy user data
391  netBufferRead(context->txBuffer, buffer, offset, length);
392 
393  //Format control word
394  header.controlWord = TX_CTRL_TXIC | (context->frameId++ & TX_CTRL_TXFID);
395  //Total number of bytes to be transmitted
396  header.byteCount = length;
397 
398  //Enable TXQ write access
400  //Write TX packet header
401  ksz8851WriteFifo(interface, (uint8_t *) &header, sizeof(Ksz8851TxHeader));
402  //Write data
403  ksz8851WriteFifo(interface, context->txBuffer, length);
404  //End TXQ write access
406 
407  //Start transmission
409 
410  //Get the amount of free memory available in the TX FIFO
412 
413  //Check whether the TX FIFO is available for writing
414  if(n >= (ETH_MAX_FRAME_SIZE + 8))
415  {
416  //The transmitter can accept another packet
417  osSetEvent(&interface->nicTxEvent);
418  }
419 
420  //Successful processing
421  return NO_ERROR;
422 }
423 
424 
425 /**
426  * @brief Receive a packet
427  * @param[in] interface Underlying network interface
428  * @return Error code
429  **/
430 
432 {
433  size_t n;
434  uint16_t status;
435  Ksz8851Context *context;
436 
437  //Point to the driver context
438  context = (Ksz8851Context *) interface->nicContext;
439 
440  //Read received frame status from RXFHSR
441  status = ksz8851ReadReg(interface, KSZ8851_REG_RXFHSR);
442 
443  //Make sure the frame is valid
444  if(status & RXFHSR_RXFV)
445  {
446  //Check error flags
447  if(!(status & (RXFHSR_RXMR | RXFHSR_RXFTL | RXFHSR_RXRF | RXFHSR_RXCE)))
448  {
449  //Read received frame byte size from RXFHBCR
451 
452  //Ensure the frame size is acceptable
453  if(n > 0 && n <= ETH_MAX_FRAME_SIZE)
454  {
455  //Reset QMU RXQ frame pointer to zero
457  //Enable RXQ read access
459  //Read data
460  ksz8851ReadFifo(interface, context->rxBuffer, n);
461  //End RXQ read access
463 
464  //Pass the packet to the upper layer
465  nicProcessPacket(interface, context->rxBuffer, n);
466  //Valid packet received
467  return NO_ERROR;
468  }
469  }
470  }
471 
472  //Release the current error frame from RXQ
474  //Report an error
475  return ERROR_INVALID_PACKET;
476 }
477 
478 
479 /**
480  * @brief Configure MAC address filtering
481  * @param[in] interface Underlying network interface
482  * @return Error code
483  **/
484 
486 {
487  uint_t i;
488  uint_t k;
489  uint32_t crc;
490  uint16_t hashTable[4];
491  MacFilterEntry *entry;
492 
493  //Debug message
494  TRACE_DEBUG("Updating MAC filter...\r\n");
495 
496  //Clear hash table
497  memset(hashTable, 0, sizeof(hashTable));
498 
499  //The MAC address filter contains the list of MAC addresses to accept
500  //when receiving an Ethernet frame
501  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
502  {
503  //Point to the current entry
504  entry = &interface->macAddrFilter[i];
505 
506  //Valid entry?
507  if(entry->refCount > 0)
508  {
509  //Compute CRC over the current MAC address
510  crc = ksz8851CalcCrc(&entry->addr, sizeof(MacAddr));
511  //Calculate the corresponding index in the table
512  k = (crc >> 26) & 0x3F;
513  //Update hash table contents
514  hashTable[k / 16] |= (1 << (k % 16));
515  }
516  }
517 
518  //Write the hash table to the KSZ8851 controller
519  ksz8851WriteReg(interface, KSZ8851_REG_MAHTR0, hashTable[0]);
520  ksz8851WriteReg(interface, KSZ8851_REG_MAHTR1, hashTable[1]);
521  ksz8851WriteReg(interface, KSZ8851_REG_MAHTR2, hashTable[2]);
522  ksz8851WriteReg(interface, KSZ8851_REG_MAHTR3, hashTable[3]);
523 
524  //Debug message
525  TRACE_DEBUG(" MAHTR0 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_REG_MAHTR0));
526  TRACE_DEBUG(" MAHTR1 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_REG_MAHTR1));
527  TRACE_DEBUG(" MAHTR2 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_REG_MAHTR2));
528  TRACE_DEBUG(" MAHTR3 = %04" PRIX16 "\r\n", ksz8851ReadReg(interface, KSZ8851_REG_MAHTR3));
529 
530  //Successful processing
531  return NO_ERROR;
532 }
533 
534 
535 /**
536  * @brief Write KSZ8851 register
537  * @param[in] interface Underlying network interface
538  * @param[in] address Register address
539  * @param[in] data Register value
540  **/
541 
542 void ksz8851WriteReg(NetInterface *interface, uint8_t address, uint16_t data)
543 {
544 #if (KSZ8851_SPI_SUPPORT == ENABLED)
545  uint8_t command;
546 
547  //Form the write command
548  if(address & 0x02)
550  else
552 
553  //Pull the CS pin low
554  interface->spiDriver->assertCs();
555 
556  //Command phase
557  interface->spiDriver->transfer(command | (address >> 6));
558  interface->spiDriver->transfer(address << 2);
559 
560  //Data phase
561  interface->spiDriver->transfer(LSB(data));
562  interface->spiDriver->transfer(MSB(data));
563 
564  //Terminate the operation by raising the CS pin
565  interface->spiDriver->deassertCs();
566 #else
567  //Set register address
568  if(address & 0x02)
570  else
572 
573  //Write register value
575 #endif
576 }
577 
578 
579 /**
580  * @brief Read KSZ8851 register
581  * @param[in] interface Underlying network interface
582  * @param[in] address Register address
583  * @return Register value
584  **/
585 
586 uint16_t ksz8851ReadReg(NetInterface *interface, uint8_t address)
587 {
588 #if (KSZ8851_SPI_SUPPORT == ENABLED)
589  uint8_t command;
590  uint16_t data;
591 
592  //Form the read command
593  if(address & 0x02)
595  else
597 
598  //Pull the CS pin low
599  interface->spiDriver->assertCs();
600 
601  //Command phase
602  interface->spiDriver->transfer(command | (address >> 6));
603  interface->spiDriver->transfer(address << 2);
604 
605  //Data phase (lower 8 bits)
606  data = interface->spiDriver->transfer(0x00);
607  //Data phase (upper 8 bits)
608  data |= interface->spiDriver->transfer(0x00) << 8;
609 
610  //Terminate the operation by raising the CS pin
611  interface->spiDriver->deassertCs();
612 
613  //Return register value
614  return data;
615 #else
616  //Set register address
617  if(address & 0x02)
619  else
621 
622  //Return register value
623  return KSZ8851_DATA_REG;
624 #endif
625 }
626 
627 
628 /**
629  * @brief Write TX FIFO
630  * @param[in] interface Underlying network interface
631  * @param[in] data Pointer to the data being written
632  * @param[in] length Number of data to write
633  **/
634 
635 void ksz8851WriteFifo(NetInterface *interface, const uint8_t *data,
636  size_t length)
637 {
638 #if (KSZ8851_SPI_SUPPORT == ENABLED)
639  uint_t i;
640 
641  //Pull the CS pin low
642  interface->spiDriver->assertCs();
643 
644  //Command phase
645  interface->spiDriver->transfer(KSZ8851_CMD_WR_FIFO);
646 
647  //Data phase
648  for(i = 0; i < length; i++)
649  interface->spiDriver->transfer(data[i]);
650 
651  //Maintain alignment to 4-byte boundaries
652  for(; i % 4; i++)
653  interface->spiDriver->transfer(0x00);
654 
655  //Terminate the operation by raising the CS pin
656  interface->spiDriver->deassertCs();
657 #else
658  uint_t i;
659 
660  //Data phase
661  for(i = 0; i < length; i+=2)
662  KSZ8851_DATA_REG = data[i] | data[i+1]<<8;
663 
664  //Maintain alignment to 4-byte boundaries
665  for(; i % 4; i+=2)
666  KSZ8851_DATA_REG = 0x0000;
667 #endif
668 }
669 
670 
671 /**
672  * @brief Read RX FIFO
673  * @param[in] interface Underlying network interface
674  * @param[in] data Buffer where to store the incoming data
675  * @param[in] length Number of data to read
676  **/
677 
678 void ksz8851ReadFifo(NetInterface *interface, uint8_t *data, size_t length)
679 {
680 #if (KSZ8851_SPI_SUPPORT == ENABLED)
681  uint_t i;
682 
683  //Pull the CS pin low
684  interface->spiDriver->assertCs();
685 
686  //Command phase
687  interface->spiDriver->transfer(KSZ8851_CMD_RD_FIFO);
688 
689  //The first 4 bytes are dummy data and must be discarded
690  for(i = 0; i < 4; i++)
691  interface->spiDriver->transfer(0x00);
692 
693  //Ignore RX packet header
694  for(i = 0; i < 4; i++)
695  interface->spiDriver->transfer(0x00);
696 
697  //Data phase
698  for(i = 0; i < length; i++)
699  data[i] = interface->spiDriver->transfer(0x00);
700 
701  //Maintain alignment to 4-byte boundaries
702  for(; i % 4; i++)
703  interface->spiDriver->transfer(0x00);
704 
705  //Terminate the operation by raising the CS pin
706  interface->spiDriver->deassertCs();
707 #else
708  uint_t i;
709  uint16_t temp;
710 
711  //The first 2 bytes are dummy data and must be discarded
712  temp = KSZ8851_DATA_REG;
713 
714  //Ignore RX packet header
715  temp = KSZ8851_DATA_REG;
716  temp = KSZ8851_DATA_REG;
717 
718  //Data phase
719  for(i = 0; i < length; i+=2)
720  {
721  temp = KSZ8851_DATA_REG;
722  data [i] = temp & 0xFF;
723  data [i+1] = (temp>>8) & 0xFF;
724  }
725 
726  //Maintain alignment to 4-byte boundaries
727  for(; i % 4; i+=2)
728  temp = KSZ8851_DATA_REG;
729 #endif
730 }
731 
732 
733 /**
734  * @brief Set bit field
735  * @param[in] interface Underlying network interface
736  * @param[in] address Register address
737  * @param[in] mask Bits to set in the target register
738  **/
739 
740 void ksz8851SetBit(NetInterface *interface, uint8_t address, uint16_t mask)
741 {
742  uint16_t value;
743 
744  //Read current register value
745  value = ksz8851ReadReg(interface, address);
746  //Set specified bits
747  ksz8851WriteReg(interface, address, value | mask);
748 }
749 
750 
751 /**
752  * @brief Clear bit field
753  * @param[in] interface Underlying network interface
754  * @param[in] address Register address
755  * @param[in] mask Bits to clear in the target register
756  **/
757 
758 void ksz8851ClearBit(NetInterface *interface, uint8_t address, uint16_t mask)
759 {
760  uint16_t value;
761 
762  //Read current register value
763  value = ksz8851ReadReg(interface, address);
764  //Clear specified bits
765  ksz8851WriteReg(interface, address, value & ~mask);
766 }
767 
768 
769 /**
770  * @brief CRC calculation
771  * @param[in] data Pointer to the data over which to calculate the CRC
772  * @param[in] length Number of bytes to process
773  * @return Resulting CRC value
774  **/
775 
776 uint32_t ksz8851CalcCrc(const void *data, size_t length)
777 {
778  uint_t i;
779  uint_t j;
780 
781  //Point to the data over which to calculate the CRC
782  const uint8_t *p = (uint8_t *) data;
783  //CRC preset value
784  uint32_t crc = 0xFFFFFFFF;
785 
786  //Loop through data
787  for(i = 0; i < length; i++)
788  {
789  //The message is processed bit by bit
790  for(j = 0; j < 8; j++)
791  {
792  //Update CRC value
793  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
794  crc = (crc << 1) ^ 0x04C11DB7;
795  else
796  crc = crc << 1;
797  }
798  }
799 
800  //Return CRC value
801  return crc;
802 }
803 
804 
805 /**
806  * @brief Dump registers for debugging purpose
807  * @param[in] interface Underlying network interface
808  **/
809 
810 void ksz8851DumpReg(NetInterface *interface)
811 {
812 #if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
813  uint_t i;
814  uint_t j;
815  uint_t address;
816 
817  //Loop through register addresses
818  for(i = 0; i < 256; i += 16)
819  {
820  //Display register address
821  TRACE_DEBUG("%02" PRIu8 ": ", i);
822 
823  //Display 8 registers at a time
824  for(j = 0; j < 16; j += 2)
825  {
826  //Format register address
827  address = i + j;
828  //Display register contents
829  TRACE_DEBUG("0x%04" PRIX16 " ", ksz8851ReadReg(interface, address));
830  }
831 
832  //Jump to the following line
833  TRACE_DEBUG("\r\n");
834  }
835 
836  //Terminate with a line feed
837  TRACE_DEBUG("\r\n");
838 #endif
839 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:525
#define KSZ8851_REG_TXMIR
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:392
uint8_t length
Definition: dtls_misc.h:149
int bool_t
Definition: compiler_port.h:49
#define IER_RXIE
void ksz8851WriteFifo(NetInterface *interface, const uint8_t *data, size_t length)
Write TX FIFO.
#define KSZ8851_REG_RXQCR
void memPoolFree(void *p)
Release a memory block.
Definition: net_mem.c:166
#define RXCR2_SRDBL2
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:119
#define KSZ8851_REG_RXFCTR
#define KSZ8851_CMD_RD_FIFO
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_REG_IER
#define IER_TXIE
uint8_t p
Definition: ndp.h:298
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:383
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define RXQCR_RRXEF
#define KSZ8851_REG_TXFDPR
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
#define TRUE
Definition: os_port.h:50
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:89
__start_packed struct @150 Ksz8851TxHeader
TX packet header.
void ksz8851Tick(NetInterface *interface)
KSZ8851 timer handler.
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:223
#define P1SR_OPERATION_DUPLEX
const NicDriver ksz8851Driver
KSZ8851 driver.
#define RXFHSR_RXCE
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
#define KSZ8851_CMD_RD_REG
#define RXQCR_ADRFE
void * memPoolAlloc(size_t size)
Allocate a memory block.
Definition: net_mem.c:100
#define TXCR_TXE
#define KSZ8851_REG_TXQCR
#define TXFDPR_TXFPAI
#define KSZ8851_DATA_REG
#define TX_CTRL_TXFID
#define KSZ8851_REG_RXCR1
#define KSZ8851_REG_MAHTR1
#define RXQCR_RXFCTE
void ksz8851WriteReg(NetInterface *interface, uint8_t address, uint16_t data)
Write KSZ8851 register.
#define KSZ8851_REG_MAHTR3
#define KSZ8851_REG_MAHTR2
#define RXCR1_RXME
#define ISR_RXOIS
#define KSZ8851_REV_A3_ID
void ksz8851DumpReg(NetInterface *interface)
Dump registers for debugging purpose.
#define ISR_RXWFDIS
#define ISR_LCIS
error_t ksz8851Init(NetInterface *interface)
KSZ8851 controller initialization.
#define TXQCR_METFE
#define KSZ8851_CMD_WR_REG
#define FALSE
Definition: os_port.h:46
bool_t ksz8851IrqHandler(NetInterface *interface)
KSZ8851 interrupt service routine.
error_t
Error codes.
Definition: error.h:42
void ksz8851ReadFifo(NetInterface *interface, uint8_t *data, size_t length)
Read RX FIFO.
#define ISR_TXIS
#define KSZ8851_REG_PHY1ILR
#define P1CR_FORCE_DUPLEX
#define ISR_RXPSIS
#define IER_LCIE
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define ISR_LDIS
#define KSZ8851_REG_PHY1IHR
#define TXCR_TXFCE
uint_t frameId
Identify a frame and its associated status.
#define TXCR_TXPE
#define ISR_RXMPDIS
@ ERROR_INVALID_PACKET
Definition: error.h:138
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:222
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:105
@ ERROR_INVALID_LENGTH
Definition: error.h:109
#define KSZ8851_CMD_WR_FIFO
#define KSZ8851_REG_TXCR
uint8_t mask
Definition: web_socket.h:317
OsEvent netEvent
Definition: net.c:77
#define MSB(x)
Definition: os_port.h:58
uint8_t * txBuffer
Transmit buffer.
#define KSZ8851_REG_ISR
#define TRACE_INFO(...)
Definition: debug.h:94
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:54
error_t ksz8851UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define KSZ8851_REG_MARH
#define RXFHSR_RXFTL
#define KSZ8851_CMD_REG
#define KSZ8851_REG_P1CR
#define TXCR_TXCE
#define RXFDPR_RXFPAI
#define P1SR_LINK_GOOD
KSZ8851 driver context.
#define RXCR1_RXE
#define KSZ8851_REG_RXFDPR
#define ISR_EDIS
#define TRACE_DEBUG(...)
Definition: debug.h:106
#define KSZ8851_CMD_B0
#define RXCR1_RXFCE
#define RXFHSR_RXFV
#define KSZ8851_REG_MARM
#define ETH_MTU
Definition: ethernet.h:91
error_t ksz8851ReceivePacket(NetInterface *interface)
Receive a packet.
uint8_t n
MAC filter table entry.
Definition: ethernet.h:220
uint16_t ksz8851ReadReg(NetInterface *interface, uint8_t address)
Read KSZ8851 register.
#define RXFHSR_RXRF
#define ISR_TXSAIS
#define KSZ8851_REG_RXFHBCR
KSZ8851 Ethernet controller.
@ NIC_HALF_DUPLEX_MODE
Definition: nic.h:118
#define KSZ8851_REG_RXFHSR
#define P1CR_RESTART_AN
uint8_t * rxBuffer
Receive buffer.
#define RXCR1_RXPAFMA
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:88
#define RXCR2_IUFFP
void ksz8851DisableIrq(NetInterface *interface)
Disable interrupts.
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define RXFHSR_RXMR
#define KSZ8851_REG_MARL
#define KSZ8851_CMD_B2
#define RXCR1_RXUE
#define RXCR1_RXBE
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:106
#define RXQCR_SDA
#define KSZ8851_REG_P1SR
error_t ksz8851SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define ISR_SPIBEIS
void ksz8851EnableIrq(NetInterface *interface)
Enable interrupts.
uint8_t value[]
Definition: dtls_misc.h:150
#define KSZ8851_CMD_B3
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
#define RXCR2_RXIUFCEZ
#define P1SR_OPERATION_SPEED
NIC driver.
Definition: nic.h:179
void ksz8851SetBit(NetInterface *interface, uint8_t address, uint16_t mask)
Set bit field.
#define RXFHBCR_RXBC_MASK
#define TX_CTRL_TXIC
#define KSZ8851_REG_MAHTR0
#define KSZ8851_REG_CIDER
#define KSZ8851_REG_RXCR2
#define KSZ8851_CMD_B1
#define ISR_TXPSIS
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint32_t ksz8851CalcCrc(const void *data, size_t length)
CRC calculation.
#define TXMIR_TXMA_MASK
__start_packed struct @108 MacAddr
MAC address.
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:79
#define ISR_RXIS