2020-07-16 11:56:30

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 00/13] qed/qede: add support for new operating modes

This series covers the support for the following:
- new port modes;
- loopback modes, previously missing;
- new speed/link modes;
- several FEC modes;
- multi-rate transceivers;

and also cleans up and optimizes several related parts of code.

Alexander Lobakin (13):
qed: convert link mode from u32 to bitmap
qed: reformat public_port::transceiver_data a bit
qed: add support for multi-rate transceivers
qed: use transceiver data to fill link partner's advertising speeds
qed: reformat several structures a bit
qed: add support for Forward Error Correction
qede: format qede{,_vf}_ethtool_ops
qede: introduce support for FEC control
qed: reformat several structures a bit
qed: add support for new port modes
qed: add missing loopback modes
qed: populate supported link modes maps on module init
qed/qede: add support for the extended speed and FEC modes

drivers/net/ethernet/qlogic/qed/qed.h | 68 +-
drivers/net/ethernet/qlogic/qed/qed_dev.c | 161 +++-
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 786 ++++++++++--------
drivers/net/ethernet/qlogic/qed/qed_main.c | 757 +++++++++++++----
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 126 ++-
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 146 ++--
.../net/ethernet/qlogic/qede/qede_ethtool.c | 468 ++++++-----
drivers/scsi/qedf/qedf_main.c | 77 +-
include/linux/qed/qed_if.h | 185 +++--
9 files changed, 1863 insertions(+), 911 deletions(-)

--

Dave, patch #0001 affects qedf under scsi tree, but could you take it
through yours? It will break incremental buildability and bisecting
otherwise. Thanks.

--
2.25.1


2020-07-16 11:56:57

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 01/13] qed: convert link mode from u32 to bitmap

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 link mode to bitmap that will always have enough space for
any number of speeds and modes.

This involves changes in qede and qedf as well, as they use definitions
from shared "qed_if.h".

Misc: add build-time check that qed_lm_map[] is always synchronized with
enum qed_link_mode_bits.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
drivers/net/ethernet/qlogic/qed/qed_main.c | 287 ++++++++++--------
.../net/ethernet/qlogic/qede/qede_ethtool.c | 247 +++++++--------
drivers/scsi/qedf/qedf_main.c | 77 +++--
include/linux/qed/qed_if.h | 90 +++---
4 files changed, 374 insertions(+), 327 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 4c5f5bd91359..8a0b8da19547 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1456,10 +1456,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;
struct qed_mcp_link_params *link_params;
+ QED_LM_DECLARE(sup_caps);
+ struct qed_hwfn *hwfn;
struct qed_ptt *ptt;
- u32 sup_caps;
+ u32 as;
int rc;

