Broadcom PoE control protocol

On the Broadcom PoE platform, an intermediate microcontroller is used to managed a Broadcom PSE controller, like the BCM59121. Although more than one microcontroller type is used over different products, they all appear to use the same serial protocol. The high level control and status commands between the microcontroller and SoC use the SoC's secondary UART. The UART connection between the SoC and microcontroller typically uses a 19200 baud, 8n1 connection. Communication between the microcontroller and the Broadcom chip uses Broadcom Serial Control (BSC), an I2C dialect.

Port to PSE output mapping

The MCU firmware used to manage the BCM59121 PSE controllers supports two port mapping modes:

Port mapping

Simple port mapping uses a look-up table mapping port numbers to PSE controller power outputs. To use this feature, pair mapping cannot be enabled. To configure the port mapping, use the Set port map enable and Set port mapping commands.

Pair mapping

Pair mapping must use a more complicated mapping to match the required PSE controller outputs to a port number. The paired outputs _must_ be located on the same PSE controller. With pair mapping enabled, returned port power values will now be the sum of the power provided by both outputs. This feature is not yet well understood.

Serial control protocol

The SoC controls the PoE controller as a slave device. A request frame is sent, to which the controller must respond. Request and reply frames are always 12 bytes long. They start with a command and a frame identifier. Frame IDs are usually sequential, but this is not required. After the 2-byte header, are 9 bytes of data. Finally the frame is terminated by a checksum, which is the sum of the preceding bytes, modulo 256. If not all data bytes are used, the data is padded with ff. Normally, the reply must contain the same command and frame ID bytes. If a request error was detected, a number of special reply commands may be returned.

Offset |         +0 |         +1 |         +2 |         +3 |
-------+------------+------------+------------+------------+
   0x0 | Command    | Frame ID   | Data[0:2]             ...
       +------------+------------+------------+------------+   
   0x4 | Data[2:6]                                       ...
       +------------+------------+------------+------------+
   0x8 | Data[6:9]                            | Checksum   |
       +------------+------------+------------+------------+

Below is a list of commands used by switches of multiple vendors. Port indices are 0-based. Unless noted otherwise, every field listed in brackets consists of one byte. Longer fields use big-endian encoding.

Set system configuration

Read system configuration and status

PoE status LED configuration

ID Description Request format Reply format Comment
41 Set port LED config
42 Get port LED config
43 Set system LED config
44 Get system LED config
48 Set port LED map
49 Get port LED map

MCU management commands

ID Description Request format Reply format Comment
af Bootloader mode n/a Controller is still booted in bootloader mode, and is requesting a FW image
e0 MCU management varies varies Special commands to manage the MCU firmware
fd Request incomplete n/a An incomplete request was received
fe Request checksum n/a Request frame checksum was incorrect
ff Not ready n/a Controller was not ready to respond

Command details

Set port enable

Enable or disable a port, by setting the "administrative status". A port can be always off, use load detection before powering the port, or provide permanent power to the output.

Field Size Description
port 1 Port index number.
enable 1 Administrative status
00: Disable port
01: Enable port
02: Forced enable. Not observed in production firmware, so use at own risk.
03: Forced enable with disconnect detection. Not observed in production firmware, so use at own risk.

Set port map enable

Enable or disable port mapping. If pair mapping is already enabled, 'error' will be non-zero. See also Set port mapping.

Field Size Description
enable 1 00: Disable port mapping, 01: Enable port mapping

Port reset

Issue a port reset. This will restart the PSE controller output(s) and start the device detection if the port is enabled.

Field Size Description
port 1 Port index number.
reset 1 Issue a reset if 01, ignore otherwise.

Clear counters

Clear the accumulators that keep track of the port counters. See Get port counters for a list of values that will be reset to 0 for all ports, when this command is issued.

Field Size Description
clear 1 01: Clear all port counters, ignore request on other values.

Set global port enable

