static void w89c840_reset(struct nic *nic) { int i; writel(0x00000001, ioaddr + PCIBusCfg); init_ring(); writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr); writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr); for (i = 0; i < ETH_ALEN; i++) writeb(nic->node_addr[i], ioaddr + StationAddr + i); writel(0xE010, ioaddr + PCIBusCfg); writel(0, ioaddr + RxStartDemand); w840private.csr6 = 0x20022002; check_duplex(); set_rx_mode(); writel(0x1A0F5, ioaddr + IntrStatus); writel(0x1A0F5, ioaddr + IntrEnable); #if defined(W89C840_DEBUG) printf("winbond-840 : Done reset.\n"); #endif }
static void init_registers(struct net_device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; int i; for (i = 0; i < 6; i++) writeb(dev->dev_addr[i], ioaddr + StationAddr + i); /* Initialize other registers. */ /* Configure the PCI bus bursts and FIFO thresholds. 486: Set 8 longword cache alignment, 8 longword burst. 586: Set 16 longword cache alignment, no burst limit. Cache alignment bits 15:14 Burst length 13:8 0000 <not allowed> 0000 align to cache 0800 8 longwords 4000 8 longwords 0100 1 longword 1000 16 longwords 8000 16 longwords 0200 2 longwords 2000 32 longwords C000 32 longwords 0400 4 longwords Wait the specified 50 PCI cycles after a reset by initializing Tx and Rx queues and the address filter list. */ #if defined(__powerpc__) /* Big-endian */ writel(0x00100080 | 0xE010, ioaddr + PCIBusCfg); #elif defined(__alpha__) writel(0xE010, ioaddr + PCIBusCfg); #elif defined(__i386__) #if defined(MODULE) writel(0xE010, ioaddr + PCIBusCfg); #else /* When not a module we can work around broken '486 PCI boards. */ #define x86 boot_cpu_data.x86 writel((x86 <= 4 ? 0x4810 : 0xE010), ioaddr + PCIBusCfg); if (x86 <= 4) printk(KERN_INFO "%s: This is a 386/486 PCI system, setting cache " "alignment to %x.\n", dev->name, (x86 <= 4 ? 0x4810 : 0x8010)); #endif #else writel(0xE010, ioaddr + PCIBusCfg); #warning Processor architecture undefined! #endif if (dev->if_port == 0) dev->if_port = np->default_port; /* Fast Ethernet; 128 byte Tx threshold; Transmit on; Receive on; */ np->csr6 = 0x20022002; check_duplex(dev); set_rx_mode(dev); writel(0, ioaddr + RxStartDemand); /* Clear and Enable interrupts by setting the interrupt mask. */ writel(0x1A0F5, ioaddr + IntrStatus); writel(0x1A0F5, ioaddr + IntrEnable); }
static void netdev_error(struct net_device *dev, int intr_status) { long ioaddr = dev->base_addr; struct netdev_private *np = dev->priv; u16 mii_reg0, mii_reg4, mii_reg5; int speed; if (intr_status & IntrDrvRqst) { /* Stop the down counter and turn interrupts back on. */ if (debug > 1) printk("%s: Turning interrupts back on.\n", dev->name); writew(0, ioaddr + IntrEnable); writew(0, ioaddr + DownCounter); writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst | IntrTxDone | StatsMax | LinkChange, ioaddr + IntrEnable); /* Ack buggy InRequest */ writew (IntrDrvRqst, ioaddr + IntrStatus); } if (intr_status & LinkChange) { if (np->an_enable) { mii_reg4 = mdio_read (dev, np->phys[0], 4); mii_reg5= mdio_read (dev, np->phys[0], 5); mii_reg4 &= mii_reg5; printk (KERN_INFO "%s: Link changed: ", dev->name); if (mii_reg4 & 0x0100) printk ("100Mbps, full duplex\n"); else if (mii_reg4 & 0x0080) printk ("100Mbps, half duplex\n"); else if (mii_reg4 & 0x0040) printk ("10Mbps, full duplex\n"); else if (mii_reg4 & 0x0020) printk ("10Mbps, half duplex\n"); else printk ("\n"); } else { mii_reg0 = mdio_read (dev, np->phys[0], 0); speed = (mii_reg0 & 0x2000) ? 100 : 10; printk (KERN_INFO "%s: Link changed: %dMbps ,", dev->name, speed); printk ("%s duplex.\n", (mii_reg0 & 0x0100) ? "full" : "half"); } check_duplex (dev); } if (intr_status & StatsMax) { get_stats(dev); } if (intr_status & IntrPCIErr) { printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", dev->name, intr_status); /* We must do a global reset of DMA to continue. */ } }
static void netdev_timer(unsigned long data) { struct device *dev = (struct device *)data; struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 10*HZ; if (debug > 3) { printk(KERN_DEBUG "%s: VIA Rhine monitor tick, status %4.4x.\n", dev->name, readw(ioaddr + IntrStatus)); } check_duplex(dev); np->timer.expires = RUN_AT(next_tick); add_timer(&np->timer); }
static void netdev_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; int next_tick = 10*HZ; if (debug > 3) { printk(KERN_DEBUG "%s: Media selection timer tick, intr status %4.4x, " "Tx %x Rx %x.\n", dev->name, readw(ioaddr + IntrEnable), readb(ioaddr + TxStatus), readl(ioaddr + RxStatus)); } check_duplex(dev); np->timer.expires = jiffies + next_tick; add_timer(&np->timer); }
/************************************************************************** w89c840_reset - Reset adapter ***************************************************************************/ static void w89c840_reset(struct nic *nic) { int i; /* Reset the chip to erase previous misconfiguration. No hold time required! */ writel(0x00000001, ioaddr + PCIBusCfg); init_ring(); writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr); writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr); for (i = 0; i < ETH_ALEN; i++) writeb(nic->node_addr[i], ioaddr + StationAddr + i); /* Initialize other registers. */ /* Configure the PCI bus bursts and FIFO thresholds. 486: Set 8 longword cache alignment, 8 longword burst. 586: Set 16 longword cache alignment, no burst limit. Cache alignment bits 15:14 Burst length 13:8 0000 <not allowed> 0000 align to cache 0800 8 longwords 4000 8 longwords 0100 1 longword 1000 16 longwords 8000 16 longwords 0200 2 longwords 2000 32 longwords C000 32 longwords 0400 4 longwords Wait the specified 50 PCI cycles after a reset by initializing Tx and Rx queues and the address filter list. */ writel(0xE010, ioaddr + PCIBusCfg); writel(0, ioaddr + RxStartDemand); w840private.csr6 = 0x20022002; check_duplex(); set_rx_mode(); /* Do not enable the interrupts Etherboot doesn't need them */ /* writel(0x1A0F5, ioaddr + IntrStatus); writel(0x1A0F5, ioaddr + IntrEnable); */ #if defined(W89C840_DEBUG) printf("winbond-840 : Done reset.\n"); #endif }
static void netdev_error(struct device *dev, int intr_status) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; if (intr_status & (IntrMIIChange | IntrLinkChange)) { if (readb(ioaddr + MIIStatus) & 0x02) /* Link failed, restart autonegotiation. */ mdio_write(dev, np->phys[0], 0, 0x3300); else check_duplex(dev); if (debug) printk(KERN_ERR "%s: MII status changed: Autonegotiation " "advertising %4.4x partner %4.4x.\n", dev->name, mdio_read(dev, np->phys[0], 4), mdio_read(dev, np->phys[0], 5)); } if (intr_status & IntrStatsMax) { np->stats.rx_crc_errors += readw(ioaddr + RxCRCErrs); np->stats.rx_missed_errors += readw(ioaddr + RxMissed); writel(0, RxMissed); } if (intr_status & IntrTxAbort) { /* Stats counted in Tx-done handler, just restart Tx. */ writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd); } if (intr_status & IntrTxUnderrun) { if (np->tx_thresh < 0xE0) writeb(np->tx_thresh += 0x20, ioaddr + TxConfig); if (debug > 1) printk(KERN_INFO "%s: Transmitter underrun, increasing Tx " "threshold setting to %2.2x.\n", dev->name, np->tx_thresh); } if ((intr_status & ~(IntrLinkChange|IntrStatsMax|IntrTxAbort)) && debug) { printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n", dev->name, intr_status); /* Recovery for other fault sources not known. */ writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd); } }
static void netdev_timer(unsigned long data) { struct net_device *dev = (struct net_device *)data; struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; int next_tick = 10*HZ; int old_csr6 = np->csr6; if (debug > 2) printk(KERN_DEBUG "%s: Media selection timer tick, status %8.8x " "config %8.8x.\n", dev->name, (int)readl(ioaddr + IntrStatus), (int)readl(ioaddr + NetworkConfig)); spin_lock_irq(&np->lock); check_duplex(dev); if (np->csr6 != old_csr6) { writel(np->csr6 & ~0x0002, ioaddr + NetworkConfig); writel(np->csr6 | 0x2002, ioaddr + NetworkConfig); } spin_unlock_irq(&np->lock); np->timer.expires = jiffies + next_tick; add_timer(&np->timer); }
static int netdev_open(struct device *dev) { struct netdev_private *np = (struct netdev_private *)dev->priv; long ioaddr = dev->base_addr; int i; /* Reset the chip. */ writew(CmdReset, ioaddr + ChipCmd); if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev)) return -EAGAIN; if (debug > 1) printk(KERN_DEBUG "%s: netdev_open() irq %d.\n", dev->name, dev->irq); MOD_INC_USE_COUNT; init_ring(dev); writel(virt_to_bus(np->rx_ring), ioaddr + RxRingPtr); writel(virt_to_bus(np->tx_ring), ioaddr + TxRingPtr); for (i = 0; i < 6; i++) writeb(dev->dev_addr[i], ioaddr + StationAddr + i); /* Initialize other registers. */ writew(0x0006, ioaddr + PCIConfig); /* Tune configuration??? */ /* Configure the FIFO thresholds. */ writeb(0x20, ioaddr + TxConfig); /* Initial threshold 32 bytes */ np->tx_thresh = 0x20; np->rx_thresh = 0x60; /* Written in set_rx_mode(). */ if (dev->if_port == 0) dev->if_port = np->default_port; dev->tbusy = 0; dev->interrupt = 0; np->in_interrupt = 0; set_rx_mode(dev); dev->start = 1; /* Enable interrupts by setting the interrupt mask. */ writew(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow| IntrRxDropped| IntrTxDone | IntrTxAbort | IntrTxUnderrun | IntrPCIErr | IntrStatsMax | IntrLinkChange | IntrMIIChange, ioaddr + IntrEnable); np->chip_cmd = CmdStart|CmdTxOn|CmdRxOn|CmdNoTxPoll; if (np->duplex_lock) np->chip_cmd |= CmdFDuplex; writew(np->chip_cmd, ioaddr + ChipCmd); check_duplex(dev); if (debug > 2) printk(KERN_DEBUG "%s: Done netdev_open(), status %4.4x " "MII status: %4.4x.\n", dev->name, readw(ioaddr + ChipCmd), mdio_read(dev, np->phys[0], 1)); /* Set the timer to check for link beat. */ init_timer(&np->timer); np->timer.expires = RUN_AT(1); np->timer.data = (unsigned long)dev; np->timer.function = &netdev_timer; /* timer handler */ add_timer(&np->timer); return 0; }