// SPDX-License-Identifier: GPL-2.0
/* Copyright (C) 2018-2021, Intel Corporation. */

/* Link Aggregation code */

#include "ice.h"
#include "ice_lib.h"
#include "ice_lag.h"

#define ICE_LAG_RES_SHARED	BIT(14)
#define ICE_LAG_RES_VALID	BIT(15)

#define LACP_TRAIN_PKT_LEN		16
static const u8 lacp_train_pkt[LACP_TRAIN_PKT_LEN] = { 0, 0, 0, 0, 0, 0,
						       0, 0, 0, 0, 0, 0,
						       0x88, 0x09, 0, 0 };

#define ICE_RECIPE_LEN			64
static const u8 ice_dflt_vsi_rcp[ICE_RECIPE_LEN] = {
	0x05, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0x85, 0, 0x01, 0, 0, 0, 0xff, 0xff, 0x08, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0x30 };
static const u8 ice_lport_rcp[ICE_RECIPE_LEN] = {
	0x05, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0x85, 0, 0x16, 0, 0, 0, 0xff, 0xff, 0x07, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0x30 };

/**
 * ice_lag_set_primary - set PF LAG state as Primary
 * @lag: LAG info struct
 */
static void ice_lag_set_primary(struct ice_lag *lag)
{
	struct ice_pf *pf = lag->pf;

	if (!pf)
		return;

	if (lag->role != ICE_LAG_UNSET && lag->role != ICE_LAG_BACKUP) {
		dev_warn(ice_pf_to_dev(pf), "%s: Attempt to be Primary, but incompatible state.\n",
			 netdev_name(lag->netdev));
		return;
	}

	lag->role = ICE_LAG_PRIMARY;
}

/**
 * ice_lag_set_backup - set PF LAG state to Backup
 * @lag: LAG info struct
 */
static void ice_lag_set_backup(struct ice_lag *lag)
{
	struct ice_pf *pf = lag->pf;

	if (!pf)
		return;

	if (lag->role != ICE_LAG_UNSET && lag->role != ICE_LAG_PRIMARY) {
		dev_dbg(ice_pf_to_dev(pf), "%s: Attempt to be Backup, but incompatible state\n",
			netdev_name(lag->netdev));
		return;
	}

	lag->role = ICE_LAG_BACKUP;
}

/**
 * netif_is_same_ice - determine if netdev is on the same ice NIC as local PF
 * @pf: local PF struct
 * @netdev: netdev we are evaluating
 */
static bool netif_is_same_ice(struct ice_pf *pf, struct net_device *netdev)
{
	struct ice_netdev_priv *np;
	struct ice_pf *test_pf;
	struct ice_vsi *vsi;

	if (!netif_is_ice(netdev))
		return false;

	np = netdev_priv(netdev);
	if (!np)
		return false;

	vsi = np->vsi;
	if (!vsi)
		return false;

	test_pf = vsi->back;
	if (!test_pf)
		return false;

	if (pf->pdev->bus != test_pf->pdev->bus ||
	    pf->pdev->slot != test_pf->pdev->slot)
		return false;

	return true;
}

/**
 * ice_netdev_to_lag - return pointer to associated lag struct from netdev
 * @netdev: pointer to net_device struct to query
 */
static struct ice_lag *ice_netdev_to_lag(struct net_device *netdev)
{
	struct ice_netdev_priv *np;
	struct ice_vsi *vsi;

	if (!netif_is_ice(netdev))
		return NULL;

	np = netdev_priv(netdev);
	if (!np)
		return NULL;

	vsi = np->vsi;
	if (!vsi)
		return NULL;

	return vsi->back->lag;
}

/**
 * ice_lag_find_hw_by_lport - return an hw struct from bond members lport
 * @lag: lag struct
 * @lport: lport value to search for
 */
static struct ice_hw *
ice_lag_find_hw_by_lport(struct ice_lag *lag, u8 lport)
{
	struct ice_lag_netdev_list *entry;
	struct net_device *tmp_netdev;
	struct ice_netdev_priv *np;
	struct ice_hw *hw;

	list_for_each_entry(entry, lag->netdev_head, node) {
		tmp_netdev = entry->netdev;
		if (!tmp_netdev || !netif_is_ice(tmp_netdev))
			continue;

		np = netdev_priv(tmp_netdev);
		if (!np || !np->vsi)
			continue;

		hw = &np->vsi->back->hw;
		if (hw->port_info->lport == lport)
			return hw;
	}

	return NULL;
}

/**
 * ice_pkg_has_lport_extract - check if lport extraction supported
 * @hw: HW struct
 */
static bool ice_pkg_has_lport_extract(struct ice_hw *hw)
{
	int i;

	for (i = 0; i < hw->blk[ICE_BLK_SW].es.count; i++) {
		u16 offset;
		u8 fv_prot;

		ice_find_prot_off(hw, ICE_BLK_SW, ICE_SW_DEFAULT_PROFILE, i,
				  &fv_prot, &offset);
		if (fv_prot == ICE_FV_PROT_MDID &&
		    offset == ICE_LP_EXT_BUF_OFFSET)
			return true;
	}
	return false;
}

/**
 * ice_lag_find_primary - returns pointer to primary interfaces lag struct
 * @lag: local interfaces lag struct
 */
static struct ice_lag *ice_lag_find_primary(struct ice_lag *lag)
{
	struct ice_lag *primary_lag = NULL;
	struct list_head *tmp;

	list_for_each(tmp, lag->netdev_head) {
		struct ice_lag_netdev_list *entry;
		struct ice_lag *tmp_lag;

		entry = list_entry(tmp, struct ice_lag_netdev_list, node);
		tmp_lag = ice_netdev_to_lag(entry->netdev);
		if (tmp_lag && tmp_lag->primary) {
			primary_lag = tmp_lag;
			break;
		}
	}

	return primary_lag;
}

/**
 * ice_lag_cfg_fltr - Add/Remove rule for LAG
 * @lag: lag struct for local interface
 * @act: rule action
 * @recipe_id: recipe id for the new rule
 * @rule_idx: pointer to rule index
 * @add: boolean on whether we are adding filters
 */
static int
ice_lag_cfg_fltr(struct ice_lag *lag, u32 act, u16 recipe_id, u16 *rule_idx,
		 bool add)
{
	struct ice_sw_rule_lkup_rx_tx *s_rule;
	u16 s_rule_sz, vsi_num;
	struct ice_hw *hw;
	u8 *eth_hdr;
	u32 opc;
	int err;

	hw = &lag->pf->hw;
	vsi_num = ice_get_hw_vsi_num(hw, 0);

	s_rule_sz = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule);
	s_rule = kzalloc(s_rule_sz, GFP_KERNEL);
	if (!s_rule) {
		dev_err(ice_pf_to_dev(lag->pf), "error allocating rule for LAG\n");
		return -ENOMEM;
	}

	if (add) {
		eth_hdr = s_rule->hdr_data;
		ice_fill_eth_hdr(eth_hdr);

		act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M, vsi_num);

		s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
		s_rule->recipe_id = cpu_to_le16(recipe_id);
		s_rule->src = cpu_to_le16(hw->port_info->lport);
		s_rule->act = cpu_to_le32(act);
		s_rule->hdr_len = cpu_to_le16(DUMMY_ETH_HDR_LEN);
		opc = ice_aqc_opc_add_sw_rules;
	} else {
		s_rule->index = cpu_to_le16(*rule_idx);
		opc = ice_aqc_opc_remove_sw_rules;
	}

	err = ice_aq_sw_rules(&lag->pf->hw, s_rule, s_rule_sz, 1, opc, NULL);
	if (err)
		goto dflt_fltr_free;

	if (add)
		*rule_idx = le16_to_cpu(s_rule->index);
	else
		*rule_idx = 0;

dflt_fltr_free:
	kfree(s_rule);
	return err;
}

/**
 * ice_lag_cfg_dflt_fltr - Add/Remove default VSI rule for LAG
 * @lag: lag struct for local interface
 * @add: boolean on whether to add filter
 */
static int
ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)
{
	u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |
		ICE_SINGLE_ACT_VALID_BIT | ICE_SINGLE_ACT_LAN_ENABLE;

	return ice_lag_cfg_fltr(lag, act, lag->pf_recipe,
				&lag->pf_rule_id, add);
}

/**
 * ice_lag_cfg_drop_fltr - Add/Remove lport drop rule
 * @lag: lag struct for local interface
 * @add: boolean on whether to add filter
 */
static int
ice_lag_cfg_drop_fltr(struct ice_lag *lag, bool add)
{
	u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |
		  ICE_SINGLE_ACT_VALID_BIT |
		  ICE_SINGLE_ACT_DROP;

	return ice_lag_cfg_fltr(lag, act, lag->lport_recipe,
				&lag->lport_rule_idx, add);
}

/**
 * ice_lag_cfg_pf_fltrs - set filters up for new active port
 * @lag: local interfaces lag struct
 * @ptr: opaque data containing notifier event
 */
