int rc = 0;
        struct hwrm_port_phy_qcaps_input req = {0};
        struct hwrm_port_phy_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+       struct bnxt_link_info *link_info = &bp->link_info;
 
        if (bp->hwrm_spec_code < 0x10201)
                return 0;
                bp->lpi_tmr_hi = le32_to_cpu(resp->valid_tx_lpi_timer_high) &
                                 PORT_PHY_QCAPS_RESP_TX_LPI_TIMER_HIGH_MASK;
        }
+       link_info->support_auto_speeds =
+               le16_to_cpu(resp->supported_speeds_auto_mode);
 
 hwrm_phy_qcaps_exit:
        mutex_unlock(&bp->hwrm_cmd_lock);
                return rc;
        }
 
+       /* Older firmware does not have supported_auto_speeds, so assume
+        * that all supported speeds can be autonegotiated.
+        */
+       if (link_info->auto_link_speeds && !link_info->support_auto_speeds)
+               link_info->support_auto_speeds = link_info->support_speeds;
+
        /*initialize the ethool setting copy with NVM settings */
        if (BNXT_AUTO_MODE(link_info->auto_mode)) {
                link_info->autoneg = BNXT_AUTONEG_SPEED;
 
        return supported | SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 }
 
+static u32 bnxt_fw_to_ethtool_support_adv_spds(struct bnxt_link_info *link_info)
+{
+       u16 fw_speeds = link_info->support_auto_speeds;
+       u32 supported;
+
+       supported = _bnxt_fw_to_ethtool_adv_spds(fw_speeds, 0);
+       if (supported)
+               supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
+       return supported;
+}
+
 u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
 {
        switch (fw_link_speed) {
 
        cmd->supported = bnxt_fw_to_ethtool_support_spds(link_info);
 
-       if (link_info->auto_link_speeds)
+       if (link_info->support_auto_speeds)
                cmd->supported |= SUPPORTED_Autoneg;
 
        if (link_info->autoneg) {
                return rc;
 
        if (cmd->autoneg == AUTONEG_ENABLE) {
-               u32 supported_spds = bnxt_fw_to_ethtool_support_spds(link_info);
+               u32 supported_spds =
+                       bnxt_fw_to_ethtool_support_adv_spds(link_info);
 
+               if (!supported_spds) {
+                       netdev_err(dev, "Autoneg not supported\n");
+                       rc = -EINVAL;
+                       goto set_setting_exit;
+               }
                if (cmd->advertising & ~(supported_spds | ADVERTISED_Autoneg |
                                         ADVERTISED_TP | ADVERTISED_FIBRE)) {
                        netdev_err(dev, "Unsupported advertising mask (adv: 0x%x)\n",
                        goto set_setting_exit;
                }
                fw_advertising = bnxt_get_fw_auto_link_speeds(cmd->advertising);
-               if (fw_advertising & ~link_info->support_speeds) {
-                       netdev_err(dev, "Advertising parameters are not supported! (adv: 0x%x)\n",
-                                  cmd->advertising);
-                       rc = -EINVAL;
-                       goto set_setting_exit;
-               }
                link_info->autoneg |= BNXT_AUTONEG_SPEED;
                if (!fw_advertising)
-                       link_info->advertising = link_info->support_speeds;
+                       link_info->advertising = link_info->support_auto_speeds;
                else
                        link_info->advertising = fw_advertising;
                /* any change to autoneg will cause link change, therefore the