Convenience call to enable or disable all ports simultaneously. Has the same effect as enabling or disabling the port one by one.

Field Size Description
enable 1 00 to disable, 01 to enable.

Set global port power limit

Configure the maximum power budget that can be assigned to any single port, in case a user-specified power budget is set. 802.3at devices should use 02 for high_power, which corresponds to the maximum power for a class 4 PD.

Field Size Description
high_power 1 Power budget for high power devices.
00: 22.5W
01: 26.5W
02: 31.2W
03: 37.0W

Set device config

Field Size Description
uvlo 1 Under-voltage lockout threshold, defaults to aa. The under-voltage threshold is calculated as (33V + 64.45mV×uvlo).
ddflag 1 Unknown boolean parameter, defaults to 00. (Field name from Zyxel GS1920)
ovlo 1 Over-voltage lockout threshold, defaults to 01. The over-voltage threshold is calculated as (57V + 64.45mV×ovlo).
p3 1 Unknown boolean parameter. Defaults to 00, but is stored as a byte and usually set to ff (bug?).

Set device power management

Power budget accounting modes: "pre-allocated" or "actual usage". If 'pre_alloc' is set to 1, the switch will calculate the used power from the maximum power a port can use. When the switch's power is set to 60W, this means only two 30W devices could be connected. If 'pre_alloc' is set to 0, the switch will allow for over-assigning power budget. For a power budget of 60W, this means e.g. five devices could be with a power limit set to 30W, as long as the total power draw does not exceed the 60W.

Field Size Description
pre_alloc 1 Use pre-allocated power budgets.
00: Total power usage is calculated with allocated power budgets
01: Total power usage is calculated with the actual power draw
powerup_mode 1 00=simultaneous power-up
01=staggered power-up
02 (on Netgear FW v1.8)
disconnect_order 1 Port disconnect order
00: Disconnect overloaded port first
01: Disconnect ports based on priority
gb_hysteresis 1 When recovering from an excessive power draw event, the consumed power must drop by this value below the power budget before the alarm status is cleared. In units of 100mW. Valid values must be less than ff, otherwise this value is ignored.

Set port to PSE output mapping

Field Size Description
port 1 Port index number. This corresponds to the port number as specified on the device's front panel.
b1 1 Values: 0-1
b2 1 Values: 0-15, likely PSE controller index
b3 1 Values: 0-7, likely a PSE output index
b4 1 Values: 0-7, likely a PSE output index
b5 1 Values: 0-3
b6 1 Values: 0-3
b7 1 Values: 0-1

Set detection type

Field Size Description
port 1 Port index number. Use 7f to configure all ports with one command.
detection_type 1 00: No detection
01: Legacy
02: IEEE 802.3af 4-point detection (default)
03: IEEE 802.3af 4-point detection, followed by legacy
04: IEEE 802.3af 2-point detection (not supported)
05: IEEE 802.3af 2-point detection, followed by legacy

Set classification enable

Field Size Description
port 1 Port index number
classification 1 Automatic PD classification
00: Disable
01: Enable

Set disconnect type

Select the port disconnect detection type. Most likely this selects DC or AC disconnect detection, as defined by the PoE standards. No firmware has been seen to allow modification of this parameter, all reporting a value of DC-disconnect.

Field Size Description
port 1 Port index number. Use 7f to configure all ports with one command.
disconnect 1 Values: 0-3, no switch firmware has been observed to change the default value (2).
00: none
01: AC-disconnect
02: DC-disconnect
03: DC with delay

Set port power limit type

Field Size Description
port 1 0-based port index
limit_type 1 00: None. Power limit is 16.2W if the connected device is "low power", or the set high power limit if the device is "high power".
01: Class based. The power limit for class 4 devices is determined by the high power limit.
02: User defined, see Set port power budget

Set port power budget

Field Size Description
port 1 0-based port index
power_limit 1 Power budget in units of 0.2W

