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