DPDK patches and discussions
 help / color / mirror / Atom feed
From: Igor Russkikh <Igor.Russkikh@aquantia.com>
To: "dev@dpdk.org" <dev@dpdk.org>
Cc: Pavel Belous <Pavel.Belous@aquantia.com>,
	Igor Russkikh <Igor.Russkikh@aquantia.com>,
	"stable@dpdk.org" <stable@dpdk.org>
Subject: [dpdk-dev] [PATCH 08/11] net/atlantic: flow control settings synchronization on rx
Date: Mon, 29 Apr 2019 08:20:23 +0000	[thread overview]
Message-ID: <78861b0be3a56a2e5d3996467e5eb05bcd395ea6.1556525874.git.igor.russkikh@aquantia.com> (raw)
Message-ID: <20190429082023.h3g_6SELR50R9tGPtVcdH1qh-NSeiENzhCMxTVHwrr4@z> (raw)
In-Reply-To: <cover.1556525874.git.igor.russkikh@aquantia.com>

From: Pavel Belous <pavel.belous@aquantia.com>

Driver should track negotiated PHY flow control settings during
link state changes and update MAC level flow control configuration.

Otherwise there could be unexpected pause frames generation which
could lockup the datapath.

Fixes: 4c1c8f76463f ("net/atlantic: add flow control configuration")
cc: stable@dpdk.org
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: Pavel Belous <pavel.belous@aquantia.com>
---
 drivers/net/atlantic/atl_ethdev.c             | 24 +++++++++++++++----
 drivers/net/atlantic/atl_types.h              |  1 +
 drivers/net/atlantic/hw_atl/hw_atl_b0.c       |  6 +++++
 drivers/net/atlantic/hw_atl/hw_atl_b0.h       |  2 ++
 .../net/atlantic/hw_atl/hw_atl_utils_fw2x.c   |  9 +++++++
 5 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c
