[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200608175255.3353-1-gvaradar@cisco.com>
Date: Mon, 8 Jun 2020 10:52:54 -0700
From: Govindarajulu Varadarajan <gvaradar@...co.com>
To: netdev@...r.kernel.org, edumazet@...gle.com, linville@...driver.com
Cc: govind.varadar@...il.com,
Govindarajulu Varadarajan <gvaradar@...co.com>
Subject: [PATCH ethtool 1/2] ethtool: add support for get/set ethtool_tunable
Add support for ETHTOOL_GTUNABLE and ETHTOOL_STUNABLE options.
Tested rx-copybreak on enic driver. Tested ETHTOOL_TUNNABLE_STRING
options with test/debug changes in kernel.
Signed-off-by: Govindarajulu Varadarajan <gvaradar@...co.com>
---
ethtool.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 227 insertions(+)
diff --git a/ethtool.c b/ethtool.c
index 900880a..6cff5dd 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -4731,6 +4731,217 @@ static int do_seee(struct cmd_context *ctx)
return 0;
}
+/* copy of net/ethtool/common.c */
+char
+tunable_strings[__ETHTOOL_TUNABLE_COUNT][ETH_GSTRING_LEN] = {
+ [ETHTOOL_ID_UNSPEC] = "Unspec",
+ [ETHTOOL_RX_COPYBREAK] = "rx-copybreak",
+ [ETHTOOL_TX_COPYBREAK] = "tx-copybreak",
+ [ETHTOOL_PFC_PREVENTION_TOUT] = "pfc-prevention-tout",
+};
+
+struct ethtool_tunable_info {
+ enum tunable_id t_id;
+ enum tunable_type_id t_type_id;
+ size_t size;
+ cmdline_type_t type;
+ union val {
+ u8 u8;
+ u16 u16;
+ u32 u32;
+ u64 u64;
+ int8_t s8;
+ int16_t s16;
+ int32_t s32;
+ int64_t s64;
+ void *str;
+ } seen;
+ union val wanted;
+};
+
+struct ethtool_tunable_info tinfo[] = {
+ { .t_id = ETHTOOL_RX_COPYBREAK,
+ .t_type_id = ETHTOOL_TUNABLE_U32,
+ .size = sizeof(u32),
+ .type = CMDL_U32,
+ },
+ { .t_id = ETHTOOL_TX_COPYBREAK,
+ .t_type_id = ETHTOOL_TUNABLE_U32,
+ .size = sizeof(u32),
+ .type = CMDL_U32,
+ },
+ { .t_id = ETHTOOL_PFC_PREVENTION_TOUT,
+ .t_type_id = ETHTOOL_TUNABLE_U16,
+ .size = sizeof(u16),
+ .type = CMDL_U16,
+ },
+};
+#define TINFO_SIZE ARRAY_SIZE(tinfo)
+
+static int do_stunable(struct cmd_context *ctx)
+{
+ struct cmdline_info cmdline_tunable[TINFO_SIZE];
+ int changed = 0;
+ int i;
+
+ for (i = 0; i < TINFO_SIZE; i++) {
+ cmdline_tunable[i].name = tunable_strings[tinfo[i].t_id];
+ cmdline_tunable[i].type = tinfo[i].type;
+ cmdline_tunable[i].wanted_val = &tinfo[i].wanted;
+ cmdline_tunable[i].seen_val = &tinfo[i].seen;
+ }
+
+ parse_generic_cmdline(ctx, &changed, cmdline_tunable, TINFO_SIZE);
+ if (!changed)
+ exit_bad_args();
+
+ for (i = 0; i < TINFO_SIZE; i++) {
+ char **val = (char **)&tinfo[i].wanted;
+ struct ethtool_tunable *tuna;
+ size_t size;
+ int *seen;
+ int ret;
+
+ seen = (int *)(&tinfo[i].seen);
+ if (!*seen)
+ continue;
+
+ size = sizeof(*tuna);
+ if (tinfo[i].type == CMDL_STR) {
+ size += strlen(*val) + 1;
+ } else {
+ size += tinfo[i].size;
+ }
+ tuna = calloc(1, size);
+ if (!tuna) {
+ perror(tunable_strings[tinfo[i].t_id]);
+ return 1;
+ }
+ tuna->cmd = ETHTOOL_STUNABLE;
+ tuna->id = tinfo[i].t_id;
+ tuna->type_id = tinfo[i].t_type_id;
+ if (tinfo[i].type == CMDL_STR) {
+ tuna->len = strlen(*val) + 1;
+ memcpy(tuna->data, *val, strlen(*val) + 1);
+ } else {
+ tuna->len = tinfo[i].size;
+ memcpy(tuna->data, &tinfo[i].wanted, tuna->len);
+ }
+ ret = send_ioctl(ctx, tuna);
+ if (ret) {
+ perror(tunable_strings[tuna->id]);
+ return ret;
+ }
+ free(tuna);
+ tuna = NULL;
+ /* reset seen and wanted to 0 */
+ memset(&tinfo[i].seen, 0, sizeof(tinfo[i].seen));
+ memset(&tinfo[i].wanted, 0, sizeof(tinfo[i].seen));
+ }
+ return 0;
+}
+
+static void print_tunable(struct ethtool_tunable *tuna)
+{
+ char *name = tunable_strings[tuna->id];
+ u8 *val_u8;
+ u16 *val_u16;
+ u32 *val_u32;
+ u64 *val_u64;
+ int8_t *val_s8;
+ int16_t *val_s16;
+ int32_t *val_s32;
+ long long int *val_s64;
+ char *val_str;
+
+ switch (tuna->type_id) {
+ case ETHTOOL_TUNABLE_U8:
+ val_u8 = (u8 *)tuna->data;
+ fprintf(stdout, "%s: %u\n", name, *val_u8);
+ break;
+ case ETHTOOL_TUNABLE_U16:
+ val_u16 = (u16 *)tuna->data;
+ fprintf(stdout, "%s: %u\n", name, *val_u16);
+ break;
+ case ETHTOOL_TUNABLE_U32:
+ val_u32 = (u32 *)tuna->data;
+ fprintf(stdout, "%s: %u\n", name, *val_u32);
+ break;
+ case ETHTOOL_TUNABLE_U64:
+ val_u64 = (u64 *)tuna->data;
+ fprintf(stdout, "%s: %llu\n", name, *val_u64);
+ break;
+ case ETHTOOL_TUNABLE_S8:
+ val_s8 = (int8_t *)tuna->data;
+ fprintf(stdout, "%s: %d\n", name, *val_s8);
+ break;
+ case ETHTOOL_TUNABLE_S16:
+ val_s16 = (int16_t *)tuna->data;
+ fprintf(stdout, "%s: %d\n", name, *val_s16);
+ break;
+ case ETHTOOL_TUNABLE_S32:
+ val_s32 = (int32_t *)tuna->data;
+ fprintf(stdout, "%s: %d\n", name, *val_s32);
+ break;
+ case ETHTOOL_TUNABLE_S64:
+ val_s64 = (long long int *)tuna->data;
+ fprintf(stdout, "%s: %lld\n", name, *val_s64);
+ break;
+ case ETHTOOL_TUNABLE_STRING:
+ val_str = (char *)tuna->data;
+ fprintf(stdout, "%s: %s\n", name, val_str);
+ break;
+ default:
+ fprintf(stdout, "%s: Unknown format\n", name);
+ }
+}
+
+static int do_gtunable(struct cmd_context *ctx)
+{
+ char **argp = ctx->argp;
+ int argc = ctx->argc;
+ int i;
+ int j;
+
+ if (argc < 1)
+ exit_bad_args();
+
+ for (i = 0; i < argc; i++) {
+ int valid = 0;
+
+ for (j = 0; j < TINFO_SIZE; j++) {
+ char *ts = tunable_strings[tinfo[j].t_id];
+ struct ethtool_tunable *tuna;
+ int ret;
+
+ if (strcmp(argp[i], ts))
+ continue;
+ valid = 1;
+
+ tuna = calloc(1, sizeof(*tuna) + tinfo[j].size);
+ if (!tuna) {
+ perror(ts);
+ return 1;
+ }
+ tuna->cmd = ETHTOOL_GTUNABLE;
+ tuna->id = tinfo[j].t_id;
+ tuna->type_id = tinfo[j].t_type_id;
+ tuna->len = tinfo[j].size;
+ ret = send_ioctl(ctx, tuna);
+ if (ret) {
+ fprintf(stderr, "%s: Cannot get tunable\n", ts);
+ return ret;
+ }
+ print_tunable(tuna);
+ free(tuna);
+ tuna = NULL;
+ }
+ if (!valid)
+ exit_bad_args();
+ }
+ return 0;
+}
+
static int do_get_phy_tunable(struct cmd_context *ctx)
{
int argc = ctx->argc;
@@ -5468,6 +5679,22 @@ static const struct option args[] = {
" [ fast-link-down ]\n"
" [ energy-detect-power-down ]\n"
},
+ {
+ .opts = "-b|--get-tunable",
+ .func = do_gtunable,
+ .help = "Get tunable",
+ .xhelp = " [ rx-copybreak ]\n"
+ " [ tx-copybreak ]\n"
+ " [ pfc-precention-tout ]\n"
+ },
+ {
+ .opts = "-B|--set-tunable",
+ .func = do_stunable,
+ .help = "Set tunable",
+ .xhelp = " [ rx-copybreak N]\n"
+ " [ tx-copybreak N]\n"
+ " [ pfc-precention-tout N]\n"
+ },
{
.opts = "--reset",
.func = do_reset,
--
2.27.0
Powered by blists - more mailing lists