spectrum_acl_flex_keys.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
  3. #include <linux/kernel.h>
  4. #include <linux/module.h>
  5. #include "spectrum.h"
  6. #include "item.h"
  7. #include "core_acl_flex_keys.h"
  8. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac[] = {
  9. MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x00, 2),
  10. MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x02, 4),
  11. MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
  12. MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12),
  13. MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
  14. };
  15. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac[] = {
  16. MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x00, 2),
  17. MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x02, 4),
  18. MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
  19. MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12),
  20. MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
  21. };
  22. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex[] = {
  23. MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x02, 2),
  24. MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),
  25. MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x0C, 0, 16),
  26. };
  27. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip[] = {
  28. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
  29. MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
  30. MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
  31. };
  32. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {
  33. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x00, 4),
  34. MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
  35. MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
  36. };
  37. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4[] = {
  38. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
  39. MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 4, 2),
  40. MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 24, 8),
  41. MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x08, 0, 6),
  42. MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x08, 8, 9), /* TCP_CONTROL+TCP_ECN */
  43. };
  44. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = {
  45. MLXSW_AFK_ELEMENT_INST_U32(VID, 0x00, 0, 12),
  46. MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 29, 3),
  47. MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x08, 0, 16),
  48. MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x0C, 0, 16),
  49. };
  50. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip[] = {
  51. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x00, 4),
  52. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),
  53. };
  54. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1[] = {
  55. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x00, 4),
  56. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),
  57. MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
  58. };
  59. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip[] = {
  60. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x00, 4),
  61. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
  62. };
  63. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex[] = {
  64. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x00, 4),
  65. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),
  66. };
  67. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = {
  68. MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16),
  69. };
  70. static const struct mlxsw_afk_block mlxsw_sp1_afk_blocks[] = {
  71. MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_l2_dmac),
  72. MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_l2_smac),
  73. MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_l2_smac_ex),
  74. MLXSW_AFK_BLOCK(0x30, mlxsw_sp_afk_element_info_ipv4_sip),
  75. MLXSW_AFK_BLOCK(0x31, mlxsw_sp_afk_element_info_ipv4_dip),
  76. MLXSW_AFK_BLOCK(0x32, mlxsw_sp_afk_element_info_ipv4),
  77. MLXSW_AFK_BLOCK(0x33, mlxsw_sp_afk_element_info_ipv4_ex),
  78. MLXSW_AFK_BLOCK(0x60, mlxsw_sp_afk_element_info_ipv6_dip),
  79. MLXSW_AFK_BLOCK(0x65, mlxsw_sp_afk_element_info_ipv6_ex1),
  80. MLXSW_AFK_BLOCK(0x62, mlxsw_sp_afk_element_info_ipv6_sip),
  81. MLXSW_AFK_BLOCK(0x63, mlxsw_sp_afk_element_info_ipv6_sip_ex),
  82. MLXSW_AFK_BLOCK(0xB0, mlxsw_sp_afk_element_info_packet_type),
  83. };
  84. #define MLXSW_SP1_AFK_KEY_BLOCK_SIZE 16
  85. static void mlxsw_sp1_afk_encode_block(char *block, int block_index,
  86. char *output)
  87. {
  88. unsigned int offset = block_index * MLXSW_SP1_AFK_KEY_BLOCK_SIZE;
  89. char *output_indexed = output + offset;
  90. memcpy(output_indexed, block, MLXSW_SP1_AFK_KEY_BLOCK_SIZE);
  91. }
  92. const struct mlxsw_afk_ops mlxsw_sp1_afk_ops = {
  93. .blocks = mlxsw_sp1_afk_blocks,
  94. .blocks_count = ARRAY_SIZE(mlxsw_sp1_afk_blocks),
  95. .encode_block = mlxsw_sp1_afk_encode_block,
  96. };
  97. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_0[] = {
  98. MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x04, 4),
  99. };
  100. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_1[] = {
  101. MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),
  102. };
  103. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_2[] = {
  104. MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x04, 2),
  105. MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),
  106. };
  107. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_3[] = {
  108. MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),
  109. MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
  110. MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x06, 2),
  111. };
  112. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_4[] = {
  113. MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x00, 0, 3),
  114. MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
  115. MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x04, 0, 16),
  116. };
  117. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_mac_5[] = {
  118. MLXSW_AFK_ELEMENT_INST_U32(VID, 0x04, 16, 12),
  119. MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x04, 0, 8), /* RX_ACL_SYSTEM_PORT */
  120. };
  121. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_0[] = {
  122. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),
  123. };
  124. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_1[] = {
  125. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
  126. };
  127. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_2[] = {
  128. MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x04, 0, 6),
  129. MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 6, 2),
  130. MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 8, 8),
  131. MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x04, 16, 8),
  132. };
  133. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_0[] = {
  134. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x04, 4),
  135. };
  136. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_1[] = {
  137. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),
  138. };
  139. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_2[] = {
  140. MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x04, 4),
  141. };
  142. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_3[] = {
  143. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x04, 4),
  144. };
  145. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_4[] = {
  146. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),
  147. };
  148. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_5[] = {
  149. MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x04, 4),
  150. };
  151. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0[] = {
  152. MLXSW_AFK_ELEMENT_INST_U32(SRC_L4_PORT, 0x04, 16, 16),
  153. MLXSW_AFK_ELEMENT_INST_U32(DST_L4_PORT, 0x04, 0, 16),
  154. };
  155. static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2[] = {
  156. MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x04, 16, 9), /* TCP_CONTROL + TCP_ECN */
  157. };
  158. static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks[] = {
  159. MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_mac_0),
  160. MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_mac_1),
  161. MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_mac_2),
  162. MLXSW_AFK_BLOCK(0x13, mlxsw_sp_afk_element_info_mac_3),
  163. MLXSW_AFK_BLOCK(0x14, mlxsw_sp_afk_element_info_mac_4),
  164. MLXSW_AFK_BLOCK(0x15, mlxsw_sp_afk_element_info_mac_5),
  165. MLXSW_AFK_BLOCK(0x38, mlxsw_sp_afk_element_info_ipv4_0),
  166. MLXSW_AFK_BLOCK(0x39, mlxsw_sp_afk_element_info_ipv4_1),
  167. MLXSW_AFK_BLOCK(0x3A, mlxsw_sp_afk_element_info_ipv4_2),
  168. MLXSW_AFK_BLOCK(0x40, mlxsw_sp_afk_element_info_ipv6_0),
  169. MLXSW_AFK_BLOCK(0x41, mlxsw_sp_afk_element_info_ipv6_1),
  170. MLXSW_AFK_BLOCK(0x42, mlxsw_sp_afk_element_info_ipv6_2),
  171. MLXSW_AFK_BLOCK(0x43, mlxsw_sp_afk_element_info_ipv6_3),
  172. MLXSW_AFK_BLOCK(0x44, mlxsw_sp_afk_element_info_ipv6_4),
  173. MLXSW_AFK_BLOCK(0x45, mlxsw_sp_afk_element_info_ipv6_5),
  174. MLXSW_AFK_BLOCK(0x90, mlxsw_sp_afk_element_info_l4_0),
  175. MLXSW_AFK_BLOCK(0x92, mlxsw_sp_afk_element_info_l4_2),
  176. };
  177. #define MLXSW_SP2_AFK_BITS_PER_BLOCK 36
  178. /* A block in Spectrum-2 is of the following form:
  179. *
  180. * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  181. * | | | | | | | | | | | | | | | | | | | | | | | | | | | | |35|34|33|32|
  182. * +-----------------------------------------------------------------------------------------------+
  183. * |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
  184. * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  185. */
  186. MLXSW_ITEM64(sp2_afk, block, value, 0x00, 0, MLXSW_SP2_AFK_BITS_PER_BLOCK);
  187. /* The key / mask block layout in Spectrum-2 is of the following form:
  188. *
  189. * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  190. * | | | | | | | | | | | | | | | | | block11_high |
  191. * +-----------------------------------------------------------------------------------------------+
  192. * | block11_low | block10_high |
  193. * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  194. * ...
  195. */
  196. struct mlxsw_sp2_afk_block_layout {
  197. unsigned short offset;
  198. struct mlxsw_item item;
  199. };
  200. #define MLXSW_SP2_AFK_BLOCK_LAYOUT(_block, _offset, _shift) \
  201. { \
  202. .offset = _offset, \
  203. { \
  204. .shift = _shift, \
  205. .size = {.bits = MLXSW_SP2_AFK_BITS_PER_BLOCK}, \
  206. .name = #_block, \
  207. } \
  208. } \
  209. static const struct mlxsw_sp2_afk_block_layout mlxsw_sp2_afk_blocks_layout[] = {
  210. MLXSW_SP2_AFK_BLOCK_LAYOUT(block0, 0x30, 0),
  211. MLXSW_SP2_AFK_BLOCK_LAYOUT(block1, 0x2C, 4),
  212. MLXSW_SP2_AFK_BLOCK_LAYOUT(block2, 0x28, 8),
  213. MLXSW_SP2_AFK_BLOCK_LAYOUT(block3, 0x24, 12),
  214. MLXSW_SP2_AFK_BLOCK_LAYOUT(block4, 0x20, 16),
  215. MLXSW_SP2_AFK_BLOCK_LAYOUT(block5, 0x1C, 20),
  216. MLXSW_SP2_AFK_BLOCK_LAYOUT(block6, 0x18, 24),
  217. MLXSW_SP2_AFK_BLOCK_LAYOUT(block7, 0x14, 28),
  218. MLXSW_SP2_AFK_BLOCK_LAYOUT(block8, 0x0C, 0),
  219. MLXSW_SP2_AFK_BLOCK_LAYOUT(block9, 0x08, 4),
  220. MLXSW_SP2_AFK_BLOCK_LAYOUT(block10, 0x04, 8),
  221. MLXSW_SP2_AFK_BLOCK_LAYOUT(block11, 0x00, 12),
  222. };
  223. static void mlxsw_sp2_afk_encode_block(char *block, int block_index,
  224. char *output)
  225. {
  226. u64 block_value = mlxsw_sp2_afk_block_value_get(block);
  227. const struct mlxsw_sp2_afk_block_layout *block_layout;
  228. if (WARN_ON(block_index < 0 ||
  229. block_index >= ARRAY_SIZE(mlxsw_sp2_afk_blocks_layout)))
  230. return;
  231. block_layout = &mlxsw_sp2_afk_blocks_layout[block_index];
  232. __mlxsw_item_set64(output + block_layout->offset,
  233. &block_layout->item, 0, block_value);
  234. }
  235. const struct mlxsw_afk_ops mlxsw_sp2_afk_ops = {
  236. .blocks = mlxsw_sp2_afk_blocks,
  237. .blocks_count = ARRAY_SIZE(mlxsw_sp2_afk_blocks),
  238. .encode_block = mlxsw_sp2_afk_encode_block,
  239. };