index 485ef159eb05..6cc8d198041e 100644
--- a/drivers/net/atlantic/atl_ethdev.c
+++ b/drivers/net/atlantic/atl_ethdev.c
@@ -1160,6 +1160,7 @@ atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
 {
 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct rte_eth_link link, old;
+	u32 fc = AQ_NIC_FC_OFF;
 	int err = 0;
 
 	link.link_status = ETH_LINK_DOWN;
@@ -1194,6 +1195,15 @@ atl_dev_link_update(struct rte_eth_dev *dev, int wait __rte_unused)
 	if (link.link_status == old.link_status)
 		return -1;
 
+	/* Driver has to update flow control settings on RX block
+	 * on any link event.
+	 * We should query FW whether it negotiated FC.
+	 */
+	if (hw->aq_fw_ops->get_flow_control) {
+		hw->aq_fw_ops->get_flow_control(hw, &fc);
+		hw_atl_b0_set_fc(hw, fc, 0U);
+	}
+
 	if (rte_eal_alarm_set(1000 * 1000,
 			      atl_dev_delayed_handler, (void *)dev) < 0)
 		PMD_DRV_LOG(ERR, "rte_eal_alarm_set fail");
@@ -1496,14 +1506,20 @@ static int
 atl_flow_ctrl_get(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
 {
 	struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	u32 fc = AQ_NIC_FC_OFF;
+
+	if (hw->aq_fw_ops->get_flow_control == NULL)
+		return -ENOTSUP;
+
+	hw->aq_fw_ops->get_flow_control(hw, &fc);
 
-	if (hw->aq_nic_cfg->flow_control == AQ_NIC_FC_OFF)
+	if (fc == AQ_NIC_FC_OFF)
 		fc_conf->mode = RTE_FC_NONE;
-	else if (hw->aq_nic_cfg->flow_control & (AQ_NIC_FC_RX | AQ_NIC_FC_TX))
+	else if (fc & (AQ_NIC_FC_RX | AQ_NIC_FC_TX))
 		fc_conf->mode = RTE_FC_FULL;
-	else if (hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
+	else if (fc & AQ_NIC_FC_RX)
 		fc_conf->mode = RTE_FC_RX_PAUSE;
-	else if (hw->aq_nic_cfg->flow_control & AQ_NIC_FC_RX)
+	else if (fc & AQ_NIC_FC_RX)
 		fc_conf->mode = RTE_FC_TX_PAUSE;
 
 	return 0;
diff --git a/drivers/net/atlantic/atl_types.h b/drivers/net/atlantic/atl_types.h
index 84a4776951db..19aaf37673cd 100644
--- a/drivers/net/atlantic/atl_types.h
+++ b/drivers/net/atlantic/atl_types.h
@@ -169,6 +169,7 @@ struct aq_fw_ops {
 	int (*get_eee_rate)(struct aq_hw_s *self, u32 *rate,
 			u32 *supported_rates);
 
+	int (*get_flow_control)(struct aq_hw_s *self, u32 *fc);
 	int (*set_flow_control)(struct aq_hw_s *self);
 
 	int (*led_control)(struct aq_hw_s *self, u32 mode);
diff --git a/drivers/net/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/atlantic/hw_atl/hw_atl_b0.c
index e525a8581e6f..a76268e923e6 100644
--- a/drivers/net/atlantic/hw_atl/hw_atl_b0.c
+++ b/drivers/net/atlantic/hw_atl/hw_atl_b0.c
@@ -26,6 +26,12 @@ int hw_atl_b0_hw_reset(struct aq_hw_s *self)
 	return err;
 }
 
+int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc)
+{
+	hw_atl_rpb_rx_xoff_en_per_tc_set(self, !!(fc & AQ_NIC_FC_RX), tc);
+	return 0;
+}
+
 static int hw_atl_b0_hw_qos_set(struct aq_hw_s *self)
 {
 	u32 tc = 0U;
diff --git a/drivers/net/atlantic/hw_atl/hw_atl_b0.h b/drivers/net/atlantic/hw_atl/hw_atl_b0.h
index 06feb56c1620..d1ba2aceb390 100644
--- a/drivers/net/atlantic/hw_atl/hw_atl_b0.h
+++ b/drivers/net/atlantic/hw_atl/hw_atl_b0.h
@@ -11,6 +11,8 @@
 int hw_atl_b0_hw_reset(struct aq_hw_s *self);
 int hw_atl_b0_hw_init(struct aq_hw_s *self, u8 *mac_addr);
 
+int hw_atl_b0_set_fc(struct aq_hw_s *self, u32 fc, u32 tc);
+
 int hw_atl_b0_hw_ring_tx_init(struct aq_hw_s *self, uint64_t base_addr,
 		int index, int size, int cpu, int vec);
 int hw_atl_b0_hw_ring_rx_init(struct aq_hw_s *self, uint64_t base_addr,
diff --git a/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c
index de4189441fad..e07ed5e3a8c9 100644
--- a/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c
+++ b/drivers/net/atlantic/hw_atl/hw_atl_utils_fw2x.c
@@ -473,7 +473,15 @@ static int aq_fw2x_get_eee_rate(struct aq_hw_s *self, u32 *rate,
 	return err;
 }
 
+static int aq_fw2x_get_flow_control(struct aq_hw_s *self, u32 *fc)
+{
+	u32 mpi_state = aq_hw_read_reg(self, HW_ATL_FW2X_MPI_CONTROL2_ADDR);
+
+	*fc = ((mpi_state & BIT(CAPS_HI_PAUSE)) ? AQ_NIC_FC_RX : 0) |
+	      ((mpi_state & BIT(CAPS_HI_ASYMMETRIC_PAUSE)) ? AQ_NIC_FC_TX : 0);
 
+	return 0;
+}
 
 static int aq_fw2x_set_flow_control(struct aq_hw_s *self)
 {
@@ -714,6 +722,7 @@ const struct aq_fw_ops aq_fw_2x_ops = {
 	.get_cable_len = aq_fw2x_get_cable_len,
 	.set_eee_rate = aq_fw2x_set_eee_rate,
 	.get_eee_rate = aq_fw2x_get_eee_rate,
+	.get_flow_control = aq_fw2x_get_flow_control,
 	.set_flow_control = aq_fw2x_set_flow_control,
 	.led_control = aq_fw2x_led_control,
 	.get_eeprom = aq_fw2x_get_eeprom,
-- 
2.17.1


  parent reply	other threads:[~2019-04-29  8:21 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-29  8:20 [dpdk-dev] [PATCH 00/11] Aquantia atlantic bugfixes Igor Russkikh
2019-04-29  8:20 ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 01/11] net/atlantic: enable broadcast traffic Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 02/11] net/atlantic: extra line at eof Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29 13:57   ` Ferruh Yigit
2019-04-29 13:57     ` Ferruh Yigit
2019-04-29  8:20 ` [dpdk-dev] [PATCH 03/11] net/atlantic: bad indentation Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 04/11] net/atlantic: eeprom get/set should consider offset Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 05/11] net/atlantic: fix max eeprom size Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 06/11] net/atlantic: validity check for eeprom dev address Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 07/11] net/atlantic: bad logic with offsets talking with firmware Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` Igor Russkikh [this message]
2019-04-29  8:20   ` [dpdk-dev] [PATCH 08/11] net/atlantic: flow control settings synchronization on rx Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 09/11] net/atlantic: use capability bits to detect eeprom access Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 10/11] net/atlantic: typo on args check Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-04-29  8:20 ` [dpdk-dev] [PATCH 11/11] net/atlantic: extra err check Igor Russkikh
2019-04-29  8:20   ` Igor Russkikh
2019-05-08 16:05 ` [dpdk-dev] [PATCH 00/11] Aquantia atlantic bugfixes Kevin Traynor
2019-05-08 16:05   ` Kevin Traynor
2019-05-13  7:59   ` Igor Russkikh
2019-05-13  7:59     ` Igor Russkikh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=78861b0be3a56a2e5d3996467e5eb05bcd395ea6.1556525874.git.igor.russkikh@aquantia.com \
    --to=igor.russkikh@aquantia.com \
    --cc=Pavel.Belous@aquantia.com \
    --cc=dev@dpdk.org \
    --cc=stable@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).