Power over Ethernet (PoE) support into the official Linux Kernel

Introduction

Power over Ethernet (PoE) is a technology that combines power and data transmission over a single Ethernet cable. It simplifies the installation of networked devices like cameras, phones, and wireless access points by eliminating the need for separate power cables. PoE standards define how power is delivered alongside data, ensuring compatibility across devices. Originally denoted as “Power via MDI” (Media Dependent Interface) in the 802.3 IEEE standard, it later evolved into the recognized term “PoE” in the 2022 version of the standard. PoE equipment consists of two key components: Power Sourcing Equipment (PSE) and Powered Devices (PD).

Linux support, DENT initiative

Up until recently, the upstream Linux kernel had absolutely no support for Power over Ethernet technologies. Due to that, every hardware vendor providing PoE hardware was delivering its own vendor-specific and non-standard solution, often centered around not so great user-space libraries, with dubious integration with the rest of the Linux ecosystem and networking stack, like is unfortunately still done quite often by hardware vendors.

The DENT project, which exists under the umbrella of the Linux Foundation, aims at using the Linux Kernel, Switchdev, and other Linux based projects as the basis for building a new standardized network operating system without abstractions or overhead. Among other things supported by DENT is dentOS, a SwitchDev based NOS built on top of Open Network Linux, which includes PoE support, but based on yet another non-standard fully user-space driven solution in the name of poed, where even the HW-specific drivers are implemented in user-space.

So DENT set as a goal to implement a fully upstream solution in the Linux kernel to properly support Power over Ethernet, and contracted Bootlin to perform this development and upstreaming effort.

Previous work

While PoE was not supported in the Linux kernel, in 2022 a PSE (Power Sourcing Equipment) subsystem was added in drivers/net/pse-pd by Oleksij Rempel, with only support for a related technology called Power over Data-Lines (PoDL), standardized by 802.3bu. The work from Oleksij Rempel only supported PoDL, with power provided by a simple regulator provided by the Linux kernel regulator subsystem. As should be the case for any upstream work, we built on top of this existing work to implement for PoE.

Initial support

Our first goal was to bring minimal support for PoE, with only basic features such as enabling/disabling power, and getting the status of a port. In order to prove that our work was generic enough, we set out to implement drivers for two completely different PoE controllers: the Microchip PD692x0 and the TI TPS23881.

Microchip PD692x0 datasheet extract

Bootlin engineer Köry Maincent conducted this development and its upstreaming, which took no less than 9 iterations, from mid-November 2023 to mid-April 2024:

Our 9th iteration has been merged, and will be part of the upcoming Linux 6.10 release, with the following main commits:

In the interest of clarity and consistency within the kernel’s networking subsystem, support for PoE is referred to as “c33”. This naming aligns with Clause 33 of the IEEE 802.3 standard, specifically addressing PoE specifications.

Our patch series:

  1. Extends the existing PSE subsystem to support c33 (PoE), while relying on the same netlink based interface to user-space
  2. Extends the PSE bindings to add the PSE Power Interface (PI) pairset pinout connection and polarity configuration.
  3. Uses regulator framework to benefit in the future for already written features like power limit, voltage status and sysfs description.

Together with the Linux kernel side, we contributed to ethtool to have user-space control for PoE. A single commit was needed for the basic support: ethtool: pse-pd: Add support for Power over Ethernet (clause 33)

Here is a minimal example of a Device Tree showing how we hooked up the TI TPS23881 evaluation board, called BOOST-PSEMTHR-007 to an STM32MP157 Discovery Kit, on which we wired only one Ethernet port through the PoE eval board:

