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