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