DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 01/24] net/axgbe: remove use of comm_owned field
@ 2024-04-12 12:52 Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 02/24] net/axgbe: remove field of SFP diagnostic support Venkat Kumar Ande
                   ` (23 more replies)
  0 siblings, 24 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The comm_owned field can hide logic where double locking is attempted
and prevent multiple threads for the same device from accessing the
mutex properly.  Remove the comm_owned field and use the mutex API
exclusively for gaining ownership.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 44ff28517c..70e7c56439 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -205,8 +205,6 @@ struct axgbe_phy_data {
 
 	unsigned int mdio_addr;
 
-	unsigned int comm_owned;
-
 	/* SFP Support */
 	enum axgbe_sfp_comm sfp_comm;
 	unsigned int sfp_mux_address;
@@ -254,12 +252,6 @@ static enum axgbe_an_mode axgbe_phy_an_mode(struct axgbe_port *pdata);
 static int axgbe_phy_i2c_xfer(struct axgbe_port *pdata,
 			      struct axgbe_i2c_op *i2c_op)
 {
-	struct axgbe_phy_data *phy_data = pdata->phy_data;
-
-	/* Be sure we own the bus */
-	if (!phy_data->comm_owned)
-		return -EIO;
-
 	return pdata->i2c_if.i2c_xfer(pdata, i2c_op);
 }
 
@@ -400,10 +392,6 @@ static int axgbe_phy_sfp_get_mux(struct axgbe_port *pdata)
 
 static void axgbe_phy_put_comm_ownership(struct axgbe_port *pdata)
 {
-	struct axgbe_phy_data *phy_data = pdata->phy_data;
-
-	phy_data->comm_owned = 0;
-
 	pthread_mutex_unlock(&pdata->phy_mutex);
 }
 
@@ -419,9 +407,6 @@ static int axgbe_phy_get_comm_ownership(struct axgbe_port *pdata)
 	 */
 	pthread_mutex_lock(&pdata->phy_mutex);
 
-	if (phy_data->comm_owned)
-		return 0;
-
 	/* Clear the mutexes */
 	XP_IOWRITE(pdata, XP_I2C_MUTEX, AXGBE_MUTEX_RELEASE);
 	XP_IOWRITE(pdata, XP_MDIO_MUTEX, AXGBE_MUTEX_RELEASE);
@@ -444,7 +429,6 @@ static int axgbe_phy_get_comm_ownership(struct axgbe_port *pdata)
 		XP_IOWRITE(pdata, XP_I2C_MUTEX, mutex_id);
 		XP_IOWRITE(pdata, XP_MDIO_MUTEX, mutex_id);
 
-		phy_data->comm_owned = 1;
 		return 0;
 	}
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 02/24] net/axgbe: remove field of SFP diagnostic support
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 03/24] net/axgbe: improve SFP 100Mbps auto-negotiation Venkat Kumar Ande
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The driver currently sets an indication of whether the SFP supports, and
that the driver can obtain, diagnostics data.  This isn't currently used
by the driver.  Remove this field and the logic supporting it.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 70e7c56439..e1b926d48a 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -220,7 +220,6 @@ struct axgbe_phy_data {
 	unsigned int sfp_rx_los;
 	unsigned int sfp_tx_fault;
 	unsigned int sfp_mod_absent;
-	unsigned int sfp_diags;
 	unsigned int sfp_changed;
 	unsigned int sfp_phy_avail;
 	unsigned int sfp_cable_len;
@@ -701,14 +700,6 @@ static int axgbe_phy_sfp_read_eeprom(struct axgbe_port *pdata)
 	if (memcmp(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom))) {
 		phy_data->sfp_changed = 1;
 		memcpy(&phy_data->sfp_eeprom, &sfp_eeprom, sizeof(sfp_eeprom));
-
-		if (sfp_eeprom.extd[AXGBE_SFP_EXTD_SFF_8472]) {
-			uint8_t diag_type;
-			diag_type = sfp_eeprom.extd[AXGBE_SFP_EXTD_DIAG];
-
-			if (!(diag_type & AXGBE_SFP_EXTD_DIAG_ADDR_CHANGE))
-				phy_data->sfp_diags = 1;
-		}
 	} else {
 		phy_data->sfp_changed = 0;
 	}
@@ -769,7 +760,6 @@ static void axgbe_phy_sfp_reset(struct axgbe_phy_data *phy_data)
 	phy_data->sfp_rx_los = 0;
 	phy_data->sfp_tx_fault = 0;
 	phy_data->sfp_mod_absent = 1;
-	phy_data->sfp_diags = 0;
 	phy_data->sfp_base = AXGBE_SFP_BASE_UNKNOWN;
 	phy_data->sfp_cable = AXGBE_SFP_CABLE_UNKNOWN;
 	phy_data->sfp_speed = AXGBE_SFP_SPEED_UNKNOWN;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 03/24] net/axgbe: improve SFP 100Mbps auto-negotiation
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 02/24] net/axgbe: remove field of SFP diagnostic support Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 04/24] net/axgbe: check mdio for non-zero ports and CL45 PHYs Venkat Kumar Ande
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

After changing speed to 100Mbps as a result of auto-negotiation (AN),
some 10/100/1000Mbps SFPs indicate a successful link (no faults or loss
of signal), but cannot successfully transmit or receive data.  These
SFPs required an extra auto-negotiation (AN) after the speed change in
order to operate properly.  Add a quirk for these SFPs so that if the
outcome of the AN actually results in changing to a new speed, re-initiate
AN at that new speed.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_ethdev.h   |  1 +
 drivers/net/axgbe/axgbe_mdio.c     | 73 ++++++++++++++++--------------
 drivers/net/axgbe/axgbe_phy_impl.c |  5 ++
 3 files changed, 46 insertions(+), 33 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index df5d63c493..924a26ebe3 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -656,6 +656,7 @@ struct axgbe_port {
 	enum axgbe_an an_state;
 	enum axgbe_rx kr_state;
 	enum axgbe_rx kx_state;
+	unsigned int an_again;
 	unsigned int an_supported;
 	unsigned int parallel_detect;
 	unsigned int fec_ability;
diff --git a/drivers/net/axgbe/axgbe_mdio.c b/drivers/net/axgbe/axgbe_mdio.c
index 913ceada0d..0beeb1d0f5 100644
--- a/drivers/net/axgbe/axgbe_mdio.c
+++ b/drivers/net/axgbe/axgbe_mdio.c
@@ -200,13 +200,14 @@ static void axgbe_switch_mode(struct axgbe_port *pdata)
 	axgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
 }
 
-static void axgbe_set_mode(struct axgbe_port *pdata,
+static bool axgbe_set_mode(struct axgbe_port *pdata,
 			   enum axgbe_mode mode)
 {
 	if (mode == axgbe_cur_mode(pdata))
-		return;
+		return false;
 
 	axgbe_change_mode(pdata, mode);
+	return true;
 }
 
 static bool axgbe_use_mode(struct axgbe_port *pdata,
@@ -880,21 +881,22 @@ static int axgbe_phy_config_fixed(struct axgbe_port *pdata)
 	return 0;
 }
 
-static int __axgbe_phy_config_aneg(struct axgbe_port *pdata)
+static int __axgbe_phy_config_aneg(struct axgbe_port *pdata, bool set_mode)
 {
 	int ret;
 
+	pthread_mutex_lock(&pdata->an_mutex);
 	rte_bit_relaxed_set32(AXGBE_LINK_INIT, &pdata->dev_state);
 	pdata->link_check = rte_get_timer_cycles();
 
 	ret = pdata->phy_if.phy_impl.an_config(pdata);
 	if (ret)
-		return ret;
+		goto out;
 
 	if (pdata->phy.autoneg != AUTONEG_ENABLE) {
 		ret = axgbe_phy_config_fixed(pdata);
 		if (ret || !pdata->kr_redrv)
-			return ret;
+			goto out;
 		PMD_DRV_LOG(DEBUG, "AN redriver support\n");
 	} else {
 		PMD_DRV_LOG(DEBUG, "AN PHY configuration\n");
@@ -904,23 +906,26 @@ static int __axgbe_phy_config_aneg(struct axgbe_port *pdata)
 	rte_intr_disable(pdata->pci_dev->intr_handle);
 
 	/* Start auto-negotiation in a supported mode */
-	if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) {
-		axgbe_set_mode(pdata, AXGBE_MODE_KR);
-	} else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) {
-		axgbe_set_mode(pdata, AXGBE_MODE_KX_2500);
-	} else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) {
-		axgbe_set_mode(pdata, AXGBE_MODE_KX_1000);
-	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) {
-		axgbe_set_mode(pdata, AXGBE_MODE_SFI);
-	} else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) {
-		axgbe_set_mode(pdata, AXGBE_MODE_X);
-	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) {
-		axgbe_set_mode(pdata, AXGBE_MODE_SGMII_1000);
-	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
-		axgbe_set_mode(pdata, AXGBE_MODE_SGMII_100);
-	} else {
-		rte_intr_enable(pdata->pci_dev->intr_handle);
-		return -EINVAL;
+	if (set_mode) {
+		if (axgbe_use_mode(pdata, AXGBE_MODE_KR)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_KR);
+		} else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_2500)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_KX_2500);
+		} else if (axgbe_use_mode(pdata, AXGBE_MODE_KX_1000)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_KX_1000);
+		} else if (axgbe_use_mode(pdata, AXGBE_MODE_SFI)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_SFI);
+		} else if (axgbe_use_mode(pdata, AXGBE_MODE_X)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_X);
+		} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_1000)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_SGMII_1000);
+		} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_SGMII_100);
+		} else {
+			rte_intr_enable(pdata->pci_dev->intr_handle);
+			ret = -EINVAL;
+			goto out;
+		}
 	}
 
 	/* Disable and stop any in progress auto-negotiation */
@@ -938,16 +943,7 @@ static int __axgbe_phy_config_aneg(struct axgbe_port *pdata)
 	axgbe_an_init(pdata);
 	axgbe_an_restart(pdata);
 
-	return 0;
-}
-
-static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
-{
-	int ret;
-
-	pthread_mutex_lock(&pdata->an_mutex);
-
-	ret = __axgbe_phy_config_aneg(pdata);
+out:
 	if (ret)
 		rte_bit_relaxed_set32(AXGBE_LINK_ERR, &pdata->dev_state);
 	else
@@ -958,6 +954,16 @@ static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
 	return ret;
 }
 
+static int axgbe_phy_config_aneg(struct axgbe_port *pdata)
+{
+	return __axgbe_phy_config_aneg(pdata, true);
+}
+
+static int axgbe_phy_reconfig_aneg(struct axgbe_port *pdata)
+{
+	return __axgbe_phy_config_aneg(pdata, false);
+}
+
 static bool axgbe_phy_aneg_done(struct axgbe_port *pdata)
 {
 	return pdata->an_result == AXGBE_AN_COMPLETE;
@@ -1016,7 +1022,8 @@ static void axgbe_phy_status_result(struct axgbe_port *pdata)
 
 	pdata->phy.duplex = DUPLEX_FULL;
 
-	axgbe_set_mode(pdata, mode);
+	if (axgbe_set_mode(pdata, mode) && pdata->an_again)
+		axgbe_phy_reconfig_aneg(pdata);
 }
 
 static int autoneg_time_out(unsigned long autoneg_start_time)
diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index e1b926d48a..5acccf9146 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -560,6 +560,8 @@ static bool axgbe_phy_belfuse_parse_quirks(struct axgbe_port *pdata)
 	if (memcmp(&sfp_eeprom->base[AXGBE_SFP_BASE_VENDOR_NAME],
 		   AXGBE_BEL_FUSE_VENDOR, strlen(AXGBE_BEL_FUSE_VENDOR)))
 		return false;
+	/* For Bel-Fuse, use the extra AN flag */
+	pdata->an_again = 1;
 
 	if (!memcmp(&sfp_eeprom->base[AXGBE_SFP_BASE_VENDOR_PN],
 		    AXGBE_BEL_FUSE_PARTNO, strlen(AXGBE_BEL_FUSE_PARTNO))) {
@@ -796,6 +798,9 @@ static void axgbe_phy_sfp_detect(struct axgbe_port *pdata)
 	struct axgbe_phy_data *phy_data = pdata->phy_data;
 	int ret;
 
+	/* Clear the extra AN flag */
+	pdata->an_again = 0;
+
 	/* Reset the SFP signals and info */
 	axgbe_phy_sfp_reset(phy_data);
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 04/24] net/axgbe: check mdio for non-zero ports and CL45 PHYs
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 02/24] net/axgbe: remove field of SFP diagnostic support Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 03/24] net/axgbe: improve SFP 100Mbps auto-negotiation Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-22 15:21   ` Ferruh Yigit
  2024-04-12 12:52 ` [PATCH 05/24] net/axgbe: remove unnecessary conversion to bool Venkat Kumar Ande
                   ` (20 subsequent siblings)
  23 siblings, 1 reply; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The XGBE hardware has support for performing MDIO operations using an
