espressif/ksz8863
uploaded 10 months ago

KSZ8863 Ethernet Driver

readme

# KSZ8863 Ethernet Driver (beta)

## Overview

The KSZ8863MLL/FLL/RLL are highly integrated 3-port switch ICs in a small footprint.

They are designed to enable a new generation of low port count, cost-sensitive and power efficient 10/100Mbps switch systems. Low power consumption, advanced power management and sophisticated QoS features (e.g., IPv6 priority classification support) make these devices ideal for IPTV, IP-STB, VoIP, automotive and industrial applications. See [KSZ8863 product page](https://www.microchip.com/en-us/product/KSZ8863) for more information.

From IOT use cases point of view, one of the advantages of usage of this chip is to enable ring topology of Ethernet connected devices which would otherwise needed to be connected in tree topology. Tree topology usually requires extensive wiring since each device is connected to the central point (switch/router) by separate cable. On the opposite, ring topology can save wiring since the devices can be "daisy-chained" (each device in path can pass the traffic further to the final destination). Note that the ring may not be "closed".

## Driver Architecture

The KSZ8863 Espressif driver can be utilized in three modes of operation:
- simple switch
- managed switch
- to act as two separate endpoints

## KSZ8863 as Simple Switch

This is the simplest way of use the KSZ8863 driver. It is completely transparent from user point of view since the KSZ8863 is initialized and used like any other Ethernet device currently supported by the ESP-IDF. The system behaves the same as the ESP32 Ethernet interface was connected to external switch. You have no tail tagging option, i.e. you cannot specifically define where to send Ethernet frame and all routing is performed in KSZ8863 based on its internal MAC lookup tables. On the other hand, you still have an option to configure the KSZ8863, if you need so. To be able to control the configuration of P1 and P2 ports (MACs or PHYs), ESP Ethernet handles associated with these ports need to be initialized. You get also an access to the port state (link status, speed, etc.). 

---

Warning:

In this **Simple Switch** configuration, KSZ8863 cannot be used in a way you connected both P1 & P2 to the same switch at psychical layer or in networks with presence of redundant paths because there is a risk of creation of Ethernet Loops (Broadcast storms). Refer to [this post](https://www.networkacademy.io/ccna/ethernet/an-switching-redundant-links) to see details and implications.

---

The figure below shows data and control flow in this mode. Notice that P1 and P2 Ethernet handles are not utilized for data path and serve only to access the control of these ports. See [KSZ8863 Control and Configuration section](#ksz8863-control-and-configuration) for more information.

![simple switch](docs/simpleswitch.png)

## KSZ8863 as Managed Switch

This is more advanced configuration of KSZ8863 driver. It behaves as switch but enables Tail Tagging and so ensures greater control over network topology. It is specifically intended to be used with Spanning Tree protocols where you need to be able to know at which port the protocol message (BPDU) was received and to have control over which port to be sent.

The Tail Tagging is not available directly to user's code (user does not have to add the Tail Tag at end of the frame, for instance). It is available indirectly via L2 TAP interface. The L2 TAP interface is bound to a specific KSZ8863 port Ethernet handle and then the traffic received/transmitted at this L2 TAP interface is tagged under the hood by the driver. For example, if user reads a frame using L2 TAP file descriptor associated with P1, it means the frame was tagged by KSZ8863 and source was port 1. Note that the driver removes the Tail Tag prior passing the frame to upper layers (e.i. to L2 TAP or ESP NETIF). At transmit side when user sends a frame via L2 TAP file descriptor associated with P1, the frame is tail tagged by driver and provided to KSZ8863 via Host port. This approach has an implication/limitation that tail tagging is available only for non-IP traffic by default. IP traffic is always routed based on internal lookup in KSZ8863 based on configuration of its MAC tables (transmit frame is tail tagged with "`0`").

---

Warning:

In this **Managed Switch** configuration, KSZ8863 cannot be used in a way you connected both P1 & P2 to the same switch at psychical layer or in networks with presence of redundant paths because there is a risk of creation of Ethernet Loops (Broadcast storms) **unless Host processor implements Spanning Tree and disables traffic at port which creates redundancy in the network**. Refer to [this post](https://www.networkacademy.io/ccna/ethernet/an-switching-redundant-links) to see details and implications.

---

The figure below shows data path when KSZ8863 is used in this Managed Switch mode. The control path is the same as presented in Simple Switch mode and is not shown here deliberately to emphasize data path which is more complex. Also see [KSZ8863 Control and Configuration section](#ksz8863-control-and-configuration) for additional information. Data flow directions are important since receive and transmit path are not symmetric for IP traffic.

![managed switch](docs/switchmode.png)

### KSZ8863 Intermediate Layer Functions Description

- `ksz8863_eth_tail_tag_port_forward` - removes Tail Tag and forwards the frame to appropriate port Ethernet handle based on it.
- `ksz8863_eth_transmit_via_host` - sends frame via Host Ethernet interface to the KSZ8863 with appropriate Tail Tag.
- `ksz8863_eth_transmit_normal_lookup` - sends frame via Host Ethernet interface to the KSZ8863 with appropriate Tail Tag


## KSZ8863 as Two Port Endpoints

Also called "Port Mode" is intended to give to ESP32 feature of two independent Ethernet interfaces. Each KSZ8863 port acts as separate endpoint with its specific MAC address, has its own NETIF instance and no traffic is exchanged between P1 and P2 inside KSZ8863. This mode takes full advantage of Tail tagging. Since the ports act independently, the KSZ8863 can be used in network configuration where P1 & P2 are connected to the same switch at psychical layer or in networks with presence of redundant paths because there is no risk of creation of Ethernet Loops (Broadcast storms). Refer to [this post](https://www.networkacademy.io/ccna/ethernet/an-switching-redundant-links) to see details and implications.

The figure below shows data path when KSZ8863 is used in this Port Mode. The control path is the same as presented in Simple Switch mode. See [KSZ8863 Control and Configuration section](#ksz8863-control-and-configuration) for more information.

![port mode](docs/portmode.png)


### Port Mode Known Limitations

- To keep the ports separated and due to a fact that there is no option to generally configure multicast forwarding in KSZ8863, **Multicast traffic is not forwarded to Host port** by default. Workaround: either configure KSZ8863 to promiscuous mode via ``esp_eth_ioctl`` or add a record to static MAC table with that multicast address forwarded to P3.
- The first Static MAC table entry (indx. 0) is not allowed to be modified in this mode using ``esp_eth_ioctl`` since it is used internally by the driver.

## KSZ8863 Configuration & Control interface

KSZ8863 can be managed via either I2C or SPI bus.

### KSZ8863 Control and Configuration

Some MAC layer related configuration (like MAC tables configuration) is common for all ports and so can be accessed by both P1 or P2 Ethernet handles, just choose one to perform these operation. Configuration features which can be accessed this way can be generally identified as `Global Control` registers in KSZ8863 datasheet.

The P3 port, which is also called as Host port in this driver (or sometimes Switch port in KSZ8863 datasheet) does not consist of any actual PHY but some of its configuration features can be handled in PHY like style from ESP32 Host EMAC point of view (e.g. speed, duplex, etc.). Therefore these features are accessible via Host Ethernet handle and P3 acts as PHY instance, see `esp_eth_phy_ksz8863`, mode `KSZ8863_MAC_MAC_MODE` for more information. Accessing MAC related features of P3 is currently not fully possible, however, it is not needed in majority of cases anyway since the P3 can be understood as a generic data gateway to KSZ8863 which does not require any specific handling and some of the features can be accessed globally via P1 or P2 as described above.

readme of simple_switch example

                                        
                                        | Supported Targets | ESP32 |
| ----------------- | ----- |

# KSZ8863 Simple Switch Example

## Overview

This example demonstrates initialization and basic usage of KSZ8863 driver in **Simple Switch Mode**. See the README.md file in the upper level directories to learn more about this mode.

## How to use example

You need one ESP32 with KSZ8863 and two PC's (or other Ethernet capable devices). Connect the network as shown in figure below, configure PC#1 as DHCP server and PC#2 as DHCP client.

![example network](../../docs/example_switch.png)

The work flow of the example is then as follows:

1. Install the KSZ8863 Ethernet driver in ESP32.
2. Wait for a DHCP leases in ESP32 and PC#2.
3. If get IP addresses successfully, then you will be able to ping the ESP32 device and PC#2 from PC#1 (and vice versa).
4. You will be able to receive **the same "L2 Test message"** in PC#1 and PC#2 (use ``Wireshark`` or ``tcpdump``).

### Configure the project

Configure pin assignment, control interface and RMII REFCLK as per your board needs.

```
idf.py menuconfig
```

For more information, see help associated with each option in ESP-IDF Configuration tool.

### Build, Flash, and Run

Build the project and flash it to the board, then run monitor tool to view serial output:

```
idf.py -p PORT build flash monitor
```

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type ``Ctrl-]``.)

See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.

## Example Output

**ESP32 with KSZ8863 output:**

```bash
I (453) simple_switch_example: Ethernet Link Up
I (453) simple_switch_example: Ethernet HW Addr 8c:4b:14:0a:14:63
I (2553) simple_switch_example: Ethernet Started
I (2553) simple_switch_example: Ethernet Link Up Port 1
I (2553) simple_switch_example: Ethernet HW Addr 00:00:00:00:00:00
I (4653) simple_switch_example: Ethernet Started
I (4653) simple_switch_example: Ethernet Link Up Port 2
I (4653) simple_switch_example: Ethernet HW Addr 00:00:00:00:00:00
I (4663) simple_switch_example: Dynamic MAC Table content:
I (4663) simple_switch_example: valid entries 2
I (4663) simple_switch_example: port 1
I (4673) simple_switch_example: 00 e0 4c 68 01 ac 
I (4673) simple_switch_example: port 3
I (4683) simple_switch_example: 8c 4b 14 0a 14 63 

I (5903) esp_netif_handlers: eth ip: 192.168.20.105, mask: 255.255.255.0, gw: 192.168.20.1
I (5903) simple_switch_example: Ethernet Got IP Address
I (5903) simple_switch_example: ~~~~~~~~~~~
I (5903) simple_switch_example: ETHIP:192.168.20.105
I (5913) simple_switch_example: ETHMASK:255.255.255.0
I (5923) simple_switch_example: ETHGW:192.168.20.1
I (5923) simple_switch_example: ~~~~~~~~~~~
```
**PC#2 output (on Linux OS):**

```bash
$ ip a

...

2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 70:85:c2:d3:ea:18 brd ff:ff:ff:ff:ff:ff
    inet 192.168.20.116/24 brd 192.168.20.255 scope global dynamic noprefixroute enp4s0
       valid_lft 346sec preferred_lft 346sec
    inet6 fe80::4efa:2bae:e58c:231e/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

...
```

Now you can ping your ESP32 in PC#1 terminal by entering `ping 192.168.20.105` and PC#2 in PC#1 terminal by entering `ping 192.168.20.116` (it depends on the actual IP address you get).

You can also check the received test message in PC#1 or PC#2 as follows (on Linux OS):

```bash
$ sudo tcpdump -i enp4s0

dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp4s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:16:12.576802 8c:4b:14:0a:14:63 (oui Unknown) > Broadcast, ethertype Unknown (0x7000), length 60: 
	0x0000:  0000 5468 6973 2069 7320 4553 5033 3220  ..This.is.ESP32.
	0x0010:  4c32 2054 4150 2074 6573 7420 6d73 6700  L2.TAP.test.msg.
	0x0020:  0000 0000 0000 0000 0000 0000 0000       ..............
```
Note: replace "enp4s0" with actual name of your Ethernet interface.

                                    

readme of switch_mode example

                                        
                                        | Supported Targets | ESP32 |
| ----------------- | ----- |

# KSZ8863 Managed Switch Example

## Overview

This example demonstrates initialization and basic usage of KSZ8863 driver in **Managed Switch Mode**. See the README.md file in the upper level directories to learn more about this mode.

## How to use example

You need one ESP32 with KSZ8863 and two PC's (or other Ethernet capable devices). Connect the network as shown in figure below, configure PC#1 as DHCP server and PC#2 as DHCP client.

![example network](../../docs/example_switch.png)

The work flow of the example is then as follows:

1. Install the KSZ8863 Ethernet driver in ESP32.
2. Wait for a DHCP leases in ESP32 and PC#2.
3. If get IP addresses successfully, then you will be able to ping the ESP32 device and PC#2 from PC#1 (and vice versa).
4. You will be able to receive **different "L2 Test messages"** in each of PC#1 and PC#2 (use ``Wireshark`` or ``tcpdump``).

### Configure the project

Configure pin assignment, control interface and RMII REFCLK as per your board needs.

```
idf.py menuconfig
```

For more information, see help associated with each option in ESP-IDF Configuration tool.

### Build, Flash, and Run

Build the project and flash it to the board, then run monitor tool to view serial output:

```
idf.py -p PORT build flash monitor
```

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type ``Ctrl-]``.)

See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.

## Example Output

**ESP32 with KSZ8863 output:**

```bash
I (455) switch_example: Ethernet Link Up
I (465) switch_example: Ethernet HW Addr 8c:4b:14:0a:14:63
I (2555) switch_example: Ethernet Started
I (2555) switch_example: Ethernet Link Up Port 1
I (2555) switch_example: Ethernet HW Addr 8c:4b:14:0a:14:63
I (4555) switch_example: Ethernet Started
I (4555) switch_example: Ethernet Link Up Port 2
I (4555) switch_example: Ethernet HW Addr 8c:4b:14:0a:14:63
I (4565) switch_example: Dynamic MAC Table content:
I (4565) switch_example: valid entries 3
I (4565) switch_example: port 1
I (4575) switch_example: 00 e0 4c 68 01 ac 
I (4575) switch_example: port 2
I (4575) switch_example: 70 85 c2 d3 ea 18 
I (4585) switch_example: port 3
I (4585) switch_example: 8c 4b 14 0a 14 63 

I (5905) esp_netif_handlers: eth ip: 192.168.20.105, mask: 255.255.255.0, gw: 192.168.20.1
I (5905) switch_example: Ethernet Got IP Address
I (5905) switch_example: ~~~~~~~~~~~
I (5905) switch_example: ETHIP:192.168.20.105
I (5915) switch_example: ETHMASK:255.255.255.0
I (5915) switch_example: ETHGW:192.168.20.1
I (5925) switch_example: ~~~~~~~~~~~
```
**PC#2 output (on Linux OS):**

```bash
$ ip a

...

2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 70:85:c2:d3:ea:18 brd ff:ff:ff:ff:ff:ff
    inet 192.168.20.116/24 brd 192.168.20.255 scope global dynamic noprefixroute enp4s0
       valid_lft 346sec preferred_lft 346sec
    inet6 fe80::4efa:2bae:e58c:231e/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

...
```
Now you can ping your ESP32 in PC#1 terminal by entering `ping 192.168.20.105` and PC#2 in PC#1 terminal by entering `ping 192.168.20.116` (it depends on the actual IP address you get).

You can also check the received test message in PC#1 or PC#2 as follows (on Linux OS):

```bash
$ sudo tcpdump -i enp4s0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp4s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:20:29.820931 8c:4b:14:0a:14:63 (oui Unknown) > Broadcast, ethertype Unknown (0x7000), length 60: 
	0x0000:  0000 5468 6973 2069 7320 4553 5033 3220  ..This.is.ESP32.
	0x0010:  4c32 2054 4150 2074 6573 7420 6d73 6720  L2.TAP.test.msg.
	0x0020:  6672 6f6d 2050 6f72 743a 2032 0000       from.Port:.2..
```
Note: replace "enp4s0" with actual name of your Ethernet interface.

                                    

readme of two_ports_mode example

                                        
                                        | Supported Targets | ESP32 |
| ----------------- | ----- |

# KSZ8863 Port Mode Example

## Overview

This example demonstrates initialization and basic usage of KSZ8863 driver in **Port Mode**. See the README.md file in the upper level directories to learn more about this mode.

## How to use example

You will either need one ESP32 with KSZ8863 and two PC's (or other Ethernet capable devices). Or you will need one ESP32 with KSZ8863, one PC (or other Ethernet capable device) and one Ethernet switch. In the first case, connect the network as shown in figure below, configure PC#1 and PC#2 as DHCP servers.

![example network 1](../../docs/example_portmode.png)

In the second case, connect the network as shown in figure below, configure PC#1 as DHCP server.

![example network 2](../../docs/example_portmode_switch.png)

The work flow of the example is then as follows:

1. Install the KSZ8863 Ethernet driver in ESP32.
2. Wait for a DHCP leases in ESP32.
3. If get IP addresses successfully, then you will be able to ping each port of ESP32 device.
4. You will be able to receive **different "L2 Test messages"** from each ESP32 device port (use ``Wireshark`` or ``tcpdump``).

### Configure the project

Configure pin assignment, control interface and RMII REFCLK as per your board needs.

```
idf.py menuconfig
```

For more information, see help associated with each option in ESP-IDF Configuration tool.

### Build, Flash, and Run

Build the project and flash it to the board, then run monitor tool to view serial output:

```
idf.py -p PORT build flash monitor
```

(Replace PORT with the name of the serial port to use.)

(To exit the serial monitor, type ``Ctrl-]``.)

See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects.

## Example Output

**ESP32 with KSZ8863 output:**

```bash
I (475) ksz8863_eth_example: Ethernet Link Up
I (475) ksz8863_eth_example: Ethernet HW Addr 8c:4b:14:0a:14:63
I (2285) ksz8863_eth_example: Ethernet Started
I (2285) ksz8863_eth_example: Ethernet Link Up Port 1
I (2285) ksz8863_eth_example: Ethernet HW Addr 8c:4b:14:0a:14:00
I (3905) esp_netif_handlers: eth0 ip: 192.168.20.107, mask: 255.255.255.0, gw: 192.168.20.1
I (3905) ksz8863_eth_example: Ethernet Got IP Address
I (3905) ksz8863_eth_example: ~~~~~~~~~~~
I (3905) ksz8863_eth_example: ETHIP:192.168.20.107
I (3915) ksz8863_eth_example: ETHMASK:255.255.255.0
I (3925) ksz8863_eth_example: ETHGW:192.168.20.1
I (3925) ksz8863_eth_example: ~~~~~~~~~~~
I (4085) ksz8863_eth_example: Ethernet Started
I (4085) ksz8863_eth_example: Ethernet Link Up Port 2
I (4085) ksz8863_eth_example: Ethernet HW Addr 8c:4b:14:0a:14:01

...

I (5905) esp_netif_handlers: eth1 ip: 192.168.20.106, mask: 255.255.255.0, gw: 192.168.20.1
I (5905) ksz8863_eth_example: Ethernet Got IP Address
I (5905) ksz8863_eth_example: ~~~~~~~~~~~
I (5905) ksz8863_eth_example: ETHIP:192.168.20.106
I (5915) ksz8863_eth_example: ETHMASK:255.255.255.0
I (5925) ksz8863_eth_example: ETHGW:192.168.20.1
I (5925) ksz8863_eth_example: ~~~~~~~~~~~
```
Now you can ping your ESP32 in PC#1 terminal by entering `ping 192.168.20.106` and  `ping 192.168.20.107` (it depends on the actual IP address you get).

You can also check the received test message in PC#1 as follows (on Linux OS and example connected to network with switch):

```bash
$ sudo tcpdump -i enp4s0
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp4s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
13:39:00.358089 8c:4b:14:0a:14:00 (oui Unknown) > Broadcast, ethertype Unknown (0x7000), length 60: 
	0x0000:  0000 5468 6973 2069 7320 4553 5033 3220  ..This.is.ESP32.
	0x0010:  4c32 2054 4150 2074 6573 7420 6d73 6720  L2.TAP.test.msg.
	0x0020:  6672 6f6d 2050 6f72 743a 2031 0000       from.Port:.1..
13:39:00.358089 8c:4b:14:0a:14:01 (oui Unknown) > Broadcast, ethertype Unknown (0x7000), length 60: 
	0x0000:  0000 5468 6973 2069 7320 4553 5033 3220  ..This.is.ESP32.
	0x0010:  4c32 2054 4150 2074 6573 7420 6d73 6720  L2.TAP.test.msg.
	0x0020:  6672 6f6d 2050 6f72 743a 2032 0000       from.Port:.2..
```
Note: replace "enp4s0" with actual name of your Ethernet interface.

                                    

Links

Target

License: Apache-2.0

To add this component to your project, run:

idf.py add-dependency "espressif/ksz8863^0.2.3"

or download archive

Dependencies

  • ESP-IDF >=5.0
  • Examples:

    simple_switch

    more details

    switch_mode

    more details

    two_ports_mode

    more details

    Stats

    • Downloaded in total
      Downloaded in total 110 times
    • Downloaded this version
      This version: 33 times

    Badge

    espressif/ksz8863 version: 0.2.3 |