ksz8863_driver.c
Go to the documentation of this file.
1 /**
2  * @file ksz8863_driver.c
3  * @brief KSZ8863 3-port Ethernet switch
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"
36 #include "core/ethernet_misc.h"
38 #include "debug.h"
39 
40 
41 /**
42  * @brief KSZ8863 Ethernet switch driver
43  **/
44 
46 {
54 };
55 
56 
57 /**
58  * @brief Tail tag rules (host to KSZ8863)
59  **/
60 
61 const uint8_t ksz8863IngressTailTag[3] =
62 {
63  0,
66 };
67 
68 
69 /**
70  * @brief KSZ8863 Ethernet switch initialization
71  * @param[in] interface Underlying network interface
72  * @return Error code
73  **/
74 
76 {
77  uint_t port;
78 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
79  uint8_t temp;
80 #endif
81 
82  //Debug message
83  TRACE_INFO("Initializing KSZ8863...\r\n");
84 
85  //SPI slave mode?
86  if(interface->spiDriver != NULL)
87  {
88  //Initialize SPI
89  interface->spiDriver->init();
90  }
91 
92 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
93  //Wait for the serial interface to be ready
94  do
95  {
96  //Read CHIP_ID0 register
97  temp = ksz8863ReadSwitchReg(interface, KSZ8863_CHIP_ID0);
98 
99  //The returned data is invalid until the serial interface is ready
100  } while(temp != KSZ8863_CHIP_ID0_FAMILY_ID_DEFAULT);
101 
102  //Tail tagging mode?
103  if(interface->port != 0)
104  {
105  //Enable tail tag feature
106  temp = ksz8863ReadSwitchReg(interface, KSZ8863_GLOBAL_CTRL1);
109 
110  //Loop through ports
112  {
113  //Disable packet transmission and switch address learning
114  temp = ksz8863ReadSwitchReg(interface, KSZ8863_PORTn_CTRL2(port));
119  }
120  }
121  else
122  {
123  //Disable tail tag feature
124  temp = ksz8863ReadSwitchReg(interface, KSZ8863_GLOBAL_CTRL1);
127 
128  //Loop through ports
130  {
131  //Enable transmission, reception and switch address learning
132  temp = ksz8863ReadSwitchReg(interface, KSZ8863_PORTn_CTRL2(port));
137  }
138  }
139 
140  //Dump switch registers for debugging purpose
141  ksz8863DumpSwitchReg(interface);
142 #endif
143 
144  //SMI interface mode?
145  if(interface->spiDriver == NULL)
146  {
147  //Loop through ports
149  {
150  //Debug message
151  TRACE_DEBUG("Port %u:\r\n", port);
152  //Dump PHY registers for debugging purpose
153  ksz8863DumpPhyReg(interface, port);
154  }
155  }
156 
157  //Force the TCP/IP stack to poll the link state at startup
158  interface->phyEvent = TRUE;
159  //Notify the TCP/IP stack of the event
161 
162  //Successful initialization
163  return NO_ERROR;
164 }
165 
166 
167 /**
168  * @brief Get link state
169  * @param[in] interface Underlying network interface
170  * @param[in] port Port number
171  * @return Link state
172  **/
173 
175 {
176  uint16_t status;
177  bool_t linkState;
178 
179  //Check port number
180  if(port >= KSZ8863_PORT1 && port <= KSZ8863_PORT2)
181  {
182  //Get exclusive access
184 
185  //SPI slave mode?
186  if(interface->spiDriver != NULL)
187  {
188  //Read port status 0 register
189  status = ksz8863ReadSwitchReg(interface, KSZ8863_PORTn_STAT0(port));
190 
191  //Retrieve current link state
192  linkState = (status & KSZ8863_PORTn_STAT0_LINK_GOOD) ? TRUE : FALSE;
193  }
194  else
195  {
196  //Read status register
197  status = ksz8863ReadPhyReg(interface, port, KSZ8863_BMSR);
198 
199  //Retrieve current link state
200  linkState = (status & KSZ8863_BMSR_LINK_STATUS) ? TRUE : FALSE;
201  }
202 
203  //Release exclusive access
205  }
206  else
207  {
208  //The specified port number is not valid
209  linkState = FALSE;
210  }
211 
212  //Return link status
213  return linkState;
214 }
215 
216 
217 /**
218  * @brief KSZ8863 timer handler
219  * @param[in] interface Underlying network interface
220  **/
221 
222 void ksz8863Tick(NetInterface *interface)
223 {
224  uint_t port;
225  uint16_t status;
226  bool_t linkState;
227 
228 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
229  //Tail tagging mode?
230  if(interface->port != 0)
231  {
232  uint_t i;
233  NetInterface *virtualInterface;
234 
235  //Loop through network interfaces
236  for(i = 0; i < NET_INTERFACE_COUNT; i++)
237  {
238  //Point to the current interface
239  virtualInterface = &netInterface[i];
240 
241  //Check whether the current virtual interface is attached to the
242  //physical interface
243  if(virtualInterface == interface || virtualInterface->parent == interface)
244  {
245  //The tail tag is used to indicate the source/destination port
246  port = virtualInterface->port;
247 
248  //Valid port?
249  if(port >= KSZ8863_PORT1 && port <= KSZ8863_PORT2)
250  {
251  //Read port status 0 register
252  status = ksz8863ReadSwitchReg(interface,
254 
255  //Retrieve current link state
256  linkState = (status & KSZ8863_PORTn_STAT0_LINK_GOOD) ? TRUE : FALSE;
257 
258  //Link up or link down event?
259  if(linkState != virtualInterface->linkState)
260  {
261  //Set event flag
262  interface->phyEvent = TRUE;
263  //Notify the TCP/IP stack of the event
265  }
266  }
267  }
268  }
269  }
270  else
271 #endif
272  {
273  //Initialize link state
274  linkState = FALSE;
275 
276  //Loop through ports
278  {
279  //SPI slave mode?
280  if(interface->spiDriver != NULL)
281  {
282  //Read port status 0 register
283  status = ksz8863ReadSwitchReg(interface, KSZ8863_PORTn_STAT0(port));
284 
285  //Retrieve current link state
286  if(status & KSZ8863_PORTn_STAT0_LINK_GOOD)
287  linkState = TRUE;
288  }
289  else
290  {
291  //Read status register
292  status = ksz8863ReadPhyReg(interface, port, KSZ8863_BMSR);
293 
294  //Retrieve current link state
295  if(status & KSZ8863_BMSR_LINK_STATUS)
296  linkState = TRUE;
297  }
298  }
299 
300  //Link up or link down event?
301  if(linkState != interface->linkState)
302  {
303  //Set event flag
304  interface->phyEvent = TRUE;
305  //Notify the TCP/IP stack of the event
307  }
308  }
309 }
310 
311 
312 /**
313  * @brief Enable interrupts
314  * @param[in] interface Underlying network interface
315  **/
316 
318 {
319 }
320 
321 
322 /**
323  * @brief Disable interrupts
324  * @param[in] interface Underlying network interface
325  **/
326 
328 {
329 }
330 
331 
332 /**
333  * @brief KSZ8863 event handler
334  * @param[in] interface Underlying network interface
335  **/
336 
338 {
339  uint_t port;
340  uint16_t status;
341  bool_t linkState;
342 
343 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
344  //Tail tagging mode?
345  if(interface->port != 0)
346  {
347  uint_t i;
348  NetInterface *virtualInterface;
349 
350  //Loop through network interfaces
351  for(i = 0; i < NET_INTERFACE_COUNT; i++)
352  {
353  //Point to the current interface
354  virtualInterface = &netInterface[i];
355 
356  //Check whether the current virtual interface is attached to the
357  //physical interface
358  if(virtualInterface == interface ||
359  virtualInterface->parent == interface)
360  {
361  //The tail tag is used to indicate the source/destination port
362  port = virtualInterface->port;
363 
364  //Valid port?
365  if(port >= KSZ8863_PORT1 && port <= KSZ8863_PORT2)
366  {
367  //Read port status 0 register
368  status = ksz8863ReadSwitchReg(interface,
370 
371  //Retrieve current link state
372  linkState = (status & KSZ8863_PORTn_STAT0_LINK_GOOD) ? TRUE : FALSE;
373 
374  //Link up event?
375  if(linkState && !virtualInterface->linkState)
376  {
377  //Adjust MAC configuration parameters for proper operation
378  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
379  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
380  interface->nicDriver->updateMacConfig(interface);
381 
382  //Read port status 1 register
383  status = ksz8863ReadSwitchReg(interface,
385 
386  //Check current speed
387  if(status & KSZ8863_PORTn_STAT1_OP_SPEED)
388  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
389  else
390  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
391 
392  //Check duplex mode
393  if(status & KSZ8863_PORTn_STAT1_OP_DUPLEX)
394  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
395  else
396  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
397 
398  //Update link state
399  virtualInterface->linkState = TRUE;
400 
401  //Process link state change event
402  nicNotifyLinkChange(virtualInterface);
403  }
404  //Link down event
405  else if(!linkState && virtualInterface->linkState)
406  {
407  //Update link state
408  virtualInterface->linkState = FALSE;
409 
410  //Process link state change event
411  nicNotifyLinkChange(virtualInterface);
412  }
413  }
414  }
415  }
416  }
417  else
418 #endif
419  {
420  //Initialize link state
421  linkState = FALSE;
422 
423  //Loop through ports
425  {
426  //SPI slave mode?
427  if(interface->spiDriver != NULL)
428  {
429  //Read port status 0 register
430  status = ksz8863ReadSwitchReg(interface, KSZ8863_PORTn_STAT0(port));
431 
432  //Retrieve current link state
433  if(status & KSZ8863_PORTn_STAT0_LINK_GOOD)
434  linkState = TRUE;
435  }
436  else
437  {
438  //Read status register
439  status = ksz8863ReadPhyReg(interface, port, KSZ8863_BMSR);
440 
441  //Retrieve current link state
442  if(status & KSZ8863_BMSR_LINK_STATUS)
443  linkState = TRUE;
444  }
445  }
446 
447  //Link up event?
448  if(linkState)
449  {
450  //Adjust MAC configuration parameters for proper operation
451  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
452  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
453  interface->nicDriver->updateMacConfig(interface);
454 
455  //Update link state
456  interface->linkState = TRUE;
457  }
458  else
459  {
460  //Update link state
461  interface->linkState = FALSE;
462  }
463 
464  //Process link state change event
465  nicNotifyLinkChange(interface);
466  }
467 }
468 
469 
470 /**
471  * @brief Add tail tag to Ethernet frame
472  * @param[in] interface Underlying network interface
473  * @param[in] buffer Multi-part buffer containing the payload
474  * @param[in,out] offset Offset to the first payload byte
475  * @param[in] port Switch port identifier
476  * @param[in,out] type Ethernet type
477  * @return Error code
478  **/
479 
481  size_t *offset, uint8_t port, uint16_t *type)
482 {
483 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
484  error_t error;
485  size_t length;
486  const uint8_t *tailTag;
487 
488  //Valid port?
489  if(port >= KSZ8863_PORT1 && port <= KSZ8863_PORT2)
490  {
491  //The one byte tail tagging is used to indicate the destination port
492  tailTag = &ksz8863IngressTailTag[port];
493 
494  //Retrieve the length of the frame
495  length = netBufferGetLength(buffer) - *offset;
496 
497  //The host controller should manually add padding to the packet before
498  //inserting the tail tag
499  error = ethPadFrame(buffer, &length);
500 
501  //Check status code
502  if(!error)
503  {
504  //The tail tag is inserted at the end of the packet, just before the CRC
505  error = netBufferAppend(buffer, tailTag, sizeof(uint8_t));
506  }
507  }
508  else
509  {
510  //Invalid port identifier
511  error = ERROR_WRONG_IDENTIFIER;
512  }
513 
514  //Return status code
515  return error;
516 #else
517  //Tail tagging mode is not implemented
518  return NO_ERROR;
519 #endif
520 }
521 
522 
523 /**
524  * @brief Decode tail tag from incoming Ethernet frame
525  * @param[in] interface Underlying network interface
526  * @param[in,out] frame Pointer to the received Ethernet frame
527  * @param[in,out] length Length of the frame, in bytes
528  * @param[out] port Switch port identifier
529  * @return Error code
530  **/
531 
532 error_t ksz8863UntagFrame(NetInterface *interface, uint8_t **frame,
533  size_t *length, uint8_t *port)
534 {
535 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
536  error_t error;
537  uint8_t *tailTag;
538 
539  //Valid Ethernet frame received?
540  if(*length >= (sizeof(EthHeader) + sizeof(uint8_t)))
541  {
542  //The tail tag is inserted at the end of the packet, just before the CRC
543  tailTag = *frame + *length - sizeof(uint8_t);
544 
545  //The one byte tail tagging is used to indicate the source port
546  *port = KSZ8863_TAIL_TAG_DECODE(*tailTag);
547 
548  //Strip tail tag from Ethernet frame
549  *length -= sizeof(uint8_t);
550 
551  //Successful processing
552  error = NO_ERROR;
553  }
554  else
555  {
556  //Drop the received frame
557  error = ERROR_INVALID_LENGTH;
558  }
559 
560  //Return status code
561  return error;
562 #else
563  //Tail tagging mode is not implemented
564  return NO_ERROR;
565 #endif
566 }
567 
568 
569 /**
570  * @brief Write PHY register
571  * @param[in] interface Underlying network interface
572  * @param[in] port Port number
573  * @param[in] address PHY register address
574  * @param[in] data Register value
575  **/
576 
577 void ksz8863WritePhyReg(NetInterface *interface, uint8_t port,
578  uint8_t address, uint16_t data)
579 {
580  //Write the specified PHY register
581  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, port, address, data);
582 }
583 
584 
585 /**
586  * @brief Read PHY register
587  * @param[in] interface Underlying network interface
588  * @param[in] port Port number
589  * @param[in] address PHY register address
590  * @return Register value
591  **/
592 
593 uint16_t ksz8863ReadPhyReg(NetInterface *interface, uint8_t port,
594  uint8_t address)
595 {
596  //Read the specified PHY register
597  return interface->nicDriver->readPhyReg(SMI_OPCODE_READ, port, address);
598 }
599 
600 
601 /**
602  * @brief Dump PHY registers for debugging purpose
603  * @param[in] interface Underlying network interface
604  * @param[in] port Port number
605  **/
606 
607 void ksz8863DumpPhyReg(NetInterface *interface, uint8_t port)
608 {
609  uint8_t i;
610 
611  //Loop through PHY registers
612  for(i = 0; i < 32; i++)
613  {
614  //Display current PHY register
615  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
616  ksz8863ReadPhyReg(interface, port, i));
617  }
618 
619  //Terminate with a line feed
620  TRACE_DEBUG("\r\n");
621 }
622 
623 
624 /**
625  * @brief Write switch register
626  * @param[in] interface Underlying network interface
627  * @param[in] address Switch register address
628  * @param[in] data Register value
629  **/
630 
631 void ksz8863WriteSwitchReg(NetInterface *interface, uint8_t address,
632  uint8_t data)
633 {
634  uint8_t phyAddr;
635  uint8_t regAddr;
636 
637  //SPI slave mode?
638  if(interface->spiDriver != NULL)
639  {
640  //Pull the CS pin low
641  interface->spiDriver->assertCs();
642 
643  //Set up a write operation
644  interface->spiDriver->transfer(KSZ8863_SPI_CMD_WRITE);
645  //Write register address
646  interface->spiDriver->transfer(address);
647 
648  //Write data
649  interface->spiDriver->transfer(data);
650 
651  //Terminate the operation by raising the CS pin
652  interface->spiDriver->deassertCs();
653  }
654  else
655  {
656  //SMI register read access is selected when opcode is set to 0 and
657  //bit 4 of the PHY address is set to 0
658  phyAddr = (address >> 5) & 0x07;
659 
660  //Register address field forms register address bits 4:0
661  regAddr = address & 0x1F;
662 
663  //Registers are 8 data bits wide. For write operation, data bits 15:8
664  //are not defined, and hence can be set to either zeroes or ones
665  interface->nicDriver->writePhyReg(SMI_OPCODE_0, phyAddr, regAddr,
666  data);
667  }
668 }
669 
670 
671 /**
672  * @brief Read switch register
673  * @param[in] interface Underlying network interface
674  * @param[in] address Switch register address
675  * @return Register value
676  **/
677 
678 uint8_t ksz8863ReadSwitchReg(NetInterface *interface, uint8_t address)
679 {
680  uint8_t phyAddr;
681  uint8_t regAddr;
682  uint8_t data;
683 
684  //SPI slave mode?
685  if(interface->spiDriver != NULL)
686  {
687  //Pull the CS pin low
688  interface->spiDriver->assertCs();
689 
690  //Set up a read operation
691  interface->spiDriver->transfer(KSZ8863_SPI_CMD_READ);
692  //Write register address
693  interface->spiDriver->transfer(address);
694 
695  //Read data
696  data = interface->spiDriver->transfer(0xFF);
697 
698  //Terminate the operation by raising the CS pin
699  interface->spiDriver->deassertCs();
700  }
701  else
702  {
703  //SMI register read access is selected when opcode is set to 0 and
704  //bit 4 of the PHY address is set to 1
705  phyAddr = 0x10 | ((address >> 5) & 0x07);
706 
707  //Register address field forms register address bits 4:0
708  regAddr = address & 0x1F;
709 
710  //Registers are 8 data bits wide. For read operation, data bits 15:8
711  //are read back as zeroes
712  data = interface->nicDriver->readPhyReg(SMI_OPCODE_0, phyAddr,
713  regAddr) & 0xFF;
714  }
715 
716  //Return register value
717  return data;
718 }
719 
720 
721 /**
722  * @brief Dump switch registers for debugging purpose
723  * @param[in] interface Underlying network interface
724  **/
725 
727 {
728  uint16_t i;
729 
730  //Loop through switch registers
731  for(i = 0; i < 256; i++)
732  {
733  //Display current switch register
734  TRACE_DEBUG("0x%02" PRIX16 " (%02" PRIu16 ") : 0x%02" PRIX8 "\r\n",
735  i, i, ksz8863ReadSwitchReg(interface, i));
736  }
737 
738  //Terminate with a line feed
739  TRACE_DEBUG("\r\n");
740 }
#define KSZ8863_CHIP_ID0
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:525
error_t ksz8863UntagFrame(NetInterface *interface, uint8_t **frame, size_t *length, uint8_t *port)
Decode tail tag from incoming Ethernet frame.
uint8_t length
Definition: dtls_misc.h:149
void ksz8863EnableIrq(NetInterface *interface)
Enable interrupts.
int bool_t
Definition: compiler_port.h:49
void ksz8863DumpPhyReg(NetInterface *interface, uint8_t port)
Dump PHY registers for debugging purpose.
#define KSZ8863_PORTn_STAT0(port)
const PhyDriver ksz8863PhyDriver
KSZ8863 Ethernet switch driver.
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:119
void ksz8863Tick(NetInterface *interface)
KSZ8863 timer handler.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define KSZ8863_GLOBAL_CTRL1
#define TRUE
Definition: os_port.h:50
PHY driver.
Definition: nic.h:214
#define KSZ8863_BMSR
void ksz8863DumpSwitchReg(NetInterface *interface)
Dump switch registers for debugging purpose.
#define KSZ8863_GLOBAL_CTRL1_TAIL_TAG_EN
#define NET_INTERFACE_COUNT
Definition: net.h:109
error_t ksz8863Init(NetInterface *interface)
KSZ8863 Ethernet switch initialization.
#define KSZ8863_PORTn_CTRL2(port)
#define KSZ8863_PORTn_STAT1_OP_SPEED
#define KSZ8863_PORT1
#define SMI_OPCODE_WRITE
Definition: nic.h:62
void ksz8863WritePhyReg(NetInterface *interface, uint8_t port, uint8_t address, uint16_t data)
Write PHY register.
error_t ksz8863TagFrame(NetInterface *interface, NetBuffer *buffer, size_t *offset, uint8_t port, uint16_t *type)
Add tail tag to Ethernet frame.
#define KSZ8863_PORTn_CTRL2_RECEIVE_EN
#define FALSE
Definition: os_port.h:46
NetInterface netInterface[NET_INTERFACE_COUNT]
Definition: net.c:79
char_t type
error_t
Error codes.
Definition: error.h:42
void ksz8863WriteSwitchReg(NetInterface *interface, uint8_t address, uint8_t data)
Write switch register.
bool_t ksz8863GetLinkState(NetInterface *interface, uint8_t port)
Get link state.
KSZ8863 3-port Ethernet switch.
#define NetInterface
Definition: net.h:36
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:105
@ ERROR_INVALID_LENGTH
Definition: error.h:109
#define KSZ8863_TAIL_TAG_DECODE(tag)
error_t ethPadFrame(NetBuffer *buffer, size_t *length)
Ethernet frame padding.
OsMutex netMutex
Definition: net.c:75
OsEvent netEvent
Definition: net.c:77
#define SMI_OPCODE_0
Definition: nic.h:61
#define KSZ8863_PORTn_STAT0_LINK_GOOD
#define KSZ8863_PORTn_CTRL2_LEARNING_DIS
#define SMI_OPCODE_READ
Definition: nic.h:63
#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 KSZ8863_CHIP_ID0_FAMILY_ID_DEFAULT
#define KSZ8863_PORTn_STAT1(port)
uint16_t port
Definition: dns_common.h:223
#define TRACE_DEBUG(...)
Definition: debug.h:106
#define KSZ8863_TAIL_TAG_ENCODE(port)
uint16_t regAddr
#define KSZ8863_BMSR_LINK_STATUS
void ksz8863DisableIrq(NetInterface *interface)
Disable interrupts.
error_t netBufferAppend(NetBuffer *dest, const void *src, size_t length)
Append data a multi-part buffer.
Definition: net_mem.c:586
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define KSZ8863_PORT2
@ NIC_HALF_DUPLEX_MODE
Definition: nic.h:118
uint8_t ksz8863ReadSwitchReg(NetInterface *interface, uint8_t address)
Read switch register.
#define KSZ8863_SPI_CMD_WRITE
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:88
void ksz8863EventHandler(NetInterface *interface)
KSZ8863 event handler.
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define KSZ8863_SPI_CMD_READ
@ NIC_LINK_SPEED_100MBPS
Definition: nic.h:106
#define KSZ8863_PORTn_STAT1_OP_DUPLEX
unsigned int uint_t
Definition: compiler_port.h:45
__start_packed struct @110 EthHeader
Ethernet frame header.
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
Helper functions for Ethernet.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint16_t ksz8863ReadPhyReg(NetInterface *interface, uint8_t port, uint8_t address)
Read PHY register.
#define KSZ8863_PORTn_CTRL2_TRANSMIT_EN
const uint8_t ksz8863IngressTailTag[3]
Tail tag rules (host to KSZ8863)