MDIO command request. The driver mistakenly uses the mdio port address
as the MDIO command request device address instead of the MDIO command
request port address. Additionally, the driver does not properly check
for and create a clause 45 MDIO command.

Check the supplied MDIO register to determine if the request is a clause
45 operation (MII_ADDR_C45). For a clause 45 operation, extract device
address and register number from the supplied MDIO register and use them
to set the MDIO command request device address and register number fields.
For a clause 22 operation, the MDIO request device address is set to zero
and the MDIO command request register number is set to the supplied MDIO
register. In either case, the supplied MDIO port address is used as the
MDIO command request port address.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_common.h |  2 --
 drivers/net/axgbe/axgbe_dev.c    | 22 ++++++++++++++++------
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h
index a5d11c5832..51532fb34a 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -407,8 +407,6 @@
 #define MAC_MDIOSCAR_PA_WIDTH		5
 #define MAC_MDIOSCAR_RA_INDEX		0
 #define MAC_MDIOSCAR_RA_WIDTH		16
-#define MAC_MDIOSCAR_REG_INDEX		0
-#define MAC_MDIOSCAR_REG_WIDTH		21
 #define MAC_MDIOSCCDR_BUSY_INDEX	22
 #define MAC_MDIOSCCDR_BUSY_WIDTH	1
 #define MAC_MDIOSCCDR_CMD_INDEX		16
diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index 6a7fddffca..3389954aa6 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -63,15 +63,27 @@ static int mdio_complete(struct axgbe_port *pdata)
 	return 0;
 }
 
+static unsigned int axgbe_create_mdio_sca(int port, int reg)
+{
+	unsigned int mdio_sca, da;
+
+	da = (reg & MII_ADDR_C45) ? reg >> 16 : 0;
+
+	mdio_sca = 0;
+	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg);
+	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, PA, port);
+	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, da);
+
+	return mdio_sca;
+}
+
 static int axgbe_write_ext_mii_regs(struct axgbe_port *pdata, int addr,
 				    int reg, u16 val)
 {
 	unsigned int mdio_sca, mdio_sccd;
 	uint64_t timeout;
 
-	mdio_sca = 0;
-	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, REG, reg);
-	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, addr);
+	mdio_sca = axgbe_create_mdio_sca(addr, reg);
 	AXGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
 
 	mdio_sccd = 0;
@@ -97,9 +109,7 @@ static int axgbe_read_ext_mii_regs(struct axgbe_port *pdata, int addr,
 	unsigned int mdio_sca, mdio_sccd;
 	uint64_t timeout;
 
-	mdio_sca = 0;
-	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, REG, reg);
-	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, DA, addr);
+	mdio_sca = axgbe_create_mdio_sca(addr, reg);
 	AXGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
 
 	mdio_sccd = 0;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 05/24] net/axgbe: remove unnecessary conversion to bool
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (2 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 04/24] net/axgbe: check mdio for non-zero ports and CL45 PHYs Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 06/24] net/axgbe: reset link when the link never comes back Venkat Kumar Ande
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The conversion to bool is not needed, remove it.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 5acccf9146..b5796b13e0 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -657,7 +657,7 @@ static bool axgbe_phy_sfp_verify_eeprom(uint8_t cc_in, uint8_t *buf,
 	for (cc = 0; len; buf++, len--)
 		cc += *buf;
 
-	return (cc == cc_in) ? true : false;
+	return cc == cc_in;
 }
 
 static int axgbe_phy_sfp_read_eeprom(struct axgbe_port *pdata)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 06/24] net/axgbe: reset link when the link never comes back
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (3 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 05/24] net/axgbe: remove unnecessary conversion to bool Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 07/24] net/axgbe: check fluctuations for 1G BELFUSE SFP Venkat Kumar Ande
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Normally, auto negotiation and reconnect should be automatically done by
the hardware. But there seems to be an issue where auto negotiation has
to be restarted manually. This happens because of link training and so
even though still connected to the partner the link never "comes back".
This needs an auto-negotiation restart.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_mdio.c     | 2 +-
 drivers/net/axgbe/axgbe_phy_impl.c | 7 +++++++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/axgbe/axgbe_mdio.c b/drivers/net/axgbe/axgbe_mdio.c
index 0beeb1d0f5..151b30e2ab 100644
--- a/drivers/net/axgbe/axgbe_mdio.c
+++ b/drivers/net/axgbe/axgbe_mdio.c
@@ -1058,7 +1058,7 @@ static void axgbe_phy_status(struct axgbe_port *pdata)
 							     &an_restart);
 	if (an_restart) {
 		axgbe_phy_config_aneg(pdata);
-		return;
+		goto adjust_link;
 	}
 
 	if (pdata->phy.link) {
diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index b5796b13e0..968ff1f867 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -1676,6 +1676,13 @@ static int axgbe_phy_link_status(struct axgbe_port *pdata, int *an_restart)
 	if (reg & MDIO_STAT1_LSTATUS)
 		return 1;
 
+	if (pdata->phy.autoneg == AUTONEG_ENABLE &&
+			phy_data->port_mode == AXGBE_PORT_MODE_BACKPLANE) {
+		if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state)) {
+			*an_restart = 1;
+		}
+	}
+
 	/* No link, attempt a receiver reset cycle */
 	if (phy_data->rrc_count++) {
 		phy_data->rrc_count = 0;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 07/24] net/axgbe: check fluctuations for 1G BELFUSE SFP
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (4 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 06/24] net/axgbe: reset link when the link never comes back Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 08/24] net/axgbe: update DMA coherency values Venkat Kumar Ande
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Frequent link up/down events can happen when a Bel Fuse SFP part is
connected to the amd-xgbe device. Try to avoid the frequent link
issues by resetting the PHY as documented in Bel Fuse SFP datasheets.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 968ff1f867..1ccb95334e 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -563,6 +563,9 @@ static bool axgbe_phy_belfuse_parse_quirks(struct axgbe_port *pdata)
 	/* For Bel-Fuse, use the extra AN flag */
 	pdata->an_again = 1;
 
+	/* Reset PHY - wait for self-clearing reset bit to clear */
+	pdata->phy_if.phy_impl.reset(pdata);
+
 	if (!memcmp(&sfp_eeprom->base[AXGBE_SFP_BASE_VENDOR_PN],
 		    AXGBE_BEL_FUSE_PARTNO, strlen(AXGBE_BEL_FUSE_PARTNO))) {
 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_SX;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 08/24] net/axgbe: update DMA coherency values
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (5 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 07/24] net/axgbe: check fluctuations for 1G BELFUSE SFP Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 09/24] net/axgbe: disable interrupts during device removal Venkat Kumar Ande
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Based on the IOMMU configuration, the current cache control settings can
result in possible coherency issues. The hardware team has recommended
new settings for the PCI device path to eliminate the issue.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_dev.c | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index 3389954aa6..9b0073eea6 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -647,23 +647,21 @@ static void axgbe_config_dma_cache(struct axgbe_port *pdata)
 	unsigned int arcache, awcache, arwcache;
 
 	arcache = 0;
-	AXGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, 0x3);
+	AXGMAC_SET_BITS(arcache, DMA_AXIARCR, DRC, 0xf);
+	AXGMAC_SET_BITS(arcache, DMA_AXIARCR, TEC, 0xf);
+	AXGMAC_SET_BITS(arcache, DMA_AXIARCR, THC, 0xf);
 	AXGMAC_IOWRITE(pdata, DMA_AXIARCR, arcache);
 
 	awcache = 0;
-	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, 0x3);
-	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, 0x3);
-	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPD, 0x1);
-	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, 0x3);
-	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHD, 0x1);
-	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RDC, 0x3);
-	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RDD, 0x1);
+	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, DWC, 0xf);
+	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RPC, 0xf);
+	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RHC, 0xf);
+	AXGMAC_SET_BITS(awcache, DMA_AXIAWCR, RDC, 0xf);
 	AXGMAC_IOWRITE(pdata, DMA_AXIAWCR, awcache);
 
 	arwcache = 0;
-	AXGMAC_SET_BITS(arwcache, DMA_AXIAWRCR, TDWD, 0x1);
-	AXGMAC_SET_BITS(arwcache, DMA_AXIAWRCR, TDWC, 0x3);
-	AXGMAC_SET_BITS(arwcache, DMA_AXIAWRCR, RDRC, 0x3);
+	AXGMAC_SET_BITS(arwcache, DMA_AXIAWRCR, TDWC, 0xf);
+	AXGMAC_SET_BITS(arwcache, DMA_AXIAWRCR, RDRC, 0xf);
 	AXGMAC_IOWRITE(pdata, DMA_AXIAWRCR, arwcache);
 }
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 09/24] net/axgbe: disable interrupts during device removal
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (6 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 08/24] net/axgbe: update DMA coherency values Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 10/24] net/axgbe: yellow carp devices do not need rrc Venkat Kumar Ande
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Hardware interrupts are enabled during the init, however,
they are not disabled during close.

Disable all hardware interrupts during close operation to avoid any
issues.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_ethdev.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index dd681f15a0..e5d8f7db02 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -2411,12 +2411,14 @@ static int
 axgbe_dev_close(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev;
+	struct axgbe_port *pdata;
 
 	PMD_INIT_FUNC_TRACE();
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	pdata = eth_dev->data->dev_private;
 	pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
 	axgbe_dev_clear_queues(eth_dev);
 
@@ -2426,6 +2428,9 @@ axgbe_dev_close(struct rte_eth_dev *eth_dev)
 				     axgbe_dev_interrupt_handler,
 				     (void *)eth_dev);
 
+	/* Disable all interrupts in the hardware */
+	XP_IOWRITE(pdata, XP_INT_EN, 0x0);
+
 	return 0;
 }
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 10/24] net/axgbe: yellow carp devices do not need rrc
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (7 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 09/24] net/axgbe: disable interrupts during device removal Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 11/24] net/axgbe: use definitions for mailbox commands Venkat Kumar Ande
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Link stability issues are noticed on Yellow carp platforms when Receiver
Reset Cycle is issued. Since the CDR workaround is disabled on these
platforms, the Receiver Reset Cycle is not needed.

So, avoid issuing rrc on Yellow carp platforms.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_ethdev.c   | 5 +++++
 drivers/net/axgbe/axgbe_ethdev.h   | 1 +
 drivers/net/axgbe/axgbe_phy_impl.c | 2 +-
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index e5d8f7db02..86c2ec64e0 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -208,6 +208,7 @@ static struct axgbe_version_data axgbe_v2a = {
 	.ecc_support			= 1,
 	.i2c_support			= 1,
 	.an_cdr_workaround		= 1,
+	.enable_rrc			= 1,
 };
 
 static struct axgbe_version_data axgbe_v2b = {
@@ -220,6 +221,7 @@ static struct axgbe_version_data axgbe_v2b = {
 	.ecc_support			= 1,
 	.i2c_support			= 1,
 	.an_cdr_workaround		= 1,
+	.enable_rrc			= 1,
 };
 
 static const struct rte_eth_desc_lim rx_desc_lim = {
@@ -2269,6 +2271,9 @@ eth_axgbe_dev_init(struct rte_eth_dev *eth_dev)
 
 			/* Yellow Carp devices do not need cdr workaround */
 			pdata->vdata->an_cdr_workaround = 0;
+
+			/* Yellow Carp devices do not need rrc */
+			pdata->vdata->enable_rrc = 0;
 		} else {
 			unknown_cpu = 1;
 		}
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 924a26ebe3..469b3876c0 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -463,6 +463,7 @@ struct axgbe_version_data {
 	unsigned int ecc_support;
 	unsigned int i2c_support;
 	unsigned int an_cdr_workaround;
+	unsigned int enable_rrc;
 };
 
 struct axgbe_mmc_stats {
diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 1ccb95334e..a58d51d606 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -1687,7 +1687,7 @@ static int axgbe_phy_link_status(struct axgbe_port *pdata, int *an_restart)
 	}
 
 	/* No link, attempt a receiver reset cycle */
-	if (phy_data->rrc_count++) {
+	if (pdata->vdata->enable_rrc && phy_data->rrc_count++) {
 		phy_data->rrc_count = 0;
 		axgbe_phy_rrc(pdata);
 	}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 11/24] net/axgbe: use definitions for mailbox commands
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (8 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 10/24] net/axgbe: yellow carp devices do not need rrc Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 12/24] net/axgbe: enable PLL control for fixed PHY modes only Venkat Kumar Ande
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Instead of using hardcoded values, use enumerations for mailbox command
and sub commands.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_ethdev.h   | 25 +++++++++++++++++++++++++
 drivers/net/axgbe/axgbe_phy_impl.c | 25 +++++++++++++++----------
 2 files changed, 40 insertions(+), 10 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 469b3876c0..20b36ced55 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -230,6 +230,31 @@ enum axgbe_mdio_mode {
 	AXGBE_MDIO_MODE_CL45,
 };
 
