Beispiel #1
0
static void mace_tx_timeout(struct net_device *dev)
{
	struct mace_data *mp = netdev_priv(dev);
	volatile struct mace *mb = mp->mace;
	unsigned long flags;

	local_irq_save(flags);

	/* turn off both tx and rx and reset the chip */
	mb->maccc = 0;
	printk(KERN_ERR "macmace: transmit timeout - resetting\n");
	mace_txdma_reset(dev);
	mace_reset(dev);

	/* restart rx dma */
	mace_rxdma_reset(dev);

	mp->tx_count = N_TX_RING;
	netif_wake_queue(dev);

	/* turn it on! */
	mb->maccc = ENXMT | ENRCV;
	/* enable all interrupts except receive interrupts */
	mb->imr = RCVINT;

	local_irq_restore(flags);
}
Beispiel #2
0
static int mace_open(struct net_device *dev)
{
    struct mace_data *mp = netdev_priv(dev);
    volatile struct mace *mb = mp->mace;

    /* reset the chip */
    mace_reset(dev);

    if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) {
        printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq);
        return -EAGAIN;
    }
    if (request_irq(mp->dma_intr, mace_dma_intr, 0, dev->name, dev)) {
        printk(KERN_ERR "%s: can't get irq %d\n", dev->name, mp->dma_intr);
        free_irq(dev->irq, dev);
        return -EAGAIN;
    }

    /* Allocate the DMA ring buffers */

    mp->tx_ring = dma_alloc_coherent(mp->device,
                                     N_TX_RING * MACE_BUFF_SIZE,
                                     &mp->tx_ring_phys, GFP_KERNEL);
    if (mp->tx_ring == NULL)
        goto out1;

    mp->rx_ring = dma_alloc_coherent(mp->device,
                                     N_RX_RING * MACE_BUFF_SIZE,
                                     &mp->rx_ring_phys, GFP_KERNEL);
    if (mp->rx_ring == NULL)
        goto out2;

    mace_dma_off(dev);

    /* Not sure what these do */

    psc_write_word(PSC_ENETWR_CTL, 0x9000);
    psc_write_word(PSC_ENETRD_CTL, 0x9000);
    psc_write_word(PSC_ENETWR_CTL, 0x0400);
    psc_write_word(PSC_ENETRD_CTL, 0x0400);

    mace_rxdma_reset(dev);
    mace_txdma_reset(dev);

    /* turn it on! */
    mb->maccc = ENXMT | ENRCV;
    /* enable all interrupts except receive interrupts */
    mb->imr = RCVINT;
    return 0;

out2:
    dma_free_coherent(mp->device, N_TX_RING * MACE_BUFF_SIZE,
                      mp->tx_ring, mp->tx_ring_phys);
out1:
    free_irq(dev->irq, dev);
    free_irq(mp->dma_intr, dev);
    return -ENOMEM;
}
Beispiel #3
0
static irqreturn_t mace_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = (struct net_device *) dev_id;
	struct mace_data *mp = netdev_priv(dev);
	volatile struct mace *mb = mp->mace;
	int intr, fs;
	unsigned int flags;

	/* don't want the dma interrupt handler to fire */
	local_irq_save(flags);

	intr = mb->ir; /* read interrupt register */
	mace_handle_misc_intrs(mp, intr);

	if (intr & XMTINT) {
		fs = mb->xmtfs;
		if ((fs & XMTSV) == 0) {
			printk(KERN_ERR "macmace: xmtfs not valid! (fs=%x)\n", fs);
			mace_reset(dev);
			/*
			 * XXX mace likes to hang the machine after a xmtfs error.
			 * This is hard to reproduce, reseting *may* help
			 */
		}
		/* dma should have finished */
		if (!mp->tx_count) {
			printk(KERN_DEBUG "macmace: tx ring ran out? (fs=%x)\n", fs);
		}
		/* Update stats */
		if (fs & (UFLO|LCOL|LCAR|RTRY)) {
			++mp->stats.tx_errors;
			if (fs & LCAR)
				++mp->stats.tx_carrier_errors;
			else if (fs & (UFLO|LCOL|RTRY)) {
				++mp->stats.tx_aborted_errors;
				if (mb->xmtfs & UFLO) {
					printk(KERN_ERR "%s: DMA underrun.\n", dev->name);
					mp->stats.tx_fifo_errors++;
					mace_txdma_reset(dev);
				}
			}
		}
	}

	if (mp->tx_count)
		netif_wake_queue(dev);

	local_irq_restore(flags);

	return IRQ_HANDLED;
}
static int mace_open(struct net_device *dev)
{
	struct mace_data *mp = netdev_priv(dev);
	volatile struct mace *mb = mp->mace;

	
	mace_reset(dev);

	if (request_irq(dev->irq, mace_interrupt, 0, dev->name, dev)) {
		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, dev->irq);
		return -EAGAIN;
	}
	if (request_irq(mp->dma_intr, mace_dma_intr, 0, dev->name, dev)) {
		printk(KERN_ERR "%s: can't get irq %d\n", dev->name, mp->dma_intr);
		free_irq(dev->irq, dev);
		return -EAGAIN;
	}

	

	mp->tx_ring = dma_alloc_coherent(mp->device,
			N_TX_RING * MACE_BUFF_SIZE,
			&mp->tx_ring_phys, GFP_KERNEL);
	if (mp->tx_ring == NULL) {
		printk(KERN_ERR "%s: unable to allocate DMA tx buffers\n", dev->name);
		goto out1;
	}

	mp->rx_ring = dma_alloc_coherent(mp->device,
			N_RX_RING * MACE_BUFF_SIZE,
			&mp->rx_ring_phys, GFP_KERNEL);
	if (mp->rx_ring == NULL) {
		printk(KERN_ERR "%s: unable to allocate DMA rx buffers\n", dev->name);
		goto out2;
	}

	mace_dma_off(dev);

	

	psc_write_word(PSC_ENETWR_CTL, 0x9000);
	psc_write_word(PSC_ENETRD_CTL, 0x9000);
	psc_write_word(PSC_ENETWR_CTL, 0x0400);
	psc_write_word(PSC_ENETRD_CTL, 0x0400);

	mace_rxdma_reset(dev);
	mace_txdma_reset(dev);

	
	mb->maccc = ENXMT | ENRCV;
	
	mb->imr = RCVINT;
	return 0;

out2:
	dma_free_coherent(mp->device, N_TX_RING * MACE_BUFF_SIZE,
	                  mp->tx_ring, mp->tx_ring_phys);
out1:
	free_irq(dev->irq, dev);
	free_irq(mp->dma_intr, dev);
	return -ENOMEM;
}