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