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