static void
ice_lag_cfg_pf_fltrs(struct ice_lag *lag, void *ptr)
{
	struct netdev_notifier_bonding_info *info;
	struct netdev_bonding_info *bonding_info;
	struct net_device *event_netdev;
	struct device *dev;

	event_netdev = netdev_notifier_info_to_dev(ptr);
	/* not for this netdev */
	if (event_netdev != lag->netdev)
		return;

	info = (struct netdev_notifier_bonding_info *)ptr;
	bonding_info = &info->bonding_info;
	dev = ice_pf_to_dev(lag->pf);

	/* interface not active - remove old default VSI rule */
	if (bonding_info->slave.state && lag->pf_rule_id) {
		if (ice_lag_cfg_dflt_fltr(lag, false))
			dev_err(dev, "Error removing old default VSI filter\n");
		if (ice_lag_cfg_drop_fltr(lag, true))
			dev_err(dev, "Error adding new drop filter\n");
		return;
	}

	/* interface becoming active - add new default VSI rule */
	if (!bonding_info->slave.state && !lag->pf_rule_id) {
		if (ice_lag_cfg_dflt_fltr(lag, true))
			dev_err(dev, "Error adding new default VSI filter\n");
		if (lag->lport_rule_idx && ice_lag_cfg_drop_fltr(lag, false))
			dev_err(dev, "Error removing old drop filter\n");
	}
}

/**
 * ice_display_lag_info - print LAG info
 * @lag: LAG info struct
 */
static void ice_display_lag_info(struct ice_lag *lag)
{
	const char *name, *upper, *role, *bonded, *primary;
	struct device *dev = &lag->pf->pdev->dev;

	name = lag->netdev ? netdev_name(lag->netdev) : "unset";
	upper = lag->upper_netdev ? netdev_name(lag->upper_netdev) : "unset";
	primary = lag->primary ? "TRUE" : "FALSE";
	bonded = lag->bonded ? "BONDED" : "UNBONDED";

	switch (lag->role) {
	case ICE_LAG_NONE:
		role = "NONE";
		break;
	case ICE_LAG_PRIMARY:
		role = "PRIMARY";
		break;
	case ICE_LAG_BACKUP:
		role = "BACKUP";
		break;
	case ICE_LAG_UNSET:
		role = "UNSET";
		break;
	default:
		role = "ERROR";
	}

	dev_dbg(dev, "%s %s, upper:%s, role:%s, primary:%s\n", name, bonded,
		upper, role, primary);
}

/**
 * ice_lag_qbuf_recfg - generate a buffer of queues for a reconfigure command
 * @hw: HW struct that contains the queue contexts
 * @qbuf: pointer to buffer to populate
 * @vsi_num: index of the VSI in PF space
 * @numq: number of queues to search for
 * @tc: traffic class that contains the queues
 *
 * function returns the number of valid queues in buffer
 */
static u16
ice_lag_qbuf_recfg(struct ice_hw *hw, struct ice_aqc_cfg_txqs_buf *qbuf,
		   u16 vsi_num, u16 numq, u8 tc)
{
	struct ice_q_ctx *q_ctx;
	u16 qid, count = 0;
	struct ice_pf *pf;
	int i;

	pf = hw->back;
	for (i = 0; i < numq; i++) {
		q_ctx = ice_get_lan_q_ctx(hw, vsi_num, tc, i);
		if (!q_ctx) {
			dev_dbg(ice_hw_to_dev(hw), "%s queue %d NO Q CONTEXT\n",
				__func__, i);
			continue;
		}
		if (q_ctx->q_teid == ICE_INVAL_TEID) {
			dev_dbg(ice_hw_to_dev(hw), "%s queue %d INVAL TEID\n",
				__func__, i);
			continue;
		}
		if (q_ctx->q_handle == ICE_INVAL_Q_HANDLE) {
			dev_dbg(ice_hw_to_dev(hw), "%s queue %d INVAL Q HANDLE\n",
				__func__, i);
			continue;
		}

		qid = pf->vsi[vsi_num]->txq_map[q_ctx->q_handle];
		qbuf->queue_info[count].q_handle = cpu_to_le16(qid);
		qbuf->queue_info[count].tc = tc;
		qbuf->queue_info[count].q_teid = cpu_to_le32(q_ctx->q_teid);
		count++;
	}

	return count;
}

/**
 * ice_lag_get_sched_parent - locate or create a sched node parent
 * @hw: HW struct for getting parent in
 * @tc: traffic class on parent/node
 */
static struct ice_sched_node *
ice_lag_get_sched_parent(struct ice_hw *hw, u8 tc)
{
	struct ice_sched_node *tc_node, *aggnode, *parent = NULL;
	u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };
	struct ice_port_info *pi = hw->port_info;
	struct device *dev;
	u8 aggl, vsil;
	int n;

	dev = ice_hw_to_dev(hw);

	tc_node = ice_sched_get_tc_node(pi, tc);
	if (!tc_node) {
		dev_warn(dev, "Failure to find TC node for LAG move\n");
		return parent;
	}

	aggnode = ice_sched_get_agg_node(pi, tc_node, ICE_DFLT_AGG_ID);
	if (!aggnode) {
		dev_warn(dev, "Failure to find aggregate node for LAG move\n");
		return parent;
	}

	aggl = ice_sched_get_agg_layer(hw);
	vsil = ice_sched_get_vsi_layer(hw);

	for (n = aggl + 1; n < vsil; n++)
		num_nodes[n] = 1;

	for (n = 0; n < aggnode->num_children; n++) {
		parent = ice_sched_get_free_vsi_parent(hw, aggnode->children[n],
						       num_nodes);
		if (parent)
			return parent;
	}

	/* if free parent not found - add one */
	parent = aggnode;
	for (n = aggl + 1; n < vsil; n++) {
		u16 num_nodes_added;
		u32 first_teid;
		int err;

		err = ice_sched_add_nodes_to_layer(pi, tc_node, parent, n,
						   num_nodes[n], &first_teid,
						   &num_nodes_added);
		if (err || num_nodes[n] != num_nodes_added)
			return NULL;

		if (num_nodes_added)
			parent = ice_sched_find_node_by_teid(tc_node,
							     first_teid);
		else
			parent = parent->children[0];
		if (!parent) {
			dev_warn(dev, "Failure to add new parent for LAG move\n");
			return parent;
		}
	}

	return parent;
}

/**
 * ice_lag_move_vf_node_tc - move scheduling nodes for one VF on one TC
 * @lag: lag info struct
 * @oldport: lport of previous nodes location
 * @newport: lport of destination nodes location
 * @vsi_num: array index of VSI in PF space
 * @tc: traffic class to move
 */
static void
ice_lag_move_vf_node_tc(struct ice_lag *lag, u8 oldport, u8 newport,
			u16 vsi_num, u8 tc)
{
	DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
	struct device *dev = ice_pf_to_dev(lag->pf);
	u16 numq, valq, num_moved, qbuf_size;
	u16 buf_size = __struct_size(buf);
	struct ice_aqc_cfg_txqs_buf *qbuf;
	struct ice_sched_node *n_prt;
	struct ice_hw *new_hw = NULL;
	__le32 teid, parent_teid;
	struct ice_vsi_ctx *ctx;
	u32 tmp_teid;

	ctx = ice_get_vsi_ctx(&lag->pf->hw, vsi_num);
	if (!ctx) {
		dev_warn(dev, "Unable to locate VSI context for LAG failover\n");
		return;
	}

	/* check to see if this VF is enabled on this TC */
	if (!ctx->sched.vsi_node[tc])
		return;

	/* locate HW struct for destination port */
	new_hw = ice_lag_find_hw_by_lport(lag, newport);
	if (!new_hw) {
		dev_warn(dev, "Unable to locate HW struct for LAG node destination\n");
		return;
	}

	numq = ctx->num_lan_q_entries[tc];
	teid = ctx->sched.vsi_node[tc]->info.node_teid;
	tmp_teid = le32_to_cpu(teid);
	parent_teid = ctx->sched.vsi_node[tc]->info.parent_teid;
	/* if no teid assigned or numq == 0, then this TC is not active */
	if (!tmp_teid || !numq)
		return;

	/* suspend VSI subtree for Traffic Class "tc" on
	 * this VF's VSI
	 */
	if (ice_sched_suspend_resume_elems(&lag->pf->hw, 1, &tmp_teid, true))
		dev_dbg(dev, "Problem suspending traffic for LAG node move\n");

	/* reconfigure all VF's queues on this Traffic Class
	 * to new port
	 */
	qbuf_size = struct_size(qbuf, queue_info, numq);
	qbuf = kzalloc(qbuf_size, GFP_KERNEL);
	if (!qbuf) {
		dev_warn(dev, "Failure allocating memory for VF queue recfg buffer\n");
		goto resume_traffic;
	}

	/* add the per queue info for the reconfigure command buffer */
	valq = ice_lag_qbuf_recfg(&lag->pf->hw, qbuf, vsi_num, numq, tc);
	if (!valq) {
		dev_dbg(dev, "No valid queues found for LAG failover\n");
		goto qbuf_none;
	}

	if (ice_aq_cfg_lan_txq(&lag->pf->hw, qbuf, qbuf_size, valq, oldport,
			       newport, NULL)) {
		dev_warn(dev, "Failure to configure queues for LAG failover\n");
		goto qbuf_err;
	}

qbuf_none:
	kfree(qbuf);

	/* find new parent in destination port's tree for VF VSI node on this
	 * Traffic Class
	 */
	n_prt = ice_lag_get_sched_parent(new_hw, tc);
	if (!n_prt)
		goto resume_traffic;

	/* Move Vf's VSI node for this TC to newport's scheduler tree */
	buf->hdr.src_parent_teid = parent_teid;
	buf->hdr.dest_parent_teid = n_prt->info.node_teid;
	buf->hdr.num_elems = cpu_to_le16(1);
	buf->hdr.mode = ICE_AQC_MOVE_ELEM_MODE_KEEP_OWN;
	buf->teid[0] = teid;

	if (ice_aq_move_sched_elems(&lag->pf->hw, buf, buf_size, &num_moved))
		dev_warn(dev, "Failure to move VF nodes for failover\n");
	else
		ice_sched_update_parent(n_prt, ctx->sched.vsi_node[tc]);

	goto resume_traffic;

qbuf_err:
	kfree(qbuf);

resume_traffic:
	/* restart traffic for VSI node */
	if (ice_sched_suspend_resume_elems(&lag->pf->hw, 1, &tmp_teid, false))
		dev_dbg(dev, "Problem restarting traffic for LAG node move\n");
}

