nfp: register flower reprs for egress dev offload
authorJohn Hurley <john.hurley@netronome.com>
Fri, 17 Nov 2017 01:06:42 +0000 (17:06 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 17 Nov 2017 05:09:36 +0000 (14:09 +0900)
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>
drivers/net/ethernet/netronome/nfp/flower/main.c
drivers/net/ethernet/netronome/nfp/flower/main.h
drivers/net/ethernet/netronome/nfp/flower/offload.c
drivers/net/ethernet/netronome/nfp/nfp_app.h
drivers/net/ethernet/netronome/nfp/nfp_net_repr.c

index e0283bb24f06876d59667484d5e909951bd0947d..8fcc90c0d2d3ad1a3f48348ca2d9c02e190133cb 100644 (file)
@@ -125,6 +125,21 @@ nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
        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,
 
index a69ea62e9c9c3a8f198409ad52eefdea3a730db1..e6b26c5ae6e0f11b8bdbe5593603e117bd1d5a4a 100644 (file)
@@ -196,5 +196,7 @@ void nfp_tunnel_del_ipv4_off(struct nfp_app *app, __be32 ipv4);
 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
index cdbb5464b790372edede5c9005833d0766ec828c..a0193e0c24a0b84241ce0ba839b40eddf0a75fef 100644 (file)
@@ -465,6 +465,12 @@ nfp_flower_repr_offload(struct nfp_app *app, struct net_device *netdev,
        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)
 {
index 54b67c9b8d5b6dc7a88785611a3dca6e84b1d563..0e5e0305ad1cea276516a9c50122c4a16575d9fe 100644 (file)
@@ -76,6 +76,8 @@ extern const struct nfp_app_type app_flower;
  * @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(struct nfp_app *app, struct nfp_repr *repr)
        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;
index fa052a929170b2e1e0091d3b6575edf24a00b3ec..924a05e05da027523e7845728c6ddc4d41accc0b 100644 (file)
@@ -258,6 +258,7 @@ const struct net_device_ops nfp_repr_netdev_ops = {
 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, struct net_device *netdev,
                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;