Commit e58f69f4 authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller
Browse files

sfc: Extend loopback mode enumeration



New NICs and PHYs support a wider variety of loopback modes.

Signed-off-by: default avatarBen Hutchings <bhutchings@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 57849460
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -36,15 +36,32 @@
const unsigned int efx_loopback_mode_max = LOOPBACK_MAX;
const char *efx_loopback_mode_names[] = {
	[LOOPBACK_NONE]		= "NONE",
	[LOOPBACK_DATA]		= "DATAPATH",
	[LOOPBACK_GMAC]		= "GMAC",
	[LOOPBACK_XGMII]	= "XGMII",
	[LOOPBACK_XGXS]		= "XGXS",
	[LOOPBACK_XAUI]  	= "XAUI",
	[LOOPBACK_GMII] 	= "GMII",
	[LOOPBACK_SGMII] 	= "SGMII",
	[LOOPBACK_XGBR]		= "XGBR",
	[LOOPBACK_XFI]		= "XFI",
	[LOOPBACK_XAUI_FAR]	= "XAUI_FAR",
	[LOOPBACK_GMII_FAR]	= "GMII_FAR",
	[LOOPBACK_SGMII_FAR]	= "SGMII_FAR",
	[LOOPBACK_XFI_FAR]	= "XFI_FAR",
	[LOOPBACK_GPHY]		= "GPHY",
	[LOOPBACK_PHYXS]	= "PHYXS",
	[LOOPBACK_PCS]	 	= "PCS",
	[LOOPBACK_PMAPMD] 	= "PMA/PMD",
	[LOOPBACK_NETWORK]	= "NETWORK",
	[LOOPBACK_XPORT]	= "XPORT",
	[LOOPBACK_XGMII_WS]	= "XGMII_WS",
	[LOOPBACK_XAUI_WS]  	= "XAUI_WS",
	[LOOPBACK_XAUI_WS_FAR]  = "XAUI_WS_FAR",
	[LOOPBACK_XAUI_WS_NEAR] = "XAUI_WS_NEAR",
	[LOOPBACK_GMII_WS] 	= "GMII_WS",
	[LOOPBACK_XFI_WS]	= "XFI_WS",
	[LOOPBACK_XFI_WS_FAR]	= "XFI_WS_FAR",
	[LOOPBACK_PHYXS_WS]  	= "PHYXS_WS",
};

/* Interrupt mode names (see INT_MODE())) */
+86 −20
Original line number Diff line number Diff line
@@ -13,38 +13,101 @@
/**
 * enum efx_loopback_mode - loopback modes
 * @LOOPBACK_NONE: no loopback
 * @LOOPBACK_GMAC: loopback within GMAC at unspecified level
 * @LOOPBACK_XGMII: loopback within XMAC at XGMII level
 * @LOOPBACK_XGXS: loopback within XMAC at XGXS level
 * @LOOPBACK_XAUI: loopback within XMAC at XAUI level
 * @LOOPBACK_DATA: data path loopback
 * @LOOPBACK_GMAC: loopback within GMAC
 * @LOOPBACK_XGMII: loopback after XMAC
 * @LOOPBACK_XGXS: loopback within BPX after XGXS
 * @LOOPBACK_XAUI: loopback within BPX before XAUI serdes
 * @LOOPBACK_GMII: loopback within BPX after GMAC
 * @LOOPBACK_SGMII: loopback within BPX within SGMII
 * @LOOPBACK_XGBR: loopback within BPX within XGBR
 * @LOOPBACK_XFI: loopback within BPX before XFI serdes
 * @LOOPBACK_XAUI_FAR: loopback within BPX after XAUI serdes
 * @LOOPBACK_GMII_FAR: loopback within BPX before SGMII
 * @LOOPBACK_SGMII_FAR: loopback within BPX after SGMII
 * @LOOPBACK_XFI_FAR: loopback after XFI serdes
 * @LOOPBACK_GPHY: loopback within 1G PHY at unspecified level
 * @LOOPBACK_PHYXS: loopback within 10G PHY at PHYXS level
 * @LOOPBACK_PCS: loopback within 10G PHY at PCS level
 * @LOOPBACK_PMAPMD: loopback within 10G PHY at PMAPMD level
 * @LOOPBACK_NETWORK: reflecting loopback (even further than furthest!)
 * @LOOPBACK_XPORT: cross port loopback
 * @LOOPBACK_XGMII_WS: wireside loopback excluding XMAC
 * @LOOPBACK_XAUI_WS: wireside loopback within BPX within XAUI serdes
 * @LOOPBACK_XAUI_WS_FAR: wireside loopback within BPX including XAUI serdes
 * @LOOPBACK_XAUI_WS_NEAR: wireside loopback within BPX excluding XAUI serdes
 * @LOOPBACK_GMII_WS: wireside loopback excluding GMAC
 * @LOOPBACK_XFI_WS: wireside loopback excluding XFI serdes
 * @LOOPBACK_XFI_WS_FAR: wireside loopback including XFI serdes
 * @LOOPBACK_PHYXS_WS: wireside loopback within 10G PHY at PHYXS level
 */