/**
 * ice_lag_build_netdev_list - populate the lag struct's netdev list
 * @lag: local lag struct
 * @ndlist: pointer to netdev list to populate
 */
static void ice_lag_build_netdev_list(struct ice_lag *lag,
				      struct ice_lag_netdev_list *ndlist)
{
	struct ice_lag_netdev_list *nl;
	struct net_device *tmp_nd;

	INIT_LIST_HEAD(&ndlist->node);
	rcu_read_lock();
	for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {
		nl = kzalloc(sizeof(*nl), GFP_ATOMIC);
		if (!nl)
			break;

		nl->netdev = tmp_nd;
		list_add(&nl->node, &ndlist->node);
	}
	rcu_read_unlock();
	lag->netdev_head = &ndlist->node;
}

/**
 * ice_lag_destroy_netdev_list - free lag struct's netdev list
 * @lag: pointer to local lag struct
 * @ndlist: pointer to lag struct netdev list
 */
static void ice_lag_destroy_netdev_list(struct ice_lag *lag,
					struct ice_lag_netdev_list *ndlist)
{
	struct ice_lag_netdev_list *entry, *n;

	rcu_read_lock();
	list_for_each_entry_safe(entry, n, &ndlist->node, node) {
		list_del(&entry->node);
		kfree(entry);
	}
	rcu_read_unlock();
	lag->netdev_head = NULL;
}

/**
 * ice_lag_move_single_vf_nodes - Move Tx scheduling nodes for single VF
 * @lag: primary interface LAG struct
 * @oldport: lport of previous interface
 * @newport: lport of destination interface
 * @vsi_num: SW index of VF's VSI
 */
static void
ice_lag_move_single_vf_nodes(struct ice_lag *lag, u8 oldport, u8 newport,
			     u16 vsi_num)
{
	u8 tc;

	ice_for_each_traffic_class(tc)
		ice_lag_move_vf_node_tc(lag, oldport, newport, vsi_num, tc);
}

/**
 * ice_lag_move_new_vf_nodes - Move Tx scheduling nodes for a VF if required
 * @vf: the VF to move Tx nodes for
 *
 * Called just after configuring new VF queues. Check whether the VF Tx
 * scheduling nodes need to be updated to fail over to the active port. If so,
 * move them now.
 */
void ice_lag_move_new_vf_nodes(struct ice_vf *vf)
{
	struct ice_lag_netdev_list ndlist;
	u8 pri_port, act_port;
	struct ice_lag *lag;
	struct ice_vsi *vsi;
	struct ice_pf *pf;

	vsi = ice_get_vf_vsi(vf);

	if (WARN_ON(!vsi))
		return;

	if (WARN_ON(vsi->type != ICE_VSI_VF))
		return;

	pf = vf->pf;
	lag = pf->lag;

	mutex_lock(&pf->lag_mutex);
	if (!lag->bonded)
		goto new_vf_unlock;

	pri_port = pf->hw.port_info->lport;
	act_port = lag->active_port;

	if (lag->upper_netdev)
		ice_lag_build_netdev_list(lag, &ndlist);

	if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) &&
	    lag->bonded && lag->primary && pri_port != act_port &&
	    !list_empty(lag->netdev_head))
		ice_lag_move_single_vf_nodes(lag, pri_port, act_port, vsi->idx);

	ice_lag_destroy_netdev_list(lag, &ndlist);

new_vf_unlock:
	mutex_unlock(&pf->lag_mutex);
}

/**
 * ice_lag_move_vf_nodes - move Tx scheduling nodes for all VFs to new port
 * @lag: lag info struct
 * @oldport: lport of previous interface
 * @newport: lport of destination interface
 */
static void ice_lag_move_vf_nodes(struct ice_lag *lag, u8 oldport, u8 newport)
{
	struct ice_pf *pf;
	int i;

	if (!lag->primary)
		return;

	pf = lag->pf;
	ice_for_each_vsi(pf, i)
		if (pf->vsi[i] && (pf->vsi[i]->type == ICE_VSI_VF ||
				   pf->vsi[i]->type == ICE_VSI_SWITCHDEV_CTRL))
			ice_lag_move_single_vf_nodes(lag, oldport, newport, i);
}

/**
 * ice_lag_move_vf_nodes_cfg - move vf nodes outside LAG netdev event context
 * @lag: local lag struct
 * @src_prt: lport value for source port
 * @dst_prt: lport value for destination port
 *
 * This function is used to move nodes during an out-of-netdev-event situation,
 * primarily when the driver needs to reconfigure or recreate resources.
 *
 * Must be called while holding the lag_mutex to avoid lag events from
 * processing while out-of-sync moves are happening.  Also, paired moves,
 * such as used in a reset flow, should both be called under the same mutex
 * lock to avoid changes between start of reset and end of reset.
 */
void ice_lag_move_vf_nodes_cfg(struct ice_lag *lag, u8 src_prt, u8 dst_prt)
{
	struct ice_lag_netdev_list ndlist;

	ice_lag_build_netdev_list(lag, &ndlist);
	ice_lag_move_vf_nodes(lag, src_prt, dst_prt);
	ice_lag_destroy_netdev_list(lag, &ndlist);
}

#define ICE_LAG_SRIOV_CP_RECIPE		10
#define ICE_LAG_SRIOV_TRAIN_PKT_LEN	16

/**
 * ice_lag_cfg_cp_fltr - configure filter for control packets
 * @lag: local interface's lag struct
 * @add: add or remove rule
 */
static void
ice_lag_cfg_cp_fltr(struct ice_lag *lag, bool add)
{
	struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;
	struct ice_vsi *vsi;
	u16 buf_len, opc;

	vsi = lag->pf->vsi[0];

	buf_len = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule,
					     ICE_LAG_SRIOV_TRAIN_PKT_LEN);
	s_rule = kzalloc(buf_len, GFP_KERNEL);
	if (!s_rule) {
		netdev_warn(lag->netdev, "-ENOMEM error configuring CP filter\n");
		return;
	}

	if (add) {
		s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);
		s_rule->recipe_id = cpu_to_le16(ICE_LAG_SRIOV_CP_RECIPE);
		s_rule->src = cpu_to_le16(vsi->port_info->lport);
		s_rule->act = cpu_to_le32(ICE_FWD_TO_VSI |
					  ICE_SINGLE_ACT_LAN_ENABLE |
					  ICE_SINGLE_ACT_VALID_BIT |
					  FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M, vsi->vsi_num));
		s_rule->hdr_len = cpu_to_le16(ICE_LAG_SRIOV_TRAIN_PKT_LEN);
		memcpy(s_rule->hdr_data, lacp_train_pkt, LACP_TRAIN_PKT_LEN);
		opc = ice_aqc_opc_add_sw_rules;
	} else {
		opc = ice_aqc_opc_remove_sw_rules;
		s_rule->index = cpu_to_le16(lag->cp_rule_idx);
	}
	if (ice_aq_sw_rules(&lag->pf->hw, s_rule, buf_len, 1, opc, NULL)) {
		netdev_warn(lag->netdev, "Error %s CP rule for fail-over\n",
			    add ? "ADDING" : "REMOVING");
		goto cp_free;
	}

	if (add)
		lag->cp_rule_idx = le16_to_cpu(s_rule->index);
	else
		lag->cp_rule_idx = 0;

cp_free:
	kfree(s_rule);
}

/**
 * ice_lag_info_event - handle NETDEV_BONDING_INFO event
 * @lag: LAG info struct
 * @ptr: opaque data pointer
 *
 * ptr is to be cast to (netdev_notifier_bonding_info *)
 */
static void ice_lag_info_event(struct ice_lag *lag, void *ptr)
{
	struct netdev_notifier_bonding_info *info;
	struct netdev_bonding_info *bonding_info;
	struct net_device *event_netdev;
	const char *lag_netdev_name;

	event_netdev = netdev_notifier_info_to_dev(ptr);
	info = ptr;
	lag_netdev_name = netdev_name(lag->netdev);
	bonding_info = &info->bonding_info;

	if (event_netdev != lag->netdev || !lag->bonded || !lag->upper_netdev)
		return;

	if (bonding_info->master.bond_mode != BOND_MODE_ACTIVEBACKUP) {
		netdev_dbg(lag->netdev, "Bonding event recv, but mode not active/backup\n");
		goto lag_out;
	}

	if (strcmp(bonding_info->slave.slave_name, lag_netdev_name)) {
		netdev_dbg(lag->netdev, "Bonding event recv, but secondary info not for us\n");
		goto lag_out;
	}

	if (bonding_info->slave.state)
		ice_lag_set_backup(lag);
	else
		ice_lag_set_primary(lag);

lag_out:
	ice_display_lag_info(lag);
}

