net/igb/e1000/e1000e: more robust ethtool duplex/speed configuration
[deliverable/linux.git] / drivers / net / igb / igb_main.c
index cdfd5727105123bbd1d2357a19d578ce58df46a4..ce7838e55827b2e639f999d0b974b074bdaff7cb 100644 (file)
@@ -6349,21 +6349,25 @@ static void igb_restore_vlan(struct igb_adapter *adapter)
        }
 }
 
-int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
+int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx)
 {
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_mac_info *mac = &adapter->hw.mac;
 
        mac->autoneg = 0;
 
+       /* Make sure dplx is at most 1 bit and lsb of speed is not set
+        * for the switch() below to work */
+       if ((spd & 1) || (dplx & ~1))
+               goto err_inval;
+
        /* Fiber NIC's only allow 1000 Gbps Full duplex */
        if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) &&
-               spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-               dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
-               return -EINVAL;
-       }
+           spd != SPEED_1000 &&
+           dplx != DUPLEX_FULL)
+               goto err_inval;
 
-       switch (spddplx) {
+       switch (spd + dplx) {
        case SPEED_10 + DUPLEX_HALF:
                mac->forced_speed_duplex = ADVERTISE_10_HALF;
                break;
@@ -6382,10 +6386,13 @@ int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
                break;
        case SPEED_1000 + DUPLEX_HALF: /* not supported */
        default:
-               dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
-               return -EINVAL;
+               goto err_inval;
        }
        return 0;
+
+err_inval:
+       dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
+       return -EINVAL;
 }
 
 static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
This page took 0.070522 seconds and 5 git commands to generate.