if (!cdev)
@@ -1482,57 +1483,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;
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_1000baseT_Full, sup_caps);
+ __set_bit(QED_LM_1000baseKX_Full, sup_caps);
+ __set_bit(QED_LM_1000baseX_Full, sup_caps);
+
+ if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
+ as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_10000baseT_Full, sup_caps);
+ __set_bit(QED_LM_10000baseKR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseKX4_Full, sup_caps);
+ __set_bit(QED_LM_10000baseR_FEC, sup_caps);
+ __set_bit(QED_LM_10000baseCR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseSR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseLR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseLRM_Full, sup_caps);
+
+ if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
+ as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_20000baseKR2_Full, sup_caps);
+
+ if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
+ as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G;
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_25000baseKR_Full, sup_caps);
+ __set_bit(QED_LM_25000baseCR_Full, sup_caps);
+ __set_bit(QED_LM_25000baseSR_Full, sup_caps);
+
+ if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
+ as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_40000baseLR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseKR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseCR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseSR4_Full, sup_caps);
+
+ if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
+ as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_50000baseKR2_Full, sup_caps);
+ __set_bit(QED_LM_50000baseCR2_Full, sup_caps);
+ __set_bit(QED_LM_50000baseSR2_Full, sup_caps);
+
+ if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
+ as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G;
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_100000baseKR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseSR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseCR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseLR4_ER4_Full, sup_caps);
+
+ if (qed_link_mode_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 +1667,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 +1690,117 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,

switch (media_type) {
case MEDIA_DA_TWINAX:
- *if_capability |= QED_LM_FIBRE_BIT;
+ __set_bit(QED_LM_FIBRE, if_caps);
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
- *if_capability |= QED_LM_20000baseKR2_Full_BIT;
+ __set_bit(QED_LM_20000baseKR2_Full, if_caps);
+
/* 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;
+ __set_bit(QED_LM_1000baseKX_Full, if_caps);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
- *if_capability |= QED_LM_10000baseCR_Full_BIT;
+ __set_bit(QED_LM_10000baseCR_Full, if_caps);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
- *if_capability |= QED_LM_40000baseCR4_Full_BIT;
+ __set_bit(QED_LM_40000baseCR4_Full, if_caps);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
- *if_capability |= QED_LM_25000baseCR_Full_BIT;
+ __set_bit(QED_LM_25000baseCR_Full, if_caps);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
- *if_capability |= QED_LM_50000baseCR2_Full_BIT;
+ __set_bit(QED_LM_50000baseCR2_Full, if_caps);
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)
+ __set_bit(QED_LM_100000baseCR4_Full, if_caps);
+
break;
case MEDIA_BASE_T:
- *if_capability |= QED_LM_TP_BIT;
+ __set_bit(QED_LM_TP, if_caps);
+
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)
+ __set_bit(QED_LM_1000baseT_Full, if_caps);
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)
+ __set_bit(QED_LM_10000baseT_Full, if_caps);
}
+
if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) {
- *if_capability |= QED_LM_FIBRE_BIT;
+ __set_bit(QED_LM_FIBRE, if_caps);
+
if (tcvr_type == ETH_TRANSCEIVER_TYPE_1000BASET)
- *if_capability |= QED_LM_1000baseT_Full_BIT;
+ __set_bit(QED_LM_1000baseT_Full, if_caps);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_BASET)
- *if_capability |= QED_LM_10000baseT_Full_BIT;
+ __set_bit(QED_LM_10000baseT_Full, if_caps);
}
+
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) {
+ __set_bit(QED_LM_FIBRE, if_caps);
+
+ 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;
+ __set_bit(QED_LM_1000baseKX_Full, if_caps);
}
- 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;
+ __set_bit(QED_LM_10000baseSR_Full, if_caps);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LR)
- *if_capability |= QED_LM_10000baseLR_Full_BIT;
+ __set_bit(QED_LM_10000baseLR_Full, if_caps);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LRM)
- *if_capability |= QED_LM_10000baseLRM_Full_BIT;
+ __set_bit(QED_LM_10000baseLRM_Full, if_caps);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_ER)
- *if_capability |= QED_LM_10000baseR_FEC_BIT;
+ __set_bit(QED_LM_10000baseR_FEC, if_caps);
}
+
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) {
+ __set_bit(QED_LM_20000baseKR2_Full, if_caps);
+
+ 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;
+ __set_bit(QED_LM_25000baseSR_Full, if_caps);
}
- 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;
+ __set_bit(QED_LM_40000baseLR4_Full, if_caps);
if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_SR4)
- *if_capability |= QED_LM_40000baseSR4_Full_BIT;
+ __set_bit(QED_LM_40000baseSR4_Full, if_caps);
}
- 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)
+ __set_bit(QED_LM_50000baseKR2_Full, if_caps);
+
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;
+ __set_bit(QED_LM_100000baseSR4_Full, if_caps);
}

break;
case MEDIA_KR:
- *if_capability |= QED_LM_Backplane_BIT;
+ __set_bit(QED_LM_Backplane, if_caps);
+
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;
+ __set_bit(QED_LM_20000baseKR2_Full, if_caps);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
+ __set_bit(QED_LM_1000baseKX_Full, if_caps);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
+ __set_bit(QED_LM_10000baseKR_Full, if_caps);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
+ __set_bit(QED_LM_25000baseKR_Full, if_caps);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
+ __set_bit(QED_LM_40000baseKR4_Full, if_caps);
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
+ __set_bit(QED_LM_50000baseKR2_Full, if_caps);
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
- *if_capability |= QED_LM_100000baseKR4_Full_BIT;
+ __set_bit(QED_LM_100000baseKR4_Full, if_caps);
+
break;
case MEDIA_UNSPECIFIED:
case MEDIA_NOT_PRESENT:
@@ -1806,26 +1833,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;
+ __set_bit(QED_LM_Autoneg, if_link->supported_caps);
if (params.pause.autoneg ||
(params.pause.forced_rx && params.pause.forced_tx))
- if_link->supported_caps |= QED_LM_Asym_Pause_BIT;
+ __set_bit(QED_LM_Asym_Pause, if_link->supported_caps);
if (params.pause.autoneg || params.pause.forced_rx ||
params.pause.forced_tx)
- if_link->supported_caps |= QED_LM_Pause_BIT;
+ __set_bit(QED_LM_Pause, if_link->supported_caps);
+
+ qed_link_mode_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;
+ __set_bit(QED_LM_Autoneg, if_link->advertised_caps);
else
- if_link->advertised_caps &= ~QED_LM_Autoneg_BIT;
+ __clear_bit(QED_LM_Autoneg, if_link->advertised_caps);

/* 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 +1873,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)
+ __set_bit(QED_LM_1000baseT_Full, if_link->lp_caps);
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_10G)
- if_link->lp_caps |= QED_LM_10000baseKR_Full_BIT;
+ __set_bit(QED_LM_10000baseKR_Full, if_link->lp_caps);
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_20G)
- if_link->lp_caps |= QED_LM_20000baseKR2_Full_BIT;
+ __set_bit(QED_LM_20000baseKR2_Full, if_link->lp_caps);
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_25G)
- if_link->lp_caps |= QED_LM_25000baseKR_Full_BIT;
+ __set_bit(QED_LM_25000baseKR_Full, if_link->lp_caps);
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_40G)
- if_link->lp_caps |= QED_LM_40000baseLR4_Full_BIT;
+ __set_bit(QED_LM_40000baseLR4_Full, if_link->lp_caps);
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_50G)
- if_link->lp_caps |= QED_LM_50000baseKR2_Full_BIT;
+ __set_bit(QED_LM_50000baseKR2_Full, if_link->lp_caps);
if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_100G)
- if_link->lp_caps |= QED_LM_100000baseKR4_Full_BIT;
+ __set_bit(QED_LM_100000baseKR4_Full, if_link->lp_caps);

if (link.an_complete)
- if_link->lp_caps |= QED_LM_Autoneg_BIT;
-
+ __set_bit(QED_LM_Autoneg, if_link->lp_caps);
if (link.partner_adv_pause)
- if_link->lp_caps |= QED_LM_Pause_BIT;
+ __set_bit(QED_LM_Pause, if_link->lp_caps);
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;
+ __set_bit(QED_LM_Asym_Pause, if_link->lp_caps);

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..f47167cfa382 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -419,75 +419,78 @@ static int qede_set_priv_flags(struct net_device *dev, u32 flags)
}

struct qede_link_mode_mapping {
- u32 qed_link_mode;
- u32 ethtool_link_mode;
+ u32 qed_link_mode;
+ u32 ethtool_link_mode;
};

+#define QEDE_ETHTOOL_LM_MAP(mode) \
+{ \
+ .qed_link_mode = QED_LM_##mode, \
+ .ethtool_link_mode = ETHTOOL_LINK_MODE_##mode##_BIT, \
+}
+
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},
+ QEDE_ETHTOOL_LM_MAP(FIBRE),
+ QEDE_ETHTOOL_LM_MAP(Autoneg),
+ QEDE_ETHTOOL_LM_MAP(Asym_Pause),
+ QEDE_ETHTOOL_LM_MAP(Pause),
+ QEDE_ETHTOOL_LM_MAP(1000baseT_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseT_Full),
+ QEDE_ETHTOOL_LM_MAP(TP),
+ QEDE_ETHTOOL_LM_MAP(Backplane),
+ QEDE_ETHTOOL_LM_MAP(1000baseKX_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseKX4_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseKR_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseR_FEC),
+ QEDE_ETHTOOL_LM_MAP(20000baseKR2_Full),
+ QEDE_ETHTOOL_LM_MAP(40000baseKR4_Full),
+ QEDE_ETHTOOL_LM_MAP(40000baseCR4_Full),
+ QEDE_ETHTOOL_LM_MAP(40000baseSR4_Full),
+ QEDE_ETHTOOL_LM_MAP(40000baseLR4_Full),
+ QEDE_ETHTOOL_LM_MAP(25000baseCR_Full),
+ QEDE_ETHTOOL_LM_MAP(25000baseKR_Full),
+ QEDE_ETHTOOL_LM_MAP(25000baseSR_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseCR2_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseKR2_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseKR4_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseSR4_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseCR4_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseLR4_ER4_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseSR2_Full),
+ QEDE_ETHTOOL_LM_MAP(1000baseX_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseCR_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseSR_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseLR_Full),
+ QEDE_ETHTOOL_LM_MAP(10000baseLRM_Full),
};

-#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); \
- } \
+static_assert(ARRAY_SIZE(qed_lm_map) == QED_LM_COUNT);
+
+static void qede_drv_to_ethtool_caps(const unsigned long *qed_caps,
+ unsigned long *ethtool_caps)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++)
+ if (test_bit(qed_lm_map[i].qed_link_mode, qed_caps))
+ __set_bit(qed_lm_map[i].ethtool_link_mode,
+ ethtool_caps);
}

-#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 void qede_ethtool_to_drv_caps(unsigned long *qed_caps,
+ const unsigned long *ethtool_caps)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(qed_lm_map); i++)
+ if (test_bit(qed_lm_map[i].ethtool_link_mode, ethtool_caps))
+ __set_bit(qed_lm_map[i].qed_link_mode, qed_caps);
}

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;
@@ -498,13 +501,16 @@ static int qede_get_link_ksettings(struct net_device *dev,
edev->ops->common->get_link(edev->cdev, &current_link);

ethtool_link_ksettings_zero_link_mode(cmd, supported);
- QEDE_DRV_TO_ETHTOOL_CAPS(current_link.supported_caps, cmd, supported)
+ qede_drv_to_ethtool_caps(current_link.supported_caps,
+ link_modes->supported);

ethtool_link_ksettings_zero_link_mode(cmd, advertising);
- QEDE_DRV_TO_ETHTOOL_CAPS(current_link.advertised_caps, cmd, advertising)
+ qede_drv_to_ethtool_caps(current_link.advertised_caps,
+ link_modes->advertising);

ethtool_link_ksettings_zero_link_mode(cmd, lp_advertising);
- QEDE_DRV_TO_ETHTOOL_CAPS(current_link.lp_caps, cmd, lp_advertising)
+ qede_drv_to_ethtool_caps(current_link.lp_caps,
+ link_modes->lp_advertising);

if ((edev->state == QEDE_STATE_OPEN) && (current_link.link_up)) {
base->speed = current_link.speed;
@@ -530,7 +536,7 @@ static int qede_set_link_ksettings(struct net_device *dev,
struct qede_dev *edev = netdev_priv(dev);
struct qed_link_output current_link;
struct qed_link_params params;
- u32 sup_caps;
+ QED_LM_DECLARE(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 +548,81 @@ 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 (!test_bit(QED_LM_Autoneg, current_link.supported_caps)) {
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)
+
+ qede_ethtool_to_drv_caps(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;
+
+ qed_link_mode_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;
+ __set_bit(QED_LM_1000baseT_Full, sup_caps);
+ __set_bit(QED_LM_1000baseKX_Full, sup_caps);
+ __set_bit(QED_LM_1000baseX_Full, sup_caps);
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;
+ __set_bit(QED_LM_10000baseT_Full, sup_caps);
+ __set_bit(QED_LM_10000baseKR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseKX4_Full, sup_caps);
+ __set_bit(QED_LM_10000baseR_FEC, sup_caps);
+ __set_bit(QED_LM_10000baseCR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseSR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseLR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseLRM_Full, sup_caps);
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;
+ __set_bit(QED_LM_20000baseKR2_Full, sup_caps);
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;
+ __set_bit(QED_LM_25000baseKR_Full, sup_caps);
+ __set_bit(QED_LM_25000baseCR_Full, sup_caps);
+ __set_bit(QED_LM_25000baseSR_Full, sup_caps);
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;
+ __set_bit(QED_LM_40000baseLR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseKR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseCR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseSR4_Full, sup_caps);
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;
+ __set_bit(QED_LM_50000baseKR2_Full, sup_caps);
+ __set_bit(QED_LM_50000baseCR2_Full, sup_caps);
+ __set_bit(QED_LM_50000baseSR2_Full, sup_caps);
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;
+ __set_bit(QED_LM_100000baseKR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseSR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseCR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseLR4_ER4_Full, sup_caps);
break;
default:
DP_INFO(edev, "Unsupported speed %u\n", base->speed);
return -EINVAL;
}
+
+ if (!qed_link_mode_intersects(current_link.supported_caps,
+ sup_caps)) {
+ DP_INFO(edev, "%uG speed not supported\n",
+ base->speed / 1000);
+ return -EINVAL;
+ }
+
+ qed_link_mode_and(params.adv_speeds,
+ current_link.supported_caps,
+ sup_caps);
}

params.link_up = true;
@@ -1006,13 +988,16 @@ static int qede_set_pauseparam(struct net_device *dev,

memset(&params, 0, sizeof(params));
params.override_flags |= QED_LINK_OVERRIDE_PAUSE_CONFIG;
+
if (epause->autoneg) {
- if (!(current_link.supported_caps & QED_LM_Autoneg_BIT)) {
+ if (!test_bit(QED_LM_Autoneg, current_link.supported_caps)) {
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..4f4f786f3710 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -441,6 +441,7 @@ static void qedf_update_link_speed(struct qedf_ctx *qedf,
struct qed_link_output *link)
{
struct fc_lport *lport = qedf->lport;
+ QED_LM_DECLARE(sup_caps);

lport->link_speed = FC_PORTSPEED_UNKNOWN;
lport->link_supported_speeds = FC_PORTSPEED_UNKNOWN;
@@ -474,40 +475,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)) {
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_10000baseT_Full, sup_caps);
+ __set_bit(QED_LM_10000baseKX4_Full, sup_caps);
+ __set_bit(QED_LM_10000baseR_FEC, sup_caps);
+ __set_bit(QED_LM_10000baseCR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseSR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseLR_Full, sup_caps);
+ __set_bit(QED_LM_10000baseLRM_Full, sup_caps);
+ __set_bit(QED_LM_10000baseKR_Full, sup_caps);
+
+ if (qed_link_mode_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)) {
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_25000baseKR_Full, sup_caps);
+ __set_bit(QED_LM_25000baseCR_Full, sup_caps);
+ __set_bit(QED_LM_25000baseSR_Full, sup_caps);
+
+ if (qed_link_mode_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)) {
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_40000baseLR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseKR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseCR4_Full, sup_caps);
+ __set_bit(QED_LM_40000baseSR4_Full, sup_caps);
+
+ if (qed_link_mode_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)) {
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_50000baseKR2_Full, sup_caps);
+ __set_bit(QED_LM_50000baseCR2_Full, sup_caps);
+ __set_bit(QED_LM_50000baseSR2_Full, sup_caps);
+
+ if (qed_link_mode_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)) {
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_100000baseKR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseSR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseCR4_Full, sup_caps);
+ __set_bit(QED_LM_100000baseLR4_ER4_Full, sup_caps);
+
+ if (qed_link_mode_intersects(link->supported_caps, sup_caps))
lport->link_supported_speeds |= FC_PORTSPEED_100GBIT;
- }
- if (link->supported_caps & QED_LM_20000baseKR2_Full_BIT)
+
+ qed_link_mode_zero(sup_caps);
+ __set_bit(QED_LM_20000baseKR2_Full, sup_caps);
+
+ if (qed_link_mode_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..a039f8519829 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -662,41 +662,54 @@ enum qed_protocol {
};

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
+ QED_LM_FIBRE,
+ QED_LM_Autoneg,
+ QED_LM_Asym_Pause,
+ QED_LM_Pause,
+ QED_LM_1000baseT_Full,
+ QED_LM_10000baseT_Full,
+ QED_LM_10000baseKR_Full,
+ QED_LM_20000baseKR2_Full,
+ QED_LM_25000baseKR_Full,
+ QED_LM_40000baseLR4_Full,
+ QED_LM_50000baseKR2_Full,
+ QED_LM_100000baseKR4_Full,
+ QED_LM_TP,
+ QED_LM_Backplane,
+ QED_LM_1000baseKX_Full,
+ QED_LM_10000baseKX4_Full,
+ QED_LM_10000baseR_FEC,
+ QED_LM_40000baseKR4_Full,
+ QED_LM_40000baseCR4_Full,
+ QED_LM_40000baseSR4_Full,
+ QED_LM_25000baseCR_Full,
+ QED_LM_25000baseSR_Full,
+ QED_LM_50000baseCR2_Full,
+ QED_LM_100000baseSR4_Full,
+ QED_LM_100000baseCR4_Full,
+ QED_LM_100000baseLR4_ER4_Full,
+ QED_LM_50000baseSR2_Full,
+ QED_LM_1000baseX_Full,
+ QED_LM_10000baseCR_Full,
+ QED_LM_10000baseSR_Full,
+ QED_LM_10000baseLR_Full,
+ QED_LM_10000baseLRM_Full,
+ QED_LM_COUNT,
};

+#define QED_LM_DECLARE(lm) DECLARE_BITMAP((lm), \
+ QED_LM_COUNT)
+
+#define qed_link_mode_zero(lm) bitmap_zero((lm), QED_LM_COUNT)
+#define qed_link_mode_copy(dst, src) bitmap_copy((dst), (src), \
+ QED_LM_COUNT)
+#define qed_link_mode_and(dst, src1, src2) bitmap_and((dst), \
+ (src1), (src2), \
+ QED_LM_COUNT)
+#define qed_link_mode_intersects(lm1, lm2) bitmap_intersects((lm1), \
+ (lm2), \
+ QED_LM_COUNT)
+
struct qed_link_params {
bool link_up;

@@ -708,7 +721,9 @@ struct qed_link_params {
#define QED_LINK_OVERRIDE_EEE_CONFIG BIT(5)
u32 override_flags;
bool autoneg;
- u32 adv_speeds;
+
+ QED_LM_DECLARE(adv_speeds);
+
u32 forced_speed;
#define QED_LINK_PAUSE_AUTONEG_ENABLE BIT(0)
#define QED_LINK_PAUSE_RX_ENABLE BIT(1)
@@ -726,10 +741,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;
+ QED_LM_DECLARE(supported_caps);
+ QED_LM_DECLARE(advertised_caps);
+ QED_LM_DECLARE(lp_caps);

u32 speed; /* In Mb/s */
u8 duplex; /* In DUPLEX defs */
--
2.25.1

2020-07-16 11:57:42

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 10/13] qed: add support for new port modes

These ports ship on new boards revisions and are supported by newer
firmware versions.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
drivers/net/ethernet/qlogic/qed/qed.h | 5 +++++
drivers/net/ethernet/qlogic/qed/qed_dev.c | 15 +++++++++++++++
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 5 +++++
3 files changed, 25 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 6a1d12da7910..63fcbd5a295a 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -257,6 +257,11 @@ enum QED_PORT_MODE {
QED_PORT_MODE_DE_1X25G,
QED_PORT_MODE_DE_4X25G,
QED_PORT_MODE_DE_2X10G,
+ QED_PORT_MODE_DE_2X50G_R1,
+ QED_PORT_MODE_DE_4X50G_R1,
+ QED_PORT_MODE_DE_1X100G_R2,
+ QED_PORT_MODE_DE_2X100G_R2,
+ QED_PORT_MODE_DE_1X100G_R4,
};

enum qed_dev_cap {
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index d929556247a5..4bad836d0f74 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -4026,6 +4026,21 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G:
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X25G;
break;
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1:
+ p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X50G_R1;
+ break;
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1:
+ p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X50G_R1;
+ break;
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2:
+ p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G_R2;
+ break;
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2:
+ p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X100G_R2;
+ break;
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4:
+ p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G_R4;
+ break;
default:
DP_NOTICE(p_hwfn, "Unknown port mode in 0x%08x\n", core_cfg);
break;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index a4a845579fd2..debc55923251 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -13015,6 +13015,11 @@ struct nvm_cfg1_glob {
#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G 0xd
#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G 0xe
#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G 0xf
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1 0x11
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1 0x12
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2 0x13
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2 0x14
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4 0x15

u32 e_lane_cfg1;
u32 e_lane_cfg2;
--
2.25.1

2020-07-16 11:57:50

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 12/13] qed: populate supported link modes maps on module init

Simplify and lighten qed_set_link() by declaring static link modes maps
and populating them on module init. This way we save plenty of text size
at the low expense of __ro_after_init and __initconst data (the latter
will be purged after module init is done).

Misc: sanitize exit callback.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
drivers/net/ethernet/qlogic/qed/qed_main.c | 194 +++++++++++++--------
1 file changed, 123 insertions(+), 71 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index ff8e41694f65..28f13cd7bd9b 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -64,20 +64,122 @@ MODULE_VERSION(DRV_MODULE_VERSION);

MODULE_FIRMWARE(QED_FW_FILE_NAME);

+/* MFW speed capabilities maps */
+
+struct qed_mfw_speed_map {
+ u32 mfw_val;
+
+ QED_LM_DECLARE(caps);
+
+ const u32 *cap_arr;
+ u32 arr_size;
+};
+
+#define QED_MFW_SPEED_MAP(type, arr) \
+{ \
+ .mfw_val = (type), \
+ .cap_arr = (arr), \
+ .arr_size = ARRAY_SIZE(arr), \
+}
+
+static const u32 qed_mfw_legacy_1g[] __initconst = {
+ QED_LM_1000baseT_Full,
+ QED_LM_1000baseKX_Full,
+ QED_LM_1000baseX_Full,
+};
+
+static const u32 qed_mfw_legacy_10g[] __initconst = {
+ QED_LM_10000baseT_Full,
+ QED_LM_10000baseKR_Full,
+ QED_LM_10000baseKX4_Full,
+ QED_LM_10000baseR_FEC,
+ QED_LM_10000baseCR_Full,
+ QED_LM_10000baseSR_Full,
+ QED_LM_10000baseLR_Full,
+ QED_LM_10000baseLRM_Full,
+};
+
+static const u32 qed_mfw_legacy_20g[] __initconst = {
+ QED_LM_20000baseKR2_Full,
+};
+
+static const u32 qed_mfw_legacy_25g[] __initconst = {
+ QED_LM_25000baseKR_Full,
+ QED_LM_25000baseCR_Full,
+ QED_LM_25000baseSR_Full,
+};
+
+static const u32 qed_mfw_legacy_40g[] __initconst = {
+ QED_LM_40000baseLR4_Full,
+ QED_LM_40000baseKR4_Full,
+ QED_LM_40000baseCR4_Full,
+ QED_LM_40000baseSR4_Full,
+};
+
+static const u32 qed_mfw_legacy_50g[] __initconst = {
+ QED_LM_50000baseKR2_Full,
+ QED_LM_50000baseCR2_Full,
+ QED_LM_50000baseSR2_Full,
+};
+
+static const u32 qed_mfw_legacy_bb_100g[] __initconst = {
+ QED_LM_100000baseKR4_Full,
+ QED_LM_100000baseSR4_Full,
+ QED_LM_100000baseCR4_Full,
+ QED_LM_100000baseLR4_ER4_Full,
+};
+
+static struct qed_mfw_speed_map qed_mfw_legacy_maps[] __ro_after_init = {
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G,
+ qed_mfw_legacy_1g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G,
+ qed_mfw_legacy_10g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G,
+ qed_mfw_legacy_20g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G,
+ qed_mfw_legacy_25g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G,
+ qed_mfw_legacy_40g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G,
+ qed_mfw_legacy_50g),
+ QED_MFW_SPEED_MAP(NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G,
+ qed_mfw_legacy_bb_100g),
+};
+
+static void __init qed_mfw_speed_map_populate(struct qed_mfw_speed_map *map)
+{
+ u32 i;
+
+ for (i = 0; i < map->arr_size; i++)
+ __set_bit(map->cap_arr[i], map->caps);
+
+ map->cap_arr = NULL;
+ map->arr_size = 0;
+}
+
+static void __init qed_mfw_speed_maps_init(void)
+{
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_legacy_maps); i++)
+ qed_mfw_speed_map_populate(qed_mfw_legacy_maps + i);
+}
+
static int __init qed_init(void)
{
pr_info("%s", version);

+ qed_mfw_speed_maps_init();
+
return 0;
}
+module_init(qed_init);

