static irqreturn_t
netx_eth_interrupt(int irq, void *dev_id)
{
	struct net_device *ndev = dev_id;
	struct netx_eth_priv *priv = netdev_priv(ndev);
	int status;
	unsigned long flags;

	spin_lock_irqsave(&priv->lock, flags);

	status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
	while (status) {
		int fill_level;
		writel(status, NETX_PFIFO_XPEC_ISR(priv->id));

		if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
			printk("%s: unexpected status: 0x%08x\n",
			    __func__, status);

		fill_level =
		    readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
		while (fill_level--)
			netx_eth_receive(ndev);

		if (status & ISR_CON_LO)
			netif_wake_queue(ndev);

		if (status & ISR_LINK_STATUS_CHANGE)
			mii_check_media(&priv->mii, netif_msg_link(priv), 1);

		status = readl(NETX_PFIFO_XPEC_ISR(priv->id));
	}
	spin_unlock_irqrestore(&priv->lock, flags);
	return IRQ_HANDLED;
}
static int netx_eth_open(struct net_device *ndev)
{
	struct netx_eth_priv *priv = netdev_priv(ndev);

	if (request_irq
	    (ndev->irq, netx_eth_interrupt, IRQF_SHARED, ndev->name, ndev))
		return -EAGAIN;

	writel(ndev->dev_addr[0] |
	       ndev->dev_addr[1]<<8 |
	       ndev->dev_addr[2]<<16 |
	       ndev->dev_addr[3]<<24,
	       priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_4321);
	writel(ndev->dev_addr[4] |
	       ndev->dev_addr[5]<<8,
	       priv->xpec_base + NETX_XPEC_RAM_START_OFS + ETH_MAC_65);

	writel(LOCAL_CONFIG_LINK_STATUS_IRQ_EN |
		LOCAL_CONFIG_CON_LO_IRQ_EN |
		LOCAL_CONFIG_CON_HI_IRQ_EN |
		LOCAL_CONFIG_IND_LO_IRQ_EN |
		LOCAL_CONFIG_IND_HI_IRQ_EN,
		priv->xpec_base + NETX_XPEC_RAM_START_OFS +
		ETH_MAC_LOCAL_CONFIG);

	mii_check_media(&priv->mii, netif_msg_link(priv), 1);
	netif_start_queue(ndev);

	return 0;
}
Beispiel #3
0
/*
 * link check timer callback
 */
static void enet_link_check(unsigned long data)
{
	struct net_device *dev;
	struct tangox_enet_priv *priv;
	int ret, speed;
	static int old_speed;

	dev = (struct net_device *)data;
	priv = netdev_priv(dev);

	/*check speed change in gigabit*/
	speed = enet_get_speed(dev);

	/* check for duplex change */
	spin_lock(&priv->mii_lock);
	ret = mii_check_media(&priv->mii, 1, 0);
	spin_unlock(&priv->mii_lock);

	if (ret || (speed && (speed !=old_speed)))
		enet_link_reconfigure(dev);

	if(speed)
		old_speed = speed;

	/* reschedule timer */
	priv->link_check_timer.expires = jiffies + LINK_CHECK_TIMER_FREQ;
	add_timer(&priv->link_check_timer);
}
Beispiel #4
0
static int cp_open (struct net_device *dev)
{
	struct cp_private *cp = netdev_priv(dev);
	int rc;

	if (netif_msg_ifup(cp))
		printk(KERN_DEBUG "%s: enabling interface\n", dev->name);

	rc = cp_alloc_rings(cp);
	if (rc)
		return rc;

	cp_init_hw(cp);

	rc = request_irq(dev->irq, cp_interrupt, SA_SHIRQ, dev->name, dev);
	if (rc)
		goto err_out_hw;

	netif_carrier_off(dev);
	mii_check_media(&cp->mii_if, netif_msg_link(cp), TRUE);
	netif_start_queue(dev);

	return 0;

err_out_hw:
	cp_stop_hw(cp);
	cp_free_rings(cp);
	return rc;
}
Beispiel #5
0
static irqreturn_t
cp_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
{
	struct net_device *dev = dev_instance;
	struct cp_private *cp;
	u16 status;

	if (unlikely(dev == NULL))
		return IRQ_NONE;
	cp = netdev_priv(dev);

	status = cpr16(IntrStatus);
	if (!status || (status == 0xFFFF))
		return IRQ_NONE;

	if (netif_msg_intr(cp))
		printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
		        dev->name, status, cpr8(Cmd), cpr16(CpCmd));

	cpw16(IntrStatus, status & ~cp_rx_intr_mask);

	spin_lock(&cp->lock);

	/* close possible race's with dev_close */
	if (unlikely(!netif_running(dev))) {
		cpw16(IntrMask, 0);
		spin_unlock(&cp->lock);
		return IRQ_HANDLED;
	}

	if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
		if (netif_rx_schedule_prep(dev)) {
			cpw16_f(IntrMask, cp_norx_intr_mask);
			__netif_rx_schedule(dev);
		}

	if (status & (TxOK | TxErr | TxEmpty | SWInt))
		cp_tx(cp);
	if (status & LinkChg)
		mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE);

	spin_unlock(&cp->lock);

	if (status & PciErr) {
		u16 pci_status;

		pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
		pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
		printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n",
		       dev->name, status, pci_status);

		/* TODO: reset hardware */
	}

	return IRQ_HANDLED;
}
Beispiel #6
0
/*
 * open callback
 */
