diff options
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 93 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.h | 46 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 10 |
3 files changed, 143 insertions, 6 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 3b0ced2a5f32..5f6c4644271c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2250,6 +2250,10 @@ static u16 bnxt_agg_ring_id_to_grp_idx(struct bnxt *bp, u16 ring_id) static u16 bnxt_get_force_speed(struct bnxt_link_info *link_info) { + struct bnxt *bp = container_of(link_info, struct bnxt, link_info); + + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) + return link_info->force_link_speed2; if (link_info->req_signal_mode == BNXT_SIG_MODE_PAM4) return link_info->force_pam4_link_speed; return link_info->force_link_speed; @@ -2257,6 +2261,28 @@ static u16 bnxt_get_force_speed(struct bnxt_link_info *link_info) static void bnxt_set_force_speed(struct bnxt_link_info *link_info) { + struct bnxt *bp = container_of(link_info, struct bnxt, link_info); + + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) { + link_info->req_link_speed = link_info->force_link_speed2; + link_info->req_signal_mode = BNXT_SIG_MODE_NRZ; + switch (link_info->req_link_speed) { + case BNXT_LINK_SPEED_50GB_PAM4: + case BNXT_LINK_SPEED_100GB_PAM4: + case BNXT_LINK_SPEED_200GB_PAM4: + case BNXT_LINK_SPEED_400GB_PAM4: + link_info->req_signal_mode = BNXT_SIG_MODE_PAM4; + break; + case BNXT_LINK_SPEED_100GB_PAM4_112: + case BNXT_LINK_SPEED_200GB_PAM4_112: + case BNXT_LINK_SPEED_400GB_PAM4_112: + link_info->req_signal_mode = BNXT_SIG_MODE_PAM4_112; + break; + default: + link_info->req_signal_mode = BNXT_SIG_MODE_NRZ; + } + return; + } link_info->req_link_speed = link_info->force_link_speed; link_info->req_signal_mode = BNXT_SIG_MODE_NRZ; if (link_info->force_pam4_link_speed) { @@ -2267,12 +2293,25 @@ static void bnxt_set_force_speed(struct bnxt_link_info *link_info) static void bnxt_set_auto_speed(struct bnxt_link_info *link_info) { + struct bnxt *bp = container_of(link_info, struct bnxt, link_info); + + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) { + link_info->advertising = link_info->auto_link_speeds2; + return; + } link_info->advertising = link_info->auto_link_speeds; link_info->advertising_pam4 = link_info->auto_pam4_link_speeds; } static bool bnxt_force_speed_updated(struct bnxt_link_info *link_info) { + struct bnxt *bp = container_of(link_info, struct bnxt, link_info); + + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) { + if (link_info->req_link_speed != link_info->force_link_speed2) + return true; + return false; + } if (link_info->req_signal_mode == BNXT_SIG_MODE_NRZ && link_info->req_link_speed != link_info->force_link_speed) return true; @@ -2284,6 +2323,13 @@ static bool bnxt_force_speed_updated(struct bnxt_link_info *link_info) static bool bnxt_auto_speed_updated(struct bnxt_link_info *link_info) { + struct bnxt *bp = container_of(link_info, struct bnxt, link_info); + + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) { + if (link_info->advertising != link_info->auto_link_speeds2) + return true; + return false; + } if (link_info->advertising != link_info->auto_link_speeds || link_info->advertising_pam4 != link_info->auto_pam4_link_speeds) return true; @@ -10082,7 +10128,10 @@ void bnxt_report_link(struct bnxt *bp) signal = "(NRZ) "; break; case PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4: - signal = "(PAM4) "; + signal = "(PAM4 56Gbps) "; + break; + case PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4_112: + signal = "(PAM4 112Gbps) "; break; default: break; @@ -10110,7 +10159,9 @@ static bool bnxt_phy_qcaps_no_speed(struct hwrm_port_phy_qcaps_output *resp) if (!resp->supported_speeds_auto_mode && !resp->supported_speeds_force_mode && !resp->supported_pam4_speeds_auto_mode && - !resp->supported_pam4_speeds_force_mode) + !resp->supported_pam4_speeds_force_mode && + !resp->supported_speeds2_auto_mode && + !resp->supported_speeds2_force_mode) return true; return false; } @@ -10156,6 +10207,7 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) /* Phy re-enabled, reprobe the speeds */ link_info->support_auto_speeds = 0; link_info->support_pam4_auto_speeds = 0; + link_info->support_auto_speeds2 = 0; } } if (resp->supported_speeds_auto_mode) @@ -10164,6 +10216,9 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) if (resp->supported_pam4_speeds_auto_mode) link_info->support_pam4_auto_speeds = le16_to_cpu(resp->supported_pam4_speeds_auto_mode); + if (resp->supported_speeds2_auto_mode) + link_info->support_auto_speeds2 = + le16_to_cpu(resp->supported_speeds2_auto_mode); bp->port_count = resp->port_cnt; @@ -10181,9 +10236,19 @@ static bool bnxt_support_dropped(u16 advertising, u16 supported) static bool bnxt_support_speed_dropped(struct bnxt_link_info *link_info) { + struct bnxt *bp = container_of(link_info, struct bnxt, link_info); + /* Check if any advertised speeds are no longer supported. The caller * holds the link_lock mutex, so we can modify link_info settings. */ + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) { + if (bnxt_support_dropped(link_info->advertising, + link_info->support_auto_speeds2)) { + link_info->advertising = link_info->support_auto_speeds2; + return true; + } + return false; + } if (bnxt_support_dropped(link_info->advertising, link_info->support_auto_speeds)) { link_info->advertising = link_info->support_auto_speeds; @@ -10232,18 +10297,25 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state) link_info->lp_pause = resp->link_partner_adv_pause; link_info->force_pause_setting = resp->force_pause; link_info->duplex_setting = resp->duplex_cfg; - if (link_info->phy_link_status == BNXT_LINK_LINK) + if (link_info->phy_link_status == BNXT_LINK_LINK) { link_info->link_speed = le16_to_cpu(resp->link_speed); - else + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) + link_info->active_lanes = resp->active_lanes; + } else { link_info->link_speed = 0; + link_info->active_lanes = 0; + } link_info->force_link_speed = le16_to_cpu(resp->force_link_speed); link_info->force_pam4_link_speed = le16_to_cpu(resp->force_pam4_link_speed); + link_info->force_link_speed2 = le16_to_cpu(resp->force_link_speeds2); link_info->support_speeds = le16_to_cpu(resp->support_speeds); link_info->support_pam4_speeds = le16_to_cpu(resp->support_pam4_speeds); + link_info->support_speeds2 = le16_to_cpu(resp->support_speeds2); link_info->auto_link_speeds = le16_to_cpu(resp->auto_link_speed_mask); link_info->auto_pam4_link_speeds = le16_to_cpu(resp->auto_pam4_link_speed_mask); + link_info->auto_link_speeds2 = le16_to_cpu(resp->auto_link_speeds2); link_info->lp_auto_link_speeds = le16_to_cpu(resp->link_partner_adv_speeds); link_info->lp_auto_pam4_link_speeds = @@ -10382,7 +10454,11 @@ static void bnxt_hwrm_set_link_common(struct bnxt *bp, struct hwrm_port_phy_cfg_ { if (bp->link_info.autoneg & BNXT_AUTONEG_SPEED) { req->auto_mode |= PORT_PHY_CFG_REQ_AUTO_MODE_SPEED_MASK; - if (bp->link_info.advertising) { + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) { + req->enables |= + cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_LINK_SPEEDS2_MASK); + req->auto_link_speeds2_mask = cpu_to_le16(bp->link_info.advertising); + } else if (bp->link_info.advertising) { req->enables |= cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_LINK_SPEED_MASK); req->auto_link_speed_mask = cpu_to_le16(bp->link_info.advertising); } @@ -10396,7 +10472,12 @@ static void bnxt_hwrm_set_link_common(struct bnxt *bp, struct hwrm_port_phy_cfg_ req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_RESTART_AUTONEG); } else { req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE); - if (bp->link_info.req_signal_mode == BNXT_SIG_MODE_PAM4) { + if (bp->phy_flags & BNXT_PHY_FL_SPEEDS2) { + req->force_link_speeds2 = cpu_to_le16(bp->link_info.req_link_speed); + req->enables |= cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_FORCE_LINK_SPEEDS2); + netif_info(bp, link, bp->dev, "Forcing FW speed2: %d\n", + (u32)bp->link_info.req_link_speed); + } else if (bp->link_info.req_signal_mode == BNXT_SIG_MODE_PAM4) { req->force_pam4_link_speed = cpu_to_le16(bp->link_info.req_link_speed); req->enables |= cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_FORCE_PAM4_LINK_SPEED); } else { diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 57694eb7feeb..d8c2b0790117 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1360,6 +1360,7 @@ struct bnxt_link_info { #define BNXT_LINK_STATE_DOWN 1 #define BNXT_LINK_STATE_UP 2 #define BNXT_LINK_IS_UP(bp) ((bp)->link_info.link_state == BNXT_LINK_STATE_UP) + u8 active_lanes; u8 duplex; #define BNXT_LINK_DUPLEX_HALF PORT_PHY_QCFG_RESP_DUPLEX_STATE_HALF #define BNXT_LINK_DUPLEX_FULL PORT_PHY_QCFG_RESP_DUPLEX_STATE_FULL @@ -1394,8 +1395,11 @@ struct bnxt_link_info { #define BNXT_LINK_SPEED_50GB PORT_PHY_QCFG_RESP_LINK_SPEED_50GB #define BNXT_LINK_SPEED_100GB PORT_PHY_QCFG_RESP_LINK_SPEED_100GB #define BNXT_LINK_SPEED_200GB PORT_PHY_QCFG_RESP_LINK_SPEED_200GB +#define BNXT_LINK_SPEED_400GB PORT_PHY_QCFG_RESP_LINK_SPEED_400GB u16 support_speeds; u16 support_pam4_speeds; + u16 support_speeds2; + u16 auto_link_speeds; /* fw adv setting */ #define BNXT_LINK_SPEED_MSK_100MB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_100MB #define BNXT_LINK_SPEED_MSK_1GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_1GB @@ -1411,12 +1415,52 @@ struct bnxt_link_info { #define BNXT_LINK_PAM4_SPEED_MSK_50GB PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_50G #define BNXT_LINK_PAM4_SPEED_MSK_100GB PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_100G #define BNXT_LINK_PAM4_SPEED_MSK_200GB PORT_PHY_QCFG_RESP_SUPPORT_PAM4_SPEEDS_200G + u16 auto_link_speeds2; +#define BNXT_LINK_SPEEDS2_MSK_1GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_1GB +#define BNXT_LINK_SPEEDS2_MSK_10GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_10GB +#define BNXT_LINK_SPEEDS2_MSK_25GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_25GB +#define BNXT_LINK_SPEEDS2_MSK_40GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_40GB +#define BNXT_LINK_SPEEDS2_MSK_50GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_50GB +#define BNXT_LINK_SPEEDS2_MSK_100GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_100GB +#define BNXT_LINK_SPEEDS2_MSK_50GB_PAM4 \ + PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_50GB_PAM4_56 +#define BNXT_LINK_SPEEDS2_MSK_100GB_PAM4 \ + PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_100GB_PAM4_56 +#define BNXT_LINK_SPEEDS2_MSK_200GB_PAM4 \ + PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_200GB_PAM4_56 +#define BNXT_LINK_SPEEDS2_MSK_400GB_PAM4 \ + PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_400GB_PAM4_56 +#define BNXT_LINK_SPEEDS2_MSK_100GB_PAM4_112 \ + PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_100GB_PAM4_112 +#define BNXT_LINK_SPEEDS2_MSK_200GB_PAM4_112 \ + PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_200GB_PAM4_112 +#define BNXT_LINK_SPEEDS2_MSK_400GB_PAM4_112 \ + PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS2_400GB_PAM4_112 + u16 support_auto_speeds; u16 support_pam4_auto_speeds; + u16 support_auto_speeds2; + u16 lp_auto_link_speeds; u16 lp_auto_pam4_link_speeds; u16 force_link_speed; u16 force_pam4_link_speed; + u16 force_link_speed2; +#define BNXT_LINK_SPEED_50GB_PAM4 \ + PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_50GB_PAM4_56 +#define BNXT_LINK_SPEED_100GB_PAM4 \ + PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_100GB_PAM4_56 +#define BNXT_LINK_SPEED_200GB_PAM4 \ + PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_200GB_PAM4_56 +#define BNXT_LINK_SPEED_400GB_PAM4 \ + PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_400GB_PAM4_56 +#define BNXT_LINK_SPEED_100GB_PAM4_112 \ + PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_100GB_PAM4_112 +#define BNXT_LINK_SPEED_200GB_PAM4_112 \ + PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_200GB_PAM4_112 +#define BNXT_LINK_SPEED_400GB_PAM4_112 \ + PORT_PHY_CFG_REQ_FORCE_LINK_SPEEDS2_400GB_PAM4_112 + u32 preemphasis; u8 module_status; u8 active_fec_sig_mode; @@ -1447,6 +1491,7 @@ struct bnxt_link_info { u8 req_signal_mode; #define BNXT_SIG_MODE_NRZ PORT_PHY_QCFG_RESP_SIGNAL_MODE_NRZ #define BNXT_SIG_MODE_PAM4 PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4 +#define BNXT_SIG_MODE_PAM4_112 PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4_112 #define BNXT_SIG_MODE_MAX (PORT_PHY_QCFG_RESP_SIGNAL_MODE_LAST + 1) u8 req_duplex; u8 req_flow_ctrl; @@ -2337,6 +2382,7 @@ struct bnxt { #define BNXT_PHY_FL_NO_PAUSE (PORT_PHY_QCAPS_RESP_FLAGS2_PAUSE_UNSUPPORTED << 8) #define BNXT_PHY_FL_NO_PFC (PORT_PHY_QCAPS_RESP_FLAGS2_PFC_UNSUPPORTED << 8) #define BNXT_PHY_FL_BANK_SEL (PORT_PHY_QCAPS_RESP_FLAGS2_BANK_ADDR_SUPPORTED << 8) +#define BNXT_PHY_FL_SPEEDS2 (PORT_PHY_QCAPS_RESP_FLAGS2_SPEEDS2_SUPPORTED << 8) u8 num_tests; struct bnxt_test_info *test_info; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index a9b6141337d4..7bc0bddbb126 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -2020,11 +2020,20 @@ u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed) case BNXT_LINK_SPEED_40GB: return SPEED_40000; case BNXT_LINK_SPEED_50GB: + case BNXT_LINK_SPEED_50GB_PAM4: return SPEED_50000; case BNXT_LINK_SPEED_100GB: + case BNXT_LINK_SPEED_100GB_PAM4: + case BNXT_LINK_SPEED_100GB_PAM4_112: return SPEED_100000; case BNXT_LINK_SPEED_200GB: + case BNXT_LINK_SPEED_200GB_PAM4: + case BNXT_LINK_SPEED_200GB_PAM4_112: return SPEED_200000; + case BNXT_LINK_SPEED_400GB: + case BNXT_LINK_SPEED_400GB_PAM4: + case BNXT_LINK_SPEED_400GB_PAM4_112: + return SPEED_400000; default: return SPEED_UNKNOWN; } @@ -2040,6 +2049,7 @@ static void bnxt_get_default_speeds(struct ethtool_link_ksettings *lk_ksettings, base->duplex = DUPLEX_HALF; if (link_info->duplex & BNXT_LINK_DUPLEX_FULL) base->duplex = DUPLEX_FULL; + lk_ksettings->lanes = link_info->active_lanes; } else if (!link_info->autoneg) { base->speed = bnxt_fw_to_ethtool_speed(link_info->req_link_speed); base->duplex = DUPLEX_HALF; |