-static void __exit qed_cleanup(void)
+static void __exit qed_exit(void)
{
- pr_notice("qed_cleanup called\n");
+ /* To prevent marking this module as "permanent" */
}
-
-module_init(qed_init);
-module_exit(qed_cleanup);
+module_exit(qed_exit);

/* Check if the DMA controller on the machine can properly handle the DMA
* addressing required by the device.
@@ -1457,11 +1559,12 @@ 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_mcp_link_params *link_params;
- QED_LM_DECLARE(sup_caps);
+ struct qed_mcp_link_speed_params *speed;
+ const struct qed_mfw_speed_map *map;
struct qed_hwfn *hwfn;
struct qed_ptt *ptt;
- u32 as;
int rc;
+ u32 i;

if (!cdev)
return -ENODEV;
@@ -1486,78 +1589,26 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
if (!link_params)
return -ENODATA;

+ speed = &link_params->speed;
+
if (params->override_flags & QED_LINK_OVERRIDE_SPEED_AUTONEG)
- link_params->speed.autoneg = params->autoneg;
+ speed->autoneg = !!params->autoneg;

if (params->override_flags & QED_LINK_OVERRIDE_SPEED_ADV_SPEEDS) {
- as = 0;
-
- qed_link_mode_zero(sup_caps);
- __set_bit(QED_LM_1000baseT_Full, sup_caps);
- __set_bit(QED_LM_1000baseKX_Full, sup_caps);
- __set_bit(QED_LM_1000baseX_Full, sup_caps);
-
- if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
- as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
-
- qed_link_mode_zero(sup_caps);
- __set_bit(QED_LM_10000baseT_Full, sup_caps);
- __set_bit(QED_LM_10000baseKR_Full, sup_caps);
- __set_bit(QED_LM_10000baseKX4_Full, sup_caps);
- __set_bit(QED_LM_10000baseR_FEC, sup_caps);
- __set_bit(QED_LM_10000baseCR_Full, sup_caps);
- __set_bit(QED_LM_10000baseSR_Full, sup_caps);
- __set_bit(QED_LM_10000baseLR_Full, sup_caps);
- __set_bit(QED_LM_10000baseLRM_Full, sup_caps);
+ speed->advertised_speeds = 0;

- if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
- as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
+ for (i = 0; i < ARRAY_SIZE(qed_mfw_legacy_maps); i++) {
+ map = qed_mfw_legacy_maps + i;

- qed_link_mode_zero(sup_caps);
- __set_bit(QED_LM_20000baseKR2_Full, sup_caps);
-
- if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
- as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G;
-
- qed_link_mode_zero(sup_caps);
- __set_bit(QED_LM_25000baseKR_Full, sup_caps);
- __set_bit(QED_LM_25000baseCR_Full, sup_caps);
- __set_bit(QED_LM_25000baseSR_Full, sup_caps);
-
- if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
- as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
-
- qed_link_mode_zero(sup_caps);
- __set_bit(QED_LM_40000baseLR4_Full, sup_caps);
- __set_bit(QED_LM_40000baseKR4_Full, sup_caps);
- __set_bit(QED_LM_40000baseCR4_Full, sup_caps);
- __set_bit(QED_LM_40000baseSR4_Full, sup_caps);
-
- if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
- as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
-
- qed_link_mode_zero(sup_caps);
- __set_bit(QED_LM_50000baseKR2_Full, sup_caps);
- __set_bit(QED_LM_50000baseCR2_Full, sup_caps);
- __set_bit(QED_LM_50000baseSR2_Full, sup_caps);
-
- if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
- as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G;
-
- qed_link_mode_zero(sup_caps);
- __set_bit(QED_LM_100000baseKR4_Full, sup_caps);
- __set_bit(QED_LM_100000baseSR4_Full, sup_caps);
- __set_bit(QED_LM_100000baseCR4_Full, sup_caps);
- __set_bit(QED_LM_100000baseLR4_ER4_Full, sup_caps);
-
- if (qed_link_mode_intersects(params->adv_speeds, sup_caps))
- as |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G;
-
- link_params->speed.advertised_speeds = as;
+ if (qed_link_mode_intersects(params->adv_speeds,
+ map->caps))
+ speed->advertised_speeds |= map->mfw_val;
+ }
}

if (params->override_flags & QED_LINK_OVERRIDE_SPEED_FORCED_SPEED)
- link_params->speed.forced_speed = params->forced_speed;
+ speed->forced_speed = params->forced_speed;
+
if (params->override_flags & QED_LINK_OVERRIDE_PAUSE_CONFIG) {
if (params->pause_config & QED_LINK_PAUSE_AUTONEG_ENABLE)
link_params->pause.autoneg = true;
@@ -1572,6 +1623,7 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
else
link_params->pause.forced_tx = false;
}
+
if (params->override_flags & QED_LINK_OVERRIDE_LOOPBACK_MODE) {
switch (params->loopback_mode) {
case QED_LINK_LOOPBACK_INT_PHY:
--
2.25.1

2020-07-16 11:57:56

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 11/13] 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 <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
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(+)

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 768d6ab5395f..ff8e41694f65 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1586,6 +1586,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 1b5286d454bf..9edd5de5645d 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -745,6 +745,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;
--
2.25.1

2020-07-16 11:58:27

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 07/13] qede: format qede{,_vf}_ethtool_ops

Prior to adding new callbacks, format qede ethtool_ops structs to make
declarations more fancy and readable.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
.../net/ethernet/qlogic/qede/qede_ethtool.c | 137 +++++++++---------
1 file changed, 68 insertions(+), 69 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index f47167cfa382..f5851a6ae729 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -2059,78 +2059,77 @@ static int qede_get_dump_data(struct net_device *dev,
}

static const struct ethtool_ops qede_ethtool_ops = {
- .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
- .get_link_ksettings = qede_get_link_ksettings,
- .set_link_ksettings = qede_set_link_ksettings,
- .get_drvinfo = qede_get_drvinfo,
- .get_regs_len = qede_get_regs_len,
- .get_regs = qede_get_regs,
- .get_wol = qede_get_wol,
- .set_wol = qede_set_wol,
- .get_msglevel = qede_get_msglevel,
- .set_msglevel = qede_set_msglevel,
- .nway_reset = qede_nway_reset,
- .get_link = qede_get_link,
- .get_coalesce = qede_get_coalesce,
- .set_coalesce = qede_set_coalesce,
- .get_ringparam = qede_get_ringparam,
- .set_ringparam = qede_set_ringparam,
- .get_pauseparam = qede_get_pauseparam,
- .set_pauseparam = qede_set_pauseparam,
- .get_strings = qede_get_strings,
- .set_phys_id = qede_set_phys_id,
- .get_ethtool_stats = qede_get_ethtool_stats,
- .get_priv_flags = qede_get_priv_flags,
- .set_priv_flags = qede_set_priv_flags,
- .get_sset_count = qede_get_sset_count,
- .get_rxnfc = qede_get_rxnfc,
- .set_rxnfc = qede_set_rxnfc,
- .get_rxfh_indir_size = qede_get_rxfh_indir_size,
- .get_rxfh_key_size = qede_get_rxfh_key_size,
- .get_rxfh = qede_get_rxfh,
- .set_rxfh = qede_set_rxfh,
- .get_ts_info = qede_get_ts_info,
- .get_channels = qede_get_channels,
- .set_channels = qede_set_channels,
- .self_test = qede_self_test,
- .get_module_info = qede_get_module_info,
- .get_module_eeprom = qede_get_module_eeprom,
- .get_eee = qede_get_eee,
- .set_eee = qede_set_eee,
-
- .get_tunable = qede_get_tunable,
- .set_tunable = qede_set_tunable,
- .flash_device = qede_flash_device,
- .get_dump_flag = qede_get_dump_flag,
- .get_dump_data = qede_get_dump_data,
- .set_dump = qede_set_dump,
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
+ .get_link_ksettings = qede_get_link_ksettings,
+ .set_link_ksettings = qede_set_link_ksettings,
+ .get_drvinfo = qede_get_drvinfo,
+ .get_regs_len = qede_get_regs_len,
+ .get_regs = qede_get_regs,
+ .get_wol = qede_get_wol,
+ .set_wol = qede_set_wol,
+ .get_msglevel = qede_get_msglevel,
+ .set_msglevel = qede_set_msglevel,
+ .nway_reset = qede_nway_reset,
+ .get_link = qede_get_link,
+ .get_coalesce = qede_get_coalesce,
+ .set_coalesce = qede_set_coalesce,
+ .get_ringparam = qede_get_ringparam,
+ .set_ringparam = qede_set_ringparam,
+ .get_pauseparam = qede_get_pauseparam,
+ .set_pauseparam = qede_set_pauseparam,
+ .get_strings = qede_get_strings,
+ .set_phys_id = qede_set_phys_id,
+ .get_ethtool_stats = qede_get_ethtool_stats,
+ .get_priv_flags = qede_get_priv_flags,
+ .set_priv_flags = qede_set_priv_flags,
+ .get_sset_count = qede_get_sset_count,
+ .get_rxnfc = qede_get_rxnfc,
+ .set_rxnfc = qede_set_rxnfc,
+ .get_rxfh_indir_size = qede_get_rxfh_indir_size,
+ .get_rxfh_key_size = qede_get_rxfh_key_size,
+ .get_rxfh = qede_get_rxfh,
+ .set_rxfh = qede_set_rxfh,
+ .get_ts_info = qede_get_ts_info,
+ .get_channels = qede_get_channels,
+ .set_channels = qede_set_channels,
+ .self_test = qede_self_test,
+ .get_module_info = qede_get_module_info,
+ .get_module_eeprom = qede_get_module_eeprom,
+ .get_eee = qede_get_eee,
+ .set_eee = qede_set_eee,
+ .get_tunable = qede_get_tunable,
+ .set_tunable = qede_set_tunable,
+ .flash_device = qede_flash_device,
+ .get_dump_flag = qede_get_dump_flag,
+ .get_dump_data = qede_get_dump_data,
+ .set_dump = qede_set_dump,
};

static const struct ethtool_ops qede_vf_ethtool_ops = {
- .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
- .get_link_ksettings = qede_get_link_ksettings,
- .get_drvinfo = qede_get_drvinfo,
- .get_msglevel = qede_get_msglevel,
- .set_msglevel = qede_set_msglevel,
- .get_link = qede_get_link,
- .get_coalesce = qede_get_coalesce,
- .set_coalesce = qede_set_coalesce,
- .get_ringparam = qede_get_ringparam,
- .set_ringparam = qede_set_ringparam,
- .get_strings = qede_get_strings,
- .get_ethtool_stats = qede_get_ethtool_stats,
- .get_priv_flags = qede_get_priv_flags,
- .get_sset_count = qede_get_sset_count,
- .get_rxnfc = qede_get_rxnfc,
- .set_rxnfc = qede_set_rxnfc,
- .get_rxfh_indir_size = qede_get_rxfh_indir_size,
- .get_rxfh_key_size = qede_get_rxfh_key_size,
- .get_rxfh = qede_get_rxfh,
- .set_rxfh = qede_set_rxfh,
- .get_channels = qede_get_channels,
- .set_channels = qede_set_channels,
- .get_tunable = qede_get_tunable,
- .set_tunable = qede_set_tunable,
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS,
+ .get_link_ksettings = qede_get_link_ksettings,
+ .get_drvinfo = qede_get_drvinfo,
+ .get_msglevel = qede_get_msglevel,
+ .set_msglevel = qede_set_msglevel,
+ .get_link = qede_get_link,
+ .get_coalesce = qede_get_coalesce,
+ .set_coalesce = qede_set_coalesce,
+ .get_ringparam = qede_get_ringparam,
+ .set_ringparam = qede_set_ringparam,
+ .get_strings = qede_get_strings,
+ .get_ethtool_stats = qede_get_ethtool_stats,
+ .get_priv_flags = qede_get_priv_flags,
+ .get_sset_count = qede_get_sset_count,
+ .get_rxnfc = qede_get_rxnfc,
+ .set_rxnfc = qede_set_rxnfc,
+ .get_rxfh_indir_size = qede_get_rxfh_indir_size,
+ .get_rxfh_key_size = qede_get_rxfh_key_size,
+ .get_rxfh = qede_get_rxfh,
+ .set_rxfh = qede_set_rxfh,
+ .get_channels = qede_get_channels,
+ .set_channels = qede_set_channels,
+ .get_tunable = qede_get_tunable,
+ .set_tunable = qede_set_tunable,
};

void qede_set_ethtool_ops(struct net_device *dev)
--
2.25.1

2020-07-16 11:58:28

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 08/13] qede: introduce support for FEC control

Add Ethtool callbacks for querying and setting FEC parameters if it's
supported by the underlying qed module and MFW version running on the
device.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
.../net/ethernet/qlogic/qede/qede_ethtool.c | 74 +++++++++++++++++++
1 file changed, 74 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index f5851a6ae729..12ec80d9247c 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -1861,6 +1861,78 @@ static int qede_set_eee(struct net_device *dev, struct ethtool_eee *edata)
return 0;
}

+static u32 qede_link_to_ethtool_fec(u32 link_fec)
+{
+ u32 eth_fec = 0;
+
+ if (link_fec & QED_FEC_MODE_NONE)
+ eth_fec |= ETHTOOL_FEC_OFF;
+ if (link_fec & QED_FEC_MODE_FIRECODE)
+ eth_fec |= ETHTOOL_FEC_BASER;
+ if (link_fec & QED_FEC_MODE_RS)
+ eth_fec |= ETHTOOL_FEC_RS;
+ if (link_fec & QED_FEC_MODE_AUTO)
+ eth_fec |= ETHTOOL_FEC_AUTO;
+ if (link_fec & QED_FEC_MODE_UNSUPPORTED)
+ eth_fec |= ETHTOOL_FEC_NONE;
+
+ return eth_fec;
+}
+
+static u32 qede_ethtool_to_link_fec(u32 eth_fec)
+{
+ u32 link_fec = 0;
+
+ if (eth_fec & ETHTOOL_FEC_OFF)
+ link_fec |= QED_FEC_MODE_NONE;
+ if (eth_fec & ETHTOOL_FEC_BASER)
+ link_fec |= QED_FEC_MODE_FIRECODE;
+ if (eth_fec & ETHTOOL_FEC_RS)
+ link_fec |= QED_FEC_MODE_RS;
+ if (eth_fec & ETHTOOL_FEC_AUTO)
+ link_fec |= QED_FEC_MODE_AUTO;
+ if (eth_fec & ETHTOOL_FEC_NONE)
+ link_fec |= QED_FEC_MODE_UNSUPPORTED;
+
+ return link_fec;
+}
+
+static int qede_get_fecparam(struct net_device *dev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct qede_dev *edev = netdev_priv(dev);
+ struct qed_link_output curr_link;
+
+ memset(&curr_link, 0, sizeof(curr_link));
+ edev->ops->common->get_link(edev->cdev, &curr_link);
+
+ fecparam->active_fec = qede_link_to_ethtool_fec(curr_link.active_fec);
+ fecparam->fec = qede_link_to_ethtool_fec(curr_link.sup_fec);
+
+ return 0;
+}
+
+static int qede_set_fecparam(struct net_device *dev,
+ struct ethtool_fecparam *fecparam)
+{
+ struct qede_dev *edev = netdev_priv(dev);
+ struct qed_link_params params;
+
+ if (!edev->ops || !edev->ops->common->can_link_change(edev->cdev)) {
+ DP_INFO(edev, "Link settings are not allowed to be changed\n");
+ return -EOPNOTSUPP;
+ }
+
+ memset(&params, 0, sizeof(params));
+ params.override_flags |= QED_LINK_OVERRIDE_FEC_CONFIG;
+ params.fec = qede_ethtool_to_link_fec(fecparam->fec);
+ params.link_up = true;
+
+ edev->ops->common->set_link(edev->cdev, &params);
+
+ return 0;
+}
+
static int qede_get_module_info(struct net_device *dev,
struct ethtool_modinfo *modinfo)
{
@@ -2097,6 +2169,8 @@ static const struct ethtool_ops qede_ethtool_ops = {
.get_module_eeprom = qede_get_module_eeprom,
.get_eee = qede_get_eee,
.set_eee = qede_set_eee,
+ .get_fecparam = qede_get_fecparam,
+ .set_fecparam = qede_set_fecparam,
.get_tunable = qede_get_tunable,
.set_tunable = qede_set_tunable,
.flash_device = qede_flash_device,
--
2.25.1

2020-07-16 11:58:31

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 02/13] qed: reformat public_port::transceiver_data a bit

Prior to adding new bitfields, reformat the existing ones from spaces
to tabs, and unify all hex values to lowercase.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 108 +++++++++++-----------
1 file changed, 55 insertions(+), 53 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 6bb0bbc0013b..0d0a109d94b4 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -11973,59 +11973,61 @@ struct public_port {
struct dcbx_mib operational_dcbx_mib;

u32 reserved[2];
- u32 transceiver_data;
-#define ETH_TRANSCEIVER_STATE_MASK 0x000000FF
-#define ETH_TRANSCEIVER_STATE_SHIFT 0x00000000
-#define ETH_TRANSCEIVER_STATE_OFFSET 0x00000000
-#define ETH_TRANSCEIVER_STATE_UNPLUGGED 0x00000000
-#define ETH_TRANSCEIVER_STATE_PRESENT 0x00000001
-#define ETH_TRANSCEIVER_STATE_VALID 0x00000003
-#define ETH_TRANSCEIVER_STATE_UPDATING 0x00000008
-#define ETH_TRANSCEIVER_TYPE_MASK 0x0000FF00
-#define ETH_TRANSCEIVER_TYPE_OFFSET 0x8
-#define ETH_TRANSCEIVER_TYPE_NONE 0x00
-#define ETH_TRANSCEIVER_TYPE_UNKNOWN 0xFF
-#define ETH_TRANSCEIVER_TYPE_1G_PCC 0x01
-#define ETH_TRANSCEIVER_TYPE_1G_ACC 0x02
-#define ETH_TRANSCEIVER_TYPE_1G_LX 0x03
-#define ETH_TRANSCEIVER_TYPE_1G_SX 0x04
-#define ETH_TRANSCEIVER_TYPE_10G_SR 0x05
-#define ETH_TRANSCEIVER_TYPE_10G_LR 0x06
-#define ETH_TRANSCEIVER_TYPE_10G_LRM 0x07
-#define ETH_TRANSCEIVER_TYPE_10G_ER 0x08
-#define ETH_TRANSCEIVER_TYPE_10G_PCC 0x09
-#define ETH_TRANSCEIVER_TYPE_10G_ACC 0x0a
-#define ETH_TRANSCEIVER_TYPE_XLPPI 0x0b
-#define ETH_TRANSCEIVER_TYPE_40G_LR4 0x0c
-#define ETH_TRANSCEIVER_TYPE_40G_SR4 0x0d
-#define ETH_TRANSCEIVER_TYPE_40G_CR4 0x0e
-#define ETH_TRANSCEIVER_TYPE_100G_AOC 0x0f
-#define ETH_TRANSCEIVER_TYPE_100G_SR4 0x10
-#define ETH_TRANSCEIVER_TYPE_100G_LR4 0x11
-#define ETH_TRANSCEIVER_TYPE_100G_ER4 0x12
-#define ETH_TRANSCEIVER_TYPE_100G_ACC 0x13
-#define ETH_TRANSCEIVER_TYPE_100G_CR4 0x14
-#define ETH_TRANSCEIVER_TYPE_4x10G_SR 0x15
-#define ETH_TRANSCEIVER_TYPE_25G_CA_N 0x16
-#define ETH_TRANSCEIVER_TYPE_25G_ACC_S 0x17
-#define ETH_TRANSCEIVER_TYPE_25G_CA_S 0x18
-#define ETH_TRANSCEIVER_TYPE_25G_ACC_M 0x19
-#define ETH_TRANSCEIVER_TYPE_25G_CA_L 0x1a
-#define ETH_TRANSCEIVER_TYPE_25G_ACC_L 0x1b
-#define ETH_TRANSCEIVER_TYPE_25G_SR 0x1c
-#define ETH_TRANSCEIVER_TYPE_25G_LR 0x1d
-#define ETH_TRANSCEIVER_TYPE_25G_AOC 0x1e
-#define ETH_TRANSCEIVER_TYPE_4x10G 0x1f
-#define ETH_TRANSCEIVER_TYPE_4x25G_CR 0x20
-#define ETH_TRANSCEIVER_TYPE_1000BASET 0x21
-#define ETH_TRANSCEIVER_TYPE_10G_BASET 0x22
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR 0x30
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR 0x31
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR 0x32
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR 0x33
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR 0x34
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR 0x35
-#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36
+
+ u32 transceiver_data;
+#define ETH_TRANSCEIVER_STATE_MASK 0x000000ff
+#define ETH_TRANSCEIVER_STATE_SHIFT 0x00000000
+#define ETH_TRANSCEIVER_STATE_OFFSET 0x00000000
+#define ETH_TRANSCEIVER_STATE_UNPLUGGED 0x00000000
+#define ETH_TRANSCEIVER_STATE_PRESENT 0x00000001
+#define ETH_TRANSCEIVER_STATE_VALID 0x00000003
+#define ETH_TRANSCEIVER_STATE_UPDATING 0x00000008
+#define ETH_TRANSCEIVER_TYPE_MASK 0x0000ff00
+#define ETH_TRANSCEIVER_TYPE_OFFSET 0x8
+#define ETH_TRANSCEIVER_TYPE_NONE 0x00
+#define ETH_TRANSCEIVER_TYPE_UNKNOWN 0xff
+#define ETH_TRANSCEIVER_TYPE_1G_PCC 0x01
+#define ETH_TRANSCEIVER_TYPE_1G_ACC 0x02
+#define ETH_TRANSCEIVER_TYPE_1G_LX 0x03
+#define ETH_TRANSCEIVER_TYPE_1G_SX 0x04
+#define ETH_TRANSCEIVER_TYPE_10G_SR 0x05
+#define ETH_TRANSCEIVER_TYPE_10G_LR 0x06
+#define ETH_TRANSCEIVER_TYPE_10G_LRM 0x07
+#define ETH_TRANSCEIVER_TYPE_10G_ER 0x08
+#define ETH_TRANSCEIVER_TYPE_10G_PCC 0x09
+#define ETH_TRANSCEIVER_TYPE_10G_ACC 0x0a
+#define ETH_TRANSCEIVER_TYPE_XLPPI 0x0b
+#define ETH_TRANSCEIVER_TYPE_40G_LR4 0x0c
+#define ETH_TRANSCEIVER_TYPE_40G_SR4 0x0d
+#define ETH_TRANSCEIVER_TYPE_40G_CR4 0x0e
+#define ETH_TRANSCEIVER_TYPE_100G_AOC 0x0f
+#define ETH_TRANSCEIVER_TYPE_100G_SR4 0x10
+#define ETH_TRANSCEIVER_TYPE_100G_LR4 0x11
+#define ETH_TRANSCEIVER_TYPE_100G_ER4 0x12
+#define ETH_TRANSCEIVER_TYPE_100G_ACC 0x13
+#define ETH_TRANSCEIVER_TYPE_100G_CR4 0x14
+#define ETH_TRANSCEIVER_TYPE_4x10G_SR 0x15
+#define ETH_TRANSCEIVER_TYPE_25G_CA_N 0x16
+#define ETH_TRANSCEIVER_TYPE_25G_ACC_S 0x17
+#define ETH_TRANSCEIVER_TYPE_25G_CA_S 0x18
+#define ETH_TRANSCEIVER_TYPE_25G_ACC_M 0x19
+#define ETH_TRANSCEIVER_TYPE_25G_CA_L 0x1a
+#define ETH_TRANSCEIVER_TYPE_25G_ACC_L 0x1b
+#define ETH_TRANSCEIVER_TYPE_25G_SR 0x1c
+#define ETH_TRANSCEIVER_TYPE_25G_LR 0x1d
+#define ETH_TRANSCEIVER_TYPE_25G_AOC 0x1e
+#define ETH_TRANSCEIVER_TYPE_4x10G 0x1f
+#define ETH_TRANSCEIVER_TYPE_4x25G_CR 0x20
+#define ETH_TRANSCEIVER_TYPE_1000BASET 0x21
+#define ETH_TRANSCEIVER_TYPE_10G_BASET 0x22
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR 0x30
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR 0x31
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR 0x32
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR 0x33
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR 0x34
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR 0x35
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36
+
u32 wol_info;
u32 wol_pkt_len;
u32 wol_pkt_details;
--
2.25.1

2020-07-16 11:58:52

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 03/13] qed: add support for multi-rate transceivers

Set the corresponding advertised and supported link modes according
to the detected transceiver type and device capabilities.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 4 +
drivers/net/ethernet/qlogic/qed/qed_main.c | 112 ++++++++++++++++-----
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 9 +-
3 files changed, 98 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 0d0a109d94b4..ebc25b34e491 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -12027,6 +12027,10 @@ struct public_port {
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR 0x34
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR 0x35
#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_AOC 0x36
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR 0x37
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR 0x38
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR 0x39
+#define ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR 0x3a

u32 wol_info;
u32 wol_pkt_len;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 8a0b8da19547..9df27c3f5cab 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1695,21 +1695,38 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
__set_bit(QED_LM_20000baseKR2_Full, if_caps);

- /* For DAC media multiple speed capabilities are supported*/
- capability = capability & speed_mask;
+ /* For DAC media multiple speed capabilities are supported */
+ capability |= speed_mask;
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
__set_bit(QED_LM_1000baseKX_Full, if_caps);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
__set_bit(QED_LM_10000baseCR_Full, if_caps);
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
- __set_bit(QED_LM_40000baseCR4_Full, if_caps);
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_40G_CR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
+ __set_bit(QED_LM_40000baseCR4_Full, if_caps);
+ default:
+ break;
+ }
+
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
__set_bit(QED_LM_25000baseCR_Full, if_caps);
if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
__set_bit(QED_LM_50000baseCR2_Full, if_caps);
+
if (capability &
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
- __set_bit(QED_LM_100000baseCR4_Full, if_caps);
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_100G_CR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_CR:
+ __set_bit(QED_LM_100000baseCR4_Full, if_caps);
+ default:
+ break;
+ }

