Skip to content

Commit

Permalink
net/ixgbe: fix flex bytes flow director rule
Browse files Browse the repository at this point in the history
[ upstream commit 06cad27 ]

When a flexbytes flow director rule is created, the FDIRCTRL.FLEX_OFFSET
register is set, and it keeps its affect even after the flow director
flexbytes rule is destroyed, causing packets to be transferred to the
wrong place.

It is because setting FDIRCTRL shall only be permitted on Flow Director
initialization flow or clearing the Flow Director table according to the
datasheet, otherwise device may behave unexpectedly.

In order to evade this limitation, simulate the Flow Director
initialization flow or clearing the Flow Director table by setting
FDIRCMD.CLEARHT to 0x1B and then clear it back to 0x0B.

Fixes: f35fec6 ("net/ixgbe: enable flex bytes for generic flow API")

Signed-off-by: Dapeng Yu <dapengx.yu@intel.com>
Tested-by: Jun W Zhou <junx.w.zhou@intel.com>
Acked-by: Jeff Guo <jia.guo@intel.com>
  • Loading branch information
yudapengx authored and cpaelzer committed Feb 2, 2021
1 parent 2e89d3c commit be95781
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 7 deletions.
29 changes: 29 additions & 0 deletions drivers/net/ixgbe/ixgbe_fdir.c
Expand Up @@ -515,9 +515,30 @@ ixgbe_fdir_set_flexbytes_offset(struct rte_eth_dev *dev,
uint16_t offset)
{
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_hw_fdir_info *fdir_info =
IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
uint32_t fdirctrl;
int i;

if (fdir_info->flex_bytes_offset == offset)
return 0;

/**
* 82599 adapters flow director init flow cannot be restarted,
* Workaround 82599 silicon errata by performing the following steps
* before re-writing the FDIRCTRL control register with the same value.
* - write 1 to bit 8 of FDIRCMD register &
* - write 0 to bit 8 of FDIRCMD register
*/
IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) |
IXGBE_FDIRCMD_CLEARHT));
IXGBE_WRITE_FLUSH(hw);
IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
~IXGBE_FDIRCMD_CLEARHT));
IXGBE_WRITE_FLUSH(hw);

fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);

fdirctrl &= ~IXGBE_FDIRCTRL_FLEX_MASK;
Expand All @@ -532,6 +553,14 @@ ixgbe_fdir_set_flexbytes_offset(struct rte_eth_dev *dev,
break;
msec_delay(1);
}

if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
PMD_DRV_LOG(ERR, "Flow Director poll time exceeded!");
return -ETIMEDOUT;
}

fdir_info->flex_bytes_offset = offset;

return 0;
}

Expand Down
15 changes: 8 additions & 7 deletions drivers/net/ixgbe/ixgbe_flow.c
Expand Up @@ -3137,13 +3137,13 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
rte_memcpy(&fdir_info->mask,
&fdir_rule.mask,
sizeof(struct ixgbe_hw_fdir_mask));
fdir_info->flex_bytes_offset =
fdir_rule.flex_bytes_offset;

if (fdir_rule.mask.flex_bytes_mask)
ixgbe_fdir_set_flexbytes_offset(dev,
if (fdir_rule.mask.flex_bytes_mask) {
ret = ixgbe_fdir_set_flexbytes_offset(dev,
fdir_rule.flex_bytes_offset);

if (ret)
goto out;
}
ret = ixgbe_fdir_set_input_mask(dev);
if (ret)
goto out;
Expand All @@ -3161,8 +3161,9 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
if (ret)
goto out;

if (fdir_info->flex_bytes_offset !=
fdir_rule.flex_bytes_offset)
if (fdir_rule.mask.flex_bytes_mask &&
fdir_info->flex_bytes_offset !=
fdir_rule.flex_bytes_offset)
goto out;
}
}
Expand Down

0 comments on commit be95781

Please sign in to comment.