/**
 * ice_lag_reclaim_vf_tc - move scheduling nodes back to primary interface
 * @lag: primary interface lag struct
 * @src_hw: HW struct current node location
 * @vsi_num: VSI index in PF space
 * @tc: traffic class to move
 */
static void
ice_lag_reclaim_vf_tc(struct ice_lag *lag, struct ice_hw *src_hw, u16 vsi_num,
		      u8 tc)
{
	DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
	struct device *dev = ice_pf_to_dev(lag->pf);
	u16 numq, valq, num_moved, qbuf_size;
	u16 buf_size = __struct_size(buf);
	struct ice_aqc_cfg_txqs_buf *qbuf;
	struct ice_sched_node *n_prt;
	__le32 teid, parent_teid;
	struct ice_vsi_ctx *ctx;
	struct ice_hw *hw;
	u32 tmp_teid;

	hw = &lag->pf->hw;
	ctx = ice_get_vsi_ctx(hw, vsi_num);
	if (!ctx) {
		dev_warn(dev, "Unable to locate VSI context for LAG reclaim\n");
		return;
	}

	/* check to see if this VF is enabled on this TC */
	if (!ctx->sched.vsi_node[tc])
		return;

	numq = ctx->num_lan_q_entries[tc];
	teid = ctx->sched.vsi_node[tc]->info.node_teid;
	tmp_teid = le32_to_cpu(teid);
	parent_teid = ctx->sched.vsi_node[tc]->info.parent_teid;

	/* if !teid or !numq, then this TC is not active */
	if (!tmp_teid || !numq)
		return;

	/* suspend traffic */
	if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, true))
		dev_dbg(dev, "Problem suspending traffic for LAG node move\n");

	/* reconfig queues for new port */
	qbuf_size = struct_size(qbuf, queue_info, numq);
	qbuf = kzalloc(qbuf_size, GFP_KERNEL);
	if (!qbuf) {
		dev_warn(dev, "Failure allocating memory for VF queue recfg buffer\n");
		goto resume_reclaim;
	}

	/* add the per queue info for the reconfigure command buffer */
	valq = ice_lag_qbuf_recfg(hw, qbuf, vsi_num, numq, tc);
	if (!valq) {
		dev_dbg(dev, "No valid queues found for LAG reclaim\n");
		goto reclaim_none;
	}

	if (ice_aq_cfg_lan_txq(hw, qbuf, qbuf_size, numq,
			       src_hw->port_info->lport, hw->port_info->lport,
			       NULL)) {
		dev_warn(dev, "Failure to configure queues for LAG failover\n");
		goto reclaim_qerr;
	}

reclaim_none:
	kfree(qbuf);

	/* find parent in primary tree */
	n_prt = ice_lag_get_sched_parent(hw, tc);
	if (!n_prt)
		goto resume_reclaim;

	/* Move node to new parent */
	buf->hdr.src_parent_teid = parent_teid;
	buf->hdr.dest_parent_teid = n_prt->info.node_teid;
	buf->hdr.num_elems = cpu_to_le16(1);
	buf->hdr.mode = ICE_AQC_MOVE_ELEM_MODE_KEEP_OWN;
	buf->teid[0] = teid;

	if (ice_aq_move_sched_elems(&lag->pf->hw, buf, buf_size, &num_moved))
		dev_warn(dev, "Failure to move VF nodes for LAG reclaim\n");
	else
		ice_sched_update_parent(n_prt, ctx->sched.vsi_node[tc]);

	goto resume_reclaim;

reclaim_qerr:
	kfree(qbuf);

resume_reclaim:
	/* restart traffic */
	if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, false))
		dev_warn(dev, "Problem restarting traffic for LAG node reclaim\n");
}

/**
 * ice_lag_reclaim_vf_nodes - When interface leaving bond primary reclaims nodes
 * @lag: primary interface lag struct
 * @src_hw: HW struct for current node location
 */
static void
ice_lag_reclaim_vf_nodes(struct ice_lag *lag, struct ice_hw *src_hw)
{
	struct ice_pf *pf;
	int i, tc;

	if (!lag->primary || !src_hw)
		return;

	pf = lag->pf;
	ice_for_each_vsi(pf, i)
		if (pf->vsi[i] && (pf->vsi[i]->type == ICE_VSI_VF ||
				   pf->vsi[i]->type == ICE_VSI_SWITCHDEV_CTRL))
			ice_for_each_traffic_class(tc)
				ice_lag_reclaim_vf_tc(lag, src_hw, i, tc);
}

/**
 * ice_lag_link - handle LAG link event
 * @lag: LAG info struct
 */
static void ice_lag_link(struct ice_lag *lag)
{
	struct ice_pf *pf = lag->pf;

	if (lag->bonded)
		dev_warn(ice_pf_to_dev(pf), "%s Already part of a bond\n",
			 netdev_name(lag->netdev));

	lag->bonded = true;
	lag->role = ICE_LAG_UNSET;
	netdev_info(lag->netdev, "Shared SR-IOV resources in bond are active\n");
}

/**
 * ice_lag_unlink - handle unlink event
 * @lag: LAG info struct
 */
static void ice_lag_unlink(struct ice_lag *lag)
{
	u8 pri_port, act_port, loc_port;
	struct ice_pf *pf = lag->pf;

	if (!lag->bonded) {
		netdev_dbg(lag->netdev, "bonding unlink event on non-LAG netdev\n");
		return;
	}

	if (lag->primary) {
		act_port = lag->active_port;
		pri_port = lag->pf->hw.port_info->lport;
		if (act_port != pri_port && act_port != ICE_LAG_INVALID_PORT)
			ice_lag_move_vf_nodes(lag, act_port, pri_port);
		lag->primary = false;
		lag->active_port = ICE_LAG_INVALID_PORT;
	} else {
		struct ice_lag *primary_lag;

		primary_lag = ice_lag_find_primary(lag);
		if (primary_lag) {
			act_port = primary_lag->active_port;
			pri_port = primary_lag->pf->hw.port_info->lport;
			loc_port = pf->hw.port_info->lport;
			if (act_port == loc_port &&
			    act_port != ICE_LAG_INVALID_PORT) {
				ice_lag_reclaim_vf_nodes(primary_lag,
							 &lag->pf->hw);
				primary_lag->active_port = ICE_LAG_INVALID_PORT;
			}
		}
	}

	lag->bonded = false;
	lag->role = ICE_LAG_NONE;
	lag->upper_netdev = NULL;
}

/**
 * ice_lag_link_unlink - helper function to call lag_link/unlink
 * @lag: lag info struct
 * @ptr: opaque pointer data
 */
static void ice_lag_link_unlink(struct ice_lag *lag, void *ptr)
{
	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
	struct netdev_notifier_changeupper_info *info = ptr;

	if (netdev != lag->netdev)
		return;

	if (info->linking)
		ice_lag_link(lag);
	else
		ice_lag_unlink(lag);
}

/**
 * ice_lag_set_swid - set the SWID on secondary interface
 * @primary_swid: primary interface's SWID
 * @local_lag: local interfaces LAG struct
 * @link: Is this a linking activity
 *
 * If link is false, then primary_swid should be expected to not be valid
 * This function should never be called in interrupt context.
 */
static void
ice_lag_set_swid(u16 primary_swid, struct ice_lag *local_lag,
		 bool link)
{
	struct ice_aqc_alloc_free_res_elem *buf;
	struct ice_aqc_set_port_params *cmd;
	struct ice_aq_desc desc;
	u16 buf_len, swid;
	int status, i;

	buf_len = struct_size(buf, elem, 1);
	buf = kzalloc(buf_len, GFP_KERNEL);
	if (!buf) {
		dev_err(ice_pf_to_dev(local_lag->pf), "-ENOMEM error setting SWID\n");
		return;
	}

	buf->num_elems = cpu_to_le16(1);
	buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_SWID);
	/* if unlinnking need to free the shared resource */
	if (!link && local_lag->bond_swid) {
		buf->elem[0].e.sw_resp = cpu_to_le16(local_lag->bond_swid);
		status = ice_aq_alloc_free_res(&local_lag->pf->hw, buf,
					       buf_len, ice_aqc_opc_free_res);
		if (status)
			dev_err(ice_pf_to_dev(local_lag->pf), "Error freeing SWID during LAG unlink\n");
		local_lag->bond_swid = 0;
	}

	if (link) {
		buf->res_type |=  cpu_to_le16(ICE_LAG_RES_SHARED |
					      ICE_LAG_RES_VALID);
		/* store the primary's SWID in case it leaves bond first */
		local_lag->bond_swid = primary_swid;
		buf->elem[0].e.sw_resp = cpu_to_le16(local_lag->bond_swid);
	} else {
		buf->elem[0].e.sw_resp =
			cpu_to_le16(local_lag->pf->hw.port_info->sw_id);
	}

	status = ice_aq_alloc_free_res(&local_lag->pf->hw, buf, buf_len,
				       ice_aqc_opc_alloc_res);
	if (status)
		dev_err(ice_pf_to_dev(local_lag->pf), "Error subscribing to SWID 0x%04X\n",
			local_lag->bond_swid);

	kfree(buf);

	/* Configure port param SWID to correct value */
	if (link)
		swid = primary_swid;
	else
		swid = local_lag->pf->hw.port_info->sw_id;

	cmd = &desc.params.set_port_params;
	ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_params);

	cmd->swid = cpu_to_le16(ICE_AQC_PORT_SWID_VALID | swid);
	/* If this is happening in reset context, it is possible that the
	 * primary interface has not finished setting its SWID to SHARED
	 * yet.  Allow retries to account for this timing issue between
	 * interfaces.
	 */
	for (i = 0; i < ICE_LAG_RESET_RETRIES; i++) {
		status = ice_aq_send_cmd(&local_lag->pf->hw, &desc, NULL, 0,
					 NULL);
		if (!status)
			break;

		usleep_range(1000, 2000);
	}

	if (status)
		dev_err(ice_pf_to_dev(local_lag->pf), "Error setting SWID in port params %d\n",
			status);
}

