Blob Blame History Raw
From: John Hurley <john.hurley@netronome.com>
Date: Thu, 16 Nov 2017 17:06:42 -0800
Subject: nfp: register flower reprs for egress dev offload
Patch-mainline: v4.15-rc1
Git-commit: 1a24d4f9c07cc5b9d2207cd84236dff3048438e5
References: bsc#1109837

Register a callback for offloading flows that have a repr as their egress
device. The new egdev_register function is added to net-next for the 4.15
release.

Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
---
 drivers/net/ethernet/netronome/nfp/flower/main.c    |   18 ++++++++++++++++++
 drivers/net/ethernet/netronome/nfp/flower/main.h    |    2 ++
 drivers/net/ethernet/netronome/nfp/flower/offload.c |    6 ++++++
 drivers/net/ethernet/netronome/nfp/nfp_app.h        |   20 ++++++++++++++++++++
 drivers/net/ethernet/netronome/nfp/nfp_net_repr.c   |    9 ++++++++-
 5 files changed, 54 insertions(+), 1 deletion(-)

--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -125,6 +125,21 @@ nfp_flower_repr_netdev_stop(struct nfp_a
 	return nfp_flower_cmsg_portmod(repr, false);
 }
 
+static int
+nfp_flower_repr_netdev_init(struct nfp_app *app, struct net_device *netdev)
+{
+	return tc_setup_cb_egdev_register(netdev,
+					  nfp_flower_setup_tc_egress_cb,
+					  netdev_priv(netdev));
+}
+
+static void
+nfp_flower_repr_netdev_clean(struct nfp_app *app, struct net_device *netdev)
+{
+	tc_setup_cb_egdev_unregister(netdev, nfp_flower_setup_tc_egress_cb,
+				     netdev_priv(netdev));
+}
+
 static void nfp_flower_sriov_disable(struct nfp_app *app)
 {
 	struct nfp_flower_priv *priv = app->priv;
@@ -452,6 +467,9 @@ const struct nfp_app_type app_flower = {
 	.vnic_init	= nfp_flower_vnic_init,
 	.vnic_clean	= nfp_flower_vnic_clean,
 
+	.repr_init	= nfp_flower_repr_netdev_init,
+	.repr_clean	= nfp_flower_repr_netdev_clean,
+
 	.repr_open	= nfp_flower_repr_netdev_open,
 	.repr_stop	= nfp_flower_repr_netdev_stop,
 
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -196,5 +196,7 @@ void nfp_tunnel_del_ipv4_off(struct nfp_
 void nfp_tunnel_add_ipv4_off(struct nfp_app *app, __be32 ipv4);
 void nfp_tunnel_request_route(struct nfp_app *app, struct sk_buff *skb);
 void nfp_tunnel_keep_alive(struct nfp_app *app, struct sk_buff *skb);
+int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data,
+				  void *cb_priv);
 
 #endif
--- a/drivers/net/ethernet/netronome/nfp/flower/offload.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/offload.c
@@ -465,6 +465,12 @@ nfp_flower_repr_offload(struct nfp_app *
 	return -EOPNOTSUPP;
 }
 
+int nfp_flower_setup_tc_egress_cb(enum tc_setup_type type, void *type_data,
+				  void *cb_priv)
+{
+	return -EINVAL;
+}
+
 static int nfp_flower_setup_tc_block_cb(enum tc_setup_type type,
 					void *type_data, void *cb_priv)
 {
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h
@@ -76,6 +76,8 @@ extern const struct nfp_app_type app_flo
  * @vnic_free:	free up app's vNIC state
  * @vnic_init:	vNIC netdev was registered
  * @vnic_clean:	vNIC netdev about to be unregistered
+ * @repr_init:	representor about to be registered
+ * @repr_clean:	representor about to be unregistered
  * @repr_open:	representor netdev open callback
  * @repr_stop:	representor netdev stop callback
  * @start:	start application logic
@@ -109,6 +111,9 @@ struct nfp_app_type {
 	int (*vnic_init)(struct nfp_app *app, struct nfp_net *nn);
 	void (*vnic_clean)(struct nfp_app *app, struct nfp_net *nn);
 
+	int (*repr_init)(struct nfp_app *app, struct net_device *netdev);
+	void (*repr_clean)(struct nfp_app *app, struct net_device *netdev);
+
 	int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
 	int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr);
 
@@ -212,6 +217,21 @@ static inline int nfp_app_repr_stop(stru
 	return app->type->repr_stop(app, repr);
 }
 
+static inline int
+nfp_app_repr_init(struct nfp_app *app, struct net_device *netdev)
+{
+	if (!app->type->repr_init)
+		return 0;
+	return app->type->repr_init(app, netdev);
+}
+
+static inline void
+nfp_app_repr_clean(struct nfp_app *app, struct net_device *netdev)
+{
+	if (app->type->repr_clean)
+		app->type->repr_clean(app, netdev);
+}
+
 static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
 {
 	app->ctrl = ctrl;
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -258,6 +258,7 @@ const struct net_device_ops nfp_repr_net
 static void nfp_repr_clean(struct nfp_repr *repr)
 {
 	unregister_netdev(repr->netdev);
+	nfp_app_repr_clean(repr->app, repr->netdev);
 	dst_release((struct dst_entry *)repr->dst);
 	nfp_port_free(repr->port);
 }
@@ -306,12 +307,18 @@ int nfp_repr_init(struct nfp_app *app, s
 		netdev->hw_features |= NETIF_F_HW_TC;
 	}
 
-	err = register_netdev(netdev);
+	err = nfp_app_repr_init(app, netdev);
 	if (err)
 		goto err_clean;
 
+	err = register_netdev(netdev);
+	if (err)
+		goto err_repr_clean;
+
 	return 0;
 
+err_repr_clean:
+	nfp_app_repr_clean(app, netdev);
 err_clean:
 	dst_release((struct dst_entry *)repr->dst);
 	return err;