break;
case MEDIA_BASE_T:
@@ -1727,10 +1744,15 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
if (board_cfg & NVM_CFG1_PORT_PORT_TYPE_MODULE) {
__set_bit(QED_LM_FIBRE, if_caps);

- if (tcvr_type == ETH_TRANSCEIVER_TYPE_1000BASET)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_1000BASET:
__set_bit(QED_LM_1000baseT_Full, if_caps);
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_BASET)
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_BASET:
__set_bit(QED_LM_10000baseT_Full, if_caps);
+ default:
+ break;
+ }
}

break;
@@ -1739,47 +1761,85 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
case MEDIA_XFP_FIBER:
case MEDIA_MODULE_FIBER:
__set_bit(QED_LM_FIBRE, if_caps);
+ capability |= speed_mask;

- 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 & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_1G_LX:
+ case ETH_TRANSCEIVER_TYPE_1G_SX:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
__set_bit(QED_LM_1000baseKX_Full, if_caps);
- }
+ default:
+ break;
+ }

- if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_SR)
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_10G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
__set_bit(QED_LM_10000baseSR_Full, if_caps);
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LR)
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
__set_bit(QED_LM_10000baseLR_Full, if_caps);
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_LRM)
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_LRM:
__set_bit(QED_LM_10000baseLRM_Full, if_caps);
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_10G_ER)
+ break;
+ case ETH_TRANSCEIVER_TYPE_10G_ER:
__set_bit(QED_LM_10000baseR_FEC, if_caps);
- }
+ default:
+ break;
+ }

