static void explain(void)
{
- fprintf(stderr, "Usage: ... taprio clockid CLOCKID\n");
- fprintf(stderr, " [num_tc NUMBER] [map P0 P1 ...] ");
- fprintf(stderr, " [queues COUNT@OFFSET COUNT@OFFSET COUNT@OFFSET ...] ");
- fprintf(stderr, " [ [sched-entry index cmd gate-mask interval] ... ] ");
- fprintf(stderr, " [base-time time] ");
- fprintf(stderr, "\nCLOCKID must be a valid SYS-V id (i.e. CLOCK_TAI)");
- fprintf(stderr, "\n");
+ fprintf(stderr,
+ "Usage: ... taprio clockid CLOCKID\n"
+ " [num_tc NUMBER] [map P0 P1 ...] "
+ " [queues COUNT@OFFSET COUNT@OFFSET COUNT@OFFSET ...] "
+ " [ [sched-entry index cmd gate-mask interval] ... ] "
+ " [base-time time] [txtime-delay delay]"
+ "\n"
+ "CLOCKID must be a valid SYS-V id (i.e. CLOCK_TAI)\n");
}
static void explain_clockid(const char *val)
{
__s32 clockid = CLOCKID_INVALID;
struct tc_mqprio_qopt opt = { };
+ __s64 cycle_time_extension = 0;
struct list_head sched_entries;
- struct rtattr *tail;
+ struct rtattr *tail, *l;
+ __u32 taprio_flags = 0;
+ __u32 txtime_delay = 0;
+ __s64 cycle_time = 0;
__s64 base_time = 0;
int err, idx;
PREV_ARG();
break;
}
+ } else if (strcmp(*argv, "cycle-time") == 0) {
+ NEXT_ARG();
+ if (cycle_time) {
+ fprintf(stderr, "taprio: duplicate \"cycle-time\" specification\n");
+ return -1;
+ }
+
+ if (get_s64(&cycle_time, *argv, 10)) {
+ PREV_ARG();
+ break;
+ }
+
+ } else if (strcmp(*argv, "cycle-time-extension") == 0) {
+ NEXT_ARG();
+ if (cycle_time_extension) {
+ fprintf(stderr, "taprio: duplicate \"cycle-time-extension\" specification\n");
+ return -1;
+ }
+
+ if (get_s64(&cycle_time_extension, *argv, 10)) {
+ PREV_ARG();
+ break;
+ }
} else if (strcmp(*argv, "clockid") == 0) {
NEXT_ARG();
if (clockid != CLOCKID_INVALID) {
explain_clockid(*argv);
return -1;
}
+ } else if (strcmp(*argv, "flags") == 0) {
+ NEXT_ARG();
+ if (taprio_flags) {
+ fprintf(stderr, "taprio: duplicate \"flags\" specification\n");
+ return -1;
+ }
+ if (get_u32(&taprio_flags, *argv, 0)) {
+ PREV_ARG();
+ return -1;
+ }
+
+ } else if (strcmp(*argv, "txtime-delay") == 0) {
+ NEXT_ARG();
+ if (txtime_delay != 0) {
+ fprintf(stderr, "taprio: duplicate \"txtime-delay\" specification\n");
+ return -1;
+ }
+ if (get_u32(&txtime_delay, *argv, 0)) {
+ PREV_ARG();
+ return -1;
+ }
+
} else if (strcmp(*argv, "help") == 0) {
explain();
return -1;
tail = NLMSG_TAIL(n);
addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
+ if (clockid != CLOCKID_INVALID)
+ addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CLOCKID, &clockid, sizeof(clockid));
+
+ if (taprio_flags)
+ addattr_l(n, 1024, TCA_TAPRIO_ATTR_FLAGS, &taprio_flags, sizeof(taprio_flags));
+
if (opt.num_tc > 0)
addattr_l(n, 1024, TCA_TAPRIO_ATTR_PRIOMAP, &opt, sizeof(opt));
+ if (txtime_delay)
+ addattr_l(n, 1024, TCA_TAPRIO_ATTR_TXTIME_DELAY, &txtime_delay, sizeof(txtime_delay));
+
if (base_time)
addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_BASE_TIME, &base_time, sizeof(base_time));
- addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CLOCKID, &clockid, sizeof(clockid));
+ if (cycle_time)
+ addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME,
+ &cycle_time, sizeof(cycle_time));
- if (!list_empty(&sched_entries)) {
- struct rtattr *entry_list;
- entry_list = addattr_nest(n, 1024, TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST | NLA_F_NESTED);
+ if (cycle_time_extension)
+ addattr_l(n, 1024, TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION,
+ &cycle_time_extension, sizeof(cycle_time_extension));
- err = add_sched_list(&sched_entries, n);
- if (err < 0) {
- fprintf(stderr, "Could not add schedule to netlink message\n");
- return -1;
- }
+ l = addattr_nest(n, 1024, TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST | NLA_F_NESTED);
- addattr_nest_end(n, entry_list);
+ err = add_sched_list(&sched_entries, n);
+ if (err < 0) {
+ fprintf(stderr, "Could not add schedule to netlink message\n");
+ return -1;
}
+ addattr_nest_end(n, l);
+
tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
return 0;
open_json_array(PRINT_JSON, "schedule");
+ print_nl();
+
for (item = RTA_DATA(list); RTA_OK(item, rem); item = RTA_NEXT(item, rem)) {
struct rtattr *tb[TCA_TAPRIO_SCHED_ENTRY_MAX + 1];
__u32 index = 0, gatemask = 0, interval = 0;
open_json_object(NULL);
print_uint(PRINT_ANY, "index", "\tindex %u", index);
print_string(PRINT_ANY, "cmd", " cmd %s", entry_cmd_to_str(command));
- print_0xhex(PRINT_ANY, "gatemask", " gatemask %#x", gatemask);
+ print_0xhex(PRINT_ANY, "gatemask", " gatemask %#llx", gatemask);
print_uint(PRINT_ANY, "interval", " interval %u", interval);
close_json_object();
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
}
close_json_array(PRINT_ANY, "");
return 0;
}
+static int print_schedule(FILE *f, struct rtattr **tb)
+{
+ int64_t base_time = 0, cycle_time = 0, cycle_time_extension = 0;
+
+ if (tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME])
+ base_time = rta_getattr_s64(tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME]);
+
+ if (tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME])
+ cycle_time = rta_getattr_s64(tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME]);
+
+ if (tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION])
+ cycle_time_extension = rta_getattr_s64(
+ tb[TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION]);
+
+ print_lluint(PRINT_ANY, "base_time", "\tbase-time %lld", base_time);
+
+ print_lluint(PRINT_ANY, "cycle_time", " cycle-time %lld", cycle_time);
+
+ print_lluint(PRINT_ANY, "cycle_time_extension",
+ " cycle-time-extension %lld", cycle_time_extension);
+
+ print_sched_list(f, tb[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST]);
+
+ return 0;
+}
+
static int taprio_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
{
struct rtattr *tb[TCA_TAPRIO_ATTR_MAX + 1];
struct tc_mqprio_qopt *qopt = 0;
__s32 clockid = CLOCKID_INVALID;
- __s64 base_time = 0;
int i;
if (opt == NULL)
print_uint(PRINT_ANY, NULL, " %u", qopt->prio_tc_map[i]);
close_json_array(PRINT_ANY, "");
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ print_nl();
open_json_array(PRINT_ANY, "queues");
for (i = 0; i < qopt->num_tc; i++) {
}
close_json_array(PRINT_ANY, "");
- print_string(PRINT_FP, NULL, "%s", _SL_);
-
- if (tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME])
- base_time = rta_getattr_s64(tb[TCA_TAPRIO_ATTR_SCHED_BASE_TIME]);
+ print_nl();
if (tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID])
clockid = rta_getattr_s32(tb[TCA_TAPRIO_ATTR_SCHED_CLOCKID]);
print_string(PRINT_ANY, "clockid", "clockid %s", get_clock_name(clockid));
- print_lluint(PRINT_ANY, "base_time", " base-time %lld", base_time);
+ if (tb[TCA_TAPRIO_ATTR_FLAGS]) {
+ __u32 flags;
+
+ flags = rta_getattr_u32(tb[TCA_TAPRIO_ATTR_FLAGS]);
+ print_0xhex(PRINT_ANY, "flags", " flags %#x", flags);
+ }
+
+ if (tb[TCA_TAPRIO_ATTR_TXTIME_DELAY]) {
+ __u32 txtime_delay;
+
+ txtime_delay = rta_getattr_s32(tb[TCA_TAPRIO_ATTR_TXTIME_DELAY]);
+ print_uint(PRINT_ANY, "txtime_delay", " txtime delay %d", txtime_delay);
+ }
+
+ print_schedule(f, tb);
- print_string(PRINT_FP, NULL, "%s", _SL_);
+ if (tb[TCA_TAPRIO_ATTR_ADMIN_SCHED]) {
+ struct rtattr *t[TCA_TAPRIO_ATTR_MAX + 1];
- return print_sched_list(f, tb[TCA_TAPRIO_ATTR_SCHED_ENTRY_LIST]);
+ parse_rtattr_nested(t, TCA_TAPRIO_ATTR_MAX,
+ tb[TCA_TAPRIO_ATTR_ADMIN_SCHED]);
+
+ open_json_object(NULL);
+
+ print_schedule(f, t);
+
+ close_json_object();
+ }
+
+ return 0;
}
struct qdisc_util taprio_qdisc_util = {