drivers/net/ethernet/qlogic/qed/qed_spq.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qlogic/qed/qed_spq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/qlogic/qed/qed_spq.c- Extension
.c- Size
- 27693 bytes
- Lines
- 1052
- Domain
- Driver Families
- Bucket
- drivers/net
- 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.
- 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.
- 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/types.hasm/byteorder.hlinux/io.hlinux/delay.hlinux/dma-mapping.hlinux/errno.hlinux/kernel.hlinux/list.hlinux/pci.hlinux/slab.hlinux/spinlock.hlinux/string.hqed.hqed_cxt.hqed_dev_api.hqed_hsi.hqed_iro_hsi.hqed_hw.hqed_int.hqed_iscsi.hqed_mcp.hqed_ooo.hqed_reg_addr.hqed_sp.hqed_sriov.hqed_rdma.h
Detected Declarations
function Copyrightfunction __qed_spq_blockfunction qed_spq_blockfunction qed_spq_fill_entryfunction qed_spq_hw_initializefunction qed_spq_hw_postfunction qed_async_event_completionfunction qed_spq_register_async_cbfunction qed_spq_unregister_async_cbfunction qed_eq_prod_updatefunction qed_eq_completionfunction qed_eq_allocfunction qed_eq_setupfunction qed_eq_freefunction qed_cqe_completionfunction qed_eth_cqe_completionfunction Queuefunction qed_spq_allocfunction qed_spq_freefunction qed_spq_get_entryfunction __qed_spq_return_entryfunction qed_spq_return_entryfunction qed_spq_add_entryfunction qed_spq_get_cidfunction qed_spq_post_listfunction qed_spq_pend_postfunction qed_spq_recov_set_ret_codefunction qed_spq_comp_bmap_updatefunction qed_spq_postfunction qed_spq_completionfunction qed_consq_allocfunction qed_consq_setupfunction qed_consq_free
Annotated Snippet
if (smp_load_acquire(&comp_done->done) == 1) { /* ^^^ */
if (p_fw_ret)
*p_fw_ret = comp_done->fw_return_code;
return 0;
}
if (sleep_between_iter)
msleep(SPQ_BLOCK_SLEEP_MS);
else
udelay(SPQ_BLOCK_DELAY_US);
}
return -EBUSY;
}
static int qed_spq_block(struct qed_hwfn *p_hwfn,
struct qed_spq_entry *p_ent,
u8 *p_fw_ret, bool skip_quick_poll)
{
struct qed_spq_comp_done *comp_done;
struct qed_ptt *p_ptt;
int rc;
/* A relatively short polling period w/o sleeping, to allow the FW to
* complete the ramrod and thus possibly to avoid the following sleeps.
*/
if (!skip_quick_poll) {
rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, false);
if (!rc)
return 0;
}
/* Move to polling with a sleeping period between iterations */
rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true);
if (!rc)
return 0;
p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt) {
DP_NOTICE(p_hwfn, "ptt, failed to acquire\n");
return -EAGAIN;
}
DP_INFO(p_hwfn, "Ramrod is stuck, requesting MCP drain\n");
rc = qed_mcp_drain(p_hwfn, p_ptt);
qed_ptt_release(p_hwfn, p_ptt);
if (rc) {
DP_NOTICE(p_hwfn, "MCP drain failed\n");
goto err;
}
/* Retry after drain */
rc = __qed_spq_block(p_hwfn, p_ent, p_fw_ret, true);
if (!rc)
return 0;
comp_done = (struct qed_spq_comp_done *)p_ent->comp_cb.cookie;
if (comp_done->done == 1) {
if (p_fw_ret)
*p_fw_ret = comp_done->fw_return_code;
return 0;
}
err:
p_ptt = qed_ptt_acquire(p_hwfn);
if (!p_ptt)
return -EBUSY;
qed_hw_err_notify(p_hwfn, p_ptt, QED_HW_ERR_RAMROD_FAIL,
"Ramrod is stuck [CID %08x %s:%02x %s:%02x echo %04x]\n",
le32_to_cpu(p_ent->elem.hdr.cid),
qed_get_ramrod_cmd_id_str(p_ent->elem.hdr.protocol_id,
p_ent->elem.hdr.cmd_id),
p_ent->elem.hdr.cmd_id,
qed_get_protocol_type_str(p_ent->elem.hdr.protocol_id),
p_ent->elem.hdr.protocol_id,
le16_to_cpu(p_ent->elem.hdr.echo));
qed_ptt_release(p_hwfn, p_ptt);
return -EBUSY;
}
/***************************************************************************
* SPQ entries inner API
***************************************************************************/
static int qed_spq_fill_entry(struct qed_hwfn *p_hwfn,
struct qed_spq_entry *p_ent)
{
p_ent->flags = 0;
switch (p_ent->comp_mode) {
case QED_SPQ_MODE_EBLOCK:
Annotation
- Immediate include surface: `linux/types.h`, `asm/byteorder.h`, `linux/io.h`, `linux/delay.h`, `linux/dma-mapping.h`, `linux/errno.h`, `linux/kernel.h`, `linux/list.h`.
- Detected declarations: `function Copyright`, `function __qed_spq_block`, `function qed_spq_block`, `function qed_spq_fill_entry`, `function qed_spq_hw_initialize`, `function qed_spq_hw_post`, `function qed_async_event_completion`, `function qed_spq_register_async_cb`, `function qed_spq_unregister_async_cb`, `function qed_eq_prod_update`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source 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.