162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (C) 2019-2021, Intel Corporation. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "ice.h" 562306a36Sopenharmony_ci#include "ice_eswitch.h" 662306a36Sopenharmony_ci#include "ice_devlink.h" 762306a36Sopenharmony_ci#include "ice_sriov.h" 862306a36Sopenharmony_ci#include "ice_tc_lib.h" 962306a36Sopenharmony_ci#include "ice_dcb_lib.h" 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/** 1262306a36Sopenharmony_ci * ice_repr_get_sw_port_id - get port ID associated with representor 1362306a36Sopenharmony_ci * @repr: pointer to port representor 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_cistatic int ice_repr_get_sw_port_id(struct ice_repr *repr) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci return repr->vf->pf->hw.port_info->lport; 1862306a36Sopenharmony_ci} 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/** 2162306a36Sopenharmony_ci * ice_repr_get_phys_port_name - get phys port name 2262306a36Sopenharmony_ci * @netdev: pointer to port representor netdev 2362306a36Sopenharmony_ci * @buf: write here port name 2462306a36Sopenharmony_ci * @len: max length of buf 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_cistatic int 2762306a36Sopenharmony_ciice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len) 2862306a36Sopenharmony_ci{ 2962306a36Sopenharmony_ci struct ice_netdev_priv *np = netdev_priv(netdev); 3062306a36Sopenharmony_ci struct ice_repr *repr = np->repr; 3162306a36Sopenharmony_ci int res; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci /* Devlink port is registered and devlink core is taking care of name formatting. */ 3462306a36Sopenharmony_ci if (repr->vf->devlink_port.devlink) 3562306a36Sopenharmony_ci return -EOPNOTSUPP; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr), 3862306a36Sopenharmony_ci repr->vf->vf_id); 3962306a36Sopenharmony_ci if (res <= 0) 4062306a36Sopenharmony_ci return -EOPNOTSUPP; 4162306a36Sopenharmony_ci return 0; 4262306a36Sopenharmony_ci} 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/** 4562306a36Sopenharmony_ci * ice_repr_get_stats64 - get VF stats for VFPR use 4662306a36Sopenharmony_ci * @netdev: pointer to port representor netdev 4762306a36Sopenharmony_ci * @stats: pointer to struct where stats can be stored 4862306a36Sopenharmony_ci */ 4962306a36Sopenharmony_cistatic void 5062306a36Sopenharmony_ciice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci struct ice_netdev_priv *np = netdev_priv(netdev); 5362306a36Sopenharmony_ci struct ice_eth_stats *eth_stats; 5462306a36Sopenharmony_ci struct ice_vsi *vsi; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if (ice_is_vf_disabled(np->repr->vf)) 5762306a36Sopenharmony_ci return; 5862306a36Sopenharmony_ci vsi = np->repr->src_vsi; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci ice_update_vsi_stats(vsi); 6162306a36Sopenharmony_ci eth_stats = &vsi->eth_stats; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci stats->tx_packets = eth_stats->tx_unicast + eth_stats->tx_broadcast + 6462306a36Sopenharmony_ci eth_stats->tx_multicast; 6562306a36Sopenharmony_ci stats->rx_packets = eth_stats->rx_unicast + eth_stats->rx_broadcast + 6662306a36Sopenharmony_ci eth_stats->rx_multicast; 6762306a36Sopenharmony_ci stats->tx_bytes = eth_stats->tx_bytes; 6862306a36Sopenharmony_ci stats->rx_bytes = eth_stats->rx_bytes; 6962306a36Sopenharmony_ci stats->multicast = eth_stats->rx_multicast; 7062306a36Sopenharmony_ci stats->tx_errors = eth_stats->tx_errors; 7162306a36Sopenharmony_ci stats->tx_dropped = eth_stats->tx_discards; 7262306a36Sopenharmony_ci stats->rx_dropped = eth_stats->rx_discards; 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/** 7662306a36Sopenharmony_ci * ice_netdev_to_repr - Get port representor for given netdevice 7762306a36Sopenharmony_ci * @netdev: pointer to port representor netdev 7862306a36Sopenharmony_ci */ 7962306a36Sopenharmony_cistruct ice_repr *ice_netdev_to_repr(struct net_device *netdev) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci struct ice_netdev_priv *np = netdev_priv(netdev); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci return np->repr; 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci/** 8762306a36Sopenharmony_ci * ice_repr_open - Enable port representor's network interface 8862306a36Sopenharmony_ci * @netdev: network interface device structure 8962306a36Sopenharmony_ci * 9062306a36Sopenharmony_ci * The open entry point is called when a port representor's network 9162306a36Sopenharmony_ci * interface is made active by the system (IFF_UP). Corresponding 9262306a36Sopenharmony_ci * VF is notified about link status change. 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci * Returns 0 on success 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_cistatic int ice_repr_open(struct net_device *netdev) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci struct ice_repr *repr = ice_netdev_to_repr(netdev); 9962306a36Sopenharmony_ci struct ice_vf *vf; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci vf = repr->vf; 10262306a36Sopenharmony_ci vf->link_forced = true; 10362306a36Sopenharmony_ci vf->link_up = true; 10462306a36Sopenharmony_ci ice_vc_notify_vf_link_state(vf); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci netif_carrier_on(netdev); 10762306a36Sopenharmony_ci netif_tx_start_all_queues(netdev); 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci return 0; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci/** 11362306a36Sopenharmony_ci * ice_repr_stop - Disable port representor's network interface 11462306a36Sopenharmony_ci * @netdev: network interface device structure 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * The stop entry point is called when a port representor's network 11762306a36Sopenharmony_ci * interface is de-activated by the system. Corresponding 11862306a36Sopenharmony_ci * VF is notified about link status change. 11962306a36Sopenharmony_ci * 12062306a36Sopenharmony_ci * Returns 0 on success 12162306a36Sopenharmony_ci */ 12262306a36Sopenharmony_cistatic int ice_repr_stop(struct net_device *netdev) 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci struct ice_repr *repr = ice_netdev_to_repr(netdev); 12562306a36Sopenharmony_ci struct ice_vf *vf; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_ci vf = repr->vf; 12862306a36Sopenharmony_ci vf->link_forced = true; 12962306a36Sopenharmony_ci vf->link_up = false; 13062306a36Sopenharmony_ci ice_vc_notify_vf_link_state(vf); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci netif_carrier_off(netdev); 13362306a36Sopenharmony_ci netif_tx_stop_all_queues(netdev); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci return 0; 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci/** 13962306a36Sopenharmony_ci * ice_repr_sp_stats64 - get slow path stats for port representor 14062306a36Sopenharmony_ci * @dev: network interface device structure 14162306a36Sopenharmony_ci * @stats: netlink stats structure 14262306a36Sopenharmony_ci * 14362306a36Sopenharmony_ci * RX/TX stats are being swapped here to be consistent with VF stats. In slow 14462306a36Sopenharmony_ci * path, port representor receives data when the corresponding VF is sending it 14562306a36Sopenharmony_ci * (and vice versa), TX and RX bytes/packets are effectively swapped on port 14662306a36Sopenharmony_ci * representor. 14762306a36Sopenharmony_ci */ 14862306a36Sopenharmony_cistatic int 14962306a36Sopenharmony_ciice_repr_sp_stats64(const struct net_device *dev, 15062306a36Sopenharmony_ci struct rtnl_link_stats64 *stats) 15162306a36Sopenharmony_ci{ 15262306a36Sopenharmony_ci struct ice_netdev_priv *np = netdev_priv(dev); 15362306a36Sopenharmony_ci int vf_id = np->repr->vf->vf_id; 15462306a36Sopenharmony_ci struct ice_tx_ring *tx_ring; 15562306a36Sopenharmony_ci struct ice_rx_ring *rx_ring; 15662306a36Sopenharmony_ci u64 pkts, bytes; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci tx_ring = np->vsi->tx_rings[vf_id]; 15962306a36Sopenharmony_ci ice_fetch_u64_stats_per_ring(&tx_ring->ring_stats->syncp, 16062306a36Sopenharmony_ci tx_ring->ring_stats->stats, 16162306a36Sopenharmony_ci &pkts, &bytes); 16262306a36Sopenharmony_ci stats->rx_packets = pkts; 16362306a36Sopenharmony_ci stats->rx_bytes = bytes; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci rx_ring = np->vsi->rx_rings[vf_id]; 16662306a36Sopenharmony_ci ice_fetch_u64_stats_per_ring(&rx_ring->ring_stats->syncp, 16762306a36Sopenharmony_ci rx_ring->ring_stats->stats, 16862306a36Sopenharmony_ci &pkts, &bytes); 16962306a36Sopenharmony_ci stats->tx_packets = pkts; 17062306a36Sopenharmony_ci stats->tx_bytes = bytes; 17162306a36Sopenharmony_ci stats->tx_dropped = rx_ring->ring_stats->rx_stats.alloc_page_failed + 17262306a36Sopenharmony_ci rx_ring->ring_stats->rx_stats.alloc_buf_failed; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci return 0; 17562306a36Sopenharmony_ci} 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_cistatic bool 17862306a36Sopenharmony_ciice_repr_ndo_has_offload_stats(const struct net_device *dev, int attr_id) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci return attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT; 18162306a36Sopenharmony_ci} 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistatic int 18462306a36Sopenharmony_ciice_repr_ndo_get_offload_stats(int attr_id, const struct net_device *dev, 18562306a36Sopenharmony_ci void *sp) 18662306a36Sopenharmony_ci{ 18762306a36Sopenharmony_ci if (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT) 18862306a36Sopenharmony_ci return ice_repr_sp_stats64(dev, (struct rtnl_link_stats64 *)sp); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci return -EINVAL; 19162306a36Sopenharmony_ci} 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic int 19462306a36Sopenharmony_ciice_repr_setup_tc_cls_flower(struct ice_repr *repr, 19562306a36Sopenharmony_ci struct flow_cls_offload *flower) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci switch (flower->command) { 19862306a36Sopenharmony_ci case FLOW_CLS_REPLACE: 19962306a36Sopenharmony_ci return ice_add_cls_flower(repr->netdev, repr->src_vsi, flower); 20062306a36Sopenharmony_ci case FLOW_CLS_DESTROY: 20162306a36Sopenharmony_ci return ice_del_cls_flower(repr->src_vsi, flower); 20262306a36Sopenharmony_ci default: 20362306a36Sopenharmony_ci return -EINVAL; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci} 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_cistatic int 20862306a36Sopenharmony_ciice_repr_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 20962306a36Sopenharmony_ci void *cb_priv) 21062306a36Sopenharmony_ci{ 21162306a36Sopenharmony_ci struct flow_cls_offload *flower = (struct flow_cls_offload *)type_data; 21262306a36Sopenharmony_ci struct ice_netdev_priv *np = (struct ice_netdev_priv *)cb_priv; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci switch (type) { 21562306a36Sopenharmony_ci case TC_SETUP_CLSFLOWER: 21662306a36Sopenharmony_ci return ice_repr_setup_tc_cls_flower(np->repr, flower); 21762306a36Sopenharmony_ci default: 21862306a36Sopenharmony_ci return -EOPNOTSUPP; 21962306a36Sopenharmony_ci } 22062306a36Sopenharmony_ci} 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cistatic LIST_HEAD(ice_repr_block_cb_list); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistatic int 22562306a36Sopenharmony_ciice_repr_setup_tc(struct net_device *netdev, enum tc_setup_type type, 22662306a36Sopenharmony_ci void *type_data) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci struct ice_netdev_priv *np = netdev_priv(netdev); 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci switch (type) { 23162306a36Sopenharmony_ci case TC_SETUP_BLOCK: 23262306a36Sopenharmony_ci return flow_block_cb_setup_simple((struct flow_block_offload *) 23362306a36Sopenharmony_ci type_data, 23462306a36Sopenharmony_ci &ice_repr_block_cb_list, 23562306a36Sopenharmony_ci ice_repr_setup_tc_block_cb, 23662306a36Sopenharmony_ci np, np, true); 23762306a36Sopenharmony_ci default: 23862306a36Sopenharmony_ci return -EOPNOTSUPP; 23962306a36Sopenharmony_ci } 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic const struct net_device_ops ice_repr_netdev_ops = { 24362306a36Sopenharmony_ci .ndo_get_phys_port_name = ice_repr_get_phys_port_name, 24462306a36Sopenharmony_ci .ndo_get_stats64 = ice_repr_get_stats64, 24562306a36Sopenharmony_ci .ndo_open = ice_repr_open, 24662306a36Sopenharmony_ci .ndo_stop = ice_repr_stop, 24762306a36Sopenharmony_ci .ndo_start_xmit = ice_eswitch_port_start_xmit, 24862306a36Sopenharmony_ci .ndo_setup_tc = ice_repr_setup_tc, 24962306a36Sopenharmony_ci .ndo_has_offload_stats = ice_repr_ndo_has_offload_stats, 25062306a36Sopenharmony_ci .ndo_get_offload_stats = ice_repr_ndo_get_offload_stats, 25162306a36Sopenharmony_ci}; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci/** 25462306a36Sopenharmony_ci * ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev 25562306a36Sopenharmony_ci * @netdev: pointer to netdev 25662306a36Sopenharmony_ci */ 25762306a36Sopenharmony_cibool ice_is_port_repr_netdev(const struct net_device *netdev) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops); 26062306a36Sopenharmony_ci} 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci/** 26362306a36Sopenharmony_ci * ice_repr_reg_netdev - register port representor netdev 26462306a36Sopenharmony_ci * @netdev: pointer to port representor netdev 26562306a36Sopenharmony_ci */ 26662306a36Sopenharmony_cistatic int 26762306a36Sopenharmony_ciice_repr_reg_netdev(struct net_device *netdev) 26862306a36Sopenharmony_ci{ 26962306a36Sopenharmony_ci eth_hw_addr_random(netdev); 27062306a36Sopenharmony_ci netdev->netdev_ops = &ice_repr_netdev_ops; 27162306a36Sopenharmony_ci ice_set_ethtool_repr_ops(netdev); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci netdev->hw_features |= NETIF_F_HW_TC; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci netif_carrier_off(netdev); 27662306a36Sopenharmony_ci netif_tx_stop_all_queues(netdev); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci return register_netdev(netdev); 27962306a36Sopenharmony_ci} 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci/** 28262306a36Sopenharmony_ci * ice_repr_add - add representor for VF 28362306a36Sopenharmony_ci * @vf: pointer to VF structure 28462306a36Sopenharmony_ci */ 28562306a36Sopenharmony_cistatic int ice_repr_add(struct ice_vf *vf) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci struct ice_q_vector *q_vector; 28862306a36Sopenharmony_ci struct ice_netdev_priv *np; 28962306a36Sopenharmony_ci struct ice_repr *repr; 29062306a36Sopenharmony_ci struct ice_vsi *vsi; 29162306a36Sopenharmony_ci int err; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci vsi = ice_get_vf_vsi(vf); 29462306a36Sopenharmony_ci if (!vsi) 29562306a36Sopenharmony_ci return -EINVAL; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci repr = kzalloc(sizeof(*repr), GFP_KERNEL); 29862306a36Sopenharmony_ci if (!repr) 29962306a36Sopenharmony_ci return -ENOMEM; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv)); 30262306a36Sopenharmony_ci if (!repr->netdev) { 30362306a36Sopenharmony_ci err = -ENOMEM; 30462306a36Sopenharmony_ci goto err_alloc; 30562306a36Sopenharmony_ci } 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci repr->src_vsi = vsi; 30862306a36Sopenharmony_ci repr->vf = vf; 30962306a36Sopenharmony_ci vf->repr = repr; 31062306a36Sopenharmony_ci np = netdev_priv(repr->netdev); 31162306a36Sopenharmony_ci np->repr = repr; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL); 31462306a36Sopenharmony_ci if (!q_vector) { 31562306a36Sopenharmony_ci err = -ENOMEM; 31662306a36Sopenharmony_ci goto err_alloc_q_vector; 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci repr->q_vector = q_vector; 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci err = ice_devlink_create_vf_port(vf); 32162306a36Sopenharmony_ci if (err) 32262306a36Sopenharmony_ci goto err_devlink; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci repr->netdev->min_mtu = ETH_MIN_MTU; 32562306a36Sopenharmony_ci repr->netdev->max_mtu = ICE_MAX_MTU; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci SET_NETDEV_DEV(repr->netdev, ice_pf_to_dev(vf->pf)); 32862306a36Sopenharmony_ci SET_NETDEV_DEVLINK_PORT(repr->netdev, &vf->devlink_port); 32962306a36Sopenharmony_ci err = ice_repr_reg_netdev(repr->netdev); 33062306a36Sopenharmony_ci if (err) 33162306a36Sopenharmony_ci goto err_netdev; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci ice_virtchnl_set_repr_ops(vf); 33462306a36Sopenharmony_ci 33562306a36Sopenharmony_ci return 0; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cierr_netdev: 33862306a36Sopenharmony_ci ice_devlink_destroy_vf_port(vf); 33962306a36Sopenharmony_cierr_devlink: 34062306a36Sopenharmony_ci kfree(repr->q_vector); 34162306a36Sopenharmony_ci vf->repr->q_vector = NULL; 34262306a36Sopenharmony_cierr_alloc_q_vector: 34362306a36Sopenharmony_ci free_netdev(repr->netdev); 34462306a36Sopenharmony_ci repr->netdev = NULL; 34562306a36Sopenharmony_cierr_alloc: 34662306a36Sopenharmony_ci kfree(repr); 34762306a36Sopenharmony_ci vf->repr = NULL; 34862306a36Sopenharmony_ci return err; 34962306a36Sopenharmony_ci} 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci/** 35262306a36Sopenharmony_ci * ice_repr_rem - remove representor from VF 35362306a36Sopenharmony_ci * @vf: pointer to VF structure 35462306a36Sopenharmony_ci */ 35562306a36Sopenharmony_cistatic void ice_repr_rem(struct ice_vf *vf) 35662306a36Sopenharmony_ci{ 35762306a36Sopenharmony_ci if (!vf->repr) 35862306a36Sopenharmony_ci return; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci kfree(vf->repr->q_vector); 36162306a36Sopenharmony_ci vf->repr->q_vector = NULL; 36262306a36Sopenharmony_ci unregister_netdev(vf->repr->netdev); 36362306a36Sopenharmony_ci ice_devlink_destroy_vf_port(vf); 36462306a36Sopenharmony_ci free_netdev(vf->repr->netdev); 36562306a36Sopenharmony_ci vf->repr->netdev = NULL; 36662306a36Sopenharmony_ci kfree(vf->repr); 36762306a36Sopenharmony_ci vf->repr = NULL; 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci ice_virtchnl_set_dflt_ops(vf); 37062306a36Sopenharmony_ci} 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci/** 37362306a36Sopenharmony_ci * ice_repr_rem_from_all_vfs - remove port representor for all VFs 37462306a36Sopenharmony_ci * @pf: pointer to PF structure 37562306a36Sopenharmony_ci */ 37662306a36Sopenharmony_civoid ice_repr_rem_from_all_vfs(struct ice_pf *pf) 37762306a36Sopenharmony_ci{ 37862306a36Sopenharmony_ci struct devlink *devlink; 37962306a36Sopenharmony_ci struct ice_vf *vf; 38062306a36Sopenharmony_ci unsigned int bkt; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci lockdep_assert_held(&pf->vfs.table_lock); 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci ice_for_each_vf(pf, bkt, vf) 38562306a36Sopenharmony_ci ice_repr_rem(vf); 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci /* since all port representors are destroyed, there is 38862306a36Sopenharmony_ci * no point in keeping the nodes 38962306a36Sopenharmony_ci */ 39062306a36Sopenharmony_ci devlink = priv_to_devlink(pf); 39162306a36Sopenharmony_ci devl_lock(devlink); 39262306a36Sopenharmony_ci devl_rate_nodes_destroy(devlink); 39362306a36Sopenharmony_ci devl_unlock(devlink); 39462306a36Sopenharmony_ci} 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci/** 39762306a36Sopenharmony_ci * ice_repr_add_for_all_vfs - add port representor for all VFs 39862306a36Sopenharmony_ci * @pf: pointer to PF structure 39962306a36Sopenharmony_ci */ 40062306a36Sopenharmony_ciint ice_repr_add_for_all_vfs(struct ice_pf *pf) 40162306a36Sopenharmony_ci{ 40262306a36Sopenharmony_ci struct devlink *devlink; 40362306a36Sopenharmony_ci struct ice_vf *vf; 40462306a36Sopenharmony_ci unsigned int bkt; 40562306a36Sopenharmony_ci int err; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci lockdep_assert_held(&pf->vfs.table_lock); 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci ice_for_each_vf(pf, bkt, vf) { 41062306a36Sopenharmony_ci err = ice_repr_add(vf); 41162306a36Sopenharmony_ci if (err) 41262306a36Sopenharmony_ci goto err; 41362306a36Sopenharmony_ci } 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_ci /* only export if ADQ and DCB disabled */ 41662306a36Sopenharmony_ci if (ice_is_adq_active(pf) || ice_is_dcb_active(pf)) 41762306a36Sopenharmony_ci return 0; 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci devlink = priv_to_devlink(pf); 42062306a36Sopenharmony_ci ice_devlink_rate_init_tx_topology(devlink, ice_get_main_vsi(pf)); 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci return 0; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cierr: 42562306a36Sopenharmony_ci ice_repr_rem_from_all_vfs(pf); 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ci return err; 42862306a36Sopenharmony_ci} 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci/** 43162306a36Sopenharmony_ci * ice_repr_start_tx_queues - start Tx queues of port representor 43262306a36Sopenharmony_ci * @repr: pointer to repr structure 43362306a36Sopenharmony_ci */ 43462306a36Sopenharmony_civoid ice_repr_start_tx_queues(struct ice_repr *repr) 43562306a36Sopenharmony_ci{ 43662306a36Sopenharmony_ci netif_carrier_on(repr->netdev); 43762306a36Sopenharmony_ci netif_tx_start_all_queues(repr->netdev); 43862306a36Sopenharmony_ci} 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci/** 44162306a36Sopenharmony_ci * ice_repr_stop_tx_queues - stop Tx queues of port representor 44262306a36Sopenharmony_ci * @repr: pointer to repr structure 44362306a36Sopenharmony_ci */ 44462306a36Sopenharmony_civoid ice_repr_stop_tx_queues(struct ice_repr *repr) 44562306a36Sopenharmony_ci{ 44662306a36Sopenharmony_ci netif_carrier_off(repr->netdev); 44762306a36Sopenharmony_ci netif_tx_stop_all_queues(repr->netdev); 44862306a36Sopenharmony_ci} 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci/** 45162306a36Sopenharmony_ci * ice_repr_set_traffic_vsi - set traffic VSI for port representor 45262306a36Sopenharmony_ci * @repr: repr on with VSI will be set 45362306a36Sopenharmony_ci * @vsi: pointer to VSI that will be used by port representor to pass traffic 45462306a36Sopenharmony_ci */ 45562306a36Sopenharmony_civoid ice_repr_set_traffic_vsi(struct ice_repr *repr, struct ice_vsi *vsi) 45662306a36Sopenharmony_ci{ 45762306a36Sopenharmony_ci struct ice_netdev_priv *np = netdev_priv(repr->netdev); 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci np->vsi = vsi; 46062306a36Sopenharmony_ci} 461