aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/netronome/nfp/nfp_app.c
diff options
context:
space:
mode:
authorJakub Kicinski <jakub.kicinski@netronome.com>2018-11-27 22:24:56 -0800
committerDavid S. Miller <davem@davemloft.net>2018-11-30 13:30:44 -0800
commit51a6588e8c08a108ca7daa899a28b3219fc47e46 (patch)
treea6582cbf8334663e6783c40358240cdf36d0fdde /drivers/net/ethernet/netronome/nfp/nfp_app.c
parentnfp: add locking around representor changes (diff)
downloadlinux-dev-51a6588e8c08a108ca7daa899a28b3219fc47e46.tar.xz
linux-dev-51a6588e8c08a108ca7daa899a28b3219fc47e46.zip
nfp: add offloads on representors
FW/HW can generally support the standard networking offloads on representors without any trouble. Add the ability for FW to advertise which features should be available on representors. Because representors are muxed on top of the vNIC we need to listen on feature changes of their lower devices, and update their features appropriately. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Reviewed-by: John Hurley <john.hurley@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/netronome/nfp/nfp_app.c')
-rw-r--r--drivers/net/ethernet/netronome/nfp/nfp_app.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.c b/drivers/net/ethernet/netronome/nfp/nfp_app.c
index 117553914342..3a973282b2bb 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.c
@@ -138,6 +138,38 @@ nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
return old;
}
+static void
+nfp_app_netdev_feat_change(struct nfp_app *app, struct net_device *netdev)
+{
+ struct nfp_net *nn;
+ unsigned int type;
+
+ if (!nfp_netdev_is_nfp_net(netdev))
+ return;
+ nn = netdev_priv(netdev);
+ if (nn->app != app)
+ return;
+
+ for (type = 0; type < __NFP_REPR_TYPE_MAX; type++) {
+ struct nfp_reprs *reprs;
+ unsigned int i;
+
+ reprs = rtnl_dereference(app->reprs[type]);
+ if (!reprs)
+ continue;
+
+ for (i = 0; i < reprs->num_reprs; i++) {
+ struct net_device *repr;
+
+ repr = rtnl_dereference(reprs->reprs[i]);
+ if (!repr)
+ continue;
+
+ nfp_repr_transfer_features(repr, netdev);
+ }
+ }
+}
+
static int
nfp_app_netdev_event(struct notifier_block *nb, unsigned long event, void *ptr)
{
@@ -147,6 +179,14 @@ nfp_app_netdev_event(struct notifier_block *nb, unsigned long event, void *ptr)
netdev = netdev_notifier_info_to_dev(ptr);
app = container_of(nb, struct nfp_app, netdev_nb);
+ /* Handle events common code is interested in */
+ switch (event) {
+ case NETDEV_FEAT_CHANGE:
+ nfp_app_netdev_feat_change(app, netdev);
+ break;
+ }
+
+ /* Call offload specific handlers */
if (app->type->netdev_event)
return app->type->netdev_event(app, netdev, event, ptr);
return NOTIFY_DONE;