X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fice%2Fice_dcf_ethdev.c;h=e0772295e91688874ae25d5dd2ba95851ee53a39;hb=e8a419d6de4b251e84a36d09e388942283d09adf;hp=2faed3cc7a7b6f81ca84500f236524a0e43f2eab;hpb=f3fddc93de16dbd3acdb859699601aef948e3e1e;p=dpdk.git diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c index 2faed3cc7a..e0772295e9 100644 --- a/drivers/net/ice/ice_dcf_ethdev.c +++ b/drivers/net/ice/ice_dcf_ethdev.c @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -26,6 +26,13 @@ #include "ice_dcf_ethdev.h" #include "ice_rxtx.h" +static int +ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel); +static int +ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel); + static uint16_t ice_dcf_recv_pkts(__rte_unused void *rx_queue, __rte_unused struct rte_mbuf **bufs, @@ -60,23 +67,23 @@ ice_dcf_init_rxq(struct rte_eth_dev *dev, struct ice_rx_queue *rxq) * correctly. */ if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) { - if (max_pkt_len <= RTE_ETHER_MAX_LEN || + if (max_pkt_len <= ICE_ETH_MAX_LEN || max_pkt_len > ICE_FRAME_SIZE_MAX) { PMD_DRV_LOG(ERR, "maximum packet length must be " "larger than %u and smaller than %u, " "as jumbo frame is enabled", - (uint32_t)RTE_ETHER_MAX_LEN, + (uint32_t)ICE_ETH_MAX_LEN, (uint32_t)ICE_FRAME_SIZE_MAX); return -EINVAL; } } else { if (max_pkt_len < RTE_ETHER_MIN_LEN || - max_pkt_len > RTE_ETHER_MAX_LEN) { + max_pkt_len > ICE_ETH_MAX_LEN) { PMD_DRV_LOG(ERR, "maximum packet length must be " "larger than %u and smaller than %u, " "as jumbo frame is disabled", (uint32_t)RTE_ETHER_MIN_LEN, - (uint32_t)RTE_ETHER_MAX_LEN); + (uint32_t)ICE_ETH_MAX_LEN); return -EINVAL; } } @@ -589,7 +596,7 @@ ice_dcf_stop_queues(struct rte_eth_dev *dev) } } -static void +static int ice_dcf_dev_stop(struct rte_eth_dev *dev) { struct ice_dcf_adapter *dcf_ad = dev->data->dev_private; @@ -598,9 +605,12 @@ ice_dcf_dev_stop(struct rte_eth_dev *dev) if (ad->pf.adapter_stopped == 1) { PMD_DRV_LOG(DEBUG, "Port is already stopped"); - return; + return 0; } + /* Stop the VF representors for this device */ + ice_dcf_vf_repr_stop_all(dcf_ad); + ice_dcf_stop_queues(dev); rte_intr_efd_disable(intr_handle); @@ -612,6 +622,8 @@ ice_dcf_dev_stop(struct rte_eth_dev *dev) ice_dcf_add_del_all_mac_addr(&dcf_ad->real_hw, false); dev->data->dev_link.link_status = ETH_LINK_DOWN; ad->pf.adapter_stopped = 1; + + return 0; } static int @@ -848,19 +860,42 @@ ice_dcf_stats_reset(struct rte_eth_dev *dev) } static void +ice_dcf_free_repr_info(struct ice_dcf_adapter *dcf_adapter) +{ + if (dcf_adapter->repr_infos) { + rte_free(dcf_adapter->repr_infos); + dcf_adapter->repr_infos = NULL; + } +} + +static int +ice_dcf_init_repr_info(struct ice_dcf_adapter *dcf_adapter) +{ + dcf_adapter->repr_infos = + rte_calloc("ice_dcf_rep_info", + dcf_adapter->real_hw.num_vfs, + sizeof(dcf_adapter->repr_infos[0]), 0); + if (!dcf_adapter->repr_infos) { + PMD_DRV_LOG(ERR, "Failed to alloc memory for VF representors\n"); + return -ENOMEM; + } + + return 0; +} + +static int ice_dcf_dev_close(struct rte_eth_dev *dev) { struct ice_dcf_adapter *adapter = dev->data->dev_private; if (rte_eal_process_type() != RTE_PROC_PRIMARY) - return; - - dev->dev_ops = NULL; - dev->rx_pkt_burst = NULL; - dev->tx_pkt_burst = NULL; + return 0; + ice_dcf_free_repr_info(adapter); ice_dcf_uninit_parent_adapter(dev); ice_dcf_uninit_hw(dev, &adapter->real_hw); + + return 0; } static int @@ -870,6 +905,64 @@ ice_dcf_link_update(__rte_unused struct rte_eth_dev *dev, return 0; } +/* Add UDP tunneling port */ +static int +ice_dcf_dev_udp_tunnel_port_add(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel) +{ + struct ice_dcf_adapter *adapter = dev->data->dev_private; + struct ice_adapter *parent_adapter = &adapter->parent; + struct ice_hw *parent_hw = &parent_adapter->hw; + int ret = 0; + + if (!udp_tunnel) + return -EINVAL; + + switch (udp_tunnel->prot_type) { + case RTE_TUNNEL_TYPE_VXLAN: + ret = ice_create_tunnel(parent_hw, TNL_VXLAN, + udp_tunnel->udp_port); + break; + case RTE_TUNNEL_TYPE_ECPRI: + ret = ice_create_tunnel(parent_hw, TNL_ECPRI, + udp_tunnel->udp_port); + break; + default: + PMD_DRV_LOG(ERR, "Invalid tunnel type"); + ret = -EINVAL; + break; + } + + return ret; +} + +/* Delete UDP tunneling port */ +static int +ice_dcf_dev_udp_tunnel_port_del(struct rte_eth_dev *dev, + struct rte_eth_udp_tunnel *udp_tunnel) +{ + struct ice_dcf_adapter *adapter = dev->data->dev_private; + struct ice_adapter *parent_adapter = &adapter->parent; + struct ice_hw *parent_hw = &parent_adapter->hw; + int ret = 0; + + if (!udp_tunnel) + return -EINVAL; + + switch (udp_tunnel->prot_type) { + case RTE_TUNNEL_TYPE_VXLAN: + case RTE_TUNNEL_TYPE_ECPRI: + ret = ice_destroy_tunnel(parent_hw, udp_tunnel->udp_port, 0); + break; + default: + PMD_DRV_LOG(ERR, "Invalid tunnel type"); + ret = -EINVAL; + break; + } + + return ret; +} + static const struct eth_dev_ops ice_dcf_eth_dev_ops = { .dev_start = ice_dcf_dev_start, .dev_stop = ice_dcf_dev_stop, @@ -892,6 +985,8 @@ static const struct eth_dev_ops ice_dcf_eth_dev_ops = { .allmulticast_enable = ice_dcf_dev_allmulticast_enable, .allmulticast_disable = ice_dcf_dev_allmulticast_disable, .filter_ctrl = ice_dcf_dev_filter_ctrl, + .udp_tunnel_port_add = ice_dcf_dev_udp_tunnel_port_add, + .udp_tunnel_port_del = ice_dcf_dev_udp_tunnel_port_del, }; static int @@ -906,7 +1001,7 @@ ice_dcf_dev_init(struct rte_eth_dev *eth_dev) if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; - eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; + eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg; if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) { @@ -970,20 +1065,114 @@ exit: return ret; } -static int eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv, - struct rte_pci_device *pci_dev) +static int +eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv, + struct rte_pci_device *pci_dev) { + struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 }; + struct ice_dcf_vf_repr_param repr_param; + char repr_name[RTE_ETH_NAME_MAX_LEN]; + struct ice_dcf_adapter *dcf_adapter; + struct rte_eth_dev *dcf_ethdev; + uint16_t dcf_vsi_id; + int i, ret; + if (!ice_dcf_cap_selected(pci_dev->device.devargs)) return 1; - return rte_eth_dev_pci_generic_probe(pci_dev, - sizeof(struct ice_dcf_adapter), - ice_dcf_dev_init); + ret = rte_eth_devargs_parse(pci_dev->device.devargs->args, ð_da); + if (ret) + return ret; + + ret = rte_eth_dev_pci_generic_probe(pci_dev, + sizeof(struct ice_dcf_adapter), + ice_dcf_dev_init); + if (ret || !eth_da.nb_representor_ports) + return ret; + + dcf_ethdev = rte_eth_dev_allocated(pci_dev->device.name); + if (dcf_ethdev == NULL) + return -ENODEV; + + dcf_adapter = dcf_ethdev->data->dev_private; + ret = ice_dcf_init_repr_info(dcf_adapter); + if (ret) + return ret; + + if (eth_da.nb_representor_ports > dcf_adapter->real_hw.num_vfs || + eth_da.nb_representor_ports >= RTE_MAX_ETHPORTS) { + PMD_DRV_LOG(ERR, "the number of port representors is too large: %u", + eth_da.nb_representor_ports); + ice_dcf_free_repr_info(dcf_adapter); + return -EINVAL; + } + + dcf_vsi_id = dcf_adapter->real_hw.vsi_id | VIRTCHNL_DCF_VF_VSI_VALID; + + repr_param.dcf_eth_dev = dcf_ethdev; + repr_param.switch_domain_id = 0; + + for (i = 0; i < eth_da.nb_representor_ports; i++) { + uint16_t vf_id = eth_da.representor_ports[i]; + struct rte_eth_dev *vf_rep_eth_dev; + + if (vf_id >= dcf_adapter->real_hw.num_vfs) { + PMD_DRV_LOG(ERR, "VF ID %u is out of range (0 ~ %u)", + vf_id, dcf_adapter->real_hw.num_vfs - 1); + ret = -EINVAL; + break; + } + + if (dcf_adapter->real_hw.vf_vsi_map[vf_id] == dcf_vsi_id) { + PMD_DRV_LOG(ERR, "VF ID %u is DCF's ID.\n", vf_id); + ret = -EINVAL; + break; + } + + repr_param.vf_id = vf_id; + snprintf(repr_name, sizeof(repr_name), "net_%s_representor_%u", + pci_dev->device.name, vf_id); + ret = rte_eth_dev_create(&pci_dev->device, repr_name, + sizeof(struct ice_dcf_vf_repr), + NULL, NULL, ice_dcf_vf_repr_init, + &repr_param); + if (ret) { + PMD_DRV_LOG(ERR, "failed to create DCF VF representor %s", + repr_name); + break; + } + + vf_rep_eth_dev = rte_eth_dev_allocated(repr_name); + if (!vf_rep_eth_dev) { + PMD_DRV_LOG(ERR, + "Failed to find the ethdev for DCF VF representor: %s", + repr_name); + ret = -ENODEV; + break; + } + + dcf_adapter->repr_infos[vf_id].vf_rep_eth_dev = vf_rep_eth_dev; + dcf_adapter->num_reprs++; + } + + return ret; } -static int eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev) +static int +eth_ice_dcf_pci_remove(struct rte_pci_device *pci_dev) { - return rte_eth_dev_pci_generic_remove(pci_dev, ice_dcf_dev_uninit); + struct rte_eth_dev *eth_dev; + + eth_dev = rte_eth_dev_allocated(pci_dev->device.name); + if (!eth_dev) + return 0; + + if (eth_dev->data->dev_flags & RTE_ETH_DEV_REPRESENTOR) + return rte_eth_dev_pci_generic_remove(pci_dev, + ice_dcf_vf_repr_uninit); + else + return rte_eth_dev_pci_generic_remove(pci_dev, + ice_dcf_dev_uninit); } static const struct rte_pci_id pci_id_ice_dcf_map[] = {