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 vlan_id = list_itr->fltr_info.l_data.vlan.vlan_id; 4449 if (rm_vlan_promisc) 4450 status = ice_clear_vsi_promisc(hw, vsi_handle, 4451 promisc_mask, vlan_id); 4452 else 4453 status = ice_set_vsi_promisc(hw, vsi_handle, 4454 promisc_mask, vlan_id); 4455 if (status) 4456 break; 4457 } 4458 4459 free_fltr_list: 4460 list_for_each_entry_safe(list_itr, tmp, &vsi_list_head, list_entry) { 4461 list_del(&list_itr->list_entry); 4462 devm_kfree(ice_hw_to_dev(hw), list_itr); 4463 } 4464 return status; 4465 } 4466 4467 /** 4468 * ice_remove_vsi_lkup_fltr - Remove lookup type filters for a VSI 4469 * @hw: pointer to the hardware structure 4470 * @vsi_handle: VSI handle to remove filters from 4471 * @lkup: switch rule filter lookup type 4472 */ 4473 static void 4474 ice_remove_vsi_lkup_fltr(struct ice_hw *hw, u16 vsi_handle, 4475 enum ice_sw_lkup_type lkup) 4476 { 4477 struct ice_switch_info *sw = hw->switch_info; 4478 struct ice_fltr_list_entry *fm_entry; 4479 struct list_head remove_list_head; 4480 struct list_head *rule_head; 4481 struct ice_fltr_list_entry *tmp; 4482 struct mutex *rule_lock; /* Lock to protect filter rule list */ 4483 int status; 4484 4485 INIT_LIST_HEAD(&remove_list_head); 4486 rule_lock = &sw->recp_list[lkup].filt_rule_lock; 4487 rule_head = &sw->recp_list[lkup].filt_rules; 4488 mutex_lock(rule_lock); 4489 status = ice_add_to_vsi_fltr_list(hw, vsi_handle, rule_head, 4490 &remove_list_head); 4491 mutex_unlock(rule_lock); 4492 if (status) 4493 goto free_fltr_list; 4494 4495 switch (lkup) { 4496 case ICE_SW_LKUP_MAC: 4497 ice_remove_mac(hw, &remove_list_head); 4498 break; 4499 case ICE_SW_LKUP_VLAN: 4500 ice_remove_vlan(hw, &remove_list_head); 4501 break; 4502 case ICE_SW_LKUP_PROMISC: 4503 case ICE_SW_LKUP_PROMISC_VLAN: 4504 ice_remove_promisc(hw, lkup, &remove_list_head); 4505 break; 4506 case ICE_SW_LKUP_MAC_VLAN: 4507 case ICE_SW_LKUP_ETHERTYPE: 4508 case ICE_SW_LKUP_ETHERTYPE_MAC: 4509 case ICE_SW_LKUP_DFLT: 4510 case ICE_SW_LKUP_LAST: 4511 default: 4512 ice_debug(hw, ICE_DBG_SW, "Unsupported lookup type %d\n", lkup); 4513 break; 4514 } 4515 4516 free_fltr_list: 4517 list_for_each_entry_safe(fm_entry, tmp, &remove_list_head, list_entry) { 4518 list_del(&fm_entry->list_entry); 4519 devm_kfree(ice_hw_to_dev(hw), fm_entry); 4520 } 4521 } 4522 4523 /** 4524 * ice_remove_vsi_fltr - Remove all filters for a VSI 4525 * @hw: pointer to the hardware structure 4526 * @vsi_handle: VSI handle to remove filters from 4527 */ 4528 void ice_remove_vsi_fltr(struct ice_hw *hw, u16 vsi_handle) 4529 { 4530 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC); 4531 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_MAC_VLAN); 4532 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC); 4533 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_VLAN); 4534 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_DFLT); 4535 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE); 4536 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_ETHERTYPE_MAC); 4537 ice_remove_vsi_lkup_fltr(hw, vsi_handle, ICE_SW_LKUP_PROMISC_VLAN); 4538 } 4539 4540 /** 4541 * ice_alloc_res_cntr - allocating resource counter 4542 * @hw: pointer to the hardware structure 4543 * @type: type of resource 4544 * @alloc_shared: if set it is shared else dedicated 4545 * @num_items: number of entries requested for FD resource type 4546 * @counter_id: counter index returned by AQ call 4547 */ 4548 int 4549 ice_alloc_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4550 u16 *counter_id) 4551 { 4552 struct ice_aqc_alloc_free_res_elem *buf; 4553 u16 buf_len; 4554 int status; 4555 4556 /* Allocate resource */ 4557 buf_len = struct_size(buf, elem, 1); 4558 buf = kzalloc(buf_len, GFP_KERNEL); 4559 if (!buf) 4560 return -ENOMEM; 4561 4562 buf->num_elems = cpu_to_le16(num_items); 4563 buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4564 ICE_AQC_RES_TYPE_M) | alloc_shared); 4565 4566 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 4567 ice_aqc_opc_alloc_res, NULL); 4568 if (status) 4569 goto exit; 4570 4571 *counter_id = le16_to_cpu(buf->elem[0].e.sw_resp); 4572 4573 exit: 4574 kfree(buf); 4575 return status; 4576 } 4577 4578 /** 4579 * ice_free_res_cntr - free resource counter 4580 * @hw: pointer to the hardware structure 4581 * @type: type of resource 4582 * @alloc_shared: if set it is shared else dedicated 4583 * @num_items: number of entries to be freed for FD resource type 4584 * @counter_id: counter ID resource which needs to be freed 4585 */ 4586 int 4587 ice_free_res_cntr(struct ice_hw *hw, u8 type, u8 alloc_shared, u16 num_items, 4588 u16 counter_id) 4589 { 4590 struct ice_aqc_alloc_free_res_elem *buf; 4591 u16 buf_len; 4592 int status; 4593 4594 /* Free resource */ 4595 buf_len = struct_size(buf, elem, 1); 4596 buf = kzalloc(buf_len, GFP_KERNEL); 4597 if (!buf) 4598 return -ENOMEM; 4599 4600 buf->num_elems = cpu_to_le16(num_items); 4601 buf->res_type = cpu_to_le16(((type << ICE_AQC_RES_TYPE_S) & 4602 ICE_AQC_RES_TYPE_M) | alloc_shared); 4603 buf->elem[0].e.sw_resp = cpu_to_le16(counter_id); 4604 4605 status = ice_aq_alloc_free_res(hw, 1, buf, buf_len, 4606 ice_aqc_opc_free_res, NULL); 4607 if (status) 4608 ice_debug(hw, ICE_DBG_SW, "counter resource could not be freed\n"); 4609 4610 kfree(buf); 4611 return status; 4612 } 4613 4614 /* This is mapping table entry that maps every word within a given protocol 4615 * structure to the real byte offset as per the specification of that 4616 * protocol header. 4617 * for example dst address is 3 words in ethertype header and corresponding 4618 * bytes are 0, 2, 3 in the actual packet header and src address is at 4, 6, 8 4619 * IMPORTANT: Every structure part of "ice_prot_hdr" union should have a 4620 * matching entry describing its field. This needs to be updated if new 4621 * structure is added to that union. 4622 */ 4623 static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = { 4624 { ICE_MAC_OFOS, { 0, 2, 4, 6, 8, 10, 12 } }, 4625 { ICE_MAC_IL, { 0, 2, 4, 6, 8, 10, 12 } }, 4626 { ICE_ETYPE_OL, { 0 } }, 4627 { ICE_ETYPE_IL, { 0 } }, 4628 { ICE_VLAN_OFOS, { 2, 0 } }, 4629 { ICE_IPV4_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } }, 4630 { ICE_IPV4_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18 } }, 4631 { ICE_IPV6_OFOS, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 4632 26, 28, 30, 32, 34, 36, 38 } }, 4633 { ICE_IPV6_IL, { 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 4634 26, 28, 30, 32, 34, 36, 38 } }, 4635 { ICE_TCP_IL, { 0, 2 } }, 4636 { ICE_UDP_OF, { 0, 2 } }, 4637 { ICE_UDP_ILOS, { 0, 2 } }, 4638 { ICE_VXLAN, { 8, 10, 12, 14 } }, 4639 { ICE_GENEVE, { 8, 10, 12, 14 } }, 4640 { ICE_NVGRE, { 0, 2, 4, 6 } }, 4641 { ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } }, 4642 { ICE_GTP_NO_PAY, { 8, 10, 12, 14 } }, 4643 { ICE_PPPOE, { 0, 2, 4, 6 } }, 4644 { ICE_VLAN_EX, { 2, 0 } }, 4645 { ICE_VLAN_IN, { 2, 0 } }, 4646 }; 4647 4648 static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { 4649 { ICE_MAC_OFOS, ICE_MAC_OFOS_HW }, 4650 { ICE_MAC_IL, ICE_MAC_IL_HW }, 4651 { ICE_ETYPE_OL, ICE_ETYPE_OL_HW }, 4652 { ICE_ETYPE_IL, ICE_ETYPE_IL_HW }, 4653 { ICE_VLAN_OFOS, ICE_VLAN_OL_HW }, 4654 { ICE_IPV4_OFOS, ICE_IPV4_OFOS_HW }, 4655 { ICE_IPV4_IL, ICE_IPV4_IL_HW }, 4656 { ICE_IPV6_OFOS, ICE_IPV6_OFOS_HW }, 4657 { ICE_IPV6_IL, ICE_IPV6_IL_HW }, 4658 { ICE_TCP_IL, ICE_TCP_IL_HW }, 4659 { ICE_UDP_OF, ICE_UDP_OF_HW }, 4660 { ICE_UDP_ILOS, ICE_UDP_ILOS_HW }, 4661 { ICE_VXLAN, ICE_UDP_OF_HW }, 4662 { ICE_GENEVE, ICE_UDP_OF_HW }, 4663 { ICE_NVGRE, ICE_GRE_OF_HW }, 4664 { ICE_GTP, ICE_UDP_OF_HW }, 4665 { ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW }, 4666 { ICE_PPPOE, ICE_PPPOE_HW }, 4667 { ICE_VLAN_EX, ICE_VLAN_OF_HW }, 4668 { ICE_VLAN_IN, ICE_VLAN_OL_HW }, 4669 }; 4670 4671 /** 4672 * ice_find_recp - find a recipe 4673 * @hw: pointer to the hardware structure 4674 * @lkup_exts: extension sequence to match 4675 * @tun_type: type of recipe tunnel 4676 * 4677 * Returns index of matching recipe, or ICE_MAX_NUM_RECIPES if not found. 4678 */ 4679 static u16 4680 ice_find_recp(struct ice_hw *hw, struct ice_prot_lkup_ext *lkup_exts, 4681 enum ice_sw_tunnel_type tun_type) 4682 { 4683 bool refresh_required = true; 4684 struct ice_sw_recipe *recp; 4685 u8 i; 4686 4687 /* Walk through existing recipes to find a match */ 4688 recp = hw->switch_info->recp_list; 4689 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 4690 /* If recipe was not created for this ID, in SW bookkeeping, 4691 * check if FW has an entry for this recipe. If the FW has an 4692 * entry update it in our SW bookkeeping and continue with the 4693 * matching. 4694 */ 4695 if (!recp[i].recp_created) 4696 if (ice_get_recp_frm_fw(hw, 4697 hw->switch_info->recp_list, i, 4698 &refresh_required)) 4699 continue; 4700 4701 /* Skip inverse action recipes */ 4702 if (recp[i].root_buf && recp[i].root_buf->content.act_ctrl & 4703 ICE_AQ_RECIPE_ACT_INV_ACT) 4704 continue; 4705 4706 /* if number of words we are looking for match */ 4707 if (lkup_exts->n_val_words == recp[i].lkup_exts.n_val_words) { 4708 struct ice_fv_word *ar = recp[i].lkup_exts.fv_words; 4709 struct ice_fv_word *be = lkup_exts->fv_words; 4710 u16 *cr = recp[i].lkup_exts.field_mask; 4711 u16 *de = lkup_exts->field_mask; 4712 bool found = true; 4713 u8 pe, qr; 4714 4715 /* ar, cr, and qr are related to the recipe words, while 4716 * be, de, and pe are related to the lookup words 4717 */ 4718 for (pe = 0; pe < lkup_exts->n_val_words; pe++) { 4719 for (qr = 0; qr < recp[i].lkup_exts.n_val_words; 4720 qr++) { 4721 if (ar[qr].off == be[pe].off && 4722 ar[qr].prot_id == be[pe].prot_id && 4723 cr[qr] == de[pe]) 4724 /* Found the "pe"th word in the 4725 * given recipe 4726 */ 4727 break; 4728 } 4729 /* After walking through all the words in the 4730 * "i"th recipe if "p"th word was not found then 4731 * this recipe is not what we are looking for. 4732 * So break out from this loop and try the next 4733 * recipe 4734 */ 4735 if (qr >= recp[i].lkup_exts.n_val_words) { 4736 found = false; 4737 break; 4738 } 4739 } 4740 /* If for "i"th recipe the found was never set to false 4741 * then it means we found our match 4742 * Also tun type of recipe needs to be checked 4743 */ 4744 if (found && recp[i].tun_type == tun_type) 4745 return i; /* Return the recipe ID */ 4746 } 4747 } 4748 return ICE_MAX_NUM_RECIPES; 4749 } 4750 4751 /** 4752 * ice_change_proto_id_to_dvm - change proto id in prot_id_tbl 4753 * 4754 * As protocol id for outer vlan is different in dvm and svm, if dvm is 4755 * supported protocol array record for outer vlan has to be modified to 4756 * reflect the value proper for DVM. 4757 */ 4758 void ice_change_proto_id_to_dvm(void) 4759 { 4760 u8 i; 4761 4762 for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4763 if (ice_prot_id_tbl[i].type == ICE_VLAN_OFOS && 4764 ice_prot_id_tbl[i].protocol_id != ICE_VLAN_OF_HW) 4765 ice_prot_id_tbl[i].protocol_id = ICE_VLAN_OF_HW; 4766 } 4767 4768 /** 4769 * ice_prot_type_to_id - get protocol ID from protocol type 4770 * @type: protocol type 4771 * @id: pointer to variable that will receive the ID 4772 * 4773 * Returns true if found, false otherwise 4774 */ 4775 static bool ice_prot_type_to_id(enum ice_protocol_type type, u8 *id) 4776 { 4777 u8 i; 4778 4779 for (i = 0; i < ARRAY_SIZE(ice_prot_id_tbl); i++) 4780 if (ice_prot_id_tbl[i].type == type) { 4781 *id = ice_prot_id_tbl[i].protocol_id; 4782 return true; 4783 } 4784 return false; 4785 } 4786 4787 /** 4788 * ice_fill_valid_words - count valid words 4789 * @rule: advanced rule with lookup information 4790 * @lkup_exts: byte offset extractions of the words that are valid 4791 * 4792 * calculate valid words in a lookup rule using mask value 4793 */ 4794 static u8 4795 ice_fill_valid_words(struct ice_adv_lkup_elem *rule, 4796 struct ice_prot_lkup_ext *lkup_exts) 4797 { 4798 u8 j, word, prot_id, ret_val; 4799 4800 if (!ice_prot_type_to_id(rule->type, &prot_id)) 4801 return 0; 4802 4803 word = lkup_exts->n_val_words; 4804 4805 for (j = 0; j < sizeof(rule->m_u) / sizeof(u16); j++) 4806 if (((u16 *)&rule->m_u)[j] && 4807 rule->type < ARRAY_SIZE(ice_prot_ext)) { 4808 /* No more space to accommodate */ 4809 if (word >= ICE_MAX_CHAIN_WORDS) 4810 return 0; 4811 lkup_exts->fv_words[word].off = 4812 ice_prot_ext[rule->type].offs[j]; 4813 lkup_exts->fv_words[word].prot_id = 4814 ice_prot_id_tbl[rule->type].protocol_id; 4815 lkup_exts->field_mask[word] = 4816 be16_to_cpu(((__force __be16 *)&rule->m_u)[j]); 4817 word++; 4818 } 4819 4820 ret_val = word - lkup_exts->n_val_words; 4821 lkup_exts->n_val_words = word; 4822 4823 return ret_val; 4824 } 4825 4826 /** 4827 * ice_create_first_fit_recp_def - Create a recipe grouping 4828 * @hw: pointer to the hardware structure 4829 * @lkup_exts: an array of protocol header extractions 4830 * @rg_list: pointer to a list that stores new recipe groups 4831 * @recp_cnt: pointer to a variable that stores returned number of recipe groups 4832 * 4833 * Using first fit algorithm, take all the words that are still not done 4834 * and start grouping them in 4-word groups. Each group makes up one 4835 * recipe. 4836 */ 4837 static int 4838 ice_create_first_fit_recp_def(struct ice_hw *hw, 4839 struct ice_prot_lkup_ext *lkup_exts, 4840 struct list_head *rg_list, 4841 u8 *recp_cnt) 4842 { 4843 struct ice_pref_recipe_group *grp = NULL; 4844 u8 j; 4845 4846 *recp_cnt = 0; 4847 4848 /* Walk through every word in the rule to check if it is not done. If so 4849 * then this word needs to be part of a new recipe. 4850 */ 4851 for (j = 0; j < lkup_exts->n_val_words; j++) 4852 if (!test_bit(j, lkup_exts->done)) { 4853 if (!grp || 4854 grp->n_val_pairs == ICE_NUM_WORDS_RECIPE) { 4855 struct ice_recp_grp_entry *entry; 4856 4857 entry = devm_kzalloc(ice_hw_to_dev(hw), 4858 sizeof(*entry), 4859 GFP_KERNEL); 4860 if (!entry) 4861 return -ENOMEM; 4862 list_add(&entry->l_entry, rg_list); 4863 grp = &entry->r_group; 4864 (*recp_cnt)++; 4865 } 4866 4867 grp->pairs[grp->n_val_pairs].prot_id = 4868 lkup_exts->fv_words[j].prot_id; 4869 grp->pairs[grp->n_val_pairs].off = 4870 lkup_exts->fv_words[j].off; 4871 grp->mask[grp->n_val_pairs] = lkup_exts->field_mask[j]; 4872 grp->n_val_pairs++; 4873 } 4874 4875 return 0; 4876 } 4877 4878 /** 4879 * ice_fill_fv_word_index - fill in the field vector indices for a recipe group 4880 * @hw: pointer to the hardware structure 4881 * @fv_list: field vector with the extraction sequence information 4882 * @rg_list: recipe groupings with protocol-offset pairs 4883 * 4884 * Helper function to fill in the field vector indices for protocol-offset 4885 * pairs. These indexes are then ultimately programmed into a recipe. 4886 */ 4887 static int 4888 ice_fill_fv_word_index(struct ice_hw *hw, struct list_head *fv_list, 4889 struct list_head *rg_list) 4890 { 4891 struct ice_sw_fv_list_entry *fv; 4892 struct ice_recp_grp_entry *rg; 4893 struct ice_fv_word *fv_ext; 4894 4895 if (list_empty(fv_list)) 4896 return 0; 4897 4898 fv = list_first_entry(fv_list, struct ice_sw_fv_list_entry, 4899 list_entry); 4900 fv_ext = fv->fv_ptr->ew; 4901 4902 list_for_each_entry(rg, rg_list, l_entry) { 4903 u8 i; 4904 4905 for (i = 0; i < rg->r_group.n_val_pairs; i++) { 4906 struct ice_fv_word *pr; 4907 bool found = false; 4908 u16 mask; 4909 u8 j; 4910 4911 pr = &rg->r_group.pairs[i]; 4912 mask = rg->r_group.mask[i]; 4913 4914 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++) 4915 if (fv_ext[j].prot_id == pr->prot_id && 4916 fv_ext[j].off == pr->off) { 4917 found = true; 4918 4919 /* Store index of field vector */ 4920 rg->fv_idx[i] = j; 4921 rg->fv_mask[i] = mask; 4922 break; 4923 } 4924 4925 /* Protocol/offset could not be found, caller gave an 4926 * invalid pair 4927 */ 4928 if (!found) 4929 return -EINVAL; 4930 } 4931 } 4932 4933 return 0; 4934 } 4935 4936 /** 4937 * ice_find_free_recp_res_idx - find free result indexes for recipe 4938 * @hw: pointer to hardware structure 4939 * @profiles: bitmap of profiles that will be associated with the new recipe 4940 * @free_idx: pointer to variable to receive the free index bitmap 4941 * 4942 * The algorithm used here is: 4943 * 1. When creating a new recipe, create a set P which contains all 4944 * Profiles that will be associated with our new recipe 4945 * 4946 * 2. For each Profile p in set P: 4947 * a. Add all recipes associated with Profile p into set R 4948 * b. Optional : PossibleIndexes &= profile[p].possibleIndexes 4949 * [initially PossibleIndexes should be 0xFFFFFFFFFFFFFFFF] 4950 * i. Or just assume they all have the same possible indexes: 4951 * 44, 45, 46, 47 4952 * i.e., PossibleIndexes = 0x0000F00000000000 4953 * 4954 * 3. For each Recipe r in set R: 4955 * a. UsedIndexes |= (bitwise or ) recipe[r].res_indexes 4956 * b. FreeIndexes = UsedIndexes ^ PossibleIndexes 4957 * 4958 * FreeIndexes will contain the bits indicating the indexes free for use, 4959 * then the code needs to update the recipe[r].used_result_idx_bits to 4960 * indicate which indexes were selected for use by this recipe. 4961 */ 4962 static u16 4963 ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, 4964 unsigned long *free_idx) 4965 { 4966 DECLARE_BITMAP(possible_idx, ICE_MAX_FV_WORDS); 4967 DECLARE_BITMAP(recipes, ICE_MAX_NUM_RECIPES); 4968 DECLARE_BITMAP(used_idx, ICE_MAX_FV_WORDS); 4969 u16 bit; 4970 4971 bitmap_zero(recipes, ICE_MAX_NUM_RECIPES); 4972 bitmap_zero(used_idx, ICE_MAX_FV_WORDS); 4973 4974 bitmap_fill(possible_idx, ICE_MAX_FV_WORDS); 4975 4976 /* For each profile we are going to associate the recipe with, add the 4977 * recipes that are associated with that profile. This will give us 4978 * the set of recipes that our recipe may collide with. Also, determine 4979 * what possible result indexes are usable given this set of profiles. 4980 */ 4981 for_each_set_bit(bit, profiles, ICE_MAX_NUM_PROFILES) { 4982 bitmap_or(recipes, recipes, profile_to_recipe[bit], 4983 ICE_MAX_NUM_RECIPES); 4984 bitmap_and(possible_idx, possible_idx, 4985 hw->switch_info->prof_res_bm[bit], 4986 ICE_MAX_FV_WORDS); 4987 } 4988 4989 /* For each recipe that our new recipe may collide with, determine 4990 * which indexes have been used. 4991 */ 4992 for_each_set_bit(bit, recipes, ICE_MAX_NUM_RECIPES) 4993 bitmap_or(used_idx, used_idx, 4994 hw->switch_info->recp_list[bit].res_idxs, 4995 ICE_MAX_FV_WORDS); 4996 4997 bitmap_xor(free_idx, used_idx, possible_idx, ICE_MAX_FV_WORDS); 4998 4999 /* return number of free indexes */ 5000 return (u16)bitmap_weight(free_idx, ICE_MAX_FV_WORDS); 5001 } 5002 5003 /** 5004 * ice_add_sw_recipe - function to call AQ calls to create switch recipe 5005 * @hw: pointer to hardware structure 5006 * @rm: recipe management list entry 5007 * @profiles: bitmap of profiles that will be associated. 5008 */ 5009 static int 5010 ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, 5011 unsigned long *profiles) 5012 { 5013 DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS); 5014 struct ice_aqc_recipe_data_elem *tmp; 5015 struct ice_aqc_recipe_data_elem *buf; 5016 struct ice_recp_grp_entry *entry; 5017 u16 free_res_idx; 5018 u16 recipe_count; 5019 u8 chain_idx; 5020 u8 recps = 0; 5021 int status; 5022 5023 /* When more than one recipe are required, another recipe is needed to 5024 * chain them together. Matching a tunnel metadata ID takes up one of 5025 * the match fields in the chaining recipe reducing the number of 5026 * chained recipes by one. 5027 */ 5028 /* check number of free result indices */ 5029 bitmap_zero(result_idx_bm, ICE_MAX_FV_WORDS); 5030 free_res_idx = ice_find_free_recp_res_idx(hw, profiles, result_idx_bm); 5031 5032 ice_debug(hw, ICE_DBG_SW, "Result idx slots: %d, need %d\n", 5033 free_res_idx, rm->n_grp_count); 5034 5035 if (rm->n_grp_count > 1) { 5036 if (rm->n_grp_count > free_res_idx) 5037 return -ENOSPC; 5038 5039 rm->n_grp_count++; 5040 } 5041 5042 if (rm->n_grp_count > ICE_MAX_CHAIN_RECIPE) 5043 return -ENOSPC; 5044 5045 tmp = kcalloc(ICE_MAX_NUM_RECIPES, sizeof(*tmp), GFP_KERNEL); 5046 if (!tmp) 5047 return -ENOMEM; 5048 5049 buf = devm_kcalloc(ice_hw_to_dev(hw), rm->n_grp_count, sizeof(*buf), 5050 GFP_KERNEL); 5051 if (!buf) { 5052 status = -ENOMEM; 5053 goto err_mem; 5054 } 5055 5056 bitmap_zero(rm->r_bitmap, ICE_MAX_NUM_RECIPES); 5057 recipe_count = ICE_MAX_NUM_RECIPES; 5058 status = ice_aq_get_recipe(hw, tmp, &recipe_count, ICE_SW_LKUP_MAC, 5059 NULL); 5060 if (status || recipe_count == 0) 5061 goto err_unroll; 5062 5063 /* Allocate the recipe resources, and configure them according to the 5064 * match fields from protocol headers and extracted field vectors. 5065 */ 5066 chain_idx = find_first_bit(result_idx_bm, ICE_MAX_FV_WORDS); 5067 list_for_each_entry(entry, &rm->rg_list, l_entry) { 5068 u8 i; 5069 5070 status = ice_alloc_recipe(hw, &entry->rid); 5071 if (status) 5072 goto err_unroll; 5073 5074 /* Clear the result index of the located recipe, as this will be 5075 * updated, if needed, later in the recipe creation process. 5076 */ 5077 tmp[0].content.result_indx = 0; 5078 5079 buf[recps] = tmp[0]; 5080 buf[recps].recipe_indx = (u8)entry->rid; 5081 /* if the recipe is a non-root recipe RID should be programmed 5082 * as 0 for the rules to be applied correctly. 5083 */ 5084 buf[recps].content.rid = 0; 5085 memset(&buf[recps].content.lkup_indx, 0, 5086 sizeof(buf[recps].content.lkup_indx)); 5087 5088 /* All recipes use look-up index 0 to match switch ID. */ 5089 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5090 buf[recps].content.mask[0] = 5091 cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5092 /* Setup lkup_indx 1..4 to INVALID/ignore and set the mask 5093 * to be 0 5094 */ 5095 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5096 buf[recps].content.lkup_indx[i] = 0x80; 5097 buf[recps].content.mask[i] = 0; 5098 } 5099 5100 for (i = 0; i < entry->r_group.n_val_pairs; i++) { 5101 buf[recps].content.lkup_indx[i + 1] = entry->fv_idx[i]; 5102 buf[recps].content.mask[i + 1] = 5103 cpu_to_le16(entry->fv_mask[i]); 5104 } 5105 5106 if (rm->n_grp_count > 1) { 5107 /* Checks to see if there really is a valid result index 5108 * that can be used. 5109 */ 5110 if (chain_idx >= ICE_MAX_FV_WORDS) { 5111 ice_debug(hw, ICE_DBG_SW, "No chain index available\n"); 5112 status = -ENOSPC; 5113 goto err_unroll; 5114 } 5115 5116 entry->chain_idx = chain_idx; 5117 buf[recps].content.result_indx = 5118 ICE_AQ_RECIPE_RESULT_EN | 5119 ((chain_idx << ICE_AQ_RECIPE_RESULT_DATA_S) & 5120 ICE_AQ_RECIPE_RESULT_DATA_M); 5121 clear_bit(chain_idx, result_idx_bm); 5122 chain_idx = find_first_bit(result_idx_bm, 5123 ICE_MAX_FV_WORDS); 5124 } 5125 5126 /* fill recipe dependencies */ 5127 bitmap_zero((unsigned long *)buf[recps].recipe_bitmap, 5128 ICE_MAX_NUM_RECIPES); 5129 set_bit(buf[recps].recipe_indx, 5130 (unsigned long *)buf[recps].recipe_bitmap); 5131 buf[recps].content.act_ctrl_fwd_priority = rm->priority; 5132 recps++; 5133 } 5134 5135 if (rm->n_grp_count == 1) { 5136 rm->root_rid = buf[0].recipe_indx; 5137 set_bit(buf[0].recipe_indx, rm->r_bitmap); 5138 buf[0].content.rid = rm->root_rid | ICE_AQ_RECIPE_ID_IS_ROOT; 5139 if (sizeof(buf[0].recipe_bitmap) >= sizeof(rm->r_bitmap)) { 5140 memcpy(buf[0].recipe_bitmap, rm->r_bitmap, 5141 sizeof(buf[0].recipe_bitmap)); 5142 } else { 5143 status = -EINVAL; 5144 goto err_unroll; 5145 } 5146 /* Applicable only for ROOT_RECIPE, set the fwd_priority for 5147 * the recipe which is getting created if specified 5148 * by user. Usually any advanced switch filter, which results 5149 * into new extraction sequence, ended up creating a new recipe 5150 * of type ROOT and usually recipes are associated with profiles 5151 * Switch rule referreing newly created recipe, needs to have 5152 * either/or 'fwd' or 'join' priority, otherwise switch rule 5153 * evaluation will not happen correctly. In other words, if 5154 * switch rule to be evaluated on priority basis, then recipe 5155 * needs to have priority, otherwise it will be evaluated last. 5156 */ 5157 buf[0].content.act_ctrl_fwd_priority = rm->priority; 5158 } else { 5159 struct ice_recp_grp_entry *last_chain_entry; 5160 u16 rid, i; 5161 5162 /* Allocate the last recipe that will chain the outcomes of the 5163 * other recipes together 5164 */ 5165 status = ice_alloc_recipe(hw, &rid); 5166 if (status) 5167 goto err_unroll; 5168 5169 buf[recps].recipe_indx = (u8)rid; 5170 buf[recps].content.rid = (u8)rid; 5171 buf[recps].content.rid |= ICE_AQ_RECIPE_ID_IS_ROOT; 5172 /* the new entry created should also be part of rg_list to 5173 * make sure we have complete recipe 5174 */ 5175 last_chain_entry = devm_kzalloc(ice_hw_to_dev(hw), 5176 sizeof(*last_chain_entry), 5177 GFP_KERNEL); 5178 if (!last_chain_entry) { 5179 status = -ENOMEM; 5180 goto err_unroll; 5181 } 5182 last_chain_entry->rid = rid; 5183 memset(&buf[recps].content.lkup_indx, 0, 5184 sizeof(buf[recps].content.lkup_indx)); 5185 /* All recipes use look-up index 0 to match switch ID. */ 5186 buf[recps].content.lkup_indx[0] = ICE_AQ_SW_ID_LKUP_IDX; 5187 buf[recps].content.mask[0] = 5188 cpu_to_le16(ICE_AQ_SW_ID_LKUP_MASK); 5189 for (i = 1; i <= ICE_NUM_WORDS_RECIPE; i++) { 5190 buf[recps].content.lkup_indx[i] = 5191 ICE_AQ_RECIPE_LKUP_IGNORE; 5192 buf[recps].content.mask[i] = 0; 5193 } 5194 5195 i = 1; 5196 /* update r_bitmap with the recp that is used for chaining */ 5197 set_bit(rid, rm->r_bitmap); 5198 /* this is the recipe that chains all the other recipes so it 5199 * should not have a chaining ID to indicate the same 5200 */ 5201 last_chain_entry->chain_idx = ICE_INVAL_CHAIN_IND; 5202 list_for_each_entry(entry, &rm->rg_list, l_entry) { 5203 last_chain_entry->fv_idx[i] = entry->chain_idx; 5204 buf[recps].content.lkup_indx[i] = entry->chain_idx; 5205 buf[recps].content.mask[i++] = cpu_to_le16(0xFFFF); 5206 set_bit(entry->rid, rm->r_bitmap); 5207 } 5208 list_add(&last_chain_entry->l_entry, &rm->rg_list); 5209 if (sizeof(buf[recps].recipe_bitmap) >= 5210 sizeof(rm->r_bitmap)) { 5211 memcpy(buf[recps].recipe_bitmap, rm->r_bitmap, 5212 sizeof(buf[recps].recipe_bitmap)); 5213 } else { 5214 status = -EINVAL; 5215 goto err_unroll; 5216 } 5217 buf[recps].content.act_ctrl_fwd_priority = rm->priority; 5218 5219 recps++; 5220 rm->root_rid = (u8)rid; 5221 } 5222 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5223 if (status) 5224 goto err_unroll; 5225 5226 status = ice_aq_add_recipe(hw, buf, rm->n_grp_count, NULL); 5227 ice_release_change_lock(hw); 5228 if (status) 5229 goto err_unroll; 5230 5231 /* Every recipe that just got created add it to the recipe 5232 * book keeping list 5233 */ 5234 list_for_each_entry(entry, &rm->rg_list, l_entry) { 5235 struct ice_switch_info *sw = hw->switch_info; 5236 bool is_root, idx_found = false; 5237 struct ice_sw_recipe *recp; 5238 u16 idx, buf_idx = 0; 5239 5240 /* find buffer index for copying some data */ 5241 for (idx = 0; idx < rm->n_grp_count; idx++) 5242 if (buf[idx].recipe_indx == entry->rid) { 5243 buf_idx = idx; 5244 idx_found = true; 5245 } 5246 5247 if (!idx_found) { 5248 status = -EIO; 5249 goto err_unroll; 5250 } 5251 5252 recp = &sw->recp_list[entry->rid]; 5253 is_root = (rm->root_rid == entry->rid); 5254 recp->is_root = is_root; 5255 5256 recp->root_rid = entry->rid; 5257 recp->big_recp = (is_root && rm->n_grp_count > 1); 5258 5259 memcpy(&recp->ext_words, entry->r_group.pairs, 5260 entry->r_group.n_val_pairs * sizeof(struct ice_fv_word)); 5261 5262 memcpy(recp->r_bitmap, buf[buf_idx].recipe_bitmap, 5263 sizeof(recp->r_bitmap)); 5264 5265 /* Copy non-result fv index values and masks to recipe. This 5266 * call will also update the result recipe bitmask. 5267 */ 5268 ice_collect_result_idx(&buf[buf_idx], recp); 5269 5270 /* for non-root recipes, also copy to the root, this allows 5271 * easier matching of a complete chained recipe 5272 */ 5273 if (!is_root) 5274 ice_collect_result_idx(&buf[buf_idx], 5275 &sw->recp_list[rm->root_rid]); 5276 5277 recp->n_ext_words = entry->r_group.n_val_pairs; 5278 recp->chain_idx = entry->chain_idx; 5279 recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority; 5280 recp->n_grp_count = rm->n_grp_count; 5281 recp->tun_type = rm->tun_type; 5282 recp->recp_created = true; 5283 } 5284 rm->root_buf = buf; 5285 kfree(tmp); 5286 return status; 5287 5288 err_unroll: 5289 err_mem: 5290 kfree(tmp); 5291 devm_kfree(ice_hw_to_dev(hw), buf); 5292 return status; 5293 } 5294 5295 /** 5296 * ice_create_recipe_group - creates recipe group 5297 * @hw: pointer to hardware structure 5298 * @rm: recipe management list entry 5299 * @lkup_exts: lookup elements 5300 */ 5301 static int 5302 ice_create_recipe_group(struct ice_hw *hw, struct ice_sw_recipe *rm, 5303 struct ice_prot_lkup_ext *lkup_exts) 5304 { 5305 u8 recp_count = 0; 5306 int status; 5307 5308 rm->n_grp_count = 0; 5309 5310 /* Create recipes for words that are marked not done by packing them 5311 * as best fit. 5312 */ 5313 status = ice_create_first_fit_recp_def(hw, lkup_exts, 5314 &rm->rg_list, &recp_count); 5315 if (!status) { 5316 rm->n_grp_count += recp_count; 5317 rm->n_ext_words = lkup_exts->n_val_words; 5318 memcpy(&rm->ext_words, lkup_exts->fv_words, 5319 sizeof(rm->ext_words)); 5320 memcpy(rm->word_masks, lkup_exts->field_mask, 5321 sizeof(rm->word_masks)); 5322 } 5323 5324 return status; 5325 } 5326 5327 /** 5328 * ice_tun_type_match_word - determine if tun type needs a match mask 5329 * @tun_type: tunnel type 5330 * @mask: mask to be used for the tunnel 5331 */ 5332 static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask) 5333 { 5334 switch (tun_type) { 5335 case ICE_SW_TUN_GENEVE: 5336 case ICE_SW_TUN_VXLAN: 5337 case ICE_SW_TUN_NVGRE: 5338 case ICE_SW_TUN_GTPU: 5339 case ICE_SW_TUN_GTPC: 5340 *mask = ICE_TUN_FLAG_MASK; 5341 return true; 5342 5343 default: 5344 *mask = 0; 5345 return false; 5346 } 5347 } 5348 5349 /** 5350 * ice_add_special_words - Add words that are not protocols, such as metadata 5351 * @rinfo: other information regarding the rule e.g. priority and action info 5352 * @lkup_exts: lookup word structure 5353 * @dvm_ena: is double VLAN mode enabled 5354 */ 5355 static int 5356 ice_add_special_words(struct ice_adv_rule_info *rinfo, 5357 struct ice_prot_lkup_ext *lkup_exts, bool dvm_ena) 5358 { 5359 u16 mask; 5360 5361 /* If this is a tunneled packet, then add recipe index to match the 5362 * tunnel bit in the packet metadata flags. 5363 */ 5364 if (ice_tun_type_match_word(rinfo->tun_type, &mask)) { 5365 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) { 5366 u8 word = lkup_exts->n_val_words++; 5367 5368 lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW; 5369 lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF; 5370 lkup_exts->field_mask[word] = mask; 5371 } else { 5372 return -ENOSPC; 5373 } 5374 } 5375 5376 if (rinfo->vlan_type != 0 && dvm_ena) { 5377 if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) { 5378 u8 word = lkup_exts->n_val_words++; 5379 5380 lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW; 5381 lkup_exts->fv_words[word].off = ICE_VLAN_FLAG_MDID_OFF; 5382 lkup_exts->field_mask[word] = 5383 ICE_PKT_FLAGS_0_TO_15_VLAN_FLAGS_MASK; 5384 } else { 5385 return -ENOSPC; 5386 } 5387 } 5388 5389 return 0; 5390 } 5391 5392 /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule 5393 * @hw: pointer to hardware structure 5394 * @rinfo: other information regarding the rule e.g. priority and action info 5395 * @bm: pointer to memory for returning the bitmap of field vectors 5396 */ 5397 static void 5398 ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, 5399 unsigned long *bm) 5400 { 5401 enum ice_prof_type prof_type; 5402 5403 bitmap_zero(bm, ICE_MAX_NUM_PROFILES); 5404 5405 switch (rinfo->tun_type) { 5406 case ICE_NON_TUN: 5407 prof_type = ICE_PROF_NON_TUN; 5408 break; 5409 case ICE_ALL_TUNNELS: 5410 prof_type = ICE_PROF_TUN_ALL; 5411 break; 5412 case ICE_SW_TUN_GENEVE: 5413 case ICE_SW_TUN_VXLAN: 5414 prof_type = ICE_PROF_TUN_UDP; 5415 break; 5416 case ICE_SW_TUN_NVGRE: 5417 prof_type = ICE_PROF_TUN_GRE; 5418 break; 5419 case ICE_SW_TUN_GTPU: 5420 prof_type = ICE_PROF_TUN_GTPU; 5421 break; 5422 case ICE_SW_TUN_GTPC: 5423 prof_type = ICE_PROF_TUN_GTPC; 5424 break; 5425 case ICE_SW_TUN_AND_NON_TUN: 5426 default: 5427 prof_type = ICE_PROF_ALL; 5428 break; 5429 } 5430 5431 ice_get_sw_fv_bitmap(hw, prof_type, bm); 5432 } 5433 5434 /** 5435 * ice_add_adv_recipe - Add an advanced recipe that is not part of the default 5436 * @hw: pointer to hardware structure 5437 * @lkups: lookup elements or match criteria for the advanced recipe, one 5438 * structure per protocol header 5439 * @lkups_cnt: number of protocols 5440 * @rinfo: other information regarding the rule e.g. priority and action info 5441 * @rid: return the recipe ID of the recipe created 5442 */ 5443 static int 5444 ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 5445 u16 lkups_cnt, struct ice_adv_rule_info *rinfo, u16 *rid) 5446 { 5447 DECLARE_BITMAP(fv_bitmap, ICE_MAX_NUM_PROFILES); 5448 DECLARE_BITMAP(profiles, ICE_MAX_NUM_PROFILES); 5449 struct ice_prot_lkup_ext *lkup_exts; 5450 struct ice_recp_grp_entry *r_entry; 5451 struct ice_sw_fv_list_entry *fvit; 5452 struct ice_recp_grp_entry *r_tmp; 5453 struct ice_sw_fv_list_entry *tmp; 5454 struct ice_sw_recipe *rm; 5455 int status = 0; 5456 u8 i; 5457 5458 if (!lkups_cnt) 5459 return -EINVAL; 5460 5461 lkup_exts = kzalloc(sizeof(*lkup_exts), GFP_KERNEL); 5462 if (!lkup_exts) 5463 return -ENOMEM; 5464 5465 /* Determine the number of words to be matched and if it exceeds a 5466 * recipe's restrictions 5467 */ 5468 for (i = 0; i < lkups_cnt; i++) { 5469 u16 count; 5470 5471 if (lkups[i].type >= ICE_PROTOCOL_LAST) { 5472 status = -EIO; 5473 goto err_free_lkup_exts; 5474 } 5475 5476 count = ice_fill_valid_words(&lkups[i], lkup_exts); 5477 if (!count) { 5478 status = -EIO; 5479 goto err_free_lkup_exts; 5480 } 5481 } 5482 5483 rm = kzalloc(sizeof(*rm), GFP_KERNEL); 5484 if (!rm) { 5485 status = -ENOMEM; 5486 goto err_free_lkup_exts; 5487 } 5488 5489 /* Get field vectors that contain fields extracted from all the protocol 5490 * headers being programmed. 5491 */ 5492 INIT_LIST_HEAD(&rm->fv_list); 5493 INIT_LIST_HEAD(&rm->rg_list); 5494 5495 /* Get bitmap of field vectors (profiles) that are compatible with the 5496 * rule request; only these will be searched in the subsequent call to 5497 * ice_get_sw_fv_list. 5498 */ 5499 ice_get_compat_fv_bitmap(hw, rinfo, fv_bitmap); 5500 5501 status = ice_get_sw_fv_list(hw, lkup_exts, fv_bitmap, &rm->fv_list); 5502 if (status) 5503 goto err_unroll; 5504 5505 /* Create any special protocol/offset pairs, such as looking at tunnel 5506 * bits by extracting metadata 5507 */ 5508 status = ice_add_special_words(rinfo, lkup_exts, ice_is_dvm_ena(hw)); 5509 if (status) 5510 goto err_free_lkup_exts; 5511 5512 /* Group match words into recipes using preferred recipe grouping 5513 * criteria. 5514 */ 5515 status = ice_create_recipe_group(hw, rm, lkup_exts); 5516 if (status) 5517 goto err_unroll; 5518 5519 /* set the recipe priority if specified */ 5520 rm->priority = (u8)rinfo->priority; 5521 5522 /* Find offsets from the field vector. Pick the first one for all the 5523 * recipes. 5524 */ 5525 status = ice_fill_fv_word_index(hw, &rm->fv_list, &rm->rg_list); 5526 if (status) 5527 goto err_unroll; 5528 5529 /* get bitmap of all profiles the recipe will be associated with */ 5530 bitmap_zero(profiles, ICE_MAX_NUM_PROFILES); 5531 list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5532 ice_debug(hw, ICE_DBG_SW, "profile: %d\n", fvit->profile_id); 5533 set_bit((u16)fvit->profile_id, profiles); 5534 } 5535 5536 /* Look for a recipe which matches our requested fv / mask list */ 5537 *rid = ice_find_recp(hw, lkup_exts, rinfo->tun_type); 5538 if (*rid < ICE_MAX_NUM_RECIPES) 5539 /* Success if found a recipe that match the existing criteria */ 5540 goto err_unroll; 5541 5542 rm->tun_type = rinfo->tun_type; 5543 /* Recipe we need does not exist, add a recipe */ 5544 status = ice_add_sw_recipe(hw, rm, profiles); 5545 if (status) 5546 goto err_unroll; 5547 5548 /* Associate all the recipes created with all the profiles in the 5549 * common field vector. 5550 */ 5551 list_for_each_entry(fvit, &rm->fv_list, list_entry) { 5552 DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); 5553 u16 j; 5554 5555 status = ice_aq_get_recipe_to_profile(hw, fvit->profile_id, 5556 (u8 *)r_bitmap, NULL); 5557 if (status) 5558 goto err_unroll; 5559 5560 bitmap_or(r_bitmap, r_bitmap, rm->r_bitmap, 5561 ICE_MAX_NUM_RECIPES); 5562 status = ice_acquire_change_lock(hw, ICE_RES_WRITE); 5563 if (status) 5564 goto err_unroll; 5565 5566 status = ice_aq_map_recipe_to_profile(hw, fvit->profile_id, 5567 (u8 *)r_bitmap, 5568 NULL); 5569 ice_release_change_lock(hw); 5570 5571 if (status) 5572 goto err_unroll; 5573 5574 /* Update profile to recipe bitmap array */ 5575 bitmap_copy(profile_to_recipe[fvit->profile_id], r_bitmap, 5576 ICE_MAX_NUM_RECIPES); 5577 5578 /* Update recipe to profile bitmap array */ 5579 for_each_set_bit(j, rm->r_bitmap, ICE_MAX_NUM_RECIPES) 5580 set_bit((u16)fvit->profile_id, recipe_to_profile[j]); 5581 } 5582 5583 *rid = rm->root_rid; 5584 memcpy(&hw->switch_info->recp_list[*rid].lkup_exts, lkup_exts, 5585 sizeof(*lkup_exts)); 5586 err_unroll: 5587 list_for_each_entry_safe(r_entry, r_tmp, &rm->rg_list, l_entry) { 5588 list_del(&r_entry->l_entry); 5589 devm_kfree(ice_hw_to_dev(hw), r_entry); 5590 } 5591 5592 list_for_each_entry_safe(fvit, tmp, &rm->fv_list, list_entry) { 5593 list_del(&fvit->list_entry); 5594 devm_kfree(ice_hw_to_dev(hw), fvit); 5595 } 5596 5597 if (rm->root_buf) 5598 devm_kfree(ice_hw_to_dev(hw), rm->root_buf); 5599 5600 kfree(rm); 5601 5602 err_free_lkup_exts: 5603 kfree(lkup_exts); 5604 5605 return status; 5606 } 5607 5608 /** 5609 * ice_dummy_packet_add_vlan - insert VLAN header to dummy pkt 5610 * 5611 * @dummy_pkt: dummy packet profile pattern to which VLAN tag(s) will be added 5612 * @num_vlan: number of VLAN tags 5613 */ 5614 static struct ice_dummy_pkt_profile * 5615 ice_dummy_packet_add_vlan(const struct ice_dummy_pkt_profile *dummy_pkt, 5616 u32 num_vlan) 5617 { 5618 struct ice_dummy_pkt_profile *profile; 5619 struct ice_dummy_pkt_offsets *offsets; 5620 u32 buf_len, off, etype_off, i; 5621 u8 *pkt; 5622 5623 if (num_vlan < 1 || num_vlan > 2) 5624 return ERR_PTR(-EINVAL); 5625 5626 off = num_vlan * VLAN_HLEN; 5627 5628 buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet_offsets)) + 5629 dummy_pkt->offsets_len; 5630 offsets = kzalloc(buf_len, GFP_KERNEL); 5631 if (!offsets) 5632 return ERR_PTR(-ENOMEM); 5633 5634 offsets[0] = dummy_pkt->offsets[0]; 5635 if (num_vlan == 2) { 5636 offsets[1] = ice_dummy_qinq_packet_offsets[0]; 5637 offsets[2] = ice_dummy_qinq_packet_offsets[1]; 5638 } else if (num_vlan == 1) { 5639 offsets[1] = ice_dummy_vlan_packet_offsets[0]; 5640 } 5641 5642 for (i = 1; dummy_pkt->offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5643 offsets[i + num_vlan].type = dummy_pkt->offsets[i].type; 5644 offsets[i + num_vlan].offset = 5645 dummy_pkt->offsets[i].offset + off; 5646 } 5647 offsets[i + num_vlan] = dummy_pkt->offsets[i]; 5648 5649 etype_off = dummy_pkt->offsets[1].offset; 5650 5651 buf_len = array_size(num_vlan, sizeof(ice_dummy_vlan_packet)) + 5652 dummy_pkt->pkt_len; 5653 pkt = kzalloc(buf_len, GFP_KERNEL); 5654 if (!pkt) { 5655 kfree(offsets); 5656 return ERR_PTR(-ENOMEM); 5657 } 5658 5659 memcpy(pkt, dummy_pkt->pkt, etype_off); 5660 memcpy(pkt + etype_off, 5661 num_vlan == 2 ? ice_dummy_qinq_packet : ice_dummy_vlan_packet, 5662 off); 5663 memcpy(pkt + etype_off + off, dummy_pkt->pkt + etype_off, 5664 dummy_pkt->pkt_len - etype_off); 5665 5666 profile = kzalloc(sizeof(*profile), GFP_KERNEL); 5667 if (!profile) { 5668 kfree(offsets); 5669 kfree(pkt); 5670 return ERR_PTR(-ENOMEM); 5671 } 5672 5673 profile->offsets = offsets; 5674 profile->pkt = pkt; 5675 profile->pkt_len = buf_len; 5676 profile->match |= ICE_PKT_KMALLOC; 5677 5678 return profile; 5679 } 5680 5681 /** 5682 * ice_find_dummy_packet - find dummy packet 5683 * 5684 * @lkups: lookup elements or match criteria for the advanced recipe, one 5685 * structure per protocol header 5686 * @lkups_cnt: number of protocols 5687 * @tun_type: tunnel type 5688 * 5689 * Returns the &ice_dummy_pkt_profile corresponding to these lookup params. 5690 */ 5691 static const struct ice_dummy_pkt_profile * 5692 ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 5693 enum ice_sw_tunnel_type tun_type) 5694 { 5695 const struct ice_dummy_pkt_profile *ret = ice_dummy_pkt_profiles; 5696 u32 match = 0, vlan_count = 0; 5697 u16 i; 5698 5699 switch (tun_type) { 5700 case ICE_SW_TUN_GTPC: 5701 match |= ICE_PKT_TUN_GTPC; 5702 break; 5703 case ICE_SW_TUN_GTPU: 5704 match |= ICE_PKT_TUN_GTPU; 5705 break; 5706 case ICE_SW_TUN_NVGRE: 5707 match |= ICE_PKT_TUN_NVGRE; 5708 break; 5709 case ICE_SW_TUN_GENEVE: 5710 case ICE_SW_TUN_VXLAN: 5711 match |= ICE_PKT_TUN_UDP; 5712 break; 5713 default: 5714 break; 5715 } 5716 5717 for (i = 0; i < lkups_cnt; i++) { 5718 if (lkups[i].type == ICE_UDP_ILOS) 5719 match |= ICE_PKT_INNER_UDP; 5720 else if (lkups[i].type == ICE_TCP_IL) 5721 match |= ICE_PKT_INNER_TCP; 5722 else if (lkups[i].type == ICE_IPV6_OFOS) 5723 match |= ICE_PKT_OUTER_IPV6; 5724 else if (lkups[i].type == ICE_VLAN_OFOS || 5725 lkups[i].type == ICE_VLAN_EX) 5726 vlan_count++; 5727 else if (lkups[i].type == ICE_VLAN_IN) 5728 vlan_count++; 5729 else if (lkups[i].type == ICE_ETYPE_OL && 5730 lkups[i].h_u.ethertype.ethtype_id == 5731 cpu_to_be16(ICE_IPV6_ETHER_ID) && 5732 lkups[i].m_u.ethertype.ethtype_id == 5733 cpu_to_be16(0xFFFF)) 5734 match |= ICE_PKT_OUTER_IPV6; 5735 else if (lkups[i].type == ICE_ETYPE_IL && 5736 lkups[i].h_u.ethertype.ethtype_id == 5737 cpu_to_be16(ICE_IPV6_ETHER_ID) && 5738 lkups[i].m_u.ethertype.ethtype_id == 5739 cpu_to_be16(0xFFFF)) 5740 match |= ICE_PKT_INNER_IPV6; 5741 else if (lkups[i].type == ICE_IPV6_IL) 5742 match |= ICE_PKT_INNER_IPV6; 5743 else if (lkups[i].type == ICE_GTP_NO_PAY) 5744 match |= ICE_PKT_GTP_NOPAY; 5745 else if (lkups[i].type == ICE_PPPOE) { 5746 match |= ICE_PKT_PPPOE; 5747 if (lkups[i].h_u.pppoe_hdr.ppp_prot_id == 5748 htons(PPP_IPV6)) 5749 match |= ICE_PKT_OUTER_IPV6; 5750 } 5751 } 5752 5753 while (ret->match && (match & ret->match) != ret->match) 5754 ret++; 5755 5756 if (vlan_count != 0) 5757 ret = ice_dummy_packet_add_vlan(ret, vlan_count); 5758 5759 return ret; 5760 } 5761 5762 /** 5763 * ice_fill_adv_dummy_packet - fill a dummy packet with given match criteria 5764 * 5765 * @lkups: lookup elements or match criteria for the advanced recipe, one 5766 * structure per protocol header 5767 * @lkups_cnt: number of protocols 5768 * @s_rule: stores rule information from the match criteria 5769 * @profile: dummy packet profile (the template, its size and header offsets) 5770 */ 5771 static int 5772 ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, 5773 struct ice_sw_rule_lkup_rx_tx *s_rule, 5774 const struct ice_dummy_pkt_profile *profile) 5775 { 5776 u8 *pkt; 5777 u16 i; 5778 5779 /* Start with a packet with a pre-defined/dummy content. Then, fill 5780 * in the header values to be looked up or matched. 5781 */ 5782 pkt = s_rule->hdr_data; 5783 5784 memcpy(pkt, profile->pkt, profile->pkt_len); 5785 5786 for (i = 0; i < lkups_cnt; i++) { 5787 const struct ice_dummy_pkt_offsets *offsets = profile->offsets; 5788 enum ice_protocol_type type; 5789 u16 offset = 0, len = 0, j; 5790 bool found = false; 5791 5792 /* find the start of this layer; it should be found since this 5793 * was already checked when search for the dummy packet 5794 */ 5795 type = lkups[i].type; 5796 for (j = 0; offsets[j].type != ICE_PROTOCOL_LAST; j++) { 5797 if (type == offsets[j].type) { 5798 offset = offsets[j].offset; 5799 found = true; 5800 break; 5801 } 5802 } 5803 /* this should never happen in a correct calling sequence */ 5804 if (!found) 5805 return -EINVAL; 5806 5807 switch (lkups[i].type) { 5808 case ICE_MAC_OFOS: 5809 case ICE_MAC_IL: 5810 len = sizeof(struct ice_ether_hdr); 5811 break; 5812 case ICE_ETYPE_OL: 5813 case ICE_ETYPE_IL: 5814 len = sizeof(struct ice_ethtype_hdr); 5815 break; 5816 case ICE_VLAN_OFOS: 5817 case ICE_VLAN_EX: 5818 case ICE_VLAN_IN: 5819 len = sizeof(struct ice_vlan_hdr); 5820 break; 5821 case ICE_IPV4_OFOS: 5822 case ICE_IPV4_IL: 5823 len = sizeof(struct ice_ipv4_hdr); 5824 break; 5825 case ICE_IPV6_OFOS: 5826 case ICE_IPV6_IL: 5827 len = sizeof(struct ice_ipv6_hdr); 5828 break; 5829 case ICE_TCP_IL: 5830 case ICE_UDP_OF: 5831 case ICE_UDP_ILOS: 5832 len = sizeof(struct ice_l4_hdr); 5833 break; 5834 case ICE_SCTP_IL: 5835 len = sizeof(struct ice_sctp_hdr); 5836 break; 5837 case ICE_NVGRE: 5838 len = sizeof(struct ice_nvgre_hdr); 5839 break; 5840 case ICE_VXLAN: 5841 case ICE_GENEVE: 5842 len = sizeof(struct ice_udp_tnl_hdr); 5843 break; 5844 case ICE_GTP_NO_PAY: 5845 case ICE_GTP: 5846 len = sizeof(struct ice_udp_gtp_hdr); 5847 break; 5848 case ICE_PPPOE: 5849 len = sizeof(struct ice_pppoe_hdr); 5850 break; 5851 default: 5852 return -EINVAL; 5853 } 5854 5855 /* the length should be a word multiple */ 5856 if (len % ICE_BYTES_PER_WORD) 5857 return -EIO; 5858 5859 /* We have the offset to the header start, the length, the 5860 * caller's header values and mask. Use this information to 5861 * copy the data into the dummy packet appropriately based on 5862 * the mask. Note that we need to only write the bits as 5863 * indicated by the mask to make sure we don't improperly write 5864 * over any significant packet data. 5865 */ 5866 for (j = 0; j < len / sizeof(u16); j++) { 5867 u16 *ptr = (u16 *)(pkt + offset); 5868 u16 mask = lkups[i].m_raw[j]; 5869 5870 if (!mask) 5871 continue; 5872 5873 ptr[j] = (ptr[j] & ~mask) | (lkups[i].h_raw[j] & mask); 5874 } 5875 } 5876 5877 s_rule->hdr_len = cpu_to_le16(profile->pkt_len); 5878 5879 return 0; 5880 } 5881 5882 /** 5883 * ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port 5884 * @hw: pointer to the hardware structure 5885 * @tun_type: tunnel type 5886 * @pkt: dummy packet to fill in 5887 * @offsets: offset info for the dummy packet 5888 */ 5889 static int 5890 ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type, 5891 u8 *pkt, const struct ice_dummy_pkt_offsets *offsets) 5892 { 5893 u16 open_port, i; 5894 5895 switch (tun_type) { 5896 case ICE_SW_TUN_VXLAN: 5897 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_VXLAN)) 5898 return -EIO; 5899 break; 5900 case ICE_SW_TUN_GENEVE: 5901 if (!ice_get_open_tunnel_port(hw, &open_port, TNL_GENEVE)) 5902 return -EIO; 5903 break; 5904 default: 5905 /* Nothing needs to be done for this tunnel type */ 5906 return 0; 5907 } 5908 5909 /* Find the outer UDP protocol header and insert the port number */ 5910 for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5911 if (offsets[i].type == ICE_UDP_OF) { 5912 struct ice_l4_hdr *hdr; 5913 u16 offset; 5914 5915 offset = offsets[i].offset; 5916 hdr = (struct ice_l4_hdr *)&pkt[offset]; 5917 hdr->dst_port = cpu_to_be16(open_port); 5918 5919 return 0; 5920 } 5921 } 5922 5923 return -EIO; 5924 } 5925 5926 /** 5927 * ice_fill_adv_packet_vlan - fill dummy packet with VLAN tag type 5928 * @vlan_type: VLAN tag type 5929 * @pkt: dummy packet to fill in 5930 * @offsets: offset info for the dummy packet 5931 */ 5932 static int 5933 ice_fill_adv_packet_vlan(u16 vlan_type, u8 *pkt, 5934 const struct ice_dummy_pkt_offsets *offsets) 5935 { 5936 u16 i; 5937 5938 /* Find VLAN header and insert VLAN TPID */ 5939 for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) { 5940 if (offsets[i].type == ICE_VLAN_OFOS || 5941 offsets[i].type == ICE_VLAN_EX) { 5942 struct ice_vlan_hdr *hdr; 5943 u16 offset; 5944 5945 offset = offsets[i].offset; 5946 hdr = (struct ice_vlan_hdr *)&pkt[offset]; 5947 hdr->type = cpu_to_be16(vlan_type); 5948 5949 return 0; 5950 } 5951 } 5952 5953 return -EIO; 5954 } 5955 5956 /** 5957 * ice_find_adv_rule_entry - Search a rule entry 5958 * @hw: pointer to the hardware structure 5959 * @lkups: lookup elements or match criteria for the advanced recipe, one 5960 * structure per protocol header 5961 * @lkups_cnt: number of protocols 5962 * @recp_id: recipe ID for which we are finding the rule 5963 * @rinfo: other information regarding the rule e.g. priority and action info 5964 * 5965 * Helper function to search for a given advance rule entry 5966 * Returns pointer to entry storing the rule if found 5967 */ 5968 static struct ice_adv_fltr_mgmt_list_entry * 5969 ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 5970 u16 lkups_cnt, u16 recp_id, 5971 struct ice_adv_rule_info *rinfo) 5972 { 5973 struct ice_adv_fltr_mgmt_list_entry *list_itr; 5974 struct ice_switch_info *sw = hw->switch_info; 5975 int i; 5976 5977 list_for_each_entry(list_itr, &sw->recp_list[recp_id].filt_rules, 5978 list_entry) { 5979 bool lkups_matched = true; 5980 5981 if (lkups_cnt != list_itr->lkups_cnt) 5982 continue; 5983 for (i = 0; i < list_itr->lkups_cnt; i++) 5984 if (memcmp(&list_itr->lkups[i], &lkups[i], 5985 sizeof(*lkups))) { 5986 lkups_matched = false; 5987 break; 5988 } 5989 if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag && 5990 rinfo->tun_type == list_itr->rule_info.tun_type && 5991 rinfo->vlan_type == list_itr->rule_info.vlan_type && 5992 lkups_matched) 5993 return list_itr; 5994 } 5995 return NULL; 5996 } 5997 5998 /** 5999 * ice_adv_add_update_vsi_list 6000 * @hw: pointer to the hardware structure 6001 * @m_entry: pointer to current adv filter management list entry 6002 * @cur_fltr: filter information from the book keeping entry 6003 * @new_fltr: filter information with the new VSI to be added 6004 * 6005 * Call AQ command to add or update previously created VSI list with new VSI. 6006 * 6007 * Helper function to do book keeping associated with adding filter information 6008 * The algorithm to do the booking keeping is described below : 6009 * When a VSI needs to subscribe to a given advanced filter 6010 * if only one VSI has been added till now 6011 * Allocate a new VSI list and add two VSIs 6012 * to this list using switch rule command 6013 * Update the previously created switch rule with the 6014 * newly created VSI list ID 6015 * if a VSI list was previously created 6016 * Add the new VSI to the previously created VSI list set 6017 * using the update switch rule command 6018 */ 6019 static int 6020 ice_adv_add_update_vsi_list(struct ice_hw *hw, 6021 struct ice_adv_fltr_mgmt_list_entry *m_entry, 6022 struct ice_adv_rule_info *cur_fltr, 6023 struct ice_adv_rule_info *new_fltr) 6024 { 6025 u16 vsi_list_id = 0; 6026 int status; 6027 6028 if (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 6029 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP || 6030 cur_fltr->sw_act.fltr_act == ICE_DROP_PACKET) 6031 return -EOPNOTSUPP; 6032 6033 if ((new_fltr->sw_act.fltr_act == ICE_FWD_TO_Q || 6034 new_fltr->sw_act.fltr_act == ICE_FWD_TO_QGRP) && 6035 (cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI || 6036 cur_fltr->sw_act.fltr_act == ICE_FWD_TO_VSI_LIST)) 6037 return -EOPNOTSUPP; 6038 6039 if (m_entry->vsi_count < 2 && !m_entry->vsi_list_info) { 6040 /* Only one entry existed in the mapping and it was not already 6041 * a part of a VSI list. So, create a VSI list with the old and 6042 * new VSIs. 6043 */ 6044 struct ice_fltr_info tmp_fltr; 6045 u16 vsi_handle_arr[2]; 6046 6047 /* A rule already exists with the new VSI being added */ 6048 if (cur_fltr->sw_act.fwd_id.hw_vsi_id == 6049 new_fltr->sw_act.fwd_id.hw_vsi_id) 6050 return -EEXIST; 6051 6052 vsi_handle_arr[0] = cur_fltr->sw_act.vsi_handle; 6053 vsi_handle_arr[1] = new_fltr->sw_act.vsi_handle; 6054 status = ice_create_vsi_list_rule(hw, &vsi_handle_arr[0], 2, 6055 &vsi_list_id, 6056 ICE_SW_LKUP_LAST); 6057 if (status) 6058 return status; 6059 6060 memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 6061 tmp_fltr.flag = m_entry->rule_info.sw_act.flag; 6062 tmp_fltr.fltr_rule_id = cur_fltr->fltr_rule_id; 6063 tmp_fltr.fltr_act = ICE_FWD_TO_VSI_LIST; 6064 tmp_fltr.fwd_id.vsi_list_id = vsi_list_id; 6065 tmp_fltr.lkup_type = ICE_SW_LKUP_LAST; 6066 6067 /* Update the previous switch rule of "forward to VSI" to 6068 * "fwd to VSI list" 6069 */ 6070 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 6071 if (status) 6072 return status; 6073 6074 cur_fltr->sw_act.fwd_id.vsi_list_id = vsi_list_id; 6075 cur_fltr->sw_act.fltr_act = ICE_FWD_TO_VSI_LIST; 6076 m_entry->vsi_list_info = 6077 ice_create_vsi_list_map(hw, &vsi_handle_arr[0], 2, 6078 vsi_list_id); 6079 } else { 6080 u16 vsi_handle = new_fltr->sw_act.vsi_handle; 6081 6082 if (!m_entry->vsi_list_info) 6083 return -EIO; 6084 6085 /* A rule already exists with the new VSI being added */ 6086 if (test_bit(vsi_handle, m_entry->vsi_list_info->vsi_map)) 6087 return 0; 6088 6089 /* Update the previously created VSI list set with 6090 * the new VSI ID passed in 6091 */ 6092 vsi_list_id = cur_fltr->sw_act.fwd_id.vsi_list_id; 6093 6094 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, 6095 vsi_list_id, false, 6096 ice_aqc_opc_update_sw_rules, 6097 ICE_SW_LKUP_LAST); 6098 /* update VSI list mapping info with new VSI ID */ 6099 if (!status) 6100 set_bit(vsi_handle, m_entry->vsi_list_info->vsi_map); 6101 } 6102 if (!status) 6103 m_entry->vsi_count++; 6104 return status; 6105 } 6106 6107 /** 6108 * ice_add_adv_rule - helper function to create an advanced switch rule 6109 * @hw: pointer to the hardware structure 6110 * @lkups: information on the words that needs to be looked up. All words 6111 * together makes one recipe 6112 * @lkups_cnt: num of entries in the lkups array 6113 * @rinfo: other information related to the rule that needs to be programmed 6114 * @added_entry: this will return recipe_id, rule_id and vsi_handle. should be 6115 * ignored is case of error. 6116 * 6117 * This function can program only 1 rule at a time. The lkups is used to 6118 * describe the all the words that forms the "lookup" portion of the recipe. 6119 * These words can span multiple protocols. Callers to this function need to 6120 * pass in a list of protocol headers with lookup information along and mask 6121 * that determines which words are valid from the given protocol header. 6122 * rinfo describes other information related to this rule such as forwarding 6123 * IDs, priority of this rule, etc. 6124 */ 6125 int 6126 ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 6127 u16 lkups_cnt, struct ice_adv_rule_info *rinfo, 6128 struct ice_rule_query_data *added_entry) 6129 { 6130 struct ice_adv_fltr_mgmt_list_entry *m_entry, *adv_fltr = NULL; 6131 struct ice_sw_rule_lkup_rx_tx *s_rule = NULL; 6132 const struct ice_dummy_pkt_profile *profile; 6133 u16 rid = 0, i, rule_buf_sz, vsi_handle; 6134 struct list_head *rule_head; 6135 struct ice_switch_info *sw; 6136 u16 word_cnt; 6137 u32 act = 0; 6138 int status; 6139 u8 q_rgn; 6140 6141 /* Initialize profile to result index bitmap */ 6142 if (!hw->switch_info->prof_res_bm_init) { 6143 hw->switch_info->prof_res_bm_init = 1; 6144 ice_init_prof_result_bm(hw); 6145 } 6146 6147 if (!lkups_cnt) 6148 return -EINVAL; 6149 6150 /* get # of words we need to match */ 6151 word_cnt = 0; 6152 for (i = 0; i < lkups_cnt; i++) { 6153 u16 j; 6154 6155 for (j = 0; j < ARRAY_SIZE(lkups->m_raw); j++) 6156 if (lkups[i].m_raw[j]) 6157 word_cnt++; 6158 } 6159 6160 if (!word_cnt) 6161 return -EINVAL; 6162 6163 if (word_cnt > ICE_MAX_CHAIN_WORDS) 6164 return -ENOSPC; 6165 6166 /* locate a dummy packet */ 6167 profile = ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type); 6168 if (IS_ERR(profile)) 6169 return PTR_ERR(profile); 6170 6171 if (!(rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI || 6172 rinfo->sw_act.fltr_act == ICE_FWD_TO_Q || 6173 rinfo->sw_act.fltr_act == ICE_FWD_TO_QGRP || 6174 rinfo->sw_act.fltr_act == ICE_DROP_PACKET)) { 6175 status = -EIO; 6176 goto free_pkt_profile; 6177 } 6178 6179 vsi_handle = rinfo->sw_act.vsi_handle; 6180 if (!ice_is_vsi_valid(hw, vsi_handle)) { 6181 status = -EINVAL; 6182 goto free_pkt_profile; 6183 } 6184 6185 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 6186 rinfo->sw_act.fwd_id.hw_vsi_id = 6187 ice_get_hw_vsi_num(hw, vsi_handle); 6188 if (rinfo->sw_act.flag & ICE_FLTR_TX) 6189 rinfo->sw_act.src = ice_get_hw_vsi_num(hw, vsi_handle); 6190 6191 status = ice_add_adv_recipe(hw, lkups, lkups_cnt, rinfo, &rid); 6192 if (status) 6193 goto free_pkt_profile; 6194 m_entry = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 6195 if (m_entry) { 6196 /* we have to add VSI to VSI_LIST and increment vsi_count. 6197 * Also Update VSI list so that we can change forwarding rule 6198 * if the rule already exists, we will check if it exists with 6199 * same vsi_id, if not then add it to the VSI list if it already 6200 * exists if not then create a VSI list and add the existing VSI 6201 * ID and the new VSI ID to the list 6202 * We will add that VSI to the list 6203 */ 6204 status = ice_adv_add_update_vsi_list(hw, m_entry, 6205 &m_entry->rule_info, 6206 rinfo); 6207 if (added_entry) { 6208 added_entry->rid = rid; 6209 added_entry->rule_id = m_entry->rule_info.fltr_rule_id; 6210 added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 6211 } 6212 goto free_pkt_profile; 6213 } 6214 rule_buf_sz = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule, profile->pkt_len); 6215 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 6216 if (!s_rule) { 6217 status = -ENOMEM; 6218 goto free_pkt_profile; 6219 } 6220 if (!rinfo->flags_info.act_valid) { 6221 act |= ICE_SINGLE_ACT_LAN_ENABLE; 6222 act |= ICE_SINGLE_ACT_LB_ENABLE; 6223 } else { 6224 act |= rinfo->flags_info.act & (ICE_SINGLE_ACT_LAN_ENABLE | 6225 ICE_SINGLE_ACT_LB_ENABLE); 6226 } 6227 6228 switch (rinfo->sw_act.fltr_act) { 6229 case ICE_FWD_TO_VSI: 6230 act |= (rinfo->sw_act.fwd_id.hw_vsi_id << 6231 ICE_SINGLE_ACT_VSI_ID_S) & ICE_SINGLE_ACT_VSI_ID_M; 6232 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT; 6233 break; 6234 case ICE_FWD_TO_Q: 6235 act |= ICE_SINGLE_ACT_TO_Q; 6236 act |= (rinfo->sw_act.fwd_id.q_id << ICE_SINGLE_ACT_Q_INDEX_S) & 6237 ICE_SINGLE_ACT_Q_INDEX_M; 6238 break; 6239 case ICE_FWD_TO_QGRP: 6240 q_rgn = rinfo->sw_act.qgrp_size > 0 ? 6241 (u8)ilog2(rinfo->sw_act.qgrp_size) : 0; 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 act |= (q_rgn << ICE_SINGLE_ACT_Q_REGION_S) & 6246 ICE_SINGLE_ACT_Q_REGION_M; 6247 break; 6248 case ICE_DROP_PACKET: 6249 act |= ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_DROP | 6250 ICE_SINGLE_ACT_VALID_BIT; 6251 break; 6252 default: 6253 status = -EIO; 6254 goto err_ice_add_adv_rule; 6255 } 6256 6257 /* set the rule LOOKUP type based on caller specified 'Rx' 6258 * instead of hardcoding it to be either LOOKUP_TX/RX 6259 * 6260 * for 'Rx' set the source to be the port number 6261 * for 'Tx' set the source to be the source HW VSI number (determined 6262 * by caller) 6263 */ 6264 if (rinfo->rx) { 6265 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX); 6266 s_rule->src = cpu_to_le16(hw->port_info->lport); 6267 } else { 6268 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX); 6269 s_rule->src = cpu_to_le16(rinfo->sw_act.src); 6270 } 6271 6272 s_rule->recipe_id = cpu_to_le16(rid); 6273 s_rule->act = cpu_to_le32(act); 6274 6275 status = ice_fill_adv_dummy_packet(lkups, lkups_cnt, s_rule, profile); 6276 if (status) 6277 goto err_ice_add_adv_rule; 6278 6279 if (rinfo->tun_type != ICE_NON_TUN && 6280 rinfo->tun_type != ICE_SW_TUN_AND_NON_TUN) { 6281 status = ice_fill_adv_packet_tun(hw, rinfo->tun_type, 6282 s_rule->hdr_data, 6283 profile->offsets); 6284 if (status) 6285 goto err_ice_add_adv_rule; 6286 } 6287 6288 if (rinfo->vlan_type != 0 && ice_is_dvm_ena(hw)) { 6289 status = ice_fill_adv_packet_vlan(rinfo->vlan_type, 6290 s_rule->hdr_data, 6291 profile->offsets); 6292 if (status) 6293 goto err_ice_add_adv_rule; 6294 } 6295 6296 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 6297 rule_buf_sz, 1, ice_aqc_opc_add_sw_rules, 6298 NULL); 6299 if (status) 6300 goto err_ice_add_adv_rule; 6301 adv_fltr = devm_kzalloc(ice_hw_to_dev(hw), 6302 sizeof(struct ice_adv_fltr_mgmt_list_entry), 6303 GFP_KERNEL); 6304 if (!adv_fltr) { 6305 status = -ENOMEM; 6306 goto err_ice_add_adv_rule; 6307 } 6308 6309 adv_fltr->lkups = devm_kmemdup(ice_hw_to_dev(hw), lkups, 6310 lkups_cnt * sizeof(*lkups), GFP_KERNEL); 6311 if (!adv_fltr->lkups) { 6312 status = -ENOMEM; 6313 goto err_ice_add_adv_rule; 6314 } 6315 6316 adv_fltr->lkups_cnt = lkups_cnt; 6317 adv_fltr->rule_info = *rinfo; 6318 adv_fltr->rule_info.fltr_rule_id = le16_to_cpu(s_rule->index); 6319 sw = hw->switch_info; 6320 sw->recp_list[rid].adv_rule = true; 6321 rule_head = &sw->recp_list[rid].filt_rules; 6322 6323 if (rinfo->sw_act.fltr_act == ICE_FWD_TO_VSI) 6324 adv_fltr->vsi_count = 1; 6325 6326 /* Add rule entry to book keeping list */ 6327 list_add(&adv_fltr->list_entry, rule_head); 6328 if (added_entry) { 6329 added_entry->rid = rid; 6330 added_entry->rule_id = adv_fltr->rule_info.fltr_rule_id; 6331 added_entry->vsi_handle = rinfo->sw_act.vsi_handle; 6332 } 6333 err_ice_add_adv_rule: 6334 if (status && adv_fltr) { 6335 devm_kfree(ice_hw_to_dev(hw), adv_fltr->lkups); 6336 devm_kfree(ice_hw_to_dev(hw), adv_fltr); 6337 } 6338 6339 kfree(s_rule); 6340 6341 free_pkt_profile: 6342 if (profile->match & ICE_PKT_KMALLOC) { 6343 kfree(profile->offsets); 6344 kfree(profile->pkt); 6345 kfree(profile); 6346 } 6347 6348 return status; 6349 } 6350 6351 /** 6352 * ice_replay_vsi_fltr - Replay filters for requested VSI 6353 * @hw: pointer to the hardware structure 6354 * @vsi_handle: driver VSI handle 6355 * @recp_id: Recipe ID for which rules need to be replayed 6356 * @list_head: list for which filters need to be replayed 6357 * 6358 * Replays the filter of recipe recp_id for a VSI represented via vsi_handle. 6359 * It is required to pass valid VSI handle. 6360 */ 6361 static int 6362 ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, 6363 struct list_head *list_head) 6364 { 6365 struct ice_fltr_mgmt_list_entry *itr; 6366 int status = 0; 6367 u16 hw_vsi_id; 6368 6369 if (list_empty(list_head)) 6370 return status; 6371 hw_vsi_id = ice_get_hw_vsi_num(hw, vsi_handle); 6372 6373 list_for_each_entry(itr, list_head, list_entry) { 6374 struct ice_fltr_list_entry f_entry; 6375 6376 f_entry.fltr_info = itr->fltr_info; 6377 if (itr->vsi_count < 2 && recp_id != ICE_SW_LKUP_VLAN && 6378 itr->fltr_info.vsi_handle == vsi_handle) { 6379 /* update the src in case it is VSI num */ 6380 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6381 f_entry.fltr_info.src = hw_vsi_id; 6382 status = ice_add_rule_internal(hw, recp_id, &f_entry); 6383 if (status) 6384 goto end; 6385 continue; 6386 } 6387 if (!itr->vsi_list_info || 6388 !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) 6389 continue; 6390 /* Clearing it so that the logic can add it back */ 6391 clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); 6392 f_entry.fltr_info.vsi_handle = vsi_handle; 6393 f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; 6394 /* update the src in case it is VSI num */ 6395 if (f_entry.fltr_info.src_id == ICE_SRC_ID_VSI) 6396 f_entry.fltr_info.src = hw_vsi_id; 6397 if (recp_id == ICE_SW_LKUP_VLAN) 6398 status = ice_add_vlan_internal(hw, &f_entry); 6399 else 6400 status = ice_add_rule_internal(hw, recp_id, &f_entry); 6401 if (status) 6402 goto end; 6403 } 6404 end: 6405 return status; 6406 } 6407 6408 /** 6409 * ice_adv_rem_update_vsi_list 6410 * @hw: pointer to the hardware structure 6411 * @vsi_handle: VSI handle of the VSI to remove 6412 * @fm_list: filter management entry for which the VSI list management needs to 6413 * be done 6414 */ 6415 static int 6416 ice_adv_rem_update_vsi_list(struct ice_hw *hw, u16 vsi_handle, 6417 struct ice_adv_fltr_mgmt_list_entry *fm_list) 6418 { 6419 struct ice_vsi_list_map_info *vsi_list_info; 6420 enum ice_sw_lkup_type lkup_type; 6421 u16 vsi_list_id; 6422 int status; 6423 6424 if (fm_list->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST || 6425 fm_list->vsi_count == 0) 6426 return -EINVAL; 6427 6428 /* A rule with the VSI being removed does not exist */ 6429 if (!test_bit(vsi_handle, fm_list->vsi_list_info->vsi_map)) 6430 return -ENOENT; 6431 6432 lkup_type = ICE_SW_LKUP_LAST; 6433 vsi_list_id = fm_list->rule_info.sw_act.fwd_id.vsi_list_id; 6434 status = ice_update_vsi_list_rule(hw, &vsi_handle, 1, vsi_list_id, true, 6435 ice_aqc_opc_update_sw_rules, 6436 lkup_type); 6437 if (status) 6438 return status; 6439 6440 fm_list->vsi_count--; 6441 clear_bit(vsi_handle, fm_list->vsi_list_info->vsi_map); 6442 vsi_list_info = fm_list->vsi_list_info; 6443 if (fm_list->vsi_count == 1) { 6444 struct ice_fltr_info tmp_fltr; 6445 u16 rem_vsi_handle; 6446 6447 rem_vsi_handle = find_first_bit(vsi_list_info->vsi_map, 6448 ICE_MAX_VSI); 6449 if (!ice_is_vsi_valid(hw, rem_vsi_handle)) 6450 return -EIO; 6451 6452 /* Make sure VSI list is empty before removing it below */ 6453 status = ice_update_vsi_list_rule(hw, &rem_vsi_handle, 1, 6454 vsi_list_id, true, 6455 ice_aqc_opc_update_sw_rules, 6456 lkup_type); 6457 if (status) 6458 return status; 6459 6460 memset(&tmp_fltr, 0, sizeof(tmp_fltr)); 6461 tmp_fltr.flag = fm_list->rule_info.sw_act.flag; 6462 tmp_fltr.fltr_rule_id = fm_list->rule_info.fltr_rule_id; 6463 fm_list->rule_info.sw_act.fltr_act = ICE_FWD_TO_VSI; 6464 tmp_fltr.fltr_act = ICE_FWD_TO_VSI; 6465 tmp_fltr.fwd_id.hw_vsi_id = 6466 ice_get_hw_vsi_num(hw, rem_vsi_handle); 6467 fm_list->rule_info.sw_act.fwd_id.hw_vsi_id = 6468 ice_get_hw_vsi_num(hw, rem_vsi_handle); 6469 fm_list->rule_info.sw_act.vsi_handle = rem_vsi_handle; 6470 6471 /* Update the previous switch rule of "MAC forward to VSI" to 6472 * "MAC fwd to VSI list" 6473 */ 6474 status = ice_update_pkt_fwd_rule(hw, &tmp_fltr); 6475 if (status) { 6476 ice_debug(hw, ICE_DBG_SW, "Failed to update pkt fwd rule to FWD_TO_VSI on HW VSI %d, error %d\n", 6477 tmp_fltr.fwd_id.hw_vsi_id, status); 6478 return status; 6479 } 6480 fm_list->vsi_list_info->ref_cnt--; 6481 6482 /* Remove the VSI list since it is no longer used */ 6483 status = ice_remove_vsi_list_rule(hw, vsi_list_id, lkup_type); 6484 if (status) { 6485 ice_debug(hw, ICE_DBG_SW, "Failed to remove VSI list %d, error %d\n", 6486 vsi_list_id, status); 6487 return status; 6488 } 6489 6490 list_del(&vsi_list_info->list_entry); 6491 devm_kfree(ice_hw_to_dev(hw), vsi_list_info); 6492 fm_list->vsi_list_info = NULL; 6493 } 6494 6495 return status; 6496 } 6497 6498 /** 6499 * ice_rem_adv_rule - removes existing advanced switch rule 6500 * @hw: pointer to the hardware structure 6501 * @lkups: information on the words that needs to be looked up. All words 6502 * together makes one recipe 6503 * @lkups_cnt: num of entries in the lkups array 6504 * @rinfo: Its the pointer to the rule information for the rule 6505 * 6506 * This function can be used to remove 1 rule at a time. The lkups is 6507 * used to describe all the words that forms the "lookup" portion of the 6508 * rule. These words can span multiple protocols. Callers to this function 6509 * need to pass in a list of protocol headers with lookup information along 6510 * and mask that determines which words are valid from the given protocol 6511 * header. rinfo describes other information related to this rule such as 6512 * forwarding IDs, priority of this rule, etc. 6513 */ 6514 static int 6515 ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, 6516 u16 lkups_cnt, struct ice_adv_rule_info *rinfo) 6517 { 6518 struct ice_adv_fltr_mgmt_list_entry *list_elem; 6519 struct ice_prot_lkup_ext lkup_exts; 6520 bool remove_rule = false; 6521 struct mutex *rule_lock; /* Lock to protect filter rule list */ 6522 u16 i, rid, vsi_handle; 6523 int status = 0; 6524 6525 memset(&lkup_exts, 0, sizeof(lkup_exts)); 6526 for (i = 0; i < lkups_cnt; i++) { 6527 u16 count; 6528 6529 if (lkups[i].type >= ICE_PROTOCOL_LAST) 6530 return -EIO; 6531 6532 count = ice_fill_valid_words(&lkups[i], &lkup_exts); 6533 if (!count) 6534 return -EIO; 6535 } 6536 6537 /* Create any special protocol/offset pairs, such as looking at tunnel 6538 * bits by extracting metadata 6539 */ 6540 status = ice_add_special_words(rinfo, &lkup_exts, ice_is_dvm_ena(hw)); 6541 if (status) 6542 return status; 6543 6544 rid = ice_find_recp(hw, &lkup_exts, rinfo->tun_type); 6545 /* If did not find a recipe that match the existing criteria */ 6546 if (rid == ICE_MAX_NUM_RECIPES) 6547 return -EINVAL; 6548 6549 rule_lock = &hw->switch_info->recp_list[rid].filt_rule_lock; 6550 list_elem = ice_find_adv_rule_entry(hw, lkups, lkups_cnt, rid, rinfo); 6551 /* the rule is already removed */ 6552 if (!list_elem) 6553 return 0; 6554 mutex_lock(rule_lock); 6555 if (list_elem->rule_info.sw_act.fltr_act != ICE_FWD_TO_VSI_LIST) { 6556 remove_rule = true; 6557 } else if (list_elem->vsi_count > 1) { 6558 remove_rule = false; 6559 vsi_handle = rinfo->sw_act.vsi_handle; 6560 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 6561 } else { 6562 vsi_handle = rinfo->sw_act.vsi_handle; 6563 status = ice_adv_rem_update_vsi_list(hw, vsi_handle, list_elem); 6564 if (status) { 6565 mutex_unlock(rule_lock); 6566 return status; 6567 } 6568 if (list_elem->vsi_count == 0) 6569 remove_rule = true; 6570 } 6571 mutex_unlock(rule_lock); 6572 if (remove_rule) { 6573 struct ice_sw_rule_lkup_rx_tx *s_rule; 6574 u16 rule_buf_sz; 6575 6576 rule_buf_sz = ICE_SW_RULE_RX_TX_NO_HDR_SIZE(s_rule); 6577 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL); 6578 if (!s_rule) 6579 return -ENOMEM; 6580 s_rule->act = 0; 6581 s_rule->index = cpu_to_le16(list_elem->rule_info.fltr_rule_id); 6582 s_rule->hdr_len = 0; 6583 status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, 6584 rule_buf_sz, 1, 6585 ice_aqc_opc_remove_sw_rules, NULL); 6586 if (!status || status == -ENOENT) { 6587 struct ice_switch_info *sw = hw->switch_info; 6588 6589 mutex_lock(rule_lock); 6590 list_del(&list_elem->list_entry); 6591 devm_kfree(ice_hw_to_dev(hw), list_elem->lkups); 6592 devm_kfree(ice_hw_to_dev(hw), list_elem); 6593 mutex_unlock(rule_lock); 6594 if (list_empty(&sw->recp_list[rid].filt_rules)) 6595 sw->recp_list[rid].adv_rule = false; 6596 } 6597 kfree(s_rule); 6598 } 6599 return status; 6600 } 6601 6602 /** 6603 * ice_rem_adv_rule_by_id - removes existing advanced switch rule by ID 6604 * @hw: pointer to the hardware structure 6605 * @remove_entry: data struct which holds rule_id, VSI handle and recipe ID 6606 * 6607 * This function is used to remove 1 rule at a time. The removal is based on 6608 * the remove_entry parameter. This function will remove rule for a given 6609 * vsi_handle with a given rule_id which is passed as parameter in remove_entry 6610 */ 6611 int 6612 ice_rem_adv_rule_by_id(struct ice_hw *hw, 6613 struct ice_rule_query_data *remove_entry) 6614 { 6615 struct ice_adv_fltr_mgmt_list_entry *list_itr; 6616 struct list_head *list_head; 6617 struct ice_adv_rule_info rinfo; 6618 struct ice_switch_info *sw; 6619 6620 sw = hw->switch_info; 6621 if (!sw->recp_list[remove_entry->rid].recp_created) 6622 return -EINVAL; 6623 list_head = &sw->recp_list[remove_entry->rid].filt_rules; 6624 list_for_each_entry(list_itr, list_head, list_entry) { 6625 if (list_itr->rule_info.fltr_rule_id == 6626 remove_entry->rule_id) { 6627 rinfo = list_itr->rule_info; 6628 rinfo.sw_act.vsi_handle = remove_entry->vsi_handle; 6629 return ice_rem_adv_rule(hw, list_itr->lkups, 6630 list_itr->lkups_cnt, &rinfo); 6631 } 6632 } 6633 /* either list is empty or unable to find rule */ 6634 return -ENOENT; 6635 } 6636 6637 /** 6638 * ice_rem_adv_rule_for_vsi - removes existing advanced switch rules for a 6639 * given VSI handle 6640 * @hw: pointer to the hardware structure 6641 * @vsi_handle: VSI handle for which we are supposed to remove all the rules. 6642 * 6643 * This function is used to remove all the rules for a given VSI and as soon 6644 * as removing a rule fails, it will return immediately with the error code, 6645 * else it will return success. 6646 */ 6647 int ice_rem_adv_rule_for_vsi(struct ice_hw *hw, u16 vsi_handle) 6648 { 6649 struct ice_adv_fltr_mgmt_list_entry *list_itr, *tmp_entry; 6650 struct ice_vsi_list_map_info *map_info; 6651 struct ice_adv_rule_info rinfo; 6652 struct list_head *list_head; 6653 struct ice_switch_info *sw; 6654 int status; 6655 u8 rid; 6656 6657 sw = hw->switch_info; 6658 for (rid = 0; rid < ICE_MAX_NUM_RECIPES; rid++) { 6659 if (!sw->recp_list[rid].recp_created) 6660 continue; 6661 if (!sw->recp_list[rid].adv_rule) 6662 continue; 6663 6664 list_head = &sw->recp_list[rid].filt_rules; 6665 list_for_each_entry_safe(list_itr, tmp_entry, list_head, 6666 list_entry) { 6667 rinfo = list_itr->rule_info; 6668 6669 if (rinfo.sw_act.fltr_act == ICE_FWD_TO_VSI_LIST) { 6670 map_info = list_itr->vsi_list_info; 6671 if (!map_info) 6672 continue; 6673 6674 if (!test_bit(vsi_handle, map_info->vsi_map)) 6675 continue; 6676 } else if (rinfo.sw_act.vsi_handle != vsi_handle) { 6677 continue; 6678 } 6679 6680 rinfo.sw_act.vsi_handle = vsi_handle; 6681 status = ice_rem_adv_rule(hw, list_itr->lkups, 6682 list_itr->lkups_cnt, &rinfo); 6683 if (status) 6684 return status; 6685 } 6686 } 6687 return 0; 6688 } 6689 6690 /** 6691 * ice_replay_vsi_adv_rule - Replay advanced rule for requested VSI 6692 * @hw: pointer to the hardware structure 6693 * @vsi_handle: driver VSI handle 6694 * @list_head: list for which filters need to be replayed 6695 * 6696 * Replay the advanced rule for the given VSI. 6697 */ 6698 static int 6699 ice_replay_vsi_adv_rule(struct ice_hw *hw, u16 vsi_handle, 6700 struct list_head *list_head) 6701 { 6702 struct ice_rule_query_data added_entry = { 0 }; 6703 struct ice_adv_fltr_mgmt_list_entry *adv_fltr; 6704 int status = 0; 6705 6706 if (list_empty(list_head)) 6707 return status; 6708 list_for_each_entry(adv_fltr, list_head, list_entry) { 6709 struct ice_adv_rule_info *rinfo = &adv_fltr->rule_info; 6710 u16 lk_cnt = adv_fltr->lkups_cnt; 6711 6712 if (vsi_handle != rinfo->sw_act.vsi_handle) 6713 continue; 6714 status = ice_add_adv_rule(hw, adv_fltr->lkups, lk_cnt, rinfo, 6715 &added_entry); 6716 if (status) 6717 break; 6718 } 6719 return status; 6720 } 6721 6722 /** 6723 * ice_replay_vsi_all_fltr - replay all filters stored in bookkeeping lists 6724 * @hw: pointer to the hardware structure 6725 * @vsi_handle: driver VSI handle 6726 * 6727 * Replays filters for requested VSI via vsi_handle. 6728 */ 6729 int ice_replay_vsi_all_fltr(struct ice_hw *hw, u16 vsi_handle) 6730 { 6731 struct ice_switch_info *sw = hw->switch_info; 6732 int status; 6733 u8 i; 6734 6735 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6736 struct list_head *head; 6737 6738 head = &sw->recp_list[i].filt_replay_rules; 6739 if (!sw->recp_list[i].adv_rule) 6740 status = ice_replay_vsi_fltr(hw, vsi_handle, i, head); 6741 else 6742 status = ice_replay_vsi_adv_rule(hw, vsi_handle, head); 6743 if (status) 6744 return status; 6745 } 6746 return status; 6747 } 6748 6749 /** 6750 * ice_rm_all_sw_replay_rule_info - deletes filter replay rules 6751 * @hw: pointer to the HW struct 6752 * 6753 * Deletes the filter replay rules. 6754 */ 6755 void ice_rm_all_sw_replay_rule_info(struct ice_hw *hw) 6756 { 6757 struct ice_switch_info *sw = hw->switch_info; 6758 u8 i; 6759 6760 if (!sw) 6761 return; 6762 6763 for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { 6764 if (!list_empty(&sw->recp_list[i].filt_replay_rules)) { 6765 struct list_head *l_head; 6766 6767 l_head = &sw->recp_list[i].filt_replay_rules; 6768 if (!sw->recp_list[i].adv_rule) 6769 ice_rem_sw_rule_info(hw, l_head); 6770 else 6771 ice_rem_adv_rule_info(hw, l_head); 6772 } 6773 } 6774 } 6775