1 /*- 2 * Copyright (c) 2015 Mellanox Technologies. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 * $FreeBSD$ 26 */ 27 28 #include "en.h" 29 30 #include <linux/list.h> 31 #include <dev/mlx5/fs.h> 32 33 #define MLX5_SET_CFG(p, f, v) MLX5_SET(create_flow_group_in, p, f, v) 34 35 enum { 36 MLX5E_FULLMATCH = 0, 37 MLX5E_ALLMULTI = 1, 38 MLX5E_PROMISC = 2, 39 }; 40 41 enum { 42 MLX5E_UC = 0, 43 MLX5E_MC_IPV4 = 1, 44 MLX5E_MC_IPV6 = 2, 45 MLX5E_MC_OTHER = 3, 46 }; 47 48 enum { 49 MLX5E_ACTION_NONE = 0, 50 MLX5E_ACTION_ADD = 1, 51 MLX5E_ACTION_DEL = 2, 52 }; 53 54 struct mlx5e_eth_addr_hash_node { 55 LIST_ENTRY(mlx5e_eth_addr_hash_node) hlist; 56 u8 action; 57 struct mlx5e_eth_addr_info ai; 58 }; 59 60 static inline int 61 mlx5e_hash_eth_addr(const u8 * addr) 62 { 63 return (addr[5]); 64 } 65 66 static void 67 mlx5e_add_eth_addr_to_hash(struct mlx5e_eth_addr_hash_head *hash, 68 const u8 * addr) 69 { 70 struct mlx5e_eth_addr_hash_node *hn; 71 int ix = mlx5e_hash_eth_addr(addr); 72 73 LIST_FOREACH(hn, &hash[ix], hlist) { 74 if (bcmp(hn->ai.addr, addr, ETHER_ADDR_LEN) == 0) { 75 if (hn->action == MLX5E_ACTION_DEL) 76 hn->action = MLX5E_ACTION_NONE; 77 return; 78 } 79 } 80 81 hn = malloc(sizeof(*hn), M_MLX5EN, M_NOWAIT | M_ZERO); 82 if (hn == NULL) 83 return; 84 85 ether_addr_copy(hn->ai.addr, addr); 86 hn->action = MLX5E_ACTION_ADD; 87 88 LIST_INSERT_HEAD(&hash[ix], hn, hlist); 89 } 90 91 static void 92 mlx5e_del_eth_addr_from_hash(struct mlx5e_eth_addr_hash_node *hn) 93 { 94 LIST_REMOVE(hn, hlist); 95 free(hn, M_MLX5EN); 96 } 97 98 static void 99 mlx5e_del_eth_addr_from_flow_table(struct mlx5e_priv *priv, 100 struct mlx5e_eth_addr_info *ai) 101 { 102 if (ai->tt_vec & (1 << MLX5E_TT_IPV6_IPSEC_ESP)) 103 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV6_IPSEC_ESP]); 104 105 if (ai->tt_vec & (1 << MLX5E_TT_IPV4_IPSEC_ESP)) 106 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV4_IPSEC_ESP]); 107 108 if (ai->tt_vec & (1 << MLX5E_TT_IPV6_IPSEC_AH)) 109 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV6_IPSEC_AH]); 110 111 if (ai->tt_vec & (1 << MLX5E_TT_IPV4_IPSEC_AH)) 112 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV4_IPSEC_AH]); 113 114 if (ai->tt_vec & (1 << MLX5E_TT_IPV6_TCP)) 115 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV6_TCP]); 116 117 if (ai->tt_vec & (1 << MLX5E_TT_IPV4_TCP)) 118 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV4_TCP]); 119 120 if (ai->tt_vec & (1 << MLX5E_TT_IPV6_UDP)) 121 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV6_UDP]); 122 123 if (ai->tt_vec & (1 << MLX5E_TT_IPV4_UDP)) 124 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV4_UDP]); 125 126 if (ai->tt_vec & (1 << MLX5E_TT_IPV6)) 127 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV6]); 128 129 if (ai->tt_vec & (1 << MLX5E_TT_IPV4)) 130 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_IPV4]); 131 132 if (ai->tt_vec & (1 << MLX5E_TT_ANY)) 133 mlx5_del_flow_rule(ai->ft_rule[MLX5E_TT_ANY]); 134 135 /* ensure the rules are not freed again */ 136 ai->tt_vec = 0; 137 } 138 139 static int 140 mlx5e_get_eth_addr_type(const u8 * addr) 141 { 142 if (ETHER_IS_MULTICAST(addr) == 0) 143 return (MLX5E_UC); 144 145 if ((addr[0] == 0x01) && 146 (addr[1] == 0x00) && 147 (addr[2] == 0x5e) && 148 !(addr[3] & 0x80)) 149 return (MLX5E_MC_IPV4); 150 151 if ((addr[0] == 0x33) && 152 (addr[1] == 0x33)) 153 return (MLX5E_MC_IPV6); 154 155 return (MLX5E_MC_OTHER); 156 } 157 158 static u32 159 mlx5e_get_tt_vec(struct mlx5e_eth_addr_info *ai, int type) 160 { 161 int eth_addr_type; 162 u32 ret; 163 164 switch (type) { 165 case MLX5E_FULLMATCH: 166 eth_addr_type = mlx5e_get_eth_addr_type(ai->addr); 167 switch (eth_addr_type) { 168 case MLX5E_UC: 169 ret = 170 (1 << MLX5E_TT_IPV4_TCP) | 171 (1 << MLX5E_TT_IPV6_TCP) | 172 (1 << MLX5E_TT_IPV4_UDP) | 173 (1 << MLX5E_TT_IPV6_UDP) | 174 (1 << MLX5E_TT_IPV4) | 175 (1 << MLX5E_TT_IPV6) | 176 (1 << MLX5E_TT_ANY) | 177 0; 178 break; 179 180 case MLX5E_MC_IPV4: 181 ret = 182 (1 << MLX5E_TT_IPV4_UDP) | 183 (1 << MLX5E_TT_IPV4) | 184 0; 185 break; 186 187 case MLX5E_MC_IPV6: 188 ret = 189 (1 << MLX5E_TT_IPV6_UDP) | 190 (1 << MLX5E_TT_IPV6) | 191 0; 192 break; 193 194 default: 195 ret = 196 (1 << MLX5E_TT_ANY) | 197 0; 198 break; 199 } 200 break; 201 202 case MLX5E_ALLMULTI: 203 ret = 204 (1 << MLX5E_TT_IPV4_UDP) | 205 (1 << MLX5E_TT_IPV6_UDP) | 206 (1 << MLX5E_TT_IPV4) | 207 (1 << MLX5E_TT_IPV6) | 208 (1 << MLX5E_TT_ANY) | 209 0; 210 break; 211 212 default: /* MLX5E_PROMISC */ 213 ret = 214 (1 << MLX5E_TT_IPV4_TCP) | 215 (1 << MLX5E_TT_IPV6_TCP) | 216 (1 << MLX5E_TT_IPV4_UDP) | 217 (1 << MLX5E_TT_IPV6_UDP) | 218 (1 << MLX5E_TT_IPV4) | 219 (1 << MLX5E_TT_IPV6) | 220 (1 << MLX5E_TT_ANY) | 221 0; 222 break; 223 } 224 225 return (ret); 226 } 227 228 static int 229 mlx5e_add_eth_addr_rule_sub(struct mlx5e_priv *priv, 230 struct mlx5e_eth_addr_info *ai, int type, 231 u32 *mc, u32 *mv) 232 { 233 struct mlx5_flow_destination dest = {}; 234 u8 mc_enable = 0; 235 struct mlx5_flow_rule **rule_p; 236 struct mlx5_flow_table *ft = priv->fts.main.t; 237 u8 *mc_dmac = MLX5_ADDR_OF(fte_match_param, mc, 238 outer_headers.dmac_47_16); 239 u8 *mv_dmac = MLX5_ADDR_OF(fte_match_param, mv, 240 outer_headers.dmac_47_16); 241 u32 *tirn = priv->tirn; 242 u32 tt_vec; 243 int err = 0; 244 245 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; 246 247 switch (type) { 248 case MLX5E_FULLMATCH: 249 mc_enable = MLX5_MATCH_OUTER_HEADERS; 250 memset(mc_dmac, 0xff, ETH_ALEN); 251 ether_addr_copy(mv_dmac, ai->addr); 252 break; 253 254 case MLX5E_ALLMULTI: 255 mc_enable = MLX5_MATCH_OUTER_HEADERS; 256 mc_dmac[0] = 0x01; 257 mv_dmac[0] = 0x01; 258 break; 259 260 case MLX5E_PROMISC: 261 break; 262 default: 263 break; 264 } 265 266 tt_vec = mlx5e_get_tt_vec(ai, type); 267 268 if (tt_vec & BIT(MLX5E_TT_ANY)) { 269 rule_p = &ai->ft_rule[MLX5E_TT_ANY]; 270 dest.tir_num = tirn[MLX5E_TT_ANY]; 271 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 272 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 273 MLX5_FS_ETH_FLOW_TAG, &dest); 274 if (IS_ERR_OR_NULL(*rule_p)) 275 goto err_del_ai; 276 ai->tt_vec |= BIT(MLX5E_TT_ANY); 277 } 278 279 mc_enable = MLX5_MATCH_OUTER_HEADERS; 280 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 281 282 if (tt_vec & BIT(MLX5E_TT_IPV4)) { 283 rule_p = &ai->ft_rule[MLX5E_TT_IPV4]; 284 dest.tir_num = tirn[MLX5E_TT_IPV4]; 285 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 286 ETHERTYPE_IP); 287 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 288 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 289 MLX5_FS_ETH_FLOW_TAG, &dest); 290 if (IS_ERR_OR_NULL(*rule_p)) 291 goto err_del_ai; 292 ai->tt_vec |= BIT(MLX5E_TT_IPV4); 293 } 294 295 if (tt_vec & BIT(MLX5E_TT_IPV6)) { 296 rule_p = &ai->ft_rule[MLX5E_TT_IPV6]; 297 dest.tir_num = tirn[MLX5E_TT_IPV6]; 298 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 299 ETHERTYPE_IPV6); 300 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 301 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 302 MLX5_FS_ETH_FLOW_TAG, &dest); 303 if (IS_ERR_OR_NULL(*rule_p)) 304 goto err_del_ai; 305 ai->tt_vec |= BIT(MLX5E_TT_IPV6); 306 } 307 308 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol); 309 MLX5_SET(fte_match_param, mv, outer_headers.ip_protocol, IPPROTO_UDP); 310 311 if (tt_vec & BIT(MLX5E_TT_IPV4_UDP)) { 312 rule_p = &ai->ft_rule[MLX5E_TT_IPV4_UDP]; 313 dest.tir_num = tirn[MLX5E_TT_IPV4_UDP]; 314 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 315 ETHERTYPE_IP); 316 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 317 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 318 MLX5_FS_ETH_FLOW_TAG, &dest); 319 if (IS_ERR_OR_NULL(*rule_p)) 320 goto err_del_ai; 321 ai->tt_vec |= BIT(MLX5E_TT_IPV4_UDP); 322 } 323 324 if (tt_vec & BIT(MLX5E_TT_IPV6_UDP)) { 325 rule_p = &ai->ft_rule[MLX5E_TT_IPV6_UDP]; 326 dest.tir_num = tirn[MLX5E_TT_IPV6_UDP]; 327 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 328 ETHERTYPE_IPV6); 329 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 330 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 331 MLX5_FS_ETH_FLOW_TAG, &dest); 332 if (IS_ERR_OR_NULL(*rule_p)) 333 goto err_del_ai; 334 ai->tt_vec |= BIT(MLX5E_TT_IPV6_UDP); 335 } 336 337 MLX5_SET(fte_match_param, mv, outer_headers.ip_protocol, IPPROTO_TCP); 338 339 if (tt_vec & BIT(MLX5E_TT_IPV4_TCP)) { 340 rule_p = &ai->ft_rule[MLX5E_TT_IPV4_TCP]; 341 dest.tir_num = tirn[MLX5E_TT_IPV4_TCP]; 342 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 343 ETHERTYPE_IP); 344 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 345 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 346 MLX5_FS_ETH_FLOW_TAG, &dest); 347 if (IS_ERR_OR_NULL(*rule_p)) 348 goto err_del_ai; 349 ai->tt_vec |= BIT(MLX5E_TT_IPV4_TCP); 350 } 351 352 if (tt_vec & BIT(MLX5E_TT_IPV6_TCP)) { 353 rule_p = &ai->ft_rule[MLX5E_TT_IPV6_TCP]; 354 dest.tir_num = tirn[MLX5E_TT_IPV6_TCP]; 355 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 356 ETHERTYPE_IPV6); 357 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 358 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 359 MLX5_FS_ETH_FLOW_TAG, &dest); 360 if (IS_ERR_OR_NULL(*rule_p)) 361 goto err_del_ai; 362 363 ai->tt_vec |= BIT(MLX5E_TT_IPV6_TCP); 364 } 365 366 MLX5_SET(fte_match_param, mv, outer_headers.ip_protocol, IPPROTO_AH); 367 368 if (tt_vec & BIT(MLX5E_TT_IPV4_IPSEC_AH)) { 369 rule_p = &ai->ft_rule[MLX5E_TT_IPV4_IPSEC_AH]; 370 dest.tir_num = tirn[MLX5E_TT_IPV4_IPSEC_AH]; 371 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 372 ETHERTYPE_IP); 373 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 374 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 375 MLX5_FS_ETH_FLOW_TAG, &dest); 376 if (IS_ERR_OR_NULL(*rule_p)) 377 goto err_del_ai; 378 ai->tt_vec |= BIT(MLX5E_TT_IPV4_IPSEC_AH); 379 } 380 381 if (tt_vec & BIT(MLX5E_TT_IPV6_IPSEC_AH)) { 382 rule_p = &ai->ft_rule[MLX5E_TT_IPV6_IPSEC_AH]; 383 dest.tir_num = tirn[MLX5E_TT_IPV6_IPSEC_AH]; 384 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 385 ETHERTYPE_IPV6); 386 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 387 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 388 MLX5_FS_ETH_FLOW_TAG, &dest); 389 if (IS_ERR_OR_NULL(*rule_p)) 390 goto err_del_ai; 391 ai->tt_vec |= BIT(MLX5E_TT_IPV6_IPSEC_AH); 392 } 393 394 MLX5_SET(fte_match_param, mv, outer_headers.ip_protocol, IPPROTO_ESP); 395 396 if (tt_vec & BIT(MLX5E_TT_IPV4_IPSEC_ESP)) { 397 rule_p = &ai->ft_rule[MLX5E_TT_IPV4_IPSEC_ESP]; 398 dest.tir_num = tirn[MLX5E_TT_IPV4_IPSEC_ESP]; 399 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 400 ETHERTYPE_IP); 401 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 402 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 403 MLX5_FS_ETH_FLOW_TAG, &dest); 404 if (IS_ERR_OR_NULL(*rule_p)) 405 goto err_del_ai; 406 ai->tt_vec |= BIT(MLX5E_TT_IPV4_IPSEC_ESP); 407 } 408 409 if (tt_vec & BIT(MLX5E_TT_IPV6_IPSEC_ESP)) { 410 rule_p = &ai->ft_rule[MLX5E_TT_IPV6_IPSEC_ESP]; 411 dest.tir_num = tirn[MLX5E_TT_IPV6_IPSEC_ESP]; 412 MLX5_SET(fte_match_param, mv, outer_headers.ethertype, 413 ETHERTYPE_IPV6); 414 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 415 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 416 MLX5_FS_ETH_FLOW_TAG, &dest); 417 if (IS_ERR_OR_NULL(*rule_p)) 418 goto err_del_ai; 419 ai->tt_vec |= BIT(MLX5E_TT_IPV6_IPSEC_ESP); 420 } 421 422 return 0; 423 424 err_del_ai: 425 err = PTR_ERR(*rule_p); 426 *rule_p = NULL; 427 mlx5e_del_eth_addr_from_flow_table(priv, ai); 428 429 return err; 430 } 431 432 static int 433 mlx5e_add_eth_addr_rule(struct mlx5e_priv *priv, 434 struct mlx5e_eth_addr_info *ai, int type) 435 { 436 u32 *match_criteria; 437 u32 *match_value; 438 int err = 0; 439 440 match_value = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param)); 441 match_criteria = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param)); 442 if (!match_value || !match_criteria) { 443 if_printf(priv->ifp, "%s: alloc failed\n", __func__); 444 err = -ENOMEM; 445 goto add_eth_addr_rule_out; 446 } 447 err = mlx5e_add_eth_addr_rule_sub(priv, ai, type, match_criteria, 448 match_value); 449 450 add_eth_addr_rule_out: 451 kvfree(match_criteria); 452 kvfree(match_value); 453 454 return (err); 455 } 456 457 static int mlx5e_vport_context_update_vlans(struct mlx5e_priv *priv) 458 { 459 struct ifnet *ifp = priv->ifp; 460 int max_list_size; 461 int list_size; 462 u16 *vlans; 463 int vlan; 464 int err; 465 int i; 466 467 list_size = 0; 468 for_each_set_bit(vlan, priv->vlan.active_vlans, VLAN_N_VID) 469 list_size++; 470 471 max_list_size = 1 << MLX5_CAP_GEN(priv->mdev, log_max_vlan_list); 472 473 if (list_size > max_list_size) { 474 if_printf(ifp, 475 "ifnet vlans list size (%d) > (%d) max vport list size, some vlans will be dropped\n", 476 list_size, max_list_size); 477 list_size = max_list_size; 478 } 479 480 vlans = kcalloc(list_size, sizeof(*vlans), GFP_KERNEL); 481 if (!vlans) 482 return -ENOMEM; 483 484 i = 0; 485 for_each_set_bit(vlan, priv->vlan.active_vlans, VLAN_N_VID) { 486 if (i >= list_size) 487 break; 488 vlans[i++] = vlan; 489 } 490 491 err = mlx5_modify_nic_vport_vlans(priv->mdev, vlans, list_size); 492 if (err) 493 if_printf(ifp, "Failed to modify vport vlans list err(%d)\n", 494 err); 495 496 kfree(vlans); 497 return err; 498 } 499 500 enum mlx5e_vlan_rule_type { 501 MLX5E_VLAN_RULE_TYPE_UNTAGGED, 502 MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 503 MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 504 MLX5E_VLAN_RULE_TYPE_MATCH_VID, 505 }; 506 507 static int 508 mlx5e_add_vlan_rule_sub(struct mlx5e_priv *priv, 509 enum mlx5e_vlan_rule_type rule_type, u16 vid, 510 u32 *mc, u32 *mv) 511 { 512 struct mlx5_flow_table *ft = priv->fts.vlan.t; 513 struct mlx5_flow_destination dest = {}; 514 u8 mc_enable = 0; 515 struct mlx5_flow_rule **rule_p; 516 int err = 0; 517 518 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 519 dest.ft = priv->fts.main.t; 520 521 mc_enable = MLX5_MATCH_OUTER_HEADERS; 522 523 switch (rule_type) { 524 case MLX5E_VLAN_RULE_TYPE_UNTAGGED: 525 rule_p = &priv->vlan.untagged_ft_rule; 526 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag); 527 break; 528 case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID: 529 rule_p = &priv->vlan.any_cvlan_ft_rule; 530 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag); 531 MLX5_SET(fte_match_param, mv, outer_headers.cvlan_tag, 1); 532 break; 533 case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID: 534 rule_p = &priv->vlan.any_svlan_ft_rule; 535 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag); 536 MLX5_SET(fte_match_param, mv, outer_headers.svlan_tag, 1); 537 break; 538 default: /* MLX5E_VLAN_RULE_TYPE_MATCH_VID */ 539 rule_p = &priv->vlan.active_vlans_ft_rule[vid]; 540 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag); 541 MLX5_SET(fte_match_param, mv, outer_headers.cvlan_tag, 1); 542 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid); 543 MLX5_SET(fte_match_param, mv, outer_headers.first_vid, vid); 544 mlx5e_vport_context_update_vlans(priv); 545 break; 546 } 547 548 *rule_p = mlx5_add_flow_rule(ft, mc_enable, mc, mv, 549 MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, 550 MLX5_FS_ETH_FLOW_TAG, 551 &dest); 552 553 if (IS_ERR(*rule_p)) { 554 err = PTR_ERR(*rule_p); 555 *rule_p = NULL; 556 if_printf(priv->ifp, "%s: add rule failed\n", __func__); 557 } 558 559 return (err); 560 } 561 562 static int 563 mlx5e_add_vlan_rule(struct mlx5e_priv *priv, 564 enum mlx5e_vlan_rule_type rule_type, u16 vid) 565 { 566 u32 *match_criteria; 567 u32 *match_value; 568 int err = 0; 569 570 match_value = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param)); 571 match_criteria = mlx5_vzalloc(MLX5_ST_SZ_BYTES(fte_match_param)); 572 if (!match_value || !match_criteria) { 573 if_printf(priv->ifp, "%s: alloc failed\n", __func__); 574 err = -ENOMEM; 575 goto add_vlan_rule_out; 576 } 577 578 err = mlx5e_add_vlan_rule_sub(priv, rule_type, vid, match_criteria, 579 match_value); 580 581 add_vlan_rule_out: 582 kvfree(match_criteria); 583 kvfree(match_value); 584 585 return (err); 586 } 587 588 static void 589 mlx5e_del_vlan_rule(struct mlx5e_priv *priv, 590 enum mlx5e_vlan_rule_type rule_type, u16 vid) 591 { 592 switch (rule_type) { 593 case MLX5E_VLAN_RULE_TYPE_UNTAGGED: 594 if (priv->vlan.untagged_ft_rule) { 595 mlx5_del_flow_rule(priv->vlan.untagged_ft_rule); 596 priv->vlan.untagged_ft_rule = NULL; 597 } 598 break; 599 case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID: 600 if (priv->vlan.any_cvlan_ft_rule) { 601 mlx5_del_flow_rule(priv->vlan.any_cvlan_ft_rule); 602 priv->vlan.any_cvlan_ft_rule = NULL; 603 } 604 break; 605 case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID: 606 if (priv->vlan.any_svlan_ft_rule) { 607 mlx5_del_flow_rule(priv->vlan.any_svlan_ft_rule); 608 priv->vlan.any_svlan_ft_rule = NULL; 609 } 610 break; 611 case MLX5E_VLAN_RULE_TYPE_MATCH_VID: 612 if (priv->vlan.active_vlans_ft_rule[vid]) { 613 mlx5_del_flow_rule(priv->vlan.active_vlans_ft_rule[vid]); 614 priv->vlan.active_vlans_ft_rule[vid] = NULL; 615 } 616 mlx5e_vport_context_update_vlans(priv); 617 break; 618 default: 619 break; 620 } 621 } 622 623 static void 624 mlx5e_del_any_vid_rules(struct mlx5e_priv *priv) 625 { 626 mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); 627 mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0); 628 } 629 630 static int 631 mlx5e_add_any_vid_rules(struct mlx5e_priv *priv) 632 { 633 int err; 634 635 err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); 636 if (err) 637 return (err); 638 639 err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0); 640 if (err) 641 mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); 642 643 return (err); 644 } 645 646 void 647 mlx5e_enable_vlan_filter(struct mlx5e_priv *priv) 648 { 649 if (priv->vlan.filter_disabled) { 650 priv->vlan.filter_disabled = false; 651 if (priv->ifp->if_flags & IFF_PROMISC) 652 return; 653 if (test_bit(MLX5E_STATE_OPENED, &priv->state)) 654 mlx5e_del_any_vid_rules(priv); 655 } 656 } 657 658 void 659 mlx5e_disable_vlan_filter(struct mlx5e_priv *priv) 660 { 661 if (!priv->vlan.filter_disabled) { 662 priv->vlan.filter_disabled = true; 663 if (priv->ifp->if_flags & IFF_PROMISC) 664 return; 665 if (test_bit(MLX5E_STATE_OPENED, &priv->state)) 666 mlx5e_add_any_vid_rules(priv); 667 } 668 } 669 670 void 671 mlx5e_vlan_rx_add_vid(void *arg, struct ifnet *ifp, u16 vid) 672 { 673 struct mlx5e_priv *priv = arg; 674 675 if (ifp != priv->ifp) 676 return; 677 678 PRIV_LOCK(priv); 679 if (!test_and_set_bit(vid, priv->vlan.active_vlans) && 680 test_bit(MLX5E_STATE_OPENED, &priv->state)) 681 mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid); 682 PRIV_UNLOCK(priv); 683 } 684 685 void 686 mlx5e_vlan_rx_kill_vid(void *arg, struct ifnet *ifp, u16 vid) 687 { 688 struct mlx5e_priv *priv = arg; 689 690 if (ifp != priv->ifp) 691 return; 692 693 PRIV_LOCK(priv); 694 clear_bit(vid, priv->vlan.active_vlans); 695 if (test_bit(MLX5E_STATE_OPENED, &priv->state)) 696 mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, vid); 697 PRIV_UNLOCK(priv); 698 } 699 700 int 701 mlx5e_add_all_vlan_rules(struct mlx5e_priv *priv) 702 { 703 int err; 704 int i; 705 706 set_bit(0, priv->vlan.active_vlans); 707 for_each_set_bit(i, priv->vlan.active_vlans, VLAN_N_VID) { 708 err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, 709 i); 710 if (err) 711 goto error; 712 } 713 714 err = mlx5e_add_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0); 715 if (err) 716 goto error; 717 718 if (priv->vlan.filter_disabled) { 719 err = mlx5e_add_any_vid_rules(priv); 720 if (err) 721 goto error; 722 } 723 return (0); 724 error: 725 mlx5e_del_all_vlan_rules(priv); 726 return (err); 727 } 728 729 void 730 mlx5e_del_all_vlan_rules(struct mlx5e_priv *priv) 731 { 732 int i; 733 734 if (priv->vlan.filter_disabled) 735 mlx5e_del_any_vid_rules(priv); 736 737 mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0); 738 739 for_each_set_bit(i, priv->vlan.active_vlans, VLAN_N_VID) 740 mlx5e_del_vlan_rule(priv, MLX5E_VLAN_RULE_TYPE_MATCH_VID, i); 741 clear_bit(0, priv->vlan.active_vlans); 742 } 743 744 #define mlx5e_for_each_hash_node(hn, tmp, hash, i) \ 745 for (i = 0; i < MLX5E_ETH_ADDR_HASH_SIZE; i++) \ 746 LIST_FOREACH_SAFE(hn, &(hash)[i], hlist, tmp) 747 748 static void 749 mlx5e_execute_action(struct mlx5e_priv *priv, 750 struct mlx5e_eth_addr_hash_node *hn) 751 { 752 switch (hn->action) { 753 case MLX5E_ACTION_ADD: 754 mlx5e_add_eth_addr_rule(priv, &hn->ai, MLX5E_FULLMATCH); 755 hn->action = MLX5E_ACTION_NONE; 756 break; 757 758 case MLX5E_ACTION_DEL: 759 mlx5e_del_eth_addr_from_flow_table(priv, &hn->ai); 760 mlx5e_del_eth_addr_from_hash(hn); 761 break; 762 763 default: 764 break; 765 } 766 } 767 768 static void 769 mlx5e_sync_ifp_addr(struct mlx5e_priv *priv) 770 { 771 struct ifnet *ifp = priv->ifp; 772 struct ifaddr *ifa; 773 struct ifmultiaddr *ifma; 774 775 /* XXX adding this entry might not be needed */ 776 mlx5e_add_eth_addr_to_hash(priv->eth_addr.if_uc, 777 LLADDR((struct sockaddr_dl *)(ifp->if_addr->ifa_addr))); 778 779 if_addr_rlock(ifp); 780 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 781 if (ifa->ifa_addr->sa_family != AF_LINK) 782 continue; 783 mlx5e_add_eth_addr_to_hash(priv->eth_addr.if_uc, 784 LLADDR((struct sockaddr_dl *)ifa->ifa_addr)); 785 } 786 if_addr_runlock(ifp); 787 788 if_maddr_rlock(ifp); 789 CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 790 if (ifma->ifma_addr->sa_family != AF_LINK) 791 continue; 792 mlx5e_add_eth_addr_to_hash(priv->eth_addr.if_mc, 793 LLADDR((struct sockaddr_dl *)ifma->ifma_addr)); 794 } 795 if_maddr_runlock(ifp); 796 } 797 798 static void mlx5e_fill_addr_array(struct mlx5e_priv *priv, int list_type, 799 u8 addr_array[][ETH_ALEN], int size) 800 { 801 bool is_uc = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC); 802 struct ifnet *ifp = priv->ifp; 803 struct mlx5e_eth_addr_hash_node *hn; 804 struct mlx5e_eth_addr_hash_head *addr_list; 805 struct mlx5e_eth_addr_hash_node *tmp; 806 int i = 0; 807 int hi; 808 809 addr_list = is_uc ? priv->eth_addr.if_uc : priv->eth_addr.if_mc; 810 811 if (is_uc) /* Make sure our own address is pushed first */ 812 ether_addr_copy(addr_array[i++], IF_LLADDR(ifp)); 813 else if (priv->eth_addr.broadcast_enabled) 814 ether_addr_copy(addr_array[i++], ifp->if_broadcastaddr); 815 816 mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) { 817 if (ether_addr_equal(IF_LLADDR(ifp), hn->ai.addr)) 818 continue; 819 if (i >= size) 820 break; 821 ether_addr_copy(addr_array[i++], hn->ai.addr); 822 } 823 } 824 825 static void mlx5e_vport_context_update_addr_list(struct mlx5e_priv *priv, 826 int list_type) 827 { 828 bool is_uc = (list_type == MLX5_NIC_VPORT_LIST_TYPE_UC); 829 struct mlx5e_eth_addr_hash_node *hn; 830 u8 (*addr_array)[ETH_ALEN] = NULL; 831 struct mlx5e_eth_addr_hash_head *addr_list; 832 struct mlx5e_eth_addr_hash_node *tmp; 833 int max_size; 834 int size; 835 int err; 836 int hi; 837 838 size = is_uc ? 0 : (priv->eth_addr.broadcast_enabled ? 1 : 0); 839 max_size = is_uc ? 840 1 << MLX5_CAP_GEN(priv->mdev, log_max_current_uc_list) : 841 1 << MLX5_CAP_GEN(priv->mdev, log_max_current_mc_list); 842 843 addr_list = is_uc ? priv->eth_addr.if_uc : priv->eth_addr.if_mc; 844 mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) 845 size++; 846 847 if (size > max_size) { 848 if_printf(priv->ifp, 849 "ifp %s list size (%d) > (%d) max vport list size, some addresses will be dropped\n", 850 is_uc ? "UC" : "MC", size, max_size); 851 size = max_size; 852 } 853 854 if (size) { 855 addr_array = kcalloc(size, ETH_ALEN, GFP_KERNEL); 856 if (!addr_array) { 857 err = -ENOMEM; 858 goto out; 859 } 860 mlx5e_fill_addr_array(priv, list_type, addr_array, size); 861 } 862 863 err = mlx5_modify_nic_vport_mac_list(priv->mdev, list_type, addr_array, size); 864 out: 865 if (err) 866 if_printf(priv->ifp, 867 "Failed to modify vport %s list err(%d)\n", 868 is_uc ? "UC" : "MC", err); 869 kfree(addr_array); 870 } 871 872 static void mlx5e_vport_context_update(struct mlx5e_priv *priv) 873 { 874 struct mlx5e_eth_addr_db *ea = &priv->eth_addr; 875 876 mlx5e_vport_context_update_addr_list(priv, MLX5_NIC_VPORT_LIST_TYPE_UC); 877 mlx5e_vport_context_update_addr_list(priv, MLX5_NIC_VPORT_LIST_TYPE_MC); 878 mlx5_modify_nic_vport_promisc(priv->mdev, 0, 879 ea->allmulti_enabled, 880 ea->promisc_enabled); 881 } 882 883 static void 884 mlx5e_apply_ifp_addr(struct mlx5e_priv *priv) 885 { 886 struct mlx5e_eth_addr_hash_node *hn; 887 struct mlx5e_eth_addr_hash_node *tmp; 888 int i; 889 890 mlx5e_for_each_hash_node(hn, tmp, priv->eth_addr.if_uc, i) 891 mlx5e_execute_action(priv, hn); 892 893 mlx5e_for_each_hash_node(hn, tmp, priv->eth_addr.if_mc, i) 894 mlx5e_execute_action(priv, hn); 895 } 896 897 static void 898 mlx5e_handle_ifp_addr(struct mlx5e_priv *priv) 899 { 900 struct mlx5e_eth_addr_hash_node *hn; 901 struct mlx5e_eth_addr_hash_node *tmp; 902 int i; 903 904 mlx5e_for_each_hash_node(hn, tmp, priv->eth_addr.if_uc, i) 905 hn->action = MLX5E_ACTION_DEL; 906 mlx5e_for_each_hash_node(hn, tmp, priv->eth_addr.if_mc, i) 907 hn->action = MLX5E_ACTION_DEL; 908 909 if (test_bit(MLX5E_STATE_OPENED, &priv->state)) 910 mlx5e_sync_ifp_addr(priv); 911 912 mlx5e_apply_ifp_addr(priv); 913 } 914 915 void 916 mlx5e_set_rx_mode_core(struct mlx5e_priv *priv) 917 { 918 struct mlx5e_eth_addr_db *ea = &priv->eth_addr; 919 struct ifnet *ndev = priv->ifp; 920 921 bool rx_mode_enable = test_bit(MLX5E_STATE_OPENED, &priv->state); 922 bool promisc_enabled = rx_mode_enable && (ndev->if_flags & IFF_PROMISC); 923 bool allmulti_enabled = rx_mode_enable && (ndev->if_flags & IFF_ALLMULTI); 924 bool broadcast_enabled = rx_mode_enable; 925 926 bool enable_promisc = !ea->promisc_enabled && promisc_enabled; 927 bool disable_promisc = ea->promisc_enabled && !promisc_enabled; 928 bool enable_allmulti = !ea->allmulti_enabled && allmulti_enabled; 929 bool disable_allmulti = ea->allmulti_enabled && !allmulti_enabled; 930 bool enable_broadcast = !ea->broadcast_enabled && broadcast_enabled; 931 bool disable_broadcast = ea->broadcast_enabled && !broadcast_enabled; 932 933 /* update broadcast address */ 934 ether_addr_copy(priv->eth_addr.broadcast.addr, 935 priv->ifp->if_broadcastaddr); 936 937 if (enable_promisc) { 938 mlx5e_add_eth_addr_rule(priv, &ea->promisc, MLX5E_PROMISC); 939 if (!priv->vlan.filter_disabled) 940 mlx5e_add_any_vid_rules(priv); 941 } 942 if (enable_allmulti) 943 mlx5e_add_eth_addr_rule(priv, &ea->allmulti, MLX5E_ALLMULTI); 944 if (enable_broadcast) 945 mlx5e_add_eth_addr_rule(priv, &ea->broadcast, MLX5E_FULLMATCH); 946 947 mlx5e_handle_ifp_addr(priv); 948 949 if (disable_broadcast) 950 mlx5e_del_eth_addr_from_flow_table(priv, &ea->broadcast); 951 if (disable_allmulti) 952 mlx5e_del_eth_addr_from_flow_table(priv, &ea->allmulti); 953 if (disable_promisc) { 954 if (!priv->vlan.filter_disabled) 955 mlx5e_del_any_vid_rules(priv); 956 mlx5e_del_eth_addr_from_flow_table(priv, &ea->promisc); 957 } 958 959 ea->promisc_enabled = promisc_enabled; 960 ea->allmulti_enabled = allmulti_enabled; 961 ea->broadcast_enabled = broadcast_enabled; 962 963 mlx5e_vport_context_update(priv); 964 } 965 966 void 967 mlx5e_set_rx_mode_work(struct work_struct *work) 968 { 969 struct mlx5e_priv *priv = 970 container_of(work, struct mlx5e_priv, set_rx_mode_work); 971 972 PRIV_LOCK(priv); 973 if (test_bit(MLX5E_STATE_OPENED, &priv->state)) 974 mlx5e_set_rx_mode_core(priv); 975 PRIV_UNLOCK(priv); 976 } 977 978 static void 979 mlx5e_destroy_groups(struct mlx5e_flow_table *ft) 980 { 981 int i; 982 983 for (i = ft->num_groups - 1; i >= 0; i--) { 984 if (!IS_ERR_OR_NULL(ft->g[i])) 985 mlx5_destroy_flow_group(ft->g[i]); 986 ft->g[i] = NULL; 987 } 988 ft->num_groups = 0; 989 } 990 991 static void 992 mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft) 993 { 994 mlx5e_destroy_groups(ft); 995 kfree(ft->g); 996 mlx5_destroy_flow_table(ft->t); 997 ft->t = NULL; 998 } 999 1000 #define MLX5E_NUM_MAIN_GROUPS 10 1001 #define MLX5E_MAIN_GROUP0_SIZE BIT(4) 1002 #define MLX5E_MAIN_GROUP1_SIZE BIT(3) 1003 #define MLX5E_MAIN_GROUP2_SIZE BIT(1) 1004 #define MLX5E_MAIN_GROUP3_SIZE BIT(0) 1005 #define MLX5E_MAIN_GROUP4_SIZE BIT(14) 1006 #define MLX5E_MAIN_GROUP5_SIZE BIT(13) 1007 #define MLX5E_MAIN_GROUP6_SIZE BIT(11) 1008 #define MLX5E_MAIN_GROUP7_SIZE BIT(2) 1009 #define MLX5E_MAIN_GROUP8_SIZE BIT(1) 1010 #define MLX5E_MAIN_GROUP9_SIZE BIT(0) 1011 #define MLX5E_MAIN_TABLE_SIZE (MLX5E_MAIN_GROUP0_SIZE +\ 1012 MLX5E_MAIN_GROUP1_SIZE +\ 1013 MLX5E_MAIN_GROUP2_SIZE +\ 1014 MLX5E_MAIN_GROUP3_SIZE +\ 1015 MLX5E_MAIN_GROUP4_SIZE +\ 1016 MLX5E_MAIN_GROUP5_SIZE +\ 1017 MLX5E_MAIN_GROUP6_SIZE +\ 1018 MLX5E_MAIN_GROUP7_SIZE +\ 1019 MLX5E_MAIN_GROUP8_SIZE +\ 1020 MLX5E_MAIN_GROUP9_SIZE +\ 1021 0) 1022 1023 static int 1024 mlx5e_create_main_groups_sub(struct mlx5e_flow_table *ft, u32 *in, 1025 int inlen) 1026 { 1027 u8 *mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); 1028 u8 *dmac = MLX5_ADDR_OF(create_flow_group_in, in, 1029 match_criteria.outer_headers.dmac_47_16); 1030 int err; 1031 int ix = 0; 1032 1033 /* Tunnel rules need to be first in this list of groups */ 1034 1035 /* Start tunnel rules */ 1036 memset(in, 0, inlen); 1037 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1038 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 1039 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol); 1040 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.udp_dport); 1041 MLX5_SET_CFG(in, start_flow_index, ix); 1042 ix += MLX5E_MAIN_GROUP0_SIZE; 1043 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1044 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1045 if (IS_ERR(ft->g[ft->num_groups])) 1046 goto err_destory_groups; 1047 ft->num_groups++; 1048 /* End Tunnel Rules */ 1049 1050 memset(in, 0, inlen); 1051 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1052 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 1053 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol); 1054 MLX5_SET_CFG(in, start_flow_index, ix); 1055 ix += MLX5E_MAIN_GROUP1_SIZE; 1056 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1057 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1058 if (IS_ERR(ft->g[ft->num_groups])) 1059 goto err_destory_groups; 1060 ft->num_groups++; 1061 1062 memset(in, 0, inlen); 1063 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1064 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 1065 MLX5_SET_CFG(in, start_flow_index, ix); 1066 ix += MLX5E_MAIN_GROUP2_SIZE; 1067 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1068 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1069 if (IS_ERR(ft->g[ft->num_groups])) 1070 goto err_destory_groups; 1071 ft->num_groups++; 1072 1073 memset(in, 0, inlen); 1074 MLX5_SET_CFG(in, start_flow_index, ix); 1075 ix += MLX5E_MAIN_GROUP3_SIZE; 1076 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1077 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1078 if (IS_ERR(ft->g[ft->num_groups])) 1079 goto err_destory_groups; 1080 ft->num_groups++; 1081 1082 memset(in, 0, inlen); 1083 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1084 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 1085 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol); 1086 memset(dmac, 0xff, ETH_ALEN); 1087 MLX5_SET_CFG(in, start_flow_index, ix); 1088 ix += MLX5E_MAIN_GROUP4_SIZE; 1089 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1090 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1091 if (IS_ERR(ft->g[ft->num_groups])) 1092 goto err_destory_groups; 1093 ft->num_groups++; 1094 1095 memset(in, 0, inlen); 1096 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1097 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 1098 memset(dmac, 0xff, ETH_ALEN); 1099 MLX5_SET_CFG(in, start_flow_index, ix); 1100 ix += MLX5E_MAIN_GROUP5_SIZE; 1101 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1102 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1103 if (IS_ERR(ft->g[ft->num_groups])) 1104 goto err_destory_groups; 1105 ft->num_groups++; 1106 1107 memset(in, 0, inlen); 1108 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1109 memset(dmac, 0xff, ETH_ALEN); 1110 MLX5_SET_CFG(in, start_flow_index, ix); 1111 ix += MLX5E_MAIN_GROUP6_SIZE; 1112 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1113 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1114 if (IS_ERR(ft->g[ft->num_groups])) 1115 goto err_destory_groups; 1116 ft->num_groups++; 1117 1118 memset(in, 0, inlen); 1119 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1120 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 1121 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ip_protocol); 1122 dmac[0] = 0x01; 1123 MLX5_SET_CFG(in, start_flow_index, ix); 1124 ix += MLX5E_MAIN_GROUP7_SIZE; 1125 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1126 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1127 if (IS_ERR(ft->g[ft->num_groups])) 1128 goto err_destory_groups; 1129 ft->num_groups++; 1130 1131 memset(in, 0, inlen); 1132 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1133 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.ethertype); 1134 dmac[0] = 0x01; 1135 MLX5_SET_CFG(in, start_flow_index, ix); 1136 ix += MLX5E_MAIN_GROUP8_SIZE; 1137 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1138 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1139 if (IS_ERR(ft->g[ft->num_groups])) 1140 goto err_destory_groups; 1141 ft->num_groups++; 1142 1143 memset(in, 0, inlen); 1144 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1145 dmac[0] = 0x01; 1146 MLX5_SET_CFG(in, start_flow_index, ix); 1147 ix += MLX5E_MAIN_GROUP9_SIZE; 1148 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1149 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1150 if (IS_ERR(ft->g[ft->num_groups])) 1151 goto err_destory_groups; 1152 ft->num_groups++; 1153 1154 return (0); 1155 1156 err_destory_groups: 1157 err = PTR_ERR(ft->g[ft->num_groups]); 1158 ft->g[ft->num_groups] = NULL; 1159 mlx5e_destroy_groups(ft); 1160 1161 return (err); 1162 } 1163 1164 static int 1165 mlx5e_create_main_groups(struct mlx5e_flow_table *ft) 1166 { 1167 u32 *in; 1168 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1169 int err; 1170 1171 in = mlx5_vzalloc(inlen); 1172 if (!in) 1173 return (-ENOMEM); 1174 1175 err = mlx5e_create_main_groups_sub(ft, in, inlen); 1176 1177 kvfree(in); 1178 return (err); 1179 } 1180 1181 static int mlx5e_create_main_flow_table(struct mlx5e_priv *priv) 1182 { 1183 struct mlx5e_flow_table *ft = &priv->fts.main; 1184 int err; 1185 1186 ft->num_groups = 0; 1187 ft->t = mlx5_create_flow_table(priv->fts.ns, 0, "main", 1188 MLX5E_MAIN_TABLE_SIZE); 1189 1190 if (IS_ERR(ft->t)) { 1191 err = PTR_ERR(ft->t); 1192 ft->t = NULL; 1193 return (err); 1194 } 1195 ft->g = kcalloc(MLX5E_NUM_MAIN_GROUPS, sizeof(*ft->g), GFP_KERNEL); 1196 if (!ft->g) { 1197 err = -ENOMEM; 1198 goto err_destroy_main_flow_table; 1199 } 1200 1201 err = mlx5e_create_main_groups(ft); 1202 if (err) 1203 goto err_free_g; 1204 return (0); 1205 1206 err_free_g: 1207 kfree(ft->g); 1208 1209 err_destroy_main_flow_table: 1210 mlx5_destroy_flow_table(ft->t); 1211 ft->t = NULL; 1212 1213 return (err); 1214 } 1215 1216 static void mlx5e_destroy_main_flow_table(struct mlx5e_priv *priv) 1217 { 1218 mlx5e_destroy_flow_table(&priv->fts.main); 1219 } 1220 1221 #define MLX5E_NUM_VLAN_GROUPS 3 1222 #define MLX5E_VLAN_GROUP0_SIZE BIT(12) 1223 #define MLX5E_VLAN_GROUP1_SIZE BIT(1) 1224 #define MLX5E_VLAN_GROUP2_SIZE BIT(0) 1225 #define MLX5E_VLAN_TABLE_SIZE (MLX5E_VLAN_GROUP0_SIZE +\ 1226 MLX5E_VLAN_GROUP1_SIZE +\ 1227 MLX5E_VLAN_GROUP2_SIZE +\ 1228 0) 1229 1230 static int 1231 mlx5e_create_vlan_groups_sub(struct mlx5e_flow_table *ft, u32 *in, 1232 int inlen) 1233 { 1234 int err; 1235 int ix = 0; 1236 u8 *mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); 1237 1238 memset(in, 0, inlen); 1239 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1240 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag); 1241 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid); 1242 MLX5_SET_CFG(in, start_flow_index, ix); 1243 ix += MLX5E_VLAN_GROUP0_SIZE; 1244 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1245 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1246 if (IS_ERR(ft->g[ft->num_groups])) 1247 goto err_destory_groups; 1248 ft->num_groups++; 1249 1250 memset(in, 0, inlen); 1251 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1252 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag); 1253 MLX5_SET_CFG(in, start_flow_index, ix); 1254 ix += MLX5E_VLAN_GROUP1_SIZE; 1255 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1256 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1257 if (IS_ERR(ft->g[ft->num_groups])) 1258 goto err_destory_groups; 1259 ft->num_groups++; 1260 1261 memset(in, 0, inlen); 1262 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1263 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag); 1264 MLX5_SET_CFG(in, start_flow_index, ix); 1265 ix += MLX5E_VLAN_GROUP2_SIZE; 1266 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1267 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1268 if (IS_ERR(ft->g[ft->num_groups])) 1269 goto err_destory_groups; 1270 ft->num_groups++; 1271 1272 return (0); 1273 1274 err_destory_groups: 1275 err = PTR_ERR(ft->g[ft->num_groups]); 1276 ft->g[ft->num_groups] = NULL; 1277 mlx5e_destroy_groups(ft); 1278 1279 return (err); 1280 } 1281 1282 static int 1283 mlx5e_create_vlan_groups(struct mlx5e_flow_table *ft) 1284 { 1285 u32 *in; 1286 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1287 int err; 1288 1289 in = mlx5_vzalloc(inlen); 1290 if (!in) 1291 return (-ENOMEM); 1292 1293 err = mlx5e_create_vlan_groups_sub(ft, in, inlen); 1294 1295 kvfree(in); 1296 return (err); 1297 } 1298 1299 static int 1300 mlx5e_create_vlan_flow_table(struct mlx5e_priv *priv) 1301 { 1302 struct mlx5e_flow_table *ft = &priv->fts.vlan; 1303 int err; 1304 1305 ft->num_groups = 0; 1306 ft->t = mlx5_create_flow_table(priv->fts.ns, 0, "vlan", 1307 MLX5E_VLAN_TABLE_SIZE); 1308 1309 if (IS_ERR(ft->t)) { 1310 err = PTR_ERR(ft->t); 1311 ft->t = NULL; 1312 return (err); 1313 } 1314 ft->g = kcalloc(MLX5E_NUM_VLAN_GROUPS, sizeof(*ft->g), GFP_KERNEL); 1315 if (!ft->g) { 1316 err = -ENOMEM; 1317 goto err_destroy_vlan_flow_table; 1318 } 1319 1320 err = mlx5e_create_vlan_groups(ft); 1321 if (err) 1322 goto err_free_g; 1323 1324 return (0); 1325 1326 err_free_g: 1327 kfree(ft->g); 1328 1329 err_destroy_vlan_flow_table: 1330 mlx5_destroy_flow_table(ft->t); 1331 ft->t = NULL; 1332 1333 return (err); 1334 } 1335 1336 static void 1337 mlx5e_destroy_vlan_flow_table(struct mlx5e_priv *priv) 1338 { 1339 mlx5e_destroy_flow_table(&priv->fts.vlan); 1340 } 1341 1342 #define MLX5E_NUM_INNER_RSS_GROUPS 3 1343 #define MLX5E_INNER_RSS_GROUP0_SIZE BIT(3) 1344 #define MLX5E_INNER_RSS_GROUP1_SIZE BIT(1) 1345 #define MLX5E_INNER_RSS_GROUP2_SIZE BIT(0) 1346 #define MLX5E_INNER_RSS_TABLE_SIZE (MLX5E_INNER_RSS_GROUP0_SIZE +\ 1347 MLX5E_INNER_RSS_GROUP1_SIZE +\ 1348 MLX5E_INNER_RSS_GROUP2_SIZE +\ 1349 0) 1350 1351 static int 1352 mlx5e_create_inner_rss_groups_sub(struct mlx5e_flow_table *ft, u32 *in, 1353 int inlen) 1354 { 1355 u8 *mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); 1356 int err; 1357 int ix = 0; 1358 1359 memset(in, 0, inlen); 1360 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_INNER_HEADERS); 1361 MLX5_SET_TO_ONES(fte_match_param, mc, inner_headers.ethertype); 1362 MLX5_SET_TO_ONES(fte_match_param, mc, inner_headers.ip_protocol); 1363 MLX5_SET_CFG(in, start_flow_index, ix); 1364 ix += MLX5E_INNER_RSS_GROUP0_SIZE; 1365 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1366 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1367 if (IS_ERR(ft->g[ft->num_groups])) 1368 goto err_destory_groups; 1369 ft->num_groups++; 1370 1371 memset(in, 0, inlen); 1372 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_INNER_HEADERS); 1373 MLX5_SET_TO_ONES(fte_match_param, mc, inner_headers.ethertype); 1374 MLX5_SET_CFG(in, start_flow_index, ix); 1375 ix += MLX5E_INNER_RSS_GROUP1_SIZE; 1376 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1377 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1378 if (IS_ERR(ft->g[ft->num_groups])) 1379 goto err_destory_groups; 1380 ft->num_groups++; 1381 1382 memset(in, 0, inlen); 1383 MLX5_SET_CFG(in, start_flow_index, ix); 1384 ix += MLX5E_INNER_RSS_GROUP2_SIZE; 1385 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1386 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1387 if (IS_ERR(ft->g[ft->num_groups])) 1388 goto err_destory_groups; 1389 ft->num_groups++; 1390 1391 return (0); 1392 1393 err_destory_groups: 1394 err = PTR_ERR(ft->g[ft->num_groups]); 1395 ft->g[ft->num_groups] = NULL; 1396 mlx5e_destroy_groups(ft); 1397 1398 return (err); 1399 } 1400 1401 static int 1402 mlx5e_create_inner_rss_groups(struct mlx5e_flow_table *ft) 1403 { 1404 u32 *in; 1405 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1406 int err; 1407 1408 in = mlx5_vzalloc(inlen); 1409 if (!in) 1410 return (-ENOMEM); 1411 1412 err = mlx5e_create_inner_rss_groups_sub(ft, in, inlen); 1413 1414 kvfree(in); 1415 return (err); 1416 } 1417 1418 static int 1419 mlx5e_create_inner_rss_flow_table(struct mlx5e_priv *priv) 1420 { 1421 struct mlx5e_flow_table *ft = &priv->fts.inner_rss; 1422 int err; 1423 1424 ft->num_groups = 0; 1425 ft->t = mlx5_create_flow_table(priv->fts.ns, 0, "inner_rss", 1426 MLX5E_INNER_RSS_TABLE_SIZE); 1427 1428 if (IS_ERR(ft->t)) { 1429 err = PTR_ERR(ft->t); 1430 ft->t = NULL; 1431 return (err); 1432 } 1433 ft->g = kcalloc(MLX5E_NUM_INNER_RSS_GROUPS, sizeof(*ft->g), 1434 GFP_KERNEL); 1435 if (!ft->g) { 1436 err = -ENOMEM; 1437 goto err_destroy_inner_rss_flow_table; 1438 } 1439 1440 err = mlx5e_create_inner_rss_groups(ft); 1441 if (err) 1442 goto err_free_g; 1443 1444 return (0); 1445 1446 err_free_g: 1447 kfree(ft->g); 1448 1449 err_destroy_inner_rss_flow_table: 1450 mlx5_destroy_flow_table(ft->t); 1451 ft->t = NULL; 1452 1453 return (err); 1454 } 1455 1456 static void mlx5e_destroy_inner_rss_flow_table(struct mlx5e_priv *priv) 1457 { 1458 mlx5e_destroy_flow_table(&priv->fts.inner_rss); 1459 } 1460 1461 int 1462 mlx5e_open_flow_table(struct mlx5e_priv *priv) 1463 { 1464 int err; 1465 1466 priv->fts.ns = mlx5_get_flow_namespace(priv->mdev, 1467 MLX5_FLOW_NAMESPACE_KERNEL); 1468 1469 err = mlx5e_create_vlan_flow_table(priv); 1470 if (err) 1471 return (err); 1472 1473 err = mlx5e_create_main_flow_table(priv); 1474 if (err) 1475 goto err_destroy_vlan_flow_table; 1476 1477 err = mlx5e_create_inner_rss_flow_table(priv); 1478 if (err) 1479 goto err_destroy_main_flow_table; 1480 1481 return (0); 1482 1483 err_destroy_main_flow_table: 1484 mlx5e_destroy_main_flow_table(priv); 1485 err_destroy_vlan_flow_table: 1486 mlx5e_destroy_vlan_flow_table(priv); 1487 1488 return (err); 1489 } 1490 1491 void 1492 mlx5e_close_flow_table(struct mlx5e_priv *priv) 1493 { 1494 mlx5e_destroy_inner_rss_flow_table(priv); 1495 mlx5e_destroy_main_flow_table(priv); 1496 mlx5e_destroy_vlan_flow_table(priv); 1497 } 1498