137165e3fSMichal Swiatkowski // SPDX-License-Identifier: GPL-2.0 237165e3fSMichal Swiatkowski /* Copyright (C) 2019-2021, Intel Corporation. */ 337165e3fSMichal Swiatkowski 437165e3fSMichal Swiatkowski #include "ice.h" 537165e3fSMichal Swiatkowski #include "ice_eswitch.h" 637165e3fSMichal Swiatkowski #include "ice_devlink.h" 70deb0bf7SJacob Keller #include "ice_sriov.h" 87fde6d8bSMichal Swiatkowski #include "ice_tc_lib.h" 9*80fe30a8SMichal Wilczynski #include "ice_dcb_lib.h" 1037165e3fSMichal Swiatkowski 1137165e3fSMichal Swiatkowski /** 1237165e3fSMichal Swiatkowski * ice_repr_get_sw_port_id - get port ID associated with representor 1337165e3fSMichal Swiatkowski * @repr: pointer to port representor 1437165e3fSMichal Swiatkowski */ 1537165e3fSMichal Swiatkowski static int ice_repr_get_sw_port_id(struct ice_repr *repr) 1637165e3fSMichal Swiatkowski { 1737165e3fSMichal Swiatkowski return repr->vf->pf->hw.port_info->lport; 1837165e3fSMichal Swiatkowski } 1937165e3fSMichal Swiatkowski 2037165e3fSMichal Swiatkowski /** 2137165e3fSMichal Swiatkowski * ice_repr_get_phys_port_name - get phys port name 2237165e3fSMichal Swiatkowski * @netdev: pointer to port representor netdev 2337165e3fSMichal Swiatkowski * @buf: write here port name 2437165e3fSMichal Swiatkowski * @len: max length of buf 2537165e3fSMichal Swiatkowski */ 2637165e3fSMichal Swiatkowski static int 2737165e3fSMichal Swiatkowski ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len) 2837165e3fSMichal Swiatkowski { 2937165e3fSMichal Swiatkowski struct ice_netdev_priv *np = netdev_priv(netdev); 3037165e3fSMichal Swiatkowski struct ice_repr *repr = np->repr; 3137165e3fSMichal Swiatkowski int res; 3237165e3fSMichal Swiatkowski 3337165e3fSMichal Swiatkowski /* Devlink port is registered and devlink core is taking care of name formatting. */ 3437165e3fSMichal Swiatkowski if (repr->vf->devlink_port.devlink) 3537165e3fSMichal Swiatkowski return -EOPNOTSUPP; 3637165e3fSMichal Swiatkowski 3737165e3fSMichal Swiatkowski res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr), 3837165e3fSMichal Swiatkowski repr->vf->vf_id); 3937165e3fSMichal Swiatkowski if (res <= 0) 4037165e3fSMichal Swiatkowski return -EOPNOTSUPP; 4137165e3fSMichal Swiatkowski return 0; 4237165e3fSMichal Swiatkowski } 4337165e3fSMichal Swiatkowski 4437165e3fSMichal Swiatkowski /** 457aae80ceSWojciech Drewek * ice_repr_get_stats64 - get VF stats for VFPR use 467aae80ceSWojciech Drewek * @netdev: pointer to port representor netdev 477aae80ceSWojciech Drewek * @stats: pointer to struct where stats can be stored 487aae80ceSWojciech Drewek */ 497aae80ceSWojciech Drewek static void 507aae80ceSWojciech Drewek ice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) 517aae80ceSWojciech Drewek { 527aae80ceSWojciech Drewek struct ice_netdev_priv *np = netdev_priv(netdev); 537aae80ceSWojciech Drewek struct ice_eth_stats *eth_stats; 547aae80ceSWojciech Drewek struct ice_vsi *vsi; 557aae80ceSWojciech Drewek 567aae80ceSWojciech Drewek if (ice_is_vf_disabled(np->repr->vf)) 577aae80ceSWojciech Drewek return; 587aae80ceSWojciech Drewek vsi = np->repr->src_vsi; 597aae80ceSWojciech Drewek 607aae80ceSWojciech Drewek ice_update_vsi_stats(vsi); 617aae80ceSWojciech Drewek eth_stats = &vsi->eth_stats; 627aae80ceSWojciech Drewek 637aae80ceSWojciech Drewek stats->tx_packets = eth_stats->tx_unicast + eth_stats->tx_broadcast + 647aae80ceSWojciech Drewek eth_stats->tx_multicast; 657aae80ceSWojciech Drewek stats->rx_packets = eth_stats->rx_unicast + eth_stats->rx_broadcast + 667aae80ceSWojciech Drewek eth_stats->rx_multicast; 677aae80ceSWojciech Drewek stats->tx_bytes = eth_stats->tx_bytes; 687aae80ceSWojciech Drewek stats->rx_bytes = eth_stats->rx_bytes; 697aae80ceSWojciech Drewek stats->multicast = eth_stats->rx_multicast; 707aae80ceSWojciech Drewek stats->tx_errors = eth_stats->tx_errors; 717aae80ceSWojciech Drewek stats->tx_dropped = eth_stats->tx_discards; 727aae80ceSWojciech Drewek stats->rx_dropped = eth_stats->rx_discards; 737aae80ceSWojciech Drewek } 747aae80ceSWojciech Drewek 757aae80ceSWojciech Drewek /** 7637165e3fSMichal Swiatkowski * ice_netdev_to_repr - Get port representor for given netdevice 7737165e3fSMichal Swiatkowski * @netdev: pointer to port representor netdev 7837165e3fSMichal Swiatkowski */ 7937165e3fSMichal Swiatkowski struct ice_repr *ice_netdev_to_repr(struct net_device *netdev) 8037165e3fSMichal Swiatkowski { 8137165e3fSMichal Swiatkowski struct ice_netdev_priv *np = netdev_priv(netdev); 8237165e3fSMichal Swiatkowski 8337165e3fSMichal Swiatkowski return np->repr; 8437165e3fSMichal Swiatkowski } 8537165e3fSMichal Swiatkowski 8637165e3fSMichal Swiatkowski /** 8737165e3fSMichal Swiatkowski * ice_repr_open - Enable port representor's network interface 8837165e3fSMichal Swiatkowski * @netdev: network interface device structure 8937165e3fSMichal Swiatkowski * 9037165e3fSMichal Swiatkowski * The open entry point is called when a port representor's network 9137165e3fSMichal Swiatkowski * interface is made active by the system (IFF_UP). Corresponding 9237165e3fSMichal Swiatkowski * VF is notified about link status change. 9337165e3fSMichal Swiatkowski * 9437165e3fSMichal Swiatkowski * Returns 0 on success 9537165e3fSMichal Swiatkowski */ 9637165e3fSMichal Swiatkowski static int ice_repr_open(struct net_device *netdev) 9737165e3fSMichal Swiatkowski { 9837165e3fSMichal Swiatkowski struct ice_repr *repr = ice_netdev_to_repr(netdev); 9937165e3fSMichal Swiatkowski struct ice_vf *vf; 10037165e3fSMichal Swiatkowski 10137165e3fSMichal Swiatkowski vf = repr->vf; 10237165e3fSMichal Swiatkowski vf->link_forced = true; 10337165e3fSMichal Swiatkowski vf->link_up = true; 10437165e3fSMichal Swiatkowski ice_vc_notify_vf_link_state(vf); 10537165e3fSMichal Swiatkowski 10637165e3fSMichal Swiatkowski netif_carrier_on(netdev); 10737165e3fSMichal Swiatkowski netif_tx_start_all_queues(netdev); 10837165e3fSMichal Swiatkowski 10937165e3fSMichal Swiatkowski return 0; 11037165e3fSMichal Swiatkowski } 11137165e3fSMichal Swiatkowski 11237165e3fSMichal Swiatkowski /** 11337165e3fSMichal Swiatkowski * ice_repr_stop - Disable port representor's network interface 11437165e3fSMichal Swiatkowski * @netdev: network interface device structure 11537165e3fSMichal Swiatkowski * 11637165e3fSMichal Swiatkowski * The stop entry point is called when a port representor's network 11737165e3fSMichal Swiatkowski * interface is de-activated by the system. Corresponding 11837165e3fSMichal Swiatkowski * VF is notified about link status change. 11937165e3fSMichal Swiatkowski * 12037165e3fSMichal Swiatkowski * Returns 0 on success 12137165e3fSMichal Swiatkowski */ 12237165e3fSMichal Swiatkowski static int ice_repr_stop(struct net_device *netdev) 12337165e3fSMichal Swiatkowski { 12437165e3fSMichal Swiatkowski struct ice_repr *repr = ice_netdev_to_repr(netdev); 12537165e3fSMichal Swiatkowski struct ice_vf *vf; 12637165e3fSMichal Swiatkowski 12737165e3fSMichal Swiatkowski vf = repr->vf; 12837165e3fSMichal Swiatkowski vf->link_forced = true; 12937165e3fSMichal Swiatkowski vf->link_up = false; 13037165e3fSMichal Swiatkowski ice_vc_notify_vf_link_state(vf); 13137165e3fSMichal Swiatkowski 13237165e3fSMichal Swiatkowski netif_carrier_off(netdev); 13337165e3fSMichal Swiatkowski netif_tx_stop_all_queues(netdev); 13437165e3fSMichal Swiatkowski 13537165e3fSMichal Swiatkowski return 0; 13637165e3fSMichal Swiatkowski } 13737165e3fSMichal Swiatkowski 138c8ff29b5SMarcin Szycik /** 139c8ff29b5SMarcin Szycik * ice_repr_sp_stats64 - get slow path stats for port representor 140c8ff29b5SMarcin Szycik * @dev: network interface device structure 141c8ff29b5SMarcin Szycik * @stats: netlink stats structure 142c8ff29b5SMarcin Szycik * 143c8ff29b5SMarcin Szycik * RX/TX stats are being swapped here to be consistent with VF stats. In slow 144c8ff29b5SMarcin Szycik * path, port representor receives data when the corresponding VF is sending it 145c8ff29b5SMarcin Szycik * (and vice versa), TX and RX bytes/packets are effectively swapped on port 146c8ff29b5SMarcin Szycik * representor. 147c8ff29b5SMarcin Szycik */ 148c8ff29b5SMarcin Szycik static int 149c8ff29b5SMarcin Szycik ice_repr_sp_stats64(const struct net_device *dev, 150c8ff29b5SMarcin Szycik struct rtnl_link_stats64 *stats) 151c8ff29b5SMarcin Szycik { 152c8ff29b5SMarcin Szycik struct ice_netdev_priv *np = netdev_priv(dev); 153c8ff29b5SMarcin Szycik int vf_id = np->repr->vf->vf_id; 154c8ff29b5SMarcin Szycik struct ice_tx_ring *tx_ring; 155c8ff29b5SMarcin Szycik struct ice_rx_ring *rx_ring; 156c8ff29b5SMarcin Szycik u64 pkts, bytes; 157c8ff29b5SMarcin Szycik 158c8ff29b5SMarcin Szycik tx_ring = np->vsi->tx_rings[vf_id]; 159c8ff29b5SMarcin Szycik ice_fetch_u64_stats_per_ring(&tx_ring->syncp, tx_ring->stats, 160c8ff29b5SMarcin Szycik &pkts, &bytes); 161c8ff29b5SMarcin Szycik stats->rx_packets = pkts; 162c8ff29b5SMarcin Szycik stats->rx_bytes = bytes; 163c8ff29b5SMarcin Szycik 164c8ff29b5SMarcin Szycik rx_ring = np->vsi->rx_rings[vf_id]; 165c8ff29b5SMarcin Szycik ice_fetch_u64_stats_per_ring(&rx_ring->syncp, rx_ring->stats, 166c8ff29b5SMarcin Szycik &pkts, &bytes); 167c8ff29b5SMarcin Szycik stats->tx_packets = pkts; 168c8ff29b5SMarcin Szycik stats->tx_bytes = bytes; 169c8ff29b5SMarcin Szycik stats->tx_dropped = rx_ring->rx_stats.alloc_page_failed + 170c8ff29b5SMarcin Szycik rx_ring->rx_stats.alloc_buf_failed; 171c8ff29b5SMarcin Szycik 172c8ff29b5SMarcin Szycik return 0; 173c8ff29b5SMarcin Szycik } 174c8ff29b5SMarcin Szycik 175c8ff29b5SMarcin Szycik static bool 176c8ff29b5SMarcin Szycik ice_repr_ndo_has_offload_stats(const struct net_device *dev, int attr_id) 177c8ff29b5SMarcin Szycik { 178c8ff29b5SMarcin Szycik return attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT; 179c8ff29b5SMarcin Szycik } 180c8ff29b5SMarcin Szycik 181c8ff29b5SMarcin Szycik static int 182c8ff29b5SMarcin Szycik ice_repr_ndo_get_offload_stats(int attr_id, const struct net_device *dev, 183c8ff29b5SMarcin Szycik void *sp) 184c8ff29b5SMarcin Szycik { 185c8ff29b5SMarcin Szycik if (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT) 186c8ff29b5SMarcin Szycik return ice_repr_sp_stats64(dev, (struct rtnl_link_stats64 *)sp); 187c8ff29b5SMarcin Szycik 188c8ff29b5SMarcin Szycik return -EINVAL; 189c8ff29b5SMarcin Szycik } 190c8ff29b5SMarcin Szycik 1917fde6d8bSMichal Swiatkowski static int 1927fde6d8bSMichal Swiatkowski ice_repr_setup_tc_cls_flower(struct ice_repr *repr, 1937fde6d8bSMichal Swiatkowski struct flow_cls_offload *flower) 1947fde6d8bSMichal Swiatkowski { 1957fde6d8bSMichal Swiatkowski switch (flower->command) { 1967fde6d8bSMichal Swiatkowski case FLOW_CLS_REPLACE: 1977fde6d8bSMichal Swiatkowski return ice_add_cls_flower(repr->netdev, repr->src_vsi, flower); 1987fde6d8bSMichal Swiatkowski case FLOW_CLS_DESTROY: 1997fde6d8bSMichal Swiatkowski return ice_del_cls_flower(repr->src_vsi, flower); 2007fde6d8bSMichal Swiatkowski default: 2017fde6d8bSMichal Swiatkowski return -EINVAL; 2027fde6d8bSMichal Swiatkowski } 2037fde6d8bSMichal Swiatkowski } 2047fde6d8bSMichal Swiatkowski 2057fde6d8bSMichal Swiatkowski static int 2067fde6d8bSMichal Swiatkowski ice_repr_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 2077fde6d8bSMichal Swiatkowski void *cb_priv) 2087fde6d8bSMichal Swiatkowski { 2097fde6d8bSMichal Swiatkowski struct flow_cls_offload *flower = (struct flow_cls_offload *)type_data; 2107fde6d8bSMichal Swiatkowski struct ice_netdev_priv *np = (struct ice_netdev_priv *)cb_priv; 2117fde6d8bSMichal Swiatkowski 2127fde6d8bSMichal Swiatkowski switch (type) { 2137fde6d8bSMichal Swiatkowski case TC_SETUP_CLSFLOWER: 2147fde6d8bSMichal Swiatkowski return ice_repr_setup_tc_cls_flower(np->repr, flower); 2157fde6d8bSMichal Swiatkowski default: 2167fde6d8bSMichal Swiatkowski return -EOPNOTSUPP; 2177fde6d8bSMichal Swiatkowski } 2187fde6d8bSMichal Swiatkowski } 2197fde6d8bSMichal Swiatkowski 2207fde6d8bSMichal Swiatkowski static LIST_HEAD(ice_repr_block_cb_list); 2217fde6d8bSMichal Swiatkowski 2227fde6d8bSMichal Swiatkowski static int 2237fde6d8bSMichal Swiatkowski ice_repr_setup_tc(struct net_device *netdev, enum tc_setup_type type, 2247fde6d8bSMichal Swiatkowski void *type_data) 2257fde6d8bSMichal Swiatkowski { 2267fde6d8bSMichal Swiatkowski struct ice_netdev_priv *np = netdev_priv(netdev); 2277fde6d8bSMichal Swiatkowski 2287fde6d8bSMichal Swiatkowski switch (type) { 2297fde6d8bSMichal Swiatkowski case TC_SETUP_BLOCK: 2307fde6d8bSMichal Swiatkowski return flow_block_cb_setup_simple((struct flow_block_offload *) 2317fde6d8bSMichal Swiatkowski type_data, 2327fde6d8bSMichal Swiatkowski &ice_repr_block_cb_list, 2337fde6d8bSMichal Swiatkowski ice_repr_setup_tc_block_cb, 2347fde6d8bSMichal Swiatkowski np, np, true); 2357fde6d8bSMichal Swiatkowski default: 2367fde6d8bSMichal Swiatkowski return -EOPNOTSUPP; 2377fde6d8bSMichal Swiatkowski } 2387fde6d8bSMichal Swiatkowski } 2397fde6d8bSMichal Swiatkowski 24037165e3fSMichal Swiatkowski static const struct net_device_ops ice_repr_netdev_ops = { 24137165e3fSMichal Swiatkowski .ndo_get_phys_port_name = ice_repr_get_phys_port_name, 2427aae80ceSWojciech Drewek .ndo_get_stats64 = ice_repr_get_stats64, 24337165e3fSMichal Swiatkowski .ndo_open = ice_repr_open, 24437165e3fSMichal Swiatkowski .ndo_stop = ice_repr_stop, 245f5396b8aSGrzegorz Nitka .ndo_start_xmit = ice_eswitch_port_start_xmit, 2467fde6d8bSMichal Swiatkowski .ndo_setup_tc = ice_repr_setup_tc, 247c8ff29b5SMarcin Szycik .ndo_has_offload_stats = ice_repr_ndo_has_offload_stats, 248c8ff29b5SMarcin Szycik .ndo_get_offload_stats = ice_repr_ndo_get_offload_stats, 24937165e3fSMichal Swiatkowski }; 25037165e3fSMichal Swiatkowski 25137165e3fSMichal Swiatkowski /** 25237165e3fSMichal Swiatkowski * ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev 25337165e3fSMichal Swiatkowski * @netdev: pointer to netdev 25437165e3fSMichal Swiatkowski */ 25537165e3fSMichal Swiatkowski bool ice_is_port_repr_netdev(struct net_device *netdev) 25637165e3fSMichal Swiatkowski { 25737165e3fSMichal Swiatkowski return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops); 25837165e3fSMichal Swiatkowski } 25937165e3fSMichal Swiatkowski 26037165e3fSMichal Swiatkowski /** 26137165e3fSMichal Swiatkowski * ice_repr_reg_netdev - register port representor netdev 26237165e3fSMichal Swiatkowski * @netdev: pointer to port representor netdev 26337165e3fSMichal Swiatkowski */ 26437165e3fSMichal Swiatkowski static int 26537165e3fSMichal Swiatkowski ice_repr_reg_netdev(struct net_device *netdev) 26637165e3fSMichal Swiatkowski { 26737165e3fSMichal Swiatkowski eth_hw_addr_random(netdev); 26837165e3fSMichal Swiatkowski netdev->netdev_ops = &ice_repr_netdev_ops; 2697aae80ceSWojciech Drewek ice_set_ethtool_repr_ops(netdev); 27037165e3fSMichal Swiatkowski 2717fde6d8bSMichal Swiatkowski netdev->hw_features |= NETIF_F_HW_TC; 2727fde6d8bSMichal Swiatkowski 27337165e3fSMichal Swiatkowski netif_carrier_off(netdev); 27437165e3fSMichal Swiatkowski netif_tx_stop_all_queues(netdev); 27537165e3fSMichal Swiatkowski 27637165e3fSMichal Swiatkowski return register_netdev(netdev); 27737165e3fSMichal Swiatkowski } 27837165e3fSMichal Swiatkowski 27937165e3fSMichal Swiatkowski /** 28037165e3fSMichal Swiatkowski * ice_repr_add - add representor for VF 28137165e3fSMichal Swiatkowski * @vf: pointer to VF structure 28237165e3fSMichal Swiatkowski */ 28337165e3fSMichal Swiatkowski static int ice_repr_add(struct ice_vf *vf) 28437165e3fSMichal Swiatkowski { 28537165e3fSMichal Swiatkowski struct ice_q_vector *q_vector; 28637165e3fSMichal Swiatkowski struct ice_netdev_priv *np; 28737165e3fSMichal Swiatkowski struct ice_repr *repr; 288baeb705fSJacob Keller struct ice_vsi *vsi; 28937165e3fSMichal Swiatkowski int err; 29037165e3fSMichal Swiatkowski 291baeb705fSJacob Keller vsi = ice_get_vf_vsi(vf); 292baeb705fSJacob Keller if (!vsi) 293baeb705fSJacob Keller return -EINVAL; 294baeb705fSJacob Keller 29537165e3fSMichal Swiatkowski repr = kzalloc(sizeof(*repr), GFP_KERNEL); 29637165e3fSMichal Swiatkowski if (!repr) 29737165e3fSMichal Swiatkowski return -ENOMEM; 29837165e3fSMichal Swiatkowski 299c1e5da5dSWojciech Drewek #ifdef CONFIG_ICE_SWITCHDEV 300c1e5da5dSWojciech Drewek repr->mac_rule = kzalloc(sizeof(*repr->mac_rule), GFP_KERNEL); 301c1e5da5dSWojciech Drewek if (!repr->mac_rule) { 302c1e5da5dSWojciech Drewek err = -ENOMEM; 303c1e5da5dSWojciech Drewek goto err_alloc_rule; 304c1e5da5dSWojciech Drewek } 305c1e5da5dSWojciech Drewek #endif 306c1e5da5dSWojciech Drewek 30737165e3fSMichal Swiatkowski repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv)); 30837165e3fSMichal Swiatkowski if (!repr->netdev) { 30937165e3fSMichal Swiatkowski err = -ENOMEM; 31037165e3fSMichal Swiatkowski goto err_alloc; 31137165e3fSMichal Swiatkowski } 31237165e3fSMichal Swiatkowski 313baeb705fSJacob Keller repr->src_vsi = vsi; 31437165e3fSMichal Swiatkowski repr->vf = vf; 31537165e3fSMichal Swiatkowski vf->repr = repr; 31637165e3fSMichal Swiatkowski np = netdev_priv(repr->netdev); 31737165e3fSMichal Swiatkowski np->repr = repr; 31837165e3fSMichal Swiatkowski 31937165e3fSMichal Swiatkowski q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL); 32037165e3fSMichal Swiatkowski if (!q_vector) { 32137165e3fSMichal Swiatkowski err = -ENOMEM; 32237165e3fSMichal Swiatkowski goto err_alloc_q_vector; 32337165e3fSMichal Swiatkowski } 32437165e3fSMichal Swiatkowski repr->q_vector = q_vector; 32537165e3fSMichal Swiatkowski 32637165e3fSMichal Swiatkowski err = ice_devlink_create_vf_port(vf); 32737165e3fSMichal Swiatkowski if (err) 32837165e3fSMichal Swiatkowski goto err_devlink; 32937165e3fSMichal Swiatkowski 330e984c440SMarcin Szycik repr->netdev->min_mtu = ETH_MIN_MTU; 331e984c440SMarcin Szycik repr->netdev->max_mtu = ICE_MAX_MTU; 332e984c440SMarcin Szycik 3336384b769SMichal Swiatkowski SET_NETDEV_DEV(repr->netdev, ice_pf_to_dev(vf->pf)); 334ac73d4bfSJiri Pirko SET_NETDEV_DEVLINK_PORT(repr->netdev, &vf->devlink_port); 33537165e3fSMichal Swiatkowski err = ice_repr_reg_netdev(repr->netdev); 33637165e3fSMichal Swiatkowski if (err) 33737165e3fSMichal Swiatkowski goto err_netdev; 33837165e3fSMichal Swiatkowski 339a7e11710SJacob Keller ice_virtchnl_set_repr_ops(vf); 340df830543SJacob Keller 34137165e3fSMichal Swiatkowski return 0; 34237165e3fSMichal Swiatkowski 34337165e3fSMichal Swiatkowski err_netdev: 34437165e3fSMichal Swiatkowski ice_devlink_destroy_vf_port(vf); 34537165e3fSMichal Swiatkowski err_devlink: 34637165e3fSMichal Swiatkowski kfree(repr->q_vector); 34737165e3fSMichal Swiatkowski vf->repr->q_vector = NULL; 34837165e3fSMichal Swiatkowski err_alloc_q_vector: 34937165e3fSMichal Swiatkowski free_netdev(repr->netdev); 35037165e3fSMichal Swiatkowski repr->netdev = NULL; 35137165e3fSMichal Swiatkowski err_alloc: 352c1e5da5dSWojciech Drewek #ifdef CONFIG_ICE_SWITCHDEV 353c1e5da5dSWojciech Drewek kfree(repr->mac_rule); 354c1e5da5dSWojciech Drewek repr->mac_rule = NULL; 355c1e5da5dSWojciech Drewek err_alloc_rule: 356c1e5da5dSWojciech Drewek #endif 35737165e3fSMichal Swiatkowski kfree(repr); 35837165e3fSMichal Swiatkowski vf->repr = NULL; 35937165e3fSMichal Swiatkowski return err; 36037165e3fSMichal Swiatkowski } 36137165e3fSMichal Swiatkowski 36237165e3fSMichal Swiatkowski /** 36337165e3fSMichal Swiatkowski * ice_repr_rem - remove representor from VF 36437165e3fSMichal Swiatkowski * @vf: pointer to VF structure 36537165e3fSMichal Swiatkowski */ 36637165e3fSMichal Swiatkowski static void ice_repr_rem(struct ice_vf *vf) 36737165e3fSMichal Swiatkowski { 368df830543SJacob Keller if (!vf->repr) 369df830543SJacob Keller return; 370df830543SJacob Keller 37137165e3fSMichal Swiatkowski kfree(vf->repr->q_vector); 37237165e3fSMichal Swiatkowski vf->repr->q_vector = NULL; 37337165e3fSMichal Swiatkowski unregister_netdev(vf->repr->netdev); 374a286ba73SJiri Pirko ice_devlink_destroy_vf_port(vf); 37537165e3fSMichal Swiatkowski free_netdev(vf->repr->netdev); 37637165e3fSMichal Swiatkowski vf->repr->netdev = NULL; 377c1e5da5dSWojciech Drewek #ifdef CONFIG_ICE_SWITCHDEV 378c1e5da5dSWojciech Drewek kfree(vf->repr->mac_rule); 379c1e5da5dSWojciech Drewek vf->repr->mac_rule = NULL; 380c1e5da5dSWojciech Drewek #endif 38137165e3fSMichal Swiatkowski kfree(vf->repr); 38237165e3fSMichal Swiatkowski vf->repr = NULL; 383df830543SJacob Keller 384a7e11710SJacob Keller ice_virtchnl_set_dflt_ops(vf); 385df830543SJacob Keller } 386df830543SJacob Keller 387df830543SJacob Keller /** 388df830543SJacob Keller * ice_repr_rem_from_all_vfs - remove port representor for all VFs 389df830543SJacob Keller * @pf: pointer to PF structure 390df830543SJacob Keller */ 391df830543SJacob Keller void ice_repr_rem_from_all_vfs(struct ice_pf *pf) 392df830543SJacob Keller { 39342c2eb6bSMichal Wilczynski struct devlink *devlink; 394c4c2c7dbSJacob Keller struct ice_vf *vf; 395c4c2c7dbSJacob Keller unsigned int bkt; 396df830543SJacob Keller 3973d5985a1SJacob Keller lockdep_assert_held(&pf->vfs.table_lock); 3983d5985a1SJacob Keller 399c4c2c7dbSJacob Keller ice_for_each_vf(pf, bkt, vf) 400df830543SJacob Keller ice_repr_rem(vf); 40142c2eb6bSMichal Wilczynski 40242c2eb6bSMichal Wilczynski /* since all port representors are destroyed, there is 40342c2eb6bSMichal Wilczynski * no point in keeping the nodes 40442c2eb6bSMichal Wilczynski */ 40542c2eb6bSMichal Wilczynski devlink = priv_to_devlink(pf); 40642c2eb6bSMichal Wilczynski devl_lock(devlink); 40742c2eb6bSMichal Wilczynski devl_rate_nodes_destroy(devlink); 40842c2eb6bSMichal Wilczynski devl_unlock(devlink); 409df830543SJacob Keller } 41037165e3fSMichal Swiatkowski 41137165e3fSMichal Swiatkowski /** 41237165e3fSMichal Swiatkowski * ice_repr_add_for_all_vfs - add port representor for all VFs 41337165e3fSMichal Swiatkowski * @pf: pointer to PF structure 41437165e3fSMichal Swiatkowski */ 41537165e3fSMichal Swiatkowski int ice_repr_add_for_all_vfs(struct ice_pf *pf) 41637165e3fSMichal Swiatkowski { 41742c2eb6bSMichal Wilczynski struct devlink *devlink; 418c4c2c7dbSJacob Keller struct ice_vf *vf; 419c4c2c7dbSJacob Keller unsigned int bkt; 42037165e3fSMichal Swiatkowski int err; 42137165e3fSMichal Swiatkowski 4223d5985a1SJacob Keller lockdep_assert_held(&pf->vfs.table_lock); 4233d5985a1SJacob Keller 424c4c2c7dbSJacob Keller ice_for_each_vf(pf, bkt, vf) { 425ac19e03eSMichal Swiatkowski err = ice_repr_add(vf); 42637165e3fSMichal Swiatkowski if (err) 42737165e3fSMichal Swiatkowski goto err; 42837165e3fSMichal Swiatkowski } 429ac19e03eSMichal Swiatkowski 430*80fe30a8SMichal Wilczynski /* only export if ADQ and DCB disabled */ 431*80fe30a8SMichal Wilczynski if (ice_is_adq_active(pf) || ice_is_dcb_active(pf)) 432*80fe30a8SMichal Wilczynski return 0; 433*80fe30a8SMichal Wilczynski 43442c2eb6bSMichal Wilczynski devlink = priv_to_devlink(pf); 43542c2eb6bSMichal Wilczynski ice_devlink_rate_init_tx_topology(devlink, ice_get_main_vsi(pf)); 43642c2eb6bSMichal Wilczynski 43737165e3fSMichal Swiatkowski return 0; 43837165e3fSMichal Swiatkowski 43937165e3fSMichal Swiatkowski err: 440df830543SJacob Keller ice_repr_rem_from_all_vfs(pf); 44137165e3fSMichal Swiatkowski 44237165e3fSMichal Swiatkowski return err; 44337165e3fSMichal Swiatkowski } 44437165e3fSMichal Swiatkowski 44537165e3fSMichal Swiatkowski /** 446b3be918dSGrzegorz Nitka * ice_repr_start_tx_queues - start Tx queues of port representor 447b3be918dSGrzegorz Nitka * @repr: pointer to repr structure 448b3be918dSGrzegorz Nitka */ 449b3be918dSGrzegorz Nitka void ice_repr_start_tx_queues(struct ice_repr *repr) 450b3be918dSGrzegorz Nitka { 451b3be918dSGrzegorz Nitka netif_carrier_on(repr->netdev); 452b3be918dSGrzegorz Nitka netif_tx_start_all_queues(repr->netdev); 453b3be918dSGrzegorz Nitka } 454b3be918dSGrzegorz Nitka 455b3be918dSGrzegorz Nitka /** 456b3be918dSGrzegorz Nitka * ice_repr_stop_tx_queues - stop Tx queues of port representor 457b3be918dSGrzegorz Nitka * @repr: pointer to repr structure 458b3be918dSGrzegorz Nitka */ 459b3be918dSGrzegorz Nitka void ice_repr_stop_tx_queues(struct ice_repr *repr) 460b3be918dSGrzegorz Nitka { 461b3be918dSGrzegorz Nitka netif_carrier_off(repr->netdev); 462b3be918dSGrzegorz Nitka netif_tx_stop_all_queues(repr->netdev); 463b3be918dSGrzegorz Nitka } 464b3be918dSGrzegorz Nitka 465b3be918dSGrzegorz Nitka /** 4661a1c40dfSGrzegorz Nitka * ice_repr_set_traffic_vsi - set traffic VSI for port representor 4671a1c40dfSGrzegorz Nitka * @repr: repr on with VSI will be set 4681a1c40dfSGrzegorz Nitka * @vsi: pointer to VSI that will be used by port representor to pass traffic 4691a1c40dfSGrzegorz Nitka */ 4701a1c40dfSGrzegorz Nitka void ice_repr_set_traffic_vsi(struct ice_repr *repr, struct ice_vsi *vsi) 4711a1c40dfSGrzegorz Nitka { 4721a1c40dfSGrzegorz Nitka struct ice_netdev_priv *np = netdev_priv(repr->netdev); 4731a1c40dfSGrzegorz Nitka 4741a1c40dfSGrzegorz Nitka np->vsi = vsi; 4751a1c40dfSGrzegorz Nitka } 476