if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G)
__set_bit(QED_LM_20000baseKR2_Full, if_caps);

- if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_25G_SR)
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_25G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
__set_bit(QED_LM_25000baseSR_Full, if_caps);
- }
+ default:
+ break;
+ }

- if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_LR4)
+ if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_40G_LR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_LR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
__set_bit(QED_LM_40000baseLR4_Full, if_caps);
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_40G_SR4)
+ break;
+ case ETH_TRANSCEIVER_TYPE_40G_SR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_SR:
__set_bit(QED_LM_40000baseSR4_Full, if_caps);
- }
+ default:
+ break;
+ }

if (capability & NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G)
__set_bit(QED_LM_50000baseKR2_Full, if_caps);

if (capability &
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G) {
- if (tcvr_type == ETH_TRANSCEIVER_TYPE_100G_SR4)
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G)
+ switch (tcvr_type) {
+ case ETH_TRANSCEIVER_TYPE_100G_SR4:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_SR:
__set_bit(QED_LM_100000baseSR4_Full, if_caps);
- }
+ break;
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_40G_100G_LR:
+ __set_bit(QED_LM_100000baseLR4_ER4_Full,
+ if_caps);
+ default:
+ break;
+ }

break;
case MEDIA_KR:
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
index 2d12bb27560c..b10a92488630 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c
@@ -2193,6 +2193,11 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_25G_LR:
+ *p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G |
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
+ break;
case ETH_TRANSCEIVER_TYPE_40G_CR4:
case ETH_TRANSCEIVER_TYPE_MULTI_RATE_10G_40G_CR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G |
@@ -2223,8 +2228,10 @@ int qed_mcp_trans_speed_mask(struct qed_hwfn *p_hwfn,
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
break;
case ETH_TRANSCEIVER_TYPE_10G_BASET:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_SR:
+ case ETH_TRANSCEIVER_TYPE_MULTI_RATE_1G_10G_LR:
*p_speed_mask = NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G |
- NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
+ NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
break;
default:
DP_INFO(p_hwfn, "Unknown transceiver type 0x%x\n",
--
2.25.1

2020-07-16 11:59:13

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 05/13] 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 <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
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(-)

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 a039f8519829..b9212b3057af 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -711,51 +711,53 @@ enum qed_link_mode_bits {
QED_LM_COUNT)

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;
QED_LM_DECLARE(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;

QED_LM_DECLARE(supported_caps);
QED_LM_DECLARE(advertised_caps);
QED_LM_DECLARE(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 {
--
2.25.1

2020-07-16 12:00:09

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 13/13] qed/qede: 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 <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
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 | 260 +++++++++++++++++-
drivers/net/ethernet/qlogic/qed/qed_mcp.c | 74 ++++-
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 45 +++
.../net/ethernet/qlogic/qede/qede_ethtool.c | 10 +
include/linux/qed/qed_if.h | 11 +
8 files changed, 563 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 63fcbd5a295a..d255e8e68cf8 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -731,6 +731,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 4bad836d0f74..c25cf132dd46 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -3968,8 +3968,9 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)

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;

@@ -4057,8 +4058,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 +
@@ -4093,13 +4093,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 &
@@ -4159,6 +4158,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 28f13cd7bd9b..cfc51c5e5bc5 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 = {
+ QED_LM_1000baseT_Full,
+ QED_LM_1000baseKX_Full,
+ QED_LM_1000baseX_Full,
+};
+
+static const u32 qed_mfw_ext_10g[] __initconst = {
+ QED_LM_10000baseT_Full,
+ QED_LM_10000baseKR_Full,
+ QED_LM_10000baseKX4_Full,
+ QED_LM_10000baseR_FEC,
+ QED_LM_10000baseCR_Full,
+ QED_LM_10000baseSR_Full,
+ QED_LM_10000baseLR_Full,
+ QED_LM_10000baseLRM_Full,
+};
+
+static const u32 qed_mfw_ext_20g[] __initconst = {
+ QED_LM_20000baseKR2_Full,
+};
+
+static const u32 qed_mfw_ext_25g[] __initconst = {
+ QED_LM_25000baseKR_Full,
+ QED_LM_25000baseCR_Full,
+ QED_LM_25000baseSR_Full,
+};
+
+static const u32 qed_mfw_ext_40g[] __initconst = {
+ QED_LM_40000baseLR4_Full,
+ QED_LM_40000baseKR4_Full,
+ QED_LM_40000baseCR4_Full,
+ QED_LM_40000baseSR4_Full,
+};
+
+static const u32 qed_mfw_ext_50g_base_r[] __initconst = {
+ QED_LM_50000baseKR_Full,
+ QED_LM_50000baseCR_Full,
+ QED_LM_50000baseSR_Full,
+ QED_LM_50000baseLR_ER_FR_Full,
+ QED_LM_50000baseDR_Full,
+};
+
+static const u32 qed_mfw_ext_50g_base_r2[] __initconst = {
+ QED_LM_50000baseKR2_Full,
+ QED_LM_50000baseCR2_Full,
+ QED_LM_50000baseSR2_Full,
+};
+
+static const u32 qed_mfw_ext_100g_base_r2[] __initconst = {
+ QED_LM_100000baseKR2_Full,
+ QED_LM_100000baseSR2_Full,
+ QED_LM_100000baseCR2_Full,
+ QED_LM_100000baseDR2_Full,
+ QED_LM_100000baseLR2_ER2_FR2_Full,
+};
+
+static const u32 qed_mfw_ext_100g_base_r4[] __initconst = {
+ QED_LM_100000baseKR4_Full,
+ QED_LM_100000baseSR4_Full,
+ QED_LM_100000baseCR4_Full,
+ QED_LM_100000baseLR4_ER4_Full,
+};
+
+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 = {
QED_LM_1000baseT_Full,
QED_LM_1000baseKX_Full,
@@ -161,6 +240,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);
}
@@ -1556,6 +1638,141 @@ 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 (qed_link_mode_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;
+ 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;
+ 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;
+ 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;
+ 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;
+ default:
+ break;
+ }
+ default:
+ break;
+ }
+}
+
static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
{
struct qed_mcp_link_params *link_params;
@@ -1609,6 +1826,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;
@@ -1686,7 +1906,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:
@@ -1695,6 +1914,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;
@@ -1986,9 +2206,34 @@ 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)
- __set_bit(QED_LM_Autoneg, if_link->supported_caps);
+ if (IS_PF(hwfn->cdev) && qed_mcp_is_ext_speed_supported(hwfn)) {
+ if (link_caps.default_ext_autoneg)
+ __set_bit(QED_LM_Autoneg, if_link->supported_caps);
+
+ qed_link_mode_copy(if_link->advertised_caps,
+ if_link->supported_caps);
+
+ if (params.ext_speed.autoneg)
+ __set_bit(QED_LM_Autoneg, if_link->advertised_caps);
+ else
+ clear_bit(QED_LM_Autoneg, if_link->advertised_caps);
+
+ qed_fill_link_capability(hwfn, ptt,
+ params.ext_speed.advertised_speeds,
+ if_link->advertised_caps);
+ } else {
+ if (link_caps.default_speed_autoneg)
+ __set_bit(QED_LM_Autoneg, if_link->supported_caps);
+
+ qed_link_mode_copy(if_link->advertised_caps,
+ if_link->supported_caps);
+
+ if (params.speed.autoneg)
+ __set_bit(QED_LM_Autoneg, if_link->advertised_caps);
+ else
+ clear_bit(QED_LM_Autoneg, if_link->advertised_caps);
+ }
+
if (params.pause.autoneg ||
(params.pause.forced_rx && params.pause.forced_tx))
__set_bit(QED_LM_Asym_Pause, if_link->supported_caps);
@@ -1996,13 +2241,6 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
params.pause.forced_tx)
__set_bit(QED_LM_Pause, if_link->supported_caps);

