Commit e8c84b98 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-stmmac-dwmac-sophgo-add-phy-interface-filter'

Inochi Amaoto says:

====================
net: stmmac: dwmac-sophgo: Add phy interface filter

As the SG2042 has an internal rx delay, the delay should be remove
when init the mac, otherwise the phy will be misconfigurated.

Since this delay fix is common for other MACs, add a common helper
for it. And use it to fix SG2042.
====================

Link: https://patch.msgid.link/20251114003805.494387-1-inochiama@gmail.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 6e90c767 db37c6e5
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -70,6 +70,25 @@ required:

allOf:
  - $ref: snps,dwmac.yaml#
  - if:
      properties:
        compatible:
          contains:
            const: sophgo,sg2042-dwmac
    then:
      properties:
        phy-mode:
          enum:
            - rgmii-rxid
            - rgmii-id
    else:
      properties:
        phy-mode:
          enum:
            - rgmii
            - rgmii-rxid
            - rgmii-txid
            - rgmii-id

unevaluatedProperties: false

+19 −1
Original line number Diff line number Diff line
@@ -7,11 +7,16 @@

#include <linux/clk.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>

#include "stmmac_platform.h"

struct sophgo_dwmac_data {
	bool has_internal_rx_delay;
};

static int sophgo_sg2044_dwmac_init(struct platform_device *pdev,
				    struct plat_stmmacenet_data *plat_dat,
				    struct stmmac_resources *stmmac_res)
@@ -31,6 +36,7 @@ static int sophgo_sg2044_dwmac_init(struct platform_device *pdev,
static int sophgo_dwmac_probe(struct platform_device *pdev)
{
	struct plat_stmmacenet_data *plat_dat;
	const struct sophgo_dwmac_data *data;
	struct stmmac_resources stmmac_res;
	struct device *dev = &pdev->dev;
	int ret;
@@ -49,11 +55,23 @@ static int sophgo_dwmac_probe(struct platform_device *pdev)
	if (ret)
		return ret;

	data = device_get_match_data(&pdev->dev);
	if (data && data->has_internal_rx_delay) {
		plat_dat->phy_interface = phy_fix_phy_mode_for_mac_delays(plat_dat->phy_interface,
									  false, true);
		if (plat_dat->phy_interface == PHY_INTERFACE_MODE_NA)
			return -EINVAL;
	}

	return stmmac_dvr_probe(dev, plat_dat, &stmmac_res);
}

static const struct sophgo_dwmac_data sg2042_dwmac_data = {
	.has_internal_rx_delay = true,
};

static const struct of_device_id sophgo_dwmac_match[] = {
	{ .compatible = "sophgo,sg2042-dwmac" },
	{ .compatible = "sophgo,sg2042-dwmac", .data = &sg2042_dwmac_data },
	{ .compatible = "sophgo,sg2044-dwmac" },
	{ /* sentinel */ }
};
+43 −0
Original line number Diff line number Diff line
@@ -101,6 +101,49 @@ const char *phy_rate_matching_to_str(int rate_matching)
}
EXPORT_SYMBOL_GPL(phy_rate_matching_to_str);

/**
 * phy_fix_phy_mode_for_mac_delays - Convenience function for fixing PHY
 * mode based on whether mac adds internal delay
 *
 * @interface: The current interface mode of the port
 * @mac_txid: True if the mac adds internal tx delay
 * @mac_rxid: True if the mac adds internal rx delay
 *
 * Return: fixed PHY mode, or PHY_INTERFACE_MODE_NA if the interface can
 * not apply the internal delay
 */
phy_interface_t phy_fix_phy_mode_for_mac_delays(phy_interface_t interface,
						bool mac_txid, bool mac_rxid)
{
	if (!phy_interface_mode_is_rgmii(interface))
		return interface;

	if (mac_txid && mac_rxid) {
		if (interface == PHY_INTERFACE_MODE_RGMII_ID)
			return PHY_INTERFACE_MODE_RGMII;
		return PHY_INTERFACE_MODE_NA;
	}

	if (mac_txid) {
		if (interface == PHY_INTERFACE_MODE_RGMII_ID)
			return PHY_INTERFACE_MODE_RGMII_RXID;
		if (interface == PHY_INTERFACE_MODE_RGMII_TXID)
			return PHY_INTERFACE_MODE_RGMII;
		return PHY_INTERFACE_MODE_NA;
	}

	if (mac_rxid) {
		if (interface == PHY_INTERFACE_MODE_RGMII_ID)
			return PHY_INTERFACE_MODE_RGMII_TXID;
		if (interface == PHY_INTERFACE_MODE_RGMII_RXID)
			return PHY_INTERFACE_MODE_RGMII;
		return PHY_INTERFACE_MODE_NA;
	}

	return interface;
}
EXPORT_SYMBOL_GPL(phy_fix_phy_mode_for_mac_delays);

/**
 * phy_interface_num_ports - Return the number of links that can be carried by
 *			     a given MAC-PHY physical link. Returns 0 if this is
+3 −0
Original line number Diff line number Diff line
@@ -2040,6 +2040,9 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev)
	return phydev->is_pseudo_fixed_link;
}

phy_interface_t phy_fix_phy_mode_for_mac_delays(phy_interface_t interface,
						bool mac_txid, bool mac_rxid);

int phy_save_page(struct phy_device *phydev);
int phy_select_page(struct phy_device *phydev, int page);
int phy_restore_page(struct phy_device *phydev, int oldpage, int ret);