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