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.
- 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/module.hlinux/errno.hlinux/types.hlinux/debugfs.hlinux/export.hlinux/list.hlinux/skbuff.hlinux/pci.hcxgb4.hcxgb4_uld.ht4_regs.ht4fw_api.ht4_msg.h
Detected Declarations
function uldrx_flush_handlerfunction uldrx_handlerfunction alloc_uld_rxqsfunction setup_sge_queues_uldfunction for_each_portfunction t4_free_uld_rxqsfunction free_sge_queues_uldfunction for_each_portfunction cfg_queues_uldfunction free_queues_uldfunction request_msix_queue_irqs_uldfunction for_each_uldrxqfunction free_msix_queue_irqs_uldfunction for_each_uldrxqfunction enable_rx_uldfunction for_each_uldrxqfunction quiesce_rx_uldfunction for_each_uldrxqfunction free_sge_txq_uldfunction alloc_sge_txq_uldfunction release_sge_txq_uldfunction setup_sge_txq_uldfunction uld_queue_initfunction t4_uld_mem_allocfunction t4_uld_mem_freefunction cxgb4_shutdown_uld_adapterfunction t4_uld_clean_upfunction uld_initfunction uld_attachfunction cxgb4_uld_in_usefunction cxgb4_set_ktls_featurefunction cxgb4_uld_alloc_resourcesfunction cxgb4_uld_enablefunction cxgb4_register_uldfunction cxgb4_unregister_uldfunction list_for_each_entry_safeexport cxgb4_register_uldexport cxgb4_unregister_uld
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, ¶m, &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
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/errno.h`, `linux/types.h`, `linux/debugfs.h`, `linux/export.h`, `linux/list.h`, `linux/skbuff.h`.
- Detected declarations: `function uldrx_flush_handler`, `function uldrx_handler`, `function alloc_uld_rxqs`, `function setup_sge_queues_uld`, `function for_each_port`, `function t4_free_uld_rxqs`, `function free_sge_queues_uld`, `function for_each_port`, `function cfg_queues_uld`, `function free_queues_uld`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.