drivers/infiniband/core/mad.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/core/mad.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/core/mad.c
Extension
.c
Size
98139 bytes
Lines
3419
Domain
Driver Families
Bucket
drivers/infiniband
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (!memcmp(vendor_class->oui[i], mad_reg_req->oui, 3)) {
			method = vendor_class->method_table[i];
			if (method) {
				if (method_in_use(&method, mad_reg_req))
					return 1;
				else
					break;
			}
		}
	}
	return 0;
}

int ib_response_mad(const struct ib_mad_hdr *hdr)
{
	return ((hdr->method & IB_MGMT_METHOD_RESP) ||
		(hdr->method == IB_MGMT_METHOD_TRAP_REPRESS) ||
		((hdr->mgmt_class == IB_MGMT_CLASS_BM) &&
		 (hdr->attr_mod & IB_BM_ATTR_MOD_RESP)));
}
EXPORT_SYMBOL(ib_response_mad);

#define SOL_FC_MAX_DEFAULT_FRAC 4
#define SOL_FC_MAX_SA_FRAC 32

static int get_sol_fc_max_outstanding(struct ib_mad_reg_req *mad_reg_req)
{
	if (!mad_reg_req)
		/* Send only agent */
		return mad_recvq_size / SOL_FC_MAX_DEFAULT_FRAC;

	switch (mad_reg_req->mgmt_class) {
	case IB_MGMT_CLASS_CM:
		return mad_recvq_size / SOL_FC_MAX_DEFAULT_FRAC;
	case IB_MGMT_CLASS_SUBN_ADM:
		return mad_recvq_size / SOL_FC_MAX_SA_FRAC;
	case IB_MGMT_CLASS_SUBN_LID_ROUTED:
	case IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE:
		return min(mad_recvq_size, IB_MAD_QP_RECV_SIZE) /
		       SOL_FC_MAX_DEFAULT_FRAC;
	default:
		return 0;
	}
}

/*
 * ib_register_mad_agent - Register to send/receive MADs
 *
 * Context: Process context.
 */
struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
					   u32 port_num,
					   enum ib_qp_type qp_type,
					   struct ib_mad_reg_req *mad_reg_req,
					   u8 rmpp_version,
					   ib_mad_send_handler send_handler,
					   ib_mad_recv_handler recv_handler,
					   void *context,
					   u32 registration_flags)
{
	struct ib_mad_port_private *port_priv;
	struct ib_mad_agent *ret = ERR_PTR(-EINVAL);
	struct ib_mad_agent_private *mad_agent_priv;
	struct ib_mad_reg_req *reg_req = NULL;
	struct ib_mad_mgmt_class_table *class;
	struct ib_mad_mgmt_vendor_class_table *vendor;
	struct ib_mad_mgmt_vendor_class *vendor_class;
	struct ib_mad_mgmt_method_table *method;
	int ret2, qpn;
	u8 mgmt_class, vclass;

	if ((qp_type == IB_QPT_SMI && !rdma_cap_ib_smi(device, port_num)) ||
	    (qp_type == IB_QPT_GSI && !rdma_cap_ib_cm(device, port_num)))
		return ERR_PTR(-EPROTONOSUPPORT);

	/* Validate parameters */
	qpn = get_spl_qp_index(qp_type);
	if (qpn == -1) {
		dev_dbg_ratelimited(&device->dev, "%s: invalid QP Type %d\n",
				    __func__, qp_type);
		goto error1;
	}

	if (rmpp_version && rmpp_version != IB_MGMT_RMPP_VERSION) {
		dev_dbg_ratelimited(&device->dev,
				    "%s: invalid RMPP Version %u\n",
				    __func__, rmpp_version);
		goto error1;
	}

Annotation

Implementation Notes