drivers/net/ethernet/chelsio/cxgb/pm3393.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/chelsio/cxgb/pm3393.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/chelsio/cxgb/pm3393.c
Extension
.c
Size
29335 bytes
Lines
781
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

struct _cmac_instance {
	u8 enabled;
	u8 fc;
	u8 mac_addr[6];
};

static int pmread(struct cmac *cmac, u32 reg, u32 * data32)
{
	t1_tpi_read(cmac->adapter, OFFSET(reg), data32);
	return 0;
}

static int pmwrite(struct cmac *cmac, u32 reg, u32 data32)
{
	t1_tpi_write(cmac->adapter, OFFSET(reg), data32);
	return 0;
}

/* Port reset. */
static int pm3393_reset(struct cmac *cmac)
{
	return 0;
}

/*
 * Enable interrupts for the PM3393
 *
 *	1. Enable PM3393 BLOCK interrupts.
 *	2. Enable PM3393 Master Interrupt bit(INTE)
 *	3. Enable ELMER's PM3393 bit.
 *	4. Enable Terminator external interrupt.
 */
static int pm3393_interrupt_enable(struct cmac *cmac)
{
	u32 pl_intr;

	/* PM3393 - Enabling all hardware block interrupts.
	 */
	pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0xffff);

	/* Don't interrupt on statistics overflow, we are polling */
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);

	pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_MASK, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_TXXG_CONFIG_3, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT_MASK, 0xffff);
	pmwrite(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_ENABLE, 0xffff);

	/* PM3393 - Global interrupt enable
	 */
	/* TBD XXX Disable for now until we figure out why error interrupts keep asserting. */
	pmwrite(cmac, SUNI1x10GEXP_REG_GLOBAL_INTERRUPT_ENABLE,
		0 /*SUNI1x10GEXP_BITMSK_TOP_INTE */ );

	/* TERMINATOR - PL_INTERRUPTS_EXT */
	pl_intr = readl(cmac->adapter->regs + A_PL_ENABLE);
	pl_intr |= F_PL_INTR_EXT;
	writel(pl_intr, cmac->adapter->regs + A_PL_ENABLE);
	return 0;
}

static int pm3393_interrupt_disable(struct cmac *cmac)
{
	u32 elmer;

	/* PM3393 - Enabling HW interrupt blocks. */
	pmwrite(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_ENABLE, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_ENABLE, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_ENABLE, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_ENABLE, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_0, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_1, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_2, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_MSTAT_INTERRUPT_MASK_3, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_ENABLE, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT_MASK, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_ENABLE, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_ENABLE, 0);
	pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_CONFIG_3, 0);

Annotation

Implementation Notes