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

net: phylink: provide phylink_get_inband_type()



Provide a function to get the type of the inband signalling used for
a PHY interface type. This will be used in the subsequent patch to
address problems with 10G optical modules.

Signed-off-by: default avatarRussell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/E1uslws-00000001SP5-1R2R@rmk-PC.armlinux.org.uk


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4beb44a2
Loading
Loading
Loading
Loading
+44 −35
Original line number Diff line number Diff line
@@ -1016,6 +1016,42 @@ static void phylink_pcs_an_restart(struct phylink *pl)
		pl->pcs->ops->pcs_an_restart(pl->pcs);
}

enum inband_type {
	INBAND_NONE,
	INBAND_CISCO_SGMII,
	INBAND_BASEX,
};

static enum inband_type phylink_get_inband_type(phy_interface_t interface)
{
	switch (interface) {
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
	case PHY_INTERFACE_MODE_QUSGMII:
	case PHY_INTERFACE_MODE_USXGMII:
	case PHY_INTERFACE_MODE_10G_QXGMII:
		/* These protocols are designed for use with a PHY which
		 * communicates its negotiation result back to the MAC via
		 * inband communication. Note: there exist PHYs that run
		 * with SGMII but do not send the inband data.
		 */
		return INBAND_CISCO_SGMII;

	case PHY_INTERFACE_MODE_1000BASEX:
	case PHY_INTERFACE_MODE_2500BASEX:
		/* 1000base-X is designed for use media-side for Fibre
		 * connections, and thus the Autoneg bit needs to be
		 * taken into account. We also do this for 2500base-X
		 * as well, but drivers may not support this, so may
		 * need to override this.
		 */
		return INBAND_BASEX;

	default:
		return INBAND_NONE;
	}
}

/**
 * phylink_pcs_neg_mode() - helper to determine PCS inband mode
 * @pl: a pointer to a &struct phylink returned from phylink_create()
@@ -1043,46 +1079,19 @@ static void phylink_pcs_neg_mode(struct phylink *pl, struct phylink_pcs *pcs,
	unsigned int pcs_ib_caps = 0;
	unsigned int phy_ib_caps = 0;
	unsigned int neg_mode, mode;
	enum {
		INBAND_CISCO_SGMII,
		INBAND_BASEX,
	} type;
	enum inband_type type;

	mode = pl->req_link_an_mode;

	pl->phy_ib_mode = 0;

	switch (interface) {
	case PHY_INTERFACE_MODE_SGMII:
	case PHY_INTERFACE_MODE_QSGMII:
	case PHY_INTERFACE_MODE_QUSGMII:
	case PHY_INTERFACE_MODE_USXGMII:
	case PHY_INTERFACE_MODE_10G_QXGMII:
		/* These protocols are designed for use with a PHY which
		 * communicates its negotiation result back to the MAC via
		 * inband communication. Note: there exist PHYs that run
		 * with SGMII but do not send the inband data.
		 */
		type = INBAND_CISCO_SGMII;
		break;

	case PHY_INTERFACE_MODE_1000BASEX:
	case PHY_INTERFACE_MODE_2500BASEX:
		/* 1000base-X is designed for use media-side for Fibre
		 * connections, and thus the Autoneg bit needs to be
		 * taken into account. We also do this for 2500base-X
		 * as well, but drivers may not support this, so may
		 * need to override this.
		 */
		type = INBAND_BASEX;
		break;

	default:
	type = phylink_get_inband_type(interface);
	if (type == INBAND_NONE) {
		pl->pcs_neg_mode = PHYLINK_PCS_NEG_NONE;
		pl->act_link_an_mode = mode;
		pl->act_link_an_mode = pl->req_link_an_mode;
		return;
	}

	mode = pl->req_link_an_mode;

	pl->phy_ib_mode = 0;

	if (pcs)
		pcs_ib_caps = phylink_pcs_inband_caps(pcs, interface);