/* * Copyright 2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ #include LOG_MODULE_DECLARE(net_shell); #include #include #include #include #include #include #include #include "net_shell_private.h" #if defined(CONFIG_NET_QBV) && defined(CONFIG_NET_L2_ETHERNET_MGMT) static struct net_if *get_iface_from_shell(const struct shell *sh, size_t argc, char **argv) { int idx; struct net_if *iface; idx = get_iface_idx(sh, argv[1]); if (idx < 0) { return NULL; } iface = net_if_get_by_index(idx); if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) { PR_WARNING("No such interface in index %d\n", idx); return NULL; } return iface; } #endif /* qbv enable */ static int cmd_net_qbv(const struct shell *sh, size_t argc, char **argv) { ARG_UNUSED(argc); ARG_UNUSED(argv); #if defined(CONFIG_NET_QBV) && defined(CONFIG_NET_L2_ETHERNET_MGMT) shell_print(sh, "To set Qbv config:"); shell_print(sh, " 1. Run enable to on"); shell_print(sh, " 2. Run set_config to set base_time/cycle_time/cycle_time_ext/list_len"); shell_print(sh, " 3. Run set_gc to set gate control"); shell_print(sh, "For example:"); shell_print(sh, " 1. net qbv enable 1 on"); shell_print(sh, " 2. net qbv set_config 1 200 0 0 10000000 0 2"); shell_print(sh, " 3. qbv set_gc 1 0 0x1 5000000"); shell_print(sh, " 4. qbv set_gc 1 0 0x2 5000000"); #else shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_QBV", "qbv"); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_L2_ETHERNET_MGMT", "Ethernet network management interface"); #endif return 0; } /* qbv enable */ static int cmd_qbv_enable(const struct shell *sh, size_t argc, char **argv) { #if defined(CONFIG_NET_QBV) && defined(CONFIG_NET_L2_ETHERNET_MGMT) struct net_if *iface; struct ethernet_req_params params; int ret; bool enable; iface = get_iface_from_shell(sh, argc, argv); if (!iface) { return -ENOEXEC; } enable = shell_strtobool(argv[2], 0, &ret); if (ret < 0) { return ret; } params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_STATUS; params.qbv_param.state = ETHERNET_QBV_STATE_TYPE_ADMIN; params.qbv_param.enabled = enable; ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); if (ret < 0) { shell_error(sh, "failed to set %s", argv[1]); return ret; } #else ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_QBV", "qbv"); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_L2_ETHERNET_MGMT", "Ethernet network management interface"); #endif return 0; } /* * qbv set_config * */ static int cmd_qbv_set_config(const struct shell *sh, size_t argc, char **argv) { #if defined(CONFIG_NET_QBV) && defined(CONFIG_NET_L2_ETHERNET_MGMT) struct net_if *iface; struct ethernet_req_params params; uint32_t list_len; int ret; iface = get_iface_from_shell(sh, argc, argv); if (!iface) { return -ENOEXEC; } params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_TIME; params.qbv_param.state = ETHERNET_QBV_STATE_TYPE_ADMIN; params.qbv_param.base_time.second = shell_strtoull(argv[2], 10, &ret); if (ret < 0) { return ret; } params.qbv_param.base_time.fract_nsecond = shell_strtoull(argv[3], 10, &ret); if (ret < 0) { return ret; } params.qbv_param.cycle_time.second = shell_strtoull(argv[4], 10, &ret); if (ret < 0) { return ret; } params.qbv_param.cycle_time.nanosecond = shell_strtoul(argv[5], 10, &ret); if (ret < 0) { return ret; } params.qbv_param.extension_time = shell_strtoul(argv[6], 10, &ret); if (ret < 0) { return ret; } ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); list_len = shell_strtol(argv[7], 10, &ret); if (ret < 0) { shell_print(sh, "failed to set times"); return ret; } params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST_LEN; params.qbv_param.gate_control_list_len = list_len; ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); if (ret < 0) { shell_print(sh, "failed to set list length"); return ret; } #else ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_QBV", "qbv"); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_L2_ETHERNET_MGMT", "Ethernet network management interface"); #endif return 0; } /* qbv set_config */ static int cmd_qbv_set_gc(const struct shell *sh, size_t argc, char **argv) { #if defined(CONFIG_NET_QBV) && defined(CONFIG_NET_L2_ETHERNET_MGMT) struct net_if *iface; struct ethernet_req_params params; uint32_t row; uint32_t interval; uint32_t gc; int ret; iface = get_iface_from_shell(sh, argc, argv); if (!iface) { return -ENOEXEC; } row = shell_strtoul(argv[2], 10, &ret); if (ret < 0) { return ret; } gc = shell_strtoul(argv[3], 16, &ret); if (ret < 0) { return ret; } interval = shell_strtoul(argv[4], 10, &ret); if (ret < 0) { return ret; } params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST; params.qbv_param.state = ETHERNET_QBV_STATE_TYPE_ADMIN; params.qbv_param.gate_control.time_interval = interval; params.qbv_param.gate_control.row = row; for (int i = 0; i < CONFIG_NET_TC_TX_COUNT; i++) { params.qbv_param.gate_control.gate_status[i] = ((gc & BIT(i)) != 0); } ret = net_mgmt(NET_REQUEST_ETHERNET_SET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); if (ret < 0) { return ret; } #else ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_QBV", "qbv"); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_L2_ETHERNET_MGMT", "Ethernet network management interface"); #endif return 0; } /* qbv get_info */ static int cmd_qbv_get_info(const struct shell *sh, size_t argc, char **argv) { #if defined(CONFIG_NET_QBV) && defined(CONFIG_NET_L2_ETHERNET_MGMT) struct net_if *iface; struct ethernet_req_params params; int ret; uint32_t list_len; uint32_t gate_status; iface = get_iface_from_shell(sh, argc, argv); if (!iface) { return -ENOEXEC; } params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_STATUS; params.qbv_param.state = ETHERNET_QBV_STATE_TYPE_ADMIN; ret = net_mgmt(NET_REQUEST_ETHERNET_GET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); if (ret < 0) { shell_error(sh, "failed to get %s status", argv[1]); return ret; } shell_print(sh, "status: %s", (params.qbv_param.enabled ? "on" : "off")); params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_TIME; ret = net_mgmt(NET_REQUEST_ETHERNET_GET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); if (ret < 0) { shell_error(sh, "failed to get %s time", argv[1]); return ret; } shell_print(sh, "base_time(s): %"PRIu64, params.qbv_param.base_time.second); shell_print(sh, "base_time(fract_ns): %"PRIu64, params.qbv_param.base_time.fract_nsecond); shell_print(sh, "cycle_time(s): %"PRIu64, params.qbv_param.cycle_time.second); shell_print(sh, "cycle_time(ns): %"PRIu32, params.qbv_param.cycle_time.nanosecond); shell_print(sh, "extension_time(ns): %"PRIu32, params.qbv_param.extension_time); params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST_LEN; ret = net_mgmt(NET_REQUEST_ETHERNET_GET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); if (ret < 0) { shell_error(sh, "failed to get %s list length", argv[1]); return ret; } shell_print(sh, "list len: %"PRIu32, params.qbv_param.gate_control_list_len); list_len = params.qbv_param.gate_control_list_len; params.qbv_param.type = ETHERNET_QBV_PARAM_TYPE_GATE_CONTROL_LIST; for (uint16_t i = 0; i < list_len; i++) { params.qbv_param.gate_control.row = i; ret = net_mgmt(NET_REQUEST_ETHERNET_GET_QBV_PARAM, iface, ¶ms, sizeof(struct ethernet_req_params)); if (ret < 0) { shell_error(sh, "failed to get %s gate control", argv[1]); return ret; } gate_status = 0; for (int j = 0; j < CONFIG_NET_TC_TX_COUNT; j++) { gate_status |= params.qbv_param.gate_control.gate_status[j] << j; } shell_print(sh, "row: %"PRIu16" interval: %"PRIu32" gate_status: 0x%x", i, params.qbv_param.gate_control.time_interval, gate_status); } #else ARG_UNUSED(argc); ARG_UNUSED(argv); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_QBV", "qbv"); shell_print(sh, "Set %s to enable %s support.\n", "CONFIG_NET_L2_ETHERNET_MGMT", "Ethernet network management interface"); #endif return 0; } SHELL_STATIC_SUBCMD_SET_CREATE(net_cmd_qbv, SHELL_CMD_ARG(enable, NULL, "Enable: enable ", cmd_qbv_enable, 3, 0), SHELL_CMD_ARG(set_config, NULL, "Set config: set ", cmd_qbv_set_config, 8, 0), SHELL_CMD_ARG(set_gc, NULL, "Set gate control: set ", cmd_qbv_set_gc, 5, 0), SHELL_CMD_ARG(get_info, NULL, "Get info: get_info ", cmd_qbv_get_info, 2, 0), SHELL_SUBCMD_SET_END /* Array terminated. */ ); SHELL_SUBCMD_ADD((net), qbv, &net_cmd_qbv, "Qbv commands", cmd_net_qbv, 1, 0);