From e812916d3278baf03aabf10044661fc3b2848823 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Mon, 20 Jul 2020 21:08:00 +0300 Subject: linkmode: introduce linkmode_intersects() Add a new helper to find intersections between Ethtool link modes, linkmode_intersects(), similar to the other linkmode helpers. Signed-off-by: Alexander Lobakin Signed-off-by: Igor Russkikh Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- include/linux/linkmode.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/linux/linkmode.h b/include/linux/linkmode.h index c664c27a29a0..f8397f300fcd 100644 --- a/include/linux/linkmode.h +++ b/include/linux/linkmode.h @@ -82,6 +82,12 @@ static inline int linkmode_equal(const unsigned long *src1, return bitmap_equal(src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS); } +static inline int linkmode_intersects(const unsigned long *src1, + const unsigned long *src2) +{ + return bitmap_intersects(src1, src2, __ETHTOOL_LINK_MODE_MASK_NBITS); +} + static inline int linkmode_subset(const unsigned long *src1, const unsigned long *src2) { -- cgit v1.2.3-71-gd317 From bdb5d8ec47611ca61e168349f233e1dd1ed063f4 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Mon, 20 Jul 2020 21:08:01 +0300 Subject: qed, qede, qedf: convert link mode from u32 to ETHTOOL_LINK_MODE Currently qed driver already ran out of 32 bits to store link modes, and this doesn't allow to add and support more speeds. Convert custom link mode to generic Ethtool bitmap and definitions (convenient Phylink shorthands are used for elegance and readability). This allowed us to drop all conversions/mappings between the driver and Ethtool. This involves changes in qede and qedf as well, as they used definitions from shared "qed_if.h". Suggested-by: Andrew Lunn Signed-off-by: Alexander Lobakin Signed-off-by: Igor Russkikh Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_main.c | 288 +++++++++++++----------- drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 200 +++++----------- drivers/scsi/qedf/qedf_main.c | 78 ++++--- include/linux/qed/qed_if.h | 47 +--- 4 files changed, 268 insertions(+), 345 deletions(-) (limited to 'include') diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 4c5f5bd91359..afc4fa3bdcaa 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "qed.h" #include "qed_sriov.h" @@ -1456,10 +1457,11 @@ static bool qed_can_link_change(struct qed_dev *cdev) static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params) { - struct qed_hwfn *hwfn; + __ETHTOOL_DECLARE_LINK_MODE_MASK(sup_caps); struct qed_mcp_link_params *link_params; + struct qed_hwfn *hwfn; struct qed_ptt *ptt; - u32 sup_caps; + u32 as; int rc; if (!cdev) @@ -1482,57 +1484,79 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params) return -EBUSY; link_params = qed_mcp_get_link_params(hwfn); + if (!link_params) + return -ENODATA; + if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG) link_params->speed.autoneg = params->autoneg; + if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) { - link_params->speed.advertised_speeds = 0; - sup_caps = QED_LM_1000baseT_Full_BIT | - QED_LM_1000baseKX_Full_BIT | - QED_LM_1000baseX_Full_BIT; - if (params->adv_speeds & sup_caps) - link_params->speed.advertised_speeds |= - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G; - sup_caps = QED_LM_10000baseT_Full_BIT | - QED_LM_10000baseKR_Full_BIT | - QED_LM_10000baseKX4_Full_BIT | - QED_LM_10000baseR_FEC_BIT | - QED_LM_10000baseCR_Full_BIT | - QED_LM_10000baseSR_Full_BIT | - QED_LM_10000baseLR_Full_BIT | - QED_LM_10000baseLRM_Full_BIT; - if (params->adv_speeds & sup_caps) - link_params->speed.advertised_speeds |= - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G; - if (params->adv_speeds & QED_LM_20000baseKR2_Full_BIT) - link_params->speed.advertised_speeds |= - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G; - sup_caps = QED_LM_25000baseKR_Full_BIT | - QED_LM_25000baseCR_Full_BIT | - QED_LM_25000baseSR_Full_BIT; - if (params->adv_speeds & sup_caps) - link_params->speed.advertised_speeds |= - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G; - sup_caps = QED_LM_40000baseLR4_Full_BIT | - QED_LM_40000baseKR4_Full_BIT | - QED_LM_40000baseCR4_Full_BIT | - QED_LM_40000baseSR4_Full_BIT; - if (params->adv_speeds & sup_caps) - link_params->speed.advertised_speeds |= - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G; - sup_caps = QED_LM_50000baseKR2_Full_BIT | - QED_LM_50000baseCR2_Full_BIT | - QED_LM_50000baseSR2_Full_BIT; - if (params->adv_speeds & sup_caps) - link_params->speed.advertised_speeds |= - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G; - sup_caps = QED_LM_100000baseKR4_Full_BIT | - QED_LM_100000baseSR4_Full_BIT | - QED_LM_100000baseCR4_Full_BIT | - QED_LM_100000baseLR4_ER4_Full_BIT; - if (params->adv_speeds & sup_caps) - link_params->speed.advertised_speeds |= - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G; + as = 0; + + phylink_zero(sup_caps); + phylink_set(sup_caps, 1000baseT_Full); + phylink_set(sup_caps, 1000baseKX_Full); + phylink_set(sup_caps, 1000baseX_Full); + + if (linkmode_intersects(params->adv_speeds, sup_caps)) + as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G; + + phylink_zero(sup_caps); + phylink_set(sup_caps, 10000baseT_Full); + phylink_set(sup_caps, 10000baseKR_Full); + phylink_set(sup_caps, 10000baseKX4_Full); + phylink_set(sup_caps, 10000baseR_FEC); + phylink_set(sup_caps, 10000baseCR_Full); + phylink_set(sup_caps, 10000baseSR_Full); + phylink_set(sup_caps, 10000baseLR_Full); + phylink_set(sup_caps, 10000baseLRM_Full); + + if (linkmode_intersects(params->adv_speeds, sup_caps)) + as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G; + + phylink_zero(sup_caps); + phylink_set(sup_caps, 20000baseKR2_Full); + + if (linkmode_intersects(params->adv_speeds, sup_caps)) + as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G; + + phylink_zero(sup_caps); + phylink_set(sup_caps, 25000baseKR_Full); + phylink_set(sup_caps, 25000baseCR_Full); + phylink_set(sup_caps, 25000baseSR_Full); + + if (linkmode_intersects(params->adv_speeds, sup_caps)) + as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G; + + phylink_zero(sup_caps); + phylink_set(sup_caps, 40000baseLR4_Full); + phylink_set(sup_caps, 40000baseKR4_Full); + phylink_set(sup_caps, 40000baseCR4_Full); + phylink_set(sup_caps, 40000baseSR4_Full); + + if (linkmode_intersects(params->adv_speeds, sup_caps)) + as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G; + + phylink_zero(sup_caps); + phylink_set(sup_caps, 50000baseKR2_Full); + phylink_set(sup_caps, 50000baseCR2_Full); + phylink_set(sup_caps, 50000baseSR2_Full); + + if (linkmode_intersects(params->adv_speeds, sup_caps)) + as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G; + + phylink_zero(sup_caps); + phylink_set(sup_caps, 100000baseKR4_Full); + phylink_set(sup_caps, 100000baseSR4_Full); + phylink_set(sup_caps, 100000baseCR4_Full); + phylink_set(sup_caps, 100000baseLR4_ER4_Full); + + if (linkmode_intersects(params->adv_speeds, sup_caps)) + as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G; + + link_params->speed.advertised_speeds = as; } + if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED) link_params->speed.forced_speed = params->forced_speed; if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) { @@ -1644,7 +1668,7 @@ static int qed_get_link_data(struct qed_hwfn *hwfn, static void qed_fill_link_capability(struct qed_hwfn *hwfn, struct qed_ptt *ptt, u32 capability, - u32 *if_capability) + unsigned long *if_caps) { u32 media_type, tcvr_state, tcvr_type; u32 speed_mask, board_cfg; @@ -1667,113 +1691,117 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn, switch (media_type) { case MEDIA_DA_TWINAX: - *if_capability |= QED_LM_FIBRE_BIT; + phylink_set(if_caps, FIBRE); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G) - *if_capability |= QED_LM_20000baseKR2_Full_BIT; + phylink_set(if_caps, 20000baseKR2_Full); + /* For DAC media multiple speed capabilities are supported*/ capability = capability & speed_mask; if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) - *if_capability |= QED_LM_1000baseKX_Full_BIT; + phylink_set(if_caps, 1000baseKX_Full); if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) - *if_capability |= QED_LM_10000baseCR_Full_BIT; + phylink_set(if_caps, 10000baseCR_Full); if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) - *if_capability |= QED_LM_40000baseCR4_Full_BIT; + phylink_set(if_caps, 40000baseCR4_Full); if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) - *if_capability |= QED_LM_25000baseCR_Full_BIT; + phylink_set(if_caps, 25000baseCR_Full); if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) - *if_capability |= QED_LM_50000baseCR2_Full_BIT; + phylink_set(if_caps, 50000baseCR2_Full); if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) - *if_capability |= QED_LM_100000baseCR4_Full_BIT; + NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) + phylink_set(if_caps, 100000baseCR4_Full); + break; case MEDIA_BASE_T: - *if_capability |= QED_LM_TP_BIT; + phylink_set(if_caps, TP); + if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_EXT_PHY) { if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) { - *if_capability |= QED_LM_1000baseT_Full_BIT; - } + NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) + phylink_set(if_caps, 1000baseT_Full); if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) { - *if_capability |= QED_LM_10000baseT_Full_BIT; - } + NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) + phylink_set(if_caps, 10000baseT_Full); } + if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) { - *if_capability |= QED_LM_FIBRE_BIT; + phylink_set(if_caps, FIBRE); + if (tcvr_type == ETH_TRANSCEIVER_TYPE_1000BASET) - *if_capability |= QED_LM_1000baseT_Full_BIT; + phylink_set(if_caps, 1000baseT_Full); if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_BASET) - *if_capability |= QED_LM_10000baseT_Full_BIT; + phylink_set(if_caps, 10000baseT_Full); } + break; case MEDIA_SFP_1G_FIBER: case MEDIA_SFPP_10G_FIBER: case MEDIA_XFP_FIBER: case MEDIA_MODULE_FIBER: - *if_capability |= QED_LM_FIBRE_BIT; - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) { + phylink_set(if_caps, FIBRE); + + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) { if ((tcvr_type == ETH_TRANSCEIVER_TYPE_1G_LX) || (tcvr_type == ETH_TRANSCEIVER_TYPE_1G_SX)) - *if_capability |= QED_LM_1000baseKX_Full_BIT; + phylink_set(if_caps, 1000baseKX_Full); } - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) { + + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) { if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_SR) - *if_capability |= QED_LM_10000baseSR_Full_BIT; + phylink_set(if_caps, 10000baseSR_Full); if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LR) - *if_capability |= QED_LM_10000baseLR_Full_BIT; + phylink_set(if_caps, 10000baseLR_Full); if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LRM) - *if_capability |= QED_LM_10000baseLRM_Full_BIT; + phylink_set(if_caps, 10000baseLRM_Full); if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_ER) - *if_capability |= QED_LM_10000baseR_FEC_BIT; + phylink_set(if_caps, 10000baseR_FEC); } + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G) - *if_capability |= QED_LM_20000baseKR2_Full_BIT; - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) { + phylink_set(if_caps, 20000baseKR2_Full); + + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) { if (tcvr_type == ETH_TRANSCEIVER_TYPE_25G_SR) - *if_capability |= QED_LM_25000baseSR_Full_BIT; + phylink_set(if_caps, 25000baseSR_Full); } - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) { + + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) { if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_LR4) - *if_capability |= QED_LM_40000baseLR4_Full_BIT; + phylink_set(if_caps, 40000baseLR4_Full); if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_SR4) - *if_capability |= QED_LM_40000baseSR4_Full_BIT; + phylink_set(if_caps, 40000baseSR4_Full); } - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) - *if_capability |= QED_LM_50000baseKR2_Full_BIT; + + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) + phylink_set(if_caps, 50000baseKR2_Full); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) { if (tcvr_type == ETH_TRANSCEIVER_TYPE_100G_SR4) - *if_capability |= QED_LM_100000baseSR4_Full_BIT; + phylink_set(if_caps, 100000baseSR4_Full); } break; case MEDIA_KR: - *if_capability |= QED_LM_Backplane_BIT; + phylink_set(if_caps, Backplane); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G) - *if_capability |= QED_LM_20000baseKR2_Full_BIT; - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) - *if_capability |= QED_LM_1000baseKX_Full_BIT; - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) - *if_capability |= QED_LM_10000baseKR_Full_BIT; - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) - *if_capability |= QED_LM_25000baseKR_Full_BIT; - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) - *if_capability |= QED_LM_40000baseKR4_Full_BIT; - if (capability & - NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) - *if_capability |= QED_LM_50000baseKR2_Full_BIT; + phylink_set(if_caps, 20000baseKR2_Full); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G) + phylink_set(if_caps, 1000baseKX_Full); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) + phylink_set(if_caps, 10000baseKR_Full); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) + phylink_set(if_caps, 25000baseKR_Full); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) + phylink_set(if_caps, 40000baseKR4_Full); + if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G) + phylink_set(if_caps, 50000baseKR2_Full); if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) - *if_capability |= QED_LM_100000baseKR4_Full_BIT; + phylink_set(if_caps, 100000baseKR4_Full); + break; case MEDIA_UNSPECIFIED: case MEDIA_NOT_PRESENT: @@ -1806,26 +1834,27 @@ static void qed_fill_link(struct qed_hwfn *hwfn, /* TODO - at the moment assume supported and advertised speed equal */ if (link_caps.default_speed_autoneg) - if_link->supported_caps |= QED_LM_Autoneg_BIT; + phylink_set(if_link->supported_caps, Autoneg); if (params.pause.autoneg || (params.pause.forced_rx && params.pause.forced_tx)) - if_link->supported_caps |= QED_LM_Asym_Pause_BIT; + phylink_set(if_link->supported_caps, Asym_Pause); if (params.pause.autoneg || params.pause.forced_rx || params.pause.forced_tx) - if_link->supported_caps |= QED_LM_Pause_BIT; + phylink_set(if_link->supported_caps, Pause); + + linkmode_copy(if_link->advertised_caps, if_link->supported_caps); - if_link->advertised_caps = if_link->supported_caps; if (params.speed.autoneg) - if_link->advertised_caps |= QED_LM_Autoneg_BIT; + phylink_set(if_link->advertised_caps, Autoneg); else - if_link->advertised_caps &= ~QED_LM_Autoneg_BIT; + phylink_clear(if_link->advertised_caps, Autoneg); /* Fill link advertised capability*/ qed_fill_link_capability(hwfn, ptt, params.speed.advertised_speeds, - &if_link->advertised_caps); + if_link->advertised_caps); /* Fill link supported capability*/ qed_fill_link_capability(hwfn, ptt, link_caps.speed_capabilities, - &if_link->supported_caps); + if_link->supported_caps); if (link.link_up) if_link->speed = link.speed; @@ -1845,30 +1874,29 @@ static void qed_fill_link(struct qed_hwfn *hwfn, if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE; /* Link partner capabilities */ - if (link.partner_adv_speed & - QED_LINK_PARTNER_SPEED_1G_FD) - if_link->lp_caps |= QED_LM_1000baseT_Full_BIT; + + if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_1G_FD) + phylink_set(if_link->lp_caps, 1000baseT_Full); if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_10G) - if_link->lp_caps |= QED_LM_10000baseKR_Full_BIT; + phylink_set(if_link->lp_caps, 10000baseKR_Full); if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_20G) - if_link->lp_caps |= QED_LM_20000baseKR2_Full_BIT; + phylink_set(if_link->lp_caps, 20000baseKR2_Full); if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_25G) - if_link->lp_caps |= QED_LM_25000baseKR_Full_BIT; + phylink_set(if_link->lp_caps, 25000baseKR_Full); if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_40G) - if_link->lp_caps |= QED_LM_40000baseLR4_Full_BIT; + phylink_set(if_link->lp_caps, 40000baseLR4_Full); if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_50G) - if_link->lp_caps |= QED_LM_50000baseKR2_Full_BIT; + phylink_set(if_link->lp_caps, 50000baseKR2_Full); if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_100G) - if_link->lp_caps |= QED_LM_100000baseKR4_Full_BIT; + phylink_set(if_link->lp_caps, 100000baseKR4_Full); if (link.an_complete) - if_link->lp_caps |= QED_LM_Autoneg_BIT; - + phylink_set(if_link->lp_caps, Autoneg); if (link.partner_adv_pause) - if_link->lp_caps |= QED_LM_Pause_BIT; + phylink_set(if_link->lp_caps, Pause); if (link.partner_adv_pause == QED_LINK_PARTNER_ASYMMETRIC_PAUSE || link.partner_adv_pause == QED_LINK_PARTNER_BOTH_PAUSE) - if_link->lp_caps |= QED_LM_Asym_Pause_BIT; + phylink_set(if_link->lp_caps, Asym_Pause); if (link_caps.default_eee == QED_MCP_EEE_UNSUPPORTED) { if_link->eee_supported = false; diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c index d3fc7403d095..0a564b06d697 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c @@ -13,6 +13,8 @@ #include #include #include +#include + #include "qede.h" #include "qede_ptp.h" @@ -418,76 +420,10 @@ static int qede_set_priv_flags(struct net_device *dev, u32 flags) return 0; } -struct qede_link_mode_mapping { - u32 qed_link_mode; - u32 ethtool_link_mode; -}; - -static const struct qede_link_mode_mapping qed_lm_map[] = { - {QED_LM_FIBRE_BIT, ETHTOOL_LINK_MODE_FIBRE_BIT}, - {QED_LM_Autoneg_BIT, ETHTOOL_LINK_MODE_Autoneg_BIT}, - {QED_LM_Asym_Pause_BIT, ETHTOOL_LINK_MODE_Asym_Pause_BIT}, - {QED_LM_Pause_BIT, ETHTOOL_LINK_MODE_Pause_BIT}, - {QED_LM_1000baseT_Full_BIT, ETHTOOL_LINK_MODE_1000baseT_Full_BIT}, - {QED_LM_10000baseT_Full_BIT, ETHTOOL_LINK_MODE_10000baseT_Full_BIT}, - {QED_LM_TP_BIT, ETHTOOL_LINK_MODE_TP_BIT}, - {QED_LM_Backplane_BIT, ETHTOOL_LINK_MODE_Backplane_BIT}, - {QED_LM_1000baseKX_Full_BIT, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT}, - {QED_LM_10000baseKX4_Full_BIT, ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT}, - {QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT}, - {QED_LM_10000baseKR_Full_BIT, ETHTOOL_LINK_MODE_10000baseKR_Full_BIT}, - {QED_LM_10000baseR_FEC_BIT, ETHTOOL_LINK_MODE_10000baseR_FEC_BIT}, - {QED_LM_20000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT}, - {QED_LM_40000baseKR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT}, - {QED_LM_40000baseCR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT}, - {QED_LM_40000baseSR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT}, - {QED_LM_40000baseLR4_Full_BIT, ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT}, - {QED_LM_25000baseCR_Full_BIT, ETHTOOL_LINK_MODE_25000baseCR_Full_BIT}, - {QED_LM_25000baseKR_Full_BIT, ETHTOOL_LINK_MODE_25000baseKR_Full_BIT}, - {QED_LM_25000baseSR_Full_BIT, ETHTOOL_LINK_MODE_25000baseSR_Full_BIT}, - {QED_LM_50000baseCR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT}, - {QED_LM_50000baseKR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT}, - {QED_LM_100000baseKR4_Full_BIT, - ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT}, - {QED_LM_100000baseSR4_Full_BIT, - ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT}, - {QED_LM_100000baseCR4_Full_BIT, - ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT}, - {QED_LM_100000baseLR4_ER4_Full_BIT, - ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT}, - {QED_LM_50000baseSR2_Full_BIT, ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT}, - {QED_LM_1000baseX_Full_BIT, ETHTOOL_LINK_MODE_1000baseX_Full_BIT}, - {QED_LM_10000baseCR_Full_BIT, ETHTOOL_LINK_MODE_10000baseCR_Full_BIT}, - {QED_LM_10000baseSR_Full_BIT, ETHTOOL_LINK_MODE_10000baseSR_Full_BIT}, - {QED_LM_10000baseLR_Full_BIT, ETHTOOL_LINK_MODE_10000baseLR_Full_BIT}, - {QED_LM_10000baseLRM_Full_BIT, ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT}, -}; - -#define QEDE_DRV_TO_ETHTOOL_CAPS(caps, lk_ksettings, name) \ -{ \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \ - if ((caps) & (qed_lm_map[i].qed_link_mode)) \ - __set_bit(qed_lm_map[i].ethtool_link_mode,\ - lk_ksettings->link_modes.name); \ - } \ -} - -#define QEDE_ETHTOOL_TO_DRV_CAPS(caps, lk_ksettings, name) \ -{ \ - int i; \ - \ - for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++) { \ - if (test_bit(qed_lm_map[i].ethtool_link_mode, \ - lk_ksettings->link_modes.name)) \ - caps |= qed_lm_map[i].qed_link_mode; \ - } \ -} - static int qede_get_link_ksettings(struct net_device *dev, struct ethtool_link_ksettings *cmd) { + typeof(cmd->link_modes) *link_modes = &cmd->link_modes; struct ethtool_link_settings *base = &cmd->base; struct qede_dev *edev = netdev_priv(dev); struct qed_link_output current_link; @@ -497,14 +433,9 @@ static int qede_get_link_ksettings(struct net_device *dev, memset(¤t_link, 0, sizeof(current_link)); edev->ops->common->get_link(edev->cdev, ¤t_link); - ethtool_link_ksettings_zero_link_mode(cmd, supported); - QEDE_DRV_TO_ETHTOOL_CAPS(current_link.supported_caps, cmd, supported) - - ethtool_link_ksettings_zero_link_mode(cmd, advertising); - QEDE_DRV_TO_ETHTOOL_CAPS(current_link.advertised_caps, cmd, advertising) - - ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising); - QEDE_DRV_TO_ETHTOOL_CAPS(current_link.lp_caps, cmd, lp_advertising) + linkmode_copy(link_modes->supported, current_link.supported_caps); + linkmode_copy(link_modes->advertising, current_link.advertised_caps); + linkmode_copy(link_modes->lp_advertising, current_link.lp_caps); if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) { base->speed = current_link.speed; @@ -527,10 +458,10 @@ static int qede_set_link_ksettings(struct net_device *dev, const struct ethtool_link_ksettings *cmd) { const struct ethtool_link_settings *base = &cmd->base; + __ETHTOOL_DECLARE_LINK_MODE_MASK(sup_caps); struct qede_dev *edev = netdev_priv(dev); struct qed_link_output current_link; struct qed_link_params params; - u32 sup_caps; if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) { DP_INFO(edev, "Link settings are not allowed to be changed\n"); @@ -542,105 +473,79 @@ static int qede_set_link_ksettings(struct net_device *dev, params.override_flags |= QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS; params.override_flags |= QED_LINK_OVERRIDE_SPEED_AUTONEG; + if (base->autoneg == AUTONEG_ENABLE) { - if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) { + if (!phylink_test(current_link.supported_caps, Autoneg)) { DP_INFO(edev, "Auto negotiation is not supported\n"); return -EOPNOTSUPP; } params.autoneg = true; params.forced_speed = 0; - QEDE_ETHTOOL_TO_DRV_CAPS(params.adv_speeds, cmd, advertising) + + linkmode_copy(params.adv_speeds, cmd->link_modes.advertising); } else { /* forced speed */ params.override_flags |= QED_LINK_OVERRIDE_SPEED_FORCED_SPEED; params.autoneg = false; params.forced_speed = base->speed; + + phylink_zero(sup_caps); + switch (base->speed) { case SPEED_1000: - sup_caps = QED_LM_1000baseT_Full_BIT | - QED_LM_1000baseKX_Full_BIT | - QED_LM_1000baseX_Full_BIT; - if (!(current_link.supported_caps & sup_caps)) { - DP_INFO(edev, "1G speed not supported\n"); - return -EINVAL; - } - params.adv_speeds = current_link.supported_caps & - sup_caps; + phylink_set(sup_caps, 1000baseT_Full); + phylink_set(sup_caps, 1000baseKX_Full); + phylink_set(sup_caps, 1000baseX_Full); break; case SPEED_10000: - sup_caps = QED_LM_10000baseT_Full_BIT | - QED_LM_10000baseKR_Full_BIT | - QED_LM_10000baseKX4_Full_BIT | - QED_LM_10000baseR_FEC_BIT | - QED_LM_10000baseCR_Full_BIT | - QED_LM_10000baseSR_Full_BIT | - QED_LM_10000baseLR_Full_BIT | - QED_LM_10000baseLRM_Full_BIT; - if (!(current_link.supported_caps & sup_caps)) { - DP_INFO(edev, "10G speed not supported\n"); - return -EINVAL; - } - params.adv_speeds = current_link.supported_caps & - sup_caps; + phylink_set(sup_caps, 10000baseT_Full); + phylink_set(sup_caps, 10000baseKR_Full); + phylink_set(sup_caps, 10000baseKX4_Full); + phylink_set(sup_caps, 10000baseR_FEC); + phylink_set(sup_caps, 10000baseCR_Full); + phylink_set(sup_caps, 10000baseSR_Full); + phylink_set(sup_caps, 10000baseLR_Full); + phylink_set(sup_caps, 10000baseLRM_Full); break; case SPEED_20000: - if (!(current_link.supported_caps & - QED_LM_20000baseKR2_Full_BIT)) { - DP_INFO(edev, "20G speed not supported\n"); - return -EINVAL; - } - params.adv_speeds = QED_LM_20000baseKR2_Full_BIT; + phylink_set(sup_caps, 20000baseKR2_Full); break; case SPEED_25000: - sup_caps = QED_LM_25000baseKR_Full_BIT | - QED_LM_25000baseCR_Full_BIT | - QED_LM_25000baseSR_Full_BIT; - if (!(current_link.supported_caps & sup_caps)) { - DP_INFO(edev, "25G speed not supported\n"); - return -EINVAL; - } - params.adv_speeds = current_link.supported_caps & - sup_caps; + phylink_set(sup_caps, 25000baseKR_Full); + phylink_set(sup_caps, 25000baseCR_Full); + phylink_set(sup_caps, 25000baseSR_Full); break; case SPEED_40000: - sup_caps = QED_LM_40000baseLR4_Full_BIT | - QED_LM_40000baseKR4_Full_BIT | - QED_LM_40000baseCR4_Full_BIT | - QED_LM_40000baseSR4_Full_BIT; - if (!(current_link.supported_caps & sup_caps)) { - DP_INFO(edev, "40G speed not supported\n"); - return -EINVAL; - } - params.adv_speeds = current_link.supported_caps & - sup_caps; + phylink_set(sup_caps, 40000baseLR4_Full); + phylink_set(sup_caps, 40000baseKR4_Full); + phylink_set(sup_caps, 40000baseCR4_Full); + phylink_set(sup_caps, 40000baseSR4_Full); break; case SPEED_50000: - sup_caps = QED_LM_50000baseKR2_Full_BIT | - QED_LM_50000baseCR2_Full_BIT | - QED_LM_50000baseSR2_Full_BIT; - if (!(current_link.supported_caps & sup_caps)) { - DP_INFO(edev, "50G speed not supported\n"); - return -EINVAL; - } - params.adv_speeds = current_link.supported_caps & - sup_caps; + phylink_set(sup_caps, 50000baseKR2_Full); + phylink_set(sup_caps, 50000baseCR2_Full); + phylink_set(sup_caps, 50000baseSR2_Full); break; case SPEED_100000: - sup_caps = QED_LM_100000baseKR4_Full_BIT | - QED_LM_100000baseSR4_Full_BIT | - QED_LM_100000baseCR4_Full_BIT | - QED_LM_100000baseLR4_ER4_Full_BIT; - if (!(current_link.supported_caps & sup_caps)) { - DP_INFO(edev, "100G speed not supported\n"); - return -EINVAL; - } - params.adv_speeds = current_link.supported_caps & - sup_caps; + phylink_set(sup_caps, 100000baseKR4_Full); + phylink_set(sup_caps, 100000baseSR4_Full); + phylink_set(sup_caps, 100000baseCR4_Full); + phylink_set(sup_caps, 100000baseLR4_ER4_Full); break; default: DP_INFO(edev, "Unsupported speed %u\n", base->speed); return -EINVAL; } + + if (!linkmode_intersects(current_link.supported_caps, + sup_caps)) { + DP_INFO(edev, "%uG speed not supported\n", + base->speed / 1000); + return -EINVAL; + } + + linkmode_and(params.adv_speeds, current_link.supported_caps, + sup_caps); } params.link_up = true; @@ -1006,13 +911,16 @@ static int qede_set_pauseparam(struct net_device *dev, memset(¶ms, 0, sizeof(params)); params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG; + if (epause->autoneg) { - if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) { + if (!phylink_test(current_link.supported_caps, Autoneg)) { DP_INFO(edev, "autoneg not supported\n"); return -EINVAL; } + params.pause_config |= QED_LINK_PAUSE_AUTONEG_ENABLE; } + if (epause->rx_pause) params.pause_config |= QED_LINK_PAUSE_RX_ENABLE; if (epause->tx_pause) diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index 36b1ca2dadbb..6e77e4908605 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -440,6 +441,7 @@ static void qedf_link_recovery(struct work_struct *work) static void qedf_update_link_speed(struct qedf_ctx *qedf, struct qed_link_output *link) { + __ETHTOOL_DECLARE_LINK_MODE_MASK(sup_caps); struct fc_lport *lport = qedf->lport; lport->link_speed = FC_PORTSPEED_UNKNOWN; @@ -474,40 +476,60 @@ static void qedf_update_link_speed(struct qedf_ctx *qedf, * Set supported link speed by querying the supported * capabilities of the link. */ - if ((link->supported_caps & QED_LM_10000baseT_Full_BIT) || - (link->supported_caps & QED_LM_10000baseKX4_Full_BIT) || - (link->supported_caps & QED_LM_10000baseR_FEC_BIT) || - (link->supported_caps & QED_LM_10000baseCR_Full_BIT) || - (link->supported_caps & QED_LM_10000baseSR_Full_BIT) || - (link->supported_caps & QED_LM_10000baseLR_Full_BIT) || - (link->supported_caps & QED_LM_10000baseLRM_Full_BIT) || - (link->supported_caps & QED_LM_10000baseKR_Full_BIT)) { + + phylink_zero(sup_caps); + phylink_set(sup_caps, 10000baseT_Full); + phylink_set(sup_caps, 10000baseKX4_Full); + phylink_set(sup_caps, 10000baseR_FEC); + phylink_set(sup_caps, 10000baseCR_Full); + phylink_set(sup_caps, 10000baseSR_Full); + phylink_set(sup_caps, 10000baseLR_Full); + phylink_set(sup_caps, 10000baseLRM_Full); + phylink_set(sup_caps, 10000baseKR_Full); + + if (linkmode_intersects(link->supported_caps, sup_caps)) lport->link_supported_speeds |= FC_PORTSPEED_10GBIT; - } - if ((link->supported_caps & QED_LM_25000baseKR_Full_BIT) || - (link->supported_caps & QED_LM_25000baseCR_Full_BIT) || - (link->supported_caps & QED_LM_25000baseSR_Full_BIT)) { + + phylink_zero(sup_caps); + phylink_set(sup_caps, 25000baseKR_Full); + phylink_set(sup_caps, 25000baseCR_Full); + phylink_set(sup_caps, 25000baseSR_Full); + + if (linkmode_intersects(link->supported_caps, sup_caps)) lport->link_supported_speeds |= FC_PORTSPEED_25GBIT; - } - if ((link->supported_caps & QED_LM_40000baseLR4_Full_BIT) || - (link->supported_caps & QED_LM_40000baseKR4_Full_BIT) || - (link->supported_caps & QED_LM_40000baseCR4_Full_BIT) || - (link->supported_caps & QED_LM_40000baseSR4_Full_BIT)) { + + phylink_zero(sup_caps); + phylink_set(sup_caps, 40000baseLR4_Full); + phylink_set(sup_caps, 40000baseKR4_Full); + phylink_set(sup_caps, 40000baseCR4_Full); + phylink_set(sup_caps, 40000baseSR4_Full); + + if (linkmode_intersects(link->supported_caps, sup_caps)) lport->link_supported_speeds |= FC_PORTSPEED_40GBIT; - } - if ((link->supported_caps & QED_LM_50000baseKR2_Full_BIT) || - (link->supported_caps & QED_LM_50000baseCR2_Full_BIT) || - (link->supported_caps & QED_LM_50000baseSR2_Full_BIT)) { + + phylink_zero(sup_caps); + phylink_set(sup_caps, 50000baseKR2_Full); + phylink_set(sup_caps, 50000baseCR2_Full); + phylink_set(sup_caps, 50000baseSR2_Full); + + if (linkmode_intersects(link->supported_caps, sup_caps)) lport->link_supported_speeds |= FC_PORTSPEED_50GBIT; - } - if ((link->supported_caps & QED_LM_100000baseKR4_Full_BIT) || - (link->supported_caps & QED_LM_100000baseSR4_Full_BIT) || - (link->supported_caps & QED_LM_100000baseCR4_Full_BIT) || - (link->supported_caps & QED_LM_100000baseLR4_ER4_Full_BIT)) { + + phylink_zero(sup_caps); + phylink_set(sup_caps, 100000baseKR4_Full); + phylink_set(sup_caps, 100000baseSR4_Full); + phylink_set(sup_caps, 100000baseCR4_Full); + phylink_set(sup_caps, 100000baseLR4_ER4_Full); + + if (linkmode_intersects(link->supported_caps, sup_caps)) lport->link_supported_speeds |= FC_PORTSPEED_100GBIT; - } - if (link->supported_caps & QED_LM_20000baseKR2_Full_BIT) + + phylink_zero(sup_caps); + phylink_set(sup_caps, 20000baseKR2_Full); + + if (linkmode_intersects(link->supported_caps, sup_caps)) lport->link_supported_speeds |= FC_PORTSPEED_20GBIT; + fc_host_supported_speeds(lport->host) = lport->link_supported_speeds; } diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index 8a6e3ad436d1..f82db1b92d45 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -661,42 +661,6 @@ enum qed_protocol { QED_PROTOCOL_FCOE, }; -enum qed_link_mode_bits { - QED_LM_FIBRE_BIT = BIT(0), - QED_LM_Autoneg_BIT = BIT(1), - QED_LM_Asym_Pause_BIT = BIT(2), - QED_LM_Pause_BIT = BIT(3), - QED_LM_1000baseT_Full_BIT = BIT(4), - QED_LM_10000baseT_Full_BIT = BIT(5), - QED_LM_10000baseKR_Full_BIT = BIT(6), - QED_LM_20000baseKR2_Full_BIT = BIT(7), - QED_LM_25000baseKR_Full_BIT = BIT(8), - QED_LM_40000baseLR4_Full_BIT = BIT(9), - QED_LM_50000baseKR2_Full_BIT = BIT(10), - QED_LM_100000baseKR4_Full_BIT = BIT(11), - QED_LM_TP_BIT = BIT(12), - QED_LM_Backplane_BIT = BIT(13), - QED_LM_1000baseKX_Full_BIT = BIT(14), - QED_LM_10000baseKX4_Full_BIT = BIT(15), - QED_LM_10000baseR_FEC_BIT = BIT(16), - QED_LM_40000baseKR4_Full_BIT = BIT(17), - QED_LM_40000baseCR4_Full_BIT = BIT(18), - QED_LM_40000baseSR4_Full_BIT = BIT(19), - QED_LM_25000baseCR_Full_BIT = BIT(20), - QED_LM_25000baseSR_Full_BIT = BIT(21), - QED_LM_50000baseCR2_Full_BIT = BIT(22), - QED_LM_100000baseSR4_Full_BIT = BIT(23), - QED_LM_100000baseCR4_Full_BIT = BIT(24), - QED_LM_100000baseLR4_ER4_Full_BIT = BIT(25), - QED_LM_50000baseSR2_Full_BIT = BIT(26), - QED_LM_1000baseX_Full_BIT = BIT(27), - QED_LM_10000baseCR_Full_BIT = BIT(28), - QED_LM_10000baseSR_Full_BIT = BIT(29), - QED_LM_10000baseLR_Full_BIT = BIT(30), - QED_LM_10000baseLRM_Full_BIT = BIT(31), - QED_LM_COUNT = 32 -}; - struct qed_link_params { bool link_up; @@ -708,7 +672,9 @@ struct qed_link_params { #define QED_LINK_OVERRIDE_EEE_CONFIG BIT(5) u32 override_flags; bool autoneg; - u32 adv_speeds; + + __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_speeds); + u32 forced_speed; #define QED_LINK_PAUSE_AUTONEG_ENABLE BIT(0) #define QED_LINK_PAUSE_RX_ENABLE BIT(1) @@ -726,10 +692,9 @@ struct qed_link_params { struct qed_link_output { bool link_up; - /* In QED_LM_* defs */ - u32 supported_caps; - u32 advertised_caps; - u32 lp_caps; + __ETHTOOL_DECLARE_LINK_MODE_MASK(supported_caps); + __ETHTOOL_DECLARE_LINK_MODE_MASK(advertised_caps); + __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_caps); u32 speed; /* In Mb/s */ u8 duplex; /* In DUPLEX defs */ -- cgit v1.2.3-71-gd317 From 37237b5b7104f91b519133d7862d1b5169a3ba8e Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Mon, 20 Jul 2020 21:08:06 +0300 Subject: qed: reformat several structures a bit Prior to adding new fields and bitfields, reformat the related structures according to the Linux style (spaces to tabs, lowercase hex, indentation etc.). Signed-off-by: Alexander Lobakin Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_hsi.h | 256 +++++++++++++++--------------- drivers/net/ethernet/qlogic/qed/qed_mcp.h | 85 +++++----- include/linux/qed/qed_if.h | 64 ++++---- 3 files changed, 205 insertions(+), 200 deletions(-) (limited to 'include') diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h index ebc25b34e491..93d33c9cf145 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h @@ -11536,34 +11536,35 @@ typedef u32 offsize_t; /* In DWORDS !!! */ /* PHY configuration */ struct eth_phy_cfg { - u32 speed; -#define ETH_SPEED_AUTONEG 0 -#define ETH_SPEED_SMARTLINQ 0x8 - - u32 pause; -#define ETH_PAUSE_NONE 0x0 -#define ETH_PAUSE_AUTONEG 0x1 -#define ETH_PAUSE_RX 0x2 -#define ETH_PAUSE_TX 0x4 - - u32 adv_speed; - u32 loopback_mode; -#define ETH_LOOPBACK_NONE (0) -#define ETH_LOOPBACK_INT_PHY (1) -#define ETH_LOOPBACK_EXT_PHY (2) -#define ETH_LOOPBACK_EXT (3) -#define ETH_LOOPBACK_MAC (4) - - u32 eee_cfg; + u32 speed; +#define ETH_SPEED_AUTONEG 0x0 +#define ETH_SPEED_SMARTLINQ 0x8 + + u32 pause; +#define ETH_PAUSE_NONE 0x0 +#define ETH_PAUSE_AUTONEG 0x1 +#define ETH_PAUSE_RX 0x2 +#define ETH_PAUSE_TX 0x4 + + u32 adv_speed; + + u32 loopback_mode; +#define ETH_LOOPBACK_NONE 0x0 +#define ETH_LOOPBACK_INT_PHY 0x1 +#define ETH_LOOPBACK_EXT_PHY 0x2 +#define ETH_LOOPBACK_EXT 0x3 +#define ETH_LOOPBACK_MAC 0x4 + + u32 eee_cfg; #define EEE_CFG_EEE_ENABLED BIT(0) #define EEE_CFG_TX_LPI BIT(1) #define EEE_CFG_ADV_SPEED_1G BIT(2) #define EEE_CFG_ADV_SPEED_10G BIT(3) -#define EEE_TX_TIMER_USEC_MASK (0xfffffff0) +#define EEE_TX_TIMER_USEC_MASK 0xfffffff0 #define EEE_TX_TIMER_USEC_OFFSET 4 -#define EEE_TX_TIMER_USEC_BALANCED_TIME (0xa00) -#define EEE_TX_TIMER_USEC_AGGRESSIVE_TIME (0x100) -#define EEE_TX_TIMER_USEC_LATENCY_TIME (0x6000) +#define EEE_TX_TIMER_USEC_BALANCED_TIME 0xa00 +#define EEE_TX_TIMER_USEC_AGGRESSIVE_TIME 0x100 +#define EEE_TX_TIMER_USEC_LATENCY_TIME 0x6000 u32 feature_config_flags; #define ETH_EEE_MODE_ADV_LPI (1 << 0) @@ -11895,41 +11896,36 @@ struct public_path { }; struct public_port { - u32 validity_map; - - u32 link_status; -#define LINK_STATUS_LINK_UP 0x00000001 -#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001e -#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (1 << 1) -#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (2 << 1) -#define LINK_STATUS_SPEED_AND_DUPLEX_10G (3 << 1) -#define LINK_STATUS_SPEED_AND_DUPLEX_20G (4 << 1) -#define LINK_STATUS_SPEED_AND_DUPLEX_40G (5 << 1) -#define LINK_STATUS_SPEED_AND_DUPLEX_50G (6 << 1) -#define LINK_STATUS_SPEED_AND_DUPLEX_100G (7 << 1) -#define LINK_STATUS_SPEED_AND_DUPLEX_25G (8 << 1) - -#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 - -#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 -#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 - + u32 validity_map; + + u32 link_status; +#define LINK_STATUS_LINK_UP 0x00000001 +#define LINK_STATUS_SPEED_AND_DUPLEX_MASK 0x0000001e +#define LINK_STATUS_SPEED_AND_DUPLEX_1000THD (1 << 1) +#define LINK_STATUS_SPEED_AND_DUPLEX_1000TFD (2 << 1) +#define LINK_STATUS_SPEED_AND_DUPLEX_10G (3 << 1) +#define LINK_STATUS_SPEED_AND_DUPLEX_20G (4 << 1) +#define LINK_STATUS_SPEED_AND_DUPLEX_40G (5 << 1) +#define LINK_STATUS_SPEED_AND_DUPLEX_50G (6 << 1) +#define LINK_STATUS_SPEED_AND_DUPLEX_100G (7 << 1) +#define LINK_STATUS_SPEED_AND_DUPLEX_25G (8 << 1) +#define LINK_STATUS_AUTO_NEGOTIATE_ENABLED 0x00000020 +#define LINK_STATUS_AUTO_NEGOTIATE_COMPLETE 0x00000040 +#define LINK_STATUS_PARALLEL_DETECTION_USED 0x00000080 #define LINK_STATUS_PFC_ENABLED 0x00000100 -#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 -#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 +#define LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE 0x00000200 +#define LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE 0x00000400 #define LINK_STATUS_LINK_PARTNER_10G_CAPABLE 0x00000800 #define LINK_STATUS_LINK_PARTNER_20G_CAPABLE 0x00001000 #define LINK_STATUS_LINK_PARTNER_40G_CAPABLE 0x00002000 #define LINK_STATUS_LINK_PARTNER_50G_CAPABLE 0x00004000 #define LINK_STATUS_LINK_PARTNER_100G_CAPABLE 0x00008000 #define LINK_STATUS_LINK_PARTNER_25G_CAPABLE 0x00010000 - -#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000C0000 +#define LINK_STATUS_LINK_PARTNER_FLOW_CONTROL_MASK 0x000c0000 #define LINK_STATUS_LINK_PARTNER_NOT_PAUSE_CAPABLE (0 << 18) #define LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE (1 << 18) #define LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE (2 << 18) #define LINK_STATUS_LINK_PARTNER_BOTH_PAUSE (3 << 18) - #define LINK_STATUS_SFP_TX_FAULT 0x00100000 #define LINK_STATUS_TX_FLOW_CONTROL_ENABLED 0x00200000 #define LINK_STATUS_RX_FLOW_CONTROL_ENABLED 0x00400000 @@ -12630,49 +12626,49 @@ struct public_drv_mb { #define FW_MSG_CODE_MDUMP_INVALID_CMD 0x00030000 - u32 fw_mb_param; -#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000 + u32 fw_mb_param; +#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xffff0000 #define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16 -#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000FFFF +#define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000ffff #define FW_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_SHIFT 0 - /* get pf rdma protocol command responce */ -#define FW_MB_PARAM_GET_PF_RDMA_NONE 0x0 -#define FW_MB_PARAM_GET_PF_RDMA_ROCE 0x1 -#define FW_MB_PARAM_GET_PF_RDMA_IWARP 0x2 -#define FW_MB_PARAM_GET_PF_RDMA_BOTH 0x3 + /* Get PF RDMA protocol command response */ +#define FW_MB_PARAM_GET_PF_RDMA_NONE 0x0 +#define FW_MB_PARAM_GET_PF_RDMA_ROCE 0x1 +#define FW_MB_PARAM_GET_PF_RDMA_IWARP 0x2 +#define FW_MB_PARAM_GET_PF_RDMA_BOTH 0x3 -/* get MFW feature support response */ -#define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ 0x00000001 -#define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x00000002 -#define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x00010000 + /* Get MFW feature support response */ +#define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ 0x00000001 +#define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x00000002 +#define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x00010000 -#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR (1 << 0) +#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR BIT(0) -#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_MASK 0x00000001 -#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_SHIFT 0 -#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_MASK 0x00000002 -#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_SHIFT 1 -#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_MASK 0x00000004 -#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_SHIFT 2 -#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_MASK 0x00000008 -#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_SHIFT 3 +#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_MASK 0x00000001 +#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALID_SHIFT 0 +#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_MASK 0x00000002 +#define FW_MB_PARAM_ENG_CFG_FIR_AFFIN_VALUE_SHIFT 1 +#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_MASK 0x00000004 +#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALID_SHIFT 2 +#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_MASK 0x00000008 +#define FW_MB_PARAM_ENG_CFG_L2_AFFIN_VALUE_SHIFT 3 -#define FW_MB_PARAM_PPFID_BITMAP_MASK 0xFF -#define FW_MB_PARAM_PPFID_BITMAP_SHIFT 0 +#define FW_MB_PARAM_PPFID_BITMAP_MASK 0xff +#define FW_MB_PARAM_PPFID_BITMAP_SHIFT 0 - u32 drv_pulse_mb; -#define DRV_PULSE_SEQ_MASK 0x00007fff -#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 -#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 + u32 drv_pulse_mb; +#define DRV_PULSE_SEQ_MASK 0x00007fff +#define DRV_PULSE_SYSTEM_TIME_MASK 0xffff0000 +#define DRV_PULSE_ALWAYS_ALIVE 0x00008000 - u32 mcp_pulse_mb; -#define MCP_PULSE_SEQ_MASK 0x00007fff -#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 -#define MCP_EVENT_MASK 0xffff0000 -#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 + u32 mcp_pulse_mb; +#define MCP_PULSE_SEQ_MASK 0x00007fff +#define MCP_PULSE_ALWAYS_ALIVE 0x00008000 +#define MCP_EVENT_MASK 0xffff0000 +#define MCP_EVENT_OTHER_DRIVER_RESET_REQ 0x00010000 - union drv_union_data union_data; + union drv_union_data union_data; }; #define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_MASK 0x00ffffff @@ -13048,24 +13044,27 @@ struct nvm_cfg1_path { }; struct nvm_cfg1_port { - u32 reserved__m_relocated_to_option_123; - u32 reserved__m_relocated_to_option_124; - u32 generic_cont0; -#define NVM_CFG1_PORT_DCBX_MODE_MASK 0x000F0000 + u32 rel_to_opt123; + u32 rel_to_opt124; + + u32 generic_cont0; +#define NVM_CFG1_PORT_DCBX_MODE_MASK 0x000f0000 #define NVM_CFG1_PORT_DCBX_MODE_OFFSET 16 #define NVM_CFG1_PORT_DCBX_MODE_DISABLED 0x0 #define NVM_CFG1_PORT_DCBX_MODE_IEEE 0x1 #define NVM_CFG1_PORT_DCBX_MODE_CEE 0x2 #define NVM_CFG1_PORT_DCBX_MODE_DYNAMIC 0x3 -#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_MASK 0x00F00000 +#define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_MASK 0x00f00000 #define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_OFFSET 20 #define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_ETHERNET 0x1 #define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_FCOE 0x2 #define NVM_CFG1_PORT_DEFAULT_ENABLED_PROTOCOLS_ISCSI 0x4 - u32 pcie_cfg; - u32 features; - u32 speed_cap_mask; -#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_MASK 0x0000FFFF + + u32 pcie_cfg; + u32 features; + + u32 speed_cap_mask; +#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_MASK 0x0000ffff #define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_OFFSET 0 #define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G 0x1 #define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G 0x2 @@ -13074,8 +13073,9 @@ struct nvm_cfg1_port { #define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G 0x10 #define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G 0x20 #define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G 0x40 - u32 link_settings; -#define NVM_CFG1_PORT_DRV_LINK_SPEED_MASK 0x0000000F + + u32 link_settings; +#define NVM_CFG1_PORT_DRV_LINK_SPEED_MASK 0x0000000f #define NVM_CFG1_PORT_DRV_LINK_SPEED_OFFSET 0 #define NVM_CFG1_PORT_DRV_LINK_SPEED_AUTONEG 0x0 #define NVM_CFG1_PORT_DRV_LINK_SPEED_1G 0x1 @@ -13091,49 +13091,53 @@ struct nvm_cfg1_port { #define NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG 0x1 #define NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX 0x2 #define NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX 0x4 - u32 phy_cfg; - u32 mgmt_traffic; - u32 ext_phy; + u32 phy_cfg; + u32 mgmt_traffic; + + u32 ext_phy; /* EEE power saving mode */ -#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_MASK 0x00FF0000 +#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_MASK 0x00ff0000 #define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_OFFSET 16 #define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_DISABLED 0x0 #define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_BALANCED 0x1 #define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_AGGRESSIVE 0x2 #define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_LOW_LATENCY 0x3 - u32 mba_cfg1; - u32 mba_cfg2; - u32 vf_cfg; - struct nvm_cfg_mac_address lldp_mac_address; - u32 led_port_settings; - u32 transceiver_00; - u32 device_ids; - u32 board_cfg; -#define NVM_CFG1_PORT_PORT_TYPE_MASK 0x000000FF -#define NVM_CFG1_PORT_PORT_TYPE_OFFSET 0 -#define NVM_CFG1_PORT_PORT_TYPE_UNDEFINED 0x0 -#define NVM_CFG1_PORT_PORT_TYPE_MODULE 0x1 -#define NVM_CFG1_PORT_PORT_TYPE_BACKPLANE 0x2 -#define NVM_CFG1_PORT_PORT_TYPE_EXT_PHY 0x3 -#define NVM_CFG1_PORT_PORT_TYPE_MODULE_SLAVE 0x4 - u32 mnm_10g_cap; - u32 mnm_10g_ctrl; - u32 mnm_10g_misc; - u32 mnm_25g_cap; - u32 mnm_25g_ctrl; - u32 mnm_25g_misc; - u32 mnm_40g_cap; - u32 mnm_40g_ctrl; - u32 mnm_40g_misc; - u32 mnm_50g_cap; - u32 mnm_50g_ctrl; - u32 mnm_50g_misc; - u32 mnm_100g_cap; - u32 mnm_100g_ctrl; - u32 mnm_100g_misc; - u32 reserved[116]; + u32 mba_cfg1; + u32 mba_cfg2; + u32 vf_cfg; + struct nvm_cfg_mac_address lldp_mac_address; + u32 led_port_settings; + u32 transceiver_00; + u32 device_ids; + + u32 board_cfg; +#define NVM_CFG1_PORT_PORT_TYPE_MASK 0x000000ff +#define NVM_CFG1_PORT_PORT_TYPE_OFFSET 0 +#define NVM_CFG1_PORT_PORT_TYPE_UNDEFINED 0x0 +#define NVM_CFG1_PORT_PORT_TYPE_MODULE 0x1 +#define NVM_CFG1_PORT_PORT_TYPE_BACKPLANE 0x2 +#define NVM_CFG1_PORT_PORT_TYPE_EXT_PHY 0x3 +#define NVM_CFG1_PORT_PORT_TYPE_MODULE_SLAVE 0x4 + + u32 mnm_10g_cap; + u32 mnm_10g_ctrl; + u32 mnm_10g_misc; + u32 mnm_25g_cap; + u32 mnm_25g_ctrl; + u32 mnm_25g_misc; + u32 mnm_40g_cap; + u32 mnm_40g_ctrl; + u32 mnm_40g_misc; + u32 mnm_50g_cap; + u32 mnm_50g_ctrl; + u32 mnm_50g_misc; + u32 mnm_100g_cap; + u32 mnm_100g_ctrl; + u32 mnm_100g_misc; + + u32 reserved[116]; }; struct nvm_cfg1_func { diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h index 63a22a615e94..cf678b6966f8 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h @@ -34,61 +34,60 @@ enum qed_mcp_eee_mode { }; struct qed_mcp_link_params { - struct qed_mcp_link_speed_params speed; - struct qed_mcp_link_pause_params pause; - u32 loopback_mode; - struct qed_link_eee_params eee; + struct qed_mcp_link_speed_params speed; + struct qed_mcp_link_pause_params pause; + u32 loopback_mode; + struct qed_link_eee_params eee; }; struct qed_mcp_link_capabilities { - u32 speed_capabilities; - bool default_speed_autoneg; - enum qed_mcp_eee_mode default_eee; - u32 eee_lpi_timer; - u8 eee_speed_caps; + u32 speed_capabilities; + bool default_speed_autoneg; + enum qed_mcp_eee_mode default_eee; + u32 eee_lpi_timer; + u8 eee_speed_caps; }; struct qed_mcp_link_state { - bool link_up; - - u32 min_pf_rate; + bool link_up; + u32 min_pf_rate; /* Actual link speed in Mb/s */ - u32 line_speed; + u32 line_speed; /* PF max speed in Mb/s, deduced from line_speed * according to PF max bandwidth configuration. */ - u32 speed; - bool full_duplex; - - bool an; - bool an_complete; - bool parallel_detection; - bool pfc_enabled; - -#define QED_LINK_PARTNER_SPEED_1G_HD BIT(0) -#define QED_LINK_PARTNER_SPEED_1G_FD BIT(1) -#define QED_LINK_PARTNER_SPEED_10G BIT(2) -#define QED_LINK_PARTNER_SPEED_20G BIT(3) -#define QED_LINK_PARTNER_SPEED_25G BIT(4) -#define QED_LINK_PARTNER_SPEED_40G BIT(5) -#define QED_LINK_PARTNER_SPEED_50G BIT(6) -#define QED_LINK_PARTNER_SPEED_100G BIT(7) - u32 partner_adv_speed; - - bool partner_tx_flow_ctrl_en; - bool partner_rx_flow_ctrl_en; - -#define QED_LINK_PARTNER_SYMMETRIC_PAUSE (1) -#define QED_LINK_PARTNER_ASYMMETRIC_PAUSE (2) -#define QED_LINK_PARTNER_BOTH_PAUSE (3) - u8 partner_adv_pause; - - bool sfp_tx_fault; - bool eee_active; - u8 eee_adv_caps; - u8 eee_lp_adv_caps; + u32 speed; + + bool full_duplex; + bool an; + bool an_complete; + bool parallel_detection; + bool pfc_enabled; + + u32 partner_adv_speed; +#define QED_LINK_PARTNER_SPEED_1G_HD BIT(0) +#define QED_LINK_PARTNER_SPEED_1G_FD BIT(1) +#define QED_LINK_PARTNER_SPEED_10G BIT(2) +#define QED_LINK_PARTNER_SPEED_20G BIT(3) +#define QED_LINK_PARTNER_SPEED_25G BIT(4) +#define QED_LINK_PARTNER_SPEED_40G BIT(5) +#define QED_LINK_PARTNER_SPEED_50G BIT(6) +#define QED_LINK_PARTNER_SPEED_100G BIT(7) + + bool partner_tx_flow_ctrl_en; + bool partner_rx_flow_ctrl_en; + + u8 partner_adv_pause; +#define QED_LINK_PARTNER_SYMMETRIC_PAUSE 0x1 +#define QED_LINK_PARTNER_ASYMMETRIC_PAUSE 0x2 +#define QED_LINK_PARTNER_BOTH_PAUSE 0x3 + + bool sfp_tx_fault; + bool eee_active; + u8 eee_adv_caps; + u8 eee_lp_adv_caps; }; struct qed_mcp_function_info { diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index f82db1b92d45..dde48f206d0d 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -662,51 +662,53 @@ enum qed_protocol { }; struct qed_link_params { - bool link_up; + bool link_up; -#define QED_LINK_OVERRIDE_SPEED_AUTONEG BIT(0) -#define QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS BIT(1) -#define QED_LINK_OVERRIDE_SPEED_FORCED_SPEED BIT(2) -#define QED_LINK_OVERRIDE_PAUSE_CONFIG BIT(3) -#define QED_LINK_OVERRIDE_LOOPBACK_MODE BIT(4) -#define QED_LINK_OVERRIDE_EEE_CONFIG BIT(5) - u32 override_flags; - bool autoneg; + u32 override_flags; +#define QED_LINK_OVERRIDE_SPEED_AUTONEG BIT(0) +#define QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS BIT(1) +#define QED_LINK_OVERRIDE_SPEED_FORCED_SPEED BIT(2) +#define QED_LINK_OVERRIDE_PAUSE_CONFIG BIT(3) +#define QED_LINK_OVERRIDE_LOOPBACK_MODE BIT(4) +#define QED_LINK_OVERRIDE_EEE_CONFIG BIT(5) + bool autoneg; __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_speeds); + u32 forced_speed; - u32 forced_speed; -#define QED_LINK_PAUSE_AUTONEG_ENABLE BIT(0) -#define QED_LINK_PAUSE_RX_ENABLE BIT(1) -#define QED_LINK_PAUSE_TX_ENABLE BIT(2) - u32 pause_config; -#define QED_LINK_LOOPBACK_NONE BIT(0) -#define QED_LINK_LOOPBACK_INT_PHY BIT(1) -#define QED_LINK_LOOPBACK_EXT_PHY BIT(2) -#define QED_LINK_LOOPBACK_EXT BIT(3) -#define QED_LINK_LOOPBACK_MAC BIT(4) - u32 loopback_mode; - struct qed_link_eee_params eee; + u32 pause_config; +#define QED_LINK_PAUSE_AUTONEG_ENABLE BIT(0) +#define QED_LINK_PAUSE_RX_ENABLE BIT(1) +#define QED_LINK_PAUSE_TX_ENABLE BIT(2) + + u32 loopback_mode; +#define QED_LINK_LOOPBACK_NONE BIT(0) +#define QED_LINK_LOOPBACK_INT_PHY BIT(1) +#define QED_LINK_LOOPBACK_EXT_PHY BIT(2) +#define QED_LINK_LOOPBACK_EXT BIT(3) +#define QED_LINK_LOOPBACK_MAC BIT(4) + + struct qed_link_eee_params eee; }; struct qed_link_output { - bool link_up; + bool link_up; __ETHTOOL_DECLARE_LINK_MODE_MASK(supported_caps); __ETHTOOL_DECLARE_LINK_MODE_MASK(advertised_caps); __ETHTOOL_DECLARE_LINK_MODE_MASK(lp_caps); - u32 speed; /* In Mb/s */ - u8 duplex; /* In DUPLEX defs */ - u8 port; /* In PORT defs */ - bool autoneg; - u32 pause_config; + u32 speed; /* In Mb/s */ + u8 duplex; /* In DUPLEX defs */ + u8 port; /* In PORT defs */ + bool autoneg; + u32 pause_config; /* EEE - capability & param */ - bool eee_supported; - bool eee_active; - u8 sup_caps; - struct qed_link_eee_params eee; + bool eee_supported; + bool eee_active; + u8 sup_caps; + struct qed_link_eee_params eee; }; struct qed_probe_params { -- cgit v1.2.3-71-gd317 From ae7e69379fd5a87141fd8c7f2efab8e73f2a9f7e Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Mon, 20 Jul 2020 21:08:07 +0300 Subject: qed: add support for Forward Error Correction Add all necessary routines for reading supported FEC modes from NVM and querying FEC control to the MFW (if the running version supports it). Signed-off-by: Alexander Lobakin Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_dev.c | 54 ++++++++++++++++++++---------- drivers/net/ethernet/qlogic/qed/qed_hsi.h | 24 +++++++++++-- drivers/net/ethernet/qlogic/qed/qed_main.c | 6 ++++ drivers/net/ethernet/qlogic/qed/qed_mcp.c | 47 +++++++++++++++++++++----- drivers/net/ethernet/qlogic/qed/qed_mcp.h | 4 +++ include/linux/qed/qed_if.h | 13 +++++++ 6 files changed, 121 insertions(+), 27 deletions(-) (limited to 'include') diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 491a6dbb5d73..d929556247a5 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -3968,7 +3968,7 @@ unlock_and_exit: static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) { - u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities; + u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities, fc; u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg; struct qed_mcp_link_capabilities *p_caps; struct qed_mcp_link_params *link; @@ -4081,16 +4081,38 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) p_hwfn->mcp_info->link_capabilities.default_speed_autoneg = link->speed.autoneg; - link_temp &= NVM_CFG1_PORT_DRV_FLOW_CONTROL_MASK; - link_temp >>= NVM_CFG1_PORT_DRV_FLOW_CONTROL_OFFSET; - link->pause.autoneg = !!(link_temp & - NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG); - link->pause.forced_rx = !!(link_temp & - NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX); - link->pause.forced_tx = !!(link_temp & - NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX); + fc = GET_MFW_FIELD(link_temp, NVM_CFG1_PORT_DRV_FLOW_CONTROL); + link->pause.autoneg = !!(fc & NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG); + link->pause.forced_rx = !!(fc & NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX); + link->pause.forced_tx = !!(fc & NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX); link->loopback_mode = 0; + if (p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL) { + switch (GET_MFW_FIELD(link_temp, + NVM_CFG1_PORT_FEC_FORCE_MODE)) { + case NVM_CFG1_PORT_FEC_FORCE_MODE_NONE: + p_caps->fec_default |= QED_FEC_MODE_NONE; + break; + case NVM_CFG1_PORT_FEC_FORCE_MODE_FIRECODE: + p_caps->fec_default |= QED_FEC_MODE_FIRECODE; + break; + case NVM_CFG1_PORT_FEC_FORCE_MODE_RS: + p_caps->fec_default |= QED_FEC_MODE_RS; + break; + case NVM_CFG1_PORT_FEC_FORCE_MODE_AUTO: + p_caps->fec_default |= QED_FEC_MODE_AUTO; + break; + default: + DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, + "unknown FEC mode in 0x%08x\n", link_temp); + } + } else { + p_caps->fec_default = QED_FEC_MODE_UNSUPPORTED; + } + + link->fec = p_caps->fec_default; + if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE) { link_temp = qed_rd(p_hwfn, p_ptt, port_cfg_addr + offsetof(struct nvm_cfg1_port, ext_phy)); @@ -4122,14 +4144,12 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) p_caps->default_eee = QED_MCP_EEE_UNSUPPORTED; } - DP_VERBOSE(p_hwfn, - NETIF_MSG_LINK, - "Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x EEE: %02x [%08x usec]\n", - link->speed.forced_speed, - link->speed.advertised_speeds, - link->speed.autoneg, - link->pause.autoneg, - p_caps->default_eee, p_caps->eee_lpi_timer); + DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, + "Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x, EEE: 0x%02x [0x%08x usec], FEC: 0x%02x\n", + link->speed.forced_speed, link->speed.advertised_speeds, + link->speed.autoneg, link->pause.autoneg, + p_caps->default_eee, p_caps->eee_lpi_timer, + p_caps->fec_default); if (IS_LEAD_HWFN(p_hwfn)) { struct qed_dev *cdev = p_hwfn->cdev; diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h index 93d33c9cf145..7c1d4efffbff 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h @@ -11566,8 +11566,15 @@ struct eth_phy_cfg { #define EEE_TX_TIMER_USEC_AGGRESSIVE_TIME 0x100 #define EEE_TX_TIMER_USEC_LATENCY_TIME 0x6000 - u32 feature_config_flags; -#define ETH_EEE_MODE_ADV_LPI (1 << 0) + u32 deprecated; + + u32 fec_mode; +#define FEC_FORCE_MODE_MASK 0x000000ff +#define FEC_FORCE_MODE_OFFSET 0 +#define FEC_FORCE_MODE_NONE 0x00 +#define FEC_FORCE_MODE_FIRECODE 0x01 +#define FEC_FORCE_MODE_RS 0x02 +#define FEC_FORCE_MODE_AUTO 0x07 }; struct port_mf_cfg { @@ -11934,6 +11941,11 @@ struct public_port { #define LINK_STATUS_MAC_REMOTE_FAULT 0x02000000 #define LINK_STATUS_UNSUPPORTED_SPD_REQ 0x04000000 +#define LINK_STATUS_FEC_MODE_MASK 0x38000000 +#define LINK_STATUS_FEC_MODE_NONE (0 << 27) +#define LINK_STATUS_FEC_MODE_FIRECODE_CL74 (1 << 27) +#define LINK_STATUS_FEC_MODE_RS_CL91 (2 << 27) + u32 link_status1; u32 ext_phy_fw_version; u32 drv_phy_cfg_addr; @@ -12553,6 +12565,7 @@ struct public_drv_mb { #define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_MASK 0x0000FFFF #define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_OFFSET 0 #define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002 +#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_FEC_CONTROL 0x00000004 #define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000 /* DRV_MSG_CODE_DEBUG_DATA_SEND parameters */ @@ -12641,6 +12654,7 @@ struct public_drv_mb { /* Get MFW feature support response */ #define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ 0x00000001 #define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x00000002 +#define FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL 0x00000020 #define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x00010000 #define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR BIT(0) @@ -13091,6 +13105,12 @@ struct nvm_cfg1_port { #define NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG 0x1 #define NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX 0x2 #define NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX 0x4 +#define NVM_CFG1_PORT_FEC_FORCE_MODE_MASK 0x000e0000 +#define NVM_CFG1_PORT_FEC_FORCE_MODE_OFFSET 17 +#define NVM_CFG1_PORT_FEC_FORCE_MODE_NONE 0x0 +#define NVM_CFG1_PORT_FEC_FORCE_MODE_FIRECODE 0x1 +#define NVM_CFG1_PORT_FEC_FORCE_MODE_RS 0x2 +#define NVM_CFG1_PORT_FEC_FORCE_MODE_AUTO 0x7 u32 phy_cfg; u32 mgmt_traffic; diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 2be9ed39c450..91e7cfc544f0 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -1597,6 +1597,9 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params) memcpy(&link_params->eee, ¶ms->eee, sizeof(link_params->eee)); + if (params->override_flags & QED_LINK_OVERRIDE_FEC_CONFIG) + link_params->fec = params->fec; + rc = qed_mcp_set_link(hwfn, ptt, params->link_up); qed_ptt_release(hwfn, ptt); @@ -1938,6 +1941,9 @@ static void qed_fill_link(struct qed_hwfn *hwfn, else phylink_clear(if_link->advertised_caps, Autoneg); + if_link->sup_fec = link_caps.fec_default; + if_link->active_fec = params.fec; + /* Fill link advertised capability */ qed_fill_link_capability(hwfn, ptt, params.speed.advertised_speeds, if_link->advertised_caps); diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index b10a92488630..78c0d3a2d164 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -1446,6 +1446,25 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn, if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE) qed_mcp_read_eee_config(p_hwfn, p_ptt, p_link); + if (p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL) { + switch (status & LINK_STATUS_FEC_MODE_MASK) { + case LINK_STATUS_FEC_MODE_NONE: + p_link->fec_active = QED_FEC_MODE_NONE; + break; + case LINK_STATUS_FEC_MODE_FIRECODE_CL74: + p_link->fec_active = QED_FEC_MODE_FIRECODE; + break; + case LINK_STATUS_FEC_MODE_RS_CL91: + p_link->fec_active = QED_FEC_MODE_RS; + break; + default: + p_link->fec_active = QED_FEC_MODE_AUTO; + } + } else { + p_link->fec_active = QED_FEC_MODE_UNSUPPORTED; + } + qed_link_update(p_hwfn, p_ptt); out: spin_unlock_bh(&p_hwfn->mcp_info->link_lock); @@ -1456,8 +1475,8 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up) struct qed_mcp_link_params *params = &p_hwfn->mcp_info->link_input; struct qed_mcp_mb_params mb_params; struct eth_phy_cfg phy_cfg; + u32 cmd, fec_bit = 0; int rc = 0; - u32 cmd; /* Set the shmem configuration according to params */ memset(&phy_cfg, 0, sizeof(phy_cfg)); @@ -1489,16 +1508,27 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up) EEE_TX_TIMER_USEC_MASK; } + if (p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL) { + if (params->fec & QED_FEC_MODE_NONE) + fec_bit |= FEC_FORCE_MODE_NONE; + else if (params->fec & QED_FEC_MODE_FIRECODE) + fec_bit |= FEC_FORCE_MODE_FIRECODE; + else if (params->fec & QED_FEC_MODE_RS) + fec_bit |= FEC_FORCE_MODE_RS; + else if (params->fec & QED_FEC_MODE_AUTO) + fec_bit |= FEC_FORCE_MODE_AUTO; + + SET_MFW_FIELD(phy_cfg.fec_mode, FEC_FORCE_MODE, fec_bit); + } + p_hwfn->b_drv_link_init = b_up; if (b_up) { DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, - "Configuring Link: Speed 0x%08x, Pause 0x%08x, adv_speed 0x%08x, loopback 0x%08x, features 0x%08x\n", - phy_cfg.speed, - phy_cfg.pause, - phy_cfg.adv_speed, - phy_cfg.loopback_mode, - phy_cfg.feature_config_flags); + "Configuring Link: Speed 0x%08x, Pause 0x%08x, adv_speed 0x%08x, loopback 0x%08x, FEC 0x%08x\n", + phy_cfg.speed, phy_cfg.pause, phy_cfg.adv_speed, + phy_cfg.loopback_mode, phy_cfg.fec_mode); } else { DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, "Resetting link\n"); @@ -3805,7 +3835,8 @@ int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) u32 mcp_resp, mcp_param, features; features = DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE | - DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK; + DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK | + DRV_MB_PARAM_FEATURE_SUPPORT_PORT_FEC_CONTROL; return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_FEATURE_SUPPORT, features, &mcp_resp, &mcp_param); diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h index cf678b6966f8..5e50405854e6 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h @@ -38,11 +38,13 @@ struct qed_mcp_link_params { struct qed_mcp_link_pause_params pause; u32 loopback_mode; struct qed_link_eee_params eee; + u32 fec; }; struct qed_mcp_link_capabilities { u32 speed_capabilities; bool default_speed_autoneg; + u32 fec_default; enum qed_mcp_eee_mode default_eee; u32 eee_lpi_timer; u8 eee_speed_caps; @@ -88,6 +90,8 @@ struct qed_mcp_link_state { bool eee_active; u8 eee_adv_caps; u8 eee_lp_adv_caps; + + u32 fec_active; }; struct qed_mcp_function_info { diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index dde48f206d0d..f0b4cdc79299 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -661,6 +661,14 @@ enum qed_protocol { QED_PROTOCOL_FCOE, }; +enum qed_fec_mode { + QED_FEC_MODE_NONE = BIT(0), + QED_FEC_MODE_FIRECODE = BIT(1), + QED_FEC_MODE_RS = BIT(2), + QED_FEC_MODE_AUTO = BIT(3), + QED_FEC_MODE_UNSUPPORTED = BIT(4), +}; + struct qed_link_params { bool link_up; @@ -671,6 +679,7 @@ struct qed_link_params { #define QED_LINK_OVERRIDE_PAUSE_CONFIG BIT(3) #define QED_LINK_OVERRIDE_LOOPBACK_MODE BIT(4) #define QED_LINK_OVERRIDE_EEE_CONFIG BIT(5) +#define QED_LINK_OVERRIDE_FEC_CONFIG BIT(6) bool autoneg; __ETHTOOL_DECLARE_LINK_MODE_MASK(adv_speeds); @@ -689,6 +698,7 @@ struct qed_link_params { #define QED_LINK_LOOPBACK_MAC BIT(4) struct qed_link_eee_params eee; + u32 fec; }; struct qed_link_output { @@ -709,6 +719,9 @@ struct qed_link_output { bool eee_active; u8 sup_caps; struct qed_link_eee_params eee; + + u32 sup_fec; + u32 active_fec; }; struct qed_probe_params { -- cgit v1.2.3-71-gd317 From 98e675ec5a92a15f6f8ade41eda883cd39df5712 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Mon, 20 Jul 2020 21:08:13 +0300 Subject: qed: add missing loopback modes These modes are relevant only for several boards, but may be reported by MFW as well as the others. Signed-off-by: Alexander Lobakin Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed_hsi.h | 5 +++++ drivers/net/ethernet/qlogic/qed/qed_main.c | 19 +++++++++++++++++++ include/linux/qed/qed_if.h | 5 +++++ 3 files changed, 29 insertions(+) (limited to 'include') diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h index debc55923251..5b81d5d42397 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h @@ -11554,6 +11554,11 @@ struct eth_phy_cfg { #define ETH_LOOPBACK_EXT_PHY 0x2 #define ETH_LOOPBACK_EXT 0x3 #define ETH_LOOPBACK_MAC 0x4 +#define ETH_LOOPBACK_CNIG_AH_ONLY_0123 0x5 +#define ETH_LOOPBACK_CNIG_AH_ONLY_2301 0x6 +#define ETH_LOOPBACK_PCS_AH_ONLY 0x7 +#define ETH_LOOPBACK_REVERSE_MAC_AH_ONLY 0x8 +#define ETH_LOOPBACK_INT_PHY_FEA_AH_ONLY 0x9 u32 eee_cfg; #define EEE_CFG_EEE_ENABLED BIT(0) diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 91e7cfc544f0..fea155c6ff11 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -1587,6 +1587,25 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params) case QED_LINK_LOOPBACK_MAC: link_params->loopback_mode = ETH_LOOPBACK_MAC; break; + case QED_LINK_LOOPBACK_CNIG_AH_ONLY_0123: + link_params->loopback_mode = + ETH_LOOPBACK_CNIG_AH_ONLY_0123; + break; + case QED_LINK_LOOPBACK_CNIG_AH_ONLY_2301: + link_params->loopback_mode = + ETH_LOOPBACK_CNIG_AH_ONLY_2301; + break; + case QED_LINK_LOOPBACK_PCS_AH_ONLY: + link_params->loopback_mode = ETH_LOOPBACK_PCS_AH_ONLY; + break; + case QED_LINK_LOOPBACK_REVERSE_MAC_AH_ONLY: + link_params->loopback_mode = + ETH_LOOPBACK_REVERSE_MAC_AH_ONLY; + break; + case QED_LINK_LOOPBACK_INT_PHY_FEA_AH_ONLY: + link_params->loopback_mode = + ETH_LOOPBACK_INT_PHY_FEA_AH_ONLY; + break; default: link_params->loopback_mode = ETH_LOOPBACK_NONE; break; diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index f0b4cdc79299..2e780159a5fb 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -696,6 +696,11 @@ struct qed_link_params { #define QED_LINK_LOOPBACK_EXT_PHY BIT(2) #define QED_LINK_LOOPBACK_EXT BIT(3) #define QED_LINK_LOOPBACK_MAC BIT(4) +#define QED_LINK_LOOPBACK_CNIG_AH_ONLY_0123 BIT(5) +#define QED_LINK_LOOPBACK_CNIG_AH_ONLY_2301 BIT(6) +#define QED_LINK_LOOPBACK_PCS_AH_ONLY BIT(7) +#define QED_LINK_LOOPBACK_REVERSE_MAC_AH_ONLY BIT(8) +#define QED_LINK_LOOPBACK_INT_PHY_FEA_AH_ONLY BIT(9) struct qed_link_eee_params eee; u32 fec; -- cgit v1.2.3-71-gd317 From 99785a87fc7d27207c7dca0f0fe04386f1981690 Mon Sep 17 00:00:00 2001 From: Alexander Lobakin Date: Mon, 20 Jul 2020 21:08:15 +0300 Subject: qed: add support for the extended speed and FEC modes Add all necessary code (NVM parsing, MFW and Ethtool reports etc.) to support extended speed and FEC modes. These new modes are supported by the new boards revisions and newer MFW versions. Misc: correct port type for MEDIA_KR. Signed-off-by: Alexander Lobakin Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/qlogic/qed/qed.h | 1 + drivers/net/ethernet/qlogic/qed/qed_dev.c | 102 ++++++++++- drivers/net/ethernet/qlogic/qed/qed_hsi.h | 85 +++++++++- drivers/net/ethernet/qlogic/qed/qed_main.c | 264 +++++++++++++++++++++++++++-- drivers/net/ethernet/qlogic/qed/qed_mcp.c | 74 +++++++- drivers/net/ethernet/qlogic/qed/qed_mcp.h | 45 +++++ include/linux/qed/qed_if.h | 1 + 7 files changed, 547 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h index 47da4f7d3be2..b2a7b53ee760 100644 --- a/drivers/net/ethernet/qlogic/qed/qed.h +++ b/drivers/net/ethernet/qlogic/qed/qed.h @@ -712,6 +712,7 @@ struct qed_dev { #define QED_IS_AH(dev) ((dev)->type == QED_DEV_TYPE_AH) #define QED_IS_K2(dev) QED_IS_AH(dev) #define QED_IS_E4(dev) (QED_IS_BB(dev) || QED_IS_AH(dev)) +#define QED_IS_E5(dev) ((dev)->type == QED_DEV_TYPE_E5) u16 vendor_id; diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 66a520099c44..6516a1f921da 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -3968,8 +3968,9 @@ unlock_and_exit: static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) { - u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities, fc; + u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities, fld; u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg; + struct qed_mcp_link_speed_params *ext_speed; struct qed_mcp_link_capabilities *p_caps; struct qed_mcp_link_params *link; @@ -4026,8 +4027,7 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) link_temp &= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_MASK; link->speed.advertised_speeds = link_temp; - link_temp = link->speed.advertised_speeds; - p_hwfn->mcp_info->link_capabilities.speed_capabilities = link_temp; + p_caps->speed_capabilities = link->speed.advertised_speeds; link_temp = qed_rd(p_hwfn, p_ptt, port_cfg_addr + @@ -4062,13 +4062,12 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) DP_NOTICE(p_hwfn, "Unknown Speed in 0x%08x\n", link_temp); } - p_hwfn->mcp_info->link_capabilities.default_speed_autoneg = - link->speed.autoneg; + p_caps->default_speed_autoneg = link->speed.autoneg; - fc = GET_MFW_FIELD(link_temp, NVM_CFG1_PORT_DRV_FLOW_CONTROL); - link->pause.autoneg = !!(fc & NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG); - link->pause.forced_rx = !!(fc & NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX); - link->pause.forced_tx = !!(fc & NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX); + fld = GET_MFW_FIELD(link_temp, NVM_CFG1_PORT_DRV_FLOW_CONTROL); + link->pause.autoneg = !!(fld & NVM_CFG1_PORT_DRV_FLOW_CONTROL_AUTONEG); + link->pause.forced_rx = !!(fld & NVM_CFG1_PORT_DRV_FLOW_CONTROL_RX); + link->pause.forced_tx = !!(fld & NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX); link->loopback_mode = 0; if (p_hwfn->mcp_info->capabilities & @@ -4128,6 +4127,91 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) p_caps->default_eee = QED_MCP_EEE_UNSUPPORTED; } + if (p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL) { + ext_speed = &link->ext_speed; + + link_temp = qed_rd(p_hwfn, p_ptt, + port_cfg_addr + + offsetof(struct nvm_cfg1_port, + extended_speed)); + + fld = GET_MFW_FIELD(link_temp, NVM_CFG1_PORT_EXTENDED_SPEED); + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_AN) + ext_speed->autoneg = true; + + ext_speed->forced_speed = 0; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_1G) + ext_speed->forced_speed |= QED_EXT_SPEED_1G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_10G) + ext_speed->forced_speed |= QED_EXT_SPEED_10G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_20G) + ext_speed->forced_speed |= QED_EXT_SPEED_20G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_25G) + ext_speed->forced_speed |= QED_EXT_SPEED_25G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_40G) + ext_speed->forced_speed |= QED_EXT_SPEED_40G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R) + ext_speed->forced_speed |= QED_EXT_SPEED_50G_R; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R2) + ext_speed->forced_speed |= QED_EXT_SPEED_50G_R2; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R2) + ext_speed->forced_speed |= QED_EXT_SPEED_100G_R2; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R4) + ext_speed->forced_speed |= QED_EXT_SPEED_100G_R4; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_P4) + ext_speed->forced_speed |= QED_EXT_SPEED_100G_P4; + + fld = GET_MFW_FIELD(link_temp, + NVM_CFG1_PORT_EXTENDED_SPEED_CAP); + + ext_speed->advertised_speeds = 0; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_RESERVED) + ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_RES; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_1G) + ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_1G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_10G) + ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_10G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_20G) + ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_20G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_25G) + ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_25G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_40G) + ext_speed->advertised_speeds |= QED_EXT_SPEED_MASK_40G; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R) + ext_speed->advertised_speeds |= + QED_EXT_SPEED_MASK_50G_R; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R2) + ext_speed->advertised_speeds |= + QED_EXT_SPEED_MASK_50G_R2; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R2) + ext_speed->advertised_speeds |= + QED_EXT_SPEED_MASK_100G_R2; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R4) + ext_speed->advertised_speeds |= + QED_EXT_SPEED_MASK_100G_R4; + if (fld & NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_P4) + ext_speed->advertised_speeds |= + QED_EXT_SPEED_MASK_100G_P4; + + link_temp = qed_rd(p_hwfn, p_ptt, + port_cfg_addr + + offsetof(struct nvm_cfg1_port, + extended_fec_mode)); + link->ext_fec_mode = link_temp; + + p_caps->default_ext_speed_caps = ext_speed->advertised_speeds; + p_caps->default_ext_speed = ext_speed->forced_speed; + p_caps->default_ext_autoneg = ext_speed->autoneg; + p_caps->default_ext_fec = link->ext_fec_mode; + + DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, + "Read default extended link config: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, FEC: 0x%02x\n", + ext_speed->forced_speed, + ext_speed->advertised_speeds, ext_speed->autoneg, + p_caps->default_ext_fec); + } + DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, "Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x, EEE: 0x%02x [0x%08x usec], FEC: 0x%02x\n", link->speed.forced_speed, link->speed.advertised_speeds, diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h index 5b81d5d42397..1af3f65ab862 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h @@ -11580,6 +11580,54 @@ struct eth_phy_cfg { #define FEC_FORCE_MODE_FIRECODE 0x01 #define FEC_FORCE_MODE_RS 0x02 #define FEC_FORCE_MODE_AUTO 0x07 +#define FEC_EXTENDED_MODE_MASK 0xffffff00 +#define FEC_EXTENDED_MODE_OFFSET 8 +#define ETH_EXT_FEC_NONE 0x00000100 +#define ETH_EXT_FEC_10G_NONE 0x00000200 +#define ETH_EXT_FEC_10G_BASE_R 0x00000400 +#define ETH_EXT_FEC_20G_NONE 0x00000800 +#define ETH_EXT_FEC_20G_BASE_R 0x00001000 +#define ETH_EXT_FEC_25G_NONE 0x00002000 +#define ETH_EXT_FEC_25G_BASE_R 0x00004000 +#define ETH_EXT_FEC_25G_RS528 0x00008000 +#define ETH_EXT_FEC_40G_NONE 0x00010000 +#define ETH_EXT_FEC_40G_BASE_R 0x00020000 +#define ETH_EXT_FEC_50G_NONE 0x00040000 +#define ETH_EXT_FEC_50G_BASE_R 0x00080000 +#define ETH_EXT_FEC_50G_RS528 0x00100000 +#define ETH_EXT_FEC_50G_RS544 0x00200000 +#define ETH_EXT_FEC_100G_NONE 0x00400000 +#define ETH_EXT_FEC_100G_BASE_R 0x00800000 +#define ETH_EXT_FEC_100G_RS528 0x01000000 +#define ETH_EXT_FEC_100G_RS544 0x02000000 + + u32 extended_speed; +#define ETH_EXT_SPEED_MASK 0x0000ffff +#define ETH_EXT_SPEED_OFFSET 0 +#define ETH_EXT_SPEED_AN 0x00000001 +#define ETH_EXT_SPEED_1G 0x00000002 +#define ETH_EXT_SPEED_10G 0x00000004 +#define ETH_EXT_SPEED_20G 0x00000008 +#define ETH_EXT_SPEED_25G 0x00000010 +#define ETH_EXT_SPEED_40G 0x00000020 +#define ETH_EXT_SPEED_50G_BASE_R 0x00000040 +#define ETH_EXT_SPEED_50G_BASE_R2 0x00000080 +#define ETH_EXT_SPEED_100G_BASE_R2 0x00000100 +#define ETH_EXT_SPEED_100G_BASE_R4 0x00000200 +#define ETH_EXT_SPEED_100G_BASE_P4 0x00000400 +#define ETH_EXT_ADV_SPEED_MASK 0xffff0000 +#define ETH_EXT_ADV_SPEED_OFFSET 16 +#define ETH_EXT_ADV_SPEED_RESERVED 0x00010000 +#define ETH_EXT_ADV_SPEED_1G 0x00020000 +#define ETH_EXT_ADV_SPEED_10G 0x00040000 +#define ETH_EXT_ADV_SPEED_20G 0x00080000 +#define ETH_EXT_ADV_SPEED_25G 0x00100000 +#define ETH_EXT_ADV_SPEED_40G 0x00200000 +#define ETH_EXT_ADV_SPEED_50G_BASE_R 0x00400000 +#define ETH_EXT_ADV_SPEED_50G_BASE_R2 0x00800000 +#define ETH_EXT_ADV_SPEED_100G_BASE_R2 0x01000000 +#define ETH_EXT_ADV_SPEED_100G_BASE_R4 0x02000000 +#define ETH_EXT_ADV_SPEED_100G_BASE_P4 0x04000000 }; struct port_mf_cfg { @@ -12571,6 +12619,7 @@ struct public_drv_mb { #define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_OFFSET 0 #define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002 #define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_FEC_CONTROL 0x00000004 +#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EXT_SPEED_FEC_CONTROL 0x00000008 #define DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK 0x00010000 /* DRV_MSG_CODE_DEBUG_DATA_SEND parameters */ @@ -12660,6 +12709,7 @@ struct public_drv_mb { #define FW_MB_PARAM_FEATURE_SUPPORT_SMARTLINQ BIT(0) #define FW_MB_PARAM_FEATURE_SUPPORT_EEE BIT(1) #define FW_MB_PARAM_FEATURE_SUPPORT_FEC_CONTROL BIT(5) +#define FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL BIT(6) #define FW_MB_PARAM_FEATURE_SUPPORT_VLINK BIT(16) #define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR BIT(0) @@ -13174,7 +13224,40 @@ struct nvm_cfg1_port { u32 mnm_100g_ctrl; u32 mnm_100g_misc; - u32 reserved[116]; + u32 temperature; + u32 ext_phy_cfg1; + + u32 extended_speed; +#define NVM_CFG1_PORT_EXTENDED_SPEED_MASK 0x0000ffff +#define NVM_CFG1_PORT_EXTENDED_SPEED_OFFSET 0 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_AN 0x1 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_1G 0x2 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_10G 0x4 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_20G 0x8 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_25G 0x10 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_40G 0x20 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R 0x40 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_50G_R2 0x80 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R2 0x100 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_R4 0x200 +#define NVM_CFG1_PORT_EXTENDED_SPEED_EXTND_SPD_100G_P4 0x400 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_MASK 0xffff0000 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_OFFSET 16 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_RESERVED 0x1 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_1G 0x2 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_10G 0x4 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_20G 0x8 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_25G 0x10 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_40G 0x20 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R 0x40 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_50G_R2 0x80 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R2 0x100 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_R4 0x200 +#define NVM_CFG1_PORT_EXTENDED_SPEED_CAP_EXTND_SPD_100G_P4 0x400 + + u32 extended_fec_mode; + + u32 reserved[112]; }; struct nvm_cfg1_func { diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 4fe66cf60f24..2558cb680db3 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -82,6 +82,85 @@ struct qed_mfw_speed_map { .arr_size = ARRAY_SIZE(arr), \ } +static const u32 qed_mfw_ext_1g[] __initconst = { + ETHTOOL_LINK_MODE_1000baseT_Full_BIT, + ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, + ETHTOOL_LINK_MODE_1000baseX_Full_BIT, +}; + +static const u32 qed_mfw_ext_10g[] __initconst = { + ETHTOOL_LINK_MODE_10000baseT_Full_BIT, + ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, + ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, + ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, + ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, +}; + +static const u32 qed_mfw_ext_20g[] __initconst = { + ETHTOOL_LINK_MODE_20000baseKR2_Full_BIT, +}; + +static const u32 qed_mfw_ext_25g[] __initconst = { + ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, + ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, +}; + +static const u32 qed_mfw_ext_40g[] __initconst = { + ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, + ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, + ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, +}; + +static const u32 qed_mfw_ext_50g_base_r[] __initconst = { + ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT, + ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, +}; + +static const u32 qed_mfw_ext_50g_base_r2[] __initconst = { + ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, + ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, + ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, +}; + +static const u32 qed_mfw_ext_100g_base_r2[] __initconst = { + ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, + ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT, +}; + +static const u32 qed_mfw_ext_100g_base_r4[] __initconst = { + ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, + ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, + ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, + ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT, +}; + +static struct qed_mfw_speed_map qed_mfw_ext_maps[] __ro_after_init = { + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_1G, qed_mfw_ext_1g), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_10G, qed_mfw_ext_10g), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_20G, qed_mfw_ext_20g), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_25G, qed_mfw_ext_25g), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_40G, qed_mfw_ext_40g), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_50G_BASE_R, + qed_mfw_ext_50g_base_r), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_50G_BASE_R2, + qed_mfw_ext_50g_base_r2), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_100G_BASE_R2, + qed_mfw_ext_100g_base_r2), + QED_MFW_SPEED_MAP(ETH_EXT_ADV_SPEED_100G_BASE_R4, + qed_mfw_ext_100g_base_r4), +}; + static const u32 qed_mfw_legacy_1g[] __initconst = { ETHTOOL_LINK_MODE_1000baseT_Full_BIT, ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, @@ -158,6 +237,9 @@ static void __init qed_mfw_speed_maps_init(void) { u32 i; + for (i = 0; i < ARRAY_SIZE(qed_mfw_ext_maps); i++) + qed_mfw_speed_map_populate(qed_mfw_ext_maps + i); + for (i = 0; i < ARRAY_SIZE(qed_mfw_legacy_maps); i++) qed_mfw_speed_map_populate(qed_mfw_legacy_maps + i); } @@ -1553,6 +1635,147 @@ static bool qed_can_link_change(struct qed_dev *cdev) return true; } +static void qed_set_ext_speed_params(struct qed_mcp_link_params *link_params, + const struct qed_link_params *params) +{ + struct qed_mcp_link_speed_params *ext_speed = &link_params->ext_speed; + const struct qed_mfw_speed_map *map; + u32 i; + + if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG) + ext_speed->autoneg = !!params->autoneg; + + if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) { + ext_speed->advertised_speeds = 0; + + for (i = 0; i < ARRAY_SIZE(qed_mfw_ext_maps); i++) { + map = qed_mfw_ext_maps + i; + + if (linkmode_intersects(params->adv_speeds, map->caps)) + ext_speed->advertised_speeds |= map->mfw_val; + } + } + + if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED) { + switch (params->forced_speed) { + case SPEED_1000: + ext_speed->forced_speed = QED_EXT_SPEED_1G; + break; + case SPEED_10000: + ext_speed->forced_speed = QED_EXT_SPEED_10G; + break; + case SPEED_20000: + ext_speed->forced_speed = QED_EXT_SPEED_20G; + break; + case SPEED_25000: + ext_speed->forced_speed = QED_EXT_SPEED_25G; + break; + case SPEED_40000: + ext_speed->forced_speed = QED_EXT_SPEED_40G; + break; + case SPEED_50000: + ext_speed->forced_speed = QED_EXT_SPEED_50G_R | + QED_EXT_SPEED_50G_R2; + break; + case SPEED_100000: + ext_speed->forced_speed = QED_EXT_SPEED_100G_R2 | + QED_EXT_SPEED_100G_R4 | + QED_EXT_SPEED_100G_P4; + break; + default: + break; + } + } + + if (!(params->override_flags & QED_LINK_OVERRIDE_FEC_CONFIG)) + return; + + switch (params->forced_speed) { + case SPEED_25000: + switch (params->fec) { + case FEC_FORCE_MODE_NONE: + link_params->ext_fec_mode = ETH_EXT_FEC_25G_NONE; + break; + case FEC_FORCE_MODE_FIRECODE: + link_params->ext_fec_mode = ETH_EXT_FEC_25G_BASE_R; + break; + case FEC_FORCE_MODE_RS: + link_params->ext_fec_mode = ETH_EXT_FEC_25G_RS528; + break; + case FEC_FORCE_MODE_AUTO: + link_params->ext_fec_mode = ETH_EXT_FEC_25G_RS528 | + ETH_EXT_FEC_25G_BASE_R | + ETH_EXT_FEC_25G_NONE; + break; + default: + break; + } + + break; + case SPEED_40000: + switch (params->fec) { + case FEC_FORCE_MODE_NONE: + link_params->ext_fec_mode = ETH_EXT_FEC_40G_NONE; + break; + case FEC_FORCE_MODE_FIRECODE: + link_params->ext_fec_mode = ETH_EXT_FEC_40G_BASE_R; + break; + case FEC_FORCE_MODE_AUTO: + link_params->ext_fec_mode = ETH_EXT_FEC_40G_BASE_R | + ETH_EXT_FEC_40G_NONE; + break; + default: + break; + } + + break; + case SPEED_50000: + switch (params->fec) { + case FEC_FORCE_MODE_NONE: + link_params->ext_fec_mode = ETH_EXT_FEC_50G_NONE; + break; + case FEC_FORCE_MODE_FIRECODE: + link_params->ext_fec_mode = ETH_EXT_FEC_50G_BASE_R; + break; + case FEC_FORCE_MODE_RS: + link_params->ext_fec_mode = ETH_EXT_FEC_50G_RS528; + break; + case FEC_FORCE_MODE_AUTO: + link_params->ext_fec_mode = ETH_EXT_FEC_50G_RS528 | + ETH_EXT_FEC_50G_BASE_R | + ETH_EXT_FEC_50G_NONE; + break; + default: + break; + } + + break; + case SPEED_100000: + switch (params->fec) { + case FEC_FORCE_MODE_NONE: + link_params->ext_fec_mode = ETH_EXT_FEC_100G_NONE; + break; + case FEC_FORCE_MODE_FIRECODE: + link_params->ext_fec_mode = ETH_EXT_FEC_100G_BASE_R; + break; + case FEC_FORCE_MODE_RS: + link_params->ext_fec_mode = ETH_EXT_FEC_100G_RS528; + break; + case FEC_FORCE_MODE_AUTO: + link_params->ext_fec_mode = ETH_EXT_FEC_100G_RS528 | + ETH_EXT_FEC_100G_BASE_R | + ETH_EXT_FEC_100G_NONE; + break; + default: + break; + } + + break; + default: + break; + } +} + static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params) { struct qed_mcp_link_params *link_params; @@ -1605,6 +1828,9 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params) if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED) speed->forced_speed = params->forced_speed; + if (qed_mcp_is_ext_speed_supported(hwfn)) + qed_set_ext_speed_params(link_params, params); + if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) { if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE) link_params->pause.autoneg = true; @@ -1682,7 +1908,6 @@ static int qed_get_port_type(u32 media_type) case MEDIA_SFP_1G_FIBER: case MEDIA_XFP_FIBER: case MEDIA_MODULE_FIBER: - case MEDIA_KR: port_type = PORT_FIBRE; break; case MEDIA_DA_TWINAX: @@ -1691,6 +1916,7 @@ static int qed_get_port_type(u32 media_type) case MEDIA_BASE_T: port_type = PORT_TP; break; + case MEDIA_KR: case MEDIA_NOT_PRESENT: port_type = PORT_NONE; break; @@ -1990,9 +2216,32 @@ static void qed_fill_link(struct qed_hwfn *hwfn, if (link.link_up) if_link->link_up = true; - /* TODO - at the moment assume supported and advertised speed equal */ - if (link_caps.default_speed_autoneg) - phylink_set(if_link->supported_caps, Autoneg); + if (IS_PF(hwfn->cdev) && qed_mcp_is_ext_speed_supported(hwfn)) { + if (link_caps.default_ext_autoneg) + phylink_set(if_link->supported_caps, Autoneg); + + linkmode_copy(if_link->advertised_caps, if_link->supported_caps); + + if (params.ext_speed.autoneg) + phylink_set(if_link->advertised_caps, Autoneg); + else + phylink_clear(if_link->advertised_caps, Autoneg); + + qed_fill_link_capability(hwfn, ptt, + params.ext_speed.advertised_speeds, + if_link->advertised_caps); + } else { + if (link_caps.default_speed_autoneg) + phylink_set(if_link->supported_caps, Autoneg); + + linkmode_copy(if_link->advertised_caps, if_link->supported_caps); + + if (params.speed.autoneg) + phylink_set(if_link->advertised_caps, Autoneg); + else + phylink_clear(if_link->advertised_caps, Autoneg); + } + if (params.pause.autoneg || (params.pause.forced_rx && params.pause.forced_tx)) phylink_set(if_link->supported_caps, Asym_Pause); @@ -2000,13 +2249,6 @@ static void qed_fill_link(struct qed_hwfn *hwfn, params.pause.forced_tx) phylink_set(if_link->supported_caps, Pause); - linkmode_copy(if_link->advertised_caps, if_link->supported_caps); - - if (params.speed.autoneg) - phylink_set(if_link->advertised_caps, Autoneg); - else - phylink_clear(if_link->advertised_caps, Autoneg); - if_link->sup_fec = link_caps.fec_default; if_link->active_fec = params.fec; diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index 78c0d3a2d164..988d84564849 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -1476,6 +1476,7 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up) struct qed_mcp_mb_params mb_params; struct eth_phy_cfg phy_cfg; u32 cmd, fec_bit = 0; + u32 val, ext_speed; int rc = 0; /* Set the shmem configuration according to params */ @@ -1522,16 +1523,77 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up) SET_MFW_FIELD(phy_cfg.fec_mode, FEC_FORCE_MODE, fec_bit); } + if (p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL) { + ext_speed = 0; + if (params->ext_speed.autoneg) + ext_speed |= ETH_EXT_SPEED_AN; + + val = params->ext_speed.forced_speed; + if (val & QED_EXT_SPEED_1G) + ext_speed |= ETH_EXT_SPEED_1G; + if (val & QED_EXT_SPEED_10G) + ext_speed |= ETH_EXT_SPEED_10G; + if (val & QED_EXT_SPEED_20G) + ext_speed |= ETH_EXT_SPEED_20G; + if (val & QED_EXT_SPEED_25G) + ext_speed |= ETH_EXT_SPEED_25G; + if (val & QED_EXT_SPEED_40G) + ext_speed |= ETH_EXT_SPEED_40G; + if (val & QED_EXT_SPEED_50G_R) + ext_speed |= ETH_EXT_SPEED_50G_BASE_R; + if (val & QED_EXT_SPEED_50G_R2) + ext_speed |= ETH_EXT_SPEED_50G_BASE_R2; + if (val & QED_EXT_SPEED_100G_R2) + ext_speed |= ETH_EXT_SPEED_100G_BASE_R2; + if (val & QED_EXT_SPEED_100G_R4) + ext_speed |= ETH_EXT_SPEED_100G_BASE_R4; + if (val & QED_EXT_SPEED_100G_P4) + ext_speed |= ETH_EXT_SPEED_100G_BASE_P4; + + SET_MFW_FIELD(phy_cfg.extended_speed, ETH_EXT_SPEED, + ext_speed); + + ext_speed = 0; + + val = params->ext_speed.advertised_speeds; + if (val & QED_EXT_SPEED_MASK_1G) + ext_speed |= ETH_EXT_ADV_SPEED_1G; + if (val & QED_EXT_SPEED_MASK_10G) + ext_speed |= ETH_EXT_ADV_SPEED_10G; + if (val & QED_EXT_SPEED_MASK_20G) + ext_speed |= ETH_EXT_ADV_SPEED_20G; + if (val & QED_EXT_SPEED_MASK_25G) + ext_speed |= ETH_EXT_ADV_SPEED_25G; + if (val & QED_EXT_SPEED_MASK_40G) + ext_speed |= ETH_EXT_ADV_SPEED_40G; + if (val & QED_EXT_SPEED_MASK_50G_R) + ext_speed |= ETH_EXT_ADV_SPEED_50G_BASE_R; + if (val & QED_EXT_SPEED_MASK_50G_R2) + ext_speed |= ETH_EXT_ADV_SPEED_50G_BASE_R2; + if (val & QED_EXT_SPEED_MASK_100G_R2) + ext_speed |= ETH_EXT_ADV_SPEED_100G_BASE_R2; + if (val & QED_EXT_SPEED_MASK_100G_R4) + ext_speed |= ETH_EXT_ADV_SPEED_100G_BASE_R4; + if (val & QED_EXT_SPEED_MASK_100G_P4) + ext_speed |= ETH_EXT_ADV_SPEED_100G_BASE_P4; + + phy_cfg.extended_speed |= ext_speed; + + SET_MFW_FIELD(phy_cfg.fec_mode, FEC_EXTENDED_MODE, + params->ext_fec_mode); + } + p_hwfn->b_drv_link_init = b_up; if (b_up) { DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, - "Configuring Link: Speed 0x%08x, Pause 0x%08x, adv_speed 0x%08x, loopback 0x%08x, FEC 0x%08x\n", + "Configuring Link: Speed 0x%08x, Pause 0x%08x, Adv. Speed 0x%08x, Loopback 0x%08x, FEC 0x%08x, Ext. Speed 0x%08x\n", phy_cfg.speed, phy_cfg.pause, phy_cfg.adv_speed, - phy_cfg.loopback_mode, phy_cfg.fec_mode); + phy_cfg.loopback_mode, phy_cfg.fec_mode, + phy_cfg.extended_speed); } else { - DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, - "Resetting link\n"); + DP_VERBOSE(p_hwfn, NETIF_MSG_LINK, "Resetting link\n"); } memset(&mb_params, 0, sizeof(mb_params)); @@ -3838,6 +3900,10 @@ int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt) DRV_MB_PARAM_FEATURE_SUPPORT_FUNC_VLINK | DRV_MB_PARAM_FEATURE_SUPPORT_PORT_FEC_CONTROL; + if (QED_IS_E5(p_hwfn->cdev)) + features |= + DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EXT_SPEED_FEC_CONTROL; + return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_FEATURE_SUPPORT, features, &mcp_resp, &mcp_param); } diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h index ea956c43e596..8edb450d0abf 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h @@ -17,8 +17,31 @@ struct qed_mcp_link_speed_params { bool autoneg; + u32 advertised_speeds; +#define QED_EXT_SPEED_MASK_RES 0x1 +#define QED_EXT_SPEED_MASK_1G 0x2 +#define QED_EXT_SPEED_MASK_10G 0x4 +#define QED_EXT_SPEED_MASK_20G 0x8 +#define QED_EXT_SPEED_MASK_25G 0x10 +#define QED_EXT_SPEED_MASK_40G 0x20 +#define QED_EXT_SPEED_MASK_50G_R 0x40 +#define QED_EXT_SPEED_MASK_50G_R2 0x80 +#define QED_EXT_SPEED_MASK_100G_R2 0x100 +#define QED_EXT_SPEED_MASK_100G_R4 0x200 +#define QED_EXT_SPEED_MASK_100G_P4 0x400 + u32 forced_speed; /* In Mb/s */ +#define QED_EXT_SPEED_1G 0x1 +#define QED_EXT_SPEED_10G 0x2 +#define QED_EXT_SPEED_20G 0x4 +#define QED_EXT_SPEED_25G 0x8 +#define QED_EXT_SPEED_40G 0x10 +#define QED_EXT_SPEED_50G_R 0x20 +#define QED_EXT_SPEED_50G_R2 0x40 +#define QED_EXT_SPEED_100G_R2 0x80 +#define QED_EXT_SPEED_100G_R4 0x100 +#define QED_EXT_SPEED_100G_P4 0x200 }; struct qed_mcp_link_pause_params { @@ -39,6 +62,9 @@ struct qed_mcp_link_params { u32 loopback_mode; struct qed_link_eee_params eee; u32 fec; + + struct qed_mcp_link_speed_params ext_speed; + u32 ext_fec_mode; }; struct qed_mcp_link_capabilities { @@ -48,6 +74,11 @@ struct qed_mcp_link_capabilities { enum qed_mcp_eee_mode default_eee; u32 eee_lpi_timer; u8 eee_speed_caps; + + u32 default_ext_speed_caps; + u32 default_ext_autoneg; + u32 default_ext_speed; + u32 default_ext_fec; }; struct qed_mcp_link_state { @@ -750,6 +781,20 @@ struct qed_drv_tlv_hdr { u8 tlv_flags; }; +/** + * qed_mcp_is_ext_speed_supported() - Check if management firmware supports + * extended speeds. + * @p_hwfn: HW device data. + * + * Return: true if supported, false otherwise. + */ +static inline bool +qed_mcp_is_ext_speed_supported(const struct qed_hwfn *p_hwfn) +{ + return !!(p_hwfn->mcp_info->capabilities & + FW_MB_PARAM_FEATURE_SUPPORT_EXT_SPEED_FEC_CONTROL); +} + /** * @brief Initialize the interface with the MCP * diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h index 2e780159a5fb..a5c6854343e6 100644 --- a/include/linux/qed/qed_if.h +++ b/include/linux/qed/qed_if.h @@ -594,6 +594,7 @@ enum qed_hw_err_type { enum qed_dev_type { QED_DEV_TYPE_BB, QED_DEV_TYPE_AH, + QED_DEV_TYPE_E5, }; struct qed_dev_info { -- cgit v1.2.3-71-gd317