0001
0002
0003
0004 #include "ice_lib.h"
0005 #include "ice_switch.h"
0006
0007 #define ICE_ETH_DA_OFFSET 0
0008 #define ICE_ETH_ETHTYPE_OFFSET 12
0009 #define ICE_ETH_VLAN_TCI_OFFSET 14
0010 #define ICE_MAX_VLAN_ID 0xFFF
0011 #define ICE_IPV6_ETHER_ID 0x86DD
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #define DUMMY_ETH_HDR_LEN 16
0029 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0,
0030 0x2, 0, 0, 0, 0, 0,
0031 0x81, 0, 0, 0};
0032
0033 enum {
0034 ICE_PKT_OUTER_IPV6 = BIT(0),
0035 ICE_PKT_TUN_GTPC = BIT(1),
0036 ICE_PKT_TUN_GTPU = BIT(2),
0037 ICE_PKT_TUN_NVGRE = BIT(3),
0038 ICE_PKT_TUN_UDP = BIT(4),
0039 ICE_PKT_INNER_IPV6 = BIT(5),
0040 ICE_PKT_INNER_TCP = BIT(6),
0041 ICE_PKT_INNER_UDP = BIT(7),
0042 ICE_PKT_GTP_NOPAY = BIT(8),
0043 ICE_PKT_KMALLOC = BIT(9),
0044 ICE_PKT_PPPOE = BIT(10),
0045 };
0046
0047 struct ice_dummy_pkt_offsets {
0048 enum ice_protocol_type type;
0049 u16 offset;
0050 };
0051
0052 struct ice_dummy_pkt_profile {
0053 const struct ice_dummy_pkt_offsets *offsets;
0054 const u8 *pkt;
0055 u32 match;
0056 u16 pkt_len;
0057 u16 offsets_len;
0058 };
0059
0060 #define ICE_DECLARE_PKT_OFFSETS(type) \
0061 static const struct ice_dummy_pkt_offsets \
0062 ice_dummy_##type##_packet_offsets[]
0063
0064 #define ICE_DECLARE_PKT_TEMPLATE(type) \
0065 static const u8 ice_dummy_##type##_packet[]
0066
0067 #define ICE_PKT_PROFILE(type, m) { \
0068 .match = (m), \
0069 .pkt = ice_dummy_##type##_packet, \
0070 .pkt_len = sizeof(ice_dummy_##type##_packet), \
0071 .offsets = ice_dummy_##type##_packet_offsets, \
0072 .offsets_len = sizeof(ice_dummy_##type##_packet_offsets), \
0073 }
0074
0075 ICE_DECLARE_PKT_OFFSETS(vlan) = {
0076 { ICE_VLAN_OFOS, 12 },
0077 };
0078
0079 ICE_DECLARE_PKT_TEMPLATE(vlan) = {
0080 0x81, 0x00, 0x00, 0x00,
0081 };
0082
0083 ICE_DECLARE_PKT_OFFSETS(qinq) = {
0084 { ICE_VLAN_EX, 12 },
0085 { ICE_VLAN_IN, 16 },
0086 };
0087
0088 ICE_DECLARE_PKT_TEMPLATE(qinq) = {
0089 0x91, 0x00, 0x00, 0x00,
0090 0x81, 0x00, 0x00, 0x00,
0091 };
0092
0093 ICE_DECLARE_PKT_OFFSETS(gre_tcp) = {
0094 { ICE_MAC_OFOS, 0 },
0095 { ICE_ETYPE_OL, 12 },
0096 { ICE_IPV4_OFOS, 14 },
0097 { ICE_NVGRE, 34 },
0098 { ICE_MAC_IL, 42 },
0099 { ICE_ETYPE_IL, 54 },
0100 { ICE_IPV4_IL, 56 },
0101 { ICE_TCP_IL, 76 },
0102 { ICE_PROTOCOL_LAST, 0 },
0103 };
0104
0105 ICE_DECLARE_PKT_TEMPLATE(gre_tcp) = {
0106 0x00, 0x00, 0x00, 0x00,
0107 0x00, 0x00, 0x00, 0x00,
0108 0x00, 0x00, 0x00, 0x00,
0109
0110 0x08, 0x00,
0111
0112 0x45, 0x00, 0x00, 0x3E,
0113 0x00, 0x00, 0x00, 0x00,
0114 0x00, 0x2F, 0x00, 0x00,
0115 0x00, 0x00, 0x00, 0x00,
0116 0x00, 0x00, 0x00, 0x00,
0117
0118 0x80, 0x00, 0x65, 0x58,
0119 0x00, 0x00, 0x00, 0x00,
0120
0121 0x00, 0x00, 0x00, 0x00,
0122 0x00, 0x00, 0x00, 0x00,
0123 0x00, 0x00, 0x00, 0x00,
0124
0125 0x08, 0x00,
0126
0127 0x45, 0x00, 0x00, 0x14,
0128 0x00, 0x00, 0x00, 0x00,
0129 0x00, 0x06, 0x00, 0x00,
0130 0x00, 0x00, 0x00, 0x00,
0131 0x00, 0x00, 0x00, 0x00,
0132
0133 0x00, 0x00, 0x00, 0x00,
0134 0x00, 0x00, 0x00, 0x00,
0135 0x00, 0x00, 0x00, 0x00,
0136 0x50, 0x02, 0x20, 0x00,
0137 0x00, 0x00, 0x00, 0x00
0138 };
0139
0140 ICE_DECLARE_PKT_OFFSETS(gre_udp) = {
0141 { ICE_MAC_OFOS, 0 },
0142 { ICE_ETYPE_OL, 12 },
0143 { ICE_IPV4_OFOS, 14 },
0144 { ICE_NVGRE, 34 },
0145 { ICE_MAC_IL, 42 },
0146 { ICE_ETYPE_IL, 54 },
0147 { ICE_IPV4_IL, 56 },
0148 { ICE_UDP_ILOS, 76 },
0149 { ICE_PROTOCOL_LAST, 0 },
0150 };
0151
0152 ICE_DECLARE_PKT_TEMPLATE(gre_udp) = {
0153 0x00, 0x00, 0x00, 0x00,
0154 0x00, 0x00, 0x00, 0x00,
0155 0x00, 0x00, 0x00, 0x00,
0156
0157 0x08, 0x00,
0158
0159 0x45, 0x00, 0x00, 0x3E,
0160 0x00, 0x00, 0x00, 0x00,
0161 0x00, 0x2F, 0x00, 0x00,
0162 0x00, 0x00, 0x00, 0x00,
0163 0x00, 0x00, 0x00, 0x00,
0164
0165 0x80, 0x00, 0x65, 0x58,
0166 0x00, 0x00, 0x00, 0x00,
0167
0168 0x00, 0x00, 0x00, 0x00,
0169 0x00, 0x00, 0x00, 0x00,
0170 0x00, 0x00, 0x00, 0x00,
0171
0172 0x08, 0x00,
0173
0174 0x45, 0x00, 0x00, 0x14,
0175 0x00, 0x00, 0x00, 0x00,
0176 0x00, 0x11, 0x00, 0x00,
0177 0x00, 0x00, 0x00, 0x00,
0178 0x00, 0x00, 0x00, 0x00,
0179
0180 0x00, 0x00, 0x00, 0x00,
0181 0x00, 0x08, 0x00, 0x00,
0182 };
0183
0184 ICE_DECLARE_PKT_OFFSETS(udp_tun_tcp) = {
0185 { ICE_MAC_OFOS, 0 },
0186 { ICE_ETYPE_OL, 12 },
0187 { ICE_IPV4_OFOS, 14 },
0188 { ICE_UDP_OF, 34 },
0189 { ICE_VXLAN, 42 },
0190 { ICE_GENEVE, 42 },
0191 { ICE_VXLAN_GPE, 42 },
0192 { ICE_MAC_IL, 50 },
0193 { ICE_ETYPE_IL, 62 },
0194 { ICE_IPV4_IL, 64 },
0195 { ICE_TCP_IL, 84 },
0196 { ICE_PROTOCOL_LAST, 0 },
0197 };
0198
0199 ICE_DECLARE_PKT_TEMPLATE(udp_tun_tcp) = {
0200 0x00, 0x00, 0x00, 0x00,
0201 0x00, 0x00, 0x00, 0x00,
0202 0x00, 0x00, 0x00, 0x00,
0203
0204 0x08, 0x00,
0205
0206 0x45, 0x00, 0x00, 0x5a,
0207 0x00, 0x01, 0x00, 0x00,
0208 0x40, 0x11, 0x00, 0x00,
0209 0x00, 0x00, 0x00, 0x00,
0210 0x00, 0x00, 0x00, 0x00,
0211
0212 0x00, 0x00, 0x12, 0xb5,
0213 0x00, 0x46, 0x00, 0x00,
0214
0215 0x00, 0x00, 0x65, 0x58,
0216 0x00, 0x00, 0x00, 0x00,
0217
0218 0x00, 0x00, 0x00, 0x00,
0219 0x00, 0x00, 0x00, 0x00,
0220 0x00, 0x00, 0x00, 0x00,
0221
0222 0x08, 0x00,
0223
0224 0x45, 0x00, 0x00, 0x28,
0225 0x00, 0x01, 0x00, 0x00,
0226 0x40, 0x06, 0x00, 0x00,
0227 0x00, 0x00, 0x00, 0x00,
0228 0x00, 0x00, 0x00, 0x00,
0229
0230 0x00, 0x00, 0x00, 0x00,
0231 0x00, 0x00, 0x00, 0x00,
0232 0x00, 0x00, 0x00, 0x00,
0233 0x50, 0x02, 0x20, 0x00,
0234 0x00, 0x00, 0x00, 0x00
0235 };
0236
0237 ICE_DECLARE_PKT_OFFSETS(udp_tun_udp) = {
0238 { ICE_MAC_OFOS, 0 },
0239 { ICE_ETYPE_OL, 12 },
0240 { ICE_IPV4_OFOS, 14 },
0241 { ICE_UDP_OF, 34 },
0242 { ICE_VXLAN, 42 },
0243 { ICE_GENEVE, 42 },
0244 { ICE_VXLAN_GPE, 42 },
0245 { ICE_MAC_IL, 50 },
0246 { ICE_ETYPE_IL, 62 },
0247 { ICE_IPV4_IL, 64 },
0248 { ICE_UDP_ILOS, 84 },
0249 { ICE_PROTOCOL_LAST, 0 },
0250 };
0251
0252 ICE_DECLARE_PKT_TEMPLATE(udp_tun_udp) = {
0253 0x00, 0x00, 0x00, 0x00,
0254 0x00, 0x00, 0x00, 0x00,
0255 0x00, 0x00, 0x00, 0x00,
0256
0257 0x08, 0x00,
0258
0259 0x45, 0x00, 0x00, 0x4e,
0260 0x00, 0x01, 0x00, 0x00,
0261 0x00, 0x11, 0x00, 0x00,
0262 0x00, 0x00, 0x00, 0x00,
0263 0x00, 0x00, 0x00, 0x00,
0264
0265 0x00, 0x00, 0x12, 0xb5,
0266 0x00, 0x3a, 0x00, 0x00,
0267
0268 0x00, 0x00, 0x65, 0x58,
0269 0x00, 0x00, 0x00, 0x00,
0270
0271 0x00, 0x00, 0x00, 0x00,
0272 0x00, 0x00, 0x00, 0x00,
0273 0x00, 0x00, 0x00, 0x00,
0274
0275 0x08, 0x00,
0276
0277 0x45, 0x00, 0x00, 0x1c,
0278 0x00, 0x01, 0x00, 0x00,
0279 0x00, 0x11, 0x00, 0x00,
0280 0x00, 0x00, 0x00, 0x00,
0281 0x00, 0x00, 0x00, 0x00,
0282
0283 0x00, 0x00, 0x00, 0x00,
0284 0x00, 0x08, 0x00, 0x00,
0285 };
0286
0287 ICE_DECLARE_PKT_OFFSETS(gre_ipv6_tcp) = {
0288 { ICE_MAC_OFOS, 0 },
0289 { ICE_ETYPE_OL, 12 },
0290 { ICE_IPV4_OFOS, 14 },
0291 { ICE_NVGRE, 34 },
0292 { ICE_MAC_IL, 42 },
0293 { ICE_ETYPE_IL, 54 },
0294 { ICE_IPV6_IL, 56 },
0295 { ICE_TCP_IL, 96 },
0296 { ICE_PROTOCOL_LAST, 0 },
0297 };
0298
0299 ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_tcp) = {
0300 0x00, 0x00, 0x00, 0x00,
0301 0x00, 0x00, 0x00, 0x00,
0302 0x00, 0x00, 0x00, 0x00,
0303
0304 0x08, 0x00,
0305
0306 0x45, 0x00, 0x00, 0x66,
0307 0x00, 0x00, 0x00, 0x00,
0308 0x00, 0x2F, 0x00, 0x00,
0309 0x00, 0x00, 0x00, 0x00,
0310 0x00, 0x00, 0x00, 0x00,
0311
0312 0x80, 0x00, 0x65, 0x58,
0313 0x00, 0x00, 0x00, 0x00,
0314
0315 0x00, 0x00, 0x00, 0x00,
0316 0x00, 0x00, 0x00, 0x00,
0317 0x00, 0x00, 0x00, 0x00,
0318
0319 0x86, 0xdd,
0320
0321 0x60, 0x00, 0x00, 0x00,
0322 0x00, 0x08, 0x06, 0x40,
0323 0x00, 0x00, 0x00, 0x00,
0324 0x00, 0x00, 0x00, 0x00,
0325 0x00, 0x00, 0x00, 0x00,
0326 0x00, 0x00, 0x00, 0x00,
0327 0x00, 0x00, 0x00, 0x00,
0328 0x00, 0x00, 0x00, 0x00,
0329 0x00, 0x00, 0x00, 0x00,
0330 0x00, 0x00, 0x00, 0x00,
0331
0332 0x00, 0x00, 0x00, 0x00,
0333 0x00, 0x00, 0x00, 0x00,
0334 0x00, 0x00, 0x00, 0x00,
0335 0x50, 0x02, 0x20, 0x00,
0336 0x00, 0x00, 0x00, 0x00
0337 };
0338
0339 ICE_DECLARE_PKT_OFFSETS(gre_ipv6_udp) = {
0340 { ICE_MAC_OFOS, 0 },
0341 { ICE_ETYPE_OL, 12 },
0342 { ICE_IPV4_OFOS, 14 },
0343 { ICE_NVGRE, 34 },
0344 { ICE_MAC_IL, 42 },
0345 { ICE_ETYPE_IL, 54 },
0346 { ICE_IPV6_IL, 56 },
0347 { ICE_UDP_ILOS, 96 },
0348 { ICE_PROTOCOL_LAST, 0 },
0349 };
0350
0351 ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_udp) = {
0352 0x00, 0x00, 0x00, 0x00,
0353 0x00, 0x00, 0x00, 0x00,
0354 0x00, 0x00, 0x00, 0x00,
0355
0356 0x08, 0x00,
0357
0358 0x45, 0x00, 0x00, 0x5a,
0359 0x00, 0x00, 0x00, 0x00,
0360 0x00, 0x2F, 0x00, 0x00,
0361 0x00, 0x00, 0x00, 0x00,
0362 0x00, 0x00, 0x00, 0x00,
0363
0364 0x80, 0x00, 0x65, 0x58,
0365 0x00, 0x00, 0x00, 0x00,
0366
0367 0x00, 0x00, 0x00, 0x00,
0368 0x00, 0x00, 0x00, 0x00,
0369 0x00, 0x00, 0x00, 0x00,
0370
0371 0x86, 0xdd,
0372
0373 0x60, 0x00, 0x00, 0x00,
0374 0x00, 0x08, 0x11, 0x40,
0375 0x00, 0x00, 0x00, 0x00,
0376 0x00, 0x00, 0x00, 0x00,
0377 0x00, 0x00, 0x00, 0x00,
0378 0x00, 0x00, 0x00, 0x00,
0379 0x00, 0x00, 0x00, 0x00,
0380 0x00, 0x00, 0x00, 0x00,
0381 0x00, 0x00, 0x00, 0x00,
0382 0x00, 0x00, 0x00, 0x00,
0383
0384 0x00, 0x00, 0x00, 0x00,
0385 0x00, 0x08, 0x00, 0x00,
0386 };
0387
0388 ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_tcp) = {
0389 { ICE_MAC_OFOS, 0 },
0390 { ICE_ETYPE_OL, 12 },
0391 { ICE_IPV4_OFOS, 14 },
0392 { ICE_UDP_OF, 34 },
0393 { ICE_VXLAN, 42 },
0394 { ICE_GENEVE, 42 },
0395 { ICE_VXLAN_GPE, 42 },
0396 { ICE_MAC_IL, 50 },
0397 { ICE_ETYPE_IL, 62 },
0398 { ICE_IPV6_IL, 64 },
0399 { ICE_TCP_IL, 104 },
0400 { ICE_PROTOCOL_LAST, 0 },
0401 };
0402
0403 ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_tcp) = {
0404 0x00, 0x00, 0x00, 0x00,
0405 0x00, 0x00, 0x00, 0x00,
0406 0x00, 0x00, 0x00, 0x00,
0407
0408 0x08, 0x00,
0409
0410 0x45, 0x00, 0x00, 0x6e,
0411 0x00, 0x01, 0x00, 0x00,
0412 0x40, 0x11, 0x00, 0x00,
0413 0x00, 0x00, 0x00, 0x00,
0414 0x00, 0x00, 0x00, 0x00,
0415
0416 0x00, 0x00, 0x12, 0xb5,
0417 0x00, 0x5a, 0x00, 0x00,
0418
0419 0x00, 0x00, 0x65, 0x58,
0420 0x00, 0x00, 0x00, 0x00,
0421
0422 0x00, 0x00, 0x00, 0x00,
0423 0x00, 0x00, 0x00, 0x00,
0424 0x00, 0x00, 0x00, 0x00,
0425
0426 0x86, 0xdd,
0427
0428 0x60, 0x00, 0x00, 0x00,
0429 0x00, 0x08, 0x06, 0x40,
0430 0x00, 0x00, 0x00, 0x00,
0431 0x00, 0x00, 0x00, 0x00,
0432 0x00, 0x00, 0x00, 0x00,
0433 0x00, 0x00, 0x00, 0x00,
0434 0x00, 0x00, 0x00, 0x00,
0435 0x00, 0x00, 0x00, 0x00,
0436 0x00, 0x00, 0x00, 0x00,
0437 0x00, 0x00, 0x00, 0x00,
0438
0439 0x00, 0x00, 0x00, 0x00,
0440 0x00, 0x00, 0x00, 0x00,
0441 0x00, 0x00, 0x00, 0x00,
0442 0x50, 0x02, 0x20, 0x00,
0443 0x00, 0x00, 0x00, 0x00
0444 };
0445
0446 ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_udp) = {
0447 { ICE_MAC_OFOS, 0 },
0448 { ICE_ETYPE_OL, 12 },
0449 { ICE_IPV4_OFOS, 14 },
0450 { ICE_UDP_OF, 34 },
0451 { ICE_VXLAN, 42 },
0452 { ICE_GENEVE, 42 },
0453 { ICE_VXLAN_GPE, 42 },
0454 { ICE_MAC_IL, 50 },
0455 { ICE_ETYPE_IL, 62 },
0456 { ICE_IPV6_IL, 64 },
0457 { ICE_UDP_ILOS, 104 },
0458 { ICE_PROTOCOL_LAST, 0 },
0459 };
0460
0461 ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_udp) = {
0462 0x00, 0x00, 0x00, 0x00,
0463 0x00, 0x00, 0x00, 0x00,
0464 0x00, 0x00, 0x00, 0x00,
0465
0466 0x08, 0x00,
0467
0468 0x45, 0x00, 0x00, 0x62,
0469 0x00, 0x01, 0x00, 0x00,
0470 0x00, 0x11, 0x00, 0x00,
0471 0x00, 0x00, 0x00, 0x00,
0472 0x00, 0x00, 0x00, 0x00,
0473
0474 0x00, 0x00, 0x12, 0xb5,
0475 0x00, 0x4e, 0x00, 0x00,
0476
0477 0x00, 0x00, 0x65, 0x58,
0478 0x00, 0x00, 0x00, 0x00,
0479
0480 0x00, 0x00, 0x00, 0x00,
0481 0x00, 0x00, 0x00, 0x00,
0482 0x00, 0x00, 0x00, 0x00,
0483
0484 0x86, 0xdd,
0485
0486 0x60, 0x00, 0x00, 0x00,
0487 0x00, 0x08, 0x11, 0x40,
0488 0x00, 0x00, 0x00, 0x00,
0489 0x00, 0x00, 0x00, 0x00,
0490 0x00, 0x00, 0x00, 0x00,
0491 0x00, 0x00, 0x00, 0x00,
0492 0x00, 0x00, 0x00, 0x00,
0493 0x00, 0x00, 0x00, 0x00,
0494 0x00, 0x00, 0x00, 0x00,
0495 0x00, 0x00, 0x00, 0x00,
0496
0497 0x00, 0x00, 0x00, 0x00,
0498 0x00, 0x08, 0x00, 0x00,
0499 };
0500
0501
0502 ICE_DECLARE_PKT_OFFSETS(udp) = {
0503 { ICE_MAC_OFOS, 0 },
0504 { ICE_ETYPE_OL, 12 },
0505 { ICE_IPV4_OFOS, 14 },
0506 { ICE_UDP_ILOS, 34 },
0507 { ICE_PROTOCOL_LAST, 0 },
0508 };
0509
0510
0511 ICE_DECLARE_PKT_TEMPLATE(udp) = {
0512 0x00, 0x00, 0x00, 0x00,
0513 0x00, 0x00, 0x00, 0x00,
0514 0x00, 0x00, 0x00, 0x00,
0515
0516 0x08, 0x00,
0517
0518 0x45, 0x00, 0x00, 0x1c,
0519 0x00, 0x01, 0x00, 0x00,
0520 0x00, 0x11, 0x00, 0x00,
0521 0x00, 0x00, 0x00, 0x00,
0522 0x00, 0x00, 0x00, 0x00,
0523
0524 0x00, 0x00, 0x00, 0x00,
0525 0x00, 0x08, 0x00, 0x00,
0526
0527 0x00, 0x00,
0528 };
0529
0530
0531 ICE_DECLARE_PKT_OFFSETS(tcp) = {
0532 { ICE_MAC_OFOS, 0 },
0533 { ICE_ETYPE_OL, 12 },
0534 { ICE_IPV4_OFOS, 14 },
0535 { ICE_TCP_IL, 34 },
0536 { ICE_PROTOCOL_LAST, 0 },
0537 };
0538
0539
0540 ICE_DECLARE_PKT_TEMPLATE(tcp) = {
0541 0x00, 0x00, 0x00, 0x00,
0542 0x00, 0x00, 0x00, 0x00,
0543 0x00, 0x00, 0x00, 0x00,
0544
0545 0x08, 0x00,
0546
0547 0x45, 0x00, 0x00, 0x28,
0548 0x00, 0x01, 0x00, 0x00,
0549 0x00, 0x06, 0x00, 0x00,
0550 0x00, 0x00, 0x00, 0x00,
0551 0x00, 0x00, 0x00, 0x00,
0552
0553 0x00, 0x00, 0x00, 0x00,
0554 0x00, 0x00, 0x00, 0x00,
0555 0x00, 0x00, 0x00, 0x00,
0556 0x50, 0x00, 0x00, 0x00,
0557 0x00, 0x00, 0x00, 0x00,
0558
0559 0x00, 0x00,
0560 };
0561
0562 ICE_DECLARE_PKT_OFFSETS(tcp_ipv6) = {
0563 { ICE_MAC_OFOS, 0 },
0564 { ICE_ETYPE_OL, 12 },
0565 { ICE_IPV6_OFOS, 14 },
0566 { ICE_TCP_IL, 54 },
0567 { ICE_PROTOCOL_LAST, 0 },
0568 };
0569
0570 ICE_DECLARE_PKT_TEMPLATE(tcp_ipv6) = {
0571 0x00, 0x00, 0x00, 0x00,
0572 0x00, 0x00, 0x00, 0x00,
0573 0x00, 0x00, 0x00, 0x00,
0574
0575 0x86, 0xDD,
0576
0577 0x60, 0x00, 0x00, 0x00,
0578 0x00, 0x14, 0x06, 0x00,
0579 0x00, 0x00, 0x00, 0x00,
0580 0x00, 0x00, 0x00, 0x00,
0581 0x00, 0x00, 0x00, 0x00,
0582 0x00, 0x00, 0x00, 0x00,
0583 0x00, 0x00, 0x00, 0x00,
0584 0x00, 0x00, 0x00, 0x00,
0585 0x00, 0x00, 0x00, 0x00,
0586 0x00, 0x00, 0x00, 0x00,
0587
0588 0x00, 0x00, 0x00, 0x00,
0589 0x00, 0x00, 0x00, 0x00,
0590 0x00, 0x00, 0x00, 0x00,
0591 0x50, 0x00, 0x00, 0x00,
0592 0x00, 0x00, 0x00, 0x00,
0593
0594 0x00, 0x00,
0595 };
0596
0597
0598 ICE_DECLARE_PKT_OFFSETS(udp_ipv6) = {
0599 { ICE_MAC_OFOS, 0 },
0600 { ICE_ETYPE_OL, 12 },
0601 { ICE_IPV6_OFOS, 14 },
0602 { ICE_UDP_ILOS, 54 },
0603 { ICE_PROTOCOL_LAST, 0 },
0604 };
0605
0606
0607 ICE_DECLARE_PKT_TEMPLATE(udp_ipv6) = {
0608 0x00, 0x00, 0x00, 0x00,
0609 0x00, 0x00, 0x00, 0x00,
0610 0x00, 0x00, 0x00, 0x00,
0611
0612 0x86, 0xDD,
0613
0614 0x60, 0x00, 0x00, 0x00,
0615 0x00, 0x10, 0x11, 0x00,
0616 0x00, 0x00, 0x00, 0x00,
0617 0x00, 0x00, 0x00, 0x00,
0618 0x00, 0x00, 0x00, 0x00,
0619 0x00, 0x00, 0x00, 0x00,
0620 0x00, 0x00, 0x00, 0x00,
0621 0x00, 0x00, 0x00, 0x00,
0622 0x00, 0x00, 0x00, 0x00,
0623 0x00, 0x00, 0x00, 0x00,
0624
0625 0x00, 0x00, 0x00, 0x00,
0626 0x00, 0x10, 0x00, 0x00,
0627
0628 0x00, 0x00, 0x00, 0x00,
0629 0x00, 0x00, 0x00, 0x00,
0630
0631 0x00, 0x00,
0632 };
0633
0634
0635 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_tcp) = {
0636 { ICE_MAC_OFOS, 0 },
0637 { ICE_IPV4_OFOS, 14 },
0638 { ICE_UDP_OF, 34 },
0639 { ICE_GTP, 42 },
0640 { ICE_IPV4_IL, 62 },
0641 { ICE_TCP_IL, 82 },
0642 { ICE_PROTOCOL_LAST, 0 },
0643 };
0644
0645 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_tcp) = {
0646 0x00, 0x00, 0x00, 0x00,
0647 0x00, 0x00, 0x00, 0x00,
0648 0x00, 0x00, 0x00, 0x00,
0649 0x08, 0x00,
0650
0651 0x45, 0x00, 0x00, 0x58,
0652 0x00, 0x00, 0x00, 0x00,
0653 0x00, 0x11, 0x00, 0x00,
0654 0x00, 0x00, 0x00, 0x00,
0655 0x00, 0x00, 0x00, 0x00,
0656
0657 0x00, 0x00, 0x08, 0x68,
0658 0x00, 0x44, 0x00, 0x00,
0659
0660 0x34, 0xff, 0x00, 0x34,
0661 0x00, 0x00, 0x00, 0x00,
0662 0x00, 0x00, 0x00, 0x85,
0663
0664 0x02, 0x00, 0x00, 0x00,
0665 0x00, 0x00, 0x00, 0x00,
0666
0667 0x45, 0x00, 0x00, 0x28,
0668 0x00, 0x00, 0x00, 0x00,
0669 0x00, 0x06, 0x00, 0x00,
0670 0x00, 0x00, 0x00, 0x00,
0671 0x00, 0x00, 0x00, 0x00,
0672
0673 0x00, 0x00, 0x00, 0x00,
0674 0x00, 0x00, 0x00, 0x00,
0675 0x00, 0x00, 0x00, 0x00,
0676 0x50, 0x00, 0x00, 0x00,
0677 0x00, 0x00, 0x00, 0x00,
0678
0679 0x00, 0x00,
0680 };
0681
0682
0683 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_udp) = {
0684 { ICE_MAC_OFOS, 0 },
0685 { ICE_IPV4_OFOS, 14 },
0686 { ICE_UDP_OF, 34 },
0687 { ICE_GTP, 42 },
0688 { ICE_IPV4_IL, 62 },
0689 { ICE_UDP_ILOS, 82 },
0690 { ICE_PROTOCOL_LAST, 0 },
0691 };
0692
0693 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_udp) = {
0694 0x00, 0x00, 0x00, 0x00,
0695 0x00, 0x00, 0x00, 0x00,
0696 0x00, 0x00, 0x00, 0x00,
0697 0x08, 0x00,
0698
0699 0x45, 0x00, 0x00, 0x4c,
0700 0x00, 0x00, 0x00, 0x00,
0701 0x00, 0x11, 0x00, 0x00,
0702 0x00, 0x00, 0x00, 0x00,
0703 0x00, 0x00, 0x00, 0x00,
0704
0705 0x00, 0x00, 0x08, 0x68,
0706 0x00, 0x38, 0x00, 0x00,
0707
0708 0x34, 0xff, 0x00, 0x28,
0709 0x00, 0x00, 0x00, 0x00,
0710 0x00, 0x00, 0x00, 0x85,
0711
0712 0x02, 0x00, 0x00, 0x00,
0713 0x00, 0x00, 0x00, 0x00,
0714
0715 0x45, 0x00, 0x00, 0x1c,
0716 0x00, 0x00, 0x00, 0x00,
0717 0x00, 0x11, 0x00, 0x00,
0718 0x00, 0x00, 0x00, 0x00,
0719 0x00, 0x00, 0x00, 0x00,
0720
0721 0x00, 0x00, 0x00, 0x00,
0722 0x00, 0x08, 0x00, 0x00,
0723
0724 0x00, 0x00,
0725 };
0726
0727
0728 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_tcp) = {
0729 { ICE_MAC_OFOS, 0 },
0730 { ICE_IPV4_OFOS, 14 },
0731 { ICE_UDP_OF, 34 },
0732 { ICE_GTP, 42 },
0733 { ICE_IPV6_IL, 62 },
0734 { ICE_TCP_IL, 102 },
0735 { ICE_PROTOCOL_LAST, 0 },
0736 };
0737
0738 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_tcp) = {
0739 0x00, 0x00, 0x00, 0x00,
0740 0x00, 0x00, 0x00, 0x00,
0741 0x00, 0x00, 0x00, 0x00,
0742 0x08, 0x00,
0743
0744 0x45, 0x00, 0x00, 0x6c,
0745 0x00, 0x00, 0x00, 0x00,
0746 0x00, 0x11, 0x00, 0x00,
0747 0x00, 0x00, 0x00, 0x00,
0748 0x00, 0x00, 0x00, 0x00,
0749
0750 0x00, 0x00, 0x08, 0x68,
0751 0x00, 0x58, 0x00, 0x00,
0752
0753 0x34, 0xff, 0x00, 0x48,
0754 0x00, 0x00, 0x00, 0x00,
0755 0x00, 0x00, 0x00, 0x85,
0756
0757 0x02, 0x00, 0x00, 0x00,
0758 0x00, 0x00, 0x00, 0x00,
0759
0760 0x60, 0x00, 0x00, 0x00,
0761 0x00, 0x14, 0x06, 0x00,
0762 0x00, 0x00, 0x00, 0x00,
0763 0x00, 0x00, 0x00, 0x00,
0764 0x00, 0x00, 0x00, 0x00,
0765 0x00, 0x00, 0x00, 0x00,
0766 0x00, 0x00, 0x00, 0x00,
0767 0x00, 0x00, 0x00, 0x00,
0768 0x00, 0x00, 0x00, 0x00,
0769 0x00, 0x00, 0x00, 0x00,
0770
0771 0x00, 0x00, 0x00, 0x00,
0772 0x00, 0x00, 0x00, 0x00,
0773 0x00, 0x00, 0x00, 0x00,
0774 0x50, 0x00, 0x00, 0x00,
0775 0x00, 0x00, 0x00, 0x00,
0776
0777 0x00, 0x00,
0778 };
0779
0780 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_udp) = {
0781 { ICE_MAC_OFOS, 0 },
0782 { ICE_IPV4_OFOS, 14 },
0783 { ICE_UDP_OF, 34 },
0784 { ICE_GTP, 42 },
0785 { ICE_IPV6_IL, 62 },
0786 { ICE_UDP_ILOS, 102 },
0787 { ICE_PROTOCOL_LAST, 0 },
0788 };
0789
0790 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_udp) = {
0791 0x00, 0x00, 0x00, 0x00,
0792 0x00, 0x00, 0x00, 0x00,
0793 0x00, 0x00, 0x00, 0x00,
0794 0x08, 0x00,
0795
0796 0x45, 0x00, 0x00, 0x60,
0797 0x00, 0x00, 0x00, 0x00,
0798 0x00, 0x11, 0x00, 0x00,
0799 0x00, 0x00, 0x00, 0x00,
0800 0x00, 0x00, 0x00, 0x00,
0801
0802 0x00, 0x00, 0x08, 0x68,
0803 0x00, 0x4c, 0x00, 0x00,
0804
0805 0x34, 0xff, 0x00, 0x3c,
0806 0x00, 0x00, 0x00, 0x00,
0807 0x00, 0x00, 0x00, 0x85,
0808
0809 0x02, 0x00, 0x00, 0x00,
0810 0x00, 0x00, 0x00, 0x00,
0811
0812 0x60, 0x00, 0x00, 0x00,
0813 0x00, 0x08, 0x11, 0x00,
0814 0x00, 0x00, 0x00, 0x00,
0815 0x00, 0x00, 0x00, 0x00,
0816 0x00, 0x00, 0x00, 0x00,
0817 0x00, 0x00, 0x00, 0x00,
0818 0x00, 0x00, 0x00, 0x00,
0819 0x00, 0x00, 0x00, 0x00,
0820 0x00, 0x00, 0x00, 0x00,
0821 0x00, 0x00, 0x00, 0x00,
0822
0823 0x00, 0x00, 0x00, 0x00,
0824 0x00, 0x08, 0x00, 0x00,
0825
0826 0x00, 0x00,
0827 };
0828
0829 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_tcp) = {
0830 { ICE_MAC_OFOS, 0 },
0831 { ICE_IPV6_OFOS, 14 },
0832 { ICE_UDP_OF, 54 },
0833 { ICE_GTP, 62 },
0834 { ICE_IPV4_IL, 82 },
0835 { ICE_TCP_IL, 102 },
0836 { ICE_PROTOCOL_LAST, 0 },
0837 };
0838
0839 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_tcp) = {
0840 0x00, 0x00, 0x00, 0x00,
0841 0x00, 0x00, 0x00, 0x00,
0842 0x00, 0x00, 0x00, 0x00,
0843 0x86, 0xdd,
0844
0845 0x60, 0x00, 0x00, 0x00,
0846 0x00, 0x44, 0x11, 0x00,
0847 0x00, 0x00, 0x00, 0x00,
0848 0x00, 0x00, 0x00, 0x00,
0849 0x00, 0x00, 0x00, 0x00,
0850 0x00, 0x00, 0x00, 0x00,
0851 0x00, 0x00, 0x00, 0x00,
0852 0x00, 0x00, 0x00, 0x00,
0853 0x00, 0x00, 0x00, 0x00,
0854 0x00, 0x00, 0x00, 0x00,
0855
0856 0x00, 0x00, 0x08, 0x68,
0857 0x00, 0x44, 0x00, 0x00,
0858
0859 0x34, 0xff, 0x00, 0x34,
0860 0x00, 0x00, 0x00, 0x00,
0861 0x00, 0x00, 0x00, 0x85,
0862
0863 0x02, 0x00, 0x00, 0x00,
0864 0x00, 0x00, 0x00, 0x00,
0865
0866 0x45, 0x00, 0x00, 0x28,
0867 0x00, 0x00, 0x00, 0x00,
0868 0x00, 0x06, 0x00, 0x00,
0869 0x00, 0x00, 0x00, 0x00,
0870 0x00, 0x00, 0x00, 0x00,
0871
0872 0x00, 0x00, 0x00, 0x00,
0873 0x00, 0x00, 0x00, 0x00,
0874 0x00, 0x00, 0x00, 0x00,
0875 0x50, 0x00, 0x00, 0x00,
0876 0x00, 0x00, 0x00, 0x00,
0877
0878 0x00, 0x00,
0879 };
0880
0881 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_udp) = {
0882 { ICE_MAC_OFOS, 0 },
0883 { ICE_IPV6_OFOS, 14 },
0884 { ICE_UDP_OF, 54 },
0885 { ICE_GTP, 62 },
0886 { ICE_IPV4_IL, 82 },
0887 { ICE_UDP_ILOS, 102 },
0888 { ICE_PROTOCOL_LAST, 0 },
0889 };
0890
0891 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_udp) = {
0892 0x00, 0x00, 0x00, 0x00,
0893 0x00, 0x00, 0x00, 0x00,
0894 0x00, 0x00, 0x00, 0x00,
0895 0x86, 0xdd,
0896
0897 0x60, 0x00, 0x00, 0x00,
0898 0x00, 0x38, 0x11, 0x00,
0899 0x00, 0x00, 0x00, 0x00,
0900 0x00, 0x00, 0x00, 0x00,
0901 0x00, 0x00, 0x00, 0x00,
0902 0x00, 0x00, 0x00, 0x00,
0903 0x00, 0x00, 0x00, 0x00,
0904 0x00, 0x00, 0x00, 0x00,
0905 0x00, 0x00, 0x00, 0x00,
0906 0x00, 0x00, 0x00, 0x00,
0907
0908 0x00, 0x00, 0x08, 0x68,
0909 0x00, 0x38, 0x00, 0x00,
0910
0911 0x34, 0xff, 0x00, 0x28,
0912 0x00, 0x00, 0x00, 0x00,
0913 0x00, 0x00, 0x00, 0x85,
0914
0915 0x02, 0x00, 0x00, 0x00,
0916 0x00, 0x00, 0x00, 0x00,
0917
0918 0x45, 0x00, 0x00, 0x1c,
0919 0x00, 0x00, 0x00, 0x00,
0920 0x00, 0x11, 0x00, 0x00,
0921 0x00, 0x00, 0x00, 0x00,
0922 0x00, 0x00, 0x00, 0x00,
0923
0924 0x00, 0x00, 0x00, 0x00,
0925 0x00, 0x08, 0x00, 0x00,
0926
0927 0x00, 0x00,
0928 };
0929
0930 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_tcp) = {
0931 { ICE_MAC_OFOS, 0 },
0932 { ICE_IPV6_OFOS, 14 },
0933 { ICE_UDP_OF, 54 },
0934 { ICE_GTP, 62 },
0935 { ICE_IPV6_IL, 82 },
0936 { ICE_TCP_IL, 122 },
0937 { ICE_PROTOCOL_LAST, 0 },
0938 };
0939
0940 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_tcp) = {
0941 0x00, 0x00, 0x00, 0x00,
0942 0x00, 0x00, 0x00, 0x00,
0943 0x00, 0x00, 0x00, 0x00,
0944 0x86, 0xdd,
0945
0946 0x60, 0x00, 0x00, 0x00,
0947 0x00, 0x58, 0x11, 0x00,
0948 0x00, 0x00, 0x00, 0x00,
0949 0x00, 0x00, 0x00, 0x00,
0950 0x00, 0x00, 0x00, 0x00,
0951 0x00, 0x00, 0x00, 0x00,
0952 0x00, 0x00, 0x00, 0x00,
0953 0x00, 0x00, 0x00, 0x00,
0954 0x00, 0x00, 0x00, 0x00,
0955 0x00, 0x00, 0x00, 0x00,
0956
0957 0x00, 0x00, 0x08, 0x68,
0958 0x00, 0x58, 0x00, 0x00,
0959
0960 0x34, 0xff, 0x00, 0x48,
0961 0x00, 0x00, 0x00, 0x00,
0962 0x00, 0x00, 0x00, 0x85,
0963
0964 0x02, 0x00, 0x00, 0x00,
0965 0x00, 0x00, 0x00, 0x00,
0966
0967 0x60, 0x00, 0x00, 0x00,
0968 0x00, 0x14, 0x06, 0x00,
0969 0x00, 0x00, 0x00, 0x00,
0970 0x00, 0x00, 0x00, 0x00,
0971 0x00, 0x00, 0x00, 0x00,
0972 0x00, 0x00, 0x00, 0x00,
0973 0x00, 0x00, 0x00, 0x00,
0974 0x00, 0x00, 0x00, 0x00,
0975 0x00, 0x00, 0x00, 0x00,
0976 0x00, 0x00, 0x00, 0x00,
0977
0978 0x00, 0x00, 0x00, 0x00,
0979 0x00, 0x00, 0x00, 0x00,
0980 0x00, 0x00, 0x00, 0x00,
0981 0x50, 0x00, 0x00, 0x00,
0982 0x00, 0x00, 0x00, 0x00,
0983
0984 0x00, 0x00,
0985 };
0986
0987 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_udp) = {
0988 { ICE_MAC_OFOS, 0 },
0989 { ICE_IPV6_OFOS, 14 },
0990 { ICE_UDP_OF, 54 },
0991 { ICE_GTP, 62 },
0992 { ICE_IPV6_IL, 82 },
0993 { ICE_UDP_ILOS, 122 },
0994 { ICE_PROTOCOL_LAST, 0 },
0995 };
0996
0997 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_udp) = {
0998 0x00, 0x00, 0x00, 0x00,
0999 0x00, 0x00, 0x00, 0x00,
1000 0x00, 0x00, 0x00, 0x00,
1001 0x86, 0xdd,
1002
1003 0x60, 0x00, 0x00, 0x00,
1004 0x00, 0x4c, 0x11, 0x00,
1005 0x00, 0x00, 0x00, 0x00,
1006 0x00, 0x00, 0x00, 0x00,
1007 0x00, 0x00, 0x00, 0x00,
1008 0x00, 0x00, 0x00, 0x00,
1009 0x00, 0x00, 0x00, 0x00,
1010 0x00, 0x00, 0x00, 0x00,
1011 0x00, 0x00, 0x00, 0x00,
1012 0x00, 0x00, 0x00, 0x00,
1013
1014 0x00, 0x00, 0x08, 0x68,
1015 0x00, 0x4c, 0x00, 0x00,
1016
1017 0x34, 0xff, 0x00, 0x3c,
1018 0x00, 0x00, 0x00, 0x00,
1019 0x00, 0x00, 0x00, 0x85,
1020
1021 0x02, 0x00, 0x00, 0x00,
1022 0x00, 0x00, 0x00, 0x00,
1023
1024 0x60, 0x00, 0x00, 0x00,
1025 0x00, 0x08, 0x11, 0x00,
1026 0x00, 0x00, 0x00, 0x00,
1027 0x00, 0x00, 0x00, 0x00,
1028 0x00, 0x00, 0x00, 0x00,
1029 0x00, 0x00, 0x00, 0x00,
1030 0x00, 0x00, 0x00, 0x00,
1031 0x00, 0x00, 0x00, 0x00,
1032 0x00, 0x00, 0x00, 0x00,
1033 0x00, 0x00, 0x00, 0x00,
1034
1035 0x00, 0x00, 0x00, 0x00,
1036 0x00, 0x08, 0x00, 0x00,
1037
1038 0x00, 0x00,
1039 };
1040
1041 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4) = {
1042 { ICE_MAC_OFOS, 0 },
1043 { ICE_IPV4_OFOS, 14 },
1044 { ICE_UDP_OF, 34 },
1045 { ICE_GTP_NO_PAY, 42 },
1046 { ICE_PROTOCOL_LAST, 0 },
1047 };
1048
1049 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4) = {
1050 0x00, 0x00, 0x00, 0x00,
1051 0x00, 0x00, 0x00, 0x00,
1052 0x00, 0x00, 0x00, 0x00,
1053 0x08, 0x00,
1054
1055 0x45, 0x00, 0x00, 0x44,
1056 0x00, 0x00, 0x40, 0x00,
1057 0x40, 0x11, 0x00, 0x00,
1058 0x00, 0x00, 0x00, 0x00,
1059 0x00, 0x00, 0x00, 0x00,
1060
1061 0x08, 0x68, 0x08, 0x68,
1062 0x00, 0x00, 0x00, 0x00,
1063
1064 0x34, 0xff, 0x00, 0x28,
1065 0x00, 0x00, 0x00, 0x00,
1066 0x00, 0x00, 0x00, 0x85,
1067
1068 0x02, 0x00, 0x00, 0x00,
1069 0x00, 0x00, 0x00, 0x00,
1070
1071 0x45, 0x00, 0x00, 0x14,
1072 0x00, 0x00, 0x40, 0x00,
1073 0x40, 0x00, 0x00, 0x00,
1074 0x00, 0x00, 0x00, 0x00,
1075 0x00, 0x00, 0x00, 0x00,
1076 0x00, 0x00,
1077 };
1078
1079 ICE_DECLARE_PKT_OFFSETS(ipv6_gtp) = {
1080 { ICE_MAC_OFOS, 0 },
1081 { ICE_IPV6_OFOS, 14 },
1082 { ICE_UDP_OF, 54 },
1083 { ICE_GTP_NO_PAY, 62 },
1084 { ICE_PROTOCOL_LAST, 0 },
1085 };
1086
1087 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = {
1088 0x00, 0x00, 0x00, 0x00,
1089 0x00, 0x00, 0x00, 0x00,
1090 0x00, 0x00, 0x00, 0x00,
1091 0x86, 0xdd,
1092
1093 0x60, 0x00, 0x00, 0x00,
1094 0x00, 0x6c, 0x11, 0x00,
1095 0x00, 0x00, 0x00, 0x00,
1096 0x00, 0x00, 0x00, 0x00,
1097 0x00, 0x00, 0x00, 0x00,
1098 0x00, 0x00, 0x00, 0x00,
1099 0x00, 0x00, 0x00, 0x00,
1100 0x00, 0x00, 0x00, 0x00,
1101 0x00, 0x00, 0x00, 0x00,
1102 0x00, 0x00, 0x00, 0x00,
1103
1104 0x08, 0x68, 0x08, 0x68,
1105 0x00, 0x00, 0x00, 0x00,
1106
1107 0x30, 0x00, 0x00, 0x28,
1108 0x00, 0x00, 0x00, 0x00,
1109
1110 0x00, 0x00,
1111 };
1112
1113 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = {
1114 { ICE_MAC_OFOS, 0 },
1115 { ICE_ETYPE_OL, 12 },
1116 { ICE_PPPOE, 14 },
1117 { ICE_IPV4_OFOS, 22 },
1118 { ICE_TCP_IL, 42 },
1119 { ICE_PROTOCOL_LAST, 0 },
1120 };
1121
1122 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = {
1123 0x00, 0x00, 0x00, 0x00,
1124 0x00, 0x00, 0x00, 0x00,
1125 0x00, 0x00, 0x00, 0x00,
1126
1127 0x88, 0x64,
1128
1129 0x11, 0x00, 0x00, 0x00,
1130 0x00, 0x16,
1131
1132 0x00, 0x21,
1133
1134 0x45, 0x00, 0x00, 0x28,
1135 0x00, 0x01, 0x00, 0x00,
1136 0x00, 0x06, 0x00, 0x00,
1137 0x00, 0x00, 0x00, 0x00,
1138 0x00, 0x00, 0x00, 0x00,
1139
1140 0x00, 0x00, 0x00, 0x00,
1141 0x00, 0x00, 0x00, 0x00,
1142 0x00, 0x00, 0x00, 0x00,
1143 0x50, 0x00, 0x00, 0x00,
1144 0x00, 0x00, 0x00, 0x00,
1145
1146 0x00, 0x00,
1147 };
1148
1149 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = {
1150 { ICE_MAC_OFOS, 0 },
1151 { ICE_ETYPE_OL, 12 },
1152 { ICE_PPPOE, 14 },
1153 { ICE_IPV4_OFOS, 22 },
1154 { ICE_UDP_ILOS, 42 },
1155 { ICE_PROTOCOL_LAST, 0 },
1156 };
1157
1158 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = {
1159 0x00, 0x00, 0x00, 0x00,
1160 0x00, 0x00, 0x00, 0x00,
1161 0x00, 0x00, 0x00, 0x00,
1162
1163 0x88, 0x64,
1164
1165 0x11, 0x00, 0x00, 0x00,
1166 0x00, 0x16,
1167
1168 0x00, 0x21,
1169
1170 0x45, 0x00, 0x00, 0x1c,
1171 0x00, 0x01, 0x00, 0x00,
1172 0x00, 0x11, 0x00, 0x00,
1173 0x00, 0x00, 0x00, 0x00,
1174 0x00, 0x00, 0x00, 0x00,
1175
1176 0x00, 0x00, 0x00, 0x00,
1177 0x00, 0x08, 0x00, 0x00,
1178
1179 0x00, 0x00,
1180 };
1181
1182 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = {
1183 { ICE_MAC_OFOS, 0 },
1184 { ICE_ETYPE_OL, 12 },
1185 { ICE_PPPOE, 14 },
1186 { ICE_IPV6_OFOS, 22 },
1187 { ICE_TCP_IL, 62 },
1188 { ICE_PROTOCOL_LAST, 0 },
1189 };
1190
1191 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = {
1192 0x00, 0x00, 0x00, 0x00,
1193 0x00, 0x00, 0x00, 0x00,
1194 0x00, 0x00, 0x00, 0x00,
1195
1196 0x88, 0x64,
1197
1198 0x11, 0x00, 0x00, 0x00,
1199 0x00, 0x2a,
1200
1201 0x00, 0x57,
1202
1203 0x60, 0x00, 0x00, 0x00,
1204 0x00, 0x14, 0x06, 0x00,
1205 0x00, 0x00, 0x00, 0x00,
1206 0x00, 0x00, 0x00, 0x00,
1207 0x00, 0x00, 0x00, 0x00,
1208 0x00, 0x00, 0x00, 0x00,
1209 0x00, 0x00, 0x00, 0x00,
1210 0x00, 0x00, 0x00, 0x00,
1211 0x00, 0x00, 0x00, 0x00,
1212 0x00, 0x00, 0x00, 0x00,
1213
1214 0x00, 0x00, 0x00, 0x00,
1215 0x00, 0x00, 0x00, 0x00,
1216 0x00, 0x00, 0x00, 0x00,
1217 0x50, 0x00, 0x00, 0x00,
1218 0x00, 0x00, 0x00, 0x00,
1219
1220 0x00, 0x00,
1221 };
1222
1223 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = {
1224 { ICE_MAC_OFOS, 0 },
1225 { ICE_ETYPE_OL, 12 },
1226 { ICE_PPPOE, 14 },
1227 { ICE_IPV6_OFOS, 22 },
1228 { ICE_UDP_ILOS, 62 },
1229 { ICE_PROTOCOL_LAST, 0 },
1230 };
1231
1232 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = {
1233 0x00, 0x00, 0x00, 0x00,
1234 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0x00, 0x00,
1236
1237 0x88, 0x64,
1238
1239 0x11, 0x00, 0x00, 0x00,
1240 0x00, 0x2a,
1241
1242 0x00, 0x57,
1243
1244 0x60, 0x00, 0x00, 0x00,
1245 0x00, 0x08, 0x11, 0x00,
1246 0x00, 0x00, 0x00, 0x00,
1247 0x00, 0x00, 0x00, 0x00,
1248 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00,
1250 0x00, 0x00, 0x00, 0x00,
1251 0x00, 0x00, 0x00, 0x00,
1252 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00,
1254
1255 0x00, 0x00, 0x00, 0x00,
1256 0x00, 0x08, 0x00, 0x00,
1257
1258 0x00, 0x00,
1259 };
1260
1261 static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
1262 ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 |
1263 ICE_PKT_GTP_NOPAY),
1264 ICE_PKT_PROFILE(ipv6_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
1265 ICE_PKT_OUTER_IPV6 |
1266 ICE_PKT_INNER_IPV6 |
1267 ICE_PKT_INNER_UDP),
1268 ICE_PKT_PROFILE(ipv6_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
1269 ICE_PKT_OUTER_IPV6 |
1270 ICE_PKT_INNER_IPV6),
1271 ICE_PKT_PROFILE(ipv6_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
1272 ICE_PKT_OUTER_IPV6 |
1273 ICE_PKT_INNER_UDP),
1274 ICE_PKT_PROFILE(ipv6_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU |
1275 ICE_PKT_OUTER_IPV6),
1276 ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPU | ICE_PKT_GTP_NOPAY),
1277 ICE_PKT_PROFILE(ipv4_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU |
1278 ICE_PKT_INNER_IPV6 |
1279 ICE_PKT_INNER_UDP),
1280 ICE_PKT_PROFILE(ipv4_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU |
1281 ICE_PKT_INNER_IPV6),
1282 ICE_PKT_PROFILE(ipv4_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU |
1283 ICE_PKT_INNER_UDP),
1284 ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
1285 ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
1286 ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC),
1287 ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 |
1288 ICE_PKT_INNER_UDP),
1289 ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6),
1290 ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP),
1291 ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE),
1292 ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 |
1293 ICE_PKT_INNER_TCP),
1294 ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP),
1295 ICE_PKT_PROFILE(gre_ipv6_udp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6),
1296 ICE_PKT_PROFILE(gre_udp, ICE_PKT_TUN_NVGRE),
1297 ICE_PKT_PROFILE(udp_tun_ipv6_tcp, ICE_PKT_TUN_UDP |
1298 ICE_PKT_INNER_IPV6 |
1299 ICE_PKT_INNER_TCP),
1300 ICE_PKT_PROFILE(udp_tun_tcp, ICE_PKT_TUN_UDP | ICE_PKT_INNER_TCP),
1301 ICE_PKT_PROFILE(udp_tun_ipv6_udp, ICE_PKT_TUN_UDP |
1302 ICE_PKT_INNER_IPV6),
1303 ICE_PKT_PROFILE(udp_tun_udp, ICE_PKT_TUN_UDP),
1304 ICE_PKT_PROFILE(udp_ipv6, ICE_PKT_OUTER_IPV6 | ICE_PKT_INNER_UDP),
1305 ICE_PKT_PROFILE(udp, ICE_PKT_INNER_UDP),
1306 ICE_PKT_PROFILE(tcp_ipv6, ICE_PKT_OUTER_IPV6),
1307 ICE_PKT_PROFILE(tcp, 0),
1308 };
1309
1310 #define ICE_SW_RULE_RX_TX_HDR_SIZE(s, l) struct_size((s), hdr_data, (l))
1311 #define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s) \
1312 ICE_SW_RULE_RX_TX_HDR_SIZE((s), DUMMY_ETH_HDR_LEN)
1313 #define ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s) \
1314 ICE_SW_RULE_RX_TX_HDR_SIZE((s), 0)
1315 #define ICE_SW_RULE_LG_ACT_SIZE(s, n) struct_size((s), act, (n))
1316 #define ICE_SW_RULE_VSI_LIST_SIZE(s, n) struct_size((s), vsi, (n))
1317
1318
1319 static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES],
1320 ICE_MAX_NUM_PROFILES);
1321
1322
1323 static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES],
1324 ICE_MAX_NUM_RECIPES);
1325
1326
1327
1328
1329
1330
1331
1332
1333 int ice_init_def_sw_recp(struct ice_hw *hw)
1334 {
1335 struct ice_sw_recipe *recps;
1336 u8 i;
1337
1338 recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES,
1339 sizeof(*recps), GFP_KERNEL);
1340 if (!recps)
1341 return -ENOMEM;
1342
1343 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
1344 recps[i].root_rid = i;
1345 INIT_LIST_HEAD(&recps[i].filt_rules);
1346 INIT_LIST_HEAD(&recps[i].filt_replay_rules);
1347 INIT_LIST_HEAD(&recps[i].rg_list);
1348 mutex_init(&recps[i].filt_rule_lock);
1349 }
1350
1351 hw->switch_info->recp_list = recps;
1352
1353 return 0;
1354 }
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381 static int
1382 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf,
1383 u16 buf_size, u16 *req_desc, u16 *num_elems,
1384 struct ice_sq_cd *cd)
1385 {
1386 struct ice_aqc_get_sw_cfg *cmd;
1387 struct ice_aq_desc desc;
1388 int status;
1389
1390 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg);
1391 cmd = &desc.params.get_sw_conf;
1392 cmd->element = cpu_to_le16(*req_desc);
1393
1394 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
1395 if (!status) {
1396 *req_desc = le16_to_cpu(cmd->element);
1397 *num_elems = le16_to_cpu(cmd->num_elems);
1398 }
1399
1400 return status;
1401 }
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411 static int
1412 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1413 struct ice_sq_cd *cd)
1414 {
1415 struct ice_aqc_add_update_free_vsi_resp *res;
1416 struct ice_aqc_add_get_update_free_vsi *cmd;
1417 struct ice_aq_desc desc;
1418 int status;
1419
1420 cmd = &desc.params.vsi_cmd;
1421 res = &desc.params.add_update_free_vsi_res;
1422
1423 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi);
1424
1425 if (!vsi_ctx->alloc_from_pool)
1426 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num |
1427 ICE_AQ_VSI_IS_VALID);
1428 cmd->vf_id = vsi_ctx->vf_num;
1429
1430 cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags);
1431
1432 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1433
1434 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
1435 sizeof(vsi_ctx->info), cd);
1436
1437 if (!status) {
1438 vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M;
1439 vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used);
1440 vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free);
1441 }
1442
1443 return status;
1444 }
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455 static int
1456 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1457 bool keep_vsi_alloc, struct ice_sq_cd *cd)
1458 {
1459 struct ice_aqc_add_update_free_vsi_resp *resp;
1460 struct ice_aqc_add_get_update_free_vsi *cmd;
1461 struct ice_aq_desc desc;
1462 int status;
1463
1464 cmd = &desc.params.vsi_cmd;
1465 resp = &desc.params.add_update_free_vsi_res;
1466
1467 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi);
1468
1469 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
1470 if (keep_vsi_alloc)
1471 cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC);
1472
1473 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1474 if (!status) {
1475 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
1476 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
1477 }
1478
1479 return status;
1480 }
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490 static int
1491 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx,
1492 struct ice_sq_cd *cd)
1493 {
1494 struct ice_aqc_add_update_free_vsi_resp *resp;
1495 struct ice_aqc_add_get_update_free_vsi *cmd;
1496 struct ice_aq_desc desc;
1497 int status;
1498
1499 cmd = &desc.params.vsi_cmd;
1500 resp = &desc.params.add_update_free_vsi_res;
1501
1502 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi);
1503
1504 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID);
1505
1506 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1507
1508 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info,
1509 sizeof(vsi_ctx->info), cd);
1510
1511 if (!status) {
1512 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used);
1513 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free);
1514 }
1515
1516 return status;
1517 }
1518
1519
1520
1521
1522
1523
1524
1525
1526 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle)
1527 {
1528 return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle];
1529 }
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle)
1540 {
1541 return hw->vsi_ctx[vsi_handle]->vsi_num;
1542 }
1543
1544
1545
1546
1547
1548
1549
1550
1551 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
1552 {
1553 return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle];
1554 }
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564 static void
1565 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi)
1566 {
1567 hw->vsi_ctx[vsi_handle] = vsi;
1568 }
1569
1570
1571
1572
1573
1574
1575 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle)
1576 {
1577 struct ice_vsi_ctx *vsi;
1578 u8 i;
1579
1580 vsi = ice_get_vsi_ctx(hw, vsi_handle);
1581 if (!vsi)
1582 return;
1583 ice_for_each_traffic_class(i) {
1584 if (vsi->lan_q_ctx[i]) {
1585 devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]);
1586 vsi->lan_q_ctx[i] = NULL;
1587 }
1588 if (vsi->rdma_q_ctx[i]) {
1589 devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]);
1590 vsi->rdma_q_ctx[i] = NULL;
1591 }
1592 }
1593 }
1594
1595
1596
1597
1598
1599
1600
1601
1602 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle)
1603 {
1604 struct ice_vsi_ctx *vsi;
1605
1606 vsi = ice_get_vsi_ctx(hw, vsi_handle);
1607 if (vsi) {
1608 ice_clear_vsi_q_ctx(hw, vsi_handle);
1609 devm_kfree(ice_hw_to_dev(hw), vsi);
1610 hw->vsi_ctx[vsi_handle] = NULL;
1611 }
1612 }
1613
1614
1615
1616
1617
1618 void ice_clear_all_vsi_ctx(struct ice_hw *hw)
1619 {
1620 u16 i;
1621
1622 for (i = 0; i < ICE_MAX_VSI; i++)
1623 ice_clear_vsi_ctx(hw, i);
1624 }
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637 int
1638 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1639 struct ice_sq_cd *cd)
1640 {
1641 struct ice_vsi_ctx *tmp_vsi_ctx;
1642 int status;
1643
1644 if (vsi_handle >= ICE_MAX_VSI)
1645 return -EINVAL;
1646 status = ice_aq_add_vsi(hw, vsi_ctx, cd);
1647 if (status)
1648 return status;
1649 tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle);
1650 if (!tmp_vsi_ctx) {
1651
1652 tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw),
1653 sizeof(*tmp_vsi_ctx), GFP_KERNEL);
1654 if (!tmp_vsi_ctx) {
1655 ice_aq_free_vsi(hw, vsi_ctx, false, cd);
1656 return -ENOMEM;
1657 }
1658 *tmp_vsi_ctx = *vsi_ctx;
1659 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx);
1660 } else {
1661
1662 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num;
1663 }
1664
1665 return 0;
1666 }
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678 int
1679 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1680 bool keep_vsi_alloc, struct ice_sq_cd *cd)
1681 {
1682 int status;
1683
1684 if (!ice_is_vsi_valid(hw, vsi_handle))
1685 return -EINVAL;
1686 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
1687 status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd);
1688 if (!status)
1689 ice_clear_vsi_ctx(hw, vsi_handle);
1690 return status;
1691 }
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702 int
1703 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx,
1704 struct ice_sq_cd *cd)
1705 {
1706 if (!ice_is_vsi_valid(hw, vsi_handle))
1707 return -EINVAL;
1708 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle);
1709 return ice_aq_update_vsi(hw, vsi_ctx, cd);
1710 }
1711
1712
1713
1714
1715
1716
1717
1718 int
1719 ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable)
1720 {
1721 struct ice_vsi_ctx *ctx;
1722
1723 ctx = ice_get_vsi_ctx(hw, vsi_handle);
1724 if (!ctx)
1725 return -EIO;
1726
1727 if (enable)
1728 ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
1729 else
1730 ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
1731
1732 return ice_update_vsi(hw, vsi_handle, ctx, NULL);
1733 }
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744 static int
1745 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id,
1746 enum ice_sw_lkup_type lkup_type,
1747 enum ice_adminq_opc opc)
1748 {
1749 struct ice_aqc_alloc_free_res_elem *sw_buf;
1750 struct ice_aqc_res_elem *vsi_ele;
1751 u16 buf_len;
1752 int status;
1753
1754 buf_len = struct_size(sw_buf, elem, 1);
1755 sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL);
1756 if (!sw_buf)
1757 return -ENOMEM;
1758 sw_buf->num_elems = cpu_to_le16(1);
1759
1760 if (lkup_type == ICE_SW_LKUP_MAC ||
1761 lkup_type == ICE_SW_LKUP_MAC_VLAN ||
1762 lkup_type == ICE_SW_LKUP_ETHERTYPE ||
1763 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
1764 lkup_type == ICE_SW_LKUP_PROMISC ||
1765 lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
1766 lkup_type == ICE_SW_LKUP_DFLT) {
1767 sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP);
1768 } else if (lkup_type == ICE_SW_LKUP_VLAN) {
1769 sw_buf->res_type =
1770 cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE);
1771 } else {
1772 status = -EINVAL;
1773 goto ice_aq_alloc_free_vsi_list_exit;
1774 }
1775
1776 if (opc == ice_aqc_opc_free_res)
1777 sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id);
1778
1779 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL);
1780 if (status)
1781 goto ice_aq_alloc_free_vsi_list_exit;
1782
1783 if (opc == ice_aqc_opc_alloc_res) {
1784 vsi_ele = &sw_buf->elem[0];
1785 *vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp);
1786 }
1787
1788 ice_aq_alloc_free_vsi_list_exit:
1789 devm_kfree(ice_hw_to_dev(hw), sw_buf);
1790 return status;
1791 }
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804 int
1805 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz,
1806 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd)
1807 {
1808 struct ice_aq_desc desc;
1809 int status;
1810
1811 if (opc != ice_aqc_opc_add_sw_rules &&
1812 opc != ice_aqc_opc_update_sw_rules &&
1813 opc != ice_aqc_opc_remove_sw_rules)
1814 return -EINVAL;
1815
1816 ice_fill_dflt_direct_cmd_desc(&desc, opc);
1817
1818 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1819 desc.params.sw_rules.num_rules_fltr_entry_index =
1820 cpu_to_le16(num_rules);
1821 status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd);
1822 if (opc != ice_aqc_opc_add_sw_rules &&
1823 hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
1824 status = -ENOENT;
1825
1826 return status;
1827 }
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838 static int
1839 ice_aq_add_recipe(struct ice_hw *hw,
1840 struct ice_aqc_recipe_data_elem *s_recipe_list,
1841 u16 num_recipes, struct ice_sq_cd *cd)
1842 {
1843 struct ice_aqc_add_get_recipe *cmd;
1844 struct ice_aq_desc desc;
1845 u16 buf_size;
1846
1847 cmd = &desc.params.add_get_recipe;
1848 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe);
1849
1850 cmd->num_sub_recipes = cpu_to_le16(num_recipes);
1851 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);
1852
1853 buf_size = num_recipes * sizeof(*s_recipe_list);
1854
1855 return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
1856 }
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875 static int
1876 ice_aq_get_recipe(struct ice_hw *hw,
1877 struct ice_aqc_recipe_data_elem *s_recipe_list,
1878 u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd)
1879 {
1880 struct ice_aqc_add_get_recipe *cmd;
1881 struct ice_aq_desc desc;
1882 u16 buf_size;
1883 int status;
1884
1885 if (*num_recipes != ICE_MAX_NUM_RECIPES)
1886 return -EINVAL;
1887
1888 cmd = &desc.params.add_get_recipe;
1889 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe);
1890
1891 cmd->return_index = cpu_to_le16(recipe_root);
1892 cmd->num_sub_recipes = 0;
1893
1894 buf_size = *num_recipes * sizeof(*s_recipe_list);
1895
1896 status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd);
1897 *num_recipes = le16_to_cpu(cmd->num_sub_recipes);
1898
1899 return status;
1900 }
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915 int
1916 ice_update_recipe_lkup_idx(struct ice_hw *hw,
1917 struct ice_update_recipe_lkup_idx_params *params)
1918 {
1919 struct ice_aqc_recipe_data_elem *rcp_list;
1920 u16 num_recps = ICE_MAX_NUM_RECIPES;
1921 int status;
1922
1923 rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL);
1924 if (!rcp_list)
1925 return -ENOMEM;
1926
1927
1928 rcp_list->recipe_indx = params->rid;
1929 status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL);
1930 if (status) {
1931 ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n",
1932 params->rid, status);
1933 goto error_out;
1934 }
1935
1936
1937
1938
1939 rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx;
1940 if (params->mask_valid)
1941 rcp_list->content.mask[params->lkup_idx] =
1942 cpu_to_le16(params->mask);
1943
1944 if (params->ignore_valid)
1945 rcp_list->content.lkup_indx[params->lkup_idx] |=
1946 ICE_AQ_RECIPE_LKUP_IGNORE;
1947
1948 status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL);
1949 if (status)
1950 ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n",
1951 params->rid, params->lkup_idx, params->fv_idx,
1952 params->mask, params->mask_valid ? "true" : "false",
1953 status);
1954
1955 error_out:
1956 kfree(rcp_list);
1957 return status;
1958 }
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968 static int
1969 ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
1970 struct ice_sq_cd *cd)
1971 {
1972 struct ice_aqc_recipe_to_profile *cmd;
1973 struct ice_aq_desc desc;
1974
1975 cmd = &desc.params.recipe_to_profile;
1976 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile);
1977 cmd->profile_id = cpu_to_le16(profile_id);
1978
1979
1980
1981 memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc));
1982
1983 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
1984 }
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994 static int
1995 ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap,
1996 struct ice_sq_cd *cd)
1997 {
1998 struct ice_aqc_recipe_to_profile *cmd;
1999 struct ice_aq_desc desc;
2000 int status;
2001
2002 cmd = &desc.params.recipe_to_profile;
2003 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile);
2004 cmd->profile_id = cpu_to_le16(profile_id);
2005
2006 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
2007 if (!status)
2008 memcpy(r_bitmap, cmd->recipe_assoc, sizeof(cmd->recipe_assoc));
2009
2010 return status;
2011 }
2012
2013
2014
2015
2016
2017
2018 static int ice_alloc_recipe(struct ice_hw *hw, u16 *rid)
2019 {
2020 struct ice_aqc_alloc_free_res_elem *sw_buf;
2021 u16 buf_len;
2022 int status;
2023
2024 buf_len = struct_size(sw_buf, elem, 1);
2025 sw_buf = kzalloc(buf_len, GFP_KERNEL);
2026 if (!sw_buf)
2027 return -ENOMEM;
2028
2029 sw_buf->num_elems = cpu_to_le16(1);
2030 sw_buf->res_type = cpu_to_le16((ICE_AQC_RES_TYPE_RECIPE <<
2031 ICE_AQC_RES_TYPE_S) |
2032 ICE_AQC_RES_TYPE_FLAG_SHARED);
2033 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len,
2034 ice_aqc_opc_alloc_res, NULL);
2035 if (!status)
2036 *rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp);
2037 kfree(sw_buf);
2038
2039 return status;
2040 }
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050 static void ice_get_recp_to_prof_map(struct ice_hw *hw)
2051 {
2052 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
2053 u16 i;
2054
2055 for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) {
2056 u16 j;
2057
2058 bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES);
2059 bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES);
2060 if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL))
2061 continue;
2062 bitmap_copy(profile_to_recipe[i], r_bitmap,
2063 ICE_MAX_NUM_RECIPES);
2064 for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES)
2065 set_bit(i, recipe_to_profile[j]);
2066 }
2067 }
2068
2069
2070
2071
2072
2073
2074 static void
2075 ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf,
2076 struct ice_sw_recipe *recp)
2077 {
2078 if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2079 set_bit(buf->content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
2080 recp->res_idxs);
2081 }
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094 static int
2095 ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid,
2096 bool *refresh_required)
2097 {
2098 DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS);
2099 struct ice_aqc_recipe_data_elem *tmp;
2100 u16 num_recps = ICE_MAX_NUM_RECIPES;
2101 struct ice_prot_lkup_ext *lkup_exts;
2102 u8 fv_word_idx = 0;
2103 u16 sub_recps;
2104 int status;
2105
2106 bitmap_zero(result_bm, ICE_MAX_FV_WORDS);
2107
2108
2109 tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
2110 if (!tmp)
2111 return -ENOMEM;
2112
2113 tmp[0].recipe_indx = rid;
2114 status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL);
2115
2116 if (status)
2117 goto err_unroll;
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127 if (*refresh_required) {
2128 ice_get_recp_to_prof_map(hw);
2129 *refresh_required = false;
2130 }
2131
2132
2133
2134
2135
2136 lkup_exts = &recps[rid].lkup_exts;
2137
2138 for (sub_recps = 0; sub_recps < num_recps; sub_recps++) {
2139 struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps];
2140 struct ice_recp_grp_entry *rg_entry;
2141 u8 i, prof, idx, prot = 0;
2142 bool is_root;
2143 u16 off = 0;
2144
2145 rg_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rg_entry),
2146 GFP_KERNEL);
2147 if (!rg_entry) {
2148 status = -ENOMEM;
2149 goto err_unroll;
2150 }
2151
2152 idx = root_bufs.recipe_indx;
2153 is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT;
2154
2155
2156 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN)
2157 set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN,
2158 result_bm);
2159
2160
2161 prof = find_first_bit(recipe_to_profile[idx],
2162 ICE_MAX_NUM_PROFILES);
2163 for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) {
2164 u8 lkup_indx = root_bufs.content.lkup_indx[i + 1];
2165
2166 rg_entry->fv_idx[i] = lkup_indx;
2167 rg_entry->fv_mask[i] =
2168 le16_to_cpu(root_bufs.content.mask[i + 1]);
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179 if (test_bit(rg_entry->fv_idx[i], hw->switch_info->prof_res_bm[prof]) ||
2180 rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE ||
2181 rg_entry->fv_idx[i] == 0)
2182 continue;
2183
2184 ice_find_prot_off(hw, ICE_BLK_SW, prof,
2185 rg_entry->fv_idx[i], &prot, &off);
2186 lkup_exts->fv_words[fv_word_idx].prot_id = prot;
2187 lkup_exts->fv_words[fv_word_idx].off = off;
2188 lkup_exts->field_mask[fv_word_idx] =
2189 rg_entry->fv_mask[i];
2190 fv_word_idx++;
2191 }
2192
2193
2194
2195 list_add(&rg_entry->l_entry, &recps[rid].rg_list);
2196
2197
2198 recps[idx].is_root = !!is_root;
2199 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2200 bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS);
2201 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) {
2202 recps[idx].chain_idx = root_bufs.content.result_indx &
2203 ~ICE_AQ_RECIPE_RESULT_EN;
2204 set_bit(recps[idx].chain_idx, recps[idx].res_idxs);
2205 } else {
2206 recps[idx].chain_idx = ICE_INVAL_CHAIN_IND;
2207 }
2208
2209 if (!is_root)
2210 continue;
2211
2212
2213 memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap,
2214 sizeof(recps[idx].r_bitmap));
2215 recps[idx].root_rid = root_bufs.content.rid &
2216 ~ICE_AQ_RECIPE_ID_IS_ROOT;
2217 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority;
2218 }
2219
2220
2221 lkup_exts->n_val_words = fv_word_idx;
2222 recps[rid].big_recp = (num_recps > 1);
2223 recps[rid].n_grp_count = (u8)num_recps;
2224 recps[rid].root_buf = devm_kmemdup(ice_hw_to_dev(hw), tmp,
2225 recps[rid].n_grp_count * sizeof(*recps[rid].root_buf),
2226 GFP_KERNEL);
2227 if (!recps[rid].root_buf) {
2228 status = -ENOMEM;
2229 goto err_unroll;
2230 }
2231
2232
2233 bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS);
2234 recps[rid].recp_created = true;
2235
2236 err_unroll:
2237 kfree(tmp);
2238 return status;
2239 }
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249 static void
2250 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type,
2251 u16 swid, u16 pf_vf_num, bool is_vf)
2252 {
2253 switch (type) {
2254 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT:
2255 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK);
2256 pi->sw_id = swid;
2257 pi->pf_vf_num = pf_vf_num;
2258 pi->is_vf = is_vf;
2259 break;
2260 default:
2261 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n");
2262 break;
2263 }
2264 }
2265
2266
2267
2268
2269 int ice_get_initial_sw_cfg(struct ice_hw *hw)
2270 {
2271 struct ice_aqc_get_sw_cfg_resp_elem *rbuf;
2272 u16 req_desc = 0;
2273 u16 num_elems;
2274 int status;
2275 u16 i;
2276
2277 rbuf = devm_kzalloc(ice_hw_to_dev(hw), ICE_SW_CFG_MAX_BUF_LEN,
2278 GFP_KERNEL);
2279
2280 if (!rbuf)
2281 return -ENOMEM;
2282
2283
2284
2285
2286
2287
2288 do {
2289 struct ice_aqc_get_sw_cfg_resp_elem *ele;
2290
2291 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN,
2292 &req_desc, &num_elems, NULL);
2293
2294 if (status)
2295 break;
2296
2297 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) {
2298 u16 pf_vf_num, swid, vsi_port_num;
2299 bool is_vf = false;
2300 u8 res_type;
2301
2302 vsi_port_num = le16_to_cpu(ele->vsi_port_num) &
2303 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M;
2304
2305 pf_vf_num = le16_to_cpu(ele->pf_vf_num) &
2306 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M;
2307
2308 swid = le16_to_cpu(ele->swid);
2309
2310 if (le16_to_cpu(ele->pf_vf_num) &
2311 ICE_AQC_GET_SW_CONF_RESP_IS_VF)
2312 is_vf = true;
2313
2314 res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >>
2315 ICE_AQC_GET_SW_CONF_RESP_TYPE_S);
2316
2317 if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) {
2318
2319 continue;
2320 }
2321
2322 ice_init_port_info(hw->port_info, vsi_port_num,
2323 res_type, swid, pf_vf_num, is_vf);
2324 }
2325 } while (req_desc && !status);
2326
2327 devm_kfree(ice_hw_to_dev(hw), rbuf);
2328 return status;
2329 }
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi)
2341 {
2342 fi->lb_en = false;
2343 fi->lan_en = false;
2344 if ((fi->flag & ICE_FLTR_TX) &&
2345 (fi->fltr_act == ICE_FWD_TO_VSI ||
2346 fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
2347 fi->fltr_act == ICE_FWD_TO_Q ||
2348 fi->fltr_act == ICE_FWD_TO_QGRP)) {
2349
2350
2351
2352 if (fi->lkup_type != ICE_SW_LKUP_VLAN)
2353 fi->lb_en = true;
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371 if (hw->evb_veb) {
2372 if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2373 fi->lkup_type == ICE_SW_LKUP_PROMISC ||
2374 fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2375 fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2376 fi->lkup_type == ICE_SW_LKUP_DFLT ||
2377 fi->lkup_type == ICE_SW_LKUP_VLAN ||
2378 (fi->lkup_type == ICE_SW_LKUP_MAC &&
2379 !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) ||
2380 (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN &&
2381 !is_unicast_ether_addr(fi->l_data.mac.mac_addr)))
2382 fi->lan_en = true;
2383 } else {
2384 fi->lan_en = true;
2385 }
2386 }
2387 }
2388
2389
2390
2391
2392
2393
2394
2395
2396 static void
2397 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info,
2398 struct ice_sw_rule_lkup_rx_tx *s_rule,
2399 enum ice_adminq_opc opc)
2400 {
2401 u16 vlan_id = ICE_MAX_VLAN_ID + 1;
2402 u16 vlan_tpid = ETH_P_8021Q;
2403 void *daddr = NULL;
2404 u16 eth_hdr_sz;
2405 u8 *eth_hdr;
2406 u32 act = 0;
2407 __be16 *off;
2408 u8 q_rgn;
2409
2410 if (opc == ice_aqc_opc_remove_sw_rules) {
2411 s_rule->act = 0;
2412 s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
2413 s_rule->hdr_len = 0;
2414 return;
2415 }
2416
2417 eth_hdr_sz = sizeof(dummy_eth_header);
2418 eth_hdr = s_rule->hdr_data;
2419
2420
2421 memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz);
2422 ice_fill_sw_info(hw, f_info);
2423
2424 switch (f_info->fltr_act) {
2425 case ICE_FWD_TO_VSI:
2426 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) &
2427 ICE_SINGLE_ACT_VSI_ID_M;
2428 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2429 act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2430 ICE_SINGLE_ACT_VALID_BIT;
2431 break;
2432 case ICE_FWD_TO_VSI_LIST:
2433 act |= ICE_SINGLE_ACT_VSI_LIST;
2434 act |= (f_info->fwd_id.vsi_list_id <<
2435 ICE_SINGLE_ACT_VSI_LIST_ID_S) &
2436 ICE_SINGLE_ACT_VSI_LIST_ID_M;
2437 if (f_info->lkup_type != ICE_SW_LKUP_VLAN)
2438 act |= ICE_SINGLE_ACT_VSI_FORWARDING |
2439 ICE_SINGLE_ACT_VALID_BIT;
2440 break;
2441 case ICE_FWD_TO_Q:
2442 act |= ICE_SINGLE_ACT_TO_Q;
2443 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
2444 ICE_SINGLE_ACT_Q_INDEX_M;
2445 break;
2446 case ICE_DROP_PACKET:
2447 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
2448 ICE_SINGLE_ACT_VALID_BIT;
2449 break;
2450 case ICE_FWD_TO_QGRP:
2451 q_rgn = f_info->qgrp_size > 0 ?
2452 (u8)ilog2(f_info->qgrp_size) : 0;
2453 act |= ICE_SINGLE_ACT_TO_Q;
2454 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
2455 ICE_SINGLE_ACT_Q_INDEX_M;
2456 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
2457 ICE_SINGLE_ACT_Q_REGION_M;
2458 break;
2459 default:
2460 return;
2461 }
2462
2463 if (f_info->lb_en)
2464 act |= ICE_SINGLE_ACT_LB_ENABLE;
2465 if (f_info->lan_en)
2466 act |= ICE_SINGLE_ACT_LAN_ENABLE;
2467
2468 switch (f_info->lkup_type) {
2469 case ICE_SW_LKUP_MAC:
2470 daddr = f_info->l_data.mac.mac_addr;
2471 break;
2472 case ICE_SW_LKUP_VLAN:
2473 vlan_id = f_info->l_data.vlan.vlan_id;
2474 if (f_info->l_data.vlan.tpid_valid)
2475 vlan_tpid = f_info->l_data.vlan.tpid;
2476 if (f_info->fltr_act == ICE_FWD_TO_VSI ||
2477 f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
2478 act |= ICE_SINGLE_ACT_PRUNE;
2479 act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS;
2480 }
2481 break;
2482 case ICE_SW_LKUP_ETHERTYPE_MAC:
2483 daddr = f_info->l_data.ethertype_mac.mac_addr;
2484 fallthrough;
2485 case ICE_SW_LKUP_ETHERTYPE:
2486 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2487 *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype);
2488 break;
2489 case ICE_SW_LKUP_MAC_VLAN:
2490 daddr = f_info->l_data.mac_vlan.mac_addr;
2491 vlan_id = f_info->l_data.mac_vlan.vlan_id;
2492 break;
2493 case ICE_SW_LKUP_PROMISC_VLAN:
2494 vlan_id = f_info->l_data.mac_vlan.vlan_id;
2495 fallthrough;
2496 case ICE_SW_LKUP_PROMISC:
2497 daddr = f_info->l_data.mac_vlan.mac_addr;
2498 break;
2499 default:
2500 break;
2501 }
2502
2503 s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ?
2504 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) :
2505 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
2506
2507
2508 s_rule->recipe_id = cpu_to_le16(f_info->lkup_type);
2509 s_rule->src = cpu_to_le16(f_info->src);
2510 s_rule->act = cpu_to_le32(act);
2511
2512 if (daddr)
2513 ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr);
2514
2515 if (!(vlan_id > ICE_MAX_VLAN_ID)) {
2516 off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET);
2517 *off = cpu_to_be16(vlan_id);
2518 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET);
2519 *off = cpu_to_be16(vlan_tpid);
2520 }
2521
2522
2523 if (opc != ice_aqc_opc_update_sw_rules)
2524 s_rule->hdr_len = cpu_to_le16(eth_hdr_sz);
2525 }
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537 static int
2538 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent,
2539 u16 sw_marker, u16 l_id)
2540 {
2541 struct ice_sw_rule_lkup_rx_tx *rx_tx;
2542 struct ice_sw_rule_lg_act *lg_act;
2543
2544
2545
2546
2547
2548 const u16 num_lg_acts = 3;
2549 u16 lg_act_size;
2550 u16 rules_size;
2551 int status;
2552 u32 act;
2553 u16 id;
2554
2555 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC)
2556 return -EINVAL;
2557
2558
2559
2560
2561
2562
2563 lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(lg_act, num_lg_acts);
2564 rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(rx_tx);
2565 lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL);
2566 if (!lg_act)
2567 return -ENOMEM;
2568
2569 rx_tx = (typeof(rx_tx))((u8 *)lg_act + lg_act_size);
2570
2571
2572 lg_act->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT);
2573 lg_act->index = cpu_to_le16(l_id);
2574 lg_act->size = cpu_to_le16(num_lg_acts);
2575
2576
2577
2578
2579 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id :
2580 m_ent->fltr_info.fwd_id.hw_vsi_id;
2581
2582 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT;
2583 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M;
2584 if (m_ent->vsi_count > 1)
2585 act |= ICE_LG_ACT_VSI_LIST;
2586 lg_act->act[0] = cpu_to_le32(act);
2587
2588
2589 act = ICE_LG_ACT_GENERIC;
2590
2591 act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M;
2592 lg_act->act[1] = cpu_to_le32(act);
2593
2594 act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX <<
2595 ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M;
2596
2597
2598 act |= ICE_LG_ACT_GENERIC;
2599 act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) &
2600 ICE_LG_ACT_GENERIC_VALUE_M;
2601
2602 lg_act->act[2] = cpu_to_le32(act);
2603
2604
2605 ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx,
2606 ice_aqc_opc_update_sw_rules);
2607
2608
2609 rx_tx->act = cpu_to_le32(ICE_SINGLE_ACT_PTR |
2610 ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) &
2611 ICE_SINGLE_ACT_PTR_VAL_M));
2612
2613
2614
2615
2616
2617 rx_tx->index = cpu_to_le16(m_ent->fltr_info.fltr_rule_id);
2618
2619 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2,
2620 ice_aqc_opc_update_sw_rules, NULL);
2621 if (!status) {
2622 m_ent->lg_act_idx = l_id;
2623 m_ent->sw_marker_id = sw_marker;
2624 }
2625
2626 devm_kfree(ice_hw_to_dev(hw), lg_act);
2627 return status;
2628 }
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640 static struct ice_vsi_list_map_info *
2641 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2642 u16 vsi_list_id)
2643 {
2644 struct ice_switch_info *sw = hw->switch_info;
2645 struct ice_vsi_list_map_info *v_map;
2646 int i;
2647
2648 v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL);
2649 if (!v_map)
2650 return NULL;
2651
2652 v_map->vsi_list_id = vsi_list_id;
2653 v_map->ref_cnt = 1;
2654 for (i = 0; i < num_vsi; i++)
2655 set_bit(vsi_handle_arr[i], v_map->vsi_map);
2656
2657 list_add(&v_map->list_entry, &sw->vsi_list_map_head);
2658 return v_map;
2659 }
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674 static int
2675 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2676 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc,
2677 enum ice_sw_lkup_type lkup_type)
2678 {
2679 struct ice_sw_rule_vsi_list *s_rule;
2680 u16 s_rule_size;
2681 u16 rule_type;
2682 int status;
2683 int i;
2684
2685 if (!num_vsi)
2686 return -EINVAL;
2687
2688 if (lkup_type == ICE_SW_LKUP_MAC ||
2689 lkup_type == ICE_SW_LKUP_MAC_VLAN ||
2690 lkup_type == ICE_SW_LKUP_ETHERTYPE ||
2691 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC ||
2692 lkup_type == ICE_SW_LKUP_PROMISC ||
2693 lkup_type == ICE_SW_LKUP_PROMISC_VLAN ||
2694 lkup_type == ICE_SW_LKUP_DFLT)
2695 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR :
2696 ICE_AQC_SW_RULES_T_VSI_LIST_SET;
2697 else if (lkup_type == ICE_SW_LKUP_VLAN)
2698 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR :
2699 ICE_AQC_SW_RULES_T_PRUNE_LIST_SET;
2700 else
2701 return -EINVAL;
2702
2703 s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);
2704 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
2705 if (!s_rule)
2706 return -ENOMEM;
2707 for (i = 0; i < num_vsi; i++) {
2708 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) {
2709 status = -EINVAL;
2710 goto exit;
2711 }
2712
2713 s_rule->vsi[i] =
2714 cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i]));
2715 }
2716
2717 s_rule->hdr.type = cpu_to_le16(rule_type);
2718 s_rule->number_vsi = cpu_to_le16(num_vsi);
2719 s_rule->index = cpu_to_le16(vsi_list_id);
2720
2721 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL);
2722
2723 exit:
2724 devm_kfree(ice_hw_to_dev(hw), s_rule);
2725 return status;
2726 }
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736 static int
2737 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi,
2738 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type)
2739 {
2740 int status;
2741
2742 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type,
2743 ice_aqc_opc_alloc_res);
2744 if (status)
2745 return status;
2746
2747
2748 return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi,
2749 *vsi_list_id, false,
2750 ice_aqc_opc_add_sw_rules, lkup_type);
2751 }
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762 static int
2763 ice_create_pkt_fwd_rule(struct ice_hw *hw,
2764 struct ice_fltr_list_entry *f_entry)
2765 {
2766 struct ice_fltr_mgmt_list_entry *fm_entry;
2767 struct ice_sw_rule_lkup_rx_tx *s_rule;
2768 enum ice_sw_lkup_type l_type;
2769 struct ice_sw_recipe *recp;
2770 int status;
2771
2772 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
2773 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
2774 GFP_KERNEL);
2775 if (!s_rule)
2776 return -ENOMEM;
2777 fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry),
2778 GFP_KERNEL);
2779 if (!fm_entry) {
2780 status = -ENOMEM;
2781 goto ice_create_pkt_fwd_rule_exit;
2782 }
2783
2784 fm_entry->fltr_info = f_entry->fltr_info;
2785
2786
2787 fm_entry->vsi_count = 1;
2788 fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX;
2789 fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID;
2790 fm_entry->counter_index = ICE_INVAL_COUNTER_ID;
2791
2792 ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule,
2793 ice_aqc_opc_add_sw_rules);
2794
2795 status = ice_aq_sw_rules(hw, s_rule,
2796 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
2797 ice_aqc_opc_add_sw_rules, NULL);
2798 if (status) {
2799 devm_kfree(ice_hw_to_dev(hw), fm_entry);
2800 goto ice_create_pkt_fwd_rule_exit;
2801 }
2802
2803 f_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
2804 fm_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index);
2805
2806
2807
2808
2809 l_type = fm_entry->fltr_info.lkup_type;
2810 recp = &hw->switch_info->recp_list[l_type];
2811 list_add(&fm_entry->list_entry, &recp->filt_rules);
2812
2813 ice_create_pkt_fwd_rule_exit:
2814 devm_kfree(ice_hw_to_dev(hw), s_rule);
2815 return status;
2816 }
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826 static int
2827 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info)
2828 {
2829 struct ice_sw_rule_lkup_rx_tx *s_rule;
2830 int status;
2831
2832 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
2833 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule),
2834 GFP_KERNEL);
2835 if (!s_rule)
2836 return -ENOMEM;
2837
2838 ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules);
2839
2840 s_rule->index = cpu_to_le16(f_info->fltr_rule_id);
2841
2842
2843 status = ice_aq_sw_rules(hw, s_rule,
2844 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1,
2845 ice_aqc_opc_update_sw_rules, NULL);
2846
2847 devm_kfree(ice_hw_to_dev(hw), s_rule);
2848 return status;
2849 }
2850
2851
2852
2853
2854
2855
2856
2857 int ice_update_sw_rule_bridge_mode(struct ice_hw *hw)
2858 {
2859 struct ice_switch_info *sw = hw->switch_info;
2860 struct ice_fltr_mgmt_list_entry *fm_entry;
2861 struct list_head *rule_head;
2862 struct mutex *rule_lock;
2863 int status = 0;
2864
2865 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
2866 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
2867
2868 mutex_lock(rule_lock);
2869 list_for_each_entry(fm_entry, rule_head, list_entry) {
2870 struct ice_fltr_info *fi = &fm_entry->fltr_info;
2871 u8 *addr = fi->l_data.mac.mac_addr;
2872
2873
2874
2875
2876 if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) &&
2877 (fi->fltr_act == ICE_FWD_TO_VSI ||
2878 fi->fltr_act == ICE_FWD_TO_VSI_LIST ||
2879 fi->fltr_act == ICE_FWD_TO_Q ||
2880 fi->fltr_act == ICE_FWD_TO_QGRP)) {
2881 status = ice_update_pkt_fwd_rule(hw, fi);
2882 if (status)
2883 break;
2884 }
2885 }
2886
2887 mutex_unlock(rule_lock);
2888
2889 return status;
2890 }
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913 static int
2914 ice_add_update_vsi_list(struct ice_hw *hw,
2915 struct ice_fltr_mgmt_list_entry *m_entry,
2916 struct ice_fltr_info *cur_fltr,
2917 struct ice_fltr_info *new_fltr)
2918 {
2919 u16 vsi_list_id = 0;
2920 int status = 0;
2921
2922 if ((cur_fltr->fltr_act == ICE_FWD_TO_Q ||
2923 cur_fltr->fltr_act == ICE_FWD_TO_QGRP))
2924 return -EOPNOTSUPP;
2925
2926 if ((new_fltr->fltr_act == ICE_FWD_TO_Q ||
2927 new_fltr->fltr_act == ICE_FWD_TO_QGRP) &&
2928 (cur_fltr->fltr_act == ICE_FWD_TO_VSI ||
2929 cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST))
2930 return -EOPNOTSUPP;
2931
2932 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
2933
2934
2935
2936
2937 struct ice_fltr_info tmp_fltr;
2938 u16 vsi_handle_arr[2];
2939
2940
2941 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id)
2942 return -EEXIST;
2943
2944 vsi_handle_arr[0] = cur_fltr->vsi_handle;
2945 vsi_handle_arr[1] = new_fltr->vsi_handle;
2946 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
2947 &vsi_list_id,
2948 new_fltr->lkup_type);
2949 if (status)
2950 return status;
2951
2952 tmp_fltr = *new_fltr;
2953 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
2954 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
2955 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
2956
2957
2958
2959 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
2960 if (status)
2961 return status;
2962
2963 cur_fltr->fwd_id.vsi_list_id = vsi_list_id;
2964 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
2965 m_entry->vsi_list_info =
2966 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
2967 vsi_list_id);
2968
2969 if (!m_entry->vsi_list_info)
2970 return -ENOMEM;
2971
2972
2973
2974
2975 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID)
2976 status =
2977 ice_add_marker_act(hw, m_entry,
2978 m_entry->sw_marker_id,
2979 m_entry->lg_act_idx);
2980 } else {
2981 u16 vsi_handle = new_fltr->vsi_handle;
2982 enum ice_adminq_opc opcode;
2983
2984 if (!m_entry->vsi_list_info)
2985 return -EIO;
2986
2987
2988 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
2989 return 0;
2990
2991
2992
2993
2994 vsi_list_id = cur_fltr->fwd_id.vsi_list_id;
2995 opcode = ice_aqc_opc_update_sw_rules;
2996
2997 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
2998 vsi_list_id, false, opcode,
2999 new_fltr->lkup_type);
3000
3001 if (!status)
3002 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
3003 }
3004 if (!status)
3005 m_entry->vsi_count++;
3006 return status;
3007 }
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018 static struct ice_fltr_mgmt_list_entry *
3019 ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info)
3020 {
3021 struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL;
3022 struct ice_switch_info *sw = hw->switch_info;
3023 struct list_head *list_head;
3024
3025 list_head = &sw->recp_list[recp_id].filt_rules;
3026 list_for_each_entry(list_itr, list_head, list_entry) {
3027 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
3028 sizeof(f_info->l_data)) &&
3029 f_info->flag == list_itr->fltr_info.flag) {
3030 ret = list_itr;
3031 break;
3032 }
3033 }
3034 return ret;
3035 }
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048 static struct ice_vsi_list_map_info *
3049 ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle,
3050 u16 *vsi_list_id)
3051 {
3052 struct ice_vsi_list_map_info *map_info = NULL;
3053 struct ice_switch_info *sw = hw->switch_info;
3054 struct ice_fltr_mgmt_list_entry *list_itr;
3055 struct list_head *list_head;
3056
3057 list_head = &sw->recp_list[recp_id].filt_rules;
3058 list_for_each_entry(list_itr, list_head, list_entry) {
3059 if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) {
3060 map_info = list_itr->vsi_list_info;
3061 if (test_bit(vsi_handle, map_info->vsi_map)) {
3062 *vsi_list_id = map_info->vsi_list_id;
3063 return map_info;
3064 }
3065 }
3066 }
3067 return NULL;
3068 }
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078 static int
3079 ice_add_rule_internal(struct ice_hw *hw, u8 recp_id,
3080 struct ice_fltr_list_entry *f_entry)
3081 {
3082 struct ice_switch_info *sw = hw->switch_info;
3083 struct ice_fltr_info *new_fltr, *cur_fltr;
3084 struct ice_fltr_mgmt_list_entry *m_entry;
3085 struct mutex *rule_lock;
3086 int status = 0;
3087
3088 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3089 return -EINVAL;
3090 f_entry->fltr_info.fwd_id.hw_vsi_id =
3091 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3092
3093 rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3094
3095 mutex_lock(rule_lock);
3096 new_fltr = &f_entry->fltr_info;
3097 if (new_fltr->flag & ICE_FLTR_RX)
3098 new_fltr->src = hw->port_info->lport;
3099 else if (new_fltr->flag & ICE_FLTR_TX)
3100 new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id;
3101
3102 m_entry = ice_find_rule_entry(hw, recp_id, new_fltr);
3103 if (!m_entry) {
3104 mutex_unlock(rule_lock);
3105 return ice_create_pkt_fwd_rule(hw, f_entry);
3106 }
3107
3108 cur_fltr = &m_entry->fltr_info;
3109 status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr);
3110 mutex_unlock(rule_lock);
3111
3112 return status;
3113 }
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124 static int
3125 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id,
3126 enum ice_sw_lkup_type lkup_type)
3127 {
3128 struct ice_sw_rule_vsi_list *s_rule;
3129 u16 s_rule_size;
3130 int status;
3131
3132 s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, 0);
3133 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL);
3134 if (!s_rule)
3135 return -ENOMEM;
3136
3137 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR);
3138 s_rule->index = cpu_to_le16(vsi_list_id);
3139
3140
3141
3142
3143 status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type,
3144 ice_aqc_opc_free_res);
3145
3146 devm_kfree(ice_hw_to_dev(hw), s_rule);
3147 return status;
3148 }
3149
3150
3151
3152
3153
3154
3155
3156
3157 static int
3158 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
3159 struct ice_fltr_mgmt_list_entry *fm_list)
3160 {
3161 enum ice_sw_lkup_type lkup_type;
3162 u16 vsi_list_id;
3163 int status = 0;
3164
3165 if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST ||
3166 fm_list->vsi_count == 0)
3167 return -EINVAL;
3168
3169
3170 if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
3171 return -ENOENT;
3172
3173 lkup_type = fm_list->fltr_info.lkup_type;
3174 vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id;
3175 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
3176 ice_aqc_opc_update_sw_rules,
3177 lkup_type);
3178 if (status)
3179 return status;
3180
3181 fm_list->vsi_count--;
3182 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
3183
3184 if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) {
3185 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info;
3186 struct ice_vsi_list_map_info *vsi_list_info =
3187 fm_list->vsi_list_info;
3188 u16 rem_vsi_handle;
3189
3190 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
3191 ICE_MAX_VSI);
3192 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
3193 return -EIO;
3194
3195
3196 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
3197 vsi_list_id, true,
3198 ice_aqc_opc_update_sw_rules,
3199 lkup_type);
3200 if (status)
3201 return status;
3202
3203 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI;
3204 tmp_fltr_info.fwd_id.hw_vsi_id =
3205 ice_get_hw_vsi_num(hw, rem_vsi_handle);
3206 tmp_fltr_info.vsi_handle = rem_vsi_handle;
3207 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info);
3208 if (status) {
3209 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
3210 tmp_fltr_info.fwd_id.hw_vsi_id, status);
3211 return status;
3212 }
3213
3214 fm_list->fltr_info = tmp_fltr_info;
3215 }
3216
3217 if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) ||
3218 (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) {
3219 struct ice_vsi_list_map_info *vsi_list_info =
3220 fm_list->vsi_list_info;
3221
3222
3223 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
3224 if (status) {
3225 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
3226 vsi_list_id, status);
3227 return status;
3228 }
3229
3230 list_del(&vsi_list_info->list_entry);
3231 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
3232 fm_list->vsi_list_info = NULL;
3233 }
3234
3235 return status;
3236 }
3237
3238
3239
3240
3241
3242
3243
3244 static int
3245 ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id,
3246 struct ice_fltr_list_entry *f_entry)
3247 {
3248 struct ice_switch_info *sw = hw->switch_info;
3249 struct ice_fltr_mgmt_list_entry *list_elem;
3250 struct mutex *rule_lock;
3251 bool remove_rule = false;
3252 u16 vsi_handle;
3253 int status = 0;
3254
3255 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3256 return -EINVAL;
3257 f_entry->fltr_info.fwd_id.hw_vsi_id =
3258 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3259
3260 rule_lock = &sw->recp_list[recp_id].filt_rule_lock;
3261 mutex_lock(rule_lock);
3262 list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info);
3263 if (!list_elem) {
3264 status = -ENOENT;
3265 goto exit;
3266 }
3267
3268 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) {
3269 remove_rule = true;
3270 } else if (!list_elem->vsi_list_info) {
3271 status = -ENOENT;
3272 goto exit;
3273 } else if (list_elem->vsi_list_info->ref_cnt > 1) {
3274
3275
3276
3277
3278
3279 list_elem->vsi_list_info->ref_cnt--;
3280 remove_rule = true;
3281 } else {
3282
3283
3284
3285
3286
3287 vsi_handle = f_entry->fltr_info.vsi_handle;
3288 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem);
3289 if (status)
3290 goto exit;
3291
3292 if (list_elem->vsi_count == 0)
3293 remove_rule = true;
3294 }
3295
3296 if (remove_rule) {
3297
3298 struct ice_sw_rule_lkup_rx_tx *s_rule;
3299
3300 s_rule = devm_kzalloc(ice_hw_to_dev(hw),
3301 ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3302 GFP_KERNEL);
3303 if (!s_rule) {
3304 status = -ENOMEM;
3305 goto exit;
3306 }
3307
3308 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule,
3309 ice_aqc_opc_remove_sw_rules);
3310
3311 status = ice_aq_sw_rules(hw, s_rule,
3312 ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule),
3313 1, ice_aqc_opc_remove_sw_rules, NULL);
3314
3315
3316 devm_kfree(ice_hw_to_dev(hw), s_rule);
3317
3318 if (status)
3319 goto exit;
3320
3321 list_del(&list_elem->list_entry);
3322 devm_kfree(ice_hw_to_dev(hw), list_elem);
3323 }
3324 exit:
3325 mutex_unlock(rule_lock);
3326 return status;
3327 }
3328
3329
3330
3331
3332
3333
3334
3335 bool ice_mac_fltr_exist(struct ice_hw *hw, u8 *mac, u16 vsi_handle)
3336 {
3337 struct ice_fltr_mgmt_list_entry *entry;
3338 struct list_head *rule_head;
3339 struct ice_switch_info *sw;
3340 struct mutex *rule_lock;
3341 u16 hw_vsi_id;
3342
3343 if (!ice_is_vsi_valid(hw, vsi_handle))
3344 return false;
3345
3346 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3347 sw = hw->switch_info;
3348 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
3349 if (!rule_head)
3350 return false;
3351
3352 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
3353 mutex_lock(rule_lock);
3354 list_for_each_entry(entry, rule_head, list_entry) {
3355 struct ice_fltr_info *f_info = &entry->fltr_info;
3356 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
3357
3358 if (is_zero_ether_addr(mac_addr))
3359 continue;
3360
3361 if (f_info->flag != ICE_FLTR_TX ||
3362 f_info->src_id != ICE_SRC_ID_VSI ||
3363 f_info->lkup_type != ICE_SW_LKUP_MAC ||
3364 f_info->fltr_act != ICE_FWD_TO_VSI ||
3365 hw_vsi_id != f_info->fwd_id.hw_vsi_id)
3366 continue;
3367
3368 if (ether_addr_equal(mac, mac_addr)) {
3369 mutex_unlock(rule_lock);
3370 return true;
3371 }
3372 }
3373 mutex_unlock(rule_lock);
3374 return false;
3375 }
3376
3377
3378
3379
3380
3381
3382
3383 bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle)
3384 {
3385 struct ice_fltr_mgmt_list_entry *entry;
3386 struct list_head *rule_head;
3387 struct ice_switch_info *sw;
3388 struct mutex *rule_lock;
3389 u16 hw_vsi_id;
3390
3391 if (vlan_id > ICE_MAX_VLAN_ID)
3392 return false;
3393
3394 if (!ice_is_vsi_valid(hw, vsi_handle))
3395 return false;
3396
3397 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3398 sw = hw->switch_info;
3399 rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
3400 if (!rule_head)
3401 return false;
3402
3403 rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3404 mutex_lock(rule_lock);
3405 list_for_each_entry(entry, rule_head, list_entry) {
3406 struct ice_fltr_info *f_info = &entry->fltr_info;
3407 u16 entry_vlan_id = f_info->l_data.vlan.vlan_id;
3408 struct ice_vsi_list_map_info *map_info;
3409
3410 if (entry_vlan_id > ICE_MAX_VLAN_ID)
3411 continue;
3412
3413 if (f_info->flag != ICE_FLTR_TX ||
3414 f_info->src_id != ICE_SRC_ID_VSI ||
3415 f_info->lkup_type != ICE_SW_LKUP_VLAN)
3416 continue;
3417
3418
3419 if (f_info->fltr_act != ICE_FWD_TO_VSI &&
3420 f_info->fltr_act != ICE_FWD_TO_VSI_LIST)
3421 continue;
3422
3423 if (f_info->fltr_act == ICE_FWD_TO_VSI) {
3424 if (hw_vsi_id != f_info->fwd_id.hw_vsi_id)
3425 continue;
3426 } else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) {
3427
3428
3429
3430 if (entry->vsi_count == 1 &&
3431 entry->vsi_list_info) {
3432 map_info = entry->vsi_list_info;
3433 if (!test_bit(vsi_handle, map_info->vsi_map))
3434 continue;
3435 }
3436 }
3437
3438 if (vlan_id == entry_vlan_id) {
3439 mutex_unlock(rule_lock);
3440 return true;
3441 }
3442 }
3443 mutex_unlock(rule_lock);
3444
3445 return false;
3446 }
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459 int ice_add_mac(struct ice_hw *hw, struct list_head *m_list)
3460 {
3461 struct ice_sw_rule_lkup_rx_tx *s_rule, *r_iter;
3462 struct ice_fltr_list_entry *m_list_itr;
3463 struct list_head *rule_head;
3464 u16 total_elem_left, s_rule_size;
3465 struct ice_switch_info *sw;
3466 struct mutex *rule_lock;
3467 u16 num_unicast = 0;
3468 int status = 0;
3469 u8 elem_sent;
3470
3471 if (!m_list || !hw)
3472 return -EINVAL;
3473
3474 s_rule = NULL;
3475 sw = hw->switch_info;
3476 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
3477 list_for_each_entry(m_list_itr, m_list, list_entry) {
3478 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0];
3479 u16 vsi_handle;
3480 u16 hw_vsi_id;
3481
3482 m_list_itr->fltr_info.flag = ICE_FLTR_TX;
3483 vsi_handle = m_list_itr->fltr_info.vsi_handle;
3484 if (!ice_is_vsi_valid(hw, vsi_handle))
3485 return -EINVAL;
3486 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3487 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id;
3488
3489 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI)
3490 return -EINVAL;
3491 m_list_itr->fltr_info.src = hw_vsi_id;
3492 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC ||
3493 is_zero_ether_addr(add))
3494 return -EINVAL;
3495 if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
3496
3497 mutex_lock(rule_lock);
3498 if (ice_find_rule_entry(hw, ICE_SW_LKUP_MAC,
3499 &m_list_itr->fltr_info)) {
3500 mutex_unlock(rule_lock);
3501 return -EEXIST;
3502 }
3503 mutex_unlock(rule_lock);
3504 num_unicast++;
3505 } else if (is_multicast_ether_addr(add) ||
3506 (is_unicast_ether_addr(add) && hw->ucast_shared)) {
3507 m_list_itr->status =
3508 ice_add_rule_internal(hw, ICE_SW_LKUP_MAC,
3509 m_list_itr);
3510 if (m_list_itr->status)
3511 return m_list_itr->status;
3512 }
3513 }
3514
3515 mutex_lock(rule_lock);
3516
3517 if (!num_unicast) {
3518 status = 0;
3519 goto ice_add_mac_exit;
3520 }
3521
3522 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules;
3523
3524
3525 s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule);
3526 s_rule = devm_kcalloc(ice_hw_to_dev(hw), num_unicast, s_rule_size,
3527 GFP_KERNEL);
3528 if (!s_rule) {
3529 status = -ENOMEM;
3530 goto ice_add_mac_exit;
3531 }
3532
3533 r_iter = s_rule;
3534 list_for_each_entry(m_list_itr, m_list, list_entry) {
3535 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
3536 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
3537
3538 if (is_unicast_ether_addr(mac_addr)) {
3539 ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter,
3540 ice_aqc_opc_add_sw_rules);
3541 r_iter = (typeof(s_rule))((u8 *)r_iter + s_rule_size);
3542 }
3543 }
3544
3545
3546 r_iter = s_rule;
3547
3548 for (total_elem_left = num_unicast; total_elem_left > 0;
3549 total_elem_left -= elem_sent) {
3550 struct ice_sw_rule_lkup_rx_tx *entry = r_iter;
3551
3552 elem_sent = min_t(u8, total_elem_left,
3553 (ICE_AQ_MAX_BUF_LEN / s_rule_size));
3554 status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size,
3555 elem_sent, ice_aqc_opc_add_sw_rules,
3556 NULL);
3557 if (status)
3558 goto ice_add_mac_exit;
3559 r_iter = (typeof(s_rule))
3560 ((u8 *)r_iter + (elem_sent * s_rule_size));
3561 }
3562
3563
3564 r_iter = s_rule;
3565 list_for_each_entry(m_list_itr, m_list, list_entry) {
3566 struct ice_fltr_info *f_info = &m_list_itr->fltr_info;
3567 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0];
3568 struct ice_fltr_mgmt_list_entry *fm_entry;
3569
3570 if (is_unicast_ether_addr(mac_addr)) {
3571 f_info->fltr_rule_id = le16_to_cpu(r_iter->index);
3572 f_info->fltr_act = ICE_FWD_TO_VSI;
3573
3574 fm_entry = devm_kzalloc(ice_hw_to_dev(hw),
3575 sizeof(*fm_entry), GFP_KERNEL);
3576 if (!fm_entry) {
3577 status = -ENOMEM;
3578 goto ice_add_mac_exit;
3579 }
3580 fm_entry->fltr_info = *f_info;
3581 fm_entry->vsi_count = 1;
3582
3583
3584
3585
3586 list_add(&fm_entry->list_entry, rule_head);
3587 r_iter = (typeof(s_rule))((u8 *)r_iter + s_rule_size);
3588 }
3589 }
3590
3591 ice_add_mac_exit:
3592 mutex_unlock(rule_lock);
3593 if (s_rule)
3594 devm_kfree(ice_hw_to_dev(hw), s_rule);
3595 return status;
3596 }
3597
3598
3599
3600
3601
3602
3603 static int
3604 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry)
3605 {
3606 struct ice_switch_info *sw = hw->switch_info;
3607 struct ice_fltr_mgmt_list_entry *v_list_itr;
3608 struct ice_fltr_info *new_fltr, *cur_fltr;
3609 enum ice_sw_lkup_type lkup_type;
3610 u16 vsi_list_id = 0, vsi_handle;
3611 struct mutex *rule_lock;
3612 int status = 0;
3613
3614 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle))
3615 return -EINVAL;
3616
3617 f_entry->fltr_info.fwd_id.hw_vsi_id =
3618 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle);
3619 new_fltr = &f_entry->fltr_info;
3620
3621
3622 if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID)
3623 return -EINVAL;
3624
3625 if (new_fltr->src_id != ICE_SRC_ID_VSI)
3626 return -EINVAL;
3627
3628 new_fltr->src = new_fltr->fwd_id.hw_vsi_id;
3629 lkup_type = new_fltr->lkup_type;
3630 vsi_handle = new_fltr->vsi_handle;
3631 rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
3632 mutex_lock(rule_lock);
3633 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr);
3634 if (!v_list_itr) {
3635 struct ice_vsi_list_map_info *map_info = NULL;
3636
3637 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) {
3638
3639
3640
3641
3642
3643 map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN,
3644 vsi_handle,
3645 &vsi_list_id);
3646 if (!map_info) {
3647 status = ice_create_vsi_list_rule(hw,
3648 &vsi_handle,
3649 1,
3650 &vsi_list_id,
3651 lkup_type);
3652 if (status)
3653 goto exit;
3654 }
3655
3656 new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST;
3657 new_fltr->fwd_id.vsi_list_id = vsi_list_id;
3658 }
3659
3660 status = ice_create_pkt_fwd_rule(hw, f_entry);
3661 if (!status) {
3662 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN,
3663 new_fltr);
3664 if (!v_list_itr) {
3665 status = -ENOENT;
3666 goto exit;
3667 }
3668
3669 if (map_info) {
3670 v_list_itr->vsi_list_info = map_info;
3671 map_info->ref_cnt++;
3672 } else {
3673 v_list_itr->vsi_list_info =
3674 ice_create_vsi_list_map(hw, &vsi_handle,
3675 1, vsi_list_id);
3676 }
3677 }
3678 } else if (v_list_itr->vsi_list_info->ref_cnt == 1) {
3679
3680
3681
3682 cur_fltr = &v_list_itr->fltr_info;
3683 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr,
3684 new_fltr);
3685 } else {
3686
3687
3688
3689
3690
3691 struct ice_fltr_info tmp_fltr;
3692 u16 vsi_handle_arr[2];
3693 u16 cur_handle;
3694
3695
3696
3697
3698 if (v_list_itr->vsi_count > 1 &&
3699 v_list_itr->vsi_list_info->ref_cnt > 1) {
3700 ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n");
3701 status = -EIO;
3702 goto exit;
3703 }
3704
3705 cur_handle =
3706 find_first_bit(v_list_itr->vsi_list_info->vsi_map,
3707 ICE_MAX_VSI);
3708
3709
3710 if (cur_handle == vsi_handle) {
3711 status = -EEXIST;
3712 goto exit;
3713 }
3714
3715 vsi_handle_arr[0] = cur_handle;
3716 vsi_handle_arr[1] = vsi_handle;
3717 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
3718 &vsi_list_id, lkup_type);
3719 if (status)
3720 goto exit;
3721
3722 tmp_fltr = v_list_itr->fltr_info;
3723 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id;
3724 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
3725 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
3726
3727
3728
3729 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
3730 if (status)
3731 goto exit;
3732
3733
3734
3735
3736 v_list_itr->vsi_list_info->ref_cnt--;
3737
3738
3739 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id;
3740 v_list_itr->vsi_list_info =
3741 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
3742 vsi_list_id);
3743 v_list_itr->vsi_count++;
3744 }
3745
3746 exit:
3747 mutex_unlock(rule_lock);
3748 return status;
3749 }
3750
3751
3752
3753
3754
3755
3756 int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list)
3757 {
3758 struct ice_fltr_list_entry *v_list_itr;
3759
3760 if (!v_list || !hw)
3761 return -EINVAL;
3762
3763 list_for_each_entry(v_list_itr, v_list, list_entry) {
3764 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN)
3765 return -EINVAL;
3766 v_list_itr->fltr_info.flag = ICE_FLTR_TX;
3767 v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr);
3768 if (v_list_itr->status)
3769 return v_list_itr->status;
3770 }
3771 return 0;
3772 }
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783 int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3784 {
3785 struct ice_fltr_list_entry *em_list_itr;
3786
3787 if (!em_list || !hw)
3788 return -EINVAL;
3789
3790 list_for_each_entry(em_list_itr, em_list, list_entry) {
3791 enum ice_sw_lkup_type l_type =
3792 em_list_itr->fltr_info.lkup_type;
3793
3794 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3795 l_type != ICE_SW_LKUP_ETHERTYPE)
3796 return -EINVAL;
3797
3798 em_list_itr->status = ice_add_rule_internal(hw, l_type,
3799 em_list_itr);
3800 if (em_list_itr->status)
3801 return em_list_itr->status;
3802 }
3803 return 0;
3804 }
3805
3806
3807
3808
3809
3810
3811 int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list)
3812 {
3813 struct ice_fltr_list_entry *em_list_itr, *tmp;
3814
3815 if (!em_list || !hw)
3816 return -EINVAL;
3817
3818 list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) {
3819 enum ice_sw_lkup_type l_type =
3820 em_list_itr->fltr_info.lkup_type;
3821
3822 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC &&
3823 l_type != ICE_SW_LKUP_ETHERTYPE)
3824 return -EINVAL;
3825
3826 em_list_itr->status = ice_remove_rule_internal(hw, l_type,
3827 em_list_itr);
3828 if (em_list_itr->status)
3829 return em_list_itr->status;
3830 }
3831 return 0;
3832 }
3833
3834
3835
3836
3837
3838
3839 static void
3840 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3841 {
3842 if (!list_empty(rule_head)) {
3843 struct ice_fltr_mgmt_list_entry *entry;
3844 struct ice_fltr_mgmt_list_entry *tmp;
3845
3846 list_for_each_entry_safe(entry, tmp, rule_head, list_entry) {
3847 list_del(&entry->list_entry);
3848 devm_kfree(ice_hw_to_dev(hw), entry);
3849 }
3850 }
3851 }
3852
3853
3854
3855
3856
3857
3858 static void
3859 ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head)
3860 {
3861 struct ice_adv_fltr_mgmt_list_entry *tmp_entry;
3862 struct ice_adv_fltr_mgmt_list_entry *lst_itr;
3863
3864 if (list_empty(rule_head))
3865 return;
3866
3867 list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) {
3868 list_del(&lst_itr->list_entry);
3869 devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups);
3870 devm_kfree(ice_hw_to_dev(hw), lst_itr);
3871 }
3872 }
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884 int
3885 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set,
3886 u8 direction)
3887 {
3888 struct ice_fltr_list_entry f_list_entry;
3889 struct ice_fltr_info f_info;
3890 struct ice_hw *hw = pi->hw;
3891 u16 hw_vsi_id;
3892 int status;
3893
3894 if (!ice_is_vsi_valid(hw, vsi_handle))
3895 return -EINVAL;
3896
3897 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
3898
3899 memset(&f_info, 0, sizeof(f_info));
3900
3901 f_info.lkup_type = ICE_SW_LKUP_DFLT;
3902 f_info.flag = direction;
3903 f_info.fltr_act = ICE_FWD_TO_VSI;
3904 f_info.fwd_id.hw_vsi_id = hw_vsi_id;
3905 f_info.vsi_handle = vsi_handle;
3906
3907 if (f_info.flag & ICE_FLTR_RX) {
3908 f_info.src = hw->port_info->lport;
3909 f_info.src_id = ICE_SRC_ID_LPORT;
3910 } else if (f_info.flag & ICE_FLTR_TX) {
3911 f_info.src_id = ICE_SRC_ID_VSI;
3912 f_info.src = hw_vsi_id;
3913 }
3914 f_list_entry.fltr_info = f_info;
3915
3916 if (set)
3917 status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT,
3918 &f_list_entry);
3919 else
3920 status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT,
3921 &f_list_entry);
3922
3923 return status;
3924 }
3925
3926
3927
3928
3929
3930
3931 static bool
3932 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle)
3933 {
3934 return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI &&
3935 fm_entry->fltr_info.vsi_handle == vsi_handle) ||
3936 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST &&
3937 fm_entry->vsi_list_info &&
3938 (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map))));
3939 }
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950 bool
3951 ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle,
3952 bool *rule_exists)
3953 {
3954 struct ice_fltr_mgmt_list_entry *fm_entry;
3955 struct ice_sw_recipe *recp_list;
3956 struct list_head *rule_head;
3957 struct mutex *rule_lock;
3958 bool ret = false;
3959
3960 recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT];
3961 rule_lock = &recp_list->filt_rule_lock;
3962 rule_head = &recp_list->filt_rules;
3963
3964 mutex_lock(rule_lock);
3965
3966 if (rule_exists && !list_empty(rule_head))
3967 *rule_exists = true;
3968
3969 list_for_each_entry(fm_entry, rule_head, list_entry) {
3970 if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) {
3971 ret = true;
3972 break;
3973 }
3974 }
3975
3976 mutex_unlock(rule_lock);
3977
3978 return ret;
3979 }
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993 static struct ice_fltr_mgmt_list_entry *
3994 ice_find_ucast_rule_entry(struct ice_hw *hw, u8 recp_id,
3995 struct ice_fltr_info *f_info)
3996 {
3997 struct ice_switch_info *sw = hw->switch_info;
3998 struct ice_fltr_mgmt_list_entry *list_itr;
3999 struct list_head *list_head;
4000
4001 list_head = &sw->recp_list[recp_id].filt_rules;
4002 list_for_each_entry(list_itr, list_head, list_entry) {
4003 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data,
4004 sizeof(f_info->l_data)) &&
4005 f_info->fwd_id.hw_vsi_id ==
4006 list_itr->fltr_info.fwd_id.hw_vsi_id &&
4007 f_info->flag == list_itr->fltr_info.flag)
4008 return list_itr;
4009 }
4010 return NULL;
4011 }
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026 int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list)
4027 {
4028 struct ice_fltr_list_entry *list_itr, *tmp;
4029 struct mutex *rule_lock;
4030
4031 if (!m_list)
4032 return -EINVAL;
4033
4034 rule_lock = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock;
4035 list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) {
4036 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type;
4037 u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0];
4038 u16 vsi_handle;
4039
4040 if (l_type != ICE_SW_LKUP_MAC)
4041 return -EINVAL;
4042
4043 vsi_handle = list_itr->fltr_info.vsi_handle;
4044 if (!ice_is_vsi_valid(hw, vsi_handle))
4045 return -EINVAL;
4046
4047 list_itr->fltr_info.fwd_id.hw_vsi_id =
4048 ice_get_hw_vsi_num(hw, vsi_handle);
4049 if (is_unicast_ether_addr(add) && !hw->ucast_shared) {
4050
4051
4052
4053
4054 mutex_lock(rule_lock);
4055 if (!ice_find_ucast_rule_entry(hw, ICE_SW_LKUP_MAC,
4056 &list_itr->fltr_info)) {
4057 mutex_unlock(rule_lock);
4058 return -ENOENT;
4059 }
4060 mutex_unlock(rule_lock);
4061 }
4062 list_itr->status = ice_remove_rule_internal(hw,
4063 ICE_SW_LKUP_MAC,
4064 list_itr);
4065 if (list_itr->status)
4066 return list_itr->status;
4067 }
4068 return 0;
4069 }
4070
4071
4072
4073
4074
4075
4076 int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list)
4077 {
4078 struct ice_fltr_list_entry *v_list_itr, *tmp;
4079
4080 if (!v_list || !hw)
4081 return -EINVAL;
4082
4083 list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
4084 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type;
4085
4086 if (l_type != ICE_SW_LKUP_VLAN)
4087 return -EINVAL;
4088 v_list_itr->status = ice_remove_rule_internal(hw,
4089 ICE_SW_LKUP_VLAN,
4090 v_list_itr);
4091 if (v_list_itr->status)
4092 return v_list_itr->status;
4093 }
4094 return 0;
4095 }
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110 static int
4111 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
4112 struct list_head *vsi_list_head,
4113 struct ice_fltr_info *fi)
4114 {
4115 struct ice_fltr_list_entry *tmp;
4116
4117
4118
4119
4120 tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL);
4121 if (!tmp)
4122 return -ENOMEM;
4123
4124 tmp->fltr_info = *fi;
4125
4126
4127
4128
4129
4130
4131 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI;
4132 tmp->fltr_info.vsi_handle = vsi_handle;
4133 tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4134
4135 list_add(&tmp->list_entry, vsi_list_head);
4136
4137 return 0;
4138 }
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153 static int
4154 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle,
4155 struct list_head *lkup_list_head,
4156 struct list_head *vsi_list_head)
4157 {
4158 struct ice_fltr_mgmt_list_entry *fm_entry;
4159 int status = 0;
4160
4161
4162 if (!ice_is_vsi_valid(hw, vsi_handle))
4163 return -EINVAL;
4164
4165 list_for_each_entry(fm_entry, lkup_list_head, list_entry) {
4166 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle))
4167 continue;
4168
4169 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4170 vsi_list_head,
4171 &fm_entry->fltr_info);
4172 if (status)
4173 return status;
4174 }
4175 return status;
4176 }
4177
4178
4179
4180
4181
4182
4183
4184
4185 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi)
4186 {
4187 u16 vid = fi->l_data.mac_vlan.vlan_id;
4188 u8 *macaddr = fi->l_data.mac.mac_addr;
4189 bool is_tx_fltr = false;
4190 u8 promisc_mask = 0;
4191
4192 if (fi->flag == ICE_FLTR_TX)
4193 is_tx_fltr = true;
4194
4195 if (is_broadcast_ether_addr(macaddr))
4196 promisc_mask |= is_tx_fltr ?
4197 ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX;
4198 else if (is_multicast_ether_addr(macaddr))
4199 promisc_mask |= is_tx_fltr ?
4200 ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX;
4201 else if (is_unicast_ether_addr(macaddr))
4202 promisc_mask |= is_tx_fltr ?
4203 ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX;
4204 if (vid)
4205 promisc_mask |= is_tx_fltr ?
4206 ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX;
4207
4208 return promisc_mask;
4209 }
4210
4211
4212
4213
4214
4215
4216
4217 static int
4218 ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list)
4219 {
4220 struct ice_fltr_list_entry *v_list_itr, *tmp;
4221
4222 list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) {
4223 v_list_itr->status =
4224 ice_remove_rule_internal(hw, recp_id, v_list_itr);
4225 if (v_list_itr->status)
4226 return v_list_itr->status;
4227 }
4228 return 0;
4229 }
4230
4231
4232
4233
4234
4235
4236
4237
4238 int
4239 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4240 u16 vid)
4241 {
4242 struct ice_switch_info *sw = hw->switch_info;
4243 struct ice_fltr_list_entry *fm_entry, *tmp;
4244 struct list_head remove_list_head;
4245 struct ice_fltr_mgmt_list_entry *itr;
4246 struct list_head *rule_head;
4247 struct mutex *rule_lock;
4248 int status = 0;
4249 u8 recipe_id;
4250
4251 if (!ice_is_vsi_valid(hw, vsi_handle))
4252 return -EINVAL;
4253
4254 if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX))
4255 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4256 else
4257 recipe_id = ICE_SW_LKUP_PROMISC;
4258
4259 rule_head = &sw->recp_list[recipe_id].filt_rules;
4260 rule_lock = &sw->recp_list[recipe_id].filt_rule_lock;
4261
4262 INIT_LIST_HEAD(&remove_list_head);
4263
4264 mutex_lock(rule_lock);
4265 list_for_each_entry(itr, rule_head, list_entry) {
4266 struct ice_fltr_info *fltr_info;
4267 u8 fltr_promisc_mask = 0;
4268
4269 if (!ice_vsi_uses_fltr(itr, vsi_handle))
4270 continue;
4271 fltr_info = &itr->fltr_info;
4272
4273 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN &&
4274 vid != fltr_info->l_data.mac_vlan.vlan_id)
4275 continue;
4276
4277 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info);
4278
4279
4280 if (fltr_promisc_mask & ~promisc_mask)
4281 continue;
4282
4283 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle,
4284 &remove_list_head,
4285 fltr_info);
4286 if (status) {
4287 mutex_unlock(rule_lock);
4288 goto free_fltr_list;
4289 }
4290 }
4291 mutex_unlock(rule_lock);
4292
4293 status = ice_remove_promisc(hw, recipe_id, &remove_list_head);
4294
4295 free_fltr_list:
4296 list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4297 list_del(&fm_entry->list_entry);
4298 devm_kfree(ice_hw_to_dev(hw), fm_entry);
4299 }
4300
4301 return status;
4302 }
4303
4304
4305
4306
4307
4308
4309
4310
4311 int
4312 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid)
4313 {
4314 enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR };
4315 struct ice_fltr_list_entry f_list_entry;
4316 struct ice_fltr_info new_fltr;
4317 bool is_tx_fltr;
4318 int status = 0;
4319 u16 hw_vsi_id;
4320 int pkt_type;
4321 u8 recipe_id;
4322
4323 if (!ice_is_vsi_valid(hw, vsi_handle))
4324 return -EINVAL;
4325 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
4326
4327 memset(&new_fltr, 0, sizeof(new_fltr));
4328
4329 if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) {
4330 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN;
4331 new_fltr.l_data.mac_vlan.vlan_id = vid;
4332 recipe_id = ICE_SW_LKUP_PROMISC_VLAN;
4333 } else {
4334 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC;
4335 recipe_id = ICE_SW_LKUP_PROMISC;
4336 }
4337
4338
4339
4340
4341
4342
4343 while (promisc_mask) {
4344 u8 *mac_addr;
4345
4346 pkt_type = 0;
4347 is_tx_fltr = false;
4348
4349 if (promisc_mask & ICE_PROMISC_UCAST_RX) {
4350 promisc_mask &= ~ICE_PROMISC_UCAST_RX;
4351 pkt_type = UCAST_FLTR;
4352 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) {
4353 promisc_mask &= ~ICE_PROMISC_UCAST_TX;
4354 pkt_type = UCAST_FLTR;
4355 is_tx_fltr = true;
4356 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) {
4357 promisc_mask &= ~ICE_PROMISC_MCAST_RX;
4358 pkt_type = MCAST_FLTR;
4359 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) {
4360 promisc_mask &= ~ICE_PROMISC_MCAST_TX;
4361 pkt_type = MCAST_FLTR;
4362 is_tx_fltr = true;
4363 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) {
4364 promisc_mask &= ~ICE_PROMISC_BCAST_RX;
4365 pkt_type = BCAST_FLTR;
4366 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) {
4367 promisc_mask &= ~ICE_PROMISC_BCAST_TX;
4368 pkt_type = BCAST_FLTR;
4369 is_tx_fltr = true;
4370 }
4371
4372
4373 if (promisc_mask & ICE_PROMISC_VLAN_RX) {
4374 promisc_mask &= ~ICE_PROMISC_VLAN_RX;
4375 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) {
4376 promisc_mask &= ~ICE_PROMISC_VLAN_TX;
4377 is_tx_fltr = true;
4378 }
4379
4380
4381 mac_addr = new_fltr.l_data.mac.mac_addr;
4382 if (pkt_type == BCAST_FLTR) {
4383 eth_broadcast_addr(mac_addr);
4384 } else if (pkt_type == MCAST_FLTR ||
4385 pkt_type == UCAST_FLTR) {
4386
4387 ether_addr_copy(mac_addr, dummy_eth_header);
4388 if (pkt_type == MCAST_FLTR)
4389 mac_addr[0] |= 0x1;
4390 }
4391
4392
4393 new_fltr.flag = 0;
4394 if (is_tx_fltr) {
4395 new_fltr.flag |= ICE_FLTR_TX;
4396 new_fltr.src = hw_vsi_id;
4397 } else {
4398 new_fltr.flag |= ICE_FLTR_RX;
4399 new_fltr.src = hw->port_info->lport;
4400 }
4401
4402 new_fltr.fltr_act = ICE_FWD_TO_VSI;
4403 new_fltr.vsi_handle = vsi_handle;
4404 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id;
4405 f_list_entry.fltr_info = new_fltr;
4406
4407 status = ice_add_rule_internal(hw, recipe_id, &f_list_entry);
4408 if (status)
4409 goto set_promisc_exit;
4410 }
4411
4412 set_promisc_exit:
4413 return status;
4414 }
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425 int
4426 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask,
4427 bool rm_vlan_promisc)
4428 {
4429 struct ice_switch_info *sw = hw->switch_info;
4430 struct ice_fltr_list_entry *list_itr, *tmp;
4431 struct list_head vsi_list_head;
4432 struct list_head *vlan_head;
4433 struct mutex *vlan_lock;
4434 u16 vlan_id;
4435 int status;
4436
4437 INIT_LIST_HEAD(&vsi_list_head);
4438 vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock;
4439 vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules;
4440 mutex_lock(vlan_lock);
4441 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head,
4442 &vsi_list_head);
4443 mutex_unlock(vlan_lock);
4444 if (status)
4445 goto free_fltr_list;
4446
4447 list_for_each_entry(list_itr, &vsi_list_head, list_entry) {
4448
4449
4450
4451 if (ice_is_dvm_ena(hw) &&
4452 list_itr->fltr_info.l_data.vlan.tpid == 0)
4453 continue;
4454
4455 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id;
4456 if (rm_vlan_promisc)
4457 status = ice_clear_vsi_promisc(hw, vsi_handle,
4458 promisc_mask, vlan_id);
4459 else
4460 status = ice_set_vsi_promisc(hw, vsi_handle,
4461 promisc_mask, vlan_id);
4462 if (status && status != -EEXIST)
4463 break;
4464 }
4465
4466 free_fltr_list:
4467 list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) {
4468 list_del(&list_itr->list_entry);
4469 devm_kfree(ice_hw_to_dev(hw), list_itr);
4470 }
4471 return status;
4472 }
4473
4474
4475
4476
4477
4478
4479
4480 static void
4481 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle,
4482 enum ice_sw_lkup_type lkup)
4483 {
4484 struct ice_switch_info *sw = hw->switch_info;
4485 struct ice_fltr_list_entry *fm_entry;
4486 struct list_head remove_list_head;
4487 struct list_head *rule_head;
4488 struct ice_fltr_list_entry *tmp;
4489 struct mutex *rule_lock;
4490 int status;
4491
4492 INIT_LIST_HEAD(&remove_list_head);
4493 rule_lock = &sw->recp_list[lkup].filt_rule_lock;
4494 rule_head = &sw->recp_list[lkup].filt_rules;
4495 mutex_lock(rule_lock);
4496 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head,
4497 &remove_list_head);
4498 mutex_unlock(rule_lock);
4499 if (status)
4500 goto free_fltr_list;
4501
4502 switch (lkup) {
4503 case ICE_SW_LKUP_MAC:
4504 ice_remove_mac(hw, &remove_list_head);
4505 break;
4506 case ICE_SW_LKUP_VLAN:
4507 ice_remove_vlan(hw, &remove_list_head);
4508 break;
4509 case ICE_SW_LKUP_PROMISC:
4510 case ICE_SW_LKUP_PROMISC_VLAN:
4511 ice_remove_promisc(hw, lkup, &remove_list_head);
4512 break;
4513 case ICE_SW_LKUP_MAC_VLAN:
4514 case ICE_SW_LKUP_ETHERTYPE:
4515 case ICE_SW_LKUP_ETHERTYPE_MAC:
4516 case ICE_SW_LKUP_DFLT:
4517 case ICE_SW_LKUP_LAST:
4518 default:
4519 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup);
4520 break;
4521 }
4522
4523 free_fltr_list:
4524 list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) {
4525 list_del(&fm_entry->list_entry);
4526 devm_kfree(ice_hw_to_dev(hw), fm_entry);
4527 }
4528 }
4529
4530
4531
4532
4533
4534
4535 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle)
4536 {
4537 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC);
4538 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN);
4539 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC);
4540 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN);
4541 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT);
4542 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE);
4543 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC);
4544 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN);
4545 }
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555 int
4556 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4557 u16 *counter_id)
4558 {
4559 struct ice_aqc_alloc_free_res_elem *buf;
4560 u16 buf_len;
4561 int status;
4562
4563
4564 buf_len = struct_size(buf, elem, 1);
4565 buf = kzalloc(buf_len, GFP_KERNEL);
4566 if (!buf)
4567 return -ENOMEM;
4568
4569 buf->num_elems = cpu_to_le16(num_items);
4570 buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
4571 ICE_AQC_RES_TYPE_M) | alloc_shared);
4572
4573 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
4574 ice_aqc_opc_alloc_res, NULL);
4575 if (status)
4576 goto exit;
4577
4578 *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp);
4579
4580 exit:
4581 kfree(buf);
4582 return status;
4583 }
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593 int
4594 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items,
4595 u16 counter_id)
4596 {
4597 struct ice_aqc_alloc_free_res_elem *buf;
4598 u16 buf_len;
4599 int status;
4600
4601
4602 buf_len = struct_size(buf, elem, 1);
4603 buf = kzalloc(buf_len, GFP_KERNEL);
4604 if (!buf)
4605 return -ENOMEM;
4606
4607 buf->num_elems = cpu_to_le16(num_items);
4608 buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) &
4609 ICE_AQC_RES_TYPE_M) | alloc_shared);
4610 buf->elem[0].e.sw_resp = cpu_to_le16(counter_id);
4611
4612 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len,
4613 ice_aqc_opc_free_res, NULL);
4614 if (status)
4615 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n");
4616
4617 kfree(buf);
4618 return status;
4619 }
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
4631 { ICE_MAC_OFOS, { 0, 2, 4, 6, 8, 10, 12 } },
4632 { ICE_MAC_IL, { 0, 2, 4, 6, 8, 10, 12 } },
4633 { ICE_ETYPE_OL, { 0 } },
4634 { ICE_ETYPE_IL, { 0 } },
4635 { ICE_VLAN_OFOS, { 2, 0 } },
4636 { ICE_IPV4_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
4637 { ICE_IPV4_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } },
4638 { ICE_IPV6_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
4639 26, 28, 30, 32, 34, 36, 38 } },
4640 { ICE_IPV6_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24,
4641 26, 28, 30, 32, 34, 36, 38 } },
4642 { ICE_TCP_IL, { 0, 2 } },
4643 { ICE_UDP_OF, { 0, 2 } },
4644 { ICE_UDP_ILOS, { 0, 2 } },
4645 { ICE_VXLAN, { 8, 10, 12, 14 } },
4646 { ICE_GENEVE, { 8, 10, 12, 14 } },
4647 { ICE_NVGRE, { 0, 2, 4, 6 } },
4648 { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
4649 { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } },
4650 { ICE_PPPOE, { 0, 2, 4, 6 } },
4651 { ICE_VLAN_EX, { 2, 0 } },
4652 { ICE_VLAN_IN, { 2, 0 } },
4653 };
4654
4655 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
4656 { ICE_MAC_OFOS, ICE_MAC_OFOS_HW },
4657 { ICE_MAC_IL, ICE_MAC_IL_HW },
4658 { ICE_ETYPE_OL, ICE_ETYPE_OL_HW },
4659 { ICE_ETYPE_IL, ICE_ETYPE_IL_HW },
4660 { ICE_VLAN_OFOS, ICE_VLAN_OL_HW },
4661 { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW },
4662 { ICE_IPV4_IL, ICE_IPV4_IL_HW },
4663 { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW },
4664 { ICE_IPV6_IL, ICE_IPV6_IL_HW },
4665 { ICE_TCP_IL, ICE_TCP_IL_HW },
4666 { ICE_UDP_OF, ICE_UDP_OF_HW },
4667 { ICE_UDP_ILOS, ICE_UDP_ILOS_HW },
4668 { ICE_VXLAN, ICE_UDP_OF_HW },
4669 { ICE_GENEVE, ICE_UDP_OF_HW },
4670 { ICE_NVGRE, ICE_GRE_OF_HW },
4671 { ICE_GTP, ICE_UDP_OF_HW },
4672 { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
4673 { ICE_PPPOE, ICE_PPPOE_HW },
4674 { ICE_VLAN_EX, ICE_VLAN_OF_HW },
4675 { ICE_VLAN_IN, ICE_VLAN_OL_HW },
4676 };
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686 static u16
4687 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts,
4688 enum ice_sw_tunnel_type tun_type)
4689 {
4690 bool refresh_required = true;
4691 struct ice_sw_recipe *recp;
4692 u8 i;
4693
4694
4695 recp = hw->switch_info->recp_list;
4696 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
4697
4698
4699
4700
4701
4702 if (!recp[i].recp_created)
4703 if (ice_get_recp_frm_fw(hw,
4704 hw->switch_info->recp_list, i,
4705 &refresh_required))
4706 continue;
4707
4708
4709 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl &
4710 ICE_AQ_RECIPE_ACT_INV_ACT)
4711 continue;
4712
4713
4714 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) {
4715 struct ice_fv_word *ar = recp[i].lkup_exts.fv_words;
4716 struct ice_fv_word *be = lkup_exts->fv_words;
4717 u16 *cr = recp[i].lkup_exts.field_mask;
4718 u16 *de = lkup_exts->field_mask;
4719 bool found = true;
4720 u8 pe, qr;
4721
4722
4723
4724
4725 for (pe = 0; pe < lkup_exts->n_val_words; pe++) {
4726 for (qr = 0; qr < recp[i].lkup_exts.n_val_words;
4727 qr++) {
4728 if (ar[qr].off == be[pe].off &&
4729 ar[qr].prot_id == be[pe].prot_id &&
4730 cr[qr] == de[pe])
4731
4732
4733
4734 break;
4735 }
4736
4737
4738
4739
4740
4741
4742 if (qr >= recp[i].lkup_exts.n_val_words) {
4743 found = false;
4744 break;
4745 }
4746 }
4747
4748
4749
4750
4751 if (found && recp[i].tun_type == tun_type)
4752 return i;
4753 }
4754 }
4755 return ICE_MAX_NUM_RECIPES;
4756 }
4757
4758
4759
4760
4761
4762
4763
4764
4765 void ice_change_proto_id_to_dvm(void)
4766 {
4767 u8 i;
4768
4769 for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4770 if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS &&
4771 ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW)
4772 ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW;
4773 }
4774
4775
4776
4777
4778
4779
4780
4781
4782 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id)
4783 {
4784 u8 i;
4785
4786 for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++)
4787 if (ice_prot_id_tbl[i].type == type) {
4788 *id = ice_prot_id_tbl[i].protocol_id;
4789 return true;
4790 }
4791 return false;
4792 }
4793
4794
4795
4796
4797
4798
4799
4800
4801 static u8
4802 ice_fill_valid_words(struct ice_adv_lkup_elem *rule,
4803 struct ice_prot_lkup_ext *lkup_exts)
4804 {
4805 u8 j, word, prot_id, ret_val;
4806
4807 if (!ice_prot_type_to_id(rule->type, &prot_id))
4808 return 0;
4809
4810 word = lkup_exts->n_val_words;
4811
4812 for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++)
4813 if (((u16 *)&rule->m_u)[j] &&
4814 rule->type < ARRAY_SIZE(ice_prot_ext)) {
4815
4816 if (word >= ICE_MAX_CHAIN_WORDS)
4817 return 0;
4818 lkup_exts->fv_words[word].off =
4819 ice_prot_ext[rule->type].offs[j];
4820 lkup_exts->fv_words[word].prot_id =
4821 ice_prot_id_tbl[rule->type].protocol_id;
4822 lkup_exts->field_mask[word] =
4823 be16_to_cpu(((__force __be16 *)&rule->m_u)[j]);
4824 word++;
4825 }
4826
4827 ret_val = word - lkup_exts->n_val_words;
4828 lkup_exts->n_val_words = word;
4829
4830 return ret_val;
4831 }
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844 static int
4845 ice_create_first_fit_recp_def(struct ice_hw *hw,
4846 struct ice_prot_lkup_ext *lkup_exts,
4847 struct list_head *rg_list,
4848 u8 *recp_cnt)
4849 {
4850 struct ice_pref_recipe_group *grp = NULL;
4851 u8 j;
4852
4853 *recp_cnt = 0;
4854
4855
4856
4857
4858 for (j = 0; j < lkup_exts->n_val_words; j++)
4859 if (!test_bit(j, lkup_exts->done)) {
4860 if (!grp ||
4861 grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) {
4862 struct ice_recp_grp_entry *entry;
4863
4864 entry = devm_kzalloc(ice_hw_to_dev(hw),
4865 sizeof(*entry),
4866 GFP_KERNEL);
4867 if (!entry)
4868 return -ENOMEM;
4869 list_add(&entry->l_entry, rg_list);
4870 grp = &entry->r_group;
4871 (*recp_cnt)++;
4872 }
4873
4874 grp->pairs[grp->n_val_pairs].prot_id =
4875 lkup_exts->fv_words[j].prot_id;
4876 grp->pairs[grp->n_val_pairs].off =
4877 lkup_exts->fv_words[j].off;
4878 grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j];
4879 grp->n_val_pairs++;
4880 }
4881
4882 return 0;
4883 }
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894 static int
4895 ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list,
4896 struct list_head *rg_list)
4897 {
4898 struct ice_sw_fv_list_entry *fv;
4899 struct ice_recp_grp_entry *rg;
4900 struct ice_fv_word *fv_ext;
4901
4902 if (list_empty(fv_list))
4903 return 0;
4904
4905 fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry,
4906 list_entry);
4907 fv_ext = fv->fv_ptr->ew;
4908
4909 list_for_each_entry(rg, rg_list, l_entry) {
4910 u8 i;
4911
4912 for (i = 0; i < rg->r_group.n_val_pairs; i++) {
4913 struct ice_fv_word *pr;
4914 bool found = false;
4915 u16 mask;
4916 u8 j;
4917
4918 pr = &rg->r_group.pairs[i];
4919 mask = rg->r_group.mask[i];
4920
4921 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
4922 if (fv_ext[j].prot_id == pr->prot_id &&
4923 fv_ext[j].off == pr->off) {
4924 found = true;
4925
4926
4927 rg->fv_idx[i] = j;
4928 rg->fv_mask[i] = mask;
4929 break;
4930 }
4931
4932
4933
4934
4935 if (!found)
4936 return -EINVAL;
4937 }
4938 }
4939
4940 return 0;
4941 }
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969 static u16
4970 ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
4971 unsigned long *free_idx)
4972 {
4973 DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS);
4974 DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES);
4975 DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS);
4976 u16 bit;
4977
4978 bitmap_zero(recipes, ICE_MAX_NUM_RECIPES);
4979 bitmap_zero(used_idx, ICE_MAX_FV_WORDS);
4980
4981 bitmap_fill(possible_idx, ICE_MAX_FV_WORDS);
4982
4983
4984
4985
4986
4987
4988 for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) {
4989 bitmap_or(recipes, recipes, profile_to_recipe[bit],
4990 ICE_MAX_NUM_RECIPES);
4991 bitmap_and(possible_idx, possible_idx,
4992 hw->switch_info->prof_res_bm[bit],
4993 ICE_MAX_FV_WORDS);
4994 }
4995
4996
4997
4998
4999 for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES)
5000 bitmap_or(used_idx, used_idx,
5001 hw->switch_info->recp_list[bit].res_idxs,
5002 ICE_MAX_FV_WORDS);
5003
5004 bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS);
5005
5006
5007 return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS);
5008 }
5009
5010
5011
5012
5013
5014
5015
5016 static int
5017 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
5018 unsigned long *profiles)
5019 {
5020 DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
5021 struct ice_aqc_recipe_data_elem *tmp;
5022 struct ice_aqc_recipe_data_elem *buf;
5023 struct ice_recp_grp_entry *entry;
5024 u16 free_res_idx;
5025 u16 recipe_count;
5026 u8 chain_idx;
5027 u8 recps = 0;
5028 int status;
5029
5030
5031
5032
5033
5034
5035
5036 bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS);
5037 free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm);
5038
5039 ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n",
5040 free_res_idx, rm->n_grp_count);
5041
5042 if (rm->n_grp_count > 1) {
5043 if (rm->n_grp_count > free_res_idx)
5044 return -ENOSPC;
5045
5046 rm->n_grp_count++;
5047 }
5048
5049 if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE)
5050 return -ENOSPC;
5051
5052 tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL);
5053 if (!tmp)
5054 return -ENOMEM;
5055
5056 buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf),
5057 GFP_KERNEL);
5058 if (!buf) {
5059 status = -ENOMEM;
5060 goto err_mem;
5061 }
5062
5063 bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES);
5064 recipe_count = ICE_MAX_NUM_RECIPES;
5065 status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC,
5066 NULL);
5067 if (status || recipe_count == 0)
5068 goto err_unroll;
5069
5070
5071
5072
5073 chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS);
5074 list_for_each_entry(entry, &rm->rg_list, l_entry) {
5075 u8 i;
5076
5077 status = ice_alloc_recipe(hw, &entry->rid);
5078 if (status)
5079 goto err_unroll;
5080
5081
5082
5083
5084 tmp[0].content.result_indx = 0;
5085
5086 buf[recps] = tmp[0];
5087 buf[recps].recipe_indx = (u8)entry->rid;
5088
5089
5090
5091 buf[recps].content.rid = 0;
5092 memset(&buf[recps].content.lkup_indx, 0,
5093 sizeof(buf[recps].content.lkup_indx));
5094
5095
5096 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
5097 buf[recps].content.mask[0] =
5098 cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
5099
5100
5101
5102 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
5103 buf[recps].content.lkup_indx[i] = 0x80;
5104 buf[recps].content.mask[i] = 0;
5105 }
5106
5107 for (i = 0; i < entry->r_group.n_val_pairs; i++) {
5108 buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i];
5109 buf[recps].content.mask[i + 1] =
5110 cpu_to_le16(entry->fv_mask[i]);
5111 }
5112
5113 if (rm->n_grp_count > 1) {
5114
5115
5116
5117 if (chain_idx >= ICE_MAX_FV_WORDS) {
5118 ice_debug(hw, ICE_DBG_SW, "No chain index available\n");
5119 status = -ENOSPC;
5120 goto err_unroll;
5121 }
5122
5123 entry->chain_idx = chain_idx;
5124 buf[recps].content.result_indx =
5125 ICE_AQ_RECIPE_RESULT_EN |
5126 ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) &
5127 ICE_AQ_RECIPE_RESULT_DATA_M);
5128 clear_bit(chain_idx, result_idx_bm);
5129 chain_idx = find_first_bit(result_idx_bm,
5130 ICE_MAX_FV_WORDS);
5131 }
5132
5133
5134 bitmap_zero((unsigned long *)buf[recps].recipe_bitmap,
5135 ICE_MAX_NUM_RECIPES);
5136 set_bit(buf[recps].recipe_indx,
5137 (unsigned long *)buf[recps].recipe_bitmap);
5138 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
5139 recps++;
5140 }
5141
5142 if (rm->n_grp_count == 1) {
5143 rm->root_rid = buf[0].recipe_indx;
5144 set_bit(buf[0].recipe_indx, rm->r_bitmap);
5145 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT;
5146 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) {
5147 memcpy(buf[0].recipe_bitmap, rm->r_bitmap,
5148 sizeof(buf[0].recipe_bitmap));
5149 } else {
5150 status = -EINVAL;
5151 goto err_unroll;
5152 }
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164 buf[0].content.act_ctrl_fwd_priority = rm->priority;
5165 } else {
5166 struct ice_recp_grp_entry *last_chain_entry;
5167 u16 rid, i;
5168
5169
5170
5171
5172 status = ice_alloc_recipe(hw, &rid);
5173 if (status)
5174 goto err_unroll;
5175
5176 buf[recps].recipe_indx = (u8)rid;
5177 buf[recps].content.rid = (u8)rid;
5178 buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT;
5179
5180
5181
5182 last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw),
5183 sizeof(*last_chain_entry),
5184 GFP_KERNEL);
5185 if (!last_chain_entry) {
5186 status = -ENOMEM;
5187 goto err_unroll;
5188 }
5189 last_chain_entry->rid = rid;
5190 memset(&buf[recps].content.lkup_indx, 0,
5191 sizeof(buf[recps].content.lkup_indx));
5192
5193 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX;
5194 buf[recps].content.mask[0] =
5195 cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK);
5196 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) {
5197 buf[recps].content.lkup_indx[i] =
5198 ICE_AQ_RECIPE_LKUP_IGNORE;
5199 buf[recps].content.mask[i] = 0;
5200 }
5201
5202 i = 1;
5203
5204 set_bit(rid, rm->r_bitmap);
5205
5206
5207
5208 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND;
5209 list_for_each_entry(entry, &rm->rg_list, l_entry) {
5210 last_chain_entry->fv_idx[i] = entry->chain_idx;
5211 buf[recps].content.lkup_indx[i] = entry->chain_idx;
5212 buf[recps].content.mask[i++] = cpu_to_le16(0xFFFF);
5213 set_bit(entry->rid, rm->r_bitmap);
5214 }
5215 list_add(&last_chain_entry->l_entry, &rm->rg_list);
5216 if (sizeof(buf[recps].recipe_bitmap) >=
5217 sizeof(rm->r_bitmap)) {
5218 memcpy(buf[recps].recipe_bitmap, rm->r_bitmap,
5219 sizeof(buf[recps].recipe_bitmap));
5220 } else {
5221 status = -EINVAL;
5222 goto err_unroll;
5223 }
5224 buf[recps].content.act_ctrl_fwd_priority = rm->priority;
5225
5226 recps++;
5227 rm->root_rid = (u8)rid;
5228 }
5229 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5230 if (status)
5231 goto err_unroll;
5232
5233 status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL);
5234 ice_release_change_lock(hw);
5235 if (status)
5236 goto err_unroll;
5237
5238
5239
5240
5241 list_for_each_entry(entry, &rm->rg_list, l_entry) {
5242 struct ice_switch_info *sw = hw->switch_info;
5243 bool is_root, idx_found = false;
5244 struct ice_sw_recipe *recp;
5245 u16 idx, buf_idx = 0;
5246
5247
5248 for (idx = 0; idx < rm->n_grp_count; idx++)
5249 if (buf[idx].recipe_indx == entry->rid) {
5250 buf_idx = idx;
5251 idx_found = true;
5252 }
5253
5254 if (!idx_found) {
5255 status = -EIO;
5256 goto err_unroll;
5257 }
5258
5259 recp = &sw->recp_list[entry->rid];
5260 is_root = (rm->root_rid == entry->rid);
5261 recp->is_root = is_root;
5262
5263 recp->root_rid = entry->rid;
5264 recp->big_recp = (is_root && rm->n_grp_count > 1);
5265
5266 memcpy(&recp->ext_words, entry->r_group.pairs,
5267 entry->r_group.n_val_pairs * sizeof(struct ice_fv_word));
5268
5269 memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap,
5270 sizeof(recp->r_bitmap));
5271
5272
5273
5274
5275 ice_collect_result_idx(&buf[buf_idx], recp);
5276
5277
5278
5279
5280 if (!is_root)
5281 ice_collect_result_idx(&buf[buf_idx],
5282 &sw->recp_list[rm->root_rid]);
5283
5284 recp->n_ext_words = entry->r_group.n_val_pairs;
5285 recp->chain_idx = entry->chain_idx;
5286 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
5287 recp->n_grp_count = rm->n_grp_count;
5288 recp->tun_type = rm->tun_type;
5289 recp->recp_created = true;
5290 }
5291 rm->root_buf = buf;
5292 kfree(tmp);
5293 return status;
5294
5295 err_unroll:
5296 err_mem:
5297 kfree(tmp);
5298 devm_kfree(ice_hw_to_dev(hw), buf);
5299 return status;
5300 }
5301
5302
5303
5304
5305
5306
5307
5308 static int
5309 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm,
5310 struct ice_prot_lkup_ext *lkup_exts)
5311 {
5312 u8 recp_count = 0;
5313 int status;
5314
5315 rm->n_grp_count = 0;
5316
5317
5318
5319
5320 status = ice_create_first_fit_recp_def(hw, lkup_exts,
5321 &rm->rg_list, &recp_count);
5322 if (!status) {
5323 rm->n_grp_count += recp_count;
5324 rm->n_ext_words = lkup_exts->n_val_words;
5325 memcpy(&rm->ext_words, lkup_exts->fv_words,
5326 sizeof(rm->ext_words));
5327 memcpy(rm->word_masks, lkup_exts->field_mask,
5328 sizeof(rm->word_masks));
5329 }
5330
5331 return status;
5332 }
5333
5334
5335
5336
5337
5338
5339 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
5340 {
5341 switch (tun_type) {
5342 case ICE_SW_TUN_GENEVE:
5343 case ICE_SW_TUN_VXLAN:
5344 case ICE_SW_TUN_NVGRE:
5345 case ICE_SW_TUN_GTPU:
5346 case ICE_SW_TUN_GTPC:
5347 *mask = ICE_TUN_FLAG_MASK;
5348 return true;
5349
5350 default:
5351 *mask = 0;
5352 return false;
5353 }
5354 }
5355
5356
5357
5358
5359
5360
5361
5362 static int
5363 ice_add_special_words(struct ice_adv_rule_info *rinfo,
5364 struct ice_prot_lkup_ext *lkup_exts, bool dvm_ena)
5365 {
5366 u16 mask;
5367
5368
5369
5370
5371 if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
5372 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
5373 u8 word = lkup_exts->n_val_words++;
5374
5375 lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
5376 lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
5377 lkup_exts->field_mask[word] = mask;
5378 } else {
5379 return -ENOSPC;
5380 }
5381 }
5382
5383 if (rinfo->vlan_type != 0 && dvm_ena) {
5384 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
5385 u8 word = lkup_exts->n_val_words++;
5386
5387 lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
5388 lkup_exts->fv_words[word].off = ICE_VLAN_FLAG_MDID_OFF;
5389 lkup_exts->field_mask[word] =
5390 ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK;
5391 } else {
5392 return -ENOSPC;
5393 }
5394 }
5395
5396 return 0;
5397 }
5398
5399
5400
5401
5402
5403
5404 static void
5405 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
5406 unsigned long *bm)
5407 {
5408 enum ice_prof_type prof_type;
5409
5410 bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
5411
5412 switch (rinfo->tun_type) {
5413 case ICE_NON_TUN:
5414 prof_type = ICE_PROF_NON_TUN;
5415 break;
5416 case ICE_ALL_TUNNELS:
5417 prof_type = ICE_PROF_TUN_ALL;
5418 break;
5419 case ICE_SW_TUN_GENEVE:
5420 case ICE_SW_TUN_VXLAN:
5421 prof_type = ICE_PROF_TUN_UDP;
5422 break;
5423 case ICE_SW_TUN_NVGRE:
5424 prof_type = ICE_PROF_TUN_GRE;
5425 break;
5426 case ICE_SW_TUN_GTPU:
5427 prof_type = ICE_PROF_TUN_GTPU;
5428 break;
5429 case ICE_SW_TUN_GTPC:
5430 prof_type = ICE_PROF_TUN_GTPC;
5431 break;
5432 case ICE_SW_TUN_AND_NON_TUN:
5433 default:
5434 prof_type = ICE_PROF_ALL;
5435 break;
5436 }
5437
5438 ice_get_sw_fv_bitmap(hw, prof_type, bm);
5439 }
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450 static int
5451 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5452 u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid)
5453 {
5454 DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES);
5455 DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES);
5456 struct ice_prot_lkup_ext *lkup_exts;
5457 struct ice_recp_grp_entry *r_entry;
5458 struct ice_sw_fv_list_entry *fvit;
5459 struct ice_recp_grp_entry *r_tmp;
5460 struct ice_sw_fv_list_entry *tmp;
5461 struct ice_sw_recipe *rm;
5462 int status = 0;
5463 u8 i;
5464
5465 if (!lkups_cnt)
5466 return -EINVAL;
5467
5468 lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL);
5469 if (!lkup_exts)
5470 return -ENOMEM;
5471
5472
5473
5474
5475 for (i = 0; i < lkups_cnt; i++) {
5476 u16 count;
5477
5478 if (lkups[i].type >= ICE_PROTOCOL_LAST) {
5479 status = -EIO;
5480 goto err_free_lkup_exts;
5481 }
5482
5483 count = ice_fill_valid_words(&lkups[i], lkup_exts);
5484 if (!count) {
5485 status = -EIO;
5486 goto err_free_lkup_exts;
5487 }
5488 }
5489
5490 rm = kzalloc(sizeof(*rm), GFP_KERNEL);
5491 if (!rm) {
5492 status = -ENOMEM;
5493 goto err_free_lkup_exts;
5494 }
5495
5496
5497
5498
5499 INIT_LIST_HEAD(&rm->fv_list);
5500 INIT_LIST_HEAD(&rm->rg_list);
5501
5502
5503
5504
5505
5506 ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap);
5507
5508 status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list);
5509 if (status)
5510 goto err_unroll;
5511
5512
5513
5514
5515 status = ice_add_special_words(rinfo, lkup_exts, ice_is_dvm_ena(hw));
5516 if (status)
5517 goto err_free_lkup_exts;
5518
5519
5520
5521
5522 status = ice_create_recipe_group(hw, rm, lkup_exts);
5523 if (status)
5524 goto err_unroll;
5525
5526
5527 rm->priority = (u8)rinfo->priority;
5528
5529
5530
5531
5532 status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list);
5533 if (status)
5534 goto err_unroll;
5535
5536
5537 bitmap_zero(profiles, ICE_MAX_NUM_PROFILES);
5538 list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5539 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id);
5540 set_bit((u16)fvit->profile_id, profiles);
5541 }
5542
5543
5544 *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type);
5545 if (*rid < ICE_MAX_NUM_RECIPES)
5546
5547 goto err_unroll;
5548
5549 rm->tun_type = rinfo->tun_type;
5550
5551 status = ice_add_sw_recipe(hw, rm, profiles);
5552 if (status)
5553 goto err_unroll;
5554
5555
5556
5557
5558 list_for_each_entry(fvit, &rm->fv_list, list_entry) {
5559 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
5560 u16 j;
5561
5562 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id,
5563 (u8 *)r_bitmap, NULL);
5564 if (status)
5565 goto err_unroll;
5566
5567 bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap,
5568 ICE_MAX_NUM_RECIPES);
5569 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
5570 if (status)
5571 goto err_unroll;
5572
5573 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id,
5574 (u8 *)r_bitmap,
5575 NULL);
5576 ice_release_change_lock(hw);
5577
5578 if (status)
5579 goto err_unroll;
5580
5581
5582 bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap,
5583 ICE_MAX_NUM_RECIPES);
5584
5585
5586 for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES)
5587 set_bit((u16)fvit->profile_id, recipe_to_profile[j]);
5588 }
5589
5590 *rid = rm->root_rid;
5591 memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts,
5592 sizeof(*lkup_exts));
5593 err_unroll:
5594 list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) {
5595 list_del(&r_entry->l_entry);
5596 devm_kfree(ice_hw_to_dev(hw), r_entry);
5597 }
5598
5599 list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) {
5600 list_del(&fvit->list_entry);
5601 devm_kfree(ice_hw_to_dev(hw), fvit);
5602 }
5603
5604 if (rm->root_buf)
5605 devm_kfree(ice_hw_to_dev(hw), rm->root_buf);
5606
5607 kfree(rm);
5608
5609 err_free_lkup_exts:
5610 kfree(lkup_exts);
5611
5612 return status;
5613 }
5614
5615
5616
5617
5618
5619
5620
5621 static struct ice_dummy_pkt_profile *
5622 ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt,
5623 u32 num_vlan)
5624 {
5625 struct ice_dummy_pkt_profile *profile;
5626 struct ice_dummy_pkt_offsets *offsets;
5627 u32 buf_len, off, etype_off, i;
5628 u8 *pkt;
5629
5630 if (num_vlan < 1 || num_vlan > 2)
5631 return ERR_PTR(-EINVAL);
5632
5633 off = num_vlan * VLAN_HLEN;
5634
5635 buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) +
5636 dummy_pkt->offsets_len;
5637 offsets = kzalloc(buf_len, GFP_KERNEL);
5638 if (!offsets)
5639 return ERR_PTR(-ENOMEM);
5640
5641 offsets[0] = dummy_pkt->offsets[0];
5642 if (num_vlan == 2) {
5643 offsets[1] = ice_dummy_qinq_packet_offsets[0];
5644 offsets[2] = ice_dummy_qinq_packet_offsets[1];
5645 } else if (num_vlan == 1) {
5646 offsets[1] = ice_dummy_vlan_packet_offsets[0];
5647 }
5648
5649 for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5650 offsets[i + num_vlan].type = dummy_pkt->offsets[i].type;
5651 offsets[i + num_vlan].offset =
5652 dummy_pkt->offsets[i].offset + off;
5653 }
5654 offsets[i + num_vlan] = dummy_pkt->offsets[i];
5655
5656 etype_off = dummy_pkt->offsets[1].offset;
5657
5658 buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) +
5659 dummy_pkt->pkt_len;
5660 pkt = kzalloc(buf_len, GFP_KERNEL);
5661 if (!pkt) {
5662 kfree(offsets);
5663 return ERR_PTR(-ENOMEM);
5664 }
5665
5666 memcpy(pkt, dummy_pkt->pkt, etype_off);
5667 memcpy(pkt + etype_off,
5668 num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet,
5669 off);
5670 memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off,
5671 dummy_pkt->pkt_len - etype_off);
5672
5673 profile = kzalloc(sizeof(*profile), GFP_KERNEL);
5674 if (!profile) {
5675 kfree(offsets);
5676 kfree(pkt);
5677 return ERR_PTR(-ENOMEM);
5678 }
5679
5680 profile->offsets = offsets;
5681 profile->pkt = pkt;
5682 profile->pkt_len = buf_len;
5683 profile->match |= ICE_PKT_KMALLOC;
5684
5685 return profile;
5686 }
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698 static const struct ice_dummy_pkt_profile *
5699 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5700 enum ice_sw_tunnel_type tun_type)
5701 {
5702 const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles;
5703 u32 match = 0, vlan_count = 0;
5704 u16 i;
5705
5706 switch (tun_type) {
5707 case ICE_SW_TUN_GTPC:
5708 match |= ICE_PKT_TUN_GTPC;
5709 break;
5710 case ICE_SW_TUN_GTPU:
5711 match |= ICE_PKT_TUN_GTPU;
5712 break;
5713 case ICE_SW_TUN_NVGRE:
5714 match |= ICE_PKT_TUN_NVGRE;
5715 break;
5716 case ICE_SW_TUN_GENEVE:
5717 case ICE_SW_TUN_VXLAN:
5718 match |= ICE_PKT_TUN_UDP;
5719 break;
5720 default:
5721 break;
5722 }
5723
5724 for (i = 0; i < lkups_cnt; i++) {
5725 if (lkups[i].type == ICE_UDP_ILOS)
5726 match |= ICE_PKT_INNER_UDP;
5727 else if (lkups[i].type == ICE_TCP_IL)
5728 match |= ICE_PKT_INNER_TCP;
5729 else if (lkups[i].type == ICE_IPV6_OFOS)
5730 match |= ICE_PKT_OUTER_IPV6;
5731 else if (lkups[i].type == ICE_VLAN_OFOS ||
5732 lkups[i].type == ICE_VLAN_EX)
5733 vlan_count++;
5734 else if (lkups[i].type == ICE_VLAN_IN)
5735 vlan_count++;
5736 else if (lkups[i].type == ICE_ETYPE_OL &&
5737 lkups[i].h_u.ethertype.ethtype_id ==
5738 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5739 lkups[i].m_u.ethertype.ethtype_id ==
5740 cpu_to_be16(0xFFFF))
5741 match |= ICE_PKT_OUTER_IPV6;
5742 else if (lkups[i].type == ICE_ETYPE_IL &&
5743 lkups[i].h_u.ethertype.ethtype_id ==
5744 cpu_to_be16(ICE_IPV6_ETHER_ID) &&
5745 lkups[i].m_u.ethertype.ethtype_id ==
5746 cpu_to_be16(0xFFFF))
5747 match |= ICE_PKT_INNER_IPV6;
5748 else if (lkups[i].type == ICE_IPV6_IL)
5749 match |= ICE_PKT_INNER_IPV6;
5750 else if (lkups[i].type == ICE_GTP_NO_PAY)
5751 match |= ICE_PKT_GTP_NOPAY;
5752 else if (lkups[i].type == ICE_PPPOE) {
5753 match |= ICE_PKT_PPPOE;
5754 if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
5755 htons(PPP_IPV6))
5756 match |= ICE_PKT_OUTER_IPV6;
5757 }
5758 }
5759
5760 while (ret->match && (match & ret->match) != ret->match)
5761 ret++;
5762
5763 if (vlan_count != 0)
5764 ret = ice_dummy_packet_add_vlan(ret, vlan_count);
5765
5766 return ret;
5767 }
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778 static int
5779 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
5780 struct ice_sw_rule_lkup_rx_tx *s_rule,
5781 const struct ice_dummy_pkt_profile *profile)
5782 {
5783 u8 *pkt;
5784 u16 i;
5785
5786
5787
5788
5789 pkt = s_rule->hdr_data;
5790
5791 memcpy(pkt, profile->pkt, profile->pkt_len);
5792
5793 for (i = 0; i < lkups_cnt; i++) {
5794 const struct ice_dummy_pkt_offsets *offsets = profile->offsets;
5795 enum ice_protocol_type type;
5796 u16 offset = 0, len = 0, j;
5797 bool found = false;
5798
5799
5800
5801
5802 type = lkups[i].type;
5803 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) {
5804 if (type == offsets[j].type) {
5805 offset = offsets[j].offset;
5806 found = true;
5807 break;
5808 }
5809 }
5810
5811 if (!found)
5812 return -EINVAL;
5813
5814 switch (lkups[i].type) {
5815 case ICE_MAC_OFOS:
5816 case ICE_MAC_IL:
5817 len = sizeof(struct ice_ether_hdr);
5818 break;
5819 case ICE_ETYPE_OL:
5820 case ICE_ETYPE_IL:
5821 len = sizeof(struct ice_ethtype_hdr);
5822 break;
5823 case ICE_VLAN_OFOS:
5824 case ICE_VLAN_EX:
5825 case ICE_VLAN_IN:
5826 len = sizeof(struct ice_vlan_hdr);
5827 break;
5828 case ICE_IPV4_OFOS:
5829 case ICE_IPV4_IL:
5830 len = sizeof(struct ice_ipv4_hdr);
5831 break;
5832 case ICE_IPV6_OFOS:
5833 case ICE_IPV6_IL:
5834 len = sizeof(struct ice_ipv6_hdr);
5835 break;
5836 case ICE_TCP_IL:
5837 case ICE_UDP_OF:
5838 case ICE_UDP_ILOS:
5839 len = sizeof(struct ice_l4_hdr);
5840 break;
5841 case ICE_SCTP_IL:
5842 len = sizeof(struct ice_sctp_hdr);
5843 break;
5844 case ICE_NVGRE:
5845 len = sizeof(struct ice_nvgre_hdr);
5846 break;
5847 case ICE_VXLAN:
5848 case ICE_GENEVE:
5849 len = sizeof(struct ice_udp_tnl_hdr);
5850 break;
5851 case ICE_GTP_NO_PAY:
5852 case ICE_GTP:
5853 len = sizeof(struct ice_udp_gtp_hdr);
5854 break;
5855 case ICE_PPPOE:
5856 len = sizeof(struct ice_pppoe_hdr);
5857 break;
5858 default:
5859 return -EINVAL;
5860 }
5861
5862
5863 if (len % ICE_BYTES_PER_WORD)
5864 return -EIO;
5865
5866
5867
5868
5869
5870
5871
5872
5873 for (j = 0; j < len / sizeof(u16); j++) {
5874 u16 *ptr = (u16 *)(pkt + offset);
5875 u16 mask = lkups[i].m_raw[j];
5876
5877 if (!mask)
5878 continue;
5879
5880 ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask);
5881 }
5882 }
5883
5884 s_rule->hdr_len = cpu_to_le16(profile->pkt_len);
5885
5886 return 0;
5887 }
5888
5889
5890
5891
5892
5893
5894
5895
5896 static int
5897 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
5898 u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
5899 {
5900 u16 open_port, i;
5901
5902 switch (tun_type) {
5903 case ICE_SW_TUN_VXLAN:
5904 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN))
5905 return -EIO;
5906 break;
5907 case ICE_SW_TUN_GENEVE:
5908 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE))
5909 return -EIO;
5910 break;
5911 default:
5912
5913 return 0;
5914 }
5915
5916
5917 for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5918 if (offsets[i].type == ICE_UDP_OF) {
5919 struct ice_l4_hdr *hdr;
5920 u16 offset;
5921
5922 offset = offsets[i].offset;
5923 hdr = (struct ice_l4_hdr *)&pkt[offset];
5924 hdr->dst_port = cpu_to_be16(open_port);
5925
5926 return 0;
5927 }
5928 }
5929
5930 return -EIO;
5931 }
5932
5933
5934
5935
5936
5937
5938
5939 static int
5940 ice_fill_adv_packet_vlan(u16 vlan_type, u8 *pkt,
5941 const struct ice_dummy_pkt_offsets *offsets)
5942 {
5943 u16 i;
5944
5945
5946 for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
5947 if (offsets[i].type == ICE_VLAN_OFOS ||
5948 offsets[i].type == ICE_VLAN_EX) {
5949 struct ice_vlan_hdr *hdr;
5950 u16 offset;
5951
5952 offset = offsets[i].offset;
5953 hdr = (struct ice_vlan_hdr *)&pkt[offset];
5954 hdr->type = cpu_to_be16(vlan_type);
5955
5956 return 0;
5957 }
5958 }
5959
5960 return -EIO;
5961 }
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975 static struct ice_adv_fltr_mgmt_list_entry *
5976 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
5977 u16 lkups_cnt, u16 recp_id,
5978 struct ice_adv_rule_info *rinfo)
5979 {
5980 struct ice_adv_fltr_mgmt_list_entry *list_itr;
5981 struct ice_switch_info *sw = hw->switch_info;
5982 int i;
5983
5984 list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules,
5985 list_entry) {
5986 bool lkups_matched = true;
5987
5988 if (lkups_cnt != list_itr->lkups_cnt)
5989 continue;
5990 for (i = 0; i < list_itr->lkups_cnt; i++)
5991 if (memcmp(&list_itr->lkups[i], &lkups[i],
5992 sizeof(*lkups))) {
5993 lkups_matched = false;
5994 break;
5995 }
5996 if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
5997 rinfo->tun_type == list_itr->rule_info.tun_type &&
5998 rinfo->vlan_type == list_itr->rule_info.vlan_type &&
5999 lkups_matched)
6000 return list_itr;
6001 }
6002 return NULL;
6003 }
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026 static int
6027 ice_adv_add_update_vsi_list(struct ice_hw *hw,
6028 struct ice_adv_fltr_mgmt_list_entry *m_entry,
6029 struct ice_adv_rule_info *cur_fltr,
6030 struct ice_adv_rule_info *new_fltr)
6031 {
6032 u16 vsi_list_id = 0;
6033 int status;
6034
6035 if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
6036 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
6037 cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET)
6038 return -EOPNOTSUPP;
6039
6040 if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q ||
6041 new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) &&
6042 (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6043 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST))
6044 return -EOPNOTSUPP;
6045
6046 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) {
6047
6048
6049
6050
6051 struct ice_fltr_info tmp_fltr;
6052 u16 vsi_handle_arr[2];
6053
6054
6055 if (cur_fltr->sw_act.fwd_id.hw_vsi_id ==
6056 new_fltr->sw_act.fwd_id.hw_vsi_id)
6057 return -EEXIST;
6058
6059 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle;
6060 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle;
6061 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2,
6062 &vsi_list_id,
6063 ICE_SW_LKUP_LAST);
6064 if (status)
6065 return status;
6066
6067 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
6068 tmp_fltr.flag = m_entry->rule_info.sw_act.flag;
6069 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id;
6070 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST;
6071 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id;
6072 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST;
6073
6074
6075
6076
6077 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
6078 if (status)
6079 return status;
6080
6081 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id;
6082 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST;
6083 m_entry->vsi_list_info =
6084 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2,
6085 vsi_list_id);
6086 } else {
6087 u16 vsi_handle = new_fltr->sw_act.vsi_handle;
6088
6089 if (!m_entry->vsi_list_info)
6090 return -EIO;
6091
6092
6093 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map))
6094 return 0;
6095
6096
6097
6098
6099 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id;
6100
6101 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1,
6102 vsi_list_id, false,
6103 ice_aqc_opc_update_sw_rules,
6104 ICE_SW_LKUP_LAST);
6105
6106 if (!status)
6107 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map);
6108 }
6109 if (!status)
6110 m_entry->vsi_count++;
6111 return status;
6112 }
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132 int
6133 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6134 u16 lkups_cnt, struct ice_adv_rule_info *rinfo,
6135 struct ice_rule_query_data *added_entry)
6136 {
6137 struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL;
6138 struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
6139 const struct ice_dummy_pkt_profile *profile;
6140 u16 rid = 0, i, rule_buf_sz, vsi_handle;
6141 struct list_head *rule_head;
6142 struct ice_switch_info *sw;
6143 u16 word_cnt;
6144 u32 act = 0;
6145 int status;
6146 u8 q_rgn;
6147
6148
6149 if (!hw->switch_info->prof_res_bm_init) {
6150 hw->switch_info->prof_res_bm_init = 1;
6151 ice_init_prof_result_bm(hw);
6152 }
6153
6154 if (!lkups_cnt)
6155 return -EINVAL;
6156
6157
6158 word_cnt = 0;
6159 for (i = 0; i < lkups_cnt; i++) {
6160 u16 j;
6161
6162 for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++)
6163 if (lkups[i].m_raw[j])
6164 word_cnt++;
6165 }
6166
6167 if (!word_cnt)
6168 return -EINVAL;
6169
6170 if (word_cnt > ICE_MAX_CHAIN_WORDS)
6171 return -ENOSPC;
6172
6173
6174 profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type);
6175 if (IS_ERR(profile))
6176 return PTR_ERR(profile);
6177
6178 if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI ||
6179 rinfo->sw_act.fltr_act == ICE_FWD_TO_Q ||
6180 rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP ||
6181 rinfo->sw_act.fltr_act == ICE_DROP_PACKET)) {
6182 status = -EIO;
6183 goto free_pkt_profile;
6184 }
6185
6186 vsi_handle = rinfo->sw_act.vsi_handle;
6187 if (!ice_is_vsi_valid(hw, vsi_handle)) {
6188 status = -EINVAL;
6189 goto free_pkt_profile;
6190 }
6191
6192 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
6193 rinfo->sw_act.fwd_id.hw_vsi_id =
6194 ice_get_hw_vsi_num(hw, vsi_handle);
6195 if (rinfo->sw_act.flag & ICE_FLTR_TX)
6196 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle);
6197
6198 status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid);
6199 if (status)
6200 goto free_pkt_profile;
6201 m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6202 if (m_entry) {
6203
6204
6205
6206
6207
6208
6209
6210
6211 status = ice_adv_add_update_vsi_list(hw, m_entry,
6212 &m_entry->rule_info,
6213 rinfo);
6214 if (added_entry) {
6215 added_entry->rid = rid;
6216 added_entry->rule_id = m_entry->rule_info.fltr_rule_id;
6217 added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6218 }
6219 goto free_pkt_profile;
6220 }
6221 rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len);
6222 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6223 if (!s_rule) {
6224 status = -ENOMEM;
6225 goto free_pkt_profile;
6226 }
6227 if (!rinfo->flags_info.act_valid) {
6228 act |= ICE_SINGLE_ACT_LAN_ENABLE;
6229 act |= ICE_SINGLE_ACT_LB_ENABLE;
6230 } else {
6231 act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE |
6232 ICE_SINGLE_ACT_LB_ENABLE);
6233 }
6234
6235 switch (rinfo->sw_act.fltr_act) {
6236 case ICE_FWD_TO_VSI:
6237 act |= (rinfo->sw_act.fwd_id.hw_vsi_id <<
6238 ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M;
6239 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT;
6240 break;
6241 case ICE_FWD_TO_Q:
6242 act |= ICE_SINGLE_ACT_TO_Q;
6243 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
6244 ICE_SINGLE_ACT_Q_INDEX_M;
6245 break;
6246 case ICE_FWD_TO_QGRP:
6247 q_rgn = rinfo->sw_act.qgrp_size > 0 ?
6248 (u8)ilog2(rinfo->sw_act.qgrp_size) : 0;
6249 act |= ICE_SINGLE_ACT_TO_Q;
6250 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) &
6251 ICE_SINGLE_ACT_Q_INDEX_M;
6252 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) &
6253 ICE_SINGLE_ACT_Q_REGION_M;
6254 break;
6255 case ICE_DROP_PACKET:
6256 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP |
6257 ICE_SINGLE_ACT_VALID_BIT;
6258 break;
6259 default:
6260 status = -EIO;
6261 goto err_ice_add_adv_rule;
6262 }
6263
6264
6265
6266
6267
6268
6269
6270
6271 if (rinfo->rx) {
6272 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
6273 s_rule->src = cpu_to_le16(hw->port_info->lport);
6274 } else {
6275 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);
6276 s_rule->src = cpu_to_le16(rinfo->sw_act.src);
6277 }
6278
6279 s_rule->recipe_id = cpu_to_le16(rid);
6280 s_rule->act = cpu_to_le32(act);
6281
6282 status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile);
6283 if (status)
6284 goto err_ice_add_adv_rule;
6285
6286 if (rinfo->tun_type != ICE_NON_TUN &&
6287 rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) {
6288 status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
6289 s_rule->hdr_data,
6290 profile->offsets);
6291 if (status)
6292 goto err_ice_add_adv_rule;
6293 }
6294
6295 if (rinfo->vlan_type != 0 && ice_is_dvm_ena(hw)) {
6296 status = ice_fill_adv_packet_vlan(rinfo->vlan_type,
6297 s_rule->hdr_data,
6298 profile->offsets);
6299 if (status)
6300 goto err_ice_add_adv_rule;
6301 }
6302
6303 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6304 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
6305 NULL);
6306 if (status)
6307 goto err_ice_add_adv_rule;
6308 adv_fltr = devm_kzalloc(ice_hw_to_dev(hw),
6309 sizeof(struct ice_adv_fltr_mgmt_list_entry),
6310 GFP_KERNEL);
6311 if (!adv_fltr) {
6312 status = -ENOMEM;
6313 goto err_ice_add_adv_rule;
6314 }
6315
6316 adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups,
6317 lkups_cnt * sizeof(*lkups), GFP_KERNEL);
6318 if (!adv_fltr->lkups) {
6319 status = -ENOMEM;
6320 goto err_ice_add_adv_rule;
6321 }
6322
6323 adv_fltr->lkups_cnt = lkups_cnt;
6324 adv_fltr->rule_info = *rinfo;
6325 adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index);
6326 sw = hw->switch_info;
6327 sw->recp_list[rid].adv_rule = true;
6328 rule_head = &sw->recp_list[rid].filt_rules;
6329
6330 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI)
6331 adv_fltr->vsi_count = 1;
6332
6333
6334 list_add(&adv_fltr->list_entry, rule_head);
6335 if (added_entry) {
6336 added_entry->rid = rid;
6337 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id;
6338 added_entry->vsi_handle = rinfo->sw_act.vsi_handle;
6339 }
6340 err_ice_add_adv_rule:
6341 if (status && adv_fltr) {
6342 devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups);
6343 devm_kfree(ice_hw_to_dev(hw), adv_fltr);
6344 }
6345
6346 kfree(s_rule);
6347
6348 free_pkt_profile:
6349 if (profile->match & ICE_PKT_KMALLOC) {
6350 kfree(profile->offsets);
6351 kfree(profile->pkt);
6352 kfree(profile);
6353 }
6354
6355 return status;
6356 }
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368 static int
6369 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id,
6370 struct list_head *list_head)
6371 {
6372 struct ice_fltr_mgmt_list_entry *itr;
6373 int status = 0;
6374 u16 hw_vsi_id;
6375
6376 if (list_empty(list_head))
6377 return status;
6378 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle);
6379
6380 list_for_each_entry(itr, list_head, list_entry) {
6381 struct ice_fltr_list_entry f_entry;
6382
6383 f_entry.fltr_info = itr->fltr_info;
6384 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN &&
6385 itr->fltr_info.vsi_handle == vsi_handle) {
6386
6387 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6388 f_entry.fltr_info.src = hw_vsi_id;
6389 status = ice_add_rule_internal(hw, recp_id, &f_entry);
6390 if (status)
6391 goto end;
6392 continue;
6393 }
6394 if (!itr->vsi_list_info ||
6395 !test_bit(vsi_handle, itr->vsi_list_info->vsi_map))
6396 continue;
6397
6398 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map);
6399 f_entry.fltr_info.vsi_handle = vsi_handle;
6400 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI;
6401
6402 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI)
6403 f_entry.fltr_info.src = hw_vsi_id;
6404 if (recp_id == ICE_SW_LKUP_VLAN)
6405 status = ice_add_vlan_internal(hw, &f_entry);
6406 else
6407 status = ice_add_rule_internal(hw, recp_id, &f_entry);
6408 if (status)
6409 goto end;
6410 }
6411 end:
6412 return status;
6413 }
6414
6415
6416
6417
6418
6419
6420
6421
6422 static int
6423 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle,
6424 struct ice_adv_fltr_mgmt_list_entry *fm_list)
6425 {
6426 struct ice_vsi_list_map_info *vsi_list_info;
6427 enum ice_sw_lkup_type lkup_type;
6428 u16 vsi_list_id;
6429 int status;
6430
6431 if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST ||
6432 fm_list->vsi_count == 0)
6433 return -EINVAL;
6434
6435
6436 if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map))
6437 return -ENOENT;
6438
6439 lkup_type = ICE_SW_LKUP_LAST;
6440 vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id;
6441 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true,
6442 ice_aqc_opc_update_sw_rules,
6443 lkup_type);
6444 if (status)
6445 return status;
6446
6447 fm_list->vsi_count--;
6448 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map);
6449 vsi_list_info = fm_list->vsi_list_info;
6450 if (fm_list->vsi_count == 1) {
6451 struct ice_fltr_info tmp_fltr;
6452 u16 rem_vsi_handle;
6453
6454 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map,
6455 ICE_MAX_VSI);
6456 if (!ice_is_vsi_valid(hw, rem_vsi_handle))
6457 return -EIO;
6458
6459
6460 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1,
6461 vsi_list_id, true,
6462 ice_aqc_opc_update_sw_rules,
6463 lkup_type);
6464 if (status)
6465 return status;
6466
6467 memset(&tmp_fltr, 0, sizeof(tmp_fltr));
6468 tmp_fltr.flag = fm_list->rule_info.sw_act.flag;
6469 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id;
6470 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI;
6471 tmp_fltr.fltr_act = ICE_FWD_TO_VSI;
6472 tmp_fltr.fwd_id.hw_vsi_id =
6473 ice_get_hw_vsi_num(hw, rem_vsi_handle);
6474 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id =
6475 ice_get_hw_vsi_num(hw, rem_vsi_handle);
6476 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle;
6477
6478
6479
6480
6481 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr);
6482 if (status) {
6483 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n",
6484 tmp_fltr.fwd_id.hw_vsi_id, status);
6485 return status;
6486 }
6487 fm_list->vsi_list_info->ref_cnt--;
6488
6489
6490 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type);
6491 if (status) {
6492 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n",
6493 vsi_list_id, status);
6494 return status;
6495 }
6496
6497 list_del(&vsi_list_info->list_entry);
6498 devm_kfree(ice_hw_to_dev(hw), vsi_list_info);
6499 fm_list->vsi_list_info = NULL;
6500 }
6501
6502 return status;
6503 }
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521 static int
6522 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
6523 u16 lkups_cnt, struct ice_adv_rule_info *rinfo)
6524 {
6525 struct ice_adv_fltr_mgmt_list_entry *list_elem;
6526 struct ice_prot_lkup_ext lkup_exts;
6527 bool remove_rule = false;
6528 struct mutex *rule_lock;
6529 u16 i, rid, vsi_handle;
6530 int status = 0;
6531
6532 memset(&lkup_exts, 0, sizeof(lkup_exts));
6533 for (i = 0; i < lkups_cnt; i++) {
6534 u16 count;
6535
6536 if (lkups[i].type >= ICE_PROTOCOL_LAST)
6537 return -EIO;
6538
6539 count = ice_fill_valid_words(&lkups[i], &lkup_exts);
6540 if (!count)
6541 return -EIO;
6542 }
6543
6544
6545
6546
6547 status = ice_add_special_words(rinfo, &lkup_exts, ice_is_dvm_ena(hw));
6548 if (status)
6549 return status;
6550
6551 rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type);
6552
6553 if (rid == ICE_MAX_NUM_RECIPES)
6554 return -EINVAL;
6555
6556 rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock;
6557 list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo);
6558
6559 if (!list_elem)
6560 return 0;
6561 mutex_lock(rule_lock);
6562 if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) {
6563 remove_rule = true;
6564 } else if (list_elem->vsi_count > 1) {
6565 remove_rule = false;
6566 vsi_handle = rinfo->sw_act.vsi_handle;
6567 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6568 } else {
6569 vsi_handle = rinfo->sw_act.vsi_handle;
6570 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem);
6571 if (status) {
6572 mutex_unlock(rule_lock);
6573 return status;
6574 }
6575 if (list_elem->vsi_count == 0)
6576 remove_rule = true;
6577 }
6578 mutex_unlock(rule_lock);
6579 if (remove_rule) {
6580 struct ice_sw_rule_lkup_rx_tx *s_rule;
6581 u16 rule_buf_sz;
6582
6583 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule);
6584 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
6585 if (!s_rule)
6586 return -ENOMEM;
6587 s_rule->act = 0;
6588 s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id);
6589 s_rule->hdr_len = 0;
6590 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
6591 rule_buf_sz, 1,
6592 ice_aqc_opc_remove_sw_rules, NULL);
6593 if (!status || status == -ENOENT) {
6594 struct ice_switch_info *sw = hw->switch_info;
6595
6596 mutex_lock(rule_lock);
6597 list_del(&list_elem->list_entry);
6598 devm_kfree(ice_hw_to_dev(hw), list_elem->lkups);
6599 devm_kfree(ice_hw_to_dev(hw), list_elem);
6600 mutex_unlock(rule_lock);
6601 if (list_empty(&sw->recp_list[rid].filt_rules))
6602 sw->recp_list[rid].adv_rule = false;
6603 }
6604 kfree(s_rule);
6605 }
6606 return status;
6607 }
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618 int
6619 ice_rem_adv_rule_by_id(struct ice_hw *hw,
6620 struct ice_rule_query_data *remove_entry)
6621 {
6622 struct ice_adv_fltr_mgmt_list_entry *list_itr;
6623 struct list_head *list_head;
6624 struct ice_adv_rule_info rinfo;
6625 struct ice_switch_info *sw;
6626
6627 sw = hw->switch_info;
6628 if (!sw->recp_list[remove_entry->rid].recp_created)
6629 return -EINVAL;
6630 list_head = &sw->recp_list[remove_entry->rid].filt_rules;
6631 list_for_each_entry(list_itr, list_head, list_entry) {
6632 if (list_itr->rule_info.fltr_rule_id ==
6633 remove_entry->rule_id) {
6634 rinfo = list_itr->rule_info;
6635 rinfo.sw_act.vsi_handle = remove_entry->vsi_handle;
6636 return ice_rem_adv_rule(hw, list_itr->lkups,
6637 list_itr->lkups_cnt, &rinfo);
6638 }
6639 }
6640
6641 return -ENOENT;
6642 }
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654 int ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle)
6655 {
6656 struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry;
6657 struct ice_vsi_list_map_info *map_info;
6658 struct ice_adv_rule_info rinfo;
6659 struct list_head *list_head;
6660 struct ice_switch_info *sw;
6661 int status;
6662 u8 rid;
6663
6664 sw = hw->switch_info;
6665 for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) {
6666 if (!sw->recp_list[rid].recp_created)
6667 continue;
6668 if (!sw->recp_list[rid].adv_rule)
6669 continue;
6670
6671 list_head = &sw->recp_list[rid].filt_rules;
6672 list_for_each_entry_safe(list_itr, tmp_entry, list_head,
6673 list_entry) {
6674 rinfo = list_itr->rule_info;
6675
6676 if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) {
6677 map_info = list_itr->vsi_list_info;
6678 if (!map_info)
6679 continue;
6680
6681 if (!test_bit(vsi_handle, map_info->vsi_map))
6682 continue;
6683 } else if (rinfo.sw_act.vsi_handle != vsi_handle) {
6684 continue;
6685 }
6686
6687 rinfo.sw_act.vsi_handle = vsi_handle;
6688 status = ice_rem_adv_rule(hw, list_itr->lkups,
6689 list_itr->lkups_cnt, &rinfo);
6690 if (status)
6691 return status;
6692 }
6693 }
6694 return 0;
6695 }
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705 static int
6706 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle,
6707 struct list_head *list_head)
6708 {
6709 struct ice_rule_query_data added_entry = { 0 };
6710 struct ice_adv_fltr_mgmt_list_entry *adv_fltr;
6711 int status = 0;
6712
6713 if (list_empty(list_head))
6714 return status;
6715 list_for_each_entry(adv_fltr, list_head, list_entry) {
6716 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info;
6717 u16 lk_cnt = adv_fltr->lkups_cnt;
6718
6719 if (vsi_handle != rinfo->sw_act.vsi_handle)
6720 continue;
6721 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo,
6722 &added_entry);
6723 if (status)
6724 break;
6725 }
6726 return status;
6727 }
6728
6729
6730
6731
6732
6733
6734
6735
6736 int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle)
6737 {
6738 struct ice_switch_info *sw = hw->switch_info;
6739 int status;
6740 u8 i;
6741
6742 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6743 struct list_head *head;
6744
6745 head = &sw->recp_list[i].filt_replay_rules;
6746 if (!sw->recp_list[i].adv_rule)
6747 status = ice_replay_vsi_fltr(hw, vsi_handle, i, head);
6748 else
6749 status = ice_replay_vsi_adv_rule(hw, vsi_handle, head);
6750 if (status)
6751 return status;
6752 }
6753 return status;
6754 }
6755
6756
6757
6758
6759
6760
6761
6762 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw)
6763 {
6764 struct ice_switch_info *sw = hw->switch_info;
6765 u8 i;
6766
6767 if (!sw)
6768 return;
6769
6770 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) {
6771 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) {
6772 struct list_head *l_head;
6773
6774 l_head = &sw->recp_list[i].filt_replay_rules;
6775 if (!sw->recp_list[i].adv_rule)
6776 ice_rem_sw_rule_info(hw, l_head);
6777 else
6778 ice_rem_adv_rule_info(hw, l_head);
6779 }
6780 }
6781 }