Set power management mode

Field Size Description
mode 1 01=static (Netgear)
02=dynamic (Netgear)
04 (Ubiquiti)

Set global power budget

Configure power budget available to all ports combined. 'total_power' gives the absolute maximum amount of power the PSE controller should deliver. 'guard_band' is the spare power budget. If at some point the total power draw from the PSE controller exceeds (total_power - guard_band), the PSE controller will start shutting devices down. Valid pse_ctrl index numbers must be smaller than the number of controllers reported by Get extended device config.

Field Size Description
pse_ctrl 1 PSE controller index number
total_power 2 Total power the PoE switch can deliver to all ports. In units of 0.1W.
guard_band 2 Power budget that should not be allocated to devices, but used a buffer in case of overload. In units of 0.1W.

Set port power pair

Select the power pair to use for the requested port(s). Note that is only makes sense to set this if it's actually possible to use the alternative power pair.

Field Size Description
port 1 Port index number
pair 1 Power pair
00: Use A pair (+1,2;-3,6)
01: Use B pair (+3,4;-7,8)

Set port priority

When the switch's assigned power budget is exceeded, powered devices must be switched off. The order in which this happens, can be managed by setting the port priority. Low priority devices will be switched of before normal priority devices, etc.

Field Size Description
port 1 Port index number
priority 1 00 = Low
01 = Normal
02 = High
03 = Critical

Set port power-up mode

Descriptions for port modes 0-3 come from the Netgear firmware. Modes 3, 5 are used by 802.3at devices from Ubiquiti. 802.3bt modes are most likely not supported on pre-802.3bt hardware.

Field Size Description
port 1 Index of port to configure
mode 1 00: 802.3af
01: legacy mode, for high inrush current devices
02: pre-802.3at
03: 802.3at
04: pre-802.3bt
05: 802.3bt

Set port mapping

Configure the mapping of port numbers to PSE output numbers. The PSE outputs are indexed by (8×APSE + N), where APSE is the PSE index, ranging from 0 to 11, and N is the N-th output on the PSE controller, ranging from 0 to 7. The "easiest" way to figure out the port mapping, is to get this from the vendor firmware. Alternative, one can sniff the serial traffic to see what values are set.

Field Size Description
port 1 Port index number
pse_output 1 PSE output index number

Get system info

Field Size Description
mode 1
max_ports 1 Maximum number of supported ports
port_map 1 Lowest bit indicates port mapping is set
device_id 2 e011=BCM59011
e111=BCM59111
e121=BCM59121
version 1 PoE firmware version, see also 'version_ext'. Full firmware version is 'version.version_ext'
mcu_type 1 00="ST Micro ST32F100"
01="Nuvoton M05xx LAN"
02="ST Micro STF030C8"
03="Nuvoton M058SAN"
04="Nuvoton NUC122"
system_status 1 System status flags.
Bit 0: Config modified, system is running with unsaved configuration changes
Bit 2: Set if the "remote enable" signal is active
Bit 3: Output pairing enabled
version_ext 1 Extended firmware version, see also 'version'

Get port status

Detailed port status. A port status summary can also be obtained with Get all port status, which packs a number of value returned by this command in one byte. When the port state is "delivering power" or "requesting power", the fault type field will just be copy of the class info field in FW v1.x.

Field Size Description
port 1 Port index number
state 1 00: Disabled
01: Searching
02: Delivering
03: Test mode
04: Fault
05: Other fault
06: Requesting
fault_type 1 Port fault type, ignore when state is 02 or 06
00: OVLO
01: MPS absent
02: Short
03: Overload
04: Power denied
05: Thermal shutdown
06: Start-up failure
07: UVLO
class_info 1 Detected PoE-PD device class
pd_type 1 00: None
01: IEEE PD
02: Pre-standard PD
03: Ext detection range
mpss_mask 1 "Port power disconnect map"
power_mode 1 00: 2-pair 15W
01: 2-pair 30W
02: 4-pair 30W
03: 4-pair 60W
04: 4-pair 15W
05: 4-pair 90W
06: 2-pair 45W
chan_pwr 1 00: Both down
01: Primary up
02: Alternative up
03: Both up
pd_alt 1 Power delivery alternative.
00: PD None
01: Shared PD
02: Separate PD
03: Unknown PD

