Commit 01972fa9 authored by Russell King (Oracle)'s avatar Russell King (Oracle) Committed by Jakub Kicinski
Browse files

net: phy: aquantia: fill in possible_interfaces for AQR113C



Fill in the possible_interfaces bitmap for AQR113C so phylink knows
which interface modes will be used by the PHY.

Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/E1r6VI6-00DDLl-2D@rmk-PC.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a2258333
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -47,6 +47,11 @@
#define VEND1_GLOBAL_CFG_5G			0x031e
#define VEND1_GLOBAL_CFG_10G			0x031f
/* ...and now the fields */
#define VEND1_GLOBAL_CFG_SERDES_MODE		GENMASK(2, 0)
#define VEND1_GLOBAL_CFG_SERDES_MODE_XFI	0
#define VEND1_GLOBAL_CFG_SERDES_MODE_SGMII	3
#define VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII	4
#define VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G	6
#define VEND1_GLOBAL_CFG_RATE_ADAPT		GENMASK(8, 7)
#define VEND1_GLOBAL_CFG_RATE_ADAPT_NONE	0
#define VEND1_GLOBAL_CFG_RATE_ADAPT_USX		1
+75 −1
Original line number Diff line number Diff line
@@ -656,6 +656,80 @@ static int aqr107_resume(struct phy_device *phydev)
	return aqr107_wait_processor_intensive_op(phydev);
}

static const u16 aqr_global_cfg_regs[] = {
	VEND1_GLOBAL_CFG_10M,
	VEND1_GLOBAL_CFG_100M,
	VEND1_GLOBAL_CFG_1G,
	VEND1_GLOBAL_CFG_2_5G,
	VEND1_GLOBAL_CFG_5G,
	VEND1_GLOBAL_CFG_10G
};

static int aqr107_fill_interface_modes(struct phy_device *phydev)
{
	unsigned long *possible = phydev->possible_interfaces;
	unsigned int serdes_mode, rate_adapt;
	phy_interface_t interface;
	int i, val;

	/* Walk the media-speed configuration registers to determine which
	 * host-side serdes modes may be used by the PHY depending on the
	 * negotiated media speed.
	 */
	for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {
		val = phy_read_mmd(phydev, MDIO_MMD_VEND1,
				   aqr_global_cfg_regs[i]);
		if (val < 0)
			return val;

		serdes_mode = FIELD_GET(VEND1_GLOBAL_CFG_SERDES_MODE, val);
		rate_adapt = FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val);

		switch (serdes_mode) {
		case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:
			if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)
				interface = PHY_INTERFACE_MODE_USXGMII;
			else
				interface = PHY_INTERFACE_MODE_10GBASER;
			break;

		case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:
			interface = PHY_INTERFACE_MODE_5GBASER;
			break;

		case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:
			interface = PHY_INTERFACE_MODE_2500BASEX;
			break;

		case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:
			interface = PHY_INTERFACE_MODE_SGMII;
			break;

		default:
			phydev_warn(phydev, "unrecognised serdes mode %u\n",
				    serdes_mode);
			interface = PHY_INTERFACE_MODE_NA;
			break;
		}

		if (interface != PHY_INTERFACE_MODE_NA)
			__set_bit(interface, possible);
	}

	return 0;
}

static int aqr113c_config_init(struct phy_device *phydev)
{
	int ret;

	ret = aqr107_config_init(phydev);
	if (ret < 0)
		return ret;

	return aqr107_fill_interface_modes(phydev);
}

static int aqr107_probe(struct phy_device *phydev)
{
	int ret;
@@ -794,7 +868,7 @@ static struct phy_driver aqr_driver[] = {
	.name           = "Aquantia AQR113C",
	.probe          = aqr107_probe,
	.get_rate_matching = aqr107_get_rate_matching,
	.config_init    = aqr107_config_init,
	.config_init    = aqr113c_config_init,
	.config_aneg    = aqr_config_aneg,
	.config_intr    = aqr_config_intr,
	.handle_interrupt       = aqr_handle_interrupt,