&i2c5 {
	status = "okay";

	tps2388:ethernet-pse@20 {
		compatible = "ti,tps23881";
		reg = <0x20>;
		channels {
			#address-cells = <1>;
			#size-cells = <0>;

			phys0: channel@0 {
				reg = <0>;
			};

			phys1: channel@1 {
				reg = <1>;
			};

			phys2: channel@2 {
				reg = <2>;
			};

			phys3: channel@3 {
				reg = <3>;
			};

			phys4: channel@5 {
				reg = <4>;
			};

			phys5: channel@5 {
				reg = <5>;
			};

			phys6: channel@6 {
				reg = <6>;
			};

			phys7: channel@7 {
				reg = <7>;
			};
		};

		pse-pis {
			#address-cells = <1>;
			#size-cells = <0>;

			pse_pi0: pse-pi@0 {
				reg = <0>;
				#pse-cells = <0>;
				pairset-names = "alternative-a";
				pairsets = <&phys0>;
				polarity-supported = "MDI";
			};

			pse_pi1: pse-pi@1 {
				reg = <1>;
				#pse-cells = <0>;
				pairset-names = "alternative-a", "alternative-b";
				pairsets = <&phys6 &phys7>;
				polarity-supported = "MDI", "S";
			};
		};
	};
};

&phy0 {
	pses = <&pse_pi0>;
};

In this Device Tree snippet, we describe the TI TPS23881 chip connected to the I2C5 bus of our system-on-chip. This TPS23881 chip has a total of 8 channels to provide power. In this particular exemple, we describe 2 PSE power interfaces:

  • pse_pi0, describes a power interface that uses the single “Alternative A” pair to provide power, using the channel phys0. This power interface is then described to be used by the single Ethernet interface of our board, through the pses property of the phy0 node, which is the standard Ethernet PHY Device Tree node
  • pse_pi1, describes another power interface that would be used for a two pairs PoE port, where both the “Alternative A” and “Alternative B” pairs are used together to provide power, which is why two channels, phys6 and phys7 are referenced here. The careful reader will notice that this pse_pi1 is not referenced anywhere, as it is indeed not used, and only shown here for illustration purposes

With this in place, one can then control PoE in a completely standard manner using the standard ethtool utility:

# ethtool --show-pse eth0
PSE attributes for eth0:
Clause 33 PSE Admin State: disabled
Clause 33 PSE Power Detection Status: disabled
# ethtool --set-pse eth0 c33-pse-admin-control enable
# ethtool --show-pse eth0
PSE attributes for eth0:
Clause 33 PSE Admin State: enabled
Clause 33 PSE Power Detection Status: delivering power

As is probably obvious from the example, we are able to show the state of the PSE associated to the eth0 network interface, then enable power on this PSE, and show the new state of the PSE.

Improved support

With the initial support merged and included for Linux 6.10, we started working on the next set of features, which include:

  • support for several more status information like consumed power, negotiated class and an extended state report
  • support for reading and configuring the PoE ports power limit

After its development, this work has gone through 6 iterations on the mailing list:

Our 6th iteration was merged very recently, and therefore it is currently in net-next and should become part of Linux 6.11. Here is the full list of commits that have been merged for this improved PoE support:

We still have to submit a few patches against ethtool to provide an easy to use user-space tool for those new features.

Talk at the Embedded Linux Conference

In order to give more details about this work, Köry Maincent gave a talk titled Adding support for PoE at the Embedded Linux Conference in Seattle, in April 2024. See the slides and video below.



Next steps

We are already very proud of these first two steps of PoE supported merged in the upstream Linux kernel, but we have more plans for the coming months, and most notably:

  • Support port priority, to define what will happen when the available power is not sufficient to power all devices over PoE, and shutdown the lowest priority devices
  • Support the PD62x0 persistent configuration mechanism, so that the PD692x0 retains its custom configuration across reboots
  • Modify the poed project to use the new standard Linux interface for PoE, instead of user-space drivers

Of course, do not hesitate to get in touch if you’re a user of PoE, or a provider of PoE hardware. We would definitely be interested in adding support for your use-case or hardware, and expand the upstream Linux kernel support for PoE!

Author: Köry Maincent

Köry Maincent is an embedded Linux and kernel engineer at Bootlin, which he joined in 2020.

Leave a Reply