Get port counters

Returns the error counters for the requested port. Since these counter are only 1 byte in size, e.g. invalid_signature can overflow quite quickly if no device is connected to the port. A larger counter should be stored in the management daemon to keep track of the counter totals, and the reset flag should be set to clear the MCU counters after reading.

Field Size Description
port 1 Port index number
reset 1 Reset counters after reading
overload 1 Number of times the port failed due to overload
short 1 Number of times the port failed due to a short-circuit
denied 1 Number of times the port was denied power
mps_absent 1 Number of times the MPS was absent
invalid_signature 1 Number of times the port was polled, but no device was found

Get power statistics

Field Size Description
consumed 2 Total consumed power, in units of 0.1W.
budget 2 Total available power budget, in units of 0.1W. This is equal to the system's power budget, minus the guard band.
b3 1
high_power 1 High power setting.
gb_hysteresis 1 Excessive power draw recovery hysteresis. Power draw must drop this much into the guard band before the system status is restored. In units of 0.1W.

Get port config

Field Size Description
port 1 Port index number
enable 1 Indicates if the port is enabled
auto_powerup 1
detection_type 1 Port detection type, see Set detection type
classification_enable 1 Enable PD classification, see Set classification enable
disconnect 1 Port disconnect type
pair 1 Port power pair, see Set port power pair

Get extended port config

Field Size Description
port 1 Port index number
powerup_mode 1 See Set port power-up mode.
power_limit_type 1 See Set port power limit type.
power_budget 1 Port power budget in units of 0.2W. See Set port power budget.
priority 1 See Set port priority.
primary_pse_output 1 Index number of the primary PSE output (to be verified)
secondary_pse_output 1 Index number of the secondary PSE output (to be verified)
primary_power_limit 1 Raw primary PSE output power limit, not used if a class based or user defined power limit is set

Get power management mode

On Ubiquiti switches, the request data is a single byte, hardcoded to 07.

On firmware version v1.6 and up, this command has been butchered up to replace the echo byte with a data byte, allowing for a response with 10 bytes instead of 9.

Field Size Description
pse 1 PSE controller index
mode 1 Power management mode. See Set power management mode
power_limit_0 2 Configured system power for the selected PSE index (FW v1.6 or higher)
guard_band_0 2 Configured guard band for the selected PSE index (FW v1.6 or higher)
power_limit_1 2 Configured system power for the selected PSE index + 1 (FW v1.6 or higher)
guard_band_1 2 Configured guard band for the selected PSE index + 1 (FW v1.6 or higher)

Get all port status

This command provides a quick way to poll the status of all ports. Multiple port statuses are requested simultaneously by repeating the 2-byte request for each port of interest. The short_status return value has three bit fields: <[7] [6 5 4] [3 2 1 0]>. Note that the meaning of bit 6:4 depends on the status returned by the lower nibble. If the port is delivering (or requesting) power, this field will contain the PoE device class. If the port has experienced a fault, this field will contain the fault type.

Field Size Description
port 1 Port index number
short_status[7] 1 bit PD type. If the powered device is standards compliant, this flag is set. This corresponds to 'pd_type' from Get port status being equal to 01, i.e "IEEE PD".
short_status[6:4] 3 bit If short_status[3:0] is 'Delivering power' or 'Requesting power': PoE device class, like 'class_info' from Get port status.