/**
 * ice_lag_primary_swid - set/clear the SHARED attrib of primary's SWID
 * @lag: primary interface's lag struct
 * @link: is this a linking activity
 *
 * Implement setting primary SWID as shared using 0x020B
 */
static void ice_lag_primary_swid(struct ice_lag *lag, bool link)
{
	struct ice_hw *hw;
	u16 swid;

	hw = &lag->pf->hw;
	swid = hw->port_info->sw_id;

	if (ice_share_res(hw, ICE_AQC_RES_TYPE_SWID, link, swid))
		dev_warn(ice_pf_to_dev(lag->pf), "Failure to set primary interface shared status\n");
}

/**
 * ice_lag_add_prune_list - Adds event_pf's VSI to primary's prune list
 * @lag: lag info struct
 * @event_pf: PF struct for VSI we are adding to primary's prune list
 */
static void ice_lag_add_prune_list(struct ice_lag *lag, struct ice_pf *event_pf)
{
	u16 num_vsi, rule_buf_sz, vsi_list_id, event_vsi_num, prim_vsi_idx;
	struct ice_sw_rule_vsi_list *s_rule = NULL;
	struct device *dev;

	num_vsi = 1;

	dev = ice_pf_to_dev(lag->pf);
	event_vsi_num = event_pf->vsi[0]->vsi_num;
	prim_vsi_idx = lag->pf->vsi[0]->idx;

	if (!ice_find_vsi_list_entry(&lag->pf->hw, ICE_SW_LKUP_VLAN,
				     prim_vsi_idx, &vsi_list_id)) {
		dev_warn(dev, "Could not locate prune list when setting up SRIOV LAG\n");
		return;
	}

	rule_buf_sz = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);
	s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
	if (!s_rule) {
		dev_warn(dev, "Error allocating space for prune list when configuring SRIOV LAG\n");
		return;
	}

	s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_PRUNE_LIST_SET);
	s_rule->index = cpu_to_le16(vsi_list_id);
	s_rule->number_vsi = cpu_to_le16(num_vsi);
	s_rule->vsi[0] = cpu_to_le16(event_vsi_num);

	if (ice_aq_sw_rules(&event_pf->hw, s_rule, rule_buf_sz, 1,
			    ice_aqc_opc_update_sw_rules, NULL))
		dev_warn(dev, "Error adding VSI prune list\n");
	kfree(s_rule);
}

/**
 * ice_lag_del_prune_list - Remove secondary's vsi from primary's prune list
 * @lag: primary interface's ice_lag struct
 * @event_pf: PF struct for unlinking interface
 */
static void ice_lag_del_prune_list(struct ice_lag *lag, struct ice_pf *event_pf)
{
	u16 num_vsi, vsi_num, vsi_idx, rule_buf_sz, vsi_list_id;
	struct ice_sw_rule_vsi_list *s_rule = NULL;
	struct device *dev;

	num_vsi = 1;

	dev = ice_pf_to_dev(lag->pf);
	vsi_num = event_pf->vsi[0]->vsi_num;
	vsi_idx = lag->pf->vsi[0]->idx;

	if (!ice_find_vsi_list_entry(&lag->pf->hw, ICE_SW_LKUP_VLAN,
				     vsi_idx, &vsi_list_id)) {
		dev_warn(dev, "Could not locate prune list when unwinding SRIOV LAG\n");
		return;
	}

	rule_buf_sz = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);
	s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);
	if (!s_rule) {
		dev_warn(dev, "Error allocating prune list when unwinding SRIOV LAG\n");
		return;
	}

	s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR);
	s_rule->index = cpu_to_le16(vsi_list_id);
	s_rule->number_vsi = cpu_to_le16(num_vsi);
	s_rule->vsi[0] = cpu_to_le16(vsi_num);

	if (ice_aq_sw_rules(&event_pf->hw, (struct ice_aqc_sw_rules *)s_rule,
			    rule_buf_sz, 1, ice_aqc_opc_update_sw_rules, NULL))
		dev_warn(dev, "Error clearing VSI prune list\n");

	kfree(s_rule);
}

/**
 * ice_lag_init_feature_support_flag - Check for package and NVM support for LAG
 * @pf: PF struct
 */
static void ice_lag_init_feature_support_flag(struct ice_pf *pf)
{
	struct ice_hw_common_caps *caps;

	caps = &pf->hw.dev_caps.common_cap;
	if (caps->roce_lag)
		ice_set_feature_support(pf, ICE_F_ROCE_LAG);
	else
		ice_clear_feature_support(pf, ICE_F_ROCE_LAG);

	if (caps->sriov_lag && ice_pkg_has_lport_extract(&pf->hw))
		ice_set_feature_support(pf, ICE_F_SRIOV_LAG);
	else
		ice_clear_feature_support(pf, ICE_F_SRIOV_LAG);
}

/**
 * ice_lag_changeupper_event - handle LAG changeupper event
 * @lag: LAG info struct
 * @ptr: opaque pointer data
 */
static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)
{
	struct netdev_notifier_changeupper_info *info;
	struct ice_lag *primary_lag;
	struct net_device *netdev;

	info = ptr;
	netdev = netdev_notifier_info_to_dev(ptr);

	/* not for this netdev */
	if (netdev != lag->netdev)
		return;

	primary_lag = ice_lag_find_primary(lag);
	if (info->linking) {
		lag->upper_netdev = info->upper_dev;
		/* If there is not already a primary interface in the LAG,
		 * then mark this one as primary.
		 */
		if (!primary_lag) {
			lag->primary = true;
			/* Configure primary's SWID to be shared */
			ice_lag_primary_swid(lag, true);
			primary_lag = lag;
		} else {
			u16 swid;

			swid = primary_lag->pf->hw.port_info->sw_id;
			ice_lag_set_swid(swid, lag, true);
			ice_lag_add_prune_list(primary_lag, lag->pf);
			ice_lag_cfg_drop_fltr(lag, true);
		}
		/* add filter for primary control packets */
		ice_lag_cfg_cp_fltr(lag, true);
	} else {
		if (!primary_lag && lag->primary)
			primary_lag = lag;

		if (!lag->primary) {
			ice_lag_set_swid(0, lag, false);
		} else {
			if (primary_lag && lag->primary) {
				ice_lag_primary_swid(lag, false);
				ice_lag_del_prune_list(primary_lag, lag->pf);
			}
		}
		/* remove filter for control packets */
		ice_lag_cfg_cp_fltr(lag, false);
	}
}

/**
 * ice_lag_monitor_link - monitor interfaces entering/leaving the aggregate
 * @lag: lag info struct
 * @ptr: opaque data containing notifier event
 *
 * This function only operates after a primary has been set.
 */
static void ice_lag_monitor_link(struct ice_lag *lag, void *ptr)
{
	struct netdev_notifier_changeupper_info *info;
	struct ice_hw *prim_hw, *active_hw;
	struct net_device *event_netdev;
	struct ice_pf *pf;
	u8 prim_port;

	if (!lag->primary)
		return;

	event_netdev = netdev_notifier_info_to_dev(ptr);
	if (!netif_is_same_ice(lag->pf, event_netdev))
		return;

	pf = lag->pf;
	prim_hw = &pf->hw;
	prim_port = prim_hw->port_info->lport;

	info = (struct netdev_notifier_changeupper_info *)ptr;
	if (info->upper_dev != lag->upper_netdev)
		return;

	if (!info->linking) {
		/* Since there are only two interfaces allowed in SRIOV+LAG, if
		 * one port is leaving, then nodes need to be on primary
		 * interface.
		 */
		if (prim_port != lag->active_port &&
		    lag->active_port != ICE_LAG_INVALID_PORT) {
			active_hw = ice_lag_find_hw_by_lport(lag,
							     lag->active_port);
			ice_lag_reclaim_vf_nodes(lag, active_hw);
			lag->active_port = ICE_LAG_INVALID_PORT;
		}
	}
}

/**
 * ice_lag_monitor_active - main PF keep track of which port is active
 * @lag: lag info struct
 * @ptr: opaque data containing notifier event
 *
 * This function is for the primary PF to monitor changes in which port is
 * active and handle changes for SRIOV VF functionality
 */
