ksz8463_driver.c
Go to the documentation of this file.
1 /**
2  * @file ksz8463_driver.c
3  * @brief KSZ8463 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.2
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 KSZ8463 Ethernet switch driver
43  **/
44 
46 {
54 };
55 
56 
57 /**
58  * @brief Tail tag rules (host to KSZ8463)
59  **/
60 
61 const uint8_t ksz8463IngressTailTag[3] =
62 {
63  0,
66 };
67 
68 
69 /**
70  * @brief KSZ8463 Ethernet switch initialization
71  * @param[in] interface Underlying network interface
72  * @return Error code
73  **/
74 
76 {
77  uint_t port;
78  uint16_t temp;
79 
80  //Debug message
81  TRACE_INFO("Initializing KSZ8463...\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 CIDER register
93  temp = ksz8463ReadSwitchReg(interface, KSZ8463_SW_REG_CIDER);
94 
95  //The returned data is invalid until the serial interface is ready
96  } while((temp & CIDER_FAMILY_ID) != CIDER_FAMILY_ID_DEFAULT);
97 
98 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
99  //Tail tagging mode?
100  if(interface->port != 0)
101  {
102  //Enable tail tag feature
104  temp |= GLOBAL_CTRL8_TAIL_TAG_EN;
106 
107  //Loop through ports
109  {
110  //Disable packet transmission and switch address learning
112  temp &= ~PORT_CTRL2_TRANSMIT_EN;
115  }
116  }
117  else
118 #endif
119  {
120  //Disable tail tag feature
122  temp &= ~GLOBAL_CTRL8_TAIL_TAG_EN;
124 
125  //Loop through ports
127  {
128  //Enable transmission, reception and switch address learning
131  temp &= ~PORT_CTRL2_LEARNING_DIS;
133  }
134  }
135 
136  //Dump switch registers for debugging purpose
137  ksz8463DumpSwitchReg(interface);
138  }
139  else
140  {
141  //Loop through ports
143  {
144  //Debug message
145  TRACE_DEBUG("Port %u:\r\n", port);
146  //Dump PHY registers for debugging purpose
147  ksz8463DumpPhyReg(interface, port);
148  }
149  }
150 
151  //Force the TCP/IP stack to poll the link state at startup
152  interface->phyEvent = TRUE;
153  //Notify the TCP/IP stack of the event
155 
156  //Successful initialization
157  return NO_ERROR;
158 }
159 
160 
161 /**
162  * @brief Get link state
163  * @param[in] interface Underlying network interface
164  * @param[in] port Port number
165  * @return Link state
166  **/
167 
169 {
170  uint16_t status;
171  bool_t linkState;
172 
173  //Check port number
174  if(port >= KSZ8463_PORT1 && port <= KSZ8463_PORT2)
175  {
176  //Get exclusive access
178 
179  //SPI slave mode?
180  if(interface->spiDriver != NULL)
181  {
182  //Read port status register
183  status = ksz8463ReadSwitchReg(interface,
185 
186  //Retrieve current link state
187  linkState = (status & PORT_STAT_LINK_STATUS) ? TRUE : FALSE;
188  }
189  else
190  {
191  //Read status register
192  status = ksz8463ReadPhyReg(interface, port, KSZ8463_PHY_REG_BMSR);
193 
194  //Retrieve current link state
195  linkState = (status & BMSR_LINK_STATUS) ? TRUE : FALSE;
196  }
197 
198  //Release exclusive access
200  }
201  else
202  {
203  //The specified port number is not valid
204  linkState = FALSE;
205  }
206 
207  //Return link status
208  return linkState;
209 }
210 
211 
212 /**
213  * @brief KSZ8463 timer handler
214  * @param[in] interface Underlying network interface
215  **/
216 
217 void ksz8463Tick(NetInterface *interface)
218 {
219  uint_t port;
220  uint16_t status;
221  bool_t linkState;
222 
223 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
224  //Tail tagging mode?
225  if(interface->port != 0)
226  {
227  uint_t i;
228  NetInterface *virtualInterface;
229 
230  //SPI slave mode?
231  if(interface->spiDriver != NULL)
232  {
233  //Loop through network interfaces
234  for(i = 0; i < NET_INTERFACE_COUNT; i++)
235  {
236  //Point to the current interface
237  virtualInterface = &netInterface[i];
238 
239  //Check whether the current virtual interface is attached to the
240  //physical interface
241  if(virtualInterface == interface || virtualInterface->parent == interface)
242  {
243  //The tail tag is used to indicate the source/destination port
244  port = virtualInterface->port;
245 
246  //Valid port?
247  if(port >= KSZ8463_PORT1 && port <= KSZ8463_PORT2)
248  {
249  //Read port status register
250  status = ksz8463ReadSwitchReg(interface,
252 
253  //Retrieve current link state
254  linkState = (status & PORT_STAT_LINK_STATUS) ? TRUE : FALSE;
255 
256  //Link up or link down event?
257  if(linkState != virtualInterface->linkState)
258  {
259  //Set event flag
260  interface->phyEvent = TRUE;
261  //Notify the TCP/IP stack of the event
263  }
264  }
265  }
266  }
267  }
268  }
269  else
270 #endif
271  {
272  //Initialize link state
273  linkState = FALSE;
274 
275  //Loop through ports
277  {
278  //SPI slave mode?
279  if(interface->spiDriver != NULL)
280  {
281  //Read port status register
282  status = ksz8463ReadSwitchReg(interface,
284 
285  //Retrieve current link state
286  if(status & PORT_STAT_LINK_STATUS)
287  linkState = TRUE;
288  }
289  else
290  {
291  //Read status register
292  status = ksz8463ReadPhyReg(interface, port, KSZ8463_PHY_REG_BMSR);
293 
294  //Retrieve current link state
295  if(status & 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 KSZ8463 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  //SPI slave mode?
351  if(interface->spiDriver != NULL)
352  {
353  //Loop through network interfaces
354  for(i = 0; i < NET_INTERFACE_COUNT; i++)
355  {
356  //Point to the current interface
357  virtualInterface = &netInterface[i];
358 
359  //Check whether the current virtual interface is attached to the
360  //physical interface
361  if(virtualInterface == interface ||
362  virtualInterface->parent == interface)
363  {
364  //The tail tag is used to indicate the source/destination port
365  port = virtualInterface->port;
366 
367  //Valid port?
368  if(port >= KSZ8463_PORT1 && port <= KSZ8463_PORT2)
369  {
370  //Read port status register
371  status = ksz8463ReadSwitchReg(interface,
373 
374  //Retrieve current link state
375  linkState = (status & PORT_STAT_LINK_STATUS) ? TRUE : FALSE;
376 
377  //Link up event?
378  if(linkState && !virtualInterface->linkState)
379  {
380  //Adjust MAC configuration parameters for proper operation
381  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
382  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
383  interface->nicDriver->updateMacConfig(interface);
384 
385  //Check current speed
386  if(status & PORT_STAT_OP_SPEED)
387  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
388  else
389  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
390 
391  //Check duplex mode
392  if(status & PORT_STAT_OP_MODE)
393  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
394  else
395  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
396 
397  //Update link state
398  virtualInterface->linkState = TRUE;
399 
400  //Process link state change event
401  nicNotifyLinkChange(virtualInterface);
402  }
403  //Link down event
404  else if(!linkState && virtualInterface->linkState)
405  {
406  //Update link state
407  virtualInterface->linkState = FALSE;
408 
409  //Process link state change event
410  nicNotifyLinkChange(virtualInterface);
411  }
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 register
430  status = ksz8463ReadSwitchReg(interface,
432 
433  //Retrieve current link state
434  if(status & PORT_STAT_LINK_STATUS)
435  linkState = TRUE;
436  }
437  else
438  {
439  //Read status register
440  status = ksz8463ReadPhyReg(interface, port, KSZ8463_PHY_REG_BMSR);
441 
442  //Retrieve current link state
443  if(status & BMSR_LINK_STATUS)
444  linkState = TRUE;
445  }
446  }
447 
448  //Link up event?
449  if(linkState)
450  {
451  //Adjust MAC configuration parameters for proper operation
452  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
453  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
454  interface->nicDriver->updateMacConfig(interface);
455 
456  //Update link state
457  interface->linkState = TRUE;
458  }
459  else
460  {
461  //Update link state
462  interface->linkState = FALSE;
463  }
464 
465  //Process link state change event
466  nicNotifyLinkChange(interface);
467  }
468 }
469 
470 
471 /**
472  * @brief Add tail tag to Ethernet frame
473  * @param[in] interface Underlying network interface
474  * @param[in] buffer Multi-part buffer containing the payload
475  * @param[in,out] offset Offset to the first payload byte
476  * @param[in] port Switch port identifier
477  * @param[in,out] type Ethernet type
478  * @return Error code
479  **/
480 
482  size_t *offset, uint8_t port, uint16_t *type)
483 {
484 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
485  error_t error;
486  size_t length;
487  const uint8_t *tailTag;
488 
489  //Valid port?
490  if(port >= KSZ8463_PORT1 && port <= KSZ8463_PORT2)
491  {
492  //The one byte tail tagging is used to indicate the destination port
493  tailTag = &ksz8463IngressTailTag[port];
494 
495  //Retrieve the length of the frame
496  length = netBufferGetLength(buffer) - *offset;
497 
498  //The host controller should manually add padding to the packet before
499  //inserting the tail tag
500  error = ethPadFrame(buffer, &length);
501 
502  //Check status code
503  if(!error)
504  {
505  //The tail tag is inserted at the end of the packet, just before the CRC
506  error = netBufferAppend(buffer, tailTag, sizeof(uint8_t));
507  }
508  }
509  else
510  {
511  //Invalid port identifier
512  error = ERROR_WRONG_IDENTIFIER;
513  }
514 
515  //Return status code
516  return error;
517 #else
518  //Tail tagging mode is not implemented
519  return NO_ERROR;
520 #endif
521 }
522 
523 
524 /**
525  * @brief Decode tail tag from incoming Ethernet frame
526  * @param[in] interface Underlying network interface
527  * @param[in,out] frame Pointer to the received Ethernet frame
528  * @param[in,out] length Length of the frame, in bytes
529  * @param[out] port Switch port identifier
530  * @return Error code
531  **/
532 
533 error_t ksz8463UntagFrame(NetInterface *interface, uint8_t **frame,
534  size_t *length, uint8_t *port)
535 {
536 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
537  error_t error;
538  uint8_t *tailTag;
539 
540  //Valid Ethernet frame received?
541  if(*length >= (sizeof(EthHeader) + sizeof(uint8_t)))
542  {
543  //The tail tag is inserted at the end of the packet, just before the CRC
544  tailTag = *frame + *length - sizeof(uint8_t);
545 
546  //The one byte tail tagging is used to indicate the source port
547  *port = KSZ8463_TAIL_TAG_DECODE(*tailTag);
548 
549  //Strip tail tag from Ethernet frame
550  *length -= sizeof(uint8_t);
551 
552  //Successful processing
553  error = NO_ERROR;
554  }
555  else
556  {
557  //Drop the received frame
558  error = ERROR_INVALID_LENGTH;
559  }
560 
561  //Return status code
562  return error;
563 #else
564  //Tail tagging mode is not implemented
565  return NO_ERROR;
566 #endif
567 }
568 
569 
570 /**
571  * @brief Write PHY register
572  * @param[in] interface Underlying network interface
573  * @param[in] port Port number
574  * @param[in] address PHY register address
575  * @param[in] data Register value
576  **/
577 
578 void ksz8463WritePhyReg(NetInterface *interface, uint8_t port,
579  uint8_t address, uint16_t data)
580 {
581  //Write the specified PHY register
582  interface->nicDriver->writePhyReg(port, address, data);
583 }
584 
585 
586 /**
587  * @brief Read PHY register
588  * @param[in] interface Underlying network interface
589  * @param[in] port Port number
590  * @param[in] address PHY register address
591  * @return Register value
592  **/
593 
594 uint16_t ksz8463ReadPhyReg(NetInterface *interface, uint8_t port,
595  uint8_t address)
596 {
597  //Read the specified PHY register
598  return interface->nicDriver->readPhyReg(port, address);
599 }
600 
601 
602 /**
603  * @brief Dump PHY registers for debugging purpose
604  * @param[in] interface Underlying network interface
605  * @param[in] port Port number
606  **/
607 
608 void ksz8463DumpPhyReg(NetInterface *interface, uint8_t port)
609 {
610  uint8_t i;
611 
612  //Loop through PHY registers
613  for(i = 0; i < 32; i++)
614  {
615  //Display current PHY register
616  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
617  ksz8463ReadPhyReg(interface, port, i));
618  }
619 
620  //Terminate with a line feed
621  TRACE_DEBUG("\r\n");
622 }
623 
624 
625 /**
626  * @brief Write switch register
627  * @param[in] interface Underlying network interface
628  * @param[in] address Switch register address
629  * @param[in] data Register value
630  **/
631 
632 void ksz8463WriteSwitchReg(NetInterface *interface, uint16_t address,
633  uint16_t data)
634 {
635  uint16_t command;
636 
637  //SPI slave mode?
638  if(interface->spiDriver != NULL)
639  {
640  //Set up a write operation
641  command = KSZ8463_SPI_CMD_WRITE;
642 
643  //The byte enable bits are set to indicate which bytes will be
644  //transferred in the data phase
645  if(address & 0x02)
647  else
649 
650  //Set register address
651  command |= (address << 4) & KSZ8463_SPI_CMD_ADDR;
652 
653  //Pull the CS pin low
654  interface->spiDriver->assertCs();
655 
656  //Write 16-bit command
657  interface->spiDriver->transfer(MSB(command));
658  interface->spiDriver->transfer(LSB(command));
659 
660  //Write 16-bit data
661  interface->spiDriver->transfer(LSB(data));
662  interface->spiDriver->transfer(MSB(data));
663 
664  //Terminate the operation by raising the CS pin
665  interface->spiDriver->deassertCs();
666  }
667  else
668  {
669  //The MDC/MDIO interface does not have access to all the configuration
670  //registers. It can only access the standard MIIM registers
671  }
672 }
673 
674 
675 /**
676  * @brief Read switch register
677  * @param[in] interface Underlying network interface
678  * @param[in] address Switch register address
679  * @return Register value
680  **/
681 
682 uint16_t ksz8463ReadSwitchReg(NetInterface *interface, uint16_t address)
683 {
684  uint16_t data;
685  uint16_t command;
686 
687  //SPI slave mode?
688  if(interface->spiDriver != NULL)
689  {
690  //Set up a read operation
691  command = KSZ8463_SPI_CMD_READ;
692 
693  //The byte enable bits are set to indicate which bytes will be
694  //transferred in the data phase
695  if(address & 0x02)
697  else
699 
700  //Set register address
701  command |= (address << 4) & KSZ8463_SPI_CMD_ADDR;
702 
703  //Pull the CS pin low
704  interface->spiDriver->assertCs();
705 
706  //Write 16-bit command
707  interface->spiDriver->transfer(MSB(command));
708  interface->spiDriver->transfer(LSB(command));
709 
710  //Read 16-bit data
711  data = interface->spiDriver->transfer(0xFF);
712  data |= interface->spiDriver->transfer(0xFF) << 8;
713 
714  //Terminate the operation by raising the CS pin
715  interface->spiDriver->deassertCs();
716  }
717  else
718  {
719  //The MDC/MDIO interface does not have access to all the configuration
720  //registers. It can only access the standard MIIM registers
721  data = 0;
722  }
723 
724  //Return register value
725  return data;
726 }
727 
728 
729 /**
730  * @brief Dump switch registers for debugging purpose
731  * @param[in] interface Underlying network interface
732  **/
733 
735 {
736  uint16_t i;
737 
738  //Loop through switch registers
739  for(i = 0; i < 256; i += 2)
740  {
741  //Display current switch register
742  TRACE_DEBUG("0x%02" PRIX16 " (%02" PRIu16 ") : 0x%04" PRIX16 "\r\n",
743  i, i, ksz8463ReadSwitchReg(interface, i));
744  }
745 
746  //Terminate with a line feed
747  TRACE_DEBUG("\r\n");
748 }
#define CIDER_FAMILY_ID
#define KSZ8463_SPI_CMD_READ
__start_packed struct @114 EthHeader
Ethernet frame header.
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:536
#define MSB(x)
Definition: os_port.h:58
void ksz8463WritePhyReg(NetInterface *interface, uint8_t port, uint8_t address, uint16_t data)
Write PHY register.
TCP/IP stack core.
Debugging facilities.
#define KSZ8463_TAIL_TAG_ENCODE(port)
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define KSZ8463_SW_REG_GLOBAL_CTRL8
#define KSZ8463_SW_REG_PORT_CTRL2(n)
#define PORT_CTRL2_LEARNING_DIS
#define BMSR_LINK_STATUS
Definition: ar8031_driver.h:97
Helper functions for Ethernet.
bool_t ksz8463GetLinkState(NetInterface *interface, uint8_t port)
Get link state.
#define KSZ8463_SW_REG_CIDER
error_t ksz8463TagFrame(NetInterface *interface, NetBuffer *buffer, size_t *offset, uint8_t port, uint16_t *type)
Add tail tag to Ethernet frame.
char_t type
void ksz8463DisableIrq(NetInterface *interface)
Disable interrupts.
#define LSB(x)
Definition: os_port.h:54
#define KSZ8463_SPI_CMD_B2
error_t ethPadFrame(NetBuffer *buffer, size_t *length)
Ethernet frame padding.
#define TRUE
Definition: os_port.h:50
#define KSZ8463_SPI_CMD_B3
#define KSZ8463_SPI_CMD_B1
PHY driver.
Definition: nic.h:199
#define KSZ8463_SPI_CMD_WRITE
#define CIDER_FAMILY_ID_DEFAULT
#define KSZ8463_SPI_CMD_B0
#define PORT_STAT_OP_MODE
#define NET_INTERFACE_COUNT
Definition: net.h:109
#define KSZ8463_PORT1
uint16_t ksz8463ReadPhyReg(NetInterface *interface, uint8_t port, uint8_t address)
Read PHY register.
error_t ksz8463Init(NetInterface *interface)
KSZ8463 Ethernet switch initialization.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
NetInterface netInterface[NET_INTERFACE_COUNT]
Definition: net.c:78
#define KSZ8463_PHY_REG_BMSR
#define TRACE_INFO(...)
Definition: debug.h:94
#define KSZ8463_SPI_CMD_ADDR
Success.
Definition: error.h:44
Ipv6Addr address
#define PORT_CTRL2_TRANSMIT_EN
OsEvent netEvent
Definition: net.c:76
uint16_t ksz8463ReadSwitchReg(NetInterface *interface, uint16_t address)
Read switch register.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:42
KSZ8463 Ethernet switch.
#define KSZ8463_SW_REG_PORT_STAT(n)
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.
void ksz8463DumpSwitchReg(NetInterface *interface)
Dump switch registers for debugging purpose.
uint8_t data[]
Definition: dtls_misc.h:169
#define NetInterface
Definition: net.h:36
void ksz8463EnableIrq(NetInterface *interface)
Enable interrupts.
#define PORT_STAT_LINK_STATUS
#define GLOBAL_CTRL8_TAIL_TAG_EN
uint16_t port
Definition: dns_common.h:223
void ksz8463Tick(NetInterface *interface)
KSZ8463 timer handler.
void ksz8463DumpPhyReg(NetInterface *interface, uint8_t port)
Dump PHY registers for debugging purpose.
#define KSZ8463_PORT2
OsMutex netMutex
Definition: net.c:74
const uint8_t ksz8463IngressTailTag[3]
Tail tag rules (host to KSZ8463)
void ksz8463EventHandler(NetInterface *interface)
KSZ8463 event handler.
#define PORT_CTRL2_RECEIVE_EN
error_t ksz8463UntagFrame(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:142
#define PORT_STAT_OP_SPEED
#define FALSE
Definition: os_port.h:46
void ksz8463WriteSwitchReg(NetInterface *interface, uint16_t address, uint16_t data)
Write switch register.
int bool_t
Definition: compiler_port.h:49
const PhyDriver ksz8463PhyDriver
KSZ8463 Ethernet switch driver.
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
#define KSZ8463_TAIL_TAG_DECODE(tag)
#define TRACE_DEBUG(...)
Definition: debug.h:106