示例#1
0
static void smc_reset(struct net_device *dev)
{
    struct smc_local *lp = netdev_priv(dev);
    void __iomem *ioaddr = lp->base;
    unsigned int ctl, cfg;
    struct sk_buff *pending_skb;

    DBG(2, "%s: %s\n", dev->name, __func__);


    spin_lock_irq(&lp->lock);
    SMC_SELECT_BANK(lp, 2);
    SMC_SET_INT_MASK(lp, 0);
    pending_skb = lp->pending_tx_skb;
    lp->pending_tx_skb = NULL;
    spin_unlock_irq(&lp->lock);


    if (pending_skb) {
        dev_kfree_skb(pending_skb);
        dev->stats.tx_errors++;
        dev->stats.tx_aborted_errors++;
    }

    SMC_SELECT_BANK(lp, 0);
    SMC_SET_RCR(lp, RCR_SOFTRST);

    SMC_SELECT_BANK(lp, 1);

    cfg = CONFIG_DEFAULT;

    if (lp->cfg.flags & SMC91X_NOWAIT)
        cfg |= CONFIG_NO_WAIT;

    cfg |= CONFIG_EPH_POWER_EN;

    SMC_SET_CONFIG(lp, cfg);


    udelay(1);


    SMC_SELECT_BANK(lp, 0);
    SMC_SET_RCR(lp, RCR_CLEAR);
    SMC_SET_TCR(lp, TCR_CLEAR);

    SMC_SELECT_BANK(lp, 1);
    ctl = SMC_GET_CTL(lp) | CTL_LE_ENABLE;

    if(!THROTTLE_TX_PKTS)
        ctl |= CTL_AUTO_RELEASE;
    else
        ctl &= ~CTL_AUTO_RELEASE;
    SMC_SET_CTL(lp, ctl);


    SMC_SELECT_BANK(lp, 2);
    SMC_SET_MMU_CMD(lp, MC_RESET);
    SMC_WAIT_MMU_BUSY(lp);
}
示例#2
0
static void smc_shutdown(struct net_device *dev)
{
	struct smc_local *lp = netdev_priv(dev);
	void __iomem *ioaddr = lp->base;
	struct sk_buff *pending_skb;

	DBG(2, "%s: %s\n", CARDNAME, __func__);

	
	spin_lock_irq(&lp->lock);
	SMC_SELECT_BANK(lp, 2);
	SMC_SET_INT_MASK(lp, 0);
	pending_skb = lp->pending_tx_skb;
	lp->pending_tx_skb = NULL;
	spin_unlock_irq(&lp->lock);
	if (pending_skb)
		dev_kfree_skb(pending_skb);

	
	SMC_SELECT_BANK(lp, 0);
	SMC_SET_RCR(lp, RCR_CLEAR);
	SMC_SET_TCR(lp, TCR_CLEAR);

#ifdef POWER_DOWN
	
	SMC_SELECT_BANK(lp, 1);
	SMC_SET_CONFIG(lp, SMC_GET_CONFIG(lp) & ~CONFIG_EPH_POWER_EN);
#endif
}
示例#3
0
static void smc_enable(struct net_device *dev)
{
	struct smc_local *lp = netdev_priv(dev);
	void __iomem *ioaddr = lp->base;
	int mask;

	DBG(2, "%s: %s\n", dev->name, __func__);

	
	SMC_SELECT_BANK(lp, 0);
	SMC_SET_TCR(lp, lp->tcr_cur_mode);
	SMC_SET_RCR(lp, lp->rcr_cur_mode);

	SMC_SELECT_BANK(lp, 1);
	SMC_SET_MAC_ADDR(lp, dev->dev_addr);

	
	mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT;
	if (lp->version >= (CHIP_91100 << 4))
		mask |= IM_MDINT;
	SMC_SELECT_BANK(lp, 2);
	SMC_SET_INT_MASK(lp, mask);

	
}
示例#4
0
/*
 * this puts the device in an inactive state
 */
static void smc_shutdown(struct net_device *dev)
{
	struct smc_local *lp = netdev_priv(dev);
	void __iomem *ioaddr = lp->base;
	struct sk_buff *pending_skb;

	DBG(2, "%s: %s\n", CARDNAME, __func__);

	/* no more interrupts for me */
	spin_lock_irq(&lp->lock);
	SMC_SELECT_BANK(lp, 2);
	SMC_SET_INT_MASK(lp, 0);
	pending_skb = lp->pending_tx_skb;
	lp->pending_tx_skb = NULL;
	spin_unlock_irq(&lp->lock);
	if (pending_skb)
		dev_kfree_skb(pending_skb);

	/* and tell the card to stay away from that nasty outside world */
	SMC_SELECT_BANK(lp, 0);
	SMC_SET_RCR(lp, RCR_CLEAR);
	SMC_SET_TCR(lp, TCR_CLEAR);

#ifdef POWER_DOWN
	/* finally, shut the chip down */
	SMC_SELECT_BANK(lp, 1);
	SMC_SET_CONFIG(lp, SMC_GET_CONFIG(lp) & ~CONFIG_EPH_POWER_EN);
#endif
}
示例#5
0
/*
 * Enable Interrupts, Receive, and Transmit
 */
