X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fenic%2Fenic_ethdev.c;h=b3d57771f92fa19f9fb291a9b7711fda469e781f;hb=5922ff069fb910946f97780754ad4b66b987d5b6;hp=111bdc82c7448f562fadf8f72b9a8227bb84c734;hpb=e39c2756e21ad50d5c7e119bb82732ef49af8ef7;p=dpdk.git diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c index 111bdc82c7..b3d57771f9 100644 --- a/drivers/net/enic/enic_ethdev.c +++ b/drivers/net/enic/enic_ethdev.c @@ -24,10 +24,6 @@ int enicpmd_logtype_init; int enicpmd_logtype_flow; -#define PMD_INIT_LOG(level, fmt, args...) \ - rte_log(RTE_LOG_ ## level, enicpmd_logtype_init, \ - "%s" fmt "\n", __func__, ##args) - #define ENICPMD_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>") /* @@ -43,9 +39,7 @@ static const struct rte_pci_id pci_id_enic_map[] = { #define ENIC_DEVARG_DISABLE_OVERLAY "disable-overlay" #define ENIC_DEVARG_IG_VLAN_REWRITE "ig-vlan-rewrite" -RTE_INIT(enicpmd_init_log); -static void -enicpmd_init_log(void) +RTE_INIT(enicpmd_init_log) { enicpmd_logtype_init = rte_log_register("pmd.net.enic.init"); if (enicpmd_logtype_init >= 0) @@ -185,17 +179,21 @@ static int enicpmd_dev_tx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t queue_idx, uint16_t nb_desc, unsigned int socket_id, - __rte_unused const struct rte_eth_txconf *tx_conf) + const struct rte_eth_txconf *tx_conf) { int ret; struct enic *enic = pmd_priv(eth_dev); + struct vnic_wq *wq; if (rte_eal_process_type() != RTE_PROC_PRIMARY) return -E_RTE_SECONDARY; ENICPMD_FUNC_TRACE(); RTE_ASSERT(queue_idx < enic->conf_wq_count); - eth_dev->data->tx_queues[queue_idx] = (void *)&enic->wq[queue_idx]; + wq = &enic->wq[queue_idx]; + wq->offloads = tx_conf->offloads | + eth_dev->data->dev_conf.txmode.offloads; + eth_dev->data->tx_queues[queue_idx] = (void *)wq; ret = enic_alloc_wq(enic, queue_idx, socket_id, nb_desc); if (ret) { @@ -477,6 +475,7 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev, device_info->max_mac_addrs = ENIC_MAX_MAC_ADDR; device_info->rx_offload_capa = enic->rx_offload_capa; device_info->tx_offload_capa = enic->tx_offload_capa; + device_info->tx_queue_offload_capa = enic->tx_queue_offload_capa; device_info->default_rxconf = (struct rte_eth_rxconf) { .rx_free_thresh = ENIC_DEFAULT_RX_FREE_THRESH }; @@ -523,7 +522,8 @@ static const uint32_t *enicpmd_dev_supported_ptypes_get(struct rte_eth_dev *dev) RTE_PTYPE_UNKNOWN }; - if (dev->rx_pkt_burst == enic_recv_pkts) + if (dev->rx_pkt_burst == enic_recv_pkts || + dev->rx_pkt_burst == enic_noscatter_recv_pkts) return ptypes; return NULL; } @@ -765,7 +765,7 @@ static void enicpmd_dev_txq_info_get(struct rte_eth_dev *dev, ENICPMD_FUNC_TRACE(); qinfo->nb_desc = wq->ring.desc_count; memset(&qinfo->conf, 0, sizeof(qinfo->conf)); - qinfo->conf.offloads = enic->tx_offload_capa; + qinfo->conf.offloads = wq->offloads; /* tx_thresh, and all the other fields are not applicable for enic */ } @@ -789,6 +789,79 @@ static int enicpmd_dev_rx_queue_intr_disable(struct rte_eth_dev *eth_dev, return 0; } +static int udp_tunnel_common_check(struct enic *enic, + struct rte_eth_udp_tunnel *tnl) +{ + if (tnl->prot_type != RTE_TUNNEL_TYPE_VXLAN) + return -ENOTSUP; + if (!enic->overlay_offload) { + PMD_INIT_LOG(DEBUG, " vxlan (overlay offload) is not " + "supported\n"); + return -ENOTSUP; + } + return 0; +} + +static int update_vxlan_port(struct enic *enic, uint16_t port) +{ + if (vnic_dev_overlay_offload_cfg(enic->vdev, + OVERLAY_CFG_VXLAN_PORT_UPDATE, + port)) { + PMD_INIT_LOG(DEBUG, " failed to update vxlan port\n"); + return -EINVAL; + } + PMD_INIT_LOG(DEBUG, " updated vxlan port to %u\n", port); + enic->vxlan_port = port; + return 0; +} + +static int enicpmd_dev_udp_tunnel_port_add(struct rte_eth_dev *eth_dev, + struct rte_eth_udp_tunnel *tnl) +{ + struct enic *enic = pmd_priv(eth_dev); + int ret; + + ENICPMD_FUNC_TRACE(); + ret = udp_tunnel_common_check(enic, tnl); + if (ret) + return ret; + /* + * The NIC has 1 configurable VXLAN port number. "Adding" a new port + * number replaces it. + */ + if (tnl->udp_port == enic->vxlan_port || tnl->udp_port == 0) { + PMD_INIT_LOG(DEBUG, " %u is already configured or invalid\n", + tnl->udp_port); + return -EINVAL; + } + return update_vxlan_port(enic, tnl->udp_port); +} + +static int enicpmd_dev_udp_tunnel_port_del(struct rte_eth_dev *eth_dev, + struct rte_eth_udp_tunnel *tnl) +{ + struct enic *enic = pmd_priv(eth_dev); + int ret; + + ENICPMD_FUNC_TRACE(); + ret = udp_tunnel_common_check(enic, tnl); + if (ret) + return ret; + /* + * Clear the previously set port number and restore the + * hardware default port number. Some drivers disable VXLAN + * offloads when there are no configured port numbers. But + * enic does not do that as VXLAN is part of overlay offload, + * which is tied to inner RSS and TSO. + */ + if (tnl->udp_port != enic->vxlan_port) { + PMD_INIT_LOG(DEBUG, " %u is not a configured vxlan port\n", + tnl->udp_port); + return -EINVAL; + } + return update_vxlan_port(enic, ENIC_DEFAULT_VXLAN_PORT); +} + static const struct eth_dev_ops enicpmd_eth_dev_ops = { .dev_configure = enicpmd_dev_configure, .dev_start = enicpmd_dev_start, @@ -838,6 +911,8 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = { .reta_update = enicpmd_dev_rss_reta_update, .rss_hash_conf_get = enicpmd_dev_rss_hash_conf_get, .rss_hash_update = enicpmd_dev_rss_hash_update, + .udp_tunnel_port_add = enicpmd_dev_udp_tunnel_port_add, + .udp_tunnel_port_del = enicpmd_dev_udp_tunnel_port_del, }; static int enic_parse_disable_overlay(__rte_unused const char *key,