drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
Extension
.c
Size
22975 bytes
Lines
854
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

if (i == rxq_info->nrxq) {
			/* start allocation of concentrator queues */
			per_chan = rxq_info->nciq / adap->params.nports;
			que_idx = 0;
		}

		if (msi_idx >= 0) {
			msi_idx = cxgb4_get_msix_idx_from_bmap(adap);
			if (msi_idx < 0) {
				err = -ENOSPC;
				goto freeout;
			}

			snprintf(adap->msix_info[msi_idx].desc,
				 sizeof(adap->msix_info[msi_idx].desc),
				 "%s-%s%d",
				 adap->port[0]->name, rxq_info->name, i);

			q->msix = &adap->msix_info[msi_idx];
		}
		err = t4_sge_alloc_rxq(adap, &q->rspq, false,
				       adap->port[que_idx++ / per_chan],
				       msi_idx,
				       q->fl.size ? &q->fl : NULL,
				       uldrx_handler,
				       lro ? uldrx_flush_handler : NULL,
				       0);
		if (err)
			goto freeout;

		memset(&q->stats, 0, sizeof(q->stats));
		if (ids)
			ids[i] = q->rspq.abs_id;
	}
	return 0;
freeout:
	q = rxq_info->uldrxq;
	for ( ; i; i--, q++) {
		if (q->rspq.desc)
			free_rspq_fl(adap, &q->rspq,
				     q->fl.size ? &q->fl : NULL);
		if (q->msix)
			cxgb4_free_msix_idx_in_bmap(adap, q->msix->idx);
	}
	return err;
}

static int
setup_sge_queues_uld(struct adapter *adap, unsigned int uld_type, bool lro)
{
	struct sge_uld_rxq_info *rxq_info = adap->sge.uld_rxq_info[uld_type];
	int i, ret;

	ret = alloc_uld_rxqs(adap, rxq_info, lro);
	if (ret)
		return ret;

	/* Tell uP to route control queue completions to rdma rspq */
	if (adap->flags & CXGB4_FULL_INIT_DONE && uld_type == CXGB4_ULD_RDMA) {
		struct sge *s = &adap->sge;
		unsigned int cmplqid;
		u32 param, cmdop;

		cmdop = FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL;
		for_each_port(adap, i) {
			cmplqid = rxq_info->uldrxq[i].rspq.cntxt_id;
			param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) |
				 FW_PARAMS_PARAM_X_V(cmdop) |
				 FW_PARAMS_PARAM_YZ_V(s->ctrlq[i].q.cntxt_id));
			ret = t4_set_params(adap, adap->mbox, adap->pf,
					    0, 1, &param, &cmplqid);
		}
	}
	return ret;
}

static void t4_free_uld_rxqs(struct adapter *adap, int n,
			     struct sge_ofld_rxq *q)
{
	for ( ; n; n--, q++) {
		if (q->rspq.desc)
			free_rspq_fl(adap, &q->rspq,
				     q->fl.size ? &q->fl : NULL);
	}
}

static void free_sge_queues_uld(struct adapter *adap, unsigned int uld_type)
{
	struct sge_uld_rxq_info *rxq_info = adap->sge.uld_rxq_info[uld_type];

Annotation

Implementation Notes