static void smc_enable(struct net_device *dev)
{
	struct smc_local *lp = netdev_priv(dev);
	void __iomem *ioaddr = lp->base;
	int mask;

	DBG(2, "%s: %s\n", dev->name, __func__);

	/* see the header file for options in TCR/RCR DEFAULT */
	SMC_SELECT_BANK(lp, 0);
	SMC_SET_TCR(lp, lp->tcr_cur_mode);
	SMC_SET_RCR(lp, lp->rcr_cur_mode);

	SMC_SELECT_BANK(lp, 1);
	SMC_SET_MAC_ADDR(lp, dev->dev_addr);

	/* now, enable interrupts */
	mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT;
	if (lp->version >= (CHIP_91100 << 4))
		mask |= IM_MDINT;
	SMC_SELECT_BANK(lp, 2);
	SMC_SET_INT_MASK(lp, mask);

	/*
	 * From this point the register bank must _NOT_ be switched away
	 * to something else than bank 2 without proper locking against
	 * races with any tasklet or interrupt handlers until smc_shutdown()
	 * or smc_reset() is called.
	 */
}
示例#6
0
/*
 * this does a soft reset on the device
 */
static void smc_reset(struct net_device *dev)
{
	struct smc_local *lp = netdev_priv(dev);
	void __iomem *ioaddr = lp->base;
	unsigned int ctl, cfg;
	struct sk_buff *pending_skb;

	DBG(2, "%s: %s\n", dev->name, __func__);

	/* Disable all interrupts, block TX tasklet */
	spin_lock_irq(&lp->lock);
	SMC_SELECT_BANK(lp, 2);
	SMC_SET_INT_MASK(lp, 0);
	pending_skb = lp->pending_tx_skb;
	lp->pending_tx_skb = NULL;
	spin_unlock_irq(&lp->lock);

	/* free any pending tx skb */
	if (pending_skb) {
		dev_kfree_skb(pending_skb);
		dev->stats.tx_errors++;
		dev->stats.tx_aborted_errors++;
	}

	/*
	 * This resets the registers mostly to defaults, but doesn't
	 * affect EEPROM.  That seems unnecessary
	 */
	SMC_SELECT_BANK(lp, 0);
	SMC_SET_RCR(lp, RCR_SOFTRST);

	/*
	 * Setup the Configuration Register
	 * This is necessary because the CONFIG_REG is not affected
	 * by a soft reset
	 */
	SMC_SELECT_BANK(lp, 1);

	cfg = CONFIG_DEFAULT;

	/*
	 * Setup for fast accesses if requested.  If the card/system
	 * can't handle it then there will be no recovery except for
	 * a hard reset or power cycle
	 */
	if (lp->cfg.flags & SMC91X_NOWAIT)
		cfg |= CONFIG_NO_WAIT;

	/*
	 * Release from possible power-down state
	 * Configuration register is not affected by Soft Reset
	 */
	cfg |= CONFIG_EPH_POWER_EN;

	SMC_SET_CONFIG(lp, cfg);

	/* this should pause enough for the chip to be happy */
	/*
	 * elaborate?  What does the chip _need_? --jgarzik
	 *
	 * This seems to be undocumented, but something the original
	 * driver(s) have always done.  Suspect undocumented timing
	 * info/determined empirically. --rmk
	 */
	udelay(1);

	/* Disable transmit and receive functionality */
	SMC_SELECT_BANK(lp, 0);
	SMC_SET_RCR(lp, RCR_CLEAR);
	SMC_SET_TCR(lp, TCR_CLEAR);

	SMC_SELECT_BANK(lp, 1);
	ctl = SMC_GET_CTL(lp) | CTL_LE_ENABLE;

	/*
	 * Set the control register to automatically release successfully
	 * transmitted packets, to make the best use out of our limited
	 * memory
	 */
	if(!THROTTLE_TX_PKTS)
		ctl |= CTL_AUTO_RELEASE;
	else
		ctl &= ~CTL_AUTO_RELEASE;
	SMC_SET_CTL(lp, ctl);

	/* Reset the MMU */
	SMC_SELECT_BANK(lp, 2);
	SMC_SET_MMU_CMD(lp, MC_RESET);
	SMC_WAIT_MMU_BUSY(lp);
}