tg3: Update ethtool set_settings error checks
authorMatt Carlson <mcarlson@broadcom.com>
Wed, 25 Feb 2009 14:23:01 +0000 (14:23 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 27 Feb 2009 07:16:32 +0000 (23:16 -0800)
The ethtool interface has acquired some new enumerations since the
tg3 driver's tg3_set_settings() error checking code was written.  The
error checking code is no longer complete.  This patch rewrites the
error checking so that it is future-proofed.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/tg3.c

index 774a01ab03be9cef6bddda4d39e3b705b28bb7f8..0ea61f7f6203c61f123c5a94ac1a179840c2c61c 100644 (file)
@@ -8552,7 +8552,7 @@ static int tg3_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                cmd->duplex = tp->link_config.active_duplex;
        }
        cmd->phy_address = PHY_ADDR;
-       cmd->transceiver = 0;
+       cmd->transceiver = XCVR_INTERNAL;
        cmd->autoneg = tp->link_config.autoneg;
        cmd->maxtxpkt = 0;
        cmd->maxrxpkt = 0;
@@ -8569,26 +8569,58 @@ static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                return phy_ethtool_sset(tp->mdio_bus->phy_map[PHY_ADDR], cmd);
        }
 
-       if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
-               /* These are the only valid advertisement bits allowed.  */
-               if (cmd->autoneg == AUTONEG_ENABLE &&
-                   (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
-                                         ADVERTISED_1000baseT_Full |
-                                         ADVERTISED_Autoneg |
-                                         ADVERTISED_FIBRE)))
-                       return -EINVAL;
-               /* Fiber can only do SPEED_1000.  */
-               else if ((cmd->autoneg != AUTONEG_ENABLE) &&
-                        (cmd->speed != SPEED_1000))
-                       return -EINVAL;
-       /* Copper cannot force SPEED_1000.  */
-       } else if ((cmd->autoneg != AUTONEG_ENABLE) &&
-                  (cmd->speed == SPEED_1000))
+       if (cmd->autoneg != AUTONEG_ENABLE &&
+           cmd->autoneg != AUTONEG_DISABLE)
                return -EINVAL;
-       else if ((cmd->speed == SPEED_1000) &&
-                (tp->tg3_flags & TG3_FLAG_10_100_ONLY))
+
+       if (cmd->autoneg == AUTONEG_DISABLE &&
+           cmd->duplex != DUPLEX_FULL &&
+           cmd->duplex != DUPLEX_HALF)
                return -EINVAL;
 
+       if (cmd->autoneg == AUTONEG_ENABLE) {
+               u32 mask = ADVERTISED_Autoneg |
+                          ADVERTISED_Pause |
+                          ADVERTISED_Asym_Pause;
+
+               if (!(tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+                       mask |= ADVERTISED_1000baseT_Half |
+                               ADVERTISED_1000baseT_Full;
+
+               if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
+                       mask |= ADVERTISED_100baseT_Half |
+                               ADVERTISED_100baseT_Full |
+                               ADVERTISED_10baseT_Half |
+                               ADVERTISED_10baseT_Full |
+                               ADVERTISED_TP;
+               else
+                       mask |= ADVERTISED_FIBRE;
+
+               if (cmd->advertising & ~mask)
+                       return -EINVAL;
+
+               mask &= (ADVERTISED_1000baseT_Half |
+                        ADVERTISED_1000baseT_Full |
+                        ADVERTISED_100baseT_Half |
+                        ADVERTISED_100baseT_Full |
+                        ADVERTISED_10baseT_Half |
+                        ADVERTISED_10baseT_Full);
+
+               cmd->advertising &= mask;
+       } else {
+               if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) {
+                       if (cmd->speed != SPEED_1000)
+                               return -EINVAL;
+
+                       if (cmd->duplex != DUPLEX_FULL)
+                               return -EINVAL;
+               } else {
+                       if (cmd->speed != SPEED_100 &&
+                           cmd->speed != SPEED_10)
+                               return -EINVAL;
+               }
+       }
+
        tg3_full_lock(tp, 0);
 
        tp->link_config.autoneg = cmd->autoneg;