/* Please keep in order and up-to-date w.r.t the following two #defines */
/* Please keep up-to-date w.r.t the following two #defines */
enum efx_loopback_mode {
	LOOPBACK_NONE = 0,
	LOOPBACK_GMAC = 1,
	LOOPBACK_XGMII = 2,
	LOOPBACK_XGXS = 3,
	LOOPBACK_XAUI = 4,
	LOOPBACK_GPHY = 5,
	LOOPBACK_PHYXS = 6,
	LOOPBACK_PCS = 7,
	LOOPBACK_PMAPMD = 8,
	LOOPBACK_NETWORK = 9,
	LOOPBACK_DATA = 1,
	LOOPBACK_GMAC = 2,
	LOOPBACK_XGMII = 3,
	LOOPBACK_XGXS = 4,
	LOOPBACK_XAUI = 5,
	LOOPBACK_GMII = 6,
	LOOPBACK_SGMII = 7,
	LOOPBACK_XGBR = 8,
	LOOPBACK_XFI = 9,
	LOOPBACK_XAUI_FAR = 10,
	LOOPBACK_GMII_FAR = 11,
	LOOPBACK_SGMII_FAR = 12,
	LOOPBACK_XFI_FAR = 13,
	LOOPBACK_GPHY = 14,
	LOOPBACK_PHYXS = 15,
	LOOPBACK_PCS = 16,
	LOOPBACK_PMAPMD = 17,
	LOOPBACK_XPORT = 18,
	LOOPBACK_XGMII_WS = 19,
	LOOPBACK_XAUI_WS = 20,
	LOOPBACK_XAUI_WS_FAR = 21,
	LOOPBACK_XAUI_WS_NEAR = 22,
	LOOPBACK_GMII_WS = 23,
	LOOPBACK_XFI_WS = 24,
	LOOPBACK_XFI_WS_FAR = 25,
	LOOPBACK_PHYXS_WS = 26,
	LOOPBACK_MAX
};

#define LOOPBACK_TEST_MAX LOOPBACK_PMAPMD

