ieee8021q_helpers.c 7.3 KB

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