drivers/net/ethernet/qlogic/qed/qed_l2.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qlogic/qed/qed_l2.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/qlogic/qed/qed_l2.c
Extension
.c
Size
81703 bytes
Lines
2890
Domain
Driver Families
Bucket
drivers/net
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

struct qed_l2_info {
	u32 queues;
	unsigned long **pp_qid_usage;

	/* The lock is meant to synchronize access to the qid usage */
	struct mutex lock;
};

int qed_l2_alloc(struct qed_hwfn *p_hwfn)
{
	struct qed_l2_info *p_l2_info;
	unsigned long **pp_qids;
	u32 i;

	if (!QED_IS_L2_PERSONALITY(p_hwfn))
		return 0;

	p_l2_info = kzalloc_obj(*p_l2_info);
	if (!p_l2_info)
		return -ENOMEM;
	p_hwfn->p_l2_info = p_l2_info;

	if (IS_PF(p_hwfn->cdev)) {
		p_l2_info->queues = RESC_NUM(p_hwfn, QED_L2_QUEUE);
	} else {
		u8 rx = 0, tx = 0;

		qed_vf_get_num_rxqs(p_hwfn, &rx);
		qed_vf_get_num_txqs(p_hwfn, &tx);

		p_l2_info->queues = max_t(u8, rx, tx);
	}

	pp_qids = kcalloc(p_l2_info->queues, sizeof(unsigned long *),
			  GFP_KERNEL);
	if (!pp_qids)
		return -ENOMEM;
	p_l2_info->pp_qid_usage = pp_qids;

	for (i = 0; i < p_l2_info->queues; i++) {
		pp_qids[i] = kzalloc(MAX_QUEUES_PER_QZONE / 8, GFP_KERNEL);
		if (!pp_qids[i])
			return -ENOMEM;
	}

	return 0;
}

void qed_l2_setup(struct qed_hwfn *p_hwfn)
{
	if (!QED_IS_L2_PERSONALITY(p_hwfn))
		return;

	mutex_init(&p_hwfn->p_l2_info->lock);
}

void qed_l2_free(struct qed_hwfn *p_hwfn)
{
	u32 i;

	if (!QED_IS_L2_PERSONALITY(p_hwfn))
		return;

	if (!p_hwfn->p_l2_info)
		return;

	if (!p_hwfn->p_l2_info->pp_qid_usage)
		goto out_l2_info;

	/* Free until hit first uninitialized entry */
	for (i = 0; i < p_hwfn->p_l2_info->queues; i++) {
		if (!p_hwfn->p_l2_info->pp_qid_usage[i])
			break;
		kfree(p_hwfn->p_l2_info->pp_qid_usage[i]);
	}

	kfree(p_hwfn->p_l2_info->pp_qid_usage);

out_l2_info:
	kfree(p_hwfn->p_l2_info);
	p_hwfn->p_l2_info = NULL;
}

static bool qed_eth_queue_qid_usage_add(struct qed_hwfn *p_hwfn,
					struct qed_queue_cid *p_cid)
{
	struct qed_l2_info *p_l2_info = p_hwfn->p_l2_info;
	u16 queue_id = p_cid->rel.queue_id;
	bool b_rc = true;
	u8 first;

Annotation

Implementation Notes