+enum axgbe_mb_cmd {
+	AXGBE_MB_CMD_POWER_OFF = 0,
+	AXGBE_MB_CMD_SET_1G,
+	AXGBE_MB_CMD_SET_2_5G,
+	AXGBE_MB_CMD_SET_10G_SFI,
+	AXGBE_MB_CMD_SET_10G_KR,
+	AXGBE_MB_CMD_RRC
+};
+
+enum axgbe_mb_subcmd {
+	AXGBE_MB_SUBCMD_NONE = 0,
+
+	/* 10GbE SFP subcommands */
+	AXGBE_MB_SUBCMD_ACTIVE = 0,
+	AXGBE_MB_SUBCMD_PASSIVE_1M,
+	AXGBE_MB_SUBCMD_PASSIVE_3M,
+	AXGBE_MB_SUBCMD_PASSIVE_OTHER,
+
+	/* 1GbE Mode subcommands */
+	AXGBE_MB_SUBCMD_10MBITS = 0,
+	AXGBE_MB_SUBCMD_100MBITS,
+	AXGBE_MB_SUBCMD_1G_SGMII,
+	AXGBE_MB_SUBCMD_1G_KX
+};
+
 struct axgbe_phy {
 	uint32_t supported;
 	uint32_t advertising;
diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index a58d51d606..8cc99d3a6b 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -1217,7 +1217,7 @@ static void axgbe_phy_pll_ctrl(struct axgbe_port *pdata, bool enable)
 }
 
 static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
-					unsigned int cmd, unsigned int sub_cmd)
+		enum axgbe_mb_cmd cmd, enum axgbe_mb_subcmd sub_cmd)
 {
 	unsigned int s0 = 0;
 	unsigned int wait;
@@ -1262,7 +1262,7 @@ static void axgbe_phy_rrc(struct axgbe_port *pdata)
 
 
 	/* Receiver Reset Cycle */
-	axgbe_phy_perform_ratechange(pdata, 5, 0);
+	axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_RRC, AXGBE_MB_SUBCMD_NONE);
 
 	PMD_DRV_LOG(DEBUG, "receiver reset complete\n");
 }
@@ -1272,7 +1272,7 @@ static void axgbe_phy_power_off(struct axgbe_port *pdata)
 	struct axgbe_phy_data *phy_data = pdata->phy_data;
 
 	/* Power off */
-	axgbe_phy_perform_ratechange(pdata, 0, 0);
+	axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_POWER_OFF, AXGBE_MB_SUBCMD_NONE);
 
 	phy_data->cur_mode = AXGBE_MODE_UNKNOWN;
 
@@ -1287,14 +1287,18 @@ static void axgbe_phy_sfi_mode(struct axgbe_port *pdata)
 
 	/* 10G/SFI */
 	if (phy_data->sfp_cable != AXGBE_SFP_CABLE_PASSIVE) {
-		axgbe_phy_perform_ratechange(pdata, 3, 0);
+		axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
+							AXGBE_MB_SUBCMD_ACTIVE);
 	} else {
 		if (phy_data->sfp_cable_len <= 1)
-			axgbe_phy_perform_ratechange(pdata, 3, 1);
+			axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
+							AXGBE_MB_SUBCMD_PASSIVE_1M);
 		else if (phy_data->sfp_cable_len <= 3)
-			axgbe_phy_perform_ratechange(pdata, 3, 2);
+			axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
+							AXGBE_MB_SUBCMD_PASSIVE_3M);
 		else
-			axgbe_phy_perform_ratechange(pdata, 3, 3);
+			axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
+							AXGBE_MB_SUBCMD_PASSIVE_OTHER);
 	}
 
 	phy_data->cur_mode = AXGBE_MODE_SFI;
@@ -1309,7 +1313,8 @@ static void axgbe_phy_kr_mode(struct axgbe_port *pdata)
 	axgbe_phy_set_redrv_mode(pdata);
 
 	/* 10G/KR */
-	axgbe_phy_perform_ratechange(pdata, 4, 0);
+		axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_KR,
+						AXGBE_MB_SUBCMD_NONE);
 	phy_data->cur_mode = AXGBE_MODE_KR;
 
 	PMD_DRV_LOG(DEBUG, "10GbE KR mode set\n");
@@ -1322,7 +1327,7 @@ static void axgbe_phy_kx_2500_mode(struct axgbe_port *pdata)
 	axgbe_phy_set_redrv_mode(pdata);
 
 	/* 2.5G/KX */
-	axgbe_phy_perform_ratechange(pdata, 2, 0);
+	axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_2_5G, AXGBE_MB_SUBCMD_NONE);
 	phy_data->cur_mode = AXGBE_MODE_KX_2500;
 }
 
@@ -1333,7 +1338,7 @@ static void axgbe_phy_sgmii_1000_mode(struct axgbe_port *pdata)
 	axgbe_phy_set_redrv_mode(pdata);
 
 	/* 1G/SGMII */
-	axgbe_phy_perform_ratechange(pdata, 1, 2);
+	axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_1G, AXGBE_MB_SUBCMD_1G_SGMII);
 
 	phy_data->cur_mode = AXGBE_MODE_SGMII_1000;
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 12/24] net/axgbe: enable PLL control for fixed PHY modes only
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (9 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 11/24] net/axgbe: use definitions for mailbox commands Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 13/24] net/axgbe: improve the SFP codes check for DAC cables Venkat Kumar Ande
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

PLL control setting(RRC) is needed only in fixed PHY configuration to
fix the peer-peer issues. Without the PLL control setting, the link up
takes longer time in a fixed phy configuration.

Driver implements SW RRC for Autoneg On configuration, hence PLL control
setting (RRC) is not needed for AN On configuration, and can be skipped.

Also, PLL re-initialization is not needed for PHY Power Off and RRC
commands. Otherwise, they lead to mailbox errors. Added the changes
accordingly.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 8cc99d3a6b..ceff36df3d 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -1207,6 +1207,10 @@ static void axgbe_phy_rx_reset(struct axgbe_port *pdata)
 
 static void axgbe_phy_pll_ctrl(struct axgbe_port *pdata, bool enable)
 {
+	/* PLL_CTRL feature needs to be enabled for fixed PHY modes (Non-Autoneg) only */
+	if (pdata->phy.autoneg != AUTONEG_DISABLE)
+		return;
+
 	XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_VEND2_PMA_MISC_CTRL0,
 			XGBE_PMA_PLL_CTRL_MASK,
 			enable ? XGBE_PMA_PLL_CTRL_SET
@@ -1251,8 +1255,10 @@ static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
 	axgbe_phy_rx_reset(pdata);
 
 reenable_pll:
-	 /* Re-enable the PLL control */
-	axgbe_phy_pll_ctrl(pdata, true);
+	/* Enable PLL re-initialization, not needed for PHY Power Off and RRC cmds */
+	if (cmd != AXGBE_MB_CMD_POWER_OFF &&
+	    cmd != AXGBE_MB_CMD_RRC)
+		axgbe_phy_pll_ctrl(pdata, true);
 
 	PMD_DRV_LOG(NOTICE, "firmware mailbox command did not complete\n");
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 13/24] net/axgbe: improve the SFP codes check for DAC cables
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (10 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 12/24] net/axgbe: enable PLL control for fixed PHY modes only Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 14/24] net/axgbe: improve logic around active and passive cables Venkat Kumar Ande
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The current AXGBE code assumes that offset 6 of EEPROM SFP DAC (passive)
cables is NULL. However, some cables (the 5 meter and 7 meter Molex
passive cables) have non-zero data at offset 6. Fix the logic by moving
the passive cable check above the active checks, so as not to be
improperly identified as an active cable. This will fix the issue for
any passive cable that advertises 1000Base-CX in offset 6.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index ceff36df3d..b5b962151d 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -610,7 +610,10 @@ static void axgbe_phy_sfp_parse_eeprom(struct axgbe_port *pdata)
 	}
 
 	/* Determine the type of SFP */
-	if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_SR)
+	if (phy_data->sfp_cable == AXGBE_SFP_CABLE_PASSIVE &&
+		 axgbe_phy_sfp_bit_rate(sfp_eeprom, AXGBE_SFP_SPEED_10000))
+		phy_data->sfp_base = AXGBE_SFP_BASE_10000_CR;
+	else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_SR)
 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_SR;
 	else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_LR)
 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_LR;
@@ -627,9 +630,6 @@ static void axgbe_phy_sfp_parse_eeprom(struct axgbe_port *pdata)
 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_CX;
 	else if (sfp_base[AXGBE_SFP_BASE_1GBE_CC] & AXGBE_SFP_BASE_1GBE_CC_T)
 		phy_data->sfp_base = AXGBE_SFP_BASE_1000_T;
-	else if ((phy_data->sfp_cable == AXGBE_SFP_CABLE_PASSIVE) &&
-		 axgbe_phy_sfp_bit_rate(sfp_eeprom, AXGBE_SFP_SPEED_10000))
-		phy_data->sfp_base = AXGBE_SFP_BASE_10000_CR;
 
 	switch (phy_data->sfp_base) {
 	case AXGBE_SFP_BASE_1000_T:
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 14/24] net/axgbe: improve logic around active and passive cables
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (11 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 13/24] net/axgbe: improve the SFP codes check for DAC cables Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 15/24] net/axgbe: check only the minimum speed for cables Venkat Kumar Ande
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

SFP+ active and passive cables are copper cables with fixed SFP+ end
connectors. Due to a misinterpretation of this, SFP+ active cables could
end up not being recognized, causing the driver to fail to establish a
connection.

Introduce a new enum in SFP+ cable types, XGBE_SFP_CABLE_FIBER, that is
the default cable type, and handle active and passive cables when they are
specifically detected.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index b5b962151d..693590da53 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -69,6 +69,7 @@ enum axgbe_sfp_cable {
 	AXGBE_SFP_CABLE_UNKNOWN = 0,
 	AXGBE_SFP_CABLE_ACTIVE,
 	AXGBE_SFP_CABLE_PASSIVE,
+	AXGBE_SFP_CABLE_FIBER,
 };
 
 enum axgbe_sfp_base {
@@ -601,16 +602,18 @@ static void axgbe_phy_sfp_parse_eeprom(struct axgbe_port *pdata)
 
 	axgbe_phy_sfp_parse_quirks(pdata);
 
-	/* Assume ACTIVE cable unless told it is PASSIVE */
+	/* Assume FIBER cable unless told otherwise */
 	if (sfp_base[AXGBE_SFP_BASE_CABLE] & AXGBE_SFP_BASE_CABLE_PASSIVE) {
 		phy_data->sfp_cable = AXGBE_SFP_CABLE_PASSIVE;
 		phy_data->sfp_cable_len = sfp_base[AXGBE_SFP_BASE_CU_CABLE_LEN];
-	} else {
+	} else if (sfp_base[AXGBE_SFP_BASE_CABLE] & AXGBE_SFP_BASE_CABLE_ACTIVE) {
 		phy_data->sfp_cable = AXGBE_SFP_CABLE_ACTIVE;
+	} else {
+		phy_data->sfp_cable = AXGBE_SFP_CABLE_FIBER;
 	}
 
 	/* Determine the type of SFP */
-	if (phy_data->sfp_cable == AXGBE_SFP_CABLE_PASSIVE &&
+	if (phy_data->sfp_cable != AXGBE_SFP_CABLE_FIBER &&
 		 axgbe_phy_sfp_bit_rate(sfp_eeprom, AXGBE_SFP_SPEED_10000))
 		phy_data->sfp_base = AXGBE_SFP_BASE_10000_CR;
 	else if (sfp_base[AXGBE_SFP_BASE_10GBE_CC] & AXGBE_SFP_BASE_10GBE_CC_SR)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 15/24] net/axgbe: check only the minimum speed for cables
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (12 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 14/24] net/axgbe: improve logic around active and passive cables Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 16/24] net/axgbe: add support for 10 Mbps speed Venkat Kumar Ande
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

