drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
Extension
.c
Size
115971 bytes
Lines
4242
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (adapter->flags & QLCNIC_MSIX_ENABLED) {
			num_msix = ahw->num_msix;
		} else {
			if (qlcnic_sriov_vf_check(adapter))
				return -EINVAL;
			num_msix = 1;
			adapter->drv_sds_rings = QLCNIC_SINGLE_RING;
			adapter->drv_tx_rings = QLCNIC_SINGLE_RING;
		}
	}

	/* setup interrupt mapping table for fw */
	ahw->intr_tbl =
		vzalloc(array_size(num_msix,
				   sizeof(struct qlcnic_intrpt_config)));
	if (!ahw->intr_tbl)
		return -ENOMEM;

	if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
		if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) {
			dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n",
				ahw->pci_func);
			return -EOPNOTSUPP;
		}

		qlcnic_83xx_enable_legacy(adapter);
	}

	for (i = 0; i < num_msix; i++) {
		if (adapter->flags & QLCNIC_MSIX_ENABLED)
			ahw->intr_tbl[i].type = QLCNIC_INTRPT_MSIX;
		else
			ahw->intr_tbl[i].type = QLCNIC_INTRPT_INTX;
		ahw->intr_tbl[i].id = i;
		ahw->intr_tbl[i].src = 0;
	}

	return 0;
}

static inline void qlcnic_83xx_clear_legacy_intr_mask(struct qlcnic_adapter *adapter)
{
	writel(0, adapter->tgt_mask_reg);
}

static inline void qlcnic_83xx_set_legacy_intr_mask(struct qlcnic_adapter *adapter)
{
	if (adapter->tgt_mask_reg)
		writel(1, adapter->tgt_mask_reg);
}

static inline void qlcnic_83xx_enable_legacy_msix_mbx_intr(struct qlcnic_adapter
						    *adapter)
{
	u32 mask;

	/* Mailbox in MSI-x mode and Legacy Interrupt share the same
	 * source register. We could be here before contexts are created
	 * and sds_ring->crb_intr_mask has not been initialized, calculate
	 * BAR offset for Interrupt Source Register
	 */
	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
	writel(0, adapter->ahw->pci_base0 + mask);
}

void qlcnic_83xx_disable_mbx_intr(struct qlcnic_adapter *adapter)
{
	u32 mask;

	mask = QLCRDX(adapter->ahw, QLCNIC_DEF_INT_MASK);
	writel(1, adapter->ahw->pci_base0 + mask);
	QLCWRX(adapter->ahw, QLCNIC_MBX_INTR_ENBL, 0);
}

static inline void qlcnic_83xx_get_mbx_data(struct qlcnic_adapter *adapter,
				     struct qlcnic_cmd_args *cmd)
{
	int i;

	if (cmd->op_type == QLC_83XX_MBX_POST_BC_OP)
		return;

	for (i = 0; i < cmd->rsp.num; i++)
		cmd->rsp.arg[i] = readl(QLCNIC_MBX_FW(adapter->ahw, i));
}

irqreturn_t qlcnic_83xx_clear_legacy_intr(struct qlcnic_adapter *adapter)
{
	u32 intr_val;
	struct qlcnic_hardware_context *ahw = adapter->ahw;

Annotation

Implementation Notes