static int channels_prepare_data(const struct ethnl_req_info *req_base,
                                 struct ethnl_reply_data *reply_base,
-                                struct genl_info *info)
+                                const struct genl_info *info)
 {
        struct channels_reply_data *data = CHANNELS_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int coalesce_prepare_data(const struct ethnl_req_info *req_base,
                                 struct ethnl_reply_data *reply_base,
-                                struct genl_info *info)
+                                const struct genl_info *info)
 {
        struct coalesce_reply_data *data = COALESCE_REPDATA(reply_base);
-       struct netlink_ext_ack *extack = info ? info->extack : NULL;
        struct net_device *dev = reply_base->dev;
        int ret;
 
        if (ret < 0)
                return ret;
        ret = dev->ethtool_ops->get_coalesce(dev, &data->coalesce,
-                                            &data->kernel_coalesce, extack);
+                                            &data->kernel_coalesce,
+                                            info->extack);
        ethnl_ops_complete(dev);
 
        return ret;
 
 
 static int debug_prepare_data(const struct ethnl_req_info *req_base,
                              struct ethnl_reply_data *reply_base,
-                             struct genl_info *info)
+                             const struct genl_info *info)
 {
        struct debug_reply_data *data = DEBUG_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int eee_prepare_data(const struct ethnl_req_info *req_base,
                            struct ethnl_reply_data *reply_base,
-                           struct genl_info *info)
+                           const struct genl_info *info)
 {
        struct eee_reply_data *data = EEE_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 }
 
 static int eeprom_fallback(struct eeprom_req_info *request,
-                          struct eeprom_reply_data *reply,
-                          struct genl_info *info)
+                          struct eeprom_reply_data *reply)
 {
        struct net_device *dev = reply->base.dev;
        struct ethtool_modinfo modinfo = {0};
 
 static int eeprom_prepare_data(const struct ethnl_req_info *req_base,
                               struct ethnl_reply_data *reply_base,
-                              struct genl_info *info)
+                              const struct genl_info *info)
 {
        struct eeprom_reply_data *reply = MODULE_EEPROM_REPDATA(reply_base);
        struct eeprom_req_info *request = MODULE_EEPROM_REQINFO(req_base);
        if (ret)
                goto err_free;
 
-       ret = get_module_eeprom_by_page(dev, &page_data, info ? info->extack : NULL);
+       ret = get_module_eeprom_by_page(dev, &page_data, info->extack);
        if (ret < 0)
                goto err_ops;
 
        kfree(page_data.data);
 
        if (ret == -EOPNOTSUPP)
-               return eeprom_fallback(request, reply, info);
+               return eeprom_fallback(request, reply);
        return ret;
 }
 
 
 
 static int features_prepare_data(const struct ethnl_req_info *req_base,
                                 struct ethnl_reply_data *reply_base,
-                                struct genl_info *info)
+                                const struct genl_info *info)
 {
        struct features_reply_data *data = FEATURES_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int fec_prepare_data(const struct ethnl_req_info *req_base,
                            struct ethnl_reply_data *reply_base,
-                           struct genl_info *info)
+                           const struct genl_info *info)
 {
        __ETHTOOL_DECLARE_LINK_MODE_MASK(active_fec_modes) = {};
        struct fec_reply_data *data = FEC_REPDATA(reply_base);
 
 
 static int linkinfo_prepare_data(const struct ethnl_req_info *req_base,
                                 struct ethnl_reply_data *reply_base,
-                                struct genl_info *info)
+                                const struct genl_info *info)
 {
        struct linkinfo_reply_data *data = LINKINFO_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int linkmodes_prepare_data(const struct ethnl_req_info *req_base,
                                  struct ethnl_reply_data *reply_base,
-                                 struct genl_info *info)
+                                 const struct genl_info *info)
 {
        struct linkmodes_reply_data *data = LINKMODES_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int linkstate_prepare_data(const struct ethnl_req_info *req_base,
                                  struct ethnl_reply_data *reply_base,
-                                 struct genl_info *info)
+                                 const struct genl_info *info)
 {
        struct linkstate_reply_data *data = LINKSTATE_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int mm_prepare_data(const struct ethnl_req_info *req_base,
                           struct ethnl_reply_data *reply_base,
-                          struct genl_info *info)
+                          const struct genl_info *info)
 {
        struct mm_reply_data *data = MM_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int module_prepare_data(const struct ethnl_req_info *req_base,
                               struct ethnl_reply_data *reply_base,
-                              struct genl_info *info)
+                              const struct genl_info *info)
 {
        struct module_reply_data *data = MODULE_REPDATA(reply_base);
-       struct netlink_ext_ack *extack = info ? info->extack : NULL;
        struct net_device *dev = reply_base->dev;
        int ret;
 
        if (ret < 0)
                return ret;
 
-       ret = module_get_power_mode(dev, data, extack);
+       ret = module_get_power_mode(dev, data, info->extack);
        if (ret < 0)
                goto out_complete;
 
 
 
 static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
                                  const struct ethnl_dump_ctx *ctx,
-                                 struct netlink_callback *cb)
+                                 const struct genl_info *info)
 {
        void *ehdr;
        int ret;
 
-       ehdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
+       ehdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
                           ðtool_genl_family, NLM_F_MULTI,
                           ctx->ops->reply_cmd);
        if (!ehdr)
 
        ethnl_init_reply_data(ctx->reply_data, ctx->ops, dev);
        rtnl_lock();
