summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIoana Radulescu <ruxandra.radulescu@nxp.com>2017-06-15 14:07:39 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-09-25 07:25:37 (GMT)
commit182f1498cc9401dae8674111a34a5adda4b2d813 (patch)
tree3eeedc135bb56983cfc6e4fd737c30c05d54e062
parent4aeb8ce16ef7b36f1c92bac193f36a6491b47760 (diff)
downloadlinux-182f1498cc9401dae8674111a34a5adda4b2d813.tar.xz
staging: fsl-dpaa2/eth: Fix adding FS rule at specific location
When inserting a flow steering rule through ethtool, the user may specify a location index. Ethtool manual says the expected behaviour is to overwrite any rule present in that location. What currently happens is that the driver passes on the location to MC with no further verifications and if there's already a rule present at that index, MC returns an error. Fix this by making sure the location is available, and if not free the current entry before inserting the new one. Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
index da5c753..9859814 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
@@ -664,6 +664,8 @@ static int prep_cls_rule(struct net_device *net_dev,
return 0;
}
+static int del_cls(struct net_device *net_dev, int location);
+
static int do_cls(struct net_device *net_dev,
struct ethtool_rx_flow_spec *fs,
bool add)
@@ -687,6 +689,13 @@ static int do_cls(struct net_device *net_dev,
fs->location >= rule_cnt)
return -EINVAL;
+ /* When adding a new rule, check if location if available,
+ * and if not free the existing table entry before inserting
+ * the new one
+ */
+ if (add && (priv->cls_rule[fs->location].in_use == true))
+ del_cls(net_dev, fs->location);
+
memset(&rule_cfg, 0, sizeof(rule_cfg));
rule_cfg.key_size = cls_key_size(priv);