2216 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (C) 2018-2021, Intel Corporation. */3 4/* Link Aggregation code */5 6#include "ice.h"7#include "ice_lib.h"8#include "ice_lag.h"9 10#define ICE_LAG_RES_SHARED BIT(14)11#define ICE_LAG_RES_VALID BIT(15)12 13#define LACP_TRAIN_PKT_LEN 1614static const u8 lacp_train_pkt[LACP_TRAIN_PKT_LEN] = { 0, 0, 0, 0, 0, 0,15 0, 0, 0, 0, 0, 0,16 0x88, 0x09, 0, 0 };17 18#define ICE_RECIPE_LEN 6419static const u8 ice_dflt_vsi_rcp[ICE_RECIPE_LEN] = {20 0x05, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,21 0x85, 0, 0x01, 0, 0, 0, 0xff, 0xff, 0x08, 0, 0, 0, 0, 0, 0, 0,22 0, 0, 0, 0, 0, 0, 0x30 };23static const u8 ice_lport_rcp[ICE_RECIPE_LEN] = {24 0x05, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,25 0x85, 0, 0x16, 0, 0, 0, 0xff, 0xff, 0x07, 0, 0, 0, 0, 0, 0, 0,26 0, 0, 0, 0, 0, 0, 0x30 };27 28/**29 * ice_lag_set_primary - set PF LAG state as Primary30 * @lag: LAG info struct31 */32static void ice_lag_set_primary(struct ice_lag *lag)33{34 struct ice_pf *pf = lag->pf;35 36 if (!pf)37 return;38 39 if (lag->role != ICE_LAG_UNSET && lag->role != ICE_LAG_BACKUP) {40 dev_warn(ice_pf_to_dev(pf), "%s: Attempt to be Primary, but incompatible state.\n",41 netdev_name(lag->netdev));42 return;43 }44 45 lag->role = ICE_LAG_PRIMARY;46}47 48/**49 * ice_lag_set_backup - set PF LAG state to Backup50 * @lag: LAG info struct51 */52static void ice_lag_set_backup(struct ice_lag *lag)53{54 struct ice_pf *pf = lag->pf;55 56 if (!pf)57 return;58 59 if (lag->role != ICE_LAG_UNSET && lag->role != ICE_LAG_PRIMARY) {60 dev_dbg(ice_pf_to_dev(pf), "%s: Attempt to be Backup, but incompatible state\n",61 netdev_name(lag->netdev));62 return;63 }64 65 lag->role = ICE_LAG_BACKUP;66}67 68/**69 * netif_is_same_ice - determine if netdev is on the same ice NIC as local PF70 * @pf: local PF struct71 * @netdev: netdev we are evaluating72 */73static bool netif_is_same_ice(struct ice_pf *pf, struct net_device *netdev)74{75 struct ice_netdev_priv *np;76 struct ice_pf *test_pf;77 struct ice_vsi *vsi;78 79 if (!netif_is_ice(netdev))80 return false;81 82 np = netdev_priv(netdev);83 if (!np)84 return false;85 86 vsi = np->vsi;87 if (!vsi)88 return false;89 90 test_pf = vsi->back;91 if (!test_pf)92 return false;93 94 if (pf->pdev->bus != test_pf->pdev->bus ||95 pf->pdev->slot != test_pf->pdev->slot)96 return false;97 98 return true;99}100 101/**102 * ice_netdev_to_lag - return pointer to associated lag struct from netdev103 * @netdev: pointer to net_device struct to query104 */105static struct ice_lag *ice_netdev_to_lag(struct net_device *netdev)106{107 struct ice_netdev_priv *np;108 struct ice_vsi *vsi;109 110 if (!netif_is_ice(netdev))111 return NULL;112 113 np = netdev_priv(netdev);114 if (!np)115 return NULL;116 117 vsi = np->vsi;118 if (!vsi)119 return NULL;120 121 return vsi->back->lag;122}123 124/**125 * ice_lag_find_hw_by_lport - return an hw struct from bond members lport126 * @lag: lag struct127 * @lport: lport value to search for128 */129static struct ice_hw *130ice_lag_find_hw_by_lport(struct ice_lag *lag, u8 lport)131{132 struct ice_lag_netdev_list *entry;133 struct net_device *tmp_netdev;134 struct ice_netdev_priv *np;135 struct ice_hw *hw;136 137 list_for_each_entry(entry, lag->netdev_head, node) {138 tmp_netdev = entry->netdev;139 if (!tmp_netdev || !netif_is_ice(tmp_netdev))140 continue;141 142 np = netdev_priv(tmp_netdev);143 if (!np || !np->vsi)144 continue;145 146 hw = &np->vsi->back->hw;147 if (hw->port_info->lport == lport)148 return hw;149 }150 151 return NULL;152}153 154/**155 * ice_pkg_has_lport_extract - check if lport extraction supported156 * @hw: HW struct157 */158static bool ice_pkg_has_lport_extract(struct ice_hw *hw)159{160 int i;161 162 for (i = 0; i < hw->blk[ICE_BLK_SW].es.count; i++) {163 u16 offset;164 u8 fv_prot;165 166 ice_find_prot_off(hw, ICE_BLK_SW, ICE_SW_DEFAULT_PROFILE, i,167 &fv_prot, &offset);168 if (fv_prot == ICE_FV_PROT_MDID &&169 offset == ICE_LP_EXT_BUF_OFFSET)170 return true;171 }172 return false;173}174 175/**176 * ice_lag_find_primary - returns pointer to primary interfaces lag struct177 * @lag: local interfaces lag struct178 */179static struct ice_lag *ice_lag_find_primary(struct ice_lag *lag)180{181 struct ice_lag *primary_lag = NULL;182 struct list_head *tmp;183 184 list_for_each(tmp, lag->netdev_head) {185 struct ice_lag_netdev_list *entry;186 struct ice_lag *tmp_lag;187 188 entry = list_entry(tmp, struct ice_lag_netdev_list, node);189 tmp_lag = ice_netdev_to_lag(entry->netdev);190 if (tmp_lag && tmp_lag->primary) {191 primary_lag = tmp_lag;192 break;193 }194 }195 196 return primary_lag;197}198 199/**200 * ice_lag_cfg_fltr - Add/Remove rule for LAG201 * @lag: lag struct for local interface202 * @act: rule action203 * @recipe_id: recipe id for the new rule204 * @rule_idx: pointer to rule index205 * @direction: ICE_FLTR_RX or ICE_FLTR_TX206 * @add: boolean on whether we are adding filters207 */208static int209ice_lag_cfg_fltr(struct ice_lag *lag, u32 act, u16 recipe_id, u16 *rule_idx,210 u8 direction, bool add)211{212 struct ice_sw_rule_lkup_rx_tx *s_rule;213 u16 s_rule_sz, vsi_num;214 struct ice_hw *hw;215 u8 *eth_hdr;216 u32 opc;217 int err;218 219 hw = &lag->pf->hw;220 vsi_num = ice_get_hw_vsi_num(hw, 0);221 222 s_rule_sz = ICE_SW_RULE_RX_TX_ETH_HDR_SIZE(s_rule);223 s_rule = kzalloc(s_rule_sz, GFP_KERNEL);224 if (!s_rule) {225 dev_err(ice_pf_to_dev(lag->pf), "error allocating rule for LAG\n");226 return -ENOMEM;227 }228 229 if (add) {230 eth_hdr = s_rule->hdr_data;231 ice_fill_eth_hdr(eth_hdr);232 233 act |= FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M, vsi_num);234 235 s_rule->recipe_id = cpu_to_le16(recipe_id);236 if (direction == ICE_FLTR_RX) {237 s_rule->hdr.type =238 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);239 s_rule->src = cpu_to_le16(hw->port_info->lport);240 } else {241 s_rule->hdr.type =242 cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_TX);243 s_rule->src = cpu_to_le16(vsi_num);244 }245 s_rule->act = cpu_to_le32(act);246 s_rule->hdr_len = cpu_to_le16(DUMMY_ETH_HDR_LEN);247 opc = ice_aqc_opc_add_sw_rules;248 } else {249 s_rule->index = cpu_to_le16(*rule_idx);250 opc = ice_aqc_opc_remove_sw_rules;251 }252 253 err = ice_aq_sw_rules(&lag->pf->hw, s_rule, s_rule_sz, 1, opc, NULL);254 if (err)255 goto dflt_fltr_free;256 257 if (add)258 *rule_idx = le16_to_cpu(s_rule->index);259 else260 *rule_idx = 0;261 262dflt_fltr_free:263 kfree(s_rule);264 return err;265}266 267/**268 * ice_lag_cfg_dflt_fltr - Add/Remove default VSI rule for LAG269 * @lag: lag struct for local interface270 * @add: boolean on whether to add filter271 */272static int273ice_lag_cfg_dflt_fltr(struct ice_lag *lag, bool add)274{275 u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |276 ICE_SINGLE_ACT_VALID_BIT | ICE_SINGLE_ACT_LAN_ENABLE;277 int err;278 279 err = ice_lag_cfg_fltr(lag, act, lag->pf_recipe, &lag->pf_rx_rule_id,280 ICE_FLTR_RX, add);281 if (err)282 goto err_rx;283 284 act = ICE_SINGLE_ACT_VSI_FORWARDING | ICE_SINGLE_ACT_VALID_BIT |285 ICE_SINGLE_ACT_LB_ENABLE;286 err = ice_lag_cfg_fltr(lag, act, lag->pf_recipe, &lag->pf_tx_rule_id,287 ICE_FLTR_TX, add);288 if (err)289 goto err_tx;290 291 return 0;292 293err_tx:294 ice_lag_cfg_fltr(lag, act, lag->pf_recipe, &lag->pf_rx_rule_id,295 ICE_FLTR_RX, !add);296err_rx:297 return err;298}299 300/**301 * ice_lag_cfg_drop_fltr - Add/Remove lport drop rule302 * @lag: lag struct for local interface303 * @add: boolean on whether to add filter304 */305static int306ice_lag_cfg_drop_fltr(struct ice_lag *lag, bool add)307{308 u32 act = ICE_SINGLE_ACT_VSI_FORWARDING |309 ICE_SINGLE_ACT_VALID_BIT |310 ICE_SINGLE_ACT_DROP;311 312 return ice_lag_cfg_fltr(lag, act, lag->lport_recipe,313 &lag->lport_rule_idx, ICE_FLTR_RX, add);314}315 316/**317 * ice_lag_cfg_pf_fltrs - set filters up for new active port318 * @lag: local interfaces lag struct319 * @ptr: opaque data containing notifier event320 */321static void322ice_lag_cfg_pf_fltrs(struct ice_lag *lag, void *ptr)323{324 struct netdev_notifier_bonding_info *info;325 struct netdev_bonding_info *bonding_info;326 struct net_device *event_netdev;327 struct device *dev;328 329 event_netdev = netdev_notifier_info_to_dev(ptr);330 /* not for this netdev */331 if (event_netdev != lag->netdev)332 return;333 334 info = (struct netdev_notifier_bonding_info *)ptr;335 bonding_info = &info->bonding_info;336 dev = ice_pf_to_dev(lag->pf);337 338 /* interface not active - remove old default VSI rule */339 if (bonding_info->slave.state && lag->pf_rx_rule_id) {340 if (ice_lag_cfg_dflt_fltr(lag, false))341 dev_err(dev, "Error removing old default VSI filter\n");342 if (ice_lag_cfg_drop_fltr(lag, true))343 dev_err(dev, "Error adding new drop filter\n");344 return;345 }346 347 /* interface becoming active - add new default VSI rule */348 if (!bonding_info->slave.state && !lag->pf_rx_rule_id) {349 if (ice_lag_cfg_dflt_fltr(lag, true))350 dev_err(dev, "Error adding new default VSI filter\n");351 if (lag->lport_rule_idx && ice_lag_cfg_drop_fltr(lag, false))352 dev_err(dev, "Error removing old drop filter\n");353 }354}355 356/**357 * ice_display_lag_info - print LAG info358 * @lag: LAG info struct359 */360static void ice_display_lag_info(struct ice_lag *lag)361{362 const char *name, *upper, *role, *bonded, *primary;363 struct device *dev = &lag->pf->pdev->dev;364 365 name = lag->netdev ? netdev_name(lag->netdev) : "unset";366 upper = lag->upper_netdev ? netdev_name(lag->upper_netdev) : "unset";367 primary = lag->primary ? "TRUE" : "FALSE";368 bonded = lag->bonded ? "BONDED" : "UNBONDED";369 370 switch (lag->role) {371 case ICE_LAG_NONE:372 role = "NONE";373 break;374 case ICE_LAG_PRIMARY:375 role = "PRIMARY";376 break;377 case ICE_LAG_BACKUP:378 role = "BACKUP";379 break;380 case ICE_LAG_UNSET:381 role = "UNSET";382 break;383 default:384 role = "ERROR";385 }386 387 dev_dbg(dev, "%s %s, upper:%s, role:%s, primary:%s\n", name, bonded,388 upper, role, primary);389}390 391/**392 * ice_lag_qbuf_recfg - generate a buffer of queues for a reconfigure command393 * @hw: HW struct that contains the queue contexts394 * @qbuf: pointer to buffer to populate395 * @vsi_num: index of the VSI in PF space396 * @numq: number of queues to search for397 * @tc: traffic class that contains the queues398 *399 * function returns the number of valid queues in buffer400 */401static u16402ice_lag_qbuf_recfg(struct ice_hw *hw, struct ice_aqc_cfg_txqs_buf *qbuf,403 u16 vsi_num, u16 numq, u8 tc)404{405 struct ice_q_ctx *q_ctx;406 u16 qid, count = 0;407 struct ice_pf *pf;408 int i;409 410 pf = hw->back;411 for (i = 0; i < numq; i++) {412 q_ctx = ice_get_lan_q_ctx(hw, vsi_num, tc, i);413 if (!q_ctx) {414 dev_dbg(ice_hw_to_dev(hw), "%s queue %d NO Q CONTEXT\n",415 __func__, i);416 continue;417 }418 if (q_ctx->q_teid == ICE_INVAL_TEID) {419 dev_dbg(ice_hw_to_dev(hw), "%s queue %d INVAL TEID\n",420 __func__, i);421 continue;422 }423 if (q_ctx->q_handle == ICE_INVAL_Q_HANDLE) {424 dev_dbg(ice_hw_to_dev(hw), "%s queue %d INVAL Q HANDLE\n",425 __func__, i);426 continue;427 }428 429 qid = pf->vsi[vsi_num]->txq_map[q_ctx->q_handle];430 qbuf->queue_info[count].q_handle = cpu_to_le16(qid);431 qbuf->queue_info[count].tc = tc;432 qbuf->queue_info[count].q_teid = cpu_to_le32(q_ctx->q_teid);433 count++;434 }435 436 return count;437}438 439/**440 * ice_lag_get_sched_parent - locate or create a sched node parent441 * @hw: HW struct for getting parent in442 * @tc: traffic class on parent/node443 */444static struct ice_sched_node *445ice_lag_get_sched_parent(struct ice_hw *hw, u8 tc)446{447 struct ice_sched_node *tc_node, *aggnode, *parent = NULL;448 u16 num_nodes[ICE_AQC_TOPO_MAX_LEVEL_NUM] = { 0 };449 struct ice_port_info *pi = hw->port_info;450 struct device *dev;451 u8 aggl, vsil;452 int n;453 454 dev = ice_hw_to_dev(hw);455 456 tc_node = ice_sched_get_tc_node(pi, tc);457 if (!tc_node) {458 dev_warn(dev, "Failure to find TC node for LAG move\n");459 return parent;460 }461 462 aggnode = ice_sched_get_agg_node(pi, tc_node, ICE_DFLT_AGG_ID);463 if (!aggnode) {464 dev_warn(dev, "Failure to find aggregate node for LAG move\n");465 return parent;466 }467 468 aggl = ice_sched_get_agg_layer(hw);469 vsil = ice_sched_get_vsi_layer(hw);470 471 for (n = aggl + 1; n < vsil; n++)472 num_nodes[n] = 1;473 474 for (n = 0; n < aggnode->num_children; n++) {475 parent = ice_sched_get_free_vsi_parent(hw, aggnode->children[n],476 num_nodes);477 if (parent)478 return parent;479 }480 481 /* if free parent not found - add one */482 parent = aggnode;483 for (n = aggl + 1; n < vsil; n++) {484 u16 num_nodes_added;485 u32 first_teid;486 int err;487 488 err = ice_sched_add_nodes_to_layer(pi, tc_node, parent, n,489 num_nodes[n], &first_teid,490 &num_nodes_added);491 if (err || num_nodes[n] != num_nodes_added)492 return NULL;493 494 if (num_nodes_added)495 parent = ice_sched_find_node_by_teid(tc_node,496 first_teid);497 else498 parent = parent->children[0];499 if (!parent) {500 dev_warn(dev, "Failure to add new parent for LAG move\n");501 return parent;502 }503 }504 505 return parent;506}507 508/**509 * ice_lag_move_vf_node_tc - move scheduling nodes for one VF on one TC510 * @lag: lag info struct511 * @oldport: lport of previous nodes location512 * @newport: lport of destination nodes location513 * @vsi_num: array index of VSI in PF space514 * @tc: traffic class to move515 */516static void517ice_lag_move_vf_node_tc(struct ice_lag *lag, u8 oldport, u8 newport,518 u16 vsi_num, u8 tc)519{520 DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);521 struct device *dev = ice_pf_to_dev(lag->pf);522 u16 numq, valq, num_moved, qbuf_size;523 u16 buf_size = __struct_size(buf);524 struct ice_aqc_cfg_txqs_buf *qbuf;525 struct ice_sched_node *n_prt;526 struct ice_hw *new_hw = NULL;527 __le32 teid, parent_teid;528 struct ice_vsi_ctx *ctx;529 u32 tmp_teid;530 531 ctx = ice_get_vsi_ctx(&lag->pf->hw, vsi_num);532 if (!ctx) {533 dev_warn(dev, "Unable to locate VSI context for LAG failover\n");534 return;535 }536 537 /* check to see if this VF is enabled on this TC */538 if (!ctx->sched.vsi_node[tc])539 return;540 541 /* locate HW struct for destination port */542 new_hw = ice_lag_find_hw_by_lport(lag, newport);543 if (!new_hw) {544 dev_warn(dev, "Unable to locate HW struct for LAG node destination\n");545 return;546 }547 548 numq = ctx->num_lan_q_entries[tc];549 teid = ctx->sched.vsi_node[tc]->info.node_teid;550 tmp_teid = le32_to_cpu(teid);551 parent_teid = ctx->sched.vsi_node[tc]->info.parent_teid;552 /* if no teid assigned or numq == 0, then this TC is not active */553 if (!tmp_teid || !numq)554 return;555 556 /* suspend VSI subtree for Traffic Class "tc" on557 * this VF's VSI558 */559 if (ice_sched_suspend_resume_elems(&lag->pf->hw, 1, &tmp_teid, true))560 dev_dbg(dev, "Problem suspending traffic for LAG node move\n");561 562 /* reconfigure all VF's queues on this Traffic Class563 * to new port564 */565 qbuf_size = struct_size(qbuf, queue_info, numq);566 qbuf = kzalloc(qbuf_size, GFP_KERNEL);567 if (!qbuf) {568 dev_warn(dev, "Failure allocating memory for VF queue recfg buffer\n");569 goto resume_traffic;570 }571 572 /* add the per queue info for the reconfigure command buffer */573 valq = ice_lag_qbuf_recfg(&lag->pf->hw, qbuf, vsi_num, numq, tc);574 if (!valq) {575 dev_dbg(dev, "No valid queues found for LAG failover\n");576 goto qbuf_none;577 }578 579 if (ice_aq_cfg_lan_txq(&lag->pf->hw, qbuf, qbuf_size, valq, oldport,580 newport, NULL)) {581 dev_warn(dev, "Failure to configure queues for LAG failover\n");582 goto qbuf_err;583 }584 585qbuf_none:586 kfree(qbuf);587 588 /* find new parent in destination port's tree for VF VSI node on this589 * Traffic Class590 */591 n_prt = ice_lag_get_sched_parent(new_hw, tc);592 if (!n_prt)593 goto resume_traffic;594 595 /* Move Vf's VSI node for this TC to newport's scheduler tree */596 buf->hdr.src_parent_teid = parent_teid;597 buf->hdr.dest_parent_teid = n_prt->info.node_teid;598 buf->hdr.num_elems = cpu_to_le16(1);599 buf->hdr.mode = ICE_AQC_MOVE_ELEM_MODE_KEEP_OWN;600 buf->teid[0] = teid;601 602 if (ice_aq_move_sched_elems(&lag->pf->hw, buf, buf_size, &num_moved))603 dev_warn(dev, "Failure to move VF nodes for failover\n");604 else605 ice_sched_update_parent(n_prt, ctx->sched.vsi_node[tc]);606 607 goto resume_traffic;608 609qbuf_err:610 kfree(qbuf);611 612resume_traffic:613 /* restart traffic for VSI node */614 if (ice_sched_suspend_resume_elems(&lag->pf->hw, 1, &tmp_teid, false))615 dev_dbg(dev, "Problem restarting traffic for LAG node move\n");616}617 618/**619 * ice_lag_build_netdev_list - populate the lag struct's netdev list620 * @lag: local lag struct621 * @ndlist: pointer to netdev list to populate622 */623static void ice_lag_build_netdev_list(struct ice_lag *lag,624 struct ice_lag_netdev_list *ndlist)625{626 struct ice_lag_netdev_list *nl;627 struct net_device *tmp_nd;628 629 INIT_LIST_HEAD(&ndlist->node);630 rcu_read_lock();631 for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {632 nl = kzalloc(sizeof(*nl), GFP_ATOMIC);633 if (!nl)634 break;635 636 nl->netdev = tmp_nd;637 list_add(&nl->node, &ndlist->node);638 }639 rcu_read_unlock();640 lag->netdev_head = &ndlist->node;641}642 643/**644 * ice_lag_destroy_netdev_list - free lag struct's netdev list645 * @lag: pointer to local lag struct646 * @ndlist: pointer to lag struct netdev list647 */648static void ice_lag_destroy_netdev_list(struct ice_lag *lag,649 struct ice_lag_netdev_list *ndlist)650{651 struct ice_lag_netdev_list *entry, *n;652 653 rcu_read_lock();654 list_for_each_entry_safe(entry, n, &ndlist->node, node) {655 list_del(&entry->node);656 kfree(entry);657 }658 rcu_read_unlock();659 lag->netdev_head = NULL;660}661 662/**663 * ice_lag_move_single_vf_nodes - Move Tx scheduling nodes for single VF664 * @lag: primary interface LAG struct665 * @oldport: lport of previous interface666 * @newport: lport of destination interface667 * @vsi_num: SW index of VF's VSI668 */669static void670ice_lag_move_single_vf_nodes(struct ice_lag *lag, u8 oldport, u8 newport,671 u16 vsi_num)672{673 u8 tc;674 675 ice_for_each_traffic_class(tc)676 ice_lag_move_vf_node_tc(lag, oldport, newport, vsi_num, tc);677}678 679/**680 * ice_lag_move_new_vf_nodes - Move Tx scheduling nodes for a VF if required681 * @vf: the VF to move Tx nodes for682 *683 * Called just after configuring new VF queues. Check whether the VF Tx684 * scheduling nodes need to be updated to fail over to the active port. If so,685 * move them now.686 */687void ice_lag_move_new_vf_nodes(struct ice_vf *vf)688{689 struct ice_lag_netdev_list ndlist;690 u8 pri_port, act_port;691 struct ice_lag *lag;692 struct ice_vsi *vsi;693 struct ice_pf *pf;694 695 vsi = ice_get_vf_vsi(vf);696 697 if (WARN_ON(!vsi))698 return;699 700 if (WARN_ON(vsi->type != ICE_VSI_VF))701 return;702 703 pf = vf->pf;704 lag = pf->lag;705 706 mutex_lock(&pf->lag_mutex);707 if (!lag->bonded)708 goto new_vf_unlock;709 710 pri_port = pf->hw.port_info->lport;711 act_port = lag->active_port;712 713 if (lag->upper_netdev)714 ice_lag_build_netdev_list(lag, &ndlist);715 716 if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) &&717 lag->bonded && lag->primary && pri_port != act_port &&718 !list_empty(lag->netdev_head))719 ice_lag_move_single_vf_nodes(lag, pri_port, act_port, vsi->idx);720 721 ice_lag_destroy_netdev_list(lag, &ndlist);722 723new_vf_unlock:724 mutex_unlock(&pf->lag_mutex);725}726 727/**728 * ice_lag_move_vf_nodes - move Tx scheduling nodes for all VFs to new port729 * @lag: lag info struct730 * @oldport: lport of previous interface731 * @newport: lport of destination interface732 */733static void ice_lag_move_vf_nodes(struct ice_lag *lag, u8 oldport, u8 newport)734{735 struct ice_pf *pf;736 int i;737 738 if (!lag->primary)739 return;740 741 pf = lag->pf;742 ice_for_each_vsi(pf, i)743 if (pf->vsi[i] && pf->vsi[i]->type == ICE_VSI_VF)744 ice_lag_move_single_vf_nodes(lag, oldport, newport, i);745}746 747/**748 * ice_lag_move_vf_nodes_cfg - move vf nodes outside LAG netdev event context749 * @lag: local lag struct750 * @src_prt: lport value for source port751 * @dst_prt: lport value for destination port752 *753 * This function is used to move nodes during an out-of-netdev-event situation,754 * primarily when the driver needs to reconfigure or recreate resources.755 *756 * Must be called while holding the lag_mutex to avoid lag events from757 * processing while out-of-sync moves are happening. Also, paired moves,758 * such as used in a reset flow, should both be called under the same mutex759 * lock to avoid changes between start of reset and end of reset.760 */761void ice_lag_move_vf_nodes_cfg(struct ice_lag *lag, u8 src_prt, u8 dst_prt)762{763 struct ice_lag_netdev_list ndlist;764 765 ice_lag_build_netdev_list(lag, &ndlist);766 ice_lag_move_vf_nodes(lag, src_prt, dst_prt);767 ice_lag_destroy_netdev_list(lag, &ndlist);768}769 770#define ICE_LAG_SRIOV_CP_RECIPE 10771#define ICE_LAG_SRIOV_TRAIN_PKT_LEN 16772 773/**774 * ice_lag_cfg_cp_fltr - configure filter for control packets775 * @lag: local interface's lag struct776 * @add: add or remove rule777 */778static void779ice_lag_cfg_cp_fltr(struct ice_lag *lag, bool add)780{781 struct ice_sw_rule_lkup_rx_tx *s_rule = NULL;782 struct ice_vsi *vsi;783 u16 buf_len, opc;784 785 vsi = lag->pf->vsi[0];786 787 buf_len = ICE_SW_RULE_RX_TX_HDR_SIZE(s_rule,788 ICE_LAG_SRIOV_TRAIN_PKT_LEN);789 s_rule = kzalloc(buf_len, GFP_KERNEL);790 if (!s_rule) {791 netdev_warn(lag->netdev, "-ENOMEM error configuring CP filter\n");792 return;793 }794 795 if (add) {796 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_LKUP_RX);797 s_rule->recipe_id = cpu_to_le16(ICE_LAG_SRIOV_CP_RECIPE);798 s_rule->src = cpu_to_le16(vsi->port_info->lport);799 s_rule->act = cpu_to_le32(ICE_FWD_TO_VSI |800 ICE_SINGLE_ACT_LAN_ENABLE |801 ICE_SINGLE_ACT_VALID_BIT |802 FIELD_PREP(ICE_SINGLE_ACT_VSI_ID_M, vsi->vsi_num));803 s_rule->hdr_len = cpu_to_le16(ICE_LAG_SRIOV_TRAIN_PKT_LEN);804 memcpy(s_rule->hdr_data, lacp_train_pkt, LACP_TRAIN_PKT_LEN);805 opc = ice_aqc_opc_add_sw_rules;806 } else {807 opc = ice_aqc_opc_remove_sw_rules;808 s_rule->index = cpu_to_le16(lag->cp_rule_idx);809 }810 if (ice_aq_sw_rules(&lag->pf->hw, s_rule, buf_len, 1, opc, NULL)) {811 netdev_warn(lag->netdev, "Error %s CP rule for fail-over\n",812 add ? "ADDING" : "REMOVING");813 goto cp_free;814 }815 816 if (add)817 lag->cp_rule_idx = le16_to_cpu(s_rule->index);818 else819 lag->cp_rule_idx = 0;820 821cp_free:822 kfree(s_rule);823}824 825/**826 * ice_lag_info_event - handle NETDEV_BONDING_INFO event827 * @lag: LAG info struct828 * @ptr: opaque data pointer829 *830 * ptr is to be cast to (netdev_notifier_bonding_info *)831 */832static void ice_lag_info_event(struct ice_lag *lag, void *ptr)833{834 struct netdev_notifier_bonding_info *info;835 struct netdev_bonding_info *bonding_info;836 struct net_device *event_netdev;837 const char *lag_netdev_name;838 839 event_netdev = netdev_notifier_info_to_dev(ptr);840 info = ptr;841 lag_netdev_name = netdev_name(lag->netdev);842 bonding_info = &info->bonding_info;843 844 if (event_netdev != lag->netdev || !lag->bonded || !lag->upper_netdev)845 return;846 847 if (bonding_info->master.bond_mode != BOND_MODE_ACTIVEBACKUP) {848 netdev_dbg(lag->netdev, "Bonding event recv, but mode not active/backup\n");849 goto lag_out;850 }851 852 if (strcmp(bonding_info->slave.slave_name, lag_netdev_name)) {853 netdev_dbg(lag->netdev, "Bonding event recv, but secondary info not for us\n");854 goto lag_out;855 }856 857 if (bonding_info->slave.state)858 ice_lag_set_backup(lag);859 else860 ice_lag_set_primary(lag);861 862lag_out:863 ice_display_lag_info(lag);864}865 866/**867 * ice_lag_reclaim_vf_tc - move scheduling nodes back to primary interface868 * @lag: primary interface lag struct869 * @src_hw: HW struct current node location870 * @vsi_num: VSI index in PF space871 * @tc: traffic class to move872 */873static void874ice_lag_reclaim_vf_tc(struct ice_lag *lag, struct ice_hw *src_hw, u16 vsi_num,875 u8 tc)876{877 DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);878 struct device *dev = ice_pf_to_dev(lag->pf);879 u16 numq, valq, num_moved, qbuf_size;880 u16 buf_size = __struct_size(buf);881 struct ice_aqc_cfg_txqs_buf *qbuf;882 struct ice_sched_node *n_prt;883 __le32 teid, parent_teid;884 struct ice_vsi_ctx *ctx;885 struct ice_hw *hw;886 u32 tmp_teid;887 888 hw = &lag->pf->hw;889 ctx = ice_get_vsi_ctx(hw, vsi_num);890 if (!ctx) {891 dev_warn(dev, "Unable to locate VSI context for LAG reclaim\n");892 return;893 }894 895 /* check to see if this VF is enabled on this TC */896 if (!ctx->sched.vsi_node[tc])897 return;898 899 numq = ctx->num_lan_q_entries[tc];900 teid = ctx->sched.vsi_node[tc]->info.node_teid;901 tmp_teid = le32_to_cpu(teid);902 parent_teid = ctx->sched.vsi_node[tc]->info.parent_teid;903 904 /* if !teid or !numq, then this TC is not active */905 if (!tmp_teid || !numq)906 return;907 908 /* suspend traffic */909 if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, true))910 dev_dbg(dev, "Problem suspending traffic for LAG node move\n");911 912 /* reconfig queues for new port */913 qbuf_size = struct_size(qbuf, queue_info, numq);914 qbuf = kzalloc(qbuf_size, GFP_KERNEL);915 if (!qbuf) {916 dev_warn(dev, "Failure allocating memory for VF queue recfg buffer\n");917 goto resume_reclaim;918 }919 920 /* add the per queue info for the reconfigure command buffer */921 valq = ice_lag_qbuf_recfg(hw, qbuf, vsi_num, numq, tc);922 if (!valq) {923 dev_dbg(dev, "No valid queues found for LAG reclaim\n");924 goto reclaim_none;925 }926 927 if (ice_aq_cfg_lan_txq(hw, qbuf, qbuf_size, numq,928 src_hw->port_info->lport, hw->port_info->lport,929 NULL)) {930 dev_warn(dev, "Failure to configure queues for LAG failover\n");931 goto reclaim_qerr;932 }933 934reclaim_none:935 kfree(qbuf);936 937 /* find parent in primary tree */938 n_prt = ice_lag_get_sched_parent(hw, tc);939 if (!n_prt)940 goto resume_reclaim;941 942 /* Move node to new parent */943 buf->hdr.src_parent_teid = parent_teid;944 buf->hdr.dest_parent_teid = n_prt->info.node_teid;945 buf->hdr.num_elems = cpu_to_le16(1);946 buf->hdr.mode = ICE_AQC_MOVE_ELEM_MODE_KEEP_OWN;947 buf->teid[0] = teid;948 949 if (ice_aq_move_sched_elems(&lag->pf->hw, buf, buf_size, &num_moved))950 dev_warn(dev, "Failure to move VF nodes for LAG reclaim\n");951 else952 ice_sched_update_parent(n_prt, ctx->sched.vsi_node[tc]);953 954 goto resume_reclaim;955 956reclaim_qerr:957 kfree(qbuf);958 959resume_reclaim:960 /* restart traffic */961 if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, false))962 dev_warn(dev, "Problem restarting traffic for LAG node reclaim\n");963}964 965/**966 * ice_lag_reclaim_vf_nodes - When interface leaving bond primary reclaims nodes967 * @lag: primary interface lag struct968 * @src_hw: HW struct for current node location969 */970static void971ice_lag_reclaim_vf_nodes(struct ice_lag *lag, struct ice_hw *src_hw)972{973 struct ice_pf *pf;974 int i, tc;975 976 if (!lag->primary || !src_hw)977 return;978 979 pf = lag->pf;980 ice_for_each_vsi(pf, i)981 if (pf->vsi[i] && pf->vsi[i]->type == ICE_VSI_VF)982 ice_for_each_traffic_class(tc)983 ice_lag_reclaim_vf_tc(lag, src_hw, i, tc);984}985 986/**987 * ice_lag_link - handle LAG link event988 * @lag: LAG info struct989 */990static void ice_lag_link(struct ice_lag *lag)991{992 struct ice_pf *pf = lag->pf;993 994 if (lag->bonded)995 dev_warn(ice_pf_to_dev(pf), "%s Already part of a bond\n",996 netdev_name(lag->netdev));997 998 lag->bonded = true;999 lag->role = ICE_LAG_UNSET;1000 netdev_info(lag->netdev, "Shared SR-IOV resources in bond are active\n");1001}1002 1003/**1004 * ice_lag_unlink - handle unlink event1005 * @lag: LAG info struct1006 */1007static void ice_lag_unlink(struct ice_lag *lag)1008{1009 u8 pri_port, act_port, loc_port;1010 struct ice_pf *pf = lag->pf;1011 1012 if (!lag->bonded) {1013 netdev_dbg(lag->netdev, "bonding unlink event on non-LAG netdev\n");1014 return;1015 }1016 1017 if (lag->primary) {1018 act_port = lag->active_port;1019 pri_port = lag->pf->hw.port_info->lport;1020 if (act_port != pri_port && act_port != ICE_LAG_INVALID_PORT)1021 ice_lag_move_vf_nodes(lag, act_port, pri_port);1022 lag->primary = false;1023 lag->active_port = ICE_LAG_INVALID_PORT;1024 } else {1025 struct ice_lag *primary_lag;1026 1027 primary_lag = ice_lag_find_primary(lag);1028 if (primary_lag) {1029 act_port = primary_lag->active_port;1030 pri_port = primary_lag->pf->hw.port_info->lport;1031 loc_port = pf->hw.port_info->lport;1032 if (act_port == loc_port &&1033 act_port != ICE_LAG_INVALID_PORT) {1034 ice_lag_reclaim_vf_nodes(primary_lag,1035 &lag->pf->hw);1036 primary_lag->active_port = ICE_LAG_INVALID_PORT;1037 }1038 }1039 }1040 1041 lag->bonded = false;1042 lag->role = ICE_LAG_NONE;1043 lag->upper_netdev = NULL;1044}1045 1046/**1047 * ice_lag_link_unlink - helper function to call lag_link/unlink1048 * @lag: lag info struct1049 * @ptr: opaque pointer data1050 */1051static void ice_lag_link_unlink(struct ice_lag *lag, void *ptr)1052{1053 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);1054 struct netdev_notifier_changeupper_info *info = ptr;1055 1056 if (netdev != lag->netdev)1057 return;1058 1059 if (info->linking)1060 ice_lag_link(lag);1061 else1062 ice_lag_unlink(lag);1063}1064 1065/**1066 * ice_lag_set_swid - set the SWID on secondary interface1067 * @primary_swid: primary interface's SWID1068 * @local_lag: local interfaces LAG struct1069 * @link: Is this a linking activity1070 *1071 * If link is false, then primary_swid should be expected to not be valid1072 * This function should never be called in interrupt context.1073 */1074static void1075ice_lag_set_swid(u16 primary_swid, struct ice_lag *local_lag,1076 bool link)1077{1078 struct ice_aqc_alloc_free_res_elem *buf;1079 struct ice_aqc_set_port_params *cmd;1080 struct ice_aq_desc desc;1081 u16 buf_len, swid;1082 int status, i;1083 1084 buf_len = struct_size(buf, elem, 1);1085 buf = kzalloc(buf_len, GFP_KERNEL);1086 if (!buf) {1087 dev_err(ice_pf_to_dev(local_lag->pf), "-ENOMEM error setting SWID\n");1088 return;1089 }1090 1091 buf->num_elems = cpu_to_le16(1);1092 buf->res_type = cpu_to_le16(ICE_AQC_RES_TYPE_SWID);1093 /* if unlinnking need to free the shared resource */1094 if (!link && local_lag->bond_swid) {1095 buf->elem[0].e.sw_resp = cpu_to_le16(local_lag->bond_swid);1096 status = ice_aq_alloc_free_res(&local_lag->pf->hw, buf,1097 buf_len, ice_aqc_opc_free_res);1098 if (status)1099 dev_err(ice_pf_to_dev(local_lag->pf), "Error freeing SWID during LAG unlink\n");1100 local_lag->bond_swid = 0;1101 }1102 1103 if (link) {1104 buf->res_type |= cpu_to_le16(ICE_LAG_RES_SHARED |1105 ICE_LAG_RES_VALID);1106 /* store the primary's SWID in case it leaves bond first */1107 local_lag->bond_swid = primary_swid;1108 buf->elem[0].e.sw_resp = cpu_to_le16(local_lag->bond_swid);1109 } else {1110 buf->elem[0].e.sw_resp =1111 cpu_to_le16(local_lag->pf->hw.port_info->sw_id);1112 }1113 1114 status = ice_aq_alloc_free_res(&local_lag->pf->hw, buf, buf_len,1115 ice_aqc_opc_alloc_res);1116 if (status)1117 dev_err(ice_pf_to_dev(local_lag->pf), "Error subscribing to SWID 0x%04X\n",1118 local_lag->bond_swid);1119 1120 kfree(buf);1121 1122 /* Configure port param SWID to correct value */1123 if (link)1124 swid = primary_swid;1125 else1126 swid = local_lag->pf->hw.port_info->sw_id;1127 1128 cmd = &desc.params.set_port_params;1129 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_port_params);1130 1131 cmd->swid = cpu_to_le16(ICE_AQC_PORT_SWID_VALID | swid);1132 /* If this is happening in reset context, it is possible that the1133 * primary interface has not finished setting its SWID to SHARED1134 * yet. Allow retries to account for this timing issue between1135 * interfaces.1136 */1137 for (i = 0; i < ICE_LAG_RESET_RETRIES; i++) {1138 status = ice_aq_send_cmd(&local_lag->pf->hw, &desc, NULL, 0,1139 NULL);1140 if (!status)1141 break;1142 1143 usleep_range(1000, 2000);1144 }1145 1146 if (status)1147 dev_err(ice_pf_to_dev(local_lag->pf), "Error setting SWID in port params %d\n",1148 status);1149}1150 1151/**1152 * ice_lag_primary_swid - set/clear the SHARED attrib of primary's SWID1153 * @lag: primary interface's lag struct1154 * @link: is this a linking activity1155 *1156 * Implement setting primary SWID as shared using 0x020B1157 */1158static void ice_lag_primary_swid(struct ice_lag *lag, bool link)1159{1160 struct ice_hw *hw;1161 u16 swid;1162 1163 hw = &lag->pf->hw;1164 swid = hw->port_info->sw_id;1165 1166 if (ice_share_res(hw, ICE_AQC_RES_TYPE_SWID, link, swid))1167 dev_warn(ice_pf_to_dev(lag->pf), "Failure to set primary interface shared status\n");1168}1169 1170/**1171 * ice_lag_add_prune_list - Adds event_pf's VSI to primary's prune list1172 * @lag: lag info struct1173 * @event_pf: PF struct for VSI we are adding to primary's prune list1174 */1175static void ice_lag_add_prune_list(struct ice_lag *lag, struct ice_pf *event_pf)1176{1177 u16 num_vsi, rule_buf_sz, vsi_list_id, event_vsi_num, prim_vsi_idx;1178 struct ice_sw_rule_vsi_list *s_rule = NULL;1179 struct device *dev;1180 1181 num_vsi = 1;1182 1183 dev = ice_pf_to_dev(lag->pf);1184 event_vsi_num = event_pf->vsi[0]->vsi_num;1185 prim_vsi_idx = lag->pf->vsi[0]->idx;1186 1187 if (!ice_find_vsi_list_entry(&lag->pf->hw, ICE_SW_LKUP_VLAN,1188 prim_vsi_idx, &vsi_list_id)) {1189 dev_warn(dev, "Could not locate prune list when setting up SRIOV LAG\n");1190 return;1191 }1192 1193 rule_buf_sz = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);1194 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);1195 if (!s_rule) {1196 dev_warn(dev, "Error allocating space for prune list when configuring SRIOV LAG\n");1197 return;1198 }1199 1200 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_PRUNE_LIST_SET);1201 s_rule->index = cpu_to_le16(vsi_list_id);1202 s_rule->number_vsi = cpu_to_le16(num_vsi);1203 s_rule->vsi[0] = cpu_to_le16(event_vsi_num);1204 1205 if (ice_aq_sw_rules(&event_pf->hw, s_rule, rule_buf_sz, 1,1206 ice_aqc_opc_update_sw_rules, NULL))1207 dev_warn(dev, "Error adding VSI prune list\n");1208 kfree(s_rule);1209}1210 1211/**1212 * ice_lag_del_prune_list - Remove secondary's vsi from primary's prune list1213 * @lag: primary interface's ice_lag struct1214 * @event_pf: PF struct for unlinking interface1215 */1216static void ice_lag_del_prune_list(struct ice_lag *lag, struct ice_pf *event_pf)1217{1218 u16 num_vsi, vsi_num, vsi_idx, rule_buf_sz, vsi_list_id;1219 struct ice_sw_rule_vsi_list *s_rule = NULL;1220 struct device *dev;1221 1222 num_vsi = 1;1223 1224 dev = ice_pf_to_dev(lag->pf);1225 vsi_num = event_pf->vsi[0]->vsi_num;1226 vsi_idx = lag->pf->vsi[0]->idx;1227 1228 if (!ice_find_vsi_list_entry(&lag->pf->hw, ICE_SW_LKUP_VLAN,1229 vsi_idx, &vsi_list_id)) {1230 dev_warn(dev, "Could not locate prune list when unwinding SRIOV LAG\n");1231 return;1232 }1233 1234 rule_buf_sz = (u16)ICE_SW_RULE_VSI_LIST_SIZE(s_rule, num_vsi);1235 s_rule = kzalloc(rule_buf_sz, GFP_KERNEL);1236 if (!s_rule) {1237 dev_warn(dev, "Error allocating prune list when unwinding SRIOV LAG\n");1238 return;1239 }1240 1241 s_rule->hdr.type = cpu_to_le16(ICE_AQC_SW_RULES_T_PRUNE_LIST_CLEAR);1242 s_rule->index = cpu_to_le16(vsi_list_id);1243 s_rule->number_vsi = cpu_to_le16(num_vsi);1244 s_rule->vsi[0] = cpu_to_le16(vsi_num);1245 1246 if (ice_aq_sw_rules(&event_pf->hw, (struct ice_aqc_sw_rules *)s_rule,1247 rule_buf_sz, 1, ice_aqc_opc_update_sw_rules, NULL))1248 dev_warn(dev, "Error clearing VSI prune list\n");1249 1250 kfree(s_rule);1251}1252 1253/**1254 * ice_lag_init_feature_support_flag - Check for package and NVM support for LAG1255 * @pf: PF struct1256 */1257static void ice_lag_init_feature_support_flag(struct ice_pf *pf)1258{1259 struct ice_hw_common_caps *caps;1260 1261 caps = &pf->hw.dev_caps.common_cap;1262 if (caps->roce_lag)1263 ice_set_feature_support(pf, ICE_F_ROCE_LAG);1264 else1265 ice_clear_feature_support(pf, ICE_F_ROCE_LAG);1266 1267 if (caps->sriov_lag && ice_pkg_has_lport_extract(&pf->hw))1268 ice_set_feature_support(pf, ICE_F_SRIOV_LAG);1269 else1270 ice_clear_feature_support(pf, ICE_F_SRIOV_LAG);1271}1272 1273/**1274 * ice_lag_changeupper_event - handle LAG changeupper event1275 * @lag: LAG info struct1276 * @ptr: opaque pointer data1277 */1278static void ice_lag_changeupper_event(struct ice_lag *lag, void *ptr)1279{1280 struct netdev_notifier_changeupper_info *info;1281 struct ice_lag *primary_lag;1282 struct net_device *netdev;1283 1284 info = ptr;1285 netdev = netdev_notifier_info_to_dev(ptr);1286 1287 /* not for this netdev */1288 if (netdev != lag->netdev)1289 return;1290 1291 primary_lag = ice_lag_find_primary(lag);1292 if (info->linking) {1293 lag->upper_netdev = info->upper_dev;1294 /* If there is not already a primary interface in the LAG,1295 * then mark this one as primary.1296 */1297 if (!primary_lag) {1298 lag->primary = true;1299 /* Configure primary's SWID to be shared */1300 ice_lag_primary_swid(lag, true);1301 primary_lag = lag;1302 } else {1303 u16 swid;1304 1305 swid = primary_lag->pf->hw.port_info->sw_id;1306 ice_lag_set_swid(swid, lag, true);1307 ice_lag_add_prune_list(primary_lag, lag->pf);1308 ice_lag_cfg_drop_fltr(lag, true);1309 }1310 /* add filter for primary control packets */1311 ice_lag_cfg_cp_fltr(lag, true);1312 } else {1313 if (!primary_lag && lag->primary)1314 primary_lag = lag;1315 1316 if (!lag->primary) {1317 ice_lag_set_swid(0, lag, false);1318 } else {1319 if (primary_lag && lag->primary) {1320 ice_lag_primary_swid(lag, false);1321 ice_lag_del_prune_list(primary_lag, lag->pf);1322 }1323 }1324 /* remove filter for control packets */1325 ice_lag_cfg_cp_fltr(lag, false);1326 }1327}1328 1329/**1330 * ice_lag_monitor_link - monitor interfaces entering/leaving the aggregate1331 * @lag: lag info struct1332 * @ptr: opaque data containing notifier event1333 *1334 * This function only operates after a primary has been set.1335 */1336static void ice_lag_monitor_link(struct ice_lag *lag, void *ptr)1337{1338 struct netdev_notifier_changeupper_info *info;1339 struct ice_hw *prim_hw, *active_hw;1340 struct net_device *event_netdev;1341 struct ice_pf *pf;1342 u8 prim_port;1343 1344 if (!lag->primary)1345 return;1346 1347 event_netdev = netdev_notifier_info_to_dev(ptr);1348 if (!netif_is_same_ice(lag->pf, event_netdev))1349 return;1350 1351 pf = lag->pf;1352 prim_hw = &pf->hw;1353 prim_port = prim_hw->port_info->lport;1354 1355 info = (struct netdev_notifier_changeupper_info *)ptr;1356 if (info->upper_dev != lag->upper_netdev)1357 return;1358 1359 if (!info->linking) {1360 /* Since there are only two interfaces allowed in SRIOV+LAG, if1361 * one port is leaving, then nodes need to be on primary1362 * interface.1363 */1364 if (prim_port != lag->active_port &&1365 lag->active_port != ICE_LAG_INVALID_PORT) {1366 active_hw = ice_lag_find_hw_by_lport(lag,1367 lag->active_port);1368 ice_lag_reclaim_vf_nodes(lag, active_hw);1369 lag->active_port = ICE_LAG_INVALID_PORT;1370 }1371 }1372}1373 1374/**1375 * ice_lag_monitor_active - main PF keep track of which port is active1376 * @lag: lag info struct1377 * @ptr: opaque data containing notifier event1378 *1379 * This function is for the primary PF to monitor changes in which port is1380 * active and handle changes for SRIOV VF functionality1381 */1382static void ice_lag_monitor_active(struct ice_lag *lag, void *ptr)1383{1384 struct net_device *event_netdev, *event_upper;1385 struct netdev_notifier_bonding_info *info;1386 struct netdev_bonding_info *bonding_info;1387 struct ice_netdev_priv *event_np;1388 struct ice_pf *pf, *event_pf;1389 u8 prim_port, event_port;1390 1391 if (!lag->primary)1392 return;1393 1394 pf = lag->pf;1395 if (!pf)1396 return;1397 1398 event_netdev = netdev_notifier_info_to_dev(ptr);1399 rcu_read_lock();1400 event_upper = netdev_master_upper_dev_get_rcu(event_netdev);1401 rcu_read_unlock();1402 if (!netif_is_ice(event_netdev) || event_upper != lag->upper_netdev)1403 return;1404 1405 event_np = netdev_priv(event_netdev);1406 event_pf = event_np->vsi->back;1407 event_port = event_pf->hw.port_info->lport;1408 prim_port = pf->hw.port_info->lport;1409 1410 info = (struct netdev_notifier_bonding_info *)ptr;1411 bonding_info = &info->bonding_info;1412 1413 if (!bonding_info->slave.state) {1414 /* if no port is currently active, then nodes and filters exist1415 * on primary port, check if we need to move them1416 */1417 if (lag->active_port == ICE_LAG_INVALID_PORT) {1418 if (event_port != prim_port)1419 ice_lag_move_vf_nodes(lag, prim_port,1420 event_port);1421 lag->active_port = event_port;1422 return;1423 }1424 1425 /* active port is already set and is current event port */1426 if (lag->active_port == event_port)1427 return;1428 /* new active port */1429 ice_lag_move_vf_nodes(lag, lag->active_port, event_port);1430 lag->active_port = event_port;1431 } else {1432 /* port not set as currently active (e.g. new active port1433 * has already claimed the nodes and filters1434 */1435 if (lag->active_port != event_port)1436 return;1437 /* This is the case when neither port is active (both link down)1438 * Link down on the bond - set active port to invalid and move1439 * nodes and filters back to primary if not already there1440 */1441 if (event_port != prim_port)1442 ice_lag_move_vf_nodes(lag, event_port, prim_port);1443 lag->active_port = ICE_LAG_INVALID_PORT;1444 }1445}1446 1447/**1448 * ice_lag_chk_comp - evaluate bonded interface for feature support1449 * @lag: lag info struct1450 * @ptr: opaque data for netdev event info1451 */1452static bool1453ice_lag_chk_comp(struct ice_lag *lag, void *ptr)1454{1455 struct net_device *event_netdev, *event_upper;1456 struct netdev_notifier_bonding_info *info;1457 struct netdev_bonding_info *bonding_info;1458 struct list_head *tmp;1459 struct device *dev;1460 int count = 0;1461 1462 if (!lag->primary)1463 return true;1464 1465 event_netdev = netdev_notifier_info_to_dev(ptr);1466 rcu_read_lock();1467 event_upper = netdev_master_upper_dev_get_rcu(event_netdev);1468 rcu_read_unlock();1469 if (event_upper != lag->upper_netdev)1470 return true;1471 1472 dev = ice_pf_to_dev(lag->pf);1473 1474 /* only supporting switchdev mode for SRIOV VF LAG.1475 * primary interface has to be in switchdev mode1476 */1477 if (!ice_is_switchdev_running(lag->pf)) {1478 dev_info(dev, "Primary interface not in switchdev mode - VF LAG disabled\n");1479 return false;1480 }1481 1482 info = (struct netdev_notifier_bonding_info *)ptr;1483 bonding_info = &info->bonding_info;1484 lag->bond_mode = bonding_info->master.bond_mode;1485 if (lag->bond_mode != BOND_MODE_ACTIVEBACKUP) {1486 dev_info(dev, "Bond Mode not ACTIVE-BACKUP - VF LAG disabled\n");1487 return false;1488 }1489 1490 list_for_each(tmp, lag->netdev_head) {1491 struct ice_dcbx_cfg *dcb_cfg, *peer_dcb_cfg;1492 struct ice_lag_netdev_list *entry;1493 struct ice_netdev_priv *peer_np;1494 struct net_device *peer_netdev;1495 struct ice_vsi *vsi, *peer_vsi;1496 struct ice_pf *peer_pf;1497 1498 entry = list_entry(tmp, struct ice_lag_netdev_list, node);1499 peer_netdev = entry->netdev;1500 if (!netif_is_ice(peer_netdev)) {1501 dev_info(dev, "Found %s non-ice netdev in LAG - VF LAG disabled\n",1502 netdev_name(peer_netdev));1503 return false;1504 }1505 1506 count++;1507 if (count > 2) {1508 dev_info(dev, "Found more than two netdevs in LAG - VF LAG disabled\n");1509 return false;1510 }1511 1512 peer_np = netdev_priv(peer_netdev);1513 vsi = ice_get_main_vsi(lag->pf);1514 peer_vsi = peer_np->vsi;1515 if (lag->pf->pdev->bus != peer_vsi->back->pdev->bus ||1516 lag->pf->pdev->slot != peer_vsi->back->pdev->slot) {1517 dev_info(dev, "Found %s on different device in LAG - VF LAG disabled\n",1518 netdev_name(peer_netdev));1519 return false;1520 }1521 1522 dcb_cfg = &vsi->port_info->qos_cfg.local_dcbx_cfg;1523 peer_dcb_cfg = &peer_vsi->port_info->qos_cfg.local_dcbx_cfg;1524 if (memcmp(dcb_cfg, peer_dcb_cfg,1525 sizeof(struct ice_dcbx_cfg))) {1526 dev_info(dev, "Found %s with different DCB in LAG - VF LAG disabled\n",1527 netdev_name(peer_netdev));1528 return false;1529 }1530 1531 peer_pf = peer_vsi->back;1532 if (test_bit(ICE_FLAG_FW_LLDP_AGENT, peer_pf->flags)) {1533 dev_warn(dev, "Found %s with FW LLDP agent active - VF LAG disabled\n",1534 netdev_name(peer_netdev));1535 return false;1536 }1537 }1538 1539 return true;1540}1541 1542/**1543 * ice_lag_unregister - handle netdev unregister events1544 * @lag: LAG info struct1545 * @event_netdev: netdev struct for target of notifier event1546 */1547static void1548ice_lag_unregister(struct ice_lag *lag, struct net_device *event_netdev)1549{1550 struct ice_netdev_priv *np;1551 struct ice_pf *event_pf;1552 struct ice_lag *p_lag;1553 1554 p_lag = ice_lag_find_primary(lag);1555 np = netdev_priv(event_netdev);1556 event_pf = np->vsi->back;1557 1558 if (p_lag) {1559 if (p_lag->active_port != p_lag->pf->hw.port_info->lport &&1560 p_lag->active_port != ICE_LAG_INVALID_PORT) {1561 struct ice_hw *active_hw;1562 1563 active_hw = ice_lag_find_hw_by_lport(lag,1564 p_lag->active_port);1565 if (active_hw)1566 ice_lag_reclaim_vf_nodes(p_lag, active_hw);1567 lag->active_port = ICE_LAG_INVALID_PORT;1568 }1569 }1570 1571 /* primary processing for primary */1572 if (lag->primary && lag->netdev == event_netdev)1573 ice_lag_primary_swid(lag, false);1574 1575 /* primary processing for secondary */1576 if (lag->primary && lag->netdev != event_netdev)1577 ice_lag_del_prune_list(lag, event_pf);1578 1579 /* secondary processing for secondary */1580 if (!lag->primary && lag->netdev == event_netdev)1581 ice_lag_set_swid(0, lag, false);1582}1583 1584/**1585 * ice_lag_monitor_rdma - set and clear rdma functionality1586 * @lag: pointer to lag struct1587 * @ptr: opaque data for netdev event info1588 */1589static void1590ice_lag_monitor_rdma(struct ice_lag *lag, void *ptr)1591{1592 struct netdev_notifier_changeupper_info *info;1593 struct net_device *netdev;1594 1595 info = ptr;1596 netdev = netdev_notifier_info_to_dev(ptr);1597 1598 if (netdev != lag->netdev)1599 return;1600 1601 if (info->linking)1602 ice_clear_rdma_cap(lag->pf);1603 else1604 ice_set_rdma_cap(lag->pf);1605}1606 1607/**1608 * ice_lag_chk_disabled_bond - monitor interfaces entering/leaving disabled bond1609 * @lag: lag info struct1610 * @ptr: opaque data containing event1611 *1612 * as interfaces enter a bond - determine if the bond is currently1613 * SRIOV LAG compliant and flag if not. As interfaces leave the1614 * bond, reset their compliant status.1615 */1616static void ice_lag_chk_disabled_bond(struct ice_lag *lag, void *ptr)1617{1618 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);1619 struct netdev_notifier_changeupper_info *info = ptr;1620 struct ice_lag *prim_lag;1621 1622 if (netdev != lag->netdev)1623 return;1624 1625 if (info->linking) {1626 prim_lag = ice_lag_find_primary(lag);1627 if (prim_lag &&1628 !ice_is_feature_supported(prim_lag->pf, ICE_F_SRIOV_LAG)) {1629 ice_clear_feature_support(lag->pf, ICE_F_SRIOV_LAG);1630 netdev_info(netdev, "Interface added to non-compliant SRIOV LAG aggregate\n");1631 }1632 } else {1633 ice_lag_init_feature_support_flag(lag->pf);1634 }1635}1636 1637/**1638 * ice_lag_disable_sriov_bond - set members of bond as not supporting SRIOV LAG1639 * @lag: primary interfaces lag struct1640 */1641static void ice_lag_disable_sriov_bond(struct ice_lag *lag)1642{1643 struct ice_netdev_priv *np;1644 struct ice_pf *pf;1645 1646 np = netdev_priv(lag->netdev);1647 pf = np->vsi->back;1648 ice_clear_feature_support(pf, ICE_F_SRIOV_LAG);1649}1650 1651/**1652 * ice_lag_process_event - process a task assigned to the lag_wq1653 * @work: pointer to work_struct1654 */1655static void ice_lag_process_event(struct work_struct *work)1656{1657 struct netdev_notifier_changeupper_info *info;1658 struct ice_lag_work *lag_work;1659 struct net_device *netdev;1660 struct list_head *tmp, *n;1661 struct ice_pf *pf;1662 1663 lag_work = container_of(work, struct ice_lag_work, lag_task);1664 pf = lag_work->lag->pf;1665 1666 mutex_lock(&pf->lag_mutex);1667 lag_work->lag->netdev_head = &lag_work->netdev_list.node;1668 1669 switch (lag_work->event) {1670 case NETDEV_CHANGEUPPER:1671 info = &lag_work->info.changeupper_info;1672 ice_lag_chk_disabled_bond(lag_work->lag, info);1673 if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) {1674 ice_lag_monitor_link(lag_work->lag, info);1675 ice_lag_changeupper_event(lag_work->lag, info);1676 ice_lag_link_unlink(lag_work->lag, info);1677 }1678 ice_lag_monitor_rdma(lag_work->lag, info);1679 break;1680 case NETDEV_BONDING_INFO:1681 if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) {1682 if (!ice_lag_chk_comp(lag_work->lag,1683 &lag_work->info.bonding_info)) {1684 netdev = lag_work->info.bonding_info.info.dev;1685 ice_lag_disable_sriov_bond(lag_work->lag);1686 ice_lag_unregister(lag_work->lag, netdev);1687 goto lag_cleanup;1688 }1689 ice_lag_monitor_active(lag_work->lag,1690 &lag_work->info.bonding_info);1691 ice_lag_cfg_pf_fltrs(lag_work->lag,1692 &lag_work->info.bonding_info);1693 }1694 ice_lag_info_event(lag_work->lag, &lag_work->info.bonding_info);1695 break;1696 case NETDEV_UNREGISTER:1697 if (ice_is_feature_supported(pf, ICE_F_SRIOV_LAG)) {1698 netdev = lag_work->info.bonding_info.info.dev;1699 if ((netdev == lag_work->lag->netdev ||1700 lag_work->lag->primary) && lag_work->lag->bonded)1701 ice_lag_unregister(lag_work->lag, netdev);1702 }1703 break;1704 default:1705 break;1706 }1707 1708lag_cleanup:1709 /* cleanup resources allocated for this work item */1710 list_for_each_safe(tmp, n, &lag_work->netdev_list.node) {1711 struct ice_lag_netdev_list *entry;1712 1713 entry = list_entry(tmp, struct ice_lag_netdev_list, node);1714 list_del(&entry->node);1715 kfree(entry);1716 }1717 lag_work->lag->netdev_head = NULL;1718 1719 mutex_unlock(&pf->lag_mutex);1720 1721 kfree(lag_work);1722}1723 1724/**1725 * ice_lag_event_handler - handle LAG events from netdev1726 * @notif_blk: notifier block registered by this netdev1727 * @event: event type1728 * @ptr: opaque data containing notifier event1729 */1730static int1731ice_lag_event_handler(struct notifier_block *notif_blk, unsigned long event,1732 void *ptr)1733{1734 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);1735 struct net_device *upper_netdev;1736 struct ice_lag_work *lag_work;1737 struct ice_lag *lag;1738 1739 if (!netif_is_ice(netdev))1740 return NOTIFY_DONE;1741 1742 if (event != NETDEV_CHANGEUPPER && event != NETDEV_BONDING_INFO &&1743 event != NETDEV_UNREGISTER)1744 return NOTIFY_DONE;1745 1746 if (!(netdev->priv_flags & IFF_BONDING))1747 return NOTIFY_DONE;1748 1749 lag = container_of(notif_blk, struct ice_lag, notif_block);1750 if (!lag->netdev)1751 return NOTIFY_DONE;1752 1753 if (!net_eq(dev_net(netdev), &init_net))1754 return NOTIFY_DONE;1755 1756 /* This memory will be freed at the end of ice_lag_process_event */1757 lag_work = kzalloc(sizeof(*lag_work), GFP_KERNEL);1758 if (!lag_work)1759 return -ENOMEM;1760 1761 lag_work->event_netdev = netdev;1762 lag_work->lag = lag;1763 lag_work->event = event;1764 if (event == NETDEV_CHANGEUPPER) {1765 struct netdev_notifier_changeupper_info *info;1766 1767 info = ptr;1768 upper_netdev = info->upper_dev;1769 } else {1770 upper_netdev = netdev_master_upper_dev_get(netdev);1771 }1772 1773 INIT_LIST_HEAD(&lag_work->netdev_list.node);1774 if (upper_netdev) {1775 struct ice_lag_netdev_list *nd_list;1776 struct net_device *tmp_nd;1777 1778 rcu_read_lock();1779 for_each_netdev_in_bond_rcu(upper_netdev, tmp_nd) {1780 nd_list = kzalloc(sizeof(*nd_list), GFP_ATOMIC);1781 if (!nd_list)1782 break;1783 1784 nd_list->netdev = tmp_nd;1785 list_add(&nd_list->node, &lag_work->netdev_list.node);1786 }1787 rcu_read_unlock();1788 }1789 1790 switch (event) {1791 case NETDEV_CHANGEUPPER:1792 lag_work->info.changeupper_info =1793 *((struct netdev_notifier_changeupper_info *)ptr);1794 break;1795 case NETDEV_BONDING_INFO:1796 lag_work->info.bonding_info =1797 *((struct netdev_notifier_bonding_info *)ptr);1798 break;1799 default:1800 lag_work->info.notifier_info =1801 *((struct netdev_notifier_info *)ptr);1802 break;1803 }1804 1805 INIT_WORK(&lag_work->lag_task, ice_lag_process_event);1806 queue_work(ice_lag_wq, &lag_work->lag_task);1807 1808 return NOTIFY_DONE;1809}1810 1811/**1812 * ice_register_lag_handler - register LAG handler on netdev1813 * @lag: LAG struct1814 */1815static int ice_register_lag_handler(struct ice_lag *lag)1816{1817 struct device *dev = ice_pf_to_dev(lag->pf);1818 struct notifier_block *notif_blk;1819 1820 notif_blk = &lag->notif_block;1821 1822 if (!notif_blk->notifier_call) {1823 notif_blk->notifier_call = ice_lag_event_handler;1824 if (register_netdevice_notifier(notif_blk)) {1825 notif_blk->notifier_call = NULL;1826 dev_err(dev, "FAIL register LAG event handler!\n");1827 return -EINVAL;1828 }1829 dev_dbg(dev, "LAG event handler registered\n");1830 }1831 return 0;1832}1833 1834/**1835 * ice_unregister_lag_handler - unregister LAG handler on netdev1836 * @lag: LAG struct1837 */1838static void ice_unregister_lag_handler(struct ice_lag *lag)1839{1840 struct device *dev = ice_pf_to_dev(lag->pf);1841 struct notifier_block *notif_blk;1842 1843 notif_blk = &lag->notif_block;1844 if (notif_blk->notifier_call) {1845 unregister_netdevice_notifier(notif_blk);1846 dev_dbg(dev, "LAG event handler unregistered\n");1847 }1848}1849 1850/**1851 * ice_create_lag_recipe1852 * @hw: pointer to HW struct1853 * @rid: pointer to u16 to pass back recipe index1854 * @base_recipe: recipe to base the new recipe on1855 * @prio: priority for new recipe1856 *1857 * function returns 0 on error1858 */1859static int ice_create_lag_recipe(struct ice_hw *hw, u16 *rid,1860 const u8 *base_recipe, u8 prio)1861{1862 struct ice_aqc_recipe_data_elem *new_rcp;1863 int err;1864 1865 err = ice_alloc_recipe(hw, rid);1866 if (err)1867 return err;1868 1869 new_rcp = kzalloc(ICE_RECIPE_LEN * ICE_MAX_NUM_RECIPES, GFP_KERNEL);1870 if (!new_rcp)1871 return -ENOMEM;1872 1873 memcpy(new_rcp, base_recipe, ICE_RECIPE_LEN);1874 new_rcp->content.act_ctrl_fwd_priority = prio;1875 new_rcp->content.rid = *rid | ICE_AQ_RECIPE_ID_IS_ROOT;1876 new_rcp->recipe_indx = *rid;1877 bitmap_zero((unsigned long *)new_rcp->recipe_bitmap,1878 ICE_MAX_NUM_RECIPES);1879 set_bit(*rid, (unsigned long *)new_rcp->recipe_bitmap);1880 1881 err = ice_aq_add_recipe(hw, new_rcp, 1, NULL);1882 if (err)1883 *rid = 0;1884 1885 kfree(new_rcp);1886 return err;1887}1888 1889/**1890 * ice_lag_move_vf_nodes_tc_sync - move a VF's nodes for a tc during reset1891 * @lag: primary interfaces lag struct1892 * @dest_hw: HW struct for destination's interface1893 * @vsi_num: VSI index in PF space1894 * @tc: traffic class to move1895 */1896static void1897ice_lag_move_vf_nodes_tc_sync(struct ice_lag *lag, struct ice_hw *dest_hw,1898 u16 vsi_num, u8 tc)1899{1900 DEFINE_RAW_FLEX(struct ice_aqc_move_elem, buf, teid, 1);1901 struct device *dev = ice_pf_to_dev(lag->pf);1902 u16 numq, valq, num_moved, qbuf_size;1903 u16 buf_size = __struct_size(buf);1904 struct ice_aqc_cfg_txqs_buf *qbuf;1905 struct ice_sched_node *n_prt;1906 __le32 teid, parent_teid;1907 struct ice_vsi_ctx *ctx;1908 struct ice_hw *hw;1909 u32 tmp_teid;1910 1911 hw = &lag->pf->hw;1912 ctx = ice_get_vsi_ctx(hw, vsi_num);1913 if (!ctx) {1914 dev_warn(dev, "LAG rebuild failed after reset due to VSI Context failure\n");1915 return;1916 }1917 1918 if (!ctx->sched.vsi_node[tc])1919 return;1920 1921 numq = ctx->num_lan_q_entries[tc];1922 teid = ctx->sched.vsi_node[tc]->info.node_teid;1923 tmp_teid = le32_to_cpu(teid);1924 parent_teid = ctx->sched.vsi_node[tc]->info.parent_teid;1925 1926 if (!tmp_teid || !numq)1927 return;1928 1929 if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, true))1930 dev_dbg(dev, "Problem suspending traffic during reset rebuild\n");1931 1932 /* reconfig queues for new port */1933 qbuf_size = struct_size(qbuf, queue_info, numq);1934 qbuf = kzalloc(qbuf_size, GFP_KERNEL);1935 if (!qbuf) {1936 dev_warn(dev, "Failure allocating VF queue recfg buffer for reset rebuild\n");1937 goto resume_sync;1938 }1939 1940 /* add the per queue info for the reconfigure command buffer */1941 valq = ice_lag_qbuf_recfg(hw, qbuf, vsi_num, numq, tc);1942 if (!valq) {1943 dev_warn(dev, "Failure to reconfig queues for LAG reset rebuild\n");1944 goto sync_none;1945 }1946 1947 if (ice_aq_cfg_lan_txq(hw, qbuf, qbuf_size, numq, hw->port_info->lport,1948 dest_hw->port_info->lport, NULL)) {1949 dev_warn(dev, "Failure to configure queues for LAG reset rebuild\n");1950 goto sync_qerr;1951 }1952 1953sync_none:1954 kfree(qbuf);1955 1956 /* find parent in destination tree */1957 n_prt = ice_lag_get_sched_parent(dest_hw, tc);1958 if (!n_prt)1959 goto resume_sync;1960 1961 /* Move node to new parent */1962 buf->hdr.src_parent_teid = parent_teid;1963 buf->hdr.dest_parent_teid = n_prt->info.node_teid;1964 buf->hdr.num_elems = cpu_to_le16(1);1965 buf->hdr.mode = ICE_AQC_MOVE_ELEM_MODE_KEEP_OWN;1966 buf->teid[0] = teid;1967 1968 if (ice_aq_move_sched_elems(&lag->pf->hw, buf, buf_size, &num_moved))1969 dev_warn(dev, "Failure to move VF nodes for LAG reset rebuild\n");1970 else1971 ice_sched_update_parent(n_prt, ctx->sched.vsi_node[tc]);1972 1973 goto resume_sync;1974 1975sync_qerr:1976 kfree(qbuf);1977 1978resume_sync:1979 if (ice_sched_suspend_resume_elems(hw, 1, &tmp_teid, false))1980 dev_warn(dev, "Problem restarting traffic for LAG node reset rebuild\n");1981}1982 1983/**1984 * ice_lag_move_vf_nodes_sync - move vf nodes to active interface1985 * @lag: primary interfaces lag struct1986 * @dest_hw: lport value for currently active port1987 *1988 * This function is used in a reset context, outside of event handling,1989 * to move the VF nodes to the secondary interface when that interface1990 * is the active interface during a reset rebuild1991 */1992static void1993ice_lag_move_vf_nodes_sync(struct ice_lag *lag, struct ice_hw *dest_hw)1994{1995 struct ice_pf *pf;1996 int i, tc;1997 1998 if (!lag->primary || !dest_hw)1999 return;2000 2001 pf = lag->pf;2002 ice_for_each_vsi(pf, i)2003 if (pf->vsi[i] && pf->vsi[i]->type == ICE_VSI_VF)2004 ice_for_each_traffic_class(tc)2005 ice_lag_move_vf_nodes_tc_sync(lag, dest_hw, i,2006 tc);2007}2008 2009/**2010 * ice_init_lag - initialize support for LAG2011 * @pf: PF struct2012 *2013 * Alloc memory for LAG structs and initialize the elements.2014 * Memory will be freed in ice_deinit_lag2015 */2016int ice_init_lag(struct ice_pf *pf)2017{2018 struct device *dev = ice_pf_to_dev(pf);2019 struct ice_lag *lag;2020 struct ice_vsi *vsi;2021 u64 recipe_bits = 0;2022 int n, err;2023 2024 ice_lag_init_feature_support_flag(pf);2025 if (!ice_is_feature_supported(pf, ICE_F_SRIOV_LAG))2026 return 0;2027 2028 pf->lag = kzalloc(sizeof(*lag), GFP_KERNEL);2029 if (!pf->lag)2030 return -ENOMEM;2031 lag = pf->lag;2032 2033 vsi = ice_get_main_vsi(pf);2034 if (!vsi) {2035 dev_err(dev, "couldn't get main vsi, link aggregation init fail\n");2036 err = -EIO;2037 goto lag_error;2038 }2039 2040 lag->pf = pf;2041 lag->netdev = vsi->netdev;2042 lag->role = ICE_LAG_NONE;2043 lag->active_port = ICE_LAG_INVALID_PORT;2044 lag->bonded = false;2045 lag->upper_netdev = NULL;2046 lag->notif_block.notifier_call = NULL;2047 2048 err = ice_register_lag_handler(lag);2049 if (err) {2050 dev_warn(dev, "INIT LAG: Failed to register event handler\n");2051 goto lag_error;2052 }2053 2054 err = ice_create_lag_recipe(&pf->hw, &lag->pf_recipe,2055 ice_dflt_vsi_rcp, 1);2056 if (err)2057 goto lag_error;2058 2059 err = ice_create_lag_recipe(&pf->hw, &lag->lport_recipe,2060 ice_lport_rcp, 3);2061 if (err)2062 goto free_rcp_res;2063 2064 /* associate recipes to profiles */2065 for (n = 0; n < ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER; n++) {2066 err = ice_aq_get_recipe_to_profile(&pf->hw, n,2067 &recipe_bits, NULL);2068 if (err)2069 continue;2070 2071 if (recipe_bits & BIT(ICE_SW_LKUP_DFLT)) {2072 recipe_bits |= BIT(lag->pf_recipe) |2073 BIT(lag->lport_recipe);2074 ice_aq_map_recipe_to_profile(&pf->hw, n,2075 recipe_bits, NULL);2076 }2077 }2078 2079 ice_display_lag_info(lag);2080 2081 dev_dbg(dev, "INIT LAG complete\n");2082 return 0;2083 2084free_rcp_res:2085 ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,2086 &pf->lag->pf_recipe);2087lag_error:2088 kfree(lag);2089 pf->lag = NULL;2090 return err;2091}2092 2093/**2094 * ice_deinit_lag - Clean up LAG2095 * @pf: PF struct2096 *2097 * Clean up kernel LAG info and free memory2098 * This function is meant to only be called on driver remove/shutdown2099 */2100void ice_deinit_lag(struct ice_pf *pf)2101{2102 struct ice_lag *lag;2103 2104 lag = pf->lag;2105 2106 if (!lag)2107 return;2108 2109 if (lag->pf)2110 ice_unregister_lag_handler(lag);2111 2112 flush_workqueue(ice_lag_wq);2113 2114 ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,2115 &pf->lag->pf_recipe);2116 ice_free_hw_res(&pf->hw, ICE_AQC_RES_TYPE_RECIPE, 1,2117 &pf->lag->lport_recipe);2118 2119 kfree(lag);2120 2121 pf->lag = NULL;2122}2123 2124/**2125 * ice_lag_rebuild - rebuild lag resources after reset2126 * @pf: pointer to local pf struct2127 *2128 * PF resets are promoted to CORER resets when interface in an aggregate. This2129 * means that we need to rebuild the PF resources for the interface. Since2130 * this will happen outside the normal event processing, need to acquire the lag2131 * lock.2132 *2133 * This function will also evaluate the VF resources if this is the primary2134 * interface.2135 */2136void ice_lag_rebuild(struct ice_pf *pf)2137{2138 struct ice_lag_netdev_list ndlist;2139 struct ice_lag *lag, *prim_lag;2140 u8 act_port, loc_port;2141 2142 if (!pf->lag || !pf->lag->bonded)2143 return;2144 2145 mutex_lock(&pf->lag_mutex);2146 2147 lag = pf->lag;2148 if (lag->primary) {2149 prim_lag = lag;2150 } else {2151 ice_lag_build_netdev_list(lag, &ndlist);2152 prim_lag = ice_lag_find_primary(lag);2153 }2154 2155 if (!prim_lag) {2156 dev_dbg(ice_pf_to_dev(pf), "No primary interface in aggregate, can't rebuild\n");2157 goto lag_rebuild_out;2158 }2159 2160 act_port = prim_lag->active_port;2161 loc_port = lag->pf->hw.port_info->lport;2162 2163 /* configure SWID for this port */2164 if (lag->primary) {2165 ice_lag_primary_swid(lag, true);2166 } else {2167 ice_lag_set_swid(prim_lag->pf->hw.port_info->sw_id, lag, true);2168 ice_lag_add_prune_list(prim_lag, pf);2169 if (act_port == loc_port)2170 ice_lag_move_vf_nodes_sync(prim_lag, &pf->hw);2171 }2172 2173 ice_lag_cfg_cp_fltr(lag, true);2174 2175 if (lag->pf_rx_rule_id)2176 if (ice_lag_cfg_dflt_fltr(lag, true))2177 dev_err(ice_pf_to_dev(pf), "Error adding default VSI rule in rebuild\n");2178 2179 ice_clear_rdma_cap(pf);2180lag_rebuild_out:2181 ice_lag_destroy_netdev_list(lag, &ndlist);2182 mutex_unlock(&pf->lag_mutex);2183}2184 2185/**2186 * ice_lag_is_switchdev_running2187 * @pf: pointer to PF structure2188 *2189 * Check if switchdev is running on any of the interfaces connected to lag.2190 */2191bool ice_lag_is_switchdev_running(struct ice_pf *pf)2192{2193 struct ice_lag *lag = pf->lag;2194 struct net_device *tmp_nd;2195 2196 if (!ice_is_feature_supported(pf, ICE_F_SRIOV_LAG) || !lag)2197 return false;2198 2199 rcu_read_lock();2200 for_each_netdev_in_bond_rcu(lag->upper_netdev, tmp_nd) {2201 struct ice_netdev_priv *priv = netdev_priv(tmp_nd);2202 2203 if (!netif_is_ice(tmp_nd) || !priv || !priv->vsi ||2204 !priv->vsi->back)2205 continue;2206 2207 if (ice_is_switchdev_running(priv->vsi->back)) {2208 rcu_read_unlock();2209 return true;2210 }2211 }2212 rcu_read_unlock();2213 2214 return false;2215}2216