- qed_link_mode_copy(if_link->advertised_caps, if_link->supported_caps);
-
- if (params.speed.autoneg)
- __set_bit(QED_LM_Autoneg, if_link->advertised_caps);
- else
- __clear_bit(QED_LM_Autoneg, if_link->advertised_caps);
-
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/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
index 12ec80d9247c..8e08bf249a06 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c
@@ -462,6 +462,16 @@ static const struct qede_link_mode_mapping qed_lm_map[] = {
QEDE_ETHTOOL_LM_MAP(10000baseSR_Full),
QEDE_ETHTOOL_LM_MAP(10000baseLR_Full),
QEDE_ETHTOOL_LM_MAP(10000baseLRM_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseKR_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseCR_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseSR_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseLR_ER_FR_Full),
+ QEDE_ETHTOOL_LM_MAP(50000baseDR_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseKR2_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseSR2_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseCR2_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseLR2_ER2_FR2_Full),
+ QEDE_ETHTOOL_LM_MAP(100000baseDR2_Full),
};

static_assert(ARRAY_SIZE(qed_lm_map) == QED_LM_COUNT);
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index 9edd5de5645d..b41ea5e13b4a 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 {
@@ -694,6 +695,16 @@ enum qed_link_mode_bits {
QED_LM_10000baseSR_Full,
QED_LM_10000baseLR_Full,
QED_LM_10000baseLRM_Full,
+ QED_LM_50000baseKR_Full,
+ QED_LM_50000baseCR_Full,
+ QED_LM_50000baseSR_Full,
+ QED_LM_50000baseLR_ER_FR_Full,
+ QED_LM_50000baseDR_Full,
+ QED_LM_100000baseKR2_Full,
+ QED_LM_100000baseSR2_Full,
+ QED_LM_100000baseCR2_Full,
+ QED_LM_100000baseLR2_ER2_FR2_Full,
+ QED_LM_100000baseDR2_Full,
QED_LM_COUNT,
};

--
2.25.1

2020-07-16 12:00:36

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 06/13] 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 <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
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(-)

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 @@ static int qed_hw_get_resc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)

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 1639210044a7..768d6ab5395f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1596,6 +1596,9 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
memcpy(&link_params->eee, &params->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);
@@ -1929,6 +1932,9 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
else
__clear_bit(QED_LM_Autoneg, if_link->advertised_caps);

+ 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 b9212b3057af..1b5286d454bf 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -710,6 +710,14 @@ enum qed_link_mode_bits {
(lm2), \
QED_LM_COUNT)

+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;

@@ -720,6 +728,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;
QED_LM_DECLARE(adv_speeds);
@@ -738,6 +747,7 @@ struct qed_link_params {
#define QED_LINK_LOOPBACK_MAC BIT(4)

struct qed_link_eee_params eee;
+ u32 fec;
};

struct qed_link_output {
@@ -758,6 +768,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 {
--
2.25.1

2020-07-16 12:00:47

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 04/13] qed: use transceiver data to fill link partner's advertising speeds

Currently qed driver does not take into consideration transceiver's
capabilities when generating link partner's speed advertisement. This
leads to e.g. incorrect ethtool link info on 10GbaseT modules.
Use transceiver info not only for advertisement and support arrays, but
also for link partner's abilities to fix it.

Misc: fix a couple of comments nearby.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
drivers/net/ethernet/qlogic/qed/qed_main.c | 49 +++++++++++++---------
1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c
index 9df27c3f5cab..1639210044a7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_main.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_main.c
@@ -1870,6 +1870,27 @@ static void qed_fill_link_capability(struct qed_hwfn *hwfn,
}
}

+static void qed_lp_caps_to_speed_mask(u32 caps, u32 *speed_mask)
+{
+ *speed_mask = 0;
+
+ if (caps &
+ (QED_LINK_PARTNER_SPEED_1G_FD | QED_LINK_PARTNER_SPEED_1G_HD))
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_1G;
+ if (caps & QED_LINK_PARTNER_SPEED_10G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_10G;
+ if (caps & QED_LINK_PARTNER_SPEED_20G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G;
+ if (caps & QED_LINK_PARTNER_SPEED_25G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G;
+ if (caps & QED_LINK_PARTNER_SPEED_40G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G;
+ if (caps & QED_LINK_PARTNER_SPEED_50G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G;
+ if (caps & QED_LINK_PARTNER_SPEED_100G)
+ *speed_mask |= NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_BB_100G;
+}
+
static void qed_fill_link(struct qed_hwfn *hwfn,
struct qed_ptt *ptt,
struct qed_link_output *if_link)
@@ -1877,7 +1898,7 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
struct qed_mcp_link_capabilities link_caps;
struct qed_mcp_link_params params;
struct qed_mcp_link_state link;
- u32 media_type;
+ u32 media_type, speed_mask;

memset(if_link, 0, sizeof(*if_link));

@@ -1908,13 +1929,18 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
else
__clear_bit(QED_LM_Autoneg, if_link->advertised_caps);

- /* Fill link advertised capability*/
+ /* Fill link advertised capability */
qed_fill_link_capability(hwfn, ptt, params.speed.advertised_speeds,
if_link->advertised_caps);
- /* Fill link supported capability*/
+
+ /* Fill link supported capability */
qed_fill_link_capability(hwfn, ptt, link_caps.speed_capabilities,
if_link->supported_caps);

+ /* Fill partner advertised capability */
+ qed_lp_caps_to_speed_mask(link.partner_adv_speed, &speed_mask);
+ qed_fill_link_capability(hwfn, ptt, speed_mask, if_link->lp_caps);
+
if (link.link_up)
if_link->speed = link.speed;

@@ -1932,23 +1958,6 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
if (params.pause.forced_tx)
if_link->pause_config |= QED_LINK_PAUSE_TX_ENABLE;

- /* Link partner capabilities */
-
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_1G_FD)
- __set_bit(QED_LM_1000baseT_Full, if_link->lp_caps);
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_10G)
- __set_bit(QED_LM_10000baseKR_Full, if_link->lp_caps);
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_20G)
- __set_bit(QED_LM_20000baseKR2_Full, if_link->lp_caps);
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_25G)
- __set_bit(QED_LM_25000baseKR_Full, if_link->lp_caps);
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_40G)
- __set_bit(QED_LM_40000baseLR4_Full, if_link->lp_caps);
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_50G)
- __set_bit(QED_LM_50000baseKR2_Full, if_link->lp_caps);
- if (link.partner_adv_speed & QED_LINK_PARTNER_SPEED_100G)
- __set_bit(QED_LM_100000baseKR4_Full, if_link->lp_caps);
-
if (link.an_complete)
__set_bit(QED_LM_Autoneg, if_link->lp_caps);
if (link.partner_adv_pause)
--
2.25.1

2020-07-16 12:01:29

by Alexander Lobakin

[permalink] [raw]
Subject: [PATCH net-next 09/13] qed: reformat several structures a bit

Reformat a few nvm_cfg* structures (and partly qed_dev) prior to adding
new fields and definitions.

Signed-off-by: Alexander Lobakin <[email protected]>
Signed-off-by: Igor Russkikh <[email protected]>
---
drivers/net/ethernet/qlogic/qed/qed.h | 62 ++--
drivers/net/ethernet/qlogic/qed/qed_hsi.h | 345 +++++++++++-----------
drivers/net/ethernet/qlogic/qed/qed_mcp.h | 12 +-
3 files changed, 213 insertions(+), 206 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index ced805399e4f..6a1d12da7910 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -715,41 +715,41 @@ struct qed_dbg_feature {
};

struct qed_dev {
- u32 dp_module;
- u8 dp_level;
- char name[NAME_SIZE];
-
- enum qed_dev_type type;
-/* Translate type/revision combo into the proper conditions */
-#define QED_IS_BB(dev) ((dev)->type == QED_DEV_TYPE_BB)
-#define QED_IS_BB_B0(dev) (QED_IS_BB(dev) && \
- CHIP_REV_IS_B0(dev))
-#define QED_IS_AH(dev) ((dev)->type == QED_DEV_TYPE_AH)
-#define QED_IS_K2(dev) QED_IS_AH(dev)
-
- u16 vendor_id;
- u16 device_id;
-#define QED_DEV_ID_MASK 0xff00
-#define QED_DEV_ID_MASK_BB 0x1600
-#define QED_DEV_ID_MASK_AH 0x8000
-#define QED_IS_E4(dev) (QED_IS_BB(dev) || QED_IS_AH(dev))
-
- u16 chip_num;
-#define CHIP_NUM_MASK 0xffff
-#define CHIP_NUM_SHIFT 16
-
- u16 chip_rev;
-#define CHIP_REV_MASK 0xf
-#define CHIP_REV_SHIFT 12
-#define CHIP_REV_IS_B0(_cdev) ((_cdev)->chip_rev == 1)
+ u32 dp_module;
+ u8 dp_level;
+ char name[NAME_SIZE];
+
+ enum qed_dev_type type;
+ /* Translate type/revision combo into the proper conditions */
+#define QED_IS_BB(dev) ((dev)->type == QED_DEV_TYPE_BB)
+#define QED_IS_BB_B0(dev) (QED_IS_BB(dev) && CHIP_REV_IS_B0(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))
+
+ u16 vendor_id;
+
+ u16 device_id;
+#define QED_DEV_ID_MASK 0xff00
+#define QED_DEV_ID_MASK_BB 0x1600
+#define QED_DEV_ID_MASK_AH 0x8000
+
+ u16 chip_num;
+#define CHIP_NUM_MASK 0xffff
+#define CHIP_NUM_SHIFT 16
+
+ u16 chip_rev;
+#define CHIP_REV_MASK 0xf
+#define CHIP_REV_SHIFT 12
+#define CHIP_REV_IS_B0(_cdev) ((_cdev)->chip_rev == 1)

u16 chip_metal;
-#define CHIP_METAL_MASK 0xff
-#define CHIP_METAL_SHIFT 4
+#define CHIP_METAL_MASK 0xff
+#define CHIP_METAL_SHIFT 4

u16 chip_bond_id;
-#define CHIP_BOND_ID_MASK 0xf
-#define CHIP_BOND_ID_SHIFT 0
+#define CHIP_BOND_ID_MASK 0xf
+#define CHIP_BOND_ID_SHIFT 0

