@@ -482,6 +482,9 @@ ethtool \- query or control network driver and hardware settings
.B ethtool \-\-set\-module
.I devname
.B2 low-power on off
+.HP
+.B ethtool \-\-reset\-module
+.I devname
.
.\" Adjust lines (i.e. full justification) and hyphenate.
.ad
@@ -1473,6 +1476,12 @@ Set the transceiver module's parameters.
.A2 low-power on off
Enable / disable forcing of low power mode by the host.
.RE
+.TP
+.B \-\-reset\-module
+Reset the transceiver module to its initial state. Reset is performed by either
+asserting the relevant hardware signal or by writing to the module's reset bit
+in its EEPROM.
+.RE
.SH BUGS
Not supported (in part or whole) on all network drivers.
.SH AUTHOR
@@ -6031,6 +6031,11 @@ static const struct option args[] = {
.help = "Set transceiver module settings",
.xhelp = " [ low-power on|off ]\n"
},
+ {
+ .opts = "--reset-module",
+ .nlfunc = nl_reset_module,
+ .help = "Reset transceiver module",
+ },
{
.opts = "-h|--help",
.no_dev = true,
@@ -416,6 +416,7 @@ const struct pretty_nlmsg_desc ethnl_umsg_desc[] = {
NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET, module_eeprom),
NLMSG_DESC(ETHTOOL_MSG_MODULE_GET, module),
NLMSG_DESC(ETHTOOL_MSG_MODULE_SET, module),
+ NLMSG_DESC(ETHTOOL_MSG_MODULE_RESET_ACT, module),
};
const unsigned int ethnl_umsg_n_desc = ARRAY_SIZE(ethnl_umsg_desc);
@@ -457,6 +458,7 @@ const struct pretty_nlmsg_desc ethnl_kmsg_desc[] = {
NLMSG_DESC(ETHTOOL_MSG_MODULE_EEPROM_GET_REPLY, module_eeprom),
NLMSG_DESC(ETHTOOL_MSG_MODULE_GET_REPLY, module),
NLMSG_DESC(ETHTOOL_MSG_MODULE_NTF, module),
+ NLMSG_DESC(ETHTOOL_MSG_MODULE_RESET_NTF, module),
};
const unsigned int ethnl_kmsg_n_desc = ARRAY_SIZE(ethnl_kmsg_desc);
@@ -45,6 +45,7 @@ bool nl_gstats_chk(struct cmd_context *ctx);
int nl_gstats(struct cmd_context *ctx);
int nl_gmodule(struct cmd_context *ctx);
int nl_smodule(struct cmd_context *ctx);
+int nl_reset_module(struct cmd_context *ctx);
int nl_monitor(struct cmd_context *ctx);
int nl_getmodule(struct cmd_context *ctx);
@@ -103,6 +104,7 @@ static inline void nl_monitor_usage(void)
#define nl_getmodule NULL
#define nl_gmodule NULL
#define nl_smodule NULL
+#define nl_reset_module NULL
#endif /* ETHTOOL_ENABLE_NETLINK */
@@ -137,3 +137,55 @@ int nl_smodule(struct cmd_context *ctx)
else
return nlctx->exit_code ?: 83;
}
+
+/* MODULE_RESET_ACT */
+
+int module_reset_ntf_cb(const struct nlmsghdr *nlhdr, void *data)
+{
+ const struct nlattr *tb[ETHTOOL_A_MODULE_MAX + 1] = {};
+ struct nl_context *nlctx = data;
+ DECLARE_ATTR_TB_INFO(tb);
+ int ret;
+
+ ret = mnl_attr_parse(nlhdr, GENL_HDRLEN, attr_cb, &tb_info);
+ if (ret < 0)
+ return MNL_CB_OK;
+ nlctx->devname = get_dev_name(tb[ETHTOOL_A_MODULE_HEADER]);
+ if (!dev_ok(nlctx))
+ return MNL_CB_OK;
+
+ printf("\nModule reset done for %s\n", nlctx->devname);
+
+ return MNL_CB_OK;
+}
+
+int nl_reset_module(struct cmd_context *ctx)
+{
+ struct nl_context *nlctx = ctx->nlctx;
+ struct nl_msg_buff *msgbuff;
+ struct nl_socket *nlsk;
+ int ret;
+
+ if (netlink_cmd_check(ctx, ETHTOOL_MSG_MODULE_RESET_ACT, false))
+ return -EOPNOTSUPP;
+
+ nlsk = nlctx->ethnl_socket;
+ msgbuff = &nlsk->msgbuff;
+
+ ret = msg_init(nlctx, msgbuff, ETHTOOL_MSG_MODULE_RESET_ACT,
+ NLM_F_REQUEST | NLM_F_ACK);
+ if (ret < 0)
+ return 2;
+ if (ethnla_fill_header(msgbuff, ETHTOOL_A_MODULE_HEADER,
+ ctx->devname, 0))
+ return -EMSGSIZE;
+
+ ret = nlsock_sendmsg(nlsk, NULL);
+ if (ret < 0)
+ return 83;
+ ret = nlsock_process_reply(nlsk, nomsg_reply_cb, nlctx);
+ if (ret == 0)
+ return 0;
+ else
+ return nlctx->exit_code ?: 83;
+}
@@ -75,6 +75,10 @@ static struct {
.cmd = ETHTOOL_MSG_MODULE_NTF,
.cb = module_reply_cb,
},
+ {
+ .cmd = ETHTOOL_MSG_MODULE_RESET_NTF,
+ .cb = module_reset_ntf_cb,
+ },
};
static void clear_filter(struct nl_context *nlctx)
@@ -92,6 +92,7 @@ int cable_test_tdr_reply_cb(const struct nlmsghdr *nlhdr, void *data);
int cable_test_tdr_ntf_cb(const struct nlmsghdr *nlhdr, void *data);
int fec_reply_cb(const struct nlmsghdr *nlhdr, void *data);
int module_reply_cb(const struct nlmsghdr *nlhdr, void *data);
+int module_reset_ntf_cb(const struct nlmsghdr *nlhdr, void *data);
/* dump helpers */
@@ -1211,6 +1211,7 @@ _ethtool()
[--test]=test
[--set-module]=set_module
[--show-module]=devname
+ [--reset-module]=devname
)
local -A other_funcs=(
[--config-ntuple]=config_nfc