diff options
Diffstat (limited to 'drivers/net/arm')
| -rw-r--r-- | drivers/net/arm/at91_ether.c | 156 | ||||
| -rw-r--r-- | drivers/net/arm/at91_ether.h | 1 | ||||
| -rw-r--r-- | drivers/net/arm/ether1.c | 3 | ||||
| -rw-r--r-- | drivers/net/arm/ether3.c | 3 |
4 files changed, 126 insertions, 37 deletions
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 5503dc8a66e4..613005a0285d 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c | |||
| @@ -43,7 +43,9 @@ | |||
| 43 | #define DRV_VERSION "1.0" | 43 | #define DRV_VERSION "1.0" |
| 44 | 44 | ||
| 45 | static struct net_device *at91_dev; | 45 | static struct net_device *at91_dev; |
| 46 | static struct clk *ether_clk; | 46 | |
| 47 | static struct timer_list check_timer; | ||
| 48 | #define LINK_POLL_INTERVAL (HZ) | ||
| 47 | 49 | ||
| 48 | /* ..................................................................... */ | 50 | /* ..................................................................... */ |
| 49 | 51 | ||
| @@ -143,7 +145,7 @@ static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int | |||
| 143 | * MAC accordingly. | 145 | * MAC accordingly. |
| 144 | * If no link or auto-negotiation is busy, then no changes are made. | 146 | * If no link or auto-negotiation is busy, then no changes are made. |
| 145 | */ | 147 | */ |
| 146 | static void update_linkspeed(struct net_device *dev) | 148 | static void update_linkspeed(struct net_device *dev, int silent) |
| 147 | { | 149 | { |
| 148 | struct at91_private *lp = (struct at91_private *) dev->priv; | 150 | struct at91_private *lp = (struct at91_private *) dev->priv; |
| 149 | unsigned int bmsr, bmcr, lpa, mac_cfg; | 151 | unsigned int bmsr, bmcr, lpa, mac_cfg; |
| @@ -151,7 +153,8 @@ static void update_linkspeed(struct net_device *dev) | |||
| 151 | 153 | ||
| 152 | if (!mii_link_ok(&lp->mii)) { /* no link */ | 154 | if (!mii_link_ok(&lp->mii)) { /* no link */ |
| 153 | netif_carrier_off(dev); | 155 | netif_carrier_off(dev); |
| 154 | printk(KERN_INFO "%s: Link down.\n", dev->name); | 156 | if (!silent) |
| 157 | printk(KERN_INFO "%s: Link down.\n", dev->name); | ||
| 155 | return; | 158 | return; |
| 156 | } | 159 | } |
| 157 | 160 | ||
| @@ -186,7 +189,8 @@ static void update_linkspeed(struct net_device *dev) | |||
| 186 | } | 189 | } |
| 187 | at91_emac_write(AT91_EMAC_CFG, mac_cfg); | 190 | at91_emac_write(AT91_EMAC_CFG, mac_cfg); |
| 188 | 191 | ||
| 189 | printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); | 192 | if (!silent) |
| 193 | printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex"); | ||
| 190 | netif_carrier_on(dev); | 194 | netif_carrier_on(dev); |
| 191 | } | 195 | } |
| 192 | 196 | ||
| @@ -226,7 +230,7 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs | |||
| 226 | goto done; | 230 | goto done; |
| 227 | } | 231 | } |
| 228 | 232 | ||
| 229 | update_linkspeed(dev); | 233 | update_linkspeed(dev, 0); |
| 230 | 234 | ||
| 231 | done: | 235 | done: |
| 232 | disable_mdi(); | 236 | disable_mdi(); |
| @@ -243,14 +247,17 @@ static void enable_phyirq(struct net_device *dev) | |||
| 243 | unsigned int dsintr, irq_number; | 247 | unsigned int dsintr, irq_number; |
| 244 | int status; | 248 | int status; |
| 245 | 249 | ||
| 246 | if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ | 250 | irq_number = lp->board_data.phy_irq_pin; |
| 247 | return; | 251 | if (!irq_number) { |
| 248 | if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ | 252 | /* |
| 249 | return; | 253 | * PHY doesn't have an IRQ pin (RTL8201, DP83847, AC101L), |
| 250 | if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ | 254 | * or board does not have it connected. |
| 255 | */ | ||
| 256 | check_timer.expires = jiffies + LINK_POLL_INTERVAL; | ||
| 257 | add_timer(&check_timer); | ||
| 251 | return; | 258 | return; |
| 259 | } | ||
| 252 | 260 | ||
| 253 | irq_number = lp->board_data.phy_irq_pin; | ||
| 254 | status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); | 261 | status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev); |
| 255 | if (status) { | 262 | if (status) { |
| 256 | printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); | 263 | printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status); |
| @@ -292,12 +299,11 @@ static void disable_phyirq(struct net_device *dev) | |||
| 292 | unsigned int dsintr; | 299 | unsigned int dsintr; |
| 293 | unsigned int irq_number; | 300 | unsigned int irq_number; |
| 294 | 301 | ||
| 295 | if (lp->phy_type == MII_RTL8201_ID) /* RTL8201 does not have an interrupt */ | 302 | irq_number = lp->board_data.phy_irq_pin; |
| 296 | return; | 303 | if (!irq_number) { |
| 297 | if (lp->phy_type == MII_DP83847_ID) /* DP83847 does not have an interrupt */ | 304 | del_timer_sync(&check_timer); |
| 298 | return; | ||
| 299 | if (lp->phy_type == MII_AC101L_ID) /* AC101L interrupt not supported yet */ | ||
| 300 | return; | 305 | return; |
| 306 | } | ||
| 301 | 307 | ||
| 302 | spin_lock_irq(&lp->lock); | 308 | spin_lock_irq(&lp->lock); |
| 303 | enable_mdi(); | 309 | enable_mdi(); |
| @@ -326,7 +332,6 @@ static void disable_phyirq(struct net_device *dev) | |||
| 326 | disable_mdi(); | 332 | disable_mdi(); |
| 327 | spin_unlock_irq(&lp->lock); | 333 | spin_unlock_irq(&lp->lock); |
| 328 | 334 | ||
| 329 | irq_number = lp->board_data.phy_irq_pin; | ||
| 330 | free_irq(irq_number, dev); /* Free interrupt handler */ | 335 | free_irq(irq_number, dev); /* Free interrupt handler */ |
| 331 | } | 336 | } |
| 332 | 337 | ||
| @@ -355,6 +360,18 @@ static void reset_phy(struct net_device *dev) | |||
| 355 | } | 360 | } |
| 356 | #endif | 361 | #endif |
| 357 | 362 | ||
| 363 | static void at91ether_check_link(unsigned long dev_id) | ||
| 364 | { | ||
| 365 | struct net_device *dev = (struct net_device *) dev_id; | ||
| 366 | |||
| 367 | enable_mdi(); | ||
| 368 | update_linkspeed(dev, 1); | ||
| 369 | disable_mdi(); | ||
| 370 | |||
| 371 | check_timer.expires = jiffies + LINK_POLL_INTERVAL; | ||
| 372 | add_timer(&check_timer); | ||
| 373 | } | ||
| 374 | |||
| 358 | /* ......................... ADDRESS MANAGEMENT ........................ */ | 375 | /* ......................... ADDRESS MANAGEMENT ........................ */ |
| 359 | 376 | ||
| 360 | /* | 377 | /* |
| @@ -501,7 +518,7 @@ static int hash_get_index(__u8 *addr) | |||
| 501 | hash_index |= (bitval << j); | 518 | hash_index |= (bitval << j); |
| 502 | } | 519 | } |
| 503 | 520 | ||
| 504 | return hash_index; | 521 | return hash_index; |
| 505 | } | 522 | } |
| 506 | 523 | ||
| 507 | /* | 524 | /* |
| @@ -557,10 +574,8 @@ static void at91ether_set_rx_mode(struct net_device *dev) | |||
| 557 | at91_emac_write(AT91_EMAC_CFG, cfg); | 574 | at91_emac_write(AT91_EMAC_CFG, cfg); |
| 558 | } | 575 | } |
| 559 | 576 | ||
| 560 | |||
| 561 | /* ......................... ETHTOOL SUPPORT ........................... */ | 577 | /* ......................... ETHTOOL SUPPORT ........................... */ |
| 562 | 578 | ||
| 563 | |||
| 564 | static int mdio_read(struct net_device *dev, int phy_id, int location) | 579 | static int mdio_read(struct net_device *dev, int phy_id, int location) |
| 565 | { | 580 | { |
| 566 | unsigned int value; | 581 | unsigned int value; |
| @@ -642,6 +657,22 @@ static struct ethtool_ops at91ether_ethtool_ops = { | |||
| 642 | .get_link = ethtool_op_get_link, | 657 | .get_link = ethtool_op_get_link, |
| 643 | }; | 658 | }; |
| 644 | 659 | ||
| 660 | static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
| 661 | { | ||
| 662 | struct at91_private *lp = (struct at91_private *) dev->priv; | ||
| 663 | int res; | ||
| 664 | |||
| 665 | if (!netif_running(dev)) | ||
| 666 | return -EINVAL; | ||
| 667 | |||
| 668 | spin_lock_irq(&lp->lock); | ||
| 669 | enable_mdi(); | ||
| 670 | res = generic_mii_ioctl(&lp->mii, if_mii(rq), cmd, NULL); | ||
| 671 | disable_mdi(); | ||
| 672 | spin_unlock_irq(&lp->lock); | ||
| 673 | |||
| 674 | return res; | ||
| 675 | } | ||
| 645 | 676 | ||
| 646 | /* ................................ MAC ................................ */ | 677 | /* ................................ MAC ................................ */ |
| 647 | 678 | ||
| @@ -685,10 +716,10 @@ static int at91ether_open(struct net_device *dev) | |||
| 685 | struct at91_private *lp = (struct at91_private *) dev->priv; | 716 | struct at91_private *lp = (struct at91_private *) dev->priv; |
| 686 | unsigned long ctl; | 717 | unsigned long ctl; |
| 687 | 718 | ||
| 688 | if (!is_valid_ether_addr(dev->dev_addr)) | 719 | if (!is_valid_ether_addr(dev->dev_addr)) |
| 689 | return -EADDRNOTAVAIL; | 720 | return -EADDRNOTAVAIL; |
| 690 | 721 | ||
| 691 | clk_enable(ether_clk); /* Re-enable Peripheral clock */ | 722 | clk_enable(lp->ether_clk); /* Re-enable Peripheral clock */ |
| 692 | 723 | ||
| 693 | /* Clear internal statistics */ | 724 | /* Clear internal statistics */ |
| 694 | ctl = at91_emac_read(AT91_EMAC_CTL); | 725 | ctl = at91_emac_read(AT91_EMAC_CTL); |
| @@ -708,7 +739,7 @@ static int at91ether_open(struct net_device *dev) | |||
| 708 | /* Determine current link speed */ | 739 | /* Determine current link speed */ |
| 709 | spin_lock_irq(&lp->lock); | 740 | spin_lock_irq(&lp->lock); |
| 710 | enable_mdi(); | 741 | enable_mdi(); |
| 711 | update_linkspeed(dev); | 742 | update_linkspeed(dev, 0); |
| 712 | disable_mdi(); | 743 | disable_mdi(); |
| 713 | spin_unlock_irq(&lp->lock); | 744 | spin_unlock_irq(&lp->lock); |
| 714 | 745 | ||
| @@ -722,6 +753,7 @@ static int at91ether_open(struct net_device *dev) | |||
| 722 | */ | 753 | */ |
| 723 | static int at91ether_close(struct net_device *dev) | 754 | static int at91ether_close(struct net_device *dev) |
| 724 | { | 755 | { |
| 756 | struct at91_private *lp = (struct at91_private *) dev->priv; | ||
| 725 | unsigned long ctl; | 757 | unsigned long ctl; |
| 726 | 758 | ||
| 727 | /* Disable Receiver and Transmitter */ | 759 | /* Disable Receiver and Transmitter */ |
| @@ -738,7 +770,7 @@ static int at91ether_close(struct net_device *dev) | |||
| 738 | 770 | ||
| 739 | netif_stop_queue(dev); | 771 | netif_stop_queue(dev); |
| 740 | 772 | ||
| 741 | clk_disable(ether_clk); /* Disable Peripheral clock */ | 773 | clk_disable(lp->ether_clk); /* Disable Peripheral clock */ |
| 742 | 774 | ||
| 743 | return 0; | 775 | return 0; |
| 744 | } | 776 | } |
| @@ -870,7 +902,7 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re | |||
| 870 | if (intstatus & AT91_EMAC_RCOM) /* Receive complete */ | 902 | if (intstatus & AT91_EMAC_RCOM) /* Receive complete */ |
| 871 | at91ether_rx(dev); | 903 | at91ether_rx(dev); |
| 872 | 904 | ||
| 873 | if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ | 905 | if (intstatus & AT91_EMAC_TCOM) { /* Transmit complete */ |
| 874 | /* The TCOM bit is set even if the transmission failed. */ | 906 | /* The TCOM bit is set even if the transmission failed. */ |
| 875 | if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) | 907 | if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY)) |
| 876 | lp->stats.tx_errors += 1; | 908 | lp->stats.tx_errors += 1; |
| @@ -899,7 +931,8 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *re | |||
| 899 | /* | 931 | /* |
| 900 | * Initialize the ethernet interface | 932 | * Initialize the ethernet interface |
| 901 | */ | 933 | */ |
| 902 | static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev) | 934 | static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, |
| 935 | struct platform_device *pdev, struct clk *ether_clk) | ||
| 903 | { | 936 | { |
| 904 | struct at91_eth_data *board_data = pdev->dev.platform_data; | 937 | struct at91_eth_data *board_data = pdev->dev.platform_data; |
| 905 | struct net_device *dev; | 938 | struct net_device *dev; |
| @@ -933,6 +966,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
| 933 | return -ENOMEM; | 966 | return -ENOMEM; |
| 934 | } | 967 | } |
| 935 | lp->board_data = *board_data; | 968 | lp->board_data = *board_data; |
| 969 | lp->ether_clk = ether_clk; | ||
| 936 | platform_set_drvdata(pdev, dev); | 970 | platform_set_drvdata(pdev, dev); |
| 937 | 971 | ||
| 938 | spin_lock_init(&lp->lock); | 972 | spin_lock_init(&lp->lock); |
| @@ -945,6 +979,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
| 945 | dev->set_multicast_list = at91ether_set_rx_mode; | 979 | dev->set_multicast_list = at91ether_set_rx_mode; |
| 946 | dev->set_mac_address = set_mac_address; | 980 | dev->set_mac_address = set_mac_address; |
| 947 | dev->ethtool_ops = &at91ether_ethtool_ops; | 981 | dev->ethtool_ops = &at91ether_ethtool_ops; |
| 982 | dev->do_ioctl = at91ether_ioctl; | ||
| 948 | 983 | ||
| 949 | SET_NETDEV_DEV(dev, &pdev->dev); | 984 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 950 | 985 | ||
| @@ -975,6 +1010,9 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
| 975 | lp->mii.dev = dev; /* Support for ethtool */ | 1010 | lp->mii.dev = dev; /* Support for ethtool */ |
| 976 | lp->mii.mdio_read = mdio_read; | 1011 | lp->mii.mdio_read = mdio_read; |
| 977 | lp->mii.mdio_write = mdio_write; | 1012 | lp->mii.mdio_write = mdio_write; |
| 1013 | lp->mii.phy_id = phy_address; | ||
| 1014 | lp->mii.phy_id_mask = 0x1f; | ||
| 1015 | lp->mii.reg_num_mask = 0x1f; | ||
| 978 | 1016 | ||
| 979 | lp->phy_type = phy_type; /* Type of PHY connected */ | 1017 | lp->phy_type = phy_type; /* Type of PHY connected */ |
| 980 | lp->phy_address = phy_address; /* MDI address of PHY */ | 1018 | lp->phy_address = phy_address; /* MDI address of PHY */ |
| @@ -992,11 +1030,18 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
| 992 | /* Determine current link speed */ | 1030 | /* Determine current link speed */ |
| 993 | spin_lock_irq(&lp->lock); | 1031 | spin_lock_irq(&lp->lock); |
| 994 | enable_mdi(); | 1032 | enable_mdi(); |
| 995 | update_linkspeed(dev); | 1033 | update_linkspeed(dev, 0); |
| 996 | disable_mdi(); | 1034 | disable_mdi(); |
| 997 | spin_unlock_irq(&lp->lock); | 1035 | spin_unlock_irq(&lp->lock); |
| 998 | netif_carrier_off(dev); /* will be enabled in open() */ | 1036 | netif_carrier_off(dev); /* will be enabled in open() */ |
| 999 | 1037 | ||
| 1038 | /* If board has no PHY IRQ, use a timer to poll the PHY */ | ||
| 1039 | if (!lp->board_data.phy_irq_pin) { | ||
| 1040 | init_timer(&check_timer); | ||
| 1041 | check_timer.data = (unsigned long)dev; | ||
| 1042 | check_timer.function = at91ether_check_link; | ||
| 1043 | } | ||
| 1044 | |||
| 1000 | /* Display ethernet banner */ | 1045 | /* Display ethernet banner */ |
| 1001 | printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", | 1046 | printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n", |
| 1002 | dev->name, (uint) dev->base_addr, dev->irq, | 1047 | dev->name, (uint) dev->base_addr, dev->irq, |
| @@ -1005,7 +1050,7 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add | |||
| 1005 | dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], | 1050 | dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], |
| 1006 | dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); | 1051 | dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); |
| 1007 | if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) | 1052 | if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) |
| 1008 | printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); | 1053 | printk(KERN_INFO "%s: Davicom 9161 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)"); |
| 1009 | else if (phy_type == MII_LXT971A_ID) | 1054 | else if (phy_type == MII_LXT971A_ID) |
| 1010 | printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); | 1055 | printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name); |
| 1011 | else if (phy_type == MII_RTL8201_ID) | 1056 | else if (phy_type == MII_RTL8201_ID) |
| @@ -1031,9 +1076,10 @@ static int __init at91ether_probe(struct platform_device *pdev) | |||
| 1031 | int detected = -1; | 1076 | int detected = -1; |
| 1032 | unsigned long phy_id; | 1077 | unsigned long phy_id; |
| 1033 | unsigned short phy_address = 0; | 1078 | unsigned short phy_address = 0; |
| 1079 | struct clk *ether_clk; | ||
| 1034 | 1080 | ||
| 1035 | ether_clk = clk_get(&pdev->dev, "ether_clk"); | 1081 | ether_clk = clk_get(&pdev->dev, "ether_clk"); |
| 1036 | if (!ether_clk) { | 1082 | if (IS_ERR(ether_clk)) { |
| 1037 | printk(KERN_ERR "at91_ether: no clock defined\n"); | 1083 | printk(KERN_ERR "at91_ether: no clock defined\n"); |
| 1038 | return -ENODEV; | 1084 | return -ENODEV; |
| 1039 | } | 1085 | } |
| @@ -1056,7 +1102,7 @@ static int __init at91ether_probe(struct platform_device *pdev) | |||
| 1056 | case MII_DP83847_ID: /* National Semiconductor DP83847: */ | 1102 | case MII_DP83847_ID: /* National Semiconductor DP83847: */ |
| 1057 | case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ | 1103 | case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ |
| 1058 | case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ | 1104 | case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ |
| 1059 | detected = at91ether_setup(phy_id, phy_address, pdev); | 1105 | detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk); |
| 1060 | break; | 1106 | break; |
| 1061 | } | 1107 | } |
| 1062 | 1108 | ||
| @@ -1075,17 +1121,61 @@ static int __devexit at91ether_remove(struct platform_device *pdev) | |||
| 1075 | unregister_netdev(at91_dev); | 1121 | unregister_netdev(at91_dev); |
| 1076 | free_irq(at91_dev->irq, at91_dev); | 1122 | free_irq(at91_dev->irq, at91_dev); |
| 1077 | dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); | 1123 | dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys); |
| 1078 | clk_put(ether_clk); | 1124 | clk_put(lp->ether_clk); |
| 1079 | 1125 | ||
| 1080 | free_netdev(at91_dev); | 1126 | free_netdev(at91_dev); |
| 1081 | at91_dev = NULL; | 1127 | at91_dev = NULL; |
| 1082 | return 0; | 1128 | return 0; |
| 1083 | } | 1129 | } |
| 1084 | 1130 | ||
| 1131 | #ifdef CONFIG_PM | ||
| 1132 | |||
| 1133 | static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) | ||
| 1134 | { | ||
| 1135 | struct at91_private *lp = (struct at91_private *) at91_dev->priv; | ||
| 1136 | struct net_device *net_dev = platform_get_drvdata(pdev); | ||
| 1137 | int phy_irq = lp->board_data.phy_irq_pin; | ||
| 1138 | |||
| 1139 | if (netif_running(net_dev)) { | ||
| 1140 | if (phy_irq) | ||
| 1141 | disable_irq(phy_irq); | ||
| 1142 | |||
| 1143 | netif_stop_queue(net_dev); | ||
| 1144 | netif_device_detach(net_dev); | ||
| 1145 | |||
| 1146 | clk_disable(lp->ether_clk); | ||
| 1147 | } | ||
| 1148 | return 0; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | static int at91ether_resume(struct platform_device *pdev) | ||
| 1152 | { | ||
| 1153 | struct at91_private *lp = (struct at91_private *) at91_dev->priv; | ||
| 1154 | struct net_device *net_dev = platform_get_drvdata(pdev); | ||
| 1155 | int phy_irq = lp->board_data.phy_irq_pin; | ||
| 1156 | |||
| 1157 | if (netif_running(net_dev)) { | ||
| 1158 | clk_enable(lp->ether_clk); | ||
| 1159 | |||
| 1160 | netif_device_attach(net_dev); | ||
| 1161 | netif_start_queue(net_dev); | ||
| 1162 | |||
| 1163 | if (phy_irq) | ||
| 1164 | enable_irq(phy_irq); | ||
| 1165 | } | ||
| 1166 | return 0; | ||
| 1167 | } | ||
| 1168 | |||
| 1169 | #else | ||
| 1170 | #define at91ether_suspend NULL | ||
| 1171 | #define at91ether_resume NULL | ||
| 1172 | #endif | ||
| 1173 | |||
| 1085 | static struct platform_driver at91ether_driver = { | 1174 | static struct platform_driver at91ether_driver = { |
| 1086 | .probe = at91ether_probe, | 1175 | .probe = at91ether_probe, |
| 1087 | .remove = __devexit_p(at91ether_remove), | 1176 | .remove = __devexit_p(at91ether_remove), |
| 1088 | /* FIXME: support suspend and resume */ | 1177 | .suspend = at91ether_suspend, |
| 1178 | .resume = at91ether_resume, | ||
| 1089 | .driver = { | 1179 | .driver = { |
| 1090 | .name = DRV_NAME, | 1180 | .name = DRV_NAME, |
| 1091 | .owner = THIS_MODULE, | 1181 | .owner = THIS_MODULE, |
diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h index 9885735c9c8a..d1e72e02be3a 100644 --- a/drivers/net/arm/at91_ether.h +++ b/drivers/net/arm/at91_ether.h | |||
| @@ -80,6 +80,7 @@ struct at91_private | |||
| 80 | struct net_device_stats stats; | 80 | struct net_device_stats stats; |
| 81 | struct mii_if_info mii; /* ethtool support */ | 81 | struct mii_if_info mii; /* ethtool support */ |
| 82 | struct at91_eth_data board_data; /* board-specific configuration */ | 82 | struct at91_eth_data board_data; /* board-specific configuration */ |
| 83 | struct clk *ether_clk; /* clock */ | ||
| 83 | 84 | ||
| 84 | /* PHY */ | 85 | /* PHY */ |
| 85 | unsigned long phy_type; /* type of PHY (PHY_ID) */ | 86 | unsigned long phy_type; /* type of PHY (PHY_ID) */ |
diff --git a/drivers/net/arm/ether1.c b/drivers/net/arm/ether1.c index 36475eb2727f..312955d07b28 100644 --- a/drivers/net/arm/ether1.c +++ b/drivers/net/arm/ether1.c | |||
| @@ -700,8 +700,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev) | |||
| 700 | } | 700 | } |
| 701 | 701 | ||
| 702 | if (skb->len < ETH_ZLEN) { | 702 | if (skb->len < ETH_ZLEN) { |
| 703 | skb = skb_padto(skb, ETH_ZLEN); | 703 | if (skb_padto(skb, ETH_ZLEN)) |
| 704 | if (skb == NULL) | ||
| 705 | goto out; | 704 | goto out; |
| 706 | } | 705 | } |
| 707 | 706 | ||
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c index f1d5b1027ff7..081074180e62 100644 --- a/drivers/net/arm/ether3.c +++ b/drivers/net/arm/ether3.c | |||
| @@ -518,8 +518,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev) | |||
| 518 | 518 | ||
| 519 | length = (length + 1) & ~1; | 519 | length = (length + 1) & ~1; |
| 520 | if (length != skb->len) { | 520 | if (length != skb->len) { |
| 521 | skb = skb_padto(skb, length); | 521 | if (skb_padto(skb, length)) |
| 522 | if (skb == NULL) | ||
| 523 | goto out; | 522 | goto out; |
| 524 | } | 523 | } |
| 525 | 524 | ||
