[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ab4982b63f36f8b0522f412cc349025f1231517c.1664218348.git.ecree.xilinx@gmail.com>
Date: Mon, 26 Sep 2022 19:57:32 +0100
From: <ecree@...inx.com>
To: <netdev@...r.kernel.org>, <linux-net-drivers@....com>
CC: <davem@...emloft.net>, <kuba@...nel.org>, <pabeni@...hat.com>,
<edumazet@...gle.com>, <habetsm.xilinx@...il.com>,
Edward Cree <ecree.xilinx@...il.com>
Subject: [PATCH v2 net-next 2/6] sfc: bind indirect blocks for TC offload on EF100
From: Edward Cree <ecree.xilinx@...il.com>
Bind indirect blocks for recognised tunnel netdevices.
Currently these connect to a stub efx_tc_flower() that only returns
-EOPNOTSUPP; subsequent patches will implement flower offloads to the
Match-Action Engine.
Signed-off-by: Edward Cree <ecree.xilinx@...il.com>
---
drivers/net/ethernet/sfc/tc.c | 6 +++
drivers/net/ethernet/sfc/tc_bindings.c | 73 +++++++++++++++++++++++++-
drivers/net/ethernet/sfc/tc_bindings.h | 6 +++
3 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/sfc/tc.c b/drivers/net/ethernet/sfc/tc.c
index 23c4325e739a..cb7f76c74e66 100644
--- a/drivers/net/ethernet/sfc/tc.c
+++ b/drivers/net/ethernet/sfc/tc.c
@@ -10,6 +10,7 @@
*/
#include "tc.h"
+#include "tc_bindings.h"
#include "mae.h"
#include "ef100_rep.h"
#include "efx.h"
@@ -217,6 +218,9 @@ int efx_init_tc(struct efx_nic *efx)
if (rc)
return rc;
efx->tc->up = true;
+ rc = flow_indr_dev_register(efx_tc_indr_setup_cb, efx);
+ if (rc)
+ return rc;
return 0;
}
@@ -225,6 +229,8 @@ void efx_fini_tc(struct efx_nic *efx)
/* We can get called even if efx_init_struct_tc() failed */
if (!efx->tc)
return;
+ if (efx->tc->up)
+ flow_indr_dev_unregister(efx_tc_indr_setup_cb, efx, efx_tc_block_unbind);
efx_tc_deconfigure_rep_mport(efx);
efx_tc_deconfigure_default_rule(efx, &efx->tc->dflt.pf);
efx_tc_deconfigure_default_rule(efx, &efx->tc->dflt.wire);
diff --git a/drivers/net/ethernet/sfc/tc_bindings.c b/drivers/net/ethernet/sfc/tc_bindings.c
index d9401ee7b8e1..c18d64519c2d 100644
--- a/drivers/net/ethernet/sfc/tc_bindings.c
+++ b/drivers/net/ethernet/sfc/tc_bindings.c
@@ -46,7 +46,7 @@ static int efx_tc_block_cb(enum tc_setup_type type, void *type_data,
}
}
-static void efx_tc_block_unbind(void *cb_priv)
+void efx_tc_block_unbind(void *cb_priv)
{
struct efx_tc_block_binding *binding = cb_priv;
@@ -135,6 +135,77 @@ int efx_tc_setup_block(struct net_device *net_dev, struct efx_nic *efx,
}
}
+int efx_tc_indr_setup_cb(struct net_device *net_dev, struct Qdisc *sch,
+ void *cb_priv, enum tc_setup_type type,
+ void *type_data, void *data,
+ void (*cleanup)(struct flow_block_cb *block_cb))
+{
+ struct flow_block_offload *tcb = type_data;
+ struct efx_tc_block_binding *binding;
+ struct flow_block_cb *block_cb;
+ struct efx_nic *efx = cb_priv;
+ bool is_ovs_int_port;
+ int rc;
+
+ if (!net_dev)
+ return -EOPNOTSUPP;
+
+ if (tcb->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS &&
+ tcb->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS)
+ return -EOPNOTSUPP;
+
+ is_ovs_int_port = netif_is_ovs_master(net_dev);
+ if (tcb->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS &&
+ !is_ovs_int_port)
+ return -EOPNOTSUPP;
+
+ if (is_ovs_int_port)
+ return -EOPNOTSUPP;
+
+ switch (type) {
+ case TC_SETUP_BLOCK:
+ switch (tcb->command) {
+ case FLOW_BLOCK_BIND:
+ binding = efx_tc_create_binding(efx, NULL, net_dev, tcb->block);
+ if (IS_ERR(binding))
+ return PTR_ERR(binding);
+ block_cb = flow_indr_block_cb_alloc(efx_tc_block_cb, binding,
+ binding, efx_tc_block_unbind,
+ tcb, net_dev, sch, data, binding,
+ cleanup);
+ rc = PTR_ERR_OR_ZERO(block_cb);
+ netif_dbg(efx, drv, efx->net_dev,
+ "bind indr block for device %s, rc %d\n",
+ net_dev ? net_dev->name : NULL, rc);
+ if (rc) {
+ list_del(&binding->list);
+ kfree(binding);
+ } else {
+ flow_block_cb_add(block_cb, tcb);
+ }
+ return rc;
+ case FLOW_BLOCK_UNBIND:
+ binding = efx_tc_find_binding(efx, net_dev);
+ if (!binding)
+ return -ENOENT;
+ block_cb = flow_block_cb_lookup(tcb->block,
+ efx_tc_block_cb,
+ binding);
+ if (!block_cb)
+ return -ENOENT;
+ flow_indr_block_cb_remove(block_cb, tcb);
+ netif_dbg(efx, drv, efx->net_dev,
+ "unbind indr block for device %s\n",
+ net_dev ? net_dev->name : NULL);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
/* .ndo_setup_tc implementation
* Entry point for flower block and filter management.
*/
diff --git a/drivers/net/ethernet/sfc/tc_bindings.h b/drivers/net/ethernet/sfc/tc_bindings.h
index bcd63c270585..c210bb09150e 100644
--- a/drivers/net/ethernet/sfc/tc_bindings.h
+++ b/drivers/net/ethernet/sfc/tc_bindings.h
@@ -16,8 +16,14 @@
struct efx_rep;
+void efx_tc_block_unbind(void *cb_priv);
int efx_tc_setup_block(struct net_device *net_dev, struct efx_nic *efx,
struct flow_block_offload *tcb, struct efx_rep *efv);
int efx_tc_setup(struct net_device *net_dev, enum tc_setup_type type,
void *type_data);
+
+int efx_tc_indr_setup_cb(struct net_device *net_dev, struct Qdisc *sch,
+ void *cb_priv, enum tc_setup_type type,
+ void *type_data, void *data,
+ void (*cleanup)(struct flow_block_cb *block_cb));
#endif /* EFX_TC_BINDINGS_H */
Powered by blists - more mailing lists