Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (C) 2019-2021, Intel Corporation. */
0003 
0004 #include "ice.h"
0005 #include "ice_eswitch.h"
0006 #include "ice_devlink.h"
0007 #include "ice_sriov.h"
0008 #include "ice_tc_lib.h"
0009 
0010 /**
0011  * ice_repr_get_sw_port_id - get port ID associated with representor
0012  * @repr: pointer to port representor
0013  */
0014 static int ice_repr_get_sw_port_id(struct ice_repr *repr)
0015 {
0016     return repr->vf->pf->hw.port_info->lport;
0017 }
0018 
0019 /**
0020  * ice_repr_get_phys_port_name - get phys port name
0021  * @netdev: pointer to port representor netdev
0022  * @buf: write here port name
0023  * @len: max length of buf
0024  */
0025 static int
0026 ice_repr_get_phys_port_name(struct net_device *netdev, char *buf, size_t len)
0027 {
0028     struct ice_netdev_priv *np = netdev_priv(netdev);
0029     struct ice_repr *repr = np->repr;
0030     int res;
0031 
0032     /* Devlink port is registered and devlink core is taking care of name formatting. */
0033     if (repr->vf->devlink_port.devlink)
0034         return -EOPNOTSUPP;
0035 
0036     res = snprintf(buf, len, "pf%dvfr%d", ice_repr_get_sw_port_id(repr),
0037                repr->vf->vf_id);
0038     if (res <= 0)
0039         return -EOPNOTSUPP;
0040     return 0;
0041 }
0042 
0043 /**
0044  * ice_repr_get_stats64 - get VF stats for VFPR use
0045  * @netdev: pointer to port representor netdev
0046  * @stats: pointer to struct where stats can be stored
0047  */
0048 static void
0049 ice_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
0050 {
0051     struct ice_netdev_priv *np = netdev_priv(netdev);
0052     struct ice_eth_stats *eth_stats;
0053     struct ice_vsi *vsi;
0054 
0055     if (ice_is_vf_disabled(np->repr->vf))
0056         return;
0057     vsi = np->repr->src_vsi;
0058 
0059     ice_update_vsi_stats(vsi);
0060     eth_stats = &vsi->eth_stats;
0061 
0062     stats->tx_packets = eth_stats->tx_unicast + eth_stats->tx_broadcast +
0063                 eth_stats->tx_multicast;
0064     stats->rx_packets = eth_stats->rx_unicast + eth_stats->rx_broadcast +
0065                 eth_stats->rx_multicast;
0066     stats->tx_bytes = eth_stats->tx_bytes;
0067     stats->rx_bytes = eth_stats->rx_bytes;
0068     stats->multicast = eth_stats->rx_multicast;
0069     stats->tx_errors = eth_stats->tx_errors;
0070     stats->tx_dropped = eth_stats->tx_discards;
0071     stats->rx_dropped = eth_stats->rx_discards;
0072 }
0073 
0074 /**
0075  * ice_netdev_to_repr - Get port representor for given netdevice
0076  * @netdev: pointer to port representor netdev
0077  */
0078 struct ice_repr *ice_netdev_to_repr(struct net_device *netdev)
0079 {
0080     struct ice_netdev_priv *np = netdev_priv(netdev);
0081 
0082     return np->repr;
0083 }
0084 
0085 /**
0086  * ice_repr_open - Enable port representor's network interface
0087  * @netdev: network interface device structure
0088  *
0089  * The open entry point is called when a port representor's network
0090  * interface is made active by the system (IFF_UP). Corresponding
0091  * VF is notified about link status change.
0092  *
0093  * Returns 0 on success
0094  */
0095 static int ice_repr_open(struct net_device *netdev)
0096 {
0097     struct ice_repr *repr = ice_netdev_to_repr(netdev);
0098     struct ice_vf *vf;
0099 
0100     vf = repr->vf;
0101     vf->link_forced = true;
0102     vf->link_up = true;
0103     ice_vc_notify_vf_link_state(vf);
0104 
0105     netif_carrier_on(netdev);
0106     netif_tx_start_all_queues(netdev);
0107 
0108     return 0;
0109 }
0110 
0111 /**
0112  * ice_repr_stop - Disable port representor's network interface
0113  * @netdev: network interface device structure
0114  *
0115  * The stop entry point is called when a port representor's network
0116  * interface is de-activated by the system. Corresponding
0117  * VF is notified about link status change.
0118  *
0119  * Returns 0 on success
0120  */
0121 static int ice_repr_stop(struct net_device *netdev)
0122 {
0123     struct ice_repr *repr = ice_netdev_to_repr(netdev);
0124     struct ice_vf *vf;
0125 
0126     vf = repr->vf;
0127     vf->link_forced = true;
0128     vf->link_up = false;
0129     ice_vc_notify_vf_link_state(vf);
0130 
0131     netif_carrier_off(netdev);
0132     netif_tx_stop_all_queues(netdev);
0133 
0134     return 0;
0135 }
0136 
0137 static struct devlink_port *
0138 ice_repr_get_devlink_port(struct net_device *netdev)
0139 {
0140     struct ice_repr *repr = ice_netdev_to_repr(netdev);
0141 
0142     return &repr->vf->devlink_port;
0143 }
0144 
0145 /**
0146  * ice_repr_sp_stats64 - get slow path stats for port representor
0147  * @dev: network interface device structure
0148  * @stats: netlink stats structure
0149  *
0150  * RX/TX stats are being swapped here to be consistent with VF stats. In slow
0151  * path, port representor receives data when the corresponding VF is sending it
0152  * (and vice versa), TX and RX bytes/packets are effectively swapped on port
0153  * representor.
0154  */
0155 static int
0156 ice_repr_sp_stats64(const struct net_device *dev,
0157             struct rtnl_link_stats64 *stats)
0158 {
0159     struct ice_netdev_priv *np = netdev_priv(dev);
0160     int vf_id = np->repr->vf->vf_id;
0161     struct ice_tx_ring *tx_ring;
0162     struct ice_rx_ring *rx_ring;
0163     u64 pkts, bytes;
0164 
0165     tx_ring = np->vsi->tx_rings[vf_id];
0166     ice_fetch_u64_stats_per_ring(&tx_ring->syncp, tx_ring->stats,
0167                      &pkts, &bytes);
0168     stats->rx_packets = pkts;
0169     stats->rx_bytes = bytes;
0170 
0171     rx_ring = np->vsi->rx_rings[vf_id];
0172     ice_fetch_u64_stats_per_ring(&rx_ring->syncp, rx_ring->stats,
0173                      &pkts, &bytes);
0174     stats->tx_packets = pkts;
0175     stats->tx_bytes = bytes;
0176     stats->tx_dropped = rx_ring->rx_stats.alloc_page_failed +
0177                 rx_ring->rx_stats.alloc_buf_failed;
0178 
0179     return 0;
0180 }
0181 
0182 static bool
0183 ice_repr_ndo_has_offload_stats(const struct net_device *dev, int attr_id)
0184 {
0185     return attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT;
0186 }
0187 
0188 static int
0189 ice_repr_ndo_get_offload_stats(int attr_id, const struct net_device *dev,
0190                    void *sp)
0191 {
0192     if (attr_id == IFLA_OFFLOAD_XSTATS_CPU_HIT)
0193         return ice_repr_sp_stats64(dev, (struct rtnl_link_stats64 *)sp);
0194 
0195     return -EINVAL;
0196 }
0197 
0198 static int
0199 ice_repr_setup_tc_cls_flower(struct ice_repr *repr,
0200                  struct flow_cls_offload *flower)
0201 {
0202     switch (flower->command) {
0203     case FLOW_CLS_REPLACE:
0204         return ice_add_cls_flower(repr->netdev, repr->src_vsi, flower);
0205     case FLOW_CLS_DESTROY:
0206         return ice_del_cls_flower(repr->src_vsi, flower);
0207     default:
0208         return -EINVAL;
0209     }
0210 }
0211 
0212 static int
0213 ice_repr_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
0214                void *cb_priv)
0215 {
0216     struct flow_cls_offload *flower = (struct flow_cls_offload *)type_data;
0217     struct ice_netdev_priv *np = (struct ice_netdev_priv *)cb_priv;
0218 
0219     switch (type) {
0220     case TC_SETUP_CLSFLOWER:
0221         return ice_repr_setup_tc_cls_flower(np->repr, flower);
0222     default:
0223         return -EOPNOTSUPP;
0224     }
0225 }
0226 
0227 static LIST_HEAD(ice_repr_block_cb_list);
0228 
0229 static int
0230 ice_repr_setup_tc(struct net_device *netdev, enum tc_setup_type type,
0231           void *type_data)
0232 {
0233     struct ice_netdev_priv *np = netdev_priv(netdev);
0234 
0235     switch (type) {
0236     case TC_SETUP_BLOCK:
0237         return flow_block_cb_setup_simple((struct flow_block_offload *)
0238                           type_data,
0239                           &ice_repr_block_cb_list,
0240                           ice_repr_setup_tc_block_cb,
0241                           np, np, true);
0242     default:
0243         return -EOPNOTSUPP;
0244     }
0245 }
0246 
0247 static const struct net_device_ops ice_repr_netdev_ops = {
0248     .ndo_get_phys_port_name = ice_repr_get_phys_port_name,
0249     .ndo_get_stats64 = ice_repr_get_stats64,
0250     .ndo_open = ice_repr_open,
0251     .ndo_stop = ice_repr_stop,
0252     .ndo_start_xmit = ice_eswitch_port_start_xmit,
0253     .ndo_get_devlink_port = ice_repr_get_devlink_port,
0254     .ndo_setup_tc = ice_repr_setup_tc,
0255     .ndo_has_offload_stats = ice_repr_ndo_has_offload_stats,
0256     .ndo_get_offload_stats = ice_repr_ndo_get_offload_stats,
0257 };
0258 
0259 /**
0260  * ice_is_port_repr_netdev - Check if a given netdevice is a port representor netdev
0261  * @netdev: pointer to netdev
0262  */
0263 bool ice_is_port_repr_netdev(struct net_device *netdev)
0264 {
0265     return netdev && (netdev->netdev_ops == &ice_repr_netdev_ops);
0266 }
0267 
0268 /**
0269  * ice_repr_reg_netdev - register port representor netdev
0270  * @netdev: pointer to port representor netdev
0271  */
0272 static int
0273 ice_repr_reg_netdev(struct net_device *netdev)
0274 {
0275     eth_hw_addr_random(netdev);
0276     netdev->netdev_ops = &ice_repr_netdev_ops;
0277     ice_set_ethtool_repr_ops(netdev);
0278 
0279     netdev->hw_features |= NETIF_F_HW_TC;
0280 
0281     netif_carrier_off(netdev);
0282     netif_tx_stop_all_queues(netdev);
0283 
0284     return register_netdev(netdev);
0285 }
0286 
0287 /**
0288  * ice_repr_add - add representor for VF
0289  * @vf: pointer to VF structure
0290  */
0291 static int ice_repr_add(struct ice_vf *vf)
0292 {
0293     struct ice_q_vector *q_vector;
0294     struct ice_netdev_priv *np;
0295     struct ice_repr *repr;
0296     struct ice_vsi *vsi;
0297     int err;
0298 
0299     vsi = ice_get_vf_vsi(vf);
0300     if (!vsi)
0301         return -EINVAL;
0302 
0303     repr = kzalloc(sizeof(*repr), GFP_KERNEL);
0304     if (!repr)
0305         return -ENOMEM;
0306 
0307 #ifdef CONFIG_ICE_SWITCHDEV
0308     repr->mac_rule = kzalloc(sizeof(*repr->mac_rule), GFP_KERNEL);
0309     if (!repr->mac_rule) {
0310         err = -ENOMEM;
0311         goto err_alloc_rule;
0312     }
0313 #endif
0314 
0315     repr->netdev = alloc_etherdev(sizeof(struct ice_netdev_priv));
0316     if (!repr->netdev) {
0317         err =  -ENOMEM;
0318         goto err_alloc;
0319     }
0320 
0321     repr->src_vsi = vsi;
0322     repr->vf = vf;
0323     vf->repr = repr;
0324     np = netdev_priv(repr->netdev);
0325     np->repr = repr;
0326 
0327     q_vector = kzalloc(sizeof(*q_vector), GFP_KERNEL);
0328     if (!q_vector) {
0329         err = -ENOMEM;
0330         goto err_alloc_q_vector;
0331     }
0332     repr->q_vector = q_vector;
0333 
0334     err = ice_devlink_create_vf_port(vf);
0335     if (err)
0336         goto err_devlink;
0337 
0338     repr->netdev->min_mtu = ETH_MIN_MTU;
0339     repr->netdev->max_mtu = ICE_MAX_MTU;
0340 
0341     SET_NETDEV_DEV(repr->netdev, ice_pf_to_dev(vf->pf));
0342     err = ice_repr_reg_netdev(repr->netdev);
0343     if (err)
0344         goto err_netdev;
0345 
0346     devlink_port_type_eth_set(&vf->devlink_port, repr->netdev);
0347 
0348     ice_virtchnl_set_repr_ops(vf);
0349 
0350     return 0;
0351 
0352 err_netdev:
0353     ice_devlink_destroy_vf_port(vf);
0354 err_devlink:
0355     kfree(repr->q_vector);
0356     vf->repr->q_vector = NULL;
0357 err_alloc_q_vector:
0358     free_netdev(repr->netdev);
0359     repr->netdev = NULL;
0360 err_alloc:
0361 #ifdef CONFIG_ICE_SWITCHDEV
0362     kfree(repr->mac_rule);
0363     repr->mac_rule = NULL;
0364 err_alloc_rule:
0365 #endif
0366     kfree(repr);
0367     vf->repr = NULL;
0368     return err;
0369 }
0370 
0371 /**
0372  * ice_repr_rem - remove representor from VF
0373  * @vf: pointer to VF structure
0374  */
0375 static void ice_repr_rem(struct ice_vf *vf)
0376 {
0377     if (!vf->repr)
0378         return;
0379 
0380     ice_devlink_destroy_vf_port(vf);
0381     kfree(vf->repr->q_vector);
0382     vf->repr->q_vector = NULL;
0383     unregister_netdev(vf->repr->netdev);
0384     free_netdev(vf->repr->netdev);
0385     vf->repr->netdev = NULL;
0386 #ifdef CONFIG_ICE_SWITCHDEV
0387     kfree(vf->repr->mac_rule);
0388     vf->repr->mac_rule = NULL;
0389 #endif
0390     kfree(vf->repr);
0391     vf->repr = NULL;
0392 
0393     ice_virtchnl_set_dflt_ops(vf);
0394 }
0395 
0396 /**
0397  * ice_repr_rem_from_all_vfs - remove port representor for all VFs
0398  * @pf: pointer to PF structure
0399  */
0400 void ice_repr_rem_from_all_vfs(struct ice_pf *pf)
0401 {
0402     struct ice_vf *vf;
0403     unsigned int bkt;
0404 
0405     lockdep_assert_held(&pf->vfs.table_lock);
0406 
0407     ice_for_each_vf(pf, bkt, vf)
0408         ice_repr_rem(vf);
0409 }
0410 
0411 /**
0412  * ice_repr_add_for_all_vfs - add port representor for all VFs
0413  * @pf: pointer to PF structure
0414  */
0415 int ice_repr_add_for_all_vfs(struct ice_pf *pf)
0416 {
0417     struct ice_vf *vf;
0418     unsigned int bkt;
0419     int err;
0420 
0421     lockdep_assert_held(&pf->vfs.table_lock);
0422 
0423     ice_for_each_vf(pf, bkt, vf) {
0424         err = ice_repr_add(vf);
0425         if (err)
0426             goto err;
0427     }
0428 
0429     return 0;
0430 
0431 err:
0432     ice_repr_rem_from_all_vfs(pf);
0433 
0434     return err;
0435 }
0436 
0437 /**
0438  * ice_repr_start_tx_queues - start Tx queues of port representor
0439  * @repr: pointer to repr structure
0440  */
0441 void ice_repr_start_tx_queues(struct ice_repr *repr)
0442 {
0443     netif_carrier_on(repr->netdev);
0444     netif_tx_start_all_queues(repr->netdev);
0445 }
0446 
0447 /**
0448  * ice_repr_stop_tx_queues - stop Tx queues of port representor
0449  * @repr: pointer to repr structure
0450  */
0451 void ice_repr_stop_tx_queues(struct ice_repr *repr)
0452 {
0453     netif_carrier_off(repr->netdev);
0454     netif_tx_stop_all_queues(repr->netdev);
0455 }
0456 
0457 /**
0458  * ice_repr_set_traffic_vsi - set traffic VSI for port representor
0459  * @repr: repr on with VSI will be set
0460  * @vsi: pointer to VSI that will be used by port representor to pass traffic
0461  */
0462 void ice_repr_set_traffic_vsi(struct ice_repr *repr, struct ice_vsi *vsi)
0463 {
0464     struct ice_netdev_priv *np = netdev_priv(repr->netdev);
0465 
0466     np->vsi = vsi;
0467 }