There are cables that exist that can support speeds in excess of 10GbE.
The driver, however, restricts the EEPROM advertised nominal bitrate to
a specific range, which can prevent usage of cables that can support,
for example, up to 25GbE.

Rather than checking that an active or passive cable supports a specific
range, only check for a minimum supported speed.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 693590da53..67a18e7c55 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -117,9 +117,7 @@ enum axgbe_sfp_speed {
 
 #define AXGBE_SFP_BASE_BR			12
 #define AXGBE_SFP_BASE_BR_1GBE_MIN		0x0a
-#define AXGBE_SFP_BASE_BR_1GBE_MAX		0x0d
 #define AXGBE_SFP_BASE_BR_10GBE_MIN		0x64
-#define AXGBE_SFP_BASE_BR_10GBE_MAX		0x68
 
 #define AXGBE_SFP_BASE_CU_CABLE_LEN		18
 
@@ -519,25 +517,22 @@ static void axgbe_phy_sfp_phy_settings(struct axgbe_port *pdata)
 static bool axgbe_phy_sfp_bit_rate(struct axgbe_sfp_eeprom *sfp_eeprom,
 				   enum axgbe_sfp_speed sfp_speed)
 {
-	u8 *sfp_base, min, max;
+	u8 *sfp_base, min;
 
 	sfp_base = sfp_eeprom->base;
 
 	switch (sfp_speed) {
 	case AXGBE_SFP_SPEED_1000:
 		min = AXGBE_SFP_BASE_BR_1GBE_MIN;
-		max = AXGBE_SFP_BASE_BR_1GBE_MAX;
 		break;
 	case AXGBE_SFP_SPEED_10000:
 		min = AXGBE_SFP_BASE_BR_10GBE_MIN;
-		max = AXGBE_SFP_BASE_BR_10GBE_MAX;
 		break;
 	default:
 		return false;
 	}
 
-	return ((sfp_base[AXGBE_SFP_BASE_BR] >= min) &&
-		(sfp_base[AXGBE_SFP_BASE_BR] <= max));
+	return sfp_base[AXGBE_SFP_BASE_BR] >= min;
 }
 
 static void axgbe_phy_sfp_external_phy(struct axgbe_port *pdata)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 16/24] net/axgbe: add support for 10 Mbps speed
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (13 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 15/24] net/axgbe: check only the minimum speed for cables Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 17/24] net/axgbe: flow Tx Ctrl Registers are h/w ver dependent Venkat Kumar Ande
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Add the necessary changes to support 10 Mbps speed for BaseT and SFP
port modes. This is supported in MAC ver >= 30H.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_dev.c      |  3 ++
 drivers/net/axgbe/axgbe_ethdev.h   |  2 +
 drivers/net/axgbe/axgbe_mdio.c     | 22 +++++++++
 drivers/net/axgbe/axgbe_phy.h      |  2 +
 drivers/net/axgbe/axgbe_phy_impl.c | 75 ++++++++++++++++++++++++++++--
 5 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index 9b0073eea6..b4afcf20ab 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -250,6 +250,9 @@ static int axgbe_set_speed(struct axgbe_port *pdata, int speed)
 	unsigned int ss;
 
 	switch (speed) {
+	case SPEED_10:
+		ss = 0x07;
+		break;
 	case SPEED_1000:
 		ss = 0x03;
 		break;
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 20b36ced55..127427c736 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -114,6 +114,7 @@
 
 #define AXGBE_SGMII_AN_LINK_STATUS	BIT(1)
 #define AXGBE_SGMII_AN_LINK_SPEED	(BIT(2) | BIT(3))
+#define AXGBE_SGMII_AN_LINK_SPEED_10	0x00
 #define AXGBE_SGMII_AN_LINK_SPEED_100	0x04
 #define AXGBE_SGMII_AN_LINK_SPEED_1000	0x08
 #define AXGBE_SGMII_AN_LINK_DUPLEX	BIT(4)
@@ -213,6 +214,7 @@ enum axgbe_mode {
 	AXGBE_MODE_KX_2500,
 	AXGBE_MODE_KR,
 	AXGBE_MODE_X,
+	AXGBE_MODE_SGMII_10,
 	AXGBE_MODE_SGMII_100,
 	AXGBE_MODE_SGMII_1000,
 	AXGBE_MODE_SFI,
diff --git a/drivers/net/axgbe/axgbe_mdio.c b/drivers/net/axgbe/axgbe_mdio.c
index 151b30e2ab..4307a7560a 100644
--- a/drivers/net/axgbe/axgbe_mdio.c
+++ b/drivers/net/axgbe/axgbe_mdio.c
@@ -143,6 +143,15 @@ static void axgbe_sgmii_1000_mode(struct axgbe_port *pdata)
 	pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_1000);
 }
 
+static void axgbe_sgmii_10_mode(struct axgbe_port *pdata)
+{
+	/* Set MAC to 10M speed */
+	pdata->hw_if.set_speed(pdata, SPEED_10);
+
+	/* Call PHY implementation support to complete rate change */
+	pdata->phy_if.phy_impl.set_mode(pdata, AXGBE_MODE_SGMII_10);
+}
+
 static void axgbe_sgmii_100_mode(struct axgbe_port *pdata)
 {
 
@@ -176,6 +185,9 @@ static void axgbe_change_mode(struct axgbe_port *pdata,
 	case AXGBE_MODE_KR:
 		axgbe_kr_mode(pdata);
 		break;
+	case AXGBE_MODE_SGMII_10:
+		axgbe_sgmii_10_mode(pdata);
+		break;
 	case AXGBE_MODE_SGMII_100:
 		axgbe_sgmii_100_mode(pdata);
 		break;
@@ -862,6 +874,7 @@ static int axgbe_phy_config_fixed(struct axgbe_port *pdata)
 	case AXGBE_MODE_KX_1000:
 	case AXGBE_MODE_KX_2500:
 	case AXGBE_MODE_KR:
+	case AXGBE_MODE_SGMII_10:
 	case AXGBE_MODE_SGMII_100:
 	case AXGBE_MODE_SGMII_1000:
 	case AXGBE_MODE_X:
@@ -921,6 +934,8 @@ static int __axgbe_phy_config_aneg(struct axgbe_port *pdata, bool set_mode)
 			axgbe_set_mode(pdata, AXGBE_MODE_SGMII_1000);
 		} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
 			axgbe_set_mode(pdata, AXGBE_MODE_SGMII_100);
+		} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_10)) {
+			axgbe_set_mode(pdata, AXGBE_MODE_SGMII_10);
 		} else {
 			rte_intr_enable(pdata->pci_dev->intr_handle);
 			ret = -EINVAL;
@@ -1000,6 +1015,9 @@ static void axgbe_phy_status_result(struct axgbe_port *pdata)
 		mode = axgbe_phy_status_aneg(pdata);
 
 	switch (mode) {
+	case AXGBE_MODE_SGMII_10:
+		pdata->phy.speed = SPEED_10;
+		break;
 	case AXGBE_MODE_SGMII_100:
 		pdata->phy.speed = SPEED_100;
 		break;
@@ -1148,6 +1166,8 @@ static int axgbe_phy_start(struct axgbe_port *pdata)
 		axgbe_sgmii_1000_mode(pdata);
 	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_100)) {
 		axgbe_sgmii_100_mode(pdata);
+	} else if (axgbe_use_mode(pdata, AXGBE_MODE_SGMII_10)) {
+		axgbe_sgmii_10_mode(pdata);
 	} else {
 		ret = -EINVAL;
 		goto err_stop;
@@ -1195,6 +1215,8 @@ static int axgbe_phy_best_advertised_speed(struct axgbe_port *pdata)
 		return SPEED_1000;
 	else if (pdata->phy.advertising & ADVERTISED_100baseT_Full)
 		return SPEED_100;
+	else if (pdata->phy.advertising & ADVERTISED_10baseT_Full)
+		return SPEED_10;
 
 	return SPEED_UNKNOWN;
 }
diff --git a/drivers/net/axgbe/axgbe_phy.h b/drivers/net/axgbe/axgbe_phy.h
index 77ee20a31a..5b844e81cd 100644
--- a/drivers/net/axgbe/axgbe_phy.h
+++ b/drivers/net/axgbe/axgbe_phy.h
@@ -168,6 +168,7 @@
 #define ADVERTISED_1000baseKX_Full	(1 << 17)
 #define ADVERTISED_1000baseT_Full	(1 << 5)
 #define ADVERTISED_100baseT_Full	(1 << 3)
+#define ADVERTISED_10baseT_Full		(1 << 2)
 #define ADVERTISED_TP			(1 << 7)
 #define ADVERTISED_FIBRE		(1 << 10)
 #define ADVERTISED_Backplane            (1 << 16)
@@ -175,6 +176,7 @@
 #define SUPPORTED_1000baseKX_Full       (1 << 17)
 #define SUPPORTED_10000baseKR_Full      (1 << 19)
 #define SUPPORTED_2500baseX_Full	(1 << 15)
+#define SUPPORTED_10baseT_Full		(1 << 3)
 #define SUPPORTED_100baseT_Full         (1 << 2)
 #define SUPPORTED_1000baseT_Full        (1 << 5)
 #define SUPPORTED_10000baseT_Full       (1 << 12)
diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 67a18e7c55..9c2c411b4f 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -7,6 +7,7 @@
 #include "axgbe_common.h"
 #include "axgbe_phy.h"
 
+#define AXGBE_PHY_PORT_SPEED_10		BIT(0)
 #define AXGBE_PHY_PORT_SPEED_100	BIT(1)
 #define AXGBE_PHY_PORT_SPEED_1000	BIT(2)
 #define AXGBE_PHY_PORT_SPEED_2500	BIT(3)
@@ -490,6 +491,8 @@ static void axgbe_phy_sfp_phy_settings(struct axgbe_port *pdata)
 
 	switch (phy_data->sfp_speed) {
 	case AXGBE_SFP_SPEED_100_1000:
+		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
+			pdata->phy.advertising |= ADVERTISED_10baseT_Full;
 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100)
 			pdata->phy.advertising |= ADVERTISED_100baseT_Full;
 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000)
@@ -511,6 +514,8 @@ static void axgbe_phy_sfp_phy_settings(struct axgbe_port *pdata)
 			pdata->phy.advertising |= ADVERTISED_1000baseT_Full;
 		else if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100)
 			pdata->phy.advertising |= ADVERTISED_100baseT_Full;
+		else if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
+			pdata->phy.advertising |= ADVERTISED_10baseT_Full;
 	}
 }
 
