File Index
Files and directories
Sign in
FILE

lag.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c C
   1/*
   2 * Copyright (c) 2016, 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/netdevice.h>
  34#include <net/bonding.h>
  35#include <linux/mlx5/driver.h>
  36#include <linux/mlx5/eswitch.h>
  37#include <linux/mlx5/vport.h>
  38#include "lib/mlx5.h"
  39#include "lib/devcom.h"
  40#include "mlx5_core.h"
  41#include "eswitch.h"
  42#include "esw/acl/ofld.h"
  43#include "lag.h"
  44#include "mp.h"
  45#include "mpesw.h"
  46
  47
  48/* General purpose, use for short periods of time.
  49 * Beware of lock dependencies (preferably, no locks should be acquired
  50 * under it).
  51 */
  52static DEFINE_SPINLOCK(lag_lock);
  53
  54static int get_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
  55{
  56	if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags))
  57		return MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_FT;
  58
  59	if (mode == MLX5_LAG_MODE_MPESW)
  60		return MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_MPESW;
  61
  62	return MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY;
  63}
  64
  65static u8 lag_active_port_bits(struct mlx5_lag *ldev)
  66{
  67	u8 enabled_ports[MLX5_MAX_PORTS] = {};
  68	u8 active_port = 0;
  69	int num_enabled;
  70	int idx;
  71
  72	mlx5_infer_tx_enabled(&ldev->tracker, ldev, enabled_ports,
  73			      &num_enabled);
  74	for (idx = 0; idx < num_enabled; idx++)
  75		active_port |= BIT_MASK(enabled_ports[idx]);
  76
  77	return active_port;
  78}
  79
  80static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, struct mlx5_lag *ldev,
  81			       int mode, unsigned long flags)
  82{
  83	bool fdb_sel_mode = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
  84				     &flags);
  85	int port_sel_mode = get_port_sel_mode(mode, flags);
  86	u32 in[MLX5_ST_SZ_DW(create_lag_in)] = {};
  87	u8 *ports = ldev->v2p_map;
  88	int idx0, idx1;
  89	void *lag_ctx;
  90
  91	lag_ctx = MLX5_ADDR_OF(create_lag_in, in, ctx);
  92	MLX5_SET(create_lag_in, in, opcode, MLX5_CMD_OP_CREATE_LAG);
  93	MLX5_SET(lagc, lag_ctx, fdb_selection_mode, fdb_sel_mode);
  94	idx0 = mlx5_lag_get_dev_index_by_seq(ldev, 0);
  95	idx1 = mlx5_lag_get_dev_index_by_seq(ldev, 1);
  96
  97	if (idx0 < 0 || idx1 < 0)
  98		return -EINVAL;
  99
 100	switch (port_sel_mode) {
 101	case MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY:
 102		MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, ports[idx0]);
 103		MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, ports[idx1]);
 104		break;
 105	case MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_FT:
 106		if (!MLX5_CAP_PORT_SELECTION(dev, port_select_flow_table_bypass))
 107			break;
 108
 109		MLX5_SET(lagc, lag_ctx, active_port,
 110			 lag_active_port_bits(mlx5_lag_dev(dev)));
 111		break;
 112	default:
 113		break;
 114	}
 115	MLX5_SET(lagc, lag_ctx, port_select_mode, port_sel_mode);
 116
 117	return mlx5_cmd_exec_in(dev, create_lag, in);
 118}
 119
 120static int mlx5_cmd_modify_lag(struct mlx5_core_dev *dev, struct mlx5_lag *ldev,
 121			       u8 *ports)
 122{
 123	u32 in[MLX5_ST_SZ_DW(modify_lag_in)] = {};
 124	void *lag_ctx = MLX5_ADDR_OF(modify_lag_in, in, ctx);
 125	int idx0, idx1;
 126
 127	idx0 = mlx5_lag_get_dev_index_by_seq(ldev, 0);
 128	idx1 = mlx5_lag_get_dev_index_by_seq(ldev, 1);
 129	if (idx0 < 0 || idx1 < 0)
 130		return -EINVAL;
 131
 132	MLX5_SET(modify_lag_in, in, opcode, MLX5_CMD_OP_MODIFY_LAG);
 133	MLX5_SET(modify_lag_in, in, field_select, 0x1);
 134
 135	MLX5_SET(lagc, lag_ctx, tx_remap_affinity_1, ports[idx0]);
 136	MLX5_SET(lagc, lag_ctx, tx_remap_affinity_2, ports[idx1]);
 137
 138	return mlx5_cmd_exec_in(dev, modify_lag, in);
 139}
 140
 141int mlx5_cmd_create_vport_lag(struct mlx5_core_dev *dev)
 142{
 143	u32 in[MLX5_ST_SZ_DW(create_vport_lag_in)] = {};
 144
 145	MLX5_SET(create_vport_lag_in, in, opcode, MLX5_CMD_OP_CREATE_VPORT_LAG);
 146
 147	return mlx5_cmd_exec_in(dev, create_vport_lag, in);
 148}
 149EXPORT_SYMBOL(mlx5_cmd_create_vport_lag);
 150
 151int mlx5_cmd_destroy_vport_lag(struct mlx5_core_dev *dev)
 152{
 153	u32 in[MLX5_ST_SZ_DW(destroy_vport_lag_in)] = {};
 154
 155	MLX5_SET(destroy_vport_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_VPORT_LAG);
 156
 157	return mlx5_cmd_exec_in(dev, destroy_vport_lag, in);
 158}
 159EXPORT_SYMBOL(mlx5_cmd_destroy_vport_lag);
 160
 161static void mlx5_infer_tx_disabled(struct lag_tracker *tracker, struct mlx5_lag *ldev,
 162				   u8 *ports, int *num_disabled)
 163{
 164	int i;
 165
 166	*num_disabled = 0;
 167	mlx5_ldev_for_each(i, 0, ldev)
 168		if (!tracker->netdev_state[i].tx_enabled ||
 169		    !tracker->netdev_state[i].link_up)
 170			ports[(*num_disabled)++] = i;
 171}
 172
 173void mlx5_infer_tx_enabled(struct lag_tracker *tracker, struct mlx5_lag *ldev,
 174			   u8 *ports, int *num_enabled)
 175{
 176	int i;
 177
 178	*num_enabled = 0;
 179	mlx5_ldev_for_each(i, 0, ldev)
 180		if (tracker->netdev_state[i].tx_enabled &&
 181		    tracker->netdev_state[i].link_up)
 182			ports[(*num_enabled)++] = i;
 183
 184	if (*num_enabled == 0)
 185		mlx5_infer_tx_disabled(tracker, ldev, ports, num_enabled);
 186}
 187
 188static void mlx5_lag_print_mapping(struct mlx5_core_dev *dev,
 189				   struct mlx5_lag *ldev,
 190				   struct lag_tracker *tracker,
 191				   unsigned long flags)
 192{
 193	char buf[MLX5_MAX_PORTS * 10 + 1] = {};
 194	u8 enabled_ports[MLX5_MAX_PORTS] = {};
 195	int written = 0;
 196	int num_enabled;
 197	int idx;
 198	int err;
 199	int i;
 200	int j;
 201
 202	if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags)) {
 203		mlx5_infer_tx_enabled(tracker, ldev, enabled_ports,
 204				      &num_enabled);
 205		for (i = 0; i < num_enabled; i++) {
 206			err = scnprintf(buf + written, 4, "%d, ", enabled_ports[i] + 1);
 207			if (err != 3)
 208				return;
 209			written += err;
 210		}
 211		buf[written - 2] = 0;
 212		mlx5_core_info(dev, "lag map active ports: %s\n", buf);
 213	} else {
 214		mlx5_ldev_for_each(i, 0, ldev) {
 215			for (j  = 0; j < ldev->buckets; j++) {
 216				idx = i * ldev->buckets + j;
 217				err = scnprintf(buf + written, 10,
 218						" port %d:%d", i + 1, ldev->v2p_map[idx]);
 219				if (err != 9)
 220					return;
 221				written += err;
 222			}
 223		}
 224		mlx5_core_info(dev, "lag map:%s\n", buf);
 225	}
 226}
 227
 228static int mlx5_lag_netdev_event(struct notifier_block *this,
 229				 unsigned long event, void *ptr);
 230static void mlx5_do_bond_work(struct work_struct *work);
 231
 232static void mlx5_ldev_free(struct kref *ref)
 233{
 234	struct mlx5_lag *ldev = container_of(ref, struct mlx5_lag, ref);
 235	struct net *net;
 236
 237	if (ldev->nb.notifier_call) {
 238		net = read_pnet(&ldev->net);
 239		unregister_netdevice_notifier_net(net, &ldev->nb);
 240	}
 241
 242	mlx5_lag_mp_cleanup(ldev);
 243	cancel_delayed_work_sync(&ldev->bond_work);
 244	destroy_workqueue(ldev->wq);
 245	mutex_destroy(&ldev->lock);
 246	kfree(ldev);
 247}
 248
 249static void mlx5_ldev_put(struct mlx5_lag *ldev)
 250{
 251	kref_put(&ldev->ref, mlx5_ldev_free);
 252}
 253
 254static void mlx5_ldev_get(struct mlx5_lag *ldev)
 255{
 256	kref_get(&ldev->ref);
 257}
 258
 259static struct mlx5_lag *mlx5_lag_dev_alloc(struct mlx5_core_dev *dev)
 260{
 261	struct mlx5_lag *ldev;
 262	int err;
 263
 264	ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
 265	if (!ldev)
 266		return NULL;
 267
 268	ldev->wq = create_singlethread_workqueue("mlx5_lag");
 269	if (!ldev->wq) {
 270		kfree(ldev);
 271		return NULL;
 272	}
 273
 274	kref_init(&ldev->ref);
 275	mutex_init(&ldev->lock);
 276	INIT_DELAYED_WORK(&ldev->bond_work, mlx5_do_bond_work);
 277
 278	ldev->nb.notifier_call = mlx5_lag_netdev_event;
 279	write_pnet(&ldev->net, mlx5_core_net(dev));
 280	if (register_netdevice_notifier_net(read_pnet(&ldev->net), &ldev->nb)) {
 281		ldev->nb.notifier_call = NULL;
 282		mlx5_core_err(dev, "Failed to register LAG netdev notifier\n");
 283	}
 284	ldev->mode = MLX5_LAG_MODE_NONE;
 285
 286	err = mlx5_lag_mp_init(ldev);
 287	if (err)
 288		mlx5_core_err(dev, "Failed to init multipath lag err=%d\n",
 289			      err);
 290
 291	ldev->ports = MLX5_CAP_GEN(dev, num_lag_ports);
 292	ldev->buckets = 1;
 293
 294	return ldev;
 295}
 296
 297int mlx5_lag_dev_get_netdev_idx(struct mlx5_lag *ldev,
 298				struct net_device *ndev)
 299{
 300	int i;
 301
 302	mlx5_ldev_for_each(i, 0, ldev)
 303		if (ldev->pf[i].netdev == ndev)
 304			return i;
 305
 306	return -ENOENT;
 307}
 308
 309int mlx5_lag_get_dev_index_by_seq(struct mlx5_lag *ldev, int seq)
 310{
 311	int i, num = 0;
 312
 313	if (!ldev)
 314		return -ENOENT;
 315
 316	mlx5_ldev_for_each(i, 0, ldev) {
 317		if (num == seq)
 318			return i;
 319		num++;
 320	}
 321	return -ENOENT;
 322}
 323
 324int mlx5_lag_num_devs(struct mlx5_lag *ldev)
 325{
 326	int i, num = 0;
 327
 328	if (!ldev)
 329		return 0;
 330
 331	mlx5_ldev_for_each(i, 0, ldev) {
 332		(void)i;
 333		num++;
 334	}
 335	return num;
 336}
 337
 338int mlx5_lag_num_netdevs(struct mlx5_lag *ldev)
 339{
 340	int i, num = 0;
 341
 342	if (!ldev)
 343		return 0;
 344
 345	mlx5_ldev_for_each(i, 0, ldev)
 346		if (ldev->pf[i].netdev)
 347			num++;
 348	return num;
 349}
 350
 351static bool __mlx5_lag_is_roce(struct mlx5_lag *ldev)
 352{
 353	return ldev->mode == MLX5_LAG_MODE_ROCE;
 354}
 355
 356static bool __mlx5_lag_is_sriov(struct mlx5_lag *ldev)
 357{
 358	return ldev->mode == MLX5_LAG_MODE_SRIOV;
 359}
 360
 361/* Create a mapping between steering slots and active ports.
 362 * As we have ldev->buckets slots per port first assume the native
 363 * mapping should be used.
 364 * If there are ports that are disabled fill the relevant slots
 365 * with mapping that points to active ports.
 366 */
 367static void mlx5_infer_tx_affinity_mapping(struct lag_tracker *tracker,
 368					   struct mlx5_lag *ldev,
 369					   u8 buckets,
 370					   u8 *ports)
 371{
 372	int disabled[MLX5_MAX_PORTS] = {};
 373	int enabled[MLX5_MAX_PORTS] = {};
 374	int disabled_ports_num = 0;
 375	int enabled_ports_num = 0;
 376	int idx;
 377	u32 rand;
 378	int i;
 379	int j;
 380
 381	mlx5_ldev_for_each(i, 0, ldev) {
 382		if (tracker->netdev_state[i].tx_enabled &&
 383		    tracker->netdev_state[i].link_up)
 384			enabled[enabled_ports_num++] = i;
 385		else
 386			disabled[disabled_ports_num++] = i;
 387	}
 388
 389	/* Use native mapping by default where each port's buckets
 390	 * point the native port: 1 1 1 .. 1 2 2 2 ... 2 3 3 3 ... 3 etc
 391	 */
 392	mlx5_ldev_for_each(i, 0, ldev) {
 393		for (j = 0; j < buckets; j++) {
 394			idx = i * buckets + j;
 395			ports[idx] = i + 1;
 396		}
 397	}
 398
 399	/* If all ports are disabled/enabled keep native mapping */
 400	if (enabled_ports_num == ldev->ports ||
 401	    disabled_ports_num == ldev->ports)
 402		return;
 403
 404	/* Go over the disabled ports and for each assign a random active port */
 405	for (i = 0; i < disabled_ports_num; i++) {
 406		for (j = 0; j < buckets; j++) {
 407			get_random_bytes(&rand, 4);
 408			ports[disabled[i] * buckets + j] = enabled[rand % enabled_ports_num] + 1;
 409		}
 410	}
 411}
 412
 413static bool mlx5_lag_has_drop_rule(struct mlx5_lag *ldev)
 414{
 415	int i;
 416
 417	mlx5_ldev_for_each(i, 0, ldev)
 418		if (ldev->pf[i].has_drop)
 419			return true;
 420	return false;
 421}
 422
 423static void mlx5_lag_drop_rule_cleanup(struct mlx5_lag *ldev)
 424{
 425	int i;
 426
 427	mlx5_ldev_for_each(i, 0, ldev) {
 428		if (!ldev->pf[i].has_drop)
 429			continue;
 430
 431		mlx5_esw_acl_ingress_vport_drop_rule_destroy(ldev->pf[i].dev->priv.eswitch,
 432							     MLX5_VPORT_UPLINK);
 433		ldev->pf[i].has_drop = false;
 434	}
 435}
 436
 437static void mlx5_lag_drop_rule_setup(struct mlx5_lag *ldev,
 438				     struct lag_tracker *tracker)
 439{
 440	u8 disabled_ports[MLX5_MAX_PORTS] = {};
 441	struct mlx5_core_dev *dev;
 442	int disabled_index;
 443	int num_disabled;
 444	int err;
 445	int i;
 446
 447	/* First delete the current drop rule so there won't be any dropped
 448	 * packets
 449	 */
 450	mlx5_lag_drop_rule_cleanup(ldev);
 451
 452	if (!ldev->tracker.has_inactive)
 453		return;
 454
 455	mlx5_infer_tx_disabled(tracker, ldev, disabled_ports, &num_disabled);
 456
 457	for (i = 0; i < num_disabled; i++) {
 458		disabled_index = disabled_ports[i];
 459		dev = ldev->pf[disabled_index].dev;
 460		err = mlx5_esw_acl_ingress_vport_drop_rule_create(dev->priv.eswitch,
 461								  MLX5_VPORT_UPLINK);
 462		if (!err)
 463			ldev->pf[disabled_index].has_drop = true;
 464		else
 465			mlx5_core_err(dev,
 466				      "Failed to create lag drop rule, error: %d", err);
 467	}
 468}
 469
 470static int mlx5_cmd_modify_active_port(struct mlx5_core_dev *dev, u8 ports)
 471{
 472	u32 in[MLX5_ST_SZ_DW(modify_lag_in)] = {};
 473	void *lag_ctx;
 474
 475	lag_ctx = MLX5_ADDR_OF(modify_lag_in, in, ctx);
 476
 477	MLX5_SET(modify_lag_in, in, opcode, MLX5_CMD_OP_MODIFY_LAG);
 478	MLX5_SET(modify_lag_in, in, field_select, 0x2);
 479
 480	MLX5_SET(lagc, lag_ctx, active_port, ports);
 481
 482	return mlx5_cmd_exec_in(dev, modify_lag, in);
 483}
 484
 485static int _mlx5_modify_lag(struct mlx5_lag *ldev, u8 *ports)
 486{
 487	int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 488	struct mlx5_core_dev *dev0;
 489	u8 active_ports;
 490	int ret;
 491
 492	if (idx < 0)
 493		return -EINVAL;
 494
 495	dev0 = ldev->pf[idx].dev;
 496	if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &ldev->mode_flags)) {
 497		ret = mlx5_lag_port_sel_modify(ldev, ports);
 498		if (ret ||
 499		    !MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table_bypass))
 500			return ret;
 501
 502		active_ports = lag_active_port_bits(ldev);
 503
 504		return mlx5_cmd_modify_active_port(dev0, active_ports);
 505	}
 506	return mlx5_cmd_modify_lag(dev0, ldev, ports);
 507}
 508
 509static struct net_device *mlx5_lag_active_backup_get_netdev(struct mlx5_core_dev *dev)
 510{
 511	struct net_device *ndev = NULL;
 512	struct mlx5_lag *ldev;
 513	unsigned long flags;
 514	int i, last_idx;
 515
 516	spin_lock_irqsave(&lag_lock, flags);
 517	ldev = mlx5_lag_dev(dev);
 518
 519	if (!ldev)
 520		goto unlock;
 521
 522	mlx5_ldev_for_each(i, 0, ldev)
 523		if (ldev->tracker.netdev_state[i].tx_enabled)
 524			ndev = ldev->pf[i].netdev;
 525	if (!ndev) {
 526		last_idx = mlx5_lag_get_dev_index_by_seq(ldev, ldev->ports - 1);
 527		if (last_idx < 0)
 528			goto unlock;
 529		ndev = ldev->pf[last_idx].netdev;
 530	}
 531
 532	dev_hold(ndev);
 533
 534unlock:
 535	spin_unlock_irqrestore(&lag_lock, flags);
 536
 537	return ndev;
 538}
 539
 540void mlx5_modify_lag(struct mlx5_lag *ldev,
 541		     struct lag_tracker *tracker)
 542{
 543	int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 544	u8 ports[MLX5_MAX_PORTS * MLX5_LAG_MAX_HASH_BUCKETS] = {};
 545	struct mlx5_core_dev *dev0;
 546	int idx;
 547	int err;
 548	int i;
 549	int j;
 550
 551	if (first_idx < 0)
 552		return;
 553
 554	dev0 = ldev->pf[first_idx].dev;
 555	mlx5_infer_tx_affinity_mapping(tracker, ldev, ldev->buckets, ports);
 556
 557	mlx5_ldev_for_each(i, 0, ldev) {
 558		for (j = 0; j < ldev->buckets; j++) {
 559			idx = i * ldev->buckets + j;
 560			if (ports[idx] == ldev->v2p_map[idx])
 561				continue;
 562			err = _mlx5_modify_lag(ldev, ports);
 563			if (err) {
 564				mlx5_core_err(dev0,
 565					      "Failed to modify LAG (%d)\n",
 566					      err);
 567				return;
 568			}
 569			memcpy(ldev->v2p_map, ports, sizeof(ports));
 570
 571			mlx5_lag_print_mapping(dev0, ldev, tracker,
 572					       ldev->mode_flags);
 573			break;
 574		}
 575	}
 576
 577	if (tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
 578		struct net_device *ndev = mlx5_lag_active_backup_get_netdev(dev0);
 579
 580		if(!(ldev->mode == MLX5_LAG_MODE_ROCE))
 581			mlx5_lag_drop_rule_setup(ldev, tracker);
 582		/** Only sriov and roce lag should have tracker->tx_type set so
 583		 *  no need to check the mode
 584		 */
 585		blocking_notifier_call_chain(&dev0->priv.lag_nh,
 586					     MLX5_DRIVER_EVENT_ACTIVE_BACKUP_LAG_CHANGE_LOWERSTATE,
 587					     ndev);
 588		dev_put(ndev);
 589	}
 590}
 591
 592static int mlx5_lag_set_port_sel_mode(struct mlx5_lag *ldev,
 593				      enum mlx5_lag_mode mode,
 594				      unsigned long *flags)
 595{
 596	int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 597	struct mlx5_core_dev *dev0;
 598
 599	if (first_idx < 0)
 600		return -EINVAL;
 601
 602	if (mode == MLX5_LAG_MODE_MPESW ||
 603	    mode == MLX5_LAG_MODE_MULTIPATH)
 604		return 0;
 605
 606	dev0 = ldev->pf[first_idx].dev;
 607
 608	if (!MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table)) {
 609		if (ldev->ports > 2)
 610			return -EINVAL;
 611		return 0;
 612	}
 613
 614	if (ldev->ports > 2)
 615		ldev->buckets = MLX5_LAG_MAX_HASH_BUCKETS;
 616
 617	set_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, flags);
 618
 619	return 0;
 620}
 621
 622static int mlx5_lag_set_flags(struct mlx5_lag *ldev, enum mlx5_lag_mode mode,
 623			      struct lag_tracker *tracker, bool shared_fdb,
 624			      unsigned long *flags)
 625{
 626	*flags = 0;
 627	if (shared_fdb) {
 628		set_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, flags);
 629		set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);
 630	}
 631
 632	if (mode == MLX5_LAG_MODE_MPESW)
 633		set_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE, flags);
 634
 635	return mlx5_lag_set_port_sel_mode(ldev, mode, flags);
 636}
 637
 638char *mlx5_get_str_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
 639{
 640	int port_sel_mode = get_port_sel_mode(mode, flags);
 641
 642	switch (port_sel_mode) {
 643	case MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY: return "queue_affinity";
 644	case MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_FT: return "hash";
 645	case MLX5_LAG_PORT_SELECT_MODE_PORT_SELECT_MPESW: return "mpesw";
 646	default: return "invalid";
 647	}
 648}
 649
 650static int mlx5_lag_create_single_fdb(struct mlx5_lag *ldev)
 651{
 652	int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 653	struct mlx5_eswitch *master_esw;
 654	struct mlx5_core_dev *dev0;
 655	int i, j;
 656	int err;
 657
 658	if (first_idx < 0)
 659		return -EINVAL;
 660
 661	dev0 = ldev->pf[first_idx].dev;
 662	master_esw = dev0->priv.eswitch;
 663	mlx5_ldev_for_each(i, first_idx + 1, ldev) {
 664		struct mlx5_eswitch *slave_esw = ldev->pf[i].dev->priv.eswitch;
 665
 666		err = mlx5_eswitch_offloads_single_fdb_add_one(master_esw,
 667							       slave_esw, ldev->ports);
 668		if (err)
 669			goto err;
 670	}
 671	return 0;
 672err:
 673	mlx5_ldev_for_each_reverse(j, i, first_idx + 1, ldev)
 674		mlx5_eswitch_offloads_single_fdb_del_one(master_esw,
 675							 ldev->pf[j].dev->priv.eswitch);
 676	return err;
 677}
 678
 679static int mlx5_create_lag(struct mlx5_lag *ldev,
 680			   struct lag_tracker *tracker,
 681			   enum mlx5_lag_mode mode,
 682			   unsigned long flags)
 683{
 684	bool shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags);
 685	int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 686	u32 in[MLX5_ST_SZ_DW(destroy_lag_in)] = {};
 687	struct mlx5_core_dev *dev0;
 688	int err;
 689
 690	if (first_idx < 0)
 691		return -EINVAL;
 692
 693	dev0 = ldev->pf[first_idx].dev;
 694	if (tracker)
 695		mlx5_lag_print_mapping(dev0, ldev, tracker, flags);
 696	mlx5_core_info(dev0, "shared_fdb:%d mode:%s\n",
 697		       shared_fdb, mlx5_get_str_port_sel_mode(mode, flags));
 698
 699	err = mlx5_cmd_create_lag(dev0, ldev, mode, flags);
 700	if (err) {
 701		mlx5_core_err(dev0,
 702			      "Failed to create LAG (%d)\n",
 703			      err);
 704		return err;
 705	}
 706
 707	if (shared_fdb) {
 708		err = mlx5_lag_create_single_fdb(ldev);
 709		if (err)
 710			mlx5_core_err(dev0, "Can't enable single FDB mode\n");
 711		else
 712			mlx5_core_info(dev0, "Operation mode is single FDB\n");
 713	}
 714
 715	if (err) {
 716		MLX5_SET(destroy_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_LAG);
 717		if (mlx5_cmd_exec_in(dev0, destroy_lag, in))
 718			mlx5_core_err(dev0,
 719				      "Failed to deactivate RoCE LAG; driver restart required\n");
 720	}
 721	BLOCKING_INIT_NOTIFIER_HEAD(&dev0->priv.lag_nh);
 722
 723	return err;
 724}
 725
 726int mlx5_activate_lag(struct mlx5_lag *ldev,
 727		      struct lag_tracker *tracker,
 728		      enum mlx5_lag_mode mode,
 729		      bool shared_fdb)
 730{
 731	int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 732	bool roce_lag = mode == MLX5_LAG_MODE_ROCE;
 733	struct mlx5_core_dev *dev0;
 734	unsigned long flags = 0;
 735	int err;
 736
 737	if (first_idx < 0)
 738		return -EINVAL;
 739
 740	dev0 = ldev->pf[first_idx].dev;
 741	err = mlx5_lag_set_flags(ldev, mode, tracker, shared_fdb, &flags);
 742	if (err)
 743		return err;
 744
 745	if (mode != MLX5_LAG_MODE_MPESW) {
 746		mlx5_infer_tx_affinity_mapping(tracker, ldev, ldev->buckets, ldev->v2p_map);
 747		if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags)) {
 748			err = mlx5_lag_port_sel_create(ldev, tracker->hash_type,
 749						       ldev->v2p_map);
 750			if (err) {
 751				mlx5_core_err(dev0,
 752					      "Failed to create LAG port selection(%d)\n",
 753					      err);
 754				return err;
 755			}
 756		}
 757	}
 758
 759	err = mlx5_create_lag(ldev, tracker, mode, flags);
 760	if (err) {
 761		if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags))
 762			mlx5_lag_port_sel_destroy(ldev);
 763		if (roce_lag)
 764			mlx5_core_err(dev0,
 765				      "Failed to activate RoCE LAG\n");
 766		else
 767			mlx5_core_err(dev0,
 768				      "Failed to activate VF LAG\n"
 769				      "Make sure all VFs are unbound prior to VF LAG activation or deactivation\n");
 770		return err;
 771	}
 772
 773	if (tracker && tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP &&
 774	    !roce_lag)
 775		mlx5_lag_drop_rule_setup(ldev, tracker);
 776
 777	ldev->mode = mode;
 778	ldev->mode_flags = flags;
 779	return 0;
 780}
 781
 782int mlx5_deactivate_lag(struct mlx5_lag *ldev)
 783{
 784	int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 785	u32 in[MLX5_ST_SZ_DW(destroy_lag_in)] = {};
 786	bool roce_lag = __mlx5_lag_is_roce(ldev);
 787	unsigned long flags = ldev->mode_flags;
 788	struct mlx5_eswitch *master_esw;
 789	struct mlx5_core_dev *dev0;
 790	int err;
 791	int i;
 792
 793	if (first_idx < 0)
 794		return -EINVAL;
 795
 796	dev0 = ldev->pf[first_idx].dev;
 797	master_esw = dev0->priv.eswitch;
 798	ldev->mode = MLX5_LAG_MODE_NONE;
 799	ldev->mode_flags = 0;
 800	mlx5_lag_mp_reset(ldev);
 801
 802	if (test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags)) {
 803		mlx5_ldev_for_each(i, first_idx + 1, ldev)
 804			mlx5_eswitch_offloads_single_fdb_del_one(master_esw,
 805								 ldev->pf[i].dev->priv.eswitch);
 806		clear_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &flags);
 807	}
 808
 809	MLX5_SET(destroy_lag_in, in, opcode, MLX5_CMD_OP_DESTROY_LAG);
 810	err = mlx5_cmd_exec_in(dev0, destroy_lag, in);
 811	if (err) {
 812		if (roce_lag) {
 813			mlx5_core_err(dev0,
 814				      "Failed to deactivate RoCE LAG; driver restart required\n");
 815		} else {
 816			mlx5_core_err(dev0,
 817				      "Failed to deactivate VF LAG; driver restart required\n"
 818				      "Make sure all VFs are unbound prior to VF LAG activation or deactivation\n");
 819		}
 820		return err;
 821	}
 822
 823	if (test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &flags)) {
 824		mlx5_lag_port_sel_destroy(ldev);
 825		ldev->buckets = 1;
 826	}
 827	if (mlx5_lag_has_drop_rule(ldev))
 828		mlx5_lag_drop_rule_cleanup(ldev);
 829
 830	return 0;
 831}
 832
 833bool mlx5_lag_check_prereq(struct mlx5_lag *ldev)
 834{
 835	int first_idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 836#ifdef CONFIG_MLX5_ESWITCH
 837	struct mlx5_core_dev *dev;
 838	u8 mode;
 839#endif
 840	bool roce_support;
 841	int i;
 842
 843	if (first_idx < 0 || mlx5_lag_num_devs(ldev) != ldev->ports)
 844		return false;
 845
 846#ifdef CONFIG_MLX5_ESWITCH
 847	mlx5_ldev_for_each(i, 0, ldev) {
 848		dev = ldev->pf[i].dev;
 849		if (mlx5_eswitch_num_vfs(dev->priv.eswitch) && !is_mdev_switchdev_mode(dev))
 850			return false;
 851	}
 852
 853	dev = ldev->pf[first_idx].dev;
 854	mode = mlx5_eswitch_mode(dev);
 855	mlx5_ldev_for_each(i, 0, ldev)
 856		if (mlx5_eswitch_mode(ldev->pf[i].dev) != mode)
 857			return false;
 858
 859#else
 860	mlx5_ldev_for_each(i, 0, ldev)
 861		if (mlx5_sriov_is_enabled(ldev->pf[i].dev))
 862			return false;
 863#endif
 864	roce_support = mlx5_get_roce_state(ldev->pf[first_idx].dev);
 865	mlx5_ldev_for_each(i, first_idx + 1, ldev)
 866		if (mlx5_get_roce_state(ldev->pf[i].dev) != roce_support)
 867			return false;
 868
 869	return true;
 870}
 871
 872void mlx5_lag_add_devices(struct mlx5_lag *ldev)
 873{
 874	int i;
 875
 876	mlx5_ldev_for_each(i, 0, ldev) {
 877		if (ldev->pf[i].dev->priv.flags &
 878		    MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)
 879			continue;
 880
 881		ldev->pf[i].dev->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
 882		mlx5_rescan_drivers_locked(ldev->pf[i].dev);
 883	}
 884}
 885
 886void mlx5_lag_remove_devices(struct mlx5_lag *ldev)
 887{
 888	int i;
 889
 890	mlx5_ldev_for_each(i, 0, ldev) {
 891		if (ldev->pf[i].dev->priv.flags &
 892		    MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)
 893			continue;
 894
 895		ldev->pf[i].dev->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
 896		mlx5_rescan_drivers_locked(ldev->pf[i].dev);
 897	}
 898}
 899
 900void mlx5_disable_lag(struct mlx5_lag *ldev)
 901{
 902	bool shared_fdb = test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
 903	int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 904	struct mlx5_core_dev *dev0;
 905	bool roce_lag;
 906	int err;
 907	int i;
 908
 909	if (idx < 0)
 910		return;
 911
 912	dev0 = ldev->pf[idx].dev;
 913	roce_lag = __mlx5_lag_is_roce(ldev);
 914
 915	if (shared_fdb) {
 916		mlx5_lag_remove_devices(ldev);
 917	} else if (roce_lag) {
 918		if (!(dev0->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)) {
 919			dev0->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
 920			mlx5_rescan_drivers_locked(dev0);
 921		}
 922		mlx5_ldev_for_each(i, idx + 1, ldev)
 923			mlx5_nic_vport_disable_roce(ldev->pf[i].dev);
 924	}
 925
 926	err = mlx5_deactivate_lag(ldev);
 927	if (err)
 928		return;
 929
 930	if (shared_fdb || roce_lag)
 931		mlx5_lag_add_devices(ldev);
 932
 933	if (shared_fdb)
 934		mlx5_ldev_for_each(i, 0, ldev)
 935			if (!(ldev->pf[i].dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV))
 936				mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
 937}
 938
 939bool mlx5_lag_shared_fdb_supported(struct mlx5_lag *ldev)
 940{
 941	int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
 942	struct mlx5_core_dev *dev;
 943	int i;
 944
 945	if (idx < 0)
 946		return false;
 947
 948	mlx5_ldev_for_each(i, idx + 1, ldev) {
 949		dev = ldev->pf[i].dev;
 950		if (is_mdev_switchdev_mode(dev) &&
 951		    mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch) &&
 952		    MLX5_CAP_GEN(dev, lag_native_fdb_selection) &&
 953		    MLX5_CAP_ESW(dev, root_ft_on_other_esw) &&
 954		    mlx5_eswitch_get_npeers(dev->priv.eswitch) ==
 955		    MLX5_CAP_GEN(dev, num_lag_ports) - 1)
 956			continue;
 957		return false;
 958	}
 959
 960	dev = ldev->pf[idx].dev;
 961	if (is_mdev_switchdev_mode(dev) &&
 962	    mlx5_eswitch_vport_match_metadata_enabled(dev->priv.eswitch) &&
 963	    mlx5_esw_offloads_devcom_is_ready(dev->priv.eswitch) &&
 964	    MLX5_CAP_ESW(dev, esw_shared_ingress_acl) &&
 965	    mlx5_eswitch_get_npeers(dev->priv.eswitch) == MLX5_CAP_GEN(dev, num_lag_ports) - 1)
 966		return true;
 967
 968	return false;
 969}
 970
 971static bool mlx5_lag_is_roce_lag(struct mlx5_lag *ldev)
 972{
 973	bool roce_lag = true;
 974	int i;
 975
 976	mlx5_ldev_for_each(i, 0, ldev)
 977		roce_lag = roce_lag && !mlx5_sriov_is_enabled(ldev->pf[i].dev);
 978
 979#ifdef CONFIG_MLX5_ESWITCH
 980	mlx5_ldev_for_each(i, 0, ldev)
 981		roce_lag = roce_lag && is_mdev_legacy_mode(ldev->pf[i].dev);
 982#endif
 983
 984	return roce_lag;
 985}
 986
 987static bool mlx5_lag_should_modify_lag(struct mlx5_lag *ldev, bool do_bond)
 988{
 989	return do_bond && __mlx5_lag_is_active(ldev) &&
 990	       ldev->mode != MLX5_LAG_MODE_MPESW;
 991}
 992
 993static bool mlx5_lag_should_disable_lag(struct mlx5_lag *ldev, bool do_bond)
 994{
 995	return !do_bond && __mlx5_lag_is_active(ldev) &&
 996	       ldev->mode != MLX5_LAG_MODE_MPESW;
 997}
 998
 999static void mlx5_do_bond(struct mlx5_lag *ldev)
