1 // SPDX-License-Identifier: GPL-2.0
4 #include <linux/array_size.h>
5 #include <linux/printk.h>
6 #include <linux/types.h>
8 #include <net/ieee8021q.h>
10 /* The following arrays map Traffic Types (TT) to traffic classes (TC) for
11 * different number of queues as shown in the example provided by
12 * IEEE 802.1Q-2022 in Annex I "I.3 Traffic type to traffic class mapping" and
13 * Table I-1 "Traffic type to traffic class mapping".
15 static const u8 ieee8021q_8queue_tt_tc_map[] = {
16 [IEEE8021Q_TT_BK] = 0,
17 [IEEE8021Q_TT_BE] = 1,
18 [IEEE8021Q_TT_EE] = 2,
19 [IEEE8021Q_TT_CA] = 3,
20 [IEEE8021Q_TT_VI] = 4,
21 [IEEE8021Q_TT_VO] = 5,
22 [IEEE8021Q_TT_IC] = 6,
23 [IEEE8021Q_TT_NC] = 7,
26 static const u8 ieee8021q_7queue_tt_tc_map[] = {
27 [IEEE8021Q_TT_BK] = 0,
28 [IEEE8021Q_TT_BE] = 1,
29 [IEEE8021Q_TT_EE] = 2,
30 [IEEE8021Q_TT_CA] = 3,
31 [IEEE8021Q_TT_VI] = 4, [IEEE8021Q_TT_VO] = 4,
32 [IEEE8021Q_TT_IC] = 5,
33 [IEEE8021Q_TT_NC] = 6,
36 static const u8 ieee8021q_6queue_tt_tc_map[] = {
37 [IEEE8021Q_TT_BK] = 0,
38 [IEEE8021Q_TT_BE] = 1,
39 [IEEE8021Q_TT_EE] = 2, [IEEE8021Q_TT_CA] = 2,
40 [IEEE8021Q_TT_VI] = 3, [IEEE8021Q_TT_VO] = 3,
41 [IEEE8021Q_TT_IC] = 4,
42 [IEEE8021Q_TT_NC] = 5,
45 static const u8 ieee8021q_5queue_tt_tc_map[] = {
46 [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
47 [IEEE8021Q_TT_EE] = 1, [IEEE8021Q_TT_CA] = 1,
48 [IEEE8021Q_TT_VI] = 2, [IEEE8021Q_TT_VO] = 2,
49 [IEEE8021Q_TT_IC] = 3,
50 [IEEE8021Q_TT_NC] = 4,
53 static const u8 ieee8021q_4queue_tt_tc_map[] = {
54 [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
55 [IEEE8021Q_TT_EE] = 1, [IEEE8021Q_TT_CA] = 1,
56 [IEEE8021Q_TT_VI] = 2, [IEEE8021Q_TT_VO] = 2,
57 [IEEE8021Q_TT_IC] = 3, [IEEE8021Q_TT_NC] = 3,
60 static const u8 ieee8021q_3queue_tt_tc_map[] = {
61 [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
62 [IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
63 [IEEE8021Q_TT_VI] = 1, [IEEE8021Q_TT_VO] = 1,
64 [IEEE8021Q_TT_IC] = 2, [IEEE8021Q_TT_NC] = 2,
67 static const u8 ieee8021q_2queue_tt_tc_map[] = {
68 [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
69 [IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
70 [IEEE8021Q_TT_VI] = 1, [IEEE8021Q_TT_VO] = 1,
71 [IEEE8021Q_TT_IC] = 1, [IEEE8021Q_TT_NC] = 1,
74 static const u8 ieee8021q_1queue_tt_tc_map[] = {
75 [IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
76 [IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
77 [IEEE8021Q_TT_VI] = 0, [IEEE8021Q_TT_VO] = 0,
78 [IEEE8021Q_TT_IC] = 0, [IEEE8021Q_TT_NC] = 0,
82 * ieee8021q_tt_to_tc - Map IEEE 802.1Q Traffic Type to Traffic Class
83 * @tt: IEEE 802.1Q Traffic Type
84 * @num_queues: Number of queues
86 * This function maps an IEEE 802.1Q Traffic Type to a Traffic Class (TC) based
87 * on the number of queues configured on the NIC. The mapping is based on the
88 * example provided by IEEE 802.1Q-2022 in Annex I "I.3 Traffic type to traffic
89 * class mapping" and Table I-1 "Traffic type to traffic class mapping".
91 * Return: Traffic Class corresponding to the given Traffic Type or negative
92 * value in case of error.
94 int ieee8021q_tt_to_tc(enum ieee8021q_traffic_type tt, unsigned int num_queues)
96 if (tt < 0 || tt >= IEEE8021Q_TT_MAX) {
97 pr_err("Requested Traffic Type (%d) is out of range (%d)\n", tt,
102 switch (num_queues) {
104 compiletime_assert(ARRAY_SIZE(ieee8021q_8queue_tt_tc_map) !=
105 IEEE8021Q_TT_MAX - 1,
106 "ieee8021q_8queue_tt_tc_map != max - 1");
107 return ieee8021q_8queue_tt_tc_map[tt];
109 compiletime_assert(ARRAY_SIZE(ieee8021q_7queue_tt_tc_map) !=
110 IEEE8021Q_TT_MAX - 1,
111 "ieee8021q_7queue_tt_tc_map != max - 1");
113 return ieee8021q_7queue_tt_tc_map[tt];
115 compiletime_assert(ARRAY_SIZE(ieee8021q_6queue_tt_tc_map) !=
116 IEEE8021Q_TT_MAX - 1,
117 "ieee8021q_6queue_tt_tc_map != max - 1");
119 return ieee8021q_6queue_tt_tc_map[tt];
121 compiletime_assert(ARRAY_SIZE(ieee8021q_5queue_tt_tc_map) !=
122 IEEE8021Q_TT_MAX - 1,
123 "ieee8021q_5queue_tt_tc_map != max - 1");
125 return ieee8021q_5queue_tt_tc_map[tt];
127 compiletime_assert(ARRAY_SIZE(ieee8021q_4queue_tt_tc_map) !=
128 IEEE8021Q_TT_MAX - 1,
129 "ieee8021q_4queue_tt_tc_map != max - 1");
131 return ieee8021q_4queue_tt_tc_map[tt];
133 compiletime_assert(ARRAY_SIZE(ieee8021q_3queue_tt_tc_map) !=
134 IEEE8021Q_TT_MAX - 1,
135 "ieee8021q_3queue_tt_tc_map != max - 1");
137 return ieee8021q_3queue_tt_tc_map[tt];
139 compiletime_assert(ARRAY_SIZE(ieee8021q_2queue_tt_tc_map) !=
140 IEEE8021Q_TT_MAX - 1,
141 "ieee8021q_2queue_tt_tc_map != max - 1");
143 return ieee8021q_2queue_tt_tc_map[tt];
145 compiletime_assert(ARRAY_SIZE(ieee8021q_1queue_tt_tc_map) !=
146 IEEE8021Q_TT_MAX - 1,
147 "ieee8021q_1queue_tt_tc_map != max - 1");
149 return ieee8021q_1queue_tt_tc_map[tt];
152 pr_err("Invalid number of queues %d\n", num_queues);
156 EXPORT_SYMBOL_GPL(ieee8021q_tt_to_tc);
159 * ietf_dscp_to_ieee8021q_tt - Map IETF DSCP to IEEE 802.1Q Traffic Type
160 * @dscp: IETF DSCP value
162 * This function maps an IETF DSCP value to an IEEE 802.1Q Traffic Type (TT).
163 * Since there is no corresponding mapping between DSCP and IEEE 802.1Q Traffic
164 * Type, this function is inspired by the RFC8325 documentation which describe
165 * the mapping between DSCP and 802.11 User Priority (UP) values.
167 * Return: IEEE 802.1Q Traffic Type corresponding to the given DSCP value
169 int ietf_dscp_to_ieee8021q_tt(u8 dscp)
173 /* Comment from RFC8325:
174 * [RFC4594], Section 4.8, recommends High-Throughput Data be marked
175 * AF1x (that is, AF11, AF12, and AF13, according to the rules defined
178 * By default (as described in Section 2.3), High-Throughput Data will
179 * map to UP 1 and, thus, to the Background Access Category (AC_BK),
180 * which is contrary to the intent expressed in [RFC4594].
182 * Unfortunately, there really is no corresponding fit for the High-
183 * Throughput Data service class within the constrained 4 Access
184 * Category [IEEE.802.11-2016] model. If the High-Throughput Data
185 * service class is assigned to the Best Effort Access Category (AC_BE),
186 * then it would contend with Low-Latency Data (while [RFC4594]
187 * recommends a distinction in servicing between these service classes)
188 * as well as with the default service class; alternatively, if it is
189 * assigned to the Background Access Category (AC_BK), then it would
190 * receive a less-then-best-effort service and contend with Low-Priority
191 * Data (as discussed in Section 4.2.10).
193 * As such, since there is no directly corresponding fit for the High-
194 * Throughout Data service class within the [IEEE.802.11-2016] model, it
195 * is generally RECOMMENDED to map High-Throughput Data to UP 0, thereby
196 * admitting it to the Best Effort Access Category (AC_BE).
198 * Note: The above text is from RFC8325 which is describing the mapping
199 * between DSCP and 802.11 User Priority (UP) values. The mapping
200 * between UP and IEEE 802.1Q Traffic Type is not defined in the RFC but
201 * the 802.11 AC_BK and AC_BE are closely related to the IEEE 802.1Q
202 * Traffic Types BE and BK.
207 return IEEE8021Q_TT_BE;
208 /* Comment from RFC8325:
209 * RFC3662 and RFC4594 both recommend Low-Priority Data be marked
210 * with DSCP CS1. The Low-Priority Data service class loosely
211 * corresponds to the [IEEE.802.11-2016] Background Access Category
214 return IEEE8021Q_TT_BK;
219 return IEEE8021Q_TT_EE;
224 return IEEE8021Q_TT_CA;
229 return IEEE8021Q_TT_VI;
232 case DSCP_VOICE_ADMIT:
233 return IEEE8021Q_TT_VO;
235 return IEEE8021Q_TT_IC;
237 return IEEE8021Q_TT_NC;
240 return SIMPLE_IETF_DSCP_TO_IEEE8021Q_TT(dscp);
242 EXPORT_SYMBOL_GPL(ietf_dscp_to_ieee8021q_tt);