@@ -980,6 +985,14 @@ static enum axgbe_mode axgbe_phy_an37_sgmii_outcome(struct axgbe_port *pdata)
 		axgbe_phy_phydev_flowctrl(pdata);
 
 	switch (pdata->an_status & AXGBE_SGMII_AN_LINK_SPEED) {
+	case AXGBE_SGMII_AN_LINK_SPEED_10:
+		if (pdata->an_status & AXGBE_SGMII_AN_LINK_DUPLEX) {
+			pdata->phy.lp_advertising |= ADVERTISED_10baseT_Full;
+			mode = AXGBE_MODE_SGMII_10;
+		} else {
+			mode = AXGBE_MODE_UNKNOWN;
+		}
+		break;
 	case AXGBE_SGMII_AN_LINK_SPEED_100:
 		if (pdata->an_status & AXGBE_SGMII_AN_LINK_DUPLEX) {
 			pdata->phy.lp_advertising |= ADVERTISED_100baseT_Full;
@@ -1347,6 +1360,18 @@ static void axgbe_phy_sgmii_1000_mode(struct axgbe_port *pdata)
 	phy_data->cur_mode = AXGBE_MODE_SGMII_1000;
 }
 
+static void axgbe_phy_sgmii_10_mode(struct axgbe_port *pdata)
+{
+	struct axgbe_phy_data *phy_data = pdata->phy_data;
+
+	axgbe_phy_set_redrv_mode(pdata);
+
+	/* 10M/SGMII */
+	axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_1G, AXGBE_MB_SUBCMD_10MBITS);
+
+	phy_data->cur_mode = AXGBE_MODE_SGMII_10;
+}
+
 static enum axgbe_mode axgbe_phy_cur_mode(struct axgbe_port *pdata)
 {
 	struct axgbe_phy_data *phy_data = pdata->phy_data;
@@ -1363,6 +1388,7 @@ static enum axgbe_mode axgbe_phy_switch_baset_mode(struct axgbe_port *pdata)
 		return axgbe_phy_cur_mode(pdata);
 
 	switch (axgbe_phy_cur_mode(pdata)) {
+	case AXGBE_MODE_SGMII_10:
 	case AXGBE_MODE_SGMII_100:
 	case AXGBE_MODE_SGMII_1000:
 		return AXGBE_MODE_KR;
@@ -1433,6 +1459,8 @@ static enum axgbe_mode axgbe_phy_get_baset_mode(struct axgbe_phy_data *phy_data
 						int speed)
 {
 	switch (speed) {
+	case SPEED_10:
+		return AXGBE_MODE_SGMII_10;
 	case SPEED_100:
 		return AXGBE_MODE_SGMII_100;
 	case SPEED_1000:
@@ -1448,6 +1476,8 @@ static enum axgbe_mode axgbe_phy_get_sfp_mode(struct axgbe_phy_data *phy_data,
 					      int speed)
 {
 	switch (speed) {
+	case SPEED_10:
+		return AXGBE_MODE_SGMII_10;
 	case SPEED_100:
 		return AXGBE_MODE_SGMII_100;
 	case SPEED_1000:
@@ -1525,6 +1555,9 @@ static void axgbe_phy_set_mode(struct axgbe_port *pdata, enum axgbe_mode mode)
 	case AXGBE_MODE_SGMII_1000:
 		axgbe_phy_sgmii_1000_mode(pdata);
 		break;
+	case AXGBE_MODE_SGMII_10:
+		axgbe_phy_sgmii_10_mode(pdata);
+		break;
 	default:
 		break;
 	}
@@ -1566,6 +1599,9 @@ static bool axgbe_phy_use_baset_mode(struct axgbe_port *pdata,
 				     enum axgbe_mode mode)
 {
 	switch (mode) {
+	case AXGBE_MODE_SGMII_10:
+		return axgbe_phy_check_mode(pdata, mode,
+					    ADVERTISED_10baseT_Full);
 	case AXGBE_MODE_SGMII_100:
 		return axgbe_phy_check_mode(pdata, mode,
 					    ADVERTISED_100baseT_Full);
@@ -1591,6 +1627,11 @@ static bool axgbe_phy_use_sfp_mode(struct axgbe_port *pdata,
 			return false;
 		return axgbe_phy_check_mode(pdata, mode,
 					    ADVERTISED_1000baseT_Full);
+	case AXGBE_MODE_SGMII_10:
+		if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
+			return false;
+		return axgbe_phy_check_mode(pdata, mode,
+					    ADVERTISED_10baseT_Full);
 	case AXGBE_MODE_SGMII_100:
 		if (phy_data->sfp_base != AXGBE_SFP_BASE_1000_T)
 			return false;
@@ -1803,6 +1844,12 @@ static int axgbe_phy_mdio_reset_setup(struct axgbe_port *pdata)
 static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
 {
 	struct axgbe_phy_data *phy_data = pdata->phy_data;
+	unsigned int ver;
+
+	/* 10 Mbps speed is not supported in ver < 30H */
+	ver = AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
+	if (ver < 0x30 && phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
+		return true;
 
 	switch (phy_data->port_mode) {
 	case AXGBE_PORT_MODE_BACKPLANE:
@@ -1816,7 +1863,8 @@ static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
 			return false;
 		break;
 	case AXGBE_PORT_MODE_1000BASE_T:
-		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
+		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)  ||
+			(phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000))
 			return false;
 		break;
@@ -1825,13 +1873,15 @@ static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
 			return false;
 		break;
 	case AXGBE_PORT_MODE_NBASE_T:
-		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
+		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)  ||
+			(phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500))
 			return false;
 		break;
 	case AXGBE_PORT_MODE_10GBASE_T:
-		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
+		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)  ||
+		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
 			return false;
@@ -1841,7 +1891,8 @@ static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
 			return false;
 		break;
 	case AXGBE_PORT_MODE_SFP:
-		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
+		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)  ||
+			(phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
 			return false;
@@ -2150,6 +2201,10 @@ static int axgbe_phy_init(struct axgbe_port *pdata)
 		pdata->phy.supported |= SUPPORTED_Autoneg;
 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 		pdata->phy.supported |= SUPPORTED_TP;
+		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
+			pdata->phy.supported |= SUPPORTED_10baseT_Full;
+			phy_data->start_mode = AXGBE_MODE_SGMII_10;
+		}
 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
@@ -2178,6 +2233,10 @@ static int axgbe_phy_init(struct axgbe_port *pdata)
 		pdata->phy.supported |= SUPPORTED_Autoneg;
 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 		pdata->phy.supported |= SUPPORTED_TP;
+		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
+			pdata->phy.supported |= SUPPORTED_10baseT_Full;
+			phy_data->start_mode = AXGBE_MODE_SGMII_10;
+		}
 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
@@ -2199,6 +2258,10 @@ static int axgbe_phy_init(struct axgbe_port *pdata)
 		pdata->phy.supported |= SUPPORTED_Autoneg;
 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 		pdata->phy.supported |= SUPPORTED_TP;
+		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
+			pdata->phy.supported |= SUPPORTED_10baseT_Full;
+			phy_data->start_mode = AXGBE_MODE_SGMII_10;
+		}
 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
@@ -2234,6 +2297,10 @@ static int axgbe_phy_init(struct axgbe_port *pdata)
 		pdata->phy.supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 		pdata->phy.supported |= SUPPORTED_TP;
 		pdata->phy.supported |= SUPPORTED_FIBRE;
+		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10) {
+			pdata->phy.supported |= SUPPORTED_10baseT_Full;
+			phy_data->start_mode = AXGBE_MODE_SGMII_10;
+		}
 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) {
 			pdata->phy.supported |= SUPPORTED_100baseT_Full;
 			phy_data->start_mode = AXGBE_MODE_SGMII_100;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 17/24] net/axgbe: flow Tx Ctrl Registers are h/w ver dependent
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (14 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 16/24] net/axgbe: add support for 10 Mbps speed Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 18/24] net/axgbe: delay AN timeout during KR training Venkat Kumar Ande
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

There is difference in the TX Flow Control registers (TFCR) between the
revisions of the hardware. The older revisions of hardware used to have
single register per queue. Whereas, the newer revision of hardware (from
ver 30H onwards) have one register per priority.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_dev.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index b4afcf20ab..6b413160c2 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -272,20 +272,28 @@ static int axgbe_set_speed(struct axgbe_port *pdata, int speed)
 	return 0;
 }
 
+static unsigned int axgbe_get_fc_queue_count(struct axgbe_port *pdata)
+{
+	unsigned int max_q_count = AXGMAC_MAX_FLOW_CONTROL_QUEUES;
+
+	/* From MAC ver 30H the TFCR is per priority, instead of per queue */
+	if (AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) >= 0x30)
+		return max_q_count;
+	else
+		return (RTE_MIN(pdata->tx_q_count, max_q_count));
+}
+
 static int axgbe_disable_tx_flow_control(struct axgbe_port *pdata)
 {
-	unsigned int max_q_count, q_count;
 	unsigned int reg, reg_val;
-	unsigned int i;
+	unsigned int i, q_count;
 
 	/* Clear MTL flow control */
 	for (i = 0; i < pdata->rx_q_count; i++)
 		AXGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_RQOMR, EHFC, 0);
 
 	/* Clear MAC flow control */
-	max_q_count = AXGMAC_MAX_FLOW_CONTROL_QUEUES;
-	q_count = RTE_MIN(pdata->tx_q_count,
-			max_q_count);
+	q_count = axgbe_get_fc_queue_count(pdata);
 	reg = MAC_Q0TFCR;
 	for (i = 0; i < q_count; i++) {
 		reg_val = AXGMAC_IOREAD(pdata, reg);
@@ -300,9 +308,8 @@ static int axgbe_disable_tx_flow_control(struct axgbe_port *pdata)
 
 static int axgbe_enable_tx_flow_control(struct axgbe_port *pdata)
 {
-	unsigned int max_q_count, q_count;
 	unsigned int reg, reg_val;
-	unsigned int i;
+	unsigned int i, q_count;
 
 	/* Set MTL flow control */
 	for (i = 0; i < pdata->rx_q_count; i++) {
@@ -319,9 +326,7 @@ static int axgbe_enable_tx_flow_control(struct axgbe_port *pdata)
 	}
 
 	/* Set MAC flow control */
-	max_q_count = AXGMAC_MAX_FLOW_CONTROL_QUEUES;
-	q_count = RTE_MIN(pdata->tx_q_count,
-			max_q_count);
+	q_count = axgbe_get_fc_queue_count(pdata);
 	reg = MAC_Q0TFCR;
 	for (i = 0; i < q_count; i++) {
 		reg_val = AXGMAC_IOREAD(pdata, reg);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 18/24] net/axgbe: delay AN timeout during KR training
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (15 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 17/24] net/axgbe: flow Tx Ctrl Registers are h/w ver dependent Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 19/24] net/axgbe: separate C22 and C45 transactions Venkat Kumar Ande
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

AN restart triggered during KR training not only aborts the KR training
process but also move the HW to unstable state. Driver has to wait up to
500ms or until the KR training is completed before restarting AN cycle.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_ethdev.h |  2 ++
 drivers/net/axgbe/axgbe_mdio.c   | 25 +++++++++++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 127427c736..4dcbf6d9a2 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -111,6 +111,7 @@
 /* Auto-negotiation */
 #define AXGBE_AN_MS_TIMEOUT		500
 #define AXGBE_LINK_TIMEOUT		5
+#define AXGBE_KR_TRAINING_WAIT_ITER	50
 
 #define AXGBE_SGMII_AN_LINK_STATUS	BIT(1)
 #define AXGBE_SGMII_AN_LINK_SPEED	(BIT(2) | BIT(3))
@@ -689,6 +690,7 @@ struct axgbe_port {
 	unsigned int parallel_detect;
 	unsigned int fec_ability;
 	unsigned long an_start;
+	unsigned long kr_start_time;
 	enum axgbe_an_mode an_mode;
 
 	/* I2C support */
diff --git a/drivers/net/axgbe/axgbe_mdio.c b/drivers/net/axgbe/axgbe_mdio.c
index 4307a7560a..9fe30e83bc 100644
--- a/drivers/net/axgbe/axgbe_mdio.c
+++ b/drivers/net/axgbe/axgbe_mdio.c
@@ -370,6 +370,7 @@ static enum axgbe_an axgbe_an73_tx_training(struct axgbe_port *pdata,
 	reg |= AXGBE_KR_TRAINING_ENABLE;
 	reg |= AXGBE_KR_TRAINING_START;
 	XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
+	pdata->kr_start_time = rte_get_timer_cycles();
 
 	PMD_DRV_LOG(DEBUG, "KR training initiated\n");
 	if (pdata->phy_if.phy_impl.kr_training_post)
@@ -500,6 +501,7 @@ static enum axgbe_an axgbe_an73_incompat_link(struct axgbe_port *pdata)
 
 	axgbe_an_disable(pdata);
 	axgbe_switch_mode(pdata);
+	pdata->an_result = AXGBE_AN_READY;
 	axgbe_an_restart(pdata);
 
 	return AXGBE_AN_INCOMPAT_LINK;
@@ -988,11 +990,34 @@ static void axgbe_check_link_timeout(struct axgbe_port *pdata)
 {
 	unsigned long link_timeout;
 	unsigned long ticks;
+	unsigned long kr_time;
+	int wait;
 
 	link_timeout = pdata->link_check + (AXGBE_LINK_TIMEOUT *
 					    2 *  rte_get_timer_hz());
 	ticks = rte_get_timer_cycles();
 	if (time_after(ticks, link_timeout)) {
+		if ((axgbe_cur_mode(pdata) == AXGBE_MODE_KR) &&
+		    pdata->phy.autoneg == AUTONEG_ENABLE) {
+			/* AN restart should not happen while KR training is in progress.
+			 * The while loop ensures no AN restart during KR training,
+			 * waits up to 500ms and AN restart is triggered only if KR
+			 * training is failed.
+			 */
+			wait = AXGBE_KR_TRAINING_WAIT_ITER;
+			while (wait--) {
+				kr_time = pdata->kr_start_time +
+					  msecs_to_timer_cycles(AXGBE_AN_MS_TIMEOUT);
+				ticks = rte_get_timer_cycles();
+				if (time_after(ticks, kr_time))
+					break;
+				/* AN restart is not required, if AN result is COMPLETE */
+				if (pdata->an_result == AXGBE_AN_COMPLETE)
+					return;
+				rte_delay_us(10500);
+			}
+		}
+
 		PMD_DRV_LOG(NOTICE, "AN link timeout\n");
 		axgbe_phy_config_aneg(pdata);
 	}
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 19/24] net/axgbe: separate C22 and C45 transactions
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (16 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 18/24] net/axgbe: delay AN timeout during KR training Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 20/24] net/axgbe: replace mii generic macro for c45 with AXGBE Venkat Kumar Ande
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The xgbe MDIO bus driver can perform both C22 and C45 transfers, when
using its MDIO bus hardware. The SFP I2C mdio bus driver only supports
C22. Create separate functions for each and register the C45 versions
using the new API calls where appropriate.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_dev.c      | 77 +++++++++++++++++++++++++-----
 drivers/net/axgbe/axgbe_ethdev.h   |  7 ++-
 drivers/net/axgbe/axgbe_phy_impl.c |  4 +-
 3 files changed, 71 insertions(+), 17 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index 6b413160c2..fa7324efa7 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -63,11 +63,20 @@ static int mdio_complete(struct axgbe_port *pdata)
 	return 0;
 }
 
-static unsigned int axgbe_create_mdio_sca(int port, int reg)
+static unsigned int axgbe_create_mdio_sca_c22(int port, int reg)
 {
-	unsigned int mdio_sca, da;
+	unsigned int mdio_sca;
 
-	da = (reg & MII_ADDR_C45) ? reg >> 16 : 0;
+	mdio_sca = 0;
+	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg);
+	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, PA, port);
+
+	return mdio_sca;
+}
+
+static unsigned int axgbe_create_mdio_sca_c45(int port, unsigned int da, int reg)
+{
+	unsigned int mdio_sca;
 
 	mdio_sca = 0;
 	AXGMAC_SET_BITS(mdio_sca, MAC_MDIOSCAR, RA, reg);
@@ -77,13 +86,12 @@ static unsigned int axgbe_create_mdio_sca(int port, int reg)
 	return mdio_sca;
 }
 