static void ice_lag_monitor_active(struct ice_lag *lag, void *ptr)
{
	struct net_device *event_netdev, *event_upper;
	struct netdev_notifier_bonding_info *info;
	struct netdev_bonding_info *bonding_info;
	struct ice_netdev_priv *event_np;
	struct ice_pf *pf, *event_pf;
	u8 prim_port, event_port;

	if (!lag->primary)
		return;

	pf = lag->pf;
	if (!pf)
		return;

	event_netdev = netdev_notifier_info_to_dev(ptr);
	rcu_read_lock();
	event_upper = netdev_master_upper_dev_get_rcu(event_netdev);
	rcu_read_unlock();
	if (!netif_is_ice(event_netdev) || event_upper != lag->upper_netdev)
		return;

	event_np = netdev_priv(event_netdev);
	event_pf = event_np->vsi->back;
	event_port = event_pf->hw.port_info->lport;
	prim_port = pf->hw.port_info->lport;

	info = (struct netdev_notifier_bonding_info *)ptr;
	bonding_info = &info->bonding_info;

	if (!bonding_info->slave.state) {
		/* if no port is currently active, then nodes and filters exist
		 * on primary port, check if we need to move them
		 */
		if (lag->active_port == ICE_LAG_INVALID_PORT) {
			if (event_port != prim_port)
				ice_lag_move_vf_nodes(lag, prim_port,
						      event_port);
			lag->active_port = event_port;
			return;
		}

		/* active port is already set and is current event port */
		if (lag->active_port == event_port)
			return;
		/* new active port */
		ice_lag_move_vf_nodes(lag, lag->active_port, event_port);
		lag->active_port = event_port;
	} else {
		/* port not set as currently active (e.g. new active port
		 * has already claimed the nodes and filters
		 */
		if (lag->active_port != event_port)
			return;
		/* This is the case when neither port is active (both link down)
		 * Link down on the bond - set active port to invalid and move
		 * nodes and filters back to primary if not already there
		 */
		if (event_port != prim_port)
			ice_lag_move_vf_nodes(lag, event_port, prim_port);
		lag->active_port = ICE_LAG_INVALID_PORT;
	}
}

/**
 * ice_lag_chk_comp - evaluate bonded interface for feature support
 * @lag: lag info struct
 * @ptr: opaque data for netdev event info
 */
static bool
ice_lag_chk_comp(struct ice_lag *lag, void *ptr)
{
	struct net_device *event_netdev, *event_upper;
	struct netdev_notifier_bonding_info *info;
	struct netdev_bonding_info *bonding_info;
	struct list_head *tmp;
	struct device *dev;
	int count = 0;

	if (!lag->primary)
		return true;

	event_netdev = netdev_notifier_info_to_dev(ptr);
	rcu_read_lock();
	event_upper = netdev_master_upper_dev_get_rcu(event_netdev);
	rcu_read_unlock();
	if (event_upper != lag->upper_netdev)
		return true;

	dev = ice_pf_to_dev(lag->pf);

	/* only supporting switchdev mode for SRIOV VF LAG.
	 * primary interface has to be in switchdev mode
	 */
	if (!ice_is_switchdev_running(lag->pf)) {
		dev_info(dev, "Primary interface not in switchdev mode - VF LAG disabled\n");
		return false;
	}

	info = (struct netdev_notifier_bonding_info *)ptr;
	bonding_info = &info->bonding_info;
	lag->bond_mode = bonding_info->master.bond_mode;
	if (lag->bond_mode != BOND_MODE_ACTIVEBACKUP) {
		dev_info(dev, "Bond Mode not ACTIVE-BACKUP - VF LAG disabled\n");
		return false;
	}

	list_for_each(tmp, lag->netdev_head) {
		struct ice_dcbx_cfg *dcb_cfg, *peer_dcb_cfg;
		struct ice_lag_netdev_list *entry;
		struct ice_netdev_priv *peer_np;
		struct net_device *peer_netdev;
		struct ice_vsi *vsi, *peer_vsi;
		struct ice_pf *peer_pf;

		entry = list_entry(tmp, struct ice_lag_netdev_list, node);
		peer_netdev = entry->netdev;
		if (!netif_is_ice(peer_netdev)) {
			dev_info(dev, "Found %s non-ice netdev in LAG - VF LAG disabled\n",
				 netdev_name(peer_netdev));
			return false;
		}

		count++;
		if (count > 2) {
			dev_info(dev, "Found more than two netdevs in LAG - VF LAG disabled\n");
			return false;
		}

		peer_np = netdev_priv(peer_netdev);
		vsi = ice_get_main_vsi(lag->pf);
		peer_vsi = peer_np->vsi;
		if (lag->pf->pdev->bus != peer_vsi->back->pdev->bus ||
		    lag->pf->pdev->slot != peer_vsi->back->pdev->slot) {
			dev_info(dev, "Found %s on different device in LAG - VF LAG disabled\n",
				 netdev_name(peer_netdev));
			return false;
		}

		dcb_cfg = &vsi->port_info->qos_cfg.local_dcbx_cfg;
		peer_dcb_cfg = &peer_vsi->port_info->qos_cfg.local_dcbx_cfg;
		if (memcmp(dcb_cfg, peer_dcb_cfg,
			   sizeof(struct ice_dcbx_cfg))) {
			dev_info(dev, "Found %s with different DCB in LAG - VF LAG disabled\n",
				 netdev_name(peer_netdev));
			return false;
		}

		peer_pf = peer_vsi->back;
		if (test_bit(ICE_FLAG_FW_LLDP_AGENT, peer_pf->flags)) {
			dev_warn(dev, "Found %s with FW LLDP agent active - VF LAG disabled\n",
				 netdev_name(peer_netdev));
			return false;
		}
	}

	return true;
}

/**
 * ice_lag_unregister - handle netdev unregister events
 * @lag: LAG info struct
 * @event_netdev: netdev struct for target of notifier event
 */
static void
ice_lag_unregister(struct ice_lag *lag, struct net_device *event_netdev)
{
	struct ice_netdev_priv *np;
	struct ice_pf *event_pf;
	struct ice_lag *p_lag;

	p_lag = ice_lag_find_primary(lag);
	np = netdev_priv(event_netdev);
	event_pf = np->vsi->back;

	if (p_lag) {
		if (p_lag->active_port != p_lag->pf->hw.port_info->lport &&
		    p_lag->active_port != ICE_LAG_INVALID_PORT) {
			struct ice_hw *active_hw;

			active_hw = ice_lag_find_hw_by_lport(lag,
							     p_lag->active_port);
			if (active_hw)
				ice_lag_reclaim_vf_nodes(p_lag, active_hw);
			lag->active_port = ICE_LAG_INVALID_PORT;
		}
	}

	/* primary processing for primary */
	if (lag->primary && lag->netdev == event_netdev)
		ice_lag_primary_swid(lag, false);

	/* primary processing for secondary */
	if (lag->primary && lag->netdev != event_netdev)
		ice_lag_del_prune_list(lag, event_pf);

	/* secondary processing for secondary */
	if (!lag->primary && lag->netdev == event_netdev)
		ice_lag_set_swid(0, lag, false);
}

/**
 * ice_lag_monitor_rdma - set and clear rdma functionality
 * @lag: pointer to lag struct
 * @ptr: opaque data for netdev event info
 */
static void
ice_lag_monitor_rdma(struct ice_lag *lag, void *ptr)
{
	struct netdev_notifier_changeupper_info *info;
	struct net_device *netdev;

	info = ptr;
	netdev = netdev_notifier_info_to_dev(ptr);

	if (netdev != lag->netdev)
		return;

	if (info->linking)
		ice_clear_rdma_cap(lag->pf);
	else
		ice_set_rdma_cap(lag->pf);
}

/**
 * ice_lag_chk_disabled_bond - monitor interfaces entering/leaving disabled bond
 * @lag: lag info struct
 * @ptr: opaque data containing event
 *
 * as interfaces enter a bond - determine if the bond is currently
 * SRIOV LAG compliant and flag if not.  As interfaces leave the
 * bond, reset their compliant status.
 */
static void ice_lag_chk_disabled_bond(struct ice_lag *lag, void *ptr)
{
	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
	struct netdev_notifier_changeupper_info *info = ptr;
	struct ice_lag *prim_lag;

	if (netdev != lag->netdev)
		return;

	if (info->linking) {
		prim_lag = ice_lag_find_primary(lag);
		if (prim_lag &&
		    !ice_is_feature_supported(prim_lag->pf, ICE_F_SRIOV_LAG)) {
			ice_clear_feature_support(lag->pf, ICE_F_SRIOV_LAG);
			netdev_info(netdev, "Interface added to non-compliant SRIOV LAG aggregate\n");
		}
	} else {
		ice_lag_init_feature_support_flag(lag->pf);
	}
}

/**
 * ice_lag_disable_sriov_bond - set members of bond as not supporting SRIOV LAG
 * @lag: primary interfaces lag struct
 */
static void ice_lag_disable_sriov_bond(struct ice_lag *lag)
{
	struct ice_netdev_priv *np;
	struct ice_pf *pf;

	np = netdev_priv(lag->netdev);
	pf = np->vsi->back;
	ice_clear_feature_support(pf, ICE_F_SRIOV_LAG);
}

