1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2001-2020 Intel Corporation 3 */ 4 5 #include "ice_switch.h" 6 #include "ice_flex_type.h" 7 #include "ice_flow.h" 8 9 #define ICE_ETH_DA_OFFSET 0 10 #define ICE_ETH_ETHTYPE_OFFSET 12 11 #define ICE_ETH_VLAN_TCI_OFFSET 14 12 #define ICE_MAX_VLAN_ID 0xFFF 13 #define ICE_IPV4_NVGRE_PROTO_ID 0x002F 14 #define ICE_PPP_IPV6_PROTO_ID 0x0057 15 #define ICE_IPV6_ETHER_ID 0x86DD 16 #define ICE_TCP_PROTO_ID 0x06 17 18 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem 19 * struct to configure any switch filter rules. 20 * {DA (6 bytes), SA(6 bytes), 21 * Ether type (2 bytes for header without VLAN tag) OR 22 * VLAN tag (4 bytes for header with VLAN tag) } 23 * 24 * Word on Hardcoded values 25 * byte 0 = 0x2: to identify it as locally administered DA MAC 26 * byte 6 = 0x2: to identify it as locally administered SA MAC 27 * byte 12 = 0x81 & byte 13 = 0x00: 28 * In case of VLAN filter first two bytes defines ether type (0x8100) 29 * and remaining two bytes are placeholder for programming a given VLAN ID 30 * In case of Ether type filter it is treated as header without VLAN tag 31 * and byte 12 and 13 is used to program a given Ether type instead 32 */ 33 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0, 34 0x2, 0, 0, 0, 0, 0, 35 0x81, 0, 0, 0}; 36 37 struct ice_dummy_pkt_offsets { 38 enum ice_protocol_type type; 39 u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */ 40 }; 41 42 static const struct ice_dummy_pkt_offsets dummy_gre_tcp_packet_offsets[] = { 43 { ICE_MAC_OFOS, 0 }, 44 { ICE_ETYPE_OL, 12 }, 45 { ICE_IPV4_OFOS, 14 }, 46 { ICE_NVGRE, 34 }, 47 { ICE_MAC_IL, 42 }, 48 { ICE_IPV4_IL, 56 }, 49 { ICE_TCP_IL, 76 }, 50 { ICE_PROTOCOL_LAST, 0 }, 51 }; 52 53 static const u8 dummy_gre_tcp_packet[] = { 54 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 55 0x00, 0x00, 0x00, 0x00, 56 0x00, 0x00, 0x00, 0x00, 57 58 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 59 60 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */ 61 0x00, 0x00, 0x00, 0x00, 62 0x00, 0x2F, 0x00, 0x00, 63 0x00, 0x00, 0x00, 0x00, 64 0x00, 0x00, 0x00, 0x00, 65 66 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 67 0x00, 0x00, 0x00, 0x00, 68 69 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 70 0x00, 0x00, 0x00, 0x00, 71 0x00, 0x00, 0x00, 0x00, 72 0x08, 0x00, 73 74 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */ 75 0x00, 0x00, 0x00, 0x00, 76 0x00, 0x06, 0x00, 0x00, 77 0x00, 0x00, 0x00, 0x00, 78 0x00, 0x00, 0x00, 0x00, 79 80 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */ 81 0x00, 0x00, 0x00, 0x00, 82 0x00, 0x00, 0x00, 0x00, 83 0x50, 0x02, 0x20, 0x00, 84 0x00, 0x00, 0x00, 0x00 85 }; 86 87 static const struct ice_dummy_pkt_offsets dummy_gre_udp_packet_offsets[] = { 88 { ICE_MAC_OFOS, 0 }, 89 { ICE_ETYPE_OL, 12 }, 90 { ICE_IPV4_OFOS, 14 }, 91 { ICE_NVGRE, 34 }, 92 { ICE_MAC_IL, 42 }, 93 { ICE_IPV4_IL, 56 }, 94 { ICE_UDP_ILOS, 76 }, 95 { ICE_PROTOCOL_LAST, 0 }, 96 }; 97 98 static const u8 dummy_gre_udp_packet[] = { 99 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 100 0x00, 0x00, 0x00, 0x00, 101 0x00, 0x00, 0x00, 0x00, 102 103 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 104 105 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */ 106 0x00, 0x00, 0x00, 0x00, 107 0x00, 0x2F, 0x00, 0x00, 108 0x00, 0x00, 0x00, 0x00, 109 0x00, 0x00, 0x00, 0x00, 110 111 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 112 0x00, 0x00, 0x00, 0x00, 113 114 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 115 0x00, 0x00, 0x00, 0x00, 116 0x00, 0x00, 0x00, 0x00, 117 0x08, 0x00, 118 119 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */ 120 0x00, 0x00, 0x00, 0x00, 121 0x00, 0x11, 0x00, 0x00, 122 0x00, 0x00, 0x00, 0x00, 123 0x00, 0x00, 0x00, 0x00, 124 125 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */ 126 0x00, 0x08, 0x00, 0x00, 127 }; 128 129 static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = { 130 { ICE_MAC_OFOS, 0 }, 131 { ICE_ETYPE_OL, 12 }, 132 { ICE_IPV4_OFOS, 14 }, 133 { ICE_UDP_OF, 34 }, 134 { ICE_VXLAN, 42 }, 135 { ICE_GENEVE, 42 }, 136 { ICE_VXLAN_GPE, 42 }, 137 { ICE_MAC_IL, 50 }, 138 { ICE_IPV4_IL, 64 }, 139 { ICE_TCP_IL, 84 }, 140 { ICE_PROTOCOL_LAST, 0 }, 141 }; 142 143 static const u8 dummy_udp_tun_tcp_packet[] = { 144 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 145 0x00, 0x00, 0x00, 0x00, 146 0x00, 0x00, 0x00, 0x00, 147 148 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 149 150 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */ 151 0x00, 0x01, 0x00, 0x00, 152 0x40, 0x11, 0x00, 0x00, 153 0x00, 0x00, 0x00, 0x00, 154 0x00, 0x00, 0x00, 0x00, 155 156 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 157 0x00, 0x46, 0x00, 0x00, 158 159 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 160 0x00, 0x00, 0x00, 0x00, 161 162 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 163 0x00, 0x00, 0x00, 0x00, 164 0x00, 0x00, 0x00, 0x00, 165 0x08, 0x00, 166 167 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */ 168 0x00, 0x01, 0x00, 0x00, 169 0x40, 0x06, 0x00, 0x00, 170 0x00, 0x00, 0x00, 0x00, 171 0x00, 0x00, 0x00, 0x00, 172 173 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */ 174 0x00, 0x00, 0x00, 0x00, 175 0x00, 0x00, 0x00, 0x00, 176 0x50, 0x02, 0x20, 0x00, 177 0x00, 0x00, 0x00, 0x00 178 }; 179 180 static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = { 181 { ICE_MAC_OFOS, 0 }, 182 { ICE_ETYPE_OL, 12 }, 183 { ICE_IPV4_OFOS, 14 }, 184 { ICE_UDP_OF, 34 }, 185 { ICE_VXLAN, 42 }, 186 { ICE_GENEVE, 42 }, 187 { ICE_VXLAN_GPE, 42 }, 188 { ICE_MAC_IL, 50 }, 189 { ICE_IPV4_IL, 64 }, 190 { ICE_UDP_ILOS, 84 }, 191 { ICE_PROTOCOL_LAST, 0 }, 192 }; 193 194 static const u8 dummy_udp_tun_udp_packet[] = { 195 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 196 0x00, 0x00, 0x00, 0x00, 197 0x00, 0x00, 0x00, 0x00, 198 199 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 200 201 0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */ 202 0x00, 0x01, 0x00, 0x00, 203 0x00, 0x11, 0x00, 0x00, 204 0x00, 0x00, 0x00, 0x00, 205 0x00, 0x00, 0x00, 0x00, 206 207 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 208 0x00, 0x3a, 0x00, 0x00, 209 210 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 211 0x00, 0x00, 0x00, 0x00, 212 213 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 214 0x00, 0x00, 0x00, 0x00, 215 0x00, 0x00, 0x00, 0x00, 216 0x08, 0x00, 217 218 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */ 219 0x00, 0x01, 0x00, 0x00, 220 0x00, 0x11, 0x00, 0x00, 221 0x00, 0x00, 0x00, 0x00, 222 0x00, 0x00, 0x00, 0x00, 223 224 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */ 225 0x00, 0x08, 0x00, 0x00, 226 }; 227 228 /* offset info for MAC + IPv4 + UDP dummy packet */ 229 static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = { 230 { ICE_MAC_OFOS, 0 }, 231 { ICE_ETYPE_OL, 12 }, 232 { ICE_IPV4_OFOS, 14 }, 233 { ICE_UDP_ILOS, 34 }, 234 { ICE_PROTOCOL_LAST, 0 }, 235 }; 236 237 /* Dummy packet for MAC + IPv4 + UDP */ 238 static const u8 dummy_udp_packet[] = { 239 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 240 0x00, 0x00, 0x00, 0x00, 241 0x00, 0x00, 0x00, 0x00, 242 243 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 244 245 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */ 246 0x00, 0x01, 0x00, 0x00, 247 0x00, 0x11, 0x00, 0x00, 248 0x00, 0x00, 0x00, 0x00, 249 0x00, 0x00, 0x00, 0x00, 250 251 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */ 252 0x00, 0x08, 0x00, 0x00, 253 254 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 255 }; 256 257 /* offset info for MAC + VLAN + IPv4 + UDP dummy packet */ 258 static const struct ice_dummy_pkt_offsets dummy_vlan_udp_packet_offsets[] = { 259 { ICE_MAC_OFOS, 0 }, 260 { ICE_ETYPE_OL, 12 }, 261 { ICE_VLAN_OFOS, 14 }, 262 { ICE_IPV4_OFOS, 18 }, 263 { ICE_UDP_ILOS, 38 }, 264 { ICE_PROTOCOL_LAST, 0 }, 265 }; 266 267 /* C-tag (801.1Q), IPv4:UDP dummy packet */ 268 static const u8 dummy_vlan_udp_packet[] = { 269 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 270 0x00, 0x00, 0x00, 0x00, 271 0x00, 0x00, 0x00, 0x00, 272 273 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 274 275 0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 14 */ 276 277 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 18 */ 278 0x00, 0x01, 0x00, 0x00, 279 0x00, 0x11, 0x00, 0x00, 280 0x00, 0x00, 0x00, 0x00, 281 0x00, 0x00, 0x00, 0x00, 282 283 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 38 */ 284 0x00, 0x08, 0x00, 0x00, 285 286 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 287 }; 288 289 /* offset info for MAC + IPv4 + TCP dummy packet */ 290 static const struct ice_dummy_pkt_offsets dummy_tcp_packet_offsets[] = { 291 { ICE_MAC_OFOS, 0 }, 292 { ICE_ETYPE_OL, 12 }, 293 { ICE_IPV4_OFOS, 14 }, 294 { ICE_TCP_IL, 34 }, 295 { ICE_PROTOCOL_LAST, 0 }, 296 }; 297 298 /* Dummy packet for MAC + IPv4 + TCP */ 299 static const u8 dummy_tcp_packet[] = { 300 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 301 0x00, 0x00, 0x00, 0x00, 302 0x00, 0x00, 0x00, 0x00, 303 304 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 305 306 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */ 307 0x00, 0x01, 0x00, 0x00, 308 0x00, 0x06, 0x00, 0x00, 309 0x00, 0x00, 0x00, 0x00, 310 0x00, 0x00, 0x00, 0x00, 311 312 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */ 313 0x00, 0x00, 0x00, 0x00, 314 0x00, 0x00, 0x00, 0x00, 315 0x50, 0x00, 0x00, 0x00, 316 0x00, 0x00, 0x00, 0x00, 317 318 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 319 }; 320 321 /* offset info for MAC + VLAN (C-tag, 802.1Q) + IPv4 + TCP dummy packet */ 322 static const struct ice_dummy_pkt_offsets dummy_vlan_tcp_packet_offsets[] = { 323 { ICE_MAC_OFOS, 0 }, 324 { ICE_ETYPE_OL, 12 }, 325 { ICE_VLAN_OFOS, 14 }, 326 { ICE_IPV4_OFOS, 18 }, 327 { ICE_TCP_IL, 38 }, 328 { ICE_PROTOCOL_LAST, 0 }, 329 }; 330 331 /* C-tag (801.1Q), IPv4:TCP dummy packet */ 332 static const u8 dummy_vlan_tcp_packet[] = { 333 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 334 0x00, 0x00, 0x00, 0x00, 335 0x00, 0x00, 0x00, 0x00, 336 337 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 338 339 0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 14 */ 340 341 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 18 */ 342 0x00, 0x01, 0x00, 0x00, 343 0x00, 0x06, 0x00, 0x00, 344 0x00, 0x00, 0x00, 0x00, 345 0x00, 0x00, 0x00, 0x00, 346 347 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 38 */ 348 0x00, 0x00, 0x00, 0x00, 349 0x00, 0x00, 0x00, 0x00, 350 0x50, 0x00, 0x00, 0x00, 351 0x00, 0x00, 0x00, 0x00, 352 353 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 354 }; 355 356 static const struct ice_dummy_pkt_offsets dummy_tcp_ipv6_packet_offsets[] = { 357 { ICE_MAC_OFOS, 0 }, 358 { ICE_ETYPE_OL, 12 }, 359 { ICE_IPV6_OFOS, 14 }, 360 { ICE_TCP_IL, 54 }, 361 { ICE_PROTOCOL_LAST, 0 }, 362 }; 363 364 static const u8 dummy_tcp_ipv6_packet[] = { 365 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 366 0x00, 0x00, 0x00, 0x00, 367 0x00, 0x00, 0x00, 0x00, 368 369 0x86, 0xDD, /* ICE_ETYPE_OL 12 */ 370 371 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */ 372 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 373 0x00, 0x00, 0x00, 0x00, 374 0x00, 0x00, 0x00, 0x00, 375 0x00, 0x00, 0x00, 0x00, 376 0x00, 0x00, 0x00, 0x00, 377 0x00, 0x00, 0x00, 0x00, 378 0x00, 0x00, 0x00, 0x00, 379 0x00, 0x00, 0x00, 0x00, 380 0x00, 0x00, 0x00, 0x00, 381 382 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */ 383 0x00, 0x00, 0x00, 0x00, 384 0x00, 0x00, 0x00, 0x00, 385 0x50, 0x00, 0x00, 0x00, 386 0x00, 0x00, 0x00, 0x00, 387 388 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 389 }; 390 391 /* C-tag (802.1Q): IPv6 + TCP */ 392 static const struct ice_dummy_pkt_offsets 393 dummy_vlan_tcp_ipv6_packet_offsets[] = { 394 { ICE_MAC_OFOS, 0 }, 395 { ICE_ETYPE_OL, 12 }, 396 { ICE_VLAN_OFOS, 14 }, 397 { ICE_IPV6_OFOS, 18 }, 398 { ICE_TCP_IL, 58 }, 399 { ICE_PROTOCOL_LAST, 0 }, 400 }; 401 402 /* C-tag (802.1Q), IPv6 + TCP dummy packet */ 403 static const u8 dummy_vlan_tcp_ipv6_packet[] = { 404 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 405 0x00, 0x00, 0x00, 0x00, 406 0x00, 0x00, 0x00, 0x00, 407 408 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 409 410 0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 14 */ 411 412 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */ 413 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 414 0x00, 0x00, 0x00, 0x00, 415 0x00, 0x00, 0x00, 0x00, 416 0x00, 0x00, 0x00, 0x00, 417 0x00, 0x00, 0x00, 0x00, 418 0x00, 0x00, 0x00, 0x00, 419 0x00, 0x00, 0x00, 0x00, 420 0x00, 0x00, 0x00, 0x00, 421 0x00, 0x00, 0x00, 0x00, 422 423 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 58 */ 424 0x00, 0x00, 0x00, 0x00, 425 0x00, 0x00, 0x00, 0x00, 426 0x50, 0x00, 0x00, 0x00, 427 0x00, 0x00, 0x00, 0x00, 428 429 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 430 }; 431 432 /* IPv6 + UDP */ 433 static const struct ice_dummy_pkt_offsets dummy_udp_ipv6_packet_offsets[] = { 434 { ICE_MAC_OFOS, 0 }, 435 { ICE_ETYPE_OL, 12 }, 436 { ICE_IPV6_OFOS, 14 }, 437 { ICE_UDP_ILOS, 54 }, 438 { ICE_PROTOCOL_LAST, 0 }, 439 }; 440 441 /* IPv6 + UDP dummy packet */ 442 static const u8 dummy_udp_ipv6_packet[] = { 443 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 444 0x00, 0x00, 0x00, 0x00, 445 0x00, 0x00, 0x00, 0x00, 446 447 0x86, 0xDD, /* ICE_ETYPE_OL 12 */ 448 449 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */ 450 0x00, 0x10, 0x11, 0x00, /* Next header UDP */ 451 0x00, 0x00, 0x00, 0x00, 452 0x00, 0x00, 0x00, 0x00, 453 0x00, 0x00, 0x00, 0x00, 454 0x00, 0x00, 0x00, 0x00, 455 0x00, 0x00, 0x00, 0x00, 456 0x00, 0x00, 0x00, 0x00, 457 0x00, 0x00, 0x00, 0x00, 458 0x00, 0x00, 0x00, 0x00, 459 460 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */ 461 0x00, 0x10, 0x00, 0x00, 462 463 0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */ 464 0x00, 0x00, 0x00, 0x00, 465 466 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 467 }; 468 469 /* C-tag (802.1Q): IPv6 + UDP */ 470 static const struct ice_dummy_pkt_offsets 471 dummy_vlan_udp_ipv6_packet_offsets[] = { 472 { ICE_MAC_OFOS, 0 }, 473 { ICE_ETYPE_OL, 12 }, 474 { ICE_VLAN_OFOS, 14 }, 475 { ICE_IPV6_OFOS, 18 }, 476 { ICE_UDP_ILOS, 58 }, 477 { ICE_PROTOCOL_LAST, 0 }, 478 }; 479 480 /* C-tag (802.1Q), IPv6 + UDP dummy packet */ 481 static const u8 dummy_vlan_udp_ipv6_packet[] = { 482 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 483 0x00, 0x00, 0x00, 0x00, 484 0x00, 0x00, 0x00, 0x00, 485 486 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 487 488 0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 14 */ 489 490 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 18 */ 491 0x00, 0x08, 0x11, 0x00, /* Next header UDP */ 492 0x00, 0x00, 0x00, 0x00, 493 0x00, 0x00, 0x00, 0x00, 494 0x00, 0x00, 0x00, 0x00, 495 0x00, 0x00, 0x00, 0x00, 496 0x00, 0x00, 0x00, 0x00, 497 0x00, 0x00, 0x00, 0x00, 498 0x00, 0x00, 0x00, 0x00, 499 0x00, 0x00, 0x00, 0x00, 500 501 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 58 */ 502 0x00, 0x08, 0x00, 0x00, 503 504 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 505 }; 506 507 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 508 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_tcp_packet_offsets[] = { 509 { ICE_MAC_OFOS, 0 }, 510 { ICE_IPV4_OFOS, 14 }, 511 { ICE_UDP_OF, 34 }, 512 { ICE_GTP, 42 }, 513 { ICE_IPV4_IL, 62 }, 514 { ICE_TCP_IL, 82 }, 515 { ICE_PROTOCOL_LAST, 0 }, 516 }; 517 518 static const u8 dummy_ipv4_gtpu_ipv4_tcp_packet[] = { 519 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 520 0x00, 0x00, 0x00, 0x00, 521 0x00, 0x00, 0x00, 0x00, 522 0x08, 0x00, 523 524 0x45, 0x00, 0x00, 0x58, /* IP 14 */ 525 0x00, 0x00, 0x00, 0x00, 526 0x00, 0x11, 0x00, 0x00, 527 0x00, 0x00, 0x00, 0x00, 528 0x00, 0x00, 0x00, 0x00, 529 530 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 531 0x00, 0x44, 0x00, 0x00, 532 533 0x34, 0xff, 0x00, 0x34, /* GTP-U Header 42 */ 534 0x00, 0x00, 0x00, 0x00, 535 0x00, 0x00, 0x00, 0x85, 536 537 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 538 0x00, 0x00, 0x00, 0x00, 539 540 0x45, 0x00, 0x00, 0x28, /* IP 62 */ 541 0x00, 0x00, 0x00, 0x00, 542 0x00, 0x06, 0x00, 0x00, 543 0x00, 0x00, 0x00, 0x00, 544 0x00, 0x00, 0x00, 0x00, 545 546 0x00, 0x00, 0x00, 0x00, /* TCP 82 */ 547 0x00, 0x00, 0x00, 0x00, 548 0x00, 0x00, 0x00, 0x00, 549 0x50, 0x00, 0x00, 0x00, 550 0x00, 0x00, 0x00, 0x00, 551 552 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 553 }; 554 555 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */ 556 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_udp_packet_offsets[] = { 557 { ICE_MAC_OFOS, 0 }, 558 { ICE_IPV4_OFOS, 14 }, 559 { ICE_UDP_OF, 34 }, 560 { ICE_GTP, 42 }, 561 { ICE_IPV4_IL, 62 }, 562 { ICE_UDP_ILOS, 82 }, 563 { ICE_PROTOCOL_LAST, 0 }, 564 }; 565 566 static const u8 dummy_ipv4_gtpu_ipv4_udp_packet[] = { 567 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 568 0x00, 0x00, 0x00, 0x00, 569 0x00, 0x00, 0x00, 0x00, 570 0x08, 0x00, 571 572 0x45, 0x00, 0x00, 0x4c, /* IP 14 */ 573 0x00, 0x00, 0x00, 0x00, 574 0x00, 0x11, 0x00, 0x00, 575 0x00, 0x00, 0x00, 0x00, 576 0x00, 0x00, 0x00, 0x00, 577 578 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 579 0x00, 0x38, 0x00, 0x00, 580 581 0x34, 0xff, 0x00, 0x28, /* GTP-U Header 42 */ 582 0x00, 0x00, 0x00, 0x00, 583 0x00, 0x00, 0x00, 0x85, 584 585 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 586 0x00, 0x00, 0x00, 0x00, 587 588 0x45, 0x00, 0x00, 0x1c, /* IP 62 */ 589 0x00, 0x00, 0x00, 0x00, 590 0x00, 0x11, 0x00, 0x00, 591 0x00, 0x00, 0x00, 0x00, 592 0x00, 0x00, 0x00, 0x00, 593 594 0x00, 0x00, 0x00, 0x00, /* UDP 82 */ 595 0x00, 0x08, 0x00, 0x00, 596 597 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 598 }; 599 600 /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 601 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_tcp_packet_offsets[] = { 602 { ICE_MAC_OFOS, 0 }, 603 { ICE_IPV4_OFOS, 14 }, 604 { ICE_UDP_OF, 34 }, 605 { ICE_GTP, 42 }, 606 { ICE_IPV6_IL, 62 }, 607 { ICE_TCP_IL, 102 }, 608 { ICE_PROTOCOL_LAST, 0 }, 609 }; 610 611 static const u8 dummy_ipv4_gtpu_ipv6_tcp_packet[] = { 612 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 613 0x00, 0x00, 0x00, 0x00, 614 0x00, 0x00, 0x00, 0x00, 615 0x08, 0x00, 616 617 0x45, 0x00, 0x00, 0x6c, /* IP 14 */ 618 0x00, 0x00, 0x00, 0x00, 619 0x00, 0x11, 0x00, 0x00, 620 0x00, 0x00, 0x00, 0x00, 621 0x00, 0x00, 0x00, 0x00, 622 623 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 624 0x00, 0x58, 0x00, 0x00, 625 626 0x34, 0xff, 0x00, 0x48, /* GTP-U Header 42 */ 627 0x00, 0x00, 0x00, 0x00, 628 0x00, 0x00, 0x00, 0x85, 629 630 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 631 0x00, 0x00, 0x00, 0x00, 632 633 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 634 0x00, 0x14, 0x06, 0x00, 635 0x00, 0x00, 0x00, 0x00, 636 0x00, 0x00, 0x00, 0x00, 637 0x00, 0x00, 0x00, 0x00, 638 0x00, 0x00, 0x00, 0x00, 639 0x00, 0x00, 0x00, 0x00, 640 0x00, 0x00, 0x00, 0x00, 641 0x00, 0x00, 0x00, 0x00, 642 0x00, 0x00, 0x00, 0x00, 643 644 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 645 0x00, 0x00, 0x00, 0x00, 646 0x00, 0x00, 0x00, 0x00, 647 0x50, 0x00, 0x00, 0x00, 648 0x00, 0x00, 0x00, 0x00, 649 650 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 651 }; 652 653 static const struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_udp_packet_offsets[] = { 654 { ICE_MAC_OFOS, 0 }, 655 { ICE_IPV4_OFOS, 14 }, 656 { ICE_UDP_OF, 34 }, 657 { ICE_GTP, 42 }, 658 { ICE_IPV6_IL, 62 }, 659 { ICE_UDP_ILOS, 102 }, 660 { ICE_PROTOCOL_LAST, 0 }, 661 }; 662 663 static const u8 dummy_ipv4_gtpu_ipv6_udp_packet[] = { 664 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 665 0x00, 0x00, 0x00, 0x00, 666 0x00, 0x00, 0x00, 0x00, 667 0x08, 0x00, 668 669 0x45, 0x00, 0x00, 0x60, /* IP 14 */ 670 0x00, 0x00, 0x00, 0x00, 671 0x00, 0x11, 0x00, 0x00, 672 0x00, 0x00, 0x00, 0x00, 673 0x00, 0x00, 0x00, 0x00, 674 675 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 676 0x00, 0x4c, 0x00, 0x00, 677 678 0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 42 */ 679 0x00, 0x00, 0x00, 0x00, 680 0x00, 0x00, 0x00, 0x85, 681 682 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 683 0x00, 0x00, 0x00, 0x00, 684 685 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 686 0x00, 0x08, 0x11, 0x00, 687 0x00, 0x00, 0x00, 0x00, 688 0x00, 0x00, 0x00, 0x00, 689 0x00, 0x00, 0x00, 0x00, 690 0x00, 0x00, 0x00, 0x00, 691 0x00, 0x00, 0x00, 0x00, 692 0x00, 0x00, 0x00, 0x00, 693 0x00, 0x00, 0x00, 0x00, 694 0x00, 0x00, 0x00, 0x00, 695 696 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 697 0x00, 0x08, 0x00, 0x00, 698 699 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 700 }; 701 702 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_tcp_packet_offsets[] = { 703 { ICE_MAC_OFOS, 0 }, 704 { ICE_IPV6_OFOS, 14 }, 705 { ICE_UDP_OF, 54 }, 706 { ICE_GTP, 62 }, 707 { ICE_IPV4_IL, 82 }, 708 { ICE_TCP_IL, 102 }, 709 { ICE_PROTOCOL_LAST, 0 }, 710 }; 711 712 static const u8 dummy_ipv6_gtpu_ipv4_tcp_packet[] = { 713 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 714 0x00, 0x00, 0x00, 0x00, 715 0x00, 0x00, 0x00, 0x00, 716 0x86, 0xdd, 717 718 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 719 0x00, 0x44, 0x11, 0x00, 720 0x00, 0x00, 0x00, 0x00, 721 0x00, 0x00, 0x00, 0x00, 722 0x00, 0x00, 0x00, 0x00, 723 0x00, 0x00, 0x00, 0x00, 724 0x00, 0x00, 0x00, 0x00, 725 0x00, 0x00, 0x00, 0x00, 726 0x00, 0x00, 0x00, 0x00, 727 0x00, 0x00, 0x00, 0x00, 728 729 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 730 0x00, 0x44, 0x00, 0x00, 731 732 0x34, 0xff, 0x00, 0x34, /* GTP-U Header 62 */ 733 0x00, 0x00, 0x00, 0x00, 734 0x00, 0x00, 0x00, 0x85, 735 736 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 737 0x00, 0x00, 0x00, 0x00, 738 739 0x45, 0x00, 0x00, 0x28, /* IP 82 */ 740 0x00, 0x00, 0x00, 0x00, 741 0x00, 0x06, 0x00, 0x00, 742 0x00, 0x00, 0x00, 0x00, 743 0x00, 0x00, 0x00, 0x00, 744 745 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 746 0x00, 0x00, 0x00, 0x00, 747 0x00, 0x00, 0x00, 0x00, 748 0x50, 0x00, 0x00, 0x00, 749 0x00, 0x00, 0x00, 0x00, 750 751 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 752 }; 753 754 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_udp_packet_offsets[] = { 755 { ICE_MAC_OFOS, 0 }, 756 { ICE_IPV6_OFOS, 14 }, 757 { ICE_UDP_OF, 54 }, 758 { ICE_GTP, 62 }, 759 { ICE_IPV4_IL, 82 }, 760 { ICE_UDP_ILOS, 102 }, 761 { ICE_PROTOCOL_LAST, 0 }, 762 }; 763 764 static const u8 dummy_ipv6_gtpu_ipv4_udp_packet[] = { 765 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 766 0x00, 0x00, 0x00, 0x00, 767 0x00, 0x00, 0x00, 0x00, 768 0x86, 0xdd, 769 770 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 771 0x00, 0x38, 0x11, 0x00, 772 0x00, 0x00, 0x00, 0x00, 773 0x00, 0x00, 0x00, 0x00, 774 0x00, 0x00, 0x00, 0x00, 775 0x00, 0x00, 0x00, 0x00, 776 0x00, 0x00, 0x00, 0x00, 777 0x00, 0x00, 0x00, 0x00, 778 0x00, 0x00, 0x00, 0x00, 779 0x00, 0x00, 0x00, 0x00, 780 781 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 782 0x00, 0x38, 0x00, 0x00, 783 784 0x34, 0xff, 0x00, 0x28, /* GTP-U Header 62 */ 785 0x00, 0x00, 0x00, 0x00, 786 0x00, 0x00, 0x00, 0x85, 787 788 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 789 0x00, 0x00, 0x00, 0x00, 790 791 0x45, 0x00, 0x00, 0x1c, /* IP 82 */ 792 0x00, 0x00, 0x00, 0x00, 793 0x00, 0x11, 0x00, 0x00, 794 0x00, 0x00, 0x00, 0x00, 795 0x00, 0x00, 0x00, 0x00, 796 797 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 798 0x00, 0x08, 0x00, 0x00, 799 800 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 801 }; 802 803 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_tcp_packet_offsets[] = { 804 { ICE_MAC_OFOS, 0 }, 805 { ICE_IPV6_OFOS, 14 }, 806 { ICE_UDP_OF, 54 }, 807 { ICE_GTP, 62 }, 808 { ICE_IPV6_IL, 82 }, 809 { ICE_TCP_IL, 102 }, 810 { ICE_PROTOCOL_LAST, 0 }, 811 }; 812 813 static const u8 dummy_ipv6_gtpu_ipv6_tcp_packet[] = { 814 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 815 0x00, 0x00, 0x00, 0x00, 816 0x00, 0x00, 0x00, 0x00, 817 0x86, 0xdd, 818 819 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 820 0x00, 0x58, 0x11, 0x00, 821 0x00, 0x00, 0x00, 0x00, 822 0x00, 0x00, 0x00, 0x00, 823 0x00, 0x00, 0x00, 0x00, 824 0x00, 0x00, 0x00, 0x00, 825 0x00, 0x00, 0x00, 0x00, 826 0x00, 0x00, 0x00, 0x00, 827 0x00, 0x00, 0x00, 0x00, 828 0x00, 0x00, 0x00, 0x00, 829 830 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 831 0x00, 0x58, 0x00, 0x00, 832 833 0x34, 0xff, 0x00, 0x48, /* GTP-U Header 62 */ 834 0x00, 0x00, 0x00, 0x00, 835 0x00, 0x00, 0x00, 0x85, 836 837 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 838 0x00, 0x00, 0x00, 0x00, 839 840 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 841 0x00, 0x14, 0x06, 0x00, 842 0x00, 0x00, 0x00, 0x00, 843 0x00, 0x00, 0x00, 0x00, 844 0x00, 0x00, 0x00, 0x00, 845 0x00, 0x00, 0x00, 0x00, 846 0x00, 0x00, 0x00, 0x00, 847 0x00, 0x00, 0x00, 0x00, 848 0x00, 0x00, 0x00, 0x00, 849 0x00, 0x00, 0x00, 0x00, 850 851 0x00, 0x00, 0x00, 0x00, /* TCP 122 */ 852 0x00, 0x00, 0x00, 0x00, 853 0x00, 0x00, 0x00, 0x00, 854 0x50, 0x00, 0x00, 0x00, 855 0x00, 0x00, 0x00, 0x00, 856 857 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 858 }; 859 860 static const struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_udp_packet_offsets[] = { 861 { ICE_MAC_OFOS, 0 }, 862 { ICE_IPV6_OFOS, 14 }, 863 { ICE_UDP_OF, 54 }, 864 { ICE_GTP, 62 }, 865 { ICE_IPV6_IL, 82 }, 866 { ICE_UDP_ILOS, 102 }, 867 { ICE_PROTOCOL_LAST, 0 }, 868 }; 869 870 static const u8 dummy_ipv6_gtpu_ipv6_udp_packet[] = { 871 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 872 0x00, 0x00, 0x00, 0x00, 873 0x00, 0x00, 0x00, 0x00, 874 0x86, 0xdd, 875 876 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 877 0x00, 0x4c, 0x11, 0x00, 878 0x00, 0x00, 0x00, 0x00, 879 0x00, 0x00, 0x00, 0x00, 880 0x00, 0x00, 0x00, 0x00, 881 0x00, 0x00, 0x00, 0x00, 882 0x00, 0x00, 0x00, 0x00, 883 0x00, 0x00, 0x00, 0x00, 884 0x00, 0x00, 0x00, 0x00, 885 0x00, 0x00, 0x00, 0x00, 886 887 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 888 0x00, 0x4c, 0x00, 0x00, 889 890 0x34, 0xff, 0x00, 0x3c, /* GTP-U Header 62 */ 891 0x00, 0x00, 0x00, 0x00, 892 0x00, 0x00, 0x00, 0x85, 893 894 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 895 0x00, 0x00, 0x00, 0x00, 896 897 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 898 0x00, 0x08, 0x11, 0x00, 899 0x00, 0x00, 0x00, 0x00, 900 0x00, 0x00, 0x00, 0x00, 901 0x00, 0x00, 0x00, 0x00, 902 0x00, 0x00, 0x00, 0x00, 903 0x00, 0x00, 0x00, 0x00, 904 0x00, 0x00, 0x00, 0x00, 905 0x00, 0x00, 0x00, 0x00, 906 0x00, 0x00, 0x00, 0x00, 907 908 0x00, 0x00, 0x00, 0x00, /* UDP 122 */ 909 0x00, 0x08, 0x00, 0x00, 910 911 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 912 }; 913 914 static const struct ice_dummy_pkt_offsets dummy_udp_gtp_packet_offsets[] = { 915 { ICE_MAC_OFOS, 0 }, 916 { ICE_IPV4_OFOS, 14 }, 917 { ICE_UDP_OF, 34 }, 918 { ICE_GTP, 42 }, 919 { ICE_PROTOCOL_LAST, 0 }, 920 }; 921 922 static const u8 dummy_udp_gtp_packet[] = { 923 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 924 0x00, 0x00, 0x00, 0x00, 925 0x00, 0x00, 0x00, 0x00, 926 0x08, 0x00, 927 928 0x45, 0x00, 0x00, 0x30, /* ICE_IPV4_OFOS 14 */ 929 0x00, 0x00, 0x00, 0x00, 930 0x00, 0x11, 0x00, 0x00, 931 0x00, 0x00, 0x00, 0x00, 932 0x00, 0x00, 0x00, 0x00, 933 934 0x00, 0x00, 0x08, 0x68, /* ICE_UDP_OF 34 */ 935 0x00, 0x1c, 0x00, 0x00, 936 937 0x34, 0xff, 0x00, 0x0c, /* ICE_GTP 42 */ 938 0x00, 0x00, 0x00, 0x00, 939 0x00, 0x00, 0x00, 0x85, 940 941 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 942 0x00, 0x00, 0x00, 0x00, 943 }; 944 945 static const 946 struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv4_packet_offsets[] = { 947 { ICE_MAC_OFOS, 0 }, 948 { ICE_IPV4_OFOS, 14 }, 949 { ICE_UDP_OF, 34 }, 950 { ICE_GTP, 42 }, 951 { ICE_IPV4_IL, 62 }, 952 { ICE_PROTOCOL_LAST, 0 }, 953 }; 954 955 static const u8 dummy_ipv4_gtpu_ipv4_packet[] = { 956 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 957 0x00, 0x00, 0x00, 0x00, 958 0x00, 0x00, 0x00, 0x00, 959 0x08, 0x00, 960 961 0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */ 962 0x00, 0x00, 0x40, 0x00, 963 0x40, 0x11, 0x00, 0x00, 964 0x00, 0x00, 0x00, 0x00, 965 0x00, 0x00, 0x00, 0x00, 966 967 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */ 968 0x00, 0x00, 0x00, 0x00, 969 970 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */ 971 0x00, 0x00, 0x00, 0x00, 972 0x00, 0x00, 0x00, 0x85, 973 974 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 975 0x00, 0x00, 0x00, 0x00, 976 977 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */ 978 0x00, 0x00, 0x40, 0x00, 979 0x40, 0x00, 0x00, 0x00, 980 0x00, 0x00, 0x00, 0x00, 981 0x00, 0x00, 0x00, 0x00, 982 0x00, 0x00, 983 }; 984 985 static const 986 struct ice_dummy_pkt_offsets dummy_ipv4_gtpu_ipv6_packet_offsets[] = { 987 { ICE_MAC_OFOS, 0 }, 988 { ICE_IPV4_OFOS, 14 }, 989 { ICE_UDP_OF, 34 }, 990 { ICE_GTP, 42 }, 991 { ICE_IPV6_IL, 62 }, 992 { ICE_PROTOCOL_LAST, 0 }, 993 }; 994 995 static const u8 dummy_ipv4_gtpu_ipv6_packet[] = { 996 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 997 0x00, 0x00, 0x00, 0x00, 998 0x00, 0x00, 0x00, 0x00, 999 0x08, 0x00, 1000 1001 0x45, 0x00, 0x00, 0x58, /* ICE_IPV4_OFOS 14 */ 1002 0x00, 0x00, 0x40, 0x00, 1003 0x40, 0x11, 0x00, 0x00, 1004 0x00, 0x00, 0x00, 0x00, 1005 0x00, 0x00, 0x00, 0x00, 1006 1007 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */ 1008 0x00, 0x00, 0x00, 0x00, 1009 1010 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */ 1011 0x00, 0x00, 0x00, 0x00, 1012 0x00, 0x00, 0x00, 0x85, 1013 1014 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 1015 0x00, 0x00, 0x00, 0x00, 1016 1017 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 62 */ 1018 0x00, 0x00, 0x3b, 0x00, 1019 0x00, 0x00, 0x00, 0x00, 1020 0x00, 0x00, 0x00, 0x00, 1021 0x00, 0x00, 0x00, 0x00, 1022 0x00, 0x00, 0x00, 0x00, 1023 0x00, 0x00, 0x00, 0x00, 1024 0x00, 0x00, 0x00, 0x00, 1025 0x00, 0x00, 0x00, 0x00, 1026 0x00, 0x00, 0x00, 0x00, 1027 1028 0x00, 0x00, 1029 }; 1030 1031 static const 1032 struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv4_packet_offsets[] = { 1033 { ICE_MAC_OFOS, 0 }, 1034 { ICE_IPV6_OFOS, 14 }, 1035 { ICE_UDP_OF, 54 }, 1036 { ICE_GTP, 62 }, 1037 { ICE_IPV4_IL, 82 }, 1038 { ICE_PROTOCOL_LAST, 0 }, 1039 }; 1040 1041 static const u8 dummy_ipv6_gtpu_ipv4_packet[] = { 1042 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1043 0x00, 0x00, 0x00, 0x00, 1044 0x00, 0x00, 0x00, 0x00, 1045 0x86, 0xdd, 1046 1047 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 1048 0x00, 0x58, 0x11, 0x00, /* Next header UDP*/ 1049 0x00, 0x00, 0x00, 0x00, 1050 0x00, 0x00, 0x00, 0x00, 1051 0x00, 0x00, 0x00, 0x00, 1052 0x00, 0x00, 0x00, 0x00, 1053 0x00, 0x00, 0x00, 0x00, 1054 0x00, 0x00, 0x00, 0x00, 1055 0x00, 0x00, 0x00, 0x00, 1056 0x00, 0x00, 0x00, 0x00, 1057 1058 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */ 1059 0x00, 0x00, 0x00, 0x00, 1060 1061 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 62 */ 1062 0x00, 0x00, 0x00, 0x00, 1063 0x00, 0x00, 0x00, 0x85, 1064 1065 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 1066 0x00, 0x00, 0x00, 0x00, 1067 1068 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 82 */ 1069 0x00, 0x00, 0x40, 0x00, 1070 0x40, 0x00, 0x00, 0x00, 1071 0x00, 0x00, 0x00, 0x00, 1072 0x00, 0x00, 0x00, 0x00, 1073 1074 0x00, 0x00, 1075 }; 1076 1077 static const 1078 struct ice_dummy_pkt_offsets dummy_ipv6_gtpu_ipv6_packet_offsets[] = { 1079 { ICE_MAC_OFOS, 0 }, 1080 { ICE_IPV6_OFOS, 14 }, 1081 { ICE_UDP_OF, 54 }, 1082 { ICE_GTP, 62 }, 1083 { ICE_IPV6_IL, 82 }, 1084 { ICE_PROTOCOL_LAST, 0 }, 1085 }; 1086 1087 static const u8 dummy_ipv6_gtpu_ipv6_packet[] = { 1088 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1089 0x00, 0x00, 0x00, 0x00, 1090 0x00, 0x00, 0x00, 0x00, 1091 0x86, 0xdd, 1092 1093 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 1094 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/ 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, /* ICE_UDP_OF 54 */ 1105 0x00, 0x00, 0x00, 0x00, 1106 1107 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 62 */ 1108 0x00, 0x00, 0x00, 0x00, 1109 0x00, 0x00, 0x00, 0x85, 1110 1111 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 1112 0x00, 0x00, 0x00, 0x00, 1113 1114 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFIL 82 */ 1115 0x00, 0x00, 0x3b, 0x00, 1116 0x00, 0x00, 0x00, 0x00, 1117 0x00, 0x00, 0x00, 0x00, 1118 0x00, 0x00, 0x00, 0x00, 1119 0x00, 0x00, 0x00, 0x00, 1120 0x00, 0x00, 0x00, 0x00, 1121 0x00, 0x00, 0x00, 0x00, 1122 0x00, 0x00, 0x00, 0x00, 1123 0x00, 0x00, 0x00, 0x00, 1124 1125 0x00, 0x00, 1126 }; 1127 1128 static const 1129 struct ice_dummy_pkt_offsets dummy_ipv4_gtp_no_pay_packet_offsets[] = { 1130 { ICE_MAC_OFOS, 0 }, 1131 { ICE_IPV4_OFOS, 14 }, 1132 { ICE_UDP_OF, 34 }, 1133 { ICE_GTP_NO_PAY, 42 }, 1134 { ICE_PROTOCOL_LAST, 0 }, 1135 }; 1136 1137 static const 1138 struct ice_dummy_pkt_offsets dummy_ipv6_gtp_no_pay_packet_offsets[] = { 1139 { ICE_MAC_OFOS, 0 }, 1140 { ICE_IPV6_OFOS, 14 }, 1141 { ICE_UDP_OF, 54 }, 1142 { ICE_GTP_NO_PAY, 62 }, 1143 { ICE_PROTOCOL_LAST, 0 }, 1144 }; 1145 1146 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_offsets[] = { 1147 { ICE_MAC_OFOS, 0 }, 1148 { ICE_ETYPE_OL, 12 }, 1149 { ICE_VLAN_OFOS, 14}, 1150 { ICE_PPPOE, 18 }, 1151 { ICE_PROTOCOL_LAST, 0 }, 1152 }; 1153 1154 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv4_offsets[] = { 1155 { ICE_MAC_OFOS, 0 }, 1156 { ICE_ETYPE_OL, 12 }, 1157 { ICE_VLAN_OFOS, 14}, 1158 { ICE_PPPOE, 18 }, 1159 { ICE_IPV4_OFOS, 26 }, 1160 { ICE_PROTOCOL_LAST, 0 }, 1161 }; 1162 1163 static const u8 dummy_pppoe_ipv4_packet[] = { 1164 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1165 0x00, 0x00, 0x00, 0x00, 1166 0x00, 0x00, 0x00, 0x00, 1167 1168 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 1169 1170 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */ 1171 1172 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */ 1173 0x00, 0x16, 1174 1175 0x00, 0x21, /* PPP Link Layer 24 */ 1176 1177 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 26 */ 1178 0x00, 0x00, 0x00, 0x00, 1179 0x00, 0x00, 0x00, 0x00, 1180 0x00, 0x00, 0x00, 0x00, 1181 0x00, 0x00, 0x00, 0x00, 1182 1183 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1184 }; 1185 1186 static const 1187 struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_tcp_packet_offsets[] = { 1188 { ICE_MAC_OFOS, 0 }, 1189 { ICE_ETYPE_OL, 12 }, 1190 { ICE_VLAN_OFOS, 14}, 1191 { ICE_PPPOE, 18 }, 1192 { ICE_IPV4_OFOS, 26 }, 1193 { ICE_TCP_IL, 46 }, 1194 { ICE_PROTOCOL_LAST, 0 }, 1195 }; 1196 1197 static const u8 dummy_pppoe_ipv4_tcp_packet[] = { 1198 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1199 0x00, 0x00, 0x00, 0x00, 1200 0x00, 0x00, 0x00, 0x00, 1201 1202 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 1203 1204 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */ 1205 1206 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */ 1207 0x00, 0x16, 1208 1209 0x00, 0x21, /* PPP Link Layer 24 */ 1210 1211 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 26 */ 1212 0x00, 0x01, 0x00, 0x00, 1213 0x00, 0x06, 0x00, 0x00, 1214 0x00, 0x00, 0x00, 0x00, 1215 0x00, 0x00, 0x00, 0x00, 1216 1217 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 46 */ 1218 0x00, 0x00, 0x00, 0x00, 1219 0x00, 0x00, 0x00, 0x00, 1220 0x50, 0x00, 0x00, 0x00, 1221 0x00, 0x00, 0x00, 0x00, 1222 1223 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1224 }; 1225 1226 static const 1227 struct ice_dummy_pkt_offsets dummy_pppoe_ipv4_udp_packet_offsets[] = { 1228 { ICE_MAC_OFOS, 0 }, 1229 { ICE_ETYPE_OL, 12 }, 1230 { ICE_VLAN_OFOS, 14}, 1231 { ICE_PPPOE, 18 }, 1232 { ICE_IPV4_OFOS, 26 }, 1233 { ICE_UDP_ILOS, 46 }, 1234 { ICE_PROTOCOL_LAST, 0 }, 1235 }; 1236 1237 static const u8 dummy_pppoe_ipv4_udp_packet[] = { 1238 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1239 0x00, 0x00, 0x00, 0x00, 1240 0x00, 0x00, 0x00, 0x00, 1241 1242 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 1243 1244 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */ 1245 1246 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */ 1247 0x00, 0x16, 1248 1249 0x00, 0x21, /* PPP Link Layer 24 */ 1250 1251 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 26 */ 1252 0x00, 0x01, 0x00, 0x00, 1253 0x00, 0x11, 0x00, 0x00, 1254 0x00, 0x00, 0x00, 0x00, 1255 0x00, 0x00, 0x00, 0x00, 1256 1257 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 46 */ 1258 0x00, 0x08, 0x00, 0x00, 1259 1260 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1261 }; 1262 1263 static const struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_offsets[] = { 1264 { ICE_MAC_OFOS, 0 }, 1265 { ICE_ETYPE_OL, 12 }, 1266 { ICE_VLAN_OFOS, 14}, 1267 { ICE_PPPOE, 18 }, 1268 { ICE_IPV6_OFOS, 26 }, 1269 { ICE_PROTOCOL_LAST, 0 }, 1270 }; 1271 1272 static const u8 dummy_pppoe_ipv6_packet[] = { 1273 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1274 0x00, 0x00, 0x00, 0x00, 1275 0x00, 0x00, 0x00, 0x00, 1276 1277 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 1278 1279 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */ 1280 1281 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */ 1282 0x00, 0x2a, 1283 1284 0x00, 0x57, /* PPP Link Layer 24 */ 1285 1286 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */ 1287 0x00, 0x00, 0x3b, 0x00, 1288 0x00, 0x00, 0x00, 0x00, 1289 0x00, 0x00, 0x00, 0x00, 1290 0x00, 0x00, 0x00, 0x00, 1291 0x00, 0x00, 0x00, 0x00, 1292 0x00, 0x00, 0x00, 0x00, 1293 0x00, 0x00, 0x00, 0x00, 1294 0x00, 0x00, 0x00, 0x00, 1295 0x00, 0x00, 0x00, 0x00, 1296 1297 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1298 }; 1299 1300 static const 1301 struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_tcp_offsets[] = { 1302 { ICE_MAC_OFOS, 0 }, 1303 { ICE_ETYPE_OL, 12 }, 1304 { ICE_VLAN_OFOS, 14}, 1305 { ICE_PPPOE, 18 }, 1306 { ICE_IPV6_OFOS, 26 }, 1307 { ICE_TCP_IL, 66 }, 1308 { ICE_PROTOCOL_LAST, 0 }, 1309 }; 1310 1311 static const u8 dummy_pppoe_ipv6_tcp_packet[] = { 1312 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1313 0x00, 0x00, 0x00, 0x00, 1314 0x00, 0x00, 0x00, 0x00, 1315 1316 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 1317 1318 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */ 1319 1320 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */ 1321 0x00, 0x2a, 1322 1323 0x00, 0x57, /* PPP Link Layer 24 */ 1324 1325 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */ 1326 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 1327 0x00, 0x00, 0x00, 0x00, 1328 0x00, 0x00, 0x00, 0x00, 1329 0x00, 0x00, 0x00, 0x00, 1330 0x00, 0x00, 0x00, 0x00, 1331 0x00, 0x00, 0x00, 0x00, 1332 0x00, 0x00, 0x00, 0x00, 1333 0x00, 0x00, 0x00, 0x00, 1334 0x00, 0x00, 0x00, 0x00, 1335 1336 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 66 */ 1337 0x00, 0x00, 0x00, 0x00, 1338 0x00, 0x00, 0x00, 0x00, 1339 0x50, 0x00, 0x00, 0x00, 1340 0x00, 0x00, 0x00, 0x00, 1341 1342 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1343 }; 1344 1345 static const 1346 struct ice_dummy_pkt_offsets dummy_pppoe_packet_ipv6_udp_offsets[] = { 1347 { ICE_MAC_OFOS, 0 }, 1348 { ICE_ETYPE_OL, 12 }, 1349 { ICE_VLAN_OFOS, 14}, 1350 { ICE_PPPOE, 18 }, 1351 { ICE_IPV6_OFOS, 26 }, 1352 { ICE_UDP_ILOS, 66 }, 1353 { ICE_PROTOCOL_LAST, 0 }, 1354 }; 1355 1356 static const u8 dummy_pppoe_ipv6_udp_packet[] = { 1357 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1358 0x00, 0x00, 0x00, 0x00, 1359 0x00, 0x00, 0x00, 0x00, 1360 1361 0x81, 0x00, /* ICE_ETYPE_OL 12 */ 1362 1363 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 14 */ 1364 1365 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 18 */ 1366 0x00, 0x2a, 1367 1368 0x00, 0x57, /* PPP Link Layer 24 */ 1369 1370 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 26 */ 1371 0x00, 0x08, 0x11, 0x00, /* Next header UDP*/ 1372 0x00, 0x00, 0x00, 0x00, 1373 0x00, 0x00, 0x00, 0x00, 1374 0x00, 0x00, 0x00, 0x00, 1375 0x00, 0x00, 0x00, 0x00, 1376 0x00, 0x00, 0x00, 0x00, 1377 0x00, 0x00, 0x00, 0x00, 1378 0x00, 0x00, 0x00, 0x00, 1379 0x00, 0x00, 0x00, 0x00, 1380 1381 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 66 */ 1382 0x00, 0x08, 0x00, 0x00, 1383 1384 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1385 }; 1386 1387 static const struct ice_dummy_pkt_offsets dummy_ipv4_esp_packet_offsets[] = { 1388 { ICE_MAC_OFOS, 0 }, 1389 { ICE_IPV4_OFOS, 14 }, 1390 { ICE_ESP, 34 }, 1391 { ICE_PROTOCOL_LAST, 0 }, 1392 }; 1393 1394 static const u8 dummy_ipv4_esp_pkt[] = { 1395 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1396 0x00, 0x00, 0x00, 0x00, 1397 0x00, 0x00, 0x00, 0x00, 1398 0x08, 0x00, 1399 1400 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 14 */ 1401 0x00, 0x00, 0x40, 0x00, 1402 0x40, 0x32, 0x00, 0x00, 1403 0x00, 0x00, 0x00, 0x00, 1404 0x00, 0x00, 0x00, 0x00, 1405 1406 0x00, 0x00, 0x00, 0x00, /* ICE_ESP 34 */ 1407 0x00, 0x00, 0x00, 0x00, 1408 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1409 }; 1410 1411 static const struct ice_dummy_pkt_offsets dummy_ipv6_esp_packet_offsets[] = { 1412 { ICE_MAC_OFOS, 0 }, 1413 { ICE_IPV6_OFOS, 14 }, 1414 { ICE_ESP, 54 }, 1415 { ICE_PROTOCOL_LAST, 0 }, 1416 }; 1417 1418 static const u8 dummy_ipv6_esp_pkt[] = { 1419 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1420 0x00, 0x00, 0x00, 0x00, 1421 0x00, 0x00, 0x00, 0x00, 1422 0x86, 0xDD, 1423 1424 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 1425 0x00, 0x08, 0x32, 0x00, /* Next header ESP */ 1426 0x00, 0x00, 0x00, 0x00, 1427 0x00, 0x00, 0x00, 0x00, 1428 0x00, 0x00, 0x00, 0x00, 1429 0x00, 0x00, 0x00, 0x00, 1430 0x00, 0x00, 0x00, 0x00, 1431 0x00, 0x00, 0x00, 0x00, 1432 0x00, 0x00, 0x00, 0x00, 1433 0x00, 0x00, 0x00, 0x00, 1434 1435 0x00, 0x00, 0x00, 0x00, /* ICE_ESP 54 */ 1436 0x00, 0x00, 0x00, 0x00, 1437 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1438 }; 1439 1440 static const struct ice_dummy_pkt_offsets dummy_ipv4_ah_packet_offsets[] = { 1441 { ICE_MAC_OFOS, 0 }, 1442 { ICE_IPV4_OFOS, 14 }, 1443 { ICE_AH, 34 }, 1444 { ICE_PROTOCOL_LAST, 0 }, 1445 }; 1446 1447 static const u8 dummy_ipv4_ah_pkt[] = { 1448 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1449 0x00, 0x00, 0x00, 0x00, 1450 0x00, 0x00, 0x00, 0x00, 1451 0x08, 0x00, 1452 1453 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */ 1454 0x00, 0x00, 0x40, 0x00, 1455 0x40, 0x33, 0x00, 0x00, 1456 0x00, 0x00, 0x00, 0x00, 1457 0x00, 0x00, 0x00, 0x00, 1458 1459 0x00, 0x00, 0x00, 0x00, /* ICE_AH 34 */ 1460 0x00, 0x00, 0x00, 0x00, 1461 0x00, 0x00, 0x00, 0x00, 1462 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1463 }; 1464 1465 static const struct ice_dummy_pkt_offsets dummy_ipv6_ah_packet_offsets[] = { 1466 { ICE_MAC_OFOS, 0 }, 1467 { ICE_IPV6_OFOS, 14 }, 1468 { ICE_AH, 54 }, 1469 { ICE_PROTOCOL_LAST, 0 }, 1470 }; 1471 1472 static const u8 dummy_ipv6_ah_pkt[] = { 1473 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1474 0x00, 0x00, 0x00, 0x00, 1475 0x00, 0x00, 0x00, 0x00, 1476 0x86, 0xDD, 1477 1478 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 1479 0x00, 0x0c, 0x33, 0x00, /* Next header AH */ 1480 0x00, 0x00, 0x00, 0x00, 1481 0x00, 0x00, 0x00, 0x00, 1482 0x00, 0x00, 0x00, 0x00, 1483 0x00, 0x00, 0x00, 0x00, 1484 0x00, 0x00, 0x00, 0x00, 1485 0x00, 0x00, 0x00, 0x00, 1486 0x00, 0x00, 0x00, 0x00, 1487 0x00, 0x00, 0x00, 0x00, 1488 1489 0x00, 0x00, 0x00, 0x00, /* ICE_AH 54 */ 1490 0x00, 0x00, 0x00, 0x00, 1491 0x00, 0x00, 0x00, 0x00, 1492 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1493 }; 1494 1495 static const struct ice_dummy_pkt_offsets dummy_ipv4_nat_packet_offsets[] = { 1496 { ICE_MAC_OFOS, 0 }, 1497 { ICE_IPV4_OFOS, 14 }, 1498 { ICE_UDP_ILOS, 34 }, 1499 { ICE_NAT_T, 42 }, 1500 { ICE_PROTOCOL_LAST, 0 }, 1501 }; 1502 1503 static const u8 dummy_ipv4_nat_pkt[] = { 1504 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1505 0x00, 0x00, 0x00, 0x00, 1506 0x00, 0x00, 0x00, 0x00, 1507 0x08, 0x00, 1508 1509 0x45, 0x00, 0x00, 0x24, /* ICE_IPV4_IL 14 */ 1510 0x00, 0x00, 0x40, 0x00, 1511 0x40, 0x11, 0x00, 0x00, 1512 0x00, 0x00, 0x00, 0x00, 1513 0x00, 0x00, 0x00, 0x00, 1514 1515 0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 34 */ 1516 0x00, 0x00, 0x00, 0x00, 1517 1518 0x00, 0x00, 0x00, 0x00, 1519 0x00, 0x00, 0x00, 0x00, 1520 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1521 }; 1522 1523 static const struct ice_dummy_pkt_offsets dummy_ipv6_nat_packet_offsets[] = { 1524 { ICE_MAC_OFOS, 0 }, 1525 { ICE_IPV6_OFOS, 14 }, 1526 { ICE_UDP_ILOS, 54 }, 1527 { ICE_NAT_T, 62 }, 1528 { ICE_PROTOCOL_LAST, 0 }, 1529 }; 1530 1531 static const u8 dummy_ipv6_nat_pkt[] = { 1532 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1533 0x00, 0x00, 0x00, 0x00, 1534 0x00, 0x00, 0x00, 0x00, 1535 0x86, 0xDD, 1536 1537 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 1538 0x00, 0x10, 0x11, 0x00, /* Next header NAT_T */ 1539 0x00, 0x00, 0x00, 0x00, 1540 0x00, 0x00, 0x00, 0x00, 1541 0x00, 0x00, 0x00, 0x00, 1542 0x00, 0x00, 0x00, 0x00, 1543 0x00, 0x00, 0x00, 0x00, 1544 0x00, 0x00, 0x00, 0x00, 1545 0x00, 0x00, 0x00, 0x00, 1546 0x00, 0x00, 0x00, 0x00, 1547 1548 0x00, 0x00, 0x11, 0x94, /* ICE_NAT_T 54 */ 1549 0x00, 0x00, 0x00, 0x00, 1550 1551 0x00, 0x00, 0x00, 0x00, 1552 0x00, 0x00, 0x00, 0x00, 1553 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1554 1555 }; 1556 1557 static const struct ice_dummy_pkt_offsets dummy_ipv4_l2tpv3_packet_offsets[] = { 1558 { ICE_MAC_OFOS, 0 }, 1559 { ICE_IPV4_OFOS, 14 }, 1560 { ICE_L2TPV3, 34 }, 1561 { ICE_PROTOCOL_LAST, 0 }, 1562 }; 1563 1564 static const u8 dummy_ipv4_l2tpv3_pkt[] = { 1565 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1566 0x00, 0x00, 0x00, 0x00, 1567 0x00, 0x00, 0x00, 0x00, 1568 0x08, 0x00, 1569 1570 0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */ 1571 0x00, 0x00, 0x40, 0x00, 1572 0x40, 0x73, 0x00, 0x00, 1573 0x00, 0x00, 0x00, 0x00, 1574 0x00, 0x00, 0x00, 0x00, 1575 1576 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */ 1577 0x00, 0x00, 0x00, 0x00, 1578 0x00, 0x00, 0x00, 0x00, 1579 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1580 }; 1581 1582 static const struct ice_dummy_pkt_offsets dummy_ipv6_l2tpv3_packet_offsets[] = { 1583 { ICE_MAC_OFOS, 0 }, 1584 { ICE_IPV6_OFOS, 14 }, 1585 { ICE_L2TPV3, 54 }, 1586 { ICE_PROTOCOL_LAST, 0 }, 1587 }; 1588 1589 static const u8 dummy_ipv6_l2tpv3_pkt[] = { 1590 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1591 0x00, 0x00, 0x00, 0x00, 1592 0x00, 0x00, 0x00, 0x00, 1593 0x86, 0xDD, 1594 1595 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */ 1596 0x00, 0x0c, 0x73, 0x40, 1597 0x00, 0x00, 0x00, 0x00, 1598 0x00, 0x00, 0x00, 0x00, 1599 0x00, 0x00, 0x00, 0x00, 1600 0x00, 0x00, 0x00, 0x00, 1601 0x00, 0x00, 0x00, 0x00, 1602 0x00, 0x00, 0x00, 0x00, 1603 0x00, 0x00, 0x00, 0x00, 1604 0x00, 0x00, 0x00, 0x00, 1605 1606 0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */ 1607 0x00, 0x00, 0x00, 0x00, 1608 0x00, 0x00, 0x00, 0x00, 1609 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1610 }; 1611 1612 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv4_packet_offsets[] = { 1613 { ICE_MAC_OFOS, 0 }, 1614 { ICE_VLAN_EX, 14 }, 1615 { ICE_VLAN_OFOS, 18 }, 1616 { ICE_IPV4_OFOS, 22 }, 1617 { ICE_PROTOCOL_LAST, 0 }, 1618 }; 1619 1620 static const u8 dummy_qinq_ipv4_pkt[] = { 1621 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1622 0x00, 0x00, 0x00, 0x00, 1623 0x00, 0x00, 0x00, 0x00, 1624 0x91, 0x00, 1625 1626 0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */ 1627 0x00, 0x00, 0x08, 0x00, /* ICE_VLAN_OFOS 18 */ 1628 1629 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */ 1630 0x00, 0x01, 0x00, 0x00, 1631 0x00, 0x11, 0x00, 0x00, 1632 0x00, 0x00, 0x00, 0x00, 1633 0x00, 0x00, 0x00, 0x00, 1634 1635 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */ 1636 0x00, 0x08, 0x00, 0x00, 1637 1638 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 1639 }; 1640 1641 static const struct ice_dummy_pkt_offsets dummy_qinq_ipv6_packet_offsets[] = { 1642 { ICE_MAC_OFOS, 0 }, 1643 { ICE_VLAN_EX, 14 }, 1644 { ICE_VLAN_OFOS, 18 }, 1645 { ICE_IPV6_OFOS, 22 }, 1646 { ICE_PROTOCOL_LAST, 0 }, 1647 }; 1648 1649 static const u8 dummy_qinq_ipv6_pkt[] = { 1650 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1651 0x00, 0x00, 0x00, 0x00, 1652 0x00, 0x00, 0x00, 0x00, 1653 0x91, 0x00, 1654 1655 0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */ 1656 0x00, 0x00, 0x86, 0xDD, /* ICE_VLAN_OFOS 18 */ 1657 1658 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */ 1659 0x00, 0x10, 0x11, 0x00, /* Next header UDP */ 1660 0x00, 0x00, 0x00, 0x00, 1661 0x00, 0x00, 0x00, 0x00, 1662 0x00, 0x00, 0x00, 0x00, 1663 0x00, 0x00, 0x00, 0x00, 1664 0x00, 0x00, 0x00, 0x00, 1665 0x00, 0x00, 0x00, 0x00, 1666 0x00, 0x00, 0x00, 0x00, 1667 0x00, 0x00, 0x00, 0x00, 1668 1669 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */ 1670 0x00, 0x10, 0x00, 0x00, 1671 1672 0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */ 1673 0x00, 0x00, 0x00, 0x00, 1674 1675 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 1676 }; 1677 1678 static const struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_offsets[] = { 1679 { ICE_MAC_OFOS, 0 }, 1680 { ICE_VLAN_EX, 14 }, 1681 { ICE_VLAN_OFOS, 18 }, 1682 { ICE_PPPOE, 22 }, 1683 { ICE_PROTOCOL_LAST, 0 }, 1684 }; 1685 1686 static const 1687 struct ice_dummy_pkt_offsets dummy_qinq_pppoe_ipv4_packet_offsets[] = { 1688 { ICE_MAC_OFOS, 0 }, 1689 { ICE_VLAN_EX, 14 }, 1690 { ICE_VLAN_OFOS, 18 }, 1691 { ICE_PPPOE, 22 }, 1692 { ICE_IPV4_OFOS, 30 }, 1693 { ICE_PROTOCOL_LAST, 0 }, 1694 }; 1695 1696 static const u8 dummy_qinq_pppoe_ipv4_pkt[] = { 1697 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1698 0x00, 0x00, 0x00, 0x00, 1699 0x00, 0x00, 0x00, 0x00, 1700 0x91, 0x00, 1701 1702 0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */ 1703 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 18 */ 1704 1705 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */ 1706 0x00, 0x16, 1707 1708 0x00, 0x21, /* PPP Link Layer 28 */ 1709 1710 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 30 */ 1711 0x00, 0x00, 0x00, 0x00, 1712 0x00, 0x00, 0x00, 0x00, 1713 0x00, 0x00, 0x00, 0x00, 1714 0x00, 0x00, 0x00, 0x00, 1715 1716 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 1717 }; 1718 1719 static const 1720 struct ice_dummy_pkt_offsets dummy_qinq_pppoe_packet_ipv6_offsets[] = { 1721 { ICE_MAC_OFOS, 0 }, 1722 { ICE_ETYPE_OL, 12 }, 1723 { ICE_VLAN_EX, 14}, 1724 { ICE_VLAN_OFOS, 18 }, 1725 { ICE_PPPOE, 22 }, 1726 { ICE_IPV6_OFOS, 30 }, 1727 { ICE_PROTOCOL_LAST, 0 }, 1728 }; 1729 1730 static const u8 dummy_qinq_pppoe_ipv6_packet[] = { 1731 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1732 0x00, 0x00, 0x00, 0x00, 1733 0x00, 0x00, 0x00, 0x00, 1734 1735 0x91, 0x00, /* ICE_ETYPE_OL 12 */ 1736 1737 0x00, 0x00, 0x81, 0x00, /* ICE_VLAN_EX 14 */ 1738 0x00, 0x00, 0x88, 0x64, /* ICE_VLAN_OFOS 18 */ 1739 1740 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 22 */ 1741 0x00, 0x2a, 1742 1743 0x00, 0x57, /* PPP Link Layer 28*/ 1744 1745 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 30 */ 1746 0x00, 0x00, 0x3b, 0x00, 1747 0x00, 0x00, 0x00, 0x00, 1748 0x00, 0x00, 0x00, 0x00, 1749 0x00, 0x00, 0x00, 0x00, 1750 0x00, 0x00, 0x00, 0x00, 1751 0x00, 0x00, 0x00, 0x00, 1752 0x00, 0x00, 0x00, 0x00, 1753 0x00, 0x00, 0x00, 0x00, 1754 0x00, 0x00, 0x00, 0x00, 1755 1756 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1757 }; 1758 1759 /* this is a recipe to profile association bitmap */ 1760 static ice_declare_bitmap(recipe_to_profile[ICE_MAX_NUM_RECIPES], 1761 ICE_MAX_NUM_PROFILES); 1762 1763 /* this is a profile to recipe association bitmap */ 1764 static ice_declare_bitmap(profile_to_recipe[ICE_MAX_NUM_PROFILES], 1765 ICE_MAX_NUM_RECIPES); 1766 1767 static void ice_get_recp_to_prof_map(struct ice_hw *hw); 1768 1769 /** 1770 * ice_collect_result_idx - copy result index values 1771 * @buf: buffer that contains the result index 1772 * @recp: the recipe struct to copy data into 1773 */ 1774 static void ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf, 1775 struct ice_sw_recipe *recp) 1776 { 1777 if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN) 1778 ice_set_bit(buf->content.result_indx & 1779 ~ICE_AQ_RECIPE_RESULT_EN, recp->res_idxs); 1780 } 1781 1782 /** 1783 * ice_get_tun_type_for_recipe - get tunnel type for the recipe 1784 * @rid: recipe ID that we are populating 1785 */ 1786 static enum ice_sw_tunnel_type ice_get_tun_type_for_recipe(u8 rid, bool vlan) 1787 { 1788 u8 vxlan_profile[12] = {10, 11, 12, 16, 17, 18, 22, 23, 24, 25, 26, 27}; 1789 u8 gre_profile[12] = {13, 14, 15, 19, 20, 21, 28, 29, 30, 31, 32, 33}; 1790 u8 pppoe_profile[7] = {34, 35, 36, 37, 38, 39, 40}; 1791 u8 non_tun_profile[6] = {4, 5, 6, 7, 8, 9}; 1792 enum ice_sw_tunnel_type tun_type; 1793 u16 i, j, profile_num = 0; 1794 bool non_tun_valid = false; 1795 bool pppoe_valid = false; 1796 bool vxlan_valid = false; 1797 bool gre_valid = false; 1798 bool gtp_valid = false; 1799 bool flag_valid = false; 1800 1801 for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) { 1802 if (!ice_is_bit_set(recipe_to_profile[rid], j)) 1803 continue; 1804 else 1805 profile_num++; 1806 1807 for (i = 0; i < 12; i++) { 1808 if (gre_profile[i] == j) 1809 gre_valid = true; 1810 } 1811 1812 for (i = 0; i < 12; i++) { 1813 if (vxlan_profile[i] == j) 1814 vxlan_valid = true; 1815 } 1816 1817 for (i = 0; i < 7; i++) { 1818 if (pppoe_profile[i] == j) 1819 pppoe_valid = true; 1820 } 1821 1822 for (i = 0; i < 6; i++) { 1823 if (non_tun_profile[i] == j) 1824 non_tun_valid = true; 1825 } 1826 1827 if (j >= ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER && 1828 j <= ICE_PROFID_IPV6_GTPU_IPV6_TCP) 1829 gtp_valid = true; 1830 1831 if ((j >= ICE_PROFID_IPV4_ESP && 1832 j <= ICE_PROFID_IPV6_PFCP_SESSION) || 1833 (j >= ICE_PROFID_IPV4_GTPC_TEID && 1834 j <= ICE_PROFID_IPV6_GTPU_TEID)) 1835 flag_valid = true; 1836 } 1837 1838 if (!non_tun_valid && vxlan_valid) 1839 tun_type = ICE_SW_TUN_VXLAN; 1840 else if (!non_tun_valid && gre_valid) 1841 tun_type = ICE_SW_TUN_NVGRE; 1842 else if (!non_tun_valid && pppoe_valid) 1843 tun_type = ICE_SW_TUN_PPPOE; 1844 else if (!non_tun_valid && gtp_valid) 1845 tun_type = ICE_SW_TUN_GTP; 1846 else if (non_tun_valid && 1847 (vxlan_valid || gre_valid || gtp_valid || pppoe_valid)) 1848 tun_type = ICE_SW_TUN_AND_NON_TUN; 1849 else if (non_tun_valid && !vxlan_valid && !gre_valid && !gtp_valid && 1850 !pppoe_valid) 1851 tun_type = ICE_NON_TUN; 1852 else 1853 tun_type = ICE_NON_TUN; 1854 1855 if (profile_num > 1 && tun_type == ICE_SW_TUN_PPPOE) { 1856 i = ice_is_bit_set(recipe_to_profile[rid], 1857 ICE_PROFID_PPPOE_IPV4_OTHER); 1858 j = ice_is_bit_set(recipe_to_profile[rid], 1859 ICE_PROFID_PPPOE_IPV6_OTHER); 1860 if (i && !j) 1861 tun_type = ICE_SW_TUN_PPPOE_IPV4; 1862 else if (!i && j) 1863 tun_type = ICE_SW_TUN_PPPOE_IPV6; 1864 } 1865 1866 if (tun_type == ICE_SW_TUN_GTP) { 1867 if (ice_is_bit_set(recipe_to_profile[rid], 1868 ICE_PROFID_IPV4_GTPU_IPV4_OTHER)) 1869 tun_type = ICE_SW_TUN_IPV4_GTPU_IPV4; 1870 else if (ice_is_bit_set(recipe_to_profile[rid], 1871 ICE_PROFID_IPV4_GTPU_IPV6_OTHER)) 1872 tun_type = ICE_SW_TUN_IPV4_GTPU_IPV6; 1873 else if (ice_is_bit_set(recipe_to_profile[rid], 1874 ICE_PROFID_IPV6_GTPU_IPV4_OTHER)) 1875 tun_type = ICE_SW_TUN_IPV6_GTPU_IPV4; 1876 else if (ice_is_bit_set(recipe_to_profile[rid], 1877 ICE_PROFID_IPV6_GTPU_IPV6_OTHER)) 1878 tun_type = ICE_SW_TUN_IPV6_GTPU_IPV6; 1879 } 1880 1881 if (profile_num == 1 && (flag_valid || non_tun_valid || pppoe_valid)) { 1882 for (j = 0; j < ICE_MAX_NUM_PROFILES; j++) { 1883 if (ice_is_bit_set(recipe_to_profile[rid], j)) { 1884 switch (j) { 1885 case ICE_PROFID_IPV4_TCP: 1886 tun_type = ICE_SW_IPV4_TCP; 1887 break; 1888 case ICE_PROFID_IPV4_UDP: 1889 tun_type = ICE_SW_IPV4_UDP; 1890 break; 1891 case ICE_PROFID_IPV6_TCP: 1892 tun_type = ICE_SW_IPV6_TCP; 1893 break; 1894 case ICE_PROFID_IPV6_UDP: 1895 tun_type = ICE_SW_IPV6_UDP; 1896 break; 1897 case ICE_PROFID_PPPOE_PAY: 1898 tun_type = ICE_SW_TUN_PPPOE_PAY; 1899 break; 1900 case ICE_PROFID_PPPOE_IPV4_TCP: 1901 tun_type = ICE_SW_TUN_PPPOE_IPV4_TCP; 1902 break; 1903 case ICE_PROFID_PPPOE_IPV4_UDP: 1904 tun_type = ICE_SW_TUN_PPPOE_IPV4_UDP; 1905 break; 1906 case ICE_PROFID_PPPOE_IPV4_OTHER: 1907 tun_type = ICE_SW_TUN_PPPOE_IPV4; 1908 break; 1909 case ICE_PROFID_PPPOE_IPV6_TCP: 1910 tun_type = ICE_SW_TUN_PPPOE_IPV6_TCP; 1911 break; 1912 case ICE_PROFID_PPPOE_IPV6_UDP: 1913 tun_type = ICE_SW_TUN_PPPOE_IPV6_UDP; 1914 break; 1915 case ICE_PROFID_PPPOE_IPV6_OTHER: 1916 tun_type = ICE_SW_TUN_PPPOE_IPV6; 1917 break; 1918 case ICE_PROFID_IPV4_ESP: 1919 tun_type = ICE_SW_TUN_IPV4_ESP; 1920 break; 1921 case ICE_PROFID_IPV6_ESP: 1922 tun_type = ICE_SW_TUN_IPV6_ESP; 1923 break; 1924 case ICE_PROFID_IPV4_AH: 1925 tun_type = ICE_SW_TUN_IPV4_AH; 1926 break; 1927 case ICE_PROFID_IPV6_AH: 1928 tun_type = ICE_SW_TUN_IPV6_AH; 1929 break; 1930 case ICE_PROFID_IPV4_NAT_T: 1931 tun_type = ICE_SW_TUN_IPV4_NAT_T; 1932 break; 1933 case ICE_PROFID_IPV6_NAT_T: 1934 tun_type = ICE_SW_TUN_IPV6_NAT_T; 1935 break; 1936 case ICE_PROFID_IPV4_PFCP_NODE: 1937 tun_type = 1938 ICE_SW_TUN_PROFID_IPV4_PFCP_NODE; 1939 break; 1940 case ICE_PROFID_IPV6_PFCP_NODE: 1941 tun_type = 1942 ICE_SW_TUN_PROFID_IPV6_PFCP_NODE; 1943 break; 1944 case ICE_PROFID_IPV4_PFCP_SESSION: 1945 tun_type = 1946 ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION; 1947 break; 1948 case ICE_PROFID_IPV6_PFCP_SESSION: 1949 tun_type = 1950 ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION; 1951 break; 1952 case ICE_PROFID_MAC_IPV4_L2TPV3: 1953 tun_type = ICE_SW_TUN_IPV4_L2TPV3; 1954 break; 1955 case ICE_PROFID_MAC_IPV6_L2TPV3: 1956 tun_type = ICE_SW_TUN_IPV6_L2TPV3; 1957 break; 1958 case ICE_PROFID_IPV4_GTPU_TEID: 1959 tun_type = ICE_SW_TUN_IPV4_GTPU_NO_PAY; 1960 break; 1961 case ICE_PROFID_IPV6_GTPU_TEID: 1962 tun_type = ICE_SW_TUN_IPV6_GTPU_NO_PAY; 1963 break; 1964 default: 1965 break; 1966 } 1967 1968 return tun_type; 1969 } 1970 } 1971 } 1972 1973 if (vlan && tun_type == ICE_SW_TUN_PPPOE) 1974 tun_type = ICE_SW_TUN_PPPOE_QINQ; 1975 else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV6) 1976 tun_type = ICE_SW_TUN_PPPOE_IPV6_QINQ; 1977 else if (vlan && tun_type == ICE_SW_TUN_PPPOE_IPV4) 1978 tun_type = ICE_SW_TUN_PPPOE_IPV4_QINQ; 1979 else if (vlan && tun_type == ICE_SW_TUN_PPPOE_PAY) 1980 tun_type = ICE_SW_TUN_PPPOE_PAY_QINQ; 1981 else if (vlan && tun_type == ICE_SW_TUN_AND_NON_TUN) 1982 tun_type = ICE_SW_TUN_AND_NON_TUN_QINQ; 1983 else if (vlan && tun_type == ICE_NON_TUN) 1984 tun_type = ICE_NON_TUN_QINQ; 1985 1986 return tun_type; 1987 } 1988 1989 /** 1990 * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries 1991 * @hw: pointer to hardware structure 1992 * @recps: struct that we need to populate 1993 * @rid: recipe ID that we are populating 1994 * @refresh_required: true if we should get recipe to profile mapping from FW 1995 * 1996 * This function is used to populate all the necessary entries into our 1997 * bookkeeping so that we have a current list of all the recipes that are 1998 * programmed in the firmware. 1999 */ 2000 static enum ice_status 2001 ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid, 2002 bool *refresh_required) 2003 { 2004 ice_declare_bitmap(result_bm, ICE_MAX_FV_WORDS); 2005 struct ice_aqc_recipe_data_elem *tmp; 2006 u16 num_recps = ICE_MAX_NUM_RECIPES; 2007 struct ice_prot_lkup_ext *lkup_exts; 2008 enum ice_status status; 2009 u8 fv_word_idx = 0; 2010 bool vlan = false; 2011 u16 sub_recps; 2012 2013 ice_zero_bitmap(result_bm, ICE_MAX_FV_WORDS); 2014 2015 /* we need a buffer big enough to accommodate all the recipes */ 2016 tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw, 2017 ICE_MAX_NUM_RECIPES, sizeof(*tmp)); 2018 if (!tmp) 2019 return ICE_ERR_NO_MEMORY; 2020 2021 tmp[0].recipe_indx = rid; 2022 status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL); 2023 /* non-zero status meaning recipe doesn't exist */ 2024 if (status) 2025 goto err_unroll; 2026 2027 /* Get recipe to profile map so that we can get the fv from lkups that 2028 * we read for a recipe from FW. Since we want to minimize the number of 2029 * times we make this FW call, just make one call and cache the copy 2030 * until a new recipe is added. This operation is only required the 2031 * first time to get the changes from FW. Then to search existing 2032 * entries we don't need to update the cache again until another recipe 2033 * gets added. 2034 */ 2035 if (*refresh_required) { 2036 ice_get_recp_to_prof_map(hw); 2037 *refresh_required = false; 2038 } 2039 2040 /* Start populating all the entries for recps[rid] based on lkups from 2041 * firmware. Note that we are only creating the root recipe in our 2042 * database. 2043 */ 2044 lkup_exts = &recps[rid].lkup_exts; 2045 2046 for (sub_recps = 0; sub_recps < num_recps; sub_recps++) { 2047 struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps]; 2048 struct ice_recp_grp_entry *rg_entry; 2049 u8 i, prof, idx, prot = 0; 2050 bool is_root; 2051 u16 off = 0; 2052 2053 rg_entry = (struct ice_recp_grp_entry *) 2054 ice_malloc(hw, sizeof(*rg_entry)); 2055 if (!rg_entry) { 2056 status = ICE_ERR_NO_MEMORY; 2057 goto err_unroll; 2058 } 2059 2060 idx = root_bufs.recipe_indx; 2061 is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT; 2062 2063 /* Mark all result indices in this chain */ 2064 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) 2065 ice_set_bit(root_bufs.content.result_indx & 2066 ~ICE_AQ_RECIPE_RESULT_EN, result_bm); 2067 2068 /* get the first profile that is associated with rid */ 2069 prof = ice_find_first_bit(recipe_to_profile[idx], 2070 ICE_MAX_NUM_PROFILES); 2071 for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) { 2072 u8 lkup_indx = root_bufs.content.lkup_indx[i + 1]; 2073 2074 rg_entry->fv_idx[i] = lkup_indx; 2075 rg_entry->fv_mask[i] = 2076 LE16_TO_CPU(root_bufs.content.mask[i + 1]); 2077 2078 /* If the recipe is a chained recipe then all its 2079 * child recipe's result will have a result index. 2080 * To fill fv_words we should not use those result 2081 * index, we only need the protocol ids and offsets. 2082 * We will skip all the fv_idx which stores result 2083 * index in them. We also need to skip any fv_idx which 2084 * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a 2085 * valid offset value. 2086 */ 2087 if (ice_is_bit_set(hw->switch_info->prof_res_bm[prof], 2088 rg_entry->fv_idx[i]) || 2089 rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE || 2090 rg_entry->fv_idx[i] == 0) 2091 continue; 2092 2093 ice_find_prot_off(hw, ICE_BLK_SW, prof, 2094 rg_entry->fv_idx[i], &prot, &off); 2095 lkup_exts->fv_words[fv_word_idx].prot_id = prot; 2096 lkup_exts->fv_words[fv_word_idx].off = off; 2097 lkup_exts->field_mask[fv_word_idx] = 2098 rg_entry->fv_mask[i]; 2099 if (prot == ICE_META_DATA_ID_HW && 2100 off == ICE_TUN_FLAG_MDID_OFF) 2101 vlan = true; 2102 fv_word_idx++; 2103 } 2104 /* populate rg_list with the data from the child entry of this 2105 * recipe 2106 */ 2107 LIST_ADD(&rg_entry->l_entry, &recps[rid].rg_list); 2108 2109 /* Propagate some data to the recipe database */ 2110 recps[idx].is_root = !!is_root; 2111 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; 2112 ice_zero_bitmap(recps[idx].res_idxs, ICE_MAX_FV_WORDS); 2113 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) { 2114 recps[idx].chain_idx = root_bufs.content.result_indx & 2115 ~ICE_AQ_RECIPE_RESULT_EN; 2116 ice_set_bit(recps[idx].chain_idx, recps[idx].res_idxs); 2117 } else { 2118 recps[idx].chain_idx = ICE_INVAL_CHAIN_IND; 2119 } 2120 2121 if (!is_root) 2122 continue; 2123 2124 /* Only do the following for root recipes entries */ 2125 ice_memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap, 2126 sizeof(recps[idx].r_bitmap), ICE_NONDMA_TO_NONDMA); 2127 recps[idx].root_rid = root_bufs.content.rid & 2128 ~ICE_AQ_RECIPE_ID_IS_ROOT; 2129 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; 2130 } 2131 2132 /* Complete initialization of the root recipe entry */ 2133 lkup_exts->n_val_words = fv_word_idx; 2134 recps[rid].big_recp = (num_recps > 1); 2135 recps[rid].n_grp_count = (u8)num_recps; 2136 recps[rid].tun_type = ice_get_tun_type_for_recipe(rid, vlan); 2137 recps[rid].root_buf = (struct ice_aqc_recipe_data_elem *) 2138 ice_memdup(hw, tmp, recps[rid].n_grp_count * 2139 sizeof(*recps[rid].root_buf), ICE_NONDMA_TO_NONDMA); 2140 if (!recps[rid].root_buf) 2141 goto err_unroll; 2142 2143 /* Copy result indexes */ 2144 ice_cp_bitmap(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS); 2145 recps[rid].recp_created = true; 2146 2147 err_unroll: 2148 ice_free(hw, tmp); 2149 return status; 2150 } 2151 2152 /** 2153 * ice_get_recp_to_prof_map - updates recipe to profile mapping 2154 * @hw: pointer to hardware structure 2155 * 2156 * This function is used to populate recipe_to_profile matrix where index to 2157 * this array is the recipe ID and the element is the mapping of which profiles 2158 * is this recipe mapped to. 2159 */ 2160 static void ice_get_recp_to_prof_map(struct ice_hw *hw) 2161 { 2162 ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES); 2163 u16 i; 2164 2165 for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) { 2166 u16 j; 2167 2168 ice_zero_bitmap(profile_to_recipe[i], ICE_MAX_NUM_RECIPES); 2169 ice_zero_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES); 2170 if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL)) 2171 continue; 2172 ice_cp_bitmap(profile_to_recipe[i], r_bitmap, 2173 ICE_MAX_NUM_RECIPES); 2174 ice_for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES) 2175 ice_set_bit(i, recipe_to_profile[j]); 2176 } 2177 } 2178 2179 /** 2180 * ice_init_def_sw_recp - initialize the recipe book keeping tables 2181 * @hw: pointer to the HW struct 2182 * @recp_list: pointer to sw recipe list 2183 * 2184 * Allocate memory for the entire recipe table and initialize the structures/ 2185 * entries corresponding to basic recipes. 2186 */ 2187 enum ice_status 2188 ice_init_def_sw_recp(struct ice_hw *hw, struct ice_sw_recipe **recp_list) 2189 { 2190 struct ice_sw_recipe *recps; 2191 u8 i; 2192 2193 recps = (struct ice_sw_recipe *) 2194 ice_calloc(hw, ICE_MAX_NUM_RECIPES, sizeof(*recps)); 2195 if (!recps) 2196 return ICE_ERR_NO_MEMORY; 2197 2198 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 2199 recps[i].root_rid = i; 2200 INIT_LIST_HEAD(&recps[i].filt_rules); 2201 INIT_LIST_HEAD(&recps[i].filt_replay_rules); 2202 INIT_LIST_HEAD(&recps[i].rg_list); 2203 ice_init_lock(&recps[i].filt_rule_lock); 2204 } 2205 2206 *recp_list = recps; 2207 2208 return ICE_SUCCESS; 2209 } 2210 2211 /** 2212 * ice_aq_get_sw_cfg - get switch configuration 2213 * @hw: pointer to the hardware structure 2214 * @buf: pointer to the result buffer 2215 * @buf_size: length of the buffer available for response 2216 * @req_desc: pointer to requested descriptor 2217 * @num_elems: pointer to number of elements 2218 * @cd: pointer to command details structure or NULL 2219 * 2220 * Get switch configuration (0x0200) to be placed in buf. 2221 * This admin command returns information such as initial VSI/port number 2222 * and switch ID it belongs to. 2223 * 2224 * NOTE: *req_desc is both an input/output parameter. 2225 * The caller of this function first calls this function with *request_desc set 2226 * to 0. If the response from f/w has *req_desc set to 0, all the switch 2227 * configuration information has been returned; if non-zero (meaning not all 2228 * the information was returned), the caller should call this function again 2229 * with *req_desc set to the previous value returned by f/w to get the 2230 * next block of switch configuration information. 2231 * 2232 * *num_elems is output only parameter. This reflects the number of elements 2233 * in response buffer. The caller of this function to use *num_elems while 2234 * parsing the response buffer. 2235 */ 2236 static enum ice_status 2237 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf, 2238 u16 buf_size, u16 *req_desc, u16 *num_elems, 2239 struct ice_sq_cd *cd) 2240 { 2241 struct ice_aqc_get_sw_cfg *cmd; 2242 struct ice_aq_desc desc; 2243 enum ice_status status; 2244 2245 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg); 2246 cmd = &desc.params.get_sw_conf; 2247 cmd->element = CPU_TO_LE16(*req_desc); 2248 2249 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 2250 if (!status) { 2251 *req_desc = LE16_TO_CPU(cmd->element); 2252 *num_elems = LE16_TO_CPU(cmd->num_elems); 2253 } 2254 2255 return status; 2256 } 2257 2258 /** 2259 * ice_alloc_rss_global_lut - allocate a RSS global LUT 2260 * @hw: pointer to the HW struct 2261 * @shared_res: true to allocate as a shared resource and false to allocate as a dedicated resource 2262 * @global_lut_id: output parameter for the RSS global LUT's ID 2263 */ 2264 enum ice_status ice_alloc_rss_global_lut(struct ice_hw *hw, bool shared_res, u16 *global_lut_id) 2265 { 2266 struct ice_aqc_alloc_free_res_elem *sw_buf; 2267 enum ice_status status; 2268 u16 buf_len; 2269 2270 buf_len = ice_struct_size(sw_buf, elem, 1); 2271 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 2272 if (!sw_buf) 2273 return ICE_ERR_NO_MEMORY; 2274 2275 sw_buf->num_elems = CPU_TO_LE16(1); 2276 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH | 2277 (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED : 2278 ICE_AQC_RES_TYPE_FLAG_DEDICATED)); 2279 2280 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, ice_aqc_opc_alloc_res, NULL); 2281 if (status) { 2282 ice_debug(hw, ICE_DBG_RES, "Failed to allocate %s RSS global LUT, status %d\n", 2283 shared_res ? "shared" : "dedicated", status); 2284 goto ice_alloc_global_lut_exit; 2285 } 2286 2287 *global_lut_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp); 2288 2289 ice_alloc_global_lut_exit: 2290 ice_free(hw, sw_buf); 2291 return status; 2292 } 2293 2294 /** 2295 * ice_free_global_lut - free a RSS global LUT 2296 * @hw: pointer to the HW struct 2297 * @global_lut_id: ID of the RSS global LUT to free 2298 */ 2299 enum ice_status ice_free_rss_global_lut(struct ice_hw *hw, u16 global_lut_id) 2300 { 2301 struct ice_aqc_alloc_free_res_elem *sw_buf; 2302 u16 buf_len, num_elems = 1; 2303 enum ice_status status; 2304 2305 buf_len = ice_struct_size(sw_buf, elem, num_elems); 2306 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 2307 if (!sw_buf) 2308 return ICE_ERR_NO_MEMORY; 2309 2310 sw_buf->num_elems = CPU_TO_LE16(num_elems); 2311 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_GLOBAL_RSS_HASH); 2312 sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(global_lut_id); 2313 2314 status = ice_aq_alloc_free_res(hw, num_elems, sw_buf, buf_len, ice_aqc_opc_free_res, NULL); 2315 if (status) 2316 ice_debug(hw, ICE_DBG_RES, "Failed to free RSS global LUT %d, status %d\n", 2317 global_lut_id, status); 2318 2319 ice_free(hw, sw_buf); 2320 return status; 2321 } 2322 2323 /** 2324 * ice_alloc_sw - allocate resources specific to switch 2325 * @hw: pointer to the HW struct 2326 * @ena_stats: true to turn on VEB stats 2327 * @shared_res: true for shared resource, false for dedicated resource 2328 * @sw_id: switch ID returned 2329 * @counter_id: VEB counter ID returned 2330 * 2331 * allocates switch resources (SWID and VEB counter) (0x0208) 2332 */ 2333 enum ice_status 2334 ice_alloc_sw(struct ice_hw *hw, bool ena_stats, bool shared_res, u16 *sw_id, 2335 u16 *counter_id) 2336 { 2337 struct ice_aqc_alloc_free_res_elem *sw_buf; 2338 struct ice_aqc_res_elem *sw_ele; 2339 enum ice_status status; 2340 u16 buf_len; 2341 2342 buf_len = ice_struct_size(sw_buf, elem, 1); 2343 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 2344 if (!sw_buf) 2345 return ICE_ERR_NO_MEMORY; 2346 2347 /* Prepare buffer for switch ID. 2348 * The number of resource entries in buffer is passed as 1 since only a 2349 * single switch/VEB instance is allocated, and hence a single sw_id 2350 * is requested. 2351 */ 2352 sw_buf->num_elems = CPU_TO_LE16(1); 2353 sw_buf->res_type = 2354 CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID | 2355 (shared_res ? ICE_AQC_RES_TYPE_FLAG_SHARED : 2356 ICE_AQC_RES_TYPE_FLAG_DEDICATED)); 2357 2358 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 2359 ice_aqc_opc_alloc_res, NULL); 2360 2361 if (status) 2362 goto ice_alloc_sw_exit; 2363 2364 sw_ele = &sw_buf->elem[0]; 2365 *sw_id = LE16_TO_CPU(sw_ele->e.sw_resp); 2366 2367 if (ena_stats) { 2368 /* Prepare buffer for VEB Counter */ 2369 enum ice_adminq_opc opc = ice_aqc_opc_alloc_res; 2370 struct ice_aqc_alloc_free_res_elem *counter_buf; 2371 struct ice_aqc_res_elem *counter_ele; 2372 2373 counter_buf = (struct ice_aqc_alloc_free_res_elem *) 2374 ice_malloc(hw, buf_len); 2375 if (!counter_buf) { 2376 status = ICE_ERR_NO_MEMORY; 2377 goto ice_alloc_sw_exit; 2378 } 2379 2380 /* The number of resource entries in buffer is passed as 1 since 2381 * only a single switch/VEB instance is allocated, and hence a 2382 * single VEB counter is requested. 2383 */ 2384 counter_buf->num_elems = CPU_TO_LE16(1); 2385 counter_buf->res_type = 2386 CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER | 2387 ICE_AQC_RES_TYPE_FLAG_DEDICATED); 2388 status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len, 2389 opc, NULL); 2390 2391 if (status) { 2392 ice_free(hw, counter_buf); 2393 goto ice_alloc_sw_exit; 2394 } 2395 counter_ele = &counter_buf->elem[0]; 2396 *counter_id = LE16_TO_CPU(counter_ele->e.sw_resp); 2397 ice_free(hw, counter_buf); 2398 } 2399 2400 ice_alloc_sw_exit: 2401 ice_free(hw, sw_buf); 2402 return status; 2403 } 2404 2405 /** 2406 * ice_free_sw - free resources specific to switch 2407 * @hw: pointer to the HW struct 2408 * @sw_id: switch ID returned 2409 * @counter_id: VEB counter ID returned 2410 * 2411 * free switch resources (SWID and VEB counter) (0x0209) 2412 * 2413 * NOTE: This function frees multiple resources. It continues 2414 * releasing other resources even after it encounters error. 2415 * The error code returned is the last error it encountered. 2416 */ 2417 enum ice_status ice_free_sw(struct ice_hw *hw, u16 sw_id, u16 counter_id) 2418 { 2419 struct ice_aqc_alloc_free_res_elem *sw_buf, *counter_buf; 2420 enum ice_status status, ret_status; 2421 u16 buf_len; 2422 2423 buf_len = ice_struct_size(sw_buf, elem, 1); 2424 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 2425 if (!sw_buf) 2426 return ICE_ERR_NO_MEMORY; 2427 2428 /* Prepare buffer to free for switch ID res. 2429 * The number of resource entries in buffer is passed as 1 since only a 2430 * single switch/VEB instance is freed, and hence a single sw_id 2431 * is released. 2432 */ 2433 sw_buf->num_elems = CPU_TO_LE16(1); 2434 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_SWID); 2435 sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(sw_id); 2436 2437 ret_status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 2438 ice_aqc_opc_free_res, NULL); 2439 2440 if (ret_status) 2441 ice_debug(hw, ICE_DBG_SW, "CQ CMD Buffer:\n"); 2442 2443 /* Prepare buffer to free for VEB Counter resource */ 2444 counter_buf = (struct ice_aqc_alloc_free_res_elem *) 2445 ice_malloc(hw, buf_len); 2446 if (!counter_buf) { 2447 ice_free(hw, sw_buf); 2448 return ICE_ERR_NO_MEMORY; 2449 } 2450 2451 /* The number of resource entries in buffer is passed as 1 since only a 2452 * single switch/VEB instance is freed, and hence a single VEB counter 2453 * is released 2454 */ 2455 counter_buf->num_elems = CPU_TO_LE16(1); 2456 counter_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VEB_COUNTER); 2457 counter_buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id); 2458 2459 status = ice_aq_alloc_free_res(hw, 1, counter_buf, buf_len, 2460 ice_aqc_opc_free_res, NULL); 2461 if (status) { 2462 ice_debug(hw, ICE_DBG_SW, "VEB counter resource could not be freed\n"); 2463 ret_status = status; 2464 } 2465 2466 ice_free(hw, counter_buf); 2467 ice_free(hw, sw_buf); 2468 return ret_status; 2469 } 2470 2471 /** 2472 * ice_aq_add_vsi 2473 * @hw: pointer to the HW struct 2474 * @vsi_ctx: pointer to a VSI context struct 2475 * @cd: pointer to command details structure or NULL 2476 * 2477 * Add a VSI context to the hardware (0x0210) 2478 */ 2479 enum ice_status 2480 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 2481 struct ice_sq_cd *cd) 2482 { 2483 struct ice_aqc_add_update_free_vsi_resp *res; 2484 struct ice_aqc_add_get_update_free_vsi *cmd; 2485 struct ice_aq_desc desc; 2486 enum ice_status status; 2487 2488 cmd = &desc.params.vsi_cmd; 2489 res = &desc.params.add_update_free_vsi_res; 2490 2491 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi); 2492 2493 if (!vsi_ctx->alloc_from_pool) 2494 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | 2495 ICE_AQ_VSI_IS_VALID); 2496 2497 cmd->vsi_flags = CPU_TO_LE16(vsi_ctx->flags); 2498 2499 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 2500 2501 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 2502 sizeof(vsi_ctx->info), cd); 2503 2504 if (!status) { 2505 vsi_ctx->vsi_num = LE16_TO_CPU(res->vsi_num) & ICE_AQ_VSI_NUM_M; 2506 vsi_ctx->vsis_allocd = LE16_TO_CPU(res->vsi_used); 2507 vsi_ctx->vsis_unallocated = LE16_TO_CPU(res->vsi_free); 2508 } 2509 2510 return status; 2511 } 2512 2513 /** 2514 * ice_aq_free_vsi 2515 * @hw: pointer to the HW struct 2516 * @vsi_ctx: pointer to a VSI context struct 2517 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 2518 * @cd: pointer to command details structure or NULL 2519 * 2520 * Free VSI context info from hardware (0x0213) 2521 */ 2522 enum ice_status 2523 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 2524 bool keep_vsi_alloc, struct ice_sq_cd *cd) 2525 { 2526 struct ice_aqc_add_update_free_vsi_resp *resp; 2527 struct ice_aqc_add_get_update_free_vsi *cmd; 2528 struct ice_aq_desc desc; 2529 enum ice_status status; 2530 2531 cmd = &desc.params.vsi_cmd; 2532 resp = &desc.params.add_update_free_vsi_res; 2533 2534 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi); 2535 2536 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 2537 if (keep_vsi_alloc) 2538 cmd->cmd_flags = CPU_TO_LE16(ICE_AQ_VSI_KEEP_ALLOC); 2539 2540 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 2541 if (!status) { 2542 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used); 2543 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free); 2544 } 2545 2546 return status; 2547 } 2548 2549 /** 2550 * ice_aq_update_vsi 2551 * @hw: pointer to the HW struct 2552 * @vsi_ctx: pointer to a VSI context struct 2553 * @cd: pointer to command details structure or NULL 2554 * 2555 * Update VSI context in the hardware (0x0211) 2556 */ 2557 enum ice_status 2558 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 2559 struct ice_sq_cd *cd) 2560 { 2561 struct ice_aqc_add_update_free_vsi_resp *resp; 2562 struct ice_aqc_add_get_update_free_vsi *cmd; 2563 struct ice_aq_desc desc; 2564 enum ice_status status; 2565 2566 cmd = &desc.params.vsi_cmd; 2567 resp = &desc.params.add_update_free_vsi_res; 2568 2569 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi); 2570 2571 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 2572 2573 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 2574 2575 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 2576 sizeof(vsi_ctx->info), cd); 2577 2578 if (!status) { 2579 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used); 2580 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free); 2581 } 2582 2583 return status; 2584 } 2585 2586 /** 2587 * ice_is_vsi_valid - check whether the VSI is valid or not 2588 * @hw: pointer to the HW struct 2589 * @vsi_handle: VSI handle 2590 * 2591 * check whether the VSI is valid or not 2592 */ 2593 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle) 2594 { 2595 return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle]; 2596 } 2597 2598 /** 2599 * ice_get_hw_vsi_num - return the HW VSI number 2600 * @hw: pointer to the HW struct 2601 * @vsi_handle: VSI handle 2602 * 2603 * return the HW VSI number 2604 * Caution: call this function only if VSI is valid (ice_is_vsi_valid) 2605 */ 2606 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle) 2607 { 2608 return hw->vsi_ctx[vsi_handle]->vsi_num; 2609 } 2610 2611 /** 2612 * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle 2613 * @hw: pointer to the HW struct 2614 * @vsi_handle: VSI handle 2615 * 2616 * return the VSI context entry for a given VSI handle 2617 */ 2618 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 2619 { 2620 return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle]; 2621 } 2622 2623 /** 2624 * ice_save_vsi_ctx - save the VSI context for a given VSI handle 2625 * @hw: pointer to the HW struct 2626 * @vsi_handle: VSI handle 2627 * @vsi: VSI context pointer 2628 * 2629 * save the VSI context entry for a given VSI handle 2630 */ 2631 static void 2632 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi) 2633 { 2634 hw->vsi_ctx[vsi_handle] = vsi; 2635 } 2636 2637 /** 2638 * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs 2639 * @hw: pointer to the HW struct 2640 * @vsi_handle: VSI handle 2641 */ 2642 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle) 2643 { 2644 struct ice_vsi_ctx *vsi; 2645 u8 i; 2646 2647 vsi = ice_get_vsi_ctx(hw, vsi_handle); 2648 if (!vsi) 2649 return; 2650 ice_for_each_traffic_class(i) { 2651 if (vsi->lan_q_ctx[i]) { 2652 ice_free(hw, vsi->lan_q_ctx[i]); 2653 vsi->lan_q_ctx[i] = NULL; 2654 } 2655 } 2656 } 2657 2658 /** 2659 * ice_clear_vsi_ctx - clear the VSI context entry 2660 * @hw: pointer to the HW struct 2661 * @vsi_handle: VSI handle 2662 * 2663 * clear the VSI context entry 2664 */ 2665 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 2666 { 2667 struct ice_vsi_ctx *vsi; 2668 2669 vsi = ice_get_vsi_ctx(hw, vsi_handle); 2670 if (vsi) { 2671 ice_clear_vsi_q_ctx(hw, vsi_handle); 2672 ice_free(hw, vsi); 2673 hw->vsi_ctx[vsi_handle] = NULL; 2674 } 2675 } 2676 2677 /** 2678 * ice_clear_all_vsi_ctx - clear all the VSI context entries 2679 * @hw: pointer to the HW struct 2680 */ 2681 void ice_clear_all_vsi_ctx(struct ice_hw *hw) 2682 { 2683 u16 i; 2684 2685 for (i = 0; i < ICE_MAX_VSI; i++) 2686 ice_clear_vsi_ctx(hw, i); 2687 } 2688 2689 /** 2690 * ice_add_vsi - add VSI context to the hardware and VSI handle list 2691 * @hw: pointer to the HW struct 2692 * @vsi_handle: unique VSI handle provided by drivers 2693 * @vsi_ctx: pointer to a VSI context struct 2694 * @cd: pointer to command details structure or NULL 2695 * 2696 * Add a VSI context to the hardware also add it into the VSI handle list. 2697 * If this function gets called after reset for existing VSIs then update 2698 * with the new HW VSI number in the corresponding VSI handle list entry. 2699 */ 2700 enum ice_status 2701 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 2702 struct ice_sq_cd *cd) 2703 { 2704 struct ice_vsi_ctx *tmp_vsi_ctx; 2705 enum ice_status status; 2706 2707 if (vsi_handle >= ICE_MAX_VSI) 2708 return ICE_ERR_PARAM; 2709 status = ice_aq_add_vsi(hw, vsi_ctx, cd); 2710 if (status) 2711 return status; 2712 tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 2713 if (!tmp_vsi_ctx) { 2714 /* Create a new VSI context */ 2715 tmp_vsi_ctx = (struct ice_vsi_ctx *) 2716 ice_malloc(hw, sizeof(*tmp_vsi_ctx)); 2717 if (!tmp_vsi_ctx) { 2718 ice_aq_free_vsi(hw, vsi_ctx, false, cd); 2719 return ICE_ERR_NO_MEMORY; 2720 } 2721 *tmp_vsi_ctx = *vsi_ctx; 2722 2723 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx); 2724 } else { 2725 /* update with new HW VSI num */ 2726 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num; 2727 } 2728 2729 return ICE_SUCCESS; 2730 } 2731 2732 /** 2733 * ice_free_vsi- free VSI context from hardware and VSI handle list 2734 * @hw: pointer to the HW struct 2735 * @vsi_handle: unique VSI handle 2736 * @vsi_ctx: pointer to a VSI context struct 2737 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 2738 * @cd: pointer to command details structure or NULL 2739 * 2740 * Free VSI context info from hardware as well as from VSI handle list 2741 */ 2742 enum ice_status 2743 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 2744 bool keep_vsi_alloc, struct ice_sq_cd *cd) 2745 { 2746 enum ice_status status; 2747 2748 if (!ice_is_vsi_valid(hw, vsi_handle)) 2749 return ICE_ERR_PARAM; 2750 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 2751 status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd); 2752 if (!status) 2753 ice_clear_vsi_ctx(hw, vsi_handle); 2754 return status; 2755 } 2756 2757 /** 2758 * ice_update_vsi 2759 * @hw: pointer to the HW struct 2760 * @vsi_handle: unique VSI handle 2761 * @vsi_ctx: pointer to a VSI context struct 2762 * @cd: pointer to command details structure or NULL 2763 * 2764 * Update VSI context in the hardware 2765 */ 2766 enum ice_status 2767 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 2768 struct ice_sq_cd *cd) 2769 { 2770 if (!ice_is_vsi_valid(hw, vsi_handle)) 2771 return ICE_ERR_PARAM; 2772 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 2773 return ice_aq_update_vsi(hw, vsi_ctx, cd); 2774 } 2775 2776 /** 2777 * ice_aq_get_vsi_params 2778 * @hw: pointer to the HW struct 2779 * @vsi_ctx: pointer to a VSI context struct 2780 * @cd: pointer to command details structure or NULL 2781 * 2782 * Get VSI context info from hardware (0x0212) 2783 */ 2784 enum ice_status 2785 ice_aq_get_vsi_params(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 2786 struct ice_sq_cd *cd) 2787 { 2788 struct ice_aqc_add_get_update_free_vsi *cmd; 2789 struct ice_aqc_get_vsi_resp *resp; 2790 struct ice_aq_desc desc; 2791 enum ice_status status; 2792 2793 cmd = &desc.params.vsi_cmd; 2794 resp = &desc.params.get_vsi_resp; 2795 2796 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_vsi_params); 2797 2798 cmd->vsi_num = CPU_TO_LE16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 2799 2800 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 2801 sizeof(vsi_ctx->info), cd); 2802 if (!status) { 2803 vsi_ctx->vsi_num = LE16_TO_CPU(resp->vsi_num) & 2804 ICE_AQ_VSI_NUM_M; 2805 vsi_ctx->vsis_allocd = LE16_TO_CPU(resp->vsi_used); 2806 vsi_ctx->vsis_unallocated = LE16_TO_CPU(resp->vsi_free); 2807 } 2808 2809 return status; 2810 } 2811 2812 /** 2813 * ice_aq_add_update_mir_rule - add/update a mirror rule 2814 * @hw: pointer to the HW struct 2815 * @rule_type: Rule Type 2816 * @dest_vsi: VSI number to which packets will be mirrored 2817 * @count: length of the list 2818 * @mr_buf: buffer for list of mirrored VSI numbers 2819 * @cd: pointer to command details structure or NULL 2820 * @rule_id: Rule ID 2821 * 2822 * Add/Update Mirror Rule (0x260). 2823 */ 2824 enum ice_status 2825 ice_aq_add_update_mir_rule(struct ice_hw *hw, u16 rule_type, u16 dest_vsi, 2826 u16 count, struct ice_mir_rule_buf *mr_buf, 2827 struct ice_sq_cd *cd, u16 *rule_id) 2828 { 2829 struct ice_aqc_add_update_mir_rule *cmd; 2830 struct ice_aq_desc desc; 2831 enum ice_status status; 2832 __le16 *mr_list = NULL; 2833 u16 buf_size = 0; 2834 2835 switch (rule_type) { 2836 case ICE_AQC_RULE_TYPE_VPORT_INGRESS: 2837 case ICE_AQC_RULE_TYPE_VPORT_EGRESS: 2838 /* Make sure count and mr_buf are set for these rule_types */ 2839 if (!(count && mr_buf)) 2840 return ICE_ERR_PARAM; 2841 2842 buf_size = count * sizeof(__le16); 2843 mr_list = (_FORCE_ __le16 *)ice_malloc(hw, buf_size); 2844 if (!mr_list) 2845 return ICE_ERR_NO_MEMORY; 2846 break; 2847 case ICE_AQC_RULE_TYPE_PPORT_INGRESS: 2848 case ICE_AQC_RULE_TYPE_PPORT_EGRESS: 2849 /* Make sure count and mr_buf are not set for these 2850 * rule_types 2851 */ 2852 if (count || mr_buf) 2853 return ICE_ERR_PARAM; 2854 break; 2855 default: 2856 ice_debug(hw, ICE_DBG_SW, "Error due to unsupported rule_type %u\n", rule_type); 2857 return ICE_ERR_OUT_OF_RANGE; 2858 } 2859 2860 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_update_mir_rule); 2861 2862 /* Pre-process 'mr_buf' items for add/update of virtual port 2863 * ingress/egress mirroring (but not physical port ingress/egress 2864 * mirroring) 2865 */ 2866 if (mr_buf) { 2867 int i; 2868 2869 for (i = 0; i < count; i++) { 2870 u16 id; 2871 2872 id = mr_buf[i].vsi_idx & ICE_AQC_RULE_MIRRORED_VSI_M; 2873 2874 /* Validate specified VSI number, make sure it is less 2875 * than ICE_MAX_VSI, if not return with error. 2876 */ 2877 if (id >= ICE_MAX_VSI) { 2878 ice_debug(hw, ICE_DBG_SW, "Error VSI index (%u) out-of-range\n", 2879 id); 2880 ice_free(hw, mr_list); 2881 return ICE_ERR_OUT_OF_RANGE; 2882 } 2883 2884 /* add VSI to mirror rule */ 2885 if (mr_buf[i].add) 2886 mr_list[i] = 2887 CPU_TO_LE16(id | ICE_AQC_RULE_ACT_M); 2888 else /* remove VSI from mirror rule */ 2889 mr_list[i] = CPU_TO_LE16(id); 2890 } 2891 } 2892 2893 cmd = &desc.params.add_update_rule; 2894 if ((*rule_id) != ICE_INVAL_MIRROR_RULE_ID) 2895 cmd->rule_id = CPU_TO_LE16(((*rule_id) & ICE_AQC_RULE_ID_M) | 2896 ICE_AQC_RULE_ID_VALID_M); 2897 cmd->rule_type = CPU_TO_LE16(rule_type & ICE_AQC_RULE_TYPE_M); 2898 cmd->num_entries = CPU_TO_LE16(count); 2899 cmd->dest = CPU_TO_LE16(dest_vsi); 2900 2901 status = ice_aq_send_cmd(hw, &desc, mr_list, buf_size, cd); 2902 if (!status) 2903 *rule_id = LE16_TO_CPU(cmd->rule_id) & ICE_AQC_RULE_ID_M; 2904 2905 ice_free(hw, mr_list); 2906 2907 return status; 2908 } 2909 2910 /** 2911 * ice_aq_delete_mir_rule - delete a mirror rule 2912 * @hw: pointer to the HW struct 2913 * @rule_id: Mirror rule ID (to be deleted) 2914 * @keep_allocd: if set, the VSI stays part of the PF allocated res, 2915 * otherwise it is returned to the shared pool 2916 * @cd: pointer to command details structure or NULL 2917 * 2918 * Delete Mirror Rule (0x261). 2919 */ 2920 enum ice_status 2921 ice_aq_delete_mir_rule(struct ice_hw *hw, u16 rule_id, bool keep_allocd, 2922 struct ice_sq_cd *cd) 2923 { 2924 struct ice_aqc_delete_mir_rule *cmd; 2925 struct ice_aq_desc desc; 2926 2927 /* rule_id should be in the range 0...63 */ 2928 if (rule_id >= ICE_MAX_NUM_MIRROR_RULES) 2929 return ICE_ERR_OUT_OF_RANGE; 2930 2931 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_del_mir_rule); 2932 2933 cmd = &desc.params.del_rule; 2934 rule_id |= ICE_AQC_RULE_ID_VALID_M; 2935 cmd->rule_id = CPU_TO_LE16(rule_id); 2936 2937 if (keep_allocd) 2938 cmd->flags = CPU_TO_LE16(ICE_AQC_FLAG_KEEP_ALLOCD_M); 2939 2940 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 2941 } 2942 2943 /** 2944 * ice_aq_alloc_free_vsi_list 2945 * @hw: pointer to the HW struct 2946 * @vsi_list_id: VSI list ID returned or used for lookup 2947 * @lkup_type: switch rule filter lookup type 2948 * @opc: switch rules population command type - pass in the command opcode 2949 * 2950 * allocates or free a VSI list resource 2951 */ 2952 static enum ice_status 2953 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, 2954 enum ice_sw_lkup_type lkup_type, 2955 enum ice_adminq_opc opc) 2956 { 2957 struct ice_aqc_alloc_free_res_elem *sw_buf; 2958 struct ice_aqc_res_elem *vsi_ele; 2959 enum ice_status status; 2960 u16 buf_len; 2961 2962 buf_len = ice_struct_size(sw_buf, elem, 1); 2963 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 2964 if (!sw_buf) 2965 return ICE_ERR_NO_MEMORY; 2966 sw_buf->num_elems = CPU_TO_LE16(1); 2967 2968 if (lkup_type == ICE_SW_LKUP_MAC || 2969 lkup_type == ICE_SW_LKUP_MAC_VLAN || 2970 lkup_type == ICE_SW_LKUP_ETHERTYPE || 2971 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 2972 lkup_type == ICE_SW_LKUP_PROMISC || 2973 lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 2974 lkup_type == ICE_SW_LKUP_LAST) { 2975 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_REP); 2976 } else if (lkup_type == ICE_SW_LKUP_VLAN) { 2977 sw_buf->res_type = 2978 CPU_TO_LE16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE); 2979 } else { 2980 status = ICE_ERR_PARAM; 2981 goto ice_aq_alloc_free_vsi_list_exit; 2982 } 2983 2984 if (opc == ice_aqc_opc_free_res) 2985 sw_buf->elem[0].e.sw_resp = CPU_TO_LE16(*vsi_list_id); 2986 2987 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL); 2988 if (status) 2989 goto ice_aq_alloc_free_vsi_list_exit; 2990 2991 if (opc == ice_aqc_opc_alloc_res) { 2992 vsi_ele = &sw_buf->elem[0]; 2993 *vsi_list_id = LE16_TO_CPU(vsi_ele->e.sw_resp); 2994 } 2995 2996 ice_aq_alloc_free_vsi_list_exit: 2997 ice_free(hw, sw_buf); 2998 return status; 2999 } 3000 3001 /** 3002 * ice_aq_set_storm_ctrl - Sets storm control configuration 3003 * @hw: pointer to the HW struct 3004 * @bcast_thresh: represents the upper threshold for broadcast storm control 3005 * @mcast_thresh: represents the upper threshold for multicast storm control 3006 * @ctl_bitmask: storm control knobs 3007 * 3008 * Sets the storm control configuration (0x0280) 3009 */ 3010 enum ice_status 3011 ice_aq_set_storm_ctrl(struct ice_hw *hw, u32 bcast_thresh, u32 mcast_thresh, 3012 u32 ctl_bitmask) 3013 { 3014 struct ice_aqc_storm_cfg *cmd; 3015 struct ice_aq_desc desc; 3016 3017 cmd = &desc.params.storm_conf; 3018 3019 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_storm_cfg); 3020 3021 cmd->bcast_thresh_size = CPU_TO_LE32(bcast_thresh & ICE_AQ_THRESHOLD_M); 3022 cmd->mcast_thresh_size = CPU_TO_LE32(mcast_thresh & ICE_AQ_THRESHOLD_M); 3023 cmd->storm_ctrl_ctrl = CPU_TO_LE32(ctl_bitmask); 3024 3025 return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 3026 } 3027 3028 /** 3029 * ice_aq_get_storm_ctrl - gets storm control configuration 3030 * @hw: pointer to the HW struct 3031 * @bcast_thresh: represents the upper threshold for broadcast storm control 3032 * @mcast_thresh: represents the upper threshold for multicast storm control 3033 * @ctl_bitmask: storm control knobs 3034 * 3035 * Gets the storm control configuration (0x0281) 3036 */ 3037 enum ice_status 3038 ice_aq_get_storm_ctrl(struct ice_hw *hw, u32 *bcast_thresh, u32 *mcast_thresh, 3039 u32 *ctl_bitmask) 3040 { 3041 enum ice_status status; 3042 struct ice_aq_desc desc; 3043 3044 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_storm_cfg); 3045 3046 status = ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); 3047 if (!status) { 3048 struct ice_aqc_storm_cfg *resp = &desc.params.storm_conf; 3049 3050 if (bcast_thresh) 3051 *bcast_thresh = LE32_TO_CPU(resp->bcast_thresh_size) & 3052 ICE_AQ_THRESHOLD_M; 3053 if (mcast_thresh) 3054 *mcast_thresh = LE32_TO_CPU(resp->mcast_thresh_size) & 3055 ICE_AQ_THRESHOLD_M; 3056 if (ctl_bitmask) 3057 *ctl_bitmask = LE32_TO_CPU(resp->storm_ctrl_ctrl); 3058 } 3059 3060 return status; 3061 } 3062 3063 /** 3064 * ice_aq_sw_rules - add/update/remove switch rules 3065 * @hw: pointer to the HW struct 3066 * @rule_list: pointer to switch rule population list 3067 * @rule_list_sz: total size of the rule list in bytes 3068 * @num_rules: number of switch rules in the rule_list 3069 * @opc: switch rules population command type - pass in the command opcode 3070 * @cd: pointer to command details structure or NULL 3071 * 3072 * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware 3073 */ 3074 static enum ice_status 3075 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, 3076 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd) 3077 { 3078 struct ice_aq_desc desc; 3079 enum ice_status status; 3080 3081 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 3082 3083 if (opc != ice_aqc_opc_add_sw_rules && 3084 opc != ice_aqc_opc_update_sw_rules && 3085 opc != ice_aqc_opc_remove_sw_rules) 3086 return ICE_ERR_PARAM; 3087 3088 ice_fill_dflt_direct_cmd_desc(&desc, opc); 3089 3090 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 3091 desc.params.sw_rules.num_rules_fltr_entry_index = 3092 CPU_TO_LE16(num_rules); 3093 status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd); 3094 if (opc != ice_aqc_opc_add_sw_rules && 3095 hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) 3096 status = ICE_ERR_DOES_NOT_EXIST; 3097 3098 return status; 3099 } 3100 3101 /** 3102 * ice_aq_add_recipe - add switch recipe 3103 * @hw: pointer to the HW struct 3104 * @s_recipe_list: pointer to switch rule population list 3105 * @num_recipes: number of switch recipes in the list 3106 * @cd: pointer to command details structure or NULL 3107 * 3108 * Add(0x0290) 3109 */ 3110 enum ice_status 3111 ice_aq_add_recipe(struct ice_hw *hw, 3112 struct ice_aqc_recipe_data_elem *s_recipe_list, 3113 u16 num_recipes, struct ice_sq_cd *cd) 3114 { 3115 struct ice_aqc_add_get_recipe *cmd; 3116 struct ice_aq_desc desc; 3117 u16 buf_size; 3118 3119 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 3120 cmd = &desc.params.add_get_recipe; 3121 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe); 3122 3123 cmd->num_sub_recipes = CPU_TO_LE16(num_recipes); 3124 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD); 3125 3126 buf_size = num_recipes * sizeof(*s_recipe_list); 3127 3128 return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd); 3129 } 3130 3131 /** 3132 * ice_aq_get_recipe - get switch recipe 3133 * @hw: pointer to the HW struct 3134 * @s_recipe_list: pointer to switch rule population list 3135 * @num_recipes: pointer to the number of recipes (input and output) 3136 * @recipe_root: root recipe number of recipe(s) to retrieve 3137 * @cd: pointer to command details structure or NULL 3138 * 3139 * Get(0x0292) 3140 * 3141 * On input, *num_recipes should equal the number of entries in s_recipe_list. 3142 * On output, *num_recipes will equal the number of entries returned in 3143 * s_recipe_list. 3144 * 3145 * The caller must supply enough space in s_recipe_list to hold all possible 3146 * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES. 3147 */ 3148 enum ice_status 3149 ice_aq_get_recipe(struct ice_hw *hw, 3150 struct ice_aqc_recipe_data_elem *s_recipe_list, 3151 u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd) 3152 { 3153 struct ice_aqc_add_get_recipe *cmd; 3154 struct ice_aq_desc desc; 3155 enum ice_status status; 3156 u16 buf_size; 3157 3158 if (*num_recipes != ICE_MAX_NUM_RECIPES) 3159 return ICE_ERR_PARAM; 3160 3161 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 3162 cmd = &desc.params.add_get_recipe; 3163 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe); 3164 3165 cmd->return_index = CPU_TO_LE16(recipe_root); 3166 cmd->num_sub_recipes = 0; 3167 3168 buf_size = *num_recipes * sizeof(*s_recipe_list); 3169 3170 status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd); 3171 /* cppcheck-suppress constArgument */ 3172 *num_recipes = LE16_TO_CPU(cmd->num_sub_recipes); 3173 3174 return status; 3175 } 3176 3177 /** 3178 * ice_aq_map_recipe_to_profile - Map recipe to packet profile 3179 * @hw: pointer to the HW struct 3180 * @profile_id: package profile ID to associate the recipe with 3181 * @r_bitmap: Recipe bitmap filled in and need to be returned as response 3182 * @cd: pointer to command details structure or NULL 3183 * Recipe to profile association (0x0291) 3184 */ 3185 enum ice_status 3186 ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, 3187 struct ice_sq_cd *cd) 3188 { 3189 struct ice_aqc_recipe_to_profile *cmd; 3190 struct ice_aq_desc desc; 3191 3192 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 3193 cmd = &desc.params.recipe_to_profile; 3194 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile); 3195 cmd->profile_id = CPU_TO_LE16(profile_id); 3196 /* Set the recipe ID bit in the bitmask to let the device know which 3197 * profile we are associating the recipe to 3198 */ 3199 ice_memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc), 3200 ICE_NONDMA_TO_NONDMA); 3201 3202 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 3203 } 3204 3205 /** 3206 * ice_aq_get_recipe_to_profile - Map recipe to packet profile 3207 * @hw: pointer to the HW struct 3208 * @profile_id: package profile ID to associate the recipe with 3209 * @r_bitmap: Recipe bitmap filled in and need to be returned as response 3210 * @cd: pointer to command details structure or NULL 3211 * Associate profile ID with given recipe (0x0293) 3212 */ 3213 enum ice_status 3214 ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, 3215 struct ice_sq_cd *cd) 3216 { 3217 struct ice_aqc_recipe_to_profile *cmd; 3218 struct ice_aq_desc desc; 3219 enum ice_status status; 3220 3221 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 3222 cmd = &desc.params.recipe_to_profile; 3223 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile); 3224 cmd->profile_id = CPU_TO_LE16(profile_id); 3225 3226 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 3227 if (!status) 3228 ice_memcpy(r_bitmap, cmd->recipe_assoc, 3229 sizeof(cmd->recipe_assoc), ICE_NONDMA_TO_NONDMA); 3230 3231 return status; 3232 } 3233 3234 /** 3235 * ice_alloc_recipe - add recipe resource 3236 * @hw: pointer to the hardware structure 3237 * @rid: recipe ID returned as response to AQ call 3238 */ 3239 enum ice_status ice_alloc_recipe(struct ice_hw *hw, u16 *rid) 3240 { 3241 struct ice_aqc_alloc_free_res_elem *sw_buf; 3242 enum ice_status status; 3243 u16 buf_len; 3244 3245 buf_len = ice_struct_size(sw_buf, elem, 1); 3246 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 3247 if (!sw_buf) 3248 return ICE_ERR_NO_MEMORY; 3249 3250 sw_buf->num_elems = CPU_TO_LE16(1); 3251 sw_buf->res_type = CPU_TO_LE16((ICE_AQC_RES_TYPE_RECIPE << 3252 ICE_AQC_RES_TYPE_S) | 3253 ICE_AQC_RES_TYPE_FLAG_SHARED); 3254 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 3255 ice_aqc_opc_alloc_res, NULL); 3256 if (!status) 3257 *rid = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp); 3258 ice_free(hw, sw_buf); 3259 3260 return status; 3261 } 3262 3263 /* ice_init_port_info - Initialize port_info with switch configuration data 3264 * @pi: pointer to port_info 3265 * @vsi_port_num: VSI number or port number 3266 * @type: Type of switch element (port or VSI) 3267 * @swid: switch ID of the switch the element is attached to 3268 * @pf_vf_num: PF or VF number 3269 * @is_vf: true if the element is a VF, false otherwise 3270 */ 3271 static void 3272 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type, 3273 u16 swid, u16 pf_vf_num, bool is_vf) 3274 { 3275 switch (type) { 3276 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT: 3277 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK); 3278 pi->sw_id = swid; 3279 pi->pf_vf_num = pf_vf_num; 3280 pi->is_vf = is_vf; 3281 pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL; 3282 pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL; 3283 break; 3284 default: 3285 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n"); 3286 break; 3287 } 3288 } 3289 3290 /* ice_get_initial_sw_cfg - Get initial port and default VSI data 3291 * @hw: pointer to the hardware structure 3292 */ 3293 enum ice_status ice_get_initial_sw_cfg(struct ice_hw *hw) 3294 { 3295 struct ice_aqc_get_sw_cfg_resp_elem *rbuf; 3296 enum ice_status status; 3297 u8 num_total_ports; 3298 u16 req_desc = 0; 3299 u16 num_elems; 3300 u8 j = 0; 3301 u16 i; 3302 3303 num_total_ports = 1; 3304 3305 rbuf = (struct ice_aqc_get_sw_cfg_resp_elem *) 3306 ice_malloc(hw, ICE_SW_CFG_MAX_BUF_LEN); 3307 3308 if (!rbuf) 3309 return ICE_ERR_NO_MEMORY; 3310 3311 /* Multiple calls to ice_aq_get_sw_cfg may be required 3312 * to get all the switch configuration information. The need 3313 * for additional calls is indicated by ice_aq_get_sw_cfg 3314 * writing a non-zero value in req_desc 3315 */ 3316 do { 3317 struct ice_aqc_get_sw_cfg_resp_elem *ele; 3318 3319 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN, 3320 &req_desc, &num_elems, NULL); 3321 3322 if (status) 3323 break; 3324 3325 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) { 3326 u16 pf_vf_num, swid, vsi_port_num; 3327 bool is_vf = false; 3328 u8 res_type; 3329 3330 vsi_port_num = LE16_TO_CPU(ele->vsi_port_num) & 3331 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M; 3332 3333 pf_vf_num = LE16_TO_CPU(ele->pf_vf_num) & 3334 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M; 3335 3336 swid = LE16_TO_CPU(ele->swid); 3337 3338 if (LE16_TO_CPU(ele->pf_vf_num) & 3339 ICE_AQC_GET_SW_CONF_RESP_IS_VF) 3340 is_vf = true; 3341 3342 res_type = (u8)(LE16_TO_CPU(ele->vsi_port_num) >> 3343 ICE_AQC_GET_SW_CONF_RESP_TYPE_S); 3344 3345 switch (res_type) { 3346 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT: 3347 case ICE_AQC_GET_SW_CONF_RESP_VIRT_PORT: 3348 if (j == num_total_ports) { 3349 ice_debug(hw, ICE_DBG_SW, "more ports than expected\n"); 3350 status = ICE_ERR_CFG; 3351 goto out; 3352 } 3353 ice_init_port_info(hw->port_info, 3354 vsi_port_num, res_type, swid, 3355 pf_vf_num, is_vf); 3356 j++; 3357 break; 3358 default: 3359 break; 3360 } 3361 } 3362 } while (req_desc && !status); 3363 3364 out: 3365 ice_free(hw, rbuf); 3366 return status; 3367 } 3368 3369 /** 3370 * ice_fill_sw_info - Helper function to populate lb_en and lan_en 3371 * @hw: pointer to the hardware structure 3372 * @fi: filter info structure to fill/update 3373 * 3374 * This helper function populates the lb_en and lan_en elements of the provided 3375 * ice_fltr_info struct using the switch's type and characteristics of the 3376 * switch rule being configured. 3377 */ 3378 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi) 3379 { 3380 if ((fi->flag & ICE_FLTR_RX) && 3381 (fi->fltr_act == ICE_FWD_TO_VSI || 3382 fi->fltr_act == ICE_FWD_TO_VSI_LIST) && 3383 fi->lkup_type == ICE_SW_LKUP_LAST) 3384 fi->lan_en = true; 3385 fi->lb_en = false; 3386 fi->lan_en = false; 3387 if ((fi->flag & ICE_FLTR_TX) && 3388 (fi->fltr_act == ICE_FWD_TO_VSI || 3389 fi->fltr_act == ICE_FWD_TO_VSI_LIST || 3390 fi->fltr_act == ICE_FWD_TO_Q || 3391 fi->fltr_act == ICE_FWD_TO_QGRP)) { 3392 /* Setting LB for prune actions will result in replicated 3393 * packets to the internal switch that will be dropped. 3394 */ 3395 if (fi->lkup_type != ICE_SW_LKUP_VLAN) 3396 fi->lb_en = true; 3397 3398 /* Set lan_en to TRUE if 3399 * 1. The switch is a VEB AND 3400 * 2 3401 * 2.1 The lookup is a directional lookup like ethertype, 3402 * promiscuous, ethertype-MAC, promiscuous-VLAN 3403 * and default-port OR 3404 * 2.2 The lookup is VLAN, OR 3405 * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR 3406 * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC. 3407 * 3408 * OR 3409 * 3410 * The switch is a VEPA. 3411 * 3412 * In all other cases, the LAN enable has to be set to false. 3413 */ 3414 if (hw->evb_veb) { 3415 if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE || 3416 fi->lkup_type == ICE_SW_LKUP_PROMISC || 3417 fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 3418 fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 3419 fi->lkup_type == ICE_SW_LKUP_DFLT || 3420 fi->lkup_type == ICE_SW_LKUP_VLAN || 3421 (fi->lkup_type == ICE_SW_LKUP_MAC && 3422 !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr)) || 3423 (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN && 3424 !IS_UNICAST_ETHER_ADDR(fi->l_data.mac.mac_addr))) 3425 fi->lan_en = true; 3426 } else { 3427 fi->lan_en = true; 3428 } 3429 } 3430 } 3431 3432 /** 3433 * ice_fill_sw_rule - Helper function to fill switch rule structure 3434 * @hw: pointer to the hardware structure 3435 * @f_info: entry containing packet forwarding information 3436 * @s_rule: switch rule structure to be filled in based on mac_entry 3437 * @opc: switch rules population command type - pass in the command opcode 3438 */ 3439 static void 3440 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info, 3441 struct ice_aqc_sw_rules_elem *s_rule, enum ice_adminq_opc opc) 3442 { 3443 u16 vlan_id = ICE_MAX_VLAN_ID + 1; 3444 void *daddr = NULL; 3445 u16 eth_hdr_sz; 3446 u8 *eth_hdr; 3447 u32 act = 0; 3448 __be16 *off; 3449 u8 q_rgn; 3450 3451 if (opc == ice_aqc_opc_remove_sw_rules) { 3452 s_rule->pdata.lkup_tx_rx.act = 0; 3453 s_rule->pdata.lkup_tx_rx.index = 3454 CPU_TO_LE16(f_info->fltr_rule_id); 3455 s_rule->pdata.lkup_tx_rx.hdr_len = 0; 3456 return; 3457 } 3458 3459 eth_hdr_sz = sizeof(dummy_eth_header); 3460 eth_hdr = s_rule->pdata.lkup_tx_rx.hdr; 3461 3462 /* initialize the ether header with a dummy header */ 3463 ice_memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz, ICE_NONDMA_TO_NONDMA); 3464 ice_fill_sw_info(hw, f_info); 3465 3466 switch (f_info->fltr_act) { 3467 case ICE_FWD_TO_VSI: 3468 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & 3469 ICE_SINGLE_ACT_VSI_ID_M; 3470 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 3471 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 3472 ICE_SINGLE_ACT_VALID_BIT; 3473 break; 3474 case ICE_FWD_TO_VSI_LIST: 3475 act |= ICE_SINGLE_ACT_VSI_LIST; 3476 act |= (f_info->fwd_id.vsi_list_id << 3477 ICE_SINGLE_ACT_VSI_LIST_ID_S) & 3478 ICE_SINGLE_ACT_VSI_LIST_ID_M; 3479 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 3480 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 3481 ICE_SINGLE_ACT_VALID_BIT; 3482 break; 3483 case ICE_FWD_TO_Q: 3484 act |= ICE_SINGLE_ACT_TO_Q; 3485 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 3486 ICE_SINGLE_ACT_Q_INDEX_M; 3487 break; 3488 case ICE_DROP_PACKET: 3489 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 3490 ICE_SINGLE_ACT_VALID_BIT; 3491 break; 3492 case ICE_FWD_TO_QGRP: 3493 q_rgn = f_info->qgrp_size > 0 ? 3494 (u8)ice_ilog2(f_info->qgrp_size) : 0; 3495 act |= ICE_SINGLE_ACT_TO_Q; 3496 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 3497 ICE_SINGLE_ACT_Q_INDEX_M; 3498 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 3499 ICE_SINGLE_ACT_Q_REGION_M; 3500 break; 3501 default: 3502 return; 3503 } 3504 3505 if (f_info->lb_en) 3506 act |= ICE_SINGLE_ACT_LB_ENABLE; 3507 if (f_info->lan_en) 3508 act |= ICE_SINGLE_ACT_LAN_ENABLE; 3509 3510 switch (f_info->lkup_type) { 3511 case ICE_SW_LKUP_MAC: 3512 daddr = f_info->l_data.mac.mac_addr; 3513 break; 3514 case ICE_SW_LKUP_VLAN: 3515 vlan_id = f_info->l_data.vlan.vlan_id; 3516 if (f_info->fltr_act == ICE_FWD_TO_VSI || 3517 f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 3518 act |= ICE_SINGLE_ACT_PRUNE; 3519 act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS; 3520 } 3521 break; 3522 case ICE_SW_LKUP_ETHERTYPE_MAC: 3523 daddr = f_info->l_data.ethertype_mac.mac_addr; 3524 /* fall-through */ 3525 case ICE_SW_LKUP_ETHERTYPE: 3526 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 3527 *off = CPU_TO_BE16(f_info->l_data.ethertype_mac.ethertype); 3528 break; 3529 case ICE_SW_LKUP_MAC_VLAN: 3530 daddr = f_info->l_data.mac_vlan.mac_addr; 3531 vlan_id = f_info->l_data.mac_vlan.vlan_id; 3532 break; 3533 case ICE_SW_LKUP_PROMISC_VLAN: 3534 vlan_id = f_info->l_data.mac_vlan.vlan_id; 3535 /* fall-through */ 3536 case ICE_SW_LKUP_PROMISC: 3537 daddr = f_info->l_data.mac_vlan.mac_addr; 3538 break; 3539 default: 3540 break; 3541 } 3542 3543 s_rule->type = (f_info->flag & ICE_FLTR_RX) ? 3544 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX) : 3545 CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX); 3546 3547 /* Recipe set depending on lookup type */ 3548 s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(f_info->lkup_type); 3549 s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(f_info->src); 3550 s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act); 3551 3552 if (daddr) 3553 ice_memcpy(eth_hdr + ICE_ETH_DA_OFFSET, daddr, ETH_ALEN, 3554 ICE_NONDMA_TO_NONDMA); 3555 3556 if (!(vlan_id > ICE_MAX_VLAN_ID)) { 3557 off = (_FORCE_ __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET); 3558 *off = CPU_TO_BE16(vlan_id); 3559 } 3560 3561 /* Create the switch rule with the final dummy Ethernet header */ 3562 if (opc != ice_aqc_opc_update_sw_rules) 3563 s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(eth_hdr_sz); 3564 } 3565 3566 /** 3567 * ice_add_marker_act 3568 * @hw: pointer to the hardware structure 3569 * @m_ent: the management entry for which sw marker needs to be added 3570 * @sw_marker: sw marker to tag the Rx descriptor with 3571 * @l_id: large action resource ID 3572 * 3573 * Create a large action to hold software marker and update the switch rule 3574 * entry pointed by m_ent with newly created large action 3575 */ 3576 static enum ice_status 3577 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, 3578 u16 sw_marker, u16 l_id) 3579 { 3580 struct ice_aqc_sw_rules_elem *lg_act, *rx_tx; 3581 /* For software marker we need 3 large actions 3582 * 1. FWD action: FWD TO VSI or VSI LIST 3583 * 2. GENERIC VALUE action to hold the profile ID 3584 * 3. GENERIC VALUE action to hold the software marker ID 3585 */ 3586 const u16 num_lg_acts = 3; 3587 enum ice_status status; 3588 u16 lg_act_size; 3589 u16 rules_size; 3590 u32 act; 3591 u16 id; 3592 3593 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 3594 return ICE_ERR_PARAM; 3595 3596 /* Create two back-to-back switch rules and submit them to the HW using 3597 * one memory buffer: 3598 * 1. Large Action 3599 * 2. Look up Tx Rx 3600 */ 3601 lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_lg_acts); 3602 rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE; 3603 lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size); 3604 if (!lg_act) 3605 return ICE_ERR_NO_MEMORY; 3606 3607 rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size); 3608 3609 /* Fill in the first switch rule i.e. large action */ 3610 lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT); 3611 lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id); 3612 lg_act->pdata.lg_act.size = CPU_TO_LE16(num_lg_acts); 3613 3614 /* First action VSI forwarding or VSI list forwarding depending on how 3615 * many VSIs 3616 */ 3617 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id : 3618 m_ent->fltr_info.fwd_id.hw_vsi_id; 3619 3620 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 3621 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M; 3622 if (m_ent->vsi_count > 1) 3623 act |= ICE_LG_ACT_VSI_LIST; 3624 lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act); 3625 3626 /* Second action descriptor type */ 3627 act = ICE_LG_ACT_GENERIC; 3628 3629 act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M; 3630 lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act); 3631 3632 act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX << 3633 ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M; 3634 3635 /* Third action Marker value */ 3636 act |= ICE_LG_ACT_GENERIC; 3637 act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) & 3638 ICE_LG_ACT_GENERIC_VALUE_M; 3639 3640 lg_act->pdata.lg_act.act[2] = CPU_TO_LE32(act); 3641 3642 /* call the fill switch rule to fill the lookup Tx Rx structure */ 3643 ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx, 3644 ice_aqc_opc_update_sw_rules); 3645 3646 /* Update the action to point to the large action ID */ 3647 rx_tx->pdata.lkup_tx_rx.act = 3648 CPU_TO_LE32(ICE_SINGLE_ACT_PTR | 3649 ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) & 3650 ICE_SINGLE_ACT_PTR_VAL_M)); 3651 3652 /* Use the filter rule ID of the previously created rule with single 3653 * act. Once the update happens, hardware will treat this as large 3654 * action 3655 */ 3656 rx_tx->pdata.lkup_tx_rx.index = 3657 CPU_TO_LE16(m_ent->fltr_info.fltr_rule_id); 3658 3659 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2, 3660 ice_aqc_opc_update_sw_rules, NULL); 3661 if (!status) { 3662 m_ent->lg_act_idx = l_id; 3663 m_ent->sw_marker_id = sw_marker; 3664 } 3665 3666 ice_free(hw, lg_act); 3667 return status; 3668 } 3669 3670 /** 3671 * ice_add_counter_act - add/update filter rule with counter action 3672 * @hw: pointer to the hardware structure 3673 * @m_ent: the management entry for which counter needs to be added 3674 * @counter_id: VLAN counter ID returned as part of allocate resource 3675 * @l_id: large action resource ID 3676 */ 3677 static enum ice_status 3678 ice_add_counter_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, 3679 u16 counter_id, u16 l_id) 3680 { 3681 struct ice_aqc_sw_rules_elem *lg_act; 3682 struct ice_aqc_sw_rules_elem *rx_tx; 3683 enum ice_status status; 3684 /* 2 actions will be added while adding a large action counter */ 3685 const int num_acts = 2; 3686 u16 lg_act_size; 3687 u16 rules_size; 3688 u16 f_rule_id; 3689 u32 act; 3690 u16 id; 3691 3692 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 3693 return ICE_ERR_PARAM; 3694 3695 /* Create two back-to-back switch rules and submit them to the HW using 3696 * one memory buffer: 3697 * 1. Large Action 3698 * 2. Look up Tx Rx 3699 */ 3700 lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(num_acts); 3701 rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE; 3702 lg_act = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rules_size); 3703 if (!lg_act) 3704 return ICE_ERR_NO_MEMORY; 3705 3706 rx_tx = (struct ice_aqc_sw_rules_elem *)((u8 *)lg_act + lg_act_size); 3707 3708 /* Fill in the first switch rule i.e. large action */ 3709 lg_act->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LG_ACT); 3710 lg_act->pdata.lg_act.index = CPU_TO_LE16(l_id); 3711 lg_act->pdata.lg_act.size = CPU_TO_LE16(num_acts); 3712 3713 /* First action VSI forwarding or VSI list forwarding depending on how 3714 * many VSIs 3715 */ 3716 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id : 3717 m_ent->fltr_info.fwd_id.hw_vsi_id; 3718 3719 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 3720 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & 3721 ICE_LG_ACT_VSI_LIST_ID_M; 3722 if (m_ent->vsi_count > 1) 3723 act |= ICE_LG_ACT_VSI_LIST; 3724 lg_act->pdata.lg_act.act[0] = CPU_TO_LE32(act); 3725 3726 /* Second action counter ID */ 3727 act = ICE_LG_ACT_STAT_COUNT; 3728 act |= (counter_id << ICE_LG_ACT_STAT_COUNT_S) & 3729 ICE_LG_ACT_STAT_COUNT_M; 3730 lg_act->pdata.lg_act.act[1] = CPU_TO_LE32(act); 3731 3732 /* call the fill switch rule to fill the lookup Tx Rx structure */ 3733 ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx, 3734 ice_aqc_opc_update_sw_rules); 3735 3736 act = ICE_SINGLE_ACT_PTR; 3737 act |= (l_id << ICE_SINGLE_ACT_PTR_VAL_S) & ICE_SINGLE_ACT_PTR_VAL_M; 3738 rx_tx->pdata.lkup_tx_rx.act = CPU_TO_LE32(act); 3739 3740 /* Use the filter rule ID of the previously created rule with single 3741 * act. Once the update happens, hardware will treat this as large 3742 * action 3743 */ 3744 f_rule_id = m_ent->fltr_info.fltr_rule_id; 3745 rx_tx->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_rule_id); 3746 3747 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2, 3748 ice_aqc_opc_update_sw_rules, NULL); 3749 if (!status) { 3750 m_ent->lg_act_idx = l_id; 3751 m_ent->counter_index = counter_id; 3752 } 3753 3754 ice_free(hw, lg_act); 3755 return status; 3756 } 3757 3758 /** 3759 * ice_create_vsi_list_map 3760 * @hw: pointer to the hardware structure 3761 * @vsi_handle_arr: array of VSI handles to set in the VSI mapping 3762 * @num_vsi: number of VSI handles in the array 3763 * @vsi_list_id: VSI list ID generated as part of allocate resource 3764 * 3765 * Helper function to create a new entry of VSI list ID to VSI mapping 3766 * using the given VSI list ID 3767 */ 3768 static struct ice_vsi_list_map_info * 3769 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 3770 u16 vsi_list_id) 3771 { 3772 struct ice_switch_info *sw = hw->switch_info; 3773 struct ice_vsi_list_map_info *v_map; 3774 int i; 3775 3776 v_map = (struct ice_vsi_list_map_info *)ice_malloc(hw, sizeof(*v_map)); 3777 if (!v_map) 3778 return NULL; 3779 3780 v_map->vsi_list_id = vsi_list_id; 3781 v_map->ref_cnt = 1; 3782 for (i = 0; i < num_vsi; i++) 3783 ice_set_bit(vsi_handle_arr[i], v_map->vsi_map); 3784 3785 LIST_ADD(&v_map->list_entry, &sw->vsi_list_map_head); 3786 return v_map; 3787 } 3788 3789 /** 3790 * ice_update_vsi_list_rule 3791 * @hw: pointer to the hardware structure 3792 * @vsi_handle_arr: array of VSI handles to form a VSI list 3793 * @num_vsi: number of VSI handles in the array 3794 * @vsi_list_id: VSI list ID generated as part of allocate resource 3795 * @remove: Boolean value to indicate if this is a remove action 3796 * @opc: switch rules population command type - pass in the command opcode 3797 * @lkup_type: lookup type of the filter 3798 * 3799 * Call AQ command to add a new switch rule or update existing switch rule 3800 * using the given VSI list ID 3801 */ 3802 static enum ice_status 3803 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 3804 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc, 3805 enum ice_sw_lkup_type lkup_type) 3806 { 3807 struct ice_aqc_sw_rules_elem *s_rule; 3808 enum ice_status status; 3809 u16 s_rule_size; 3810 u16 rule_type; 3811 int i; 3812 3813 if (!num_vsi) 3814 return ICE_ERR_PARAM; 3815 3816 if (lkup_type == ICE_SW_LKUP_MAC || 3817 lkup_type == ICE_SW_LKUP_MAC_VLAN || 3818 lkup_type == ICE_SW_LKUP_ETHERTYPE || 3819 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 3820 lkup_type == ICE_SW_LKUP_PROMISC || 3821 lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 3822 lkup_type == ICE_SW_LKUP_LAST) 3823 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR : 3824 ICE_AQC_SW_RULES_T_VSI_LIST_SET; 3825 else if (lkup_type == ICE_SW_LKUP_VLAN) 3826 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR : 3827 ICE_AQC_SW_RULES_T_PRUNE_LIST_SET; 3828 else 3829 return ICE_ERR_PARAM; 3830 3831 s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(num_vsi); 3832 s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size); 3833 if (!s_rule) 3834 return ICE_ERR_NO_MEMORY; 3835 for (i = 0; i < num_vsi; i++) { 3836 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) { 3837 status = ICE_ERR_PARAM; 3838 goto exit; 3839 } 3840 /* AQ call requires hw_vsi_id(s) */ 3841 s_rule->pdata.vsi_list.vsi[i] = 3842 CPU_TO_LE16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i])); 3843 } 3844 3845 s_rule->type = CPU_TO_LE16(rule_type); 3846 s_rule->pdata.vsi_list.number_vsi = CPU_TO_LE16(num_vsi); 3847 s_rule->pdata.vsi_list.index = CPU_TO_LE16(vsi_list_id); 3848 3849 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL); 3850 3851 exit: 3852 ice_free(hw, s_rule); 3853 return status; 3854 } 3855 3856 /** 3857 * ice_create_vsi_list_rule - Creates and populates a VSI list rule 3858 * @hw: pointer to the HW struct 3859 * @vsi_handle_arr: array of VSI handles to form a VSI list 3860 * @num_vsi: number of VSI handles in the array 3861 * @vsi_list_id: stores the ID of the VSI list to be created 3862 * @lkup_type: switch rule filter's lookup type 3863 */ 3864 static enum ice_status 3865 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 3866 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type) 3867 { 3868 enum ice_status status; 3869 3870 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type, 3871 ice_aqc_opc_alloc_res); 3872 if (status) 3873 return status; 3874 3875 /* Update the newly created VSI list to include the specified VSIs */ 3876 return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi, 3877 *vsi_list_id, false, 3878 ice_aqc_opc_add_sw_rules, lkup_type); 3879 } 3880 3881 /** 3882 * ice_create_pkt_fwd_rule 3883 * @hw: pointer to the hardware structure 3884 * @recp_list: corresponding filter management list 3885 * @f_entry: entry containing packet forwarding information 3886 * 3887 * Create switch rule with given filter information and add an entry 3888 * to the corresponding filter management list to track this switch rule 3889 * and VSI mapping 3890 */ 3891 static enum ice_status 3892 ice_create_pkt_fwd_rule(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 3893 struct ice_fltr_list_entry *f_entry) 3894 { 3895 struct ice_fltr_mgmt_list_entry *fm_entry; 3896 struct ice_aqc_sw_rules_elem *s_rule; 3897 enum ice_status status; 3898 3899 s_rule = (struct ice_aqc_sw_rules_elem *) 3900 ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE); 3901 if (!s_rule) 3902 return ICE_ERR_NO_MEMORY; 3903 fm_entry = (struct ice_fltr_mgmt_list_entry *) 3904 ice_malloc(hw, sizeof(*fm_entry)); 3905 if (!fm_entry) { 3906 status = ICE_ERR_NO_MEMORY; 3907 goto ice_create_pkt_fwd_rule_exit; 3908 } 3909 3910 fm_entry->fltr_info = f_entry->fltr_info; 3911 3912 /* Initialize all the fields for the management entry */ 3913 fm_entry->vsi_count = 1; 3914 fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX; 3915 fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID; 3916 fm_entry->counter_index = ICE_INVAL_COUNTER_ID; 3917 3918 ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule, 3919 ice_aqc_opc_add_sw_rules); 3920 3921 status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1, 3922 ice_aqc_opc_add_sw_rules, NULL); 3923 if (status) { 3924 ice_free(hw, fm_entry); 3925 goto ice_create_pkt_fwd_rule_exit; 3926 } 3927 3928 f_entry->fltr_info.fltr_rule_id = 3929 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index); 3930 fm_entry->fltr_info.fltr_rule_id = 3931 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index); 3932 3933 /* The book keeping entries will get removed when base driver 3934 * calls remove filter AQ command 3935 */ 3936 LIST_ADD(&fm_entry->list_entry, &recp_list->filt_rules); 3937 3938 ice_create_pkt_fwd_rule_exit: 3939 ice_free(hw, s_rule); 3940 return status; 3941 } 3942 3943 /** 3944 * ice_update_pkt_fwd_rule 3945 * @hw: pointer to the hardware structure 3946 * @f_info: filter information for switch rule 3947 * 3948 * Call AQ command to update a previously created switch rule with a 3949 * VSI list ID 3950 */ 3951 static enum ice_status 3952 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info) 3953 { 3954 struct ice_aqc_sw_rules_elem *s_rule; 3955 enum ice_status status; 3956 3957 s_rule = (struct ice_aqc_sw_rules_elem *) 3958 ice_malloc(hw, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE); 3959 if (!s_rule) 3960 return ICE_ERR_NO_MEMORY; 3961 3962 ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules); 3963 3964 s_rule->pdata.lkup_tx_rx.index = CPU_TO_LE16(f_info->fltr_rule_id); 3965 3966 /* Update switch rule with new rule set to forward VSI list */ 3967 status = ice_aq_sw_rules(hw, s_rule, ICE_SW_RULE_RX_TX_ETH_HDR_SIZE, 1, 3968 ice_aqc_opc_update_sw_rules, NULL); 3969 3970 ice_free(hw, s_rule); 3971 return status; 3972 } 3973 3974 /** 3975 * ice_update_sw_rule_bridge_mode 3976 * @hw: pointer to the HW struct 3977 * 3978 * Updates unicast switch filter rules based on VEB/VEPA mode 3979 */ 3980 enum ice_status ice_update_sw_rule_bridge_mode(struct ice_hw *hw) 3981 { 3982 struct ice_switch_info *sw = hw->switch_info; 3983 struct ice_fltr_mgmt_list_entry *fm_entry; 3984 enum ice_status status = ICE_SUCCESS; 3985 struct LIST_HEAD_TYPE *rule_head; 3986 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 3987 3988 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 3989 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 3990 3991 ice_acquire_lock(rule_lock); 3992 LIST_FOR_EACH_ENTRY(fm_entry, rule_head, ice_fltr_mgmt_list_entry, 3993 list_entry) { 3994 struct ice_fltr_info *fi = &fm_entry->fltr_info; 3995 u8 *addr = fi->l_data.mac.mac_addr; 3996 3997 /* Update unicast Tx rules to reflect the selected 3998 * VEB/VEPA mode 3999 */ 4000 if ((fi->flag & ICE_FLTR_TX) && IS_UNICAST_ETHER_ADDR(addr) && 4001 (fi->fltr_act == ICE_FWD_TO_VSI || 4002 fi->fltr_act == ICE_FWD_TO_VSI_LIST || 4003 fi->fltr_act == ICE_FWD_TO_Q || 4004 fi->fltr_act == ICE_FWD_TO_QGRP)) { 4005 status = ice_update_pkt_fwd_rule(hw, fi); 4006 if (status) 4007 break; 4008 } 4009 } 4010 4011 ice_release_lock(rule_lock); 4012 4013 return status; 4014 } 4015 4016 /** 4017 * ice_add_update_vsi_list 4018 * @hw: pointer to the hardware structure 4019 * @m_entry: pointer to current filter management list entry 4020 * @cur_fltr: filter information from the book keeping entry 4021 * @new_fltr: filter information with the new VSI to be added 4022 * 4023 * Call AQ command to add or update previously created VSI list with new VSI. 4024 * 4025 * Helper function to do book keeping associated with adding filter information 4026 * The algorithm to do the book keeping is described below : 4027 * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.) 4028 * if only one VSI has been added till now 4029 * Allocate a new VSI list and add two VSIs 4030 * to this list using switch rule command 4031 * Update the previously created switch rule with the 4032 * newly created VSI list ID 4033 * if a VSI list was previously created 4034 * Add the new VSI to the previously created VSI list set 4035 * using the update switch rule command 4036 */ 4037 static enum ice_status 4038 ice_add_update_vsi_list(struct ice_hw *hw, 4039 struct ice_fltr_mgmt_list_entry *m_entry, 4040 struct ice_fltr_info *cur_fltr, 4041 struct ice_fltr_info *new_fltr) 4042 { 4043 enum ice_status status = ICE_SUCCESS; 4044 u16 vsi_list_id = 0; 4045 4046 if ((cur_fltr->fltr_act == ICE_FWD_TO_Q || 4047 cur_fltr->fltr_act == ICE_FWD_TO_QGRP)) 4048 return ICE_ERR_NOT_IMPL; 4049 4050 if ((new_fltr->fltr_act == ICE_FWD_TO_Q || 4051 new_fltr->fltr_act == ICE_FWD_TO_QGRP) && 4052 (cur_fltr->fltr_act == ICE_FWD_TO_VSI || 4053 cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST)) 4054 return ICE_ERR_NOT_IMPL; 4055 4056 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 4057 /* Only one entry existed in the mapping and it was not already 4058 * a part of a VSI list. So, create a VSI list with the old and 4059 * new VSIs. 4060 */ 4061 struct ice_fltr_info tmp_fltr; 4062 u16 vsi_handle_arr[2]; 4063 4064 /* A rule already exists with the new VSI being added */ 4065 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id) 4066 return ICE_ERR_ALREADY_EXISTS; 4067 4068 vsi_handle_arr[0] = cur_fltr->vsi_handle; 4069 vsi_handle_arr[1] = new_fltr->vsi_handle; 4070 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 4071 &vsi_list_id, 4072 new_fltr->lkup_type); 4073 if (status) 4074 return status; 4075 4076 tmp_fltr = *new_fltr; 4077 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 4078 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 4079 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 4080 /* Update the previous switch rule of "MAC forward to VSI" to 4081 * "MAC fwd to VSI list" 4082 */ 4083 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 4084 if (status) 4085 return status; 4086 4087 cur_fltr->fwd_id.vsi_list_id = vsi_list_id; 4088 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 4089 m_entry->vsi_list_info = 4090 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 4091 vsi_list_id); 4092 4093 if (!m_entry->vsi_list_info) 4094 return ICE_ERR_NO_MEMORY; 4095 4096 /* If this entry was large action then the large action needs 4097 * to be updated to point to FWD to VSI list 4098 */ 4099 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) 4100 status = 4101 ice_add_marker_act(hw, m_entry, 4102 m_entry->sw_marker_id, 4103 m_entry->lg_act_idx); 4104 } else { 4105 u16 vsi_handle = new_fltr->vsi_handle; 4106 enum ice_adminq_opc opcode; 4107 4108 if (!m_entry->vsi_list_info) 4109 return ICE_ERR_CFG; 4110 4111 /* A rule already exists with the new VSI being added */ 4112 if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle)) 4113 return ICE_SUCCESS; 4114 4115 /* Update the previously created VSI list set with 4116 * the new VSI ID passed in 4117 */ 4118 vsi_list_id = cur_fltr->fwd_id.vsi_list_id; 4119 opcode = ice_aqc_opc_update_sw_rules; 4120 4121 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 4122 vsi_list_id, false, opcode, 4123 new_fltr->lkup_type); 4124 /* update VSI list mapping info with new VSI ID */ 4125 if (!status) 4126 ice_set_bit(vsi_handle, 4127 m_entry->vsi_list_info->vsi_map); 4128 } 4129 if (!status) 4130 m_entry->vsi_count++; 4131 return status; 4132 } 4133 4134 /** 4135 * ice_find_rule_entry - Search a rule entry 4136 * @list_head: head of rule list 4137 * @f_info: rule information 4138 * 4139 * Helper function to search for a given rule entry 4140 * Returns pointer to entry storing the rule if found 4141 */ 4142 static struct ice_fltr_mgmt_list_entry * 4143 ice_find_rule_entry(struct LIST_HEAD_TYPE *list_head, 4144 struct ice_fltr_info *f_info) 4145 { 4146 struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL; 4147 4148 LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry, 4149 list_entry) { 4150 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, 4151 sizeof(f_info->l_data)) && 4152 f_info->flag == list_itr->fltr_info.flag) { 4153 ret = list_itr; 4154 break; 4155 } 4156 } 4157 return ret; 4158 } 4159 4160 /** 4161 * ice_find_vsi_list_entry - Search VSI list map with VSI count 1 4162 * @recp_list: VSI lists needs to be searched 4163 * @vsi_handle: VSI handle to be found in VSI list 4164 * @vsi_list_id: VSI list ID found containing vsi_handle 4165 * 4166 * Helper function to search a VSI list with single entry containing given VSI 4167 * handle element. This can be extended further to search VSI list with more 4168 * than 1 vsi_count. Returns pointer to VSI list entry if found. 4169 */ 4170 static struct ice_vsi_list_map_info * 4171 ice_find_vsi_list_entry(struct ice_sw_recipe *recp_list, u16 vsi_handle, 4172 u16 *vsi_list_id) 4173 { 4174 struct ice_vsi_list_map_info *map_info = NULL; 4175 struct LIST_HEAD_TYPE *list_head; 4176 4177 list_head = &recp_list->filt_rules; 4178 if (recp_list->adv_rule) { 4179 struct ice_adv_fltr_mgmt_list_entry *list_itr; 4180 4181 LIST_FOR_EACH_ENTRY(list_itr, list_head, 4182 ice_adv_fltr_mgmt_list_entry, 4183 list_entry) { 4184 if (list_itr->vsi_list_info) { 4185 map_info = list_itr->vsi_list_info; 4186 if (ice_is_bit_set(map_info->vsi_map, 4187 vsi_handle)) { 4188 *vsi_list_id = map_info->vsi_list_id; 4189 return map_info; 4190 } 4191 } 4192 } 4193 } else { 4194 struct ice_fltr_mgmt_list_entry *list_itr; 4195 4196 LIST_FOR_EACH_ENTRY(list_itr, list_head, 4197 ice_fltr_mgmt_list_entry, 4198 list_entry) { 4199 if (list_itr->vsi_count == 1 && 4200 list_itr->vsi_list_info) { 4201 map_info = list_itr->vsi_list_info; 4202 if (ice_is_bit_set(map_info->vsi_map, 4203 vsi_handle)) { 4204 *vsi_list_id = map_info->vsi_list_id; 4205 return map_info; 4206 } 4207 } 4208 } 4209 } 4210 return NULL; 4211 } 4212 4213 /** 4214 * ice_add_rule_internal - add rule for a given lookup type 4215 * @hw: pointer to the hardware structure 4216 * @recp_list: recipe list for which rule has to be added 4217 * @lport: logic port number on which function add rule 4218 * @f_entry: structure containing MAC forwarding information 4219 * 4220 * Adds or updates the rule lists for a given recipe 4221 */ 4222 static enum ice_status 4223 ice_add_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 4224 u8 lport, struct ice_fltr_list_entry *f_entry) 4225 { 4226 struct ice_fltr_info *new_fltr, *cur_fltr; 4227 struct ice_fltr_mgmt_list_entry *m_entry; 4228 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 4229 enum ice_status status = ICE_SUCCESS; 4230 4231 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 4232 return ICE_ERR_PARAM; 4233 4234 /* Load the hw_vsi_id only if the fwd action is fwd to VSI */ 4235 if (f_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI) 4236 f_entry->fltr_info.fwd_id.hw_vsi_id = 4237 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 4238 4239 rule_lock = &recp_list->filt_rule_lock; 4240 4241 ice_acquire_lock(rule_lock); 4242 new_fltr = &f_entry->fltr_info; 4243 if (new_fltr->flag & ICE_FLTR_RX) 4244 new_fltr->src = lport; 4245 else if (new_fltr->flag & ICE_FLTR_TX) 4246 new_fltr->src = 4247 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 4248 4249 m_entry = ice_find_rule_entry(&recp_list->filt_rules, new_fltr); 4250 if (!m_entry) { 4251 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry); 4252 goto exit_add_rule_internal; 4253 } 4254 4255 cur_fltr = &m_entry->fltr_info; 4256 status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr); 4257 4258 exit_add_rule_internal: 4259 ice_release_lock(rule_lock); 4260 return status; 4261 } 4262 4263 /** 4264 * ice_remove_vsi_list_rule 4265 * @hw: pointer to the hardware structure 4266 * @vsi_list_id: VSI list ID generated as part of allocate resource 4267 * @lkup_type: switch rule filter lookup type 4268 * 4269 * The VSI list should be emptied before this function is called to remove the 4270 * VSI list. 4271 */ 4272 static enum ice_status 4273 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id, 4274 enum ice_sw_lkup_type lkup_type) 4275 { 4276 /* Free the vsi_list resource that we allocated. It is assumed that the 4277 * list is empty at this point. 4278 */ 4279 return ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type, 4280 ice_aqc_opc_free_res); 4281 } 4282 4283 /** 4284 * ice_rem_update_vsi_list 4285 * @hw: pointer to the hardware structure 4286 * @vsi_handle: VSI handle of the VSI to remove 4287 * @fm_list: filter management entry for which the VSI list management needs to 4288 * be done 4289 */ 4290 static enum ice_status 4291 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 4292 struct ice_fltr_mgmt_list_entry *fm_list) 4293 { 4294 enum ice_sw_lkup_type lkup_type; 4295 enum ice_status status = ICE_SUCCESS; 4296 u16 vsi_list_id; 4297 4298 if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST || 4299 fm_list->vsi_count == 0) 4300 return ICE_ERR_PARAM; 4301 4302 /* A rule with the VSI being removed does not exist */ 4303 if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle)) 4304 return ICE_ERR_DOES_NOT_EXIST; 4305 4306 lkup_type = fm_list->fltr_info.lkup_type; 4307 vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id; 4308 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 4309 ice_aqc_opc_update_sw_rules, 4310 lkup_type); 4311 if (status) 4312 return status; 4313 4314 fm_list->vsi_count--; 4315 ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 4316 4317 if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) { 4318 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info; 4319 struct ice_vsi_list_map_info *vsi_list_info = 4320 fm_list->vsi_list_info; 4321 u16 rem_vsi_handle; 4322 4323 rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map, 4324 ICE_MAX_VSI); 4325 if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 4326 return ICE_ERR_OUT_OF_RANGE; 4327 4328 /* Make sure VSI list is empty before removing it below */ 4329 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 4330 vsi_list_id, true, 4331 ice_aqc_opc_update_sw_rules, 4332 lkup_type); 4333 if (status) 4334 return status; 4335 4336 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI; 4337 tmp_fltr_info.fwd_id.hw_vsi_id = 4338 ice_get_hw_vsi_num(hw, rem_vsi_handle); 4339 tmp_fltr_info.vsi_handle = rem_vsi_handle; 4340 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info); 4341 if (status) { 4342 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 4343 tmp_fltr_info.fwd_id.hw_vsi_id, status); 4344 return status; 4345 } 4346 4347 fm_list->fltr_info = tmp_fltr_info; 4348 } 4349 4350 if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) || 4351 (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) { 4352 struct ice_vsi_list_map_info *vsi_list_info = 4353 fm_list->vsi_list_info; 4354 4355 /* Remove the VSI list since it is no longer used */ 4356 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 4357 if (status) { 4358 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 4359 vsi_list_id, status); 4360 return status; 4361 } 4362 4363 LIST_DEL(&vsi_list_info->list_entry); 4364 ice_free(hw, vsi_list_info); 4365 fm_list->vsi_list_info = NULL; 4366 } 4367 4368 return status; 4369 } 4370 4371 /** 4372 * ice_remove_rule_internal - Remove a filter rule of a given type 4373 * 4374 * @hw: pointer to the hardware structure 4375 * @recp_list: recipe list for which the rule needs to removed 4376 * @f_entry: rule entry containing filter information 4377 */ 4378 static enum ice_status 4379 ice_remove_rule_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 4380 struct ice_fltr_list_entry *f_entry) 4381 { 4382 struct ice_fltr_mgmt_list_entry *list_elem; 4383 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 4384 enum ice_status status = ICE_SUCCESS; 4385 bool remove_rule = false; 4386 u16 vsi_handle; 4387 4388 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 4389 return ICE_ERR_PARAM; 4390 f_entry->fltr_info.fwd_id.hw_vsi_id = 4391 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 4392 4393 rule_lock = &recp_list->filt_rule_lock; 4394 ice_acquire_lock(rule_lock); 4395 list_elem = ice_find_rule_entry(&recp_list->filt_rules, 4396 &f_entry->fltr_info); 4397 if (!list_elem) { 4398 status = ICE_ERR_DOES_NOT_EXIST; 4399 goto exit; 4400 } 4401 4402 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) { 4403 remove_rule = true; 4404 } else if (!list_elem->vsi_list_info) { 4405 status = ICE_ERR_DOES_NOT_EXIST; 4406 goto exit; 4407 } else if (list_elem->vsi_list_info->ref_cnt > 1) { 4408 /* a ref_cnt > 1 indicates that the vsi_list is being 4409 * shared by multiple rules. Decrement the ref_cnt and 4410 * remove this rule, but do not modify the list, as it 4411 * is in-use by other rules. 4412 */ 4413 list_elem->vsi_list_info->ref_cnt--; 4414 remove_rule = true; 4415 } else { 4416 /* a ref_cnt of 1 indicates the vsi_list is only used 4417 * by one rule. However, the original removal request is only 4418 * for a single VSI. Update the vsi_list first, and only 4419 * remove the rule if there are no further VSIs in this list. 4420 */ 4421 vsi_handle = f_entry->fltr_info.vsi_handle; 4422 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem); 4423 if (status) 4424 goto exit; 4425 /* if VSI count goes to zero after updating the VSI list */ 4426 if (list_elem->vsi_count == 0) 4427 remove_rule = true; 4428 } 4429 4430 if (remove_rule) { 4431 /* Remove the lookup rule */ 4432 struct ice_aqc_sw_rules_elem *s_rule; 4433 4434 s_rule = (struct ice_aqc_sw_rules_elem *) 4435 ice_malloc(hw, ICE_SW_RULE_RX_TX_NO_HDR_SIZE); 4436 if (!s_rule) { 4437 status = ICE_ERR_NO_MEMORY; 4438 goto exit; 4439 } 4440 4441 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule, 4442 ice_aqc_opc_remove_sw_rules); 4443 4444 status = ice_aq_sw_rules(hw, s_rule, 4445 ICE_SW_RULE_RX_TX_NO_HDR_SIZE, 1, 4446 ice_aqc_opc_remove_sw_rules, NULL); 4447 4448 /* Remove a book keeping from the list */ 4449 ice_free(hw, s_rule); 4450 4451 if (status) 4452 goto exit; 4453 4454 LIST_DEL(&list_elem->list_entry); 4455 ice_free(hw, list_elem); 4456 } 4457 exit: 4458 ice_release_lock(rule_lock); 4459 return status; 4460 } 4461 4462 /** 4463 * ice_aq_get_res_alloc - get allocated resources 4464 * @hw: pointer to the HW struct 4465 * @num_entries: pointer to u16 to store the number of resource entries returned 4466 * @buf: pointer to buffer 4467 * @buf_size: size of buf 4468 * @cd: pointer to command details structure or NULL 4469 * 4470 * The caller-supplied buffer must be large enough to store the resource 4471 * information for all resource types. Each resource type is an 4472 * ice_aqc_get_res_resp_elem structure. 4473 */ 4474 enum ice_status 4475 ice_aq_get_res_alloc(struct ice_hw *hw, u16 *num_entries, 4476 struct ice_aqc_get_res_resp_elem *buf, u16 buf_size, 4477 struct ice_sq_cd *cd) 4478 { 4479 struct ice_aqc_get_res_alloc *resp; 4480 enum ice_status status; 4481 struct ice_aq_desc desc; 4482 4483 if (!buf) 4484 return ICE_ERR_BAD_PTR; 4485 4486 if (buf_size < ICE_AQ_GET_RES_ALLOC_BUF_LEN) 4487 return ICE_ERR_INVAL_SIZE; 4488 4489 resp = &desc.params.get_res; 4490 4491 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_res_alloc); 4492 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 4493 4494 if (!status && num_entries) 4495 *num_entries = LE16_TO_CPU(resp->resp_elem_num); 4496 4497 return status; 4498 } 4499 4500 /** 4501 * ice_aq_get_res_descs - get allocated resource descriptors 4502 * @hw: pointer to the hardware structure 4503 * @num_entries: number of resource entries in buffer 4504 * @buf: structure to hold response data buffer 4505 * @buf_size: size of buffer 4506 * @res_type: resource type 4507 * @res_shared: is resource shared 4508 * @desc_id: input - first desc ID to start; output - next desc ID 4509 * @cd: pointer to command details structure or NULL 4510 */ 4511 enum ice_status 4512 ice_aq_get_res_descs(struct ice_hw *hw, u16 num_entries, 4513 struct ice_aqc_res_elem *buf, u16 buf_size, u16 res_type, 4514 bool res_shared, u16 *desc_id, struct ice_sq_cd *cd) 4515 { 4516 struct ice_aqc_get_allocd_res_desc *cmd; 4517 struct ice_aq_desc desc; 4518 enum ice_status status; 4519 4520 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 4521 4522 cmd = &desc.params.get_res_desc; 4523 4524 if (!buf) 4525 return ICE_ERR_PARAM; 4526 4527 if (buf_size != (num_entries * sizeof(*buf))) 4528 return ICE_ERR_PARAM; 4529 4530 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_allocd_res_desc); 4531 4532 cmd->ops.cmd.res = CPU_TO_LE16(((res_type << ICE_AQC_RES_TYPE_S) & 4533 ICE_AQC_RES_TYPE_M) | (res_shared ? 4534 ICE_AQC_RES_TYPE_FLAG_SHARED : 0)); 4535 cmd->ops.cmd.first_desc = CPU_TO_LE16(*desc_id); 4536 4537 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 4538 if (!status) 4539 *desc_id = LE16_TO_CPU(cmd->ops.resp.next_desc); 4540 4541 return status; 4542 } 4543 4544 /** 4545 * ice_add_mac_rule - Add a MAC address based filter rule 4546 * @hw: pointer to the hardware structure 4547 * @m_list: list of MAC addresses and forwarding information 4548 * @sw: pointer to switch info struct for which function add rule 4549 * @lport: logic port number on which function add rule 4550 * 4551 * IMPORTANT: When the ucast_shared flag is set to false and m_list has 4552 * multiple unicast addresses, the function assumes that all the 4553 * addresses are unique in a given add_mac call. It doesn't 4554 * check for duplicates in this case, removing duplicates from a given 4555 * list should be taken care of in the caller of this function. 4556 */ 4557 static enum ice_status 4558 ice_add_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list, 4559 struct ice_switch_info *sw, u8 lport) 4560 { 4561 struct ice_sw_recipe *recp_list = &sw->recp_list[ICE_SW_LKUP_MAC]; 4562 struct ice_aqc_sw_rules_elem *s_rule, *r_iter; 4563 struct ice_fltr_list_entry *m_list_itr; 4564 struct LIST_HEAD_TYPE *rule_head; 4565 u16 total_elem_left, s_rule_size; 4566 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 4567 enum ice_status status = ICE_SUCCESS; 4568 u16 num_unicast = 0; 4569 u8 elem_sent; 4570 4571 s_rule = NULL; 4572 rule_lock = &recp_list->filt_rule_lock; 4573 rule_head = &recp_list->filt_rules; 4574 4575 LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry, 4576 list_entry) { 4577 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0]; 4578 u16 vsi_handle; 4579 u16 hw_vsi_id; 4580 4581 m_list_itr->fltr_info.flag = ICE_FLTR_TX; 4582 vsi_handle = m_list_itr->fltr_info.vsi_handle; 4583 if (!ice_is_vsi_valid(hw, vsi_handle)) 4584 return ICE_ERR_PARAM; 4585 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 4586 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id; 4587 /* update the src in case it is VSI num */ 4588 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI) 4589 return ICE_ERR_PARAM; 4590 m_list_itr->fltr_info.src = hw_vsi_id; 4591 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC || 4592 IS_ZERO_ETHER_ADDR(add)) 4593 return ICE_ERR_PARAM; 4594 if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) { 4595 /* Don't overwrite the unicast address */ 4596 ice_acquire_lock(rule_lock); 4597 if (ice_find_rule_entry(rule_head, 4598 &m_list_itr->fltr_info)) { 4599 ice_release_lock(rule_lock); 4600 return ICE_ERR_ALREADY_EXISTS; 4601 } 4602 ice_release_lock(rule_lock); 4603 num_unicast++; 4604 } else if (IS_MULTICAST_ETHER_ADDR(add) || 4605 (IS_UNICAST_ETHER_ADDR(add) && hw->ucast_shared)) { 4606 m_list_itr->status = 4607 ice_add_rule_internal(hw, recp_list, lport, 4608 m_list_itr); 4609 if (m_list_itr->status) 4610 return m_list_itr->status; 4611 } 4612 } 4613 4614 ice_acquire_lock(rule_lock); 4615 /* Exit if no suitable entries were found for adding bulk switch rule */ 4616 if (!num_unicast) { 4617 status = ICE_SUCCESS; 4618 goto ice_add_mac_exit; 4619 } 4620 4621 /* Allocate switch rule buffer for the bulk update for unicast */ 4622 s_rule_size = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE; 4623 s_rule = (struct ice_aqc_sw_rules_elem *) 4624 ice_calloc(hw, num_unicast, s_rule_size); 4625 if (!s_rule) { 4626 status = ICE_ERR_NO_MEMORY; 4627 goto ice_add_mac_exit; 4628 } 4629 4630 r_iter = s_rule; 4631 LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry, 4632 list_entry) { 4633 struct ice_fltr_info *f_info = &m_list_itr->fltr_info; 4634 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 4635 4636 if (IS_UNICAST_ETHER_ADDR(mac_addr)) { 4637 ice_fill_sw_rule(hw, &m_list_itr->fltr_info, r_iter, 4638 ice_aqc_opc_add_sw_rules); 4639 r_iter = (struct ice_aqc_sw_rules_elem *) 4640 ((u8 *)r_iter + s_rule_size); 4641 } 4642 } 4643 4644 /* Call AQ bulk switch rule update for all unicast addresses */ 4645 r_iter = s_rule; 4646 /* Call AQ switch rule in AQ_MAX chunk */ 4647 for (total_elem_left = num_unicast; total_elem_left > 0; 4648 total_elem_left -= elem_sent) { 4649 struct ice_aqc_sw_rules_elem *entry = r_iter; 4650 4651 elem_sent = MIN_T(u8, total_elem_left, 4652 (ICE_AQ_MAX_BUF_LEN / s_rule_size)); 4653 status = ice_aq_sw_rules(hw, entry, elem_sent * s_rule_size, 4654 elem_sent, ice_aqc_opc_add_sw_rules, 4655 NULL); 4656 if (status) 4657 goto ice_add_mac_exit; 4658 r_iter = (struct ice_aqc_sw_rules_elem *) 4659 ((u8 *)r_iter + (elem_sent * s_rule_size)); 4660 } 4661 4662 /* Fill up rule ID based on the value returned from FW */ 4663 r_iter = s_rule; 4664 LIST_FOR_EACH_ENTRY(m_list_itr, m_list, ice_fltr_list_entry, 4665 list_entry) { 4666 struct ice_fltr_info *f_info = &m_list_itr->fltr_info; 4667 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 4668 struct ice_fltr_mgmt_list_entry *fm_entry; 4669 4670 if (IS_UNICAST_ETHER_ADDR(mac_addr)) { 4671 f_info->fltr_rule_id = 4672 LE16_TO_CPU(r_iter->pdata.lkup_tx_rx.index); 4673 f_info->fltr_act = ICE_FWD_TO_VSI; 4674 /* Create an entry to track this MAC address */ 4675 fm_entry = (struct ice_fltr_mgmt_list_entry *) 4676 ice_malloc(hw, sizeof(*fm_entry)); 4677 if (!fm_entry) { 4678 status = ICE_ERR_NO_MEMORY; 4679 goto ice_add_mac_exit; 4680 } 4681 fm_entry->fltr_info = *f_info; 4682 fm_entry->vsi_count = 1; 4683 /* The book keeping entries will get removed when 4684 * base driver calls remove filter AQ command 4685 */ 4686 4687 LIST_ADD(&fm_entry->list_entry, rule_head); 4688 r_iter = (struct ice_aqc_sw_rules_elem *) 4689 ((u8 *)r_iter + s_rule_size); 4690 } 4691 } 4692 4693 ice_add_mac_exit: 4694 ice_release_lock(rule_lock); 4695 if (s_rule) 4696 ice_free(hw, s_rule); 4697 return status; 4698 } 4699 4700 /** 4701 * ice_add_mac - Add a MAC address based filter rule 4702 * @hw: pointer to the hardware structure 4703 * @m_list: list of MAC addresses and forwarding information 4704 * 4705 * Function add MAC rule for logical port from HW struct 4706 */ 4707 enum ice_status ice_add_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list) 4708 { 4709 if (!m_list || !hw) 4710 return ICE_ERR_PARAM; 4711 4712 return ice_add_mac_rule(hw, m_list, hw->switch_info, 4713 hw->port_info->lport); 4714 } 4715 4716 /** 4717 * ice_add_vlan_internal - Add one VLAN based filter rule 4718 * @hw: pointer to the hardware structure 4719 * @recp_list: recipe list for which rule has to be added 4720 * @f_entry: filter entry containing one VLAN information 4721 */ 4722 static enum ice_status 4723 ice_add_vlan_internal(struct ice_hw *hw, struct ice_sw_recipe *recp_list, 4724 struct ice_fltr_list_entry *f_entry) 4725 { 4726 struct ice_fltr_mgmt_list_entry *v_list_itr; 4727 struct ice_fltr_info *new_fltr, *cur_fltr; 4728 enum ice_sw_lkup_type lkup_type; 4729 u16 vsi_list_id = 0, vsi_handle; 4730 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 4731 enum ice_status status = ICE_SUCCESS; 4732 4733 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 4734 return ICE_ERR_PARAM; 4735 4736 f_entry->fltr_info.fwd_id.hw_vsi_id = 4737 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 4738 new_fltr = &f_entry->fltr_info; 4739 4740 /* VLAN ID should only be 12 bits */ 4741 if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID) 4742 return ICE_ERR_PARAM; 4743 4744 if (new_fltr->src_id != ICE_SRC_ID_VSI) 4745 return ICE_ERR_PARAM; 4746 4747 new_fltr->src = new_fltr->fwd_id.hw_vsi_id; 4748 lkup_type = new_fltr->lkup_type; 4749 vsi_handle = new_fltr->vsi_handle; 4750 rule_lock = &recp_list->filt_rule_lock; 4751 ice_acquire_lock(rule_lock); 4752 v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, new_fltr); 4753 if (!v_list_itr) { 4754 struct ice_vsi_list_map_info *map_info = NULL; 4755 4756 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) { 4757 /* All VLAN pruning rules use a VSI list. Check if 4758 * there is already a VSI list containing VSI that we 4759 * want to add. If found, use the same vsi_list_id for 4760 * this new VLAN rule or else create a new list. 4761 */ 4762 map_info = ice_find_vsi_list_entry(recp_list, 4763 vsi_handle, 4764 &vsi_list_id); 4765 if (!map_info) { 4766 status = ice_create_vsi_list_rule(hw, 4767 &vsi_handle, 4768 1, 4769 &vsi_list_id, 4770 lkup_type); 4771 if (status) 4772 goto exit; 4773 } 4774 /* Convert the action to forwarding to a VSI list. */ 4775 new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 4776 new_fltr->fwd_id.vsi_list_id = vsi_list_id; 4777 } 4778 4779 status = ice_create_pkt_fwd_rule(hw, recp_list, f_entry); 4780 if (!status) { 4781 v_list_itr = ice_find_rule_entry(&recp_list->filt_rules, 4782 new_fltr); 4783 if (!v_list_itr) { 4784 status = ICE_ERR_DOES_NOT_EXIST; 4785 goto exit; 4786 } 4787 /* reuse VSI list for new rule and increment ref_cnt */ 4788 if (map_info) { 4789 v_list_itr->vsi_list_info = map_info; 4790 map_info->ref_cnt++; 4791 } else { 4792 v_list_itr->vsi_list_info = 4793 ice_create_vsi_list_map(hw, &vsi_handle, 4794 1, vsi_list_id); 4795 } 4796 } 4797 } else if (v_list_itr->vsi_list_info->ref_cnt == 1) { 4798 /* Update existing VSI list to add new VSI ID only if it used 4799 * by one VLAN rule. 4800 */ 4801 cur_fltr = &v_list_itr->fltr_info; 4802 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, 4803 new_fltr); 4804 } else { 4805 /* If VLAN rule exists and VSI list being used by this rule is 4806 * referenced by more than 1 VLAN rule. Then create a new VSI 4807 * list appending previous VSI with new VSI and update existing 4808 * VLAN rule to point to new VSI list ID 4809 */ 4810 struct ice_fltr_info tmp_fltr; 4811 u16 vsi_handle_arr[2]; 4812 u16 cur_handle; 4813 4814 /* Current implementation only supports reusing VSI list with 4815 * one VSI count. We should never hit below condition 4816 */ 4817 if (v_list_itr->vsi_count > 1 && 4818 v_list_itr->vsi_list_info->ref_cnt > 1) { 4819 ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n"); 4820 status = ICE_ERR_CFG; 4821 goto exit; 4822 } 4823 4824 cur_handle = 4825 ice_find_first_bit(v_list_itr->vsi_list_info->vsi_map, 4826 ICE_MAX_VSI); 4827 4828 /* A rule already exists with the new VSI being added */ 4829 if (cur_handle == vsi_handle) { 4830 status = ICE_ERR_ALREADY_EXISTS; 4831 goto exit; 4832 } 4833 4834 vsi_handle_arr[0] = cur_handle; 4835 vsi_handle_arr[1] = vsi_handle; 4836 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 4837 &vsi_list_id, lkup_type); 4838 if (status) 4839 goto exit; 4840 4841 tmp_fltr = v_list_itr->fltr_info; 4842 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id; 4843 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 4844 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 4845 /* Update the previous switch rule to a new VSI list which 4846 * includes current VSI that is requested 4847 */ 4848 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 4849 if (status) 4850 goto exit; 4851 4852 /* before overriding VSI list map info. decrement ref_cnt of 4853 * previous VSI list 4854 */ 4855 v_list_itr->vsi_list_info->ref_cnt--; 4856 4857 /* now update to newly created list */ 4858 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id; 4859 v_list_itr->vsi_list_info = 4860 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 4861 vsi_list_id); 4862 v_list_itr->vsi_count++; 4863 } 4864 4865 exit: 4866 ice_release_lock(rule_lock); 4867 return status; 4868 } 4869 4870 /** 4871 * ice_add_vlan_rule - Add VLAN based filter rule 4872 * @hw: pointer to the hardware structure 4873 * @v_list: list of VLAN entries and forwarding information 4874 * @sw: pointer to switch info struct for which function add rule 4875 */ 4876 static enum ice_status 4877 ice_add_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list, 4878 struct ice_switch_info *sw) 4879 { 4880 struct ice_fltr_list_entry *v_list_itr; 4881 struct ice_sw_recipe *recp_list; 4882 4883 recp_list = &sw->recp_list[ICE_SW_LKUP_VLAN]; 4884 LIST_FOR_EACH_ENTRY(v_list_itr, v_list, ice_fltr_list_entry, 4885 list_entry) { 4886 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN) 4887 return ICE_ERR_PARAM; 4888 v_list_itr->fltr_info.flag = ICE_FLTR_TX; 4889 v_list_itr->status = ice_add_vlan_internal(hw, recp_list, 4890 v_list_itr); 4891 if (v_list_itr->status) 4892 return v_list_itr->status; 4893 } 4894 return ICE_SUCCESS; 4895 } 4896 4897 /** 4898 * ice_add_vlan - Add a VLAN based filter rule 4899 * @hw: pointer to the hardware structure 4900 * @v_list: list of VLAN and forwarding information 4901 * 4902 * Function add VLAN rule for logical port from HW struct 4903 */ 4904 enum ice_status ice_add_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list) 4905 { 4906 if (!v_list || !hw) 4907 return ICE_ERR_PARAM; 4908 4909 return ice_add_vlan_rule(hw, v_list, hw->switch_info); 4910 } 4911 4912 /** 4913 * ice_add_mac_vlan - Add MAC and VLAN pair based filter rule 4914 * @hw: pointer to the hardware structure 4915 * @mv_list: list of MAC and VLAN filters 4916 * @sw: pointer to switch info struct for which function add rule 4917 * @lport: logic port number on which function add rule 4918 * 4919 * If the VSI on which the MAC-VLAN pair has to be added has Rx and Tx VLAN 4920 * pruning bits enabled, then it is the responsibility of the caller to make 4921 * sure to add a VLAN only filter on the same VSI. Packets belonging to that 4922 * VLAN won't be received on that VSI otherwise. 4923 */ 4924 static enum ice_status 4925 ice_add_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list, 4926 struct ice_switch_info *sw, u8 lport) 4927 { 4928 struct ice_fltr_list_entry *mv_list_itr; 4929 struct ice_sw_recipe *recp_list; 4930 4931 if (!mv_list || !hw) 4932 return ICE_ERR_PARAM; 4933 4934 recp_list = &sw->recp_list[ICE_SW_LKUP_MAC_VLAN]; 4935 LIST_FOR_EACH_ENTRY(mv_list_itr, mv_list, ice_fltr_list_entry, 4936 list_entry) { 4937 enum ice_sw_lkup_type l_type = 4938 mv_list_itr->fltr_info.lkup_type; 4939 4940 if (l_type != ICE_SW_LKUP_MAC_VLAN) 4941 return ICE_ERR_PARAM; 4942 mv_list_itr->fltr_info.flag = ICE_FLTR_TX; 4943 mv_list_itr->status = 4944 ice_add_rule_internal(hw, recp_list, lport, 4945 mv_list_itr); 4946 if (mv_list_itr->status) 4947 return mv_list_itr->status; 4948 } 4949 return ICE_SUCCESS; 4950 } 4951 4952 /** 4953 * ice_add_mac_vlan - Add a MAC VLAN address based filter rule 4954 * @hw: pointer to the hardware structure 4955 * @mv_list: list of MAC VLAN addresses and forwarding information 4956 * 4957 * Function add MAC VLAN rule for logical port from HW struct 4958 */ 4959 enum ice_status 4960 ice_add_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list) 4961 { 4962 if (!mv_list || !hw) 4963 return ICE_ERR_PARAM; 4964 4965 return ice_add_mac_vlan_rule(hw, mv_list, hw->switch_info, 4966 hw->port_info->lport); 4967 } 4968 4969 /** 4970 * ice_add_eth_mac_rule - Add ethertype and MAC based filter rule 4971 * @hw: pointer to the hardware structure 4972 * @em_list: list of ether type MAC filter, MAC is optional 4973 * @sw: pointer to switch info struct for which function add rule 4974 * @lport: logic port number on which function add rule 4975 * 4976 * This function requires the caller to populate the entries in 4977 * the filter list with the necessary fields (including flags to 4978 * indicate Tx or Rx rules). 4979 */ 4980 static enum ice_status 4981 ice_add_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list, 4982 struct ice_switch_info *sw, u8 lport) 4983 { 4984 struct ice_fltr_list_entry *em_list_itr; 4985 4986 LIST_FOR_EACH_ENTRY(em_list_itr, em_list, ice_fltr_list_entry, 4987 list_entry) { 4988 struct ice_sw_recipe *recp_list; 4989 enum ice_sw_lkup_type l_type; 4990 4991 l_type = em_list_itr->fltr_info.lkup_type; 4992 recp_list = &sw->recp_list[l_type]; 4993 4994 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 4995 l_type != ICE_SW_LKUP_ETHERTYPE) 4996 return ICE_ERR_PARAM; 4997 4998 em_list_itr->status = ice_add_rule_internal(hw, recp_list, 4999 lport, 5000 em_list_itr); 5001 if (em_list_itr->status) 5002 return em_list_itr->status; 5003 } 5004 return ICE_SUCCESS; 5005 } 5006 5007 /** 5008 * ice_add_eth_mac - Add a ethertype based filter rule 5009 * @hw: pointer to the hardware structure 5010 * @em_list: list of ethertype and forwarding information 5011 * 5012 * Function add ethertype rule for logical port from HW struct 5013 */ 5014 enum ice_status 5015 ice_add_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list) 5016 { 5017 if (!em_list || !hw) 5018 return ICE_ERR_PARAM; 5019 5020 return ice_add_eth_mac_rule(hw, em_list, hw->switch_info, 5021 hw->port_info->lport); 5022 } 5023 5024 /** 5025 * ice_remove_eth_mac_rule - Remove an ethertype (or MAC) based filter rule 5026 * @hw: pointer to the hardware structure 5027 * @em_list: list of ethertype or ethertype MAC entries 5028 * @sw: pointer to switch info struct for which function add rule 5029 */ 5030 static enum ice_status 5031 ice_remove_eth_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list, 5032 struct ice_switch_info *sw) 5033 { 5034 struct ice_fltr_list_entry *em_list_itr, *tmp; 5035 5036 LIST_FOR_EACH_ENTRY_SAFE(em_list_itr, tmp, em_list, ice_fltr_list_entry, 5037 list_entry) { 5038 struct ice_sw_recipe *recp_list; 5039 enum ice_sw_lkup_type l_type; 5040 5041 l_type = em_list_itr->fltr_info.lkup_type; 5042 5043 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 5044 l_type != ICE_SW_LKUP_ETHERTYPE) 5045 return ICE_ERR_PARAM; 5046 5047 recp_list = &sw->recp_list[l_type]; 5048 em_list_itr->status = ice_remove_rule_internal(hw, recp_list, 5049 em_list_itr); 5050 if (em_list_itr->status) 5051 return em_list_itr->status; 5052 } 5053 return ICE_SUCCESS; 5054 } 5055 5056 /** 5057 * ice_remove_eth_mac - remove a ethertype based filter rule 5058 * @hw: pointer to the hardware structure 5059 * @em_list: list of ethertype and forwarding information 5060 * 5061 */ 5062 enum ice_status 5063 ice_remove_eth_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *em_list) 5064 { 5065 if (!em_list || !hw) 5066 return ICE_ERR_PARAM; 5067 5068 return ice_remove_eth_mac_rule(hw, em_list, hw->switch_info); 5069 } 5070 5071 /** 5072 * ice_rem_sw_rule_info 5073 * @hw: pointer to the hardware structure 5074 * @rule_head: pointer to the switch list structure that we want to delete 5075 */ 5076 static void 5077 ice_rem_sw_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head) 5078 { 5079 if (!LIST_EMPTY(rule_head)) { 5080 struct ice_fltr_mgmt_list_entry *entry; 5081 struct ice_fltr_mgmt_list_entry *tmp; 5082 5083 LIST_FOR_EACH_ENTRY_SAFE(entry, tmp, rule_head, 5084 ice_fltr_mgmt_list_entry, list_entry) { 5085 LIST_DEL(&entry->list_entry); 5086 ice_free(hw, entry); 5087 } 5088 } 5089 } 5090 5091 /** 5092 * ice_rem_adv_rule_info 5093 * @hw: pointer to the hardware structure 5094 * @rule_head: pointer to the switch list structure that we want to delete 5095 */ 5096 static void 5097 ice_rem_adv_rule_info(struct ice_hw *hw, struct LIST_HEAD_TYPE *rule_head) 5098 { 5099 struct ice_adv_fltr_mgmt_list_entry *tmp_entry; 5100 struct ice_adv_fltr_mgmt_list_entry *lst_itr; 5101 5102 if (LIST_EMPTY(rule_head)) 5103 return; 5104 5105 LIST_FOR_EACH_ENTRY_SAFE(lst_itr, tmp_entry, rule_head, 5106 ice_adv_fltr_mgmt_list_entry, list_entry) { 5107 LIST_DEL(&lst_itr->list_entry); 5108 ice_free(hw, lst_itr->lkups); 5109 ice_free(hw, lst_itr); 5110 } 5111 } 5112 5113 /** 5114 * ice_rem_all_sw_rules_info 5115 * @hw: pointer to the hardware structure 5116 */ 5117 void ice_rem_all_sw_rules_info(struct ice_hw *hw) 5118 { 5119 struct ice_switch_info *sw = hw->switch_info; 5120 u8 i; 5121 5122 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 5123 struct LIST_HEAD_TYPE *rule_head; 5124 5125 rule_head = &sw->recp_list[i].filt_rules; 5126 if (!sw->recp_list[i].adv_rule) 5127 ice_rem_sw_rule_info(hw, rule_head); 5128 else 5129 ice_rem_adv_rule_info(hw, rule_head); 5130 if (sw->recp_list[i].adv_rule && 5131 LIST_EMPTY(&sw->recp_list[i].filt_rules)) 5132 sw->recp_list[i].adv_rule = false; 5133 } 5134 } 5135 5136 /** 5137 * ice_cfg_dflt_vsi - change state of VSI to set/clear default 5138 * @pi: pointer to the port_info structure 5139 * @vsi_handle: VSI handle to set as default 5140 * @set: true to add the above mentioned switch rule, false to remove it 5141 * @direction: ICE_FLTR_RX or ICE_FLTR_TX 5142 * 5143 * add filter rule to set/unset given VSI as default VSI for the switch 5144 * (represented by swid) 5145 */ 5146 enum ice_status 5147 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set, 5148 u8 direction) 5149 { 5150 struct ice_aqc_sw_rules_elem *s_rule; 5151 struct ice_fltr_info f_info; 5152 struct ice_hw *hw = pi->hw; 5153 enum ice_adminq_opc opcode; 5154 enum ice_status status; 5155 u16 s_rule_size; 5156 u16 hw_vsi_id; 5157 5158 if (!ice_is_vsi_valid(hw, vsi_handle)) 5159 return ICE_ERR_PARAM; 5160 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 5161 5162 s_rule_size = set ? ICE_SW_RULE_RX_TX_ETH_HDR_SIZE : 5163 ICE_SW_RULE_RX_TX_NO_HDR_SIZE; 5164 5165 s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, s_rule_size); 5166 if (!s_rule) 5167 return ICE_ERR_NO_MEMORY; 5168 5169 ice_memset(&f_info, 0, sizeof(f_info), ICE_NONDMA_MEM); 5170 5171 f_info.lkup_type = ICE_SW_LKUP_DFLT; 5172 f_info.flag = direction; 5173 f_info.fltr_act = ICE_FWD_TO_VSI; 5174 f_info.fwd_id.hw_vsi_id = hw_vsi_id; 5175 5176 if (f_info.flag & ICE_FLTR_RX) { 5177 f_info.src = pi->lport; 5178 f_info.src_id = ICE_SRC_ID_LPORT; 5179 if (!set) 5180 f_info.fltr_rule_id = 5181 pi->dflt_rx_vsi_rule_id; 5182 } else if (f_info.flag & ICE_FLTR_TX) { 5183 f_info.src_id = ICE_SRC_ID_VSI; 5184 f_info.src = hw_vsi_id; 5185 if (!set) 5186 f_info.fltr_rule_id = 5187 pi->dflt_tx_vsi_rule_id; 5188 } 5189 5190 if (set) 5191 opcode = ice_aqc_opc_add_sw_rules; 5192 else 5193 opcode = ice_aqc_opc_remove_sw_rules; 5194 5195 ice_fill_sw_rule(hw, &f_info, s_rule, opcode); 5196 5197 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opcode, NULL); 5198 if (status || !(f_info.flag & ICE_FLTR_TX_RX)) 5199 goto out; 5200 if (set) { 5201 u16 index = LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index); 5202 5203 if (f_info.flag & ICE_FLTR_TX) { 5204 pi->dflt_tx_vsi_num = hw_vsi_id; 5205 pi->dflt_tx_vsi_rule_id = index; 5206 } else if (f_info.flag & ICE_FLTR_RX) { 5207 pi->dflt_rx_vsi_num = hw_vsi_id; 5208 pi->dflt_rx_vsi_rule_id = index; 5209 } 5210 } else { 5211 if (f_info.flag & ICE_FLTR_TX) { 5212 pi->dflt_tx_vsi_num = ICE_DFLT_VSI_INVAL; 5213 pi->dflt_tx_vsi_rule_id = ICE_INVAL_ACT; 5214 } else if (f_info.flag & ICE_FLTR_RX) { 5215 pi->dflt_rx_vsi_num = ICE_DFLT_VSI_INVAL; 5216 pi->dflt_rx_vsi_rule_id = ICE_INVAL_ACT; 5217 } 5218 } 5219 5220 out: 5221 ice_free(hw, s_rule); 5222 return status; 5223 } 5224 5225 /** 5226 * ice_find_ucast_rule_entry - Search for a unicast MAC filter rule entry 5227 * @list_head: head of rule list 5228 * @f_info: rule information 5229 * 5230 * Helper function to search for a unicast rule entry - this is to be used 5231 * to remove unicast MAC filter that is not shared with other VSIs on the 5232 * PF switch. 5233 * 5234 * Returns pointer to entry storing the rule if found 5235 */ 5236 static struct ice_fltr_mgmt_list_entry * 5237 ice_find_ucast_rule_entry(struct LIST_HEAD_TYPE *list_head, 5238 struct ice_fltr_info *f_info) 5239 { 5240 struct ice_fltr_mgmt_list_entry *list_itr; 5241 5242 LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_fltr_mgmt_list_entry, 5243 list_entry) { 5244 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, 5245 sizeof(f_info->l_data)) && 5246 f_info->fwd_id.hw_vsi_id == 5247 list_itr->fltr_info.fwd_id.hw_vsi_id && 5248 f_info->flag == list_itr->fltr_info.flag) 5249 return list_itr; 5250 } 5251 return NULL; 5252 } 5253 5254 /** 5255 * ice_remove_mac_rule - remove a MAC based filter rule 5256 * @hw: pointer to the hardware structure 5257 * @m_list: list of MAC addresses and forwarding information 5258 * @recp_list: list from which function remove MAC address 5259 * 5260 * This function removes either a MAC filter rule or a specific VSI from a 5261 * VSI list for a multicast MAC address. 5262 * 5263 * Returns ICE_ERR_DOES_NOT_EXIST if a given entry was not added by 5264 * ice_add_mac. Caller should be aware that this call will only work if all 5265 * the entries passed into m_list were added previously. It will not attempt to 5266 * do a partial remove of entries that were found. 5267 */ 5268 static enum ice_status 5269 ice_remove_mac_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list, 5270 struct ice_sw_recipe *recp_list) 5271 { 5272 struct ice_fltr_list_entry *list_itr, *tmp; 5273 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 5274 5275 if (!m_list) 5276 return ICE_ERR_PARAM; 5277 5278 rule_lock = &recp_list->filt_rule_lock; 5279 LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, m_list, ice_fltr_list_entry, 5280 list_entry) { 5281 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; 5282 u8 *add = &list_itr->fltr_info.l_data.mac.mac_addr[0]; 5283 u16 vsi_handle; 5284 5285 if (l_type != ICE_SW_LKUP_MAC) 5286 return ICE_ERR_PARAM; 5287 5288 vsi_handle = list_itr->fltr_info.vsi_handle; 5289 if (!ice_is_vsi_valid(hw, vsi_handle)) 5290 return ICE_ERR_PARAM; 5291 5292 list_itr->fltr_info.fwd_id.hw_vsi_id = 5293 ice_get_hw_vsi_num(hw, vsi_handle); 5294 if (IS_UNICAST_ETHER_ADDR(add) && !hw->ucast_shared) { 5295 /* Don't remove the unicast address that belongs to 5296 * another VSI on the switch, since it is not being 5297 * shared... 5298 */ 5299 ice_acquire_lock(rule_lock); 5300 if (!ice_find_ucast_rule_entry(&recp_list->filt_rules, 5301 &list_itr->fltr_info)) { 5302 ice_release_lock(rule_lock); 5303 return ICE_ERR_DOES_NOT_EXIST; 5304 } 5305 ice_release_lock(rule_lock); 5306 } 5307 list_itr->status = ice_remove_rule_internal(hw, recp_list, 5308 list_itr); 5309 if (list_itr->status) 5310 return list_itr->status; 5311 } 5312 return ICE_SUCCESS; 5313 } 5314 5315 /** 5316 * ice_remove_mac - remove a MAC address based filter rule 5317 * @hw: pointer to the hardware structure 5318 * @m_list: list of MAC addresses and forwarding information 5319 * 5320 */ 5321 enum ice_status ice_remove_mac(struct ice_hw *hw, struct LIST_HEAD_TYPE *m_list) 5322 { 5323 struct ice_sw_recipe *recp_list; 5324 5325 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC]; 5326 return ice_remove_mac_rule(hw, m_list, recp_list); 5327 } 5328 5329 /** 5330 * ice_remove_vlan_rule - Remove VLAN based filter rule 5331 * @hw: pointer to the hardware structure 5332 * @v_list: list of VLAN entries and forwarding information 5333 * @recp_list: list from which function remove VLAN 5334 */ 5335 static enum ice_status 5336 ice_remove_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list, 5337 struct ice_sw_recipe *recp_list) 5338 { 5339 struct ice_fltr_list_entry *v_list_itr, *tmp; 5340 5341 LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry, 5342 list_entry) { 5343 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type; 5344 5345 if (l_type != ICE_SW_LKUP_VLAN) 5346 return ICE_ERR_PARAM; 5347 v_list_itr->status = ice_remove_rule_internal(hw, recp_list, 5348 v_list_itr); 5349 if (v_list_itr->status) 5350 return v_list_itr->status; 5351 } 5352 return ICE_SUCCESS; 5353 } 5354 5355 /** 5356 * ice_remove_vlan - remove a VLAN address based filter rule 5357 * @hw: pointer to the hardware structure 5358 * @v_list: list of VLAN and forwarding information 5359 * 5360 */ 5361 enum ice_status 5362 ice_remove_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list) 5363 { 5364 struct ice_sw_recipe *recp_list; 5365 5366 if (!v_list || !hw) 5367 return ICE_ERR_PARAM; 5368 5369 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_VLAN]; 5370 return ice_remove_vlan_rule(hw, v_list, recp_list); 5371 } 5372 5373 /** 5374 * ice_remove_mac_vlan_rule - Remove MAC VLAN based filter rule 5375 * @hw: pointer to the hardware structure 5376 * @v_list: list of MAC VLAN entries and forwarding information 5377 * @recp_list: list from which function remove MAC VLAN 5378 */ 5379 static enum ice_status 5380 ice_remove_mac_vlan_rule(struct ice_hw *hw, struct LIST_HEAD_TYPE *v_list, 5381 struct ice_sw_recipe *recp_list) 5382 { 5383 struct ice_fltr_list_entry *v_list_itr, *tmp; 5384 5385 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN]; 5386 LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry, 5387 list_entry) { 5388 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type; 5389 5390 if (l_type != ICE_SW_LKUP_MAC_VLAN) 5391 return ICE_ERR_PARAM; 5392 v_list_itr->status = 5393 ice_remove_rule_internal(hw, recp_list, 5394 v_list_itr); 5395 if (v_list_itr->status) 5396 return v_list_itr->status; 5397 } 5398 return ICE_SUCCESS; 5399 } 5400 5401 /** 5402 * ice_remove_mac_vlan - remove a MAC VLAN address based filter rule 5403 * @hw: pointer to the hardware structure 5404 * @mv_list: list of MAC VLAN and forwarding information 5405 */ 5406 enum ice_status 5407 ice_remove_mac_vlan(struct ice_hw *hw, struct LIST_HEAD_TYPE *mv_list) 5408 { 5409 struct ice_sw_recipe *recp_list; 5410 5411 if (!mv_list || !hw) 5412 return ICE_ERR_PARAM; 5413 5414 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC_VLAN]; 5415 return ice_remove_mac_vlan_rule(hw, mv_list, recp_list); 5416 } 5417 5418 /** 5419 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter 5420 * @fm_entry: filter entry to inspect 5421 * @vsi_handle: VSI handle to compare with filter info 5422 */ 5423 static bool 5424 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle) 5425 { 5426 return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && 5427 fm_entry->fltr_info.vsi_handle == vsi_handle) || 5428 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && 5429 fm_entry->vsi_list_info && 5430 (ice_is_bit_set(fm_entry->vsi_list_info->vsi_map, 5431 vsi_handle)))); 5432 } 5433 5434 /** 5435 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list 5436 * @hw: pointer to the hardware structure 5437 * @vsi_handle: VSI handle to remove filters from 5438 * @vsi_list_head: pointer to the list to add entry to 5439 * @fi: pointer to fltr_info of filter entry to copy & add 5440 * 5441 * Helper function, used when creating a list of filters to remove from 5442 * a specific VSI. The entry added to vsi_list_head is a COPY of the 5443 * original filter entry, with the exception of fltr_info.fltr_act and 5444 * fltr_info.fwd_id fields. These are set such that later logic can 5445 * extract which VSI to remove the fltr from, and pass on that information. 5446 */ 5447 static enum ice_status 5448 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 5449 struct LIST_HEAD_TYPE *vsi_list_head, 5450 struct ice_fltr_info *fi) 5451 { 5452 struct ice_fltr_list_entry *tmp; 5453 5454 /* this memory is freed up in the caller function 5455 * once filters for this VSI are removed 5456 */ 5457 tmp = (struct ice_fltr_list_entry *)ice_malloc(hw, sizeof(*tmp)); 5458 if (!tmp) 5459 return ICE_ERR_NO_MEMORY; 5460 5461 tmp->fltr_info = *fi; 5462 5463 /* Overwrite these fields to indicate which VSI to remove filter from, 5464 * so find and remove logic can extract the information from the 5465 * list entries. Note that original entries will still have proper 5466 * values. 5467 */ 5468 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 5469 tmp->fltr_info.vsi_handle = vsi_handle; 5470 tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 5471 5472 LIST_ADD(&tmp->list_entry, vsi_list_head); 5473 5474 return ICE_SUCCESS; 5475 } 5476 5477 /** 5478 * ice_add_to_vsi_fltr_list - Add VSI filters to the list 5479 * @hw: pointer to the hardware structure 5480 * @vsi_handle: VSI handle to remove filters from 5481 * @lkup_list_head: pointer to the list that has certain lookup type filters 5482 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle 5483 * 5484 * Locates all filters in lkup_list_head that are used by the given VSI, 5485 * and adds COPIES of those entries to vsi_list_head (intended to be used 5486 * to remove the listed filters). 5487 * Note that this means all entries in vsi_list_head must be explicitly 5488 * deallocated by the caller when done with list. 5489 */ 5490 static enum ice_status 5491 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 5492 struct LIST_HEAD_TYPE *lkup_list_head, 5493 struct LIST_HEAD_TYPE *vsi_list_head) 5494 { 5495 struct ice_fltr_mgmt_list_entry *fm_entry; 5496 enum ice_status status = ICE_SUCCESS; 5497 5498 /* check to make sure VSI ID is valid and within boundary */ 5499 if (!ice_is_vsi_valid(hw, vsi_handle)) 5500 return ICE_ERR_PARAM; 5501 5502 LIST_FOR_EACH_ENTRY(fm_entry, lkup_list_head, 5503 ice_fltr_mgmt_list_entry, list_entry) { 5504 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle)) 5505 continue; 5506 5507 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 5508 vsi_list_head, 5509 &fm_entry->fltr_info); 5510 if (status) 5511 return status; 5512 } 5513 return status; 5514 } 5515 5516 /** 5517 * ice_determine_promisc_mask 5518 * @fi: filter info to parse 5519 * 5520 * Helper function to determine which ICE_PROMISC_ mask corresponds 5521 * to given filter into. 5522 */ 5523 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi) 5524 { 5525 u16 vid = fi->l_data.mac_vlan.vlan_id; 5526 u8 *macaddr = fi->l_data.mac.mac_addr; 5527 bool is_tx_fltr = false; 5528 u8 promisc_mask = 0; 5529 5530 if (fi->flag == ICE_FLTR_TX) 5531 is_tx_fltr = true; 5532 5533 if (IS_BROADCAST_ETHER_ADDR(macaddr)) 5534 promisc_mask |= is_tx_fltr ? 5535 ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX; 5536 else if (IS_MULTICAST_ETHER_ADDR(macaddr)) 5537 promisc_mask |= is_tx_fltr ? 5538 ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX; 5539 else if (IS_UNICAST_ETHER_ADDR(macaddr)) 5540 promisc_mask |= is_tx_fltr ? 5541 ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX; 5542 if (vid) 5543 promisc_mask |= is_tx_fltr ? 5544 ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX; 5545 5546 return promisc_mask; 5547 } 5548 5549 /** 5550 * _ice_get_vsi_promisc - get promiscuous mode of given VSI 5551 * @hw: pointer to the hardware structure 5552 * @vsi_handle: VSI handle to retrieve info from 5553 * @promisc_mask: pointer to mask to be filled in 5554 * @vid: VLAN ID of promisc VLAN VSI 5555 * @sw: pointer to switch info struct for which function add rule 5556 */ 5557 static enum ice_status 5558 _ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask, 5559 u16 *vid, struct ice_switch_info *sw) 5560 { 5561 struct ice_fltr_mgmt_list_entry *itr; 5562 struct LIST_HEAD_TYPE *rule_head; 5563 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 5564 5565 if (!ice_is_vsi_valid(hw, vsi_handle)) 5566 return ICE_ERR_PARAM; 5567 5568 *vid = 0; 5569 *promisc_mask = 0; 5570 rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rules; 5571 rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC].filt_rule_lock; 5572 5573 ice_acquire_lock(rule_lock); 5574 LIST_FOR_EACH_ENTRY(itr, rule_head, 5575 ice_fltr_mgmt_list_entry, list_entry) { 5576 /* Continue if this filter doesn't apply to this VSI or the 5577 * VSI ID is not in the VSI map for this filter 5578 */ 5579 if (!ice_vsi_uses_fltr(itr, vsi_handle)) 5580 continue; 5581 5582 *promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info); 5583 } 5584 ice_release_lock(rule_lock); 5585 5586 return ICE_SUCCESS; 5587 } 5588 5589 /** 5590 * ice_get_vsi_promisc - get promiscuous mode of given VSI 5591 * @hw: pointer to the hardware structure 5592 * @vsi_handle: VSI handle to retrieve info from 5593 * @promisc_mask: pointer to mask to be filled in 5594 * @vid: VLAN ID of promisc VLAN VSI 5595 */ 5596 enum ice_status 5597 ice_get_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask, 5598 u16 *vid) 5599 { 5600 return _ice_get_vsi_promisc(hw, vsi_handle, promisc_mask, 5601 vid, hw->switch_info); 5602 } 5603 5604 /** 5605 * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI 5606 * @hw: pointer to the hardware structure 5607 * @vsi_handle: VSI handle to retrieve info from 5608 * @promisc_mask: pointer to mask to be filled in 5609 * @vid: VLAN ID of promisc VLAN VSI 5610 * @sw: pointer to switch info struct for which function add rule 5611 */ 5612 static enum ice_status 5613 _ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask, 5614 u16 *vid, struct ice_switch_info *sw) 5615 { 5616 struct ice_fltr_mgmt_list_entry *itr; 5617 struct LIST_HEAD_TYPE *rule_head; 5618 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 5619 5620 if (!ice_is_vsi_valid(hw, vsi_handle)) 5621 return ICE_ERR_PARAM; 5622 5623 *vid = 0; 5624 *promisc_mask = 0; 5625 rule_head = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rules; 5626 rule_lock = &sw->recp_list[ICE_SW_LKUP_PROMISC_VLAN].filt_rule_lock; 5627 5628 ice_acquire_lock(rule_lock); 5629 LIST_FOR_EACH_ENTRY(itr, rule_head, ice_fltr_mgmt_list_entry, 5630 list_entry) { 5631 /* Continue if this filter doesn't apply to this VSI or the 5632 * VSI ID is not in the VSI map for this filter 5633 */ 5634 if (!ice_vsi_uses_fltr(itr, vsi_handle)) 5635 continue; 5636 5637 *promisc_mask |= ice_determine_promisc_mask(&itr->fltr_info); 5638 } 5639 ice_release_lock(rule_lock); 5640 5641 return ICE_SUCCESS; 5642 } 5643 5644 /** 5645 * ice_get_vsi_vlan_promisc - get VLAN promiscuous mode of given VSI 5646 * @hw: pointer to the hardware structure 5647 * @vsi_handle: VSI handle to retrieve info from 5648 * @promisc_mask: pointer to mask to be filled in 5649 * @vid: VLAN ID of promisc VLAN VSI 5650 */ 5651 enum ice_status 5652 ice_get_vsi_vlan_promisc(struct ice_hw *hw, u16 vsi_handle, u8 *promisc_mask, 5653 u16 *vid) 5654 { 5655 return _ice_get_vsi_vlan_promisc(hw, vsi_handle, promisc_mask, 5656 vid, hw->switch_info); 5657 } 5658 5659 /** 5660 * ice_remove_promisc - Remove promisc based filter rules 5661 * @hw: pointer to the hardware structure 5662 * @recp_id: recipe ID for which the rule needs to removed 5663 * @v_list: list of promisc entries 5664 */ 5665 static enum ice_status 5666 ice_remove_promisc(struct ice_hw *hw, u8 recp_id, 5667 struct LIST_HEAD_TYPE *v_list) 5668 { 5669 struct ice_fltr_list_entry *v_list_itr, *tmp; 5670 struct ice_sw_recipe *recp_list; 5671 5672 recp_list = &hw->switch_info->recp_list[recp_id]; 5673 LIST_FOR_EACH_ENTRY_SAFE(v_list_itr, tmp, v_list, ice_fltr_list_entry, 5674 list_entry) { 5675 v_list_itr->status = 5676 ice_remove_rule_internal(hw, recp_list, v_list_itr); 5677 if (v_list_itr->status) 5678 return v_list_itr->status; 5679 } 5680 return ICE_SUCCESS; 5681 } 5682 5683 /** 5684 * _ice_clear_vsi_promisc - clear specified promiscuous mode(s) 5685 * @hw: pointer to the hardware structure 5686 * @vsi_handle: VSI handle to clear mode 5687 * @promisc_mask: mask of promiscuous config bits to clear 5688 * @vid: VLAN ID to clear VLAN promiscuous 5689 * @sw: pointer to switch info struct for which function add rule 5690 */ 5691 static enum ice_status 5692 _ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 5693 u16 vid, struct ice_switch_info *sw) 5694 { 5695 struct ice_fltr_list_entry *fm_entry, *tmp; 5696 struct LIST_HEAD_TYPE remove_list_head; 5697 struct ice_fltr_mgmt_list_entry *itr; 5698 struct LIST_HEAD_TYPE *rule_head; 5699 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 5700 enum ice_status status = ICE_SUCCESS; 5701 u8 recipe_id; 5702 5703 if (!ice_is_vsi_valid(hw, vsi_handle)) 5704 return ICE_ERR_PARAM; 5705 5706 if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) 5707 recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 5708 else 5709 recipe_id = ICE_SW_LKUP_PROMISC; 5710 5711 rule_head = &sw->recp_list[recipe_id].filt_rules; 5712 rule_lock = &sw->recp_list[recipe_id].filt_rule_lock; 5713 5714 INIT_LIST_HEAD(&remove_list_head); 5715 5716 ice_acquire_lock(rule_lock); 5717 LIST_FOR_EACH_ENTRY(itr, rule_head, 5718 ice_fltr_mgmt_list_entry, list_entry) { 5719 struct ice_fltr_info *fltr_info; 5720 u8 fltr_promisc_mask = 0; 5721 5722 if (!ice_vsi_uses_fltr(itr, vsi_handle)) 5723 continue; 5724 fltr_info = &itr->fltr_info; 5725 5726 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN && 5727 vid != fltr_info->l_data.mac_vlan.vlan_id) 5728 continue; 5729 5730 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info); 5731 5732 /* Skip if filter is not completely specified by given mask */ 5733 if (fltr_promisc_mask & ~promisc_mask) 5734 continue; 5735 5736 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 5737 &remove_list_head, 5738 fltr_info); 5739 if (status) { 5740 ice_release_lock(rule_lock); 5741 goto free_fltr_list; 5742 } 5743 } 5744 ice_release_lock(rule_lock); 5745 5746 status = ice_remove_promisc(hw, recipe_id, &remove_list_head); 5747 5748 free_fltr_list: 5749 LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head, 5750 ice_fltr_list_entry, list_entry) { 5751 LIST_DEL(&fm_entry->list_entry); 5752 ice_free(hw, fm_entry); 5753 } 5754 5755 return status; 5756 } 5757 5758 /** 5759 * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI 5760 * @hw: pointer to the hardware structure 5761 * @vsi_handle: VSI handle to clear mode 5762 * @promisc_mask: mask of promiscuous config bits to clear 5763 * @vid: VLAN ID to clear VLAN promiscuous 5764 */ 5765 enum ice_status 5766 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, 5767 u8 promisc_mask, u16 vid) 5768 { 5769 return _ice_clear_vsi_promisc(hw, vsi_handle, promisc_mask, 5770 vid, hw->switch_info); 5771 } 5772 5773 /** 5774 * _ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) 5775 * @hw: pointer to the hardware structure 5776 * @vsi_handle: VSI handle to configure 5777 * @promisc_mask: mask of promiscuous config bits 5778 * @vid: VLAN ID to set VLAN promiscuous 5779 * @lport: logical port number to configure promisc mode 5780 * @sw: pointer to switch info struct for which function add rule 5781 */ 5782 static enum ice_status 5783 _ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 5784 u16 vid, u8 lport, struct ice_switch_info *sw) 5785 { 5786 enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR }; 5787 struct ice_fltr_list_entry f_list_entry; 5788 struct ice_fltr_info new_fltr; 5789 enum ice_status status = ICE_SUCCESS; 5790 bool is_tx_fltr; 5791 u16 hw_vsi_id; 5792 int pkt_type; 5793 u8 recipe_id; 5794 5795 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 5796 5797 if (!ice_is_vsi_valid(hw, vsi_handle)) 5798 return ICE_ERR_PARAM; 5799 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 5800 5801 ice_memset(&new_fltr, 0, sizeof(new_fltr), ICE_NONDMA_MEM); 5802 5803 if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) { 5804 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN; 5805 new_fltr.l_data.mac_vlan.vlan_id = vid; 5806 recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 5807 } else { 5808 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC; 5809 recipe_id = ICE_SW_LKUP_PROMISC; 5810 } 5811 5812 /* Separate filters must be set for each direction/packet type 5813 * combination, so we will loop over the mask value, store the 5814 * individual type, and clear it out in the input mask as it 5815 * is found. 5816 */ 5817 while (promisc_mask) { 5818 struct ice_sw_recipe *recp_list; 5819 u8 *mac_addr; 5820 5821 pkt_type = 0; 5822 is_tx_fltr = false; 5823 5824 if (promisc_mask & ICE_PROMISC_UCAST_RX) { 5825 promisc_mask &= ~ICE_PROMISC_UCAST_RX; 5826 pkt_type = UCAST_FLTR; 5827 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) { 5828 promisc_mask &= ~ICE_PROMISC_UCAST_TX; 5829 pkt_type = UCAST_FLTR; 5830 is_tx_fltr = true; 5831 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) { 5832 promisc_mask &= ~ICE_PROMISC_MCAST_RX; 5833 pkt_type = MCAST_FLTR; 5834 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) { 5835 promisc_mask &= ~ICE_PROMISC_MCAST_TX; 5836 pkt_type = MCAST_FLTR; 5837 is_tx_fltr = true; 5838 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) { 5839 promisc_mask &= ~ICE_PROMISC_BCAST_RX; 5840 pkt_type = BCAST_FLTR; 5841 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) { 5842 promisc_mask &= ~ICE_PROMISC_BCAST_TX; 5843 pkt_type = BCAST_FLTR; 5844 is_tx_fltr = true; 5845 } 5846 5847 /* Check for VLAN promiscuous flag */ 5848 if (promisc_mask & ICE_PROMISC_VLAN_RX) { 5849 promisc_mask &= ~ICE_PROMISC_VLAN_RX; 5850 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) { 5851 promisc_mask &= ~ICE_PROMISC_VLAN_TX; 5852 is_tx_fltr = true; 5853 } 5854 5855 /* Set filter DA based on packet type */ 5856 mac_addr = new_fltr.l_data.mac.mac_addr; 5857 if (pkt_type == BCAST_FLTR) { 5858 ice_memset(mac_addr, 0xff, ETH_ALEN, ICE_NONDMA_MEM); 5859 } else if (pkt_type == MCAST_FLTR || 5860 pkt_type == UCAST_FLTR) { 5861 /* Use the dummy ether header DA */ 5862 ice_memcpy(mac_addr, dummy_eth_header, ETH_ALEN, 5863 ICE_NONDMA_TO_NONDMA); 5864 if (pkt_type == MCAST_FLTR) 5865 mac_addr[0] |= 0x1; /* Set multicast bit */ 5866 } 5867 5868 /* Need to reset this to zero for all iterations */ 5869 new_fltr.flag = 0; 5870 if (is_tx_fltr) { 5871 new_fltr.flag |= ICE_FLTR_TX; 5872 new_fltr.src = hw_vsi_id; 5873 } else { 5874 new_fltr.flag |= ICE_FLTR_RX; 5875 new_fltr.src = lport; 5876 } 5877 5878 new_fltr.fltr_act = ICE_FWD_TO_VSI; 5879 new_fltr.vsi_handle = vsi_handle; 5880 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id; 5881 f_list_entry.fltr_info = new_fltr; 5882 recp_list = &sw->recp_list[recipe_id]; 5883 5884 status = ice_add_rule_internal(hw, recp_list, lport, 5885 &f_list_entry); 5886 if (status != ICE_SUCCESS) 5887 goto set_promisc_exit; 5888 } 5889 5890 set_promisc_exit: 5891 return status; 5892 } 5893 5894 /** 5895 * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) 5896 * @hw: pointer to the hardware structure 5897 * @vsi_handle: VSI handle to configure 5898 * @promisc_mask: mask of promiscuous config bits 5899 * @vid: VLAN ID to set VLAN promiscuous 5900 */ 5901 enum ice_status 5902 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 5903 u16 vid) 5904 { 5905 return _ice_set_vsi_promisc(hw, vsi_handle, promisc_mask, vid, 5906 hw->port_info->lport, 5907 hw->switch_info); 5908 } 5909 5910 /** 5911 * _ice_set_vlan_vsi_promisc 5912 * @hw: pointer to the hardware structure 5913 * @vsi_handle: VSI handle to configure 5914 * @promisc_mask: mask of promiscuous config bits 5915 * @rm_vlan_promisc: Clear VLANs VSI promisc mode 5916 * @lport: logical port number to configure promisc mode 5917 * @sw: pointer to switch info struct for which function add rule 5918 * 5919 * Configure VSI with all associated VLANs to given promiscuous mode(s) 5920 */ 5921 static enum ice_status 5922 _ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 5923 bool rm_vlan_promisc, u8 lport, 5924 struct ice_switch_info *sw) 5925 { 5926 struct ice_fltr_list_entry *list_itr, *tmp; 5927 struct LIST_HEAD_TYPE vsi_list_head; 5928 struct LIST_HEAD_TYPE *vlan_head; 5929 struct ice_lock *vlan_lock; /* Lock to protect filter rule list */ 5930 enum ice_status status; 5931 u16 vlan_id; 5932 5933 INIT_LIST_HEAD(&vsi_list_head); 5934 vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 5935 vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 5936 ice_acquire_lock(vlan_lock); 5937 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head, 5938 &vsi_list_head); 5939 ice_release_lock(vlan_lock); 5940 if (status) 5941 goto free_fltr_list; 5942 5943 LIST_FOR_EACH_ENTRY(list_itr, &vsi_list_head, ice_fltr_list_entry, 5944 list_entry) { 5945 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id; 5946 if (rm_vlan_promisc) 5947 status = _ice_clear_vsi_promisc(hw, vsi_handle, 5948 promisc_mask, 5949 vlan_id, sw); 5950 else 5951 status = _ice_set_vsi_promisc(hw, vsi_handle, 5952 promisc_mask, vlan_id, 5953 lport, sw); 5954 if (status) 5955 break; 5956 } 5957 5958 free_fltr_list: 5959 LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp, &vsi_list_head, 5960 ice_fltr_list_entry, list_entry) { 5961 LIST_DEL(&list_itr->list_entry); 5962 ice_free(hw, list_itr); 5963 } 5964 return status; 5965 } 5966 5967 /** 5968 * ice_set_vlan_vsi_promisc 5969 * @hw: pointer to the hardware structure 5970 * @vsi_handle: VSI handle to configure 5971 * @promisc_mask: mask of promiscuous config bits 5972 * @rm_vlan_promisc: Clear VLANs VSI promisc mode 5973 * 5974 * Configure VSI with all associated VLANs to given promiscuous mode(s) 5975 */ 5976 enum ice_status 5977 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 5978 bool rm_vlan_promisc) 5979 { 5980 return _ice_set_vlan_vsi_promisc(hw, vsi_handle, promisc_mask, 5981 rm_vlan_promisc, hw->port_info->lport, 5982 hw->switch_info); 5983 } 5984 5985 /** 5986 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 5987 * @hw: pointer to the hardware structure 5988 * @vsi_handle: VSI handle to remove filters from 5989 * @recp_list: recipe list from which function remove fltr 5990 * @lkup: switch rule filter lookup type 5991 */ 5992 static void 5993 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, 5994 struct ice_sw_recipe *recp_list, 5995 enum ice_sw_lkup_type lkup) 5996 { 5997 struct ice_fltr_list_entry *fm_entry; 5998 struct LIST_HEAD_TYPE remove_list_head; 5999 struct LIST_HEAD_TYPE *rule_head; 6000 struct ice_fltr_list_entry *tmp; 6001 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 6002 enum ice_status status; 6003 6004 INIT_LIST_HEAD(&remove_list_head); 6005 rule_lock = &recp_list[lkup].filt_rule_lock; 6006 rule_head = &recp_list[lkup].filt_rules; 6007 ice_acquire_lock(rule_lock); 6008 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head, 6009 &remove_list_head); 6010 ice_release_lock(rule_lock); 6011 if (status) 6012 return; 6013 6014 switch (lkup) { 6015 case ICE_SW_LKUP_MAC: 6016 ice_remove_mac_rule(hw, &remove_list_head, &recp_list[lkup]); 6017 break; 6018 case ICE_SW_LKUP_VLAN: 6019 ice_remove_vlan_rule(hw, &remove_list_head, &recp_list[lkup]); 6020 break; 6021 case ICE_SW_LKUP_PROMISC: 6022 case ICE_SW_LKUP_PROMISC_VLAN: 6023 ice_remove_promisc(hw, lkup, &remove_list_head); 6024 break; 6025 case ICE_SW_LKUP_MAC_VLAN: 6026 ice_remove_mac_vlan(hw, &remove_list_head); 6027 break; 6028 case ICE_SW_LKUP_ETHERTYPE: 6029 case ICE_SW_LKUP_ETHERTYPE_MAC: 6030 ice_remove_eth_mac(hw, &remove_list_head); 6031 break; 6032 case ICE_SW_LKUP_DFLT: 6033 ice_debug(hw, ICE_DBG_SW, "Remove filters for this lookup type hasn't been implemented yet\n"); 6034 break; 6035 case ICE_SW_LKUP_LAST: 6036 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type\n"); 6037 break; 6038 } 6039 6040 LIST_FOR_EACH_ENTRY_SAFE(fm_entry, tmp, &remove_list_head, 6041 ice_fltr_list_entry, list_entry) { 6042 LIST_DEL(&fm_entry->list_entry); 6043 ice_free(hw, fm_entry); 6044 } 6045 } 6046 6047 /** 6048 * ice_remove_vsi_fltr_rule - Remove all filters for a VSI 6049 * @hw: pointer to the hardware structure 6050 * @vsi_handle: VSI handle to remove filters from 6051 * @sw: pointer to switch info struct 6052 */ 6053 static void 6054 ice_remove_vsi_fltr_rule(struct ice_hw *hw, u16 vsi_handle, 6055 struct ice_switch_info *sw) 6056 { 6057 ice_debug(hw, ICE_DBG_TRACE, "%s\n", __func__); 6058 6059 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6060 sw->recp_list, ICE_SW_LKUP_MAC); 6061 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6062 sw->recp_list, ICE_SW_LKUP_MAC_VLAN); 6063 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6064 sw->recp_list, ICE_SW_LKUP_PROMISC); 6065 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6066 sw->recp_list, ICE_SW_LKUP_VLAN); 6067 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6068 sw->recp_list, ICE_SW_LKUP_DFLT); 6069 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6070 sw->recp_list, ICE_SW_LKUP_ETHERTYPE); 6071 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6072 sw->recp_list, ICE_SW_LKUP_ETHERTYPE_MAC); 6073 ice_remove_vsi_lkup_fltr(hw, vsi_handle, 6074 sw->recp_list, ICE_SW_LKUP_PROMISC_VLAN); 6075 } 6076 6077 /** 6078 * ice_remove_vsi_fltr - Remove all filters for a VSI 6079 * @hw: pointer to the hardware structure 6080 * @vsi_handle: VSI handle to remove filters from 6081 */ 6082 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) 6083 { 6084 ice_remove_vsi_fltr_rule(hw, vsi_handle, hw->switch_info); 6085 } 6086 6087 /** 6088 * ice_alloc_res_cntr - allocating resource counter 6089 * @hw: pointer to the hardware structure 6090 * @type: type of resource 6091 * @alloc_shared: if set it is shared else dedicated 6092 * @num_items: number of entries requested for FD resource type 6093 * @counter_id: counter index returned by AQ call 6094 */ 6095 enum ice_status 6096 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 6097 u16 *counter_id) 6098 { 6099 struct ice_aqc_alloc_free_res_elem *buf; 6100 enum ice_status status; 6101 u16 buf_len; 6102 6103 /* Allocate resource */ 6104 buf_len = ice_struct_size(buf, elem, 1); 6105 buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 6106 if (!buf) 6107 return ICE_ERR_NO_MEMORY; 6108 6109 buf->num_elems = CPU_TO_LE16(num_items); 6110 buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) & 6111 ICE_AQC_RES_TYPE_M) | alloc_shared); 6112 6113 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 6114 ice_aqc_opc_alloc_res, NULL); 6115 if (status) 6116 goto exit; 6117 6118 *counter_id = LE16_TO_CPU(buf->elem[0].e.sw_resp); 6119 6120 exit: 6121 ice_free(hw, buf); 6122 return status; 6123 } 6124 6125 /** 6126 * ice_free_res_cntr - free resource counter 6127 * @hw: pointer to the hardware structure 6128 * @type: type of resource 6129 * @alloc_shared: if set it is shared else dedicated 6130 * @num_items: number of entries to be freed for FD resource type 6131 * @counter_id: counter ID resource which needs to be freed 6132 */ 6133 enum ice_status 6134 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 6135 u16 counter_id) 6136 { 6137 struct ice_aqc_alloc_free_res_elem *buf; 6138 enum ice_status status; 6139 u16 buf_len; 6140 6141 /* Free resource */ 6142 buf_len = ice_struct_size(buf, elem, 1); 6143 buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 6144 if (!buf) 6145 return ICE_ERR_NO_MEMORY; 6146 6147 buf->num_elems = CPU_TO_LE16(num_items); 6148 buf->res_type = CPU_TO_LE16(((type << ICE_AQC_RES_TYPE_S) & 6149 ICE_AQC_RES_TYPE_M) | alloc_shared); 6150 buf->elem[0].e.sw_resp = CPU_TO_LE16(counter_id); 6151 6152 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 6153 ice_aqc_opc_free_res, NULL); 6154 if (status) 6155 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n"); 6156 6157 ice_free(hw, buf); 6158 return status; 6159 } 6160 6161 /** 6162 * ice_alloc_vlan_res_counter - obtain counter resource for VLAN type 6163 * @hw: pointer to the hardware structure 6164 * @counter_id: returns counter index 6165 */ 6166 enum ice_status ice_alloc_vlan_res_counter(struct ice_hw *hw, u16 *counter_id) 6167 { 6168 return ice_alloc_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER, 6169 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, 6170 counter_id); 6171 } 6172 6173 /** 6174 * ice_free_vlan_res_counter - Free counter resource for VLAN type 6175 * @hw: pointer to the hardware structure 6176 * @counter_id: counter index to be freed 6177 */ 6178 enum ice_status ice_free_vlan_res_counter(struct ice_hw *hw, u16 counter_id) 6179 { 6180 return ice_free_res_cntr(hw, ICE_AQC_RES_TYPE_VLAN_COUNTER, 6181 ICE_AQC_RES_TYPE_FLAG_DEDICATED, 1, 6182 counter_id); 6183 } 6184 6185 /** 6186 * ice_alloc_res_lg_act - add large action resource 6187 * @hw: pointer to the hardware structure 6188 * @l_id: large action ID to fill it in 6189 * @num_acts: number of actions to hold with a large action entry 6190 */ 6191 static enum ice_status 6192 ice_alloc_res_lg_act(struct ice_hw *hw, u16 *l_id, u16 num_acts) 6193 { 6194 struct ice_aqc_alloc_free_res_elem *sw_buf; 6195 enum ice_status status; 6196 u16 buf_len; 6197 6198 if (num_acts > ICE_MAX_LG_ACT || num_acts == 0) 6199 return ICE_ERR_PARAM; 6200 6201 /* Allocate resource for large action */ 6202 buf_len = ice_struct_size(sw_buf, elem, 1); 6203 sw_buf = (struct ice_aqc_alloc_free_res_elem *)ice_malloc(hw, buf_len); 6204 if (!sw_buf) 6205 return ICE_ERR_NO_MEMORY; 6206 6207 sw_buf->num_elems = CPU_TO_LE16(1); 6208 6209 /* If num_acts is 1, use ICE_AQC_RES_TYPE_WIDE_TABLE_1. 6210 * If num_acts is 2, use ICE_AQC_RES_TYPE_WIDE_TABLE_3. 6211 * If num_acts is greater than 2, then use 6212 * ICE_AQC_RES_TYPE_WIDE_TABLE_4. 6213 * The num_acts cannot exceed 4. This was ensured at the 6214 * beginning of the function. 6215 */ 6216 if (num_acts == 1) 6217 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_1); 6218 else if (num_acts == 2) 6219 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_2); 6220 else 6221 sw_buf->res_type = CPU_TO_LE16(ICE_AQC_RES_TYPE_WIDE_TABLE_4); 6222 6223 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 6224 ice_aqc_opc_alloc_res, NULL); 6225 if (!status) 6226 *l_id = LE16_TO_CPU(sw_buf->elem[0].e.sw_resp); 6227 6228 ice_free(hw, sw_buf); 6229 return status; 6230 } 6231 6232 /** 6233 * ice_add_mac_with_sw_marker - add filter with sw marker 6234 * @hw: pointer to the hardware structure 6235 * @f_info: filter info structure containing the MAC filter information 6236 * @sw_marker: sw marker to tag the Rx descriptor with 6237 */ 6238 enum ice_status 6239 ice_add_mac_with_sw_marker(struct ice_hw *hw, struct ice_fltr_info *f_info, 6240 u16 sw_marker) 6241 { 6242 struct ice_fltr_mgmt_list_entry *m_entry; 6243 struct ice_fltr_list_entry fl_info; 6244 struct ice_sw_recipe *recp_list; 6245 struct LIST_HEAD_TYPE l_head; 6246 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 6247 enum ice_status ret; 6248 bool entry_exists; 6249 u16 lg_act_id; 6250 6251 if (f_info->fltr_act != ICE_FWD_TO_VSI) 6252 return ICE_ERR_PARAM; 6253 6254 if (f_info->lkup_type != ICE_SW_LKUP_MAC) 6255 return ICE_ERR_PARAM; 6256 6257 if (sw_marker == ICE_INVAL_SW_MARKER_ID) 6258 return ICE_ERR_PARAM; 6259 6260 if (!ice_is_vsi_valid(hw, f_info->vsi_handle)) 6261 return ICE_ERR_PARAM; 6262 f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle); 6263 6264 /* Add filter if it doesn't exist so then the adding of large 6265 * action always results in update 6266 */ 6267 6268 INIT_LIST_HEAD(&l_head); 6269 fl_info.fltr_info = *f_info; 6270 LIST_ADD(&fl_info.list_entry, &l_head); 6271 6272 entry_exists = false; 6273 ret = ice_add_mac_rule(hw, &l_head, hw->switch_info, 6274 hw->port_info->lport); 6275 if (ret == ICE_ERR_ALREADY_EXISTS) 6276 entry_exists = true; 6277 else if (ret) 6278 return ret; 6279 6280 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC]; 6281 rule_lock = &recp_list->filt_rule_lock; 6282 ice_acquire_lock(rule_lock); 6283 /* Get the book keeping entry for the filter */ 6284 m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info); 6285 if (!m_entry) 6286 goto exit_error; 6287 6288 /* If counter action was enabled for this rule then don't enable 6289 * sw marker large action 6290 */ 6291 if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) { 6292 ret = ICE_ERR_PARAM; 6293 goto exit_error; 6294 } 6295 6296 /* if same marker was added before */ 6297 if (m_entry->sw_marker_id == sw_marker) { 6298 ret = ICE_ERR_ALREADY_EXISTS; 6299 goto exit_error; 6300 } 6301 6302 /* Allocate a hardware table entry to hold large act. Three actions 6303 * for marker based large action 6304 */ 6305 ret = ice_alloc_res_lg_act(hw, &lg_act_id, 3); 6306 if (ret) 6307 goto exit_error; 6308 6309 if (lg_act_id == ICE_INVAL_LG_ACT_INDEX) 6310 goto exit_error; 6311 6312 /* Update the switch rule to add the marker action */ 6313 ret = ice_add_marker_act(hw, m_entry, sw_marker, lg_act_id); 6314 if (!ret) { 6315 ice_release_lock(rule_lock); 6316 return ret; 6317 } 6318 6319 exit_error: 6320 ice_release_lock(rule_lock); 6321 /* only remove entry if it did not exist previously */ 6322 if (!entry_exists) 6323 ret = ice_remove_mac(hw, &l_head); 6324 6325 return ret; 6326 } 6327 6328 /** 6329 * ice_add_mac_with_counter - add filter with counter enabled 6330 * @hw: pointer to the hardware structure 6331 * @f_info: pointer to filter info structure containing the MAC filter 6332 * information 6333 */ 6334 enum ice_status 6335 ice_add_mac_with_counter(struct ice_hw *hw, struct ice_fltr_info *f_info) 6336 { 6337 struct ice_fltr_mgmt_list_entry *m_entry; 6338 struct ice_fltr_list_entry fl_info; 6339 struct ice_sw_recipe *recp_list; 6340 struct LIST_HEAD_TYPE l_head; 6341 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 6342 enum ice_status ret; 6343 bool entry_exist; 6344 u16 counter_id; 6345 u16 lg_act_id; 6346 6347 if (f_info->fltr_act != ICE_FWD_TO_VSI) 6348 return ICE_ERR_PARAM; 6349 6350 if (f_info->lkup_type != ICE_SW_LKUP_MAC) 6351 return ICE_ERR_PARAM; 6352 6353 if (!ice_is_vsi_valid(hw, f_info->vsi_handle)) 6354 return ICE_ERR_PARAM; 6355 f_info->fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, f_info->vsi_handle); 6356 recp_list = &hw->switch_info->recp_list[ICE_SW_LKUP_MAC]; 6357 6358 entry_exist = false; 6359 6360 rule_lock = &recp_list->filt_rule_lock; 6361 6362 /* Add filter if it doesn't exist so then the adding of large 6363 * action always results in update 6364 */ 6365 INIT_LIST_HEAD(&l_head); 6366 6367 fl_info.fltr_info = *f_info; 6368 LIST_ADD(&fl_info.list_entry, &l_head); 6369 6370 ret = ice_add_mac_rule(hw, &l_head, hw->switch_info, 6371 hw->port_info->lport); 6372 if (ret == ICE_ERR_ALREADY_EXISTS) 6373 entry_exist = true; 6374 else if (ret) 6375 return ret; 6376 6377 ice_acquire_lock(rule_lock); 6378 m_entry = ice_find_rule_entry(&recp_list->filt_rules, f_info); 6379 if (!m_entry) { 6380 ret = ICE_ERR_BAD_PTR; 6381 goto exit_error; 6382 } 6383 6384 /* Don't enable counter for a filter for which sw marker was enabled */ 6385 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) { 6386 ret = ICE_ERR_PARAM; 6387 goto exit_error; 6388 } 6389 6390 /* If a counter was already enabled then don't need to add again */ 6391 if (m_entry->counter_index != ICE_INVAL_COUNTER_ID) { 6392 ret = ICE_ERR_ALREADY_EXISTS; 6393 goto exit_error; 6394 } 6395 6396 /* Allocate a hardware table entry to VLAN counter */ 6397 ret = ice_alloc_vlan_res_counter(hw, &counter_id); 6398 if (ret) 6399 goto exit_error; 6400 6401 /* Allocate a hardware table entry to hold large act. Two actions for 6402 * counter based large action 6403 */ 6404 ret = ice_alloc_res_lg_act(hw, &lg_act_id, 2); 6405 if (ret) 6406 goto exit_error; 6407 6408 if (lg_act_id == ICE_INVAL_LG_ACT_INDEX) 6409 goto exit_error; 6410 6411 /* Update the switch rule to add the counter action */ 6412 ret = ice_add_counter_act(hw, m_entry, counter_id, lg_act_id); 6413 if (!ret) { 6414 ice_release_lock(rule_lock); 6415 return ret; 6416 } 6417 6418 exit_error: 6419 ice_release_lock(rule_lock); 6420 /* only remove entry if it did not exist previously */ 6421 if (!entry_exist) 6422 ret = ice_remove_mac(hw, &l_head); 6423 6424 return ret; 6425 } 6426 6427 /* This is mapping table entry that maps every word within a given protocol 6428 * structure to the real byte offset as per the specification of that 6429 * protocol header. 6430 * for example dst address is 3 words in ethertype header and corresponding 6431 * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8 6432 * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a 6433 * matching entry describing its field. This needs to be updated if new 6434 * structure is added to that union. 6435 */ 6436 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = { 6437 { ICE_MAC_OFOS, { 0, 2, 4, 6, 8, 10, 12 } }, 6438 { ICE_MAC_IL, { 0, 2, 4, 6, 8, 10, 12 } }, 6439 { ICE_ETYPE_OL, { 0 } }, 6440 { ICE_VLAN_OFOS, { 0, 2 } }, 6441 { ICE_IPV4_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } }, 6442 { ICE_IPV4_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } }, 6443 { ICE_IPV6_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 6444 26, 28, 30, 32, 34, 36, 38 } }, 6445 { ICE_IPV6_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 6446 26, 28, 30, 32, 34, 36, 38 } }, 6447 { ICE_TCP_IL, { 0, 2 } }, 6448 { ICE_UDP_OF, { 0, 2 } }, 6449 { ICE_UDP_ILOS, { 0, 2 } }, 6450 { ICE_SCTP_IL, { 0, 2 } }, 6451 { ICE_VXLAN, { 8, 10, 12, 14 } }, 6452 { ICE_GENEVE, { 8, 10, 12, 14 } }, 6453 { ICE_VXLAN_GPE, { 8, 10, 12, 14 } }, 6454 { ICE_NVGRE, { 0, 2, 4, 6 } }, 6455 { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20 } }, 6456 { ICE_PPPOE, { 0, 2, 4, 6 } }, 6457 { ICE_PFCP, { 8, 10, 12, 14, 16, 18, 20, 22 } }, 6458 { ICE_L2TPV3, { 0, 2, 4, 6, 8, 10 } }, 6459 { ICE_ESP, { 0, 2, 4, 6 } }, 6460 { ICE_AH, { 0, 2, 4, 6, 8, 10 } }, 6461 { ICE_NAT_T, { 8, 10, 12, 14 } }, 6462 { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } }, 6463 { ICE_VLAN_EX, { 0, 2 } }, 6464 }; 6465 6466 /* The following table describes preferred grouping of recipes. 6467 * If a recipe that needs to be programmed is a superset or matches one of the 6468 * following combinations, then the recipe needs to be chained as per the 6469 * following policy. 6470 */ 6471 6472 static const struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { 6473 { ICE_MAC_OFOS, ICE_MAC_OFOS_HW }, 6474 { ICE_MAC_IL, ICE_MAC_IL_HW }, 6475 { ICE_ETYPE_OL, ICE_ETYPE_OL_HW }, 6476 { ICE_VLAN_OFOS, ICE_VLAN_OL_HW }, 6477 { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW }, 6478 { ICE_IPV4_IL, ICE_IPV4_IL_HW }, 6479 { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW }, 6480 { ICE_IPV6_IL, ICE_IPV6_IL_HW }, 6481 { ICE_TCP_IL, ICE_TCP_IL_HW }, 6482 { ICE_UDP_OF, ICE_UDP_OF_HW }, 6483 { ICE_UDP_ILOS, ICE_UDP_ILOS_HW }, 6484 { ICE_SCTP_IL, ICE_SCTP_IL_HW }, 6485 { ICE_VXLAN, ICE_UDP_OF_HW }, 6486 { ICE_GENEVE, ICE_UDP_OF_HW }, 6487 { ICE_VXLAN_GPE, ICE_UDP_OF_HW }, 6488 { ICE_NVGRE, ICE_GRE_OF_HW }, 6489 { ICE_GTP, ICE_UDP_OF_HW }, 6490 { ICE_PPPOE, ICE_PPPOE_HW }, 6491 { ICE_PFCP, ICE_UDP_ILOS_HW }, 6492 { ICE_L2TPV3, ICE_L2TPV3_HW }, 6493 { ICE_ESP, ICE_ESP_HW }, 6494 { ICE_AH, ICE_AH_HW }, 6495 { ICE_NAT_T, ICE_UDP_ILOS_HW }, 6496 { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW }, 6497 { ICE_VLAN_EX, ICE_VLAN_OF_HW }, 6498 }; 6499 6500 /** 6501 * ice_find_recp - find a recipe 6502 * @hw: pointer to the hardware structure 6503 * @lkup_exts: extension sequence to match 6504 * 6505 * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. 6506 */ 6507 static u16 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, 6508 enum ice_sw_tunnel_type tun_type) 6509 { 6510 bool refresh_required = true; 6511 struct ice_sw_recipe *recp; 6512 u8 i; 6513 6514 /* Walk through existing recipes to find a match */ 6515 recp = hw->switch_info->recp_list; 6516 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6517 /* If recipe was not created for this ID, in SW bookkeeping, 6518 * check if FW has an entry for this recipe. If the FW has an 6519 * entry update it in our SW bookkeeping and continue with the 6520 * matching. 6521 */ 6522 if (!recp[i].recp_created) 6523 if (ice_get_recp_frm_fw(hw, 6524 hw->switch_info->recp_list, i, 6525 &refresh_required)) 6526 continue; 6527 6528 /* Skip inverse action recipes */ 6529 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl & 6530 ICE_AQ_RECIPE_ACT_INV_ACT) 6531 continue; 6532 6533 /* if number of words we are looking for match */ 6534 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) { 6535 struct ice_fv_word *ar = recp[i].lkup_exts.fv_words; 6536 struct ice_fv_word *be = lkup_exts->fv_words; 6537 u16 *cr = recp[i].lkup_exts.field_mask; 6538 u16 *de = lkup_exts->field_mask; 6539 bool found = true; 6540 u8 pe, qr; 6541 6542 /* ar, cr, and qr are related to the recipe words, while 6543 * be, de, and pe are related to the lookup words 6544 */ 6545 for (pe = 0; pe < lkup_exts->n_val_words; pe++) { 6546 for (qr = 0; qr < recp[i].lkup_exts.n_val_words; 6547 qr++) { 6548 if (ar[qr].off == be[pe].off && 6549 ar[qr].prot_id == be[pe].prot_id && 6550 cr[qr] == de[pe]) 6551 /* Found the "pe"th word in the 6552 * given recipe 6553 */ 6554 break; 6555 } 6556 /* After walking through all the words in the 6557 * "i"th recipe if "p"th word was not found then 6558 * this recipe is not what we are looking for. 6559 * So break out from this loop and try the next 6560 * recipe 6561 */ 6562 if (qr >= recp[i].lkup_exts.n_val_words) { 6563 found = false; 6564 break; 6565 } 6566 } 6567 /* If for "i"th recipe the found was never set to false 6568 * then it means we found our match 6569 */ 6570 if (tun_type == recp[i].tun_type && found) 6571 return i; /* Return the recipe ID */ 6572 } 6573 } 6574 return ICE_MAX_NUM_RECIPES; 6575 } 6576 6577 /** 6578 * ice_prot_type_to_id - get protocol ID from protocol type 6579 * @type: protocol type 6580 * @id: pointer to variable that will receive the ID 6581 * 6582 * Returns true if found, false otherwise 6583 */ 6584 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) 6585 { 6586 u8 i; 6587 6588 for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 6589 if (ice_prot_id_tbl[i].type == type) { 6590 *id = ice_prot_id_tbl[i].protocol_id; 6591 return true; 6592 } 6593 return false; 6594 } 6595 6596 /** 6597 * ice_find_valid_words - count valid words 6598 * @rule: advanced rule with lookup information 6599 * @lkup_exts: byte offset extractions of the words that are valid 6600 * 6601 * calculate valid words in a lookup rule using mask value 6602 */ 6603 static u8 6604 ice_fill_valid_words(struct ice_adv_lkup_elem *rule, 6605 struct ice_prot_lkup_ext *lkup_exts) 6606 { 6607 u8 j, word, prot_id, ret_val; 6608 6609 if (!ice_prot_type_to_id(rule->type, &prot_id)) 6610 return 0; 6611 6612 word = lkup_exts->n_val_words; 6613 6614 for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++) 6615 if (((u16 *)&rule->m_u)[j] && 6616 rule->type < ARRAY_SIZE(ice_prot_ext)) { 6617 /* No more space to accommodate */ 6618 if (word >= ICE_MAX_CHAIN_WORDS) 6619 return 0; 6620 lkup_exts->fv_words[word].off = 6621 ice_prot_ext[rule->type].offs[j]; 6622 lkup_exts->fv_words[word].prot_id = 6623 ice_prot_id_tbl[rule->type].protocol_id; 6624 lkup_exts->field_mask[word] = 6625 BE16_TO_CPU(((_FORCE_ __be16 *)&rule->m_u)[j]); 6626 word++; 6627 } 6628 6629 ret_val = word - lkup_exts->n_val_words; 6630 lkup_exts->n_val_words = word; 6631 6632 return ret_val; 6633 } 6634 6635 /** 6636 * ice_create_first_fit_recp_def - Create a recipe grouping 6637 * @hw: pointer to the hardware structure 6638 * @lkup_exts: an array of protocol header extractions 6639 * @rg_list: pointer to a list that stores new recipe groups 6640 * @recp_cnt: pointer to a variable that stores returned number of recipe groups 6641 * 6642 * Using first fit algorithm, take all the words that are still not done 6643 * and start grouping them in 4-word groups. Each group makes up one 6644 * recipe. 6645 */ 6646 static enum ice_status 6647 ice_create_first_fit_recp_def(struct ice_hw *hw, 6648 struct ice_prot_lkup_ext *lkup_exts, 6649 struct LIST_HEAD_TYPE *rg_list, 6650 u8 *recp_cnt) 6651 { 6652 struct ice_pref_recipe_group *grp = NULL; 6653 u8 j; 6654 6655 *recp_cnt = 0; 6656 6657 if (!lkup_exts->n_val_words) { 6658 struct ice_recp_grp_entry *entry; 6659 6660 entry = (struct ice_recp_grp_entry *) 6661 ice_malloc(hw, sizeof(*entry)); 6662 if (!entry) 6663 return ICE_ERR_NO_MEMORY; 6664 LIST_ADD(&entry->l_entry, rg_list); 6665 grp = &entry->r_group; 6666 (*recp_cnt)++; 6667 grp->n_val_pairs = 0; 6668 } 6669 6670 /* Walk through every word in the rule to check if it is not done. If so 6671 * then this word needs to be part of a new recipe. 6672 */ 6673 for (j = 0; j < lkup_exts->n_val_words; j++) 6674 if (!ice_is_bit_set(lkup_exts->done, j)) { 6675 if (!grp || 6676 grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) { 6677 struct ice_recp_grp_entry *entry; 6678 6679 entry = (struct ice_recp_grp_entry *) 6680 ice_malloc(hw, sizeof(*entry)); 6681 if (!entry) 6682 return ICE_ERR_NO_MEMORY; 6683 LIST_ADD(&entry->l_entry, rg_list); 6684 grp = &entry->r_group; 6685 (*recp_cnt)++; 6686 } 6687 6688 grp->pairs[grp->n_val_pairs].prot_id = 6689 lkup_exts->fv_words[j].prot_id; 6690 grp->pairs[grp->n_val_pairs].off = 6691 lkup_exts->fv_words[j].off; 6692 grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j]; 6693 grp->n_val_pairs++; 6694 } 6695 6696 return ICE_SUCCESS; 6697 } 6698 6699 /** 6700 * ice_fill_fv_word_index - fill in the field vector indices for a recipe group 6701 * @hw: pointer to the hardware structure 6702 * @fv_list: field vector with the extraction sequence information 6703 * @rg_list: recipe groupings with protocol-offset pairs 6704 * 6705 * Helper function to fill in the field vector indices for protocol-offset 6706 * pairs. These indexes are then ultimately programmed into a recipe. 6707 */ 6708 static enum ice_status 6709 ice_fill_fv_word_index(struct ice_hw *hw, struct LIST_HEAD_TYPE *fv_list, 6710 struct LIST_HEAD_TYPE *rg_list) 6711 { 6712 struct ice_sw_fv_list_entry *fv; 6713 struct ice_recp_grp_entry *rg; 6714 struct ice_fv_word *fv_ext; 6715 6716 if (LIST_EMPTY(fv_list)) 6717 return ICE_SUCCESS; 6718 6719 fv = LIST_FIRST_ENTRY(fv_list, struct ice_sw_fv_list_entry, list_entry); 6720 fv_ext = fv->fv_ptr->ew; 6721 6722 LIST_FOR_EACH_ENTRY(rg, rg_list, ice_recp_grp_entry, l_entry) { 6723 u8 i; 6724 6725 for (i = 0; i < rg->r_group.n_val_pairs; i++) { 6726 struct ice_fv_word *pr; 6727 bool found = false; 6728 u16 mask; 6729 u8 j; 6730 6731 pr = &rg->r_group.pairs[i]; 6732 mask = rg->r_group.mask[i]; 6733 6734 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 6735 if (fv_ext[j].prot_id == pr->prot_id && 6736 fv_ext[j].off == pr->off) { 6737 found = true; 6738 6739 /* Store index of field vector */ 6740 rg->fv_idx[i] = j; 6741 rg->fv_mask[i] = mask; 6742 break; 6743 } 6744 6745 /* Protocol/offset could not be found, caller gave an 6746 * invalid pair 6747 */ 6748 if (!found) 6749 return ICE_ERR_PARAM; 6750 } 6751 } 6752 6753 return ICE_SUCCESS; 6754 } 6755 6756 /** 6757 * ice_find_free_recp_res_idx - find free result indexes for recipe 6758 * @hw: pointer to hardware structure 6759 * @profiles: bitmap of profiles that will be associated with the new recipe 6760 * @free_idx: pointer to variable to receive the free index bitmap 6761 * 6762 * The algorithm used here is: 6763 * 1. When creating a new recipe, create a set P which contains all 6764 * Profiles that will be associated with our new recipe 6765 * 6766 * 2. For each Profile p in set P: 6767 * a. Add all recipes associated with Profile p into set R 6768 * b. Optional : PossibleIndexes &= profile[p].possibleIndexes 6769 * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF] 6770 * i. Or just assume they all have the same possible indexes: 6771 * 44, 45, 46, 47 6772 * i.e., PossibleIndexes = 0x0000F00000000000 6773 * 6774 * 3. For each Recipe r in set R: 6775 * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes 6776 * b. FreeIndexes = UsedIndexes ^ PossibleIndexes 6777 * 6778 * FreeIndexes will contain the bits indicating the indexes free for use, 6779 * then the code needs to update the recipe[r].used_result_idx_bits to 6780 * indicate which indexes were selected for use by this recipe. 6781 */ 6782 static u16 6783 ice_find_free_recp_res_idx(struct ice_hw *hw, const ice_bitmap_t *profiles, 6784 ice_bitmap_t *free_idx) 6785 { 6786 ice_declare_bitmap(possible_idx, ICE_MAX_FV_WORDS); 6787 ice_declare_bitmap(recipes, ICE_MAX_NUM_RECIPES); 6788 ice_declare_bitmap(used_idx, ICE_MAX_FV_WORDS); 6789 u16 bit; 6790 6791 ice_zero_bitmap(possible_idx, ICE_MAX_FV_WORDS); 6792 ice_zero_bitmap(recipes, ICE_MAX_NUM_RECIPES); 6793 ice_zero_bitmap(used_idx, ICE_MAX_FV_WORDS); 6794 ice_zero_bitmap(free_idx, ICE_MAX_FV_WORDS); 6795 6796 ice_bitmap_set(possible_idx, 0, ICE_MAX_FV_WORDS); 6797 6798 /* For each profile we are going to associate the recipe with, add the 6799 * recipes that are associated with that profile. This will give us 6800 * the set of recipes that our recipe may collide with. Also, determine 6801 * what possible result indexes are usable given this set of profiles. 6802 */ 6803 ice_for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) { 6804 ice_or_bitmap(recipes, recipes, profile_to_recipe[bit], 6805 ICE_MAX_NUM_RECIPES); 6806 ice_and_bitmap(possible_idx, possible_idx, 6807 hw->switch_info->prof_res_bm[bit], 6808 ICE_MAX_FV_WORDS); 6809 } 6810 6811 /* For each recipe that our new recipe may collide with, determine 6812 * which indexes have been used. 6813 */ 6814 ice_for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES) 6815 ice_or_bitmap(used_idx, used_idx, 6816 hw->switch_info->recp_list[bit].res_idxs, 6817 ICE_MAX_FV_WORDS); 6818 6819 ice_xor_bitmap(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS); 6820 6821 /* return number of free indexes */ 6822 return (u16)ice_bitmap_hweight(free_idx, ICE_MAX_FV_WORDS); 6823 } 6824 6825 /** 6826 * ice_add_sw_recipe - function to call AQ calls to create switch recipe 6827 * @hw: pointer to hardware structure 6828 * @rm: recipe management list entry 6829 * @profiles: bitmap of profiles that will be associated. 6830 */ 6831 static enum ice_status 6832 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, 6833 ice_bitmap_t *profiles) 6834 { 6835 ice_declare_bitmap(result_idx_bm, ICE_MAX_FV_WORDS); 6836 struct ice_aqc_recipe_data_elem *tmp; 6837 struct ice_aqc_recipe_data_elem *buf; 6838 struct ice_recp_grp_entry *entry; 6839 enum ice_status status; 6840 u16 free_res_idx; 6841 u16 recipe_count; 6842 u8 chain_idx; 6843 u8 recps = 0; 6844 6845 /* When more than one recipe are required, another recipe is needed to 6846 * chain them together. Matching a tunnel metadata ID takes up one of 6847 * the match fields in the chaining recipe reducing the number of 6848 * chained recipes by one. 6849 */ 6850 /* check number of free result indices */ 6851 ice_zero_bitmap(result_idx_bm, ICE_MAX_FV_WORDS); 6852 free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm); 6853 6854 ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n", 6855 free_res_idx, rm->n_grp_count); 6856 6857 if (rm->n_grp_count > 1) { 6858 if (rm->n_grp_count > free_res_idx) 6859 return ICE_ERR_MAX_LIMIT; 6860 6861 rm->n_grp_count++; 6862 } 6863 6864 if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE) 6865 return ICE_ERR_MAX_LIMIT; 6866 6867 tmp = (struct ice_aqc_recipe_data_elem *)ice_calloc(hw, 6868 ICE_MAX_NUM_RECIPES, 6869 sizeof(*tmp)); 6870 if (!tmp) 6871 return ICE_ERR_NO_MEMORY; 6872 6873 buf = (struct ice_aqc_recipe_data_elem *) 6874 ice_calloc(hw, rm->n_grp_count, sizeof(*buf)); 6875 if (!buf) { 6876 status = ICE_ERR_NO_MEMORY; 6877 goto err_mem; 6878 } 6879 6880 ice_zero_bitmap(rm->r_bitmap, ICE_MAX_NUM_RECIPES); 6881 recipe_count = ICE_MAX_NUM_RECIPES; 6882 status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC, 6883 NULL); 6884 if (status || recipe_count == 0) 6885 goto err_unroll; 6886 6887 /* Allocate the recipe resources, and configure them according to the 6888 * match fields from protocol headers and extracted field vectors. 6889 */ 6890 chain_idx = ice_find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS); 6891 LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) { 6892 u8 i; 6893 6894 status = ice_alloc_recipe(hw, &entry->rid); 6895 if (status) 6896 goto err_unroll; 6897 6898 /* Clear the result index of the located recipe, as this will be 6899 * updated, if needed, later in the recipe creation process. 6900 */ 6901 tmp[0].content.result_indx = 0; 6902 6903 buf[recps] = tmp[0]; 6904 buf[recps].recipe_indx = (u8)entry->rid; 6905 /* if the recipe is a non-root recipe RID should be programmed 6906 * as 0 for the rules to be applied correctly. 6907 */ 6908 buf[recps].content.rid = 0; 6909 ice_memset(&buf[recps].content.lkup_indx, 0, 6910 sizeof(buf[recps].content.lkup_indx), 6911 ICE_NONDMA_MEM); 6912 6913 /* All recipes use look-up index 0 to match switch ID. */ 6914 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 6915 buf[recps].content.mask[0] = 6916 CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK); 6917 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask 6918 * to be 0 6919 */ 6920 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 6921 buf[recps].content.lkup_indx[i] = 0x80; 6922 buf[recps].content.mask[i] = 0; 6923 } 6924 6925 for (i = 0; i < entry->r_group.n_val_pairs; i++) { 6926 buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i]; 6927 buf[recps].content.mask[i + 1] = 6928 CPU_TO_LE16(entry->fv_mask[i]); 6929 } 6930 6931 if (rm->n_grp_count > 1) { 6932 /* Checks to see if there really is a valid result index 6933 * that can be used. 6934 */ 6935 if (chain_idx >= ICE_MAX_FV_WORDS) { 6936 ice_debug(hw, ICE_DBG_SW, "No chain index available\n"); 6937 status = ICE_ERR_MAX_LIMIT; 6938 goto err_unroll; 6939 } 6940 6941 entry->chain_idx = chain_idx; 6942 buf[recps].content.result_indx = 6943 ICE_AQ_RECIPE_RESULT_EN | 6944 ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) & 6945 ICE_AQ_RECIPE_RESULT_DATA_M); 6946 ice_clear_bit(chain_idx, result_idx_bm); 6947 chain_idx = ice_find_first_bit(result_idx_bm, 6948 ICE_MAX_FV_WORDS); 6949 } 6950 6951 /* fill recipe dependencies */ 6952 ice_zero_bitmap((ice_bitmap_t *)buf[recps].recipe_bitmap, 6953 ICE_MAX_NUM_RECIPES); 6954 ice_set_bit(buf[recps].recipe_indx, 6955 (ice_bitmap_t *)buf[recps].recipe_bitmap); 6956 buf[recps].content.act_ctrl_fwd_priority = rm->priority; 6957 recps++; 6958 } 6959 6960 if (rm->n_grp_count == 1) { 6961 rm->root_rid = buf[0].recipe_indx; 6962 ice_set_bit(buf[0].recipe_indx, rm->r_bitmap); 6963 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT; 6964 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) { 6965 ice_memcpy(buf[0].recipe_bitmap, rm->r_bitmap, 6966 sizeof(buf[0].recipe_bitmap), 6967 ICE_NONDMA_TO_NONDMA); 6968 } else { 6969 status = ICE_ERR_BAD_PTR; 6970 goto err_unroll; 6971 } 6972 /* Applicable only for ROOT_RECIPE, set the fwd_priority for 6973 * the recipe which is getting created if specified 6974 * by user. Usually any advanced switch filter, which results 6975 * into new extraction sequence, ended up creating a new recipe 6976 * of type ROOT and usually recipes are associated with profiles 6977 * Switch rule referreing newly created recipe, needs to have 6978 * either/or 'fwd' or 'join' priority, otherwise switch rule 6979 * evaluation will not happen correctly. In other words, if 6980 * switch rule to be evaluated on priority basis, then recipe 6981 * needs to have priority, otherwise it will be evaluated last. 6982 */ 6983 buf[0].content.act_ctrl_fwd_priority = rm->priority; 6984 } else { 6985 struct ice_recp_grp_entry *last_chain_entry; 6986 u16 rid, i; 6987 6988 /* Allocate the last recipe that will chain the outcomes of the 6989 * other recipes together 6990 */ 6991 status = ice_alloc_recipe(hw, &rid); 6992 if (status) 6993 goto err_unroll; 6994 6995 buf[recps].recipe_indx = (u8)rid; 6996 buf[recps].content.rid = (u8)rid; 6997 buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT; 6998 /* the new entry created should also be part of rg_list to 6999 * make sure we have complete recipe 7000 */ 7001 last_chain_entry = (struct ice_recp_grp_entry *)ice_malloc(hw, 7002 sizeof(*last_chain_entry)); 7003 if (!last_chain_entry) { 7004 status = ICE_ERR_NO_MEMORY; 7005 goto err_unroll; 7006 } 7007 last_chain_entry->rid = rid; 7008 ice_memset(&buf[recps].content.lkup_indx, 0, 7009 sizeof(buf[recps].content.lkup_indx), 7010 ICE_NONDMA_MEM); 7011 /* All recipes use look-up index 0 to match switch ID. */ 7012 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 7013 buf[recps].content.mask[0] = 7014 CPU_TO_LE16(ICE_AQ_SW_ID_LKUP_MASK); 7015 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 7016 buf[recps].content.lkup_indx[i] = 7017 ICE_AQ_RECIPE_LKUP_IGNORE; 7018 buf[recps].content.mask[i] = 0; 7019 } 7020 7021 i = 1; 7022 /* update r_bitmap with the recp that is used for chaining */ 7023 ice_set_bit(rid, rm->r_bitmap); 7024 /* this is the recipe that chains all the other recipes so it 7025 * should not have a chaining ID to indicate the same 7026 */ 7027 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND; 7028 LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, 7029 l_entry) { 7030 last_chain_entry->fv_idx[i] = entry->chain_idx; 7031 buf[recps].content.lkup_indx[i] = entry->chain_idx; 7032 buf[recps].content.mask[i++] = CPU_TO_LE16(0xFFFF); 7033 ice_set_bit(entry->rid, rm->r_bitmap); 7034 } 7035 LIST_ADD(&last_chain_entry->l_entry, &rm->rg_list); 7036 if (sizeof(buf[recps].recipe_bitmap) >= 7037 sizeof(rm->r_bitmap)) { 7038 ice_memcpy(buf[recps].recipe_bitmap, rm->r_bitmap, 7039 sizeof(buf[recps].recipe_bitmap), 7040 ICE_NONDMA_TO_NONDMA); 7041 } else { 7042 status = ICE_ERR_BAD_PTR; 7043 goto err_unroll; 7044 } 7045 buf[recps].content.act_ctrl_fwd_priority = rm->priority; 7046 7047 recps++; 7048 rm->root_rid = (u8)rid; 7049 } 7050 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 7051 if (status) 7052 goto err_unroll; 7053 7054 status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL); 7055 ice_release_change_lock(hw); 7056 if (status) 7057 goto err_unroll; 7058 7059 /* Every recipe that just got created add it to the recipe 7060 * book keeping list 7061 */ 7062 LIST_FOR_EACH_ENTRY(entry, &rm->rg_list, ice_recp_grp_entry, l_entry) { 7063 struct ice_switch_info *sw = hw->switch_info; 7064 bool is_root, idx_found = false; 7065 struct ice_sw_recipe *recp; 7066 u16 idx, buf_idx = 0; 7067 7068 /* find buffer index for copying some data */ 7069 for (idx = 0; idx < rm->n_grp_count; idx++) 7070 if (buf[idx].recipe_indx == entry->rid) { 7071 buf_idx = idx; 7072 idx_found = true; 7073 } 7074 7075 if (!idx_found) { 7076 status = ICE_ERR_OUT_OF_RANGE; 7077 goto err_unroll; 7078 } 7079 7080 recp = &sw->recp_list[entry->rid]; 7081 is_root = (rm->root_rid == entry->rid); 7082 recp->is_root = is_root; 7083 7084 recp->root_rid = entry->rid; 7085 recp->big_recp = (is_root && rm->n_grp_count > 1); 7086 7087 ice_memcpy(&recp->ext_words, entry->r_group.pairs, 7088 entry->r_group.n_val_pairs * 7089 sizeof(struct ice_fv_word), 7090 ICE_NONDMA_TO_NONDMA); 7091 7092 ice_memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap, 7093 sizeof(recp->r_bitmap), ICE_NONDMA_TO_NONDMA); 7094 7095 /* Copy non-result fv index values and masks to recipe. This 7096 * call will also update the result recipe bitmask. 7097 */ 7098 ice_collect_result_idx(&buf[buf_idx], recp); 7099 7100 /* for non-root recipes, also copy to the root, this allows 7101 * easier matching of a complete chained recipe 7102 */ 7103 if (!is_root) 7104 ice_collect_result_idx(&buf[buf_idx], 7105 &sw->recp_list[rm->root_rid]); 7106 7107 recp->n_ext_words = entry->r_group.n_val_pairs; 7108 recp->chain_idx = entry->chain_idx; 7109 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority; 7110 recp->n_grp_count = rm->n_grp_count; 7111 recp->tun_type = rm->tun_type; 7112 recp->recp_created = true; 7113 } 7114 rm->root_buf = buf; 7115 ice_free(hw, tmp); 7116 return status; 7117 7118 err_unroll: 7119 err_mem: 7120 ice_free(hw, tmp); 7121 ice_free(hw, buf); 7122 return status; 7123 } 7124 7125 /** 7126 * ice_create_recipe_group - creates recipe group 7127 * @hw: pointer to hardware structure 7128 * @rm: recipe management list entry 7129 * @lkup_exts: lookup elements 7130 */ 7131 static enum ice_status 7132 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm, 7133 struct ice_prot_lkup_ext *lkup_exts) 7134 { 7135 enum ice_status status; 7136 u8 recp_count = 0; 7137 7138 rm->n_grp_count = 0; 7139 7140 /* Create recipes for words that are marked not done by packing them 7141 * as best fit. 7142 */ 7143 status = ice_create_first_fit_recp_def(hw, lkup_exts, 7144 &rm->rg_list, &recp_count); 7145 if (!status) { 7146 rm->n_grp_count += recp_count; 7147 rm->n_ext_words = lkup_exts->n_val_words; 7148 ice_memcpy(&rm->ext_words, lkup_exts->fv_words, 7149 sizeof(rm->ext_words), ICE_NONDMA_TO_NONDMA); 7150 ice_memcpy(rm->word_masks, lkup_exts->field_mask, 7151 sizeof(rm->word_masks), ICE_NONDMA_TO_NONDMA); 7152 } 7153 7154 return status; 7155 } 7156 7157 /** 7158 * ice_get_fv - get field vectors/extraction sequences for spec. lookup types 7159 * @hw: pointer to hardware structure 7160 * @lkups: lookup elements or match criteria for the advanced recipe, one 7161 * structure per protocol header 7162 * @lkups_cnt: number of protocols 7163 * @bm: bitmap of field vectors to consider 7164 * @fv_list: pointer to a list that holds the returned field vectors 7165 */ 7166 static enum ice_status 7167 ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 7168 ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list) 7169 { 7170 enum ice_status status; 7171 u8 *prot_ids; 7172 u16 i; 7173 7174 if (!lkups_cnt) 7175 return ICE_SUCCESS; 7176 7177 prot_ids = (u8 *)ice_calloc(hw, lkups_cnt, sizeof(*prot_ids)); 7178 if (!prot_ids) 7179 return ICE_ERR_NO_MEMORY; 7180 7181 for (i = 0; i < lkups_cnt; i++) 7182 if (!ice_prot_type_to_id(lkups[i].type, &prot_ids[i])) { 7183 status = ICE_ERR_CFG; 7184 goto free_mem; 7185 } 7186 7187 /* Find field vectors that include all specified protocol types */ 7188 status = ice_get_sw_fv_list(hw, prot_ids, lkups_cnt, bm, fv_list); 7189 7190 free_mem: 7191 ice_free(hw, prot_ids); 7192 return status; 7193 } 7194 7195 /** 7196 * ice_tun_type_match_mask - determine if tun type needs a match mask 7197 * @tun_type: tunnel type 7198 * @mask: mask to be used for the tunnel 7199 */ 7200 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) 7201 { 7202 switch (tun_type) { 7203 case ICE_SW_TUN_VXLAN_GPE: 7204 case ICE_SW_TUN_GENEVE: 7205 case ICE_SW_TUN_VXLAN: 7206 case ICE_SW_TUN_NVGRE: 7207 case ICE_SW_TUN_UDP: 7208 case ICE_ALL_TUNNELS: 7209 case ICE_SW_TUN_AND_NON_TUN_QINQ: 7210 case ICE_NON_TUN_QINQ: 7211 case ICE_SW_TUN_PPPOE_QINQ: 7212 case ICE_SW_TUN_PPPOE_PAY_QINQ: 7213 case ICE_SW_TUN_PPPOE_IPV4_QINQ: 7214 case ICE_SW_TUN_PPPOE_IPV6_QINQ: 7215 *mask = ICE_TUN_FLAG_MASK; 7216 return true; 7217 7218 case ICE_SW_TUN_GENEVE_VLAN: 7219 case ICE_SW_TUN_VXLAN_VLAN: 7220 *mask = ICE_TUN_FLAG_MASK & ~ICE_TUN_FLAG_VLAN_MASK; 7221 return true; 7222 7223 default: 7224 *mask = 0; 7225 return false; 7226 } 7227 } 7228 7229 /** 7230 * ice_add_special_words - Add words that are not protocols, such as metadata 7231 * @rinfo: other information regarding the rule e.g. priority and action info 7232 * @lkup_exts: lookup word structure 7233 */ 7234 static enum ice_status 7235 ice_add_special_words(struct ice_adv_rule_info *rinfo, 7236 struct ice_prot_lkup_ext *lkup_exts) 7237 { 7238 u16 mask; 7239 7240 /* If this is a tunneled packet, then add recipe index to match the 7241 * tunnel bit in the packet metadata flags. 7242 */ 7243 if (ice_tun_type_match_word(rinfo->tun_type, &mask)) { 7244 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) { 7245 u8 word = lkup_exts->n_val_words++; 7246 7247 lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW; 7248 lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF; 7249 lkup_exts->field_mask[word] = mask; 7250 } else { 7251 return ICE_ERR_MAX_LIMIT; 7252 } 7253 } 7254 7255 return ICE_SUCCESS; 7256 } 7257 7258 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule 7259 * @hw: pointer to hardware structure 7260 * @rinfo: other information regarding the rule e.g. priority and action info 7261 * @bm: pointer to memory for returning the bitmap of field vectors 7262 */ 7263 static void 7264 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, 7265 ice_bitmap_t *bm) 7266 { 7267 enum ice_prof_type prof_type; 7268 7269 ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES); 7270 7271 switch (rinfo->tun_type) { 7272 case ICE_NON_TUN: 7273 case ICE_NON_TUN_QINQ: 7274 prof_type = ICE_PROF_NON_TUN; 7275 break; 7276 case ICE_ALL_TUNNELS: 7277 prof_type = ICE_PROF_TUN_ALL; 7278 break; 7279 case ICE_SW_TUN_VXLAN_GPE: 7280 case ICE_SW_TUN_GENEVE: 7281 case ICE_SW_TUN_GENEVE_VLAN: 7282 case ICE_SW_TUN_VXLAN: 7283 case ICE_SW_TUN_VXLAN_VLAN: 7284 case ICE_SW_TUN_UDP: 7285 case ICE_SW_TUN_GTP: 7286 prof_type = ICE_PROF_TUN_UDP; 7287 break; 7288 case ICE_SW_TUN_NVGRE: 7289 prof_type = ICE_PROF_TUN_GRE; 7290 break; 7291 case ICE_SW_TUN_PPPOE: 7292 case ICE_SW_TUN_PPPOE_QINQ: 7293 prof_type = ICE_PROF_TUN_PPPOE; 7294 break; 7295 case ICE_SW_TUN_PPPOE_PAY: 7296 case ICE_SW_TUN_PPPOE_PAY_QINQ: 7297 ice_set_bit(ICE_PROFID_PPPOE_PAY, bm); 7298 return; 7299 case ICE_SW_TUN_PPPOE_IPV4: 7300 case ICE_SW_TUN_PPPOE_IPV4_QINQ: 7301 ice_set_bit(ICE_PROFID_PPPOE_IPV4_OTHER, bm); 7302 ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm); 7303 ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm); 7304 return; 7305 case ICE_SW_TUN_PPPOE_IPV4_TCP: 7306 ice_set_bit(ICE_PROFID_PPPOE_IPV4_TCP, bm); 7307 return; 7308 case ICE_SW_TUN_PPPOE_IPV4_UDP: 7309 ice_set_bit(ICE_PROFID_PPPOE_IPV4_UDP, bm); 7310 return; 7311 case ICE_SW_TUN_PPPOE_IPV6: 7312 case ICE_SW_TUN_PPPOE_IPV6_QINQ: 7313 ice_set_bit(ICE_PROFID_PPPOE_IPV6_OTHER, bm); 7314 ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm); 7315 ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm); 7316 return; 7317 case ICE_SW_TUN_PPPOE_IPV6_TCP: 7318 ice_set_bit(ICE_PROFID_PPPOE_IPV6_TCP, bm); 7319 return; 7320 case ICE_SW_TUN_PPPOE_IPV6_UDP: 7321 ice_set_bit(ICE_PROFID_PPPOE_IPV6_UDP, bm); 7322 return; 7323 case ICE_SW_TUN_PROFID_IPV6_ESP: 7324 case ICE_SW_TUN_IPV6_ESP: 7325 ice_set_bit(ICE_PROFID_IPV6_ESP, bm); 7326 return; 7327 case ICE_SW_TUN_PROFID_IPV6_AH: 7328 case ICE_SW_TUN_IPV6_AH: 7329 ice_set_bit(ICE_PROFID_IPV6_AH, bm); 7330 return; 7331 case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3: 7332 case ICE_SW_TUN_IPV6_L2TPV3: 7333 ice_set_bit(ICE_PROFID_MAC_IPV6_L2TPV3, bm); 7334 return; 7335 case ICE_SW_TUN_PROFID_IPV6_NAT_T: 7336 case ICE_SW_TUN_IPV6_NAT_T: 7337 ice_set_bit(ICE_PROFID_IPV6_NAT_T, bm); 7338 return; 7339 case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE: 7340 ice_set_bit(ICE_PROFID_IPV4_PFCP_NODE, bm); 7341 return; 7342 case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION: 7343 ice_set_bit(ICE_PROFID_IPV4_PFCP_SESSION, bm); 7344 return; 7345 case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE: 7346 ice_set_bit(ICE_PROFID_IPV6_PFCP_NODE, bm); 7347 return; 7348 case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION: 7349 ice_set_bit(ICE_PROFID_IPV6_PFCP_SESSION, bm); 7350 return; 7351 case ICE_SW_TUN_IPV4_NAT_T: 7352 ice_set_bit(ICE_PROFID_IPV4_NAT_T, bm); 7353 return; 7354 case ICE_SW_TUN_IPV4_L2TPV3: 7355 ice_set_bit(ICE_PROFID_MAC_IPV4_L2TPV3, bm); 7356 return; 7357 case ICE_SW_TUN_IPV4_ESP: 7358 ice_set_bit(ICE_PROFID_IPV4_ESP, bm); 7359 return; 7360 case ICE_SW_TUN_IPV4_AH: 7361 ice_set_bit(ICE_PROFID_IPV4_AH, bm); 7362 return; 7363 case ICE_SW_IPV4_TCP: 7364 ice_set_bit(ICE_PROFID_IPV4_TCP, bm); 7365 return; 7366 case ICE_SW_IPV4_UDP: 7367 ice_set_bit(ICE_PROFID_IPV4_UDP, bm); 7368 return; 7369 case ICE_SW_IPV6_TCP: 7370 ice_set_bit(ICE_PROFID_IPV6_TCP, bm); 7371 return; 7372 case ICE_SW_IPV6_UDP: 7373 ice_set_bit(ICE_PROFID_IPV6_UDP, bm); 7374 return; 7375 case ICE_SW_TUN_IPV4_GTPU_IPV4: 7376 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_OTHER, bm); 7377 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_OTHER, bm); 7378 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_UDP, bm); 7379 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_UDP, bm); 7380 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV4_TCP, bm); 7381 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV4_TCP, bm); 7382 return; 7383 case ICE_SW_TUN_IPV6_GTPU_IPV4: 7384 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_OTHER, bm); 7385 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_OTHER, bm); 7386 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_UDP, bm); 7387 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_UDP, bm); 7388 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV4_TCP, bm); 7389 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV4_TCP, bm); 7390 return; 7391 case ICE_SW_TUN_IPV4_GTPU_IPV6: 7392 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_OTHER, bm); 7393 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_OTHER, bm); 7394 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_UDP, bm); 7395 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_UDP, bm); 7396 ice_set_bit(ICE_PROFID_IPV4_GTPU_EH_IPV6_TCP, bm); 7397 ice_set_bit(ICE_PROFID_IPV4_GTPU_IPV6_TCP, bm); 7398 return; 7399 case ICE_SW_TUN_IPV6_GTPU_IPV6: 7400 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_OTHER, bm); 7401 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_OTHER, bm); 7402 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_UDP, bm); 7403 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_UDP, bm); 7404 ice_set_bit(ICE_PROFID_IPV6_GTPU_EH_IPV6_TCP, bm); 7405 ice_set_bit(ICE_PROFID_IPV6_GTPU_IPV6_TCP, bm); 7406 return; 7407 case ICE_SW_TUN_AND_NON_TUN: 7408 case ICE_SW_TUN_AND_NON_TUN_QINQ: 7409 default: 7410 prof_type = ICE_PROF_ALL; 7411 break; 7412 } 7413 7414 ice_get_sw_fv_bitmap(hw, prof_type, bm); 7415 } 7416 7417 /** 7418 * ice_is_prof_rule - determine if rule type is a profile rule 7419 * @type: the rule type 7420 * 7421 * if the rule type is a profile rule, that means that there no field value 7422 * match required, in this case just a profile hit is required. 7423 */ 7424 bool ice_is_prof_rule(enum ice_sw_tunnel_type type) 7425 { 7426 switch (type) { 7427 case ICE_SW_TUN_PROFID_IPV6_ESP: 7428 case ICE_SW_TUN_PROFID_IPV6_AH: 7429 case ICE_SW_TUN_PROFID_MAC_IPV6_L2TPV3: 7430 case ICE_SW_TUN_PROFID_IPV6_NAT_T: 7431 case ICE_SW_TUN_PROFID_IPV4_PFCP_NODE: 7432 case ICE_SW_TUN_PROFID_IPV4_PFCP_SESSION: 7433 case ICE_SW_TUN_PROFID_IPV6_PFCP_NODE: 7434 case ICE_SW_TUN_PROFID_IPV6_PFCP_SESSION: 7435 return true; 7436 default: 7437 break; 7438 } 7439 7440 return false; 7441 } 7442 7443 /** 7444 * ice_add_adv_recipe - Add an advanced recipe that is not part of the default 7445 * @hw: pointer to hardware structure 7446 * @lkups: lookup elements or match criteria for the advanced recipe, one 7447 * structure per protocol header 7448 * @lkups_cnt: number of protocols 7449 * @rinfo: other information regarding the rule e.g. priority and action info 7450 * @rid: return the recipe ID of the recipe created 7451 */ 7452 static enum ice_status 7453 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 7454 u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid) 7455 { 7456 ice_declare_bitmap(fv_bitmap, ICE_MAX_NUM_PROFILES); 7457 ice_declare_bitmap(profiles, ICE_MAX_NUM_PROFILES); 7458 struct ice_prot_lkup_ext *lkup_exts; 7459 struct ice_recp_grp_entry *r_entry; 7460 struct ice_sw_fv_list_entry *fvit; 7461 struct ice_recp_grp_entry *r_tmp; 7462 struct ice_sw_fv_list_entry *tmp; 7463 enum ice_status status = ICE_SUCCESS; 7464 struct ice_sw_recipe *rm; 7465 u8 i; 7466 7467 if (!ice_is_prof_rule(rinfo->tun_type) && !lkups_cnt) 7468 return ICE_ERR_PARAM; 7469 7470 lkup_exts = (struct ice_prot_lkup_ext *) 7471 ice_malloc(hw, sizeof(*lkup_exts)); 7472 if (!lkup_exts) 7473 return ICE_ERR_NO_MEMORY; 7474 7475 /* Determine the number of words to be matched and if it exceeds a 7476 * recipe's restrictions 7477 */ 7478 for (i = 0; i < lkups_cnt; i++) { 7479 u16 count; 7480 7481 if (lkups[i].type >= ICE_PROTOCOL_LAST) { 7482 status = ICE_ERR_CFG; 7483 goto err_free_lkup_exts; 7484 } 7485 7486 count = ice_fill_valid_words(&lkups[i], lkup_exts); 7487 if (!count) { 7488 status = ICE_ERR_CFG; 7489 goto err_free_lkup_exts; 7490 } 7491 } 7492 7493 rm = (struct ice_sw_recipe *)ice_malloc(hw, sizeof(*rm)); 7494 if (!rm) { 7495 status = ICE_ERR_NO_MEMORY; 7496 goto err_free_lkup_exts; 7497 } 7498 7499 /* Get field vectors that contain fields extracted from all the protocol 7500 * headers being programmed. 7501 */ 7502 INIT_LIST_HEAD(&rm->fv_list); 7503 INIT_LIST_HEAD(&rm->rg_list); 7504 7505 /* Get bitmap of field vectors (profiles) that are compatible with the 7506 * rule request; only these will be searched in the subsequent call to 7507 * ice_get_fv. 7508 */ 7509 ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); 7510 7511 status = ice_get_fv(hw, lkups, lkups_cnt, fv_bitmap, &rm->fv_list); 7512 if (status) 7513 goto err_unroll; 7514 7515 /* Create any special protocol/offset pairs, such as looking at tunnel 7516 * bits by extracting metadata 7517 */ 7518 status = ice_add_special_words(rinfo, lkup_exts); 7519 if (status) 7520 goto err_free_lkup_exts; 7521 7522 /* Group match words into recipes using preferred recipe grouping 7523 * criteria. 7524 */ 7525 status = ice_create_recipe_group(hw, rm, lkup_exts); 7526 if (status) 7527 goto err_unroll; 7528 7529 /* set the recipe priority if specified */ 7530 rm->priority = (u8)rinfo->priority; 7531 7532 /* Find offsets from the field vector. Pick the first one for all the 7533 * recipes. 7534 */ 7535 status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list); 7536 if (status) 7537 goto err_unroll; 7538 7539 /* An empty FV list means to use all the profiles returned in the 7540 * profile bitmap 7541 */ 7542 if (LIST_EMPTY(&rm->fv_list)) { 7543 u16 j; 7544 7545 ice_for_each_set_bit(j, fv_bitmap, ICE_MAX_NUM_PROFILES) { 7546 struct ice_sw_fv_list_entry *fvl; 7547 7548 fvl = (struct ice_sw_fv_list_entry *) 7549 ice_malloc(hw, sizeof(*fvl)); 7550 if (!fvl) 7551 goto err_unroll; 7552 fvl->fv_ptr = NULL; 7553 fvl->profile_id = j; 7554 LIST_ADD(&fvl->list_entry, &rm->fv_list); 7555 } 7556 } 7557 7558 /* get bitmap of all profiles the recipe will be associated with */ 7559 ice_zero_bitmap(profiles, ICE_MAX_NUM_PROFILES); 7560 LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry, 7561 list_entry) { 7562 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id); 7563 ice_set_bit((u16)fvit->profile_id, profiles); 7564 } 7565 7566 /* Look for a recipe which matches our requested fv / mask list */ 7567 *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type); 7568 if (*rid < ICE_MAX_NUM_RECIPES) 7569 /* Success if found a recipe that match the existing criteria */ 7570 goto err_unroll; 7571 7572 rm->tun_type = rinfo->tun_type; 7573 /* Recipe we need does not exist, add a recipe */ 7574 status = ice_add_sw_recipe(hw, rm, profiles); 7575 if (status) 7576 goto err_unroll; 7577 7578 /* Associate all the recipes created with all the profiles in the 7579 * common field vector. 7580 */ 7581 LIST_FOR_EACH_ENTRY(fvit, &rm->fv_list, ice_sw_fv_list_entry, 7582 list_entry) { 7583 ice_declare_bitmap(r_bitmap, ICE_MAX_NUM_RECIPES); 7584 u16 j; 7585 7586 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id, 7587 (u8 *)r_bitmap, NULL); 7588 if (status) 7589 goto err_unroll; 7590 7591 ice_or_bitmap(r_bitmap, r_bitmap, rm->r_bitmap, 7592 ICE_MAX_NUM_RECIPES); 7593 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 7594 if (status) 7595 goto err_unroll; 7596 7597 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id, 7598 (u8 *)r_bitmap, 7599 NULL); 7600 ice_release_change_lock(hw); 7601 7602 if (status) 7603 goto err_unroll; 7604 7605 /* Update profile to recipe bitmap array */ 7606 ice_cp_bitmap(profile_to_recipe[fvit->profile_id], r_bitmap, 7607 ICE_MAX_NUM_RECIPES); 7608 7609 /* Update recipe to profile bitmap array */ 7610 ice_for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES) 7611 ice_set_bit((u16)fvit->profile_id, 7612 recipe_to_profile[j]); 7613 } 7614 7615 *rid = rm->root_rid; 7616 ice_memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, 7617 lkup_exts, sizeof(*lkup_exts), ICE_NONDMA_TO_NONDMA); 7618 err_unroll: 7619 LIST_FOR_EACH_ENTRY_SAFE(r_entry, r_tmp, &rm->rg_list, 7620 ice_recp_grp_entry, l_entry) { 7621 LIST_DEL(&r_entry->l_entry); 7622 ice_free(hw, r_entry); 7623 } 7624 7625 LIST_FOR_EACH_ENTRY_SAFE(fvit, tmp, &rm->fv_list, ice_sw_fv_list_entry, 7626 list_entry) { 7627 LIST_DEL(&fvit->list_entry); 7628 ice_free(hw, fvit); 7629 } 7630 7631 if (rm->root_buf) 7632 ice_free(hw, rm->root_buf); 7633 7634 ice_free(hw, rm); 7635 7636 err_free_lkup_exts: 7637 ice_free(hw, lkup_exts); 7638 7639 return status; 7640 } 7641 7642 /** 7643 * ice_find_dummy_packet - find dummy packet by tunnel type 7644 * 7645 * @lkups: lookup elements or match criteria for the advanced recipe, one 7646 * structure per protocol header 7647 * @lkups_cnt: number of protocols 7648 * @tun_type: tunnel type from the match criteria 7649 * @pkt: dummy packet to fill according to filter match criteria 7650 * @pkt_len: packet length of dummy packet 7651 * @offsets: pointer to receive the pointer to the offsets for the packet 7652 */ 7653 static void 7654 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 7655 enum ice_sw_tunnel_type tun_type, const u8 **pkt, 7656 u16 *pkt_len, 7657 const struct ice_dummy_pkt_offsets **offsets) 7658 { 7659 bool tcp = false, udp = false, ipv6 = false, vlan = false; 7660 bool gre = false; 7661 u16 i; 7662 7663 for (i = 0; i < lkups_cnt; i++) { 7664 if (lkups[i].type == ICE_UDP_ILOS) 7665 udp = true; 7666 else if (lkups[i].type == ICE_TCP_IL) 7667 tcp = true; 7668 else if (lkups[i].type == ICE_IPV6_OFOS) 7669 ipv6 = true; 7670 else if (lkups[i].type == ICE_VLAN_OFOS) 7671 vlan = true; 7672 else if (lkups[i].type == ICE_IPV4_OFOS && 7673 lkups[i].h_u.ipv4_hdr.protocol == 7674 ICE_IPV4_NVGRE_PROTO_ID && 7675 lkups[i].m_u.ipv4_hdr.protocol == 7676 0xFF) 7677 gre = true; 7678 else if (lkups[i].type == ICE_PPPOE && 7679 lkups[i].h_u.pppoe_hdr.ppp_prot_id == 7680 CPU_TO_BE16(ICE_PPP_IPV6_PROTO_ID) && 7681 lkups[i].m_u.pppoe_hdr.ppp_prot_id == 7682 0xFFFF) 7683 ipv6 = true; 7684 else if (lkups[i].type == ICE_ETYPE_OL && 7685 lkups[i].h_u.ethertype.ethtype_id == 7686 CPU_TO_BE16(ICE_IPV6_ETHER_ID) && 7687 lkups[i].m_u.ethertype.ethtype_id == 7688 0xFFFF) 7689 ipv6 = true; 7690 else if (lkups[i].type == ICE_IPV4_IL && 7691 lkups[i].h_u.ipv4_hdr.protocol == 7692 ICE_TCP_PROTO_ID && 7693 lkups[i].m_u.ipv4_hdr.protocol == 7694 0xFF) 7695 tcp = true; 7696 } 7697 7698 if ((tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ || 7699 tun_type == ICE_NON_TUN_QINQ) && ipv6) { 7700 *pkt = dummy_qinq_ipv6_pkt; 7701 *pkt_len = sizeof(dummy_qinq_ipv6_pkt); 7702 *offsets = dummy_qinq_ipv6_packet_offsets; 7703 return; 7704 } else if (tun_type == ICE_SW_TUN_AND_NON_TUN_QINQ || 7705 tun_type == ICE_NON_TUN_QINQ) { 7706 *pkt = dummy_qinq_ipv4_pkt; 7707 *pkt_len = sizeof(dummy_qinq_ipv4_pkt); 7708 *offsets = dummy_qinq_ipv4_packet_offsets; 7709 return; 7710 } 7711 7712 if (tun_type == ICE_SW_TUN_PPPOE_IPV6_QINQ) { 7713 *pkt = dummy_qinq_pppoe_ipv6_packet; 7714 *pkt_len = sizeof(dummy_qinq_pppoe_ipv6_packet); 7715 *offsets = dummy_qinq_pppoe_packet_ipv6_offsets; 7716 return; 7717 } else if (tun_type == ICE_SW_TUN_PPPOE_IPV4_QINQ) { 7718 *pkt = dummy_qinq_pppoe_ipv4_pkt; 7719 *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt); 7720 *offsets = dummy_qinq_pppoe_ipv4_packet_offsets; 7721 return; 7722 } else if (tun_type == ICE_SW_TUN_PPPOE_QINQ || 7723 tun_type == ICE_SW_TUN_PPPOE_PAY_QINQ) { 7724 *pkt = dummy_qinq_pppoe_ipv4_pkt; 7725 *pkt_len = sizeof(dummy_qinq_pppoe_ipv4_pkt); 7726 *offsets = dummy_qinq_pppoe_packet_offsets; 7727 return; 7728 } 7729 7730 if (tun_type == ICE_SW_TUN_IPV4_GTPU_NO_PAY) { 7731 *pkt = dummy_ipv4_gtpu_ipv4_packet; 7732 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet); 7733 *offsets = dummy_ipv4_gtp_no_pay_packet_offsets; 7734 return; 7735 } else if (tun_type == ICE_SW_TUN_IPV6_GTPU_NO_PAY) { 7736 *pkt = dummy_ipv6_gtpu_ipv6_packet; 7737 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet); 7738 *offsets = dummy_ipv6_gtp_no_pay_packet_offsets; 7739 return; 7740 } else if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV4) { 7741 *pkt = dummy_ipv4_gtpu_ipv4_packet; 7742 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv4_packet); 7743 *offsets = dummy_ipv4_gtpu_ipv4_packet_offsets; 7744 return; 7745 } else if (tun_type == ICE_SW_TUN_IPV4_GTPU_IPV6) { 7746 *pkt = dummy_ipv4_gtpu_ipv6_packet; 7747 *pkt_len = sizeof(dummy_ipv4_gtpu_ipv6_packet); 7748 *offsets = dummy_ipv4_gtpu_ipv6_packet_offsets; 7749 return; 7750 } else if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV4) { 7751 *pkt = dummy_ipv6_gtpu_ipv4_packet; 7752 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv4_packet); 7753 *offsets = dummy_ipv6_gtpu_ipv4_packet_offsets; 7754 return; 7755 } else if (tun_type == ICE_SW_TUN_IPV6_GTPU_IPV6) { 7756 *pkt = dummy_ipv6_gtpu_ipv6_packet; 7757 *pkt_len = sizeof(dummy_ipv6_gtpu_ipv6_packet); 7758 *offsets = dummy_ipv6_gtpu_ipv6_packet_offsets; 7759 return; 7760 } 7761 7762 if (tun_type == ICE_SW_TUN_IPV4_ESP) { 7763 *pkt = dummy_ipv4_esp_pkt; 7764 *pkt_len = sizeof(dummy_ipv4_esp_pkt); 7765 *offsets = dummy_ipv4_esp_packet_offsets; 7766 return; 7767 } 7768 7769 if (tun_type == ICE_SW_TUN_IPV6_ESP) { 7770 *pkt = dummy_ipv6_esp_pkt; 7771 *pkt_len = sizeof(dummy_ipv6_esp_pkt); 7772 *offsets = dummy_ipv6_esp_packet_offsets; 7773 return; 7774 } 7775 7776 if (tun_type == ICE_SW_TUN_IPV4_AH) { 7777 *pkt = dummy_ipv4_ah_pkt; 7778 *pkt_len = sizeof(dummy_ipv4_ah_pkt); 7779 *offsets = dummy_ipv4_ah_packet_offsets; 7780 return; 7781 } 7782 7783 if (tun_type == ICE_SW_TUN_IPV6_AH) { 7784 *pkt = dummy_ipv6_ah_pkt; 7785 *pkt_len = sizeof(dummy_ipv6_ah_pkt); 7786 *offsets = dummy_ipv6_ah_packet_offsets; 7787 return; 7788 } 7789 7790 if (tun_type == ICE_SW_TUN_IPV4_NAT_T) { 7791 *pkt = dummy_ipv4_nat_pkt; 7792 *pkt_len = sizeof(dummy_ipv4_nat_pkt); 7793 *offsets = dummy_ipv4_nat_packet_offsets; 7794 return; 7795 } 7796 7797 if (tun_type == ICE_SW_TUN_IPV6_NAT_T) { 7798 *pkt = dummy_ipv6_nat_pkt; 7799 *pkt_len = sizeof(dummy_ipv6_nat_pkt); 7800 *offsets = dummy_ipv6_nat_packet_offsets; 7801 return; 7802 } 7803 7804 if (tun_type == ICE_SW_TUN_IPV4_L2TPV3) { 7805 *pkt = dummy_ipv4_l2tpv3_pkt; 7806 *pkt_len = sizeof(dummy_ipv4_l2tpv3_pkt); 7807 *offsets = dummy_ipv4_l2tpv3_packet_offsets; 7808 return; 7809 } 7810 7811 if (tun_type == ICE_SW_TUN_IPV6_L2TPV3) { 7812 *pkt = dummy_ipv6_l2tpv3_pkt; 7813 *pkt_len = sizeof(dummy_ipv6_l2tpv3_pkt); 7814 *offsets = dummy_ipv6_l2tpv3_packet_offsets; 7815 return; 7816 } 7817 7818 if (tun_type == ICE_SW_TUN_GTP) { 7819 *pkt = dummy_udp_gtp_packet; 7820 *pkt_len = sizeof(dummy_udp_gtp_packet); 7821 *offsets = dummy_udp_gtp_packet_offsets; 7822 return; 7823 } 7824 7825 if (tun_type == ICE_SW_TUN_PPPOE && ipv6) { 7826 *pkt = dummy_pppoe_ipv6_packet; 7827 *pkt_len = sizeof(dummy_pppoe_ipv6_packet); 7828 *offsets = dummy_pppoe_packet_offsets; 7829 return; 7830 } else if (tun_type == ICE_SW_TUN_PPPOE || 7831 tun_type == ICE_SW_TUN_PPPOE_PAY) { 7832 *pkt = dummy_pppoe_ipv4_packet; 7833 *pkt_len = sizeof(dummy_pppoe_ipv4_packet); 7834 *offsets = dummy_pppoe_packet_offsets; 7835 return; 7836 } 7837 7838 if (tun_type == ICE_SW_TUN_PPPOE_IPV4) { 7839 *pkt = dummy_pppoe_ipv4_packet; 7840 *pkt_len = sizeof(dummy_pppoe_ipv4_packet); 7841 *offsets = dummy_pppoe_packet_ipv4_offsets; 7842 return; 7843 } 7844 7845 if (tun_type == ICE_SW_TUN_PPPOE_IPV4_TCP) { 7846 *pkt = dummy_pppoe_ipv4_tcp_packet; 7847 *pkt_len = sizeof(dummy_pppoe_ipv4_tcp_packet); 7848 *offsets = dummy_pppoe_ipv4_tcp_packet_offsets; 7849 return; 7850 } 7851 7852 if (tun_type == ICE_SW_TUN_PPPOE_IPV4_UDP) { 7853 *pkt = dummy_pppoe_ipv4_udp_packet; 7854 *pkt_len = sizeof(dummy_pppoe_ipv4_udp_packet); 7855 *offsets = dummy_pppoe_ipv4_udp_packet_offsets; 7856 return; 7857 } 7858 7859 if (tun_type == ICE_SW_TUN_PPPOE_IPV6) { 7860 *pkt = dummy_pppoe_ipv6_packet; 7861 *pkt_len = sizeof(dummy_pppoe_ipv6_packet); 7862 *offsets = dummy_pppoe_packet_ipv6_offsets; 7863 return; 7864 } 7865 7866 if (tun_type == ICE_SW_TUN_PPPOE_IPV6_TCP) { 7867 *pkt = dummy_pppoe_ipv6_tcp_packet; 7868 *pkt_len = sizeof(dummy_pppoe_ipv6_tcp_packet); 7869 *offsets = dummy_pppoe_packet_ipv6_tcp_offsets; 7870 return; 7871 } 7872 7873 if (tun_type == ICE_SW_TUN_PPPOE_IPV6_UDP) { 7874 *pkt = dummy_pppoe_ipv6_udp_packet; 7875 *pkt_len = sizeof(dummy_pppoe_ipv6_udp_packet); 7876 *offsets = dummy_pppoe_packet_ipv6_udp_offsets; 7877 return; 7878 } 7879 7880 if (tun_type == ICE_SW_IPV4_TCP) { 7881 *pkt = dummy_tcp_packet; 7882 *pkt_len = sizeof(dummy_tcp_packet); 7883 *offsets = dummy_tcp_packet_offsets; 7884 return; 7885 } 7886 7887 if (tun_type == ICE_SW_IPV4_UDP) { 7888 *pkt = dummy_udp_packet; 7889 *pkt_len = sizeof(dummy_udp_packet); 7890 *offsets = dummy_udp_packet_offsets; 7891 return; 7892 } 7893 7894 if (tun_type == ICE_SW_IPV6_TCP) { 7895 *pkt = dummy_tcp_ipv6_packet; 7896 *pkt_len = sizeof(dummy_tcp_ipv6_packet); 7897 *offsets = dummy_tcp_ipv6_packet_offsets; 7898 return; 7899 } 7900 7901 if (tun_type == ICE_SW_IPV6_UDP) { 7902 *pkt = dummy_udp_ipv6_packet; 7903 *pkt_len = sizeof(dummy_udp_ipv6_packet); 7904 *offsets = dummy_udp_ipv6_packet_offsets; 7905 return; 7906 } 7907 7908 if (tun_type == ICE_ALL_TUNNELS) { 7909 *pkt = dummy_gre_udp_packet; 7910 *pkt_len = sizeof(dummy_gre_udp_packet); 7911 *offsets = dummy_gre_udp_packet_offsets; 7912 return; 7913 } 7914 7915 if (tun_type == ICE_SW_TUN_NVGRE || gre) { 7916 if (tcp) { 7917 *pkt = dummy_gre_tcp_packet; 7918 *pkt_len = sizeof(dummy_gre_tcp_packet); 7919 *offsets = dummy_gre_tcp_packet_offsets; 7920 return; 7921 } 7922 7923 *pkt = dummy_gre_udp_packet; 7924 *pkt_len = sizeof(dummy_gre_udp_packet); 7925 *offsets = dummy_gre_udp_packet_offsets; 7926 return; 7927 } 7928 7929 if (tun_type == ICE_SW_TUN_VXLAN || tun_type == ICE_SW_TUN_GENEVE || 7930 tun_type == ICE_SW_TUN_VXLAN_GPE || tun_type == ICE_SW_TUN_UDP || 7931 tun_type == ICE_SW_TUN_GENEVE_VLAN || 7932 tun_type == ICE_SW_TUN_VXLAN_VLAN) { 7933 if (tcp) { 7934 *pkt = dummy_udp_tun_tcp_packet; 7935 *pkt_len = sizeof(dummy_udp_tun_tcp_packet); 7936 *offsets = dummy_udp_tun_tcp_packet_offsets; 7937 return; 7938 } 7939 7940 *pkt = dummy_udp_tun_udp_packet; 7941 *pkt_len = sizeof(dummy_udp_tun_udp_packet); 7942 *offsets = dummy_udp_tun_udp_packet_offsets; 7943 return; 7944 } 7945 7946 if (udp && !ipv6) { 7947 if (vlan) { 7948 *pkt = dummy_vlan_udp_packet; 7949 *pkt_len = sizeof(dummy_vlan_udp_packet); 7950 *offsets = dummy_vlan_udp_packet_offsets; 7951 return; 7952 } 7953 *pkt = dummy_udp_packet; 7954 *pkt_len = sizeof(dummy_udp_packet); 7955 *offsets = dummy_udp_packet_offsets; 7956 return; 7957 } else if (udp && ipv6) { 7958 if (vlan) { 7959 *pkt = dummy_vlan_udp_ipv6_packet; 7960 *pkt_len = sizeof(dummy_vlan_udp_ipv6_packet); 7961 *offsets = dummy_vlan_udp_ipv6_packet_offsets; 7962 return; 7963 } 7964 *pkt = dummy_udp_ipv6_packet; 7965 *pkt_len = sizeof(dummy_udp_ipv6_packet); 7966 *offsets = dummy_udp_ipv6_packet_offsets; 7967 return; 7968 } else if ((tcp && ipv6) || ipv6) { 7969 if (vlan) { 7970 *pkt = dummy_vlan_tcp_ipv6_packet; 7971 *pkt_len = sizeof(dummy_vlan_tcp_ipv6_packet); 7972 *offsets = dummy_vlan_tcp_ipv6_packet_offsets; 7973 return; 7974 } 7975 *pkt = dummy_tcp_ipv6_packet; 7976 *pkt_len = sizeof(dummy_tcp_ipv6_packet); 7977 *offsets = dummy_tcp_ipv6_packet_offsets; 7978 return; 7979 } 7980 7981 if (vlan) { 7982 *pkt = dummy_vlan_tcp_packet; 7983 *pkt_len = sizeof(dummy_vlan_tcp_packet); 7984 *offsets = dummy_vlan_tcp_packet_offsets; 7985 } else { 7986 *pkt = dummy_tcp_packet; 7987 *pkt_len = sizeof(dummy_tcp_packet); 7988 *offsets = dummy_tcp_packet_offsets; 7989 } 7990 } 7991 7992 /** 7993 * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria 7994 * 7995 * @lkups: lookup elements or match criteria for the advanced recipe, one 7996 * structure per protocol header 7997 * @lkups_cnt: number of protocols 7998 * @s_rule: stores rule information from the match criteria 7999 * @dummy_pkt: dummy packet to fill according to filter match criteria 8000 * @pkt_len: packet length of dummy packet 8001 * @offsets: offset info for the dummy packet 8002 */ 8003 static enum ice_status 8004 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 8005 struct ice_aqc_sw_rules_elem *s_rule, 8006 const u8 *dummy_pkt, u16 pkt_len, 8007 const struct ice_dummy_pkt_offsets *offsets) 8008 { 8009 u8 *pkt; 8010 u16 i; 8011 8012 /* Start with a packet with a pre-defined/dummy content. Then, fill 8013 * in the header values to be looked up or matched. 8014 */ 8015 pkt = s_rule->pdata.lkup_tx_rx.hdr; 8016 8017 ice_memcpy(pkt, dummy_pkt, pkt_len, ICE_NONDMA_TO_NONDMA); 8018 8019 for (i = 0; i < lkups_cnt; i++) { 8020 enum ice_protocol_type type; 8021 u16 offset = 0, len = 0, j; 8022 bool found = false; 8023 8024 /* find the start of this layer; it should be found since this 8025 * was already checked when search for the dummy packet 8026 */ 8027 type = lkups[i].type; 8028 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) { 8029 if (type == offsets[j].type) { 8030 offset = offsets[j].offset; 8031 found = true; 8032 break; 8033 } 8034 } 8035 /* this should never happen in a correct calling sequence */ 8036 if (!found) 8037 return ICE_ERR_PARAM; 8038 8039 switch (lkups[i].type) { 8040 case ICE_MAC_OFOS: 8041 case ICE_MAC_IL: 8042 len = sizeof(struct ice_ether_hdr); 8043 break; 8044 case ICE_ETYPE_OL: 8045 len = sizeof(struct ice_ethtype_hdr); 8046 break; 8047 case ICE_VLAN_OFOS: 8048 case ICE_VLAN_EX: 8049 len = sizeof(struct ice_vlan_hdr); 8050 break; 8051 case ICE_IPV4_OFOS: 8052 case ICE_IPV4_IL: 8053 len = sizeof(struct ice_ipv4_hdr); 8054 break; 8055 case ICE_IPV6_OFOS: 8056 case ICE_IPV6_IL: 8057 len = sizeof(struct ice_ipv6_hdr); 8058 break; 8059 case ICE_TCP_IL: 8060 case ICE_UDP_OF: 8061 case ICE_UDP_ILOS: 8062 len = sizeof(struct ice_l4_hdr); 8063 break; 8064 case ICE_SCTP_IL: 8065 len = sizeof(struct ice_sctp_hdr); 8066 break; 8067 case ICE_NVGRE: 8068 len = sizeof(struct ice_nvgre); 8069 break; 8070 case ICE_VXLAN: 8071 case ICE_GENEVE: 8072 case ICE_VXLAN_GPE: 8073 len = sizeof(struct ice_udp_tnl_hdr); 8074 break; 8075 8076 case ICE_GTP: 8077 case ICE_GTP_NO_PAY: 8078 len = sizeof(struct ice_udp_gtp_hdr); 8079 break; 8080 case ICE_PPPOE: 8081 len = sizeof(struct ice_pppoe_hdr); 8082 break; 8083 case ICE_ESP: 8084 len = sizeof(struct ice_esp_hdr); 8085 break; 8086 case ICE_NAT_T: 8087 len = sizeof(struct ice_nat_t_hdr); 8088 break; 8089 case ICE_AH: 8090 len = sizeof(struct ice_ah_hdr); 8091 break; 8092 case ICE_L2TPV3: 8093 len = sizeof(struct ice_l2tpv3_sess_hdr); 8094 break; 8095 default: 8096 return ICE_ERR_PARAM; 8097 } 8098 8099 /* the length should be a word multiple */ 8100 if (len % ICE_BYTES_PER_WORD) 8101 return ICE_ERR_CFG; 8102 8103 /* We have the offset to the header start, the length, the 8104 * caller's header values and mask. Use this information to 8105 * copy the data into the dummy packet appropriately based on 8106 * the mask. Note that we need to only write the bits as 8107 * indicated by the mask to make sure we don't improperly write 8108 * over any significant packet data. 8109 */ 8110 for (j = 0; j < len / sizeof(u16); j++) 8111 if (((u16 *)&lkups[i].m_u)[j]) 8112 ((u16 *)(pkt + offset))[j] = 8113 (((u16 *)(pkt + offset))[j] & 8114 ~((u16 *)&lkups[i].m_u)[j]) | 8115 (((u16 *)&lkups[i].h_u)[j] & 8116 ((u16 *)&lkups[i].m_u)[j]); 8117 } 8118 8119 s_rule->pdata.lkup_tx_rx.hdr_len = CPU_TO_LE16(pkt_len); 8120 8121 return ICE_SUCCESS; 8122 } 8123 8124 /** 8125 * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port 8126 * @hw: pointer to the hardware structure 8127 * @tun_type: tunnel type 8128 * @pkt: dummy packet to fill in 8129 * @offsets: offset info for the dummy packet 8130 */ 8131 static enum ice_status 8132 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type, 8133 u8 *pkt, const struct ice_dummy_pkt_offsets *offsets) 8134 { 8135 u16 open_port, i; 8136 8137 switch (tun_type) { 8138 case ICE_SW_TUN_AND_NON_TUN: 8139 case ICE_SW_TUN_VXLAN_GPE: 8140 case ICE_SW_TUN_VXLAN: 8141 case ICE_SW_TUN_VXLAN_VLAN: 8142 case ICE_SW_TUN_UDP: 8143 if (!ice_get_open_tunnel_port(hw, TNL_VXLAN, &open_port)) 8144 return ICE_ERR_CFG; 8145 break; 8146 8147 case ICE_SW_TUN_GENEVE: 8148 case ICE_SW_TUN_GENEVE_VLAN: 8149 if (!ice_get_open_tunnel_port(hw, TNL_GENEVE, &open_port)) 8150 return ICE_ERR_CFG; 8151 break; 8152 8153 default: 8154 /* Nothing needs to be done for this tunnel type */ 8155 return ICE_SUCCESS; 8156 } 8157 8158 /* Find the outer UDP protocol header and insert the port number */ 8159 for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 8160 if (offsets[i].type == ICE_UDP_OF) { 8161 struct ice_l4_hdr *hdr; 8162 u16 offset; 8163 8164 offset = offsets[i].offset; 8165 hdr = (struct ice_l4_hdr *)&pkt[offset]; 8166 hdr->dst_port = CPU_TO_BE16(open_port); 8167 8168 return ICE_SUCCESS; 8169 } 8170 } 8171 8172 return ICE_ERR_CFG; 8173 } 8174 8175 /** 8176 * ice_find_adv_rule_entry - Search a rule entry 8177 * @hw: pointer to the hardware structure 8178 * @lkups: lookup elements or match criteria for the advanced recipe, one 8179 * structure per protocol header 8180 * @lkups_cnt: number of protocols 8181 * @recp_id: recipe ID for which we are finding the rule 8182 * @rinfo: other information regarding the rule e.g. priority and action info 8183 * 8184 * Helper function to search for a given advance rule entry 8185 * Returns pointer to entry storing the rule if found 8186 */ 8187 static struct ice_adv_fltr_mgmt_list_entry * 8188 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 8189 u16 lkups_cnt, u16 recp_id, 8190 struct ice_adv_rule_info *rinfo) 8191 { 8192 struct ice_adv_fltr_mgmt_list_entry *list_itr; 8193 struct ice_switch_info *sw = hw->switch_info; 8194 int i; 8195 8196 LIST_FOR_EACH_ENTRY(list_itr, &sw->recp_list[recp_id].filt_rules, 8197 ice_adv_fltr_mgmt_list_entry, list_entry) { 8198 bool lkups_matched = true; 8199 8200 if (lkups_cnt != list_itr->lkups_cnt) 8201 continue; 8202 for (i = 0; i < list_itr->lkups_cnt; i++) 8203 if (memcmp(&list_itr->lkups[i], &lkups[i], 8204 sizeof(*lkups))) { 8205 lkups_matched = false; 8206 break; 8207 } 8208 if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag && 8209 rinfo->tun_type == list_itr->rule_info.tun_type && 8210 lkups_matched) 8211 return list_itr; 8212 } 8213 return NULL; 8214 } 8215 8216 /** 8217 * ice_adv_add_update_vsi_list 8218 * @hw: pointer to the hardware structure 8219 * @m_entry: pointer to current adv filter management list entry 8220 * @cur_fltr: filter information from the book keeping entry 8221 * @new_fltr: filter information with the new VSI to be added 8222 * 8223 * Call AQ command to add or update previously created VSI list with new VSI. 8224 * 8225 * Helper function to do book keeping associated with adding filter information 8226 * The algorithm to do the booking keeping is described below : 8227 * When a VSI needs to subscribe to a given advanced filter 8228 * if only one VSI has been added till now 8229 * Allocate a new VSI list and add two VSIs 8230 * to this list using switch rule command 8231 * Update the previously created switch rule with the 8232 * newly created VSI list ID 8233 * if a VSI list was previously created 8234 * Add the new VSI to the previously created VSI list set 8235 * using the update switch rule command 8236 */ 8237 static enum ice_status 8238 ice_adv_add_update_vsi_list(struct ice_hw *hw, 8239 struct ice_adv_fltr_mgmt_list_entry *m_entry, 8240 struct ice_adv_rule_info *cur_fltr, 8241 struct ice_adv_rule_info *new_fltr) 8242 { 8243 enum ice_status status; 8244 u16 vsi_list_id = 0; 8245 8246 if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 8247 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP || 8248 cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET) 8249 return ICE_ERR_NOT_IMPL; 8250 8251 if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 8252 new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) && 8253 (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI || 8254 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST)) 8255 return ICE_ERR_NOT_IMPL; 8256 8257 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 8258 /* Only one entry existed in the mapping and it was not already 8259 * a part of a VSI list. So, create a VSI list with the old and 8260 * new VSIs. 8261 */ 8262 struct ice_fltr_info tmp_fltr; 8263 u16 vsi_handle_arr[2]; 8264 8265 /* A rule already exists with the new VSI being added */ 8266 if (cur_fltr->sw_act.fwd_id.hw_vsi_id == 8267 new_fltr->sw_act.fwd_id.hw_vsi_id) 8268 return ICE_ERR_ALREADY_EXISTS; 8269 8270 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle; 8271 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle; 8272 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 8273 &vsi_list_id, 8274 ICE_SW_LKUP_LAST); 8275 if (status) 8276 return status; 8277 8278 ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM); 8279 tmp_fltr.flag = m_entry->rule_info.sw_act.flag; 8280 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 8281 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 8282 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 8283 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST; 8284 8285 /* Update the previous switch rule of "forward to VSI" to 8286 * "fwd to VSI list" 8287 */ 8288 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 8289 if (status) 8290 return status; 8291 8292 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id; 8293 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST; 8294 m_entry->vsi_list_info = 8295 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 8296 vsi_list_id); 8297 } else { 8298 u16 vsi_handle = new_fltr->sw_act.vsi_handle; 8299 8300 if (!m_entry->vsi_list_info) 8301 return ICE_ERR_CFG; 8302 8303 /* A rule already exists with the new VSI being added */ 8304 if (ice_is_bit_set(m_entry->vsi_list_info->vsi_map, vsi_handle)) 8305 return ICE_SUCCESS; 8306 8307 /* Update the previously created VSI list set with 8308 * the new VSI ID passed in 8309 */ 8310 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id; 8311 8312 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 8313 vsi_list_id, false, 8314 ice_aqc_opc_update_sw_rules, 8315 ICE_SW_LKUP_LAST); 8316 /* update VSI list mapping info with new VSI ID */ 8317 if (!status) 8318 ice_set_bit(vsi_handle, 8319 m_entry->vsi_list_info->vsi_map); 8320 } 8321 if (!status) 8322 m_entry->vsi_count++; 8323 return status; 8324 } 8325 8326 /** 8327 * ice_add_adv_rule - helper function to create an advanced switch rule 8328 * @hw: pointer to the hardware structure 8329 * @lkups: information on the words that needs to be looked up. All words 8330 * together makes one recipe 8331 * @lkups_cnt: num of entries in the lkups array 8332 * @rinfo: other information related to the rule that needs to be programmed 8333 * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be 8334 * ignored is case of error. 8335 * 8336 * This function can program only 1 rule at a time. The lkups is used to 8337 * describe the all the words that forms the "lookup" portion of the recipe. 8338 * These words can span multiple protocols. Callers to this function need to 8339 * pass in a list of protocol headers with lookup information along and mask 8340 * that determines which words are valid from the given protocol header. 8341 * rinfo describes other information related to this rule such as forwarding 8342 * IDs, priority of this rule, etc. 8343 */ 8344 enum ice_status 8345 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 8346 u16 lkups_cnt, struct ice_adv_rule_info *rinfo, 8347 struct ice_rule_query_data *added_entry) 8348 { 8349 struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL; 8350 u16 rid = 0, i, pkt_len, rule_buf_sz, vsi_handle; 8351 const struct ice_dummy_pkt_offsets *pkt_offsets; 8352 struct ice_aqc_sw_rules_elem *s_rule = NULL; 8353 struct LIST_HEAD_TYPE *rule_head; 8354 struct ice_switch_info *sw; 8355 enum ice_status status; 8356 const u8 *pkt = NULL; 8357 bool prof_rule; 8358 u16 word_cnt; 8359 u32 act = 0; 8360 u8 q_rgn; 8361 8362 /* Initialize profile to result index bitmap */ 8363 if (!hw->switch_info->prof_res_bm_init) { 8364 hw->switch_info->prof_res_bm_init = 1; 8365 ice_init_prof_result_bm(hw); 8366 } 8367 8368 prof_rule = ice_is_prof_rule(rinfo->tun_type); 8369 if (!prof_rule && !lkups_cnt) 8370 return ICE_ERR_PARAM; 8371 8372 /* get # of words we need to match */ 8373 word_cnt = 0; 8374 for (i = 0; i < lkups_cnt; i++) { 8375 u16 j, *ptr; 8376 8377 ptr = (u16 *)&lkups[i].m_u; 8378 for (j = 0; j < sizeof(lkups->m_u) / sizeof(u16); j++) 8379 if (ptr[j] != 0) 8380 word_cnt++; 8381 } 8382 8383 if (prof_rule) { 8384 if (word_cnt > ICE_MAX_CHAIN_WORDS) 8385 return ICE_ERR_PARAM; 8386 } else { 8387 if (!word_cnt || word_cnt > ICE_MAX_CHAIN_WORDS) 8388 return ICE_ERR_PARAM; 8389 } 8390 8391 /* make sure that we can locate a dummy packet */ 8392 ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len, 8393 &pkt_offsets); 8394 if (!pkt) { 8395 status = ICE_ERR_PARAM; 8396 goto err_ice_add_adv_rule; 8397 } 8398 8399 if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI || 8400 rinfo->sw_act.fltr_act == ICE_FWD_TO_Q || 8401 rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP || 8402 rinfo->sw_act.fltr_act == ICE_DROP_PACKET)) 8403 return ICE_ERR_CFG; 8404 8405 vsi_handle = rinfo->sw_act.vsi_handle; 8406 if (!ice_is_vsi_valid(hw, vsi_handle)) 8407 return ICE_ERR_PARAM; 8408 8409 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 8410 rinfo->sw_act.fwd_id.hw_vsi_id = 8411 ice_get_hw_vsi_num(hw, vsi_handle); 8412 if (rinfo->sw_act.flag & ICE_FLTR_TX) 8413 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle); 8414 8415 status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid); 8416 if (status) 8417 return status; 8418 m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 8419 if (m_entry) { 8420 /* we have to add VSI to VSI_LIST and increment vsi_count. 8421 * Also Update VSI list so that we can change forwarding rule 8422 * if the rule already exists, we will check if it exists with 8423 * same vsi_id, if not then add it to the VSI list if it already 8424 * exists if not then create a VSI list and add the existing VSI 8425 * ID and the new VSI ID to the list 8426 * We will add that VSI to the list 8427 */ 8428 status = ice_adv_add_update_vsi_list(hw, m_entry, 8429 &m_entry->rule_info, 8430 rinfo); 8431 if (added_entry) { 8432 added_entry->rid = rid; 8433 added_entry->rule_id = m_entry->rule_info.fltr_rule_id; 8434 added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 8435 } 8436 return status; 8437 } 8438 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE + pkt_len; 8439 s_rule = (struct ice_aqc_sw_rules_elem *)ice_malloc(hw, rule_buf_sz); 8440 if (!s_rule) 8441 return ICE_ERR_NO_MEMORY; 8442 act |= ICE_SINGLE_ACT_LAN_ENABLE; 8443 switch (rinfo->sw_act.fltr_act) { 8444 case ICE_FWD_TO_VSI: 8445 act |= (rinfo->sw_act.fwd_id.hw_vsi_id << 8446 ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M; 8447 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT; 8448 break; 8449 case ICE_FWD_TO_Q: 8450 act |= ICE_SINGLE_ACT_TO_Q; 8451 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 8452 ICE_SINGLE_ACT_Q_INDEX_M; 8453 break; 8454 case ICE_FWD_TO_QGRP: 8455 q_rgn = rinfo->sw_act.qgrp_size > 0 ? 8456 (u8)ice_ilog2(rinfo->sw_act.qgrp_size) : 0; 8457 act |= ICE_SINGLE_ACT_TO_Q; 8458 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 8459 ICE_SINGLE_ACT_Q_INDEX_M; 8460 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 8461 ICE_SINGLE_ACT_Q_REGION_M; 8462 break; 8463 case ICE_DROP_PACKET: 8464 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 8465 ICE_SINGLE_ACT_VALID_BIT; 8466 break; 8467 default: 8468 status = ICE_ERR_CFG; 8469 goto err_ice_add_adv_rule; 8470 } 8471 8472 /* set the rule LOOKUP type based on caller specified 'RX' 8473 * instead of hardcoding it to be either LOOKUP_TX/RX 8474 * 8475 * for 'RX' set the source to be the port number 8476 * for 'TX' set the source to be the source HW VSI number (determined 8477 * by caller) 8478 */ 8479 if (rinfo->rx) { 8480 s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_RX); 8481 s_rule->pdata.lkup_tx_rx.src = 8482 CPU_TO_LE16(hw->port_info->lport); 8483 } else { 8484 s_rule->type = CPU_TO_LE16(ICE_AQC_SW_RULES_T_LKUP_TX); 8485 s_rule->pdata.lkup_tx_rx.src = CPU_TO_LE16(rinfo->sw_act.src); 8486 } 8487 8488 s_rule->pdata.lkup_tx_rx.recipe_id = CPU_TO_LE16(rid); 8489 s_rule->pdata.lkup_tx_rx.act = CPU_TO_LE32(act); 8490 8491 status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, pkt, 8492 pkt_len, pkt_offsets); 8493 if (status) 8494 goto err_ice_add_adv_rule; 8495 8496 if (rinfo->tun_type != ICE_NON_TUN && 8497 rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) { 8498 status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, 8499 s_rule->pdata.lkup_tx_rx.hdr, 8500 pkt_offsets); 8501 if (status) 8502 goto err_ice_add_adv_rule; 8503 } 8504 8505 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 8506 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules, 8507 NULL); 8508 if (status) 8509 goto err_ice_add_adv_rule; 8510 adv_fltr = (struct ice_adv_fltr_mgmt_list_entry *) 8511 ice_malloc(hw, sizeof(struct ice_adv_fltr_mgmt_list_entry)); 8512 if (!adv_fltr) { 8513 status = ICE_ERR_NO_MEMORY; 8514 goto err_ice_add_adv_rule; 8515 } 8516 8517 adv_fltr->lkups = (struct ice_adv_lkup_elem *) 8518 ice_memdup(hw, lkups, lkups_cnt * sizeof(*lkups), 8519 ICE_NONDMA_TO_NONDMA); 8520 if (!adv_fltr->lkups && !prof_rule) { 8521 status = ICE_ERR_NO_MEMORY; 8522 goto err_ice_add_adv_rule; 8523 } 8524 8525 adv_fltr->lkups_cnt = lkups_cnt; 8526 adv_fltr->rule_info = *rinfo; 8527 adv_fltr->rule_info.fltr_rule_id = 8528 LE16_TO_CPU(s_rule->pdata.lkup_tx_rx.index); 8529 sw = hw->switch_info; 8530 sw->recp_list[rid].adv_rule = true; 8531 rule_head = &sw->recp_list[rid].filt_rules; 8532 8533 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 8534 adv_fltr->vsi_count = 1; 8535 8536 /* Add rule entry to book keeping list */ 8537 LIST_ADD(&adv_fltr->list_entry, rule_head); 8538 if (added_entry) { 8539 added_entry->rid = rid; 8540 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id; 8541 added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 8542 } 8543 err_ice_add_adv_rule: 8544 if (status && adv_fltr) { 8545 ice_free(hw, adv_fltr->lkups); 8546 ice_free(hw, adv_fltr); 8547 } 8548 8549 ice_free(hw, s_rule); 8550 8551 return status; 8552 } 8553 8554 /** 8555 * ice_adv_rem_update_vsi_list 8556 * @hw: pointer to the hardware structure 8557 * @vsi_handle: VSI handle of the VSI to remove 8558 * @fm_list: filter management entry for which the VSI list management needs to 8559 * be done 8560 */ 8561 static enum ice_status 8562 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 8563 struct ice_adv_fltr_mgmt_list_entry *fm_list) 8564 { 8565 struct ice_vsi_list_map_info *vsi_list_info; 8566 enum ice_sw_lkup_type lkup_type; 8567 enum ice_status status; 8568 u16 vsi_list_id; 8569 8570 if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST || 8571 fm_list->vsi_count == 0) 8572 return ICE_ERR_PARAM; 8573 8574 /* A rule with the VSI being removed does not exist */ 8575 if (!ice_is_bit_set(fm_list->vsi_list_info->vsi_map, vsi_handle)) 8576 return ICE_ERR_DOES_NOT_EXIST; 8577 8578 lkup_type = ICE_SW_LKUP_LAST; 8579 vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id; 8580 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 8581 ice_aqc_opc_update_sw_rules, 8582 lkup_type); 8583 if (status) 8584 return status; 8585 8586 fm_list->vsi_count--; 8587 ice_clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 8588 vsi_list_info = fm_list->vsi_list_info; 8589 if (fm_list->vsi_count == 1) { 8590 struct ice_fltr_info tmp_fltr; 8591 u16 rem_vsi_handle; 8592 8593 rem_vsi_handle = ice_find_first_bit(vsi_list_info->vsi_map, 8594 ICE_MAX_VSI); 8595 if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 8596 return ICE_ERR_OUT_OF_RANGE; 8597 8598 /* Make sure VSI list is empty before removing it below */ 8599 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 8600 vsi_list_id, true, 8601 ice_aqc_opc_update_sw_rules, 8602 lkup_type); 8603 if (status) 8604 return status; 8605 8606 ice_memset(&tmp_fltr, 0, sizeof(tmp_fltr), ICE_NONDMA_MEM); 8607 tmp_fltr.flag = fm_list->rule_info.sw_act.flag; 8608 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id; 8609 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI; 8610 tmp_fltr.fltr_act = ICE_FWD_TO_VSI; 8611 tmp_fltr.fwd_id.hw_vsi_id = 8612 ice_get_hw_vsi_num(hw, rem_vsi_handle); 8613 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id = 8614 ice_get_hw_vsi_num(hw, rem_vsi_handle); 8615 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle; 8616 8617 /* Update the previous switch rule of "MAC forward to VSI" to 8618 * "MAC fwd to VSI list" 8619 */ 8620 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 8621 if (status) { 8622 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 8623 tmp_fltr.fwd_id.hw_vsi_id, status); 8624 return status; 8625 } 8626 fm_list->vsi_list_info->ref_cnt--; 8627 8628 /* Remove the VSI list since it is no longer used */ 8629 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 8630 if (status) { 8631 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 8632 vsi_list_id, status); 8633 return status; 8634 } 8635 8636 LIST_DEL(&vsi_list_info->list_entry); 8637 ice_free(hw, vsi_list_info); 8638 fm_list->vsi_list_info = NULL; 8639 } 8640 8641 return status; 8642 } 8643 8644 /** 8645 * ice_rem_adv_rule - removes existing advanced switch rule 8646 * @hw: pointer to the hardware structure 8647 * @lkups: information on the words that needs to be looked up. All words 8648 * together makes one recipe 8649 * @lkups_cnt: num of entries in the lkups array 8650 * @rinfo: Its the pointer to the rule information for the rule 8651 * 8652 * This function can be used to remove 1 rule at a time. The lkups is 8653 * used to describe all the words that forms the "lookup" portion of the 8654 * rule. These words can span multiple protocols. Callers to this function 8655 * need to pass in a list of protocol headers with lookup information along 8656 * and mask that determines which words are valid from the given protocol 8657 * header. rinfo describes other information related to this rule such as 8658 * forwarding IDs, priority of this rule, etc. 8659 */ 8660 enum ice_status 8661 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 8662 u16 lkups_cnt, struct ice_adv_rule_info *rinfo) 8663 { 8664 struct ice_adv_fltr_mgmt_list_entry *list_elem; 8665 struct ice_prot_lkup_ext lkup_exts; 8666 struct ice_lock *rule_lock; /* Lock to protect filter rule list */ 8667 enum ice_status status = ICE_SUCCESS; 8668 bool remove_rule = false; 8669 u16 i, rid, vsi_handle; 8670 8671 ice_memset(&lkup_exts, 0, sizeof(lkup_exts), ICE_NONDMA_MEM); 8672 for (i = 0; i < lkups_cnt; i++) { 8673 u16 count; 8674 8675 if (lkups[i].type >= ICE_PROTOCOL_LAST) 8676 return ICE_ERR_CFG; 8677 8678 count = ice_fill_valid_words(&lkups[i], &lkup_exts); 8679 if (!count) 8680 return ICE_ERR_CFG; 8681 } 8682 8683 /* Create any special protocol/offset pairs, such as looking at tunnel 8684 * bits by extracting metadata 8685 */ 8686 status = ice_add_special_words(rinfo, &lkup_exts); 8687 if (status) 8688 return status; 8689 8690 rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type); 8691 /* If did not find a recipe that match the existing criteria */ 8692 if (rid == ICE_MAX_NUM_RECIPES) 8693 return ICE_ERR_PARAM; 8694 8695 rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock; 8696 list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 8697 /* the rule is already removed */ 8698 if (!list_elem) 8699 return ICE_SUCCESS; 8700 ice_acquire_lock(rule_lock); 8701 if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) { 8702 remove_rule = true; 8703 } else if (list_elem->vsi_count > 1) { 8704 remove_rule = false; 8705 vsi_handle = rinfo->sw_act.vsi_handle; 8706 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 8707 } else { 8708 vsi_handle = rinfo->sw_act.vsi_handle; 8709 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 8710 if (status) { 8711 ice_release_lock(rule_lock); 8712 return status; 8713 } 8714 if (list_elem->vsi_count == 0) 8715 remove_rule = true; 8716 } 8717 ice_release_lock(rule_lock); 8718 if (remove_rule) { 8719 struct ice_aqc_sw_rules_elem *s_rule; 8720 u16 rule_buf_sz; 8721 8722 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE; 8723 s_rule = (struct ice_aqc_sw_rules_elem *) 8724 ice_malloc(hw, rule_buf_sz); 8725 if (!s_rule) 8726 return ICE_ERR_NO_MEMORY; 8727 s_rule->pdata.lkup_tx_rx.act = 0; 8728 s_rule->pdata.lkup_tx_rx.index = 8729 CPU_TO_LE16(list_elem->rule_info.fltr_rule_id); 8730 s_rule->pdata.lkup_tx_rx.hdr_len = 0; 8731 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 8732 rule_buf_sz, 1, 8733 ice_aqc_opc_remove_sw_rules, NULL); 8734 if (status == ICE_SUCCESS || status == ICE_ERR_DOES_NOT_EXIST) { 8735 struct ice_switch_info *sw = hw->switch_info; 8736 8737 ice_acquire_lock(rule_lock); 8738 LIST_DEL(&list_elem->list_entry); 8739 ice_free(hw, list_elem->lkups); 8740 ice_free(hw, list_elem); 8741 ice_release_lock(rule_lock); 8742 if (LIST_EMPTY(&sw->recp_list[rid].filt_rules)) 8743 sw->recp_list[rid].adv_rule = false; 8744 } 8745 ice_free(hw, s_rule); 8746 } 8747 return status; 8748 } 8749 8750 /** 8751 * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID 8752 * @hw: pointer to the hardware structure 8753 * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID 8754 * 8755 * This function is used to remove 1 rule at a time. The removal is based on 8756 * the remove_entry parameter. This function will remove rule for a given 8757 * vsi_handle with a given rule_id which is passed as parameter in remove_entry 8758 */ 8759 enum ice_status 8760 ice_rem_adv_rule_by_id(struct ice_hw *hw, 8761 struct ice_rule_query_data *remove_entry) 8762 { 8763 struct ice_adv_fltr_mgmt_list_entry *list_itr; 8764 struct LIST_HEAD_TYPE *list_head; 8765 struct ice_adv_rule_info rinfo; 8766 struct ice_switch_info *sw; 8767 8768 sw = hw->switch_info; 8769 if (!sw->recp_list[remove_entry->rid].recp_created) 8770 return ICE_ERR_PARAM; 8771 list_head = &sw->recp_list[remove_entry->rid].filt_rules; 8772 LIST_FOR_EACH_ENTRY(list_itr, list_head, ice_adv_fltr_mgmt_list_entry, 8773 list_entry) { 8774 if (list_itr->rule_info.fltr_rule_id == 8775 remove_entry->rule_id) { 8776 rinfo = list_itr->rule_info; 8777 rinfo.sw_act.vsi_handle = remove_entry->vsi_handle; 8778 return ice_rem_adv_rule(hw, list_itr->lkups, 8779 list_itr->lkups_cnt, &rinfo); 8780 } 8781 } 8782 /* either list is empty or unable to find rule */ 8783 return ICE_ERR_DOES_NOT_EXIST; 8784 } 8785 8786 /** 8787 * ice_rem_adv_for_vsi - removes existing advanced switch rules for a 8788 * given VSI handle 8789 * @hw: pointer to the hardware structure 8790 * @vsi_handle: VSI handle for which we are supposed to remove all the rules. 8791 * 8792 * This function is used to remove all the rules for a given VSI and as soon 8793 * as removing a rule fails, it will return immediately with the error code, 8794 * else it will return ICE_SUCCESS 8795 */ 8796 enum ice_status ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle) 8797 { 8798 struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry; 8799 struct ice_vsi_list_map_info *map_info; 8800 struct LIST_HEAD_TYPE *list_head; 8801 struct ice_adv_rule_info rinfo; 8802 struct ice_switch_info *sw; 8803 enum ice_status status; 8804 u8 rid; 8805 8806 sw = hw->switch_info; 8807 for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) { 8808 if (!sw->recp_list[rid].recp_created) 8809 continue; 8810 if (!sw->recp_list[rid].adv_rule) 8811 continue; 8812 8813 list_head = &sw->recp_list[rid].filt_rules; 8814 LIST_FOR_EACH_ENTRY_SAFE(list_itr, tmp_entry, list_head, 8815 ice_adv_fltr_mgmt_list_entry, 8816 list_entry) { 8817 rinfo = list_itr->rule_info; 8818 8819 if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) { 8820 map_info = list_itr->vsi_list_info; 8821 if (!map_info) 8822 continue; 8823 8824 if (!ice_is_bit_set(map_info->vsi_map, 8825 vsi_handle)) 8826 continue; 8827 } else if (rinfo.sw_act.vsi_handle != vsi_handle) { 8828 continue; 8829 } 8830 8831 rinfo.sw_act.vsi_handle = vsi_handle; 8832 status = ice_rem_adv_rule(hw, list_itr->lkups, 8833 list_itr->lkups_cnt, &rinfo); 8834 8835 if (status) 8836 return status; 8837 } 8838 } 8839 return ICE_SUCCESS; 8840 } 8841 8842 /** 8843 * ice_replay_fltr - Replay all the filters stored by a specific list head 8844 * @hw: pointer to the hardware structure 8845 * @list_head: list for which filters needs to be replayed 8846 * @recp_id: Recipe ID for which rules need to be replayed 8847 */ 8848 static enum ice_status 8849 ice_replay_fltr(struct ice_hw *hw, u8 recp_id, struct LIST_HEAD_TYPE *list_head) 8850 { 8851 struct ice_fltr_mgmt_list_entry *itr; 8852 enum ice_status status = ICE_SUCCESS; 8853 struct ice_sw_recipe *recp_list; 8854 u8 lport = hw->port_info->lport; 8855 struct LIST_HEAD_TYPE l_head; 8856 8857 if (LIST_EMPTY(list_head)) 8858 return status; 8859 8860 recp_list = &hw->switch_info->recp_list[recp_id]; 8861 /* Move entries from the given list_head to a temporary l_head so that 8862 * they can be replayed. Otherwise when trying to re-add the same 8863 * filter, the function will return already exists 8864 */ 8865 LIST_REPLACE_INIT(list_head, &l_head); 8866 8867 /* Mark the given list_head empty by reinitializing it so filters 8868 * could be added again by *handler 8869 */ 8870 LIST_FOR_EACH_ENTRY(itr, &l_head, ice_fltr_mgmt_list_entry, 8871 list_entry) { 8872 struct ice_fltr_list_entry f_entry; 8873 u16 vsi_handle; 8874 8875 f_entry.fltr_info = itr->fltr_info; 8876 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN) { 8877 status = ice_add_rule_internal(hw, recp_list, lport, 8878 &f_entry); 8879 if (status != ICE_SUCCESS) 8880 goto end; 8881 continue; 8882 } 8883 8884 /* Add a filter per VSI separately */ 8885 ice_for_each_set_bit(vsi_handle, itr->vsi_list_info->vsi_map, 8886 ICE_MAX_VSI) { 8887 if (!ice_is_vsi_valid(hw, vsi_handle)) 8888 break; 8889 8890 ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 8891 f_entry.fltr_info.vsi_handle = vsi_handle; 8892 f_entry.fltr_info.fwd_id.hw_vsi_id = 8893 ice_get_hw_vsi_num(hw, vsi_handle); 8894 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 8895 if (recp_id == ICE_SW_LKUP_VLAN) 8896 status = ice_add_vlan_internal(hw, recp_list, 8897 &f_entry); 8898 else 8899 status = ice_add_rule_internal(hw, recp_list, 8900 lport, 8901 &f_entry); 8902 if (status != ICE_SUCCESS) 8903 goto end; 8904 } 8905 } 8906 end: 8907 /* Clear the filter management list */ 8908 ice_rem_sw_rule_info(hw, &l_head); 8909 return status; 8910 } 8911 8912 /** 8913 * ice_replay_all_fltr - replay all filters stored in bookkeeping lists 8914 * @hw: pointer to the hardware structure 8915 * 8916 * NOTE: This function does not clean up partially added filters on error. 8917 * It is up to caller of the function to issue a reset or fail early. 8918 */ 8919 enum ice_status ice_replay_all_fltr(struct ice_hw *hw) 8920 { 8921 struct ice_switch_info *sw = hw->switch_info; 8922 enum ice_status status = ICE_SUCCESS; 8923 u8 i; 8924 8925 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 8926 struct LIST_HEAD_TYPE *head = &sw->recp_list[i].filt_rules; 8927 8928 status = ice_replay_fltr(hw, i, head); 8929 if (status != ICE_SUCCESS) 8930 return status; 8931 } 8932 return status; 8933 } 8934 8935 /** 8936 * ice_replay_vsi_fltr - Replay filters for requested VSI 8937 * @hw: pointer to the hardware structure 8938 * @pi: pointer to port information structure 8939 * @sw: pointer to switch info struct for which function replays filters 8940 * @vsi_handle: driver VSI handle 8941 * @recp_id: Recipe ID for which rules need to be replayed 8942 * @list_head: list for which filters need to be replayed 8943 * 8944 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. 8945 * It is required to pass valid VSI handle. 8946 */ 8947 static enum ice_status 8948 ice_replay_vsi_fltr(struct ice_hw *hw, struct ice_port_info *pi, 8949 struct ice_switch_info *sw, u16 vsi_handle, u8 recp_id, 8950 struct LIST_HEAD_TYPE *list_head) 8951 { 8952 struct ice_fltr_mgmt_list_entry *itr; 8953 enum ice_status status = ICE_SUCCESS; 8954 struct ice_sw_recipe *recp_list; 8955 u16 hw_vsi_id; 8956 8957 if (LIST_EMPTY(list_head)) 8958 return status; 8959 recp_list = &sw->recp_list[recp_id]; 8960 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 8961 8962 LIST_FOR_EACH_ENTRY(itr, list_head, ice_fltr_mgmt_list_entry, 8963 list_entry) { 8964 struct ice_fltr_list_entry f_entry; 8965 8966 f_entry.fltr_info = itr->fltr_info; 8967 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN && 8968 itr->fltr_info.vsi_handle == vsi_handle) { 8969 /* update the src in case it is VSI num */ 8970 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 8971 f_entry.fltr_info.src = hw_vsi_id; 8972 status = ice_add_rule_internal(hw, recp_list, 8973 pi->lport, 8974 &f_entry); 8975 if (status != ICE_SUCCESS) 8976 goto end; 8977 continue; 8978 } 8979 if (!itr->vsi_list_info || 8980 !ice_is_bit_set(itr->vsi_list_info->vsi_map, vsi_handle)) 8981 continue; 8982 /* Clearing it so that the logic can add it back */ 8983 ice_clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 8984 f_entry.fltr_info.vsi_handle = vsi_handle; 8985 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 8986 /* update the src in case it is VSI num */ 8987 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 8988 f_entry.fltr_info.src = hw_vsi_id; 8989 if (recp_id == ICE_SW_LKUP_VLAN) 8990 status = ice_add_vlan_internal(hw, recp_list, &f_entry); 8991 else 8992 status = ice_add_rule_internal(hw, recp_list, 8993 pi->lport, 8994 &f_entry); 8995 if (status != ICE_SUCCESS) 8996 goto end; 8997 } 8998 end: 8999 return status; 9000 } 9001 9002 /** 9003 * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI 9004 * @hw: pointer to the hardware structure 9005 * @vsi_handle: driver VSI handle 9006 * @list_head: list for which filters need to be replayed 9007 * 9008 * Replay the advanced rule for the given VSI. 9009 */ 9010 static enum ice_status 9011 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle, 9012 struct LIST_HEAD_TYPE *list_head) 9013 { 9014 struct ice_rule_query_data added_entry = { 0 }; 9015 struct ice_adv_fltr_mgmt_list_entry *adv_fltr; 9016 enum ice_status status = ICE_SUCCESS; 9017 9018 if (LIST_EMPTY(list_head)) 9019 return status; 9020 LIST_FOR_EACH_ENTRY(adv_fltr, list_head, ice_adv_fltr_mgmt_list_entry, 9021 list_entry) { 9022 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info; 9023 u16 lk_cnt = adv_fltr->lkups_cnt; 9024 9025 if (vsi_handle != rinfo->sw_act.vsi_handle) 9026 continue; 9027 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo, 9028 &added_entry); 9029 if (status) 9030 break; 9031 } 9032 return status; 9033 } 9034 9035 /** 9036 * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists 9037 * @hw: pointer to the hardware structure 9038 * @pi: pointer to port information structure 9039 * @vsi_handle: driver VSI handle 9040 * 9041 * Replays filters for requested VSI via vsi_handle. 9042 */ 9043 enum ice_status 9044 ice_replay_vsi_all_fltr(struct ice_hw *hw, struct ice_port_info *pi, 9045 u16 vsi_handle) 9046 { 9047 struct ice_switch_info *sw = hw->switch_info; 9048 enum ice_status status; 9049 u8 i; 9050 9051 /* Update the recipes that were created */ 9052 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 9053 struct LIST_HEAD_TYPE *head; 9054 9055 head = &sw->recp_list[i].filt_replay_rules; 9056 if (!sw->recp_list[i].adv_rule) 9057 status = ice_replay_vsi_fltr(hw, pi, sw, vsi_handle, i, 9058 head); 9059 else 9060 status = ice_replay_vsi_adv_rule(hw, vsi_handle, head); 9061 if (status != ICE_SUCCESS) 9062 return status; 9063 } 9064 9065 return ICE_SUCCESS; 9066 } 9067 9068 /** 9069 * ice_rm_all_sw_replay_rule - helper function to delete filter replay rules 9070 * @hw: pointer to the HW struct 9071 * @sw: pointer to switch info struct for which function removes filters 9072 * 9073 * Deletes the filter replay rules for given switch 9074 */ 9075 void ice_rm_sw_replay_rule_info(struct ice_hw *hw, struct ice_switch_info *sw) 9076 { 9077 u8 i; 9078 9079 if (!sw) 9080 return; 9081 9082 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 9083 if (!LIST_EMPTY(&sw->recp_list[i].filt_replay_rules)) { 9084 struct LIST_HEAD_TYPE *l_head; 9085 9086 l_head = &sw->recp_list[i].filt_replay_rules; 9087 if (!sw->recp_list[i].adv_rule) 9088 ice_rem_sw_rule_info(hw, l_head); 9089 else 9090 ice_rem_adv_rule_info(hw, l_head); 9091 } 9092 } 9093 } 9094 9095 /** 9096 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules 9097 * @hw: pointer to the HW struct 9098 * 9099 * Deletes the filter replay rules. 9100 */ 9101 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) 9102 { 9103 ice_rm_sw_replay_rule_info(hw, hw->switch_info); 9104 } 9105