in prov/efa/src/efa_fabric.c [281:482]
static int efa_alloc_fid_nic(struct fi_info *fi, struct efa_context *ctx,
struct efa_device_attr *efa_device_attr,
struct ibv_port_attr *port_attr)
{
struct fi_device_attr *device_attr;
char driver_real_path[PATH_MAX];
struct fi_link_attr *link_attr;
char dbdf_real_path[PATH_MAX];
struct fi_bus_attr *bus_attr;
struct fi_pci_attr *pci_attr;
char *driver_sym_path;
char *dbdf_sym_path;
char *sysfs_path;
void *src_addr;
char *driver;
int name_len;
char *dbdf;
int ret;
int max_hdr_size = 0;
int pkt_type = RXR_REQ_PKT_BEGIN;
/* Sets nic ops and allocates basic structure */
fi->nic = ofi_nic_dup(NULL);
if (!fi->nic)
return -FI_ENOMEM;
device_attr = fi->nic->device_attr;
bus_attr = fi->nic->bus_attr;
pci_attr = &bus_attr->attr.pci;
link_attr = fi->nic->link_attr;
/* fi_device_attr */
device_attr->name = strdup(ctx->ibv_ctx->device->name);
if (!device_attr->name) {
ret = -FI_ENOMEM;
goto err_free_nic;
}
ret = asprintf(&device_attr->device_id, "0x%x",
efa_device_attr->ibv_attr.vendor_part_id);
/* ofi_nic_close will free all attributes of the fi_nic struct */
if (ret < 0) {
ret = -FI_ENOMEM;
goto err_free_nic;
}
device_attr->device_version = calloc(1, EFA_ABI_VER_MAX_LEN + 1);
if (!device_attr->device_version) {
ret = -FI_ENOMEM;
goto err_free_nic;
}
sysfs_path = get_sysfs_path();
if (!sysfs_path) {
ret = -FI_ENOMEM;
goto err_free_nic;
}
ret = fi_read_file(sysfs_path, "class/infiniband_verbs/abi_version",
device_attr->device_version,
sizeof(device_attr->device_version));
if (ret < 0)
goto err_free_sysfs;
ret = asprintf(&device_attr->vendor_id, "0x%x",
efa_device_attr->ibv_attr.vendor_id);
if (ret < 0) {
ret = -FI_ENOMEM;
goto err_free_sysfs;
}
ret = asprintf(&driver_sym_path, "%s%s",
ctx->ibv_ctx->device->ibdev_path, "/device/driver");
if (ret < 0) {
ret = -FI_ENOMEM;
goto err_free_sysfs;
}
if (!realpath(driver_sym_path, driver_real_path)) {
ret = -errno;
goto err_free_driver_sym;
}
driver = strrchr(driver_real_path, '/');
if (!driver) {
ret = -FI_EINVAL;
goto err_free_driver_sym;
}
driver++;
device_attr->driver = strdup(driver);
if (!device_attr->driver) {
ret = -FI_ENOMEM;
goto err_free_driver_sym;
}
device_attr->firmware = strdup(efa_device_attr->ibv_attr.fw_ver);
if (!device_attr->firmware) {
ret = -FI_ENOMEM;
goto err_free_driver_sym;
}
/* fi_bus_attr */
bus_attr->bus_type = FI_BUS_PCI;
/* fi_pci_attr */
ret = asprintf(&dbdf_sym_path, "%s%s",
ctx->ibv_ctx->device->ibdev_path, "/device");
if (ret < 0) {
ret = -FI_ENOMEM;
goto err_free_driver_sym;
}
if (!realpath(dbdf_sym_path, dbdf_real_path)) {
ret = -errno;
goto err_free_dbdf_sym;
}
dbdf = strrchr(dbdf_real_path, '/');
if (!dbdf) {
ret = -FI_EINVAL;
goto err_free_dbdf_sym;
}
dbdf++;
ret = sscanf(dbdf, "%hx:%hhx:%hhx.%hhx", &pci_attr->domain_id,
&pci_attr->bus_id, &pci_attr->device_id,
&pci_attr->function_id);
if (ret != 4) {
ret = -FI_EINVAL;
goto err_free_dbdf_sym;
}
/* fi_link_attr */
src_addr = calloc(1, EFA_EP_ADDR_LEN);
if (!src_addr) {
ret = -FI_ENOMEM;
goto err_free_dbdf_sym;
}
ret = efa_get_addr(ctx, src_addr);
if (ret)
goto err_free_src_addr;
name_len = strlen(EFA_FABRIC_PREFIX) + INET6_ADDRSTRLEN;
link_attr->address = calloc(1, name_len + 1);
if (!link_attr->address) {
ret = -FI_ENOMEM;
goto err_free_src_addr;
}
efa_addr_to_str(src_addr, link_attr->address);
while (pkt_type < RXR_EXTRA_REQ_PKT_END) {
max_hdr_size = MAX(max_hdr_size,
rxr_pkt_req_max_header_size(pkt_type));
if (pkt_type == RXR_BASELINE_REQ_PKT_END)
pkt_type = RXR_EXTRA_REQ_PKT_BEGIN;
else
pkt_type += 1;
}
link_attr->mtu = port_attr->max_msg_sz - max_hdr_size;
link_attr->speed = ofi_vrb_speed(port_attr->active_speed,
port_attr->active_width);
switch (port_attr->state) {
case IBV_PORT_DOWN:
link_attr->state = FI_LINK_DOWN;
break;
case IBV_PORT_ACTIVE:
link_attr->state = FI_LINK_UP;
break;
default:
link_attr->state = FI_LINK_UNKNOWN;
break;
}
link_attr->network_type = strdup("Ethernet");
if (!link_attr->network_type) {
ret = -FI_ENOMEM;
goto err_free_src_addr;
}
free(src_addr);
free(dbdf_sym_path);
free(driver_sym_path);
free(sysfs_path);
return FI_SUCCESS;
err_free_src_addr:
free(src_addr);
err_free_dbdf_sym:
free(dbdf_sym_path);
err_free_driver_sym:
free(driver_sym_path);
err_free_sysfs:
free(sysfs_path);
err_free_nic:
fi_close(&fi->nic->fid);
fi->nic = NULL;
return ret;
}