1000{
1001	int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
1002	struct lag_tracker tracker = { };
1003	struct mlx5_core_dev *dev0;
1004	struct net_device *ndev;
1005	bool do_bond, roce_lag;
1006	int err;
1007	int i;
1008
1009	if (idx < 0)
1010		return;
1011
1012	dev0 = ldev->pf[idx].dev;
1013	if (!mlx5_lag_is_ready(ldev)) {
1014		do_bond = false;
1015	} else {
1016		/* VF LAG is in multipath mode, ignore bond change requests */
1017		if (mlx5_lag_is_multipath(dev0))
1018			return;
1019
1020		tracker = ldev->tracker;
1021
1022		do_bond = tracker.is_bonded && mlx5_lag_check_prereq(ldev);
1023	}
1024
1025	if (do_bond && !__mlx5_lag_is_active(ldev)) {
1026		bool shared_fdb = mlx5_lag_shared_fdb_supported(ldev);
1027
1028		roce_lag = mlx5_lag_is_roce_lag(ldev);
1029
1030		if (shared_fdb || roce_lag)
1031			mlx5_lag_remove_devices(ldev);
1032
1033		err = mlx5_activate_lag(ldev, &tracker,
1034					roce_lag ? MLX5_LAG_MODE_ROCE :
1035						   MLX5_LAG_MODE_SRIOV,
1036					shared_fdb);
1037		if (err) {
1038			if (shared_fdb || roce_lag)
1039				mlx5_lag_add_devices(ldev);
1040			if (shared_fdb) {
1041				mlx5_ldev_for_each(i, 0, ldev)
1042					mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
1043			}
1044
1045			return;
1046		} else if (roce_lag) {
1047			dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
1048			mlx5_rescan_drivers_locked(dev0);
1049			mlx5_ldev_for_each(i, idx + 1, ldev) {
1050				if (mlx5_get_roce_state(ldev->pf[i].dev))
1051					mlx5_nic_vport_enable_roce(ldev->pf[i].dev);
1052			}
1053		} else if (shared_fdb) {
1054			int i;
1055
1056			dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
1057			mlx5_rescan_drivers_locked(dev0);
1058
1059			mlx5_ldev_for_each(i, 0, ldev) {
1060				err = mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
1061				if (err)
1062					break;
1063			}
1064
1065			if (err) {
1066				dev0->priv.flags |= MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
1067				mlx5_rescan_drivers_locked(dev0);
1068				mlx5_deactivate_lag(ldev);
1069				mlx5_lag_add_devices(ldev);
1070				mlx5_ldev_for_each(i, 0, ldev)
1071					mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
1072				mlx5_core_err(dev0, "Failed to enable lag\n");
1073				return;
1074			}
1075		}
1076		if (tracker.tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP) {
1077			ndev = mlx5_lag_active_backup_get_netdev(dev0);
1078			/** Only sriov and roce lag should have tracker->TX_type
1079			 *  set so no need to check the mode
1080			 */
1081			blocking_notifier_call_chain(&dev0->priv.lag_nh,
1082						     MLX5_DRIVER_EVENT_ACTIVE_BACKUP_LAG_CHANGE_LOWERSTATE,
1083						     ndev);
1084			dev_put(ndev);
1085		}
1086	} else if (mlx5_lag_should_modify_lag(ldev, do_bond)) {
1087		mlx5_modify_lag(ldev, &tracker);
1088	} else if (mlx5_lag_should_disable_lag(ldev, do_bond)) {
1089		mlx5_disable_lag(ldev);
1090	}
1091}
1092
1093/* The last mdev to unregister will destroy the workqueue before removing the
1094 * devcom component, and as all the mdevs use the same devcom component we are
1095 * guaranteed that the devcom is valid while the calling work is running.
1096 */
1097struct mlx5_devcom_comp_dev *mlx5_lag_get_devcom_comp(struct mlx5_lag *ldev)
1098{
1099	struct mlx5_devcom_comp_dev *devcom = NULL;
1100	int i;
1101
1102	mutex_lock(&ldev->lock);
1103	i = mlx5_get_next_ldev_func(ldev, 0);
1104	if (i < MLX5_MAX_PORTS)
1105		devcom = ldev->pf[i].dev->priv.hca_devcom_comp;
1106	mutex_unlock(&ldev->lock);
1107	return devcom;
1108}
1109
1110static void mlx5_queue_bond_work(struct mlx5_lag *ldev, unsigned long delay)
1111{
1112	queue_delayed_work(ldev->wq, &ldev->bond_work, delay);
1113}
1114
1115static void mlx5_do_bond_work(struct work_struct *work)
1116{
1117	struct delayed_work *delayed_work = to_delayed_work(work);
1118	struct mlx5_lag *ldev = container_of(delayed_work, struct mlx5_lag,
1119					     bond_work);
1120	struct mlx5_devcom_comp_dev *devcom;
1121	int status;
1122
1123	devcom = mlx5_lag_get_devcom_comp(ldev);
1124	if (!devcom)
1125		return;
1126
1127	status = mlx5_devcom_comp_trylock(devcom);
1128	if (!status) {
1129		mlx5_queue_bond_work(ldev, HZ);
1130		return;
1131	}
1132
1133	mutex_lock(&ldev->lock);
1134	if (ldev->mode_changes_in_progress) {
1135		mutex_unlock(&ldev->lock);
1136		mlx5_devcom_comp_unlock(devcom);
1137		mlx5_queue_bond_work(ldev, HZ);
1138		return;
1139	}
1140
1141	mlx5_do_bond(ldev);
1142	mutex_unlock(&ldev->lock);
1143	mlx5_devcom_comp_unlock(devcom);
1144}
1145
1146static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
1147					 struct lag_tracker *tracker,
1148					 struct netdev_notifier_changeupper_info *info)
1149{
1150	struct net_device *upper = info->upper_dev, *ndev_tmp;
1151	struct netdev_lag_upper_info *lag_upper_info = NULL;
1152	bool is_bonded, is_in_lag, mode_supported;
1153	bool has_inactive = 0;
1154	struct slave *slave;
1155	u8 bond_status = 0;
1156	int num_slaves = 0;
1157	int changed = 0;
1158	int i, idx = -1;
1159
1160	if (!netif_is_lag_master(upper))
1161		return 0;
1162
1163	if (info->linking)
1164		lag_upper_info = info->upper_info;
1165
1166	/* The event may still be of interest if the slave does not belong to
1167	 * us, but is enslaved to a master which has one or more of our netdevs
1168	 * as slaves (e.g., if a new slave is added to a master that bonds two
1169	 * of our netdevs, we should unbond).
1170	 */
1171	rcu_read_lock();
1172	for_each_netdev_in_bond_rcu(upper, ndev_tmp) {
1173		mlx5_ldev_for_each(i, 0, ldev) {
1174			if (ldev->pf[i].netdev == ndev_tmp) {
1175				idx++;
1176				break;
1177			}
1178		}
1179		if (i < MLX5_MAX_PORTS) {
1180			slave = bond_slave_get_rcu(ndev_tmp);
1181			if (slave)
1182				has_inactive |= bond_is_slave_inactive(slave);
1183			bond_status |= (1 << idx);
1184		}
1185
1186		num_slaves++;
1187	}
1188	rcu_read_unlock();
1189
1190	/* None of this lagdev's netdevs are slaves of this master. */
1191	if (!(bond_status & GENMASK(ldev->ports - 1, 0)))
1192		return 0;
1193
1194	if (lag_upper_info) {
1195		tracker->tx_type = lag_upper_info->tx_type;
1196		tracker->hash_type = lag_upper_info->hash_type;
1197	}
1198
1199	tracker->has_inactive = has_inactive;
1200	/* Determine bonding status:
1201	 * A device is considered bonded if both its physical ports are slaves
1202	 * of the same lag master, and only them.
1203	 */
1204	is_in_lag = num_slaves == ldev->ports &&
1205		bond_status == GENMASK(ldev->ports - 1, 0);
1206
1207	/* Lag mode must be activebackup or hash. */
1208	mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP ||
1209			 tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH;
1210
1211	is_bonded = is_in_lag && mode_supported;
1212	if (tracker->is_bonded != is_bonded) {
1213		tracker->is_bonded = is_bonded;
1214		changed = 1;
1215	}
1216
1217	if (!is_in_lag)
1218		return changed;
1219
1220	if (!mlx5_lag_is_ready(ldev))
1221		NL_SET_ERR_MSG_MOD(info->info.extack,
1222				   "Can't activate LAG offload, PF is configured with more than 64 VFs");
1223	else if (!mode_supported)
1224		NL_SET_ERR_MSG_MOD(info->info.extack,
1225				   "Can't activate LAG offload, TX type isn't supported");
1226
1227	return changed;
1228}
1229
1230static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev,
1231					      struct lag_tracker *tracker,
1232					      struct net_device *ndev,
1233					      struct netdev_notifier_changelowerstate_info *info)
1234{
1235	struct netdev_lag_lower_state_info *lag_lower_info;
1236	int idx;
1237
1238	if (!netif_is_lag_port(ndev))
1239		return 0;
1240
1241	idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev);
1242	if (idx < 0)
1243		return 0;
1244
1245	/* This information is used to determine virtual to physical
1246	 * port mapping.
1247	 */
1248	lag_lower_info = info->lower_state_info;
1249	if (!lag_lower_info)
1250		return 0;
1251
1252	tracker->netdev_state[idx] = *lag_lower_info;
1253
1254	return 1;
1255}
1256
1257static int mlx5_handle_changeinfodata_event(struct mlx5_lag *ldev,
1258					    struct lag_tracker *tracker,
1259					    struct net_device *ndev)
1260{
1261	struct net_device *ndev_tmp;
1262	struct slave *slave;
1263	bool has_inactive = 0;
1264	int idx;
1265
1266	if (!netif_is_lag_master(ndev))
1267		return 0;
1268
1269	rcu_read_lock();
1270	for_each_netdev_in_bond_rcu(ndev, ndev_tmp) {
1271		idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
1272		if (idx < 0)
1273			continue;
1274
1275		slave = bond_slave_get_rcu(ndev_tmp);
1276		if (slave)
1277			has_inactive |= bond_is_slave_inactive(slave);
1278	}
1279	rcu_read_unlock();
1280
1281	if (tracker->has_inactive == has_inactive)
1282		return 0;
1283
1284	tracker->has_inactive = has_inactive;
1285
1286	return 1;
1287}
1288
1289/* this handler is always registered to netdev events */
1290static int mlx5_lag_netdev_event(struct notifier_block *this,
1291				 unsigned long event, void *ptr)
1292{
1293	struct net_device *ndev = netdev_notifier_info_to_dev(ptr);
1294	struct lag_tracker tracker;
1295	struct mlx5_lag *ldev;
1296	int changed = 0;
1297
1298	if (event != NETDEV_CHANGEUPPER &&
1299	    event != NETDEV_CHANGELOWERSTATE &&
1300	    event != NETDEV_CHANGEINFODATA)
1301		return NOTIFY_DONE;
1302
1303	ldev    = container_of(this, struct mlx5_lag, nb);
1304
1305	tracker = ldev->tracker;
1306
1307	switch (event) {
1308	case NETDEV_CHANGEUPPER:
1309		changed = mlx5_handle_changeupper_event(ldev, &tracker, ptr);
1310		break;
1311	case NETDEV_CHANGELOWERSTATE:
1312		changed = mlx5_handle_changelowerstate_event(ldev, &tracker,
1313							     ndev, ptr);
1314		break;
1315	case NETDEV_CHANGEINFODATA:
1316		changed = mlx5_handle_changeinfodata_event(ldev, &tracker, ndev);
1317		break;
1318	}
1319
1320	ldev->tracker = tracker;
1321
1322	if (changed)
1323		mlx5_queue_bond_work(ldev, 0);
1324
1325	return NOTIFY_DONE;
1326}
1327
1328static void mlx5_ldev_add_netdev(struct mlx5_lag *ldev,
1329				struct mlx5_core_dev *dev,
1330				struct net_device *netdev)
1331{
1332	unsigned int fn = mlx5_get_dev_index(dev);
1333	unsigned long flags;
1334
1335	spin_lock_irqsave(&lag_lock, flags);
1336	ldev->pf[fn].netdev = netdev;
1337	ldev->tracker.netdev_state[fn].link_up = 0;
1338	ldev->tracker.netdev_state[fn].tx_enabled = 0;
1339	spin_unlock_irqrestore(&lag_lock, flags);
1340}
1341
1342static void mlx5_ldev_remove_netdev(struct mlx5_lag *ldev,
1343				    struct net_device *netdev)
1344{
1345	unsigned long flags;
1346	int i;
1347
1348	spin_lock_irqsave(&lag_lock, flags);
1349	mlx5_ldev_for_each(i, 0, ldev) {
1350		if (ldev->pf[i].netdev == netdev) {
1351			ldev->pf[i].netdev = NULL;
1352			break;
1353		}
1354	}
1355	spin_unlock_irqrestore(&lag_lock, flags);
1356}
1357
1358static void mlx5_ldev_add_mdev(struct mlx5_lag *ldev,
1359			      struct mlx5_core_dev *dev)
1360{
1361	unsigned int fn = mlx5_get_dev_index(dev);
1362
1363	ldev->pf[fn].dev = dev;
1364	dev->priv.lag = ldev;
1365}
1366
1367static void mlx5_ldev_remove_mdev(struct mlx5_lag *ldev,
1368				  struct mlx5_core_dev *dev)
1369{
1370	int fn;
1371
1372	fn = mlx5_get_dev_index(dev);
1373	if (ldev->pf[fn].dev != dev)
1374		return;
1375
1376	ldev->pf[fn].dev = NULL;
1377	dev->priv.lag = NULL;
1378}
1379
1380/* Must be called with HCA devcom component lock held */
1381static int __mlx5_lag_dev_add_mdev(struct mlx5_core_dev *dev)
1382{
1383	struct mlx5_devcom_comp_dev *pos = NULL;
1384	struct mlx5_lag *ldev = NULL;
1385	struct mlx5_core_dev *tmp_dev;
1386
1387	tmp_dev = mlx5_devcom_get_next_peer_data(dev->priv.hca_devcom_comp, &pos);
1388	if (tmp_dev)
1389		ldev = mlx5_lag_dev(tmp_dev);
1390
1391	if (!ldev) {
1392		ldev = mlx5_lag_dev_alloc(dev);
1393		if (!ldev) {
1394			mlx5_core_err(dev, "Failed to alloc lag dev\n");
1395			return 0;
1396		}
1397		mlx5_ldev_add_mdev(ldev, dev);
1398		return 0;
1399	}
1400
1401	mutex_lock(&ldev->lock);
1402	if (ldev->mode_changes_in_progress) {
1403		mutex_unlock(&ldev->lock);
1404		return -EAGAIN;
1405	}
1406	mlx5_ldev_get(ldev);
1407	mlx5_ldev_add_mdev(ldev, dev);
1408	mutex_unlock(&ldev->lock);
1409
1410	return 0;
1411}
1412
1413static void mlx5_lag_unregister_hca_devcom_comp(struct mlx5_core_dev *dev)
1414{
1415	mlx5_devcom_unregister_component(dev->priv.hca_devcom_comp);
1416	dev->priv.hca_devcom_comp = NULL;
1417}
1418
1419static int mlx5_lag_register_hca_devcom_comp(struct mlx5_core_dev *dev)
1420{
1421	struct mlx5_devcom_match_attr attr = {
1422		.flags = MLX5_DEVCOM_MATCH_FLAGS_NS,
1423		.net = mlx5_core_net(dev),
1424	};
1425	u8 len __always_unused;
1426
1427	mlx5_query_nic_sw_system_image_guid(dev, attr.key.buf, &len);
1428
1429	/* This component is use to sync adding core_dev to lag_dev and to sync
1430	 * changes of mlx5_adev_devices between LAG layer and other layers.
1431	 */
1432	dev->priv.hca_devcom_comp =
1433		mlx5_devcom_register_component(dev->priv.devc,
1434					       MLX5_DEVCOM_HCA_PORTS,
1435					       &attr, NULL, dev);
1436	if (!dev->priv.hca_devcom_comp) {
1437		mlx5_core_err(dev,
1438			      "Failed to register devcom HCA component.");
1439		return -EINVAL;
1440	}
1441
1442	return 0;
1443}
1444
1445void mlx5_lag_remove_mdev(struct mlx5_core_dev *dev)
1446{
1447	struct mlx5_lag *ldev;
1448
1449	ldev = mlx5_lag_dev(dev);
1450	if (!ldev)
1451		return;
1452
1453	/* mdev is being removed, might as well remove debugfs
1454	 * as early as possible.
1455	 */
1456	mlx5_ldev_remove_debugfs(dev->priv.dbg.lag_debugfs);
1457recheck:
1458	mutex_lock(&ldev->lock);
1459	if (ldev->mode_changes_in_progress) {
1460		mutex_unlock(&ldev->lock);
1461		msleep(100);
1462		goto recheck;
1463	}
1464	mlx5_ldev_remove_mdev(ldev, dev);
1465	mutex_unlock(&ldev->lock);
1466	mlx5_lag_unregister_hca_devcom_comp(dev);
1467	mlx5_ldev_put(ldev);
1468}
1469
1470void mlx5_lag_add_mdev(struct mlx5_core_dev *dev)
1471{
1472	int err;
1473
1474	if (!mlx5_lag_is_supported(dev))
1475		return;
1476
1477	if (mlx5_lag_register_hca_devcom_comp(dev))
1478		return;
1479
1480recheck:
1481	mlx5_devcom_comp_lock(dev->priv.hca_devcom_comp);
1482	err = __mlx5_lag_dev_add_mdev(dev);
1483	mlx5_devcom_comp_unlock(dev->priv.hca_devcom_comp);
1484
1485	if (err) {
1486		msleep(100);
1487		goto recheck;
1488	}
1489	mlx5_ldev_add_debugfs(dev);
1490}
1491
1492void mlx5_lag_remove_netdev(struct mlx5_core_dev *dev,
1493			    struct net_device *netdev)
1494{
1495	struct mlx5_lag *ldev;
1496	bool lag_is_active;
1497
1498	ldev = mlx5_lag_dev(dev);
1499	if (!ldev)
1500		return;
1501
1502	mutex_lock(&ldev->lock);
1503	mlx5_ldev_remove_netdev(ldev, netdev);
1504	clear_bit(MLX5_LAG_FLAG_NDEVS_READY, &ldev->state_flags);
1505
1506	lag_is_active = __mlx5_lag_is_active(ldev);
1507	mutex_unlock(&ldev->lock);
1508
1509	if (lag_is_active)
1510		mlx5_queue_bond_work(ldev, 0);
1511}
1512
1513void mlx5_lag_add_netdev(struct mlx5_core_dev *dev,
1514			 struct net_device *netdev)
1515{
1516	struct mlx5_lag *ldev;
1517	int num = 0;
1518
1519	ldev = mlx5_lag_dev(dev);
1520	if (!ldev)
1521		return;
1522
1523	mutex_lock(&ldev->lock);
1524	mlx5_ldev_add_netdev(ldev, dev, netdev);
1525	num = mlx5_lag_num_netdevs(ldev);
1526	if (num >= ldev->ports)
1527		set_bit(MLX5_LAG_FLAG_NDEVS_READY, &ldev->state_flags);
1528	mutex_unlock(&ldev->lock);
1529	mlx5_queue_bond_work(ldev, 0);
1530}
1531
1532int mlx5_get_pre_ldev_func(struct mlx5_lag *ldev, int start_idx, int end_idx)
1533{
1534	int i;
1535
1536	for (i = start_idx; i >= end_idx; i--)
1537		if (ldev->pf[i].dev)
1538			return i;
1539	return -1;
1540}
1541
1542int mlx5_get_next_ldev_func(struct mlx5_lag *ldev, int start_idx)
1543{
1544	int i;
1545
1546	for (i = start_idx; i < MLX5_MAX_PORTS; i++)
1547		if (ldev->pf[i].dev)
1548			return i;
1549	return MLX5_MAX_PORTS;
1550}
1551
1552bool mlx5_lag_is_roce(struct mlx5_core_dev *dev)
1553{
1554	struct mlx5_lag *ldev;
1555	unsigned long flags;
1556	bool res;
1557
1558	spin_lock_irqsave(&lag_lock, flags);
1559	ldev = mlx5_lag_dev(dev);
1560	res  = ldev && __mlx5_lag_is_roce(ldev);
1561	spin_unlock_irqrestore(&lag_lock, flags);
1562
1563	return res;
1564}
1565EXPORT_SYMBOL(mlx5_lag_is_roce);
1566
1567bool mlx5_lag_is_active(struct mlx5_core_dev *dev)
1568{
1569	struct mlx5_lag *ldev;
1570	unsigned long flags;
1571	bool res;
1572
1573	spin_lock_irqsave(&lag_lock, flags);
1574	ldev = mlx5_lag_dev(dev);
1575	res  = ldev && __mlx5_lag_is_active(ldev);
1576	spin_unlock_irqrestore(&lag_lock, flags);
1577
1578	return res;
1579}
1580EXPORT_SYMBOL(mlx5_lag_is_active);
1581
1582bool mlx5_lag_mode_is_hash(struct mlx5_core_dev *dev)
1583{
1584	struct mlx5_lag *ldev;
1585	unsigned long flags;
1586	bool res = 0;
1587
1588	spin_lock_irqsave(&lag_lock, flags);
1589	ldev = mlx5_lag_dev(dev);
1590	if (ldev)
1591		res = test_bit(MLX5_LAG_MODE_FLAG_HASH_BASED, &ldev->mode_flags);
1592	spin_unlock_irqrestore(&lag_lock, flags);
1593
1594	return res;
1595}
1596EXPORT_SYMBOL(mlx5_lag_mode_is_hash);
1597
1598bool mlx5_lag_is_master(struct mlx5_core_dev *dev)
1599{
1600	struct mlx5_lag *ldev;
1601	unsigned long flags;
1602	bool res = false;
1603	int idx;
1604
1605	spin_lock_irqsave(&lag_lock, flags);
1606	ldev = mlx5_lag_dev(dev);
1607	idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
1608	res = ldev && __mlx5_lag_is_active(ldev) && idx >= 0 && dev == ldev->pf[idx].dev;
1609	spin_unlock_irqrestore(&lag_lock, flags);
1610
1611	return res;
1612}
1613EXPORT_SYMBOL(mlx5_lag_is_master);
1614
1615bool mlx5_lag_is_sriov(struct mlx5_core_dev *dev)
1616{
1617	struct mlx5_lag *ldev;
1618	unsigned long flags;
1619	bool res;
1620
1621	spin_lock_irqsave(&lag_lock, flags);
1622	ldev = mlx5_lag_dev(dev);
1623	res  = ldev && __mlx5_lag_is_sriov(ldev);
1624	spin_unlock_irqrestore(&lag_lock, flags);
1625
1626	return res;
1627}
1628EXPORT_SYMBOL(mlx5_lag_is_sriov);
1629
1630bool mlx5_lag_is_shared_fdb(struct mlx5_core_dev *dev)
1631{
1632	struct mlx5_lag *ldev;
1633	unsigned long flags;
1634	bool res;
1635
1636	spin_lock_irqsave(&lag_lock, flags);
1637	ldev = mlx5_lag_dev(dev);
1638	res = ldev && test_bit(MLX5_LAG_MODE_FLAG_SHARED_FDB, &ldev->mode_flags);
1639	spin_unlock_irqrestore(&lag_lock, flags);
1640
1641	return res;
1642}
1643EXPORT_SYMBOL(mlx5_lag_is_shared_fdb);
1644
1645void mlx5_lag_disable_change(struct mlx5_core_dev *dev)
1646{
1647	struct mlx5_lag *ldev;
1648
1649	ldev = mlx5_lag_dev(dev);
1650	if (!ldev)
1651		return;
1652
1653	mlx5_devcom_comp_lock(dev->priv.hca_devcom_comp);
1654	mutex_lock(&ldev->lock);
1655
1656	ldev->mode_changes_in_progress++;
1657	if (__mlx5_lag_is_active(ldev)) {
1658		if (ldev->mode == MLX5_LAG_MODE_MPESW)
1659			mlx5_lag_disable_mpesw(ldev);
1660		else
1661			mlx5_disable_lag(ldev);
1662	}
1663
1664	mutex_unlock(&ldev->lock);
1665	mlx5_devcom_comp_unlock(dev->priv.hca_devcom_comp);
1666}
1667
1668void mlx5_lag_enable_change(struct mlx5_core_dev *dev)
1669{
1670	struct mlx5_lag *ldev;
1671
1672	ldev = mlx5_lag_dev(dev);
1673	if (!ldev)
1674		return;
1675
1676	mutex_lock(&ldev->lock);
1677	ldev->mode_changes_in_progress--;
1678	mutex_unlock(&ldev->lock);
1679	mlx5_queue_bond_work(ldev, 0);
1680}
1681
1682u8 mlx5_lag_get_slave_port(struct mlx5_core_dev *dev,
1683			   struct net_device *slave)
1684{
1685	struct mlx5_lag *ldev;
1686	unsigned long flags;
1687	u8 port = 0;
1688	int i;
1689
1690	spin_lock_irqsave(&lag_lock, flags);
1691	ldev = mlx5_lag_dev(dev);
1692	if (!(ldev && __mlx5_lag_is_roce(ldev)))
1693		goto unlock;
1694
1695	mlx5_ldev_for_each(i, 0, ldev) {
1696		if (ldev->pf[i].netdev == slave) {
1697			port = i;
1698			break;
1699		}
1700	}
1701
1702	port = ldev->v2p_map[port * ldev->buckets];
1703
1704unlock:
1705	spin_unlock_irqrestore(&lag_lock, flags);
1706	return port;
1707}
1708EXPORT_SYMBOL(mlx5_lag_get_slave_port);
1709
1710u8 mlx5_lag_get_num_ports(struct mlx5_core_dev *dev)
1711{
1712	struct mlx5_lag *ldev;
1713
1714	ldev = mlx5_lag_dev(dev);
1715	if (!ldev)
1716		return 0;
1717
1718	return ldev->ports;
1719}
1720EXPORT_SYMBOL(mlx5_lag_get_num_ports);
1721
1722struct mlx5_core_dev *mlx5_lag_get_next_peer_mdev(struct mlx5_core_dev *dev, int *i)
1723{
1724	struct mlx5_core_dev *peer_dev = NULL;
1725	struct mlx5_lag *ldev;
1726	unsigned long flags;
1727	int idx;
1728
1729	spin_lock_irqsave(&lag_lock, flags);
1730	ldev = mlx5_lag_dev(dev);
1731	if (!ldev)
1732		goto unlock;
1733
1734	if (*i == MLX5_MAX_PORTS)
1735		goto unlock;
1736	mlx5_ldev_for_each(idx, *i, ldev)
1737		if (ldev->pf[idx].dev != dev)
1738			break;
1739
1740	if (idx == MLX5_MAX_PORTS) {
1741		*i = idx;
1742		goto unlock;
1743	}
1744	*i = idx + 1;
1745
1746	peer_dev = ldev->pf[idx].dev;
1747
1748unlock:
1749	spin_unlock_irqrestore(&lag_lock, flags);
1750	return peer_dev;
1751}
1752EXPORT_SYMBOL(mlx5_lag_get_next_peer_mdev);
1753
1754int mlx5_lag_query_cong_counters(struct mlx5_core_dev *dev,
1755				 u64 *values,
1756				 int num_counters,
1757				 size_t *offsets)
1758{
1759	int outlen = MLX5_ST_SZ_BYTES(query_cong_statistics_out);
1760	struct mlx5_core_dev **mdev;
1761	int ret = 0, i, j, idx = 0;
1762	struct mlx5_lag *ldev;
1763	unsigned long flags;
1764	int num_ports;
1765	void *out;
1766
1767	out = kvzalloc(outlen, GFP_KERNEL);
1768	if (!out)
1769		return -ENOMEM;
1770
1771	mdev = kvzalloc(sizeof(mdev[0]) * MLX5_MAX_PORTS, GFP_KERNEL);
1772	if (!mdev) {
1773		ret = -ENOMEM;
1774		goto free_out;
1775	}
1776
1777	memset(values, 0, sizeof(*values) * num_counters);
1778
1779	spin_lock_irqsave(&lag_lock, flags);
1780	ldev = mlx5_lag_dev(dev);
1781	if (ldev && __mlx5_lag_is_active(ldev)) {
1782		num_ports = ldev->ports;
1783		mlx5_ldev_for_each(i, 0, ldev)
1784			mdev[idx++] = ldev->pf[i].dev;
1785	} else {
1786		num_ports = 1;
1787		mdev[MLX5_LAG_P1] = dev;
1788	}
1789	spin_unlock_irqrestore(&lag_lock, flags);
1790
1791	for (i = 0; i < num_ports; ++i) {
1792		u32 in[MLX5_ST_SZ_DW(query_cong_statistics_in)] = {};
1793
1794		MLX5_SET(query_cong_statistics_in, in, opcode,
1795			 MLX5_CMD_OP_QUERY_CONG_STATISTICS);
1796		ret = mlx5_cmd_exec_inout(mdev[i], query_cong_statistics, in,
1797					  out);
1798		if (ret)
1799			goto free_mdev;
1800
1801		for (j = 0; j < num_counters; ++j)
1802			values[j] += be64_to_cpup((__be64 *)(out + offsets[j]));
1803	}
1804
1805free_mdev:
1806	kvfree(mdev);
1807free_out:
1808	kvfree(out);
1809	return ret;
1810}
1811EXPORT_SYMBOL(mlx5_lag_query_cong_counters);
~/ Read-only file preview.