diff options
Diffstat (limited to 'drivers/net/yellowfin.c')
-rw-r--r-- | drivers/net/yellowfin.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 76764237cde6..4987040c414b 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c | |||
@@ -346,8 +346,9 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | |||
346 | static int yellowfin_open(struct net_device *dev); | 346 | static int yellowfin_open(struct net_device *dev); |
347 | static void yellowfin_timer(unsigned long data); | 347 | static void yellowfin_timer(unsigned long data); |
348 | static void yellowfin_tx_timeout(struct net_device *dev); | 348 | static void yellowfin_tx_timeout(struct net_device *dev); |
349 | static void yellowfin_init_ring(struct net_device *dev); | 349 | static int yellowfin_init_ring(struct net_device *dev); |
350 | static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev); | 350 | static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb, |
351 | struct net_device *dev); | ||
351 | static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); | 352 | static irqreturn_t yellowfin_interrupt(int irq, void *dev_instance); |
352 | static int yellowfin_rx(struct net_device *dev); | 353 | static int yellowfin_rx(struct net_device *dev); |
353 | static void yellowfin_error(struct net_device *dev, int intr_status); | 354 | static void yellowfin_error(struct net_device *dev, int intr_status); |
@@ -573,19 +574,24 @@ static int yellowfin_open(struct net_device *dev) | |||
573 | { | 574 | { |
574 | struct yellowfin_private *yp = netdev_priv(dev); | 575 | struct yellowfin_private *yp = netdev_priv(dev); |
575 | void __iomem *ioaddr = yp->base; | 576 | void __iomem *ioaddr = yp->base; |
576 | int i; | 577 | int i, ret; |
577 | 578 | ||
578 | /* Reset the chip. */ | 579 | /* Reset the chip. */ |
579 | iowrite32(0x80000000, ioaddr + DMACtrl); | 580 | iowrite32(0x80000000, ioaddr + DMACtrl); |
580 | 581 | ||
581 | i = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); | 582 | ret = request_irq(dev->irq, &yellowfin_interrupt, IRQF_SHARED, dev->name, dev); |
582 | if (i) return i; | 583 | if (ret) |
584 | return ret; | ||
583 | 585 | ||
584 | if (yellowfin_debug > 1) | 586 | if (yellowfin_debug > 1) |
585 | printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", | 587 | printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n", |
586 | dev->name, dev->irq); | 588 | dev->name, dev->irq); |
587 | 589 | ||
588 | yellowfin_init_ring(dev); | 590 | ret = yellowfin_init_ring(dev); |
591 | if (ret) { | ||
592 | free_irq(dev->irq, dev); | ||
593 | return ret; | ||
594 | } | ||
589 | 595 | ||
590 | iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); | 596 | iowrite32(yp->rx_ring_dma, ioaddr + RxPtr); |
591 | iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); | 597 | iowrite32(yp->tx_ring_dma, ioaddr + TxPtr); |
@@ -725,10 +731,10 @@ static void yellowfin_tx_timeout(struct net_device *dev) | |||
725 | } | 731 | } |
726 | 732 | ||
727 | /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ | 733 | /* Initialize the Rx and Tx rings, along with various 'dev' bits. */ |
728 | static void yellowfin_init_ring(struct net_device *dev) | 734 | static int yellowfin_init_ring(struct net_device *dev) |
729 | { | 735 | { |
730 | struct yellowfin_private *yp = netdev_priv(dev); | 736 | struct yellowfin_private *yp = netdev_priv(dev); |
731 | int i; | 737 | int i, j; |
732 | 738 | ||
733 | yp->tx_full = 0; | 739 | yp->tx_full = 0; |
734 | yp->cur_rx = yp->cur_tx = 0; | 740 | yp->cur_rx = yp->cur_tx = 0; |
@@ -753,6 +759,11 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
753 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, | 759 | yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, |
754 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); | 760 | skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); |
755 | } | 761 | } |
762 | if (i != RX_RING_SIZE) { | ||
763 | for (j = 0; j < i; j++) | ||
764 | dev_kfree_skb(yp->rx_skbuff[j]); | ||
765 | return -ENOMEM; | ||
766 | } | ||
756 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); | 767 | yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); |
757 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); | 768 | yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); |
758 | 769 | ||
@@ -769,8 +780,6 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
769 | yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); | 780 | yp->tx_ring[--i].dbdma_cmd = cpu_to_le32(CMD_STOP | BRANCH_ALWAYS); |
770 | #else | 781 | #else |
771 | { | 782 | { |
772 | int j; | ||
773 | |||
774 | /* Tx ring needs a pair of descriptors, the second for the status. */ | 783 | /* Tx ring needs a pair of descriptors, the second for the status. */ |
775 | for (i = 0; i < TX_RING_SIZE; i++) { | 784 | for (i = 0; i < TX_RING_SIZE; i++) { |
776 | j = 2*i; | 785 | j = 2*i; |
@@ -805,10 +814,11 @@ static void yellowfin_init_ring(struct net_device *dev) | |||
805 | } | 814 | } |
806 | #endif | 815 | #endif |
807 | yp->tx_tail_desc = &yp->tx_status[0]; | 816 | yp->tx_tail_desc = &yp->tx_status[0]; |
808 | return; | 817 | return 0; |
809 | } | 818 | } |
810 | 819 | ||
811 | static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev) | 820 | static netdev_tx_t yellowfin_start_xmit(struct sk_buff *skb, |
821 | struct net_device *dev) | ||
812 | { | 822 | { |
813 | struct yellowfin_private *yp = netdev_priv(dev); | 823 | struct yellowfin_private *yp = netdev_priv(dev); |
814 | unsigned entry; | 824 | unsigned entry; |