aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c52
1 files changed, 10 insertions, 42 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index cb9cb3013f42..070b78d959cc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -613,38 +613,20 @@ down:
613static int bond_update_speed_duplex(struct slave *slave) 613static int bond_update_speed_duplex(struct slave *slave)
614{ 614{
615 struct net_device *slave_dev = slave->dev; 615 struct net_device *slave_dev = slave->dev;
616 static int (* ioctl)(struct net_device *, struct ifreq *, int);
617 struct ifreq ifr;
618 struct ethtool_cmd etool; 616 struct ethtool_cmd etool;
617 int res;
619 618
620 /* Fake speed and duplex */ 619 /* Fake speed and duplex */
621 slave->speed = SPEED_100; 620 slave->speed = SPEED_100;
622 slave->duplex = DUPLEX_FULL; 621 slave->duplex = DUPLEX_FULL;
623 622
624 if (slave_dev->ethtool_ops) { 623 if (!slave_dev->ethtool_ops || !slave_dev->ethtool_ops->get_settings)
625 int res; 624 return -1;
626
627 if (!slave_dev->ethtool_ops->get_settings) {
628 return -1;
629 }
630
631 res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool);
632 if (res < 0) {
633 return -1;
634 }
635
636 goto verify;
637 }
638 625
639 ioctl = slave_dev->do_ioctl; 626 res = slave_dev->ethtool_ops->get_settings(slave_dev, &etool);
640 strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ); 627 if (res < 0)
641 etool.cmd = ETHTOOL_GSET;
642 ifr.ifr_data = (char*)&etool;
643 if (!ioctl || (IOCTL(slave_dev, &ifr, SIOCETHTOOL) < 0)) {
644 return -1; 628 return -1;
645 }
646 629
647verify:
648 switch (etool.speed) { 630 switch (etool.speed) {
649 case SPEED_10: 631 case SPEED_10:
650 case SPEED_100: 632 case SPEED_100:
@@ -690,7 +672,6 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
690 static int (* ioctl)(struct net_device *, struct ifreq *, int); 672 static int (* ioctl)(struct net_device *, struct ifreq *, int);
691 struct ifreq ifr; 673 struct ifreq ifr;
692 struct mii_ioctl_data *mii; 674 struct mii_ioctl_data *mii;
693 struct ethtool_value etool;
694 675
695 if (bond->params.use_carrier) { 676 if (bond->params.use_carrier) {
696 return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0; 677 return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
@@ -721,9 +702,10 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
721 } 702 }
722 } 703 }
723 704
724 /* try SIOCETHTOOL ioctl, some drivers cache ETHTOOL_GLINK */ 705 /*
725 /* for a period of time so we attempt to get link status */ 706 * Some drivers cache ETHTOOL_GLINK for a period of time so we only
726 /* from it last if the above MII ioctls fail... */ 707 * attempt to get link status from it if the above MII ioctls fail.
708 */
727 if (slave_dev->ethtool_ops) { 709 if (slave_dev->ethtool_ops) {
728 if (slave_dev->ethtool_ops->get_link) { 710 if (slave_dev->ethtool_ops->get_link) {
729 u32 link; 711 u32 link;
@@ -734,23 +716,9 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
734 } 716 }
735 } 717 }
736 718
737 if (ioctl) {
738 strncpy(ifr.ifr_name, slave_dev->name, IFNAMSIZ);
739 etool.cmd = ETHTOOL_GLINK;
740 ifr.ifr_data = (char*)&etool;
741 if (IOCTL(slave_dev, &ifr, SIOCETHTOOL) == 0) {
742 if (etool.data == 1) {
743 return BMSR_LSTATUS;
744 } else {
745 dprintk("SIOCETHTOOL shows link down\n");
746 return 0;
747 }
748 }
749 }
750
751 /* 719 /*
752 * If reporting, report that either there's no dev->do_ioctl, 720 * If reporting, report that either there's no dev->do_ioctl,
753 * or both SIOCGMIIREG and SIOCETHTOOL failed (meaning that we 721 * or both SIOCGMIIREG and get_link failed (meaning that we
754 * cannot report link status). If not reporting, pretend 722 * cannot report link status). If not reporting, pretend
755 * we're ok. 723 * we're ok.
756 */ 724 */