#include "mlx5_common.h"
#include "mlx5_common_log.h"
+#include "mlx5_common_defs.h"
#include "mlx5_common_os.h"
#include "mlx5_glue.h"
const struct mlx5_glue *mlx5_glue;
#endif
-/**
- * Get PCI information by sysfs device path.
- *
- * @param dev_path
- * Pointer to device sysfs folder name.
- * @param[out] pci_addr
- * PCI bus address output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
int
-mlx5_dev_to_pci_addr(const char *dev_path,
- struct rte_pci_addr *pci_addr)
+mlx5_get_pci_addr(const char *dev_path, struct rte_pci_addr *pci_addr)
{
FILE *file;
char line[32];
port_info_out->name_type = MLX5_PHYS_PORT_NAME_TYPE_UNKNOWN;
}
-/**
- * Get kernel interface name from IB device path.
- *
- * @param[in] ibdev_path
- * Pointer to IB device path.
- * @param[out] ifname
- * Interface name output buffer.
- *
- * @return
- * 0 on success, a negative errno value otherwise and rte_errno is set.
- */
int
mlx5_get_ifname_sysfs(const char *ibdev_path, char *ifname)
{
}
struct ibv_device *
-mlx5_os_get_ibv_device(struct rte_pci_addr *addr)
+mlx5_os_get_ibv_device(const struct rte_pci_addr *addr)
{
int n;
struct ibv_device **ibv_list = mlx5_glue->get_device_list(&n);
struct rte_pci_addr paddr;
DRV_LOG(DEBUG, "Checking device \"%s\"..", ibv_list[n]->name);
- if (mlx5_dev_to_pci_addr(ibv_list[n]->ibdev_path, &paddr) != 0)
+ if (mlx5_get_pci_addr(ibv_list[n]->ibdev_path, &paddr) != 0)
continue;
if (rte_pci_addr_cmp(addr, &paddr) != 0)
continue;
ibv_match = ibv_list[n];
break;
}
- if (ibv_match == NULL)
+ if (ibv_match == NULL) {
+ DRV_LOG(WARNING,
+ "No Verbs device matches PCI device " PCI_PRI_FMT ","
+ " are kernel drivers loaded?",
+ addr->domain, addr->bus, addr->devid, addr->function);
rte_errno = ENOENT;
+ }
mlx5_glue->free_device_list(ibv_list);
return ibv_match;
}
+
+static int
+mlx5_config_doorbell_mapping_env(int dbnc)
+{
+ char *env;
+ int value;
+
+ MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
+ /* Get environment variable to store. */
+ env = getenv(MLX5_SHUT_UP_BF);
+ value = env ? !!strcmp(env, "0") : MLX5_ARG_UNSET;
+ if (dbnc == MLX5_ARG_UNSET)
+ setenv(MLX5_SHUT_UP_BF, MLX5_SHUT_UP_BF_DEFAULT, 1);
+ else
+ setenv(MLX5_SHUT_UP_BF,
+ dbnc == MLX5_TXDB_NCACHED ? "1" : "0", 1);
+ return value;
+}
+
+static void
+mlx5_restore_doorbell_mapping_env(int value)
+{
+ MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
+ /* Restore the original environment variable state. */
+ if (value == MLX5_ARG_UNSET)
+ unsetenv(MLX5_SHUT_UP_BF);
+ else
+ setenv(MLX5_SHUT_UP_BF, value ? "1" : "0", 1);
+}
+
+/**
+ * Function API to open IB device.
+ *
+ *
+ * @param cdev
+ * Pointer to the mlx5 device.
+ * @param classes
+ * Chosen classes come from device arguments.
+ *
+ * @return
+ * 0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_os_open_device(struct mlx5_common_device *cdev, uint32_t classes)
+{
+ struct ibv_device *ibv;
+ struct ibv_context *ctx = NULL;
+ int dbmap_env;
+
+ ibv = mlx5_os_get_ibv_dev(cdev->dev);
+ if (!ibv)
+ return -rte_errno;
+ DRV_LOG(INFO, "Dev information matches for device \"%s\".", ibv->name);
+ /*
+ * Configure environment variable "MLX5_BF_SHUT_UP" before the device
+ * creation. The rdma_core library checks the variable at device
+ * creation and stores the result internally.
+ */
+ dbmap_env = mlx5_config_doorbell_mapping_env(cdev->config.dbnc);
+ /* Try to open IB device with DV first, then usual Verbs. */
+ errno = 0;
+ ctx = mlx5_glue->dv_open_device(ibv);
+ if (ctx) {
+ cdev->config.devx = 1;
+ DRV_LOG(DEBUG, "DevX is supported.");
+ } else if (classes == MLX5_CLASS_ETH) {
+ /* The environment variable is still configured. */
+ ctx = mlx5_glue->open_device(ibv);
+ if (ctx == NULL)
+ goto error;
+ DRV_LOG(DEBUG, "DevX is NOT supported.");
+ } else {
+ goto error;
+ }
+ /* The device is created, no need for environment. */
+ mlx5_restore_doorbell_mapping_env(dbmap_env);
+ /* Hint libmlx5 to use PMD allocator for data plane resources */
+ mlx5_set_context_attr(cdev->dev, ctx);
+ cdev->ctx = ctx;
+ return 0;
+error:
+ rte_errno = errno ? errno : ENODEV;
+ /* The device creation is failed, no need for environment. */
+ mlx5_restore_doorbell_mapping_env(dbmap_env);
+ DRV_LOG(ERR, "Failed to open IB device \"%s\".", ibv->name);
+ return -rte_errno;
+}