X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Flinux%2Fmlx5_os.c;h=0dcf5000e91e2fce1da5f5911a2117255d6338e3;hb=ff4e52efb39517f75eccba261c87b48cb464b246;hp=db44169b844bf45b9eea0789eef62cad0646530d;hpb=cdfdb82d0b361d9e0848917b0ed6e9cf30e46dd1;p=dpdk.git diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c index db44169b84..0dcf5000e9 100644 --- a/drivers/net/mlx5/linux/mlx5_os.c +++ b/drivers/net/mlx5/linux/mlx5_os.c @@ -786,6 +786,32 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused) #endif } +/** + * DR flow drop action support detect. + * + * @param dev + * Pointer to rte_eth_dev structure. + * + */ +static void +mlx5_flow_drop_action_config(struct rte_eth_dev *dev __rte_unused) +{ +#ifdef HAVE_MLX5DV_DR + struct mlx5_priv *priv = dev->data->dev_private; + + if (!priv->config.dv_flow_en || !priv->sh->dr_drop_action) + return; + /** + * DR supports drop action placeholder when it is supported; + * otherwise, use the queue drop action. + */ + if (mlx5_flow_discover_dr_action_support(dev)) + priv->root_drop_action = priv->drop_queue.hrxq->action; + else + priv->root_drop_action = priv->sh->dr_drop_action; +#endif +} + static void mlx5_queue_counter_id_prepare(struct rte_eth_dev *dev) { @@ -1008,8 +1034,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev, err = mlx5_proc_priv_init(eth_dev); if (err) return NULL; - mp_id.port_id = eth_dev->data->port_id; - strlcpy(mp_id.name, MLX5_MP_NAME, RTE_MP_MAX_NAME_LEN); + mlx5_mp_id_init(&mp_id, eth_dev->data->port_id); /* Receive command fd from primary process */ err = mlx5_mp_req_verbs_cmd_fd(&mp_id); if (err < 0) @@ -1181,6 +1206,13 @@ err_secondary: priv->vport_meta_tag = 0; priv->vport_meta_mask = 0; priv->pf_bond = spawn->pf_bond; + + DRV_LOG(DEBUG, + "dev_port=%u bus=%s pci=%s master=%d representor=%d pf_bond=%d\n", + priv->dev_port, dpdk_dev->bus->name, + priv->pci_dev ? priv->pci_dev->name : "NONE", + priv->master, priv->representor, priv->pf_bond); + /* * If we have E-Switch we should determine the vport attributes. * E-Switch may use either source vport field or reg_c[0] metadata @@ -1253,7 +1285,7 @@ err_secondary: * Look for sibling devices in order to reuse their switch domain * if any, otherwise allocate one. */ - MLX5_ETH_FOREACH_DEV(port_id, NULL) { + MLX5_ETH_FOREACH_DEV(port_id, dpdk_dev) { const struct mlx5_priv *opriv = rte_eth_devices[port_id].data->dev_private; @@ -1263,6 +1295,8 @@ err_secondary: RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) continue; priv->domain_id = opriv->domain_id; + DRV_LOG(DEBUG, "dev_port-%u inherit domain_id=%u\n", + priv->dev_port, priv->domain_id); break; } if (priv->domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) { @@ -1274,10 +1308,12 @@ err_secondary: goto error; } own_domain_id = 1; + DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n", + priv->dev_port, priv->domain_id); } /* Override some values set by hardware configuration. */ mlx5_args(config, dpdk_dev->devargs); - err = mlx5_dev_check_sibling_config(priv, config); + err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev); if (err) goto error; config->hw_csum = !!(sh->device_attr.device_cap_flags_ex & @@ -1364,6 +1400,8 @@ err_secondary: } sh->rq_ts_format = config->hca_attr.rq_ts_format; sh->sq_ts_format = config->hca_attr.sq_ts_format; + sh->steering_format_version = + config->hca_attr.steering_format_version; sh->qp_ts_format = config->hca_attr.qp_ts_format; /* Check for LRO support. */ if (config->dest_tir && config->hca_attr.lro_cap && @@ -1638,6 +1676,19 @@ err_secondary: if (priv->representor) { eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR; eth_dev->data->representor_id = priv->representor_id; + MLX5_ETH_FOREACH_DEV(port_id, dpdk_dev) { + struct mlx5_priv *opriv = + rte_eth_devices[port_id].data->dev_private; + if (opriv && + opriv->master && + opriv->domain_id == priv->domain_id && + opriv->sh == priv->sh) { + eth_dev->data->backer_port_id = port_id; + break; + } + } + if (port_id >= RTE_MAX_ETHPORTS) + eth_dev->data->backer_port_id = eth_dev->data->port_id; } priv->mp_id.port_id = eth_dev->data->port_id; strlcpy(priv->mp_id.name, MLX5_MP_NAME, RTE_MP_MAX_NAME_LEN); @@ -1663,11 +1714,8 @@ err_secondary: goto error; } DRV_LOG(INFO, - "port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x", - eth_dev->data->port_id, - mac.addr_bytes[0], mac.addr_bytes[1], - mac.addr_bytes[2], mac.addr_bytes[3], - mac.addr_bytes[4], mac.addr_bytes[5]); + "port %u MAC address is " RTE_ETHER_ADDR_PRT_FMT, + eth_dev->data->port_id, RTE_ETHER_ADDR_BYTES(&mac)); #ifdef RTE_LIBRTE_MLX5_DEBUG { char ifname[MLX5_NAMESIZE]; @@ -1776,6 +1824,21 @@ err_secondary: } else { priv->obj_ops = ibv_obj_ops; } + if (config->tx_pp && + (priv->config.dv_esw_en || + priv->obj_ops.txq_obj_new != mlx5_os_txq_obj_new)) { + /* + * HAVE_MLX5DV_DEVX_UAR_OFFSET is required to support + * packet pacing and already checked above. + * Hence, we should only make sure the SQs will be created + * with DevX, not with Verbs. + * Verbs allocates the SQ UAR on its own and it can't be shared + * with Clock Queue UAR as required for Tx scheduling. + */ + DRV_LOG(ERR, "Verbs SQs, UAR can't be shared as required for packet pacing"); + err = ENODEV; + goto error; + } priv->drop_queue.hrxq = mlx5_drop_action_create(eth_dev); if (!priv->drop_queue.hrxq) goto error; @@ -1847,6 +1910,7 @@ err_secondary: } rte_spinlock_init(&priv->shared_act_sl); mlx5_flow_counter_mode_config(eth_dev); + mlx5_flow_drop_action_config(eth_dev); if (priv->config.dv_flow_en) eth_dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE; return eth_dev; @@ -2081,12 +2145,14 @@ mlx5_os_config_default(struct mlx5_dev_config *config) config->txqs_inline = MLX5_ARG_UNSET; config->vf_nl_en = 1; config->mr_ext_memseg_en = 1; + config->mr_mempool_reg_en = 1; config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN; config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS; config->dv_esw_en = 1; config->dv_flow_en = 1; config->decap_en = 1; config->log_hp_size = MLX5_ARG_UNSET; + config->allow_duplicate_pattern = 1; } /** @@ -2236,19 +2302,6 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev, goto exit; } } -#ifndef HAVE_MLX5DV_DR_DEVX_PORT - if (bd >= 0) { - /* - * This may happen if there is VF LAG kernel support and - * application is compiled with older rdma_core library. - */ - DRV_LOG(ERR, - "No kernel/verbs support for VF LAG bonding found."); - rte_errno = ENOTSUP; - ret = -rte_errno; - goto exit; - } -#endif /* * Now we can determine the maximal * amount of devices to be spawned. @@ -2312,10 +2365,18 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev, (list[ns].ifindex, &list[ns].info); } -#ifdef HAVE_MLX5DV_DR_DEVX_PORT if (!ret && bd >= 0) { switch (list[ns].info.name_type) { case MLX5_PHYS_PORT_NAME_TYPE_UPLINK: + if (np == 1) { + /* + * Force standalone bonding + * device for ROCE LAG + * confgiurations. + */ + list[ns].info.master = 0; + list[ns].info.representor = 0; + } if (list[ns].info.port_name == bd) ns++; break; @@ -2332,7 +2393,6 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev, } continue; } -#endif if (!ret && (list[ns].info.representor ^ list[ns].info.master)) ns++; @@ -2515,7 +2575,6 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev, /* Default configuration. */ mlx5_os_config_default(&dev_config); dev_config.vf = dev_config_vf; - dev_config.allow_duplicate_pattern = 1; list[i].numa_node = pci_dev->device.numa_node; list[i].eth_dev = mlx5_dev_spawn(&pci_dev->device, &list[i], @@ -2529,6 +2588,31 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev, } restore = list[i].eth_dev->data->dev_flags; rte_eth_copy_pci_info(list[i].eth_dev, pci_dev); + /** + * Each representor has a dedicated interrupts vector. + * rte_eth_copy_pci_info() assigns PF interrupts handle to + * representor eth_dev object because representor and PF + * share the same PCI address. + * Override representor device with a dedicated + * interrupts handle here. + * Representor interrupts handle is released in mlx5_dev_stop(). + */ + if (list[i].info.representor) { + struct rte_intr_handle *intr_handle; + intr_handle = mlx5_malloc(MLX5_MEM_SYS | MLX5_MEM_ZERO, + sizeof(*intr_handle), 0, + SOCKET_ID_ANY); + if (!intr_handle) { + DRV_LOG(ERR, + "port %u failed to allocate memory for interrupt handler " + "Rx interrupts will not be supported", + i); + rte_errno = ENOMEM; + ret = -rte_errno; + goto exit; + } + list[i].eth_dev->intr_handle = intr_handle; + } /* Restore non-PCI flags cleared by the above call. */ list[i].eth_dev->data->dev_flags |= restore; rte_eth_dev_probing_finish(list[i].eth_dev); @@ -2626,9 +2710,20 @@ mlx5_os_pci_probe(struct rte_pci_device *pci_dev) if (eth_da.nb_ports > 0) { /* Iterate all port if devargs pf is range: "pf[0-1]vf[...]". */ - for (p = 0; p < eth_da.nb_ports; p++) + for (p = 0; p < eth_da.nb_ports; p++) { ret = mlx5_os_pci_probe_pf(pci_dev, ð_da, eth_da.ports[p]); + if (ret) + break; + } + if (ret) { + DRV_LOG(ERR, "Probe of PCI device " PCI_PRI_FMT " " + "aborted due to proding failure of PF %u", + pci_dev->addr.domain, pci_dev->addr.bus, + pci_dev->addr.devid, pci_dev->addr.function, + eth_da.ports[p]); + mlx5_net_remove(&pci_dev->device); + } } else { ret = mlx5_os_pci_probe_pf(pci_dev, ð_da, 0); }