Beispiel #1
0
static void gpio_set_irqenable(int enabled, irqreturn_t (*handler)(int, void *))
{
	int irq;
	int err;

	irq = gpio_to_irq(0);
	if (irq < 0) {
		pr_err("no irq for gpio available\n");
		return;
	}
	
	if (enabled) {
		err = request_irq(irq, handler, IRQF_SHARED, "gpio", handler);
		if (err) {
			pr_err("can not reqeust irq\n");
			return;
		}
	} else {
		free_irq(irq, handler);
	}

	switch (bcm47xx_bus_type) {
#ifdef CONFIG_BCM47XX_SSB
	case BCM47XX_BUS_TYPE_SSB:
		if (bcm47xx_bus.ssb.chipco.dev)
			ssb_maskset32(bcm47xx_bus.ssb.chipco.dev, SSB_CHIPCO_IRQMASK, ~SSB_CHIPCO_IRQ_GPIO, (enabled ? SSB_CHIPCO_IRQ_GPIO : 0));
		break;
#endif
#ifdef CONFIG_BCM47XX_BCMA
	case BCM47XX_BUS_TYPE_BCMA:
		if (bcm47xx_bus.bcma.bus.drv_cc.core)
			bcma_maskset32(bcm47xx_bus.bcma.bus.drv_cc.core, BCMA_CC_IRQMASK, ~BCMA_CC_IRQ_GPIO, (enabled ? BCMA_CC_IRQ_GPIO : 0));
		break;
#endif
	}
}
Beispiel #2
0
/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/chipreset */
static void bgmac_chip_reset(struct bgmac *bgmac)
{
	struct bcma_device *core = bgmac->core;
	struct bcma_bus *bus = core->bus;
	struct bcma_chipinfo *ci = &bus->chipinfo;
	u32 flags;
	u32 iost;
	int i;

	if (bcma_core_is_enabled(core)) {
		if (!bgmac->stats_grabbed) {
			/* bgmac_chip_stats_update(bgmac); */
			bgmac->stats_grabbed = true;
		}

		for (i = 0; i < BGMAC_MAX_TX_RINGS; i++)
			bgmac_dma_tx_reset(bgmac, &bgmac->tx_ring[i]);

		bgmac_cmdcfg_maskset(bgmac, ~0, BGMAC_CMDCFG_ML, false);
		udelay(1);

		for (i = 0; i < BGMAC_MAX_RX_RINGS; i++)
			bgmac_dma_rx_reset(bgmac, &bgmac->rx_ring[i]);

		/* TODO: Clear software multicast filter list */
	}

	iost = bcma_aread32(core, BCMA_IOST);
	if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM47186) ||
	    (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) ||
	    (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188))
		iost &= ~BGMAC_BCMA_IOST_ATTACHED;

	/* 3GMAC: for BCM4707 & BCM47094, only do core reset at bgmac_probe() */
	if (ci->id != BCMA_CHIP_ID_BCM4707 &&
	    ci->id != BCMA_CHIP_ID_BCM47094) {
		flags = 0;
		if (iost & BGMAC_BCMA_IOST_ATTACHED) {
			flags = BGMAC_BCMA_IOCTL_SW_CLKEN;
			if (!bgmac->has_robosw)
				flags |= BGMAC_BCMA_IOCTL_SW_RESET;
		}
		bcma_core_enable(core, flags);
	}

	/* Request Misc PLL for corerev > 2 */
	if (core->id.rev > 2 && !bgmac_is_bcm4707_family(bgmac)) {
		bgmac_set(bgmac, BCMA_CLKCTLST,
			  BGMAC_BCMA_CLKCTLST_MISC_PLL_REQ);
		bgmac_wait_value(bgmac->core, BCMA_CLKCTLST,
				 BGMAC_BCMA_CLKCTLST_MISC_PLL_ST,
				 BGMAC_BCMA_CLKCTLST_MISC_PLL_ST,
				 1000);
	}

	if (ci->id == BCMA_CHIP_ID_BCM5357 ||
	    ci->id == BCMA_CHIP_ID_BCM4749 ||
	    ci->id == BCMA_CHIP_ID_BCM53572) {
		struct bcma_drv_cc *cc = &bgmac->core->bus->drv_cc;
		u8 et_swtype = 0;
		u8 sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHY |
			     BGMAC_CHIPCTL_1_IF_TYPE_MII;
		char buf[4];

		if (bcm47xx_nvram_getenv("et_swtype", buf, sizeof(buf)) > 0) {
			if (kstrtou8(buf, 0, &et_swtype))
				bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n",
					  buf);
			et_swtype &= 0x0f;
			et_swtype <<= 4;
			sw_type = et_swtype;
		} else if (ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM5358) {
			sw_type = BGMAC_CHIPCTL_1_SW_TYPE_EPHYRMII;
		} else if ((ci->id == BCMA_CHIP_ID_BCM5357 && ci->pkg == BCMA_PKG_ID_BCM47186) ||
			   (ci->id == BCMA_CHIP_ID_BCM4749 && ci->pkg == 10) ||
			   (ci->id == BCMA_CHIP_ID_BCM53572 && ci->pkg == BCMA_PKG_ID_BCM47188)) {
			sw_type = BGMAC_CHIPCTL_1_IF_TYPE_RGMII |
				  BGMAC_CHIPCTL_1_SW_TYPE_RGMII;
		}
		bcma_chipco_chipctl_maskset(cc, 1,
					    ~(BGMAC_CHIPCTL_1_IF_TYPE_MASK |
					      BGMAC_CHIPCTL_1_SW_TYPE_MASK),
					    sw_type);
	}

	if (iost & BGMAC_BCMA_IOST_ATTACHED && !bgmac->has_robosw)
		bcma_awrite32(core, BCMA_IOCTL,
			      bcma_aread32(core, BCMA_IOCTL) &
			      ~BGMAC_BCMA_IOCTL_SW_RESET);

	/* http://bcm-v4.sipsolutions.net/mac-gbit/gmac/gmac_reset
	 * Specs don't say about using BGMAC_CMDCFG_SR, but in this routine
	 * BGMAC_CMDCFG is read _after_ putting chip in a reset. So it has to
	 * be keps until taking MAC out of the reset.
	 */
	bgmac_cmdcfg_maskset(bgmac,
			     ~(BGMAC_CMDCFG_TE |
			       BGMAC_CMDCFG_RE |
			       BGMAC_CMDCFG_RPI |
			       BGMAC_CMDCFG_TAI |
			       BGMAC_CMDCFG_HD |
			       BGMAC_CMDCFG_ML |
			       BGMAC_CMDCFG_CFE |
			       BGMAC_CMDCFG_RL |
			       BGMAC_CMDCFG_RED |
			       BGMAC_CMDCFG_PE |
			       BGMAC_CMDCFG_TPI |
			       BGMAC_CMDCFG_PAD_EN |
			       BGMAC_CMDCFG_PF),
			     BGMAC_CMDCFG_PROM |
			     BGMAC_CMDCFG_NLC |
			     BGMAC_CMDCFG_CFE |
			     BGMAC_CMDCFG_SR(core->id.rev),
			     false);
	bgmac->mac_speed = SPEED_UNKNOWN;
	bgmac->mac_duplex = DUPLEX_UNKNOWN;

	bgmac_clear_mib(bgmac);
	if (core->id.id == BCMA_CORE_4706_MAC_GBIT)
		bcma_maskset32(bgmac->cmn, BCMA_GMAC_CMN_PHY_CTL, ~0,
			       BCMA_GMAC_CMN_PC_MTE);
	else
		bgmac_set(bgmac, BGMAC_PHY_CNTL, BGMAC_PC_MTE);
	bgmac_miiconfig(bgmac);
	bgmac_phy_init(bgmac);

	netdev_reset_queue(bgmac->net_dev);
}
Beispiel #3
0
static void bcma_bgmac_cmn_maskset32(struct bgmac *bgmac, u16 offset, u32 mask,
				     u32 set)
{
	bcma_maskset32(bgmac->bcma.cmn, offset, mask, set);
}