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