[PATCH v4 2/2] phy: mediatek: Add support for PCI-Express Gen4 S-PHY

AngeloGioacchino Del Regno angelogioacchino.delregno at collabora.com
Tue Sep 15 03:59:02 PDT 2026


On 9/15/26 12:26, sashiko-bot at kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] phy: mediatek: endianness bug when reading split NVMEM cells in mtk_pcie_sphy_get_one_cal_para()
> --
> 
> commit ab276d5dc9414b3b5618ea96c84dcc086bdf9036
> Author: AngeloGioacchino Del Regno <angelogioacchino.delregno at collabora.com>
> 
> phy: mediatek: Add support for PCI-Express Gen4 S-PHY
> 
> This commit introduces the driver for the PCI-Express Gen4 S-PHY found in
> recent MediaTek SoCs such as MT6991 and MT8196. It implements the PHY
> initialization routines and handles reading eFuse calibration data from
> the NVMEM framework.
> 
>> diff --git a/drivers/phy/mediatek/phy-mtk-pcie-sphy.c b/drivers/phy/mediatek/phy-mtk-pcie-sphy.c
>> new file mode 100644
>> index 0000000000000..2bf10346ea97a
>> --- /dev/null
>> +++ b/drivers/phy/mediatek/phy-mtk-pcie-sphy.c
> [ ... ]
>> +static int mtk_pcie_sphy_get_one_cal_para(struct device *dev, const char *name, u8 max_val)
>> +{
>> +	u16 buf;
>> +	u8 tmp;
>> +	int ret;
>> +
>> +	/*
>> +	 * All of the calibrations are always max 8 bits long, but some may
>> +	 * be split between two different 8-bits cells: handle this corner
>> +	 * case by retrying reading as u16.
>> +	 */
>> +	ret = nvmem_cell_read_u8(dev, name, &tmp);
>> +	if (ret == 0)
>> +		buf = tmp;
>> +	else
>> +		ret = nvmem_cell_read_u16(dev, name, &buf);
> 
> [Severity: Medium]
> When an 8-bit (or smaller) NVMEM cell crosses a byte boundary in hardware,
> the NVMEM core evaluates its length as 2 bytes, causing nvmem_cell_read_u8()
> to fail with -EINVAL.
> 
> Does falling back to nvmem_cell_read_u16() cause an endianness issue here?

No, it reads fine.

> 
> Because the NVMEM core populates the buffer with a direct memory copy, the
> shifted valid data is placed in the first byte and zeroes in the second byte.
> On big-endian architectures

But this runs only on LE architectures.

>, interpreting this buffer directly as a native
> u16 variable evaluates to buf[0] << 8, which effectively multiplies the
> calibration value by 256. This could lead to spurious -ERANGE failures or
> incorrect calibration values being written to the PHY.
> 
> Would it be safer to use nvmem_cell_read_variable_le_u32() to handle these
> split cells robustly across different architectures?
> 
>> +
>> +	if (ret == -ENOENT) {
>> +		dev_info(dev, "No calibration for %s. Using defaults\n", name);
>> +		return -ENOENT;
>> +	} else if (ret)
>> +		return dev_err_probe(dev, ret,
>> +				     "Cannot get calibration data for %s\n", name);
>> +
>> +	if (buf > max_val)
>> +		return dev_err_probe(dev, -ERANGE,
>> +				     "Bad value %u retrieved for %s.\n", buf, name);
>> +
>> +	return buf;
>> +}
> [ ... ]
> 



More information about the linux-phy mailing list