diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 109 |
1 files changed, 45 insertions, 64 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 5de06d714ab0..6118ea799a65 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -83,8 +83,8 @@ static int eth_port_link_is_up(unsigned int eth_port_num); | |||
83 | static void eth_port_uc_addr_get(struct net_device *dev, | 83 | static void eth_port_uc_addr_get(struct net_device *dev, |
84 | unsigned char *MacAddr); | 84 | unsigned char *MacAddr); |
85 | static void eth_port_set_multicast_list(struct net_device *); | 85 | static void eth_port_set_multicast_list(struct net_device *); |
86 | static int mv643xx_eth_real_open(struct net_device *); | 86 | static int mv643xx_eth_open(struct net_device *); |
87 | static int mv643xx_eth_real_stop(struct net_device *); | 87 | static int mv643xx_eth_stop(struct net_device *); |
88 | static int mv643xx_eth_change_mtu(struct net_device *, int); | 88 | static int mv643xx_eth_change_mtu(struct net_device *, int); |
89 | static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *); | 89 | static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *); |
90 | static void eth_port_init_mac_tables(unsigned int eth_port_num); | 90 | static void eth_port_init_mac_tables(unsigned int eth_port_num); |
@@ -140,11 +140,8 @@ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) | |||
140 | * to memory is full, which might fail the open function. | 140 | * to memory is full, which might fail the open function. |
141 | */ | 141 | */ |
142 | if (netif_running(dev)) { | 142 | if (netif_running(dev)) { |
143 | if (mv643xx_eth_real_stop(dev)) | 143 | mv643xx_eth_stop(dev); |
144 | printk(KERN_ERR | 144 | if (mv643xx_eth_open(dev)) |
145 | "%s: Fatal error on stopping device\n", | ||
146 | dev->name); | ||
147 | if (mv643xx_eth_real_open(dev)) | ||
148 | printk(KERN_ERR | 145 | printk(KERN_ERR |
149 | "%s: Fatal error on opening device\n", | 146 | "%s: Fatal error on opening device\n", |
150 | dev->name); | 147 | dev->name); |
@@ -632,42 +629,6 @@ static unsigned int eth_port_set_tx_coal(unsigned int eth_port_num, | |||
632 | } | 629 | } |
633 | 630 | ||
634 | /* | 631 | /* |
635 | * mv643xx_eth_open | ||
636 | * | ||
637 | * This function is called when openning the network device. The function | ||
638 | * should initialize all the hardware, initialize cyclic Rx/Tx | ||
639 | * descriptors chain and buffers and allocate an IRQ to the network | ||
640 | * device. | ||
641 | * | ||
642 | * Input : a pointer to the network device structure | ||
643 | * | ||
644 | * Output : zero of success , nonzero if fails. | ||
645 | */ | ||
646 | |||
647 | static int mv643xx_eth_open(struct net_device *dev) | ||
648 | { | ||
649 | struct mv643xx_private *mp = netdev_priv(dev); | ||
650 | unsigned int port_num = mp->port_num; | ||
651 | int err; | ||
652 | |||
653 | err = request_irq(dev->irq, mv643xx_eth_int_handler, | ||
654 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); | ||
655 | if (err) { | ||
656 | printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n", | ||
657 | port_num); | ||
658 | return -EAGAIN; | ||
659 | } | ||
660 | |||
661 | if (mv643xx_eth_real_open(dev)) { | ||
662 | printk("%s: Error opening interface\n", dev->name); | ||
663 | free_irq(dev->irq, dev); | ||
664 | err = -EBUSY; | ||
665 | } | ||
666 | |||
667 | return err; | ||
668 | } | ||
669 | |||
670 | /* | ||
671 | * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. | 632 | * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. |
672 | * | 633 | * |
673 | * DESCRIPTION: | 634 | * DESCRIPTION: |
@@ -759,12 +720,33 @@ static void ether_init_tx_desc_ring(struct mv643xx_private *mp) | |||
759 | mp->port_tx_queue_command |= 1; | 720 | mp->port_tx_queue_command |= 1; |
760 | } | 721 | } |
761 | 722 | ||
762 | /* Helper function for mv643xx_eth_open */ | 723 | /* |
763 | static int mv643xx_eth_real_open(struct net_device *dev) | 724 | * mv643xx_eth_open |
725 | * | ||
726 | * This function is called when openning the network device. The function | ||
727 | * should initialize all the hardware, initialize cyclic Rx/Tx | ||
728 | * descriptors chain and buffers and allocate an IRQ to the network | ||
729 | * device. | ||
730 | * | ||
731 | * Input : a pointer to the network device structure | ||
732 | * | ||
733 | * Output : zero of success , nonzero if fails. | ||
734 | */ | ||
735 | |||
736 | static int mv643xx_eth_open(struct net_device *dev) | ||
764 | { | 737 | { |
765 | struct mv643xx_private *mp = netdev_priv(dev); | 738 | struct mv643xx_private *mp = netdev_priv(dev); |
766 | unsigned int port_num = mp->port_num; | 739 | unsigned int port_num = mp->port_num; |
767 | unsigned int size; | 740 | unsigned int size; |
741 | int err; | ||
742 | |||
743 | err = request_irq(dev->irq, mv643xx_eth_int_handler, | ||
744 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); | ||
745 | if (err) { | ||
746 | printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n", | ||
747 | port_num); | ||
748 | return -EAGAIN; | ||
749 | } | ||
768 | 750 | ||
769 | /* Stop RX Queues */ | 751 | /* Stop RX Queues */ |
770 | mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); | 752 | mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); |
@@ -788,14 +770,15 @@ static int mv643xx_eth_real_open(struct net_device *dev) | |||
788 | GFP_KERNEL); | 770 | GFP_KERNEL); |
789 | if (!mp->rx_skb) { | 771 | if (!mp->rx_skb) { |
790 | printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name); | 772 | printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name); |
791 | return -ENOMEM; | 773 | err = -ENOMEM; |
774 | goto out_free_irq; | ||
792 | } | 775 | } |
793 | mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size, | 776 | mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size, |
794 | GFP_KERNEL); | 777 | GFP_KERNEL); |
795 | if (!mp->tx_skb) { | 778 | if (!mp->tx_skb) { |
796 | printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name); | 779 | printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name); |
797 | kfree(mp->rx_skb); | 780 | err = -ENOMEM; |
798 | return -ENOMEM; | 781 | goto out_free_rx_skb; |
799 | } | 782 | } |
800 | 783 | ||
801 | /* Allocate TX ring */ | 784 | /* Allocate TX ring */ |
@@ -815,9 +798,8 @@ static int mv643xx_eth_real_open(struct net_device *dev) | |||
815 | if (!mp->p_tx_desc_area) { | 798 | if (!mp->p_tx_desc_area) { |
816 | printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", | 799 | printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", |
817 | dev->name, size); | 800 | dev->name, size); |
818 | kfree(mp->rx_skb); | 801 | err = -ENOMEM; |
819 | kfree(mp->tx_skb); | 802 | goto out_free_tx_skb; |
820 | return -ENOMEM; | ||
821 | } | 803 | } |
822 | BUG_ON((u32) mp->p_tx_desc_area & 0xf); /* check 16-byte alignment */ | 804 | BUG_ON((u32) mp->p_tx_desc_area & 0xf); /* check 16-byte alignment */ |
823 | memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size); | 805 | memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size); |
@@ -848,9 +830,8 @@ static int mv643xx_eth_real_open(struct net_device *dev) | |||
848 | else | 830 | else |
849 | dma_free_coherent(NULL, mp->tx_desc_area_size, | 831 | dma_free_coherent(NULL, mp->tx_desc_area_size, |
850 | mp->p_tx_desc_area, mp->tx_desc_dma); | 832 | mp->p_tx_desc_area, mp->tx_desc_dma); |
851 | kfree(mp->rx_skb); | 833 | err = -ENOMEM; |
852 | kfree(mp->tx_skb); | 834 | goto out_free_tx_skb; |
853 | return -ENOMEM; | ||
854 | } | 835 | } |
855 | memset((void *)mp->p_rx_desc_area, 0, size); | 836 | memset((void *)mp->p_rx_desc_area, 0, size); |
856 | 837 | ||
@@ -882,6 +863,15 @@ static int mv643xx_eth_real_open(struct net_device *dev) | |||
882 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), | 863 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), |
883 | INT_CAUSE_UNMASK_ALL); | 864 | INT_CAUSE_UNMASK_ALL); |
884 | return 0; | 865 | return 0; |
866 | |||
867 | out_free_tx_skb: | ||
868 | kfree(mp->tx_skb); | ||
869 | out_free_rx_skb: | ||
870 | kfree(mp->rx_skb); | ||
871 | out_free_irq: | ||
872 | free_irq(dev->irq, dev); | ||
873 | |||
874 | return err; | ||
885 | } | 875 | } |
886 | 876 | ||
887 | static void mv643xx_eth_free_tx_rings(struct net_device *dev) | 877 | static void mv643xx_eth_free_tx_rings(struct net_device *dev) |
@@ -955,9 +945,7 @@ static void mv643xx_eth_free_rx_rings(struct net_device *dev) | |||
955 | * Output : zero if success , nonzero if fails | 945 | * Output : zero if success , nonzero if fails |
956 | */ | 946 | */ |
957 | 947 | ||
958 | /* Helper function for mv643xx_eth_stop */ | 948 | static int mv643xx_eth_stop(struct net_device *dev) |
959 | |||
960 | static int mv643xx_eth_real_stop(struct net_device *dev) | ||
961 | { | 949 | { |
962 | struct mv643xx_private *mp = netdev_priv(dev); | 950 | struct mv643xx_private *mp = netdev_priv(dev); |
963 | unsigned int port_num = mp->port_num; | 951 | unsigned int port_num = mp->port_num; |
@@ -986,13 +974,6 @@ static int mv643xx_eth_real_stop(struct net_device *dev) | |||
986 | netif_poll_enable(dev); | 974 | netif_poll_enable(dev); |
987 | #endif | 975 | #endif |
988 | 976 | ||
989 | return 0; | ||
990 | } | ||
991 | |||
992 | static int mv643xx_eth_stop(struct net_device *dev) | ||
993 | { | ||
994 | mv643xx_eth_real_stop(dev); | ||
995 | |||
996 | free_irq(dev->irq, dev); | 977 | free_irq(dev->irq, dev); |
997 | 978 | ||
998 | return 0; | 979 | return 0; |