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" 7*0deb0bf7SJacob Keller #include "ice_sriov.h" 87fde6d8bSMichal Swiatkowski #include "ice_tc_lib.h" 937165e3fSMichal Swiatkowski 1037165e3fSMichal Swiatkowski /** 1137165e3fSMichal Swiatkowski * ice_repr_get_sw_port_id - get port ID associated with representor 1237165e3fSMichal Swiatkowski * @repr: pointer to port representor 1337165e3fSMichal Swiatkowski */ 1437165e3fSMichal Swiatkowski static int ice_repr_get_sw_port_id(struct ice_repr *repr) 1537165e3fSMichal Swiatkowski { 1637165e3fSMichal Swiatkowski return repr->vf->pf->hw.port_info->lport; 1737165e3fSMichal Swiatkowski } 1837165e3fSMichal Swiatkowski 1937165e3fSMichal Swiatkowski /** 2037165e3fSMichal Swiatkowski * ice_repr_get_phys_port_name - get phys port name 2137165e3fSMichal Swiatkowski * @netdev: pointer to port representor netdev 2237165e3fSMichal Swiatkowski * @buf: write here port name 2337165e3fSMichal Swiatkowski * @len: max length of buf 2437165e3fSMichal Swiatkowski */ 2537165e3fSMichal Swiatkowski static int 2637165e3fSMichal Swiatkowski ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len) 2737165e3fSMichal Swiatkowski { 2837165e3fSMichal Swiatkowski struct ice_netdev_priv *np = netdev_priv(netdev); 2937165e3fSMichal Swiatkowski struct ice_repr *repr = np->repr; 3037165e3fSMichal Swiatkowski int res; 3137165e3fSMichal Swiatkowski 3237165e3fSMichal Swiatkowski /* Devlink port is registered and devlink core is taking care of name formatting. */ 3337165e3fSMichal Swiatkowski if (repr->vf->devlink_port.devlink) 3437165e3fSMichal Swiatkowski return -EOPNOTSUPP; 3537165e3fSMichal Swiatkowski 3637165e3fSMichal Swiatkowski res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr), 3737165e3fSMichal Swiatkowski repr->vf->vf_id); 3837165e3fSMichal Swiatkowski if (res <= 0) 3937165e3fSMichal Swiatkowski return -EOPNOTSUPP; 4037165e3fSMichal Swiatkowski return 0; 4137165e3fSMichal Swiatkowski } 4237165e3fSMichal Swiatkowski 4337165e3fSMichal Swiatkowski /** 447aae80ceSWojciech Drewek * ice_repr_get_stats64 - get VF stats for VFPR use 457aae80ceSWojciech Drewek * @netdev: pointer to port representor netdev 467aae80ceSWojciech Drewek * @stats: pointer to struct where stats can be stored 477aae80ceSWojciech Drewek */ 487aae80ceSWojciech Drewek static void 497aae80ceSWojciech Drewek ice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) 507aae80ceSWojciech Drewek { 517aae80ceSWojciech Drewek struct ice_netdev_priv *np = netdev_priv(netdev); 527aae80ceSWojciech Drewek struct ice_eth_stats *eth_stats; 537aae80ceSWojciech Drewek struct ice_vsi *vsi; 547aae80ceSWojciech Drewek 557aae80ceSWojciech Drewek if (ice_is_vf_disabled(np->repr->vf)) 567aae80ceSWojciech Drewek return; 577aae80ceSWojciech Drewek vsi = np->repr->src_vsi; 587aae80ceSWojciech Drewek 597aae80ceSWojciech Drewek ice_update_vsi_stats(vsi); 607aae80ceSWojciech Drewek eth_stats = &vsi->eth_stats; 617aae80ceSWojciech Drewek 627aae80ceSWojciech Drewek stats->tx_packets = eth_stats->tx_unicast + eth_stats->tx_broadcast + 637aae80ceSWojciech Drewek eth_stats->tx_multicast; 647aae80ceSWojciech Drewek stats->rx_packets = eth_stats->rx_unicast + eth_stats->rx_broadcast + 657aae80ceSWojciech Drewek eth_stats->rx_multicast; 667aae80ceSWojciech Drewek stats->tx_bytes = eth_stats->tx_bytes; 677aae80ceSWojciech Drewek stats->rx_bytes = eth_stats->rx_bytes; 687aae80ceSWojciech Drewek stats->multicast = eth_stats->rx_multicast; 697aae80ceSWojciech Drewek stats->tx_errors = eth_stats->tx_errors; 707aae80ceSWojciech Drewek stats->tx_dropped = eth_stats->tx_discards; 717aae80ceSWojciech Drewek stats->rx_dropped = eth_stats->rx_discards; 727aae80ceSWojciech Drewek } 737aae80ceSWojciech Drewek 747aae80ceSWojciech Drewek /** 7537165e3fSMichal Swiatkowski * ice_netdev_to_repr - Get port representor for given netdevice 7637165e3fSMichal Swiatkowski * @netdev: pointer to port representor netdev 7737165e3fSMichal Swiatkowski */ 7837165e3fSMichal Swiatkowski struct ice_repr *ice_netdev_to_repr(struct net_device *netdev) 7937165e3fSMichal Swiatkowski { 8037165e3fSMichal Swiatkowski struct ice_netdev_priv *np = netdev_priv(netdev); 8137165e3fSMichal Swiatkowski 8237165e3fSMichal Swiatkowski return np->repr; 8337165e3fSMichal Swiatkowski } 8437165e3fSMichal Swiatkowski 8537165e3fSMichal Swiatkowski /** 8637165e3fSMichal Swiatkowski * ice_repr_open - Enable port representor's network interface 8737165e3fSMichal Swiatkowski * @netdev: network interface device structure 8837165e3fSMichal Swiatkowski * 8937165e3fSMichal Swiatkowski * The open entry point is called when a port representor's network 9037165e3fSMichal Swiatkowski * interface is made active by the system (IFF_UP). Corresponding 9137165e3fSMichal Swiatkowski * VF is notified about link status change. 9237165e3fSMichal Swiatkowski * 9337165e3fSMichal Swiatkowski * Returns 0 on success 9437165e3fSMichal Swiatkowski */ 9537165e3fSMichal Swiatkowski static int ice_repr_open(struct net_device *netdev) 9637165e3fSMichal Swiatkowski { 9737165e3fSMichal Swiatkowski struct ice_repr *repr = ice_netdev_to_repr(netdev); 9837165e3fSMichal Swiatkowski struct ice_vf *vf; 9937165e3fSMichal Swiatkowski 10037165e3fSMichal Swiatkowski vf = repr->vf; 10137165e3fSMichal Swiatkowski vf->link_forced = true; 10237165e3fSMichal Swiatkowski vf->link_up = true; 10337165e3fSMichal Swiatkowski ice_vc_notify_vf_link_state(vf); 10437165e3fSMichal Swiatkowski 10537165e3fSMichal Swiatkowski netif_carrier_on(netdev); 10637165e3fSMichal Swiatkowski netif_tx_start_all_queues(netdev); 10737165e3fSMichal Swiatkowski 10837165e3fSMichal Swiatkowski return 0; 10937165e3fSMichal Swiatkowski } 11037165e3fSMichal Swiatkowski 11137165e3fSMichal Swiatkowski /** 11237165e3fSMichal Swiatkowski * ice_repr_stop - Disable port representor's network interface 11337165e3fSMichal Swiatkowski * @netdev: network interface device structure 11437165e3fSMichal Swiatkowski * 11537165e3fSMichal Swiatkowski * The stop entry point is called when a port representor's network 11637165e3fSMichal Swiatkowski * interface is de-activated by the system. Corresponding 11737165e3fSMichal Swiatkowski * VF is notified about link status change. 11837165e3fSMichal Swiatkowski * 11937165e3fSMichal Swiatkowski * Returns 0 on success 12037165e3fSMichal Swiatkowski */ 12137165e3fSMichal Swiatkowski static int ice_repr_stop(struct net_device *netdev) 12237165e3fSMichal Swiatkowski { 12337165e3fSMichal Swiatkowski struct ice_repr *repr = ice_netdev_to_repr(netdev); 12437165e3fSMichal Swiatkowski struct ice_vf *vf; 12537165e3fSMichal Swiatkowski 12637165e3fSMichal Swiatkowski vf = repr->vf; 12737165e3fSMichal Swiatkowski vf->link_forced = true; 12837165e3fSMichal Swiatkowski vf->link_up = false; 12937165e3fSMichal Swiatkowski ice_vc_notify_vf_link_state(vf); 13037165e3fSMichal Swiatkowski 13137165e3fSMichal Swiatkowski netif_carrier_off(netdev); 13237165e3fSMichal Swiatkowski netif_tx_stop_all_queues(netdev); 13337165e3fSMichal Swiatkowski 13437165e3fSMichal Swiatkowski return 0; 13537165e3fSMichal Swiatkowski } 13637165e3fSMichal Swiatkowski 13737165e3fSMichal Swiatkowski static struct devlink_port * 13837165e3fSMichal Swiatkowski ice_repr_get_devlink_port(struct net_device *netdev) 13937165e3fSMichal Swiatkowski { 14037165e3fSMichal Swiatkowski struct ice_repr *repr = ice_netdev_to_repr(netdev); 14137165e3fSMichal Swiatkowski 14237165e3fSMichal Swiatkowski return &repr->vf->devlink_port; 14337165e3fSMichal Swiatkowski } 14437165e3fSMichal Swiatkowski 145c8ff29b5SMarcin Szycik /** 146c8ff29b5SMarcin Szycik * ice_repr_sp_stats64 - get slow path stats for port representor 147c8ff29b5SMarcin Szycik * @dev: network interface device structure 148c8ff29b5SMarcin Szycik * @stats: netlink stats structure 149c8ff29b5SMarcin Szycik * 150c8ff29b5SMarcin Szycik * RX/TX stats are being swapped here to be consistent with VF stats. In slow 151c8ff29b5SMarcin Szycik * path, port representor receives data when the corresponding VF is sending it 152c8ff29b5SMarcin Szycik * (and vice versa), TX and RX bytes/packets are effectively swapped on port 153c8ff29b5SMarcin Szycik * representor. 154c8ff29b5SMarcin Szycik */ 155c8ff29b5SMarcin Szycik static int 156c8ff29b5SMarcin Szycik ice_repr_sp_stats64(const struct net_device *dev, 157c8ff29b5SMarcin Szycik struct rtnl_link_stats64 *stats) 158c8ff29b5SMarcin Szycik { 159c8ff29b5SMarcin Szycik struct ice_netdev_priv *np = netdev_priv(dev); 160c8ff29b5SMarcin Szycik int vf_id = np->repr->vf->vf_id; 161c8ff29b5SMarcin Szycik struct ice_tx_ring *tx_ring; 162c8ff29b5SMarcin Szycik struct ice_rx_ring *rx_ring; 163c8ff29b5SMarcin Szycik u64 pkts, bytes; 164c8ff29b5SMarcin Szycik 165c8ff29b5SMarcin Szycik tx_ring = np->vsi->tx_rings[vf_id]; 166c8ff29b5SMarcin Szycik ice_fetch_u64_stats_per_ring(&tx_ring->syncp, tx_ring->stats, 167c8ff29b5SMarcin Szycik &pkts, &bytes); 168c8ff29b5SMarcin Szycik stats->rx_packets = pkts; 169c8ff29b5SMarcin Szycik stats->rx_bytes = bytes; 170c8ff29b5SMarcin Szycik 171c8ff29b5SMarcin Szycik rx_ring = np->vsi->rx_rings[vf_id]; 172c8ff29b5SMarcin Szycik ice_fetch_u64_stats_per_ring(&rx_ring->syncp, rx_ring->stats, 173c8ff29b5SMarcin Szycik &pkts, &bytes); 174c8ff29b5SMarcin Szycik stats->tx_packets = pkts; 175c8ff29b5SMarcin Szycik stats->tx_bytes = bytes; 176c8ff29b5SMarcin Szycik stats->tx_dropped = rx_ring->rx_stats.alloc_page_failed + 177c8ff29b5SMarcin Szycik rx_ring->rx_stats.alloc_buf_failed; 178c8ff29b5SMarcin Szycik 179c8ff29b5SMarcin Szycik return 0; 180c8ff29b5SMarcin Szycik } 181c8ff29b5SMarcin Szycik 182c8ff29b5SMarcin Szycik static bool 183c8ff29b5SMarcin Szycik ice_repr_ndo_has_offload_stats(const struct net_device *dev, int attr_id) 184c8ff29b5SMarcin Szycik { 185c8ff29b5SMarcin Szycik return attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT; 186c8ff29b5SMarcin Szycik } 187c8ff29b5SMarcin Szycik 188c8ff29b5SMarcin Szycik static int 189c8ff29b5SMarcin Szycik ice_repr_ndo_get_offload_stats(int attr_id, const struct net_device *dev, 190c8ff29b5SMarcin Szycik void *sp) 191c8ff29b5SMarcin Szycik { 192c8ff29b5SMarcin Szycik if (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT) 193c8ff29b5SMarcin Szycik return ice_repr_sp_stats64(dev, (struct rtnl_link_stats64 *)sp); 194c8ff29b5SMarcin Szycik 195c8ff29b5SMarcin Szycik return -EINVAL; 196c8ff29b5SMarcin Szycik } 197c8ff29b5SMarcin Szycik 1987fde6d8bSMichal Swiatkowski static int 1997fde6d8bSMichal Swiatkowski ice_repr_setup_tc_cls_flower(struct ice_repr *repr, 2007fde6d8bSMichal Swiatkowski struct flow_cls_offload *flower) 2017fde6d8bSMichal Swiatkowski { 2027fde6d8bSMichal Swiatkowski switch (flower->command) { 2037fde6d8bSMichal Swiatkowski case FLOW_CLS_REPLACE: 2047fde6d8bSMichal Swiatkowski return ice_add_cls_flower(repr->netdev, repr->src_vsi, flower); 2057fde6d8bSMichal Swiatkowski case FLOW_CLS_DESTROY: 2067fde6d8bSMichal Swiatkowski return ice_del_cls_flower(repr->src_vsi, flower); 2077fde6d8bSMichal Swiatkowski default: 2087fde6d8bSMichal Swiatkowski return -EINVAL; 2097fde6d8bSMichal Swiatkowski } 2107fde6d8bSMichal Swiatkowski } 2117fde6d8bSMichal Swiatkowski 2127fde6d8bSMichal Swiatkowski static int 2137fde6d8bSMichal Swiatkowski ice_repr_setup_tc_block_cb(enum tc_setup_type type, void *type_data, 2147fde6d8bSMichal Swiatkowski void *cb_priv) 2157fde6d8bSMichal Swiatkowski { 2167fde6d8bSMichal Swiatkowski struct flow_cls_offload *flower = (struct flow_cls_offload *)type_data; 2177fde6d8bSMichal Swiatkowski struct ice_netdev_priv *np = (struct ice_netdev_priv *)cb_priv; 2187fde6d8bSMichal Swiatkowski 2197fde6d8bSMichal Swiatkowski switch (type) { 2207fde6d8bSMichal Swiatkowski case TC_SETUP_CLSFLOWER: 2217fde6d8bSMichal Swiatkowski return ice_repr_setup_tc_cls_flower(np->repr, flower); 2227fde6d8bSMichal Swiatkowski default: 2237fde6d8bSMichal Swiatkowski return -EOPNOTSUPP; 2247fde6d8bSMichal Swiatkowski } 2257fde6d8bSMichal Swiatkowski } 2267fde6d8bSMichal Swiatkowski 2277fde6d8bSMichal Swiatkowski static LIST_HEAD(ice_repr_block_cb_list); 2287fde6d8bSMichal Swiatkowski 2297fde6d8bSMichal Swiatkowski static int 2307fde6d8bSMichal Swiatkowski ice_repr_setup_tc(struct net_device *netdev, enum tc_setup_type type, 2317fde6d8bSMichal Swiatkowski void *type_data) 2327fde6d8bSMichal Swiatkowski { 2337fde6d8bSMichal Swiatkowski struct ice_netdev_priv *np = netdev_priv(netdev); 2347fde6d8bSMichal Swiatkowski 2357fde6d8bSMichal Swiatkowski switch (type) { 2367fde6d8bSMichal Swiatkowski case TC_SETUP_BLOCK: 2377fde6d8bSMichal Swiatkowski return flow_block_cb_setup_simple((struct flow_block_offload *) 2387fde6d8bSMichal Swiatkowski type_data, 2397fde6d8bSMichal Swiatkowski &ice_repr_block_cb_list, 2407fde6d8bSMichal Swiatkowski ice_repr_setup_tc_block_cb, 2417fde6d8bSMichal Swiatkowski np, np, true); 2427fde6d8bSMichal Swiatkowski default: 2437fde6d8bSMichal Swiatkowski return -EOPNOTSUPP; 2447fde6d8bSMichal Swiatkowski } 2457fde6d8bSMichal Swiatkowski } 2467fde6d8bSMichal Swiatkowski 24737165e3fSMichal Swiatkowski static const struct net_device_ops ice_repr_netdev_ops = { 24837165e3fSMichal Swiatkowski .ndo_get_phys_port_name = ice_repr_get_phys_port_name, 2497aae80ceSWojciech Drewek .ndo_get_stats64 = ice_repr_get_stats64, 25037165e3fSMichal Swiatkowski .ndo_open = ice_repr_open, 25137165e3fSMichal Swiatkowski .ndo_stop = ice_repr_stop, 252f5396b8aSGrzegorz Nitka .ndo_start_xmit = ice_eswitch_port_start_xmit, 25337165e3fSMichal Swiatkowski .ndo_get_devlink_port = ice_repr_get_devlink_port, 2547fde6d8bSMichal Swiatkowski .ndo_setup_tc = ice_repr_setup_tc, 255c8ff29b5SMarcin Szycik .ndo_has_offload_stats = ice_repr_ndo_has_offload_stats, 256c8ff29b5SMarcin Szycik .ndo_get_offload_stats = ice_repr_ndo_get_offload_stats, 25737165e3fSMichal Swiatkowski }; 25837165e3fSMichal Swiatkowski 25937165e3fSMichal Swiatkowski /** 26037165e3fSMichal Swiatkowski * ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev 26137165e3fSMichal Swiatkowski * @netdev: pointer to netdev 26237165e3fSMichal Swiatkowski */ 26337165e3fSMichal Swiatkowski bool ice_is_port_repr_netdev(struct net_device *netdev) 26437165e3fSMichal Swiatkowski { 26537165e3fSMichal Swiatkowski return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops); 26637165e3fSMichal Swiatkowski } 26737165e3fSMichal Swiatkowski 26837165e3fSMichal Swiatkowski /** 26937165e3fSMichal Swiatkowski * ice_repr_reg_netdev - register port representor netdev 27037165e3fSMichal Swiatkowski * @netdev: pointer to port representor netdev 27137165e3fSMichal Swiatkowski */ 27237165e3fSMichal Swiatkowski static int 27337165e3fSMichal Swiatkowski ice_repr_reg_netdev(struct net_device *netdev) 27437165e3fSMichal Swiatkowski { 27537165e3fSMichal Swiatkowski eth_hw_addr_random(netdev); 27637165e3fSMichal Swiatkowski netdev->netdev_ops = &ice_repr_netdev_ops; 2777aae80ceSWojciech Drewek ice_set_ethtool_repr_ops(netdev); 27837165e3fSMichal Swiatkowski 2797fde6d8bSMichal Swiatkowski netdev->hw_features |= NETIF_F_HW_TC; 2807fde6d8bSMichal Swiatkowski 28137165e3fSMichal Swiatkowski netif_carrier_off(netdev); 28237165e3fSMichal Swiatkowski netif_tx_stop_all_queues(netdev); 28337165e3fSMichal Swiatkowski 28437165e3fSMichal Swiatkowski return register_netdev(netdev); 28537165e3fSMichal Swiatkowski } 28637165e3fSMichal Swiatkowski 28737165e3fSMichal Swiatkowski /** 28837165e3fSMichal Swiatkowski * ice_repr_add - add representor for VF 28937165e3fSMichal Swiatkowski * @vf: pointer to VF structure 29037165e3fSMichal Swiatkowski */ 29137165e3fSMichal Swiatkowski static int ice_repr_add(struct ice_vf *vf) 29237165e3fSMichal Swiatkowski { 29337165e3fSMichal Swiatkowski struct ice_q_vector *q_vector; 29437165e3fSMichal Swiatkowski struct ice_netdev_priv *np; 29537165e3fSMichal Swiatkowski struct ice_repr *repr; 29637165e3fSMichal Swiatkowski int err; 29737165e3fSMichal Swiatkowski 29837165e3fSMichal Swiatkowski repr = kzalloc(sizeof(*repr), GFP_KERNEL); 29937165e3fSMichal Swiatkowski if (!repr) 30037165e3fSMichal Swiatkowski return -ENOMEM; 30137165e3fSMichal Swiatkowski 302c1e5da5dSWojciech Drewek #ifdef CONFIG_ICE_SWITCHDEV 303c1e5da5dSWojciech Drewek repr->mac_rule = kzalloc(sizeof(*repr->mac_rule), GFP_KERNEL); 304c1e5da5dSWojciech Drewek if (!repr->mac_rule) { 305c1e5da5dSWojciech Drewek err = -ENOMEM; 306c1e5da5dSWojciech Drewek goto err_alloc_rule; 307c1e5da5dSWojciech Drewek } 308c1e5da5dSWojciech Drewek #endif 309c1e5da5dSWojciech Drewek 31037165e3fSMichal Swiatkowski repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv)); 31137165e3fSMichal Swiatkowski if (!repr->netdev) { 31237165e3fSMichal Swiatkowski err = -ENOMEM; 31337165e3fSMichal Swiatkowski goto err_alloc; 31437165e3fSMichal Swiatkowski } 31537165e3fSMichal Swiatkowski 31637165e3fSMichal Swiatkowski repr->src_vsi = ice_get_vf_vsi(vf); 31737165e3fSMichal Swiatkowski repr->vf = vf; 31837165e3fSMichal Swiatkowski vf->repr = repr; 31937165e3fSMichal Swiatkowski np = netdev_priv(repr->netdev); 32037165e3fSMichal Swiatkowski np->repr = repr; 32137165e3fSMichal Swiatkowski 32237165e3fSMichal Swiatkowski q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL); 32337165e3fSMichal Swiatkowski if (!q_vector) { 32437165e3fSMichal Swiatkowski err = -ENOMEM; 32537165e3fSMichal Swiatkowski goto err_alloc_q_vector; 32637165e3fSMichal Swiatkowski } 32737165e3fSMichal Swiatkowski repr->q_vector = q_vector; 32837165e3fSMichal Swiatkowski 32937165e3fSMichal Swiatkowski err = ice_devlink_create_vf_port(vf); 33037165e3fSMichal Swiatkowski if (err) 33137165e3fSMichal Swiatkowski goto err_devlink; 33237165e3fSMichal Swiatkowski 333e984c440SMarcin Szycik repr->netdev->min_mtu = ETH_MIN_MTU; 334e984c440SMarcin Szycik repr->netdev->max_mtu = ICE_MAX_MTU; 335e984c440SMarcin Szycik 33637165e3fSMichal Swiatkowski err = ice_repr_reg_netdev(repr->netdev); 33737165e3fSMichal Swiatkowski if (err) 33837165e3fSMichal Swiatkowski goto err_netdev; 33937165e3fSMichal Swiatkowski 34037165e3fSMichal Swiatkowski devlink_port_type_eth_set(&vf->devlink_port, repr->netdev); 34137165e3fSMichal Swiatkowski 342df830543SJacob Keller ice_vc_change_ops_to_repr(&vf->vc_ops); 343df830543SJacob Keller 34437165e3fSMichal Swiatkowski return 0; 34537165e3fSMichal Swiatkowski 34637165e3fSMichal Swiatkowski err_netdev: 34737165e3fSMichal Swiatkowski ice_devlink_destroy_vf_port(vf); 34837165e3fSMichal Swiatkowski err_devlink: 34937165e3fSMichal Swiatkowski kfree(repr->q_vector); 35037165e3fSMichal Swiatkowski vf->repr->q_vector = NULL; 35137165e3fSMichal Swiatkowski err_alloc_q_vector: 35237165e3fSMichal Swiatkowski free_netdev(repr->netdev); 35337165e3fSMichal Swiatkowski repr->netdev = NULL; 35437165e3fSMichal Swiatkowski err_alloc: 355c1e5da5dSWojciech Drewek #ifdef CONFIG_ICE_SWITCHDEV 356c1e5da5dSWojciech Drewek kfree(repr->mac_rule); 357c1e5da5dSWojciech Drewek repr->mac_rule = NULL; 358c1e5da5dSWojciech Drewek err_alloc_rule: 359c1e5da5dSWojciech Drewek #endif 36037165e3fSMichal Swiatkowski kfree(repr); 36137165e3fSMichal Swiatkowski vf->repr = NULL; 36237165e3fSMichal Swiatkowski return err; 36337165e3fSMichal Swiatkowski } 36437165e3fSMichal Swiatkowski 36537165e3fSMichal Swiatkowski /** 36637165e3fSMichal Swiatkowski * ice_repr_rem - remove representor from VF 36737165e3fSMichal Swiatkowski * @vf: pointer to VF structure 36837165e3fSMichal Swiatkowski */ 36937165e3fSMichal Swiatkowski static void ice_repr_rem(struct ice_vf *vf) 37037165e3fSMichal Swiatkowski { 371df830543SJacob Keller if (!vf->repr) 372df830543SJacob Keller return; 373df830543SJacob Keller 37437165e3fSMichal Swiatkowski ice_devlink_destroy_vf_port(vf); 37537165e3fSMichal Swiatkowski kfree(vf->repr->q_vector); 37637165e3fSMichal Swiatkowski vf->repr->q_vector = NULL; 37737165e3fSMichal Swiatkowski unregister_netdev(vf->repr->netdev); 37837165e3fSMichal Swiatkowski free_netdev(vf->repr->netdev); 37937165e3fSMichal Swiatkowski vf->repr->netdev = NULL; 380c1e5da5dSWojciech Drewek #ifdef CONFIG_ICE_SWITCHDEV 381c1e5da5dSWojciech Drewek kfree(vf->repr->mac_rule); 382c1e5da5dSWojciech Drewek vf->repr->mac_rule = NULL; 383c1e5da5dSWojciech Drewek #endif 38437165e3fSMichal Swiatkowski kfree(vf->repr); 38537165e3fSMichal Swiatkowski vf->repr = NULL; 386df830543SJacob Keller 387df830543SJacob Keller ice_vc_set_dflt_vf_ops(&vf->vc_ops); 388df830543SJacob Keller } 389df830543SJacob Keller 390df830543SJacob Keller /** 391df830543SJacob Keller * ice_repr_rem_from_all_vfs - remove port representor for all VFs 392df830543SJacob Keller * @pf: pointer to PF structure 393df830543SJacob Keller */ 394df830543SJacob Keller void ice_repr_rem_from_all_vfs(struct ice_pf *pf) 395df830543SJacob Keller { 396c4c2c7dbSJacob Keller struct ice_vf *vf; 397c4c2c7dbSJacob Keller unsigned int bkt; 398df830543SJacob Keller 3993d5985a1SJacob Keller lockdep_assert_held(&pf->vfs.table_lock); 4003d5985a1SJacob Keller 401c4c2c7dbSJacob Keller ice_for_each_vf(pf, bkt, vf) 402df830543SJacob Keller ice_repr_rem(vf); 403df830543SJacob Keller } 40437165e3fSMichal Swiatkowski 40537165e3fSMichal Swiatkowski /** 40637165e3fSMichal Swiatkowski * ice_repr_add_for_all_vfs - add port representor for all VFs 40737165e3fSMichal Swiatkowski * @pf: pointer to PF structure 40837165e3fSMichal Swiatkowski */ 40937165e3fSMichal Swiatkowski int ice_repr_add_for_all_vfs(struct ice_pf *pf) 41037165e3fSMichal Swiatkowski { 411c4c2c7dbSJacob Keller struct ice_vf *vf; 412c4c2c7dbSJacob Keller unsigned int bkt; 41337165e3fSMichal Swiatkowski int err; 41437165e3fSMichal Swiatkowski 4153d5985a1SJacob Keller lockdep_assert_held(&pf->vfs.table_lock); 4163d5985a1SJacob Keller 417c4c2c7dbSJacob Keller ice_for_each_vf(pf, bkt, vf) { 418ac19e03eSMichal Swiatkowski err = ice_repr_add(vf); 41937165e3fSMichal Swiatkowski if (err) 42037165e3fSMichal Swiatkowski goto err; 42137165e3fSMichal Swiatkowski } 422ac19e03eSMichal Swiatkowski 42337165e3fSMichal Swiatkowski return 0; 42437165e3fSMichal Swiatkowski 42537165e3fSMichal Swiatkowski err: 426df830543SJacob Keller ice_repr_rem_from_all_vfs(pf); 42737165e3fSMichal Swiatkowski 42837165e3fSMichal Swiatkowski return err; 42937165e3fSMichal Swiatkowski } 43037165e3fSMichal Swiatkowski 43137165e3fSMichal Swiatkowski /** 432b3be918dSGrzegorz Nitka * ice_repr_start_tx_queues - start Tx queues of port representor 433b3be918dSGrzegorz Nitka * @repr: pointer to repr structure 434b3be918dSGrzegorz Nitka */ 435b3be918dSGrzegorz Nitka void ice_repr_start_tx_queues(struct ice_repr *repr) 436b3be918dSGrzegorz Nitka { 437b3be918dSGrzegorz Nitka netif_carrier_on(repr->netdev); 438b3be918dSGrzegorz Nitka netif_tx_start_all_queues(repr->netdev); 439b3be918dSGrzegorz Nitka } 440b3be918dSGrzegorz Nitka 441b3be918dSGrzegorz Nitka /** 442b3be918dSGrzegorz Nitka * ice_repr_stop_tx_queues - stop Tx queues of port representor 443b3be918dSGrzegorz Nitka * @repr: pointer to repr structure 444b3be918dSGrzegorz Nitka */ 445b3be918dSGrzegorz Nitka void ice_repr_stop_tx_queues(struct ice_repr *repr) 446b3be918dSGrzegorz Nitka { 447b3be918dSGrzegorz Nitka netif_carrier_off(repr->netdev); 448b3be918dSGrzegorz Nitka netif_tx_stop_all_queues(repr->netdev); 449b3be918dSGrzegorz Nitka } 450b3be918dSGrzegorz Nitka 451b3be918dSGrzegorz Nitka /** 4521a1c40dfSGrzegorz Nitka * ice_repr_set_traffic_vsi - set traffic VSI for port representor 4531a1c40dfSGrzegorz Nitka * @repr: repr on with VSI will be set 4541a1c40dfSGrzegorz Nitka * @vsi: pointer to VSI that will be used by port representor to pass traffic 4551a1c40dfSGrzegorz Nitka */ 4561a1c40dfSGrzegorz Nitka void ice_repr_set_traffic_vsi(struct ice_repr *repr, struct ice_vsi *vsi) 4571a1c40dfSGrzegorz Nitka { 4581a1c40dfSGrzegorz Nitka struct ice_netdev_priv *np = netdev_priv(repr->netdev); 4591a1c40dfSGrzegorz Nitka 4601a1c40dfSGrzegorz Nitka np->vsi = vsi; 4611a1c40dfSGrzegorz Nitka } 462