-       ret = ctx->ops->prepare_data(ctx->req_info, ctx->reply_data, NULL);
+       ret = ctx->ops->prepare_data(ctx->req_info, ctx->reply_data, info);
        rtnl_unlock();
        if (ret < 0)
                goto out;
                dev_hold(dev);
                rtnl_unlock();
 
-               ret = ethnl_default_dump_one(skb, dev, ctx, cb);
+               ret = ethnl_default_dump_one(skb, dev, ctx, genl_info_dump(cb));
 
                rtnl_lock();
                dev_put(dev);
        struct ethnl_reply_data *reply_data;
        const struct ethnl_request_ops *ops;
        struct ethnl_req_info *req_info;
+       struct genl_info info;
        struct sk_buff *skb;
        void *reply_payload;
        int reply_len;
        int ret;
 
+       genl_info_init_ntf(&info, ðtool_genl_family, cmd);
+
        if (WARN_ONCE(cmd > ETHTOOL_MSG_KERNEL_MAX ||
                      !ethnl_default_notify_ops[cmd],
                      "unexpected notification type %u\n", cmd))
        req_info->flags |= ETHTOOL_FLAG_COMPACT_BITSETS;
 
        ethnl_init_reply_data(reply_data, ops, dev);
-       ret = ops->prepare_data(req_info, reply_data, NULL);
+       ret = ops->prepare_data(req_info, reply_data, &info);
        if (ret < 0)
                goto err_cleanup;
        ret = ops->reply_size(req_info, reply_data);
 
                             struct netlink_ext_ack *extack);
        int (*prepare_data)(const struct ethnl_req_info *req_info,
                            struct ethnl_reply_data *reply_data,
-                           struct genl_info *info);
+                           const struct genl_info *info);
        int (*reply_size)(const struct ethnl_req_info *req_info,
                          const struct ethnl_reply_data *reply_data);
        int (*fill_reply)(struct sk_buff *skb,
 
 
 static int pause_prepare_data(const struct ethnl_req_info *req_base,
                              struct ethnl_reply_data *reply_base,
-                             struct genl_info *info)
+                             const struct genl_info *info)
 {
        const struct pause_req_info *req_info = PAUSE_REQINFO(req_base);
-       struct netlink_ext_ack *extack = info ? info->extack : NULL;
        struct pause_reply_data *data = PAUSE_REPDATA(reply_base);
        enum ethtool_mac_stats_src src = req_info->src;
        struct net_device *dev = reply_base->dev;
        if ((src == ETHTOOL_MAC_STATS_SRC_EMAC ||
             src == ETHTOOL_MAC_STATS_SRC_PMAC) &&
            !__ethtool_dev_mm_supported(dev)) {
-               NL_SET_ERR_MSG_MOD(extack,
+               NL_SET_ERR_MSG_MOD(info->extack,
                                   "Device does not support MAC merge layer");
                ethnl_ops_complete(dev);
                return -EOPNOTSUPP;
 
 
 static int phc_vclocks_prepare_data(const struct ethnl_req_info *req_base,
                                    struct ethnl_reply_data *reply_base,
-                                   struct genl_info *info)
+                                   const struct genl_info *info)
 {
        struct phc_vclocks_reply_data *data = PHC_VCLOCKS_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int plca_get_cfg_prepare_data(const struct ethnl_req_info *req_base,
                                     struct ethnl_reply_data *reply_base,
-                                    struct genl_info *info)
+                                    const struct genl_info *info)
 {
        struct plca_reply_data *data = PLCA_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 static int plca_get_status_prepare_data(const struct ethnl_req_info *req_base,
                                        struct ethnl_reply_data *reply_base,
-                                       struct genl_info *info)
+                                       const struct genl_info *info)
 {
        struct plca_reply_data *data = PLCA_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int privflags_prepare_data(const struct ethnl_req_info *req_base,
                                  struct ethnl_reply_data *reply_base,
-                                 struct genl_info *info)
+                                 const struct genl_info *info)
 {
        struct privflags_reply_data *data = PRIVFLAGS_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 }
 
 static int pse_prepare_data(const struct ethnl_req_info *req_base,
-                              struct ethnl_reply_data *reply_base,
-                              struct genl_info *info)
+                           struct ethnl_reply_data *reply_base,
+                           const struct genl_info *info)
 {
        struct pse_reply_data *data = PSE_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
        if (ret < 0)
                return ret;
 
-       ret = pse_get_pse_attributes(dev, info ? info->extack : NULL, data);
+       ret = pse_get_pse_attributes(dev, info->extack, data);
 
        ethnl_ops_complete(dev);
 
 
 
 static int rings_prepare_data(const struct ethnl_req_info *req_base,
                              struct ethnl_reply_data *reply_base,
-                             struct genl_info *info)
+                             const struct genl_info *info)
 {
        struct rings_reply_data *data = RINGS_REPDATA(reply_base);
-       struct netlink_ext_ack *extack = info ? info->extack : NULL;
        struct net_device *dev = reply_base->dev;
        int ret;
 
        if (ret < 0)
                return ret;
        dev->ethtool_ops->get_ringparam(dev, &data->ringparam,
-                                       &data->kernel_ringparam, extack);
+                                       &data->kernel_ringparam, info->extack);
        ethnl_ops_complete(dev);
 
        return 0;
 
 
 static int
 rss_prepare_data(const struct ethnl_req_info *req_base,
-                struct ethnl_reply_data *reply_base, struct genl_info *info)
+                struct ethnl_reply_data *reply_base,
+                const struct genl_info *info)
 {
        struct rss_reply_data *data = RSS_REPDATA(reply_base);
        struct rss_req_info *request = RSS_REQINFO(req_base);
 
 
 static int stats_prepare_data(const struct ethnl_req_info *req_base,
                              struct ethnl_reply_data *reply_base,
-                             struct genl_info *info)
+                             const struct genl_info *info)
 {
        const struct stats_req_info *req_info = STATS_REQINFO(req_base);
-       struct netlink_ext_ack *extack = info ? info->extack : NULL;
        struct stats_reply_data *data = STATS_REPDATA(reply_base);
        enum ethtool_mac_stats_src src = req_info->src;
        struct net_device *dev = reply_base->dev;
        if ((src == ETHTOOL_MAC_STATS_SRC_EMAC ||
             src == ETHTOOL_MAC_STATS_SRC_PMAC) &&
            !__ethtool_dev_mm_supported(dev)) {
-               NL_SET_ERR_MSG_MOD(extack,
+               NL_SET_ERR_MSG_MOD(info->extack,
                                   "Device does not support MAC merge layer");
                ethnl_ops_complete(dev);
                return -EOPNOTSUPP;
 
 
 static int strset_prepare_data(const struct ethnl_req_info *req_base,
                               struct ethnl_reply_data *reply_base,
-                              struct genl_info *info)
+                              const struct genl_info *info)
 {
        const struct strset_req_info *req_info = STRSET_REQINFO(req_base);
        struct strset_reply_data *data = STRSET_REPDATA(reply_base);
 
 
 static int tsinfo_prepare_data(const struct ethnl_req_info *req_base,
                               struct ethnl_reply_data *reply_base,
-                              struct genl_info *info)
+                              const struct genl_info *info)
 {
        struct tsinfo_reply_data *data = TSINFO_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
 
 
 static int wol_prepare_data(const struct ethnl_req_info *req_base,
                            struct ethnl_reply_data *reply_base,
-                           struct genl_info *info)
+                           const struct genl_info *info)
 {
        struct wol_reply_data *data = WOL_REPDATA(reply_base);
        struct net_device *dev = reply_base->dev;
        dev->ethtool_ops->get_wol(dev, &data->wol);
        ethnl_ops_complete(dev);
        /* do not include password in notifications */
-       data->show_sopass = info && (data->wol.supported & WAKE_MAGICSECURE);
+       data->show_sopass = !genl_info_is_ntf(info) &&
+               (data->wol.supported & WAKE_MAGICSECURE);
 
        return 0;
 }