Пример #1
0
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
}
Пример #2
0
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);

}
Пример #3
0
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. */
	}
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
/**************************************************************************
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
}
Пример #7
0
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);
	}
}
Пример #8
0
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);
}
Пример #9
0
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;
}