633 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (C) 2019-2021, Intel Corporation. */3 4#include "ice.h"5#include "ice_lib.h"6#include "ice_eswitch.h"7#include "ice_eswitch_br.h"8#include "ice_fltr.h"9#include "ice_repr.h"10#include "devlink/devlink.h"11#include "ice_tc_lib.h"12 13/**14 * ice_eswitch_setup_env - configure eswitch HW filters15 * @pf: pointer to PF struct16 *17 * This function adds HW filters configuration specific for switchdev18 * mode.19 */20static int ice_eswitch_setup_env(struct ice_pf *pf)21{22 struct ice_vsi *uplink_vsi = pf->eswitch.uplink_vsi;23 struct net_device *netdev = uplink_vsi->netdev;24 bool if_running = netif_running(netdev);25 struct ice_vsi_vlan_ops *vlan_ops;26 27 if (if_running && !test_and_set_bit(ICE_VSI_DOWN, uplink_vsi->state))28 if (ice_down(uplink_vsi))29 return -ENODEV;30 31 ice_remove_vsi_fltr(&pf->hw, uplink_vsi->idx);32 33 netif_addr_lock_bh(netdev);34 __dev_uc_unsync(netdev, NULL);35 __dev_mc_unsync(netdev, NULL);36 netif_addr_unlock_bh(netdev);37 38 if (ice_vsi_add_vlan_zero(uplink_vsi))39 goto err_vlan_zero;40 41 if (ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, true,42 ICE_FLTR_RX))43 goto err_def_rx;44 45 if (ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, true,46 ICE_FLTR_TX))47 goto err_def_tx;48 49 vlan_ops = ice_get_compat_vsi_vlan_ops(uplink_vsi);50 if (vlan_ops->dis_rx_filtering(uplink_vsi))51 goto err_vlan_filtering;52 53 if (ice_vsi_update_security(uplink_vsi, ice_vsi_ctx_set_allow_override))54 goto err_override_uplink;55 56 if (ice_vsi_update_local_lb(uplink_vsi, true))57 goto err_override_local_lb;58 59 if (if_running && ice_up(uplink_vsi))60 goto err_up;61 62 return 0;63 64err_up:65 ice_vsi_update_local_lb(uplink_vsi, false);66err_override_local_lb:67 ice_vsi_update_security(uplink_vsi, ice_vsi_ctx_clear_allow_override);68err_override_uplink:69 vlan_ops->ena_rx_filtering(uplink_vsi);70err_vlan_filtering:71 ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,72 ICE_FLTR_TX);73err_def_tx:74 ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,75 ICE_FLTR_RX);76err_def_rx:77 ice_vsi_del_vlan_zero(uplink_vsi);78err_vlan_zero:79 ice_fltr_add_mac_and_broadcast(uplink_vsi,80 uplink_vsi->port_info->mac.perm_addr,81 ICE_FWD_TO_VSI);82 if (if_running)83 ice_up(uplink_vsi);84 85 return -ENODEV;86}87 88/**89 * ice_eswitch_release_repr - clear PR VSI configuration90 * @pf: poiner to PF struct91 * @repr: pointer to PR92 */93static void94ice_eswitch_release_repr(struct ice_pf *pf, struct ice_repr *repr)95{96 struct ice_vsi *vsi = repr->src_vsi;97 98 /* Skip representors that aren't configured */99 if (!repr->dst)100 return;101 102 ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);103 metadata_dst_free(repr->dst);104 repr->dst = NULL;105 ice_fltr_add_mac_and_broadcast(vsi, repr->parent_mac,106 ICE_FWD_TO_VSI);107}108 109/**110 * ice_eswitch_setup_repr - configure PR to run in switchdev mode111 * @pf: pointer to PF struct112 * @repr: pointer to PR struct113 */114static int ice_eswitch_setup_repr(struct ice_pf *pf, struct ice_repr *repr)115{116 struct ice_vsi *uplink_vsi = pf->eswitch.uplink_vsi;117 struct ice_vsi *vsi = repr->src_vsi;118 struct metadata_dst *dst;119 120 repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX,121 GFP_KERNEL);122 if (!repr->dst)123 return -ENOMEM;124 125 netif_keep_dst(uplink_vsi->netdev);126 127 dst = repr->dst;128 dst->u.port_info.port_id = vsi->vsi_num;129 dst->u.port_info.lower_dev = uplink_vsi->netdev;130 131 return 0;132}133 134/**135 * ice_eswitch_cfg_vsi - configure VSI to work in slow-path136 * @vsi: VSI structure of representee137 * @mac: representee MAC138 *139 * Return: 0 on success, non-zero on error.140 */141int ice_eswitch_cfg_vsi(struct ice_vsi *vsi, const u8 *mac)142{143 int err;144 145 ice_remove_vsi_fltr(&vsi->back->hw, vsi->idx);146 147 err = ice_vsi_update_security(vsi, ice_vsi_ctx_clear_antispoof);148 if (err)149 goto err_update_security;150 151 err = ice_vsi_add_vlan_zero(vsi);152 if (err)153 goto err_vlan_zero;154 155 return 0;156 157err_vlan_zero:158 ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);159err_update_security:160 ice_fltr_add_mac_and_broadcast(vsi, mac, ICE_FWD_TO_VSI);161 162 return err;163}164 165/**166 * ice_eswitch_decfg_vsi - unroll changes done to VSI for switchdev167 * @vsi: VSI structure of representee168 * @mac: representee MAC169 */170void ice_eswitch_decfg_vsi(struct ice_vsi *vsi, const u8 *mac)171{172 ice_vsi_update_security(vsi, ice_vsi_ctx_set_antispoof);173 ice_fltr_add_mac_and_broadcast(vsi, mac, ICE_FWD_TO_VSI);174}175 176/**177 * ice_eswitch_update_repr - reconfigure port representor178 * @repr_id: representor ID179 * @vsi: VSI for which port representor is configured180 */181void ice_eswitch_update_repr(unsigned long *repr_id, struct ice_vsi *vsi)182{183 struct ice_pf *pf = vsi->back;184 struct ice_repr *repr;185 int err;186 187 if (!ice_is_switchdev_running(pf))188 return;189 190 repr = xa_load(&pf->eswitch.reprs, *repr_id);191 if (!repr)192 return;193 194 repr->src_vsi = vsi;195 repr->dst->u.port_info.port_id = vsi->vsi_num;196 197 if (repr->br_port)198 repr->br_port->vsi = vsi;199 200 err = ice_eswitch_cfg_vsi(vsi, repr->parent_mac);201 if (err)202 dev_err(ice_pf_to_dev(pf), "Failed to update VSI of port representor %d",203 repr->id);204 205 /* The VSI number is different, reload the PR with new id */206 if (repr->id != vsi->vsi_num) {207 xa_erase(&pf->eswitch.reprs, repr->id);208 repr->id = vsi->vsi_num;209 if (xa_insert(&pf->eswitch.reprs, repr->id, repr, GFP_KERNEL))210 dev_err(ice_pf_to_dev(pf), "Failed to reload port representor %d",211 repr->id);212 *repr_id = repr->id;213 }214}215 216/**217 * ice_eswitch_port_start_xmit - callback for packets transmit218 * @skb: send buffer219 * @netdev: network interface device structure220 *221 * Returns NETDEV_TX_OK if sent, else an error code222 */223netdev_tx_t224ice_eswitch_port_start_xmit(struct sk_buff *skb, struct net_device *netdev)225{226 struct ice_repr *repr = ice_netdev_to_repr(netdev);227 unsigned int len = skb->len;228 int ret;229 230 skb_dst_drop(skb);231 dst_hold((struct dst_entry *)repr->dst);232 skb_dst_set(skb, (struct dst_entry *)repr->dst);233 skb->dev = repr->dst->u.port_info.lower_dev;234 235 ret = dev_queue_xmit(skb);236 ice_repr_inc_tx_stats(repr, len, ret);237 238 return ret;239}240 241/**242 * ice_eswitch_set_target_vsi - set eswitch context in Tx context descriptor243 * @skb: pointer to send buffer244 * @off: pointer to offload struct245 */246void247ice_eswitch_set_target_vsi(struct sk_buff *skb,248 struct ice_tx_offload_params *off)249{250 struct metadata_dst *dst = skb_metadata_dst(skb);251 u64 cd_cmd, dst_vsi;252 253 if (!dst) {254 cd_cmd = ICE_TX_CTX_DESC_SWTCH_UPLINK << ICE_TXD_CTX_QW1_CMD_S;255 off->cd_qw1 |= (cd_cmd | ICE_TX_DESC_DTYPE_CTX);256 } else {257 cd_cmd = ICE_TX_CTX_DESC_SWTCH_VSI << ICE_TXD_CTX_QW1_CMD_S;258 dst_vsi = FIELD_PREP(ICE_TXD_CTX_QW1_VSI_M,259 dst->u.port_info.port_id);260 off->cd_qw1 = cd_cmd | dst_vsi | ICE_TX_DESC_DTYPE_CTX;261 }262}263 264/**265 * ice_eswitch_release_env - clear eswitch HW filters266 * @pf: pointer to PF struct267 *268 * This function removes HW filters configuration specific for switchdev269 * mode and restores default legacy mode settings.270 */271static void ice_eswitch_release_env(struct ice_pf *pf)272{273 struct ice_vsi *uplink_vsi = pf->eswitch.uplink_vsi;274 struct ice_vsi_vlan_ops *vlan_ops;275 276 vlan_ops = ice_get_compat_vsi_vlan_ops(uplink_vsi);277 278 ice_vsi_update_local_lb(uplink_vsi, false);279 ice_vsi_update_security(uplink_vsi, ice_vsi_ctx_clear_allow_override);280 vlan_ops->ena_rx_filtering(uplink_vsi);281 ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,282 ICE_FLTR_TX);283 ice_cfg_dflt_vsi(uplink_vsi->port_info, uplink_vsi->idx, false,284 ICE_FLTR_RX);285 ice_fltr_add_mac_and_broadcast(uplink_vsi,286 uplink_vsi->port_info->mac.perm_addr,287 ICE_FWD_TO_VSI);288}289 290/**291 * ice_eswitch_enable_switchdev - configure eswitch in switchdev mode292 * @pf: pointer to PF structure293 */294static int ice_eswitch_enable_switchdev(struct ice_pf *pf)295{296 struct ice_vsi *uplink_vsi;297 298 uplink_vsi = ice_get_main_vsi(pf);299 if (!uplink_vsi)300 return -ENODEV;301 302 if (netif_is_any_bridge_port(uplink_vsi->netdev)) {303 dev_err(ice_pf_to_dev(pf),304 "Uplink port cannot be a bridge port\n");305 return -EINVAL;306 }307 308 pf->eswitch.uplink_vsi = uplink_vsi;309 310 if (ice_eswitch_setup_env(pf))311 return -ENODEV;312 313 if (ice_eswitch_br_offloads_init(pf))314 goto err_br_offloads;315 316 pf->eswitch.is_running = true;317 318 return 0;319 320err_br_offloads:321 ice_eswitch_release_env(pf);322 return -ENODEV;323}324 325/**326 * ice_eswitch_disable_switchdev - disable eswitch resources327 * @pf: pointer to PF structure328 */329static void ice_eswitch_disable_switchdev(struct ice_pf *pf)330{331 ice_eswitch_br_offloads_deinit(pf);332 ice_eswitch_release_env(pf);333 334 pf->eswitch.is_running = false;335}336 337/**338 * ice_eswitch_mode_set - set new eswitch mode339 * @devlink: pointer to devlink structure340 * @mode: eswitch mode to switch to341 * @extack: pointer to extack structure342 */343int344ice_eswitch_mode_set(struct devlink *devlink, u16 mode,345 struct netlink_ext_ack *extack)346{347 struct ice_pf *pf = devlink_priv(devlink);348 349 if (pf->eswitch_mode == mode)350 return 0;351 352 if (ice_has_vfs(pf)) {353 dev_info(ice_pf_to_dev(pf), "Changing eswitch mode is allowed only if there is no VFs created");354 NL_SET_ERR_MSG_MOD(extack, "Changing eswitch mode is allowed only if there is no VFs created");355 return -EOPNOTSUPP;356 }357 358 switch (mode) {359 case DEVLINK_ESWITCH_MODE_LEGACY:360 dev_info(ice_pf_to_dev(pf), "PF %d changed eswitch mode to legacy",361 pf->hw.pf_id);362 xa_destroy(&pf->eswitch.reprs);363 NL_SET_ERR_MSG_MOD(extack, "Changed eswitch mode to legacy");364 break;365 case DEVLINK_ESWITCH_MODE_SWITCHDEV:366 {367 if (ice_is_adq_active(pf)) {368 dev_err(ice_pf_to_dev(pf), "Couldn't change eswitch mode to switchdev - ADQ is active. Delete ADQ configs and try again, e.g. tc qdisc del dev $PF root");369 NL_SET_ERR_MSG_MOD(extack, "Couldn't change eswitch mode to switchdev - ADQ is active. Delete ADQ configs and try again, e.g. tc qdisc del dev $PF root");370 return -EOPNOTSUPP;371 }372 373 dev_info(ice_pf_to_dev(pf), "PF %d changed eswitch mode to switchdev",374 pf->hw.pf_id);375 xa_init(&pf->eswitch.reprs);376 NL_SET_ERR_MSG_MOD(extack, "Changed eswitch mode to switchdev");377 break;378 }379 default:380 NL_SET_ERR_MSG_MOD(extack, "Unknown eswitch mode");381 return -EINVAL;382 }383 384 pf->eswitch_mode = mode;385 return 0;386}387 388/**389 * ice_eswitch_mode_get - get current eswitch mode390 * @devlink: pointer to devlink structure391 * @mode: output parameter for current eswitch mode392 */393int ice_eswitch_mode_get(struct devlink *devlink, u16 *mode)394{395 struct ice_pf *pf = devlink_priv(devlink);396 397 *mode = pf->eswitch_mode;398 return 0;399}400 401/**402 * ice_is_eswitch_mode_switchdev - check if eswitch mode is set to switchdev403 * @pf: pointer to PF structure404 *405 * Returns true if eswitch mode is set to DEVLINK_ESWITCH_MODE_SWITCHDEV,406 * false otherwise.407 */408bool ice_is_eswitch_mode_switchdev(struct ice_pf *pf)409{410 return pf->eswitch_mode == DEVLINK_ESWITCH_MODE_SWITCHDEV;411}412 413/**414 * ice_eswitch_start_all_tx_queues - start Tx queues of all port representors415 * @pf: pointer to PF structure416 */417static void ice_eswitch_start_all_tx_queues(struct ice_pf *pf)418{419 struct ice_repr *repr;420 unsigned long id;421 422 if (test_bit(ICE_DOWN, pf->state))423 return;424 425 xa_for_each(&pf->eswitch.reprs, id, repr)426 ice_repr_start_tx_queues(repr);427}428 429/**430 * ice_eswitch_stop_all_tx_queues - stop Tx queues of all port representors431 * @pf: pointer to PF structure432 */433void ice_eswitch_stop_all_tx_queues(struct ice_pf *pf)434{435 struct ice_repr *repr;436 unsigned long id;437 438 if (test_bit(ICE_DOWN, pf->state))439 return;440 441 xa_for_each(&pf->eswitch.reprs, id, repr)442 ice_repr_stop_tx_queues(repr);443}444 445static void ice_eswitch_stop_reprs(struct ice_pf *pf)446{447 ice_eswitch_stop_all_tx_queues(pf);448}449 450static void ice_eswitch_start_reprs(struct ice_pf *pf)451{452 ice_eswitch_start_all_tx_queues(pf);453}454 455static int456ice_eswitch_attach(struct ice_pf *pf, struct ice_repr *repr, unsigned long *id)457{458 int err;459 460 if (pf->eswitch_mode == DEVLINK_ESWITCH_MODE_LEGACY)461 return 0;462 463 if (xa_empty(&pf->eswitch.reprs)) {464 err = ice_eswitch_enable_switchdev(pf);465 if (err)466 return err;467 }468 469 ice_eswitch_stop_reprs(pf);470 471 err = repr->ops.add(repr);472 if (err)473 goto err_create_repr;474 475 err = ice_eswitch_setup_repr(pf, repr);476 if (err)477 goto err_setup_repr;478 479 err = xa_insert(&pf->eswitch.reprs, repr->id, repr, GFP_KERNEL);480 if (err)481 goto err_xa_alloc;482 483 *id = repr->id;484 485 ice_eswitch_start_reprs(pf);486 487 return 0;488 489err_xa_alloc:490 ice_eswitch_release_repr(pf, repr);491err_setup_repr:492 repr->ops.rem(repr);493err_create_repr:494 if (xa_empty(&pf->eswitch.reprs))495 ice_eswitch_disable_switchdev(pf);496 ice_eswitch_start_reprs(pf);497 498 return err;499}500 501/**502 * ice_eswitch_attach_vf - attach VF to a eswitch503 * @pf: pointer to PF structure504 * @vf: pointer to VF structure to be attached505 *506 * During attaching port representor for VF is created.507 *508 * Return: zero on success or an error code on failure.509 */510int ice_eswitch_attach_vf(struct ice_pf *pf, struct ice_vf *vf)511{512 struct ice_repr *repr = ice_repr_create_vf(vf);513 struct devlink *devlink = priv_to_devlink(pf);514 int err;515 516 if (IS_ERR(repr))517 return PTR_ERR(repr);518 519 devl_lock(devlink);520 err = ice_eswitch_attach(pf, repr, &vf->repr_id);521 if (err)522 ice_repr_destroy(repr);523 devl_unlock(devlink);524 525 return err;526}527 528/**529 * ice_eswitch_attach_sf - attach SF to a eswitch530 * @pf: pointer to PF structure531 * @sf: pointer to SF structure to be attached532 *533 * During attaching port representor for SF is created.534 *535 * Return: zero on success or an error code on failure.536 */537int ice_eswitch_attach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf)538{539 struct ice_repr *repr = ice_repr_create_sf(sf);540 int err;541 542 if (IS_ERR(repr))543 return PTR_ERR(repr);544 545 err = ice_eswitch_attach(pf, repr, &sf->repr_id);546 if (err)547 ice_repr_destroy(repr);548 549 return err;550}551 552static void ice_eswitch_detach(struct ice_pf *pf, struct ice_repr *repr)553{554 ice_eswitch_stop_reprs(pf);555 repr->ops.rem(repr);556 557 xa_erase(&pf->eswitch.reprs, repr->id);558 559 if (xa_empty(&pf->eswitch.reprs))560 ice_eswitch_disable_switchdev(pf);561 562 ice_eswitch_release_repr(pf, repr);563 ice_repr_destroy(repr);564 565 if (xa_empty(&pf->eswitch.reprs)) {566 struct devlink *devlink = priv_to_devlink(pf);567 568 /* since all port representors are destroyed, there is569 * no point in keeping the nodes570 */571 ice_devlink_rate_clear_tx_topology(ice_get_main_vsi(pf));572 devl_rate_nodes_destroy(devlink);573 } else {574 ice_eswitch_start_reprs(pf);575 }576}577 578/**579 * ice_eswitch_detach_vf - detach VF from a eswitch580 * @pf: pointer to PF structure581 * @vf: pointer to VF structure to be detached582 */583void ice_eswitch_detach_vf(struct ice_pf *pf, struct ice_vf *vf)584{585 struct ice_repr *repr = xa_load(&pf->eswitch.reprs, vf->repr_id);586 struct devlink *devlink = priv_to_devlink(pf);587 588 if (!repr)589 return;590 591 devl_lock(devlink);592 ice_eswitch_detach(pf, repr);593 devl_unlock(devlink);594}595 596/**597 * ice_eswitch_detach_sf - detach SF from a eswitch598 * @pf: pointer to PF structure599 * @sf: pointer to SF structure to be detached600 */601void ice_eswitch_detach_sf(struct ice_pf *pf, struct ice_dynamic_port *sf)602{603 struct ice_repr *repr = xa_load(&pf->eswitch.reprs, sf->repr_id);604 605 if (!repr)606 return;607 608 ice_eswitch_detach(pf, repr);609}610 611/**612 * ice_eswitch_get_target - get netdev based on src_vsi from descriptor613 * @rx_ring: ring used to receive the packet614 * @rx_desc: descriptor used to get src_vsi value615 *616 * Get src_vsi value from descriptor and load correct representor. If it isn't617 * found return rx_ring->netdev.618 */619struct net_device *ice_eswitch_get_target(struct ice_rx_ring *rx_ring,620 union ice_32b_rx_flex_desc *rx_desc)621{622 struct ice_eswitch *eswitch = &rx_ring->vsi->back->eswitch;623 struct ice_32b_rx_flex_desc_nic_2 *desc;624 struct ice_repr *repr;625 626 desc = (struct ice_32b_rx_flex_desc_nic_2 *)rx_desc;627 repr = xa_load(&eswitch->reprs, le16_to_cpu(desc->src_vsi));628 if (!repr)629 return rx_ring->netdev;630 631 return repr->netdev;632}633