/**
 * ice_lag_process_event - process a task assigned to the lag_wq
 * @work: pointer to work_struct
 */
static void ice_lag_process_event(struct work_struct *work)
{
	struct netdev_notifier_changeupper_info *info;
	struct ice_lag_work *lag_work;
	struct net_device *netdev;
	struct list_head *tmp, *n;
	struct ice_pf *pf;

	lag_work = container_of(work, struct ice_lag_work, lag_task);
	pf = lag_work->lag->pf;

	mutex_lock(&pf->lag_mutex);
	lag_work->lag->netdev_head = &lag_work->netdev_list.node;

	switch (lag_work->event) {
	case NETDEV_CHANGEUPPER:
		info = &lag_work->info.changeupper_info;
		ice_lag_chk_disabled_bond(lag_work->lag, info);
		if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) {
			ice_lag_monitor_link(lag_work->lag, info);
			ice_lag_changeupper_event(lag_work->lag, info);
			ice_lag_link_unlink(lag_work->lag, info);
		}
		ice_lag_monitor_rdma(lag_work->lag, info);
		break;
	case NETDEV_BONDING_INFO:
		if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) {
			if (!ice_lag_chk_comp(lag_work->lag,
					      &lag_work->info.bonding_info)) {
				netdev = lag_work->info.bonding_info.info.dev;
				ice_lag_disable_sriov_bond(lag_work->lag);
				ice_lag_unregister(lag_work->lag, netdev);
				goto lag_cleanup;
			}
			ice_lag_monitor_active(lag_work->lag,
					       &lag_work->info.bonding_info);
			ice_lag_cfg_pf_fltrs(lag_work->lag,
					     &lag_work->info.bonding_info);
		}
		ice_lag_info_event(lag_work->lag, &lag_work->info.bonding_info);
		break;
	case NETDEV_UNREGISTER:
		if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) {
			netdev = lag_work->info.bonding_info.info.dev;
			if ((netdev == lag_work->lag->netdev ||
			     lag_work->lag->primary) && lag_work->lag->bonded)
				ice_lag_unregister(lag_work->lag, netdev);
		}
		break;
	default:
		break;
	}

lag_cleanup:
	/* cleanup resources allocated for this work item */
	list_for_each_safe(tmp, n, &lag_work->netdev_list.node) {
		struct ice_lag_netdev_list *entry;

		entry = list_entry(tmp, struct ice_lag_netdev_list, node);
		list_del(&entry->node);
		kfree(entry);
	}
	lag_work->lag->netdev_head = NULL;

	mutex_unlock(&pf->lag_mutex);

	kfree(lag_work);
}

/**
 * ice_lag_event_handler - handle LAG events from netdev
 * @notif_blk: notifier block registered by this netdev
 * @event: event type
 * @ptr: opaque data containing notifier event
 */
static int
ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event,
		      void *ptr)
{
	struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
	struct net_device *upper_netdev;
	struct ice_lag_work *lag_work;
	struct ice_lag *lag;

	if (!netif_is_ice(netdev))
		return NOTIFY_DONE;

	if (event != NETDEV_CHANGEUPPER && event != NETDEV_BONDING_INFO &&
	    event != NETDEV_UNREGISTER)
		return NOTIFY_DONE;

	if (!(netdev->priv_flags & IFF_BONDING))
		return NOTIFY_DONE;

	lag = container_of(notif_blk, struct ice_lag, notif_block);
	if (!lag->netdev)
		return NOTIFY_DONE;

	if (!net_eq(dev_net(netdev), &init_net))
		return NOTIFY_DONE;

	/* This memory will be freed at the end of ice_lag_process_event */
	lag_work = kzalloc(sizeof(*lag_work), GFP_KERNEL);
	if (!lag_work)
		return -ENOMEM;

	lag_work->event_netdev = netdev;
	lag_work->lag = lag;
	lag_work->event = event;
	if (event == NETDEV_CHANGEUPPER) {
		struct netdev_notifier_changeupper_info *info;

		info = ptr;
		upper_netdev = info->upper_dev;
	} else {
		upper_netdev = netdev_master_upper_dev_get(netdev);
	}

	INIT_LIST_HEAD(&lag_work->netdev_list.node);
	if (upper_netdev) {
		struct ice_lag_netdev_list *nd_list;
		struct net_device *tmp_nd;

		rcu_read_lock();
		for_each_netdev_in_bond_rcu(upper_netdev, tmp_nd) {
			nd_list = kzalloc(sizeof(*nd_list), GFP_ATOMIC);
			if (!nd_list)
				break;

			nd_list->netdev = tmp_nd;
			list_add(&nd_list->node, &lag_work->netdev_list.node);
		}
		rcu_read_unlock();
	}

	switch (event) {
	case NETDEV_CHANGEUPPER:
		lag_work->info.changeupper_info =
			*((struct netdev_notifier_changeupper_info *)ptr);
		break;
	case NETDEV_BONDING_INFO:
		lag_work->info.bonding_info =
			*((struct netdev_notifier_bonding_info *)ptr);
		break;
	default:
		lag_work->info.notifier_info =
			*((struct netdev_notifier_info *)ptr);
		break;
	}

	INIT_WORK(&lag_work->lag_task, ice_lag_process_event);
	queue_work(ice_lag_wq, &lag_work->lag_task);

	return NOTIFY_DONE;
}

/**
 * ice_register_lag_handler - register LAG handler on netdev
 * @lag: LAG struct
 */
static int ice_register_lag_handler(struct ice_lag *lag)
{
	struct device *dev = ice_pf_to_dev(lag->pf);
	struct notifier_block *notif_blk;

	notif_blk = &lag->notif_block;

	if (!notif_blk->notifier_call) {
		notif_blk->notifier_call = ice_lag_event_handler;
		if (register_netdevice_notifier(notif_blk)) {
			notif_blk->notifier_call = NULL;
			dev_err(dev, "FAIL register LAG event handler!\n");
			return -EINVAL;
		}
		dev_dbg(dev, "LAG event handler registered\n");
	}
	return 0;
}

/**
 * ice_unregister_lag_handler - unregister LAG handler on netdev
 * @lag: LAG struct
 */
static void ice_unregister_lag_handler(struct ice_lag *lag)
{
	struct device *dev = ice_pf_to_dev(lag->pf);
	struct notifier_block *notif_blk;

	notif_blk = &lag->notif_block;
	if (notif_blk->notifier_call) {
		unregister_netdevice_notifier(notif_blk);
		dev_dbg(dev, "LAG event handler unregistered\n");
	}
}

/**
 * ice_create_lag_recipe
 * @hw: pointer to HW struct
 * @rid: pointer to u16 to pass back recipe index
 * @base_recipe: recipe to base the new recipe on
 * @prio: priority for new recipe
 *
 * function returns 0 on error
 */
static int ice_create_lag_recipe(struct ice_hw *hw, u16 *rid,
				 const u8 *base_recipe, u8 prio)
{
	struct ice_aqc_recipe_data_elem *new_rcp;
	int err;

	err = ice_alloc_recipe(hw, rid);
	if (err)
		return err;

	new_rcp = kzalloc(ICE_RECIPE_LEN * ICE_MAX_NUM_RECIPES, GFP_KERNEL);
	if (!new_rcp)
		return -ENOMEM;

	memcpy(new_rcp, base_recipe, ICE_RECIPE_LEN);
	new_rcp->content.act_ctrl_fwd_priority = prio;
	new_rcp->content.rid = *rid | ICE_AQ_RECIPE_ID_IS_ROOT;
	new_rcp->recipe_indx = *rid;
	bitmap_zero((unsigned long *)new_rcp->recipe_bitmap,
		    ICE_MAX_NUM_RECIPES);
	set_bit(*rid, (unsigned long *)new_rcp->recipe_bitmap);

	err = ice_aq_add_recipe(hw, new_rcp, 1, NULL);
	if (err)
		*rid = 0;

	kfree(new_rcp);
	return err;
}

/**
 * ice_lag_move_vf_nodes_tc_sync - move a VF's nodes for a tc during reset
 * @lag: primary interfaces lag struct
 * @dest_hw: HW struct for destination's interface
 * @vsi_num: VSI index in PF space
 * @tc: traffic class to move
 */