u8 num_engines;
u8 num_ports;
diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
index 7c1d4efffbff..a4a845579fd2 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
@@ -12532,67 +12532,67 @@ struct public_drv_mb {
#define DRV_MB_PARAM_SET_LED_MODE_ON 0x1
#define DRV_MB_PARAM_SET_LED_MODE_OFF 0x2

-#define DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET 0
-#define DRV_MB_PARAM_TRANSCEIVER_PORT_MASK 0x00000003
-#define DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET 2
-#define DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK 0x000000FC
-#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET 8
-#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK 0x0000FF00
-#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET 16
-#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK 0xFFFF0000
+#define DRV_MB_PARAM_TRANSCEIVER_PORT_OFFSET 0
+#define DRV_MB_PARAM_TRANSCEIVER_PORT_MASK 0x00000003
+#define DRV_MB_PARAM_TRANSCEIVER_SIZE_OFFSET 2
+#define DRV_MB_PARAM_TRANSCEIVER_SIZE_MASK 0x000000fc
+#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_OFFSET 8
+#define DRV_MB_PARAM_TRANSCEIVER_I2C_ADDRESS_MASK 0x0000ff00
+#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_OFFSET 16
+#define DRV_MB_PARAM_TRANSCEIVER_OFFSET_MASK 0xffff0000

/* Resource Allocation params - Driver version support */
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xFFFF0000
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000FFFF
-#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_SHIFT 0
-
-#define DRV_MB_PARAM_BIST_REGISTER_TEST 1
-#define DRV_MB_PARAM_BIST_CLOCK_TEST 2
-#define DRV_MB_PARAM_BIST_NVM_TEST_NUM_IMAGES 3
-#define DRV_MB_PARAM_BIST_NVM_TEST_IMAGE_BY_INDEX 4
-
-#define DRV_MB_PARAM_BIST_RC_UNKNOWN 0
-#define DRV_MB_PARAM_BIST_RC_PASSED 1
-#define DRV_MB_PARAM_BIST_RC_FAILED 2
-#define DRV_MB_PARAM_BIST_RC_INVALID_PARAMETER 3
-
-#define DRV_MB_PARAM_BIST_TEST_INDEX_SHIFT 0
-#define DRV_MB_PARAM_BIST_TEST_INDEX_MASK 0x000000FF
-#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_SHIFT 8
-#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_MASK 0x0000FF00
-
-#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
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_MASK 0xffff0000
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MAJOR_SHIFT 16
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_MASK 0x0000ffff
+#define DRV_MB_PARAM_RESOURCE_ALLOC_VERSION_MINOR_SHIFT 0
+
+#define DRV_MB_PARAM_BIST_REGISTER_TEST 1
+#define DRV_MB_PARAM_BIST_CLOCK_TEST 2
+#define DRV_MB_PARAM_BIST_NVM_TEST_NUM_IMAGES 3
+#define DRV_MB_PARAM_BIST_NVM_TEST_IMAGE_BY_INDEX 4
+
+#define DRV_MB_PARAM_BIST_RC_UNKNOWN 0
+#define DRV_MB_PARAM_BIST_RC_PASSED 1
+#define DRV_MB_PARAM_BIST_RC_FAILED 2
+#define DRV_MB_PARAM_BIST_RC_INVALID_PARAMETER 3
+
+#define DRV_MB_PARAM_BIST_TEST_INDEX_SHIFT 0
+#define DRV_MB_PARAM_BIST_TEST_INDEX_MASK 0x000000ff
+#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_SHIFT 8
+#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_MASK 0x0000ff00
+
+#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 */
-#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_OFFSET 0
-#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_MASK 0xFF
+#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_OFFSET 0
+#define DRV_MSG_CODE_DEBUG_DATA_SEND_SIZE_MASK 0xff

/* Driver attributes params */
-#define DRV_MB_PARAM_ATTRIBUTE_KEY_OFFSET 0
-#define DRV_MB_PARAM_ATTRIBUTE_KEY_MASK 0x00FFFFFF
-#define DRV_MB_PARAM_ATTRIBUTE_CMD_OFFSET 24
-#define DRV_MB_PARAM_ATTRIBUTE_CMD_MASK 0xFF000000
-
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_OFFSET 0
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_SHIFT 0
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_MASK 0x0000FFFF
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_SHIFT 16
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_MASK 0x00010000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_SHIFT 17
-#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_MASK 0x00020000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_SHIFT 18
-#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_MASK 0x00040000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_SHIFT 19
-#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_MASK 0x00080000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_SHIFT 20
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_MASK 0x00100000
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_SHIFT 24
-#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_MASK 0x0f000000
+#define DRV_MB_PARAM_ATTRIBUTE_KEY_OFFSET 0
+#define DRV_MB_PARAM_ATTRIBUTE_KEY_MASK 0x00ffffff
+#define DRV_MB_PARAM_ATTRIBUTE_CMD_OFFSET 24
+#define DRV_MB_PARAM_ATTRIBUTE_CMD_MASK 0xff000000
+
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_OFFSET 0
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_SHIFT 0
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ID_MASK 0x0000ffff
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_SHIFT 16
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ALL_MASK 0x00010000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_SHIFT 17
+#define DRV_MB_PARAM_NVM_CFG_OPTION_INIT_MASK 0x00020000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_SHIFT 18
+#define DRV_MB_PARAM_NVM_CFG_OPTION_COMMIT_MASK 0x00040000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_SHIFT 19
+#define DRV_MB_PARAM_NVM_CFG_OPTION_FREE_MASK 0x00080000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_SHIFT 20
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_SEL_MASK 0x00100000
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_SHIFT 24
+#define DRV_MB_PARAM_NVM_CFG_OPTION_ENTITY_ID_MASK 0x0f000000

u32 fw_mb_header;
#define FW_MSG_CODE_MASK 0xffff0000
@@ -12639,56 +12639,56 @@ 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
-#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_SHIFT 0
+ 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_SHIFT 0

/* 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
+#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_FEC_CONTROL 0x00000020
-#define FW_MB_PARAM_FEATURE_SUPPORT_VLINK 0x00010000
+#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_VLINK BIT(16)

-#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR BIT(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
-#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_SHIFT 0
-#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_MASK 0xff000000
-#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_SHIFT 24
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_MASK 0x00ffffff
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_OFFSET_SHIFT 0
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_MASK 0xff000000
+#define FW_MB_PARAM_NVM_PUT_FILE_REQ_SIZE_SHIFT 24

enum MFW_DRV_MSG_TYPE {
MFW_DRV_MSG_LINK_CHANGE,
@@ -12975,86 +12975,93 @@ enum tlvs {
};

struct nvm_cfg_mac_address {
- u32 mac_addr_hi;
-#define NVM_CFG_MAC_ADDRESS_HI_MASK 0x0000FFFF
-#define NVM_CFG_MAC_ADDRESS_HI_OFFSET 0
- u32 mac_addr_lo;
+ u32 mac_addr_hi;
+#define NVM_CFG_MAC_ADDRESS_HI_MASK 0x0000ffff
+#define NVM_CFG_MAC_ADDRESS_HI_OFFSET 0
+
+ u32 mac_addr_lo;
};

struct nvm_cfg1_glob {
- u32 generic_cont0;
-#define NVM_CFG1_GLOB_MF_MODE_MASK 0x00000FF0
-#define NVM_CFG1_GLOB_MF_MODE_OFFSET 4
-#define NVM_CFG1_GLOB_MF_MODE_MF_ALLOWED 0x0
-#define NVM_CFG1_GLOB_MF_MODE_DEFAULT 0x1
-#define NVM_CFG1_GLOB_MF_MODE_SPIO4 0x2
-#define NVM_CFG1_GLOB_MF_MODE_NPAR1_0 0x3
-#define NVM_CFG1_GLOB_MF_MODE_NPAR1_5 0x4
-#define NVM_CFG1_GLOB_MF_MODE_NPAR2_0 0x5
-#define NVM_CFG1_GLOB_MF_MODE_BD 0x6
-#define NVM_CFG1_GLOB_MF_MODE_UFP 0x7
- u32 engineering_change[3];
- u32 manufacturing_id;
- u32 serial_number[4];
- u32 pcie_cfg;
- u32 mgmt_traffic;
- u32 core_cfg;
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK 0x000000FF
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET 0
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_2X40G 0x0
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X50G 0x1
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_1X100G 0x2
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X10G_F 0x3
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X10G_E 0x4
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X20G 0x5
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X40G 0xB
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X25G 0xC
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G 0xD
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G 0xE
-#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G 0xF
-
- u32 e_lane_cfg1;
- u32 e_lane_cfg2;
- u32 f_lane_cfg1;
- u32 f_lane_cfg2;
- u32 mps10_preemphasis;
- u32 mps10_driver_current;
- u32 mps25_preemphasis;
- u32 mps25_driver_current;
- u32 pci_id;
- u32 pci_subsys_id;
- u32 bar;
- u32 mps10_txfir_main;
- u32 mps10_txfir_post;
- u32 mps25_txfir_main;
- u32 mps25_txfir_post;
- u32 manufacture_ver;
- u32 manufacture_time;
- u32 led_global_settings;
- u32 generic_cont1;
- u32 mbi_version;
-#define NVM_CFG1_GLOB_MBI_VERSION_0_MASK 0x000000FF
-#define NVM_CFG1_GLOB_MBI_VERSION_0_OFFSET 0
-#define NVM_CFG1_GLOB_MBI_VERSION_1_MASK 0x0000FF00
-#define NVM_CFG1_GLOB_MBI_VERSION_1_OFFSET 8
-#define NVM_CFG1_GLOB_MBI_VERSION_2_MASK 0x00FF0000
-#define NVM_CFG1_GLOB_MBI_VERSION_2_OFFSET 16
- u32 mbi_date;
- u32 misc_sig;
- u32 device_capabilities;
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ETHERNET 0x1
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_FCOE 0x2
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ISCSI 0x4
-#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ROCE 0x8
- u32 power_dissipated;
- u32 power_consumed;
- u32 efi_version;
- u32 multi_network_modes_capability;
- u32 reserved[41];
+ u32 generic_cont0;
+#define NVM_CFG1_GLOB_MF_MODE_MASK 0x00000ff0
+#define NVM_CFG1_GLOB_MF_MODE_OFFSET 4
+#define NVM_CFG1_GLOB_MF_MODE_MF_ALLOWED 0x0
+#define NVM_CFG1_GLOB_MF_MODE_DEFAULT 0x1
+#define NVM_CFG1_GLOB_MF_MODE_SPIO4 0x2
+#define NVM_CFG1_GLOB_MF_MODE_NPAR1_0 0x3
+#define NVM_CFG1_GLOB_MF_MODE_NPAR1_5 0x4
+#define NVM_CFG1_GLOB_MF_MODE_NPAR2_0 0x5
+#define NVM_CFG1_GLOB_MF_MODE_BD 0x6
+#define NVM_CFG1_GLOB_MF_MODE_UFP 0x7
+
+ u32 engineering_change[3];
+ u32 manufacturing_id;
+ u32 serial_number[4];
+ u32 pcie_cfg;
+ u32 mgmt_traffic;
+
+ u32 core_cfg;
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_MASK 0x000000ff
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_OFFSET 0
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_2X40G 0x0
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X50G 0x1
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_1X100G 0x2
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X10G_F 0x3
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X10G_E 0x4
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_BB_4X20G 0x5
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X40G 0xb
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X25G 0xc
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G 0xd
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G 0xe
+#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G 0xf
+
+ u32 e_lane_cfg1;
+ u32 e_lane_cfg2;
+ u32 f_lane_cfg1;
+ u32 f_lane_cfg2;
+ u32 mps10_preemphasis;
+ u32 mps10_driver_current;
+ u32 mps25_preemphasis;
+ u32 mps25_driver_current;
+ u32 pci_id;
+ u32 pci_subsys_id;
+ u32 bar;
+ u32 mps10_txfir_main;
+ u32 mps10_txfir_post;
+ u32 mps25_txfir_main;
+ u32 mps25_txfir_post;
+ u32 manufacture_ver;
+ u32 manufacture_time;
+ u32 led_global_settings;
+ u32 generic_cont1;
+
+ u32 mbi_version;
+#define NVM_CFG1_GLOB_MBI_VERSION_0_MASK 0x000000ff
+#define NVM_CFG1_GLOB_MBI_VERSION_0_OFFSET 0
+#define NVM_CFG1_GLOB_MBI_VERSION_1_MASK 0x0000ff00
+#define NVM_CFG1_GLOB_MBI_VERSION_1_OFFSET 8
+#define NVM_CFG1_GLOB_MBI_VERSION_2_MASK 0x00ff0000
+#define NVM_CFG1_GLOB_MBI_VERSION_2_OFFSET 16
+
+ u32 mbi_date;
+ u32 misc_sig;
+
+ u32 device_capabilities;
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ETHERNET 0x1
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_FCOE 0x2
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ISCSI 0x4
+#define NVM_CFG1_GLOB_DEVICE_CAPABILITIES_ROCE 0x8
+
+ u32 power_dissipated;
+ u32 power_consumed;
+ u32 efi_version;
+ u32 multi_net_modes_cap;
+ u32 reserved[41];
};

struct nvm_cfg1_path {
- u32 reserved[30];
+ u32 reserved[30];
};

struct nvm_cfg1_port {
@@ -13082,7 +13089,7 @@ struct nvm_cfg1_port {
#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
-#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G 0x4
+#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_20G 0x4
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_25G 0x8
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_40G 0x10
#define NVM_CFG1_PORT_DRV_SPEED_CAPABILITY_MASK_50G 0x20
@@ -13094,7 +13101,7 @@ struct nvm_cfg1_port {
#define NVM_CFG1_PORT_DRV_LINK_SPEED_AUTONEG 0x0
#define NVM_CFG1_PORT_DRV_LINK_SPEED_1G 0x1
#define NVM_CFG1_PORT_DRV_LINK_SPEED_10G 0x2
-#define NVM_CFG1_PORT_DRV_LINK_SPEED_20G 0x3
+#define NVM_CFG1_PORT_DRV_LINK_SPEED_20G 0x3
#define NVM_CFG1_PORT_DRV_LINK_SPEED_25G 0x4
#define NVM_CFG1_PORT_DRV_LINK_SPEED_40G 0x5
#define NVM_CFG1_PORT_DRV_LINK_SPEED_50G 0x6
diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.h b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
index 5e50405854e6..ea956c43e596 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_mcp.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.h
@@ -16,15 +16,15 @@
#include "qed_dev_api.h"

struct qed_mcp_link_speed_params {
- bool autoneg;
- u32 advertised_speeds; /* bitmask of DRV_SPEED_CAPABILITY */
- u32 forced_speed; /* In Mb/s */
+ bool autoneg;
+ u32 advertised_speeds;
+ u32 forced_speed; /* In Mb/s */
};

