ksz9563_driver.c
Go to the documentation of this file.
1 /**
2  * @file ksz9563_driver.c
3  * @brief KSZ9563 3-port Gigabit 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.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"
36 #include "core/ethernet_misc.h"
38 #include "debug.h"
39 
40 
41 /**
42  * @brief KSZ9563 Ethernet switch driver
43  **/
44 
46 {
54 };
55 
56 
57 /**
58  * @brief Tail tag rules (host to KSZ9563)
59  **/
60 
61 const uint8_t ksz9563IngressTailTag[3] =
62 {
63  0,
66 };
67 
68 
69 /**
70  * @brief KSZ9563 Ethernet switch initialization
71  * @param[in] interface Underlying network interface
72  * @return Error code
73  **/
74 
76 {
77  uint_t port;
78  uint8_t temp;
79 
80  //Debug message
81  TRACE_INFO("Initializing KSZ9563...\r\n");
82 
83  //SPI slave mode?
84  if(interface->spiDriver != NULL)
85  {
86  //Initialize SPI
87  interface->spiDriver->init();
88 
89  //Wait for the serial interface to be ready
90  do
91  {
92  //Read CHIP_ID1 register
93  temp = ksz9563ReadSwitchReg(interface, KSZ9563_CHIP_ID1);
94 
95  //The returned data is invalid until the serial interface is ready
96  } while(temp != KSZ9563_CHIP_ID1_DEFAULT);
97 
98  //Reset switch
101 
102  //Wait for the reset to complete
103  do
104  {
105  //Read switch operation register
106  temp = ksz9563ReadSwitchReg(interface, KSZ9563_SWITCH_OP);
107 
108  //The reset bit is self-clearing
109  } while((temp & KSZ9563_SWITCH_OP_SOFT_HARD_RESET) != 0);
110 
111 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
112  //Tail tagging mode?
113  if(interface->port != 0)
114  {
115  //Enable tail tag feature
116  temp = ksz9563ReadSwitchReg(interface, KSZ9563_PORT3_OP_CTRL0);
119 
120  //Loop through ports
122  {
123  //Disable packet transmission and switch address learning
129  }
130  }
131  else
132 #endif
133  {
134  //Disable tail tag feature
135  temp = ksz9563ReadSwitchReg(interface, KSZ9563_PORT3_OP_CTRL0);
138 
139  //Loop through ports
141  {
142  //Enable transmission, reception and switch address learning
148  }
149  }
150 
151  //Add internal delay to ingress and egress RGMII clocks
156 
157  //Start switch operation
160  }
161 
162  //Loop through ports
164  {
165  //Debug message
166  TRACE_DEBUG("Port %u:\r\n", port);
167  //Dump PHY registers for debugging purpose
168  ksz9563DumpPhyReg(interface, port);
169  }
170 
171  //Force the TCP/IP stack to poll the link state at startup
172  interface->phyEvent = TRUE;
173  //Notify the TCP/IP stack of the event
175 
176  //Successful initialization
177  return NO_ERROR;
178 }
179 
180 
181 /**
182  * @brief Get link state
183  * @param[in] interface Underlying network interface
184  * @param[in] port Port number
185  * @return Link state
186  **/
187 
189 {
190  uint16_t value;
191  bool_t linkState;
192 
193  //Check port number
194  if(port >= KSZ9563_PORT1 && port <= KSZ9563_PORT2)
195  {
196  //Get exclusive access
198 
199  //Any link failure condition is latched in the BMSR register. Reading
200  //the register twice will always return the actual link status
201  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
202  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
203 
204  //Retrieve current link state
205  linkState = (value & KSZ9563_BMSR_LINK_STATUS) ? TRUE : FALSE;
206 
207  //Release exclusive access
209  }
210  else
211  {
212  //The specified port number is not valid
213  linkState = FALSE;
214  }
215 
216  //Return link status
217  return linkState;
218 }
219 
220 
221 /**
222  * @brief KSZ9563 timer handler
223  * @param[in] interface Underlying network interface
224  **/
225 
226 void ksz9563Tick(NetInterface *interface)
227 {
228  uint_t port;
229  uint16_t value;
230  bool_t linkState;
231 
232 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
233  //Tail tagging mode?
234  if(interface->port != 0)
235  {
236  uint_t i;
237  NetInterface *virtualInterface;
238 
239  //Loop through network interfaces
240  for(i = 0; i < NET_INTERFACE_COUNT; i++)
241  {
242  //Point to the current interface
243  virtualInterface = &netInterface[i];
244 
245  //Check whether the current virtual interface is attached to the
246  //physical interface
247  if(virtualInterface == interface || virtualInterface->parent == interface)
248  {
249  //The tail tag is used to indicate the source/destination port
250  port = virtualInterface->port;
251 
252  //Valid port?
253  if(port >= KSZ9563_PORT1 && port <= KSZ9563_PORT2)
254  {
255  //Read status register
256  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
257 
258  //Retrieve current link state
259  linkState = (value & KSZ9563_BMSR_LINK_STATUS) ? TRUE : FALSE;
260 
261  //Link up or link down event?
262  if(linkState != virtualInterface->linkState)
263  {
264  //Set event flag
265  interface->phyEvent = TRUE;
266  //Notify the TCP/IP stack of the event
268  }
269  }
270  }
271  }
272  }
273  else
274 #endif
275  {
276  //Initialize link state
277  linkState = FALSE;
278 
279  //Loop through ports
281  {
282  //Read status register
283  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
284 
285  //Retrieve current link state
287  linkState = TRUE;
288  }
289 
290  //Link up or link down event?
291  if(linkState != interface->linkState)
292  {
293  //Set event flag
294  interface->phyEvent = TRUE;
295  //Notify the TCP/IP stack of the event
297  }
298  }
299 }
300 
301 
302 /**
303  * @brief Enable interrupts
304  * @param[in] interface Underlying network interface
305  **/
306 
308 {
309 }
310 
311 
312 /**
313  * @brief Disable interrupts
314  * @param[in] interface Underlying network interface
315  **/
316 
318 {
319 }
320 
321 
322 /**
323  * @brief KSZ9563 event handler
324  * @param[in] interface Underlying network interface
325  **/
326 
328 {
329  uint_t port;
330  uint16_t value;
331  bool_t linkState;
332 
333 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
334  //Tail tagging mode?
335  if(interface->port != 0)
336  {
337  uint_t i;
338  NetInterface *virtualInterface;
339 
340  //Loop through network interfaces
341  for(i = 0; i < NET_INTERFACE_COUNT; i++)
342  {
343  //Point to the current interface
344  virtualInterface = &netInterface[i];
345 
346  //Check whether the current virtual interface is attached to the
347  //physical interface
348  if(virtualInterface == interface ||
349  virtualInterface->parent == interface)
350  {
351  //The tail tag is used to indicate the source/destination port
352  port = virtualInterface->port;
353 
354  //Valid port?
355  if(port >= KSZ9563_PORT1 && port <= KSZ9563_PORT2)
356  {
357  //Any link failure condition is latched in the BMSR register. Reading
358  //the register twice will always return the actual link status
359  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
360  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
361 
362  //Retrieve current link state
363  linkState = (value & KSZ9563_BMSR_LINK_STATUS) ? TRUE : FALSE;
364 
365  //Link up event?
366  if(linkState && !virtualInterface->linkState)
367  {
368  //Adjust MAC configuration parameters for proper operation
369  interface->linkSpeed = NIC_LINK_SPEED_1GBPS;
370  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
371  interface->nicDriver->updateMacConfig(interface);
372 
373  //Read PHY control register
375 
376  //Check current speed
378  {
379  //1000BASE-T
380  virtualInterface->linkSpeed = NIC_LINK_SPEED_1GBPS;
381  }
383  {
384  //100BASE-TX
385  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
386  }
388  {
389  //10BASE-T
390  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
391  }
392  else
393  {
394  //Debug message
395  TRACE_WARNING("Invalid speed!\r\n");
396  }
397 
398  //Check current duplex mode
400  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
401  else
402  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
403 
404  //Update link state
405  virtualInterface->linkState = TRUE;
406 
407  //Process link state change event
408  nicNotifyLinkChange(virtualInterface);
409  }
410  //Link down event
411  else if(!linkState && virtualInterface->linkState)
412  {
413  //Update link state
414  virtualInterface->linkState = FALSE;
415 
416  //Process link state change event
417  nicNotifyLinkChange(virtualInterface);
418  }
419  }
420  }
421  }
422  }
423  else
424 #endif
425  {
426  //Initialize link state
427  linkState = FALSE;
428 
429  //Loop through ports
431  {
432  //Any link failure condition is latched in the BMSR register. Reading
433  //the register twice will always return the actual link status
434  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
435  value = ksz9563ReadPhyReg(interface, port, KSZ9563_BMSR);
436 
437  //Retrieve current link state
439  linkState = TRUE;
440  }
441 
442  //Link up event?
443  if(linkState)
444  {
445  //Adjust MAC configuration parameters for proper operation
446  interface->linkSpeed = NIC_LINK_SPEED_1GBPS;
447  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
448  interface->nicDriver->updateMacConfig(interface);
449 
450  //Update link state
451  interface->linkState = TRUE;
452  }
453  else
454  {
455  //Update link state
456  interface->linkState = FALSE;
457  }
458 
459  //Process link state change event
460  nicNotifyLinkChange(interface);
461  }
462 }
463 
464 
465 /**
466  * @brief Add tail tag to Ethernet frame
467  * @param[in] interface Underlying network interface
468  * @param[in] buffer Multi-part buffer containing the payload
469  * @param[in,out] offset Offset to the first payload byte
470  * @param[in] port Switch port identifier
471  * @param[in,out] type Ethernet type
472  * @return Error code
473  **/
474 
476  size_t *offset, uint8_t port, uint16_t *type)
477 {
478 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
479  error_t error;
480  size_t length;
481  const uint8_t *tailTag;
482 
483  //Valid port?
484  if(port >= KSZ9563_PORT1 && port <= KSZ9563_PORT2)
485  {
486  //The one byte tail tagging is used to indicate the destination port
487  tailTag = &ksz9563IngressTailTag[port];
488 
489  //Retrieve the length of the frame
490  length = netBufferGetLength(buffer) - *offset;
491 
492  //The host controller should manually add padding to the packet before
493  //inserting the tail tag
494  error = ethPadFrame(buffer, &length);
495 
496  //Check status code
497  if(!error)
498  {
499  //The tail tag is inserted at the end of the packet, just before the CRC
500  error = netBufferAppend(buffer, tailTag, sizeof(uint8_t));
501  }
502  }
503  else
504  {
505  //Invalid port identifier
506  error = ERROR_WRONG_IDENTIFIER;
507  }
508 
509  //Return status code
510  return error;
511 #else
512  //Tail tagging mode is not implemented
513  return NO_ERROR;
514 #endif
515 }
516 
517 
518 /**
519  * @brief Decode tail tag from incoming Ethernet frame
520  * @param[in] interface Underlying network interface
521  * @param[in,out] frame Pointer to the received Ethernet frame
522  * @param[in,out] length Length of the frame, in bytes
523  * @param[out] port Switch port identifier
524  * @return Error code
525  **/
526 
527 error_t ksz9563UntagFrame(NetInterface *interface, uint8_t **frame,
528  size_t *length, uint8_t *port)
529 {
530 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
531  error_t error;
532  uint8_t *tailTag;
533 
534  //Valid Ethernet frame received?
535  if(*length >= (sizeof(EthHeader) + sizeof(uint8_t)))
536  {
537  //The tail tag is inserted at the end of the packet, just before the CRC
538  tailTag = *frame + *length - sizeof(uint8_t);
539 
540  //The one byte tail tagging is used to indicate the source port
541  *port = KSZ9563_TAIL_TAG_DECODE(*tailTag);
542 
543  //Strip tail tag from Ethernet frame
544  *length -= sizeof(uint8_t);
545 
546  //Successful processing
547  error = NO_ERROR;
548  }
549  else
550  {
551  //Drop the received frame
552  error = ERROR_INVALID_LENGTH;
553  }
554 
555  //Return status code
556  return error;
557 #else
558  //Tail tagging mode is not implemented
559  return NO_ERROR;
560 #endif
561 }
562 
563 
564 /**
565  * @brief Write PHY register
566  * @param[in] interface Underlying network interface
567  * @param[in] port Port number
568  * @param[in] address PHY register address
569  * @param[in] data Register value
570  **/
571 
572 void ksz9563WritePhyReg(NetInterface *interface, uint8_t port,
573  uint8_t address, uint16_t data)
574 {
575  uint32_t command;
576 
577  //SPI slave mode?
578  if(interface->spiDriver != NULL)
579  {
580  //Set up a write operation
581  command = KSZ9563_SPI_CMD_WRITE;
582  //Set register address
583  command |= KSZ9563_PORTn_ETH_PHY_REG(port, address) << 5;
584 
585  //Pull the CS pin low
586  interface->spiDriver->assertCs();
587 
588  //Write 32-bit command
589  interface->spiDriver->transfer((command >> 24) & 0xFF);
590  interface->spiDriver->transfer((command >> 16) & 0xFF);
591  interface->spiDriver->transfer((command >> 8) & 0xFF);
592  interface->spiDriver->transfer(command & 0xFF);
593 
594  //Write 16-bit data
595  interface->spiDriver->transfer(MSB(data));
596  interface->spiDriver->transfer(LSB(data));
597 
598  //Terminate the operation by raising the CS pin
599  interface->spiDriver->deassertCs();
600  }
601  else
602  {
603  //Write the specified PHY register
604  interface->nicDriver->writePhyReg(SMI_OPCODE_WRITE, port, address, data);
605  }
606 }
607 
608 
609 /**
610  * @brief Read PHY register
611  * @param[in] interface Underlying network interface
612  * @param[in] port Port number
613  * @param[in] address PHY register address
614  * @return Register value
615  **/
616 
617 uint16_t ksz9563ReadPhyReg(NetInterface *interface, uint8_t port,
618  uint8_t address)
619 {
620  uint16_t data;
621  uint32_t command;
622 
623  //SPI slave mode?
624  if(interface->spiDriver != NULL)
625  {
626  //Set up a read operation
627  command = KSZ9563_SPI_CMD_READ;
628  //Set register address
629  command |= KSZ9563_PORTn_ETH_PHY_REG(port, address) << 5;
630 
631  //Pull the CS pin low
632  interface->spiDriver->assertCs();
633 
634  //Write 32-bit command
635  interface->spiDriver->transfer((command >> 24) & 0xFF);
636  interface->spiDriver->transfer((command >> 16) & 0xFF);
637  interface->spiDriver->transfer((command >> 8) & 0xFF);
638  interface->spiDriver->transfer(command & 0xFF);
639 
640  //Read 16-bit data
641  data = interface->spiDriver->transfer(0xFF) << 8;
642  data |= interface->spiDriver->transfer(0xFF);
643 
644  //Terminate the operation by raising the CS pin
645  interface->spiDriver->deassertCs();
646  }
647  else
648  {
649  //Read the specified PHY register
650  data = interface->nicDriver->readPhyReg(SMI_OPCODE_READ, port, address);
651  }
652 
653  //Return register value
654  return data;
655 }
656 
657 
658 /**
659  * @brief Dump PHY registers for debugging purpose
660  * @param[in] interface Underlying network interface
661  * @param[in] port Port number
662  **/
663 
664 void ksz9563DumpPhyReg(NetInterface *interface, uint8_t port)
665 {
666  uint8_t i;
667 
668  //Loop through PHY registers
669  for(i = 0; i < 32; i++)
670  {
671  //Display current PHY register
672  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
673  ksz9563ReadPhyReg(interface, port, i));
674  }
675 
676  //Terminate with a line feed
677  TRACE_DEBUG("\r\n");
678 }
679 
680 
681 /**
682  * @brief Write switch register
683  * @param[in] interface Underlying network interface
684  * @param[in] address Switch register address
685  * @param[in] data Register value
686  **/
687 
688 void ksz9563WriteSwitchReg(NetInterface *interface, uint16_t address,
689  uint8_t data)
690 {
691  uint32_t command;
692 
693  //SPI slave mode?
694  if(interface->spiDriver != NULL)
695  {
696  //Set up a write operation
697  command = KSZ9563_SPI_CMD_WRITE;
698  //Set register address
699  command |= (address << 5) & KSZ9563_SPI_CMD_ADDR;
700 
701  //Pull the CS pin low
702  interface->spiDriver->assertCs();
703 
704  //Write 32-bit command
705  interface->spiDriver->transfer((command >> 24) & 0xFF);
706  interface->spiDriver->transfer((command >> 16) & 0xFF);
707  interface->spiDriver->transfer((command >> 8) & 0xFF);
708  interface->spiDriver->transfer(command & 0xFF);
709 
710  //Write data
711  interface->spiDriver->transfer(data);
712 
713  //Terminate the operation by raising the CS pin
714  interface->spiDriver->deassertCs();
715  }
716  else
717  {
718  //The MDC/MDIO interface does not have access to all the configuration
719  //registers. It can only access the standard MIIM registers
720  }
721 }
722 
723 
724 /**
725  * @brief Read switch register
726  * @param[in] interface Underlying network interface
727  * @param[in] address Switch register address
728  * @return Register value
729  **/
730 
731 uint8_t ksz9563ReadSwitchReg(NetInterface *interface, uint16_t address)
732 {
733  uint8_t data;
734  uint32_t command;
735 
736  //SPI slave mode?
737  if(interface->spiDriver != NULL)
738  {
739  //Set up a read operation
740  command = KSZ9563_SPI_CMD_READ;
741  //Set register address
742  command |= (address << 5) & KSZ9563_SPI_CMD_ADDR;
743 
744  //Pull the CS pin low
745  interface->spiDriver->assertCs();
746 
747  //Write 32-bit command
748  interface->spiDriver->transfer((command >> 24) & 0xFF);
749  interface->spiDriver->transfer((command >> 16) & 0xFF);
750  interface->spiDriver->transfer((command >> 8) & 0xFF);
751  interface->spiDriver->transfer(command & 0xFF);
752 
753  //Read data
754  data = interface->spiDriver->transfer(0xFF);
755 
756  //Terminate the operation by raising the CS pin
757  interface->spiDriver->deassertCs();
758  }
759  else
760  {
761  //The MDC/MDIO interface does not have access to all the configuration
762  //registers. It can only access the standard MIIM registers
763  data = 0;
764  }
765 
766  //Return register value
767  return data;
768 }
769 
770 
771 /**
772  * @brief Dump switch registers for debugging purpose
773  * @param[in] interface Underlying network interface
774  **/
775 
777 {
778  uint16_t i;
779 
780  //Loop through switch registers
781  for(i = 0; i < 256; i++)
782  {
783  //Display current switch register
784  TRACE_DEBUG("0x%02" PRIX16 " (%02" PRIu16 ") : 0x%02" PRIX8 "\r\n",
785  i, i, ksz9563ReadSwitchReg(interface, i));
786  }
787 
788  //Terminate with a line feed
789  TRACE_DEBUG("\r\n");
790 }
void ksz9563WritePhyReg(NetInterface *interface, uint8_t port, uint8_t address, uint16_t data)
Write PHY register.
#define KSZ9563_PORT3_OP_CTRL0
#define KSZ9563_PHYCON_SPEED_1000BT
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:536
#define MSB(x)
Definition: os_port.h:58
TCP/IP stack core.
#define KSZ9563_PHYCON_SPEED_100BTX
#define KSZ9563_PORTn_XMII_CTRL1_RGMII_ID_IG
Debugging facilities.
void ksz9563Tick(NetInterface *interface)
KSZ9563 timer handler.
void ksz9563DumpPhyReg(NetInterface *interface, uint8_t port)
Dump PHY registers for debugging purpose.
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
uint16_t ksz9563ReadPhyReg(NetInterface *interface, uint8_t port, uint8_t address)
Read PHY register.
#define KSZ9563_SWITCH_OP_SOFT_HARD_RESET
#define KSZ9563_CHIP_ID1
#define KSZ9563_PORTn_MSTP_STATE_LEARNING_DIS
Helper functions for Ethernet.
#define KSZ9563_PORT1
#define KSZ9563_SPI_CMD_ADDR
#define KSZ9563_PHYCON_DUPLEX_STATUS
KSZ9563 3-port Gigabit Ethernet switch.
char_t type
#define SMI_OPCODE_READ
Definition: nic.h:63
#define KSZ9563_TAIL_TAG_DECODE(tag)
#define LSB(x)
Definition: os_port.h:54
#define KSZ9563_BMSR
error_t ksz9563Init(NetInterface *interface)
KSZ9563 Ethernet switch initialization.
error_t ethPadFrame(NetBuffer *buffer, size_t *length)
Ethernet frame padding.
void ksz9563DisableIrq(NetInterface *interface)
Disable interrupts.
__start_packed struct @110 EthHeader
Ethernet frame header.
#define TRUE
Definition: os_port.h:50
#define SMI_OPCODE_WRITE
Definition: nic.h:62
PHY driver.
Definition: nic.h:214
#define KSZ9563_PORTn_ETH_PHY_REG(port, addr)
#define KSZ9563_PHYCON
#define KSZ9563_PORTn_XMII_CTRL1_RGMII_ID_EG
void ksz9563EnableIrq(NetInterface *interface)
Enable interrupts.
#define KSZ9563_TAIL_TAG_ENCODE(port)
#define NET_INTERFACE_COUNT
Definition: net.h:109
void ksz9563WriteSwitchReg(NetInterface *interface, uint16_t address, uint8_t data)
Write switch register.
void ksz9563EventHandler(NetInterface *interface)
KSZ9563 event handler.
#define KSZ9563_PORTn_MSTP_STATE_RECEIVE_EN
const PhyDriver ksz9563PhyDriver
KSZ9563 Ethernet switch driver.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define KSZ9563_SWITCH_OP_START_SWITCH
NetInterface netInterface[NET_INTERFACE_COUNT]
Definition: net.c:76
error_t ksz9563UntagFrame(NetInterface *interface, uint8_t **frame, size_t *length, uint8_t *port)
Decode tail tag from incoming Ethernet frame.
#define KSZ9563_PORT2
#define KSZ9563_BMSR_LINK_STATUS
#define TRACE_INFO(...)
Definition: debug.h:94
Success.
Definition: error.h:44
Ipv6Addr address
#define KSZ9563_PORT3_XMII_CTRL1
OsEvent netEvent
Definition: net.c:74
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:42
#define TRACE_WARNING(...)
Definition: debug.h:84
unsigned int uint_t
Definition: compiler_port.h:45
error_t netBufferAppend(NetBuffer *dest, const void *src, size_t length)
Append data a multi-part buffer.
Definition: net_mem.c:586
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define KSZ9563_PORTn_MSTP_STATE_TRANSMIT_EN
uint8_t data[]
Definition: dtls_misc.h:169
error_t ksz9563TagFrame(NetInterface *interface, NetBuffer *buffer, size_t *offset, uint8_t port, uint16_t *type)
Add tail tag to Ethernet frame.
void ksz9563DumpSwitchReg(NetInterface *interface)
Dump switch registers for debugging purpose.
#define NetInterface
Definition: net.h:36
uint8_t ksz9563ReadSwitchReg(NetInterface *interface, uint16_t address)
Read switch register.
#define KSZ9563_SWITCH_OP
uint8_t value[]
Definition: dtls_misc.h:143
const uint8_t ksz9563IngressTailTag[3]
Tail tag rules (host to KSZ9563)
#define KSZ9563_PHYCON_SPEED_10BT
uint16_t port
Definition: dns_common.h:223
#define KSZ9563_CHIP_ID1_DEFAULT
OsMutex netMutex
Definition: net.c:72
#define KSZ9563_PORTn_OP_CTRL0_TAIL_TAG_EN
#define KSZ9563_PORTn_MSTP_STATE(port)
#define KSZ9563_SPI_CMD_WRITE
uint8_t length
Definition: dtls_misc.h:142
#define FALSE
Definition: os_port.h:46
int bool_t
Definition: compiler_port.h:49
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
#define KSZ9563_SPI_CMD_READ
#define TRACE_DEBUG(...)
Definition: debug.h:106
bool_t ksz9563GetLinkState(NetInterface *interface, uint8_t port)
Get link state.