-static int axgbe_write_ext_mii_regs(struct axgbe_port *pdata, int addr,
-				    int reg, u16 val)
+static int axgbe_write_ext_mii_regs(struct axgbe_port *pdata,
+						unsigned int mdio_sca, u16 val)
 {
-	unsigned int mdio_sca, mdio_sccd;
+	unsigned int mdio_sccd;
 	uint64_t timeout;
 
-	mdio_sca = axgbe_create_mdio_sca(addr, reg);
 	AXGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
 
 	mdio_sccd = 0;
@@ -103,13 +111,34 @@ static int axgbe_write_ext_mii_regs(struct axgbe_port *pdata, int addr,
 	return -ETIMEDOUT;
 }
 
-static int axgbe_read_ext_mii_regs(struct axgbe_port *pdata, int addr,
-				   int reg)
+
+static int axgbe_write_ext_mii_regs_c22(struct axgbe_port *pdata,
+							int addr, int reg, u16 val)
+{
+	unsigned int mdio_sca;
+
+	mdio_sca = axgbe_create_mdio_sca_c22(addr, reg);
+
+	return axgbe_write_ext_mii_regs(pdata, mdio_sca, val);
+}
+
+static int axgbe_write_ext_mii_regs_c45(struct axgbe_port *pdata,
+					int addr, int devad, int reg, u16 val)
 {
-	unsigned int mdio_sca, mdio_sccd;
+	unsigned int mdio_sca;
+
+	mdio_sca = axgbe_create_mdio_sca_c45(addr, devad, reg);
+
+	return axgbe_write_ext_mii_regs(pdata, mdio_sca, val);
+}
+
+
+static int axgbe_read_ext_mii_regs(struct axgbe_port *pdata,
+							unsigned int mdio_sca)
+{
+	unsigned int mdio_sccd;
 	uint64_t timeout;
 
-	mdio_sca = axgbe_create_mdio_sca(addr, reg);
 	AXGMAC_IOWRITE(pdata, MAC_MDIOSCAR, mdio_sca);
 
 	mdio_sccd = 0;
@@ -132,6 +161,25 @@ static int axgbe_read_ext_mii_regs(struct axgbe_port *pdata, int addr,
 	return AXGMAC_IOREAD_BITS(pdata, MAC_MDIOSCCDR, DATA);
 }
 
+static int axgbe_read_ext_mii_regs_c22(struct axgbe_port *pdata, int addr, int reg)
+{
+	unsigned int mdio_sca;
+
+	mdio_sca = axgbe_create_mdio_sca_c22(addr, reg);
+
+	return axgbe_read_ext_mii_regs(pdata, mdio_sca);
+}
+
+static int axgbe_read_ext_mii_regs_c45(struct axgbe_port *pdata, int addr,
+								int devad, int reg)
+{
+	unsigned int mdio_sca;
+
+	mdio_sca = axgbe_create_mdio_sca_c45(addr, devad, reg);
+
+	return axgbe_read_ext_mii_regs(pdata, mdio_sca);
+}
+
 static int axgbe_set_ext_mii_mode(struct axgbe_port *pdata, unsigned int port,
 				  enum axgbe_mdio_mode mode)
 {
@@ -1373,8 +1421,11 @@ void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if)
 	hw_if->set_speed = axgbe_set_speed;
 
 	hw_if->set_ext_mii_mode = axgbe_set_ext_mii_mode;
-	hw_if->read_ext_mii_regs = axgbe_read_ext_mii_regs;
-	hw_if->write_ext_mii_regs = axgbe_write_ext_mii_regs;
+	hw_if->read_ext_mii_regs_c22 = axgbe_read_ext_mii_regs_c22;
+	hw_if->write_ext_mii_regs_c22 = axgbe_write_ext_mii_regs_c22;
+	hw_if->read_ext_mii_regs_c45 = axgbe_read_ext_mii_regs_c45;
+	hw_if->write_ext_mii_regs_c45 = axgbe_write_ext_mii_regs_c45;
+
 	/* For FLOW ctrl */
 	hw_if->config_tx_flow_control = axgbe_config_tx_flow_control;
 	hw_if->config_rx_flow_control = axgbe_config_rx_flow_control;
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 4dcbf6d9a2..cb3df47a63 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -325,8 +325,11 @@ struct axgbe_hw_if {
 
 	int (*set_ext_mii_mode)(struct axgbe_port *, unsigned int,
 				enum axgbe_mdio_mode);
-	int (*read_ext_mii_regs)(struct axgbe_port *, int, int);
-	int (*write_ext_mii_regs)(struct axgbe_port *, int, int, uint16_t);
+	int (*read_ext_mii_regs_c22)(struct axgbe_port *pdata, int addr, int reg);
+	int (*write_ext_mii_regs_c22)(struct axgbe_port *pdata, int addr, int reg, uint16_t val);
+	int (*read_ext_mii_regs_c45)(struct axgbe_port *pdata, int addr, int devad, int reg);
+	int (*write_ext_mii_regs_c45)(struct axgbe_port *pdata, int addr, int devad,
+									int reg, uint16_t val);
 
 	/* For FLOW ctrl */
 	int (*config_tx_flow_control)(struct axgbe_port *);
diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 9c2c411b4f..d173545e83 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -1148,8 +1148,8 @@ static int axgbe_phy_set_redrv_mode_mdio(struct axgbe_port *pdata,
 	redrv_reg = AXGBE_PHY_REDRV_MODE_REG + (phy_data->redrv_lane * 0x1000);
 	redrv_val = (u16)mode;
 
-	return pdata->hw_if.write_ext_mii_regs(pdata, phy_data->redrv_addr,
-					       redrv_reg, redrv_val);
+	return pdata->hw_if.write_ext_mii_regs_c22(pdata,
+		phy_data->redrv_addr, redrv_reg, redrv_val);
 }
 
 static int axgbe_phy_set_redrv_mode_i2c(struct axgbe_port *pdata,
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 20/24] net/axgbe: replace mii generic macro for c45 with AXGBE
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (17 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 19/24] net/axgbe: separate C22 and C45 transactions Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 21/24] net/axgbe: add 2.5GbE support to 10G BaseT mode Venkat Kumar Ande
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The axgbe driver reuses MII_ADDR_C45 for its own purpose. The values
derived with it are never passed to phylib or a linux MDIO bus driver.
In order that MII_ADDR_C45 can be removed, add an AXGBE specific

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_common.h | 4 ++--
 drivers/net/axgbe/axgbe_dev.c    | 8 ++++----
 drivers/net/axgbe/axgbe_phy.h    | 2 +-
 3 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h
index 51532fb34a..1a43192630 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -1732,14 +1732,14 @@ do {									\
  */
 #define XMDIO_READ(_pdata, _mmd, _reg)					\
 	((_pdata)->hw_if.read_mmd_regs((_pdata), 0,			\
-		MII_ADDR_C45 | ((_mmd) << 16) | ((_reg) & 0xffff)))
+		AXGBE_ADDR_C45 | ((_mmd) << 16) | ((_reg) & 0xffff)))
 
 #define XMDIO_READ_BITS(_pdata, _mmd, _reg, _mask)			\
 	(XMDIO_READ((_pdata), _mmd, _reg) & _mask)
 
 #define XMDIO_WRITE(_pdata, _mmd, _reg, _val)				\
 	((_pdata)->hw_if.write_mmd_regs((_pdata), 0,			\
-		MII_ADDR_C45 | ((_mmd) << 16) | ((_reg) & 0xffff), (_val)))
+		AXGBE_ADDR_C45 | ((_mmd) << 16) | ((_reg) & 0xffff), (_val)))
 
 #define XMDIO_WRITE_BITS(_pdata, _mmd, _reg, _mask, _val)		\
 do {									\
diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index fa7324efa7..ebe64295aa 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -207,8 +207,8 @@ static int axgbe_read_mmd_regs_v2(struct axgbe_port *pdata,
 	unsigned int mmd_address, index, offset;
 	int mmd_data;
 
-	if (mmd_reg & MII_ADDR_C45)
-		mmd_address = mmd_reg & ~MII_ADDR_C45;
+	if (mmd_reg & AXGBE_ADDR_C45)
+		mmd_address = mmd_reg & ~AXGBE_ADDR_C45;
 	else
 		mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
 
@@ -241,8 +241,8 @@ static void axgbe_write_mmd_regs_v2(struct axgbe_port *pdata,
 {
 	unsigned int mmd_address, index, offset;
 
-	if (mmd_reg & MII_ADDR_C45)
-		mmd_address = mmd_reg & ~MII_ADDR_C45;
+	if (mmd_reg & AXGBE_ADDR_C45)
+		mmd_address = mmd_reg & ~AXGBE_ADDR_C45;
 	else
 		mmd_address = (pdata->mdio_mmd << 16) | (mmd_reg & 0xffff);
 
diff --git a/drivers/net/axgbe/axgbe_phy.h b/drivers/net/axgbe/axgbe_phy.h
index 5b844e81cd..eee3afc370 100644
--- a/drivers/net/axgbe/axgbe_phy.h
+++ b/drivers/net/axgbe/axgbe_phy.h
@@ -16,7 +16,7 @@
 /* Or MII_ADDR_C45 into regnum for read/write on mii_bus to enable the 21 bit
  * IEEE 802.3ae clause 45 addressing mode used by 10GIGE phy chips.
  */
-#define MII_ADDR_C45 (1 << 30)
+#define AXGBE_ADDR_C45  (1 << 30)
 
 /* Basic mode status register. */
 #define BMSR_LSTATUS            0x0004  /* Link status */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 21/24] net/axgbe: add 2.5GbE support to 10G BaseT mode
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (18 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 20/24] net/axgbe: replace mii generic macro for c45 with AXGBE Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 22/24] net/axgbe: add support for Rx adaptation Venkat Kumar Ande
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

Add support to the driver to fully recognize and enable 2.5GbE speed in
10GBaseT mode.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index d173545e83..13b37e9b8b 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -1392,9 +1392,11 @@ static enum axgbe_mode axgbe_phy_switch_baset_mode(struct axgbe_port *pdata)
 	case AXGBE_MODE_SGMII_100:
 	case AXGBE_MODE_SGMII_1000:
 		return AXGBE_MODE_KR;
+	case AXGBE_MODE_KX_2500:
+		return AXGBE_MODE_SGMII_1000;
 	case AXGBE_MODE_KR:
 	default:
-		return AXGBE_MODE_SGMII_1000;
+		return AXGBE_MODE_KX_2500;
 	}
 }
 
@@ -1883,6 +1885,7 @@ static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
 		if ((phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)  ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_100) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_1000) ||