struct qed_mcp_link_pause_params {
- bool autoneg;
- bool forced_rx;
- bool forced_tx;
+ bool autoneg;
+ bool forced_rx;
+ bool forced_tx;
};

enum qed_mcp_eee_mode {
--
2.25.1

2020-07-17 01:19:29

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH net-next 10/13] qed: add support for new port modes

On Thu, 16 Jul 2020 14:54:43 +0300 Alexander Lobakin wrote:
> These ports ship on new boards revisions and are supported by newer
> firmware versions.
>
> Signed-off-by: Alexander Lobakin <[email protected]>
> Signed-off-by: Igor Russkikh <[email protected]>

What is the driver actually doing with them, tho?

Looks like you translate some firmware specific field to a driver
specific field, but I can't figure out what part of the code cares
about hw_info.port_mode

> diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
> index 6a1d12da7910..63fcbd5a295a 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed.h
> +++ b/drivers/net/ethernet/qlogic/qed/qed.h
> @@ -257,6 +257,11 @@ enum QED_PORT_MODE {
> QED_PORT_MODE_DE_1X25G,
> QED_PORT_MODE_DE_4X25G,
> QED_PORT_MODE_DE_2X10G,
> + QED_PORT_MODE_DE_2X50G_R1,
> + QED_PORT_MODE_DE_4X50G_R1,
> + QED_PORT_MODE_DE_1X100G_R2,
> + QED_PORT_MODE_DE_2X100G_R2,
> + QED_PORT_MODE_DE_1X100G_R4,
> };
>
> enum qed_dev_cap {
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
> index d929556247a5..4bad836d0f74 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
> @@ -4026,6 +4026,21 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
> case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G:
> p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X25G;
> break;
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1:
> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X50G_R1;
> + break;
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1:
> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X50G_R1;
> + break;
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2:
> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G_R2;
> + break;
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2:
> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X100G_R2;
> + break;
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4:
> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G_R4;
> + break;
> default:
> DP_NOTICE(p_hwfn, "Unknown port mode in 0x%08x\n", core_cfg);
> break;
> diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
> index a4a845579fd2..debc55923251 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
> +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
> @@ -13015,6 +13015,11 @@ struct nvm_cfg1_glob {
> #define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G 0xd
> #define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G 0xe
> #define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G 0xf
> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1 0x11
> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1 0x12
> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2 0x13
> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2 0x14
> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4 0x15
>
> u32 e_lane_cfg1;
> u32 e_lane_cfg2;

2020-07-17 10:45:57

by Alexander Lobakin

[permalink] [raw]
Subject: Re: [PATCH net-next 10/13] qed: add support for new port modes

From: Jakub Kicinski <[email protected]>
Date: Thu, 16 Jul 2020 18:18:57 -0700

Hi Jakub,

> On Thu, 16 Jul 2020 14:54:43 +0300 Alexander Lobakin wrote:
>> These ports ship on new boards revisions and are supported by newer
>> firmware versions.
>>
>> Signed-off-by: Alexander Lobakin <[email protected]>
>> Signed-off-by: Igor Russkikh <[email protected]>
>
> What is the driver actually doing with them, tho?
>
> Looks like you translate some firmware specific field to a driver
> specific field, but I can't figure out what part of the code cares
> about hw_info.port_mode

You're right, we just check NVM port type for validity and store it
for the case of future expansions. Is that OK or I should do smth
with that?

>> diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
>> index 6a1d12da7910..63fcbd5a295a 100644
>> --- a/drivers/net/ethernet/qlogic/qed/qed.h
>> +++ b/drivers/net/ethernet/qlogic/qed/qed.h
>> @@ -257,6 +257,11 @@ enum QED_PORT_MODE {
>> QED_PORT_MODE_DE_1X25G,
>> QED_PORT_MODE_DE_4X25G,
>> QED_PORT_MODE_DE_2X10G,
>> + QED_PORT_MODE_DE_2X50G_R1,
>> + QED_PORT_MODE_DE_4X50G_R1,
>> + QED_PORT_MODE_DE_1X100G_R2,
>> + QED_PORT_MODE_DE_2X100G_R2,
>> + QED_PORT_MODE_DE_1X100G_R4,
>> };
>>
>> enum qed_dev_cap {
>> diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
>> index d929556247a5..4bad836d0f74 100644
>> --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
>> +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
>> @@ -4026,6 +4026,21 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
>> case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G:
>> p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X25G;
>> break;
>> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1:
>> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X50G_R1;
>> + break;
>> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1:
>> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X50G_R1;
>> + break;
>> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2:
>> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G_R2;
>> + break;
>> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2:
>> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_2X100G_R2;
>> + break;
>> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4:
>> + p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_1X100G_R4;
>> + break;
>> default:
>> DP_NOTICE(p_hwfn, "Unknown port mode in 0x%08x\n", core_cfg);
>> break;
>> diff --git a/drivers/net/ethernet/qlogic/qed/qed_hsi.h b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
>> index a4a845579fd2..debc55923251 100644
>> --- a/drivers/net/ethernet/qlogic/qed/qed_hsi.h
>> +++ b/drivers/net/ethernet/qlogic/qed/qed_hsi.h
>> @@ -13015,6 +13015,11 @@ struct nvm_cfg1_glob {
>> #define NVM_CFG1_GLOB_NETWORK_PORT_MODE_1X25G 0xd
>> #define NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G 0xe
>> #define NVM_CFG1_GLOB_NETWORK_PORT_MODE_2X10G 0xf
>> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1 0x11
>> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1 0x12
>> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2 0x13
>> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2 0x14
>> +#define NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4 0x15
>>
>> u32 e_lane_cfg1;
>> u32 e_lane_cfg2;

Al

2020-07-17 10:50:17

by Igor Russkikh

[permalink] [raw]
Subject: Re: [EXT] Re: [PATCH net-next 10/13] qed: add support for new port modes



> ----------------------------------------------------------------------
> On Thu, 16 Jul 2020 14:54:43 +0300 Alexander Lobakin wrote:
>> These ports ship on new boards revisions and are supported by newer
>> firmware versions.
>>
>> Signed-off-by: Alexander Lobakin <[email protected]>
>> Signed-off-by: Igor Russkikh <[email protected]>
>
> What is the driver actually doing with them, tho?
>
> Looks like you translate some firmware specific field to a driver
> specific field, but I can't figure out what part of the code cares
> about hw_info.port_mode

Hi Jakub,

You are right, this info is never used/reported.

Alexander is extending already existing non used field with new values from
our latest hardware revisions.

I thought devlink info could be a good place to output such kind of information.

Thats basically a layout of *Physical* ports on device - quite useful info I
think.

Important thing is these ports may not be directly mapped to PCI PFs. So
reading `ethtool eth*` may not explain you the real device capabilities.

Do you think it makes sense adding such info to `devlink info` then?

Thanks
Igor

2020-07-17 18:33:15

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [EXT] Re: [PATCH net-next 10/13] qed: add support for new port modes

On Fri, 17 Jul 2020 13:49:33 +0300 Igor Russkikh wrote:
> > ----------------------------------------------------------------------
> > On Thu, 16 Jul 2020 14:54:43 +0300 Alexander Lobakin wrote:
> >> These ports ship on new boards revisions and are supported by newer
> >> firmware versions.
> >>
> >> Signed-off-by: Alexander Lobakin <[email protected]>
> >> Signed-off-by: Igor Russkikh <[email protected]>
> >
> > What is the driver actually doing with them, tho?
> >
> > Looks like you translate some firmware specific field to a driver
> > specific field, but I can't figure out what part of the code cares
> > about hw_info.port_mode
>
> Hi Jakub,
>
> You are right, this info is never used/reported.
>
> Alexander is extending already existing non used field with new values from
> our latest hardware revisions.
>
> I thought devlink info could be a good place to output such kind of information.
>
> Thats basically a layout of *Physical* ports on device - quite useful info I
> think.
>
> Important thing is these ports may not be directly mapped to PCI PFs. So
> reading `ethtool eth*` may not explain you the real device capabilities.
>
> Do you think it makes sense adding such info to `devlink info` then?

Devlink port has information about physical port, which don't have to
map 1:1 to netdevs. It also has lanes and port splitting which you may
want to report.


For now please make sure to not include any dead code in your
submissions (register defines etc. may be okay), perhaps try:

diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index d929556247a5..4bad836d0f74 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -4026,6 +4026,21 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G:
p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X25G;
break;
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2:
+ case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4:
+ /* TODO: set port_mode when it's actually used */
+ break;
default:
DP_NOTICE(p_hwfn, "Unknown port mode in 0x%08x\n", core_cfg);
break;

And see if it will pass the muster.

Dead code makes it harder to review the patches.

2020-07-17 19:30:11

by Alexander Lobakin

[permalink] [raw]
Subject: Re: [PATCH net-next 10/13] qed: add support for new port modes

Date: Fri, 17 Jul 2020 11:31:55 -0700
From: Jakub Kicinski <[email protected]>

> On Fri, 17 Jul 2020 13:49:33 +0300 Igor Russkikh wrote:
>>> ----------------------------------------------------------------------
>>> On Thu, 16 Jul 2020 14:54:43 +0300 Alexander Lobakin wrote:
>>>> These ports ship on new boards revisions and are supported by newer
>>>> firmware versions.
>>>>
>>>> Signed-off-by: Alexander Lobakin <[email protected]>
>>>> Signed-off-by: Igor Russkikh <[email protected]>
>>>
>>> What is the driver actually doing with them, tho?
>>>
>>> Looks like you translate some firmware specific field to a driver
>>> specific field, but I can't figure out what part of the code cares
>>> about hw_info.port_mode
>>
>> Hi Jakub,
>>
>> You are right, this info is never used/reported.
>>
>> Alexander is extending already existing non used field with new values from
>> our latest hardware revisions.
>>
>> I thought devlink info could be a good place to output such kind of information.
>>
>> Thats basically a layout of *Physical* ports on device - quite useful info I
>> think.
>>
>> Important thing is these ports may not be directly mapped to PCI PFs. So
>> reading `ethtool eth*` may not explain you the real device capabilities.
>>
>> Do you think it makes sense adding such info to `devlink info` then?
>
> Devlink port has information about physical port, which don't have to
> map 1:1 to netdevs. It also has lanes and port splitting which you may
> want to report.
>
>
> For now please make sure to not include any dead code in your
> submissions (register defines etc. may be okay), perhaps try:

I think it would be better to drop this struct member at all since it's
really not used anywhere. There'll be no problem to add it back anytime
we might need it, but for now it seems unreasonable to keep it "just in
case".

Got it, thanks, will send v2 soon.

> diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
> index d929556247a5..4bad836d0f74 100644
> --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
> +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
> @@ -4026,6 +4026,21 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
> case NVM_CFG1_GLOB_NETWORK_PORT_MODE_4X25G:
> p_hwfn->hw_info.port_mode = QED_PORT_MODE_DE_4X25G;
> break;
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X50G_R1:
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_4X50G_R1:
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R2:
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_2X100G_R2:
> + case NVM_CFG1_GLOB_NETWORK_PORT_MODE_AHP_1X100G_R4:
> + /* TODO: set port_mode when it's actually used */
> + break;
> default:
> DP_NOTICE(p_hwfn, "Unknown port mode in 0x%08x\n", core_cfg);
> break;
>
> And see if it will pass the muster.
>
> Dead code makes it harder to review the patches.