net/cxgbe: implement flow flush operation
authorShagun Agrawal <shaguna@chelsio.com>
Fri, 8 Jun 2018 17:58:17 +0000 (23:28 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Thu, 14 Jun 2018 17:27:50 +0000 (19:27 +0200)
Add API to flush all the filters under specified port.

Signed-off-by: Shagun Agrawal <shaguna@chelsio.com>
Signed-off-by: Kumar Sanghvi <kumaras@chelsio.com>
Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
drivers/net/cxgbe/cxgbe_filter.h
drivers/net/cxgbe/cxgbe_flow.c

index cd1e329..4df37b9 100644 (file)
@@ -141,6 +141,7 @@ struct filter_entry {
        u32 pending:1;              /* filter action is pending FW reply */
        struct filter_ctx *ctx;     /* caller's completion hook */
        struct rte_eth_dev *dev;    /* Port's rte eth device */
+       void *private;              /* For use by apps using filter_entry */
 
        /* This will store the actual tid */
        u32 tid;
index 7af18c3..23b7d00 100644 (file)
@@ -468,6 +468,8 @@ cxgbe_flow_create(struct rte_eth_dev *dev,
                return NULL;
        }
 
+       flow->f->private = flow; /* Will be used during flush */
+
        return flow;
 }
 
@@ -632,11 +634,47 @@ cxgbe_flow_validate(struct rte_eth_dev *dev,
        return 0;
 }
 
+/*
+ * @ret : > 0 filter destroyed succsesfully
+ *        < 0 error destroying filter
+ *        == 1 filter not active / not found
+ */
+static int
+cxgbe_check_n_destroy(struct filter_entry *f, struct rte_eth_dev *dev,
+                     struct rte_flow_error *e)
+{
+       if (f && (f->valid || f->pending) &&
+           f->dev == dev && /* Only if user has asked for this port */
+            f->private) /* We (rte_flow) created this filter */
+               return cxgbe_flow_destroy(dev, (struct rte_flow *)f->private,
+                                         e);
+       return 1;
+}
+
+static int cxgbe_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *e)
+{
+       struct adapter *adap = ethdev2adap(dev);
+       unsigned int i;
+       int ret = 0;
+
+       if (adap->tids.ftid_tab) {
+               struct filter_entry *f = &adap->tids.ftid_tab[0];
+
+               for (i = 0; i < adap->tids.nftids; i++, f++) {
+                       ret = cxgbe_check_n_destroy(f, dev, e);
+                       if (ret < 0)
+                               goto out;
+               }
+       }
+out:
+       return ret >= 0 ? 0 : ret;
+}
+
 static const struct rte_flow_ops cxgbe_flow_ops = {
        .validate       = cxgbe_flow_validate,
        .create         = cxgbe_flow_create,
        .destroy        = cxgbe_flow_destroy,
-       .flush          = NULL,
+       .flush          = cxgbe_flow_flush,
        .query          = cxgbe_flow_query,
        .isolate        = NULL,
 };