An active DAC can be misidentified as a 40G optical module, in which
case the driver reports 40G and enables autoneg for a module that
does not support it; DACs and optical modules are also treated
differently in the FFE, CTLE and capability-report paths.
Rework the AML40/AML link capabilities and DAC classification:
- Port the five-branch capability layout to AML40:
backplane, DAC (txgbe_is_dac_cable() plus the 10G-only AN-off
case), multispeed fiber, 40G QSFP and 10G SFP. Modules previously
misreported as 40G through the fallback now report the correct
speed and autoneg.
- Add the 40G-active transceiver identification (sfp_type enum and
identify branch).
- Unify DAC classification on txgbe_is_dac_cable(), so active DACs
are no longer treated as optical modules.
Fixes: fb6eb170dfa2 ("net/txgbe: add basic link configuration for Amber-Lite")
Cc: [email protected]
Signed-off-by: Zaiyu Wang <[email protected]>
---
drivers/net/txgbe/base/txgbe_aml.c | 3 +-
drivers/net/txgbe/base/txgbe_aml40.c | 71 ++++++++++++++++++++++++----
drivers/net/txgbe/base/txgbe_e56.c | 6 +--
drivers/net/txgbe/base/txgbe_phy.c | 7 +++
drivers/net/txgbe/base/txgbe_phy.h | 1 +
drivers/net/txgbe/base/txgbe_type.h | 2 +
6 files changed, 74 insertions(+), 16 deletions(-)
diff --git a/drivers/net/txgbe/base/txgbe_aml.c
b/drivers/net/txgbe/base/txgbe_aml.c
index ac80d85f08..fe4becf198 100644
--- a/drivers/net/txgbe/base/txgbe_aml.c
+++ b/drivers/net/txgbe/base/txgbe_aml.c
@@ -103,8 +103,7 @@ s32 txgbe_get_link_capabilities_aml(struct txgbe_hw *hw,
*speed = TXGBE_LINK_SPEED_10GB_FULL |
TXGBE_LINK_SPEED_25GB_FULL;
*autoneg = true;
- } else if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
- hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) {
+ } else if (txgbe_is_dac_cable(hw)) {
if (hw->phy.fiber_suppport_speed ==
TXGBE_LINK_SPEED_10GB_FULL) {
hw->devarg.auto_neg = false;
diff --git a/drivers/net/txgbe/base/txgbe_aml40.c
b/drivers/net/txgbe/base/txgbe_aml40.c
index bfb8a4bc7f..b4371921cd 100644
--- a/drivers/net/txgbe/base/txgbe_aml40.c
+++ b/drivers/net/txgbe/base/txgbe_aml40.c
@@ -95,26 +95,77 @@ s32 txgbe_check_mac_link_aml40(struct txgbe_hw *hw, u32
*speed,
return 0;
}
+static int txgbe_is_40g_fiber_qsfp(struct txgbe_hw *hw)
+{
+ if (hw->phy.sfp_type == txgbe_qsfp_type_40g_sr_core0 ||
+ hw->phy.sfp_type == txgbe_qsfp_type_40g_sr_core1 ||
+ hw->phy.sfp_type == txgbe_qsfp_type_40g_lr_core0 ||
+ hw->phy.sfp_type == txgbe_qsfp_type_40g_lr_core1 ||
+ hw->phy.sfp_type == txgbe_qsfp_type_40g_active_core0 ||
+ hw->phy.sfp_type == txgbe_qsfp_type_40g_active_core1)
+ return true;
+
+ return false;
+}
+
+static int txgbe_is_10g_fiber_sfp(struct txgbe_hw *hw)
+{
+ if (hw->phy.sfp_type == txgbe_sfp_type_srlr_core0 ||
+ hw->phy.sfp_type == txgbe_sfp_type_srlr_core1)
+ return true;
+
+ return false;
+}
+
s32 txgbe_get_link_capabilities_aml40(struct txgbe_hw *hw,
u32 *speed,
bool *autoneg)
{
- if (hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core0 ||
- hw->phy.sfp_type == txgbe_qsfp_type_40g_cu_core1) {
- *speed = TXGBE_LINK_SPEED_40GB_FULL;
+ PMD_DRV_LOG(DEBUG, "port[%d]hw->phy.sfp_type = %d",
+ hw->bus.lan_id, hw->phy.sfp_type);
+
+ /* Backplane */
+ if (txgbe_is_backplane(hw)) {
+ *speed = TXGBE_LINK_SPEED_10GB_FULL |
+ TXGBE_LINK_SPEED_40GB_FULL;
+ /* Backplane supports autonegotiation */
+ *autoneg = hw->devarg.auto_neg;
+ return 0;
+ }
+
+ /* Fiber or DAC cable */
+ if (txgbe_is_dac_cable(hw)) {
+ /*
+ * 10G-only DAC cable: legacy build-time AUTO=0/1 default
+ * mode forces AN off. DPDK equivalent: devarg.auto_neg == 0.
+ */
+ if (hw->phy.fiber_suppport_speed ==
+ TXGBE_LINK_SPEED_10GB_FULL &&
+ hw->devarg.auto_neg == 0) {
+ *autoneg = false;
+ } else {
+ *autoneg = hw->devarg.auto_neg;
+ }
+ *speed = hw->phy.fiber_suppport_speed;
+ } else if (hw->phy.multispeed_fiber) {
+ /* multispeed fiber must come before single-sfp/qsfp fiber */
+ *speed = TXGBE_LINK_SPEED_10GB_FULL |
+ TXGBE_LINK_SPEED_40GB_FULL;
*autoneg = true;
- } else if (txgbe_is_backplane(hw)) {
+ } else if (txgbe_is_40g_fiber_qsfp(hw)) {
*speed = TXGBE_LINK_SPEED_40GB_FULL;
- *autoneg = true;
+ *autoneg = false;
+ } else if (txgbe_is_10g_fiber_sfp(hw)) {
+ *speed = TXGBE_LINK_SPEED_10GB_FULL;
+ *autoneg = false;
} else {
/*
- * Temporary workaround: set speed to 40G even if sfp not
present
- * to avoid TXGBE_ERR_LINK_SETUP returned by setup_mac_link, but
- * a more reasonable solution is don't execute setup_mac_link
when
- * sfp module not present.
+ * Unknown / unsupported module: keep 40G default to avoid
+ * TXGBE_ERR_LINK_SETUP returned by setup_mac_link, mirroring
+ * the temporary workaround in the previous version.
*/
*speed = TXGBE_LINK_SPEED_40GB_FULL;
- *autoneg = true;
+ *autoneg = false;
}
return 0;
diff --git a/drivers/net/txgbe/base/txgbe_e56.c
b/drivers/net/txgbe/base/txgbe_e56.c
index 8e986daf96..cc168a9f81 100644
--- a/drivers/net/txgbe/base/txgbe_e56.c
+++ b/drivers/net/txgbe/base/txgbe_e56.c
@@ -73,8 +73,7 @@ u32 txgbe_e56_tx_ffe_cfg(struct txgbe_hw *hw, u32 speed)
pre2 = S10G_TX_FFE_CFG_PRE2;
post = S10G_TX_FFE_CFG_POST;
} else if (speed == TXGBE_LINK_SPEED_25GB_FULL) {
- if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
- hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1 ||
+ if (txgbe_is_dac_cable(hw) ||
txgbe_is_backplane(hw)) {
ffe_main = S25G_TX_FFE_CFG_DAC_MAIN;
pre1 = S25G_TX_FFE_CFG_DAC_PRE1;
@@ -2622,8 +2621,7 @@ txgbe_e56_rxs_calib_adapt_seq(struct txgbe_hw *hw, u32
speed)
u32 rdata = 0x0;
bool bypass_ctle = true;
- if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 ||
- hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1)
+ if (txgbe_is_dac_cable(hw))
bypass_ctle = 0;
if (hw->mac.type == txgbe_mac_aml) {
diff --git a/drivers/net/txgbe/base/txgbe_phy.c
b/drivers/net/txgbe/base/txgbe_phy.c
index 10df23afae..e52f1da87d 100644
--- a/drivers/net/txgbe/base/txgbe_phy.c
+++ b/drivers/net/txgbe/base/txgbe_phy.c
@@ -1156,6 +1156,13 @@ s32 txgbe_identify_qsfp_module(struct txgbe_hw *hw)
else
hw->phy.sfp_type = txgbe_qsfp_type_40g_lr_core1;
}
+
+ if (transceiver_type & TXGBE_SFF_ETHERNET_40G_ACTIVE) {
+ if (hw->bus.lan_id == 0)
+ hw->phy.sfp_type =
txgbe_qsfp_type_40g_active_core0;
+ else
+ hw->phy.sfp_type =
txgbe_qsfp_type_40g_active_core1;
+ }
}
hw->mac.release_swfw_sync(hw, TXGBE_MNGSEM_SWPHY);
diff --git a/drivers/net/txgbe/base/txgbe_phy.h
b/drivers/net/txgbe/base/txgbe_phy.h
index a5df015a4d..b00f00931c 100644
--- a/drivers/net/txgbe/base/txgbe_phy.h
+++ b/drivers/net/txgbe/base/txgbe_phy.h
@@ -310,6 +310,7 @@
#define TXGBE_SFF_ETHERNET_40G_CR4 MS(3, 0x1)
#define TXGBE_SFF_ETHERNET_40G_SR4 MS(2, 0x1)
#define TXGBE_SFF_ETHERNET_40G_LR4 MS(1, 0x1)
+#define TXGBE_SFF_ETHERNET_40G_ACTIVE MS(0, 0x1)
#define TXGBE_SFF_SOFT_RS_SELECT_MASK 0x8
#define TXGBE_SFF_SOFT_RS_SELECT_10G 0x8
diff --git a/drivers/net/txgbe/base/txgbe_type.h
b/drivers/net/txgbe/base/txgbe_type.h
index 39a70746a7..91771b9cbd 100644
--- a/drivers/net/txgbe/base/txgbe_type.h
+++ b/drivers/net/txgbe/base/txgbe_type.h
@@ -249,6 +249,8 @@ enum txgbe_sfp_type {
txgbe_qsfp_type_40g_sr_core1,
txgbe_qsfp_type_40g_lr_core0,
txgbe_qsfp_type_40g_lr_core1,
+ txgbe_qsfp_type_40g_active_core0,
+ txgbe_qsfp_type_40g_active_core1,
txgbe_sfp_type_not_present = 0xFFFE,
txgbe_sfp_type_not_known = 0xFFFF
};
--
2.55.0.windows.2