nfp: register a notifier handler in a central location for the device
authorJakub Kicinski <jakub.kicinski@netronome.com>
Wed, 7 Nov 2018 01:07:33 +0000 (17:07 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 7 Nov 2018 19:45:22 +0000 (11:45 -0800)
Code interested in networking events registers its own notifier
handlers.  Create one device-wide notifier instance.

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>
drivers/net/ethernet/netronome/nfp/nfp_app.c
drivers/net/ethernet/netronome/nfp/nfp_app.h

index 68a0991aac22434d6d334c2e70eff543c5b0510f..4a1b8f79e7313d2b2cac0cabdce283ea01a63c2d 100644 (file)
@@ -136,6 +136,53 @@ nfp_app_reprs_set(struct nfp_app *app, enum nfp_repr_type type,
        return old;
 }
 
+static int
+nfp_app_netdev_event(struct notifier_block *nb, unsigned long event, void *ptr)
+{
+       struct net_device *netdev;
+       struct nfp_app *app;
+
+       netdev = netdev_notifier_info_to_dev(ptr);
+       app = container_of(nb, struct nfp_app, netdev_nb);
+
+       if (app->type->netdev_event)
+               return app->type->netdev_event(app, netdev, event, ptr);
+       return NOTIFY_DONE;
+}
+
+int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
+{
+       int err;
+
+       app->ctrl = ctrl;
+
+       if (app->type->start) {
+               err = app->type->start(app);
+               if (err)
+                       return err;
+       }
+
+       app->netdev_nb.notifier_call = nfp_app_netdev_event;
+       err = register_netdevice_notifier(&app->netdev_nb);
+       if (err)
+               goto err_app_stop;
+
+       return 0;
+
+err_app_stop:
+       if (app->type->stop)
+               app->type->stop(app);
+       return err;
+}
+
+void nfp_app_stop(struct nfp_app *app)
+{
+       unregister_netdevice_notifier(&app->netdev_nb);
+
+       if (app->type->stop)
+               app->type->stop(app);
+}
+
 struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id)
 {
        struct nfp_app *app;
index 4d6ecf99b1cc1ffd34dc5594c14d82e6bef00e0e..d578d856a009f8d7608615a4bb185eee70be2fb9 100644 (file)
@@ -69,6 +69,7 @@ extern const struct nfp_app_type app_abm;
  * @port_get_stats_strings:    get strings for extra statistics
  * @start:     start application logic
  * @stop:      stop application logic
+ * @netdev_event:      Netdevice notifier event
  * @ctrl_msg_rx:    control message handler
  * @ctrl_msg_rx_raw:   handler for control messages from data queues
  * @setup_tc:  setup TC ndo
@@ -122,6 +123,9 @@ struct nfp_app_type {
        int (*start)(struct nfp_app *app);
        void (*stop)(struct nfp_app *app);
 
+       int (*netdev_event)(struct nfp_app *app, struct net_device *netdev,
+                           unsigned long event, void *ptr);
+
        void (*ctrl_msg_rx)(struct nfp_app *app, struct sk_buff *skb);
        void (*ctrl_msg_rx_raw)(struct nfp_app *app, const void *data,
                                unsigned int len);
@@ -151,6 +155,7 @@ struct nfp_app_type {
  * @reprs:     array of pointers to representors
  * @type:      pointer to const application ops and info
  * @ctrl_mtu:  MTU to set on the control vNIC (set in .init())
+ * @netdev_nb: Netdevice notifier block
  * @priv:      app-specific priv data
  */
 struct nfp_app {
@@ -163,6 +168,9 @@ struct nfp_app {
 
        const struct nfp_app_type *type;
        unsigned int ctrl_mtu;
+
+       struct notifier_block netdev_nb;
+
        void *priv;
 };
 
@@ -264,21 +272,6 @@ nfp_app_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
        return app->type->repr_change_mtu(app, netdev, new_mtu);
 }
 
-static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
-{
-       app->ctrl = ctrl;
-       if (!app->type->start)
-               return 0;
-       return app->type->start(app);
-}
-
-static inline void nfp_app_stop(struct nfp_app *app)
-{
-       if (!app->type->stop)
-               return;
-       app->type->stop(app);
-}
-
 static inline const char *nfp_app_name(struct nfp_app *app)
 {
        if (!app)
@@ -430,6 +423,8 @@ nfp_app_ctrl_msg_alloc(struct nfp_app *app, unsigned int size, gfp_t priority);
 
 struct nfp_app *nfp_app_alloc(struct nfp_pf *pf, enum nfp_app_id id);
 void nfp_app_free(struct nfp_app *app);
+int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl);
+void nfp_app_stop(struct nfp_app *app);
 
 /* Callbacks shared between apps */