If short_status[3:0] is not 'Delivering power' or 'Requesting power': Port fault status, like 'fault_type' from Get port status.
0 = OVLO (over-voltage lockout)
1 = MPS absent
2 = Short
3 = Overload
4 = Power denied
5 = Thermal shutdown
6 = Start-up failure
7 = UVLO (under-voltage lockout)
short_status[3:0] 4 bit Port status, like 'state' from Get port status.
0 = Disabled
1 = Searching
2 = Delivering power
4 = Fault
5 = Other fault
6 = Requesting power

Get all PSE output consumed power

Request the currently consumed power for a number of PSE outputs. The returned value is expressed in units of 0.2W, so the value fits in one byte. See Get port measurements to read the port power instead of the PSE output power.

Field Size Description
pse_output 1 Port index number
consumed_power 1 Consumed power on the requested PSE output, in units of 0.2W.

Get port overview

Deprecated, use Get all port status.

Return the short status for eight ports, starting at the requested port.

Field Size Description
first_port 1 Port index number of the first requested port.
short_status 8×1 Packed status with standards compliant flag, PD class, failure type and port status. See 'short_status' from Get all port status for packing details.

Get extended device config

Field Size Description
uvlo 1 Under-voltage lockout threshold, see Set device config
pre_alloc 1
powerup_mode 1
disconnect 1
ddflag 1 See Set device config
ovlo 1 Over-voltage lockout threshold, see Set device config
num_pse 1 Number of BCM59xxx PSE controllers present in the system
ext_param_7 1 p3 from Set device config
ext_param_8 1 3 LSB are flags

Get direct PSE flag

Returns a system-wide mask in the first data byte. The second byte contains an OR-ed status returned for all PSE output channels. All other bytes are set to zero. The system-wide mask can be set by command 0d.

Get direct PSE status

Get port measurements

Field Size Description
port 1 Port index number
voltage 2 Measured supplied voltage, in units of 64.45mV
current 2 Measured current, in units of 1mA
temperature 2 Measured temperature. The value can be converted to Celsius by (220 - temperature)×1.25°C.
power 2 Measured power, in units of 0.1W

Set port LED config

Configure the MCU to manage the PoE status LEDs of the network ports. The fields 'off', 'req(uesting)', 'err(or)', and 'on' contain packed bitmasks: <[B] [S] 0 0 0 0 [m m]>:

The LED mask bits are written out directly to hardware, so you will have to take into account the physical layout of the LEDs. If for example two LEDs are in an anti-parallel configuration, both the 00 and 11 values for the LED mask will result in no output being shown, as there would be no voltage difference across the LEDs. This is often the case with the bi-color LEDs used in RJ45 sockets.

Field Size Description
enable 1 Enable port LED management
interface 1 Interface used to drive port LEDs shift register
00: SPI
01: GPIO (parallel port)
shift_order 1 00: LSB first
01: MSB first
port_led_count 1 Number of LEDs used per port. Determines the number of valid led mask bits in the fields 'off', 'req', 'err', and 'on'.
01: one LED per port
02: two LEDs per port
off 1 LED values used when the PoE status is 'disabled' or 'searching' (1 or 2 bits)
req 1 LED values used when the PoE status is 'requesting' (1 or 2 bits).
If the B bit is also set (0x80 | led_mask), then the selected LED(s) will blink at 2Hz.
err 1 LED values used when the PoE status is 'fault' or 'other fault' (1 or 2 bits).
If B bit is also set (0x80 | led_mask), then the selected LED(s) will blink at 10Hz.
on 1 LED values used when the PoE status is 'delivering' (1 or 2 bits).
If S bit is also set (0x40 | led_mask), the led_mask should only contain one bit. This will be the LED to indicate 802.3at PD, the other LED will indicate 802.3af PD.
blink_override 1 Optional, valid values <0-3>. If present, this will override the blink bits from 'req' and 'err'.
01: set bit to enable blinking when the port status is 'requesting'
02: set bit to enable blinking the the port in a fault state

Get port LED config