static void
ice_lag_move_vf_nodes_tc_sync(struct ice_lag *lag, struct ice_hw *dest_hw,
			      u16 vsi_num, u8 tc)
{
	DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);
	struct device *dev = ice_pf_to_dev(lag->pf);
	u16 numq, valq, num_moved, qbuf_size;
	u16 buf_size = __struct_size(buf);
	struct ice_aqc_cfg_txqs_buf *qbuf;
	struct ice_sched_node *n_prt;
	__le32 teid, parent_teid;
	struct ice_vsi_ctx *ctx;
	struct ice_hw *hw;
	u32 tmp_teid;

	hw = &lag->pf->hw;
	ctx = ice_get_vsi_ctx(hw, vsi_num);
	if (!ctx) {
		dev_warn(dev, "LAG rebuild failed after reset due to VSI Context failure\n");
		return;
	}

	if (!ctx->sched.vsi_node[tc])
		return;

	numq = ctx->num_lan_q_entries[tc];
	teid = ctx->sched.vsi_node[tc]->info.node_teid;
	tmp_teid = le32_to_cpu(teid);
	parent_teid = ctx->sched.vsi_node[tc]->info.parent_teid;

	if (!tmp_teid || !numq)
		return;

	if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, true))
		dev_dbg(dev, "Problem suspending traffic during reset rebuild\n");

	/* reconfig queues for new port */
	qbuf_size = struct_size(qbuf, queue_info, numq);
	qbuf = kzalloc(qbuf_size, GFP_KERNEL);
	if (!qbuf) {
		dev_warn(dev, "Failure allocating VF queue recfg buffer for reset rebuild\n");
		goto resume_sync;
	}

	/* add the per queue info for the reconfigure command buffer */
	valq = ice_lag_qbuf_recfg(hw, qbuf, vsi_num, numq, tc);
	if (!valq) {
		dev_warn(dev, "Failure to reconfig queues for LAG reset rebuild\n");
		goto sync_none;
	}

	if (ice_aq_cfg_lan_txq(hw, qbuf, qbuf_size, numq, hw->port_info->lport,
			       dest_hw->port_info->lport, NULL)) {
		dev_warn(dev, "Failure to configure queues for LAG reset rebuild\n");
		goto sync_qerr;
	}

sync_none:
	kfree(qbuf);

	/* find parent in destination tree */
	n_prt = ice_lag_get_sched_parent(dest_hw, tc);
	if (!n_prt)
		goto resume_sync;

	/* Move node to new parent */
	buf->hdr.src_parent_teid = parent_teid;
	buf->hdr.dest_parent_teid = n_prt->info.node_teid;
	buf->hdr.num_elems = cpu_to_le16(1);
	buf->hdr.mode = ICE_AQC_MOVE_ELEM_MODE_KEEP_OWN;
	buf->teid[0] = teid;

	if (ice_aq_move_sched_elems(&lag->pf->hw, buf, buf_size, &num_moved))
		dev_warn(dev, "Failure to move VF nodes for LAG reset rebuild\n");
	else
		ice_sched_update_parent(n_prt, ctx->sched.vsi_node[tc]);

	goto resume_sync;

sync_qerr:
	kfree(qbuf);

resume_sync:
	if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, false))
		dev_warn(dev, "Problem restarting traffic for LAG node reset rebuild\n");
}

/**
 * ice_lag_move_vf_nodes_sync - move vf nodes to active interface
 * @lag: primary interfaces lag struct
 * @dest_hw: lport value for currently active port
 *
 * This function is used in a reset context, outside of event handling,
 * to move the VF nodes to the secondary interface when that interface
 * is the active interface during a reset rebuild
 */
static void
ice_lag_move_vf_nodes_sync(struct ice_lag *lag, struct ice_hw *dest_hw)
{
	struct ice_pf *pf;
	int i, tc;

	if (!lag->primary || !dest_hw)
		return;

	pf = lag->pf;
	ice_for_each_vsi(pf, i)
		if (pf->vsi[i] && (pf->vsi[i]->type == ICE_VSI_VF ||
				   pf->vsi[i]->type == ICE_VSI_SWITCHDEV_CTRL))
			ice_for_each_traffic_class(tc)
				ice_lag_move_vf_nodes_tc_sync(lag, dest_hw, i,
							      tc);
}

/**
 * ice_init_lag - initialize support for LAG
 * @pf: PF struct
 *
 * Alloc memory for LAG structs and initialize the elements.
 * Memory will be freed in ice_deinit_lag
 */
int ice_init_lag(struct ice_pf *pf)
{
	struct device *dev = ice_pf_to_dev(pf);
	struct ice_lag *lag;
	struct ice_vsi *vsi;
	u64 recipe_bits = 0;
	int n, err;

	ice_lag_init_feature_support_flag(pf);
	if (!ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))
		return 0;

	pf->lag = kzalloc(sizeof(*lag), GFP_KERNEL);
	if (!pf->lag)
		return -ENOMEM;
	lag = pf->lag;

	vsi = ice_get_main_vsi(pf);
	if (!vsi) {
		dev_err(dev, "couldn't get main vsi, link aggregation init fail\n");
		err = -EIO;
		goto lag_error;
	}

	lag->pf = pf;
	lag->netdev = vsi->netdev;
	lag->role = ICE_LAG_NONE;
	lag->active_port = ICE_LAG_INVALID_PORT;
	lag->bonded = false;
	lag->upper_netdev = NULL;
	lag->notif_block.notifier_call = NULL;

	err = ice_register_lag_handler(lag);
	if (err) {
		dev_warn(dev, "INIT LAG: Failed to register event handler\n");
		goto lag_error;
	}

	err = ice_create_lag_recipe(&pf->hw, &lag->pf_recipe,
				    ice_dflt_vsi_rcp, 1);
	if (err)
		goto lag_error;

	err = ice_create_lag_recipe(&pf->hw, &lag->lport_recipe,
				    ice_lport_rcp, 3);
	if (err)
		goto free_rcp_res;

	/* associate recipes to profiles */
	for (n = 0; n < ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER; n++) {
		err = ice_aq_get_recipe_to_profile(&pf->hw, n,
						   (u8 *)&recipe_bits, NULL);
		if (err)
			continue;

		if (recipe_bits & BIT(ICE_SW_LKUP_DFLT)) {
			recipe_bits |= BIT(lag->pf_recipe) |
				       BIT(lag->lport_recipe);
			ice_aq_map_recipe_to_profile(&pf->hw, n,
						     (u8 *)&recipe_bits, NULL);
		}
	}

	ice_display_lag_info(lag);

	dev_dbg(dev, "INIT LAG complete\n");
	return 0;

free_rcp_res:
	ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,
			&pf->lag->pf_recipe);
lag_error:
	kfree(lag);
	pf->lag = NULL;
	return err;
}

/**
 * ice_deinit_lag - Clean up LAG
 * @pf: PF struct
 *
 * Clean up kernel LAG info and free memory
 * This function is meant to only be called on driver remove/shutdown
 */
void ice_deinit_lag(struct ice_pf *pf)
{
	struct ice_lag *lag;

	lag = pf->lag;

	if (!lag)
		return;

	if (lag->pf)
		ice_unregister_lag_handler(lag);

	flush_workqueue(ice_lag_wq);

	ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,
			&pf->lag->pf_recipe);
	ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,
			&pf->lag->lport_recipe);

	kfree(lag);

	pf->lag = NULL;
}

/**
 * ice_lag_rebuild - rebuild lag resources after reset
 * @pf: pointer to local pf struct
 *
 * PF resets are promoted to CORER resets when interface in an aggregate.  This
 * means that we need to rebuild the PF resources for the interface.  Since
 * this will happen outside the normal event processing, need to acquire the lag
 * lock.
 *
 * This function will also evaluate the VF resources if this is the primary
 * interface.
 */
void ice_lag_rebuild(struct ice_pf *pf)
{
	struct ice_lag_netdev_list ndlist;
	struct ice_lag *lag, *prim_lag;
	u8 act_port, loc_port;

	if (!pf->lag || !pf->lag->bonded)
		return;

	mutex_lock(&pf->lag_mutex);

	lag = pf->lag;
	if (lag->primary) {
		prim_lag = lag;
	} else {
		ice_lag_build_netdev_list(lag, &ndlist);
		prim_lag = ice_lag_find_primary(lag);
	}

	if (!prim_lag) {
		dev_dbg(ice_pf_to_dev(pf), "No primary interface in aggregate, can't rebuild\n");
		goto lag_rebuild_out;
	}

	act_port = prim_lag->active_port;
	loc_port = lag->pf->hw.port_info->lport;

	/* configure SWID for this port */
	if (lag->primary) {
		ice_lag_primary_swid(lag, true);
	} else {
		ice_lag_set_swid(prim_lag->pf->hw.port_info->sw_id, lag, true);
		ice_lag_add_prune_list(prim_lag, pf);
		if (act_port == loc_port)
			ice_lag_move_vf_nodes_sync(prim_lag, &pf->hw);
	}

	ice_lag_cfg_cp_fltr(lag, true);

	if (lag->pf_rule_id)
		if (ice_lag_cfg_dflt_fltr(lag, true))
			dev_err(ice_pf_to_dev(pf), "Error adding default VSI rule in rebuild\n");

	ice_clear_rdma_cap(pf);
lag_rebuild_out:
	ice_lag_destroy_netdev_list(lag, &ndlist);
	mutex_unlock(&pf->lag_mutex);
}

/**
 * ice_lag_is_switchdev_running
 * @pf: pointer to PF structure
 *
 * Check if switchdev is running on any of the interfaces connected to lag.
 */
bool ice_lag_is_switchdev_running(struct ice_pf *pf)
{
	struct ice_lag *lag = pf->lag;
	struct net_device *tmp_nd;

	if (!ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) || !lag)
		return false;

	rcu_read_lock();
	for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {
		struct ice_netdev_priv *priv = netdev_priv(tmp_nd);

		if (!netif_is_ice(tmp_nd) || !priv || !priv->vsi ||
		    !priv->vsi->back)
			continue;

		if (ice_is_switchdev_running(priv->vsi->back)) {
			rcu_read_unlock();
			return true;
		}
	}
	rcu_read_unlock();

	return false;
}
