When the last FDIR rule is destroyed, on flush, or when enabling
FDIR fails, the FDIR mode is reset to none, but Flow Director is
left enabled and the Rx packet buffer stays reduced.
Disable Flow Director and restore the Rx packet buffer size in
these cases, and when the first rule fails after FDIR was enabled.
Fixes: ea230dda16ad ("net/txgbe: configure flow director filter")
Fixes: 26048c25942f ("net/txgbe: fix FDIR mode clearing")
Cc: [email protected]
Signed-off-by: Zhang Tengfei <[email protected]>
---
drivers/net/txgbe/txgbe_ethdev.h | 1 +
drivers/net/txgbe/txgbe_fdir.c | 31 +++++++++++++++++++++++++++----
drivers/net/txgbe/txgbe_flow.c | 7 ++++++-
3 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index a617b70e3c..05c20fd58c 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -552,6 +552,7 @@ void txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t
direction,
* Flow director function prototypes
*/
int txgbe_fdir_configure(struct rte_eth_dev *dev);
+void txgbe_fdir_disable(struct txgbe_hw *hw);
int txgbe_fdir_set_input_mask(struct rte_eth_dev *dev);
uint16_t txgbe_fdir_get_flex_base(struct txgbe_fdir_rule *rule);
int txgbe_fdir_set_flexbytes_offset(struct rte_eth_dev *dev,
diff --git a/drivers/net/txgbe/txgbe_fdir.c b/drivers/net/txgbe/txgbe_fdir.c
index cee38a42b8..8e397c995c 100644
--- a/drivers/net/txgbe/txgbe_fdir.c
+++ b/drivers/net/txgbe/txgbe_fdir.c
@@ -368,6 +368,18 @@ txgbe_set_fdir_flex_conf(struct rte_eth_dev *dev, uint32_t
flex)
return 0;
}
+void
+txgbe_fdir_disable(struct txgbe_hw *hw)
+{
+ int i;
+
+ wr32(hw, TXGBE_FDIRCTL, 0);
+ wr32(hw, TXGBE_PBRXSIZE(0), hw->mac.rx_pb_size << 10);
+ for (i = 1; i < 8; i++)
+ wr32(hw, TXGBE_PBRXSIZE(i), 0);
+ txgbe_flush(hw);
+}
+
int
txgbe_fdir_configure(struct rte_eth_dev *dev)
{
@@ -408,27 +420,31 @@ txgbe_fdir_configure(struct rte_eth_dev *dev)
err = txgbe_fdir_store_input_mask(dev);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on setting FD mask");
- return err;
+ goto error;
}
err = txgbe_fdir_set_input_mask(dev);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on setting FD mask");
- return err;
+ goto error;
}
err = txgbe_set_fdir_flex_conf(dev, flex);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on setting FD flexible arguments.");
- return err;
+ goto error;
}
err = txgbe_fdir_enable(hw, fdirctrl);
if (err < 0) {
PMD_INIT_LOG(ERR, " Error on enabling FD.");
- return err;
+ goto error;
}
return 0;
+
+error:
+ txgbe_fdir_disable(hw);
+ return err;
}
/*
@@ -1138,12 +1154,16 @@ txgbe_fdir_filter_restore(struct rte_eth_dev *dev)
int
txgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
{
+ struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev);
struct txgbe_hw_fdir_info *fdir_info = TXGBE_DEV_FDIR(dev);
struct txgbe_fdir_filter *fdir_filter;
struct txgbe_fdir_filter *filter_flag;
+ bool fdir_enabled;
int ret = 0;
+ fdir_enabled = fdir_conf->mode != RTE_FDIR_MODE_NONE;
+
/* flush flow director */
rte_hash_reset(fdir_info->hash_handle);
memset(fdir_info->hash_map, 0,
@@ -1161,5 +1181,8 @@ txgbe_clear_all_fdir_filter(struct rte_eth_dev *dev)
if (filter_flag != NULL)
ret = txgbe_fdir_flush(dev);
+ if (fdir_enabled && txgbe_is_pf(hw))
+ txgbe_fdir_disable(hw);
+
return ret;
}
diff --git a/drivers/net/txgbe/txgbe_flow.c b/drivers/net/txgbe/txgbe_flow.c
index f2fc589a10..9fa79fc064 100644
--- a/drivers/net/txgbe/txgbe_flow.c
+++ b/drivers/net/txgbe/txgbe_flow.c
@@ -3483,8 +3483,10 @@ txgbe_flow_create(struct rte_eth_dev *dev,
rte_free(fdir_rule_ptr);
if (first_mask)
fdir_info->mask_added = FALSE;
- if (fdir_configured)
+ if (fdir_configured) {
+ txgbe_fdir_disable(TXGBE_DEV_HW(dev));
fdir_conf->mode = RTE_FDIR_MODE_NONE;
+ }
out:
TAILQ_REMOVE(&txgbe_flow_list,
txgbe_flow_mem_ptr, entries);
@@ -3637,6 +3639,9 @@ txgbe_flow_destroy(struct rte_eth_dev *dev,
fdir_info->mask_added = false;
fdir_info->flex_relative = false;
fdir_info->flex_bytes_offset = 0;
+ if (fdir_conf->mode != RTE_FDIR_MODE_NONE &&
+ txgbe_is_pf(TXGBE_DEV_HW(dev)))
+ txgbe_fdir_disable(TXGBE_DEV_HW(dev));
fdir_conf->mode = RTE_FDIR_MODE_NONE;
}
}
--
2.53.0