ixgbe: ethtool support to change advertised link modes of 82599 adapters
authorMallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Thu, 4 Jun 2009 11:11:34 +0000 (11:11 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 7 Jun 2009 12:20:19 +0000 (05:20 -0700)
Add ethtool support to change advertised link modes/autoneg settings of
82599 multispeed fiber adapters.

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_ethtool.c

index 4d83e59165930ce3d6021018f634eab790d53b42..3f36d834ccfdf70c2e331430286fff48485eaeb3 100644 (file)
@@ -464,6 +464,15 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
        hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
        speed &= phy_link_speed;
 
+        /* Set autoneg_advertised value based on input link speed */
+       hw->phy.autoneg_advertised = 0;
+
+       if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+       if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
        /*
         * When the driver changes the link speeds that it can support,
         * it sets autotry_restart to true to indicate that we need to
index 1c110459d33b816ef3889bba6f48878cb853cda8..e0feaf5725bb99588b9c91f27db162ae9599bd32 100644 (file)
@@ -136,11 +136,12 @@ static int ixgbe_get_settings(struct net_device *netdev,
        ecmd->supported = SUPPORTED_10000baseT_Full;
        ecmd->autoneg = AUTONEG_ENABLE;
        ecmd->transceiver = XCVR_EXTERNAL;
-       if (hw->phy.media_type == ixgbe_media_type_copper) {
+       if ((hw->phy.media_type == ixgbe_media_type_copper) ||
+           (hw->mac.type == ixgbe_mac_82599EB)) {
                ecmd->supported |= (SUPPORTED_1000baseT_Full |
-                                   SUPPORTED_TP | SUPPORTED_Autoneg);
+                                   SUPPORTED_Autoneg);
 
-               ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
+               ecmd->advertising = ADVERTISED_Autoneg;
                if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
                        ecmd->advertising |= ADVERTISED_10000baseT_Full;
                if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
@@ -155,7 +156,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
                        ecmd->advertising |= (ADVERTISED_10000baseT_Full |
                                              ADVERTISED_1000baseT_Full);
 
-               ecmd->port = PORT_TP;
+               if (hw->phy.media_type == ixgbe_media_type_copper) {
+                       ecmd->supported |= SUPPORTED_TP;
+                       ecmd->advertising |= ADVERTISED_TP;
+                       ecmd->port = PORT_TP;
+               } else {
+                       ecmd->supported |= SUPPORTED_FIBRE;
+                       ecmd->advertising |= ADVERTISED_FIBRE;
+                       ecmd->port = PORT_FIBRE;
+               }
        } else if (hw->phy.media_type == ixgbe_media_type_backplane) {
                /* Set as FIBRE until SERDES defined in kernel */
                switch (hw->device_id) {
@@ -203,16 +212,10 @@ static int ixgbe_set_settings(struct net_device *netdev,
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
        u32 advertised, old;
-       s32 err;
+       s32 err = 0;
 
-       switch (hw->phy.media_type) {
-       case ixgbe_media_type_fiber:
-               if ((ecmd->autoneg == AUTONEG_ENABLE) ||
-                   (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
-                       return -EINVAL;
-               /* in this case we currently only support 10Gb/FULL */
-               break;
-       case ixgbe_media_type_copper:
+       if ((hw->phy.media_type == ixgbe_media_type_copper) ||
+           (hw->mac.type == ixgbe_mac_82599EB)) {
                /* 10000/copper and 1000/copper must autoneg
                 * this function does not support any duplex forcing, but can
                 * limit the advertising of the adapter to only 10000 or 1000 */
@@ -228,20 +231,23 @@ static int ixgbe_set_settings(struct net_device *netdev,
                        advertised |= IXGBE_LINK_SPEED_1GB_FULL;
 
                if (old == advertised)
-                       break;
+                       return err;
                /* this sets the link speed and restarts auto-neg */
+               hw->mac.autotry_restart = true;
                err = hw->mac.ops.setup_link_speed(hw, advertised, true, true);
                if (err) {
                        DPRINTK(PROBE, INFO,
                                "setup link failed with code %d\n", err);
                        hw->mac.ops.setup_link_speed(hw, old, true, true);
                }
-               break;
-       default:
-               break;
+       } else {
+               /* in this case we currently only support 10Gb/FULL */
+               if ((ecmd->autoneg == AUTONEG_ENABLE) ||
+                   (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
+                       return -EINVAL;
        }
 
-       return 0;
+       return err;
 }
 
 static void ixgbe_get_pauseparam(struct net_device *netdev,