]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
bnxt_en: Check for valid forced speed during ethtool -s.
authorMichael Chan <michael.chan@broadcom.com>
Tue, 5 Apr 2016 18:09:02 +0000 (14:09 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 5 Apr 2016 20:20:48 +0000 (16:20 -0400)
Check that the forced speed is a valid speed supported by firmware.
If not supported, return -EINVAL.

Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index 47e08a8b15631ac06f73b78a1868259e6f57078e..952b5ba1c4da7846a405818155934629f0fa5337 100644 (file)
@@ -739,28 +739,49 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 static u32 bnxt_get_fw_speed(struct net_device *dev, u16 ethtool_speed)
 {
+       struct bnxt *bp = netdev_priv(dev);
+       struct bnxt_link_info *link_info = &bp->link_info;
+       u16 support_spds = link_info->support_speeds;
+       u32 fw_speed = 0;
+
        switch (ethtool_speed) {
        case SPEED_100:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_100MB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_100MB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_100MB;
+               break;
        case SPEED_1000:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_1GB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_1GB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_1GB;
+               break;
        case SPEED_2500:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_2_5GB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_2_5GB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_2_5GB;
+               break;
        case SPEED_10000:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_10GB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_10GB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_10GB;
+               break;
        case SPEED_20000:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_20GB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_20GB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_20GB;
+               break;
        case SPEED_25000:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_25GB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_25GB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_25GB;
+               break;
        case SPEED_40000:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_40GB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_40GB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_40GB;
+               break;
        case SPEED_50000:
-               return PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_50GB;
+               if (support_spds & BNXT_LINK_SPEED_MSK_50GB)
+                       fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_50GB;
+               break;
        default:
                netdev_err(dev, "unsupported speed!\n");
                break;
        }
-       return 0;
+       return fw_speed;
 }
 
 u16 bnxt_get_fw_auto_link_speeds(u32 advertising)
@@ -823,6 +844,8 @@ static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                 */
                set_pause = true;
        } else {
+               u16 fw_speed;
+
                /* TODO: currently don't support half duplex */
                if (cmd->duplex == DUPLEX_HALF) {
                        netdev_err(dev, "HALF DUPLEX is not supported!\n");
@@ -833,7 +856,12 @@ static int bnxt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                if (cmd->duplex == DUPLEX_UNKNOWN)
                        cmd->duplex = DUPLEX_FULL;
                speed = ethtool_cmd_speed(cmd);
-               link_info->req_link_speed = bnxt_get_fw_speed(dev, speed);
+               fw_speed = bnxt_get_fw_speed(dev, speed);
+               if (!fw_speed) {
+                       rc = -EINVAL;
+                       goto set_setting_exit;
+               }
+               link_info->req_link_speed = fw_speed;
                link_info->req_duplex = BNXT_LINK_DUPLEX_FULL;
                link_info->autoneg = 0;
                link_info->advertising = 0;