+		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) ||
 		    (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000))
 			return false;
 		break;
@@ -2270,6 +2273,10 @@ static int axgbe_phy_init(struct axgbe_port *pdata)
 			pdata->phy.supported |= SUPPORTED_1000baseT_Full;
 			phy_data->start_mode = AXGBE_MODE_SGMII_1000;
 		}
+		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_2500) {
+			pdata->phy.supported |= SUPPORTED_2500baseX_Full;
+			phy_data->start_mode = AXGBE_MODE_KX_2500;
+		}
 		if (phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10000) {
 			pdata->phy.supported |= SUPPORTED_10000baseT_Full;
 			phy_data->start_mode = AXGBE_MODE_KR;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 22/24] net/axgbe: add support for Rx adaptation
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (19 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 21/24] net/axgbe: add 2.5GbE support to 10G BaseT mode Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 23/24] net/axgbe: improve the false linkup in axgbe PHY status Venkat Kumar Ande
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

The existing implementation for non-Autonegotiation 10G speed modes does
not enable RX adaptation in the Driver and FW. The RX Equalization
settings (AFE settings alone) are manually configured and the existing
link-up sequence in the driver does not perform rx adaptation process as
mentioned in the Synopsys databook. There's a customer request for 10G
backplane mode without Auto-negotiation and for the DAC cables of more
significant length that follow the non-Autonegotiation mode. These modes
require PHY to perform RX Adaptation.

The proposed logic adds the necessary changes to Yellow Carp devices to
ensure seamless RX Adaptation for 10G-SFI (LONG DAC) and 10G-KR without
AN (CL72 not present). The RX adaptation core algorithm is executed by
firmware, however, to achieve that a new mailbox sub-command is required
to be sent by the driver.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_common.h   |  38 +++++++
 drivers/net/axgbe/axgbe_ethdev.h   |   5 +
 drivers/net/axgbe/axgbe_phy_impl.c | 170 ++++++++++++++++++++++++++++-
 3 files changed, 210 insertions(+), 3 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h
index 1a43192630..0e1b2c1500 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -1274,6 +1274,22 @@
 #define MDIO_PMA_RX_CTRL1		0x8051
 #endif
 
+#ifndef MDIO_PMA_RX_LSTS
+#define MDIO_PMA_RX_LSTS		0x018020
+#endif
+
+#ifndef MDIO_PMA_RX_EQ_CTRL4
+#define MDIO_PMA_RX_EQ_CTRL4		0x0001805C
+#endif
+
+#ifndef MDIO_PMA_MP_MISC_STS
+#define MDIO_PMA_MP_MISC_STS		0x0078
+#endif
+
+#ifndef MDIO_PMA_PHY_RX_EQ_CEU
+#define MDIO_PMA_PHY_RX_EQ_CEU		0x1800E
+#endif
+
 #ifndef MDIO_PCS_DIG_CTRL
 #define MDIO_PCS_DIG_CTRL		0x8000
 #endif
@@ -1415,6 +1431,28 @@ static inline uint32_t high32_value(uint64_t addr)
 #define XGBE_PMA_RX_RST_0_RESET_ON     0x10
 #define XGBE_PMA_RX_RST_0_RESET_OFF    0x00
 
+#define XGBE_PMA_RX_SIG_DET_0_MASK	BIT(4)
+#define XGBE_PMA_RX_SIG_DET_0_ENABLE	BIT(4)
+#define XGBE_PMA_RX_SIG_DET_0_DISABLE	0x0000
+
+#define XGBE_PMA_RX_VALID_0_MASK	BIT(12)
+#define XGBE_PMA_RX_VALID_0_ENABLE	BIT(12)
+#define XGBE_PMA_RX_VALID_0_DISABLE	0x0000
+
+#define XGBE_PMA_RX_AD_REQ_MASK		BIT(12)
+#define XGBE_PMA_RX_AD_REQ_ENABLE	BIT(12)
+#define XGBE_PMA_RX_AD_REQ_DISABLE	0x0000
+
+#define XGBE_PMA_RX_ADPT_ACK_MASK	BIT(12)
+#define XGBE_PMA_RX_ADPT_ACK		BIT(12)
+
+#define XGBE_PMA_CFF_UPDTM1_VLD		BIT(8)
+#define XGBE_PMA_CFF_UPDT0_VLD		BIT(9)
+#define XGBE_PMA_CFF_UPDT1_VLD		BIT(10)
+#define XGBE_PMA_CFF_UPDT_MASK		(XGBE_PMA_CFF_UPDTM1_VLD |\
+					 XGBE_PMA_CFF_UPDT0_VLD | \
+					 XGBE_PMA_CFF_UPDT1_VLD)
+
 /*END*/
 
 /* Bit setting and getting macros
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index cb3df47a63..dd00ae8af5 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -244,6 +244,7 @@ enum axgbe_mb_cmd {
 
 enum axgbe_mb_subcmd {
 	AXGBE_MB_SUBCMD_NONE = 0,
+	AXGBE_MB_SUBCMD_RX_ADAP,
 
 	/* 10GbE SFP subcommands */
 	AXGBE_MB_SUBCMD_ACTIVE = 0,
@@ -722,6 +723,10 @@ struct axgbe_port {
 	struct rte_timecounter tx_tstamp;
 	unsigned int tstamp_addend;
 
+	bool en_rx_adap;
+	int rx_adapt_retries;
+	bool rx_adapt_done;
+	bool mode_set;
 };
 
 void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if);
diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index 13b37e9b8b..a1c42b7dd4 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -247,6 +247,10 @@ struct axgbe_phy_data {
 };
 
 static enum axgbe_an_mode axgbe_phy_an_mode(struct axgbe_port *pdata);
+static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
+		enum axgbe_mb_cmd cmd, enum axgbe_mb_subcmd sub_cmd);
+static void axgbe_phy_rrc(struct axgbe_port *pdata);
+
 
 static int axgbe_phy_i2c_xfer(struct axgbe_port *pdata,
 			      struct axgbe_i2c_op *i2c_op)
@@ -1194,6 +1198,92 @@ static void axgbe_phy_set_redrv_mode(struct axgbe_port *pdata)
 	axgbe_phy_put_comm_ownership(pdata);
 }
 
+#define MAX_RX_ADAPT_RETRIES		1
+#define XGBE_PMA_RX_VAL_SIG_MASK	(XGBE_PMA_RX_SIG_DET_0_MASK | \
+					 XGBE_PMA_RX_VALID_0_MASK)
+
+static void axgbe_set_rx_adap_mode(struct axgbe_port *pdata,
+				  enum axgbe_mode mode)
+{
+	if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
+		pdata->rx_adapt_retries = 0;
+		return;
+	}
+
+	axgbe_phy_perform_ratechange(pdata,
+				    mode == AXGBE_MODE_KR ?
+				    AXGBE_MB_CMD_SET_10G_KR :
+				    AXGBE_MB_CMD_SET_10G_SFI,
+				    AXGBE_MB_SUBCMD_RX_ADAP);
+}
+
+static void axgbe_rx_adaptation(struct axgbe_port *pdata)
+{
+	struct axgbe_phy_data *phy_data = pdata->phy_data;
+	unsigned int reg;
+
+	/* step 2: force PCS to send RX_ADAPT Req to PHY */
+	XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
+			 XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_ENABLE);
+
+	/* Step 3: Wait for RX_ADAPT ACK from the PHY */
+	rte_delay_ms(200);
+
+	/* Software polls for coefficient update command (given by local PHY) */
+	reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_PHY_RX_EQ_CEU);
+
+	/* Clear the RX_AD_REQ bit */
+	XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
+			 XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_DISABLE);
+
+	/* Check if coefficient update command is set */
+	if ((reg & XGBE_PMA_CFF_UPDT_MASK) != XGBE_PMA_CFF_UPDT_MASK)
+		goto set_mode;
+
+	/* Step 4: Check for Block lock */
+
+	/* Link status is latched low, so read once to clear
+	 * and then read again to get current state
+	 */
+	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
+	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
+	if (reg & MDIO_STAT1_LSTATUS) {
+		/* If the block lock is found, update the helpers
+		 * and declare the link up
+		 */
+		PMD_DRV_LOG(NOTICE, "Rx adaptation - Block_lock done\n");
+		pdata->rx_adapt_done = true;
+		pdata->mode_set = false;
+		return;
+	}
+
+set_mode:
+	axgbe_set_rx_adap_mode(pdata, phy_data->cur_mode);
+}
+
+static void axgbe_phy_rx_adaptation(struct axgbe_port *pdata)
+{
+	unsigned int reg;
+
+rx_adapt_reinit:
+	reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_LSTS,
+			      XGBE_PMA_RX_VAL_SIG_MASK);
+
+	/* step 1: Check for RX_VALID && LF_SIGDET */
+	if ((reg & XGBE_PMA_RX_VAL_SIG_MASK) != XGBE_PMA_RX_VAL_SIG_MASK) {
+		PMD_DRV_LOG(NOTICE, "RX_VALID or LF_SIGDET is unset, issue rrc\n");
+		axgbe_phy_rrc(pdata);
+		if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
+			pdata->rx_adapt_retries = 0;
+			return;
+		}
+		goto rx_adapt_reinit;
+	}
+
+	/* perform rx adaptation */
+	axgbe_rx_adaptation(pdata);
+}
+
 static void axgbe_phy_rx_reset(struct axgbe_port *pdata)
 {
 	int reg;
@@ -1258,12 +1348,27 @@ static void axgbe_phy_perform_ratechange(struct axgbe_port *pdata,
 	wait = AXGBE_RATECHANGE_COUNT;
 	while (wait--) {
 		if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
-			goto reenable_pll;
+			goto do_rx_adaptation;
 		rte_delay_us(1500);
 	}
 	PMD_DRV_LOG(NOTICE, "firmware mailbox command did not complete\n");
 	/* Reset on error */
 	axgbe_phy_rx_reset(pdata);
+	goto reenable_pll;
+
+
+do_rx_adaptation:
+	if (pdata->en_rx_adap && sub_cmd == AXGBE_MB_SUBCMD_RX_ADAP &&
+	    (cmd == AXGBE_MB_CMD_SET_10G_KR || cmd == AXGBE_MB_CMD_SET_10G_SFI)) {
+		PMD_DRV_LOG(NOTICE, "Enabling RX adaptation\n");
+		pdata->mode_set = true;
+		axgbe_phy_rx_adaptation(pdata);
+		/* return from here to avoid enabling PLL ctrl
+		 * during adaptation phase
+		 */
+		return;
+	}
+
 
 reenable_pll:
 	/* Enable PLL re-initialization, not needed for PHY Power Off and RRC cmds */
@@ -1296,6 +1401,31 @@ static void axgbe_phy_power_off(struct axgbe_port *pdata)
 	PMD_DRV_LOG(DEBUG, "phy powered off\n");
 }
 
+static bool enable_rx_adap(struct axgbe_port *pdata, enum axgbe_mode mode)
+{
+	struct axgbe_phy_data *phy_data = pdata->phy_data;
+	unsigned int ver;
+
+	/* Rx-Adaptation is not supported on older platforms(< 0x30H) */
+	ver = AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
+	if (ver < 0x30)
+		return false;
+
+	/* Re-driver models 4223 && 4227 do not support Rx-Adaptation */
+	if (phy_data->redrv &&
+	    (phy_data->redrv_model == AXGBE_PHY_REDRV_MODEL_4223 ||
+	     phy_data->redrv_model == AXGBE_PHY_REDRV_MODEL_4227))
+		return false;
+
+	/* 10G KR mode with AN does not support Rx-Adaptation */
+	if (mode == AXGBE_MODE_KR &&
+	    phy_data->port_mode != AXGBE_PORT_MODE_BACKPLANE_NO_AUTONEG)
+		return false;
+
+	pdata->en_rx_adap = 1;
+	return true;
+}
+
 static void axgbe_phy_sfi_mode(struct axgbe_port *pdata)
 {
 	struct axgbe_phy_data *phy_data = pdata->phy_data;
@@ -1304,8 +1434,13 @@ static void axgbe_phy_sfi_mode(struct axgbe_port *pdata)
 
 	/* 10G/SFI */
 	if (phy_data->sfp_cable != AXGBE_SFP_CABLE_PASSIVE) {
+		pdata->en_rx_adap = 0;
 		axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
 							AXGBE_MB_SUBCMD_ACTIVE);
+	} else if ((phy_data->sfp_cable == AXGBE_SFP_CABLE_PASSIVE) &&
+				(enable_rx_adap(pdata, AXGBE_MODE_SFI))) {
+		axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
+						AXGBE_MB_SUBCMD_RX_ADAP);
 	} else {
 		if (phy_data->sfp_cable_len <= 1)
 			axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_SFI,
@@ -1330,6 +1465,10 @@ static void axgbe_phy_kr_mode(struct axgbe_port *pdata)
 	axgbe_phy_set_redrv_mode(pdata);
 
 	/* 10G/KR */
+	if (enable_rx_adap(pdata, AXGBE_MODE_KR))
+		axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_KR,
+						AXGBE_MB_SUBCMD_RX_ADAP);
+	else
 		axgbe_phy_perform_ratechange(pdata, AXGBE_MB_CMD_SET_10G_KR,
 						AXGBE_MB_SUBCMD_NONE);
 	phy_data->cur_mode = AXGBE_MODE_KR;
