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