/* These loopbacks occur within the controller */
#define LOOPBACKS_INTERNAL ((1 << LOOPBACK_GMAC) |     \
#define LOOPBACKS_INTERNAL ((1 << LOOPBACK_DATA) |		\
			    (1 << LOOPBACK_GMAC) |		\
			    (1 << LOOPBACK_XGMII)|		\
			    (1 << LOOPBACK_XGXS) |		\
			    (1 << LOOPBACK_XAUI))
			    (1 << LOOPBACK_XAUI) |		\
			    (1 << LOOPBACK_GMII) |		\
			    (1 << LOOPBACK_SGMII) |		\
			    (1 << LOOPBACK_SGMII) |		\
			    (1 << LOOPBACK_XGBR) |		\
			    (1 << LOOPBACK_XFI) |		\
			    (1 << LOOPBACK_XAUI_FAR) |		\
			    (1 << LOOPBACK_GMII_FAR) |		\
			    (1 << LOOPBACK_SGMII_FAR) |		\
			    (1 << LOOPBACK_XFI_FAR) |		\
			    (1 << LOOPBACK_XGMII_WS) |		\
			    (1 << LOOPBACK_XAUI_WS) |		\
			    (1 << LOOPBACK_XAUI_WS_FAR) |	\
			    (1 << LOOPBACK_XAUI_WS_NEAR) |	\
			    (1 << LOOPBACK_GMII_WS) |		\
			    (1 << LOOPBACK_XFI_WS) |		\
			    (1 << LOOPBACK_XFI_WS_FAR))

#define LOOPBACKS_WS ((1 << LOOPBACK_XGMII_WS) |		\
		      (1 << LOOPBACK_XAUI_WS) |			\
		      (1 << LOOPBACK_XAUI_WS_FAR) |		\
		      (1 << LOOPBACK_XAUI_WS_NEAR) |		\
		      (1 << LOOPBACK_GMII_WS) |			\
		      (1 << LOOPBACK_XFI_WS) |			\
		      (1 << LOOPBACK_XFI_WS_FAR) |		\
		      (1 << LOOPBACK_PHYXS_WS))

#define LOOPBACKS_EXTERNAL(_efx)					\
	((_efx)->loopback_modes & ~LOOPBACKS_INTERNAL &			\
	 ~(1 << LOOPBACK_NONE))

#define LOOPBACK_MASK(_efx)			\
	(1 << (_efx)->loopback_mode)
@@ -52,6 +115,9 @@ enum efx_loopback_mode {
#define LOOPBACK_INTERNAL(_efx)				\
	(!!(LOOPBACKS_INTERNAL & LOOPBACK_MASK(_efx)))

#define LOOPBACK_EXTERNAL(_efx)				\
	(!!(LOOPBACK_MASK(_efx) & LOOPBACKS_EXTERNAL(_efx)))

#define LOOPBACK_CHANGED(_from, _to, _mask)				\
	(!!((LOOPBACK_MASK(_from) ^ LOOPBACK_MASK(_to)) & (_mask)))

+1 −1
Original line number Diff line number Diff line
@@ -249,7 +249,7 @@ static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
{
	bool mac_up = falcon_xaui_link_ok(efx);

	if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
	if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS ||
	    efx_phy_mode_disabled(efx->phy_mode))
		/* XAUI link is expected to be down */
		return mac_up;
+2 −2
Original line number Diff line number Diff line
@@ -173,7 +173,7 @@ bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
	 * of mmd's */
	if (LOOPBACK_INTERNAL(efx))
		return true;
	else if (efx->loopback_mode == LOOPBACK_NETWORK)
	else if (LOOPBACK_MASK(efx) & LOOPBACKS_WS)
		return false;
	else if (efx_phy_mode_disabled(efx->phy_mode))
		return false;
@@ -210,7 +210,7 @@ void efx_mdio_phy_reconfigure(struct efx_nic *efx)
			  efx->loopback_mode == LOOPBACK_PCS);
	efx_mdio_set_flag(efx, MDIO_MMD_PHYXS,
			  MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK,
			  efx->loopback_mode == LOOPBACK_NETWORK);
			  efx->loopback_mode == LOOPBACK_PHYXS_WS);
}

static void efx_mdio_set_mmd_lpower(struct efx_nic *efx,
+1 −1
Original line number Diff line number Diff line
@@ -824,7 +824,7 @@ struct efx_nic {

	atomic_t rx_reset;
	enum efx_loopback_mode loopback_mode;
	unsigned int loopback_modes;
	u64 loopback_modes;

	void *loopback_selftest;
};
Loading