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