Пример #1
0
/* Interrupt handler */
static int pm3393_interrupt_handler(struct cmac *cmac)
{
	u32 master_intr_status;

	/* Read the master interrupt status register. */
	pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
	       &master_intr_status);
	if (netif_msg_intr(cmac->adapter))
		dev_dbg(&cmac->adapter->pdev->dev, "PM3393 intr cause 0x%x\n",
			master_intr_status);

	/* TBD XXX Lets just clear everything for now */
	pm3393_interrupt_clear(cmac);

	return 0;
}
Пример #2
0
static int pm3393_interrupt_handler(struct cmac *cmac)
{
	u32 master_intr_status;

	
	pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS,
	       &master_intr_status);
	if (netif_msg_intr(cmac->adapter))
		dev_dbg(&cmac->adapter->pdev->dev, "PM3393 intr cause 0x%x\n",
			master_intr_status);

	
	pm3393_interrupt_clear(cmac);

	return 0;
}
Пример #3
0
static int pm3393_set_rx_mode(struct cmac *cmac, struct t1_rx_mode *rm)
{
	int enabled = cmac->instance->enabled & MAC_DIRECTION_RX;
	u32 rx_mode;

	/* Disable MAC RX before reconfiguring it */
	if (enabled)
		pm3393_disable(cmac, MAC_DIRECTION_RX);

	pmread(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2, &rx_mode);
	rx_mode &= ~(SUNI1x10GEXP_BITMSK_RXXG_PMODE |
		     SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN);
	pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_ADDRESS_FILTER_CONTROL_2,
		(u16)rx_mode);

	if (t1_rx_mode_promisc(rm)) {
		/* Promiscuous mode. */
		rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_PMODE;
	}
	if (t1_rx_mode_allmulti(rm)) {
		/* Accept all multicast. */
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, 0xffff);
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, 0xffff);
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, 0xffff);
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, 0xffff);
		rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
	} else if (t1_rx_mode_mc_cnt(rm)) {
		/* Accept one or more multicast(s). */
		struct netdev_hw_addr *ha;
		int bit;
		u16 mc_filter[4] = { 0, };

		netdev_for_each_mc_addr(ha, t1_get_netdev(rm)) {
			/* bit[23:28] */
			bit = (ether_crc(ETH_ALEN, ha->addr) >> 23) & 0x3f;
			mc_filter[bit >> 4] |= 1 << (bit & 0xf);
		}
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_LOW, mc_filter[0]);
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDLOW, mc_filter[1]);
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_MIDHIGH, mc_filter[2]);
		pmwrite(cmac, SUNI1x10GEXP_REG_RXXG_MULTICAST_HASH_HIGH, mc_filter[3]);
		rx_mode |= SUNI1x10GEXP_BITMSK_RXXG_MHASH_EN;
	}
Пример #4
0
static int pm3393_interrupt_clear(struct cmac *cmac)
{
	u32 elmer;
	u32 pl_intr;
	u32 val32;

	/* PM3393 - Clearing HW interrupt blocks. Note, this assumes
	 *          bit WCIMODE=0 for a clear-on-read.
	 */
	pmread(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_RXXG_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_TXXG_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION,
	       &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE, &val32);

	/* PM3393 - Global interrupt status
	 */
	pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, &val32);

	/* ELMER - External chip interrupts.
	 */
	t1_tpi_read(cmac->adapter, A_ELMER0_INT_CAUSE, &elmer);
	elmer |= ELMER0_GP_BIT1;
	t1_tpi_write(cmac->adapter, A_ELMER0_INT_CAUSE, elmer);

	/* TERMINATOR - PL_INTERUPTS_EXT
	 */
	pl_intr = readl(cmac->adapter->regs + A_PL_CAUSE);
	pl_intr |= F_PL_INTR_EXT;
	writel(pl_intr, cmac->adapter->regs + A_PL_CAUSE);

	return 0;
}
Пример #5
0
static int pm3393_interrupt_clear(struct cmac *cmac)
{
	u32 elmer;
	u32 pl_intr;
	u32 val32;

	pmread(cmac, SUNI1x10GEXP_REG_SERDES_3125_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_XRF_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_XRF_DIAG_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_RXOAM_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4ODP_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_XTEF_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_IFLX_FIFO_OVERFLOW_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_TXOAM_INTERRUPT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_RXXG_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_TXXG_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4IDU_INTERRUPT, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_EFLX_FIFO_OVERFLOW_ERROR_INDICATION,
	       &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_STATUS, &val32);
	pmread(cmac, SUNI1x10GEXP_REG_PL4IO_LOCK_DETECT_CHANGE, &val32);

	pmread(cmac, SUNI1x10GEXP_REG_MASTER_INTERRUPT_STATUS, &val32);

	t1_tpi_read(cmac->adapter, A_ELMER0_INT_CAUSE, &elmer);
	elmer |= ELMER0_GP_BIT1;
	t1_tpi_write(cmac->adapter, A_ELMER0_INT_CAUSE, elmer);

	pl_intr = readl(cmac->adapter->regs + A_PL_CAUSE);
	pl_intr |= F_PL_INTR_EXT;
	writel(pl_intr, cmac->adapter->regs + A_PL_CAUSE);

	return 0;
}