bnxt_en: Add reporting of link partner advertisement.
authorMichael Chan <michael.chan@broadcom.com>
Mon, 7 Mar 2016 20:38:42 +0000 (15:38 -0500)
committerDavid S. Miller <davem@davemloft.net>
Tue, 8 Mar 2016 19:51:42 +0000 (14:51 -0500)
And report actual pause settings to ETHTOOL_GPAUSEPARAM to let ethtool
resolve the actual pause settings.

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

index 4dfc25f..b740489 100644 (file)
@@ -4468,6 +4468,7 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
        link_info->pause = resp->pause;
        link_info->auto_mode = resp->auto_mode;
        link_info->auto_pause_setting = resp->auto_pause;
+       link_info->lp_pause = resp->link_partner_adv_pause;
        link_info->force_pause_setting = resp->force_pause;
        link_info->duplex_setting = resp->duplex;
        if (link_info->phy_link_status == BNXT_LINK_LINK)
@@ -4478,6 +4479,8 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
        link_info->auto_link_speed = le16_to_cpu(resp->auto_link_speed);
        link_info->support_speeds = le16_to_cpu(resp->support_speeds);
        link_info->auto_link_speeds = le16_to_cpu(resp->auto_link_speed_mask);
+       link_info->lp_auto_link_speeds =
+               le16_to_cpu(resp->link_partner_adv_speeds);
        link_info->preemphasis = le32_to_cpu(resp->preemphasis);
        link_info->phy_ver[0] = resp->phy_maj;
        link_info->phy_ver[1] = resp->phy_min;
index 9aa38f5..2f24e4e 100644 (file)
@@ -780,6 +780,7 @@ struct bnxt_link_info {
 #define BNXT_LINK_PAUSE_RX     PORT_PHY_QCFG_RESP_PAUSE_RX
 #define BNXT_LINK_PAUSE_BOTH   (PORT_PHY_QCFG_RESP_PAUSE_RX | \
                                 PORT_PHY_QCFG_RESP_PAUSE_TX)
+       u8                      lp_pause;
        u8                      auto_pause_setting;
        u8                      force_pause_setting;
        u8                      duplex_setting;
@@ -814,6 +815,7 @@ struct bnxt_link_info {
 #define BNXT_LINK_SPEED_MSK_25GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_25GB
 #define BNXT_LINK_SPEED_MSK_40GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_40GB
 #define BNXT_LINK_SPEED_MSK_50GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_50GB
+       u16                     lp_auto_link_speeds;
        u16                     auto_link_speed;
        u16                     force_link_speed;
        u32                     preemphasis;
index a6ee26a..591c290 100644 (file)
@@ -553,6 +553,17 @@ static u32 bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info)
        return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause);
 }
 
+static u32 bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info)
+{
+       u16 fw_speeds = link_info->lp_auto_link_speeds;
+       u8 fw_pause = 0;
+
+       if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL)
+               fw_pause = link_info->lp_pause;
+
+       return _bnxt_fw_to_ethtool_adv_spds(fw_speeds, fw_pause);
+}
+
 u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed)
 {
        switch (fw_link_speed) {
@@ -594,6 +605,9 @@ static int bnxt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                        bnxt_fw_to_ethtool_advertised_spds(link_info);
                cmd->advertising |= ADVERTISED_Autoneg;
                cmd->autoneg = AUTONEG_ENABLE;
+               if (link_info->phy_link_status == BNXT_LINK_LINK)
+                       cmd->lp_advertising =
+                               bnxt_fw_to_ethtool_lp_adv(link_info);
        } else {
                cmd->autoneg = AUTONEG_DISABLE;
                cmd->advertising = 0;
@@ -757,8 +771,10 @@ static void bnxt_get_pauseparam(struct net_device *dev,
        if (BNXT_VF(bp))
                return;
        epause->autoneg = !!(link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL);
-       epause->rx_pause = ((link_info->pause & BNXT_LINK_PAUSE_RX) != 0);
-       epause->tx_pause = ((link_info->pause & BNXT_LINK_PAUSE_TX) != 0);
+       epause->rx_pause =
+               ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_RX) != 0);
+       epause->tx_pause =
+               ((link_info->auto_pause_setting & BNXT_LINK_PAUSE_TX) != 0);
 }
 
 static int bnxt_set_pauseparam(struct net_device *dev,