#include "nfp_net_ctrl.h"
 #include "nfp_net.h"
 
+enum nfp_dump_diag {
+       NFP_DUMP_NSP_DIAG = 0,
+};
+
 /* Support for stats. Returns netdev, driver, and device stats */
 enum { NETDEV_ET_STATS, NFP_NET_DRV_ET_STATS, NFP_NET_DEV_ET_STATS };
 struct _nfp_net_et_stats {
        return 0;
 }
 
+/* Other debug dumps
+ */
+static int
+nfp_dump_nsp_diag(struct nfp_net *nn, struct ethtool_dump *dump, void *buffer)
+{
+       struct nfp_resource *res;
+       int ret;
+
+       if (!nn->cpp)
+               return -EOPNOTSUPP;
+
+       dump->version = 1;
+       dump->flag = NFP_DUMP_NSP_DIAG;
+
+       res = nfp_resource_acquire(nn->cpp, NFP_RESOURCE_NSP_DIAG);
+       if (IS_ERR(res))
+               return PTR_ERR(res);
+
+       if (buffer) {
+               if (dump->len != nfp_resource_size(res)) {
+                       ret = -EINVAL;
+                       goto exit_release;
+               }
+
+               ret = nfp_cpp_read(nn->cpp, nfp_resource_cpp_id(res),
+                                  nfp_resource_address(res),
+                                  buffer, dump->len);
+               if (ret != dump->len)
+                       ret = ret < 0 ? ret : -EIO;
+               else
+                       ret = 0;
+       } else {
+               dump->len = nfp_resource_size(res);
+               ret = 0;
+       }
+exit_release:
+       nfp_resource_release(res);
+
+       return ret;
+}
+
+static int nfp_net_set_dump(struct net_device *netdev, struct ethtool_dump *val)
+{
+       struct nfp_net *nn = netdev_priv(netdev);
+
+       if (!nn->cpp)
+               return -EOPNOTSUPP;
+
+       if (val->flag != NFP_DUMP_NSP_DIAG)
+               return -EINVAL;
+
+       nn->ethtool_dump_flag = val->flag;
+
+       return 0;
+}
+
+static int
+nfp_net_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
+{
+       return nfp_dump_nsp_diag(netdev_priv(netdev), dump, NULL);
+}
+
+static int
+nfp_net_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
+                     void *buffer)
+{
+       return nfp_dump_nsp_diag(netdev_priv(netdev), dump, buffer);
+}
+
 static int nfp_net_set_coalesce(struct net_device *netdev,
                                struct ethtool_coalesce *ec)
 {
        .set_rxfh               = nfp_net_set_rxfh,
        .get_regs_len           = nfp_net_get_regs_len,
        .get_regs               = nfp_net_get_regs,
+       .set_dump               = nfp_net_set_dump,
+       .get_dump_flag          = nfp_net_get_dump_flag,
+       .get_dump_data          = nfp_net_get_dump_data,
        .get_coalesce           = nfp_net_get_coalesce,
        .set_coalesce           = nfp_net_set_coalesce,
        .get_channels           = nfp_net_get_channels,