xref: /aosp_15_r20/external/libnl/lib/route/qdisc/mqprio.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2018 Volodymyr Bendiuga <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
7*4dc78e53SAndroid Build Coastguard Worker 
8*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
9*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
10*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc.h>
11*4dc78e53SAndroid Build Coastguard Worker #include <netlink/route/qdisc/mqprio.h>
12*4dc78e53SAndroid Build Coastguard Worker 
13*4dc78e53SAndroid Build Coastguard Worker #include "tc-api.h"
14*4dc78e53SAndroid Build Coastguard Worker 
15*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
16*4dc78e53SAndroid Build Coastguard Worker struct rtnl_mqprio {
17*4dc78e53SAndroid Build Coastguard Worker 	uint8_t qm_num_tc;
18*4dc78e53SAndroid Build Coastguard Worker 	uint8_t qm_prio_map[TC_QOPT_BITMASK + 1];
19*4dc78e53SAndroid Build Coastguard Worker 	uint8_t qm_hw;
20*4dc78e53SAndroid Build Coastguard Worker 	uint16_t qm_count[TC_QOPT_MAX_QUEUE];
21*4dc78e53SAndroid Build Coastguard Worker 	uint16_t qm_offset[TC_QOPT_MAX_QUEUE];
22*4dc78e53SAndroid Build Coastguard Worker 	uint16_t qm_mode;
23*4dc78e53SAndroid Build Coastguard Worker 	uint16_t qm_shaper;
24*4dc78e53SAndroid Build Coastguard Worker 	uint64_t qm_min_rate[TC_QOPT_MAX_QUEUE];
25*4dc78e53SAndroid Build Coastguard Worker 	uint64_t qm_max_rate[TC_QOPT_MAX_QUEUE];
26*4dc78e53SAndroid Build Coastguard Worker 	uint32_t qm_mask;
27*4dc78e53SAndroid Build Coastguard Worker };
28*4dc78e53SAndroid Build Coastguard Worker 
29*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_NUMTC           (1 << 0)
30*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_PRIOMAP         (1 << 1)
31*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_HW              (1 << 2)
32*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_QUEUE           (1 << 3)
33*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_MODE            (1 << 4)
34*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_SHAPER          (1 << 5)
35*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_MIN_RATE        (1 << 6)
36*4dc78e53SAndroid Build Coastguard Worker #define SCH_MQPRIO_ATTR_MAX_RATE        (1 << 7)
37*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
38*4dc78e53SAndroid Build Coastguard Worker 
39*4dc78e53SAndroid Build Coastguard Worker static struct nla_policy mqprio_policy[TCA_MQPRIO_MAX + 1] = {
40*4dc78e53SAndroid Build Coastguard Worker 	[TCA_MQPRIO_MODE]       = { .minlen = sizeof(uint16_t) },
41*4dc78e53SAndroid Build Coastguard Worker 	[TCA_MQPRIO_SHAPER]     = { .minlen = sizeof(uint16_t) },
42*4dc78e53SAndroid Build Coastguard Worker 	[TCA_MQPRIO_MIN_RATE64] = { .type = NLA_NESTED },
43*4dc78e53SAndroid Build Coastguard Worker 	[TCA_MQPRIO_MAX_RATE64] = { .type = NLA_NESTED },
44*4dc78e53SAndroid Build Coastguard Worker };
45*4dc78e53SAndroid Build Coastguard Worker 
mqprio_msg_parser(struct rtnl_tc * tc,void * data)46*4dc78e53SAndroid Build Coastguard Worker static int mqprio_msg_parser(struct rtnl_tc *tc, void *data)
47*4dc78e53SAndroid Build Coastguard Worker {
48*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio = data;
49*4dc78e53SAndroid Build Coastguard Worker 	struct tc_mqprio_qopt *qopt;
50*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *attr;
51*4dc78e53SAndroid Build Coastguard Worker 	int len, rem, i, err;
52*4dc78e53SAndroid Build Coastguard Worker 
53*4dc78e53SAndroid Build Coastguard Worker 	if (tc->tc_opts->d_size < sizeof(*qopt))
54*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
55*4dc78e53SAndroid Build Coastguard Worker 
56*4dc78e53SAndroid Build Coastguard Worker 	qopt = (struct tc_mqprio_qopt *) tc->tc_opts->d_data;
57*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_num_tc = qopt->num_tc;
58*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_hw = qopt->hw;
59*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_prio_map, qopt->prio_tc_map,
60*4dc78e53SAndroid Build Coastguard Worker 	       TC_QOPT_MAX_QUEUE * sizeof(uint8_t));
61*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_count, qopt->count,
62*4dc78e53SAndroid Build Coastguard Worker 	       TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
63*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_offset, qopt->offset,
64*4dc78e53SAndroid Build Coastguard Worker 	       TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
65*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask = (SCH_MQPRIO_ATTR_NUMTC | SCH_MQPRIO_ATTR_PRIOMAP |
66*4dc78e53SAndroid Build Coastguard Worker 	                   SCH_MQPRIO_ATTR_QUEUE | SCH_MQPRIO_ATTR_HW);
67*4dc78e53SAndroid Build Coastguard Worker 
68*4dc78e53SAndroid Build Coastguard Worker 	len = tc->tc_opts->d_size - NLA_ALIGN(sizeof(*qopt));
69*4dc78e53SAndroid Build Coastguard Worker 
70*4dc78e53SAndroid Build Coastguard Worker 	if (len > 0) {
71*4dc78e53SAndroid Build Coastguard Worker 		struct nlattr *tb[TCA_MQPRIO_MAX + 1];
72*4dc78e53SAndroid Build Coastguard Worker 
73*4dc78e53SAndroid Build Coastguard Worker 		err = nla_parse(tb, TCA_MQPRIO_MAX, (struct nlattr *)
74*4dc78e53SAndroid Build Coastguard Worker 		                ((char *) tc->tc_opts->d_data + NLA_ALIGN(sizeof(*qopt))),
75*4dc78e53SAndroid Build Coastguard Worker 		                len, mqprio_policy);
76*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
77*4dc78e53SAndroid Build Coastguard Worker 			return err;
78*4dc78e53SAndroid Build Coastguard Worker 
79*4dc78e53SAndroid Build Coastguard Worker 		if (tb[TCA_MQPRIO_MODE]) {
80*4dc78e53SAndroid Build Coastguard Worker 			mqprio->qm_mode = nla_get_u16(tb[TCA_MQPRIO_MODE]);
81*4dc78e53SAndroid Build Coastguard Worker 			mqprio->qm_mask |= SCH_MQPRIO_ATTR_MODE;
82*4dc78e53SAndroid Build Coastguard Worker 		}
83*4dc78e53SAndroid Build Coastguard Worker 
84*4dc78e53SAndroid Build Coastguard Worker 		if (tb[TCA_MQPRIO_SHAPER]) {
85*4dc78e53SAndroid Build Coastguard Worker 			mqprio->qm_shaper = nla_get_u16(tb[TCA_MQPRIO_SHAPER]);
86*4dc78e53SAndroid Build Coastguard Worker 			mqprio->qm_mask |= SCH_MQPRIO_ATTR_SHAPER;
87*4dc78e53SAndroid Build Coastguard Worker 		}
88*4dc78e53SAndroid Build Coastguard Worker 
89*4dc78e53SAndroid Build Coastguard Worker 		if (tb[TCA_MQPRIO_MIN_RATE64]) {
90*4dc78e53SAndroid Build Coastguard Worker 			i = 0;
91*4dc78e53SAndroid Build Coastguard Worker 			nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64], rem) {
92*4dc78e53SAndroid Build Coastguard Worker 				if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
93*4dc78e53SAndroid Build Coastguard Worker 					return -EINVAL;
94*4dc78e53SAndroid Build Coastguard Worker 
95*4dc78e53SAndroid Build Coastguard Worker 				if (i >= mqprio->qm_num_tc)
96*4dc78e53SAndroid Build Coastguard Worker 					break;
97*4dc78e53SAndroid Build Coastguard Worker 
98*4dc78e53SAndroid Build Coastguard Worker 				mqprio->qm_min_rate[i] = nla_get_u64(attr);
99*4dc78e53SAndroid Build Coastguard Worker 			}
100*4dc78e53SAndroid Build Coastguard Worker 
101*4dc78e53SAndroid Build Coastguard Worker 			mqprio->qm_mask |= SCH_MQPRIO_ATTR_MIN_RATE;
102*4dc78e53SAndroid Build Coastguard Worker 		}
103*4dc78e53SAndroid Build Coastguard Worker 
104*4dc78e53SAndroid Build Coastguard Worker 		if (tb[TCA_MQPRIO_MAX_RATE64]) {
105*4dc78e53SAndroid Build Coastguard Worker 			i = 0;
106*4dc78e53SAndroid Build Coastguard Worker 			nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64], rem) {
107*4dc78e53SAndroid Build Coastguard Worker 				if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
108*4dc78e53SAndroid Build Coastguard Worker 					return -EINVAL;
109*4dc78e53SAndroid Build Coastguard Worker 
110*4dc78e53SAndroid Build Coastguard Worker 				if (i >= mqprio->qm_num_tc)
111*4dc78e53SAndroid Build Coastguard Worker 					break;
112*4dc78e53SAndroid Build Coastguard Worker 
113*4dc78e53SAndroid Build Coastguard Worker 				mqprio->qm_max_rate[i] = nla_get_u64(attr);
114*4dc78e53SAndroid Build Coastguard Worker 			}
115*4dc78e53SAndroid Build Coastguard Worker 
116*4dc78e53SAndroid Build Coastguard Worker 			mqprio->qm_mask |= SCH_MQPRIO_ATTR_MAX_RATE;
117*4dc78e53SAndroid Build Coastguard Worker 		}
118*4dc78e53SAndroid Build Coastguard Worker 	}
119*4dc78e53SAndroid Build Coastguard Worker 
120*4dc78e53SAndroid Build Coastguard Worker 	return 0;
121*4dc78e53SAndroid Build Coastguard Worker }
122*4dc78e53SAndroid Build Coastguard Worker 
mqprio_msg_fill(struct rtnl_tc * tc,void * data,struct nl_msg * msg)123*4dc78e53SAndroid Build Coastguard Worker static int mqprio_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
124*4dc78e53SAndroid Build Coastguard Worker {
125*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio = data;
126*4dc78e53SAndroid Build Coastguard Worker 	struct tc_mqprio_qopt qopt = { 0 };
127*4dc78e53SAndroid Build Coastguard Worker 	struct nlattr *nest = NULL;
128*4dc78e53SAndroid Build Coastguard Worker 	int i;
129*4dc78e53SAndroid Build Coastguard Worker 
130*4dc78e53SAndroid Build Coastguard Worker 	if (!mqprio ||
131*4dc78e53SAndroid Build Coastguard Worker 	    !(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC) ||
132*4dc78e53SAndroid Build Coastguard Worker 	    !(mqprio->qm_mask & SCH_MQPRIO_ATTR_PRIOMAP) ||
133*4dc78e53SAndroid Build Coastguard Worker 	    !(mqprio->qm_mask & SCH_MQPRIO_ATTR_QUEUE))
134*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
135*4dc78e53SAndroid Build Coastguard Worker 
136*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
137*4dc78e53SAndroid Build Coastguard Worker 		qopt.hw = 0;
138*4dc78e53SAndroid Build Coastguard Worker 	else
139*4dc78e53SAndroid Build Coastguard Worker 		qopt.hw = mqprio->qm_hw;
140*4dc78e53SAndroid Build Coastguard Worker 
141*4dc78e53SAndroid Build Coastguard Worker 	qopt.num_tc = mqprio->qm_num_tc;
142*4dc78e53SAndroid Build Coastguard Worker 	memcpy(qopt.count, mqprio->qm_count, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
143*4dc78e53SAndroid Build Coastguard Worker 	memcpy(qopt.offset, mqprio->qm_offset, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
144*4dc78e53SAndroid Build Coastguard Worker 	memcpy(qopt.prio_tc_map, mqprio->qm_prio_map, TC_QOPT_MAX_QUEUE * sizeof(uint8_t));
145*4dc78e53SAndroid Build Coastguard Worker 
146*4dc78e53SAndroid Build Coastguard Worker 	nlmsg_append(msg, &qopt, sizeof(qopt), NL_DONTPAD);
147*4dc78e53SAndroid Build Coastguard Worker 
148*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_hw) {
149*4dc78e53SAndroid Build Coastguard Worker 		if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MODE)
150*4dc78e53SAndroid Build Coastguard Worker 			NLA_PUT_U16(msg, TCA_MQPRIO_MODE, mqprio->qm_mode);
151*4dc78e53SAndroid Build Coastguard Worker 
152*4dc78e53SAndroid Build Coastguard Worker 		if (mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER)
153*4dc78e53SAndroid Build Coastguard Worker 			NLA_PUT_U16(msg, TCA_MQPRIO_SHAPER, mqprio->qm_shaper);
154*4dc78e53SAndroid Build Coastguard Worker 
155*4dc78e53SAndroid Build Coastguard Worker 		if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MIN_RATE) {
156*4dc78e53SAndroid Build Coastguard Worker 			nest = nla_nest_start(msg, TCA_MQPRIO_MIN_RATE64);
157*4dc78e53SAndroid Build Coastguard Worker 			if (!nest)
158*4dc78e53SAndroid Build Coastguard Worker 				goto nla_put_failure;
159*4dc78e53SAndroid Build Coastguard Worker 
160*4dc78e53SAndroid Build Coastguard Worker 			for (i = 0; i < mqprio->qm_num_tc; i++) {
161*4dc78e53SAndroid Build Coastguard Worker 				if (nla_put(msg, TCA_MQPRIO_MIN_RATE64,
162*4dc78e53SAndroid Build Coastguard Worker 				            sizeof(mqprio->qm_min_rate[i]),
163*4dc78e53SAndroid Build Coastguard Worker 				            &mqprio->qm_min_rate[i]) < 0)
164*4dc78e53SAndroid Build Coastguard Worker 					goto nla_nest_cancel;
165*4dc78e53SAndroid Build Coastguard Worker 			}
166*4dc78e53SAndroid Build Coastguard Worker 			nla_nest_end(msg, nest);
167*4dc78e53SAndroid Build Coastguard Worker 		}
168*4dc78e53SAndroid Build Coastguard Worker 
169*4dc78e53SAndroid Build Coastguard Worker 		if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MAX_RATE) {
170*4dc78e53SAndroid Build Coastguard Worker 			nest = nla_nest_start(msg, TCA_MQPRIO_MAX_RATE64);
171*4dc78e53SAndroid Build Coastguard Worker 			if (!nest)
172*4dc78e53SAndroid Build Coastguard Worker 				goto nla_put_failure;
173*4dc78e53SAndroid Build Coastguard Worker 
174*4dc78e53SAndroid Build Coastguard Worker 			for (i = 0; i < mqprio->qm_num_tc; i++) {
175*4dc78e53SAndroid Build Coastguard Worker 				if (nla_put(msg, TCA_MQPRIO_MAX_RATE64,
176*4dc78e53SAndroid Build Coastguard Worker 				            sizeof(mqprio->qm_max_rate[i]),
177*4dc78e53SAndroid Build Coastguard Worker 				            &mqprio->qm_max_rate[i]) < 0)
178*4dc78e53SAndroid Build Coastguard Worker 					goto nla_nest_cancel;
179*4dc78e53SAndroid Build Coastguard Worker 			}
180*4dc78e53SAndroid Build Coastguard Worker 			nla_nest_end(msg, nest);
181*4dc78e53SAndroid Build Coastguard Worker 		}
182*4dc78e53SAndroid Build Coastguard Worker 	}
183*4dc78e53SAndroid Build Coastguard Worker 
184*4dc78e53SAndroid Build Coastguard Worker 	return 0;
185*4dc78e53SAndroid Build Coastguard Worker 
186*4dc78e53SAndroid Build Coastguard Worker nla_nest_cancel:
187*4dc78e53SAndroid Build Coastguard Worker 	nla_nest_cancel(msg, nest);
188*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_MSGSIZE;
189*4dc78e53SAndroid Build Coastguard Worker 
190*4dc78e53SAndroid Build Coastguard Worker nla_put_failure:
191*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_MSGSIZE;
192*4dc78e53SAndroid Build Coastguard Worker }
193*4dc78e53SAndroid Build Coastguard Worker 
mqprio_dump_line(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)194*4dc78e53SAndroid Build Coastguard Worker static void mqprio_dump_line(struct rtnl_tc *tc, void *data,
195*4dc78e53SAndroid Build Coastguard Worker                              struct nl_dump_params *p)
196*4dc78e53SAndroid Build Coastguard Worker {
197*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio = data;
198*4dc78e53SAndroid Build Coastguard Worker 
199*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio)
200*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, " num_tc %u", mqprio->qm_num_tc);
201*4dc78e53SAndroid Build Coastguard Worker }
202*4dc78e53SAndroid Build Coastguard Worker 
mqprio_dump_details(struct rtnl_tc * tc,void * data,struct nl_dump_params * p)203*4dc78e53SAndroid Build Coastguard Worker static void mqprio_dump_details(struct rtnl_tc *tc, void *data,
204*4dc78e53SAndroid Build Coastguard Worker                                 struct nl_dump_params *p)
205*4dc78e53SAndroid Build Coastguard Worker {
206*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio = data;
207*4dc78e53SAndroid Build Coastguard Worker 	int i;
208*4dc78e53SAndroid Build Coastguard Worker 
209*4dc78e53SAndroid Build Coastguard Worker 	if (!mqprio)
210*4dc78e53SAndroid Build Coastguard Worker 		return;
211*4dc78e53SAndroid Build Coastguard Worker 
212*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "map [");
213*4dc78e53SAndroid Build Coastguard Worker 
214*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; i <= TC_QOPT_BITMASK; i++)
215*4dc78e53SAndroid Build Coastguard Worker 		nl_dump(p, "%u%s", mqprio->qm_prio_map[i],
216*4dc78e53SAndroid Build Coastguard Worker 			i < TC_QOPT_BITMASK ? " " : "");
217*4dc78e53SAndroid Build Coastguard Worker 
218*4dc78e53SAndroid Build Coastguard Worker 	nl_dump(p, "]\n");
219*4dc78e53SAndroid Build Coastguard Worker 	nl_new_line(p);
220*4dc78e53SAndroid Build Coastguard Worker }
221*4dc78e53SAndroid Build Coastguard Worker 
222*4dc78e53SAndroid Build Coastguard Worker /**
223*4dc78e53SAndroid Build Coastguard Worker  * @name Attribute Modification
224*4dc78e53SAndroid Build Coastguard Worker  * @{
225*4dc78e53SAndroid Build Coastguard Worker  */
226*4dc78e53SAndroid Build Coastguard Worker 
227*4dc78e53SAndroid Build Coastguard Worker /**
228*4dc78e53SAndroid Build Coastguard Worker  * Set number of traffic classes.
229*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
230*4dc78e53SAndroid Build Coastguard Worker  * @arg num_tc          Number of traffic classes to create.
231*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
232*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_set_num_tc(struct rtnl_qdisc * qdisc,int num_tc)233*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_set_num_tc(struct rtnl_qdisc *qdisc, int num_tc)
234*4dc78e53SAndroid Build Coastguard Worker {
235*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
236*4dc78e53SAndroid Build Coastguard Worker 
237*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
238*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
239*4dc78e53SAndroid Build Coastguard Worker 
240*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_num_tc = num_tc;
241*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_NUMTC;
242*4dc78e53SAndroid Build Coastguard Worker 	return 0;
243*4dc78e53SAndroid Build Coastguard Worker }
244*4dc78e53SAndroid Build Coastguard Worker 
245*4dc78e53SAndroid Build Coastguard Worker /**
246*4dc78e53SAndroid Build Coastguard Worker  * Get number of traffic classes of MQPRIO qdisc.
247*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
248*4dc78e53SAndroid Build Coastguard Worker  * @return Number of traffic classes or a negative error code.
249*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_num_tc(struct rtnl_qdisc * qdisc)250*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_get_num_tc(struct rtnl_qdisc *qdisc)
251*4dc78e53SAndroid Build Coastguard Worker {
252*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
253*4dc78e53SAndroid Build Coastguard Worker 
254*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
255*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
256*4dc78e53SAndroid Build Coastguard Worker 
257*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC)
258*4dc78e53SAndroid Build Coastguard Worker 		return mqprio->qm_num_tc;
259*4dc78e53SAndroid Build Coastguard Worker 	else
260*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
261*4dc78e53SAndroid Build Coastguard Worker }
262*4dc78e53SAndroid Build Coastguard Worker 
263*4dc78e53SAndroid Build Coastguard Worker /**
264*4dc78e53SAndroid Build Coastguard Worker  * Set priomap of the MQPRIO qdisc.
265*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
266*4dc78e53SAndroid Build Coastguard Worker  * @arg priomap         New priority mapping.
267*4dc78e53SAndroid Build Coastguard Worker  * @arg len             Length of priomap (# of elements).
268*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
269*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_set_priomap(struct rtnl_qdisc * qdisc,uint8_t priomap[],int len)270*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[],
271*4dc78e53SAndroid Build Coastguard Worker                                 int len)
272*4dc78e53SAndroid Build Coastguard Worker {
273*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
274*4dc78e53SAndroid Build Coastguard Worker 	int i;
275*4dc78e53SAndroid Build Coastguard Worker 
276*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
277*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
278*4dc78e53SAndroid Build Coastguard Worker 
279*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
280*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
281*4dc78e53SAndroid Build Coastguard Worker 
282*4dc78e53SAndroid Build Coastguard Worker 	if (len > TC_QOPT_BITMASK + 1)
283*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
284*4dc78e53SAndroid Build Coastguard Worker 
285*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; i < len; i++) {
286*4dc78e53SAndroid Build Coastguard Worker 		if (priomap[i] > mqprio->qm_num_tc)
287*4dc78e53SAndroid Build Coastguard Worker 			return -NLE_RANGE;
288*4dc78e53SAndroid Build Coastguard Worker 	}
289*4dc78e53SAndroid Build Coastguard Worker 
290*4dc78e53SAndroid Build Coastguard Worker 	memset(mqprio->qm_prio_map, 0, sizeof(mqprio->qm_prio_map));
291*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_prio_map, priomap, len * sizeof(uint8_t));
292*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_PRIOMAP;
293*4dc78e53SAndroid Build Coastguard Worker 
294*4dc78e53SAndroid Build Coastguard Worker 	return 0;
295*4dc78e53SAndroid Build Coastguard Worker }
296*4dc78e53SAndroid Build Coastguard Worker 
297*4dc78e53SAndroid Build Coastguard Worker /**
298*4dc78e53SAndroid Build Coastguard Worker  * Get priomap of MQPRIO qdisc.
299*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
300*4dc78e53SAndroid Build Coastguard Worker  * @return Priority mapping as array of size TC_QOPT_BANDS+1
301*4dc78e53SAndroid Build Coastguard Worker  *         or NULL if an error occured.
302*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_priomap(struct rtnl_qdisc * qdisc)303*4dc78e53SAndroid Build Coastguard Worker uint8_t *rtnl_qdisc_mqprio_get_priomap(struct rtnl_qdisc *qdisc)
304*4dc78e53SAndroid Build Coastguard Worker {
305*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
306*4dc78e53SAndroid Build Coastguard Worker 
307*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
308*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
309*4dc78e53SAndroid Build Coastguard Worker 
310*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_mask & SCH_MQPRIO_ATTR_PRIOMAP)
311*4dc78e53SAndroid Build Coastguard Worker 		return mqprio->qm_prio_map;
312*4dc78e53SAndroid Build Coastguard Worker 	else
313*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
314*4dc78e53SAndroid Build Coastguard Worker }
315*4dc78e53SAndroid Build Coastguard Worker 
316*4dc78e53SAndroid Build Coastguard Worker /**
317*4dc78e53SAndroid Build Coastguard Worker  * Offload to HW or run in SW (default).
318*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
319*4dc78e53SAndroid Build Coastguard Worker  * @arg offload         1 - offload to HW, 0 - run in SW only (default).
320*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
321*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_hw_offload(struct rtnl_qdisc * qdisc,int offload)322*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_hw_offload(struct rtnl_qdisc *qdisc, int offload)
323*4dc78e53SAndroid Build Coastguard Worker {
324*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
325*4dc78e53SAndroid Build Coastguard Worker 
326*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
327*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
328*4dc78e53SAndroid Build Coastguard Worker 
329*4dc78e53SAndroid Build Coastguard Worker 	switch (offload) {
330*4dc78e53SAndroid Build Coastguard Worker 	case 0:
331*4dc78e53SAndroid Build Coastguard Worker 	case 1:
332*4dc78e53SAndroid Build Coastguard Worker 		mqprio->qm_hw = offload;
333*4dc78e53SAndroid Build Coastguard Worker 		break;
334*4dc78e53SAndroid Build Coastguard Worker 	default:
335*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
336*4dc78e53SAndroid Build Coastguard Worker 	}
337*4dc78e53SAndroid Build Coastguard Worker 
338*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_HW;
339*4dc78e53SAndroid Build Coastguard Worker 	return 0;
340*4dc78e53SAndroid Build Coastguard Worker }
341*4dc78e53SAndroid Build Coastguard Worker 
342*4dc78e53SAndroid Build Coastguard Worker /**
343*4dc78e53SAndroid Build Coastguard Worker  * Check whether running in HW or SW.
344*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
345*4dc78e53SAndroid Build Coastguard Worker  * @return 0 if running in SW, otherwise 1 (HW)
346*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_hw_offload(struct rtnl_qdisc * qdisc)347*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_get_hw_offload(struct rtnl_qdisc *qdisc)
348*4dc78e53SAndroid Build Coastguard Worker {
349*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
350*4dc78e53SAndroid Build Coastguard Worker 
351*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
352*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
353*4dc78e53SAndroid Build Coastguard Worker 
354*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_mask & SCH_MQPRIO_ATTR_HW)
355*4dc78e53SAndroid Build Coastguard Worker 		return mqprio->qm_hw;
356*4dc78e53SAndroid Build Coastguard Worker 
357*4dc78e53SAndroid Build Coastguard Worker 	return 0;
358*4dc78e53SAndroid Build Coastguard Worker }
359*4dc78e53SAndroid Build Coastguard Worker 
360*4dc78e53SAndroid Build Coastguard Worker /**
361*4dc78e53SAndroid Build Coastguard Worker  * Set tc queue of the MQPRIO qdisc.
362*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
363*4dc78e53SAndroid Build Coastguard Worker  * @arg count           count of queue range for each traffic class
364*4dc78e53SAndroid Build Coastguard Worker  * @arg offset          offset of queue range for each traffic class
365*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
366*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_set_queue(struct rtnl_qdisc * qdisc,uint16_t count[],uint16_t offset[],int len)367*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_set_queue(struct rtnl_qdisc *qdisc, uint16_t count[],
368*4dc78e53SAndroid Build Coastguard Worker                                 uint16_t offset[], int len)
369*4dc78e53SAndroid Build Coastguard Worker {
370*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
371*4dc78e53SAndroid Build Coastguard Worker 
372*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
373*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
374*4dc78e53SAndroid Build Coastguard Worker 
375*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
376*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
377*4dc78e53SAndroid Build Coastguard Worker 
378*4dc78e53SAndroid Build Coastguard Worker 	if (len < 0 || len > TC_QOPT_MAX_QUEUE)
379*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
380*4dc78e53SAndroid Build Coastguard Worker 
381*4dc78e53SAndroid Build Coastguard Worker 	memset(mqprio->qm_count, 0, sizeof(mqprio->qm_count));
382*4dc78e53SAndroid Build Coastguard Worker 	memset(mqprio->qm_offset, 0, sizeof(mqprio->qm_offset));
383*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_count, count, len * sizeof(uint16_t));
384*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_offset, offset, len * sizeof(uint16_t));
385*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_QUEUE;
386*4dc78e53SAndroid Build Coastguard Worker 
387*4dc78e53SAndroid Build Coastguard Worker 	return 0;
388*4dc78e53SAndroid Build Coastguard Worker }
389*4dc78e53SAndroid Build Coastguard Worker 
390*4dc78e53SAndroid Build Coastguard Worker /**
391*4dc78e53SAndroid Build Coastguard Worker  * Get tc queue of the MQPRIO qdisc.
392*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
393*4dc78e53SAndroid Build Coastguard Worker  * @arg count           count of queue range for each traffic class
394*4dc78e53SAndroid Build Coastguard Worker  * @arg offset          offset of queue range for each traffic class
395*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
396*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_queue(struct rtnl_qdisc * qdisc,uint16_t * count,uint16_t * offset)397*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_get_queue(struct rtnl_qdisc *qdisc, uint16_t *count,
398*4dc78e53SAndroid Build Coastguard Worker                                 uint16_t *offset)
399*4dc78e53SAndroid Build Coastguard Worker {
400*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
401*4dc78e53SAndroid Build Coastguard Worker 
402*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
403*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
404*4dc78e53SAndroid Build Coastguard Worker 
405*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_QUEUE))
406*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
407*4dc78e53SAndroid Build Coastguard Worker 
408*4dc78e53SAndroid Build Coastguard Worker 	memcpy(count, mqprio->qm_count, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
409*4dc78e53SAndroid Build Coastguard Worker 	memcpy(offset, mqprio->qm_offset, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
410*4dc78e53SAndroid Build Coastguard Worker 
411*4dc78e53SAndroid Build Coastguard Worker 	return 0;
412*4dc78e53SAndroid Build Coastguard Worker }
413*4dc78e53SAndroid Build Coastguard Worker 
414*4dc78e53SAndroid Build Coastguard Worker /**
415*4dc78e53SAndroid Build Coastguard Worker  * Set mode of mqprio Qdisc
416*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
417*4dc78e53SAndroid Build Coastguard Worker  * @arg mode            one of: TC_MQPRIO_MODE_DCB, TC_MQPRIO_MODE_CHANNEL
418*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
419*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_set_mode(struct rtnl_qdisc * qdisc,uint16_t mode)420*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_set_mode(struct rtnl_qdisc *qdisc, uint16_t mode)
421*4dc78e53SAndroid Build Coastguard Worker {
422*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
423*4dc78e53SAndroid Build Coastguard Worker 
424*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
425*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
426*4dc78e53SAndroid Build Coastguard Worker 
427*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
428*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
429*4dc78e53SAndroid Build Coastguard Worker 
430*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mode = mode;
431*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_MODE;
432*4dc78e53SAndroid Build Coastguard Worker 
433*4dc78e53SAndroid Build Coastguard Worker 	return 0;
434*4dc78e53SAndroid Build Coastguard Worker }
435*4dc78e53SAndroid Build Coastguard Worker 
436*4dc78e53SAndroid Build Coastguard Worker /**
437*4dc78e53SAndroid Build Coastguard Worker  * Get mode of mqprio Qdisc
438*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
439*4dc78e53SAndroid Build Coastguard Worker  * @return mode on success or negative error code.
440*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_mode(struct rtnl_qdisc * qdisc)441*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_get_mode(struct rtnl_qdisc *qdisc)
442*4dc78e53SAndroid Build Coastguard Worker {
443*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
444*4dc78e53SAndroid Build Coastguard Worker 
445*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
446*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
447*4dc78e53SAndroid Build Coastguard Worker 
448*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MODE)
449*4dc78e53SAndroid Build Coastguard Worker 		return mqprio->qm_mode;
450*4dc78e53SAndroid Build Coastguard Worker 	else
451*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
452*4dc78e53SAndroid Build Coastguard Worker }
453*4dc78e53SAndroid Build Coastguard Worker 
454*4dc78e53SAndroid Build Coastguard Worker /**
455*4dc78e53SAndroid Build Coastguard Worker  * Set shaper of mqprio Qdisc
456*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc to be modified.
457*4dc78e53SAndroid Build Coastguard Worker  * @arg shaper          one of: TC_MQPRIO_SHAPER_DCB, TC_MQPRIO_SHAPER_BW_RATE
458*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
459*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_set_shaper(struct rtnl_qdisc * qdisc,uint16_t shaper)460*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_set_shaper(struct rtnl_qdisc *qdisc, uint16_t shaper)
461*4dc78e53SAndroid Build Coastguard Worker {
462*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
463*4dc78e53SAndroid Build Coastguard Worker 
464*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
465*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
466*4dc78e53SAndroid Build Coastguard Worker 
467*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
468*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
469*4dc78e53SAndroid Build Coastguard Worker 
470*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_shaper = shaper;
471*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_SHAPER;
472*4dc78e53SAndroid Build Coastguard Worker 
473*4dc78e53SAndroid Build Coastguard Worker 	return 0;
474*4dc78e53SAndroid Build Coastguard Worker }
475*4dc78e53SAndroid Build Coastguard Worker 
476*4dc78e53SAndroid Build Coastguard Worker /**
477*4dc78e53SAndroid Build Coastguard Worker  * Get shaper of mqprio Qdisc
478*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
479*4dc78e53SAndroid Build Coastguard Worker  * @return shaper on success or negative error code.
480*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_shaper(struct rtnl_qdisc * qdisc)481*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_get_shaper(struct rtnl_qdisc *qdisc)
482*4dc78e53SAndroid Build Coastguard Worker {
483*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
484*4dc78e53SAndroid Build Coastguard Worker 
485*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
486*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
487*4dc78e53SAndroid Build Coastguard Worker 
488*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER)
489*4dc78e53SAndroid Build Coastguard Worker 		return mqprio->qm_shaper;
490*4dc78e53SAndroid Build Coastguard Worker 	else
491*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
492*4dc78e53SAndroid Build Coastguard Worker }
493*4dc78e53SAndroid Build Coastguard Worker 
494*4dc78e53SAndroid Build Coastguard Worker /**
495*4dc78e53SAndroid Build Coastguard Worker  * Set minimum value of bandwidth rate limit for each traffic class
496*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
497*4dc78e53SAndroid Build Coastguard Worker  * @arg min             minimum rate for each traffic class
498*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
499*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_set_min_rate(struct rtnl_qdisc * qdisc,uint64_t min[],int len)500*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_set_min_rate(struct rtnl_qdisc *qdisc, uint64_t min[], int len)
501*4dc78e53SAndroid Build Coastguard Worker {
502*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
503*4dc78e53SAndroid Build Coastguard Worker 
504*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
505*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
506*4dc78e53SAndroid Build Coastguard Worker 
507*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER))
508*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
509*4dc78e53SAndroid Build Coastguard Worker 
510*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
511*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
512*4dc78e53SAndroid Build Coastguard Worker 
513*4dc78e53SAndroid Build Coastguard Worker 	if (len < 0 || len > TC_QOPT_MAX_QUEUE)
514*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
515*4dc78e53SAndroid Build Coastguard Worker 
516*4dc78e53SAndroid Build Coastguard Worker 	memset(mqprio->qm_min_rate, 0, sizeof(mqprio->qm_min_rate));
517*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_min_rate, min, len * sizeof(uint64_t));
518*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_MIN_RATE;
519*4dc78e53SAndroid Build Coastguard Worker 
520*4dc78e53SAndroid Build Coastguard Worker 	return 0;
521*4dc78e53SAndroid Build Coastguard Worker }
522*4dc78e53SAndroid Build Coastguard Worker 
523*4dc78e53SAndroid Build Coastguard Worker /**
524*4dc78e53SAndroid Build Coastguard Worker  * Get minimum value of bandwidth rate limit for each traffic class
525*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
526*4dc78e53SAndroid Build Coastguard Worker  * @arg min             minimum rate for each traffic class
527*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
528*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_min_rate(struct rtnl_qdisc * qdisc,uint64_t * min)529*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_get_min_rate(struct rtnl_qdisc *qdisc, uint64_t *min)
530*4dc78e53SAndroid Build Coastguard Worker {
531*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
532*4dc78e53SAndroid Build Coastguard Worker 
533*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
534*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
535*4dc78e53SAndroid Build Coastguard Worker 
536*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MIN_RATE) {
537*4dc78e53SAndroid Build Coastguard Worker 		memcpy(min, mqprio->qm_min_rate, TC_QOPT_MAX_QUEUE * sizeof(uint64_t));
538*4dc78e53SAndroid Build Coastguard Worker 		return 0;
539*4dc78e53SAndroid Build Coastguard Worker 	}
540*4dc78e53SAndroid Build Coastguard Worker 
541*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_MISSING_ATTR;
542*4dc78e53SAndroid Build Coastguard Worker }
543*4dc78e53SAndroid Build Coastguard Worker 
544*4dc78e53SAndroid Build Coastguard Worker /**
545*4dc78e53SAndroid Build Coastguard Worker  * Set maximum value of bandwidth rate limit for each traffic class
546*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
547*4dc78e53SAndroid Build Coastguard Worker  * @arg max             maximum rate for each traffic class
548*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
549*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_set_max_rate(struct rtnl_qdisc * qdisc,uint64_t max[],int len)550*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_set_max_rate(struct rtnl_qdisc *qdisc, uint64_t max[], int len)
551*4dc78e53SAndroid Build Coastguard Worker {
552*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
553*4dc78e53SAndroid Build Coastguard Worker 
554*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
555*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_NOMEM;
556*4dc78e53SAndroid Build Coastguard Worker 
557*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER))
558*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_MISSING_ATTR;
559*4dc78e53SAndroid Build Coastguard Worker 
560*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
561*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
562*4dc78e53SAndroid Build Coastguard Worker 
563*4dc78e53SAndroid Build Coastguard Worker 	if (len < 0 || len > TC_QOPT_MAX_QUEUE)
564*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
565*4dc78e53SAndroid Build Coastguard Worker 
566*4dc78e53SAndroid Build Coastguard Worker 	memset(mqprio->qm_max_rate, 0, sizeof(mqprio->qm_max_rate));
567*4dc78e53SAndroid Build Coastguard Worker 	memcpy(mqprio->qm_max_rate, max, len * sizeof(uint64_t));
568*4dc78e53SAndroid Build Coastguard Worker 	mqprio->qm_mask |= SCH_MQPRIO_ATTR_MAX_RATE;
569*4dc78e53SAndroid Build Coastguard Worker 
570*4dc78e53SAndroid Build Coastguard Worker 	return 0;
571*4dc78e53SAndroid Build Coastguard Worker }
572*4dc78e53SAndroid Build Coastguard Worker 
573*4dc78e53SAndroid Build Coastguard Worker /**
574*4dc78e53SAndroid Build Coastguard Worker  * Get maximum value of bandwidth rate limit for each traffic class
575*4dc78e53SAndroid Build Coastguard Worker  * @arg qdisc           MQPRIO qdisc.
576*4dc78e53SAndroid Build Coastguard Worker  * @arg min             maximum rate for each traffic class
577*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code.
578*4dc78e53SAndroid Build Coastguard Worker  */
rtnl_qdisc_mqprio_get_max_rate(struct rtnl_qdisc * qdisc,uint64_t * max)579*4dc78e53SAndroid Build Coastguard Worker int rtnl_qdisc_mqprio_get_max_rate(struct rtnl_qdisc *qdisc, uint64_t *max)
580*4dc78e53SAndroid Build Coastguard Worker {
581*4dc78e53SAndroid Build Coastguard Worker 	struct rtnl_mqprio *mqprio;
582*4dc78e53SAndroid Build Coastguard Worker 
583*4dc78e53SAndroid Build Coastguard Worker 	if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
584*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_INVAL;
585*4dc78e53SAndroid Build Coastguard Worker 
586*4dc78e53SAndroid Build Coastguard Worker 	if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MAX_RATE) {
587*4dc78e53SAndroid Build Coastguard Worker 		memcpy(max, mqprio->qm_max_rate, TC_QOPT_MAX_QUEUE * sizeof(uint64_t));
588*4dc78e53SAndroid Build Coastguard Worker 		return 0;
589*4dc78e53SAndroid Build Coastguard Worker 	}
590*4dc78e53SAndroid Build Coastguard Worker 
591*4dc78e53SAndroid Build Coastguard Worker 	return -NLE_MISSING_ATTR;
592*4dc78e53SAndroid Build Coastguard Worker }
593*4dc78e53SAndroid Build Coastguard Worker 
594*4dc78e53SAndroid Build Coastguard Worker /** @} */
595*4dc78e53SAndroid Build Coastguard Worker 
596*4dc78e53SAndroid Build Coastguard Worker static struct rtnl_tc_ops mqprio_ops = {
597*4dc78e53SAndroid Build Coastguard Worker 	.to_kind                = "mqprio",
598*4dc78e53SAndroid Build Coastguard Worker 	.to_type                = RTNL_TC_TYPE_QDISC,
599*4dc78e53SAndroid Build Coastguard Worker 	.to_size                = sizeof(struct rtnl_mqprio),
600*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_parser          = mqprio_msg_parser,
601*4dc78e53SAndroid Build Coastguard Worker 	.to_dump = {
602*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_LINE]      = mqprio_dump_line,
603*4dc78e53SAndroid Build Coastguard Worker 	    [NL_DUMP_DETAILS]   = mqprio_dump_details,
604*4dc78e53SAndroid Build Coastguard Worker 	},
605*4dc78e53SAndroid Build Coastguard Worker 	.to_msg_fill            = mqprio_msg_fill,
606*4dc78e53SAndroid Build Coastguard Worker };
607*4dc78e53SAndroid Build Coastguard Worker 
mqprio_init(void)608*4dc78e53SAndroid Build Coastguard Worker static void _nl_init mqprio_init(void)
609*4dc78e53SAndroid Build Coastguard Worker {
610*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_register(&mqprio_ops);
611*4dc78e53SAndroid Build Coastguard Worker }
612*4dc78e53SAndroid Build Coastguard Worker 
mqprio_exit(void)613*4dc78e53SAndroid Build Coastguard Worker static void _nl_exit mqprio_exit(void)
614*4dc78e53SAndroid Build Coastguard Worker {
615*4dc78e53SAndroid Build Coastguard Worker 	rtnl_tc_unregister(&mqprio_ops);
616*4dc78e53SAndroid Build Coastguard Worker }
617*4dc78e53SAndroid Build Coastguard Worker 
618*4dc78e53SAndroid Build Coastguard Worker /** @} */
619