Re: [PATCH net-next 3/4] net: pse-pd: realtek-pse-mcu: configure global power budget

From: Sander Vanheule

Date: Thu Nov 05 2026 - 16:57:21 EST


Hi Jonas,

On Tue, 2026-11-03 at 22:03 +0000, Jonas Jelonek wrote:
> Use the optional VMAIN regulator power budget to configure the MCU's
> aggregate PoE power limit during probe. Quantize the available budget to
> the protocol's 100 mW units and reserve exactly that amount through the
> regulator core.
>
> The regulator budget represents the usable PoE allowance. Program zero
> reserved power so the previous firmware guard band does not further reduce
> that allowance.
>
> Require a finite budget of at least one protocol unit when vmain-supply is
> provided. Program the budget before selecting dynamic power management and
> ungating the ports, so enforcement starts with the regulator-derived limit.
>
> Enable VMAIN before hardware initialization and register one managed cleanup
> action to free any reserved budget and release the enable reference on probe
> failure and driver removal. Record each successful reservation immediately
> so subsequent initialization failures are covered by this action.
>
> Read the current budget index before programming the MCU. Retain the
> programmed MCU limit on probe failure and driver removal, as reducing that
> limit to zero would interrupt ongoing power delivery.
>
> Boards without vmain-supply retain their existing firmware-managed
> budget.
>
> Signed-off-by: Jonas Jelonek <jonas@xxxxxxxxxxxxxxx>
> ---

...

>  
> +static int rtpse_mcu_get_global_budget_idx(struct rtpse_mcu_ctrl *pse, u8
> *budget_idx)
> +{
> + struct rtpse_mcu_msg req, resp;
> + const struct rtpse_mcu_opcode *opc;
> + int ret;
> +
> + opc = &pse->dialect->opcode[RTPSE_MCU_CMD_GET_POWER_STATUS];
> + if (!opc->valid)
> + return -EOPNOTSUPP;
> +
> + rtpse_mcu_msg_init(&req, opc->op);
> + ret = rtpse_mcu_do_xfer(pse, &req, &resp);
> + if (ret)
> + return ret;
> +
> + if (resp.payload[4] > 0x7)
> + return -ERANGE;
> +
> + *budget_idx = resp.payload[4];
> + return 0;
> +}
> +
> +static int rtpse_mcu_set_global_budget(struct rtpse_mcu_ctrl *pse, u8
> budget_idx,
> +        u16 budget_raw)
> +{
> + const struct rtpse_mcu_opcode *opc;
> + struct rtpse_mcu_msg req, resp;
> + int ret;
> +
> + opc = &pse->dialect->opcode[RTPSE_MCU_CMD_SET_GLOBAL_BUDGET];
> + if (!opc->valid)
> + return -EOPNOTSUPP;
> +
> + rtpse_mcu_msg_init(&req, opc->op);
> + req.payload[0] = budget_idx;
> + put_unaligned_be16(budget_raw, &req.payload[1]);
> + put_unaligned_be16(0, &req.payload[3]);

You don't want to configure a guard band? Can this lead to flapping of devices,
where a port is rapidly switched off and on by the consumed power going above
and below the power limit?

> +
> + ret = rtpse_mcu_do_xfer(pse, &req, &resp);
> + if (ret)
> + return ret;
> + if (resp.payload[0] != budget_idx || resp.payload[1] != 0)
> + return -EIO;
> +
> + return 0;
> +}
> +
> +static int rtpse_mcu_apply_global_budget(struct rtpse_mcu_ctrl *pse,
> + struct regulator *vmain)
> +{
> + int budget, ret;
> + u16 budget_raw;
> + u8 budget_idx;
> +
> + budget = regulator_get_unclaimed_power_budget(vmain);
> + if (budget == INT_MAX)
> + return -ENODATA;
> + if (budget < 0 || budget > U16_MAX * RTPSE_MCU_GLOBAL_BUDGET_LSB_MW)
> + return -ERANGE;
> +
> + budget = rounddown(budget, RTPSE_MCU_GLOBAL_BUDGET_LSB_MW);
> + if (!budget)
> + return -ERANGE;
> + budget_raw = budget / RTPSE_MCU_GLOBAL_BUDGET_LSB_MW;
> +
> + ret = regulator_request_power_budget(vmain, budget);
> + if (ret)
> + return ret;
> + pse->requested_budget_mW = budget;
> +
> + ret = rtpse_mcu_get_global_budget_idx(pse, &budget_idx);
> + if (ret)
> + return ret;
> +
> + /* Retain the programmed MCU limit even if later probe steps fail. */
> + return rtpse_mcu_set_global_budget(pse, budget_idx, budget_raw);

This index is different from an earlier version of this patch, no? 

My (old) documentation [1] describes the retrieved index as:
"Last updated PSE device ID. Also the PSE device the budget belongs to."

I'm afraid I don't remember what I meant with the second part, but I suspect the
power budget needs to be configured on all PSE devices. Does this work
consistently on switches with multiple PSE chips? If "last updated" means it
might sometimes return a lower index, I'm worried this might also lead to some
cases where you query the MCU in the middle of an update cycle.

Otherwise this looks okay to me. I'll try to test it over the weekend.

Best,
Sander

[1] https://svanheule.net/switches/software/broadcom_poe_control_protocol#get_power_statistics