The configuration knobs that can be set are:
  - enabling/disabling frame preemption per-device;
  - setting the mask of preemptible queues;
  - configuring the minimum fragment size;

The values that can be retrieved from the hardware are:
  - if frame preemption is supported;
  - if frame preemption is active;
  - which queues can be set as preemptible;
  - which queues are set as preemptible;
  - the current minimum fragment size;

Signed-off-by: Vinicius Costa Gomes <vinicius.go...@intel.com>
---
 ethtool.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/ethtool.c b/ethtool.c
index 900880a..4c69d1c 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1573,6 +1573,28 @@ static void dump_fec(u32 fec)
                fprintf(stdout, " LLRS");
 }
 
+static void dump_fpcmd(struct ethtool_fp *fpcmd)
+{
+       fprintf(stdout, "       support: ");
+       if (fpcmd->fp_supported)
+               fprintf(stdout, "supported\n");
+       else
+               fprintf(stdout, "not supported\n");
+
+       fprintf(stdout, "       status: ");
+       if (fpcmd->fp_enabled)
+               fprintf(stdout, "enabled\n");
+       else
+               fprintf(stdout, "disabled\n");
+
+       fprintf(stdout, "       supported queues: %#x\n",
+               fpcmd->supported_queues_mask);
+       fprintf(stdout, "       preemptible queues: %#x\n",
+               fpcmd->preemptible_queues_mask);
+       fprintf(stdout, "       minimum fragment size: %d\n",
+               fpcmd->min_frag_size);
+}
+
 #define N_SOTS 7
 
 static char *so_timestamping_labels[N_SOTS] = {
@@ -4731,6 +4753,63 @@ static int do_seee(struct cmd_context *ctx)
        return 0;
 }
 
+static int do_get_preempt(struct cmd_context *ctx)
+{
+       struct ethtool_fp fpcmd;
+
+       if (ctx->argc != 0)
+               exit_bad_args();
+
+       fpcmd.cmd = ETHTOOL_GFP;
+       if (send_ioctl(ctx, &fpcmd)) {
+               perror("Cannot get frame preemption settings");
+               return 1;
+       }
+
+       fprintf(stdout, "Frame preemption Settings for %s:\n", ctx->devname);
+       dump_fpcmd(&fpcmd);
+
+       return 0;
+}
+
+static int do_set_preempt(struct cmd_context *ctx)
+{
+       int fp_c = -1, preempt_queues_mask_c = -1, min_frag_c = -1;
+       int change = -1;
+       struct ethtool_fp fpcmd;
+       struct cmdline_info cmdline_fp[] = {
+               { "fp", CMDL_BOOL, &fp_c, &fpcmd.fp_enabled },
+               { "preemptible-queues-mask", CMDL_U32, &preempt_queues_mask_c,
+                 &fpcmd.preemptible_queues_mask },
+               { "min-frag-size", CMDL_U32, &min_frag_c,
+                 &fpcmd.min_frag_size },
+       };
+
+       if (ctx->argc == 0)
+               exit_bad_args();
+
+       parse_generic_cmdline(ctx, &change, cmdline_fp,
+                             ARRAY_SIZE(cmdline_fp));
+
+       fpcmd.cmd = ETHTOOL_GFP;
+       if (send_ioctl(ctx, &fpcmd)) {
+               perror("Cannot get frame preemption settings");
+               return 1;
+       }
+
+       do_generic_set(cmdline_fp, ARRAY_SIZE(cmdline_fp), &change);
+
+       if (change) {
+               fpcmd.cmd = ETHTOOL_SFP;
+               if (send_ioctl(ctx, &fpcmd)) {
+                       perror("Cannot set frame preemption settings");
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 static int do_get_phy_tunable(struct cmd_context *ctx)
 {
        int argc = ctx->argc;
@@ -5505,6 +5584,19 @@ static const struct option args[] = {
                .help   = "Set FEC settings",
                .xhelp  = "             [ encoding auto|off|rs|baser|llrs 
[...]]\n"
        },
+       {
+               .opts   = "--show-frame-preemption",
+               .func   = do_get_preempt,
+               .help   = "Show Frame Preemption settings",
+       },
+       {
+               .opts   = "--set-frame-preemption",
+               .func   = do_set_preempt,
+               .help   = "Set Frame Preemption settings",
+               .xhelp  = "             [ fp on|off ]\n"
+                         "             [ preemptible-queues-mask %x ]\n"
+                         "             [ min-frag-size %d ]\n",
+       },
        {
                .opts   = "-Q|--per-queue",
                .func   = do_perqueue,
-- 
2.26.2

Reply via email to