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

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
...@@ -79,6 +79,18 @@ enum nfp_eth_aneg { ...@@ -79,6 +79,18 @@ enum nfp_eth_aneg {
NFP_ANEG_DISABLED, 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 * struct nfp_eth_table - ETH table information
* @count: number of table entries * @count: number of table entries
...@@ -93,6 +105,7 @@ enum nfp_eth_aneg { ...@@ -93,6 +105,7 @@ enum nfp_eth_aneg {
* @speed: interface speed (in Mbps) * @speed: interface speed (in Mbps)
* @interface: interface (module) plugged in * @interface: interface (module) plugged in
* @media: media type of the @interface * @media: media type of the @interface
* @fec: forward error correction mode
* @aneg: auto negotiation mode * @aneg: auto negotiation mode
* @mac_addr: interface MAC address * @mac_addr: interface MAC address
* @label_port: port id * @label_port: port id
...@@ -105,6 +118,7 @@ enum nfp_eth_aneg { ...@@ -105,6 +118,7 @@ enum nfp_eth_aneg {
* @port_type: one of %PORT_* defines for ethtool * @port_type: one of %PORT_* defines for ethtool
* @port_lanes: total number of lanes on the port (sum of lanes of all subports) * @port_lanes: total number of lanes on the port (sum of lanes of all subports)
* @is_split: is interface part of a split port * @is_split: is interface part of a split port
* @fec_modes_supported: bitmap of FEC modes supported
*/ */
struct nfp_eth_table { struct nfp_eth_table {
unsigned int count; unsigned int count;
...@@ -120,6 +134,7 @@ struct nfp_eth_table { ...@@ -120,6 +134,7 @@ struct nfp_eth_table {
unsigned int interface; unsigned int interface;
enum nfp_eth_media media; enum nfp_eth_media media;
enum nfp_eth_fec fec;
enum nfp_eth_aneg aneg; enum nfp_eth_aneg aneg;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
...@@ -139,6 +154,8 @@ struct nfp_eth_table { ...@@ -139,6 +154,8 @@ struct nfp_eth_table {
unsigned int port_lanes; unsigned int port_lanes;
bool is_split; bool is_split;
unsigned int fec_modes_supported;
} ports[0]; } ports[0];
}; };
...@@ -149,6 +166,19 @@ __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp); ...@@ -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_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable);
int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx, int nfp_eth_set_configured(struct nfp_cpp *cpp, unsigned int idx,
bool configed); 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); struct nfp_nsp *nfp_eth_config_start(struct nfp_cpp *cpp, unsigned int idx);
int nfp_eth_config_commit_end(struct nfp_nsp *nsp); int nfp_eth_config_commit_end(struct nfp_nsp *nsp);
......
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
#define NSP_ETH_PORT_INDEX GENMASK_ULL(15, 8) #define NSP_ETH_PORT_INDEX GENMASK_ULL(15, 8)
#define NSP_ETH_PORT_LABEL GENMASK_ULL(53, 48) #define NSP_ETH_PORT_LABEL GENMASK_ULL(53, 48)
#define NSP_ETH_PORT_PHYLABEL GENMASK_ULL(59, 54) #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) #define NSP_ETH_PORT_LANES_MASK cpu_to_le64(NSP_ETH_PORT_LANES)
...@@ -67,6 +69,7 @@ ...@@ -67,6 +69,7 @@
#define NSP_ETH_STATE_MEDIA GENMASK_ULL(21, 20) #define NSP_ETH_STATE_MEDIA GENMASK_ULL(21, 20)
#define NSP_ETH_STATE_OVRD_CHNG BIT_ULL(22) #define NSP_ETH_STATE_OVRD_CHNG BIT_ULL(22)
#define NSP_ETH_STATE_ANEG GENMASK_ULL(25, 23) #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_CONFIGURED BIT_ULL(0)
#define NSP_ETH_CTRL_ENABLED BIT_ULL(1) #define NSP_ETH_CTRL_ENABLED BIT_ULL(1)
...@@ -75,6 +78,7 @@ ...@@ -75,6 +78,7 @@
#define NSP_ETH_CTRL_SET_RATE BIT_ULL(4) #define NSP_ETH_CTRL_SET_RATE BIT_ULL(4)
#define NSP_ETH_CTRL_SET_LANES BIT_ULL(5) #define NSP_ETH_CTRL_SET_LANES BIT_ULL(5)
#define NSP_ETH_CTRL_SET_ANEG BIT_ULL(6) #define NSP_ETH_CTRL_SET_ANEG BIT_ULL(6)
#define NSP_ETH_CTRL_SET_FEC BIT_ULL(7)
enum nfp_eth_raw { enum nfp_eth_raw {
NSP_ETH_RAW_PORT = 0, NSP_ETH_RAW_PORT = 0,
...@@ -152,6 +156,7 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src, ...@@ -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 index, struct nfp_eth_table_port *dst)
{ {
unsigned int rate; unsigned int rate;
unsigned int fec;
u64 port, state; u64 port, state;
port = le64_to_cpu(src->port); port = le64_to_cpu(src->port);
...@@ -183,6 +188,18 @@ nfp_eth_port_translate(struct nfp_nsp *nsp, const union eth_table_entry *src, ...@@ -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->override_changed = FIELD_GET(NSP_ETH_STATE_OVRD_CHNG, state);
dst->aneg = FIELD_GET(NSP_ETH_STATE_ANEG, 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 static void
...@@ -527,6 +544,53 @@ int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode) ...@@ -527,6 +544,53 @@ int __nfp_eth_set_aneg(struct nfp_nsp *nsp, enum nfp_eth_aneg mode)
NSP_ETH_CTRL_SET_ANEG); 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 * __nfp_eth_set_speed() - set interface speed/rate
* @nsp: NFP NSP handle returned from nfp_eth_config_start() * @nsp: NFP NSP handle returned from nfp_eth_config_start()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment