drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/vmw_pvrdma/pvrdma_verbs.c
Extension
.c
Size
15760 bytes
Lines
531
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret) {
			pvrdma_dealloc_pd(&pd->ibpd, udata);
			return ret;
		}
	}

	/* u32 pd handle */
	return 0;

err:
	atomic_dec(&dev->num_pds);
	return ret;
}

/**
 * pvrdma_dealloc_pd - deallocate protection domain
 * @pd: the protection domain to be released
 * @udata: user data or null for kernel object
 *
 * @return: Always 0
 */
int pvrdma_dealloc_pd(struct ib_pd *pd, struct ib_udata *udata)
{
	struct pvrdma_dev *dev = to_vdev(pd->device);
	union pvrdma_cmd_req req = {};
	struct pvrdma_cmd_destroy_pd *cmd = &req.destroy_pd;
	int ret;

	cmd->hdr.cmd = PVRDMA_CMD_DESTROY_PD;
	cmd->pd_handle = to_vpd(pd)->pd_handle;

	ret = pvrdma_cmd_post(dev, &req, NULL, 0);
	if (ret)
		dev_warn(&dev->pdev->dev,
			 "could not dealloc protection domain, error: %d\n",
			 ret);

	atomic_dec(&dev->num_pds);
	return 0;
}

/**
 * pvrdma_create_ah - create an address handle
 * @ibah: the IB address handle
 * @init_attr: the attributes of the AH
 * @udata: pointer to user data
 *
 * @return: 0 on success, otherwise errno.
 */
int pvrdma_create_ah(struct ib_ah *ibah, struct rdma_ah_init_attr *init_attr,
		     struct ib_udata *udata)
{
	struct rdma_ah_attr *ah_attr = init_attr->ah_attr;
	struct pvrdma_dev *dev = to_vdev(ibah->device);
	struct pvrdma_ah *ah = to_vah(ibah);
	const struct ib_global_route *grh;
	u32 port_num = rdma_ah_get_port_num(ah_attr);

	if (!(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
		return -EINVAL;

	grh = rdma_ah_read_grh(ah_attr);
	if ((ah_attr->type != RDMA_AH_ATTR_TYPE_ROCE)  ||
	    rdma_is_multicast_addr((struct in6_addr *)grh->dgid.raw))
		return -EINVAL;

	if (!atomic_add_unless(&dev->num_ahs, 1, dev->dsr->caps.max_ah))
		return -ENOMEM;

	ah->av.port_pd = to_vpd(ibah->pd)->pd_handle | (port_num << 24);
	ah->av.src_path_bits = rdma_ah_get_path_bits(ah_attr);
	ah->av.src_path_bits |= 0x80;
	ah->av.gid_index = grh->sgid_index;
	ah->av.hop_limit = grh->hop_limit;
	ah->av.sl_tclass_flowlabel = (grh->traffic_class << 20) |
				      grh->flow_label;
	memcpy(ah->av.dgid, grh->dgid.raw, 16);
	memcpy(ah->av.dmac, ah_attr->roce.dmac, ETH_ALEN);

	return 0;
}

/**
 * pvrdma_destroy_ah - destroy an address handle
 * @ah: the address handle to destroyed
 * @flags: destroy address handle flags (see enum rdma_destroy_ah_flags)
 *
 */
int pvrdma_destroy_ah(struct ib_ah *ah, u32 flags)
{

Annotation

Implementation Notes