1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2018, Intel Corporation. */ 3 4 #include "ice_lib.h" 5 #include "ice_switch.h" 6 7 #define ICE_ETH_DA_OFFSET 0 8 #define ICE_ETH_ETHTYPE_OFFSET 12 9 #define ICE_ETH_VLAN_TCI_OFFSET 14 10 #define ICE_MAX_VLAN_ID 0xFFF 11 #define ICE_IPV6_ETHER_ID 0x86DD 12 13 /* Dummy ethernet header needed in the ice_aqc_sw_rules_elem 14 * struct to configure any switch filter rules. 15 * {DA (6 bytes), SA(6 bytes), 16 * Ether type (2 bytes for header without VLAN tag) OR 17 * VLAN tag (4 bytes for header with VLAN tag) } 18 * 19 * Word on Hardcoded values 20 * byte 0 = 0x2: to identify it as locally administered DA MAC 21 * byte 6 = 0x2: to identify it as locally administered SA MAC 22 * byte 12 = 0x81 & byte 13 = 0x00: 23 * In case of VLAN filter first two bytes defines ether type (0x8100) 24 * and remaining two bytes are placeholder for programming a given VLAN ID 25 * In case of Ether type filter it is treated as header without VLAN tag 26 * and byte 12 and 13 is used to program a given Ether type instead 27 */ 28 #define DUMMY_ETH_HDR_LEN 16 29 static const u8 dummy_eth_header[DUMMY_ETH_HDR_LEN] = { 0x2, 0, 0, 0, 0, 0, 30 0x2, 0, 0, 0, 0, 0, 31 0x81, 0, 0, 0}; 32 33 enum { 34 ICE_PKT_OUTER_IPV6 = BIT(0), 35 ICE_PKT_TUN_GTPC = BIT(1), 36 ICE_PKT_TUN_GTPU = BIT(2), 37 ICE_PKT_TUN_NVGRE = BIT(3), 38 ICE_PKT_TUN_UDP = BIT(4), 39 ICE_PKT_INNER_IPV6 = BIT(5), 40 ICE_PKT_INNER_TCP = BIT(6), 41 ICE_PKT_INNER_UDP = BIT(7), 42 ICE_PKT_GTP_NOPAY = BIT(8), 43 ICE_PKT_KMALLOC = BIT(9), 44 ICE_PKT_PPPOE = BIT(10), 45 }; 46 47 struct ice_dummy_pkt_offsets { 48 enum ice_protocol_type type; 49 u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */ 50 }; 51 52 struct ice_dummy_pkt_profile { 53 const struct ice_dummy_pkt_offsets *offsets; 54 const u8 *pkt; 55 u32 match; 56 u16 pkt_len; 57 u16 offsets_len; 58 }; 59 60 #define ICE_DECLARE_PKT_OFFSETS(type) \ 61 static const struct ice_dummy_pkt_offsets \ 62 ice_dummy_##type##_packet_offsets[] 63 64 #define ICE_DECLARE_PKT_TEMPLATE(type) \ 65 static const u8 ice_dummy_##type##_packet[] 66 67 #define ICE_PKT_PROFILE(type, m) { \ 68 .match = (m), \ 69 .pkt = ice_dummy_##type##_packet, \ 70 .pkt_len = sizeof(ice_dummy_##type##_packet), \ 71 .offsets = ice_dummy_##type##_packet_offsets, \ 72 .offsets_len = sizeof(ice_dummy_##type##_packet_offsets), \ 73 } 74 75 ICE_DECLARE_PKT_OFFSETS(vlan) = { 76 { ICE_VLAN_OFOS, 12 }, 77 }; 78 79 ICE_DECLARE_PKT_TEMPLATE(vlan) = { 80 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_OFOS 12 */ 81 }; 82 83 ICE_DECLARE_PKT_OFFSETS(qinq) = { 84 { ICE_VLAN_EX, 12 }, 85 { ICE_VLAN_IN, 16 }, 86 }; 87 88 ICE_DECLARE_PKT_TEMPLATE(qinq) = { 89 0x91, 0x00, 0x00, 0x00, /* ICE_VLAN_EX 12 */ 90 0x81, 0x00, 0x00, 0x00, /* ICE_VLAN_IN 16 */ 91 }; 92 93 ICE_DECLARE_PKT_OFFSETS(gre_tcp) = { 94 { ICE_MAC_OFOS, 0 }, 95 { ICE_ETYPE_OL, 12 }, 96 { ICE_IPV4_OFOS, 14 }, 97 { ICE_NVGRE, 34 }, 98 { ICE_MAC_IL, 42 }, 99 { ICE_ETYPE_IL, 54 }, 100 { ICE_IPV4_IL, 56 }, 101 { ICE_TCP_IL, 76 }, 102 { ICE_PROTOCOL_LAST, 0 }, 103 }; 104 105 ICE_DECLARE_PKT_TEMPLATE(gre_tcp) = { 106 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 107 0x00, 0x00, 0x00, 0x00, 108 0x00, 0x00, 0x00, 0x00, 109 110 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 111 112 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */ 113 0x00, 0x00, 0x00, 0x00, 114 0x00, 0x2F, 0x00, 0x00, 115 0x00, 0x00, 0x00, 0x00, 116 0x00, 0x00, 0x00, 0x00, 117 118 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 119 0x00, 0x00, 0x00, 0x00, 120 121 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 122 0x00, 0x00, 0x00, 0x00, 123 0x00, 0x00, 0x00, 0x00, 124 125 0x08, 0x00, /* ICE_ETYPE_IL 54 */ 126 127 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */ 128 0x00, 0x00, 0x00, 0x00, 129 0x00, 0x06, 0x00, 0x00, 130 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00, 132 133 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 76 */ 134 0x00, 0x00, 0x00, 0x00, 135 0x00, 0x00, 0x00, 0x00, 136 0x50, 0x02, 0x20, 0x00, 137 0x00, 0x00, 0x00, 0x00 138 }; 139 140 ICE_DECLARE_PKT_OFFSETS(gre_udp) = { 141 { ICE_MAC_OFOS, 0 }, 142 { ICE_ETYPE_OL, 12 }, 143 { ICE_IPV4_OFOS, 14 }, 144 { ICE_NVGRE, 34 }, 145 { ICE_MAC_IL, 42 }, 146 { ICE_ETYPE_IL, 54 }, 147 { ICE_IPV4_IL, 56 }, 148 { ICE_UDP_ILOS, 76 }, 149 { ICE_PROTOCOL_LAST, 0 }, 150 }; 151 152 ICE_DECLARE_PKT_TEMPLATE(gre_udp) = { 153 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 154 0x00, 0x00, 0x00, 0x00, 155 0x00, 0x00, 0x00, 0x00, 156 157 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 158 159 0x45, 0x00, 0x00, 0x3E, /* ICE_IPV4_OFOS 14 */ 160 0x00, 0x00, 0x00, 0x00, 161 0x00, 0x2F, 0x00, 0x00, 162 0x00, 0x00, 0x00, 0x00, 163 0x00, 0x00, 0x00, 0x00, 164 165 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 166 0x00, 0x00, 0x00, 0x00, 167 168 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 169 0x00, 0x00, 0x00, 0x00, 170 0x00, 0x00, 0x00, 0x00, 171 172 0x08, 0x00, /* ICE_ETYPE_IL 54 */ 173 174 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 56 */ 175 0x00, 0x00, 0x00, 0x00, 176 0x00, 0x11, 0x00, 0x00, 177 0x00, 0x00, 0x00, 0x00, 178 0x00, 0x00, 0x00, 0x00, 179 180 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 76 */ 181 0x00, 0x08, 0x00, 0x00, 182 }; 183 184 ICE_DECLARE_PKT_OFFSETS(udp_tun_tcp) = { 185 { ICE_MAC_OFOS, 0 }, 186 { ICE_ETYPE_OL, 12 }, 187 { ICE_IPV4_OFOS, 14 }, 188 { ICE_UDP_OF, 34 }, 189 { ICE_VXLAN, 42 }, 190 { ICE_GENEVE, 42 }, 191 { ICE_VXLAN_GPE, 42 }, 192 { ICE_MAC_IL, 50 }, 193 { ICE_ETYPE_IL, 62 }, 194 { ICE_IPV4_IL, 64 }, 195 { ICE_TCP_IL, 84 }, 196 { ICE_PROTOCOL_LAST, 0 }, 197 }; 198 199 ICE_DECLARE_PKT_TEMPLATE(udp_tun_tcp) = { 200 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 201 0x00, 0x00, 0x00, 0x00, 202 0x00, 0x00, 0x00, 0x00, 203 204 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 205 206 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */ 207 0x00, 0x01, 0x00, 0x00, 208 0x40, 0x11, 0x00, 0x00, 209 0x00, 0x00, 0x00, 0x00, 210 0x00, 0x00, 0x00, 0x00, 211 212 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 213 0x00, 0x46, 0x00, 0x00, 214 215 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 216 0x00, 0x00, 0x00, 0x00, 217 218 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 219 0x00, 0x00, 0x00, 0x00, 220 0x00, 0x00, 0x00, 0x00, 221 222 0x08, 0x00, /* ICE_ETYPE_IL 62 */ 223 224 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */ 225 0x00, 0x01, 0x00, 0x00, 226 0x40, 0x06, 0x00, 0x00, 227 0x00, 0x00, 0x00, 0x00, 228 0x00, 0x00, 0x00, 0x00, 229 230 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */ 231 0x00, 0x00, 0x00, 0x00, 232 0x00, 0x00, 0x00, 0x00, 233 0x50, 0x02, 0x20, 0x00, 234 0x00, 0x00, 0x00, 0x00 235 }; 236 237 ICE_DECLARE_PKT_OFFSETS(udp_tun_udp) = { 238 { ICE_MAC_OFOS, 0 }, 239 { ICE_ETYPE_OL, 12 }, 240 { ICE_IPV4_OFOS, 14 }, 241 { ICE_UDP_OF, 34 }, 242 { ICE_VXLAN, 42 }, 243 { ICE_GENEVE, 42 }, 244 { ICE_VXLAN_GPE, 42 }, 245 { ICE_MAC_IL, 50 }, 246 { ICE_ETYPE_IL, 62 }, 247 { ICE_IPV4_IL, 64 }, 248 { ICE_UDP_ILOS, 84 }, 249 { ICE_PROTOCOL_LAST, 0 }, 250 }; 251 252 ICE_DECLARE_PKT_TEMPLATE(udp_tun_udp) = { 253 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 254 0x00, 0x00, 0x00, 0x00, 255 0x00, 0x00, 0x00, 0x00, 256 257 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 258 259 0x45, 0x00, 0x00, 0x4e, /* ICE_IPV4_OFOS 14 */ 260 0x00, 0x01, 0x00, 0x00, 261 0x00, 0x11, 0x00, 0x00, 262 0x00, 0x00, 0x00, 0x00, 263 0x00, 0x00, 0x00, 0x00, 264 265 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 266 0x00, 0x3a, 0x00, 0x00, 267 268 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 269 0x00, 0x00, 0x00, 0x00, 270 271 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 272 0x00, 0x00, 0x00, 0x00, 273 0x00, 0x00, 0x00, 0x00, 274 275 0x08, 0x00, /* ICE_ETYPE_IL 62 */ 276 277 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */ 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 84 */ 284 0x00, 0x08, 0x00, 0x00, 285 }; 286 287 ICE_DECLARE_PKT_OFFSETS(gre_ipv6_tcp) = { 288 { ICE_MAC_OFOS, 0 }, 289 { ICE_ETYPE_OL, 12 }, 290 { ICE_IPV4_OFOS, 14 }, 291 { ICE_NVGRE, 34 }, 292 { ICE_MAC_IL, 42 }, 293 { ICE_ETYPE_IL, 54 }, 294 { ICE_IPV6_IL, 56 }, 295 { ICE_TCP_IL, 96 }, 296 { ICE_PROTOCOL_LAST, 0 }, 297 }; 298 299 ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_tcp) = { 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, 0x66, /* ICE_IPV4_OFOS 14 */ 307 0x00, 0x00, 0x00, 0x00, 308 0x00, 0x2F, 0x00, 0x00, 309 0x00, 0x00, 0x00, 0x00, 310 0x00, 0x00, 0x00, 0x00, 311 312 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 313 0x00, 0x00, 0x00, 0x00, 314 315 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 316 0x00, 0x00, 0x00, 0x00, 317 0x00, 0x00, 0x00, 0x00, 318 319 0x86, 0xdd, /* ICE_ETYPE_IL 54 */ 320 321 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */ 322 0x00, 0x08, 0x06, 0x40, 323 0x00, 0x00, 0x00, 0x00, 324 0x00, 0x00, 0x00, 0x00, 325 0x00, 0x00, 0x00, 0x00, 326 0x00, 0x00, 0x00, 0x00, 327 0x00, 0x00, 0x00, 0x00, 328 0x00, 0x00, 0x00, 0x00, 329 0x00, 0x00, 0x00, 0x00, 330 0x00, 0x00, 0x00, 0x00, 331 332 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 96 */ 333 0x00, 0x00, 0x00, 0x00, 334 0x00, 0x00, 0x00, 0x00, 335 0x50, 0x02, 0x20, 0x00, 336 0x00, 0x00, 0x00, 0x00 337 }; 338 339 ICE_DECLARE_PKT_OFFSETS(gre_ipv6_udp) = { 340 { ICE_MAC_OFOS, 0 }, 341 { ICE_ETYPE_OL, 12 }, 342 { ICE_IPV4_OFOS, 14 }, 343 { ICE_NVGRE, 34 }, 344 { ICE_MAC_IL, 42 }, 345 { ICE_ETYPE_IL, 54 }, 346 { ICE_IPV6_IL, 56 }, 347 { ICE_UDP_ILOS, 96 }, 348 { ICE_PROTOCOL_LAST, 0 }, 349 }; 350 351 ICE_DECLARE_PKT_TEMPLATE(gre_ipv6_udp) = { 352 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 353 0x00, 0x00, 0x00, 0x00, 354 0x00, 0x00, 0x00, 0x00, 355 356 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 357 358 0x45, 0x00, 0x00, 0x5a, /* ICE_IPV4_OFOS 14 */ 359 0x00, 0x00, 0x00, 0x00, 360 0x00, 0x2F, 0x00, 0x00, 361 0x00, 0x00, 0x00, 0x00, 362 0x00, 0x00, 0x00, 0x00, 363 364 0x80, 0x00, 0x65, 0x58, /* ICE_NVGRE 34 */ 365 0x00, 0x00, 0x00, 0x00, 366 367 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 42 */ 368 0x00, 0x00, 0x00, 0x00, 369 0x00, 0x00, 0x00, 0x00, 370 371 0x86, 0xdd, /* ICE_ETYPE_IL 54 */ 372 373 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 56 */ 374 0x00, 0x08, 0x11, 0x40, 375 0x00, 0x00, 0x00, 0x00, 376 0x00, 0x00, 0x00, 0x00, 377 0x00, 0x00, 0x00, 0x00, 378 0x00, 0x00, 0x00, 0x00, 379 0x00, 0x00, 0x00, 0x00, 380 0x00, 0x00, 0x00, 0x00, 381 0x00, 0x00, 0x00, 0x00, 382 0x00, 0x00, 0x00, 0x00, 383 384 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 96 */ 385 0x00, 0x08, 0x00, 0x00, 386 }; 387 388 ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_tcp) = { 389 { ICE_MAC_OFOS, 0 }, 390 { ICE_ETYPE_OL, 12 }, 391 { ICE_IPV4_OFOS, 14 }, 392 { ICE_UDP_OF, 34 }, 393 { ICE_VXLAN, 42 }, 394 { ICE_GENEVE, 42 }, 395 { ICE_VXLAN_GPE, 42 }, 396 { ICE_MAC_IL, 50 }, 397 { ICE_ETYPE_IL, 62 }, 398 { ICE_IPV6_IL, 64 }, 399 { ICE_TCP_IL, 104 }, 400 { ICE_PROTOCOL_LAST, 0 }, 401 }; 402 403 ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_tcp) = { 404 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 405 0x00, 0x00, 0x00, 0x00, 406 0x00, 0x00, 0x00, 0x00, 407 408 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 409 410 0x45, 0x00, 0x00, 0x6e, /* ICE_IPV4_OFOS 14 */ 411 0x00, 0x01, 0x00, 0x00, 412 0x40, 0x11, 0x00, 0x00, 413 0x00, 0x00, 0x00, 0x00, 414 0x00, 0x00, 0x00, 0x00, 415 416 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 417 0x00, 0x5a, 0x00, 0x00, 418 419 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 420 0x00, 0x00, 0x00, 0x00, 421 422 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 423 0x00, 0x00, 0x00, 0x00, 424 0x00, 0x00, 0x00, 0x00, 425 426 0x86, 0xdd, /* ICE_ETYPE_IL 62 */ 427 428 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */ 429 0x00, 0x08, 0x06, 0x40, 430 0x00, 0x00, 0x00, 0x00, 431 0x00, 0x00, 0x00, 0x00, 432 0x00, 0x00, 0x00, 0x00, 433 0x00, 0x00, 0x00, 0x00, 434 0x00, 0x00, 0x00, 0x00, 435 0x00, 0x00, 0x00, 0x00, 436 0x00, 0x00, 0x00, 0x00, 437 0x00, 0x00, 0x00, 0x00, 438 439 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 104 */ 440 0x00, 0x00, 0x00, 0x00, 441 0x00, 0x00, 0x00, 0x00, 442 0x50, 0x02, 0x20, 0x00, 443 0x00, 0x00, 0x00, 0x00 444 }; 445 446 ICE_DECLARE_PKT_OFFSETS(udp_tun_ipv6_udp) = { 447 { ICE_MAC_OFOS, 0 }, 448 { ICE_ETYPE_OL, 12 }, 449 { ICE_IPV4_OFOS, 14 }, 450 { ICE_UDP_OF, 34 }, 451 { ICE_VXLAN, 42 }, 452 { ICE_GENEVE, 42 }, 453 { ICE_VXLAN_GPE, 42 }, 454 { ICE_MAC_IL, 50 }, 455 { ICE_ETYPE_IL, 62 }, 456 { ICE_IPV6_IL, 64 }, 457 { ICE_UDP_ILOS, 104 }, 458 { ICE_PROTOCOL_LAST, 0 }, 459 }; 460 461 ICE_DECLARE_PKT_TEMPLATE(udp_tun_ipv6_udp) = { 462 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 463 0x00, 0x00, 0x00, 0x00, 464 0x00, 0x00, 0x00, 0x00, 465 466 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 467 468 0x45, 0x00, 0x00, 0x62, /* ICE_IPV4_OFOS 14 */ 469 0x00, 0x01, 0x00, 0x00, 470 0x00, 0x11, 0x00, 0x00, 471 0x00, 0x00, 0x00, 0x00, 472 0x00, 0x00, 0x00, 0x00, 473 474 0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */ 475 0x00, 0x4e, 0x00, 0x00, 476 477 0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */ 478 0x00, 0x00, 0x00, 0x00, 479 480 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */ 481 0x00, 0x00, 0x00, 0x00, 482 0x00, 0x00, 0x00, 0x00, 483 484 0x86, 0xdd, /* ICE_ETYPE_IL 62 */ 485 486 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 64 */ 487 0x00, 0x08, 0x11, 0x40, 488 0x00, 0x00, 0x00, 0x00, 489 0x00, 0x00, 0x00, 0x00, 490 0x00, 0x00, 0x00, 0x00, 491 0x00, 0x00, 0x00, 0x00, 492 0x00, 0x00, 0x00, 0x00, 493 0x00, 0x00, 0x00, 0x00, 494 0x00, 0x00, 0x00, 0x00, 495 0x00, 0x00, 0x00, 0x00, 496 497 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 104 */ 498 0x00, 0x08, 0x00, 0x00, 499 }; 500 501 /* offset info for MAC + IPv4 + UDP dummy packet */ 502 ICE_DECLARE_PKT_OFFSETS(udp) = { 503 { ICE_MAC_OFOS, 0 }, 504 { ICE_ETYPE_OL, 12 }, 505 { ICE_IPV4_OFOS, 14 }, 506 { ICE_UDP_ILOS, 34 }, 507 { ICE_PROTOCOL_LAST, 0 }, 508 }; 509 510 /* Dummy packet for MAC + IPv4 + UDP */ 511 ICE_DECLARE_PKT_TEMPLATE(udp) = { 512 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 513 0x00, 0x00, 0x00, 0x00, 514 0x00, 0x00, 0x00, 0x00, 515 516 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 517 518 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 14 */ 519 0x00, 0x01, 0x00, 0x00, 520 0x00, 0x11, 0x00, 0x00, 521 0x00, 0x00, 0x00, 0x00, 522 0x00, 0x00, 0x00, 0x00, 523 524 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 34 */ 525 0x00, 0x08, 0x00, 0x00, 526 527 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 528 }; 529 530 /* offset info for MAC + IPv4 + TCP dummy packet */ 531 ICE_DECLARE_PKT_OFFSETS(tcp) = { 532 { ICE_MAC_OFOS, 0 }, 533 { ICE_ETYPE_OL, 12 }, 534 { ICE_IPV4_OFOS, 14 }, 535 { ICE_TCP_IL, 34 }, 536 { ICE_PROTOCOL_LAST, 0 }, 537 }; 538 539 /* Dummy packet for MAC + IPv4 + TCP */ 540 ICE_DECLARE_PKT_TEMPLATE(tcp) = { 541 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 542 0x00, 0x00, 0x00, 0x00, 543 0x00, 0x00, 0x00, 0x00, 544 545 0x08, 0x00, /* ICE_ETYPE_OL 12 */ 546 547 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 14 */ 548 0x00, 0x01, 0x00, 0x00, 549 0x00, 0x06, 0x00, 0x00, 550 0x00, 0x00, 0x00, 0x00, 551 0x00, 0x00, 0x00, 0x00, 552 553 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 34 */ 554 0x00, 0x00, 0x00, 0x00, 555 0x00, 0x00, 0x00, 0x00, 556 0x50, 0x00, 0x00, 0x00, 557 0x00, 0x00, 0x00, 0x00, 558 559 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 560 }; 561 562 ICE_DECLARE_PKT_OFFSETS(tcp_ipv6) = { 563 { ICE_MAC_OFOS, 0 }, 564 { ICE_ETYPE_OL, 12 }, 565 { ICE_IPV6_OFOS, 14 }, 566 { ICE_TCP_IL, 54 }, 567 { ICE_PROTOCOL_LAST, 0 }, 568 }; 569 570 ICE_DECLARE_PKT_TEMPLATE(tcp_ipv6) = { 571 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 572 0x00, 0x00, 0x00, 0x00, 573 0x00, 0x00, 0x00, 0x00, 574 575 0x86, 0xDD, /* ICE_ETYPE_OL 12 */ 576 577 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */ 578 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 579 0x00, 0x00, 0x00, 0x00, 580 0x00, 0x00, 0x00, 0x00, 581 0x00, 0x00, 0x00, 0x00, 582 0x00, 0x00, 0x00, 0x00, 583 0x00, 0x00, 0x00, 0x00, 584 0x00, 0x00, 0x00, 0x00, 585 0x00, 0x00, 0x00, 0x00, 586 0x00, 0x00, 0x00, 0x00, 587 588 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 54 */ 589 0x00, 0x00, 0x00, 0x00, 590 0x00, 0x00, 0x00, 0x00, 591 0x50, 0x00, 0x00, 0x00, 592 0x00, 0x00, 0x00, 0x00, 593 594 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 595 }; 596 597 /* IPv6 + UDP */ 598 ICE_DECLARE_PKT_OFFSETS(udp_ipv6) = { 599 { ICE_MAC_OFOS, 0 }, 600 { ICE_ETYPE_OL, 12 }, 601 { ICE_IPV6_OFOS, 14 }, 602 { ICE_UDP_ILOS, 54 }, 603 { ICE_PROTOCOL_LAST, 0 }, 604 }; 605 606 /* IPv6 + UDP dummy packet */ 607 ICE_DECLARE_PKT_TEMPLATE(udp_ipv6) = { 608 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 609 0x00, 0x00, 0x00, 0x00, 610 0x00, 0x00, 0x00, 0x00, 611 612 0x86, 0xDD, /* ICE_ETYPE_OL 12 */ 613 614 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 40 */ 615 0x00, 0x10, 0x11, 0x00, /* Next header UDP */ 616 0x00, 0x00, 0x00, 0x00, 617 0x00, 0x00, 0x00, 0x00, 618 0x00, 0x00, 0x00, 0x00, 619 0x00, 0x00, 0x00, 0x00, 620 0x00, 0x00, 0x00, 0x00, 621 0x00, 0x00, 0x00, 0x00, 622 0x00, 0x00, 0x00, 0x00, 623 0x00, 0x00, 0x00, 0x00, 624 625 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 54 */ 626 0x00, 0x10, 0x00, 0x00, 627 628 0x00, 0x00, 0x00, 0x00, /* needed for ESP packets */ 629 0x00, 0x00, 0x00, 0x00, 630 631 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 632 }; 633 634 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 635 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_tcp) = { 636 { ICE_MAC_OFOS, 0 }, 637 { ICE_IPV4_OFOS, 14 }, 638 { ICE_UDP_OF, 34 }, 639 { ICE_GTP, 42 }, 640 { ICE_IPV4_IL, 62 }, 641 { ICE_TCP_IL, 82 }, 642 { ICE_PROTOCOL_LAST, 0 }, 643 }; 644 645 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_tcp) = { 646 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 647 0x00, 0x00, 0x00, 0x00, 648 0x00, 0x00, 0x00, 0x00, 649 0x08, 0x00, 650 651 0x45, 0x00, 0x00, 0x58, /* IP 14 */ 652 0x00, 0x00, 0x00, 0x00, 653 0x00, 0x11, 0x00, 0x00, 654 0x00, 0x00, 0x00, 0x00, 655 0x00, 0x00, 0x00, 0x00, 656 657 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 658 0x00, 0x44, 0x00, 0x00, 659 660 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 42 */ 661 0x00, 0x00, 0x00, 0x00, 662 0x00, 0x00, 0x00, 0x85, 663 664 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 665 0x00, 0x00, 0x00, 0x00, 666 667 0x45, 0x00, 0x00, 0x28, /* IP 62 */ 668 0x00, 0x00, 0x00, 0x00, 669 0x00, 0x06, 0x00, 0x00, 670 0x00, 0x00, 0x00, 0x00, 671 0x00, 0x00, 0x00, 0x00, 672 673 0x00, 0x00, 0x00, 0x00, /* TCP 82 */ 674 0x00, 0x00, 0x00, 0x00, 675 0x00, 0x00, 0x00, 0x00, 676 0x50, 0x00, 0x00, 0x00, 677 0x00, 0x00, 0x00, 0x00, 678 679 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 680 }; 681 682 /* Outer IPv4 + Outer UDP + GTP + Inner IPv4 + Inner UDP */ 683 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4_udp) = { 684 { ICE_MAC_OFOS, 0 }, 685 { ICE_IPV4_OFOS, 14 }, 686 { ICE_UDP_OF, 34 }, 687 { ICE_GTP, 42 }, 688 { ICE_IPV4_IL, 62 }, 689 { ICE_UDP_ILOS, 82 }, 690 { ICE_PROTOCOL_LAST, 0 }, 691 }; 692 693 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4_udp) = { 694 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 695 0x00, 0x00, 0x00, 0x00, 696 0x00, 0x00, 0x00, 0x00, 697 0x08, 0x00, 698 699 0x45, 0x00, 0x00, 0x4c, /* IP 14 */ 700 0x00, 0x00, 0x00, 0x00, 701 0x00, 0x11, 0x00, 0x00, 702 0x00, 0x00, 0x00, 0x00, 703 0x00, 0x00, 0x00, 0x00, 704 705 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 706 0x00, 0x38, 0x00, 0x00, 707 708 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 42 */ 709 0x00, 0x00, 0x00, 0x00, 710 0x00, 0x00, 0x00, 0x85, 711 712 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 713 0x00, 0x00, 0x00, 0x00, 714 715 0x45, 0x00, 0x00, 0x1c, /* IP 62 */ 716 0x00, 0x00, 0x00, 0x00, 717 0x00, 0x11, 0x00, 0x00, 718 0x00, 0x00, 0x00, 0x00, 719 0x00, 0x00, 0x00, 0x00, 720 721 0x00, 0x00, 0x00, 0x00, /* UDP 82 */ 722 0x00, 0x08, 0x00, 0x00, 723 724 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 725 }; 726 727 /* Outer IPv6 + Outer UDP + GTP + Inner IPv4 + Inner TCP */ 728 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_tcp) = { 729 { ICE_MAC_OFOS, 0 }, 730 { ICE_IPV4_OFOS, 14 }, 731 { ICE_UDP_OF, 34 }, 732 { ICE_GTP, 42 }, 733 { ICE_IPV6_IL, 62 }, 734 { ICE_TCP_IL, 102 }, 735 { ICE_PROTOCOL_LAST, 0 }, 736 }; 737 738 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_tcp) = { 739 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 740 0x00, 0x00, 0x00, 0x00, 741 0x00, 0x00, 0x00, 0x00, 742 0x08, 0x00, 743 744 0x45, 0x00, 0x00, 0x6c, /* IP 14 */ 745 0x00, 0x00, 0x00, 0x00, 746 0x00, 0x11, 0x00, 0x00, 747 0x00, 0x00, 0x00, 0x00, 748 0x00, 0x00, 0x00, 0x00, 749 750 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 751 0x00, 0x58, 0x00, 0x00, 752 753 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 42 */ 754 0x00, 0x00, 0x00, 0x00, 755 0x00, 0x00, 0x00, 0x85, 756 757 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 758 0x00, 0x00, 0x00, 0x00, 759 760 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 761 0x00, 0x14, 0x06, 0x00, 762 0x00, 0x00, 0x00, 0x00, 763 0x00, 0x00, 0x00, 0x00, 764 0x00, 0x00, 0x00, 0x00, 765 0x00, 0x00, 0x00, 0x00, 766 0x00, 0x00, 0x00, 0x00, 767 0x00, 0x00, 0x00, 0x00, 768 0x00, 0x00, 0x00, 0x00, 769 0x00, 0x00, 0x00, 0x00, 770 771 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 772 0x00, 0x00, 0x00, 0x00, 773 0x00, 0x00, 0x00, 0x00, 774 0x50, 0x00, 0x00, 0x00, 775 0x00, 0x00, 0x00, 0x00, 776 777 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 778 }; 779 780 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv6_udp) = { 781 { ICE_MAC_OFOS, 0 }, 782 { ICE_IPV4_OFOS, 14 }, 783 { ICE_UDP_OF, 34 }, 784 { ICE_GTP, 42 }, 785 { ICE_IPV6_IL, 62 }, 786 { ICE_UDP_ILOS, 102 }, 787 { ICE_PROTOCOL_LAST, 0 }, 788 }; 789 790 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv6_udp) = { 791 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 792 0x00, 0x00, 0x00, 0x00, 793 0x00, 0x00, 0x00, 0x00, 794 0x08, 0x00, 795 796 0x45, 0x00, 0x00, 0x60, /* IP 14 */ 797 0x00, 0x00, 0x00, 0x00, 798 0x00, 0x11, 0x00, 0x00, 799 0x00, 0x00, 0x00, 0x00, 800 0x00, 0x00, 0x00, 0x00, 801 802 0x00, 0x00, 0x08, 0x68, /* UDP 34 */ 803 0x00, 0x4c, 0x00, 0x00, 804 805 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 42 */ 806 0x00, 0x00, 0x00, 0x00, 807 0x00, 0x00, 0x00, 0x85, 808 809 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 54 */ 810 0x00, 0x00, 0x00, 0x00, 811 812 0x60, 0x00, 0x00, 0x00, /* IPv6 62 */ 813 0x00, 0x08, 0x11, 0x00, 814 0x00, 0x00, 0x00, 0x00, 815 0x00, 0x00, 0x00, 0x00, 816 0x00, 0x00, 0x00, 0x00, 817 0x00, 0x00, 0x00, 0x00, 818 0x00, 0x00, 0x00, 0x00, 819 0x00, 0x00, 0x00, 0x00, 820 0x00, 0x00, 0x00, 0x00, 821 0x00, 0x00, 0x00, 0x00, 822 823 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 824 0x00, 0x08, 0x00, 0x00, 825 826 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 827 }; 828 829 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_tcp) = { 830 { ICE_MAC_OFOS, 0 }, 831 { ICE_IPV6_OFOS, 14 }, 832 { ICE_UDP_OF, 54 }, 833 { ICE_GTP, 62 }, 834 { ICE_IPV4_IL, 82 }, 835 { ICE_TCP_IL, 102 }, 836 { ICE_PROTOCOL_LAST, 0 }, 837 }; 838 839 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_tcp) = { 840 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 841 0x00, 0x00, 0x00, 0x00, 842 0x00, 0x00, 0x00, 0x00, 843 0x86, 0xdd, 844 845 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 846 0x00, 0x44, 0x11, 0x00, 847 0x00, 0x00, 0x00, 0x00, 848 0x00, 0x00, 0x00, 0x00, 849 0x00, 0x00, 0x00, 0x00, 850 0x00, 0x00, 0x00, 0x00, 851 0x00, 0x00, 0x00, 0x00, 852 0x00, 0x00, 0x00, 0x00, 853 0x00, 0x00, 0x00, 0x00, 854 0x00, 0x00, 0x00, 0x00, 855 856 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 857 0x00, 0x44, 0x00, 0x00, 858 859 0x34, 0xff, 0x00, 0x34, /* ICE_GTP Header 62 */ 860 0x00, 0x00, 0x00, 0x00, 861 0x00, 0x00, 0x00, 0x85, 862 863 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 864 0x00, 0x00, 0x00, 0x00, 865 866 0x45, 0x00, 0x00, 0x28, /* IP 82 */ 867 0x00, 0x00, 0x00, 0x00, 868 0x00, 0x06, 0x00, 0x00, 869 0x00, 0x00, 0x00, 0x00, 870 0x00, 0x00, 0x00, 0x00, 871 872 0x00, 0x00, 0x00, 0x00, /* TCP 102 */ 873 0x00, 0x00, 0x00, 0x00, 874 0x00, 0x00, 0x00, 0x00, 875 0x50, 0x00, 0x00, 0x00, 876 0x00, 0x00, 0x00, 0x00, 877 878 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 879 }; 880 881 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv4_udp) = { 882 { ICE_MAC_OFOS, 0 }, 883 { ICE_IPV6_OFOS, 14 }, 884 { ICE_UDP_OF, 54 }, 885 { ICE_GTP, 62 }, 886 { ICE_IPV4_IL, 82 }, 887 { ICE_UDP_ILOS, 102 }, 888 { ICE_PROTOCOL_LAST, 0 }, 889 }; 890 891 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv4_udp) = { 892 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 893 0x00, 0x00, 0x00, 0x00, 894 0x00, 0x00, 0x00, 0x00, 895 0x86, 0xdd, 896 897 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 898 0x00, 0x38, 0x11, 0x00, 899 0x00, 0x00, 0x00, 0x00, 900 0x00, 0x00, 0x00, 0x00, 901 0x00, 0x00, 0x00, 0x00, 902 0x00, 0x00, 0x00, 0x00, 903 0x00, 0x00, 0x00, 0x00, 904 0x00, 0x00, 0x00, 0x00, 905 0x00, 0x00, 0x00, 0x00, 906 0x00, 0x00, 0x00, 0x00, 907 908 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 909 0x00, 0x38, 0x00, 0x00, 910 911 0x34, 0xff, 0x00, 0x28, /* ICE_GTP Header 62 */ 912 0x00, 0x00, 0x00, 0x00, 913 0x00, 0x00, 0x00, 0x85, 914 915 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 916 0x00, 0x00, 0x00, 0x00, 917 918 0x45, 0x00, 0x00, 0x1c, /* IP 82 */ 919 0x00, 0x00, 0x00, 0x00, 920 0x00, 0x11, 0x00, 0x00, 921 0x00, 0x00, 0x00, 0x00, 922 0x00, 0x00, 0x00, 0x00, 923 924 0x00, 0x00, 0x00, 0x00, /* UDP 102 */ 925 0x00, 0x08, 0x00, 0x00, 926 927 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 928 }; 929 930 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_tcp) = { 931 { ICE_MAC_OFOS, 0 }, 932 { ICE_IPV6_OFOS, 14 }, 933 { ICE_UDP_OF, 54 }, 934 { ICE_GTP, 62 }, 935 { ICE_IPV6_IL, 82 }, 936 { ICE_TCP_IL, 122 }, 937 { ICE_PROTOCOL_LAST, 0 }, 938 }; 939 940 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_tcp) = { 941 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 942 0x00, 0x00, 0x00, 0x00, 943 0x00, 0x00, 0x00, 0x00, 944 0x86, 0xdd, 945 946 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 947 0x00, 0x58, 0x11, 0x00, 948 0x00, 0x00, 0x00, 0x00, 949 0x00, 0x00, 0x00, 0x00, 950 0x00, 0x00, 0x00, 0x00, 951 0x00, 0x00, 0x00, 0x00, 952 0x00, 0x00, 0x00, 0x00, 953 0x00, 0x00, 0x00, 0x00, 954 0x00, 0x00, 0x00, 0x00, 955 0x00, 0x00, 0x00, 0x00, 956 957 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 958 0x00, 0x58, 0x00, 0x00, 959 960 0x34, 0xff, 0x00, 0x48, /* ICE_GTP Header 62 */ 961 0x00, 0x00, 0x00, 0x00, 962 0x00, 0x00, 0x00, 0x85, 963 964 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 965 0x00, 0x00, 0x00, 0x00, 966 967 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 968 0x00, 0x14, 0x06, 0x00, 969 0x00, 0x00, 0x00, 0x00, 970 0x00, 0x00, 0x00, 0x00, 971 0x00, 0x00, 0x00, 0x00, 972 0x00, 0x00, 0x00, 0x00, 973 0x00, 0x00, 0x00, 0x00, 974 0x00, 0x00, 0x00, 0x00, 975 0x00, 0x00, 0x00, 0x00, 976 0x00, 0x00, 0x00, 0x00, 977 978 0x00, 0x00, 0x00, 0x00, /* TCP 122 */ 979 0x00, 0x00, 0x00, 0x00, 980 0x00, 0x00, 0x00, 0x00, 981 0x50, 0x00, 0x00, 0x00, 982 0x00, 0x00, 0x00, 0x00, 983 984 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 985 }; 986 987 ICE_DECLARE_PKT_OFFSETS(ipv6_gtpu_ipv6_udp) = { 988 { ICE_MAC_OFOS, 0 }, 989 { ICE_IPV6_OFOS, 14 }, 990 { ICE_UDP_OF, 54 }, 991 { ICE_GTP, 62 }, 992 { ICE_IPV6_IL, 82 }, 993 { ICE_UDP_ILOS, 122 }, 994 { ICE_PROTOCOL_LAST, 0 }, 995 }; 996 997 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtpu_ipv6_udp) = { 998 0x00, 0x00, 0x00, 0x00, /* Ethernet 0 */ 999 0x00, 0x00, 0x00, 0x00, 1000 0x00, 0x00, 0x00, 0x00, 1001 0x86, 0xdd, 1002 1003 0x60, 0x00, 0x00, 0x00, /* IPv6 14 */ 1004 0x00, 0x4c, 0x11, 0x00, 1005 0x00, 0x00, 0x00, 0x00, 1006 0x00, 0x00, 0x00, 0x00, 1007 0x00, 0x00, 0x00, 0x00, 1008 0x00, 0x00, 0x00, 0x00, 1009 0x00, 0x00, 0x00, 0x00, 1010 0x00, 0x00, 0x00, 0x00, 1011 0x00, 0x00, 0x00, 0x00, 1012 0x00, 0x00, 0x00, 0x00, 1013 1014 0x00, 0x00, 0x08, 0x68, /* UDP 54 */ 1015 0x00, 0x4c, 0x00, 0x00, 1016 1017 0x34, 0xff, 0x00, 0x3c, /* ICE_GTP Header 62 */ 1018 0x00, 0x00, 0x00, 0x00, 1019 0x00, 0x00, 0x00, 0x85, 1020 1021 0x02, 0x00, 0x00, 0x00, /* GTP_PDUSession_ExtensionHeader 74 */ 1022 0x00, 0x00, 0x00, 0x00, 1023 1024 0x60, 0x00, 0x00, 0x00, /* IPv6 82 */ 1025 0x00, 0x08, 0x11, 0x00, 1026 0x00, 0x00, 0x00, 0x00, 1027 0x00, 0x00, 0x00, 0x00, 1028 0x00, 0x00, 0x00, 0x00, 1029 0x00, 0x00, 0x00, 0x00, 1030 0x00, 0x00, 0x00, 0x00, 1031 0x00, 0x00, 0x00, 0x00, 1032 0x00, 0x00, 0x00, 0x00, 1033 0x00, 0x00, 0x00, 0x00, 1034 1035 0x00, 0x00, 0x00, 0x00, /* UDP 122 */ 1036 0x00, 0x08, 0x00, 0x00, 1037 1038 0x00, 0x00, /* 2 bytes for 4 byte alignment */ 1039 }; 1040 1041 ICE_DECLARE_PKT_OFFSETS(ipv4_gtpu_ipv4) = { 1042 { ICE_MAC_OFOS, 0 }, 1043 { ICE_IPV4_OFOS, 14 }, 1044 { ICE_UDP_OF, 34 }, 1045 { ICE_GTP_NO_PAY, 42 }, 1046 { ICE_PROTOCOL_LAST, 0 }, 1047 }; 1048 1049 ICE_DECLARE_PKT_TEMPLATE(ipv4_gtpu_ipv4) = { 1050 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1051 0x00, 0x00, 0x00, 0x00, 1052 0x00, 0x00, 0x00, 0x00, 1053 0x08, 0x00, 1054 1055 0x45, 0x00, 0x00, 0x44, /* ICE_IPV4_OFOS 14 */ 1056 0x00, 0x00, 0x40, 0x00, 1057 0x40, 0x11, 0x00, 0x00, 1058 0x00, 0x00, 0x00, 0x00, 1059 0x00, 0x00, 0x00, 0x00, 1060 1061 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 34 */ 1062 0x00, 0x00, 0x00, 0x00, 1063 1064 0x34, 0xff, 0x00, 0x28, /* ICE_GTP 42 */ 1065 0x00, 0x00, 0x00, 0x00, 1066 0x00, 0x00, 0x00, 0x85, 1067 1068 0x02, 0x00, 0x00, 0x00, /* PDU Session extension header */ 1069 0x00, 0x00, 0x00, 0x00, 1070 1071 0x45, 0x00, 0x00, 0x14, /* ICE_IPV4_IL 62 */ 1072 0x00, 0x00, 0x40, 0x00, 1073 0x40, 0x00, 0x00, 0x00, 1074 0x00, 0x00, 0x00, 0x00, 1075 0x00, 0x00, 0x00, 0x00, 1076 0x00, 0x00, 1077 }; 1078 1079 ICE_DECLARE_PKT_OFFSETS(ipv6_gtp) = { 1080 { ICE_MAC_OFOS, 0 }, 1081 { ICE_IPV6_OFOS, 14 }, 1082 { ICE_UDP_OF, 54 }, 1083 { ICE_GTP_NO_PAY, 62 }, 1084 { ICE_PROTOCOL_LAST, 0 }, 1085 }; 1086 1087 ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = { 1088 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1089 0x00, 0x00, 0x00, 0x00, 1090 0x00, 0x00, 0x00, 0x00, 1091 0x86, 0xdd, 1092 1093 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 14 */ 1094 0x00, 0x6c, 0x11, 0x00, /* Next header UDP*/ 1095 0x00, 0x00, 0x00, 0x00, 1096 0x00, 0x00, 0x00, 0x00, 1097 0x00, 0x00, 0x00, 0x00, 1098 0x00, 0x00, 0x00, 0x00, 1099 0x00, 0x00, 0x00, 0x00, 1100 0x00, 0x00, 0x00, 0x00, 1101 0x00, 0x00, 0x00, 0x00, 1102 0x00, 0x00, 0x00, 0x00, 1103 1104 0x08, 0x68, 0x08, 0x68, /* ICE_UDP_OF 54 */ 1105 0x00, 0x00, 0x00, 0x00, 1106 1107 0x30, 0x00, 0x00, 0x28, /* ICE_GTP 62 */ 1108 0x00, 0x00, 0x00, 0x00, 1109 1110 0x00, 0x00, 1111 }; 1112 1113 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = { 1114 { ICE_MAC_OFOS, 0 }, 1115 { ICE_ETYPE_OL, 12 }, 1116 { ICE_PPPOE, 14 }, 1117 { ICE_IPV4_OFOS, 22 }, 1118 { ICE_TCP_IL, 42 }, 1119 { ICE_PROTOCOL_LAST, 0 }, 1120 }; 1121 1122 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = { 1123 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1124 0x00, 0x00, 0x00, 0x00, 1125 0x00, 0x00, 0x00, 0x00, 1126 1127 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1128 1129 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1130 0x00, 0x16, 1131 1132 0x00, 0x21, /* PPP Link Layer 20 */ 1133 1134 0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */ 1135 0x00, 0x01, 0x00, 0x00, 1136 0x00, 0x06, 0x00, 0x00, 1137 0x00, 0x00, 0x00, 0x00, 1138 0x00, 0x00, 0x00, 0x00, 1139 1140 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */ 1141 0x00, 0x00, 0x00, 0x00, 1142 0x00, 0x00, 0x00, 0x00, 1143 0x50, 0x00, 0x00, 0x00, 1144 0x00, 0x00, 0x00, 0x00, 1145 1146 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1147 }; 1148 1149 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = { 1150 { ICE_MAC_OFOS, 0 }, 1151 { ICE_ETYPE_OL, 12 }, 1152 { ICE_PPPOE, 14 }, 1153 { ICE_IPV4_OFOS, 22 }, 1154 { ICE_UDP_ILOS, 42 }, 1155 { ICE_PROTOCOL_LAST, 0 }, 1156 }; 1157 1158 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = { 1159 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1160 0x00, 0x00, 0x00, 0x00, 1161 0x00, 0x00, 0x00, 0x00, 1162 1163 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1164 1165 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1166 0x00, 0x16, 1167 1168 0x00, 0x21, /* PPP Link Layer 20 */ 1169 1170 0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */ 1171 0x00, 0x01, 0x00, 0x00, 1172 0x00, 0x11, 0x00, 0x00, 1173 0x00, 0x00, 0x00, 0x00, 1174 0x00, 0x00, 0x00, 0x00, 1175 1176 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */ 1177 0x00, 0x08, 0x00, 0x00, 1178 1179 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1180 }; 1181 1182 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = { 1183 { ICE_MAC_OFOS, 0 }, 1184 { ICE_ETYPE_OL, 12 }, 1185 { ICE_PPPOE, 14 }, 1186 { ICE_IPV6_OFOS, 22 }, 1187 { ICE_TCP_IL, 62 }, 1188 { ICE_PROTOCOL_LAST, 0 }, 1189 }; 1190 1191 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = { 1192 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1193 0x00, 0x00, 0x00, 0x00, 1194 0x00, 0x00, 0x00, 0x00, 1195 1196 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1197 1198 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1199 0x00, 0x2a, 1200 1201 0x00, 0x57, /* PPP Link Layer 20 */ 1202 1203 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */ 1204 0x00, 0x14, 0x06, 0x00, /* Next header is TCP */ 1205 0x00, 0x00, 0x00, 0x00, 1206 0x00, 0x00, 0x00, 0x00, 1207 0x00, 0x00, 0x00, 0x00, 1208 0x00, 0x00, 0x00, 0x00, 1209 0x00, 0x00, 0x00, 0x00, 1210 0x00, 0x00, 0x00, 0x00, 1211 0x00, 0x00, 0x00, 0x00, 1212 0x00, 0x00, 0x00, 0x00, 1213 1214 0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 62 */ 1215 0x00, 0x00, 0x00, 0x00, 1216 0x00, 0x00, 0x00, 0x00, 1217 0x50, 0x00, 0x00, 0x00, 1218 0x00, 0x00, 0x00, 0x00, 1219 1220 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1221 }; 1222 1223 ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = { 1224 { ICE_MAC_OFOS, 0 }, 1225 { ICE_ETYPE_OL, 12 }, 1226 { ICE_PPPOE, 14 }, 1227 { ICE_IPV6_OFOS, 22 }, 1228 { ICE_UDP_ILOS, 62 }, 1229 { ICE_PROTOCOL_LAST, 0 }, 1230 }; 1231 1232 ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = { 1233 0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */ 1234 0x00, 0x00, 0x00, 0x00, 1235 0x00, 0x00, 0x00, 0x00, 1236 1237 0x88, 0x64, /* ICE_ETYPE_OL 12 */ 1238 1239 0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */ 1240 0x00, 0x2a, 1241 1242 0x00, 0x57, /* PPP Link Layer 20 */ 1243 1244 0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */ 1245 0x00, 0x08, 0x11, 0x00, /* Next header UDP*/ 1246 0x00, 0x00, 0x00, 0x00, 1247 0x00, 0x00, 0x00, 0x00, 1248 0x00, 0x00, 0x00, 0x00, 1249 0x00, 0x00, 0x00, 0x00, 1250 0x00, 0x00, 0x00, 0x00, 1251 0x00, 0x00, 0x00, 0x00, 1252 0x00, 0x00, 0x00, 0x00, 1253 0x00, 0x00, 0x00, 0x00, 1254 1255 0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 62 */ 1256 0x00, 0x08, 0x00, 0x00, 1257 1258 0x00, 0x00, /* 2 bytes for 4 bytes alignment */ 1259 }; 1260 1261 static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = { 1262 ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 | 1263 ICE_PKT_GTP_NOPAY), 1264 ICE_PKT_PROFILE(ipv6_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU | 1265 ICE_PKT_OUTER_IPV6 | 1266 ICE_PKT_INNER_IPV6 | 1267 ICE_PKT_INNER_UDP), 1268 ICE_PKT_PROFILE(ipv6_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU | 1269 ICE_PKT_OUTER_IPV6 | 1270 ICE_PKT_INNER_IPV6), 1271 ICE_PKT_PROFILE(ipv6_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU | 1272 ICE_PKT_OUTER_IPV6 | 1273 ICE_PKT_INNER_UDP), 1274 ICE_PKT_PROFILE(ipv6_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU | 1275 ICE_PKT_OUTER_IPV6), 1276 ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPU | ICE_PKT_GTP_NOPAY), 1277 ICE_PKT_PROFILE(ipv4_gtpu_ipv6_udp, ICE_PKT_TUN_GTPU | 1278 ICE_PKT_INNER_IPV6 | 1279 ICE_PKT_INNER_UDP), 1280 ICE_PKT_PROFILE(ipv4_gtpu_ipv6_tcp, ICE_PKT_TUN_GTPU | 1281 ICE_PKT_INNER_IPV6), 1282 ICE_PKT_PROFILE(ipv4_gtpu_ipv4_udp, ICE_PKT_TUN_GTPU | 1283 ICE_PKT_INNER_UDP), 1284 ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU), 1285 ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6), 1286 ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC), 1287 ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 | 1288 ICE_PKT_INNER_UDP), 1289 ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6), 1290 ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP), 1291 ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE), 1292 ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 | 1293 ICE_PKT_INNER_TCP), 1294 ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP), 1295 ICE_PKT_PROFILE(gre_ipv6_udp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6), 1296 ICE_PKT_PROFILE(gre_udp, ICE_PKT_TUN_NVGRE), 1297 ICE_PKT_PROFILE(udp_tun_ipv6_tcp, ICE_PKT_TUN_UDP | 1298 ICE_PKT_INNER_IPV6 | 1299 ICE_PKT_INNER_TCP), 1300 ICE_PKT_PROFILE(udp_tun_tcp, ICE_PKT_TUN_UDP | ICE_PKT_INNER_TCP), 1301 ICE_PKT_PROFILE(udp_tun_ipv6_udp, ICE_PKT_TUN_UDP | 1302 ICE_PKT_INNER_IPV6), 1303 ICE_PKT_PROFILE(udp_tun_udp, ICE_PKT_TUN_UDP), 1304 ICE_PKT_PROFILE(udp_ipv6, ICE_PKT_OUTER_IPV6 | ICE_PKT_INNER_UDP), 1305 ICE_PKT_PROFILE(udp, ICE_PKT_INNER_UDP), 1306 ICE_PKT_PROFILE(tcp_ipv6, ICE_PKT_OUTER_IPV6), 1307 ICE_PKT_PROFILE(tcp, 0), 1308 }; 1309 1310 #define ICE_SW_RULE_RX_TX_HDR_SIZE(s, l) struct_size((s), hdr_data, (l)) 1311 #define ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s) \ 1312 ICE_SW_RULE_RX_TX_HDR_SIZE((s), DUMMY_ETH_HDR_LEN) 1313 #define ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s) \ 1314 ICE_SW_RULE_RX_TX_HDR_SIZE((s), 0) 1315 #define ICE_SW_RULE_LG_ACT_SIZE(s, n) struct_size((s), act, (n)) 1316 #define ICE_SW_RULE_VSI_LIST_SIZE(s, n) struct_size((s), vsi, (n)) 1317 1318 /* this is a recipe to profile association bitmap */ 1319 static DECLARE_BITMAP(recipe_to_profile[ICE_MAX_NUM_RECIPES], 1320 ICE_MAX_NUM_PROFILES); 1321 1322 /* this is a profile to recipe association bitmap */ 1323 static DECLARE_BITMAP(profile_to_recipe[ICE_MAX_NUM_PROFILES], 1324 ICE_MAX_NUM_RECIPES); 1325 1326 /** 1327 * ice_init_def_sw_recp - initialize the recipe book keeping tables 1328 * @hw: pointer to the HW struct 1329 * 1330 * Allocate memory for the entire recipe table and initialize the structures/ 1331 * entries corresponding to basic recipes. 1332 */ 1333 int ice_init_def_sw_recp(struct ice_hw *hw) 1334 { 1335 struct ice_sw_recipe *recps; 1336 u8 i; 1337 1338 recps = devm_kcalloc(ice_hw_to_dev(hw), ICE_MAX_NUM_RECIPES, 1339 sizeof(*recps), GFP_KERNEL); 1340 if (!recps) 1341 return -ENOMEM; 1342 1343 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 1344 recps[i].root_rid = i; 1345 INIT_LIST_HEAD(&recps[i].filt_rules); 1346 INIT_LIST_HEAD(&recps[i].filt_replay_rules); 1347 INIT_LIST_HEAD(&recps[i].rg_list); 1348 mutex_init(&recps[i].filt_rule_lock); 1349 } 1350 1351 hw->switch_info->recp_list = recps; 1352 1353 return 0; 1354 } 1355 1356 /** 1357 * ice_aq_get_sw_cfg - get switch configuration 1358 * @hw: pointer to the hardware structure 1359 * @buf: pointer to the result buffer 1360 * @buf_size: length of the buffer available for response 1361 * @req_desc: pointer to requested descriptor 1362 * @num_elems: pointer to number of elements 1363 * @cd: pointer to command details structure or NULL 1364 * 1365 * Get switch configuration (0x0200) to be placed in buf. 1366 * This admin command returns information such as initial VSI/port number 1367 * and switch ID it belongs to. 1368 * 1369 * NOTE: *req_desc is both an input/output parameter. 1370 * The caller of this function first calls this function with *request_desc set 1371 * to 0. If the response from f/w has *req_desc set to 0, all the switch 1372 * configuration information has been returned; if non-zero (meaning not all 1373 * the information was returned), the caller should call this function again 1374 * with *req_desc set to the previous value returned by f/w to get the 1375 * next block of switch configuration information. 1376 * 1377 * *num_elems is output only parameter. This reflects the number of elements 1378 * in response buffer. The caller of this function to use *num_elems while 1379 * parsing the response buffer. 1380 */ 1381 static int 1382 ice_aq_get_sw_cfg(struct ice_hw *hw, struct ice_aqc_get_sw_cfg_resp_elem *buf, 1383 u16 buf_size, u16 *req_desc, u16 *num_elems, 1384 struct ice_sq_cd *cd) 1385 { 1386 struct ice_aqc_get_sw_cfg *cmd; 1387 struct ice_aq_desc desc; 1388 int status; 1389 1390 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_sw_cfg); 1391 cmd = &desc.params.get_sw_conf; 1392 cmd->element = cpu_to_le16(*req_desc); 1393 1394 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd); 1395 if (!status) { 1396 *req_desc = le16_to_cpu(cmd->element); 1397 *num_elems = le16_to_cpu(cmd->num_elems); 1398 } 1399 1400 return status; 1401 } 1402 1403 /** 1404 * ice_aq_add_vsi 1405 * @hw: pointer to the HW struct 1406 * @vsi_ctx: pointer to a VSI context struct 1407 * @cd: pointer to command details structure or NULL 1408 * 1409 * Add a VSI context to the hardware (0x0210) 1410 */ 1411 static int 1412 ice_aq_add_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 1413 struct ice_sq_cd *cd) 1414 { 1415 struct ice_aqc_add_update_free_vsi_resp *res; 1416 struct ice_aqc_add_get_update_free_vsi *cmd; 1417 struct ice_aq_desc desc; 1418 int status; 1419 1420 cmd = &desc.params.vsi_cmd; 1421 res = &desc.params.add_update_free_vsi_res; 1422 1423 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_vsi); 1424 1425 if (!vsi_ctx->alloc_from_pool) 1426 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | 1427 ICE_AQ_VSI_IS_VALID); 1428 cmd->vf_id = vsi_ctx->vf_num; 1429 1430 cmd->vsi_flags = cpu_to_le16(vsi_ctx->flags); 1431 1432 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1433 1434 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 1435 sizeof(vsi_ctx->info), cd); 1436 1437 if (!status) { 1438 vsi_ctx->vsi_num = le16_to_cpu(res->vsi_num) & ICE_AQ_VSI_NUM_M; 1439 vsi_ctx->vsis_allocd = le16_to_cpu(res->vsi_used); 1440 vsi_ctx->vsis_unallocated = le16_to_cpu(res->vsi_free); 1441 } 1442 1443 return status; 1444 } 1445 1446 /** 1447 * ice_aq_free_vsi 1448 * @hw: pointer to the HW struct 1449 * @vsi_ctx: pointer to a VSI context struct 1450 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 1451 * @cd: pointer to command details structure or NULL 1452 * 1453 * Free VSI context info from hardware (0x0213) 1454 */ 1455 static int 1456 ice_aq_free_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 1457 bool keep_vsi_alloc, struct ice_sq_cd *cd) 1458 { 1459 struct ice_aqc_add_update_free_vsi_resp *resp; 1460 struct ice_aqc_add_get_update_free_vsi *cmd; 1461 struct ice_aq_desc desc; 1462 int status; 1463 1464 cmd = &desc.params.vsi_cmd; 1465 resp = &desc.params.add_update_free_vsi_res; 1466 1467 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_free_vsi); 1468 1469 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 1470 if (keep_vsi_alloc) 1471 cmd->cmd_flags = cpu_to_le16(ICE_AQ_VSI_KEEP_ALLOC); 1472 1473 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 1474 if (!status) { 1475 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used); 1476 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free); 1477 } 1478 1479 return status; 1480 } 1481 1482 /** 1483 * ice_aq_update_vsi 1484 * @hw: pointer to the HW struct 1485 * @vsi_ctx: pointer to a VSI context struct 1486 * @cd: pointer to command details structure or NULL 1487 * 1488 * Update VSI context in the hardware (0x0211) 1489 */ 1490 static int 1491 ice_aq_update_vsi(struct ice_hw *hw, struct ice_vsi_ctx *vsi_ctx, 1492 struct ice_sq_cd *cd) 1493 { 1494 struct ice_aqc_add_update_free_vsi_resp *resp; 1495 struct ice_aqc_add_get_update_free_vsi *cmd; 1496 struct ice_aq_desc desc; 1497 int status; 1498 1499 cmd = &desc.params.vsi_cmd; 1500 resp = &desc.params.add_update_free_vsi_res; 1501 1502 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_vsi); 1503 1504 cmd->vsi_num = cpu_to_le16(vsi_ctx->vsi_num | ICE_AQ_VSI_IS_VALID); 1505 1506 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1507 1508 status = ice_aq_send_cmd(hw, &desc, &vsi_ctx->info, 1509 sizeof(vsi_ctx->info), cd); 1510 1511 if (!status) { 1512 vsi_ctx->vsis_allocd = le16_to_cpu(resp->vsi_used); 1513 vsi_ctx->vsis_unallocated = le16_to_cpu(resp->vsi_free); 1514 } 1515 1516 return status; 1517 } 1518 1519 /** 1520 * ice_is_vsi_valid - check whether the VSI is valid or not 1521 * @hw: pointer to the HW struct 1522 * @vsi_handle: VSI handle 1523 * 1524 * check whether the VSI is valid or not 1525 */ 1526 bool ice_is_vsi_valid(struct ice_hw *hw, u16 vsi_handle) 1527 { 1528 return vsi_handle < ICE_MAX_VSI && hw->vsi_ctx[vsi_handle]; 1529 } 1530 1531 /** 1532 * ice_get_hw_vsi_num - return the HW VSI number 1533 * @hw: pointer to the HW struct 1534 * @vsi_handle: VSI handle 1535 * 1536 * return the HW VSI number 1537 * Caution: call this function only if VSI is valid (ice_is_vsi_valid) 1538 */ 1539 u16 ice_get_hw_vsi_num(struct ice_hw *hw, u16 vsi_handle) 1540 { 1541 return hw->vsi_ctx[vsi_handle]->vsi_num; 1542 } 1543 1544 /** 1545 * ice_get_vsi_ctx - return the VSI context entry for a given VSI handle 1546 * @hw: pointer to the HW struct 1547 * @vsi_handle: VSI handle 1548 * 1549 * return the VSI context entry for a given VSI handle 1550 */ 1551 struct ice_vsi_ctx *ice_get_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 1552 { 1553 return (vsi_handle >= ICE_MAX_VSI) ? NULL : hw->vsi_ctx[vsi_handle]; 1554 } 1555 1556 /** 1557 * ice_save_vsi_ctx - save the VSI context for a given VSI handle 1558 * @hw: pointer to the HW struct 1559 * @vsi_handle: VSI handle 1560 * @vsi: VSI context pointer 1561 * 1562 * save the VSI context entry for a given VSI handle 1563 */ 1564 static void 1565 ice_save_vsi_ctx(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi) 1566 { 1567 hw->vsi_ctx[vsi_handle] = vsi; 1568 } 1569 1570 /** 1571 * ice_clear_vsi_q_ctx - clear VSI queue contexts for all TCs 1572 * @hw: pointer to the HW struct 1573 * @vsi_handle: VSI handle 1574 */ 1575 static void ice_clear_vsi_q_ctx(struct ice_hw *hw, u16 vsi_handle) 1576 { 1577 struct ice_vsi_ctx *vsi; 1578 u8 i; 1579 1580 vsi = ice_get_vsi_ctx(hw, vsi_handle); 1581 if (!vsi) 1582 return; 1583 ice_for_each_traffic_class(i) { 1584 if (vsi->lan_q_ctx[i]) { 1585 devm_kfree(ice_hw_to_dev(hw), vsi->lan_q_ctx[i]); 1586 vsi->lan_q_ctx[i] = NULL; 1587 } 1588 if (vsi->rdma_q_ctx[i]) { 1589 devm_kfree(ice_hw_to_dev(hw), vsi->rdma_q_ctx[i]); 1590 vsi->rdma_q_ctx[i] = NULL; 1591 } 1592 } 1593 } 1594 1595 /** 1596 * ice_clear_vsi_ctx - clear the VSI context entry 1597 * @hw: pointer to the HW struct 1598 * @vsi_handle: VSI handle 1599 * 1600 * clear the VSI context entry 1601 */ 1602 static void ice_clear_vsi_ctx(struct ice_hw *hw, u16 vsi_handle) 1603 { 1604 struct ice_vsi_ctx *vsi; 1605 1606 vsi = ice_get_vsi_ctx(hw, vsi_handle); 1607 if (vsi) { 1608 ice_clear_vsi_q_ctx(hw, vsi_handle); 1609 devm_kfree(ice_hw_to_dev(hw), vsi); 1610 hw->vsi_ctx[vsi_handle] = NULL; 1611 } 1612 } 1613 1614 /** 1615 * ice_clear_all_vsi_ctx - clear all the VSI context entries 1616 * @hw: pointer to the HW struct 1617 */ 1618 void ice_clear_all_vsi_ctx(struct ice_hw *hw) 1619 { 1620 u16 i; 1621 1622 for (i = 0; i < ICE_MAX_VSI; i++) 1623 ice_clear_vsi_ctx(hw, i); 1624 } 1625 1626 /** 1627 * ice_add_vsi - add VSI context to the hardware and VSI handle list 1628 * @hw: pointer to the HW struct 1629 * @vsi_handle: unique VSI handle provided by drivers 1630 * @vsi_ctx: pointer to a VSI context struct 1631 * @cd: pointer to command details structure or NULL 1632 * 1633 * Add a VSI context to the hardware also add it into the VSI handle list. 1634 * If this function gets called after reset for existing VSIs then update 1635 * with the new HW VSI number in the corresponding VSI handle list entry. 1636 */ 1637 int 1638 ice_add_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 1639 struct ice_sq_cd *cd) 1640 { 1641 struct ice_vsi_ctx *tmp_vsi_ctx; 1642 int status; 1643 1644 if (vsi_handle >= ICE_MAX_VSI) 1645 return -EINVAL; 1646 status = ice_aq_add_vsi(hw, vsi_ctx, cd); 1647 if (status) 1648 return status; 1649 tmp_vsi_ctx = ice_get_vsi_ctx(hw, vsi_handle); 1650 if (!tmp_vsi_ctx) { 1651 /* Create a new VSI context */ 1652 tmp_vsi_ctx = devm_kzalloc(ice_hw_to_dev(hw), 1653 sizeof(*tmp_vsi_ctx), GFP_KERNEL); 1654 if (!tmp_vsi_ctx) { 1655 ice_aq_free_vsi(hw, vsi_ctx, false, cd); 1656 return -ENOMEM; 1657 } 1658 *tmp_vsi_ctx = *vsi_ctx; 1659 ice_save_vsi_ctx(hw, vsi_handle, tmp_vsi_ctx); 1660 } else { 1661 /* update with new HW VSI num */ 1662 tmp_vsi_ctx->vsi_num = vsi_ctx->vsi_num; 1663 } 1664 1665 return 0; 1666 } 1667 1668 /** 1669 * ice_free_vsi- free VSI context from hardware and VSI handle list 1670 * @hw: pointer to the HW struct 1671 * @vsi_handle: unique VSI handle 1672 * @vsi_ctx: pointer to a VSI context struct 1673 * @keep_vsi_alloc: keep VSI allocation as part of this PF's resources 1674 * @cd: pointer to command details structure or NULL 1675 * 1676 * Free VSI context info from hardware as well as from VSI handle list 1677 */ 1678 int 1679 ice_free_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 1680 bool keep_vsi_alloc, struct ice_sq_cd *cd) 1681 { 1682 int status; 1683 1684 if (!ice_is_vsi_valid(hw, vsi_handle)) 1685 return -EINVAL; 1686 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 1687 status = ice_aq_free_vsi(hw, vsi_ctx, keep_vsi_alloc, cd); 1688 if (!status) 1689 ice_clear_vsi_ctx(hw, vsi_handle); 1690 return status; 1691 } 1692 1693 /** 1694 * ice_update_vsi 1695 * @hw: pointer to the HW struct 1696 * @vsi_handle: unique VSI handle 1697 * @vsi_ctx: pointer to a VSI context struct 1698 * @cd: pointer to command details structure or NULL 1699 * 1700 * Update VSI context in the hardware 1701 */ 1702 int 1703 ice_update_vsi(struct ice_hw *hw, u16 vsi_handle, struct ice_vsi_ctx *vsi_ctx, 1704 struct ice_sq_cd *cd) 1705 { 1706 if (!ice_is_vsi_valid(hw, vsi_handle)) 1707 return -EINVAL; 1708 vsi_ctx->vsi_num = ice_get_hw_vsi_num(hw, vsi_handle); 1709 return ice_aq_update_vsi(hw, vsi_ctx, cd); 1710 } 1711 1712 /** 1713 * ice_cfg_rdma_fltr - enable/disable RDMA filtering on VSI 1714 * @hw: pointer to HW struct 1715 * @vsi_handle: VSI SW index 1716 * @enable: boolean for enable/disable 1717 */ 1718 int 1719 ice_cfg_rdma_fltr(struct ice_hw *hw, u16 vsi_handle, bool enable) 1720 { 1721 struct ice_vsi_ctx *ctx; 1722 1723 ctx = ice_get_vsi_ctx(hw, vsi_handle); 1724 if (!ctx) 1725 return -EIO; 1726 1727 if (enable) 1728 ctx->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 1729 else 1730 ctx->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 1731 1732 return ice_update_vsi(hw, vsi_handle, ctx, NULL); 1733 } 1734 1735 /** 1736 * ice_aq_alloc_free_vsi_list 1737 * @hw: pointer to the HW struct 1738 * @vsi_list_id: VSI list ID returned or used for lookup 1739 * @lkup_type: switch rule filter lookup type 1740 * @opc: switch rules population command type - pass in the command opcode 1741 * 1742 * allocates or free a VSI list resource 1743 */ 1744 static int 1745 ice_aq_alloc_free_vsi_list(struct ice_hw *hw, u16 *vsi_list_id, 1746 enum ice_sw_lkup_type lkup_type, 1747 enum ice_adminq_opc opc) 1748 { 1749 struct ice_aqc_alloc_free_res_elem *sw_buf; 1750 struct ice_aqc_res_elem *vsi_ele; 1751 u16 buf_len; 1752 int status; 1753 1754 buf_len = struct_size(sw_buf, elem, 1); 1755 sw_buf = devm_kzalloc(ice_hw_to_dev(hw), buf_len, GFP_KERNEL); 1756 if (!sw_buf) 1757 return -ENOMEM; 1758 sw_buf->num_elems = cpu_to_le16(1); 1759 1760 if (lkup_type == ICE_SW_LKUP_MAC || 1761 lkup_type == ICE_SW_LKUP_MAC_VLAN || 1762 lkup_type == ICE_SW_LKUP_ETHERTYPE || 1763 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 1764 lkup_type == ICE_SW_LKUP_PROMISC || 1765 lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 1766 lkup_type == ICE_SW_LKUP_DFLT) { 1767 sw_buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_REP); 1768 } else if (lkup_type == ICE_SW_LKUP_VLAN) { 1769 sw_buf->res_type = 1770 cpu_to_le16(ICE_AQC_RES_TYPE_VSI_LIST_PRUNE); 1771 } else { 1772 status = -EINVAL; 1773 goto ice_aq_alloc_free_vsi_list_exit; 1774 } 1775 1776 if (opc == ice_aqc_opc_free_res) 1777 sw_buf->elem[0].e.sw_resp = cpu_to_le16(*vsi_list_id); 1778 1779 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, opc, NULL); 1780 if (status) 1781 goto ice_aq_alloc_free_vsi_list_exit; 1782 1783 if (opc == ice_aqc_opc_alloc_res) { 1784 vsi_ele = &sw_buf->elem[0]; 1785 *vsi_list_id = le16_to_cpu(vsi_ele->e.sw_resp); 1786 } 1787 1788 ice_aq_alloc_free_vsi_list_exit: 1789 devm_kfree(ice_hw_to_dev(hw), sw_buf); 1790 return status; 1791 } 1792 1793 /** 1794 * ice_aq_sw_rules - add/update/remove switch rules 1795 * @hw: pointer to the HW struct 1796 * @rule_list: pointer to switch rule population list 1797 * @rule_list_sz: total size of the rule list in bytes 1798 * @num_rules: number of switch rules in the rule_list 1799 * @opc: switch rules population command type - pass in the command opcode 1800 * @cd: pointer to command details structure or NULL 1801 * 1802 * Add(0x02a0)/Update(0x02a1)/Remove(0x02a2) switch rules commands to firmware 1803 */ 1804 int 1805 ice_aq_sw_rules(struct ice_hw *hw, void *rule_list, u16 rule_list_sz, 1806 u8 num_rules, enum ice_adminq_opc opc, struct ice_sq_cd *cd) 1807 { 1808 struct ice_aq_desc desc; 1809 int status; 1810 1811 if (opc != ice_aqc_opc_add_sw_rules && 1812 opc != ice_aqc_opc_update_sw_rules && 1813 opc != ice_aqc_opc_remove_sw_rules) 1814 return -EINVAL; 1815 1816 ice_fill_dflt_direct_cmd_desc(&desc, opc); 1817 1818 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1819 desc.params.sw_rules.num_rules_fltr_entry_index = 1820 cpu_to_le16(num_rules); 1821 status = ice_aq_send_cmd(hw, &desc, rule_list, rule_list_sz, cd); 1822 if (opc != ice_aqc_opc_add_sw_rules && 1823 hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) 1824 status = -ENOENT; 1825 1826 return status; 1827 } 1828 1829 /** 1830 * ice_aq_add_recipe - add switch recipe 1831 * @hw: pointer to the HW struct 1832 * @s_recipe_list: pointer to switch rule population list 1833 * @num_recipes: number of switch recipes in the list 1834 * @cd: pointer to command details structure or NULL 1835 * 1836 * Add(0x0290) 1837 */ 1838 static int 1839 ice_aq_add_recipe(struct ice_hw *hw, 1840 struct ice_aqc_recipe_data_elem *s_recipe_list, 1841 u16 num_recipes, struct ice_sq_cd *cd) 1842 { 1843 struct ice_aqc_add_get_recipe *cmd; 1844 struct ice_aq_desc desc; 1845 u16 buf_size; 1846 1847 cmd = &desc.params.add_get_recipe; 1848 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_add_recipe); 1849 1850 cmd->num_sub_recipes = cpu_to_le16(num_recipes); 1851 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD); 1852 1853 buf_size = num_recipes * sizeof(*s_recipe_list); 1854 1855 return ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd); 1856 } 1857 1858 /** 1859 * ice_aq_get_recipe - get switch recipe 1860 * @hw: pointer to the HW struct 1861 * @s_recipe_list: pointer to switch rule population list 1862 * @num_recipes: pointer to the number of recipes (input and output) 1863 * @recipe_root: root recipe number of recipe(s) to retrieve 1864 * @cd: pointer to command details structure or NULL 1865 * 1866 * Get(0x0292) 1867 * 1868 * On input, *num_recipes should equal the number of entries in s_recipe_list. 1869 * On output, *num_recipes will equal the number of entries returned in 1870 * s_recipe_list. 1871 * 1872 * The caller must supply enough space in s_recipe_list to hold all possible 1873 * recipes and *num_recipes must equal ICE_MAX_NUM_RECIPES. 1874 */ 1875 static int 1876 ice_aq_get_recipe(struct ice_hw *hw, 1877 struct ice_aqc_recipe_data_elem *s_recipe_list, 1878 u16 *num_recipes, u16 recipe_root, struct ice_sq_cd *cd) 1879 { 1880 struct ice_aqc_add_get_recipe *cmd; 1881 struct ice_aq_desc desc; 1882 u16 buf_size; 1883 int status; 1884 1885 if (*num_recipes != ICE_MAX_NUM_RECIPES) 1886 return -EINVAL; 1887 1888 cmd = &desc.params.add_get_recipe; 1889 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe); 1890 1891 cmd->return_index = cpu_to_le16(recipe_root); 1892 cmd->num_sub_recipes = 0; 1893 1894 buf_size = *num_recipes * sizeof(*s_recipe_list); 1895 1896 status = ice_aq_send_cmd(hw, &desc, s_recipe_list, buf_size, cd); 1897 *num_recipes = le16_to_cpu(cmd->num_sub_recipes); 1898 1899 return status; 1900 } 1901 1902 /** 1903 * ice_update_recipe_lkup_idx - update a default recipe based on the lkup_idx 1904 * @hw: pointer to the HW struct 1905 * @params: parameters used to update the default recipe 1906 * 1907 * This function only supports updating default recipes and it only supports 1908 * updating a single recipe based on the lkup_idx at a time. 1909 * 1910 * This is done as a read-modify-write operation. First, get the current recipe 1911 * contents based on the recipe's ID. Then modify the field vector index and 1912 * mask if it's valid at the lkup_idx. Finally, use the add recipe AQ to update 1913 * the pre-existing recipe with the modifications. 1914 */ 1915 int 1916 ice_update_recipe_lkup_idx(struct ice_hw *hw, 1917 struct ice_update_recipe_lkup_idx_params *params) 1918 { 1919 struct ice_aqc_recipe_data_elem *rcp_list; 1920 u16 num_recps = ICE_MAX_NUM_RECIPES; 1921 int status; 1922 1923 rcp_list = kcalloc(num_recps, sizeof(*rcp_list), GFP_KERNEL); 1924 if (!rcp_list) 1925 return -ENOMEM; 1926 1927 /* read current recipe list from firmware */ 1928 rcp_list->recipe_indx = params->rid; 1929 status = ice_aq_get_recipe(hw, rcp_list, &num_recps, params->rid, NULL); 1930 if (status) { 1931 ice_debug(hw, ICE_DBG_SW, "Failed to get recipe %d, status %d\n", 1932 params->rid, status); 1933 goto error_out; 1934 } 1935 1936 /* only modify existing recipe's lkup_idx and mask if valid, while 1937 * leaving all other fields the same, then update the recipe firmware 1938 */ 1939 rcp_list->content.lkup_indx[params->lkup_idx] = params->fv_idx; 1940 if (params->mask_valid) 1941 rcp_list->content.mask[params->lkup_idx] = 1942 cpu_to_le16(params->mask); 1943 1944 if (params->ignore_valid) 1945 rcp_list->content.lkup_indx[params->lkup_idx] |= 1946 ICE_AQ_RECIPE_LKUP_IGNORE; 1947 1948 status = ice_aq_add_recipe(hw, &rcp_list[0], 1, NULL); 1949 if (status) 1950 ice_debug(hw, ICE_DBG_SW, "Failed to update recipe %d lkup_idx %d fv_idx %d mask %d mask_valid %s, status %d\n", 1951 params->rid, params->lkup_idx, params->fv_idx, 1952 params->mask, params->mask_valid ? "true" : "false", 1953 status); 1954 1955 error_out: 1956 kfree(rcp_list); 1957 return status; 1958 } 1959 1960 /** 1961 * ice_aq_map_recipe_to_profile - Map recipe to packet profile 1962 * @hw: pointer to the HW struct 1963 * @profile_id: package profile ID to associate the recipe with 1964 * @r_bitmap: Recipe bitmap filled in and need to be returned as response 1965 * @cd: pointer to command details structure or NULL 1966 * Recipe to profile association (0x0291) 1967 */ 1968 static int 1969 ice_aq_map_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, 1970 struct ice_sq_cd *cd) 1971 { 1972 struct ice_aqc_recipe_to_profile *cmd; 1973 struct ice_aq_desc desc; 1974 1975 cmd = &desc.params.recipe_to_profile; 1976 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_recipe_to_profile); 1977 cmd->profile_id = cpu_to_le16(profile_id); 1978 /* Set the recipe ID bit in the bitmask to let the device know which 1979 * profile we are associating the recipe to 1980 */ 1981 memcpy(cmd->recipe_assoc, r_bitmap, sizeof(cmd->recipe_assoc)); 1982 1983 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 1984 } 1985 1986 /** 1987 * ice_aq_get_recipe_to_profile - Map recipe to packet profile 1988 * @hw: pointer to the HW struct 1989 * @profile_id: package profile ID to associate the recipe with 1990 * @r_bitmap: Recipe bitmap filled in and need to be returned as response 1991 * @cd: pointer to command details structure or NULL 1992 * Associate profile ID with given recipe (0x0293) 1993 */ 1994 static int 1995 ice_aq_get_recipe_to_profile(struct ice_hw *hw, u32 profile_id, u8 *r_bitmap, 1996 struct ice_sq_cd *cd) 1997 { 1998 struct ice_aqc_recipe_to_profile *cmd; 1999 struct ice_aq_desc desc; 2000 int status; 2001 2002 cmd = &desc.params.recipe_to_profile; 2003 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_recipe_to_profile); 2004 cmd->profile_id = cpu_to_le16(profile_id); 2005 2006 status = ice_aq_send_cmd(hw, &desc, NULL, 0, cd); 2007 if (!status) 2008 memcpy(r_bitmap, cmd->recipe_assoc, sizeof(cmd->recipe_assoc)); 2009 2010 return status; 2011 } 2012 2013 /** 2014 * ice_alloc_recipe - add recipe resource 2015 * @hw: pointer to the hardware structure 2016 * @rid: recipe ID returned as response to AQ call 2017 */ 2018 static int ice_alloc_recipe(struct ice_hw *hw, u16 *rid) 2019 { 2020 struct ice_aqc_alloc_free_res_elem *sw_buf; 2021 u16 buf_len; 2022 int status; 2023 2024 buf_len = struct_size(sw_buf, elem, 1); 2025 sw_buf = kzalloc(buf_len, GFP_KERNEL); 2026 if (!sw_buf) 2027 return -ENOMEM; 2028 2029 sw_buf->num_elems = cpu_to_le16(1); 2030 sw_buf->res_type = cpu_to_le16((ICE_AQC_RES_TYPE_RECIPE << 2031 ICE_AQC_RES_TYPE_S) | 2032 ICE_AQC_RES_TYPE_FLAG_SHARED); 2033 status = ice_aq_alloc_free_res(hw, 1, sw_buf, buf_len, 2034 ice_aqc_opc_alloc_res, NULL); 2035 if (!status) 2036 *rid = le16_to_cpu(sw_buf->elem[0].e.sw_resp); 2037 kfree(sw_buf); 2038 2039 return status; 2040 } 2041 2042 /** 2043 * ice_get_recp_to_prof_map - updates recipe to profile mapping 2044 * @hw: pointer to hardware structure 2045 * 2046 * This function is used to populate recipe_to_profile matrix where index to 2047 * this array is the recipe ID and the element is the mapping of which profiles 2048 * is this recipe mapped to. 2049 */ 2050 static void ice_get_recp_to_prof_map(struct ice_hw *hw) 2051 { 2052 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); 2053 u16 i; 2054 2055 for (i = 0; i < hw->switch_info->max_used_prof_index + 1; i++) { 2056 u16 j; 2057 2058 bitmap_zero(profile_to_recipe[i], ICE_MAX_NUM_RECIPES); 2059 bitmap_zero(r_bitmap, ICE_MAX_NUM_RECIPES); 2060 if (ice_aq_get_recipe_to_profile(hw, i, (u8 *)r_bitmap, NULL)) 2061 continue; 2062 bitmap_copy(profile_to_recipe[i], r_bitmap, 2063 ICE_MAX_NUM_RECIPES); 2064 for_each_set_bit(j, r_bitmap, ICE_MAX_NUM_RECIPES) 2065 set_bit(i, recipe_to_profile[j]); 2066 } 2067 } 2068 2069 /** 2070 * ice_collect_result_idx - copy result index values 2071 * @buf: buffer that contains the result index 2072 * @recp: the recipe struct to copy data into 2073 */ 2074 static void 2075 ice_collect_result_idx(struct ice_aqc_recipe_data_elem *buf, 2076 struct ice_sw_recipe *recp) 2077 { 2078 if (buf->content.result_indx & ICE_AQ_RECIPE_RESULT_EN) 2079 set_bit(buf->content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN, 2080 recp->res_idxs); 2081 } 2082 2083 /** 2084 * ice_get_recp_frm_fw - update SW bookkeeping from FW recipe entries 2085 * @hw: pointer to hardware structure 2086 * @recps: struct that we need to populate 2087 * @rid: recipe ID that we are populating 2088 * @refresh_required: true if we should get recipe to profile mapping from FW 2089 * 2090 * This function is used to populate all the necessary entries into our 2091 * bookkeeping so that we have a current list of all the recipes that are 2092 * programmed in the firmware. 2093 */ 2094 static int 2095 ice_get_recp_frm_fw(struct ice_hw *hw, struct ice_sw_recipe *recps, u8 rid, 2096 bool *refresh_required) 2097 { 2098 DECLARE_BITMAP(result_bm, ICE_MAX_FV_WORDS); 2099 struct ice_aqc_recipe_data_elem *tmp; 2100 u16 num_recps = ICE_MAX_NUM_RECIPES; 2101 struct ice_prot_lkup_ext *lkup_exts; 2102 u8 fv_word_idx = 0; 2103 u16 sub_recps; 2104 int status; 2105 2106 bitmap_zero(result_bm, ICE_MAX_FV_WORDS); 2107 2108 /* we need a buffer big enough to accommodate all the recipes */ 2109 tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); 2110 if (!tmp) 2111 return -ENOMEM; 2112 2113 tmp[0].recipe_indx = rid; 2114 status = ice_aq_get_recipe(hw, tmp, &num_recps, rid, NULL); 2115 /* non-zero status meaning recipe doesn't exist */ 2116 if (status) 2117 goto err_unroll; 2118 2119 /* Get recipe to profile map so that we can get the fv from lkups that 2120 * we read for a recipe from FW. Since we want to minimize the number of 2121 * times we make this FW call, just make one call and cache the copy 2122 * until a new recipe is added. This operation is only required the 2123 * first time to get the changes from FW. Then to search existing 2124 * entries we don't need to update the cache again until another recipe 2125 * gets added. 2126 */ 2127 if (*refresh_required) { 2128 ice_get_recp_to_prof_map(hw); 2129 *refresh_required = false; 2130 } 2131 2132 /* Start populating all the entries for recps[rid] based on lkups from 2133 * firmware. Note that we are only creating the root recipe in our 2134 * database. 2135 */ 2136 lkup_exts = &recps[rid].lkup_exts; 2137 2138 for (sub_recps = 0; sub_recps < num_recps; sub_recps++) { 2139 struct ice_aqc_recipe_data_elem root_bufs = tmp[sub_recps]; 2140 struct ice_recp_grp_entry *rg_entry; 2141 u8 i, prof, idx, prot = 0; 2142 bool is_root; 2143 u16 off = 0; 2144 2145 rg_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*rg_entry), 2146 GFP_KERNEL); 2147 if (!rg_entry) { 2148 status = -ENOMEM; 2149 goto err_unroll; 2150 } 2151 2152 idx = root_bufs.recipe_indx; 2153 is_root = root_bufs.content.rid & ICE_AQ_RECIPE_ID_IS_ROOT; 2154 2155 /* Mark all result indices in this chain */ 2156 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) 2157 set_bit(root_bufs.content.result_indx & ~ICE_AQ_RECIPE_RESULT_EN, 2158 result_bm); 2159 2160 /* get the first profile that is associated with rid */ 2161 prof = find_first_bit(recipe_to_profile[idx], 2162 ICE_MAX_NUM_PROFILES); 2163 for (i = 0; i < ICE_NUM_WORDS_RECIPE; i++) { 2164 u8 lkup_indx = root_bufs.content.lkup_indx[i + 1]; 2165 2166 rg_entry->fv_idx[i] = lkup_indx; 2167 rg_entry->fv_mask[i] = 2168 le16_to_cpu(root_bufs.content.mask[i + 1]); 2169 2170 /* If the recipe is a chained recipe then all its 2171 * child recipe's result will have a result index. 2172 * To fill fv_words we should not use those result 2173 * index, we only need the protocol ids and offsets. 2174 * We will skip all the fv_idx which stores result 2175 * index in them. We also need to skip any fv_idx which 2176 * has ICE_AQ_RECIPE_LKUP_IGNORE or 0 since it isn't a 2177 * valid offset value. 2178 */ 2179 if (test_bit(rg_entry->fv_idx[i], hw->switch_info->prof_res_bm[prof]) || 2180 rg_entry->fv_idx[i] & ICE_AQ_RECIPE_LKUP_IGNORE || 2181 rg_entry->fv_idx[i] == 0) 2182 continue; 2183 2184 ice_find_prot_off(hw, ICE_BLK_SW, prof, 2185 rg_entry->fv_idx[i], &prot, &off); 2186 lkup_exts->fv_words[fv_word_idx].prot_id = prot; 2187 lkup_exts->fv_words[fv_word_idx].off = off; 2188 lkup_exts->field_mask[fv_word_idx] = 2189 rg_entry->fv_mask[i]; 2190 fv_word_idx++; 2191 } 2192 /* populate rg_list with the data from the child entry of this 2193 * recipe 2194 */ 2195 list_add(&rg_entry->l_entry, &recps[rid].rg_list); 2196 2197 /* Propagate some data to the recipe database */ 2198 recps[idx].is_root = !!is_root; 2199 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; 2200 bitmap_zero(recps[idx].res_idxs, ICE_MAX_FV_WORDS); 2201 if (root_bufs.content.result_indx & ICE_AQ_RECIPE_RESULT_EN) { 2202 recps[idx].chain_idx = root_bufs.content.result_indx & 2203 ~ICE_AQ_RECIPE_RESULT_EN; 2204 set_bit(recps[idx].chain_idx, recps[idx].res_idxs); 2205 } else { 2206 recps[idx].chain_idx = ICE_INVAL_CHAIN_IND; 2207 } 2208 2209 if (!is_root) 2210 continue; 2211 2212 /* Only do the following for root recipes entries */ 2213 memcpy(recps[idx].r_bitmap, root_bufs.recipe_bitmap, 2214 sizeof(recps[idx].r_bitmap)); 2215 recps[idx].root_rid = root_bufs.content.rid & 2216 ~ICE_AQ_RECIPE_ID_IS_ROOT; 2217 recps[idx].priority = root_bufs.content.act_ctrl_fwd_priority; 2218 } 2219 2220 /* Complete initialization of the root recipe entry */ 2221 lkup_exts->n_val_words = fv_word_idx; 2222 recps[rid].big_recp = (num_recps > 1); 2223 recps[rid].n_grp_count = (u8)num_recps; 2224 recps[rid].root_buf = devm_kmemdup(ice_hw_to_dev(hw), tmp, 2225 recps[rid].n_grp_count * sizeof(*recps[rid].root_buf), 2226 GFP_KERNEL); 2227 if (!recps[rid].root_buf) { 2228 status = -ENOMEM; 2229 goto err_unroll; 2230 } 2231 2232 /* Copy result indexes */ 2233 bitmap_copy(recps[rid].res_idxs, result_bm, ICE_MAX_FV_WORDS); 2234 recps[rid].recp_created = true; 2235 2236 err_unroll: 2237 kfree(tmp); 2238 return status; 2239 } 2240 2241 /* ice_init_port_info - Initialize port_info with switch configuration data 2242 * @pi: pointer to port_info 2243 * @vsi_port_num: VSI number or port number 2244 * @type: Type of switch element (port or VSI) 2245 * @swid: switch ID of the switch the element is attached to 2246 * @pf_vf_num: PF or VF number 2247 * @is_vf: true if the element is a VF, false otherwise 2248 */ 2249 static void 2250 ice_init_port_info(struct ice_port_info *pi, u16 vsi_port_num, u8 type, 2251 u16 swid, u16 pf_vf_num, bool is_vf) 2252 { 2253 switch (type) { 2254 case ICE_AQC_GET_SW_CONF_RESP_PHYS_PORT: 2255 pi->lport = (u8)(vsi_port_num & ICE_LPORT_MASK); 2256 pi->sw_id = swid; 2257 pi->pf_vf_num = pf_vf_num; 2258 pi->is_vf = is_vf; 2259 break; 2260 default: 2261 ice_debug(pi->hw, ICE_DBG_SW, "incorrect VSI/port type received\n"); 2262 break; 2263 } 2264 } 2265 2266 /* ice_get_initial_sw_cfg - Get initial port and default VSI data 2267 * @hw: pointer to the hardware structure 2268 */ 2269 int ice_get_initial_sw_cfg(struct ice_hw *hw) 2270 { 2271 struct ice_aqc_get_sw_cfg_resp_elem *rbuf; 2272 u16 req_desc = 0; 2273 u16 num_elems; 2274 int status; 2275 u16 i; 2276 2277 rbuf = devm_kzalloc(ice_hw_to_dev(hw), ICE_SW_CFG_MAX_BUF_LEN, 2278 GFP_KERNEL); 2279 2280 if (!rbuf) 2281 return -ENOMEM; 2282 2283 /* Multiple calls to ice_aq_get_sw_cfg may be required 2284 * to get all the switch configuration information. The need 2285 * for additional calls is indicated by ice_aq_get_sw_cfg 2286 * writing a non-zero value in req_desc 2287 */ 2288 do { 2289 struct ice_aqc_get_sw_cfg_resp_elem *ele; 2290 2291 status = ice_aq_get_sw_cfg(hw, rbuf, ICE_SW_CFG_MAX_BUF_LEN, 2292 &req_desc, &num_elems, NULL); 2293 2294 if (status) 2295 break; 2296 2297 for (i = 0, ele = rbuf; i < num_elems; i++, ele++) { 2298 u16 pf_vf_num, swid, vsi_port_num; 2299 bool is_vf = false; 2300 u8 res_type; 2301 2302 vsi_port_num = le16_to_cpu(ele->vsi_port_num) & 2303 ICE_AQC_GET_SW_CONF_RESP_VSI_PORT_NUM_M; 2304 2305 pf_vf_num = le16_to_cpu(ele->pf_vf_num) & 2306 ICE_AQC_GET_SW_CONF_RESP_FUNC_NUM_M; 2307 2308 swid = le16_to_cpu(ele->swid); 2309 2310 if (le16_to_cpu(ele->pf_vf_num) & 2311 ICE_AQC_GET_SW_CONF_RESP_IS_VF) 2312 is_vf = true; 2313 2314 res_type = (u8)(le16_to_cpu(ele->vsi_port_num) >> 2315 ICE_AQC_GET_SW_CONF_RESP_TYPE_S); 2316 2317 if (res_type == ICE_AQC_GET_SW_CONF_RESP_VSI) { 2318 /* FW VSI is not needed. Just continue. */ 2319 continue; 2320 } 2321 2322 ice_init_port_info(hw->port_info, vsi_port_num, 2323 res_type, swid, pf_vf_num, is_vf); 2324 } 2325 } while (req_desc && !status); 2326 2327 devm_kfree(ice_hw_to_dev(hw), rbuf); 2328 return status; 2329 } 2330 2331 /** 2332 * ice_fill_sw_info - Helper function to populate lb_en and lan_en 2333 * @hw: pointer to the hardware structure 2334 * @fi: filter info structure to fill/update 2335 * 2336 * This helper function populates the lb_en and lan_en elements of the provided 2337 * ice_fltr_info struct using the switch's type and characteristics of the 2338 * switch rule being configured. 2339 */ 2340 static void ice_fill_sw_info(struct ice_hw *hw, struct ice_fltr_info *fi) 2341 { 2342 fi->lb_en = false; 2343 fi->lan_en = false; 2344 if ((fi->flag & ICE_FLTR_TX) && 2345 (fi->fltr_act == ICE_FWD_TO_VSI || 2346 fi->fltr_act == ICE_FWD_TO_VSI_LIST || 2347 fi->fltr_act == ICE_FWD_TO_Q || 2348 fi->fltr_act == ICE_FWD_TO_QGRP)) { 2349 /* Setting LB for prune actions will result in replicated 2350 * packets to the internal switch that will be dropped. 2351 */ 2352 if (fi->lkup_type != ICE_SW_LKUP_VLAN) 2353 fi->lb_en = true; 2354 2355 /* Set lan_en to TRUE if 2356 * 1. The switch is a VEB AND 2357 * 2 2358 * 2.1 The lookup is a directional lookup like ethertype, 2359 * promiscuous, ethertype-MAC, promiscuous-VLAN 2360 * and default-port OR 2361 * 2.2 The lookup is VLAN, OR 2362 * 2.3 The lookup is MAC with mcast or bcast addr for MAC, OR 2363 * 2.4 The lookup is MAC_VLAN with mcast or bcast addr for MAC. 2364 * 2365 * OR 2366 * 2367 * The switch is a VEPA. 2368 * 2369 * In all other cases, the LAN enable has to be set to false. 2370 */ 2371 if (hw->evb_veb) { 2372 if (fi->lkup_type == ICE_SW_LKUP_ETHERTYPE || 2373 fi->lkup_type == ICE_SW_LKUP_PROMISC || 2374 fi->lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 2375 fi->lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 2376 fi->lkup_type == ICE_SW_LKUP_DFLT || 2377 fi->lkup_type == ICE_SW_LKUP_VLAN || 2378 (fi->lkup_type == ICE_SW_LKUP_MAC && 2379 !is_unicast_ether_addr(fi->l_data.mac.mac_addr)) || 2380 (fi->lkup_type == ICE_SW_LKUP_MAC_VLAN && 2381 !is_unicast_ether_addr(fi->l_data.mac.mac_addr))) 2382 fi->lan_en = true; 2383 } else { 2384 fi->lan_en = true; 2385 } 2386 } 2387 } 2388 2389 /** 2390 * ice_fill_sw_rule - Helper function to fill switch rule structure 2391 * @hw: pointer to the hardware structure 2392 * @f_info: entry containing packet forwarding information 2393 * @s_rule: switch rule structure to be filled in based on mac_entry 2394 * @opc: switch rules population command type - pass in the command opcode 2395 */ 2396 static void 2397 ice_fill_sw_rule(struct ice_hw *hw, struct ice_fltr_info *f_info, 2398 struct ice_sw_rule_lkup_rx_tx *s_rule, 2399 enum ice_adminq_opc opc) 2400 { 2401 u16 vlan_id = ICE_MAX_VLAN_ID + 1; 2402 u16 vlan_tpid = ETH_P_8021Q; 2403 void *daddr = NULL; 2404 u16 eth_hdr_sz; 2405 u8 *eth_hdr; 2406 u32 act = 0; 2407 __be16 *off; 2408 u8 q_rgn; 2409 2410 if (opc == ice_aqc_opc_remove_sw_rules) { 2411 s_rule->act = 0; 2412 s_rule->index = cpu_to_le16(f_info->fltr_rule_id); 2413 s_rule->hdr_len = 0; 2414 return; 2415 } 2416 2417 eth_hdr_sz = sizeof(dummy_eth_header); 2418 eth_hdr = s_rule->hdr_data; 2419 2420 /* initialize the ether header with a dummy header */ 2421 memcpy(eth_hdr, dummy_eth_header, eth_hdr_sz); 2422 ice_fill_sw_info(hw, f_info); 2423 2424 switch (f_info->fltr_act) { 2425 case ICE_FWD_TO_VSI: 2426 act |= (f_info->fwd_id.hw_vsi_id << ICE_SINGLE_ACT_VSI_ID_S) & 2427 ICE_SINGLE_ACT_VSI_ID_M; 2428 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 2429 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 2430 ICE_SINGLE_ACT_VALID_BIT; 2431 break; 2432 case ICE_FWD_TO_VSI_LIST: 2433 act |= ICE_SINGLE_ACT_VSI_LIST; 2434 act |= (f_info->fwd_id.vsi_list_id << 2435 ICE_SINGLE_ACT_VSI_LIST_ID_S) & 2436 ICE_SINGLE_ACT_VSI_LIST_ID_M; 2437 if (f_info->lkup_type != ICE_SW_LKUP_VLAN) 2438 act |= ICE_SINGLE_ACT_VSI_FORWARDING | 2439 ICE_SINGLE_ACT_VALID_BIT; 2440 break; 2441 case ICE_FWD_TO_Q: 2442 act |= ICE_SINGLE_ACT_TO_Q; 2443 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 2444 ICE_SINGLE_ACT_Q_INDEX_M; 2445 break; 2446 case ICE_DROP_PACKET: 2447 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 2448 ICE_SINGLE_ACT_VALID_BIT; 2449 break; 2450 case ICE_FWD_TO_QGRP: 2451 q_rgn = f_info->qgrp_size > 0 ? 2452 (u8)ilog2(f_info->qgrp_size) : 0; 2453 act |= ICE_SINGLE_ACT_TO_Q; 2454 act |= (f_info->fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 2455 ICE_SINGLE_ACT_Q_INDEX_M; 2456 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 2457 ICE_SINGLE_ACT_Q_REGION_M; 2458 break; 2459 default: 2460 return; 2461 } 2462 2463 if (f_info->lb_en) 2464 act |= ICE_SINGLE_ACT_LB_ENABLE; 2465 if (f_info->lan_en) 2466 act |= ICE_SINGLE_ACT_LAN_ENABLE; 2467 2468 switch (f_info->lkup_type) { 2469 case ICE_SW_LKUP_MAC: 2470 daddr = f_info->l_data.mac.mac_addr; 2471 break; 2472 case ICE_SW_LKUP_VLAN: 2473 vlan_id = f_info->l_data.vlan.vlan_id; 2474 if (f_info->l_data.vlan.tpid_valid) 2475 vlan_tpid = f_info->l_data.vlan.tpid; 2476 if (f_info->fltr_act == ICE_FWD_TO_VSI || 2477 f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 2478 act |= ICE_SINGLE_ACT_PRUNE; 2479 act |= ICE_SINGLE_ACT_EGRESS | ICE_SINGLE_ACT_INGRESS; 2480 } 2481 break; 2482 case ICE_SW_LKUP_ETHERTYPE_MAC: 2483 daddr = f_info->l_data.ethertype_mac.mac_addr; 2484 fallthrough; 2485 case ICE_SW_LKUP_ETHERTYPE: 2486 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 2487 *off = cpu_to_be16(f_info->l_data.ethertype_mac.ethertype); 2488 break; 2489 case ICE_SW_LKUP_MAC_VLAN: 2490 daddr = f_info->l_data.mac_vlan.mac_addr; 2491 vlan_id = f_info->l_data.mac_vlan.vlan_id; 2492 break; 2493 case ICE_SW_LKUP_PROMISC_VLAN: 2494 vlan_id = f_info->l_data.mac_vlan.vlan_id; 2495 fallthrough; 2496 case ICE_SW_LKUP_PROMISC: 2497 daddr = f_info->l_data.mac_vlan.mac_addr; 2498 break; 2499 default: 2500 break; 2501 } 2502 2503 s_rule->hdr.type = (f_info->flag & ICE_FLTR_RX) ? 2504 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX) : 2505 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 2506 2507 /* Recipe set depending on lookup type */ 2508 s_rule->recipe_id = cpu_to_le16(f_info->lkup_type); 2509 s_rule->src = cpu_to_le16(f_info->src); 2510 s_rule->act = cpu_to_le32(act); 2511 2512 if (daddr) 2513 ether_addr_copy(eth_hdr + ICE_ETH_DA_OFFSET, daddr); 2514 2515 if (!(vlan_id > ICE_MAX_VLAN_ID)) { 2516 off = (__force __be16 *)(eth_hdr + ICE_ETH_VLAN_TCI_OFFSET); 2517 *off = cpu_to_be16(vlan_id); 2518 off = (__force __be16 *)(eth_hdr + ICE_ETH_ETHTYPE_OFFSET); 2519 *off = cpu_to_be16(vlan_tpid); 2520 } 2521 2522 /* Create the switch rule with the final dummy Ethernet header */ 2523 if (opc != ice_aqc_opc_update_sw_rules) 2524 s_rule->hdr_len = cpu_to_le16(eth_hdr_sz); 2525 } 2526 2527 /** 2528 * ice_add_marker_act 2529 * @hw: pointer to the hardware structure 2530 * @m_ent: the management entry for which sw marker needs to be added 2531 * @sw_marker: sw marker to tag the Rx descriptor with 2532 * @l_id: large action resource ID 2533 * 2534 * Create a large action to hold software marker and update the switch rule 2535 * entry pointed by m_ent with newly created large action 2536 */ 2537 static int 2538 ice_add_marker_act(struct ice_hw *hw, struct ice_fltr_mgmt_list_entry *m_ent, 2539 u16 sw_marker, u16 l_id) 2540 { 2541 struct ice_sw_rule_lkup_rx_tx *rx_tx; 2542 struct ice_sw_rule_lg_act *lg_act; 2543 /* For software marker we need 3 large actions 2544 * 1. FWD action: FWD TO VSI or VSI LIST 2545 * 2. GENERIC VALUE action to hold the profile ID 2546 * 3. GENERIC VALUE action to hold the software marker ID 2547 */ 2548 const u16 num_lg_acts = 3; 2549 u16 lg_act_size; 2550 u16 rules_size; 2551 int status; 2552 u32 act; 2553 u16 id; 2554 2555 if (m_ent->fltr_info.lkup_type != ICE_SW_LKUP_MAC) 2556 return -EINVAL; 2557 2558 /* Create two back-to-back switch rules and submit them to the HW using 2559 * one memory buffer: 2560 * 1. Large Action 2561 * 2. Look up Tx Rx 2562 */ 2563 lg_act_size = (u16)ICE_SW_RULE_LG_ACT_SIZE(lg_act, num_lg_acts); 2564 rules_size = lg_act_size + ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(rx_tx); 2565 lg_act = devm_kzalloc(ice_hw_to_dev(hw), rules_size, GFP_KERNEL); 2566 if (!lg_act) 2567 return -ENOMEM; 2568 2569 rx_tx = (typeof(rx_tx))((u8 *)lg_act + lg_act_size); 2570 2571 /* Fill in the first switch rule i.e. large action */ 2572 lg_act->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LG_ACT); 2573 lg_act->index = cpu_to_le16(l_id); 2574 lg_act->size = cpu_to_le16(num_lg_acts); 2575 2576 /* First action VSI forwarding or VSI list forwarding depending on how 2577 * many VSIs 2578 */ 2579 id = (m_ent->vsi_count > 1) ? m_ent->fltr_info.fwd_id.vsi_list_id : 2580 m_ent->fltr_info.fwd_id.hw_vsi_id; 2581 2582 act = ICE_LG_ACT_VSI_FORWARDING | ICE_LG_ACT_VALID_BIT; 2583 act |= (id << ICE_LG_ACT_VSI_LIST_ID_S) & ICE_LG_ACT_VSI_LIST_ID_M; 2584 if (m_ent->vsi_count > 1) 2585 act |= ICE_LG_ACT_VSI_LIST; 2586 lg_act->act[0] = cpu_to_le32(act); 2587 2588 /* Second action descriptor type */ 2589 act = ICE_LG_ACT_GENERIC; 2590 2591 act |= (1 << ICE_LG_ACT_GENERIC_VALUE_S) & ICE_LG_ACT_GENERIC_VALUE_M; 2592 lg_act->act[1] = cpu_to_le32(act); 2593 2594 act = (ICE_LG_ACT_GENERIC_OFF_RX_DESC_PROF_IDX << 2595 ICE_LG_ACT_GENERIC_OFFSET_S) & ICE_LG_ACT_GENERIC_OFFSET_M; 2596 2597 /* Third action Marker value */ 2598 act |= ICE_LG_ACT_GENERIC; 2599 act |= (sw_marker << ICE_LG_ACT_GENERIC_VALUE_S) & 2600 ICE_LG_ACT_GENERIC_VALUE_M; 2601 2602 lg_act->act[2] = cpu_to_le32(act); 2603 2604 /* call the fill switch rule to fill the lookup Tx Rx structure */ 2605 ice_fill_sw_rule(hw, &m_ent->fltr_info, rx_tx, 2606 ice_aqc_opc_update_sw_rules); 2607 2608 /* Update the action to point to the large action ID */ 2609 rx_tx->act = cpu_to_le32(ICE_SINGLE_ACT_PTR | 2610 ((l_id << ICE_SINGLE_ACT_PTR_VAL_S) & 2611 ICE_SINGLE_ACT_PTR_VAL_M)); 2612 2613 /* Use the filter rule ID of the previously created rule with single 2614 * act. Once the update happens, hardware will treat this as large 2615 * action 2616 */ 2617 rx_tx->index = cpu_to_le16(m_ent->fltr_info.fltr_rule_id); 2618 2619 status = ice_aq_sw_rules(hw, lg_act, rules_size, 2, 2620 ice_aqc_opc_update_sw_rules, NULL); 2621 if (!status) { 2622 m_ent->lg_act_idx = l_id; 2623 m_ent->sw_marker_id = sw_marker; 2624 } 2625 2626 devm_kfree(ice_hw_to_dev(hw), lg_act); 2627 return status; 2628 } 2629 2630 /** 2631 * ice_create_vsi_list_map 2632 * @hw: pointer to the hardware structure 2633 * @vsi_handle_arr: array of VSI handles to set in the VSI mapping 2634 * @num_vsi: number of VSI handles in the array 2635 * @vsi_list_id: VSI list ID generated as part of allocate resource 2636 * 2637 * Helper function to create a new entry of VSI list ID to VSI mapping 2638 * using the given VSI list ID 2639 */ 2640 static struct ice_vsi_list_map_info * 2641 ice_create_vsi_list_map(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 2642 u16 vsi_list_id) 2643 { 2644 struct ice_switch_info *sw = hw->switch_info; 2645 struct ice_vsi_list_map_info *v_map; 2646 int i; 2647 2648 v_map = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*v_map), GFP_KERNEL); 2649 if (!v_map) 2650 return NULL; 2651 2652 v_map->vsi_list_id = vsi_list_id; 2653 v_map->ref_cnt = 1; 2654 for (i = 0; i < num_vsi; i++) 2655 set_bit(vsi_handle_arr[i], v_map->vsi_map); 2656 2657 list_add(&v_map->list_entry, &sw->vsi_list_map_head); 2658 return v_map; 2659 } 2660 2661 /** 2662 * ice_update_vsi_list_rule 2663 * @hw: pointer to the hardware structure 2664 * @vsi_handle_arr: array of VSI handles to form a VSI list 2665 * @num_vsi: number of VSI handles in the array 2666 * @vsi_list_id: VSI list ID generated as part of allocate resource 2667 * @remove: Boolean value to indicate if this is a remove action 2668 * @opc: switch rules population command type - pass in the command opcode 2669 * @lkup_type: lookup type of the filter 2670 * 2671 * Call AQ command to add a new switch rule or update existing switch rule 2672 * using the given VSI list ID 2673 */ 2674 static int 2675 ice_update_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 2676 u16 vsi_list_id, bool remove, enum ice_adminq_opc opc, 2677 enum ice_sw_lkup_type lkup_type) 2678 { 2679 struct ice_sw_rule_vsi_list *s_rule; 2680 u16 s_rule_size; 2681 u16 rule_type; 2682 int status; 2683 int i; 2684 2685 if (!num_vsi) 2686 return -EINVAL; 2687 2688 if (lkup_type == ICE_SW_LKUP_MAC || 2689 lkup_type == ICE_SW_LKUP_MAC_VLAN || 2690 lkup_type == ICE_SW_LKUP_ETHERTYPE || 2691 lkup_type == ICE_SW_LKUP_ETHERTYPE_MAC || 2692 lkup_type == ICE_SW_LKUP_PROMISC || 2693 lkup_type == ICE_SW_LKUP_PROMISC_VLAN || 2694 lkup_type == ICE_SW_LKUP_DFLT) 2695 rule_type = remove ? ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR : 2696 ICE_AQC_SW_RULES_T_VSI_LIST_SET; 2697 else if (lkup_type == ICE_SW_LKUP_VLAN) 2698 rule_type = remove ? ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR : 2699 ICE_AQC_SW_RULES_T_PRUNE_LIST_SET; 2700 else 2701 return -EINVAL; 2702 2703 s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi); 2704 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 2705 if (!s_rule) 2706 return -ENOMEM; 2707 for (i = 0; i < num_vsi; i++) { 2708 if (!ice_is_vsi_valid(hw, vsi_handle_arr[i])) { 2709 status = -EINVAL; 2710 goto exit; 2711 } 2712 /* AQ call requires hw_vsi_id(s) */ 2713 s_rule->vsi[i] = 2714 cpu_to_le16(ice_get_hw_vsi_num(hw, vsi_handle_arr[i])); 2715 } 2716 2717 s_rule->hdr.type = cpu_to_le16(rule_type); 2718 s_rule->number_vsi = cpu_to_le16(num_vsi); 2719 s_rule->index = cpu_to_le16(vsi_list_id); 2720 2721 status = ice_aq_sw_rules(hw, s_rule, s_rule_size, 1, opc, NULL); 2722 2723 exit: 2724 devm_kfree(ice_hw_to_dev(hw), s_rule); 2725 return status; 2726 } 2727 2728 /** 2729 * ice_create_vsi_list_rule - Creates and populates a VSI list rule 2730 * @hw: pointer to the HW struct 2731 * @vsi_handle_arr: array of VSI handles to form a VSI list 2732 * @num_vsi: number of VSI handles in the array 2733 * @vsi_list_id: stores the ID of the VSI list to be created 2734 * @lkup_type: switch rule filter's lookup type 2735 */ 2736 static int 2737 ice_create_vsi_list_rule(struct ice_hw *hw, u16 *vsi_handle_arr, u16 num_vsi, 2738 u16 *vsi_list_id, enum ice_sw_lkup_type lkup_type) 2739 { 2740 int status; 2741 2742 status = ice_aq_alloc_free_vsi_list(hw, vsi_list_id, lkup_type, 2743 ice_aqc_opc_alloc_res); 2744 if (status) 2745 return status; 2746 2747 /* Update the newly created VSI list to include the specified VSIs */ 2748 return ice_update_vsi_list_rule(hw, vsi_handle_arr, num_vsi, 2749 *vsi_list_id, false, 2750 ice_aqc_opc_add_sw_rules, lkup_type); 2751 } 2752 2753 /** 2754 * ice_create_pkt_fwd_rule 2755 * @hw: pointer to the hardware structure 2756 * @f_entry: entry containing packet forwarding information 2757 * 2758 * Create switch rule with given filter information and add an entry 2759 * to the corresponding filter management list to track this switch rule 2760 * and VSI mapping 2761 */ 2762 static int 2763 ice_create_pkt_fwd_rule(struct ice_hw *hw, 2764 struct ice_fltr_list_entry *f_entry) 2765 { 2766 struct ice_fltr_mgmt_list_entry *fm_entry; 2767 struct ice_sw_rule_lkup_rx_tx *s_rule; 2768 enum ice_sw_lkup_type l_type; 2769 struct ice_sw_recipe *recp; 2770 int status; 2771 2772 s_rule = devm_kzalloc(ice_hw_to_dev(hw), 2773 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 2774 GFP_KERNEL); 2775 if (!s_rule) 2776 return -ENOMEM; 2777 fm_entry = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*fm_entry), 2778 GFP_KERNEL); 2779 if (!fm_entry) { 2780 status = -ENOMEM; 2781 goto ice_create_pkt_fwd_rule_exit; 2782 } 2783 2784 fm_entry->fltr_info = f_entry->fltr_info; 2785 2786 /* Initialize all the fields for the management entry */ 2787 fm_entry->vsi_count = 1; 2788 fm_entry->lg_act_idx = ICE_INVAL_LG_ACT_INDEX; 2789 fm_entry->sw_marker_id = ICE_INVAL_SW_MARKER_ID; 2790 fm_entry->counter_index = ICE_INVAL_COUNTER_ID; 2791 2792 ice_fill_sw_rule(hw, &fm_entry->fltr_info, s_rule, 2793 ice_aqc_opc_add_sw_rules); 2794 2795 status = ice_aq_sw_rules(hw, s_rule, 2796 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1, 2797 ice_aqc_opc_add_sw_rules, NULL); 2798 if (status) { 2799 devm_kfree(ice_hw_to_dev(hw), fm_entry); 2800 goto ice_create_pkt_fwd_rule_exit; 2801 } 2802 2803 f_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index); 2804 fm_entry->fltr_info.fltr_rule_id = le16_to_cpu(s_rule->index); 2805 2806 /* The book keeping entries will get removed when base driver 2807 * calls remove filter AQ command 2808 */ 2809 l_type = fm_entry->fltr_info.lkup_type; 2810 recp = &hw->switch_info->recp_list[l_type]; 2811 list_add(&fm_entry->list_entry, &recp->filt_rules); 2812 2813 ice_create_pkt_fwd_rule_exit: 2814 devm_kfree(ice_hw_to_dev(hw), s_rule); 2815 return status; 2816 } 2817 2818 /** 2819 * ice_update_pkt_fwd_rule 2820 * @hw: pointer to the hardware structure 2821 * @f_info: filter information for switch rule 2822 * 2823 * Call AQ command to update a previously created switch rule with a 2824 * VSI list ID 2825 */ 2826 static int 2827 ice_update_pkt_fwd_rule(struct ice_hw *hw, struct ice_fltr_info *f_info) 2828 { 2829 struct ice_sw_rule_lkup_rx_tx *s_rule; 2830 int status; 2831 2832 s_rule = devm_kzalloc(ice_hw_to_dev(hw), 2833 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 2834 GFP_KERNEL); 2835 if (!s_rule) 2836 return -ENOMEM; 2837 2838 ice_fill_sw_rule(hw, f_info, s_rule, ice_aqc_opc_update_sw_rules); 2839 2840 s_rule->index = cpu_to_le16(f_info->fltr_rule_id); 2841 2842 /* Update switch rule with new rule set to forward VSI list */ 2843 status = ice_aq_sw_rules(hw, s_rule, 2844 ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule), 1, 2845 ice_aqc_opc_update_sw_rules, NULL); 2846 2847 devm_kfree(ice_hw_to_dev(hw), s_rule); 2848 return status; 2849 } 2850 2851 /** 2852 * ice_update_sw_rule_bridge_mode 2853 * @hw: pointer to the HW struct 2854 * 2855 * Updates unicast switch filter rules based on VEB/VEPA mode 2856 */ 2857 int ice_update_sw_rule_bridge_mode(struct ice_hw *hw) 2858 { 2859 struct ice_switch_info *sw = hw->switch_info; 2860 struct ice_fltr_mgmt_list_entry *fm_entry; 2861 struct list_head *rule_head; 2862 struct mutex *rule_lock; /* Lock to protect filter rule list */ 2863 int status = 0; 2864 2865 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 2866 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 2867 2868 mutex_lock(rule_lock); 2869 list_for_each_entry(fm_entry, rule_head, list_entry) { 2870 struct ice_fltr_info *fi = &fm_entry->fltr_info; 2871 u8 *addr = fi->l_data.mac.mac_addr; 2872 2873 /* Update unicast Tx rules to reflect the selected 2874 * VEB/VEPA mode 2875 */ 2876 if ((fi->flag & ICE_FLTR_TX) && is_unicast_ether_addr(addr) && 2877 (fi->fltr_act == ICE_FWD_TO_VSI || 2878 fi->fltr_act == ICE_FWD_TO_VSI_LIST || 2879 fi->fltr_act == ICE_FWD_TO_Q || 2880 fi->fltr_act == ICE_FWD_TO_QGRP)) { 2881 status = ice_update_pkt_fwd_rule(hw, fi); 2882 if (status) 2883 break; 2884 } 2885 } 2886 2887 mutex_unlock(rule_lock); 2888 2889 return status; 2890 } 2891 2892 /** 2893 * ice_add_update_vsi_list 2894 * @hw: pointer to the hardware structure 2895 * @m_entry: pointer to current filter management list entry 2896 * @cur_fltr: filter information from the book keeping entry 2897 * @new_fltr: filter information with the new VSI to be added 2898 * 2899 * Call AQ command to add or update previously created VSI list with new VSI. 2900 * 2901 * Helper function to do book keeping associated with adding filter information 2902 * The algorithm to do the book keeping is described below : 2903 * When a VSI needs to subscribe to a given filter (MAC/VLAN/Ethtype etc.) 2904 * if only one VSI has been added till now 2905 * Allocate a new VSI list and add two VSIs 2906 * to this list using switch rule command 2907 * Update the previously created switch rule with the 2908 * newly created VSI list ID 2909 * if a VSI list was previously created 2910 * Add the new VSI to the previously created VSI list set 2911 * using the update switch rule command 2912 */ 2913 static int 2914 ice_add_update_vsi_list(struct ice_hw *hw, 2915 struct ice_fltr_mgmt_list_entry *m_entry, 2916 struct ice_fltr_info *cur_fltr, 2917 struct ice_fltr_info *new_fltr) 2918 { 2919 u16 vsi_list_id = 0; 2920 int status = 0; 2921 2922 if ((cur_fltr->fltr_act == ICE_FWD_TO_Q || 2923 cur_fltr->fltr_act == ICE_FWD_TO_QGRP)) 2924 return -EOPNOTSUPP; 2925 2926 if ((new_fltr->fltr_act == ICE_FWD_TO_Q || 2927 new_fltr->fltr_act == ICE_FWD_TO_QGRP) && 2928 (cur_fltr->fltr_act == ICE_FWD_TO_VSI || 2929 cur_fltr->fltr_act == ICE_FWD_TO_VSI_LIST)) 2930 return -EOPNOTSUPP; 2931 2932 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 2933 /* Only one entry existed in the mapping and it was not already 2934 * a part of a VSI list. So, create a VSI list with the old and 2935 * new VSIs. 2936 */ 2937 struct ice_fltr_info tmp_fltr; 2938 u16 vsi_handle_arr[2]; 2939 2940 /* A rule already exists with the new VSI being added */ 2941 if (cur_fltr->fwd_id.hw_vsi_id == new_fltr->fwd_id.hw_vsi_id) 2942 return -EEXIST; 2943 2944 vsi_handle_arr[0] = cur_fltr->vsi_handle; 2945 vsi_handle_arr[1] = new_fltr->vsi_handle; 2946 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 2947 &vsi_list_id, 2948 new_fltr->lkup_type); 2949 if (status) 2950 return status; 2951 2952 tmp_fltr = *new_fltr; 2953 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 2954 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 2955 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 2956 /* Update the previous switch rule of "MAC forward to VSI" to 2957 * "MAC fwd to VSI list" 2958 */ 2959 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 2960 if (status) 2961 return status; 2962 2963 cur_fltr->fwd_id.vsi_list_id = vsi_list_id; 2964 cur_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 2965 m_entry->vsi_list_info = 2966 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 2967 vsi_list_id); 2968 2969 if (!m_entry->vsi_list_info) 2970 return -ENOMEM; 2971 2972 /* If this entry was large action then the large action needs 2973 * to be updated to point to FWD to VSI list 2974 */ 2975 if (m_entry->sw_marker_id != ICE_INVAL_SW_MARKER_ID) 2976 status = 2977 ice_add_marker_act(hw, m_entry, 2978 m_entry->sw_marker_id, 2979 m_entry->lg_act_idx); 2980 } else { 2981 u16 vsi_handle = new_fltr->vsi_handle; 2982 enum ice_adminq_opc opcode; 2983 2984 if (!m_entry->vsi_list_info) 2985 return -EIO; 2986 2987 /* A rule already exists with the new VSI being added */ 2988 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) 2989 return 0; 2990 2991 /* Update the previously created VSI list set with 2992 * the new VSI ID passed in 2993 */ 2994 vsi_list_id = cur_fltr->fwd_id.vsi_list_id; 2995 opcode = ice_aqc_opc_update_sw_rules; 2996 2997 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 2998 vsi_list_id, false, opcode, 2999 new_fltr->lkup_type); 3000 /* update VSI list mapping info with new VSI ID */ 3001 if (!status) 3002 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map); 3003 } 3004 if (!status) 3005 m_entry->vsi_count++; 3006 return status; 3007 } 3008 3009 /** 3010 * ice_find_rule_entry - Search a rule entry 3011 * @hw: pointer to the hardware structure 3012 * @recp_id: lookup type for which the specified rule needs to be searched 3013 * @f_info: rule information 3014 * 3015 * Helper function to search for a given rule entry 3016 * Returns pointer to entry storing the rule if found 3017 */ 3018 static struct ice_fltr_mgmt_list_entry * 3019 ice_find_rule_entry(struct ice_hw *hw, u8 recp_id, struct ice_fltr_info *f_info) 3020 { 3021 struct ice_fltr_mgmt_list_entry *list_itr, *ret = NULL; 3022 struct ice_switch_info *sw = hw->switch_info; 3023 struct list_head *list_head; 3024 3025 list_head = &sw->recp_list[recp_id].filt_rules; 3026 list_for_each_entry(list_itr, list_head, list_entry) { 3027 if (!memcmp(&f_info->l_data, &list_itr->fltr_info.l_data, 3028 sizeof(f_info->l_data)) && 3029 f_info->flag == list_itr->fltr_info.flag) { 3030 ret = list_itr; 3031 break; 3032 } 3033 } 3034 return ret; 3035 } 3036 3037 /** 3038 * ice_find_vsi_list_entry - Search VSI list map with VSI count 1 3039 * @hw: pointer to the hardware structure 3040 * @recp_id: lookup type for which VSI lists needs to be searched 3041 * @vsi_handle: VSI handle to be found in VSI list 3042 * @vsi_list_id: VSI list ID found containing vsi_handle 3043 * 3044 * Helper function to search a VSI list with single entry containing given VSI 3045 * handle element. This can be extended further to search VSI list with more 3046 * than 1 vsi_count. Returns pointer to VSI list entry if found. 3047 */ 3048 static struct ice_vsi_list_map_info * 3049 ice_find_vsi_list_entry(struct ice_hw *hw, u8 recp_id, u16 vsi_handle, 3050 u16 *vsi_list_id) 3051 { 3052 struct ice_vsi_list_map_info *map_info = NULL; 3053 struct ice_switch_info *sw = hw->switch_info; 3054 struct ice_fltr_mgmt_list_entry *list_itr; 3055 struct list_head *list_head; 3056 3057 list_head = &sw->recp_list[recp_id].filt_rules; 3058 list_for_each_entry(list_itr, list_head, list_entry) { 3059 if (list_itr->vsi_count == 1 && list_itr->vsi_list_info) { 3060 map_info = list_itr->vsi_list_info; 3061 if (test_bit(vsi_handle, map_info->vsi_map)) { 3062 *vsi_list_id = map_info->vsi_list_id; 3063 return map_info; 3064 } 3065 } 3066 } 3067 return NULL; 3068 } 3069 3070 /** 3071 * ice_add_rule_internal - add rule for a given lookup type 3072 * @hw: pointer to the hardware structure 3073 * @recp_id: lookup type (recipe ID) for which rule has to be added 3074 * @f_entry: structure containing MAC forwarding information 3075 * 3076 * Adds or updates the rule lists for a given recipe 3077 */ 3078 static int 3079 ice_add_rule_internal(struct ice_hw *hw, u8 recp_id, 3080 struct ice_fltr_list_entry *f_entry) 3081 { 3082 struct ice_switch_info *sw = hw->switch_info; 3083 struct ice_fltr_info *new_fltr, *cur_fltr; 3084 struct ice_fltr_mgmt_list_entry *m_entry; 3085 struct mutex *rule_lock; /* Lock to protect filter rule list */ 3086 int status = 0; 3087 3088 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 3089 return -EINVAL; 3090 f_entry->fltr_info.fwd_id.hw_vsi_id = 3091 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 3092 3093 rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 3094 3095 mutex_lock(rule_lock); 3096 new_fltr = &f_entry->fltr_info; 3097 if (new_fltr->flag & ICE_FLTR_RX) 3098 new_fltr->src = hw->port_info->lport; 3099 else if (new_fltr->flag & ICE_FLTR_TX) 3100 new_fltr->src = f_entry->fltr_info.fwd_id.hw_vsi_id; 3101 3102 m_entry = ice_find_rule_entry(hw, recp_id, new_fltr); 3103 if (!m_entry) { 3104 mutex_unlock(rule_lock); 3105 return ice_create_pkt_fwd_rule(hw, f_entry); 3106 } 3107 3108 cur_fltr = &m_entry->fltr_info; 3109 status = ice_add_update_vsi_list(hw, m_entry, cur_fltr, new_fltr); 3110 mutex_unlock(rule_lock); 3111 3112 return status; 3113 } 3114 3115 /** 3116 * ice_remove_vsi_list_rule 3117 * @hw: pointer to the hardware structure 3118 * @vsi_list_id: VSI list ID generated as part of allocate resource 3119 * @lkup_type: switch rule filter lookup type 3120 * 3121 * The VSI list should be emptied before this function is called to remove the 3122 * VSI list. 3123 */ 3124 static int 3125 ice_remove_vsi_list_rule(struct ice_hw *hw, u16 vsi_list_id, 3126 enum ice_sw_lkup_type lkup_type) 3127 { 3128 struct ice_sw_rule_vsi_list *s_rule; 3129 u16 s_rule_size; 3130 int status; 3131 3132 s_rule_size = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, 0); 3133 s_rule = devm_kzalloc(ice_hw_to_dev(hw), s_rule_size, GFP_KERNEL); 3134 if (!s_rule) 3135 return -ENOMEM; 3136 3137 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_VSI_LIST_CLEAR); 3138 s_rule->index = cpu_to_le16(vsi_list_id); 3139 3140 /* Free the vsi_list resource that we allocated. It is assumed that the 3141 * list is empty at this point. 3142 */ 3143 status = ice_aq_alloc_free_vsi_list(hw, &vsi_list_id, lkup_type, 3144 ice_aqc_opc_free_res); 3145 3146 devm_kfree(ice_hw_to_dev(hw), s_rule); 3147 return status; 3148 } 3149 3150 /** 3151 * ice_rem_update_vsi_list 3152 * @hw: pointer to the hardware structure 3153 * @vsi_handle: VSI handle of the VSI to remove 3154 * @fm_list: filter management entry for which the VSI list management needs to 3155 * be done 3156 */ 3157 static int 3158 ice_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 3159 struct ice_fltr_mgmt_list_entry *fm_list) 3160 { 3161 enum ice_sw_lkup_type lkup_type; 3162 u16 vsi_list_id; 3163 int status = 0; 3164 3165 if (fm_list->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST || 3166 fm_list->vsi_count == 0) 3167 return -EINVAL; 3168 3169 /* A rule with the VSI being removed does not exist */ 3170 if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map)) 3171 return -ENOENT; 3172 3173 lkup_type = fm_list->fltr_info.lkup_type; 3174 vsi_list_id = fm_list->fltr_info.fwd_id.vsi_list_id; 3175 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 3176 ice_aqc_opc_update_sw_rules, 3177 lkup_type); 3178 if (status) 3179 return status; 3180 3181 fm_list->vsi_count--; 3182 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 3183 3184 if (fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) { 3185 struct ice_fltr_info tmp_fltr_info = fm_list->fltr_info; 3186 struct ice_vsi_list_map_info *vsi_list_info = 3187 fm_list->vsi_list_info; 3188 u16 rem_vsi_handle; 3189 3190 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map, 3191 ICE_MAX_VSI); 3192 if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 3193 return -EIO; 3194 3195 /* Make sure VSI list is empty before removing it below */ 3196 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 3197 vsi_list_id, true, 3198 ice_aqc_opc_update_sw_rules, 3199 lkup_type); 3200 if (status) 3201 return status; 3202 3203 tmp_fltr_info.fltr_act = ICE_FWD_TO_VSI; 3204 tmp_fltr_info.fwd_id.hw_vsi_id = 3205 ice_get_hw_vsi_num(hw, rem_vsi_handle); 3206 tmp_fltr_info.vsi_handle = rem_vsi_handle; 3207 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr_info); 3208 if (status) { 3209 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 3210 tmp_fltr_info.fwd_id.hw_vsi_id, status); 3211 return status; 3212 } 3213 3214 fm_list->fltr_info = tmp_fltr_info; 3215 } 3216 3217 if ((fm_list->vsi_count == 1 && lkup_type != ICE_SW_LKUP_VLAN) || 3218 (fm_list->vsi_count == 0 && lkup_type == ICE_SW_LKUP_VLAN)) { 3219 struct ice_vsi_list_map_info *vsi_list_info = 3220 fm_list->vsi_list_info; 3221 3222 /* Remove the VSI list since it is no longer used */ 3223 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 3224 if (status) { 3225 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 3226 vsi_list_id, status); 3227 return status; 3228 } 3229 3230 list_del(&vsi_list_info->list_entry); 3231 devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 3232 fm_list->vsi_list_info = NULL; 3233 } 3234 3235 return status; 3236 } 3237 3238 /** 3239 * ice_remove_rule_internal - Remove a filter rule of a given type 3240 * @hw: pointer to the hardware structure 3241 * @recp_id: recipe ID for which the rule needs to removed 3242 * @f_entry: rule entry containing filter information 3243 */ 3244 static int 3245 ice_remove_rule_internal(struct ice_hw *hw, u8 recp_id, 3246 struct ice_fltr_list_entry *f_entry) 3247 { 3248 struct ice_switch_info *sw = hw->switch_info; 3249 struct ice_fltr_mgmt_list_entry *list_elem; 3250 struct mutex *rule_lock; /* Lock to protect filter rule list */ 3251 bool remove_rule = false; 3252 u16 vsi_handle; 3253 int status = 0; 3254 3255 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 3256 return -EINVAL; 3257 f_entry->fltr_info.fwd_id.hw_vsi_id = 3258 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 3259 3260 rule_lock = &sw->recp_list[recp_id].filt_rule_lock; 3261 mutex_lock(rule_lock); 3262 list_elem = ice_find_rule_entry(hw, recp_id, &f_entry->fltr_info); 3263 if (!list_elem) { 3264 status = -ENOENT; 3265 goto exit; 3266 } 3267 3268 if (list_elem->fltr_info.fltr_act != ICE_FWD_TO_VSI_LIST) { 3269 remove_rule = true; 3270 } else if (!list_elem->vsi_list_info) { 3271 status = -ENOENT; 3272 goto exit; 3273 } else if (list_elem->vsi_list_info->ref_cnt > 1) { 3274 /* a ref_cnt > 1 indicates that the vsi_list is being 3275 * shared by multiple rules. Decrement the ref_cnt and 3276 * remove this rule, but do not modify the list, as it 3277 * is in-use by other rules. 3278 */ 3279 list_elem->vsi_list_info->ref_cnt--; 3280 remove_rule = true; 3281 } else { 3282 /* a ref_cnt of 1 indicates the vsi_list is only used 3283 * by one rule. However, the original removal request is only 3284 * for a single VSI. Update the vsi_list first, and only 3285 * remove the rule if there are no further VSIs in this list. 3286 */ 3287 vsi_handle = f_entry->fltr_info.vsi_handle; 3288 status = ice_rem_update_vsi_list(hw, vsi_handle, list_elem); 3289 if (status) 3290 goto exit; 3291 /* if VSI count goes to zero after updating the VSI list */ 3292 if (list_elem->vsi_count == 0) 3293 remove_rule = true; 3294 } 3295 3296 if (remove_rule) { 3297 /* Remove the lookup rule */ 3298 struct ice_sw_rule_lkup_rx_tx *s_rule; 3299 3300 s_rule = devm_kzalloc(ice_hw_to_dev(hw), 3301 ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule), 3302 GFP_KERNEL); 3303 if (!s_rule) { 3304 status = -ENOMEM; 3305 goto exit; 3306 } 3307 3308 ice_fill_sw_rule(hw, &list_elem->fltr_info, s_rule, 3309 ice_aqc_opc_remove_sw_rules); 3310 3311 status = ice_aq_sw_rules(hw, s_rule, 3312 ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule), 3313 1, ice_aqc_opc_remove_sw_rules, NULL); 3314 3315 /* Remove a book keeping from the list */ 3316 devm_kfree(ice_hw_to_dev(hw), s_rule); 3317 3318 if (status) 3319 goto exit; 3320 3321 list_del(&list_elem->list_entry); 3322 devm_kfree(ice_hw_to_dev(hw), list_elem); 3323 } 3324 exit: 3325 mutex_unlock(rule_lock); 3326 return status; 3327 } 3328 3329 /** 3330 * ice_mac_fltr_exist - does this MAC filter exist for given VSI 3331 * @hw: pointer to the hardware structure 3332 * @mac: MAC address to be checked (for MAC filter) 3333 * @vsi_handle: check MAC filter for this VSI 3334 */ 3335 bool ice_mac_fltr_exist(struct ice_hw *hw, u8 *mac, u16 vsi_handle) 3336 { 3337 struct ice_fltr_mgmt_list_entry *entry; 3338 struct list_head *rule_head; 3339 struct ice_switch_info *sw; 3340 struct mutex *rule_lock; /* Lock to protect filter rule list */ 3341 u16 hw_vsi_id; 3342 3343 if (!ice_is_vsi_valid(hw, vsi_handle)) 3344 return false; 3345 3346 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3347 sw = hw->switch_info; 3348 rule_head = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rules; 3349 if (!rule_head) 3350 return false; 3351 3352 rule_lock = &sw->recp_list[ICE_SW_LKUP_MAC].filt_rule_lock; 3353 mutex_lock(rule_lock); 3354 list_for_each_entry(entry, rule_head, list_entry) { 3355 struct ice_fltr_info *f_info = &entry->fltr_info; 3356 u8 *mac_addr = &f_info->l_data.mac.mac_addr[0]; 3357 3358 if (is_zero_ether_addr(mac_addr)) 3359 continue; 3360 3361 if (f_info->flag != ICE_FLTR_TX || 3362 f_info->src_id != ICE_SRC_ID_VSI || 3363 f_info->lkup_type != ICE_SW_LKUP_MAC || 3364 f_info->fltr_act != ICE_FWD_TO_VSI || 3365 hw_vsi_id != f_info->fwd_id.hw_vsi_id) 3366 continue; 3367 3368 if (ether_addr_equal(mac, mac_addr)) { 3369 mutex_unlock(rule_lock); 3370 return true; 3371 } 3372 } 3373 mutex_unlock(rule_lock); 3374 return false; 3375 } 3376 3377 /** 3378 * ice_vlan_fltr_exist - does this VLAN filter exist for given VSI 3379 * @hw: pointer to the hardware structure 3380 * @vlan_id: VLAN ID 3381 * @vsi_handle: check MAC filter for this VSI 3382 */ 3383 bool ice_vlan_fltr_exist(struct ice_hw *hw, u16 vlan_id, u16 vsi_handle) 3384 { 3385 struct ice_fltr_mgmt_list_entry *entry; 3386 struct list_head *rule_head; 3387 struct ice_switch_info *sw; 3388 struct mutex *rule_lock; /* Lock to protect filter rule list */ 3389 u16 hw_vsi_id; 3390 3391 if (vlan_id > ICE_MAX_VLAN_ID) 3392 return false; 3393 3394 if (!ice_is_vsi_valid(hw, vsi_handle)) 3395 return false; 3396 3397 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3398 sw = hw->switch_info; 3399 rule_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 3400 if (!rule_head) 3401 return false; 3402 3403 rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 3404 mutex_lock(rule_lock); 3405 list_for_each_entry(entry, rule_head, list_entry) { 3406 struct ice_fltr_info *f_info = &entry->fltr_info; 3407 u16 entry_vlan_id = f_info->l_data.vlan.vlan_id; 3408 struct ice_vsi_list_map_info *map_info; 3409 3410 if (entry_vlan_id > ICE_MAX_VLAN_ID) 3411 continue; 3412 3413 if (f_info->flag != ICE_FLTR_TX || 3414 f_info->src_id != ICE_SRC_ID_VSI || 3415 f_info->lkup_type != ICE_SW_LKUP_VLAN) 3416 continue; 3417 3418 /* Only allowed filter action are FWD_TO_VSI/_VSI_LIST */ 3419 if (f_info->fltr_act != ICE_FWD_TO_VSI && 3420 f_info->fltr_act != ICE_FWD_TO_VSI_LIST) 3421 continue; 3422 3423 if (f_info->fltr_act == ICE_FWD_TO_VSI) { 3424 if (hw_vsi_id != f_info->fwd_id.hw_vsi_id) 3425 continue; 3426 } else if (f_info->fltr_act == ICE_FWD_TO_VSI_LIST) { 3427 /* If filter_action is FWD_TO_VSI_LIST, make sure 3428 * that VSI being checked is part of VSI list 3429 */ 3430 if (entry->vsi_count == 1 && 3431 entry->vsi_list_info) { 3432 map_info = entry->vsi_list_info; 3433 if (!test_bit(vsi_handle, map_info->vsi_map)) 3434 continue; 3435 } 3436 } 3437 3438 if (vlan_id == entry_vlan_id) { 3439 mutex_unlock(rule_lock); 3440 return true; 3441 } 3442 } 3443 mutex_unlock(rule_lock); 3444 3445 return false; 3446 } 3447 3448 /** 3449 * ice_add_mac - Add a MAC address based filter rule 3450 * @hw: pointer to the hardware structure 3451 * @m_list: list of MAC addresses and forwarding information 3452 */ 3453 int ice_add_mac(struct ice_hw *hw, struct list_head *m_list) 3454 { 3455 struct ice_fltr_list_entry *m_list_itr; 3456 int status = 0; 3457 3458 if (!m_list || !hw) 3459 return -EINVAL; 3460 3461 list_for_each_entry(m_list_itr, m_list, list_entry) { 3462 u8 *add = &m_list_itr->fltr_info.l_data.mac.mac_addr[0]; 3463 u16 vsi_handle; 3464 u16 hw_vsi_id; 3465 3466 m_list_itr->fltr_info.flag = ICE_FLTR_TX; 3467 vsi_handle = m_list_itr->fltr_info.vsi_handle; 3468 if (!ice_is_vsi_valid(hw, vsi_handle)) 3469 return -EINVAL; 3470 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3471 m_list_itr->fltr_info.fwd_id.hw_vsi_id = hw_vsi_id; 3472 /* update the src in case it is VSI num */ 3473 if (m_list_itr->fltr_info.src_id != ICE_SRC_ID_VSI) 3474 return -EINVAL; 3475 m_list_itr->fltr_info.src = hw_vsi_id; 3476 if (m_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_MAC || 3477 is_zero_ether_addr(add)) 3478 return -EINVAL; 3479 3480 m_list_itr->status = ice_add_rule_internal(hw, ICE_SW_LKUP_MAC, 3481 m_list_itr); 3482 if (m_list_itr->status) 3483 return m_list_itr->status; 3484 } 3485 3486 return status; 3487 } 3488 3489 /** 3490 * ice_add_vlan_internal - Add one VLAN based filter rule 3491 * @hw: pointer to the hardware structure 3492 * @f_entry: filter entry containing one VLAN information 3493 */ 3494 static int 3495 ice_add_vlan_internal(struct ice_hw *hw, struct ice_fltr_list_entry *f_entry) 3496 { 3497 struct ice_switch_info *sw = hw->switch_info; 3498 struct ice_fltr_mgmt_list_entry *v_list_itr; 3499 struct ice_fltr_info *new_fltr, *cur_fltr; 3500 enum ice_sw_lkup_type lkup_type; 3501 u16 vsi_list_id = 0, vsi_handle; 3502 struct mutex *rule_lock; /* Lock to protect filter rule list */ 3503 int status = 0; 3504 3505 if (!ice_is_vsi_valid(hw, f_entry->fltr_info.vsi_handle)) 3506 return -EINVAL; 3507 3508 f_entry->fltr_info.fwd_id.hw_vsi_id = 3509 ice_get_hw_vsi_num(hw, f_entry->fltr_info.vsi_handle); 3510 new_fltr = &f_entry->fltr_info; 3511 3512 /* VLAN ID should only be 12 bits */ 3513 if (new_fltr->l_data.vlan.vlan_id > ICE_MAX_VLAN_ID) 3514 return -EINVAL; 3515 3516 if (new_fltr->src_id != ICE_SRC_ID_VSI) 3517 return -EINVAL; 3518 3519 new_fltr->src = new_fltr->fwd_id.hw_vsi_id; 3520 lkup_type = new_fltr->lkup_type; 3521 vsi_handle = new_fltr->vsi_handle; 3522 rule_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 3523 mutex_lock(rule_lock); 3524 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, new_fltr); 3525 if (!v_list_itr) { 3526 struct ice_vsi_list_map_info *map_info = NULL; 3527 3528 if (new_fltr->fltr_act == ICE_FWD_TO_VSI) { 3529 /* All VLAN pruning rules use a VSI list. Check if 3530 * there is already a VSI list containing VSI that we 3531 * want to add. If found, use the same vsi_list_id for 3532 * this new VLAN rule or else create a new list. 3533 */ 3534 map_info = ice_find_vsi_list_entry(hw, ICE_SW_LKUP_VLAN, 3535 vsi_handle, 3536 &vsi_list_id); 3537 if (!map_info) { 3538 status = ice_create_vsi_list_rule(hw, 3539 &vsi_handle, 3540 1, 3541 &vsi_list_id, 3542 lkup_type); 3543 if (status) 3544 goto exit; 3545 } 3546 /* Convert the action to forwarding to a VSI list. */ 3547 new_fltr->fltr_act = ICE_FWD_TO_VSI_LIST; 3548 new_fltr->fwd_id.vsi_list_id = vsi_list_id; 3549 } 3550 3551 status = ice_create_pkt_fwd_rule(hw, f_entry); 3552 if (!status) { 3553 v_list_itr = ice_find_rule_entry(hw, ICE_SW_LKUP_VLAN, 3554 new_fltr); 3555 if (!v_list_itr) { 3556 status = -ENOENT; 3557 goto exit; 3558 } 3559 /* reuse VSI list for new rule and increment ref_cnt */ 3560 if (map_info) { 3561 v_list_itr->vsi_list_info = map_info; 3562 map_info->ref_cnt++; 3563 } else { 3564 v_list_itr->vsi_list_info = 3565 ice_create_vsi_list_map(hw, &vsi_handle, 3566 1, vsi_list_id); 3567 } 3568 } 3569 } else if (v_list_itr->vsi_list_info->ref_cnt == 1) { 3570 /* Update existing VSI list to add new VSI ID only if it used 3571 * by one VLAN rule. 3572 */ 3573 cur_fltr = &v_list_itr->fltr_info; 3574 status = ice_add_update_vsi_list(hw, v_list_itr, cur_fltr, 3575 new_fltr); 3576 } else { 3577 /* If VLAN rule exists and VSI list being used by this rule is 3578 * referenced by more than 1 VLAN rule. Then create a new VSI 3579 * list appending previous VSI with new VSI and update existing 3580 * VLAN rule to point to new VSI list ID 3581 */ 3582 struct ice_fltr_info tmp_fltr; 3583 u16 vsi_handle_arr[2]; 3584 u16 cur_handle; 3585 3586 /* Current implementation only supports reusing VSI list with 3587 * one VSI count. We should never hit below condition 3588 */ 3589 if (v_list_itr->vsi_count > 1 && 3590 v_list_itr->vsi_list_info->ref_cnt > 1) { 3591 ice_debug(hw, ICE_DBG_SW, "Invalid configuration: Optimization to reuse VSI list with more than one VSI is not being done yet\n"); 3592 status = -EIO; 3593 goto exit; 3594 } 3595 3596 cur_handle = 3597 find_first_bit(v_list_itr->vsi_list_info->vsi_map, 3598 ICE_MAX_VSI); 3599 3600 /* A rule already exists with the new VSI being added */ 3601 if (cur_handle == vsi_handle) { 3602 status = -EEXIST; 3603 goto exit; 3604 } 3605 3606 vsi_handle_arr[0] = cur_handle; 3607 vsi_handle_arr[1] = vsi_handle; 3608 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 3609 &vsi_list_id, lkup_type); 3610 if (status) 3611 goto exit; 3612 3613 tmp_fltr = v_list_itr->fltr_info; 3614 tmp_fltr.fltr_rule_id = v_list_itr->fltr_info.fltr_rule_id; 3615 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 3616 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 3617 /* Update the previous switch rule to a new VSI list which 3618 * includes current VSI that is requested 3619 */ 3620 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 3621 if (status) 3622 goto exit; 3623 3624 /* before overriding VSI list map info. decrement ref_cnt of 3625 * previous VSI list 3626 */ 3627 v_list_itr->vsi_list_info->ref_cnt--; 3628 3629 /* now update to newly created list */ 3630 v_list_itr->fltr_info.fwd_id.vsi_list_id = vsi_list_id; 3631 v_list_itr->vsi_list_info = 3632 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 3633 vsi_list_id); 3634 v_list_itr->vsi_count++; 3635 } 3636 3637 exit: 3638 mutex_unlock(rule_lock); 3639 return status; 3640 } 3641 3642 /** 3643 * ice_add_vlan - Add VLAN based filter rule 3644 * @hw: pointer to the hardware structure 3645 * @v_list: list of VLAN entries and forwarding information 3646 */ 3647 int ice_add_vlan(struct ice_hw *hw, struct list_head *v_list) 3648 { 3649 struct ice_fltr_list_entry *v_list_itr; 3650 3651 if (!v_list || !hw) 3652 return -EINVAL; 3653 3654 list_for_each_entry(v_list_itr, v_list, list_entry) { 3655 if (v_list_itr->fltr_info.lkup_type != ICE_SW_LKUP_VLAN) 3656 return -EINVAL; 3657 v_list_itr->fltr_info.flag = ICE_FLTR_TX; 3658 v_list_itr->status = ice_add_vlan_internal(hw, v_list_itr); 3659 if (v_list_itr->status) 3660 return v_list_itr->status; 3661 } 3662 return 0; 3663 } 3664 3665 /** 3666 * ice_add_eth_mac - Add ethertype and MAC based filter rule 3667 * @hw: pointer to the hardware structure 3668 * @em_list: list of ether type MAC filter, MAC is optional 3669 * 3670 * This function requires the caller to populate the entries in 3671 * the filter list with the necessary fields (including flags to 3672 * indicate Tx or Rx rules). 3673 */ 3674 int ice_add_eth_mac(struct ice_hw *hw, struct list_head *em_list) 3675 { 3676 struct ice_fltr_list_entry *em_list_itr; 3677 3678 if (!em_list || !hw) 3679 return -EINVAL; 3680 3681 list_for_each_entry(em_list_itr, em_list, list_entry) { 3682 enum ice_sw_lkup_type l_type = 3683 em_list_itr->fltr_info.lkup_type; 3684 3685 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 3686 l_type != ICE_SW_LKUP_ETHERTYPE) 3687 return -EINVAL; 3688 3689 em_list_itr->status = ice_add_rule_internal(hw, l_type, 3690 em_list_itr); 3691 if (em_list_itr->status) 3692 return em_list_itr->status; 3693 } 3694 return 0; 3695 } 3696 3697 /** 3698 * ice_remove_eth_mac - Remove an ethertype (or MAC) based filter rule 3699 * @hw: pointer to the hardware structure 3700 * @em_list: list of ethertype or ethertype MAC entries 3701 */ 3702 int ice_remove_eth_mac(struct ice_hw *hw, struct list_head *em_list) 3703 { 3704 struct ice_fltr_list_entry *em_list_itr, *tmp; 3705 3706 if (!em_list || !hw) 3707 return -EINVAL; 3708 3709 list_for_each_entry_safe(em_list_itr, tmp, em_list, list_entry) { 3710 enum ice_sw_lkup_type l_type = 3711 em_list_itr->fltr_info.lkup_type; 3712 3713 if (l_type != ICE_SW_LKUP_ETHERTYPE_MAC && 3714 l_type != ICE_SW_LKUP_ETHERTYPE) 3715 return -EINVAL; 3716 3717 em_list_itr->status = ice_remove_rule_internal(hw, l_type, 3718 em_list_itr); 3719 if (em_list_itr->status) 3720 return em_list_itr->status; 3721 } 3722 return 0; 3723 } 3724 3725 /** 3726 * ice_rem_sw_rule_info 3727 * @hw: pointer to the hardware structure 3728 * @rule_head: pointer to the switch list structure that we want to delete 3729 */ 3730 static void 3731 ice_rem_sw_rule_info(struct ice_hw *hw, struct list_head *rule_head) 3732 { 3733 if (!list_empty(rule_head)) { 3734 struct ice_fltr_mgmt_list_entry *entry; 3735 struct ice_fltr_mgmt_list_entry *tmp; 3736 3737 list_for_each_entry_safe(entry, tmp, rule_head, list_entry) { 3738 list_del(&entry->list_entry); 3739 devm_kfree(ice_hw_to_dev(hw), entry); 3740 } 3741 } 3742 } 3743 3744 /** 3745 * ice_rem_adv_rule_info 3746 * @hw: pointer to the hardware structure 3747 * @rule_head: pointer to the switch list structure that we want to delete 3748 */ 3749 static void 3750 ice_rem_adv_rule_info(struct ice_hw *hw, struct list_head *rule_head) 3751 { 3752 struct ice_adv_fltr_mgmt_list_entry *tmp_entry; 3753 struct ice_adv_fltr_mgmt_list_entry *lst_itr; 3754 3755 if (list_empty(rule_head)) 3756 return; 3757 3758 list_for_each_entry_safe(lst_itr, tmp_entry, rule_head, list_entry) { 3759 list_del(&lst_itr->list_entry); 3760 devm_kfree(ice_hw_to_dev(hw), lst_itr->lkups); 3761 devm_kfree(ice_hw_to_dev(hw), lst_itr); 3762 } 3763 } 3764 3765 /** 3766 * ice_cfg_dflt_vsi - change state of VSI to set/clear default 3767 * @pi: pointer to the port_info structure 3768 * @vsi_handle: VSI handle to set as default 3769 * @set: true to add the above mentioned switch rule, false to remove it 3770 * @direction: ICE_FLTR_RX or ICE_FLTR_TX 3771 * 3772 * add filter rule to set/unset given VSI as default VSI for the switch 3773 * (represented by swid) 3774 */ 3775 int 3776 ice_cfg_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, bool set, 3777 u8 direction) 3778 { 3779 struct ice_fltr_list_entry f_list_entry; 3780 struct ice_fltr_info f_info; 3781 struct ice_hw *hw = pi->hw; 3782 u16 hw_vsi_id; 3783 int status; 3784 3785 if (!ice_is_vsi_valid(hw, vsi_handle)) 3786 return -EINVAL; 3787 3788 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3789 3790 memset(&f_info, 0, sizeof(f_info)); 3791 3792 f_info.lkup_type = ICE_SW_LKUP_DFLT; 3793 f_info.flag = direction; 3794 f_info.fltr_act = ICE_FWD_TO_VSI; 3795 f_info.fwd_id.hw_vsi_id = hw_vsi_id; 3796 f_info.vsi_handle = vsi_handle; 3797 3798 if (f_info.flag & ICE_FLTR_RX) { 3799 f_info.src = hw->port_info->lport; 3800 f_info.src_id = ICE_SRC_ID_LPORT; 3801 } else if (f_info.flag & ICE_FLTR_TX) { 3802 f_info.src_id = ICE_SRC_ID_VSI; 3803 f_info.src = hw_vsi_id; 3804 } 3805 f_list_entry.fltr_info = f_info; 3806 3807 if (set) 3808 status = ice_add_rule_internal(hw, ICE_SW_LKUP_DFLT, 3809 &f_list_entry); 3810 else 3811 status = ice_remove_rule_internal(hw, ICE_SW_LKUP_DFLT, 3812 &f_list_entry); 3813 3814 return status; 3815 } 3816 3817 /** 3818 * ice_vsi_uses_fltr - Determine if given VSI uses specified filter 3819 * @fm_entry: filter entry to inspect 3820 * @vsi_handle: VSI handle to compare with filter info 3821 */ 3822 static bool 3823 ice_vsi_uses_fltr(struct ice_fltr_mgmt_list_entry *fm_entry, u16 vsi_handle) 3824 { 3825 return ((fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI && 3826 fm_entry->fltr_info.vsi_handle == vsi_handle) || 3827 (fm_entry->fltr_info.fltr_act == ICE_FWD_TO_VSI_LIST && 3828 fm_entry->vsi_list_info && 3829 (test_bit(vsi_handle, fm_entry->vsi_list_info->vsi_map)))); 3830 } 3831 3832 /** 3833 * ice_check_if_dflt_vsi - check if VSI is default VSI 3834 * @pi: pointer to the port_info structure 3835 * @vsi_handle: vsi handle to check for in filter list 3836 * @rule_exists: indicates if there are any VSI's in the rule list 3837 * 3838 * checks if the VSI is in a default VSI list, and also indicates 3839 * if the default VSI list is empty 3840 */ 3841 bool 3842 ice_check_if_dflt_vsi(struct ice_port_info *pi, u16 vsi_handle, 3843 bool *rule_exists) 3844 { 3845 struct ice_fltr_mgmt_list_entry *fm_entry; 3846 struct ice_sw_recipe *recp_list; 3847 struct list_head *rule_head; 3848 struct mutex *rule_lock; /* Lock to protect filter rule list */ 3849 bool ret = false; 3850 3851 recp_list = &pi->hw->switch_info->recp_list[ICE_SW_LKUP_DFLT]; 3852 rule_lock = &recp_list->filt_rule_lock; 3853 rule_head = &recp_list->filt_rules; 3854 3855 mutex_lock(rule_lock); 3856 3857 if (rule_exists && !list_empty(rule_head)) 3858 *rule_exists = true; 3859 3860 list_for_each_entry(fm_entry, rule_head, list_entry) { 3861 if (ice_vsi_uses_fltr(fm_entry, vsi_handle)) { 3862 ret = true; 3863 break; 3864 } 3865 } 3866 3867 mutex_unlock(rule_lock); 3868 3869 return ret; 3870 } 3871 3872 /** 3873 * ice_remove_mac - remove a MAC address based filter rule 3874 * @hw: pointer to the hardware structure 3875 * @m_list: list of MAC addresses and forwarding information 3876 * 3877 * This function removes either a MAC filter rule or a specific VSI from a 3878 * VSI list for a multicast MAC address. 3879 * 3880 * Returns -ENOENT if a given entry was not added by ice_add_mac. Caller should 3881 * be aware that this call will only work if all the entries passed into m_list 3882 * were added previously. It will not attempt to do a partial remove of entries 3883 * that were found. 3884 */ 3885 int ice_remove_mac(struct ice_hw *hw, struct list_head *m_list) 3886 { 3887 struct ice_fltr_list_entry *list_itr, *tmp; 3888 3889 if (!m_list) 3890 return -EINVAL; 3891 3892 list_for_each_entry_safe(list_itr, tmp, m_list, list_entry) { 3893 enum ice_sw_lkup_type l_type = list_itr->fltr_info.lkup_type; 3894 u16 vsi_handle; 3895 3896 if (l_type != ICE_SW_LKUP_MAC) 3897 return -EINVAL; 3898 3899 vsi_handle = list_itr->fltr_info.vsi_handle; 3900 if (!ice_is_vsi_valid(hw, vsi_handle)) 3901 return -EINVAL; 3902 3903 list_itr->fltr_info.fwd_id.hw_vsi_id = 3904 ice_get_hw_vsi_num(hw, vsi_handle); 3905 3906 list_itr->status = ice_remove_rule_internal(hw, 3907 ICE_SW_LKUP_MAC, 3908 list_itr); 3909 if (list_itr->status) 3910 return list_itr->status; 3911 } 3912 return 0; 3913 } 3914 3915 /** 3916 * ice_remove_vlan - Remove VLAN based filter rule 3917 * @hw: pointer to the hardware structure 3918 * @v_list: list of VLAN entries and forwarding information 3919 */ 3920 int ice_remove_vlan(struct ice_hw *hw, struct list_head *v_list) 3921 { 3922 struct ice_fltr_list_entry *v_list_itr, *tmp; 3923 3924 if (!v_list || !hw) 3925 return -EINVAL; 3926 3927 list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) { 3928 enum ice_sw_lkup_type l_type = v_list_itr->fltr_info.lkup_type; 3929 3930 if (l_type != ICE_SW_LKUP_VLAN) 3931 return -EINVAL; 3932 v_list_itr->status = ice_remove_rule_internal(hw, 3933 ICE_SW_LKUP_VLAN, 3934 v_list_itr); 3935 if (v_list_itr->status) 3936 return v_list_itr->status; 3937 } 3938 return 0; 3939 } 3940 3941 /** 3942 * ice_add_entry_to_vsi_fltr_list - Add copy of fltr_list_entry to remove list 3943 * @hw: pointer to the hardware structure 3944 * @vsi_handle: VSI handle to remove filters from 3945 * @vsi_list_head: pointer to the list to add entry to 3946 * @fi: pointer to fltr_info of filter entry to copy & add 3947 * 3948 * Helper function, used when creating a list of filters to remove from 3949 * a specific VSI. The entry added to vsi_list_head is a COPY of the 3950 * original filter entry, with the exception of fltr_info.fltr_act and 3951 * fltr_info.fwd_id fields. These are set such that later logic can 3952 * extract which VSI to remove the fltr from, and pass on that information. 3953 */ 3954 static int 3955 ice_add_entry_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 3956 struct list_head *vsi_list_head, 3957 struct ice_fltr_info *fi) 3958 { 3959 struct ice_fltr_list_entry *tmp; 3960 3961 /* this memory is freed up in the caller function 3962 * once filters for this VSI are removed 3963 */ 3964 tmp = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*tmp), GFP_KERNEL); 3965 if (!tmp) 3966 return -ENOMEM; 3967 3968 tmp->fltr_info = *fi; 3969 3970 /* Overwrite these fields to indicate which VSI to remove filter from, 3971 * so find and remove logic can extract the information from the 3972 * list entries. Note that original entries will still have proper 3973 * values. 3974 */ 3975 tmp->fltr_info.fltr_act = ICE_FWD_TO_VSI; 3976 tmp->fltr_info.vsi_handle = vsi_handle; 3977 tmp->fltr_info.fwd_id.hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 3978 3979 list_add(&tmp->list_entry, vsi_list_head); 3980 3981 return 0; 3982 } 3983 3984 /** 3985 * ice_add_to_vsi_fltr_list - Add VSI filters to the list 3986 * @hw: pointer to the hardware structure 3987 * @vsi_handle: VSI handle to remove filters from 3988 * @lkup_list_head: pointer to the list that has certain lookup type filters 3989 * @vsi_list_head: pointer to the list pertaining to VSI with vsi_handle 3990 * 3991 * Locates all filters in lkup_list_head that are used by the given VSI, 3992 * and adds COPIES of those entries to vsi_list_head (intended to be used 3993 * to remove the listed filters). 3994 * Note that this means all entries in vsi_list_head must be explicitly 3995 * deallocated by the caller when done with list. 3996 */ 3997 static int 3998 ice_add_to_vsi_fltr_list(struct ice_hw *hw, u16 vsi_handle, 3999 struct list_head *lkup_list_head, 4000 struct list_head *vsi_list_head) 4001 { 4002 struct ice_fltr_mgmt_list_entry *fm_entry; 4003 int status = 0; 4004 4005 /* check to make sure VSI ID is valid and within boundary */ 4006 if (!ice_is_vsi_valid(hw, vsi_handle)) 4007 return -EINVAL; 4008 4009 list_for_each_entry(fm_entry, lkup_list_head, list_entry) { 4010 if (!ice_vsi_uses_fltr(fm_entry, vsi_handle)) 4011 continue; 4012 4013 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 4014 vsi_list_head, 4015 &fm_entry->fltr_info); 4016 if (status) 4017 return status; 4018 } 4019 return status; 4020 } 4021 4022 /** 4023 * ice_determine_promisc_mask 4024 * @fi: filter info to parse 4025 * 4026 * Helper function to determine which ICE_PROMISC_ mask corresponds 4027 * to given filter into. 4028 */ 4029 static u8 ice_determine_promisc_mask(struct ice_fltr_info *fi) 4030 { 4031 u16 vid = fi->l_data.mac_vlan.vlan_id; 4032 u8 *macaddr = fi->l_data.mac.mac_addr; 4033 bool is_tx_fltr = false; 4034 u8 promisc_mask = 0; 4035 4036 if (fi->flag == ICE_FLTR_TX) 4037 is_tx_fltr = true; 4038 4039 if (is_broadcast_ether_addr(macaddr)) 4040 promisc_mask |= is_tx_fltr ? 4041 ICE_PROMISC_BCAST_TX : ICE_PROMISC_BCAST_RX; 4042 else if (is_multicast_ether_addr(macaddr)) 4043 promisc_mask |= is_tx_fltr ? 4044 ICE_PROMISC_MCAST_TX : ICE_PROMISC_MCAST_RX; 4045 else if (is_unicast_ether_addr(macaddr)) 4046 promisc_mask |= is_tx_fltr ? 4047 ICE_PROMISC_UCAST_TX : ICE_PROMISC_UCAST_RX; 4048 if (vid) 4049 promisc_mask |= is_tx_fltr ? 4050 ICE_PROMISC_VLAN_TX : ICE_PROMISC_VLAN_RX; 4051 4052 return promisc_mask; 4053 } 4054 4055 /** 4056 * ice_remove_promisc - Remove promisc based filter rules 4057 * @hw: pointer to the hardware structure 4058 * @recp_id: recipe ID for which the rule needs to removed 4059 * @v_list: list of promisc entries 4060 */ 4061 static int 4062 ice_remove_promisc(struct ice_hw *hw, u8 recp_id, struct list_head *v_list) 4063 { 4064 struct ice_fltr_list_entry *v_list_itr, *tmp; 4065 4066 list_for_each_entry_safe(v_list_itr, tmp, v_list, list_entry) { 4067 v_list_itr->status = 4068 ice_remove_rule_internal(hw, recp_id, v_list_itr); 4069 if (v_list_itr->status) 4070 return v_list_itr->status; 4071 } 4072 return 0; 4073 } 4074 4075 /** 4076 * ice_clear_vsi_promisc - clear specified promiscuous mode(s) for given VSI 4077 * @hw: pointer to the hardware structure 4078 * @vsi_handle: VSI handle to clear mode 4079 * @promisc_mask: mask of promiscuous config bits to clear 4080 * @vid: VLAN ID to clear VLAN promiscuous 4081 */ 4082 int 4083 ice_clear_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 4084 u16 vid) 4085 { 4086 struct ice_switch_info *sw = hw->switch_info; 4087 struct ice_fltr_list_entry *fm_entry, *tmp; 4088 struct list_head remove_list_head; 4089 struct ice_fltr_mgmt_list_entry *itr; 4090 struct list_head *rule_head; 4091 struct mutex *rule_lock; /* Lock to protect filter rule list */ 4092 int status = 0; 4093 u8 recipe_id; 4094 4095 if (!ice_is_vsi_valid(hw, vsi_handle)) 4096 return -EINVAL; 4097 4098 if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) 4099 recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 4100 else 4101 recipe_id = ICE_SW_LKUP_PROMISC; 4102 4103 rule_head = &sw->recp_list[recipe_id].filt_rules; 4104 rule_lock = &sw->recp_list[recipe_id].filt_rule_lock; 4105 4106 INIT_LIST_HEAD(&remove_list_head); 4107 4108 mutex_lock(rule_lock); 4109 list_for_each_entry(itr, rule_head, list_entry) { 4110 struct ice_fltr_info *fltr_info; 4111 u8 fltr_promisc_mask = 0; 4112 4113 if (!ice_vsi_uses_fltr(itr, vsi_handle)) 4114 continue; 4115 fltr_info = &itr->fltr_info; 4116 4117 if (recipe_id == ICE_SW_LKUP_PROMISC_VLAN && 4118 vid != fltr_info->l_data.mac_vlan.vlan_id) 4119 continue; 4120 4121 fltr_promisc_mask |= ice_determine_promisc_mask(fltr_info); 4122 4123 /* Skip if filter is not completely specified by given mask */ 4124 if (fltr_promisc_mask & ~promisc_mask) 4125 continue; 4126 4127 status = ice_add_entry_to_vsi_fltr_list(hw, vsi_handle, 4128 &remove_list_head, 4129 fltr_info); 4130 if (status) { 4131 mutex_unlock(rule_lock); 4132 goto free_fltr_list; 4133 } 4134 } 4135 mutex_unlock(rule_lock); 4136 4137 status = ice_remove_promisc(hw, recipe_id, &remove_list_head); 4138 4139 free_fltr_list: 4140 list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 4141 list_del(&fm_entry->list_entry); 4142 devm_kfree(ice_hw_to_dev(hw), fm_entry); 4143 } 4144 4145 return status; 4146 } 4147 4148 /** 4149 * ice_set_vsi_promisc - set given VSI to given promiscuous mode(s) 4150 * @hw: pointer to the hardware structure 4151 * @vsi_handle: VSI handle to configure 4152 * @promisc_mask: mask of promiscuous config bits 4153 * @vid: VLAN ID to set VLAN promiscuous 4154 */ 4155 int 4156 ice_set_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, u16 vid) 4157 { 4158 enum { UCAST_FLTR = 1, MCAST_FLTR, BCAST_FLTR }; 4159 struct ice_fltr_list_entry f_list_entry; 4160 struct ice_fltr_info new_fltr; 4161 bool is_tx_fltr; 4162 int status = 0; 4163 u16 hw_vsi_id; 4164 int pkt_type; 4165 u8 recipe_id; 4166 4167 if (!ice_is_vsi_valid(hw, vsi_handle)) 4168 return -EINVAL; 4169 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 4170 4171 memset(&new_fltr, 0, sizeof(new_fltr)); 4172 4173 if (promisc_mask & (ICE_PROMISC_VLAN_RX | ICE_PROMISC_VLAN_TX)) { 4174 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC_VLAN; 4175 new_fltr.l_data.mac_vlan.vlan_id = vid; 4176 recipe_id = ICE_SW_LKUP_PROMISC_VLAN; 4177 } else { 4178 new_fltr.lkup_type = ICE_SW_LKUP_PROMISC; 4179 recipe_id = ICE_SW_LKUP_PROMISC; 4180 } 4181 4182 /* Separate filters must be set for each direction/packet type 4183 * combination, so we will loop over the mask value, store the 4184 * individual type, and clear it out in the input mask as it 4185 * is found. 4186 */ 4187 while (promisc_mask) { 4188 u8 *mac_addr; 4189 4190 pkt_type = 0; 4191 is_tx_fltr = false; 4192 4193 if (promisc_mask & ICE_PROMISC_UCAST_RX) { 4194 promisc_mask &= ~ICE_PROMISC_UCAST_RX; 4195 pkt_type = UCAST_FLTR; 4196 } else if (promisc_mask & ICE_PROMISC_UCAST_TX) { 4197 promisc_mask &= ~ICE_PROMISC_UCAST_TX; 4198 pkt_type = UCAST_FLTR; 4199 is_tx_fltr = true; 4200 } else if (promisc_mask & ICE_PROMISC_MCAST_RX) { 4201 promisc_mask &= ~ICE_PROMISC_MCAST_RX; 4202 pkt_type = MCAST_FLTR; 4203 } else if (promisc_mask & ICE_PROMISC_MCAST_TX) { 4204 promisc_mask &= ~ICE_PROMISC_MCAST_TX; 4205 pkt_type = MCAST_FLTR; 4206 is_tx_fltr = true; 4207 } else if (promisc_mask & ICE_PROMISC_BCAST_RX) { 4208 promisc_mask &= ~ICE_PROMISC_BCAST_RX; 4209 pkt_type = BCAST_FLTR; 4210 } else if (promisc_mask & ICE_PROMISC_BCAST_TX) { 4211 promisc_mask &= ~ICE_PROMISC_BCAST_TX; 4212 pkt_type = BCAST_FLTR; 4213 is_tx_fltr = true; 4214 } 4215 4216 /* Check for VLAN promiscuous flag */ 4217 if (promisc_mask & ICE_PROMISC_VLAN_RX) { 4218 promisc_mask &= ~ICE_PROMISC_VLAN_RX; 4219 } else if (promisc_mask & ICE_PROMISC_VLAN_TX) { 4220 promisc_mask &= ~ICE_PROMISC_VLAN_TX; 4221 is_tx_fltr = true; 4222 } 4223 4224 /* Set filter DA based on packet type */ 4225 mac_addr = new_fltr.l_data.mac.mac_addr; 4226 if (pkt_type == BCAST_FLTR) { 4227 eth_broadcast_addr(mac_addr); 4228 } else if (pkt_type == MCAST_FLTR || 4229 pkt_type == UCAST_FLTR) { 4230 /* Use the dummy ether header DA */ 4231 ether_addr_copy(mac_addr, dummy_eth_header); 4232 if (pkt_type == MCAST_FLTR) 4233 mac_addr[0] |= 0x1; /* Set multicast bit */ 4234 } 4235 4236 /* Need to reset this to zero for all iterations */ 4237 new_fltr.flag = 0; 4238 if (is_tx_fltr) { 4239 new_fltr.flag |= ICE_FLTR_TX; 4240 new_fltr.src = hw_vsi_id; 4241 } else { 4242 new_fltr.flag |= ICE_FLTR_RX; 4243 new_fltr.src = hw->port_info->lport; 4244 } 4245 4246 new_fltr.fltr_act = ICE_FWD_TO_VSI; 4247 new_fltr.vsi_handle = vsi_handle; 4248 new_fltr.fwd_id.hw_vsi_id = hw_vsi_id; 4249 f_list_entry.fltr_info = new_fltr; 4250 4251 status = ice_add_rule_internal(hw, recipe_id, &f_list_entry); 4252 if (status) 4253 goto set_promisc_exit; 4254 } 4255 4256 set_promisc_exit: 4257 return status; 4258 } 4259 4260 /** 4261 * ice_set_vlan_vsi_promisc 4262 * @hw: pointer to the hardware structure 4263 * @vsi_handle: VSI handle to configure 4264 * @promisc_mask: mask of promiscuous config bits 4265 * @rm_vlan_promisc: Clear VLANs VSI promisc mode 4266 * 4267 * Configure VSI with all associated VLANs to given promiscuous mode(s) 4268 */ 4269 int 4270 ice_set_vlan_vsi_promisc(struct ice_hw *hw, u16 vsi_handle, u8 promisc_mask, 4271 bool rm_vlan_promisc) 4272 { 4273 struct ice_switch_info *sw = hw->switch_info; 4274 struct ice_fltr_list_entry *list_itr, *tmp; 4275 struct list_head vsi_list_head; 4276 struct list_head *vlan_head; 4277 struct mutex *vlan_lock; /* Lock to protect filter rule list */ 4278 u16 vlan_id; 4279 int status; 4280 4281 INIT_LIST_HEAD(&vsi_list_head); 4282 vlan_lock = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rule_lock; 4283 vlan_head = &sw->recp_list[ICE_SW_LKUP_VLAN].filt_rules; 4284 mutex_lock(vlan_lock); 4285 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, vlan_head, 4286 &vsi_list_head); 4287 mutex_unlock(vlan_lock); 4288 if (status) 4289 goto free_fltr_list; 4290 4291 list_for_each_entry(list_itr, &vsi_list_head, list_entry) { 4292 /* Avoid enabling or disabling VLAN zero twice when in double 4293 * VLAN mode 4294 */ 4295 if (ice_is_dvm_ena(hw) && 4296 list_itr->fltr_info.l_data.vlan.tpid == 0) 4297 continue; 4298 4299 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id; 4300 if (rm_vlan_promisc) 4301 status = ice_clear_vsi_promisc(hw, vsi_handle, 4302 promisc_mask, vlan_id); 4303 else 4304 status = ice_set_vsi_promisc(hw, vsi_handle, 4305 promisc_mask, vlan_id); 4306 if (status && status != -EEXIST) 4307 break; 4308 } 4309 4310 free_fltr_list: 4311 list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) { 4312 list_del(&list_itr->list_entry); 4313 devm_kfree(ice_hw_to_dev(hw), list_itr); 4314 } 4315 return status; 4316 } 4317 4318 /** 4319 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 4320 * @hw: pointer to the hardware structure 4321 * @vsi_handle: VSI handle to remove filters from 4322 * @lkup: switch rule filter lookup type 4323 */ 4324 static void 4325 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, 4326 enum ice_sw_lkup_type lkup) 4327 { 4328 struct ice_switch_info *sw = hw->switch_info; 4329 struct ice_fltr_list_entry *fm_entry; 4330 struct list_head remove_list_head; 4331 struct list_head *rule_head; 4332 struct ice_fltr_list_entry *tmp; 4333 struct mutex *rule_lock; /* Lock to protect filter rule list */ 4334 int status; 4335 4336 INIT_LIST_HEAD(&remove_list_head); 4337 rule_lock = &sw->recp_list[lkup].filt_rule_lock; 4338 rule_head = &sw->recp_list[lkup].filt_rules; 4339 mutex_lock(rule_lock); 4340 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head, 4341 &remove_list_head); 4342 mutex_unlock(rule_lock); 4343 if (status) 4344 goto free_fltr_list; 4345 4346 switch (lkup) { 4347 case ICE_SW_LKUP_MAC: 4348 ice_remove_mac(hw, &remove_list_head); 4349 break; 4350 case ICE_SW_LKUP_VLAN: 4351 ice_remove_vlan(hw, &remove_list_head); 4352 break; 4353 case ICE_SW_LKUP_PROMISC: 4354 case ICE_SW_LKUP_PROMISC_VLAN: 4355 ice_remove_promisc(hw, lkup, &remove_list_head); 4356 break; 4357 case ICE_SW_LKUP_MAC_VLAN: 4358 case ICE_SW_LKUP_ETHERTYPE: 4359 case ICE_SW_LKUP_ETHERTYPE_MAC: 4360 case ICE_SW_LKUP_DFLT: 4361 case ICE_SW_LKUP_LAST: 4362 default: 4363 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup); 4364 break; 4365 } 4366 4367 free_fltr_list: 4368 list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 4369 list_del(&fm_entry->list_entry); 4370 devm_kfree(ice_hw_to_dev(hw), fm_entry); 4371 } 4372 } 4373 4374 /** 4375 * ice_remove_vsi_fltr - Remove all filters for a VSI 4376 * @hw: pointer to the hardware structure 4377 * @vsi_handle: VSI handle to remove filters from 4378 */ 4379 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) 4380 { 4381 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC); 4382 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN); 4383 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC); 4384 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN); 4385 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT); 4386 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE); 4387 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC); 4388 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN); 4389 } 4390 4391 /** 4392 * ice_alloc_res_cntr - allocating resource counter 4393 * @hw: pointer to the hardware structure 4394 * @type: type of resource 4395 * @alloc_shared: if set it is shared else dedicated 4396 * @num_items: number of entries requested for FD resource type 4397 * @counter_id: counter index returned by AQ call 4398 */ 4399 int 4400 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4401 u16 *counter_id) 4402 { 4403 struct ice_aqc_alloc_free_res_elem *buf; 4404 u16 buf_len; 4405 int status; 4406 4407 /* Allocate resource */ 4408 buf_len = struct_size(buf, elem, 1); 4409 buf = kzalloc(buf_len, GFP_KERNEL); 4410 if (!buf) 4411 return -ENOMEM; 4412 4413 buf->num_elems = cpu_to_le16(num_items); 4414 buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4415 ICE_AQC_RES_TYPE_M) | alloc_shared); 4416 4417 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 4418 ice_aqc_opc_alloc_res, NULL); 4419 if (status) 4420 goto exit; 4421 4422 *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp); 4423 4424 exit: 4425 kfree(buf); 4426 return status; 4427 } 4428 4429 /** 4430 * ice_free_res_cntr - free resource counter 4431 * @hw: pointer to the hardware structure 4432 * @type: type of resource 4433 * @alloc_shared: if set it is shared else dedicated 4434 * @num_items: number of entries to be freed for FD resource type 4435 * @counter_id: counter ID resource which needs to be freed 4436 */ 4437 int 4438 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4439 u16 counter_id) 4440 { 4441 struct ice_aqc_alloc_free_res_elem *buf; 4442 u16 buf_len; 4443 int status; 4444 4445 /* Free resource */ 4446 buf_len = struct_size(buf, elem, 1); 4447 buf = kzalloc(buf_len, GFP_KERNEL); 4448 if (!buf) 4449 return -ENOMEM; 4450 4451 buf->num_elems = cpu_to_le16(num_items); 4452 buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4453 ICE_AQC_RES_TYPE_M) | alloc_shared); 4454 buf->elem[0].e.sw_resp = cpu_to_le16(counter_id); 4455 4456 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 4457 ice_aqc_opc_free_res, NULL); 4458 if (status) 4459 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n"); 4460 4461 kfree(buf); 4462 return status; 4463 } 4464 4465 /* This is mapping table entry that maps every word within a given protocol 4466 * structure to the real byte offset as per the specification of that 4467 * protocol header. 4468 * for example dst address is 3 words in ethertype header and corresponding 4469 * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8 4470 * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a 4471 * matching entry describing its field. This needs to be updated if new 4472 * structure is added to that union. 4473 */ 4474 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = { 4475 { ICE_MAC_OFOS, { 0, 2, 4, 6, 8, 10, 12 } }, 4476 { ICE_MAC_IL, { 0, 2, 4, 6, 8, 10, 12 } }, 4477 { ICE_ETYPE_OL, { 0 } }, 4478 { ICE_ETYPE_IL, { 0 } }, 4479 { ICE_VLAN_OFOS, { 2, 0 } }, 4480 { ICE_IPV4_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } }, 4481 { ICE_IPV4_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } }, 4482 { ICE_IPV6_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 4483 26, 28, 30, 32, 34, 36, 38 } }, 4484 { ICE_IPV6_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 4485 26, 28, 30, 32, 34, 36, 38 } }, 4486 { ICE_TCP_IL, { 0, 2 } }, 4487 { ICE_UDP_OF, { 0, 2 } }, 4488 { ICE_UDP_ILOS, { 0, 2 } }, 4489 { ICE_VXLAN, { 8, 10, 12, 14 } }, 4490 { ICE_GENEVE, { 8, 10, 12, 14 } }, 4491 { ICE_NVGRE, { 0, 2, 4, 6 } }, 4492 { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } }, 4493 { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } }, 4494 { ICE_PPPOE, { 0, 2, 4, 6 } }, 4495 { ICE_VLAN_EX, { 2, 0 } }, 4496 { ICE_VLAN_IN, { 2, 0 } }, 4497 }; 4498 4499 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { 4500 { ICE_MAC_OFOS, ICE_MAC_OFOS_HW }, 4501 { ICE_MAC_IL, ICE_MAC_IL_HW }, 4502 { ICE_ETYPE_OL, ICE_ETYPE_OL_HW }, 4503 { ICE_ETYPE_IL, ICE_ETYPE_IL_HW }, 4504 { ICE_VLAN_OFOS, ICE_VLAN_OL_HW }, 4505 { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW }, 4506 { ICE_IPV4_IL, ICE_IPV4_IL_HW }, 4507 { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW }, 4508 { ICE_IPV6_IL, ICE_IPV6_IL_HW }, 4509 { ICE_TCP_IL, ICE_TCP_IL_HW }, 4510 { ICE_UDP_OF, ICE_UDP_OF_HW }, 4511 { ICE_UDP_ILOS, ICE_UDP_ILOS_HW }, 4512 { ICE_VXLAN, ICE_UDP_OF_HW }, 4513 { ICE_GENEVE, ICE_UDP_OF_HW }, 4514 { ICE_NVGRE, ICE_GRE_OF_HW }, 4515 { ICE_GTP, ICE_UDP_OF_HW }, 4516 { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW }, 4517 { ICE_PPPOE, ICE_PPPOE_HW }, 4518 { ICE_VLAN_EX, ICE_VLAN_OF_HW }, 4519 { ICE_VLAN_IN, ICE_VLAN_OL_HW }, 4520 }; 4521 4522 /** 4523 * ice_find_recp - find a recipe 4524 * @hw: pointer to the hardware structure 4525 * @lkup_exts: extension sequence to match 4526 * @tun_type: type of recipe tunnel 4527 * 4528 * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. 4529 */ 4530 static u16 4531 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, 4532 enum ice_sw_tunnel_type tun_type) 4533 { 4534 bool refresh_required = true; 4535 struct ice_sw_recipe *recp; 4536 u8 i; 4537 4538 /* Walk through existing recipes to find a match */ 4539 recp = hw->switch_info->recp_list; 4540 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 4541 /* If recipe was not created for this ID, in SW bookkeeping, 4542 * check if FW has an entry for this recipe. If the FW has an 4543 * entry update it in our SW bookkeeping and continue with the 4544 * matching. 4545 */ 4546 if (!recp[i].recp_created) 4547 if (ice_get_recp_frm_fw(hw, 4548 hw->switch_info->recp_list, i, 4549 &refresh_required)) 4550 continue; 4551 4552 /* Skip inverse action recipes */ 4553 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl & 4554 ICE_AQ_RECIPE_ACT_INV_ACT) 4555 continue; 4556 4557 /* if number of words we are looking for match */ 4558 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) { 4559 struct ice_fv_word *ar = recp[i].lkup_exts.fv_words; 4560 struct ice_fv_word *be = lkup_exts->fv_words; 4561 u16 *cr = recp[i].lkup_exts.field_mask; 4562 u16 *de = lkup_exts->field_mask; 4563 bool found = true; 4564 u8 pe, qr; 4565 4566 /* ar, cr, and qr are related to the recipe words, while 4567 * be, de, and pe are related to the lookup words 4568 */ 4569 for (pe = 0; pe < lkup_exts->n_val_words; pe++) { 4570 for (qr = 0; qr < recp[i].lkup_exts.n_val_words; 4571 qr++) { 4572 if (ar[qr].off == be[pe].off && 4573 ar[qr].prot_id == be[pe].prot_id && 4574 cr[qr] == de[pe]) 4575 /* Found the "pe"th word in the 4576 * given recipe 4577 */ 4578 break; 4579 } 4580 /* After walking through all the words in the 4581 * "i"th recipe if "p"th word was not found then 4582 * this recipe is not what we are looking for. 4583 * So break out from this loop and try the next 4584 * recipe 4585 */ 4586 if (qr >= recp[i].lkup_exts.n_val_words) { 4587 found = false; 4588 break; 4589 } 4590 } 4591 /* If for "i"th recipe the found was never set to false 4592 * then it means we found our match 4593 * Also tun type of recipe needs to be checked 4594 */ 4595 if (found && recp[i].tun_type == tun_type) 4596 return i; /* Return the recipe ID */ 4597 } 4598 } 4599 return ICE_MAX_NUM_RECIPES; 4600 } 4601 4602 /** 4603 * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl 4604 * 4605 * As protocol id for outer vlan is different in dvm and svm, if dvm is 4606 * supported protocol array record for outer vlan has to be modified to 4607 * reflect the value proper for DVM. 4608 */ 4609 void ice_change_proto_id_to_dvm(void) 4610 { 4611 u8 i; 4612 4613 for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4614 if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS && 4615 ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW) 4616 ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW; 4617 } 4618 4619 /** 4620 * ice_prot_type_to_id - get protocol ID from protocol type 4621 * @type: protocol type 4622 * @id: pointer to variable that will receive the ID 4623 * 4624 * Returns true if found, false otherwise 4625 */ 4626 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) 4627 { 4628 u8 i; 4629 4630 for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4631 if (ice_prot_id_tbl[i].type == type) { 4632 *id = ice_prot_id_tbl[i].protocol_id; 4633 return true; 4634 } 4635 return false; 4636 } 4637 4638 /** 4639 * ice_fill_valid_words - count valid words 4640 * @rule: advanced rule with lookup information 4641 * @lkup_exts: byte offset extractions of the words that are valid 4642 * 4643 * calculate valid words in a lookup rule using mask value 4644 */ 4645 static u8 4646 ice_fill_valid_words(struct ice_adv_lkup_elem *rule, 4647 struct ice_prot_lkup_ext *lkup_exts) 4648 { 4649 u8 j, word, prot_id, ret_val; 4650 4651 if (!ice_prot_type_to_id(rule->type, &prot_id)) 4652 return 0; 4653 4654 word = lkup_exts->n_val_words; 4655 4656 for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++) 4657 if (((u16 *)&rule->m_u)[j] && 4658 rule->type < ARRAY_SIZE(ice_prot_ext)) { 4659 /* No more space to accommodate */ 4660 if (word >= ICE_MAX_CHAIN_WORDS) 4661 return 0; 4662 lkup_exts->fv_words[word].off = 4663 ice_prot_ext[rule->type].offs[j]; 4664 lkup_exts->fv_words[word].prot_id = 4665 ice_prot_id_tbl[rule->type].protocol_id; 4666 lkup_exts->field_mask[word] = 4667 be16_to_cpu(((__force __be16 *)&rule->m_u)[j]); 4668 word++; 4669 } 4670 4671 ret_val = word - lkup_exts->n_val_words; 4672 lkup_exts->n_val_words = word; 4673 4674 return ret_val; 4675 } 4676 4677 /** 4678 * ice_create_first_fit_recp_def - Create a recipe grouping 4679 * @hw: pointer to the hardware structure 4680 * @lkup_exts: an array of protocol header extractions 4681 * @rg_list: pointer to a list that stores new recipe groups 4682 * @recp_cnt: pointer to a variable that stores returned number of recipe groups 4683 * 4684 * Using first fit algorithm, take all the words that are still not done 4685 * and start grouping them in 4-word groups. Each group makes up one 4686 * recipe. 4687 */ 4688 static int 4689 ice_create_first_fit_recp_def(struct ice_hw *hw, 4690 struct ice_prot_lkup_ext *lkup_exts, 4691 struct list_head *rg_list, 4692 u8 *recp_cnt) 4693 { 4694 struct ice_pref_recipe_group *grp = NULL; 4695 u8 j; 4696 4697 *recp_cnt = 0; 4698 4699 /* Walk through every word in the rule to check if it is not done. If so 4700 * then this word needs to be part of a new recipe. 4701 */ 4702 for (j = 0; j < lkup_exts->n_val_words; j++) 4703 if (!test_bit(j, lkup_exts->done)) { 4704 if (!grp || 4705 grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) { 4706 struct ice_recp_grp_entry *entry; 4707 4708 entry = devm_kzalloc(ice_hw_to_dev(hw), 4709 sizeof(*entry), 4710 GFP_KERNEL); 4711 if (!entry) 4712 return -ENOMEM; 4713 list_add(&entry->l_entry, rg_list); 4714 grp = &entry->r_group; 4715 (*recp_cnt)++; 4716 } 4717 4718 grp->pairs[grp->n_val_pairs].prot_id = 4719 lkup_exts->fv_words[j].prot_id; 4720 grp->pairs[grp->n_val_pairs].off = 4721 lkup_exts->fv_words[j].off; 4722 grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j]; 4723 grp->n_val_pairs++; 4724 } 4725 4726 return 0; 4727 } 4728 4729 /** 4730 * ice_fill_fv_word_index - fill in the field vector indices for a recipe group 4731 * @hw: pointer to the hardware structure 4732 * @fv_list: field vector with the extraction sequence information 4733 * @rg_list: recipe groupings with protocol-offset pairs 4734 * 4735 * Helper function to fill in the field vector indices for protocol-offset 4736 * pairs. These indexes are then ultimately programmed into a recipe. 4737 */ 4738 static int 4739 ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list, 4740 struct list_head *rg_list) 4741 { 4742 struct ice_sw_fv_list_entry *fv; 4743 struct ice_recp_grp_entry *rg; 4744 struct ice_fv_word *fv_ext; 4745 4746 if (list_empty(fv_list)) 4747 return 0; 4748 4749 fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry, 4750 list_entry); 4751 fv_ext = fv->fv_ptr->ew; 4752 4753 list_for_each_entry(rg, rg_list, l_entry) { 4754 u8 i; 4755 4756 for (i = 0; i < rg->r_group.n_val_pairs; i++) { 4757 struct ice_fv_word *pr; 4758 bool found = false; 4759 u16 mask; 4760 u8 j; 4761 4762 pr = &rg->r_group.pairs[i]; 4763 mask = rg->r_group.mask[i]; 4764 4765 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 4766 if (fv_ext[j].prot_id == pr->prot_id && 4767 fv_ext[j].off == pr->off) { 4768 found = true; 4769 4770 /* Store index of field vector */ 4771 rg->fv_idx[i] = j; 4772 rg->fv_mask[i] = mask; 4773 break; 4774 } 4775 4776 /* Protocol/offset could not be found, caller gave an 4777 * invalid pair 4778 */ 4779 if (!found) 4780 return -EINVAL; 4781 } 4782 } 4783 4784 return 0; 4785 } 4786 4787 /** 4788 * ice_find_free_recp_res_idx - find free result indexes for recipe 4789 * @hw: pointer to hardware structure 4790 * @profiles: bitmap of profiles that will be associated with the new recipe 4791 * @free_idx: pointer to variable to receive the free index bitmap 4792 * 4793 * The algorithm used here is: 4794 * 1. When creating a new recipe, create a set P which contains all 4795 * Profiles that will be associated with our new recipe 4796 * 4797 * 2. For each Profile p in set P: 4798 * a. Add all recipes associated with Profile p into set R 4799 * b. Optional : PossibleIndexes &= profile[p].possibleIndexes 4800 * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF] 4801 * i. Or just assume they all have the same possible indexes: 4802 * 44, 45, 46, 47 4803 * i.e., PossibleIndexes = 0x0000F00000000000 4804 * 4805 * 3. For each Recipe r in set R: 4806 * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes 4807 * b. FreeIndexes = UsedIndexes ^ PossibleIndexes 4808 * 4809 * FreeIndexes will contain the bits indicating the indexes free for use, 4810 * then the code needs to update the recipe[r].used_result_idx_bits to 4811 * indicate which indexes were selected for use by this recipe. 4812 */ 4813 static u16 4814 ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, 4815 unsigned long *free_idx) 4816 { 4817 DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS); 4818 DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES); 4819 DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS); 4820 u16 bit; 4821 4822 bitmap_zero(recipes, ICE_MAX_NUM_RECIPES); 4823 bitmap_zero(used_idx, ICE_MAX_FV_WORDS); 4824 4825 bitmap_fill(possible_idx, ICE_MAX_FV_WORDS); 4826 4827 /* For each profile we are going to associate the recipe with, add the 4828 * recipes that are associated with that profile. This will give us 4829 * the set of recipes that our recipe may collide with. Also, determine 4830 * what possible result indexes are usable given this set of profiles. 4831 */ 4832 for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) { 4833 bitmap_or(recipes, recipes, profile_to_recipe[bit], 4834 ICE_MAX_NUM_RECIPES); 4835 bitmap_and(possible_idx, possible_idx, 4836 hw->switch_info->prof_res_bm[bit], 4837 ICE_MAX_FV_WORDS); 4838 } 4839 4840 /* For each recipe that our new recipe may collide with, determine 4841 * which indexes have been used. 4842 */ 4843 for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES) 4844 bitmap_or(used_idx, used_idx, 4845 hw->switch_info->recp_list[bit].res_idxs, 4846 ICE_MAX_FV_WORDS); 4847 4848 bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS); 4849 4850 /* return number of free indexes */ 4851 return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS); 4852 } 4853 4854 /** 4855 * ice_add_sw_recipe - function to call AQ calls to create switch recipe 4856 * @hw: pointer to hardware structure 4857 * @rm: recipe management list entry 4858 * @profiles: bitmap of profiles that will be associated. 4859 */ 4860 static int 4861 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, 4862 unsigned long *profiles) 4863 { 4864 DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS); 4865 struct ice_aqc_recipe_data_elem *tmp; 4866 struct ice_aqc_recipe_data_elem *buf; 4867 struct ice_recp_grp_entry *entry; 4868 u16 free_res_idx; 4869 u16 recipe_count; 4870 u8 chain_idx; 4871 u8 recps = 0; 4872 int status; 4873 4874 /* When more than one recipe are required, another recipe is needed to 4875 * chain them together. Matching a tunnel metadata ID takes up one of 4876 * the match fields in the chaining recipe reducing the number of 4877 * chained recipes by one. 4878 */ 4879 /* check number of free result indices */ 4880 bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS); 4881 free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm); 4882 4883 ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n", 4884 free_res_idx, rm->n_grp_count); 4885 4886 if (rm->n_grp_count > 1) { 4887 if (rm->n_grp_count > free_res_idx) 4888 return -ENOSPC; 4889 4890 rm->n_grp_count++; 4891 } 4892 4893 if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE) 4894 return -ENOSPC; 4895 4896 tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); 4897 if (!tmp) 4898 return -ENOMEM; 4899 4900 buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf), 4901 GFP_KERNEL); 4902 if (!buf) { 4903 status = -ENOMEM; 4904 goto err_mem; 4905 } 4906 4907 bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES); 4908 recipe_count = ICE_MAX_NUM_RECIPES; 4909 status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC, 4910 NULL); 4911 if (status || recipe_count == 0) 4912 goto err_unroll; 4913 4914 /* Allocate the recipe resources, and configure them according to the 4915 * match fields from protocol headers and extracted field vectors. 4916 */ 4917 chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS); 4918 list_for_each_entry(entry, &rm->rg_list, l_entry) { 4919 u8 i; 4920 4921 status = ice_alloc_recipe(hw, &entry->rid); 4922 if (status) 4923 goto err_unroll; 4924 4925 /* Clear the result index of the located recipe, as this will be 4926 * updated, if needed, later in the recipe creation process. 4927 */ 4928 tmp[0].content.result_indx = 0; 4929 4930 buf[recps] = tmp[0]; 4931 buf[recps].recipe_indx = (u8)entry->rid; 4932 /* if the recipe is a non-root recipe RID should be programmed 4933 * as 0 for the rules to be applied correctly. 4934 */ 4935 buf[recps].content.rid = 0; 4936 memset(&buf[recps].content.lkup_indx, 0, 4937 sizeof(buf[recps].content.lkup_indx)); 4938 4939 /* All recipes use look-up index 0 to match switch ID. */ 4940 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 4941 buf[recps].content.mask[0] = 4942 cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 4943 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask 4944 * to be 0 4945 */ 4946 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 4947 buf[recps].content.lkup_indx[i] = 0x80; 4948 buf[recps].content.mask[i] = 0; 4949 } 4950 4951 for (i = 0; i < entry->r_group.n_val_pairs; i++) { 4952 buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i]; 4953 buf[recps].content.mask[i + 1] = 4954 cpu_to_le16(entry->fv_mask[i]); 4955 } 4956 4957 if (rm->n_grp_count > 1) { 4958 /* Checks to see if there really is a valid result index 4959 * that can be used. 4960 */ 4961 if (chain_idx >= ICE_MAX_FV_WORDS) { 4962 ice_debug(hw, ICE_DBG_SW, "No chain index available\n"); 4963 status = -ENOSPC; 4964 goto err_unroll; 4965 } 4966 4967 entry->chain_idx = chain_idx; 4968 buf[recps].content.result_indx = 4969 ICE_AQ_RECIPE_RESULT_EN | 4970 ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) & 4971 ICE_AQ_RECIPE_RESULT_DATA_M); 4972 clear_bit(chain_idx, result_idx_bm); 4973 chain_idx = find_first_bit(result_idx_bm, 4974 ICE_MAX_FV_WORDS); 4975 } 4976 4977 /* fill recipe dependencies */ 4978 bitmap_zero((unsigned long *)buf[recps].recipe_bitmap, 4979 ICE_MAX_NUM_RECIPES); 4980 set_bit(buf[recps].recipe_indx, 4981 (unsigned long *)buf[recps].recipe_bitmap); 4982 buf[recps].content.act_ctrl_fwd_priority = rm->priority; 4983 recps++; 4984 } 4985 4986 if (rm->n_grp_count == 1) { 4987 rm->root_rid = buf[0].recipe_indx; 4988 set_bit(buf[0].recipe_indx, rm->r_bitmap); 4989 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT; 4990 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) { 4991 memcpy(buf[0].recipe_bitmap, rm->r_bitmap, 4992 sizeof(buf[0].recipe_bitmap)); 4993 } else { 4994 status = -EINVAL; 4995 goto err_unroll; 4996 } 4997 /* Applicable only for ROOT_RECIPE, set the fwd_priority for 4998 * the recipe which is getting created if specified 4999 * by user. Usually any advanced switch filter, which results 5000 * into new extraction sequence, ended up creating a new recipe 5001 * of type ROOT and usually recipes are associated with profiles 5002 * Switch rule referreing newly created recipe, needs to have 5003 * either/or 'fwd' or 'join' priority, otherwise switch rule 5004 * evaluation will not happen correctly. In other words, if 5005 * switch rule to be evaluated on priority basis, then recipe 5006 * needs to have priority, otherwise it will be evaluated last. 5007 */ 5008 buf[0].content.act_ctrl_fwd_priority = rm->priority; 5009 } else { 5010 struct ice_recp_grp_entry *last_chain_entry; 5011 u16 rid, i; 5012 5013 /* Allocate the last recipe that will chain the outcomes of the 5014 * other recipes together 5015 */ 5016 status = ice_alloc_recipe(hw, &rid); 5017 if (status) 5018 goto err_unroll; 5019 5020 buf[recps].recipe_indx = (u8)rid; 5021 buf[recps].content.rid = (u8)rid; 5022 buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT; 5023 /* the new entry created should also be part of rg_list to 5024 * make sure we have complete recipe 5025 */ 5026 last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw), 5027 sizeof(*last_chain_entry), 5028 GFP_KERNEL); 5029 if (!last_chain_entry) { 5030 status = -ENOMEM; 5031 goto err_unroll; 5032 } 5033 last_chain_entry->rid = rid; 5034 memset(&buf[recps].content.lkup_indx, 0, 5035 sizeof(buf[recps].content.lkup_indx)); 5036 /* All recipes use look-up index 0 to match switch ID. */ 5037 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5038 buf[recps].content.mask[0] = 5039 cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5040 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5041 buf[recps].content.lkup_indx[i] = 5042 ICE_AQ_RECIPE_LKUP_IGNORE; 5043 buf[recps].content.mask[i] = 0; 5044 } 5045 5046 i = 1; 5047 /* update r_bitmap with the recp that is used for chaining */ 5048 set_bit(rid, rm->r_bitmap); 5049 /* this is the recipe that chains all the other recipes so it 5050 * should not have a chaining ID to indicate the same 5051 */ 5052 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND; 5053 list_for_each_entry(entry, &rm->rg_list, l_entry) { 5054 last_chain_entry->fv_idx[i] = entry->chain_idx; 5055 buf[recps].content.lkup_indx[i] = entry->chain_idx; 5056 buf[recps].content.mask[i++] = cpu_to_le16(0xFFFF); 5057 set_bit(entry->rid, rm->r_bitmap); 5058 } 5059 list_add(&last_chain_entry->l_entry, &rm->rg_list); 5060 if (sizeof(buf[recps].recipe_bitmap) >= 5061 sizeof(rm->r_bitmap)) { 5062 memcpy(buf[recps].recipe_bitmap, rm->r_bitmap, 5063 sizeof(buf[recps].recipe_bitmap)); 5064 } else { 5065 status = -EINVAL; 5066 goto err_unroll; 5067 } 5068 buf[recps].content.act_ctrl_fwd_priority = rm->priority; 5069 5070 recps++; 5071 rm->root_rid = (u8)rid; 5072 } 5073 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5074 if (status) 5075 goto err_unroll; 5076 5077 status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL); 5078 ice_release_change_lock(hw); 5079 if (status) 5080 goto err_unroll; 5081 5082 /* Every recipe that just got created add it to the recipe 5083 * book keeping list 5084 */ 5085 list_for_each_entry(entry, &rm->rg_list, l_entry) { 5086 struct ice_switch_info *sw = hw->switch_info; 5087 bool is_root, idx_found = false; 5088 struct ice_sw_recipe *recp; 5089 u16 idx, buf_idx = 0; 5090 5091 /* find buffer index for copying some data */ 5092 for (idx = 0; idx < rm->n_grp_count; idx++) 5093 if (buf[idx].recipe_indx == entry->rid) { 5094 buf_idx = idx; 5095 idx_found = true; 5096 } 5097 5098 if (!idx_found) { 5099 status = -EIO; 5100 goto err_unroll; 5101 } 5102 5103 recp = &sw->recp_list[entry->rid]; 5104 is_root = (rm->root_rid == entry->rid); 5105 recp->is_root = is_root; 5106 5107 recp->root_rid = entry->rid; 5108 recp->big_recp = (is_root && rm->n_grp_count > 1); 5109 5110 memcpy(&recp->ext_words, entry->r_group.pairs, 5111 entry->r_group.n_val_pairs * sizeof(struct ice_fv_word)); 5112 5113 memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap, 5114 sizeof(recp->r_bitmap)); 5115 5116 /* Copy non-result fv index values and masks to recipe. This 5117 * call will also update the result recipe bitmask. 5118 */ 5119 ice_collect_result_idx(&buf[buf_idx], recp); 5120 5121 /* for non-root recipes, also copy to the root, this allows 5122 * easier matching of a complete chained recipe 5123 */ 5124 if (!is_root) 5125 ice_collect_result_idx(&buf[buf_idx], 5126 &sw->recp_list[rm->root_rid]); 5127 5128 recp->n_ext_words = entry->r_group.n_val_pairs; 5129 recp->chain_idx = entry->chain_idx; 5130 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority; 5131 recp->n_grp_count = rm->n_grp_count; 5132 recp->tun_type = rm->tun_type; 5133 recp->recp_created = true; 5134 } 5135 rm->root_buf = buf; 5136 kfree(tmp); 5137 return status; 5138 5139 err_unroll: 5140 err_mem: 5141 kfree(tmp); 5142 devm_kfree(ice_hw_to_dev(hw), buf); 5143 return status; 5144 } 5145 5146 /** 5147 * ice_create_recipe_group - creates recipe group 5148 * @hw: pointer to hardware structure 5149 * @rm: recipe management list entry 5150 * @lkup_exts: lookup elements 5151 */ 5152 static int 5153 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm, 5154 struct ice_prot_lkup_ext *lkup_exts) 5155 { 5156 u8 recp_count = 0; 5157 int status; 5158 5159 rm->n_grp_count = 0; 5160 5161 /* Create recipes for words that are marked not done by packing them 5162 * as best fit. 5163 */ 5164 status = ice_create_first_fit_recp_def(hw, lkup_exts, 5165 &rm->rg_list, &recp_count); 5166 if (!status) { 5167 rm->n_grp_count += recp_count; 5168 rm->n_ext_words = lkup_exts->n_val_words; 5169 memcpy(&rm->ext_words, lkup_exts->fv_words, 5170 sizeof(rm->ext_words)); 5171 memcpy(rm->word_masks, lkup_exts->field_mask, 5172 sizeof(rm->word_masks)); 5173 } 5174 5175 return status; 5176 } 5177 5178 /** 5179 * ice_tun_type_match_word - determine if tun type needs a match mask 5180 * @tun_type: tunnel type 5181 * @mask: mask to be used for the tunnel 5182 */ 5183 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) 5184 { 5185 switch (tun_type) { 5186 case ICE_SW_TUN_GENEVE: 5187 case ICE_SW_TUN_VXLAN: 5188 case ICE_SW_TUN_NVGRE: 5189 case ICE_SW_TUN_GTPU: 5190 case ICE_SW_TUN_GTPC: 5191 *mask = ICE_TUN_FLAG_MASK; 5192 return true; 5193 5194 default: 5195 *mask = 0; 5196 return false; 5197 } 5198 } 5199 5200 /** 5201 * ice_add_special_words - Add words that are not protocols, such as metadata 5202 * @rinfo: other information regarding the rule e.g. priority and action info 5203 * @lkup_exts: lookup word structure 5204 * @dvm_ena: is double VLAN mode enabled 5205 */ 5206 static int 5207 ice_add_special_words(struct ice_adv_rule_info *rinfo, 5208 struct ice_prot_lkup_ext *lkup_exts, bool dvm_ena) 5209 { 5210 u16 mask; 5211 5212 /* If this is a tunneled packet, then add recipe index to match the 5213 * tunnel bit in the packet metadata flags. 5214 */ 5215 if (ice_tun_type_match_word(rinfo->tun_type, &mask)) { 5216 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) { 5217 u8 word = lkup_exts->n_val_words++; 5218 5219 lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW; 5220 lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF; 5221 lkup_exts->field_mask[word] = mask; 5222 } else { 5223 return -ENOSPC; 5224 } 5225 } 5226 5227 if (rinfo->vlan_type != 0 && dvm_ena) { 5228 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) { 5229 u8 word = lkup_exts->n_val_words++; 5230 5231 lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW; 5232 lkup_exts->fv_words[word].off = ICE_VLAN_FLAG_MDID_OFF; 5233 lkup_exts->field_mask[word] = 5234 ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK; 5235 } else { 5236 return -ENOSPC; 5237 } 5238 } 5239 5240 return 0; 5241 } 5242 5243 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule 5244 * @hw: pointer to hardware structure 5245 * @rinfo: other information regarding the rule e.g. priority and action info 5246 * @bm: pointer to memory for returning the bitmap of field vectors 5247 */ 5248 static void 5249 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, 5250 unsigned long *bm) 5251 { 5252 enum ice_prof_type prof_type; 5253 5254 bitmap_zero(bm, ICE_MAX_NUM_PROFILES); 5255 5256 switch (rinfo->tun_type) { 5257 case ICE_NON_TUN: 5258 prof_type = ICE_PROF_NON_TUN; 5259 break; 5260 case ICE_ALL_TUNNELS: 5261 prof_type = ICE_PROF_TUN_ALL; 5262 break; 5263 case ICE_SW_TUN_GENEVE: 5264 case ICE_SW_TUN_VXLAN: 5265 prof_type = ICE_PROF_TUN_UDP; 5266 break; 5267 case ICE_SW_TUN_NVGRE: 5268 prof_type = ICE_PROF_TUN_GRE; 5269 break; 5270 case ICE_SW_TUN_GTPU: 5271 prof_type = ICE_PROF_TUN_GTPU; 5272 break; 5273 case ICE_SW_TUN_GTPC: 5274 prof_type = ICE_PROF_TUN_GTPC; 5275 break; 5276 case ICE_SW_TUN_AND_NON_TUN: 5277 default: 5278 prof_type = ICE_PROF_ALL; 5279 break; 5280 } 5281 5282 ice_get_sw_fv_bitmap(hw, prof_type, bm); 5283 } 5284 5285 /** 5286 * ice_add_adv_recipe - Add an advanced recipe that is not part of the default 5287 * @hw: pointer to hardware structure 5288 * @lkups: lookup elements or match criteria for the advanced recipe, one 5289 * structure per protocol header 5290 * @lkups_cnt: number of protocols 5291 * @rinfo: other information regarding the rule e.g. priority and action info 5292 * @rid: return the recipe ID of the recipe created 5293 */ 5294 static int 5295 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 5296 u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid) 5297 { 5298 DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES); 5299 DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES); 5300 struct ice_prot_lkup_ext *lkup_exts; 5301 struct ice_recp_grp_entry *r_entry; 5302 struct ice_sw_fv_list_entry *fvit; 5303 struct ice_recp_grp_entry *r_tmp; 5304 struct ice_sw_fv_list_entry *tmp; 5305 struct ice_sw_recipe *rm; 5306 int status = 0; 5307 u8 i; 5308 5309 if (!lkups_cnt) 5310 return -EINVAL; 5311 5312 lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL); 5313 if (!lkup_exts) 5314 return -ENOMEM; 5315 5316 /* Determine the number of words to be matched and if it exceeds a 5317 * recipe's restrictions 5318 */ 5319 for (i = 0; i < lkups_cnt; i++) { 5320 u16 count; 5321 5322 if (lkups[i].type >= ICE_PROTOCOL_LAST) { 5323 status = -EIO; 5324 goto err_free_lkup_exts; 5325 } 5326 5327 count = ice_fill_valid_words(&lkups[i], lkup_exts); 5328 if (!count) { 5329 status = -EIO; 5330 goto err_free_lkup_exts; 5331 } 5332 } 5333 5334 rm = kzalloc(sizeof(*rm), GFP_KERNEL); 5335 if (!rm) { 5336 status = -ENOMEM; 5337 goto err_free_lkup_exts; 5338 } 5339 5340 /* Get field vectors that contain fields extracted from all the protocol 5341 * headers being programmed. 5342 */ 5343 INIT_LIST_HEAD(&rm->fv_list); 5344 INIT_LIST_HEAD(&rm->rg_list); 5345 5346 /* Get bitmap of field vectors (profiles) that are compatible with the 5347 * rule request; only these will be searched in the subsequent call to 5348 * ice_get_sw_fv_list. 5349 */ 5350 ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); 5351 5352 status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list); 5353 if (status) 5354 goto err_unroll; 5355 5356 /* Create any special protocol/offset pairs, such as looking at tunnel 5357 * bits by extracting metadata 5358 */ 5359 status = ice_add_special_words(rinfo, lkup_exts, ice_is_dvm_ena(hw)); 5360 if (status) 5361 goto err_free_lkup_exts; 5362 5363 /* Group match words into recipes using preferred recipe grouping 5364 * criteria. 5365 */ 5366 status = ice_create_recipe_group(hw, rm, lkup_exts); 5367 if (status) 5368 goto err_unroll; 5369 5370 /* set the recipe priority if specified */ 5371 rm->priority = (u8)rinfo->priority; 5372 5373 /* Find offsets from the field vector. Pick the first one for all the 5374 * recipes. 5375 */ 5376 status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list); 5377 if (status) 5378 goto err_unroll; 5379 5380 /* get bitmap of all profiles the recipe will be associated with */ 5381 bitmap_zero(profiles, ICE_MAX_NUM_PROFILES); 5382 list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5383 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id); 5384 set_bit((u16)fvit->profile_id, profiles); 5385 } 5386 5387 /* Look for a recipe which matches our requested fv / mask list */ 5388 *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type); 5389 if (*rid < ICE_MAX_NUM_RECIPES) 5390 /* Success if found a recipe that match the existing criteria */ 5391 goto err_unroll; 5392 5393 rm->tun_type = rinfo->tun_type; 5394 /* Recipe we need does not exist, add a recipe */ 5395 status = ice_add_sw_recipe(hw, rm, profiles); 5396 if (status) 5397 goto err_unroll; 5398 5399 /* Associate all the recipes created with all the profiles in the 5400 * common field vector. 5401 */ 5402 list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5403 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); 5404 u16 j; 5405 5406 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id, 5407 (u8 *)r_bitmap, NULL); 5408 if (status) 5409 goto err_unroll; 5410 5411 bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap, 5412 ICE_MAX_NUM_RECIPES); 5413 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5414 if (status) 5415 goto err_unroll; 5416 5417 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id, 5418 (u8 *)r_bitmap, 5419 NULL); 5420 ice_release_change_lock(hw); 5421 5422 if (status) 5423 goto err_unroll; 5424 5425 /* Update profile to recipe bitmap array */ 5426 bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap, 5427 ICE_MAX_NUM_RECIPES); 5428 5429 /* Update recipe to profile bitmap array */ 5430 for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES) 5431 set_bit((u16)fvit->profile_id, recipe_to_profile[j]); 5432 } 5433 5434 *rid = rm->root_rid; 5435 memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts, 5436 sizeof(*lkup_exts)); 5437 err_unroll: 5438 list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) { 5439 list_del(&r_entry->l_entry); 5440 devm_kfree(ice_hw_to_dev(hw), r_entry); 5441 } 5442 5443 list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) { 5444 list_del(&fvit->list_entry); 5445 devm_kfree(ice_hw_to_dev(hw), fvit); 5446 } 5447 5448 if (rm->root_buf) 5449 devm_kfree(ice_hw_to_dev(hw), rm->root_buf); 5450 5451 kfree(rm); 5452 5453 err_free_lkup_exts: 5454 kfree(lkup_exts); 5455 5456 return status; 5457 } 5458 5459 /** 5460 * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt 5461 * 5462 * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added 5463 * @num_vlan: number of VLAN tags 5464 */ 5465 static struct ice_dummy_pkt_profile * 5466 ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt, 5467 u32 num_vlan) 5468 { 5469 struct ice_dummy_pkt_profile *profile; 5470 struct ice_dummy_pkt_offsets *offsets; 5471 u32 buf_len, off, etype_off, i; 5472 u8 *pkt; 5473 5474 if (num_vlan < 1 || num_vlan > 2) 5475 return ERR_PTR(-EINVAL); 5476 5477 off = num_vlan * VLAN_HLEN; 5478 5479 buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) + 5480 dummy_pkt->offsets_len; 5481 offsets = kzalloc(buf_len, GFP_KERNEL); 5482 if (!offsets) 5483 return ERR_PTR(-ENOMEM); 5484 5485 offsets[0] = dummy_pkt->offsets[0]; 5486 if (num_vlan == 2) { 5487 offsets[1] = ice_dummy_qinq_packet_offsets[0]; 5488 offsets[2] = ice_dummy_qinq_packet_offsets[1]; 5489 } else if (num_vlan == 1) { 5490 offsets[1] = ice_dummy_vlan_packet_offsets[0]; 5491 } 5492 5493 for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5494 offsets[i + num_vlan].type = dummy_pkt->offsets[i].type; 5495 offsets[i + num_vlan].offset = 5496 dummy_pkt->offsets[i].offset + off; 5497 } 5498 offsets[i + num_vlan] = dummy_pkt->offsets[i]; 5499 5500 etype_off = dummy_pkt->offsets[1].offset; 5501 5502 buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) + 5503 dummy_pkt->pkt_len; 5504 pkt = kzalloc(buf_len, GFP_KERNEL); 5505 if (!pkt) { 5506 kfree(offsets); 5507 return ERR_PTR(-ENOMEM); 5508 } 5509 5510 memcpy(pkt, dummy_pkt->pkt, etype_off); 5511 memcpy(pkt + etype_off, 5512 num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet, 5513 off); 5514 memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off, 5515 dummy_pkt->pkt_len - etype_off); 5516 5517 profile = kzalloc(sizeof(*profile), GFP_KERNEL); 5518 if (!profile) { 5519 kfree(offsets); 5520 kfree(pkt); 5521 return ERR_PTR(-ENOMEM); 5522 } 5523 5524 profile->offsets = offsets; 5525 profile->pkt = pkt; 5526 profile->pkt_len = buf_len; 5527 profile->match |= ICE_PKT_KMALLOC; 5528 5529 return profile; 5530 } 5531 5532 /** 5533 * ice_find_dummy_packet - find dummy packet 5534 * 5535 * @lkups: lookup elements or match criteria for the advanced recipe, one 5536 * structure per protocol header 5537 * @lkups_cnt: number of protocols 5538 * @tun_type: tunnel type 5539 * 5540 * Returns the &ice_dummy_pkt_profile corresponding to these lookup params. 5541 */ 5542 static const struct ice_dummy_pkt_profile * 5543 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 5544 enum ice_sw_tunnel_type tun_type) 5545 { 5546 const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles; 5547 u32 match = 0, vlan_count = 0; 5548 u16 i; 5549 5550 switch (tun_type) { 5551 case ICE_SW_TUN_GTPC: 5552 match |= ICE_PKT_TUN_GTPC; 5553 break; 5554 case ICE_SW_TUN_GTPU: 5555 match |= ICE_PKT_TUN_GTPU; 5556 break; 5557 case ICE_SW_TUN_NVGRE: 5558 match |= ICE_PKT_TUN_NVGRE; 5559 break; 5560 case ICE_SW_TUN_GENEVE: 5561 case ICE_SW_TUN_VXLAN: 5562 match |= ICE_PKT_TUN_UDP; 5563 break; 5564 default: 5565 break; 5566 } 5567 5568 for (i = 0; i < lkups_cnt; i++) { 5569 if (lkups[i].type == ICE_UDP_ILOS) 5570 match |= ICE_PKT_INNER_UDP; 5571 else if (lkups[i].type == ICE_TCP_IL) 5572 match |= ICE_PKT_INNER_TCP; 5573 else if (lkups[i].type == ICE_IPV6_OFOS) 5574 match |= ICE_PKT_OUTER_IPV6; 5575 else if (lkups[i].type == ICE_VLAN_OFOS || 5576 lkups[i].type == ICE_VLAN_EX) 5577 vlan_count++; 5578 else if (lkups[i].type == ICE_VLAN_IN) 5579 vlan_count++; 5580 else if (lkups[i].type == ICE_ETYPE_OL && 5581 lkups[i].h_u.ethertype.ethtype_id == 5582 cpu_to_be16(ICE_IPV6_ETHER_ID) && 5583 lkups[i].m_u.ethertype.ethtype_id == 5584 cpu_to_be16(0xFFFF)) 5585 match |= ICE_PKT_OUTER_IPV6; 5586 else if (lkups[i].type == ICE_ETYPE_IL && 5587 lkups[i].h_u.ethertype.ethtype_id == 5588 cpu_to_be16(ICE_IPV6_ETHER_ID) && 5589 lkups[i].m_u.ethertype.ethtype_id == 5590 cpu_to_be16(0xFFFF)) 5591 match |= ICE_PKT_INNER_IPV6; 5592 else if (lkups[i].type == ICE_IPV6_IL) 5593 match |= ICE_PKT_INNER_IPV6; 5594 else if (lkups[i].type == ICE_GTP_NO_PAY) 5595 match |= ICE_PKT_GTP_NOPAY; 5596 else if (lkups[i].type == ICE_PPPOE) { 5597 match |= ICE_PKT_PPPOE; 5598 if (lkups[i].h_u.pppoe_hdr.ppp_prot_id == 5599 htons(PPP_IPV6)) 5600 match |= ICE_PKT_OUTER_IPV6; 5601 } 5602 } 5603 5604 while (ret->match && (match & ret->match) != ret->match) 5605 ret++; 5606 5607 if (vlan_count != 0) 5608 ret = ice_dummy_packet_add_vlan(ret, vlan_count); 5609 5610 return ret; 5611 } 5612 5613 /** 5614 * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria 5615 * 5616 * @lkups: lookup elements or match criteria for the advanced recipe, one 5617 * structure per protocol header 5618 * @lkups_cnt: number of protocols 5619 * @s_rule: stores rule information from the match criteria 5620 * @profile: dummy packet profile (the template, its size and header offsets) 5621 */ 5622 static int 5623 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 5624 struct ice_sw_rule_lkup_rx_tx *s_rule, 5625 const struct ice_dummy_pkt_profile *profile) 5626 { 5627 u8 *pkt; 5628 u16 i; 5629 5630 /* Start with a packet with a pre-defined/dummy content. Then, fill 5631 * in the header values to be looked up or matched. 5632 */ 5633 pkt = s_rule->hdr_data; 5634 5635 memcpy(pkt, profile->pkt, profile->pkt_len); 5636 5637 for (i = 0; i < lkups_cnt; i++) { 5638 const struct ice_dummy_pkt_offsets *offsets = profile->offsets; 5639 enum ice_protocol_type type; 5640 u16 offset = 0, len = 0, j; 5641 bool found = false; 5642 5643 /* find the start of this layer; it should be found since this 5644 * was already checked when search for the dummy packet 5645 */ 5646 type = lkups[i].type; 5647 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) { 5648 if (type == offsets[j].type) { 5649 offset = offsets[j].offset; 5650 found = true; 5651 break; 5652 } 5653 } 5654 /* this should never happen in a correct calling sequence */ 5655 if (!found) 5656 return -EINVAL; 5657 5658 switch (lkups[i].type) { 5659 case ICE_MAC_OFOS: 5660 case ICE_MAC_IL: 5661 len = sizeof(struct ice_ether_hdr); 5662 break; 5663 case ICE_ETYPE_OL: 5664 case ICE_ETYPE_IL: 5665 len = sizeof(struct ice_ethtype_hdr); 5666 break; 5667 case ICE_VLAN_OFOS: 5668 case ICE_VLAN_EX: 5669 case ICE_VLAN_IN: 5670 len = sizeof(struct ice_vlan_hdr); 5671 break; 5672 case ICE_IPV4_OFOS: 5673 case ICE_IPV4_IL: 5674 len = sizeof(struct ice_ipv4_hdr); 5675 break; 5676 case ICE_IPV6_OFOS: 5677 case ICE_IPV6_IL: 5678 len = sizeof(struct ice_ipv6_hdr); 5679 break; 5680 case ICE_TCP_IL: 5681 case ICE_UDP_OF: 5682 case ICE_UDP_ILOS: 5683 len = sizeof(struct ice_l4_hdr); 5684 break; 5685 case ICE_SCTP_IL: 5686 len = sizeof(struct ice_sctp_hdr); 5687 break; 5688 case ICE_NVGRE: 5689 len = sizeof(struct ice_nvgre_hdr); 5690 break; 5691 case ICE_VXLAN: 5692 case ICE_GENEVE: 5693 len = sizeof(struct ice_udp_tnl_hdr); 5694 break; 5695 case ICE_GTP_NO_PAY: 5696 case ICE_GTP: 5697 len = sizeof(struct ice_udp_gtp_hdr); 5698 break; 5699 case ICE_PPPOE: 5700 len = sizeof(struct ice_pppoe_hdr); 5701 break; 5702 default: 5703 return -EINVAL; 5704 } 5705 5706 /* the length should be a word multiple */ 5707 if (len % ICE_BYTES_PER_WORD) 5708 return -EIO; 5709 5710 /* We have the offset to the header start, the length, the 5711 * caller's header values and mask. Use this information to 5712 * copy the data into the dummy packet appropriately based on 5713 * the mask. Note that we need to only write the bits as 5714 * indicated by the mask to make sure we don't improperly write 5715 * over any significant packet data. 5716 */ 5717 for (j = 0; j < len / sizeof(u16); j++) { 5718 u16 *ptr = (u16 *)(pkt + offset); 5719 u16 mask = lkups[i].m_raw[j]; 5720 5721 if (!mask) 5722 continue; 5723 5724 ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask); 5725 } 5726 } 5727 5728 s_rule->hdr_len = cpu_to_le16(profile->pkt_len); 5729 5730 return 0; 5731 } 5732 5733 /** 5734 * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port 5735 * @hw: pointer to the hardware structure 5736 * @tun_type: tunnel type 5737 * @pkt: dummy packet to fill in 5738 * @offsets: offset info for the dummy packet 5739 */ 5740 static int 5741 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type, 5742 u8 *pkt, const struct ice_dummy_pkt_offsets *offsets) 5743 { 5744 u16 open_port, i; 5745 5746 switch (tun_type) { 5747 case ICE_SW_TUN_VXLAN: 5748 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN)) 5749 return -EIO; 5750 break; 5751 case ICE_SW_TUN_GENEVE: 5752 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE)) 5753 return -EIO; 5754 break; 5755 default: 5756 /* Nothing needs to be done for this tunnel type */ 5757 return 0; 5758 } 5759 5760 /* Find the outer UDP protocol header and insert the port number */ 5761 for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5762 if (offsets[i].type == ICE_UDP_OF) { 5763 struct ice_l4_hdr *hdr; 5764 u16 offset; 5765 5766 offset = offsets[i].offset; 5767 hdr = (struct ice_l4_hdr *)&pkt[offset]; 5768 hdr->dst_port = cpu_to_be16(open_port); 5769 5770 return 0; 5771 } 5772 } 5773 5774 return -EIO; 5775 } 5776 5777 /** 5778 * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type 5779 * @vlan_type: VLAN tag type 5780 * @pkt: dummy packet to fill in 5781 * @offsets: offset info for the dummy packet 5782 */ 5783 static int 5784 ice_fill_adv_packet_vlan(u16 vlan_type, u8 *pkt, 5785 const struct ice_dummy_pkt_offsets *offsets) 5786 { 5787 u16 i; 5788 5789 /* Find VLAN header and insert VLAN TPID */ 5790 for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5791 if (offsets[i].type == ICE_VLAN_OFOS || 5792 offsets[i].type == ICE_VLAN_EX) { 5793 struct ice_vlan_hdr *hdr; 5794 u16 offset; 5795 5796 offset = offsets[i].offset; 5797 hdr = (struct ice_vlan_hdr *)&pkt[offset]; 5798 hdr->type = cpu_to_be16(vlan_type); 5799 5800 return 0; 5801 } 5802 } 5803 5804 return -EIO; 5805 } 5806 5807 /** 5808 * ice_find_adv_rule_entry - Search a rule entry 5809 * @hw: pointer to the hardware structure 5810 * @lkups: lookup elements or match criteria for the advanced recipe, one 5811 * structure per protocol header 5812 * @lkups_cnt: number of protocols 5813 * @recp_id: recipe ID for which we are finding the rule 5814 * @rinfo: other information regarding the rule e.g. priority and action info 5815 * 5816 * Helper function to search for a given advance rule entry 5817 * Returns pointer to entry storing the rule if found 5818 */ 5819 static struct ice_adv_fltr_mgmt_list_entry * 5820 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 5821 u16 lkups_cnt, u16 recp_id, 5822 struct ice_adv_rule_info *rinfo) 5823 { 5824 struct ice_adv_fltr_mgmt_list_entry *list_itr; 5825 struct ice_switch_info *sw = hw->switch_info; 5826 int i; 5827 5828 list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules, 5829 list_entry) { 5830 bool lkups_matched = true; 5831 5832 if (lkups_cnt != list_itr->lkups_cnt) 5833 continue; 5834 for (i = 0; i < list_itr->lkups_cnt; i++) 5835 if (memcmp(&list_itr->lkups[i], &lkups[i], 5836 sizeof(*lkups))) { 5837 lkups_matched = false; 5838 break; 5839 } 5840 if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag && 5841 rinfo->tun_type == list_itr->rule_info.tun_type && 5842 rinfo->vlan_type == list_itr->rule_info.vlan_type && 5843 lkups_matched) 5844 return list_itr; 5845 } 5846 return NULL; 5847 } 5848 5849 /** 5850 * ice_adv_add_update_vsi_list 5851 * @hw: pointer to the hardware structure 5852 * @m_entry: pointer to current adv filter management list entry 5853 * @cur_fltr: filter information from the book keeping entry 5854 * @new_fltr: filter information with the new VSI to be added 5855 * 5856 * Call AQ command to add or update previously created VSI list with new VSI. 5857 * 5858 * Helper function to do book keeping associated with adding filter information 5859 * The algorithm to do the booking keeping is described below : 5860 * When a VSI needs to subscribe to a given advanced filter 5861 * if only one VSI has been added till now 5862 * Allocate a new VSI list and add two VSIs 5863 * to this list using switch rule command 5864 * Update the previously created switch rule with the 5865 * newly created VSI list ID 5866 * if a VSI list was previously created 5867 * Add the new VSI to the previously created VSI list set 5868 * using the update switch rule command 5869 */ 5870 static int 5871 ice_adv_add_update_vsi_list(struct ice_hw *hw, 5872 struct ice_adv_fltr_mgmt_list_entry *m_entry, 5873 struct ice_adv_rule_info *cur_fltr, 5874 struct ice_adv_rule_info *new_fltr) 5875 { 5876 u16 vsi_list_id = 0; 5877 int status; 5878 5879 if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 5880 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP || 5881 cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET) 5882 return -EOPNOTSUPP; 5883 5884 if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 5885 new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) && 5886 (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI || 5887 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST)) 5888 return -EOPNOTSUPP; 5889 5890 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 5891 /* Only one entry existed in the mapping and it was not already 5892 * a part of a VSI list. So, create a VSI list with the old and 5893 * new VSIs. 5894 */ 5895 struct ice_fltr_info tmp_fltr; 5896 u16 vsi_handle_arr[2]; 5897 5898 /* A rule already exists with the new VSI being added */ 5899 if (cur_fltr->sw_act.fwd_id.hw_vsi_id == 5900 new_fltr->sw_act.fwd_id.hw_vsi_id) 5901 return -EEXIST; 5902 5903 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle; 5904 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle; 5905 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 5906 &vsi_list_id, 5907 ICE_SW_LKUP_LAST); 5908 if (status) 5909 return status; 5910 5911 memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 5912 tmp_fltr.flag = m_entry->rule_info.sw_act.flag; 5913 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 5914 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 5915 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 5916 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST; 5917 5918 /* Update the previous switch rule of "forward to VSI" to 5919 * "fwd to VSI list" 5920 */ 5921 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 5922 if (status) 5923 return status; 5924 5925 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id; 5926 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST; 5927 m_entry->vsi_list_info = 5928 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 5929 vsi_list_id); 5930 } else { 5931 u16 vsi_handle = new_fltr->sw_act.vsi_handle; 5932 5933 if (!m_entry->vsi_list_info) 5934 return -EIO; 5935 5936 /* A rule already exists with the new VSI being added */ 5937 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) 5938 return 0; 5939 5940 /* Update the previously created VSI list set with 5941 * the new VSI ID passed in 5942 */ 5943 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id; 5944 5945 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 5946 vsi_list_id, false, 5947 ice_aqc_opc_update_sw_rules, 5948 ICE_SW_LKUP_LAST); 5949 /* update VSI list mapping info with new VSI ID */ 5950 if (!status) 5951 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map); 5952 } 5953 if (!status) 5954 m_entry->vsi_count++; 5955 return status; 5956 } 5957 5958 /** 5959 * ice_add_adv_rule - helper function to create an advanced switch rule 5960 * @hw: pointer to the hardware structure 5961 * @lkups: information on the words that needs to be looked up. All words 5962 * together makes one recipe 5963 * @lkups_cnt: num of entries in the lkups array 5964 * @rinfo: other information related to the rule that needs to be programmed 5965 * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be 5966 * ignored is case of error. 5967 * 5968 * This function can program only 1 rule at a time. The lkups is used to 5969 * describe the all the words that forms the "lookup" portion of the recipe. 5970 * These words can span multiple protocols. Callers to this function need to 5971 * pass in a list of protocol headers with lookup information along and mask 5972 * that determines which words are valid from the given protocol header. 5973 * rinfo describes other information related to this rule such as forwarding 5974 * IDs, priority of this rule, etc. 5975 */ 5976 int 5977 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 5978 u16 lkups_cnt, struct ice_adv_rule_info *rinfo, 5979 struct ice_rule_query_data *added_entry) 5980 { 5981 struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL; 5982 struct ice_sw_rule_lkup_rx_tx *s_rule = NULL; 5983 const struct ice_dummy_pkt_profile *profile; 5984 u16 rid = 0, i, rule_buf_sz, vsi_handle; 5985 struct list_head *rule_head; 5986 struct ice_switch_info *sw; 5987 u16 word_cnt; 5988 u32 act = 0; 5989 int status; 5990 u8 q_rgn; 5991 5992 /* Initialize profile to result index bitmap */ 5993 if (!hw->switch_info->prof_res_bm_init) { 5994 hw->switch_info->prof_res_bm_init = 1; 5995 ice_init_prof_result_bm(hw); 5996 } 5997 5998 if (!lkups_cnt) 5999 return -EINVAL; 6000 6001 /* get # of words we need to match */ 6002 word_cnt = 0; 6003 for (i = 0; i < lkups_cnt; i++) { 6004 u16 j; 6005 6006 for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++) 6007 if (lkups[i].m_raw[j]) 6008 word_cnt++; 6009 } 6010 6011 if (!word_cnt) 6012 return -EINVAL; 6013 6014 if (word_cnt > ICE_MAX_CHAIN_WORDS) 6015 return -ENOSPC; 6016 6017 /* locate a dummy packet */ 6018 profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type); 6019 if (IS_ERR(profile)) 6020 return PTR_ERR(profile); 6021 6022 if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI || 6023 rinfo->sw_act.fltr_act == ICE_FWD_TO_Q || 6024 rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP || 6025 rinfo->sw_act.fltr_act == ICE_DROP_PACKET)) { 6026 status = -EIO; 6027 goto free_pkt_profile; 6028 } 6029 6030 vsi_handle = rinfo->sw_act.vsi_handle; 6031 if (!ice_is_vsi_valid(hw, vsi_handle)) { 6032 status = -EINVAL; 6033 goto free_pkt_profile; 6034 } 6035 6036 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 6037 rinfo->sw_act.fwd_id.hw_vsi_id = 6038 ice_get_hw_vsi_num(hw, vsi_handle); 6039 if (rinfo->sw_act.flag & ICE_FLTR_TX) 6040 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle); 6041 6042 status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid); 6043 if (status) 6044 goto free_pkt_profile; 6045 m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 6046 if (m_entry) { 6047 /* we have to add VSI to VSI_LIST and increment vsi_count. 6048 * Also Update VSI list so that we can change forwarding rule 6049 * if the rule already exists, we will check if it exists with 6050 * same vsi_id, if not then add it to the VSI list if it already 6051 * exists if not then create a VSI list and add the existing VSI 6052 * ID and the new VSI ID to the list 6053 * We will add that VSI to the list 6054 */ 6055 status = ice_adv_add_update_vsi_list(hw, m_entry, 6056 &m_entry->rule_info, 6057 rinfo); 6058 if (added_entry) { 6059 added_entry->rid = rid; 6060 added_entry->rule_id = m_entry->rule_info.fltr_rule_id; 6061 added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 6062 } 6063 goto free_pkt_profile; 6064 } 6065 rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len); 6066 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 6067 if (!s_rule) { 6068 status = -ENOMEM; 6069 goto free_pkt_profile; 6070 } 6071 if (!rinfo->flags_info.act_valid) { 6072 act |= ICE_SINGLE_ACT_LAN_ENABLE; 6073 act |= ICE_SINGLE_ACT_LB_ENABLE; 6074 } else { 6075 act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE | 6076 ICE_SINGLE_ACT_LB_ENABLE); 6077 } 6078 6079 switch (rinfo->sw_act.fltr_act) { 6080 case ICE_FWD_TO_VSI: 6081 act |= (rinfo->sw_act.fwd_id.hw_vsi_id << 6082 ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M; 6083 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT; 6084 break; 6085 case ICE_FWD_TO_Q: 6086 act |= ICE_SINGLE_ACT_TO_Q; 6087 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 6088 ICE_SINGLE_ACT_Q_INDEX_M; 6089 break; 6090 case ICE_FWD_TO_QGRP: 6091 q_rgn = rinfo->sw_act.qgrp_size > 0 ? 6092 (u8)ilog2(rinfo->sw_act.qgrp_size) : 0; 6093 act |= ICE_SINGLE_ACT_TO_Q; 6094 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 6095 ICE_SINGLE_ACT_Q_INDEX_M; 6096 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 6097 ICE_SINGLE_ACT_Q_REGION_M; 6098 break; 6099 case ICE_DROP_PACKET: 6100 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 6101 ICE_SINGLE_ACT_VALID_BIT; 6102 break; 6103 default: 6104 status = -EIO; 6105 goto err_ice_add_adv_rule; 6106 } 6107 6108 /* set the rule LOOKUP type based on caller specified 'Rx' 6109 * instead of hardcoding it to be either LOOKUP_TX/RX 6110 * 6111 * for 'Rx' set the source to be the port number 6112 * for 'Tx' set the source to be the source HW VSI number (determined 6113 * by caller) 6114 */ 6115 if (rinfo->rx) { 6116 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX); 6117 s_rule->src = cpu_to_le16(hw->port_info->lport); 6118 } else { 6119 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 6120 s_rule->src = cpu_to_le16(rinfo->sw_act.src); 6121 } 6122 6123 s_rule->recipe_id = cpu_to_le16(rid); 6124 s_rule->act = cpu_to_le32(act); 6125 6126 status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile); 6127 if (status) 6128 goto err_ice_add_adv_rule; 6129 6130 if (rinfo->tun_type != ICE_NON_TUN && 6131 rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) { 6132 status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, 6133 s_rule->hdr_data, 6134 profile->offsets); 6135 if (status) 6136 goto err_ice_add_adv_rule; 6137 } 6138 6139 if (rinfo->vlan_type != 0 && ice_is_dvm_ena(hw)) { 6140 status = ice_fill_adv_packet_vlan(rinfo->vlan_type, 6141 s_rule->hdr_data, 6142 profile->offsets); 6143 if (status) 6144 goto err_ice_add_adv_rule; 6145 } 6146 6147 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 6148 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules, 6149 NULL); 6150 if (status) 6151 goto err_ice_add_adv_rule; 6152 adv_fltr = devm_kzalloc(ice_hw_to_dev(hw), 6153 sizeof(struct ice_adv_fltr_mgmt_list_entry), 6154 GFP_KERNEL); 6155 if (!adv_fltr) { 6156 status = -ENOMEM; 6157 goto err_ice_add_adv_rule; 6158 } 6159 6160 adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups, 6161 lkups_cnt * sizeof(*lkups), GFP_KERNEL); 6162 if (!adv_fltr->lkups) { 6163 status = -ENOMEM; 6164 goto err_ice_add_adv_rule; 6165 } 6166 6167 adv_fltr->lkups_cnt = lkups_cnt; 6168 adv_fltr->rule_info = *rinfo; 6169 adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index); 6170 sw = hw->switch_info; 6171 sw->recp_list[rid].adv_rule = true; 6172 rule_head = &sw->recp_list[rid].filt_rules; 6173 6174 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 6175 adv_fltr->vsi_count = 1; 6176 6177 /* Add rule entry to book keeping list */ 6178 list_add(&adv_fltr->list_entry, rule_head); 6179 if (added_entry) { 6180 added_entry->rid = rid; 6181 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id; 6182 added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 6183 } 6184 err_ice_add_adv_rule: 6185 if (status && adv_fltr) { 6186 devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups); 6187 devm_kfree(ice_hw_to_dev(hw), adv_fltr); 6188 } 6189 6190 kfree(s_rule); 6191 6192 free_pkt_profile: 6193 if (profile->match & ICE_PKT_KMALLOC) { 6194 kfree(profile->offsets); 6195 kfree(profile->pkt); 6196 kfree(profile); 6197 } 6198 6199 return status; 6200 } 6201 6202 /** 6203 * ice_replay_vsi_fltr - Replay filters for requested VSI 6204 * @hw: pointer to the hardware structure 6205 * @vsi_handle: driver VSI handle 6206 * @recp_id: Recipe ID for which rules need to be replayed 6207 * @list_head: list for which filters need to be replayed 6208 * 6209 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. 6210 * It is required to pass valid VSI handle. 6211 */ 6212 static int 6213 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, 6214 struct list_head *list_head) 6215 { 6216 struct ice_fltr_mgmt_list_entry *itr; 6217 int status = 0; 6218 u16 hw_vsi_id; 6219 6220 if (list_empty(list_head)) 6221 return status; 6222 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 6223 6224 list_for_each_entry(itr, list_head, list_entry) { 6225 struct ice_fltr_list_entry f_entry; 6226 6227 f_entry.fltr_info = itr->fltr_info; 6228 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN && 6229 itr->fltr_info.vsi_handle == vsi_handle) { 6230 /* update the src in case it is VSI num */ 6231 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6232 f_entry.fltr_info.src = hw_vsi_id; 6233 status = ice_add_rule_internal(hw, recp_id, &f_entry); 6234 if (status) 6235 goto end; 6236 continue; 6237 } 6238 if (!itr->vsi_list_info || 6239 !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) 6240 continue; 6241 /* Clearing it so that the logic can add it back */ 6242 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 6243 f_entry.fltr_info.vsi_handle = vsi_handle; 6244 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 6245 /* update the src in case it is VSI num */ 6246 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6247 f_entry.fltr_info.src = hw_vsi_id; 6248 if (recp_id == ICE_SW_LKUP_VLAN) 6249 status = ice_add_vlan_internal(hw, &f_entry); 6250 else 6251 status = ice_add_rule_internal(hw, recp_id, &f_entry); 6252 if (status) 6253 goto end; 6254 } 6255 end: 6256 return status; 6257 } 6258 6259 /** 6260 * ice_adv_rem_update_vsi_list 6261 * @hw: pointer to the hardware structure 6262 * @vsi_handle: VSI handle of the VSI to remove 6263 * @fm_list: filter management entry for which the VSI list management needs to 6264 * be done 6265 */ 6266 static int 6267 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 6268 struct ice_adv_fltr_mgmt_list_entry *fm_list) 6269 { 6270 struct ice_vsi_list_map_info *vsi_list_info; 6271 enum ice_sw_lkup_type lkup_type; 6272 u16 vsi_list_id; 6273 int status; 6274 6275 if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST || 6276 fm_list->vsi_count == 0) 6277 return -EINVAL; 6278 6279 /* A rule with the VSI being removed does not exist */ 6280 if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map)) 6281 return -ENOENT; 6282 6283 lkup_type = ICE_SW_LKUP_LAST; 6284 vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id; 6285 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 6286 ice_aqc_opc_update_sw_rules, 6287 lkup_type); 6288 if (status) 6289 return status; 6290 6291 fm_list->vsi_count--; 6292 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 6293 vsi_list_info = fm_list->vsi_list_info; 6294 if (fm_list->vsi_count == 1) { 6295 struct ice_fltr_info tmp_fltr; 6296 u16 rem_vsi_handle; 6297 6298 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map, 6299 ICE_MAX_VSI); 6300 if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 6301 return -EIO; 6302 6303 /* Make sure VSI list is empty before removing it below */ 6304 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 6305 vsi_list_id, true, 6306 ice_aqc_opc_update_sw_rules, 6307 lkup_type); 6308 if (status) 6309 return status; 6310 6311 memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 6312 tmp_fltr.flag = fm_list->rule_info.sw_act.flag; 6313 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id; 6314 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI; 6315 tmp_fltr.fltr_act = ICE_FWD_TO_VSI; 6316 tmp_fltr.fwd_id.hw_vsi_id = 6317 ice_get_hw_vsi_num(hw, rem_vsi_handle); 6318 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id = 6319 ice_get_hw_vsi_num(hw, rem_vsi_handle); 6320 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle; 6321 6322 /* Update the previous switch rule of "MAC forward to VSI" to 6323 * "MAC fwd to VSI list" 6324 */ 6325 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 6326 if (status) { 6327 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 6328 tmp_fltr.fwd_id.hw_vsi_id, status); 6329 return status; 6330 } 6331 fm_list->vsi_list_info->ref_cnt--; 6332 6333 /* Remove the VSI list since it is no longer used */ 6334 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 6335 if (status) { 6336 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 6337 vsi_list_id, status); 6338 return status; 6339 } 6340 6341 list_del(&vsi_list_info->list_entry); 6342 devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 6343 fm_list->vsi_list_info = NULL; 6344 } 6345 6346 return status; 6347 } 6348 6349 /** 6350 * ice_rem_adv_rule - removes existing advanced switch rule 6351 * @hw: pointer to the hardware structure 6352 * @lkups: information on the words that needs to be looked up. All words 6353 * together makes one recipe 6354 * @lkups_cnt: num of entries in the lkups array 6355 * @rinfo: Its the pointer to the rule information for the rule 6356 * 6357 * This function can be used to remove 1 rule at a time. The lkups is 6358 * used to describe all the words that forms the "lookup" portion of the 6359 * rule. These words can span multiple protocols. Callers to this function 6360 * need to pass in a list of protocol headers with lookup information along 6361 * and mask that determines which words are valid from the given protocol 6362 * header. rinfo describes other information related to this rule such as 6363 * forwarding IDs, priority of this rule, etc. 6364 */ 6365 static int 6366 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 6367 u16 lkups_cnt, struct ice_adv_rule_info *rinfo) 6368 { 6369 struct ice_adv_fltr_mgmt_list_entry *list_elem; 6370 struct ice_prot_lkup_ext lkup_exts; 6371 bool remove_rule = false; 6372 struct mutex *rule_lock; /* Lock to protect filter rule list */ 6373 u16 i, rid, vsi_handle; 6374 int status = 0; 6375 6376 memset(&lkup_exts, 0, sizeof(lkup_exts)); 6377 for (i = 0; i < lkups_cnt; i++) { 6378 u16 count; 6379 6380 if (lkups[i].type >= ICE_PROTOCOL_LAST) 6381 return -EIO; 6382 6383 count = ice_fill_valid_words(&lkups[i], &lkup_exts); 6384 if (!count) 6385 return -EIO; 6386 } 6387 6388 /* Create any special protocol/offset pairs, such as looking at tunnel 6389 * bits by extracting metadata 6390 */ 6391 status = ice_add_special_words(rinfo, &lkup_exts, ice_is_dvm_ena(hw)); 6392 if (status) 6393 return status; 6394 6395 rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type); 6396 /* If did not find a recipe that match the existing criteria */ 6397 if (rid == ICE_MAX_NUM_RECIPES) 6398 return -EINVAL; 6399 6400 rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock; 6401 list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 6402 /* the rule is already removed */ 6403 if (!list_elem) 6404 return 0; 6405 mutex_lock(rule_lock); 6406 if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) { 6407 remove_rule = true; 6408 } else if (list_elem->vsi_count > 1) { 6409 remove_rule = false; 6410 vsi_handle = rinfo->sw_act.vsi_handle; 6411 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 6412 } else { 6413 vsi_handle = rinfo->sw_act.vsi_handle; 6414 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 6415 if (status) { 6416 mutex_unlock(rule_lock); 6417 return status; 6418 } 6419 if (list_elem->vsi_count == 0) 6420 remove_rule = true; 6421 } 6422 mutex_unlock(rule_lock); 6423 if (remove_rule) { 6424 struct ice_sw_rule_lkup_rx_tx *s_rule; 6425 u16 rule_buf_sz; 6426 6427 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule); 6428 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 6429 if (!s_rule) 6430 return -ENOMEM; 6431 s_rule->act = 0; 6432 s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id); 6433 s_rule->hdr_len = 0; 6434 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 6435 rule_buf_sz, 1, 6436 ice_aqc_opc_remove_sw_rules, NULL); 6437 if (!status || status == -ENOENT) { 6438 struct ice_switch_info *sw = hw->switch_info; 6439 6440 mutex_lock(rule_lock); 6441 list_del(&list_elem->list_entry); 6442 devm_kfree(ice_hw_to_dev(hw), list_elem->lkups); 6443 devm_kfree(ice_hw_to_dev(hw), list_elem); 6444 mutex_unlock(rule_lock); 6445 if (list_empty(&sw->recp_list[rid].filt_rules)) 6446 sw->recp_list[rid].adv_rule = false; 6447 } 6448 kfree(s_rule); 6449 } 6450 return status; 6451 } 6452 6453 /** 6454 * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID 6455 * @hw: pointer to the hardware structure 6456 * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID 6457 * 6458 * This function is used to remove 1 rule at a time. The removal is based on 6459 * the remove_entry parameter. This function will remove rule for a given 6460 * vsi_handle with a given rule_id which is passed as parameter in remove_entry 6461 */ 6462 int 6463 ice_rem_adv_rule_by_id(struct ice_hw *hw, 6464 struct ice_rule_query_data *remove_entry) 6465 { 6466 struct ice_adv_fltr_mgmt_list_entry *list_itr; 6467 struct list_head *list_head; 6468 struct ice_adv_rule_info rinfo; 6469 struct ice_switch_info *sw; 6470 6471 sw = hw->switch_info; 6472 if (!sw->recp_list[remove_entry->rid].recp_created) 6473 return -EINVAL; 6474 list_head = &sw->recp_list[remove_entry->rid].filt_rules; 6475 list_for_each_entry(list_itr, list_head, list_entry) { 6476 if (list_itr->rule_info.fltr_rule_id == 6477 remove_entry->rule_id) { 6478 rinfo = list_itr->rule_info; 6479 rinfo.sw_act.vsi_handle = remove_entry->vsi_handle; 6480 return ice_rem_adv_rule(hw, list_itr->lkups, 6481 list_itr->lkups_cnt, &rinfo); 6482 } 6483 } 6484 /* either list is empty or unable to find rule */ 6485 return -ENOENT; 6486 } 6487 6488 /** 6489 * ice_rem_adv_rule_for_vsi - removes existing advanced switch rules for a 6490 * given VSI handle 6491 * @hw: pointer to the hardware structure 6492 * @vsi_handle: VSI handle for which we are supposed to remove all the rules. 6493 * 6494 * This function is used to remove all the rules for a given VSI and as soon 6495 * as removing a rule fails, it will return immediately with the error code, 6496 * else it will return success. 6497 */ 6498 int ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle) 6499 { 6500 struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry; 6501 struct ice_vsi_list_map_info *map_info; 6502 struct ice_adv_rule_info rinfo; 6503 struct list_head *list_head; 6504 struct ice_switch_info *sw; 6505 int status; 6506 u8 rid; 6507 6508 sw = hw->switch_info; 6509 for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) { 6510 if (!sw->recp_list[rid].recp_created) 6511 continue; 6512 if (!sw->recp_list[rid].adv_rule) 6513 continue; 6514 6515 list_head = &sw->recp_list[rid].filt_rules; 6516 list_for_each_entry_safe(list_itr, tmp_entry, list_head, 6517 list_entry) { 6518 rinfo = list_itr->rule_info; 6519 6520 if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) { 6521 map_info = list_itr->vsi_list_info; 6522 if (!map_info) 6523 continue; 6524 6525 if (!test_bit(vsi_handle, map_info->vsi_map)) 6526 continue; 6527 } else if (rinfo.sw_act.vsi_handle != vsi_handle) { 6528 continue; 6529 } 6530 6531 rinfo.sw_act.vsi_handle = vsi_handle; 6532 status = ice_rem_adv_rule(hw, list_itr->lkups, 6533 list_itr->lkups_cnt, &rinfo); 6534 if (status) 6535 return status; 6536 } 6537 } 6538 return 0; 6539 } 6540 6541 /** 6542 * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI 6543 * @hw: pointer to the hardware structure 6544 * @vsi_handle: driver VSI handle 6545 * @list_head: list for which filters need to be replayed 6546 * 6547 * Replay the advanced rule for the given VSI. 6548 */ 6549 static int 6550 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle, 6551 struct list_head *list_head) 6552 { 6553 struct ice_rule_query_data added_entry = { 0 }; 6554 struct ice_adv_fltr_mgmt_list_entry *adv_fltr; 6555 int status = 0; 6556 6557 if (list_empty(list_head)) 6558 return status; 6559 list_for_each_entry(adv_fltr, list_head, list_entry) { 6560 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info; 6561 u16 lk_cnt = adv_fltr->lkups_cnt; 6562 6563 if (vsi_handle != rinfo->sw_act.vsi_handle) 6564 continue; 6565 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo, 6566 &added_entry); 6567 if (status) 6568 break; 6569 } 6570 return status; 6571 } 6572 6573 /** 6574 * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists 6575 * @hw: pointer to the hardware structure 6576 * @vsi_handle: driver VSI handle 6577 * 6578 * Replays filters for requested VSI via vsi_handle. 6579 */ 6580 int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle) 6581 { 6582 struct ice_switch_info *sw = hw->switch_info; 6583 int status; 6584 u8 i; 6585 6586 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6587 struct list_head *head; 6588 6589 head = &sw->recp_list[i].filt_replay_rules; 6590 if (!sw->recp_list[i].adv_rule) 6591 status = ice_replay_vsi_fltr(hw, vsi_handle, i, head); 6592 else 6593 status = ice_replay_vsi_adv_rule(hw, vsi_handle, head); 6594 if (status) 6595 return status; 6596 } 6597 return status; 6598 } 6599 6600 /** 6601 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules 6602 * @hw: pointer to the HW struct 6603 * 6604 * Deletes the filter replay rules. 6605 */ 6606 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) 6607 { 6608 struct ice_switch_info *sw = hw->switch_info; 6609 u8 i; 6610 6611 if (!sw) 6612 return; 6613 6614 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6615 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) { 6616 struct list_head *l_head; 6617 6618 l_head = &sw->recp_list[i].filt_replay_rules; 6619 if (!sw->recp_list[i].adv_rule) 6620 ice_rem_sw_rule_info(hw, l_head); 6621 else 6622 ice_rem_adv_rule_info(hw, l_head); 6623 } 6624 } 6625 } 6626