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