Get the PoE status LED configuration for the network ports. See Set port LED config for the field details.

Set system LED config

Configure the MCU to manage the PoE system status LED.

Field Size Description
sys_ok 1 00: output low
01: output high
in_gb 1 00: output low
01: output high
02: output blink slow (2Hz)
03: output blink fast (10Hz)
out_of_gb 1 00: output low
01: output high
02: output blink slow (2Hz)
03: output blink fast (10Hz)
exceeds_ps 1 00: output low
01: output high
02: output blink slow (2Hz)
03: output blink fast (10Hz)
out_of_gb_off_delay 1 Time in seconds the out_of_gb LED stays blinking after the condition is de-asserted. If simple on/off is used there is no off-delay.
exceeds_ps_off_delay 1 Time in seconds the exceeds_ps LED stays blinking after the condition is de-asserted. If simple on/off is used there is no off-delay.
map_enable 1 Optional flag to enable PoE port LED mapping.
00 or ff: mapping disabled
01: mapping enabled

Get system LED config

Get PoE system status LED configuration. See Set system LED config for the field details.

Set port LED map

If port PoE LEDs are managed by the MCU, and the order of LEDs does not match the port numbers on the device, a port PoE LED mapping can be set.

This command allows to set the mapping, eight ports at a time. The port offset must be a multiple of 8, otherwise this value will be rounded down by the MCU. The eight following bytes then respresent the LED index corresponding to (port_offset), (port_offset+1)…

By default, the MCU will initialise the port mapping such that the LED indices equal the port index numbers.

Field Size Description
port_offset 1 Port index number, must be a multiple of 8. Otherwise, mapping data will be written to 8×floor(port_offset/8)
led_index[i] 8×1 Eight bytes representing the LED indices corresponding to (port_offset+i).

Get port LED map

Read the port PoE LED mapping, eight ports at a time. See Set port LED map.

The port offset must be a multiple of 8, otherwise this value will be rounded down by the MCU. The eight following bytes then respresent the LED index corresponding to (port_offset), (port_offset+1)…

Field Size Description
port_offset 1 Port index number, must be a multiple of 8. Otherwise, mapping data will be read from 8×floor(port_offset/8)
led_index[i] 8×1 Eight bytes representing the LED indices corresponding to (port_offset+i).

MCU management

The frame format used for regular commands, does not apply to MCU management frames. Some control commands are formatted as a regular frame, but with the echo field used as a subcommand: e0 [subcommand] [9 data bytes] [checksum]

Extended command Payload data format Description
e0 40 no payload Check firmware CRC and reset MCU.
e0 80 [offset] {data} Write MCU image data bytes {data} at address offset (16 bit, big endian). {data} can vary in length.
e0 c0 10 bytes: all-ff frame with checksum Clear MCU image. The application image is erased to prepare for a new image to be uploaded.
e0 e0 10 bytes: all-ff frame with checksum Clear saved configuration in flash.
e0 f0 10 bytes: all-ff frame with checksum Save runtime configuration to flash, which is then loaded again on system power-up.

To flash a new MCU firmware, follow the following procedure:

  1. Clear the MCU image with a e0 c0 command.
  2. Verify the MCU is requesting a new image, by polling e.g. system info and checking the reply command to be af
  3. Write the new MCU image with the e0 80 command. The MCU replies with an af frame when the data was written successfully.
  4. After writing all data, request a CRC check and reset the MCU with a e0 40 command. If the firmware write was successful, the MCU will run in application mode, instead of bootloader mode.

In Netgear and Zyxel firmwares, the MCU write payload length is 8 bytes, to match the normal 12 byte frame size. In Ubiquiti firmware, the payload length is 20 bytes, possibly to speed up MCU flashing. Ubiquiti sends a shorter final frame if the MCU firmware length was not a multiple of 20. Other firmwares assume the FW length is a multiple of 8 bytes, so may send trailing garbage in the last frame (but probably won't).