FILE
en_fs.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
1/* 2 * Copyright (c) 2015, Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 33#include <linux/debugfs.h> 34#include <linux/list.h> 35#include <linux/ip.h> 36#include <linux/ipv6.h> 37#include <linux/tcp.h> 38#include <linux/mlx5/fs.h> 39#include <linux/mlx5/mpfs.h> 40#include "en_tc.h" 41#include "lib/mpfs.h" 42#include "en/ptp.h" 43#include "en/fs_ethtool.h" 44 45struct mlx5e_flow_steering { 46 struct work_struct set_rx_mode_work; 47 bool state_destroy; 48 bool vlan_strip_disable; 49 struct mlx5_core_dev *mdev; 50 struct net_device *netdev; 51 struct mlx5_flow_namespace *ns; 52 struct mlx5_flow_namespace *egress_ns; 53#ifdef CONFIG_MLX5_EN_RXNFC 54 struct mlx5e_ethtool_steering *ethtool; 55#endif 56 struct mlx5e_tc_table *tc; 57 struct mlx5e_promisc_table promisc; 58 struct mlx5e_vlan_table *vlan; 59 struct mlx5e_l2_table l2; 60 struct mlx5_ttc_table *ttc; 61 struct mlx5_ttc_table *inner_ttc; 62#ifdef CONFIG_MLX5_EN_ARFS 63 struct mlx5e_arfs_tables *arfs; 64#endif 65#ifdef CONFIG_MLX5_EN_TLS 66 struct mlx5e_accel_fs_tcp *accel_tcp; 67#endif 68 struct mlx5e_fs_udp *udp; 69 struct mlx5e_fs_any *any; 70 struct mlx5e_ptp_fs *ptp_fs; 71 struct dentry *dfs_root; 72}; 73 74static int mlx5e_add_l2_flow_rule(struct mlx5e_flow_steering *fs, 75 struct mlx5e_l2_rule *ai, int type); 76static void mlx5e_del_l2_flow_rule(struct mlx5e_flow_steering *fs, 77 struct mlx5e_l2_rule *ai); 78 79enum { 80 MLX5E_FULLMATCH = 0, 81 MLX5E_ALLMULTI = 1, 82}; 83 84enum { 85 MLX5E_UC = 0, 86 MLX5E_MC_IPV4 = 1, 87 MLX5E_MC_IPV6 = 2, 88 MLX5E_MC_OTHER = 3, 89}; 90 91enum { 92 MLX5E_ACTION_NONE = 0, 93 MLX5E_ACTION_ADD = 1, 94 MLX5E_ACTION_DEL = 2, 95}; 96 97struct mlx5e_l2_hash_node { 98 struct hlist_node hlist; 99 u8 action; 100 struct mlx5e_l2_rule ai; 101 bool mpfs; 102}; 103 104static inline int mlx5e_hash_l2(const u8 *addr) 105{ 106 return addr[5]; 107} 108 109struct dentry *mlx5e_fs_get_debugfs_root(struct mlx5e_flow_steering *fs) 110{ 111 return fs->dfs_root; 112} 113 114static void mlx5e_add_l2_to_hash(struct hlist_head *hash, const u8 *addr) 115{ 116 struct mlx5e_l2_hash_node *hn; 117 int ix = mlx5e_hash_l2(addr); 118 int found = 0; 119 120 hlist_for_each_entry(hn, &hash[ix], hlist) 121 if (ether_addr_equal_64bits(hn->ai.addr, addr)) { 122 found = 1; 123 break; 124 } 125 126 if (found) { 127 hn->action = MLX5E_ACTION_NONE; 128 return; 129 } 130 131 hn = kzalloc(sizeof(*hn), GFP_ATOMIC); 132 if (!hn) 133 return; 134 135 ether_addr_copy(hn->ai.addr, addr); 136 hn->action = MLX5E_ACTION_ADD; 137 138 hlist_add_head(&hn->hlist, &hash[ix]); 139} 140 141static void mlx5e_del_l2_from_hash(struct mlx5e_l2_hash_node *hn) 142{ 143 hlist_del(&hn->hlist); 144 kfree(hn); 145} 146 147struct mlx5e_vlan_table { 148 struct mlx5e_flow_table ft; 149 DECLARE_BITMAP(active_cvlans, VLAN_N_VID); 150 DECLARE_BITMAP(active_svlans, VLAN_N_VID); 151 struct mlx5_flow_handle *active_cvlans_rule[VLAN_N_VID]; 152 struct mlx5_flow_handle *active_svlans_rule[VLAN_N_VID]; 153 struct mlx5_flow_handle *untagged_rule; 154 struct mlx5_flow_handle *any_cvlan_rule; 155 struct mlx5_flow_handle *any_svlan_rule; 156 struct mlx5_flow_handle *trap_rule; 157 bool cvlan_filter_disabled; 158}; 159 160unsigned long *mlx5e_vlan_get_active_svlans(struct mlx5e_vlan_table *vlan) 161{ 162 return vlan->active_svlans; 163} 164 165struct mlx5_flow_table *mlx5e_vlan_get_flowtable(struct mlx5e_vlan_table *vlan) 166{ 167 return vlan->ft.t; 168} 169 170static int mlx5e_vport_context_update_vlans(struct mlx5e_flow_steering *fs) 171{ 172 int max_list_size; 173 int list_size; 174 u16 *vlans; 175 int vlan; 176 int err; 177 int i; 178 179 list_size = 0; 180 for_each_set_bit(vlan, fs->vlan->active_cvlans, VLAN_N_VID) 181 list_size++; 182 183 max_list_size = 1 << MLX5_CAP_GEN(fs->mdev, log_max_vlan_list); 184 185 if (list_size > max_list_size) { 186 fs_warn(fs, "netdev vlans list size (%d) > (%d) max vport list size, some vlans will be dropped\n", 187 list_size, max_list_size); 188 list_size = max_list_size; 189 } 190 191 vlans = kvcalloc(list_size, sizeof(*vlans), GFP_KERNEL); 192 if (!vlans) 193 return -ENOMEM; 194 195 i = 0; 196 for_each_set_bit(vlan, fs->vlan->active_cvlans, VLAN_N_VID) { 197 if (i >= list_size) 198 break; 199 vlans[i++] = vlan; 200 } 201 202 err = mlx5_modify_nic_vport_vlans(fs->mdev, vlans, list_size); 203 if (err) 204 fs_err(fs, "Failed to modify vport vlans list err(%d)\n", 205 err); 206 207 kvfree(vlans); 208 return err; 209} 210 211enum mlx5e_vlan_rule_type { 212 MLX5E_VLAN_RULE_TYPE_UNTAGGED, 213 MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 214 MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 215 MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, 216 MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, 217}; 218 219static int __mlx5e_add_vlan_rule(struct mlx5e_flow_steering *fs, 220 enum mlx5e_vlan_rule_type rule_type, 221 u16 vid, struct mlx5_flow_spec *spec) 222{ 223 struct mlx5_flow_table *ft = fs->vlan->ft.t; 224 struct mlx5_flow_destination dest = {}; 225 struct mlx5_flow_handle **rule_p; 226 MLX5_DECLARE_FLOW_ACT(flow_act); 227 int err = 0; 228 229 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 230 dest.ft = fs->l2.ft.t; 231 232 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 233 234 switch (rule_type) { 235 case MLX5E_VLAN_RULE_TYPE_UNTAGGED: 236 /* cvlan_tag enabled in match criteria and 237 * disabled in match value means both S & C tags 238 * don't exist (untagged of both) 239 */ 240 rule_p = &fs->vlan->untagged_rule; 241 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, 242 outer_headers.cvlan_tag); 243 break; 244 case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID: 245 rule_p = &fs->vlan->any_cvlan_rule; 246 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, 247 outer_headers.cvlan_tag); 248 MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1); 249 break; 250 case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID: 251 rule_p = &fs->vlan->any_svlan_rule; 252 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, 253 outer_headers.svlan_tag); 254 MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1); 255 break; 256 case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID: 257 rule_p = &fs->vlan->active_svlans_rule[vid]; 258 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, 259 outer_headers.svlan_tag); 260 MLX5_SET(fte_match_param, spec->match_value, outer_headers.svlan_tag, 1); 261 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, 262 outer_headers.first_vid); 263 MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid, 264 vid); 265 break; 266 default: /* MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID */ 267 rule_p = &fs->vlan->active_cvlans_rule[vid]; 268 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, 269 outer_headers.cvlan_tag); 270 MLX5_SET(fte_match_param, spec->match_value, outer_headers.cvlan_tag, 1); 271 MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, 272 outer_headers.first_vid); 273 MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid, 274 vid); 275 break; 276 } 277 278 if (WARN_ONCE(*rule_p, "VLAN rule already exists type %d", rule_type)) 279 return 0; 280 281 *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1); 282 283 if (IS_ERR(*rule_p)) { 284 err = PTR_ERR(*rule_p); 285 *rule_p = NULL; 286 fs_err(fs, "add rule failed\n"); 287 } 288 289 return err; 290} 291 292static int mlx5e_add_vlan_rule(struct mlx5e_flow_steering *fs, 293 enum mlx5e_vlan_rule_type rule_type, u16 vid) 294{ 295 struct mlx5_flow_spec *spec; 296 int err = 0; 297 298 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 299 if (!spec) 300 return -ENOMEM; 301 302 if (rule_type == MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID) 303 mlx5e_vport_context_update_vlans(fs); 304 305 err = __mlx5e_add_vlan_rule(fs, rule_type, vid, spec); 306 307 kvfree(spec); 308 309 return err; 310} 311 312static void mlx5e_fs_del_vlan_rule(struct mlx5e_flow_steering *fs, 313 enum mlx5e_vlan_rule_type rule_type, u16 vid) 314{ 315 switch (rule_type) { 316 case MLX5E_VLAN_RULE_TYPE_UNTAGGED: 317 if (fs->vlan->untagged_rule) { 318 mlx5_del_flow_rules(fs->vlan->untagged_rule); 319 fs->vlan->untagged_rule = NULL; 320 } 321 break; 322 case MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID: 323 if (fs->vlan->any_cvlan_rule) { 324 mlx5_del_flow_rules(fs->vlan->any_cvlan_rule); 325 fs->vlan->any_cvlan_rule = NULL; 326 } 327 break; 328 case MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID: 329 if (fs->vlan->any_svlan_rule) { 330 mlx5_del_flow_rules(fs->vlan->any_svlan_rule); 331 fs->vlan->any_svlan_rule = NULL; 332 } 333 break; 334 case MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID: 335 if (fs->vlan->active_svlans_rule[vid]) { 336 mlx5_del_flow_rules(fs->vlan->active_svlans_rule[vid]); 337 fs->vlan->active_svlans_rule[vid] = NULL; 338 } 339 break; 340 case MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID: 341 if (fs->vlan->active_cvlans_rule[vid]) { 342 mlx5_del_flow_rules(fs->vlan->active_cvlans_rule[vid]); 343 fs->vlan->active_cvlans_rule[vid] = NULL; 344 } 345 mlx5e_vport_context_update_vlans(fs); 346 break; 347 } 348} 349 350static void mlx5e_fs_del_any_vid_rules(struct mlx5e_flow_steering *fs) 351{ 352 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); 353 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0); 354} 355 356static int mlx5e_fs_add_any_vid_rules(struct mlx5e_flow_steering *fs) 357{ 358 int err; 359 360 err = mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); 361 if (err) 362 return err; 363 364 return mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_STAG_VID, 0); 365} 366 367static struct mlx5_flow_handle * 368mlx5e_add_trap_rule(struct mlx5_flow_table *ft, int trap_id, int tir_num) 369{ 370 struct mlx5_flow_destination dest = {}; 371 MLX5_DECLARE_FLOW_ACT(flow_act); 372 struct mlx5_flow_handle *rule; 373 struct mlx5_flow_spec *spec; 374 375 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 376 if (!spec) 377 return ERR_PTR(-ENOMEM); 378 spec->flow_context.flags |= FLOW_CONTEXT_HAS_TAG; 379 spec->flow_context.flow_tag = trap_id; 380 dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; 381 dest.tir_num = tir_num; 382 383 rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1); 384 kvfree(spec); 385 return rule; 386} 387 388int mlx5e_add_vlan_trap(struct mlx5e_flow_steering *fs, int trap_id, int tir_num) 389{ 390 struct mlx5_flow_table *ft = fs->vlan->ft.t; 391 struct mlx5_flow_handle *rule; 392 int err; 393 394 rule = mlx5e_add_trap_rule(ft, trap_id, tir_num); 395 if (IS_ERR(rule)) { 396 err = PTR_ERR(rule); 397 fs->vlan->trap_rule = NULL; 398 fs_err(fs, "add VLAN trap rule failed, err %d\n", err); 399 return err; 400 } 401 fs->vlan->trap_rule = rule; 402 return 0; 403} 404 405void mlx5e_remove_vlan_trap(struct mlx5e_flow_steering *fs) 406{ 407 if (fs->vlan->trap_rule) { 408 mlx5_del_flow_rules(fs->vlan->trap_rule); 409 fs->vlan->trap_rule = NULL; 410 } 411} 412 413int mlx5e_add_mac_trap(struct mlx5e_flow_steering *fs, int trap_id, int tir_num) 414{ 415 struct mlx5_flow_table *ft = fs->l2.ft.t; 416 struct mlx5_flow_handle *rule; 417 int err; 418 419 rule = mlx5e_add_trap_rule(ft, trap_id, tir_num); 420 if (IS_ERR(rule)) { 421 err = PTR_ERR(rule); 422 fs->l2.trap_rule = NULL; 423 fs_err(fs, "add MAC trap rule failed, err %d\n", err); 424 return err; 425 } 426 fs->l2.trap_rule = rule; 427 return 0; 428} 429 430void mlx5e_remove_mac_trap(struct mlx5e_flow_steering *fs) 431{ 432 if (fs->l2.trap_rule) { 433 mlx5_del_flow_rules(fs->l2.trap_rule); 434 fs->l2.trap_rule = NULL; 435 } 436} 437 438void mlx5e_enable_cvlan_filter(struct mlx5e_flow_steering *fs, bool promisc) 439{ 440 if (!fs->vlan->cvlan_filter_disabled) 441 return; 442 443 fs->vlan->cvlan_filter_disabled = false; 444 if (promisc) 445 return; 446 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); 447} 448 449void mlx5e_disable_cvlan_filter(struct mlx5e_flow_steering *fs, bool promisc) 450{ 451 if (!fs->vlan || fs->vlan->cvlan_filter_disabled) 452 return; 453 454 fs->vlan->cvlan_filter_disabled = true; 455 if (promisc) 456 return; 457 mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_ANY_CTAG_VID, 0); 458} 459 460static int mlx5e_vlan_rx_add_cvid(struct mlx5e_flow_steering *fs, u16 vid) 461{ 462 int err; 463 464 set_bit(vid, fs->vlan->active_cvlans); 465 466 err = mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, vid); 467 if (err) 468 clear_bit(vid, fs->vlan->active_cvlans); 469 470 return err; 471} 472 473static int mlx5e_vlan_rx_add_svid(struct mlx5e_flow_steering *fs, 474 struct net_device *netdev, u16 vid) 475{ 476 int err; 477 478 set_bit(vid, fs->vlan->active_svlans); 479 480 err = mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, vid); 481 if (err) { 482 clear_bit(vid, fs->vlan->active_svlans); 483 return err; 484 } 485 486 /* Need to fix some features.. */ 487 netdev_lock(netdev); 488 netdev_update_features(netdev); 489 netdev_unlock(netdev); 490 return err; 491} 492 493int mlx5e_fs_vlan_rx_add_vid(struct mlx5e_flow_steering *fs, 494 struct net_device *netdev, 495 __be16 proto, u16 vid) 496{ 497 498 if (!fs->vlan) { 499 fs_err(fs, "Vlan doesn't exist\n"); 500 return -EINVAL; 501 } 502 503 if (be16_to_cpu(proto) == ETH_P_8021Q) 504 return mlx5e_vlan_rx_add_cvid(fs, vid); 505 else if (be16_to_cpu(proto) == ETH_P_8021AD) 506 return mlx5e_vlan_rx_add_svid(fs, netdev, vid); 507 508 return -EOPNOTSUPP; 509} 510 511int mlx5e_fs_vlan_rx_kill_vid(struct mlx5e_flow_steering *fs, 512 struct net_device *netdev, 513 __be16 proto, u16 vid) 514{ 515 if (!fs->vlan) { 516 fs_err(fs, "Vlan doesn't exist\n"); 517 return -EINVAL; 518 } 519 520 if (be16_to_cpu(proto) == ETH_P_8021Q) { 521 clear_bit(vid, fs->vlan->active_cvlans); 522 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, vid); 523 } else if (be16_to_cpu(proto) == ETH_P_8021AD) { 524 clear_bit(vid, fs->vlan->active_svlans); 525 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, vid); 526 netdev_lock(netdev); 527 netdev_update_features(netdev); 528 netdev_unlock(netdev); 529 } 530 531 return 0; 532} 533 534static void mlx5e_fs_add_vlan_rules(struct mlx5e_flow_steering *fs) 535{ 536 int i; 537 538 mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0); 539 540 for_each_set_bit(i, fs->vlan->active_cvlans, VLAN_N_VID) { 541 mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, i); 542 } 543 544 for_each_set_bit(i, fs->vlan->active_svlans, VLAN_N_VID) 545 mlx5e_add_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i); 546 547 if (fs->vlan->cvlan_filter_disabled) 548 mlx5e_fs_add_any_vid_rules(fs); 549} 550 551static void mlx5e_del_vlan_rules(struct mlx5e_flow_steering *fs) 552{ 553 int i; 554 555 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_UNTAGGED, 0); 556 557 for_each_set_bit(i, fs->vlan->active_cvlans, VLAN_N_VID) { 558 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_CTAG_VID, i); 559 } 560 561 for_each_set_bit(i, fs->vlan->active_svlans, VLAN_N_VID) 562 mlx5e_fs_del_vlan_rule(fs, MLX5E_VLAN_RULE_TYPE_MATCH_STAG_VID, i); 563 564 WARN_ON_ONCE(fs->state_destroy); 565 566 mlx5e_remove_vlan_trap(fs); 567 568 /* must be called after DESTROY bit is set and 569 * set_rx_mode is called and flushed 570 */ 571 if (fs->vlan->cvlan_filter_disabled) 572 mlx5e_fs_del_any_vid_rules(fs); 573} 574 575#define mlx5e_for_each_hash_node(hn, tmp, hash, i) \ 576 for (i = 0; i < MLX5E_L2_ADDR_HASH_SIZE; i++) \ 577 hlist_for_each_entry_safe(hn, tmp, &hash[i], hlist) 578 579static void mlx5e_execute_l2_action(struct mlx5e_flow_steering *fs, 580 struct mlx5e_l2_hash_node *hn) 581{ 582 u8 action = hn->action; 583 u8 mac_addr[ETH_ALEN]; 584 int l2_err = 0; 585 586 ether_addr_copy(mac_addr, hn->ai.addr); 587 588 switch (action) { 589 case MLX5E_ACTION_ADD: 590 mlx5e_add_l2_flow_rule(fs, &hn->ai, MLX5E_FULLMATCH); 591 if (!is_multicast_ether_addr(mac_addr)) { 592 l2_err = mlx5_mpfs_add_mac(fs->mdev, mac_addr); 593 hn->mpfs = !l2_err; 594 } 595 hn->action = MLX5E_ACTION_NONE; 596 break; 597 598 case MLX5E_ACTION_DEL: 599 if (!is_multicast_ether_addr(mac_addr) && hn->mpfs) 600 l2_err = mlx5_mpfs_del_mac(fs->mdev, mac_addr); 601 mlx5e_del_l2_flow_rule(fs, &hn->ai); 602 mlx5e_del_l2_from_hash(hn); 603 break; 604 } 605 606 if (l2_err) 607 fs_warn(fs, "MPFS, failed to %s mac %pM, err(%d)\n", 608 action == MLX5E_ACTION_ADD ? "add" : "del", 609 mac_addr, l2_err); 610} 611 612static void mlx5e_sync_netdev_addr(struct mlx5e_flow_steering *fs, 613 struct net_device *netdev) 614{ 615 struct netdev_hw_addr *ha; 616 617 netif_addr_lock_bh(netdev); 618 619 mlx5e_add_l2_to_hash(fs->l2.netdev_uc, netdev->dev_addr); 620 netdev_for_each_uc_addr(ha, netdev) 621 mlx5e_add_l2_to_hash(fs->l2.netdev_uc, ha->addr); 622 623 netdev_for_each_mc_addr(ha, netdev) 624 mlx5e_add_l2_to_hash(fs->l2.netdev_mc, ha->addr); 625 626 netif_addr_unlock_bh(netdev); 627} 628 629static void mlx5e_fill_addr_array(struct mlx5e_flow_steering *fs, int list_type, 630 struct net_device *ndev, 631 u8 addr_array[][ETH_ALEN], int size) 632{ 633 bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC); 634 struct mlx5e_l2_hash_node *hn; 635 struct hlist_head *addr_list; 636 struct hlist_node *tmp; 637 int i = 0; 638 int hi; 639 640 addr_list = is_uc ? fs->l2.netdev_uc : fs->l2.netdev_mc; 641 642 if (is_uc) /* Make sure our own address is pushed first */ 643 ether_addr_copy(addr_array[i++], ndev->dev_addr); 644 else if (fs->l2.broadcast_enabled) 645 ether_addr_copy(addr_array[i++], ndev->broadcast); 646 647 mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) { 648 if (ether_addr_equal(ndev->dev_addr, hn->ai.addr)) 649 continue; 650 if (i >= size) 651 break; 652 ether_addr_copy(addr_array[i++], hn->ai.addr); 653 } 654} 655 656static void mlx5e_vport_context_update_addr_list(struct mlx5e_flow_steering *fs, 657 struct net_device *netdev, 658 int list_type) 659{ 660 bool is_uc = (list_type == MLX5_NVPRT_LIST_TYPE_UC); 661 struct mlx5e_l2_hash_node *hn; 662 u8 (*addr_array)[ETH_ALEN] = NULL; 663 struct hlist_head *addr_list; 664 struct hlist_node *tmp; 665 int max_size; 666 int size; 667 int err; 668 int hi; 669 670 size = is_uc ? 0 : (fs->l2.broadcast_enabled ? 1 : 0); 671 max_size = is_uc ? 672 1 << MLX5_CAP_GEN(fs->mdev, log_max_current_uc_list) : 673 1 << MLX5_CAP_GEN(fs->mdev, log_max_current_mc_list); 674 675 addr_list = is_uc ? fs->l2.netdev_uc : fs->l2.netdev_mc; 676 mlx5e_for_each_hash_node(hn, tmp, addr_list, hi) 677 size++; 678 679 if (size > max_size) { 680 fs_warn(fs, "mdev %s list size (%d) > (%d) max vport list size, some addresses will be dropped\n", 681 is_uc ? "UC" : "MC", size, max_size); 682 size = max_size; 683 } 684 685 if (size) { 686 addr_array = kcalloc(size, ETH_ALEN, GFP_KERNEL); 687 if (!addr_array) { 688 err = -ENOMEM; 689 goto out; 690 } 691 mlx5e_fill_addr_array(fs, list_type, netdev, addr_array, size); 692 } 693 694 err = mlx5_modify_nic_vport_mac_list(fs->mdev, list_type, addr_array, size); 695out: 696 if (err) 697 fs_err(fs, "Failed to modify vport %s list err(%d)\n", 698 is_uc ? "UC" : "MC", err); 699 kfree(addr_array); 700} 701 702static void mlx5e_vport_context_update(struct mlx5e_flow_steering *fs, 703 struct net_device *netdev) 704{ 705 struct mlx5e_l2_table *ea = &fs->l2; 706 707 mlx5e_vport_context_update_addr_list(fs, netdev, MLX5_NVPRT_LIST_TYPE_UC); 708 mlx5e_vport_context_update_addr_list(fs, netdev, MLX5_NVPRT_LIST_TYPE_MC); 709 mlx5_modify_nic_vport_promisc(fs->mdev, 0, 710 ea->allmulti_enabled, 711 ea->promisc_enabled); 712} 713 714static void mlx5e_apply_netdev_addr(struct mlx5e_flow_steering *fs) 715{ 716 struct mlx5e_l2_hash_node *hn; 717 struct hlist_node *tmp; 718 int i; 719 720 mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_uc, i) 721 mlx5e_execute_l2_action(fs, hn); 722 723 mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_mc, i) 724 mlx5e_execute_l2_action(fs, hn); 725} 726 727static void mlx5e_handle_netdev_addr(struct mlx5e_flow_steering *fs, 728 struct net_device *netdev) 729{ 730 struct mlx5e_l2_hash_node *hn; 731 struct hlist_node *tmp; 732 int i; 733 734 mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_uc, i) 735 hn->action = MLX5E_ACTION_DEL; 736 mlx5e_for_each_hash_node(hn, tmp, fs->l2.netdev_mc, i) 737 hn->action = MLX5E_ACTION_DEL; 738 739 if (fs->state_destroy) 740 mlx5e_sync_netdev_addr(fs, netdev); 741 742 mlx5e_apply_netdev_addr(fs); 743} 744 745#define MLX5E_PROMISC_GROUP0_SIZE BIT(0) 746#define MLX5E_PROMISC_TABLE_SIZE MLX5E_PROMISC_GROUP0_SIZE 747 748static int mlx5e_add_promisc_rule(struct mlx5e_flow_steering *fs) 749{ 750 struct mlx5_flow_table *ft = fs->promisc.ft.t; 751 struct mlx5_flow_destination dest = {}; 752 struct mlx5_flow_handle **rule_p; 753 MLX5_DECLARE_FLOW_ACT(flow_act); 754 struct mlx5_flow_spec *spec; 755 int err = 0; 756 757 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 758 if (!spec) 759 return -ENOMEM; 760 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 761 dest.ft = mlx5_get_ttc_flow_table(fs->ttc); 762 763 rule_p = &fs->promisc.rule; 764 *rule_p = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1); 765 if (IS_ERR(*rule_p)) { 766 err = PTR_ERR(*rule_p); 767 *rule_p = NULL; 768 fs_err(fs, "add promiscuous rule failed\n"); 769 } 770 kvfree(spec); 771 return err; 772} 773 774static int mlx5e_create_promisc_table(struct mlx5e_flow_steering *fs) 775{ 776 struct mlx5e_flow_table *ft = &fs->promisc.ft; 777 struct mlx5_flow_table_attr ft_attr = {}; 778 int err; 779 780 ft_attr.max_fte = MLX5E_PROMISC_TABLE_SIZE; 781 ft_attr.autogroup.max_num_groups = 1; 782 ft_attr.level = MLX5E_PROMISC_FT_LEVEL; 783 ft_attr.prio = MLX5E_PROMISC_PRIO; 784 785 ft->t = mlx5_create_auto_grouped_flow_table(fs->ns, &ft_attr); 786 if (IS_ERR(ft->t)) { 787 err = PTR_ERR(ft->t); 788 ft->t = NULL; 789 fs_err(fs, "fail to create promisc table err=%d\n", err); 790 return err; 791 } 792 793 err = mlx5e_add_promisc_rule(fs); 794 if (err) 795 goto err_destroy_promisc_table; 796 797 return 0; 798 799err_destroy_promisc_table: 800 mlx5_destroy_flow_table(ft->t); 801 ft->t = NULL; 802 803 return err; 804} 805 806static void mlx5e_del_promisc_rule(struct mlx5e_flow_steering *fs) 807{ 808 if (WARN(!fs->promisc.rule, "Trying to remove non-existing promiscuous rule")) 809 return; 810 mlx5_del_flow_rules(fs->promisc.rule); 811 fs->promisc.rule = NULL; 812} 813 814static void mlx5e_destroy_promisc_table(struct mlx5e_flow_steering *fs) 815{ 816 if (!fs->promisc.ft.t) 817 return; 818 mlx5e_del_promisc_rule(fs); 819 mlx5_destroy_flow_table(fs->promisc.ft.t); 820 fs->promisc.ft.t = NULL; 821} 822 823void mlx5e_fs_set_rx_mode_work(struct mlx5e_flow_steering *fs, 824 struct net_device *netdev) 825{ 826 struct mlx5e_l2_table *ea = &fs->l2; 827 828 bool rx_mode_enable = fs->state_destroy; 829 bool promisc_enabled = rx_mode_enable && (netdev->flags & IFF_PROMISC); 830 bool allmulti_enabled = rx_mode_enable && (netdev->flags & IFF_ALLMULTI); 831 bool broadcast_enabled = rx_mode_enable; 832 833 bool enable_promisc = !ea->promisc_enabled && promisc_enabled; 834 bool disable_promisc = ea->promisc_enabled && !promisc_enabled; 835 bool enable_allmulti = !ea->allmulti_enabled && allmulti_enabled; 836 bool disable_allmulti = ea->allmulti_enabled && !allmulti_enabled; 837 bool enable_broadcast = !ea->broadcast_enabled && broadcast_enabled; 838 bool disable_broadcast = ea->broadcast_enabled && !broadcast_enabled; 839 int err; 840 841 if (enable_promisc) { 842 err = mlx5e_create_promisc_table(fs); 843 if (err) 844 enable_promisc = false; 845 if (!fs->vlan_strip_disable && !err) 846 fs_warn_once(fs, 847 "S-tagged traffic will be dropped while C-tag vlan stripping is enabled\n"); 848 } 849 if (enable_allmulti) 850 mlx5e_add_l2_flow_rule(fs, &ea->allmulti, MLX5E_ALLMULTI); 851 if (enable_broadcast) 852 mlx5e_add_l2_flow_rule(fs, &ea->broadcast, MLX5E_FULLMATCH); 853 854 mlx5e_handle_netdev_addr(fs, netdev); 855 856 if (disable_broadcast) 857 mlx5e_del_l2_flow_rule(fs, &ea->broadcast); 858 if (disable_allmulti) 859 mlx5e_del_l2_flow_rule(fs, &ea->allmulti); 860 if (disable_promisc) 861 mlx5e_destroy_promisc_table(fs); 862 863 ea->promisc_enabled = promisc_enabled; 864 ea->allmulti_enabled = allmulti_enabled; 865 ea->broadcast_enabled = broadcast_enabled; 866 867 mlx5e_vport_context_update(fs, netdev); 868} 869 870static void mlx5e_destroy_groups(struct mlx5e_flow_table *ft) 871{ 872 int i; 873 874 for (i = ft->num_groups - 1; i >= 0; i--) { 875 if (!IS_ERR_OR_NULL(ft->g[i])) 876 mlx5_destroy_flow_group(ft->g[i]); 877 ft->g[i] = NULL; 878 } 879 ft->num_groups = 0; 880} 881 882void mlx5e_fs_init_l2_addr(struct mlx5e_flow_steering *fs, struct net_device *netdev) 883{ 884 ether_addr_copy(fs->l2.broadcast.addr, netdev->broadcast); 885} 886 887void mlx5e_destroy_flow_table(struct mlx5e_flow_table *ft) 888{ 889 mlx5e_destroy_groups(ft); 890 kfree(ft->g); 891 mlx5_destroy_flow_table(ft->t); 892 ft->t = NULL; 893} 894 895static void mlx5e_set_inner_ttc_params(struct mlx5e_flow_steering *fs, 896 struct mlx5e_rx_res *rx_res, 897 struct ttc_params *ttc_params) 898{ 899 struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr; 900 int tt; 901 902 memset(ttc_params, 0, sizeof(*ttc_params)); 903 ttc_params->ns_type = MLX5_FLOW_NAMESPACE_KERNEL; 904 ft_attr->level = MLX5E_INNER_TTC_FT_LEVEL; 905 ft_attr->prio = MLX5E_NIC_PRIO; 906 907 for (tt = 0; tt < MLX5_NUM_TT; tt++) { 908 if (mlx5_ttc_is_decrypted_esp_tt(tt)) 909 continue; 910 911 ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR; 912 ttc_params->dests[tt].tir_num = 913 tt == MLX5_TT_ANY ? 914 mlx5e_rx_res_get_tirn_direct(rx_res, 0) : 915 mlx5e_rx_res_get_tirn_rss_inner(rx_res, 916 tt); 917 } 918} 919 920static bool mlx5e_ipsec_rss_supported(struct mlx5_core_dev *mdev) 921{ 922 return MLX5_CAP_NIC_RX_FT_FIELD_SUPPORT_2(mdev, ipsec_next_header) && 923 MLX5_CAP_NIC_RX_FT_FIELD_SUPPORT_2(mdev, outer_l4_type_ext) && 924 MLX5_CAP_NIC_RX_FT_FIELD_SUPPORT_2(mdev, inner_l4_type_ext); 925} 926 927void mlx5e_set_ttc_params(struct mlx5e_flow_steering *fs, 928 struct mlx5e_rx_res *rx_res, 929 struct ttc_params *ttc_params, bool tunnel, 930 bool ipsec_rss) 931 932{ 933 struct mlx5_flow_table_attr *ft_attr = &ttc_params->ft_attr; 934 int tt; 935 936 memset(ttc_params, 0, sizeof(*ttc_params)); 937 ttc_params->ns_type = MLX5_FLOW_NAMESPACE_KERNEL; 938 ft_attr->level = MLX5E_TTC_FT_LEVEL; 939 ft_attr->prio = MLX5E_NIC_PRIO; 940 941 ttc_params->ipsec_rss = ipsec_rss && 942 mlx5e_ipsec_rss_supported(fs->mdev); 943 944 for (tt = 0; tt < MLX5_NUM_TT; tt++) { 945 if (mlx5_ttc_is_decrypted_esp_tt(tt)) 946 continue; 947 948 ttc_params->dests[tt].type = MLX5_FLOW_DESTINATION_TYPE_TIR; 949 ttc_params->dests[tt].tir_num = 950 tt == MLX5_TT_ANY ? 951 mlx5e_rx_res_get_tirn_direct(rx_res, 0) : 952 mlx5e_rx_res_get_tirn_rss(rx_res, tt); 953 } 954 955 ttc_params->inner_ttc = tunnel; 956 if (!tunnel || !mlx5_tunnel_inner_ft_supported(fs->mdev)) 957 return; 958 959 for (tt = 0; tt < MLX5_NUM_TUNNEL_TT; tt++) { 960 ttc_params->tunnel_dests[tt].type = 961 MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 962 ttc_params->tunnel_dests[tt].ft = 963 mlx5_get_ttc_flow_table(fs->inner_ttc); 964 } 965} 966 967static void mlx5e_del_l2_flow_rule(struct mlx5e_flow_steering *fs, 968 struct mlx5e_l2_rule *ai) 969{ 970 if (!IS_ERR_OR_NULL(ai->rule)) { 971 mlx5_del_flow_rules(ai->rule); 972 ai->rule = NULL; 973 } 974} 975 976static int mlx5e_add_l2_flow_rule(struct mlx5e_flow_steering *fs, 977 struct mlx5e_l2_rule *ai, int type) 978{ 979 struct mlx5_flow_table *ft = fs->l2.ft.t; 980 struct mlx5_flow_destination dest = {}; 981 MLX5_DECLARE_FLOW_ACT(flow_act); 982 struct mlx5_flow_spec *spec; 983 int err = 0; 984 u8 *mc_dmac; 985 u8 *mv_dmac; 986 987 spec = kvzalloc(sizeof(*spec), GFP_KERNEL); 988 if (!spec) 989 return -ENOMEM; 990 991 mc_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_criteria, 992 outer_headers.dmac_47_16); 993 mv_dmac = MLX5_ADDR_OF(fte_match_param, spec->match_value, 994 outer_headers.dmac_47_16); 995 996 dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 997 dest.ft = mlx5_get_ttc_flow_table(fs->ttc); 998 999 switch (type) { 1000 case MLX5E_FULLMATCH: 1001 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 1002 eth_broadcast_addr(mc_dmac); 1003 ether_addr_copy(mv_dmac, ai->addr); 1004 break; 1005 1006 case MLX5E_ALLMULTI: 1007 spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; 1008 mc_dmac[0] = 0x01; 1009 mv_dmac[0] = 0x01; 1010 break; 1011 } 1012 1013 ai->rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1); 1014 if (IS_ERR(ai->rule)) { 1015 fs_err(fs, "add l2 rule(mac:%pM) failed\n", mv_dmac); 1016 err = PTR_ERR(ai->rule); 1017 ai->rule = NULL; 1018 } 1019 1020 kvfree(spec); 1021 1022 return err; 1023} 1024 1025#define MLX5E_NUM_L2_GROUPS 3 1026#define MLX5E_L2_GROUP1_SIZE BIT(15) 1027#define MLX5E_L2_GROUP2_SIZE BIT(0) 1028#define MLX5E_L2_GROUP_TRAP_SIZE BIT(0) /* must be last */ 1029#define MLX5E_L2_TABLE_SIZE (MLX5E_L2_GROUP1_SIZE +\ 1030 MLX5E_L2_GROUP2_SIZE +\ 1031 MLX5E_L2_GROUP_TRAP_SIZE) 1032static int mlx5e_create_l2_table_groups(struct mlx5e_l2_table *l2_table) 1033{ 1034 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1035 struct mlx5e_flow_table *ft = &l2_table->ft; 1036 int ix = 0; 1037 u8 *mc_dmac; 1038 u32 *in; 1039 int err; 1040 u8 *mc; 1041 1042 ft->g = kcalloc(MLX5E_NUM_L2_GROUPS, sizeof(*ft->g), GFP_KERNEL); 1043 if (!ft->g) 1044 return -ENOMEM; 1045 in = kvzalloc(inlen, GFP_KERNEL); 1046 if (!in) { 1047 kfree(ft->g); 1048 return -ENOMEM; 1049 } 1050 1051 mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); 1052 mc_dmac = MLX5_ADDR_OF(fte_match_param, mc, 1053 outer_headers.dmac_47_16); 1054 /* Flow Group for full match */ 1055 eth_broadcast_addr(mc_dmac); 1056 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1057 MLX5_SET_CFG(in, start_flow_index, ix); 1058 ix += MLX5E_L2_GROUP1_SIZE; 1059 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1060 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1061 if (IS_ERR(ft->g[ft->num_groups])) 1062 goto err_destroy_groups; 1063 ft->num_groups++; 1064 1065 /* Flow Group for allmulti */ 1066 eth_zero_addr(mc_dmac); 1067 mc_dmac[0] = 0x01; 1068 MLX5_SET_CFG(in, start_flow_index, ix); 1069 ix += MLX5E_L2_GROUP2_SIZE; 1070 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1071 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1072 if (IS_ERR(ft->g[ft->num_groups])) 1073 goto err_destroy_groups; 1074 ft->num_groups++; 1075 1076 /* Flow Group for l2 traps */ 1077 memset(in, 0, inlen); 1078 MLX5_SET_CFG(in, start_flow_index, ix); 1079 ix += MLX5E_L2_GROUP_TRAP_SIZE; 1080 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1081 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1082 if (IS_ERR(ft->g[ft->num_groups])) 1083 goto err_destroy_groups; 1084 ft->num_groups++; 1085 1086 kvfree(in); 1087 return 0; 1088 1089err_destroy_groups: 1090 err = PTR_ERR(ft->g[ft->num_groups]); 1091 ft->g[ft->num_groups] = NULL; 1092 mlx5e_destroy_groups(ft); 1093 kvfree(in); 1094 kfree(ft->g); 1095 1096 return err; 1097} 1098 1099static void mlx5e_destroy_l2_table(struct mlx5e_flow_steering *fs) 1100{ 1101 mlx5e_destroy_flow_table(&fs->l2.ft); 1102} 1103 1104static int mlx5e_create_l2_table(struct mlx5e_flow_steering *fs) 1105{ 1106 struct mlx5e_l2_table *l2_table = &fs->l2; 1107 struct mlx5e_flow_table *ft = &l2_table->ft; 1108 struct mlx5_flow_table_attr ft_attr = {}; 1109 int err; 1110 1111 ft->num_groups = 0; 1112 1113 ft_attr.max_fte = MLX5E_L2_TABLE_SIZE; 1114 ft_attr.level = MLX5E_L2_FT_LEVEL; 1115 ft_attr.prio = MLX5E_NIC_PRIO; 1116 1117 ft->t = mlx5_create_flow_table(fs->ns, &ft_attr); 1118 if (IS_ERR(ft->t)) { 1119 err = PTR_ERR(ft->t); 1120 ft->t = NULL; 1121 return err; 1122 } 1123 1124 err = mlx5e_create_l2_table_groups(l2_table); 1125 if (err) 1126 goto err_destroy_flow_table; 1127 1128 return 0; 1129 1130err_destroy_flow_table: 1131 mlx5_destroy_flow_table(ft->t); 1132 ft->t = NULL; 1133 1134 return err; 1135} 1136 1137#define MLX5E_NUM_VLAN_GROUPS 5 1138#define MLX5E_VLAN_GROUP0_SIZE BIT(12) 1139#define MLX5E_VLAN_GROUP1_SIZE BIT(12) 1140#define MLX5E_VLAN_GROUP2_SIZE BIT(1) 1141#define MLX5E_VLAN_GROUP3_SIZE BIT(0) 1142#define MLX5E_VLAN_GROUP_TRAP_SIZE BIT(0) /* must be last */ 1143#define MLX5E_VLAN_TABLE_SIZE (MLX5E_VLAN_GROUP0_SIZE +\ 1144 MLX5E_VLAN_GROUP1_SIZE +\ 1145 MLX5E_VLAN_GROUP2_SIZE +\ 1146 MLX5E_VLAN_GROUP3_SIZE +\ 1147 MLX5E_VLAN_GROUP_TRAP_SIZE) 1148 1149static int __mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft, u32 *in, 1150 int inlen) 1151{ 1152 int err; 1153 int ix = 0; 1154 u8 *mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); 1155 1156 memset(in, 0, inlen); 1157 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1158 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag); 1159 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid); 1160 MLX5_SET_CFG(in, start_flow_index, ix); 1161 ix += MLX5E_VLAN_GROUP0_SIZE; 1162 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1163 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1164 if (IS_ERR(ft->g[ft->num_groups])) 1165 goto err_destroy_groups; 1166 ft->num_groups++; 1167 1168 memset(in, 0, inlen); 1169 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1170 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag); 1171 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.first_vid); 1172 MLX5_SET_CFG(in, start_flow_index, ix); 1173 ix += MLX5E_VLAN_GROUP1_SIZE; 1174 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1175 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1176 if (IS_ERR(ft->g[ft->num_groups])) 1177 goto err_destroy_groups; 1178 ft->num_groups++; 1179 1180 memset(in, 0, inlen); 1181 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1182 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.cvlan_tag); 1183 MLX5_SET_CFG(in, start_flow_index, ix); 1184 ix += MLX5E_VLAN_GROUP2_SIZE; 1185 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1186 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1187 if (IS_ERR(ft->g[ft->num_groups])) 1188 goto err_destroy_groups; 1189 ft->num_groups++; 1190 1191 memset(in, 0, inlen); 1192 MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); 1193 MLX5_SET_TO_ONES(fte_match_param, mc, outer_headers.svlan_tag); 1194 MLX5_SET_CFG(in, start_flow_index, ix); 1195 ix += MLX5E_VLAN_GROUP3_SIZE; 1196 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1197 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1198 if (IS_ERR(ft->g[ft->num_groups])) 1199 goto err_destroy_groups; 1200 ft->num_groups++; 1201 1202 memset(in, 0, inlen); 1203 MLX5_SET_CFG(in, start_flow_index, ix); 1204 ix += MLX5E_VLAN_GROUP_TRAP_SIZE; 1205 MLX5_SET_CFG(in, end_flow_index, ix - 1); 1206 ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); 1207 if (IS_ERR(ft->g[ft->num_groups])) 1208 goto err_destroy_groups; 1209 ft->num_groups++; 1210 1211 return 0; 1212 1213err_destroy_groups: 1214 err = PTR_ERR(ft->g[ft->num_groups]); 1215 ft->g[ft->num_groups] = NULL; 1216 mlx5e_destroy_groups(ft); 1217 1218 return err; 1219} 1220 1221static int mlx5e_create_vlan_table_groups(struct mlx5e_flow_table *ft) 1222{ 1223 u32 *in; 1224 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 1225 int err; 1226 1227 in = kvzalloc(inlen, GFP_KERNEL); 1228 if (!in) 1229 return -ENOMEM; 1230 1231 err = __mlx5e_create_vlan_table_groups(ft, in, inlen); 1232 1233 kvfree(in); 1234 return err; 1235} 1236 1237static int mlx5e_fs_create_vlan_table(struct mlx5e_flow_steering *fs) 1238{ 1239 struct mlx5_flow_table_attr ft_attr = {}; 1240 struct mlx5e_flow_table *ft; 1241 int err; 1242 1243 ft = &fs->vlan->ft; 1244 ft->num_groups = 0; 1245 1246 ft_attr.max_fte = MLX5E_VLAN_TABLE_SIZE; 1247 ft_attr.level = MLX5E_VLAN_FT_LEVEL; 1248 ft_attr.prio = MLX5E_NIC_PRIO; 1249 1250 ft->t = mlx5_create_flow_table(fs->ns, &ft_attr); 1251 if (IS_ERR(ft->t)) 1252 return PTR_ERR(ft->t); 1253 1254 ft->g = kcalloc(MLX5E_NUM_VLAN_GROUPS, sizeof(*ft->g), GFP_KERNEL); 1255 if (!ft->g) { 1256 err = -ENOMEM; 1257 goto err_destroy_vlan_table; 1258 } 1259 1260 err = mlx5e_create_vlan_table_groups(ft); 1261 if (err) 1262 goto err_free_g; 1263 1264 mlx5e_fs_add_vlan_rules(fs); 1265 1266 return 0; 1267 1268err_free_g: 1269 kfree(ft->g); 1270err_destroy_vlan_table: 1271 mlx5_destroy_flow_table(ft->t); 1272 1273 return err; 1274} 1275 1276static void mlx5e_destroy_vlan_table(struct mlx5e_flow_steering *fs) 1277{ 1278 mlx5e_del_vlan_rules(fs); 1279 mlx5e_destroy_flow_table(&fs->vlan->ft); 1280} 1281 1282static void mlx5e_destroy_inner_ttc_table(struct mlx5e_flow_steering *fs) 1283{ 1284 if (!mlx5_tunnel_inner_ft_supported(fs->mdev)) 1285 return; 1286 mlx5_destroy_ttc_table(fs->inner_ttc); 1287} 1288 1289void mlx5e_destroy_ttc_table(struct mlx5e_flow_steering *fs) 1290{ 1291 mlx5_destroy_ttc_table(fs->ttc); 1292} 1293 1294static int mlx5e_create_inner_ttc_table(struct mlx5e_flow_steering *fs, 1295 struct mlx5e_rx_res *rx_res) 1296{ 1297 struct ttc_params ttc_params = {}; 1298 1299 if (!mlx5_tunnel_inner_ft_supported(fs->mdev)) 1300 return 0; 1301 1302 mlx5e_set_inner_ttc_params(fs, rx_res, &ttc_params); 1303 fs->inner_ttc = mlx5_create_inner_ttc_table(fs->mdev, 1304 &ttc_params); 1305 return PTR_ERR_OR_ZERO(fs->inner_ttc); 1306} 1307 1308int mlx5e_create_ttc_table(struct mlx5e_flow_steering *fs, 1309 struct mlx5e_rx_res *rx_res) 1310{ 1311 struct ttc_params ttc_params = {}; 1312 1313 mlx5e_set_ttc_params(fs, rx_res, &ttc_params, true, true); 1314 fs->ttc = mlx5_create_ttc_table(fs->mdev, &ttc_params); 1315 return PTR_ERR_OR_ZERO(fs->ttc); 1316} 1317 1318int mlx5e_create_flow_steering(struct mlx5e_flow_steering *fs, 1319 struct mlx5e_rx_res *rx_res, 1320 const struct mlx5e_profile *profile, 1321 struct net_device *netdev) 1322{ 1323 struct mlx5_flow_namespace *ns = mlx5_get_flow_namespace(fs->mdev, 1324 MLX5_FLOW_NAMESPACE_KERNEL); 1325 int err; 1326 1327 if (!ns) 1328 return -EOPNOTSUPP; 1329 1330 mlx5e_fs_set_ns(fs, ns, false); 1331 err = mlx5e_arfs_create_tables(fs, rx_res, mlx5e_fs_has_arfs(netdev)); 1332 if (err) { 1333 fs_err(fs, "Failed to create arfs tables, err=%d\n", err); 1334 netdev->hw_features &= ~NETIF_F_NTUPLE; 1335 } 1336 1337 err = mlx5e_create_inner_ttc_table(fs, rx_res); 1338 if (err) { 1339 fs_err(fs, "Failed to create inner ttc table, err=%d\n", err); 1340 goto err_destroy_arfs_tables; 1341 } 1342 1343 err = mlx5e_create_ttc_table(fs, rx_res); 1344 if (err) { 1345 fs_err(fs, "Failed to create ttc table, err=%d\n", err); 1346 goto err_destroy_inner_ttc_table; 1347 } 1348 1349 err = mlx5e_create_l2_table(fs); 1350 if (err) { 1351 fs_err(fs, "Failed to create l2 table, err=%d\n", err); 1352 goto err_destroy_ttc_table; 1353 } 1354 1355 err = mlx5e_fs_create_vlan_table(fs); 1356 if (err) { 1357 fs_err(fs, "Failed to create vlan table, err=%d\n", err); 1358 goto err_destroy_l2_table; 1359 } 1360 1361 err = mlx5e_ptp_alloc_rx_fs(fs, profile); 1362 if (err) 1363 goto err_destory_vlan_table; 1364 1365 mlx5e_ethtool_init_steering(fs); 1366 1367 return 0; 1368 1369err_destory_vlan_table: 1370 mlx5e_destroy_vlan_table(fs); 1371err_destroy_l2_table: 1372 mlx5e_destroy_l2_table(fs); 1373err_destroy_ttc_table: 1374 mlx5e_destroy_ttc_table(fs); 1375err_destroy_inner_ttc_table: 1376 mlx5e_destroy_inner_ttc_table(fs); 1377err_destroy_arfs_tables: 1378 mlx5e_arfs_destroy_tables(fs, mlx5e_fs_has_arfs(netdev)); 1379 1380 return err; 1381} 1382 1383void mlx5e_destroy_flow_steering(struct mlx5e_flow_steering *fs, bool ntuple, 1384 const struct mlx5e_profile *profile) 1385{ 1386 mlx5e_ptp_free_rx_fs(fs, profile); 1387 mlx5e_destroy_vlan_table(fs); 1388 mlx5e_destroy_l2_table(fs); 1389 mlx5e_destroy_ttc_table(fs); 1390 mlx5e_destroy_inner_ttc_table(fs); 1391 mlx5e_arfs_destroy_tables(fs, ntuple); 1392 mlx5e_ethtool_cleanup_steering(fs); 1393} 1394 1395static int mlx5e_fs_vlan_alloc(struct mlx5e_flow_steering *fs) 1396{ 1397 fs->vlan = kvzalloc(sizeof(*fs->vlan), GFP_KERNEL); 1398 if (!fs->vlan) 1399 return -ENOMEM; 1400 return 0; 1401} 1402 1403static void mlx5e_fs_vlan_free(struct mlx5e_flow_steering *fs) 1404{ 1405 kvfree(fs->vlan); 1406} 1407 1408struct mlx5e_vlan_table *mlx5e_fs_get_vlan(struct mlx5e_flow_steering *fs) 1409{ 1410 return fs->vlan; 1411} 1412 1413static int mlx5e_fs_tc_alloc(struct mlx5e_flow_steering *fs) 1414{ 1415 fs->tc = mlx5e_tc_table_alloc(); 1416 if (IS_ERR(fs->tc)) 1417 return -ENOMEM; 1418 return 0; 1419} 1420 1421static void mlx5e_fs_tc_free(struct mlx5e_flow_steering *fs) 1422{ 1423 mlx5e_tc_table_free(fs->tc); 1424} 1425 1426struct mlx5e_tc_table *mlx5e_fs_get_tc(struct mlx5e_flow_steering *fs) 1427{ 1428 return fs->tc; 1429} 1430 1431#ifdef CONFIG_MLX5_EN_RXNFC 1432static int mlx5e_fs_ethtool_alloc(struct mlx5e_flow_steering *fs) 1433{ 1434 return mlx5e_ethtool_alloc(&fs->ethtool); 1435} 1436 1437static void mlx5e_fs_ethtool_free(struct mlx5e_flow_steering *fs) 1438{ 1439 mlx5e_ethtool_free(fs->ethtool); 1440} 1441 1442struct mlx5e_ethtool_steering *mlx5e_fs_get_ethtool(struct mlx5e_flow_steering *fs) 1443{ 1444 return fs->ethtool; 1445} 1446#else 1447static int mlx5e_fs_ethtool_alloc(struct mlx5e_flow_steering *fs) 1448{ return 0; } 1449static void mlx5e_fs_ethtool_free(struct mlx5e_flow_steering *fs) { } 1450#endif 1451 1452static void mlx5e_fs_debugfs_init(struct mlx5e_flow_steering *fs, 1453 struct dentry *dfs_root) 1454{ 1455 if (IS_ERR_OR_NULL(dfs_root)) 1456 return; 1457 1458 fs->dfs_root = debugfs_create_dir("fs", dfs_root); 1459} 1460 1461struct mlx5e_flow_steering *mlx5e_fs_init(const struct mlx5e_profile *profile, 1462 struct mlx5_core_dev *mdev, 1463 bool state_destroy, 1464 struct dentry *dfs_root) 1465{ 1466 struct mlx5e_flow_steering *fs; 1467 int err; 1468 1469 fs = kvzalloc(sizeof(*fs), GFP_KERNEL); 1470 if (!fs) 1471 goto err; 1472 1473 fs->mdev = mdev; 1474 fs->state_destroy = state_destroy; 1475 if (mlx5e_profile_feature_cap(profile, FS_VLAN)) { 1476 err = mlx5e_fs_vlan_alloc(fs); 1477 if (err) 1478 goto err_free_fs; 1479 } 1480 1481 if (mlx5e_profile_feature_cap(profile, FS_TC)) { 1482 err = mlx5e_fs_tc_alloc(fs); 1483 if (err) 1484 goto err_free_vlan; 1485 } 1486 1487 err = mlx5e_fs_ethtool_alloc(fs); 1488 if (err) 1489 goto err_free_tc; 1490 1491 mlx5e_fs_debugfs_init(fs, dfs_root); 1492 1493 return fs; 1494err_free_tc: 1495 mlx5e_fs_tc_free(fs); 1496err_free_vlan: 1497 mlx5e_fs_vlan_free(fs); 1498err_free_fs: 1499 kvfree(fs); 1500err: 1501 return NULL; 1502} 1503 1504void mlx5e_fs_cleanup(struct mlx5e_flow_steering *fs) 1505{ 1506 if (!fs) 1507 return; 1508 debugfs_remove_recursive(fs->dfs_root); 1509 mlx5e_fs_ethtool_free(fs); 1510 mlx5e_fs_tc_free(fs); 1511 mlx5e_fs_vlan_free(fs); 1512 kvfree(fs); 1513} 1514 1515struct mlx5e_l2_table *mlx5e_fs_get_l2(struct mlx5e_flow_steering *fs) 1516{ 1517 return &fs->l2; 1518} 1519 1520struct mlx5_flow_namespace *mlx5e_fs_get_ns(struct mlx5e_flow_steering *fs, bool egress) 1521{ 1522 return egress ? fs->egress_ns : fs->ns; 1523} 1524 1525void mlx5e_fs_set_ns(struct mlx5e_flow_steering *fs, struct mlx5_flow_namespace *ns, bool egress) 1526{ 1527 if (!egress) 1528 fs->ns = ns; 1529 else 1530 fs->egress_ns = ns; 1531} 1532 1533struct mlx5_ttc_table *mlx5e_fs_get_ttc(struct mlx5e_flow_steering *fs, bool inner) 1534{ 1535 return inner ? fs->inner_ttc : fs->ttc; 1536} 1537 1538void mlx5e_fs_set_ttc(struct mlx5e_flow_steering *fs, struct mlx5_ttc_table *ttc, bool inner) 1539{ 1540 if (!inner) 1541 fs->ttc = ttc; 1542 else 1543 fs->inner_ttc = ttc; 1544} 1545 1546#ifdef CONFIG_MLX5_EN_ARFS 1547struct mlx5e_arfs_tables *mlx5e_fs_get_arfs(struct mlx5e_flow_steering *fs) 1548{ 1549 return fs->arfs; 1550} 1551 1552void mlx5e_fs_set_arfs(struct mlx5e_flow_steering *fs, struct mlx5e_arfs_tables *arfs) 1553{ 1554 fs->arfs = arfs; 1555} 1556#endif 1557 1558struct mlx5e_ptp_fs *mlx5e_fs_get_ptp(struct mlx5e_flow_steering *fs) 1559{ 1560 return fs->ptp_fs; 1561} 1562 1563void mlx5e_fs_set_ptp(struct mlx5e_flow_steering *fs, struct mlx5e_ptp_fs *ptp_fs) 1564{ 1565 fs->ptp_fs = ptp_fs; 1566} 1567 1568struct mlx5e_fs_any *mlx5e_fs_get_any(struct mlx5e_flow_steering *fs) 1569{ 1570 return fs->any; 1571} 1572 1573void mlx5e_fs_set_any(struct mlx5e_flow_steering *fs, struct mlx5e_fs_any *any) 1574{ 1575 fs->any = any; 1576} 1577 1578#ifdef CONFIG_MLX5_EN_TLS 1579struct mlx5e_accel_fs_tcp *mlx5e_fs_get_accel_tcp(struct mlx5e_flow_steering *fs) 1580{ 1581 return fs->accel_tcp; 1582} 1583 1584void mlx5e_fs_set_accel_tcp(struct mlx5e_flow_steering *fs, struct mlx5e_accel_fs_tcp *accel_tcp) 1585{ 1586 fs->accel_tcp = accel_tcp; 1587} 1588#endif 1589 1590void mlx5e_fs_set_state_destroy(struct mlx5e_flow_steering *fs, bool state_destroy) 1591{ 1592 fs->state_destroy = state_destroy; 1593} 1594 1595void mlx5e_fs_set_vlan_strip_disable(struct mlx5e_flow_steering *fs, 1596 bool vlan_strip_disable) 1597{ 1598 fs->vlan_strip_disable = vlan_strip_disable; 1599} 1600 1601struct mlx5e_fs_udp *mlx5e_fs_get_udp(struct mlx5e_flow_steering *fs) 1602{ 1603 return fs->udp; 1604} 1605 1606void mlx5e_fs_set_udp(struct mlx5e_flow_steering *fs, struct mlx5e_fs_udp *udp) 1607{ 1608 fs->udp = udp; 1609} 1610 1611struct mlx5_core_dev *mlx5e_fs_get_mdev(struct mlx5e_flow_steering *fs) 1612{ 1613 return fs->mdev; 1614}
~/
Read-only file preview.