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; }
/* * 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); }
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; }
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; }
/* * 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; }
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); } }