drivers/net/ethernet/cavium/liquidio/cn66xx_device.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/cavium/liquidio/cn66xx_device.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/cavium/liquidio/cn66xx_device.c
Extension
.c
Size
22306 bytes
Lines
739
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 (pkt_count) {
			oct->droq_intr |= BIT_ULL(oq_no);
			if (droq->ops.poll_mode) {
				u32 value;
				u32 reg;

				struct octeon_cn6xxx *cn6xxx =
					(struct octeon_cn6xxx *)oct->chip;

				/* disable interrupts for this droq */
				spin_lock
					(&cn6xxx->lock_for_droq_int_enb_reg);
				reg = CN6XXX_SLI_PKT_TIME_INT_ENB;
				value = octeon_read_csr(oct, reg);
				value &= ~(1 << oq_no);
				octeon_write_csr(oct, reg, value);
				reg = CN6XXX_SLI_PKT_CNT_INT_ENB;
				value = octeon_read_csr(oct, reg);
				value &= ~(1 << oq_no);
				octeon_write_csr(oct, reg, value);

				spin_unlock(&cn6xxx->lock_for_droq_int_enb_reg);
			}
		}
	}

	droq_time_mask &= oct->io_qmask.oq;
	droq_cnt_mask &= oct->io_qmask.oq;

	/* Reset the PKT_CNT/TIME_INT registers. */
	if (droq_time_mask)
		octeon_write_csr(oct, CN6XXX_SLI_PKT_TIME_INT, droq_time_mask);

	if (droq_cnt_mask)      /* reset PKT_CNT register:66xx */
		octeon_write_csr(oct, CN6XXX_SLI_PKT_CNT_INT, droq_cnt_mask);

	return 0;
}

irqreturn_t lio_cn6xxx_process_interrupt_regs(void *dev)
{
	struct octeon_device *oct = (struct octeon_device *)dev;
	struct octeon_cn6xxx *cn6xxx = (struct octeon_cn6xxx *)oct->chip;
	u64 intr64;

	intr64 = readq(cn6xxx->intr_sum_reg64);

	/* If our device has interrupted, then proceed.
	 * Also check for all f's if interrupt was triggered on an error
	 * and the PCI read fails.
	 */
	if (!intr64 || (intr64 == 0xFFFFFFFFFFFFFFFFULL))
		return IRQ_NONE;

	oct->int_status = 0;

	if (intr64 & CN6XXX_INTR_ERR)
		lio_cn6xxx_process_pcie_error_intr(oct, intr64);

	if (intr64 & CN6XXX_INTR_PKT_DATA) {
		lio_cn6xxx_process_droq_intr_regs(oct);
		oct->int_status |= OCT_DEV_INTR_PKT_DATA;
	}

	if (intr64 & CN6XXX_INTR_DMA0_FORCE)
		oct->int_status |= OCT_DEV_INTR_DMA0_FORCE;

	if (intr64 & CN6XXX_INTR_DMA1_FORCE)
		oct->int_status |= OCT_DEV_INTR_DMA1_FORCE;

	/* Clear the current interrupts */
	writeq(intr64, cn6xxx->intr_sum_reg64);

	return IRQ_HANDLED;
}

void lio_cn6xxx_setup_reg_address(struct octeon_device *oct,
				  void *chip,
				  struct octeon_reg_list *reg_list)
{
	u8 __iomem *bar0_pciaddr = oct->mmio[0].hw_addr;
	struct octeon_cn6xxx *cn6xxx = (struct octeon_cn6xxx *)chip;

	reg_list->pci_win_wr_addr_hi =
		(u32 __iomem *)(bar0_pciaddr + CN6XXX_WIN_WR_ADDR_HI);
	reg_list->pci_win_wr_addr_lo =
		(u32 __iomem *)(bar0_pciaddr + CN6XXX_WIN_WR_ADDR_LO);
	reg_list->pci_win_wr_addr =
		(u64 __iomem *)(bar0_pciaddr + CN6XXX_WIN_WR_ADDR64);

Annotation

Implementation Notes