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