static int enet_open(struct net_device *dev)
{
	struct tangox_enet_priv *priv;
	unsigned char val;

	priv = netdev_priv(dev);

#ifdef CONFIG_ETHERENET_LED_ON_OFF_IP101A
	{
	int mii_bmcr_val;
	mii_bmcr_val=priv->mii.mdio_read(dev,priv->mii.phy_id,MII_BMCR);
	mii_bmcr_val &= ~(1<<11);
	priv->mii.mdio_write(dev,priv->mii.phy_id,MII_BMCR,mii_bmcr_val);
	}
#endif

	/* check link */
	if (mii_check_media(&priv->mii, 1, 1))
		enet_link_reconfigure(dev);

	/* enable mac rx & tx */
	val = enet_readb(ENET_RX_CTL(priv->enet_mac_base));
	val |= RX_EN;
	enet_writeb(ENET_RX_CTL(priv->enet_mac_base), val);

	val = enet_readb(ENET_TX_CTL1(priv->enet_mac_base));
	val |= TX_EN;
	enet_writeb(ENET_TX_CTL1(priv->enet_mac_base), val);

	/*
	 * clear & enable interrupts, we want:
	 * - receive complete
	 * - transmit complete
	 */
	enet_writel(ENET_TXC_SR(priv->enet_mac_base), 0xff);
	enet_writel(ENET_RXC_SR(priv->enet_mac_base), 0xff);

	/* start link check & tx reclaim timer */
	priv->link_check_timer.expires = jiffies + LINK_CHECK_TIMER_FREQ;
	add_timer(&priv->link_check_timer);

	//priv->tx_reclaim_timer.expires = jiffies + TX_RECLAIM_TIMER_FREQ;
	//add_timer(&priv->tx_reclaim_timer);

	/* and finally start tx queue */
	netif_start_queue(dev);

	/* start rx dma engine */
	enet_start_rx(priv);

	return 0;
}
Beispiel #7
0
static void smc_phy_check_media(struct net_device *dev, int init)
{
	struct smc_local *lp = netdev_priv(dev);
	void __iomem *ioaddr = lp->base;

	if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
		
		if (lp->mii.full_duplex) {
			lp->tcr_cur_mode |= TCR_SWFDUP;
		} else {
			lp->tcr_cur_mode &= ~TCR_SWFDUP;
		}

		SMC_SELECT_BANK(lp, 0);
		SMC_SET_TCR(lp, lp->tcr_cur_mode);
	}
}