Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b471232e authored by Dirk van der Merwe's avatar Dirk van der Merwe Committed by David S. Miller
Browse files

nfp: add helpers for FEC support



Implement helpers to determine and modify FEC modes via the NSP.
The NSP advertises FEC capabilities on a per port basis and provides
support for:
* Auto mode selection
* Reed Solomon
* BaseR
* None/Off

Signed-off-by: default avatarDirk van der Merwe <dirk.vandermerwe@netronome.com>
Signed-off-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a564d30e
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -79,6 +79,18 @@ enum nfp_eth_aneg {
	NFP_ANEG_DISABLED,
};

enum nfp_eth_fec {
	NFP_FEC_AUTO_BIT = 0,
	NFP_FEC_BASER_BIT,
	NFP_FEC_REED_SOLOMON_BIT,
	NFP_FEC_DISABLED_BIT,
};

#define NFP_FEC_AUTO		BIT(NFP_FEC_AUTO_BIT)
#define NFP_FEC_BASER		BIT(NFP_FEC_BASER_BIT)
#define NFP_FEC_REED_SOLOMON	BIT(NFP_FEC_REED_SOLOMON_BIT)
#define NFP_FEC_DISABLED	BIT(NFP_FEC_DISABLED_BIT)

/**
 * struct nfp_eth_table - ETH table information
 * @count:	number of table entries
@@ -93,6 +105,7 @@ enum nfp_eth_aneg {
 * @speed:	interface speed (in Mbps)
 * @interface:	interface (module) plugged in
 * @media:	media type of the @interface
 * @fec:	forward error correction mode
 * @aneg:	auto negotiation mode
 * @mac_addr:	interface MAC address
 * @label_port:	port id
@@ -105,6 +118,7 @@ enum nfp_eth_aneg {
 * @port_type:	one of %PORT_* defines for ethtool
 * @port_lanes:	total number of lanes on the port (sum of lanes of all subports)
 * @is_split:	is interface part of a split port
 * @fec_modes_supported:	bitmap of FEC modes supported
 */
struct nfp_eth_table {
	unsigned int count;
@@ -120,6 +134,7 @@ struct nfp_eth_table {
		unsigned int interface;
		enum nfp_eth_media media;

		enum nfp_eth_fec fec;
		enum nfp_eth_aneg aneg;

		u8 mac_addr[ETH_ALEN];
@@ -139,6 +154,8 @@ struct nfp_eth_table {
		unsigned int port_lanes;

		bool is_split;

		unsigned int fec_modes_supported;
	} ports[0];
};

@@ -149,6 +166,19 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp);
int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable);
int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx,
			   bool configed);
int
nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode);

static inline bool nfp_eth_can_support_fec(struct nfp_eth_table_port *eth_port)
{
	return !!eth_port->fec_modes_supported;
}

static inline unsigned int
nfp_eth_supported_fec_modes(struct nfp_eth_table_port *eth_port)
{
	return eth_port->fec_modes_supported;
}

struct nfp_nsp *nfp_eth_config_start(struct nfp_cpp *cpp, unsigned int idx);
int nfp_eth_config_commit_end(struct nfp_nsp *nsp);
+64 −0
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@
#define NSP_ETH_PORT_INDEX		GENMASK_ULL(15, 8)
#define NSP_ETH_PORT_LABEL		GENMASK_ULL(53, 48)
#define NSP_ETH_PORT_PHYLABEL		GENMASK_ULL(59, 54)
#define NSP_ETH_PORT_FEC_SUPP_BASER	BIT_ULL(60)
#define NSP_ETH_PORT_FEC_SUPP_RS	BIT_ULL(61)

#define NSP_ETH_PORT_LANES_MASK		cpu_to_le64(NSP_ETH_PORT_LANES)

@@ -67,6 +69,7 @@
#define NSP_ETH_STATE_MEDIA		GENMASK_ULL(21, 20)
#define NSP_ETH_STATE_OVRD_CHNG		BIT_ULL(22)
#define NSP_ETH_STATE_ANEG		GENMASK_ULL(25, 23)
#define NSP_ETH_STATE_FEC		GENMASK_ULL(27, 26)

#define NSP_ETH_CTRL_CONFIGURED		BIT_ULL(0)
#define NSP_ETH_CTRL_ENABLED		BIT_ULL(1)
@@ -75,6 +78,7 @@
#define NSP_ETH_CTRL_SET_RATE		BIT_ULL(4)
#define NSP_ETH_CTRL_SET_LANES		BIT_ULL(5)
#define NSP_ETH_CTRL_SET_ANEG		BIT_ULL(6)
#define NSP_ETH_CTRL_SET_FEC		BIT_ULL(7)

enum nfp_eth_raw {
	NSP_ETH_RAW_PORT = 0,
@@ -152,6 +156,7 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src,
		       unsigned int index, struct nfp_eth_table_port *dst)
{
	unsigned int rate;
	unsigned int fec;
	u64 port, state;

	port = le64_to_cpu(src->port);
@@ -183,6 +188,18 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src,

	dst->override_changed = FIELD_GET(NSP_ETH_STATE_OVRD_CHNG, state);
	dst->aneg = FIELD_GET(NSP_ETH_STATE_ANEG, state);

	if (nfp_nsp_get_abi_ver_minor(nsp) < 22)
		return;

	fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_BASER, port);
	dst->fec_modes_supported |= fec << NFP_FEC_BASER_BIT;
	fec = FIELD_GET(NSP_ETH_PORT_FEC_SUPP_RS, port);
	dst->fec_modes_supported |= fec << NFP_FEC_REED_SOLOMON_BIT;
	if (dst->fec_modes_supported)
		dst->fec_modes_supported |= NFP_FEC_AUTO | NFP_FEC_DISABLED;

	dst->fec = 1 << FIELD_GET(NSP_ETH_STATE_FEC, state);
}

static void
@@ -527,6 +544,53 @@ int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode)
				      NSP_ETH_CTRL_SET_ANEG);
}

/**
 * __nfp_eth_set_fec() - set PHY forward error correction control bit
 * @nsp:	NFP NSP handle returned from nfp_eth_config_start()
 * @mode:	Desired fec mode
 *
 * Set the PHY module forward error correction mode.
 * Will write to hwinfo overrides in the flash (persistent config).
 *
 * Return: 0 or -ERRNO.
 */
static int __nfp_eth_set_fec(struct nfp_nsp *nsp, enum nfp_eth_fec mode)
{
	return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_STATE,
				      NSP_ETH_STATE_FEC, mode,
				      NSP_ETH_CTRL_SET_FEC);
}

/**
 * nfp_eth_set_fec() - set PHY forward error correction control mode
 * @cpp:	NFP CPP handle
 * @idx:	NFP chip-wide port index
 * @mode:	Desired fec mode
 *
 * Return:
 * 0 - configuration successful;
 * 1 - no changes were needed;
 * -ERRNO - configuration failed.
 */
int
nfp_eth_set_fec(struct nfp_cpp *cpp, unsigned int idx, enum nfp_eth_fec mode)
{
	struct nfp_nsp *nsp;
	int err;

	nsp = nfp_eth_config_start(cpp, idx);
	if (IS_ERR(nsp))
		return PTR_ERR(nsp);

	err = __nfp_eth_set_fec(nsp, mode);
	if (err) {
		nfp_eth_config_cleanup_end(nsp);
		return err;
	}

	return nfp_eth_config_commit_end(nsp);
}

/**
 * __nfp_eth_set_speed() - set interface speed/rate
 * @nsp:	NFP NSP handle returned from nfp_eth_config_start()