ksz8794_driver.c
Go to the documentation of this file.
1 /**
2  * @file ksz8794_driver.c
3  * @brief KSZ8794 Ethernet switch
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"
34 #include "core/ethernet.h"
36 #include "debug.h"
37 
38 
39 /**
40  * @brief KSZ8794 Ethernet switch driver
41  **/
42 
44 {
52 };
53 
54 
55 /**
56  * @brief Tail tag rules (host to KSZ8794)
57  **/
58 
59 const uint8_t ksz8794IngressTailTag[4] =
60 {
61  0,
65 };
66 
67 
68 /**
69  * @brief KSZ8794 Ethernet switch initialization
70  * @param[in] interface Underlying network interface
71  * @return Error code
72  **/
73 
75 {
76  uint_t port;
77  uint8_t temp;
78 
79  //Debug message
80  TRACE_INFO("Initializing KSZ8794...\r\n");
81 
82  //SPI slave mode?
83  if(interface->spiDriver != NULL)
84  {
85  //Initialize SPI
86  interface->spiDriver->init();
87 
88 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
89  //Tail tagging mode?
90  if(interface->port != 0)
91  {
92  //Enable tail tag feature
96 
97  //Loop through ports
99  {
100  //Disable packet transmission and switch address learning
102  temp &= ~PORT_CTRL2_TRANSMIT_EN;
105  }
106  }
107  else
108 #endif
109  {
110  //Disable tail tag feature
112  temp &= ~GLOBAL_CTRL10_TAIL_TAG_EN;
114 
115  //Loop through ports
117  {
118  //Enable transmission, reception and switch address learning
121  temp &= ~PORT_CTRL2_LEARNING_DIS;
123  }
124  }
125 
126  //Dump switch registers for debugging purpose
127  ksz8794DumpSwitchReg(interface);
128  }
129  else
130  {
131  //Loop through ports
133  {
134  //Debug message
135  TRACE_DEBUG("Port %u:\r\n", port);
136  //Dump PHY registers for debugging purpose
137  ksz8794DumpPhyReg(interface, port);
138  }
139  }
140 
141  //Force the TCP/IP stack to poll the link state at startup
142  interface->phyEvent = TRUE;
143  //Notify the TCP/IP stack of the event
145 
146  //Successful initialization
147  return NO_ERROR;
148 }
149 
150 
151 /**
152  * @brief Get link state
153  * @param[in] interface Underlying network interface
154  * @param[in] port Port number
155  * @return Link state
156  **/
157 
159 {
160  uint16_t status;
161  bool_t linkState;
162 
163  //Check port number
164  if(port >= KSZ8794_PORT1 && port <= KSZ8794_PORT3)
165  {
166  //Get exclusive access
168 
169  //SPI slave mode?
170  if(interface->spiDriver != NULL)
171  {
172  //Read port status 2 register
173  status = ksz8794ReadSwitchReg(interface,
175 
176  //Retrieve current link state
177  linkState = (status & PORT_STAT2_LINK_GOOD) ? TRUE : FALSE;
178  }
179  else
180  {
181  //Read status register
182  status = ksz8794ReadPhyReg(interface, port, KSZ8794_PHY_REG_BMSR);
183 
184  //Retrieve current link state
185  linkState = (status & BMSR_LINK_STATUS) ? TRUE : FALSE;
186  }
187 
188  //Release exclusive access
190  }
191  else
192  {
193  //The specified port number is not valid
194  linkState = FALSE;
195  }
196 
197  //Return link status
198  return linkState;
199 }
200 
201 
202 /**
203  * @brief KSZ8794 timer handler
204  * @param[in] interface Underlying network interface
205  **/
206 
207 void ksz8794Tick(NetInterface *interface)
208 {
209  uint_t port;
210  uint16_t status;
211  bool_t linkState;
212 
213 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
214  //Tail tagging mode?
215  if(interface->port != 0)
216  {
217  uint_t i;
218  NetInterface *virtualInterface;
219 
220  //SPI slave mode?
221  if(interface->spiDriver != NULL)
222  {
223  //Loop through network interfaces
224  for(i = 0; i < NET_INTERFACE_COUNT; i++)
225  {
226  //Point to the current interface
227  virtualInterface = &netInterface[i];
228 
229  //Check whether the current virtual interface is attached to the
230  //physical interface
231  if(virtualInterface == interface || virtualInterface->parent == interface)
232  {
233  //The tail tag is used to indicate the source/destination port
234  port = virtualInterface->port;
235 
236  //Valid port?
237  if(port >= KSZ8794_PORT1 && port <= KSZ8794_PORT3)
238  {
239  //Read port status 2 register
240  status = ksz8794ReadSwitchReg(interface,
242 
243  //Retrieve current link state
244  linkState = (status & PORT_STAT2_LINK_GOOD) ? TRUE : FALSE;
245 
246  //Link up or link down event?
247  if(linkState != virtualInterface->linkState)
248  {
249  //Set event flag
250  interface->phyEvent = TRUE;
251  //Notify the TCP/IP stack of the event
253  }
254  }
255  }
256  }
257  }
258  }
259  else
260 #endif
261  {
262  //Initialize link state
263  linkState = FALSE;
264 
265  //Loop through ports
267  {
268  //SPI slave mode?
269  if(interface->spiDriver != NULL)
270  {
271  //Read port status 2 register
272  status = ksz8794ReadSwitchReg(interface,
274 
275  //Retrieve current link state
276  if(status & PORT_STAT2_LINK_GOOD)
277  linkState = TRUE;
278  }
279  else
280  {
281  //Read status register
282  status = ksz8794ReadPhyReg(interface, port, KSZ8794_PHY_REG_BMSR);
283 
284  //Retrieve current link state
285  if(status & BMSR_LINK_STATUS)
286  linkState = TRUE;
287  }
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 KSZ8794 event handler
324  * @param[in] interface Underlying network interface
325  **/
326 
328 {
329  uint_t port;
330  uint16_t status;
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  //SPI slave mode?
341  if(interface->spiDriver != NULL)
342  {
343  //Loop through network interfaces
344  for(i = 0; i < NET_INTERFACE_COUNT; i++)
345  {
346  //Point to the current interface
347  virtualInterface = &netInterface[i];
348 
349  //Check whether the current virtual interface is attached to the
350  //physical interface
351  if(virtualInterface == interface || virtualInterface->parent == interface)
352  {
353  //The tail tag is used to indicate the source/destination port
354  port = virtualInterface->port;
355 
356  //Valid port?
357  if(port >= KSZ8794_PORT1 && port <= KSZ8794_PORT3)
358  {
359  //Read port status 2 register
360  status = ksz8794ReadSwitchReg(interface,
362 
363  //Retrieve current link state
364  linkState = (status & PORT_STAT2_LINK_GOOD) ? TRUE : FALSE;
365 
366  //Link up event?
367  if(linkState && !virtualInterface->linkState)
368  {
369  //Adjust MAC configuration parameters for proper operation
370  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
371  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
372  interface->nicDriver->updateMacConfig(interface);
373 
374  //Read port status 3 register
375  status = ksz8794ReadSwitchReg(interface,
377 
378  //Check current operation mode
379  switch(status & PORT_STAT3_PHY_OP_MODE_MASK)
380  {
381  //10BASE-T
383  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
384  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
385  break;
386  //10BASE-T full-duplex
388  virtualInterface->linkSpeed = NIC_LINK_SPEED_10MBPS;
389  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
390  break;
391  //100BASE-TX
393  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
394  virtualInterface->duplexMode = NIC_HALF_DUPLEX_MODE;
395  break;
396  //100BASE-TX full-duplex
398  virtualInterface->linkSpeed = NIC_LINK_SPEED_100MBPS;
399  virtualInterface->duplexMode = NIC_FULL_DUPLEX_MODE;
400  break;
401  //Unknown operation mode
402  default:
403  //Debug message
404  TRACE_WARNING("Invalid Duplex mode\r\n");
405  break;
406  }
407 
408  //Update link state
409  virtualInterface->linkState = TRUE;
410 
411  //Process link state change event
412  nicNotifyLinkChange(virtualInterface);
413  }
414  //Link down event
415  else if(!linkState && virtualInterface->linkState)
416  {
417  //Update link state
418  virtualInterface->linkState = FALSE;
419 
420  //Process link state change event
421  nicNotifyLinkChange(virtualInterface);
422  }
423  }
424  }
425  }
426  }
427  }
428  else
429 #endif
430  {
431  //Initialize link state
432  linkState = FALSE;
433 
434  //Loop through ports
436  {
437  //SPI slave mode?
438  if(interface->spiDriver != NULL)
439  {
440  //Read port status 2 register
441  status = ksz8794ReadSwitchReg(interface,
443 
444  //Retrieve current link state
445  if(status & PORT_STAT2_LINK_GOOD)
446  linkState = TRUE;
447  }
448  else
449  {
450  //Read status register
451  status = ksz8794ReadPhyReg(interface, port, KSZ8794_PHY_REG_BMSR);
452 
453  //Retrieve current link state
454  if(status & BMSR_LINK_STATUS)
455  linkState = TRUE;
456  }
457  }
458 
459  //Link up event?
460  if(linkState)
461  {
462  //Adjust MAC configuration parameters for proper operation
463  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
464  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
465  interface->nicDriver->updateMacConfig(interface);
466 
467  //Update link state
468  interface->linkState = TRUE;
469  }
470  else
471  {
472  //Update link state
473  interface->linkState = FALSE;
474  }
475 
476  //Process link state change event
477  nicNotifyLinkChange(interface);
478  }
479 }
480 
481 
482 /**
483  * @brief Add tail tag to Ethernet frame
484  * @param[in,out] interface Underlying network interface
485  * @param[in,out] buffer Multi-part buffer containing the payload
486  * @param[in,out] offset Offset to the first payload byte
487  * @param[in,out] type Ethernet type
488  * @return Error code
489  **/
490 
492  size_t *offset, uint16_t *type)
493 {
494 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
495  error_t error;
496  uint8_t port;
497  size_t length;
498  const uint8_t *tailTag;
499 
500  //Retrieve port identifier
501  port = (*interface)->port;
502 
503  //Valid port?
504  if(port >= KSZ8794_PORT1 && port <= KSZ8794_PORT3)
505  {
506  //The one byte tail tagging is used to indicate the destination port
507  tailTag = &ksz8794IngressTailTag[port];
508 
509  //Retrieve the length of the frame
510  length = netBufferGetLength(buffer) - *offset;
511 
512  //The host controller should manually add padding to the packet before
513  //inserting the tail tag
514  error = ethPadFrame(buffer, &length);
515 
516  //Check status code
517  if(!error)
518  {
519  //The tail tag is inserted at the end of the packet, just before the CRC
520  error = netBufferAppend(buffer, tailTag, sizeof(uint8_t));
521 
522  //Check status code
523  if(!error)
524  {
525  //Forward the frame to the physical network interface
526  *interface = nicGetPhysicalInterface(*interface);
527  }
528  }
529  }
530  else
531  {
532  //Invalid port identifier
533  error = ERROR_WRONG_IDENTIFIER;
534  }
535 
536  //Return status code
537  return error;
538 #else
539  //Tail tagging mode is not implemented
540  return NO_ERROR;
541 #endif
542 }
543 
544 
545 /**
546  * @brief Decode tail tag from incoming Ethernet frame
547  * @param[in,out] interface Underlying network interface
548  * @param[in,out] frame Incoming Ethernet frame to process
549  * @param[in,out] length Total frame length
550  * @return Error code
551  **/
552 
553 error_t ksz8794UntagFrame(NetInterface **interface, uint8_t **frame,
554  size_t *length)
555 {
556 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
557  error_t error;
558  uint_t i;
559  uint8_t port;
560  uint8_t *p;
561 
562  //Valid Ethernet frame received?
563  if(*length >= (sizeof(EthHeader) + sizeof(uint8_t)))
564  {
565  //The tail tag is inserted at the end of the packet, just before the CRC
566  p = *frame + *length - 1;
567  //The one byte tail tagging is used to indicate the source port
569 
570  //Loop through network interfaces
571  for(i = 0; i < NET_INTERFACE_COUNT; i++)
572  {
573  //Check whether the current virtual interface is attached to the
574  //physical interface where the packet was received
575  if(netInterface[i].parent == *interface || &netInterface[i] == *interface)
576  {
577  //Check port identifier
578  if(netInterface[i].port != 0 && netInterface[i].port == port)
579  break;
580  }
581  }
582 
583  //Matching interface found?
584  if(i < NET_INTERFACE_COUNT)
585  {
586  //Forward the packet to the relevant virtual interface
587  *interface = &netInterface[i];
588  //Strip tail tag from Ethernet frame
589  *length -= sizeof(uint8_t);
590 
591  //Successful processing
592  error = NO_ERROR;
593  }
594  else
595  {
596  //Drop incoming frames with invalid tail tag
597  error = ERROR_WRONG_IDENTIFIER;
598  }
599  }
600  else
601  {
602  //Drop the received frame
603  error = ERROR_INVALID_LENGTH;
604  }
605 
606  //Return status code
607  return error;
608 #else
609  //Tail tagging mode is not implemented
610  return NO_ERROR;
611 #endif
612 }
613 
614 
615 /**
616  * @brief Write PHY register
617  * @param[in] interface Underlying network interface
618  * @param[in] port Port number
619  * @param[in] address PHY register address
620  * @param[in] data Register value
621  **/
622 
624  uint8_t port, uint8_t address, uint16_t data)
625 {
626  //Write the specified PHY register
627  interface->nicDriver->writePhyReg(port, address, data);
628 }
629 
630 
631 /**
632  * @brief Read PHY register
633  * @param[in] interface Underlying network interface
634  * @param[in] port Port number
635  * @param[in] address PHY register address
636  * @return Register value
637  **/
638 
639 uint16_t ksz8794ReadPhyReg(NetInterface *interface,
640  uint8_t port, uint8_t address)
641 {
642  //Read the specified PHY register
643  return interface->nicDriver->readPhyReg(port, address);
644 }
645 
646 
647 /**
648  * @brief Dump PHY registers for debugging purpose
649  * @param[in] interface Underlying network interface
650  * @param[in] port Port number
651  **/
652 
653 void ksz8794DumpPhyReg(NetInterface *interface, uint8_t port)
654 {
655  uint8_t i;
656 
657  //Loop through PHY registers
658  for(i = 0; i < 32; i++)
659  {
660  //Display current PHY register
661  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
662  ksz8794ReadPhyReg(interface, port, i));
663  }
664 
665  //Terminate with a line feed
666  TRACE_DEBUG("\r\n");
667 }
668 
669 
670 /**
671  * @brief Write switch register
672  * @param[in] interface Underlying network interface
673  * @param[in] address PHY register address
674  * @param[in] data Register value
675  **/
676 
678  uint16_t address, uint8_t data)
679 {
680  uint16_t command;
681 
682  //SPI slave mode?
683  if(interface->spiDriver != NULL)
684  {
685  //Set up a write operation
686  command = KSZ8794_SPI_CMD_WRITE;
687  //Register address
688  command |= (address << 1) & KSZ8794_SPI_ADDR_MASK;
689 
690  //Pull the CS pin low
691  interface->spiDriver->assertCs();
692 
693  //Write 16-bit command
694  interface->spiDriver->transfer(MSB(command));
695  interface->spiDriver->transfer(LSB(command));
696 
697  //Write data
698  interface->spiDriver->transfer(data);
699 
700  //Terminate the operation by raising the CS pin
701  interface->spiDriver->deassertCs();
702  }
703  else
704  {
705  //The MDC/MDIO interface does not have access to all the configuration
706  //registers. It can only access the standard MIIM registers
707  }
708 }
709 
710 
711 /**
712  * @brief Read switch register
713  * @param[in] interface Underlying network interface
714  * @param[in] address PHY register address
715  * @return Register value
716  **/
717 
719  uint16_t address)
720 {
721  uint8_t data;
722  uint16_t command;
723 
724  //SPI slave mode?
725  if(interface->spiDriver != NULL)
726  {
727  //Set up a read operation
728  command = KSZ8794_SPI_CMD_READ;
729  //Register address
730  command |= (address << 1) & KSZ8794_SPI_ADDR_MASK;
731 
732  //Pull the CS pin low
733  interface->spiDriver->assertCs();
734 
735  //Write 16-bit command
736  interface->spiDriver->transfer(MSB(command));
737  interface->spiDriver->transfer(LSB(command));
738 
739  //Read data
740  data = interface->spiDriver->transfer(0xFF);
741 
742  //Terminate the operation by raising the CS pin
743  interface->spiDriver->deassertCs();
744  }
745  else
746  {
747  //The MDC/MDIO interface does not have access to all the configuration
748  //registers. It can only access the standard MIIM registers
749  data = 0;
750  }
751 
752  //Return register value
753  return data;
754 }
755 
756 
757 /**
758  * @brief Dump switch registers for debugging purpose
759  * @param[in] interface Underlying network interface
760  **/
761 
763 {
764  uint16_t i;
765 
766  //Loop through switch registers
767  for(i = 0; i < 256; i++)
768  {
769  //Display current switch register
770  TRACE_DEBUG("0x%02" PRIX8 " (%02" PRIu8 ") : 0x%02" PRIX8 "\r\n",
771  i, i, ksz8794ReadSwitchReg(interface, i));
772  }
773 
774  //Terminate with a line feed
775  TRACE_DEBUG("\r\n");
776 }
void ksz8794EventHandler(NetInterface *interface)
KSZ8794 event handler.
void ksz8794DumpPhyReg(NetInterface *interface, uint8_t port)
Dump PHY registers for debugging purpose.
__start_packed struct @114 EthHeader
Ethernet frame header.
void nicNotifyLinkChange(NetInterface *interface)
Process link state change event.
Definition: nic.c:298
#define GLOBAL_CTRL10_TAIL_TAG_EN
#define MSB(x)
Definition: os_port.h:56
TCP/IP stack core.
#define PORT_CTRL2_RECEIVE_EN
void ksz8794EnableIrq(NetInterface *interface)
Enable interrupts.
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
KSZ8794 Ethernet switch.
#define KSZ8794_TAIL_TAG_ENCODE(port)
#define PORT_CTRL2_TRANSMIT_EN
#define BMSR_LINK_STATUS
Definition: ar8031_driver.h:95
bool_t ksz8794GetLinkState(NetInterface *interface, uint8_t port)
Get link state.
char_t type
void ksz8794Tick(NetInterface *interface)
KSZ8794 timer handler.
#define PORT_STAT3_PHY_OP_MODE_100BTX
#define LSB(x)
Definition: os_port.h:52
#define KSZ8794_SW_REG_GLOBAL_CTRL10
#define TRUE
Definition: os_port.h:48
#define PORT_STAT3_PHY_OP_MODE_MASK
#define PORT_STAT3_PHY_OP_MODE_10BT_FD
#define PORT_CTRL2_LEARNING_DIS
PHY driver.
Definition: nic.h:196
Ethernet.
error_t ethPadFrame(NetBuffer *buffer, size_t *length)
Ethernet frame padding.
Definition: ethernet.c:634
#define PORT_STAT3_PHY_OP_MODE_100BTX_FD
#define NET_INTERFACE_COUNT
Definition: net.h:108
error_t ksz8794Init(NetInterface *interface)
KSZ8794 Ethernet switch initialization.
error_t ksz8794UntagFrame(NetInterface **interface, uint8_t **frame, size_t *length)
Decode tail tag from incoming Ethernet frame.
void ksz8794WritePhyReg(NetInterface *interface, uint8_t port, uint8_t address, uint16_t data)
Write PHY register.
#define PORT_STAT3_PHY_OP_MODE_10BT
#define KSZ8794_SPI_ADDR_MASK
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
NetInterface netInterface[NET_INTERFACE_COUNT]
Definition: net.c:74
void ksz8794WriteSwitchReg(NetInterface *interface, uint16_t address, uint8_t data)
Write switch register.
#define TRACE_INFO(...)
Definition: debug.h:86
#define KSZ8794_TAIL_TAG_DECODE(tag)
Success.
Definition: error.h:42
uint16_t ksz8794ReadPhyReg(NetInterface *interface, uint8_t port, uint8_t address)
Read PHY register.
void ksz8794DisableIrq(NetInterface *interface)
Disable interrupts.
Ipv6Addr address
#define KSZ8794_SW_REG_PORT_CTRL2(n)
OsEvent netEvent
Definition: net.c:72
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
#define TRACE_WARNING(...)
Definition: debug.h:78
NetInterface * nicGetPhysicalInterface(NetInterface *interface)
Retrieve physical interface.
Definition: nic.c:85
unsigned int uint_t
Definition: compiler_port.h:43
error_t netBufferAppend(NetBuffer *dest, const void *src, size_t length)
Append data a multi-part buffer.
Definition: net_mem.c:584
#define KSZ8794_SPI_CMD_READ
#define PORT_STAT2_LINK_GOOD
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
const uint8_t ksz8794IngressTailTag[4]
Tail tag rules (host to KSZ8794)
uint8_t ksz8794ReadSwitchReg(NetInterface *interface, uint16_t address)
Read switch register.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
#define KSZ8794_PORT1
#define KSZ8794_SPI_CMD_WRITE
#define KSZ8794_SW_REG_PORT_STAT2(n)
uint16_t port
Definition: dns_common.h:221
#define KSZ8794_PORT3
#define KSZ8794_PHY_REG_BMSR
OsMutex netMutex
Definition: net.c:70
error_t ksz8794TagFrame(NetInterface **interface, NetBuffer *buffer, size_t *offset, uint16_t *type)
Add tail tag to Ethernet frame.
void ksz8794DumpSwitchReg(NetInterface *interface)
Dump switch registers for debugging purpose.
uint8_t length
Definition: dtls_misc.h:140
#define KSZ8794_SW_REG_PORT_STAT3(n)
const PhyDriver ksz8794PhyDriver
KSZ8794 Ethernet switch driver.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
#define TRACE_DEBUG(...)
Definition: debug.h:98