@@ -1719,8 +1858,11 @@ static int axgbe_phy_link_status(struct axgbe_port *pdata, int *an_restart)
 			return 0;
 		}
 
-		if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los)
+		if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los) {
+			if (pdata->en_rx_adap)
+				pdata->rx_adapt_done = false;
 			return 0;
+		}
 	}
 
 	/* Link status is latched low, so read once to clear
@@ -1728,7 +1870,29 @@ static int axgbe_phy_link_status(struct axgbe_port *pdata, int *an_restart)
 	 */
 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
-	if (reg & MDIO_STAT1_LSTATUS)
+
+	if (pdata->en_rx_adap) {
+		/* if the link is available and adaptation is done,
+		 * declare link up
+		 */
+		if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
+			return 1;
+		/* If either link is not available or adaptation is not done,
+		 * retrigger the adaptation logic. (if the mode is not set,
+		 * then issue mailbox command first)
+		 */
+		if (pdata->mode_set) {
+			axgbe_phy_rx_adaptation(pdata);
+		} else {
+			pdata->rx_adapt_done = false;
+			axgbe_phy_set_mode(pdata, phy_data->cur_mode);
+		}
+
+		/* check again for the link and adaptation status */
+		reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
+		if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
+			return 1;
+	} else if (reg & MDIO_STAT1_LSTATUS)
 		return 1;
 
 	if (pdata->phy.autoneg == AUTONEG_ENABLE &&
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 23/24] net/axgbe: improve the false linkup in axgbe PHY status
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (20 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 22/24] net/axgbe: add support for Rx adaptation Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-12 12:52 ` [PATCH 24/24] net/axgbe: extend 10Mbps support to MAC version 21H Venkat Kumar Ande
  2024-04-22 15:12 ` [PATCH 01/24] net/axgbe: remove use of comm_owned field Ferruh Yigit
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

In the event of a change in AXGBE mode, the current auto-negotiation
needs to be reset and the AN cycle needs to be re-triggerred. However,
the current code ignores the return value of axgbe_set_mode(), leading to
false information as the link is declared without checking the status
register.

Fix this by propagating the mode switch status information to
axgbe_phy_status().

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_mdio.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_mdio.c b/drivers/net/axgbe/axgbe_mdio.c
index 9fe30e83bc..130a67479e 100644
--- a/drivers/net/axgbe/axgbe_mdio.c
+++ b/drivers/net/axgbe/axgbe_mdio.c
@@ -1028,7 +1028,7 @@ static enum axgbe_mode axgbe_phy_status_aneg(struct axgbe_port *pdata)
 	return pdata->phy_if.phy_impl.an_outcome(pdata);
 }
 
-static void axgbe_phy_status_result(struct axgbe_port *pdata)
+static bool axgbe_phy_status_result(struct axgbe_port *pdata)
 {
 	enum axgbe_mode mode;
 
@@ -1065,8 +1065,13 @@ static void axgbe_phy_status_result(struct axgbe_port *pdata)
 
 	pdata->phy.duplex = DUPLEX_FULL;
 
-	if (axgbe_set_mode(pdata, mode) && pdata->an_again)
+	if (!axgbe_set_mode(pdata, mode))
+		return false;
+
+	if (pdata->an_again)
 		axgbe_phy_reconfig_aneg(pdata);
+
+	return true;
 }
 
 static int autoneg_time_out(unsigned long autoneg_start_time)
@@ -1133,7 +1138,10 @@ static void axgbe_phy_status(struct axgbe_port *pdata)
 				return;
 			}
 		}
-		axgbe_phy_status_result(pdata);
+
+		if (axgbe_phy_status_result(pdata))
+			return;
+
 		if (rte_bit_relaxed_get32(AXGBE_LINK_INIT, &pdata->dev_state))
 			rte_bit_relaxed_clear32(AXGBE_LINK_INIT,
 						&pdata->dev_state);
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH 24/24] net/axgbe: extend 10Mbps support to MAC version 21H
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (21 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 23/24] net/axgbe: improve the false linkup in axgbe PHY status Venkat Kumar Ande
@ 2024-04-12 12:52 ` Venkat Kumar Ande
  2024-04-22 15:12 ` [PATCH 01/24] net/axgbe: remove use of comm_owned field Ferruh Yigit
  23 siblings, 0 replies; 26+ messages in thread
From: Venkat Kumar Ande @ 2024-04-12 12:52 UTC (permalink / raw)
  To: dev; +Cc: Selwin.Sebastian, Venkat Kumar Ande

MAC version 21H supports the 10Mbps speed. So, extend support to
platforms that support it.

Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
---
 drivers/net/axgbe/axgbe_phy_impl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/axgbe/axgbe_phy_impl.c b/drivers/net/axgbe/axgbe_phy_impl.c
index a1c42b7dd4..d41c6e9bc7 100644
--- a/drivers/net/axgbe/axgbe_phy_impl.c
+++ b/drivers/net/axgbe/axgbe_phy_impl.c
@@ -2012,9 +2012,9 @@ static bool axgbe_phy_port_mode_mismatch(struct axgbe_port *pdata)
 	struct axgbe_phy_data *phy_data = pdata->phy_data;
 	unsigned int ver;
 
-	/* 10 Mbps speed is not supported in ver < 30H */
+	/* 10 Mbps speed is supported in ver 21H and ver >= 30H */
 	ver = AXGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
-	if (ver < 0x30 && phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
+	if ((ver < 0x30 && ver != 0x21) && phy_data->port_speeds & AXGBE_PHY_PORT_SPEED_10)
 		return true;
 
 	switch (phy_data->port_mode) {
-- 
2.34.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 01/24] net/axgbe: remove use of comm_owned field
  2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
                   ` (22 preceding siblings ...)
  2024-04-12 12:52 ` [PATCH 24/24] net/axgbe: extend 10Mbps support to MAC version 21H Venkat Kumar Ande
@ 2024-04-22 15:12 ` Ferruh Yigit
  23 siblings, 0 replies; 26+ messages in thread
From: Ferruh Yigit @ 2024-04-22 15:12 UTC (permalink / raw)
  To: Venkat Kumar Ande, dev; +Cc: Selwin.Sebastian

On 4/12/2024 1:52 PM, Venkat Kumar Ande wrote:
> The comm_owned field can hide logic where double locking is attempted
> and prevent multiple threads for the same device from accessing the
> mutex properly.  Remove the comm_owned field and use the mutex API
> exclusively for gaining ownership.
> 
> Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
>

Hi Venkat,

None of the patches seems requested to be backported to the stable
trees, so users of the LTS release won't be able to benefit from these
fixes.

To backport fixes, it requires "Fixes: .." tag and "Cc: stable@dpdk.org"
For details please check:
https://doc.dpdk.org/guides/contributing/patches.html#patch-for-stable-releases


Can you please update commit logs to add mentioned metadata for backporting?


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH 04/24] net/axgbe: check mdio for non-zero ports and CL45 PHYs
  2024-04-12 12:52 ` [PATCH 04/24] net/axgbe: check mdio for non-zero ports and CL45 PHYs Venkat Kumar Ande
@ 2024-04-22 15:21   ` Ferruh Yigit
  0 siblings, 0 replies; 26+ messages in thread
From: Ferruh Yigit @ 2024-04-22 15:21 UTC (permalink / raw)
  To: Venkat Kumar Ande, dev; +Cc: Selwin.Sebastian

On 4/12/2024 1:52 PM, Venkat Kumar Ande wrote:
> The XGBE hardware has support for performing MDIO operations using an
> MDIO command request. The driver mistakenly uses the mdio port address
> as the MDIO command request device address instead of the MDIO command
> request port address. Additionally, the driver does not properly check
> for and create a clause 45 MDIO command.
> 
> Check the supplied MDIO register to determine if the request is a clause
> 45 operation (MII_ADDR_C45). For a clause 45 operation, extract device
> address and register number from the supplied MDIO register and use them
> to set the MDIO command request device address and register number fields.
> For a clause 22 operation, the MDIO request device address is set to zero
> and the MDIO command request register number is set to the supplied MDIO
> register. In either case, the supplied MDIO port address is used as the
> MDIO command request port address.
> 
> Signed-off-by: Venkat Kumar Ande <VenkatKumar.Ande@amd.com>
>

Hi Venkat,

I can see this commit fixes the mdio command, and commit log clearly
explains what was wrong and what is fixed.

But it is not possible to get what was the impact and what is fixed from
user perspective.
Like when MDIO command request was formed badly, what was wrong for
user, was driver completely not usable or setting some link config was
broken, or something else etc...

Same is valid for a few more commits in this set, can you please
describe the user impact in the commit log? This also helps users to
understand the priority of the issue/fix.

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2024-04-22 15:22 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-12 12:52 [PATCH 01/24] net/axgbe: remove use of comm_owned field Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 02/24] net/axgbe: remove field of SFP diagnostic support Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 03/24] net/axgbe: improve SFP 100Mbps auto-negotiation Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 04/24] net/axgbe: check mdio for non-zero ports and CL45 PHYs Venkat Kumar Ande
2024-04-22 15:21   ` Ferruh Yigit
2024-04-12 12:52 ` [PATCH 05/24] net/axgbe: remove unnecessary conversion to bool Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 06/24] net/axgbe: reset link when the link never comes back Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 07/24] net/axgbe: check fluctuations for 1G BELFUSE SFP Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 08/24] net/axgbe: update DMA coherency values Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 09/24] net/axgbe: disable interrupts during device removal Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 10/24] net/axgbe: yellow carp devices do not need rrc Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 11/24] net/axgbe: use definitions for mailbox commands Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 12/24] net/axgbe: enable PLL control for fixed PHY modes only Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 13/24] net/axgbe: improve the SFP codes check for DAC cables Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 14/24] net/axgbe: improve logic around active and passive cables Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 15/24] net/axgbe: check only the minimum speed for cables Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 16/24] net/axgbe: add support for 10 Mbps speed Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 17/24] net/axgbe: flow Tx Ctrl Registers are h/w ver dependent Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 18/24] net/axgbe: delay AN timeout during KR training Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 19/24] net/axgbe: separate C22 and C45 transactions Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 20/24] net/axgbe: replace mii generic macro for c45 with AXGBE Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 21/24] net/axgbe: add 2.5GbE support to 10G BaseT mode Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 22/24] net/axgbe: add support for Rx adaptation Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 23/24] net/axgbe: improve the false linkup in axgbe PHY status Venkat Kumar Ande
2024-04-12 12:52 ` [PATCH 24/24] net/axgbe: extend 10Mbps support to MAC version 21H Venkat Kumar Ande
2024-04-22 15:12 ` [PATCH 01/24] net/axgbe: remove use of comm_owned field Ferruh Yigit

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).