File Index
Files and directories
Sign in
FILE

ieee8021q_helpers.c

File preview with syntax highlighting.

linux-6.19.14/net/core/ieee8021q_helpers.c C
  1// SPDX-License-Identifier: GPL-2.0
  2// Copyright (c) 2024 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
  3
  4#include <linux/array_size.h>
  5#include <linux/printk.h>
  6#include <linux/types.h>
  7#include <net/dscp.h>
  8#include <net/ieee8021q.h>
  9
 10/* verify that table covers all 8 traffic types */
 11#define TT_MAP_SIZE_OK(tbl)                                 \
 12	compiletime_assert(ARRAY_SIZE(tbl) == IEEE8021Q_TT_MAX, \
 13			   #tbl " size mismatch")
 14
 15/* The following arrays map Traffic Types (TT) to traffic classes (TC) for
 16 * different number of queues as shown in the example provided by
 17 * IEEE 802.1Q-2022 in Annex I "I.3 Traffic type to traffic class mapping" and
 18 * Table I-1 "Traffic type to traffic class mapping".
 19 */
 20static const u8 ieee8021q_8queue_tt_tc_map[] = {
 21	[IEEE8021Q_TT_BK] = 0,
 22	[IEEE8021Q_TT_BE] = 1,
 23	[IEEE8021Q_TT_EE] = 2,
 24	[IEEE8021Q_TT_CA] = 3,
 25	[IEEE8021Q_TT_VI] = 4,
 26	[IEEE8021Q_TT_VO] = 5,
 27	[IEEE8021Q_TT_IC] = 6,
 28	[IEEE8021Q_TT_NC] = 7,
 29};
 30
 31static const u8 ieee8021q_7queue_tt_tc_map[] = {
 32	[IEEE8021Q_TT_BK] = 0,
 33	[IEEE8021Q_TT_BE] = 1,
 34	[IEEE8021Q_TT_EE] = 2,
 35	[IEEE8021Q_TT_CA] = 3,
 36	[IEEE8021Q_TT_VI] = 4,	[IEEE8021Q_TT_VO] = 4,
 37	[IEEE8021Q_TT_IC] = 5,
 38	[IEEE8021Q_TT_NC] = 6,
 39};
 40
 41static const u8 ieee8021q_6queue_tt_tc_map[] = {
 42	[IEEE8021Q_TT_BK] = 0,
 43	[IEEE8021Q_TT_BE] = 1,
 44	[IEEE8021Q_TT_EE] = 2,	[IEEE8021Q_TT_CA] = 2,
 45	[IEEE8021Q_TT_VI] = 3,	[IEEE8021Q_TT_VO] = 3,
 46	[IEEE8021Q_TT_IC] = 4,
 47	[IEEE8021Q_TT_NC] = 5,
 48};
 49
 50static const u8 ieee8021q_5queue_tt_tc_map[] = {
 51	[IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 52	[IEEE8021Q_TT_EE] = 1, [IEEE8021Q_TT_CA] = 1,
 53	[IEEE8021Q_TT_VI] = 2, [IEEE8021Q_TT_VO] = 2,
 54	[IEEE8021Q_TT_IC] = 3,
 55	[IEEE8021Q_TT_NC] = 4,
 56};
 57
 58static const u8 ieee8021q_4queue_tt_tc_map[] = {
 59	[IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 60	[IEEE8021Q_TT_EE] = 1, [IEEE8021Q_TT_CA] = 1,
 61	[IEEE8021Q_TT_VI] = 2, [IEEE8021Q_TT_VO] = 2,
 62	[IEEE8021Q_TT_IC] = 3, [IEEE8021Q_TT_NC] = 3,
 63};
 64
 65static const u8 ieee8021q_3queue_tt_tc_map[] = {
 66	[IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 67	[IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
 68	[IEEE8021Q_TT_VI] = 1, [IEEE8021Q_TT_VO] = 1,
 69	[IEEE8021Q_TT_IC] = 2, [IEEE8021Q_TT_NC] = 2,
 70};
 71
 72static const u8 ieee8021q_2queue_tt_tc_map[] = {
 73	[IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 74	[IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
 75	[IEEE8021Q_TT_VI] = 1, [IEEE8021Q_TT_VO] = 1,
 76	[IEEE8021Q_TT_IC] = 1, [IEEE8021Q_TT_NC] = 1,
 77};
 78
 79static const u8 ieee8021q_1queue_tt_tc_map[] = {
 80	[IEEE8021Q_TT_BK] = 0, [IEEE8021Q_TT_BE] = 0,
 81	[IEEE8021Q_TT_EE] = 0, [IEEE8021Q_TT_CA] = 0,
 82	[IEEE8021Q_TT_VI] = 0, [IEEE8021Q_TT_VO] = 0,
 83	[IEEE8021Q_TT_IC] = 0, [IEEE8021Q_TT_NC] = 0,
 84};
 85
 86/**
 87 * ieee8021q_tt_to_tc - Map IEEE 802.1Q Traffic Type to Traffic Class
 88 * @tt: IEEE 802.1Q Traffic Type
 89 * @num_queues: Number of queues
 90 *
 91 * This function maps an IEEE 802.1Q Traffic Type to a Traffic Class (TC) based
 92 * on the number of queues configured on the NIC. The mapping is based on the
 93 * example provided by IEEE 802.1Q-2022 in Annex I "I.3 Traffic type to traffic
 94 * class mapping" and Table I-1 "Traffic type to traffic class mapping".
 95 *
 96 * Return: Traffic Class corresponding to the given Traffic Type or negative
 97 * value in case of error.
 98 */
 99int ieee8021q_tt_to_tc(enum ieee8021q_traffic_type tt, unsigned int num_queues)
100{
101	if (tt < 0 || tt >= IEEE8021Q_TT_MAX) {
102		pr_err("Requested Traffic Type (%d) is out of range (%d)\n", tt,
103		       IEEE8021Q_TT_MAX);
104		return -EINVAL;
105	}
106
107	switch (num_queues) {
108	case 8:
109		TT_MAP_SIZE_OK(ieee8021q_8queue_tt_tc_map);
110		return ieee8021q_8queue_tt_tc_map[tt];
111	case 7:
112		TT_MAP_SIZE_OK(ieee8021q_7queue_tt_tc_map);
113		return ieee8021q_7queue_tt_tc_map[tt];
114	case 6:
115		TT_MAP_SIZE_OK(ieee8021q_6queue_tt_tc_map);
116		return ieee8021q_6queue_tt_tc_map[tt];
117	case 5:
118		TT_MAP_SIZE_OK(ieee8021q_5queue_tt_tc_map);
119		return ieee8021q_5queue_tt_tc_map[tt];
120	case 4:
121		TT_MAP_SIZE_OK(ieee8021q_4queue_tt_tc_map);
122		return ieee8021q_4queue_tt_tc_map[tt];
123	case 3:
124		TT_MAP_SIZE_OK(ieee8021q_3queue_tt_tc_map);
125		return ieee8021q_3queue_tt_tc_map[tt];
126	case 2:
127		TT_MAP_SIZE_OK(ieee8021q_2queue_tt_tc_map);
128		return ieee8021q_2queue_tt_tc_map[tt];
129	case 1:
130		TT_MAP_SIZE_OK(ieee8021q_1queue_tt_tc_map);
131		return ieee8021q_1queue_tt_tc_map[tt];
132	}
133
134	pr_err("Invalid number of queues %d\n", num_queues);
135
136	return -EINVAL;
137}
138EXPORT_SYMBOL_GPL(ieee8021q_tt_to_tc);
139
140/**
141 * ietf_dscp_to_ieee8021q_tt - Map IETF DSCP to IEEE 802.1Q Traffic Type
142 * @dscp: IETF DSCP value
143 *
144 * This function maps an IETF DSCP value to an IEEE 802.1Q Traffic Type (TT).
145 * Since there is no corresponding mapping between DSCP and IEEE 802.1Q Traffic
146 * Type, this function is inspired by the RFC8325 documentation which describe
147 * the mapping between DSCP and 802.11 User Priority (UP) values.
148 *
149 * Return: IEEE 802.1Q Traffic Type corresponding to the given DSCP value
150 */
151int ietf_dscp_to_ieee8021q_tt(u8 dscp)
152{
153	switch (dscp) {
154	case DSCP_CS0:
155	/* Comment from RFC8325:
156	 * [RFC4594], Section 4.8, recommends High-Throughput Data be marked
157	 * AF1x (that is, AF11, AF12, and AF13, according to the rules defined
158	 * in [RFC2475]).
159	 *
160	 * By default (as described in Section 2.3), High-Throughput Data will
161	 * map to UP 1 and, thus, to the Background Access Category (AC_BK),
162	 * which is contrary to the intent expressed in [RFC4594].
163
164	 * Unfortunately, there really is no corresponding fit for the High-
165	 * Throughput Data service class within the constrained 4 Access
166	 * Category [IEEE.802.11-2016] model.  If the High-Throughput Data
167	 * service class is assigned to the Best Effort Access Category (AC_BE),
168	 * then it would contend with Low-Latency Data (while [RFC4594]
169	 * recommends a distinction in servicing between these service classes)
170	 * as well as with the default service class; alternatively, if it is
171	 * assigned to the Background Access Category (AC_BK), then it would
172	 * receive a less-then-best-effort service and contend with Low-Priority
173	 * Data (as discussed in Section 4.2.10).
174	 *
175	 * As such, since there is no directly corresponding fit for the High-
176	 * Throughout Data service class within the [IEEE.802.11-2016] model, it
177	 * is generally RECOMMENDED to map High-Throughput Data to UP 0, thereby
178	 * admitting it to the Best Effort Access Category (AC_BE).
179	 *
180	 * Note: The above text is from RFC8325 which is describing the mapping
181	 * between DSCP and 802.11 User Priority (UP) values. The mapping
182	 * between UP and IEEE 802.1Q Traffic Type is not defined in the RFC but
183	 * the 802.11 AC_BK and AC_BE are closely related to the IEEE 802.1Q
184	 * Traffic Types BE and BK.
185	 */
186	case DSCP_AF11:
187	case DSCP_AF12:
188	case DSCP_AF13:
189		return IEEE8021Q_TT_BE;
190	/* Comment from RFC8325:
191	 * RFC3662 and RFC4594 both recommend Low-Priority Data be marked
192	 * with DSCP CS1. The Low-Priority Data service class loosely
193	 * corresponds to the [IEEE.802.11-2016] Background Access Category
194	 */
195	case DSCP_CS1:
196		return IEEE8021Q_TT_BK;
197	case DSCP_CS2:
198	case DSCP_AF21:
199	case DSCP_AF22:
200	case DSCP_AF23:
201		return IEEE8021Q_TT_EE;
202	case DSCP_CS3:
203	case DSCP_AF31:
204	case DSCP_AF32:
205	case DSCP_AF33:
206		return IEEE8021Q_TT_CA;
207	case DSCP_CS4:
208	case DSCP_AF41:
209	case DSCP_AF42:
210	case DSCP_AF43:
211		return IEEE8021Q_TT_VI;
212	case DSCP_CS5:
213	case DSCP_EF:
214	case DSCP_VOICE_ADMIT:
215		return IEEE8021Q_TT_VO;
216	case DSCP_CS6:
217		return IEEE8021Q_TT_IC;
218	case DSCP_CS7:
219		return IEEE8021Q_TT_NC;
220	}
221
222	return SIMPLE_IETF_DSCP_TO_IEEE8021Q_TT(dscp);
223}
224EXPORT_SYMBOL_GPL(ietf_dscp_to_ieee8021q_tt);
~/ Read-only file preview.