From 9d6b648c3112012dac6d804d331cdd3a2247765c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 27 Sep 2020 13:42:10 -0400 Subject: [PATCH 01/11] bnxt_en: Update firmware interface spec to 1.10.1.65. The main changes include FEC, ECN statistics, HWRM_PORT_PHY_QCFG response size reduction, and a new counter added to ctx_hw_stats_ext struct to support the new 58818 chip. The ctx_hw_stats_ext structure is now the superset supporting the new 58818 chips and the prior P5 chips. Add a new flag to identify the new chip and use constants for the chip specific ring statistics sizes instead of the size of the structure. Because the HWRM_PORT_PHY_QCFG response structure size has shrunk back to 96 bytes, the workaround added earlier to limit the size of this message for forwarding to the VF can be removed. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 16 +- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 71 ++-- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 10 +- drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h | 375 +++++++++++++++--- .../net/ethernet/broadcom/bnxt/bnxt_sriov.c | 2 +- 5 files changed, 361 insertions(+), 113 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 65c298f1f333..b57f28d2e716 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -5343,13 +5343,16 @@ static int bnxt_hwrm_vnic_qcaps(struct bnxt *bp) * VLAN_STRIP_CAP properly. */ if ((flags & VNIC_QCAPS_RESP_FLAGS_VLAN_STRIP_CAP) || - ((bp->flags & BNXT_FLAG_CHIP_P5) && + (BNXT_CHIP_P5_THOR(bp) && !(bp->fw_cap & BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED))) bp->fw_cap |= BNXT_FW_CAP_VLAN_RX_STRIP; bp->max_tpa_v2 = le16_to_cpu(resp->max_aggs_supported); - if (bp->max_tpa_v2) - bp->hw_ring_stats_size = - sizeof(struct ctx_hw_stats_ext); + if (bp->max_tpa_v2) { + if (BNXT_CHIP_P5_THOR(bp)) + bp->hw_ring_stats_size = BNXT_RING_STATS_SIZE_P5; + else + bp->hw_ring_stats_size = BNXT_RING_STATS_SIZE_P5_SR2; + } } mutex_unlock(&bp->hwrm_cmd_lock); return rc; @@ -12233,8 +12236,11 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) if (rc) goto init_err_pci_clean; - if (BNXT_CHIP_P5(bp)) + if (BNXT_CHIP_P5(bp)) { bp->flags |= BNXT_FLAG_CHIP_P5; + if (BNXT_CHIP_SR2(bp)) + bp->flags |= BNXT_FLAG_CHIP_SR2; + } rc = bnxt_alloc_rss_indir_tbl(bp); if (rc) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 0ef89dabfd61..21f2b82287a9 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1142,50 +1142,6 @@ struct bnxt_ntuple_filter { #define BNXT_FLTR_UPDATE 1 }; -struct hwrm_port_phy_qcfg_output_compat { - __le16 error_code; - __le16 req_type; - __le16 seq_id; - __le16 resp_len; - u8 link; - u8 link_signal_mode; - __le16 link_speed; - u8 duplex_cfg; - u8 pause; - __le16 support_speeds; - __le16 force_link_speed; - u8 auto_mode; - u8 auto_pause; - __le16 auto_link_speed; - __le16 auto_link_speed_mask; - u8 wirespeed; - u8 lpbk; - u8 force_pause; - u8 module_status; - __le32 preemphasis; - u8 phy_maj; - u8 phy_min; - u8 phy_bld; - u8 phy_type; - u8 media_type; - u8 xcvr_pkg_type; - u8 eee_config_phy_addr; - u8 parallel_detect; - __le16 link_partner_adv_speeds; - u8 link_partner_adv_auto_mode; - u8 link_partner_adv_pause; - __le16 adv_eee_link_speed_mask; - __le16 link_partner_adv_eee_link_speed_mask; - __le32 xcvr_identifier_type_tx_lpi_timer; - __le16 fec_cfg; - u8 duplex_state; - u8 option_flags; - char phy_vendor_name[16]; - char phy_vendor_partnumber[16]; - u8 unused_0[7]; - u8 valid; -}; - struct bnxt_link_info { u8 phy_type; u8 media_type; @@ -1535,6 +1491,8 @@ struct bnxt { u8 chip_rev; +#define CHIP_NUM_58818 0xd818 + #define BNXT_CHIP_NUM_5730X(chip_num) \ ((chip_num) >= CHIP_NUM_57301 && \ (chip_num) <= CHIP_NUM_57304) @@ -1613,6 +1571,7 @@ struct bnxt { BNXT_FLAG_ROCEV2_CAP) #define BNXT_FLAG_NO_AGG_RINGS 0x20000 #define BNXT_FLAG_RX_PAGE_MODE 0x40000 + #define BNXT_FLAG_CHIP_SR2 0x80000 #define BNXT_FLAG_MULTI_HOST 0x100000 #define BNXT_FLAG_DSN_VALID 0x200000 #define BNXT_FLAG_DOUBLE_DB 0x400000 @@ -1638,12 +1597,18 @@ struct bnxt { (!((bp)->flags & BNXT_FLAG_CHIP_P5) || \ (bp)->max_tpa_v2) && !is_kdump_kernel()) -/* Chip class phase 5 */ -#define BNXT_CHIP_P5(bp) \ +#define BNXT_CHIP_SR2(bp) \ + ((bp)->chip_num == CHIP_NUM_58818) + +#define BNXT_CHIP_P5_THOR(bp) \ ((bp)->chip_num == CHIP_NUM_57508 || \ (bp)->chip_num == CHIP_NUM_57504 || \ (bp)->chip_num == CHIP_NUM_57502) +/* Chip class phase 5 */ +#define BNXT_CHIP_P5(bp) \ + (BNXT_CHIP_P5_THOR(bp) || BNXT_CHIP_SR2(bp)) + /* Chip class phase 4.x */ #define BNXT_CHIP_P4(bp) \ (BNXT_CHIP_NUM_57X1X((bp)->chip_num) || \ @@ -1935,6 +1900,20 @@ struct bnxt { struct device *hwmon_dev; }; +#define BNXT_NUM_RX_RING_STATS 8 +#define BNXT_NUM_TX_RING_STATS 8 +#define BNXT_NUM_TPA_RING_STATS 4 +#define BNXT_NUM_TPA_RING_STATS_P5 5 +#define BNXT_NUM_TPA_RING_STATS_P5_SR2 6 + +#define BNXT_RING_STATS_SIZE_P5 \ + ((BNXT_NUM_RX_RING_STATS + BNXT_NUM_TX_RING_STATS + \ + BNXT_NUM_TPA_RING_STATS_P5) * 8) + +#define BNXT_RING_STATS_SIZE_P5_SR2 \ + ((BNXT_NUM_RX_RING_STATS + BNXT_NUM_TX_RING_STATS + \ + BNXT_NUM_TPA_RING_STATS_P5_SR2) * 8) + #define BNXT_GET_RING_STATS64(sw, counter) \ (*((sw) + offsetof(struct ctx_hw_stats, counter) / 8)) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 6a3453f46d9a..9703ff48f2ab 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -172,6 +172,7 @@ static const char * const bnxt_ring_tpa2_stats_str[] = { "rx_tpa_pkt", "rx_tpa_bytes", "rx_tpa_errors", + "rx_tpa_events", }; static const char * const bnxt_rx_sw_stats_str[] = { @@ -462,9 +463,12 @@ static const struct { static int bnxt_get_num_tpa_ring_stats(struct bnxt *bp) { if (BNXT_SUPPORTS_TPA(bp)) { - if (bp->max_tpa_v2) - return ARRAY_SIZE(bnxt_ring_tpa2_stats_str); - return ARRAY_SIZE(bnxt_ring_tpa_stats_str); + if (bp->max_tpa_v2) { + if (BNXT_CHIP_P5_THOR(bp)) + return BNXT_NUM_TPA_RING_STATS_P5; + return BNXT_NUM_TPA_RING_STATS_P5_SR2; + } + return BNXT_NUM_TPA_RING_STATS; } return 0; } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h index c4af6bf15e36..303713aa03b0 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hsi.h @@ -213,7 +213,10 @@ struct cmd_nums { #define HWRM_PORT_PHY_MDIO_BUS_ACQUIRE 0xb7UL #define HWRM_PORT_PHY_MDIO_BUS_RELEASE 0xb8UL #define HWRM_PORT_QSTATS_EXT_PFC_WD 0xb9UL - #define HWRM_PORT_ECN_QSTATS 0xbaUL + #define HWRM_RESERVED7 0xbaUL + #define HWRM_PORT_TX_FIR_CFG 0xbbUL + #define HWRM_PORT_TX_FIR_QCFG 0xbcUL + #define HWRM_PORT_ECN_QSTATS 0xbdUL #define HWRM_FW_RESET 0xc0UL #define HWRM_FW_QSTATUS 0xc1UL #define HWRM_FW_HEALTH_CHECK 0xc2UL @@ -370,6 +373,8 @@ struct cmd_nums { #define HWRM_TF_SESSION_RESC_FLUSH 0x2cfUL #define HWRM_TF_TBL_TYPE_GET 0x2daUL #define HWRM_TF_TBL_TYPE_SET 0x2dbUL + #define HWRM_TF_CTXT_MEM_ALLOC 0x2e2UL + #define HWRM_TF_CTXT_MEM_FREE 0x2e3UL #define HWRM_TF_CTXT_MEM_RGTR 0x2e4UL #define HWRM_TF_CTXT_MEM_UNRGTR 0x2e5UL #define HWRM_TF_EXT_EM_QCAPS 0x2e6UL @@ -384,6 +389,8 @@ struct cmd_nums { #define HWRM_TF_TCAM_FREE 0x2fbUL #define HWRM_TF_GLOBAL_CFG_SET 0x2fcUL #define HWRM_TF_GLOBAL_CFG_GET 0x2fdUL + #define HWRM_TF_IF_TBL_SET 0x2feUL + #define HWRM_TF_IF_TBL_GET 0x2ffUL #define HWRM_SV 0x400UL #define HWRM_DBG_READ_DIRECT 0xff10UL #define HWRM_DBG_READ_INDIRECT 0xff11UL @@ -447,6 +454,7 @@ struct ret_codes { #define HWRM_ERR_CODE_KEY_ALREADY_EXISTS 0xeUL #define HWRM_ERR_CODE_HWRM_ERROR 0xfUL #define HWRM_ERR_CODE_BUSY 0x10UL + #define HWRM_ERR_CODE_RESOURCE_LOCKED 0x11UL #define HWRM_ERR_CODE_TLV_ENCAPSULATED_RESPONSE 0x8000UL #define HWRM_ERR_CODE_UNKNOWN_ERR 0xfffeUL #define HWRM_ERR_CODE_CMD_NOT_SUPPORTED 0xffffUL @@ -478,8 +486,8 @@ struct hwrm_err_output { #define HWRM_VERSION_MAJOR 1 #define HWRM_VERSION_MINOR 10 #define HWRM_VERSION_UPDATE 1 -#define HWRM_VERSION_RSVD 54 -#define HWRM_VERSION_STR "1.10.1.54" +#define HWRM_VERSION_RSVD 65 +#define HWRM_VERSION_STR "1.10.1.65" /* hwrm_ver_get_input (size:192b/24B) */ struct hwrm_ver_get_input { @@ -675,6 +683,7 @@ struct hwrm_async_event_cmpl { #define ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE 0x7UL #define ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY 0x8UL #define ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY 0x9UL + #define ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG 0xaUL #define ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD 0x10UL #define ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD 0x11UL #define ASYNC_EVENT_CMPL_EVENT_ID_FUNC_FLR_PROC_CMPLT 0x12UL @@ -851,6 +860,32 @@ struct hwrm_async_event_cmpl_error_recovery { #define ASYNC_EVENT_CMPL_ERROR_RECOVERY_EVENT_DATA1_FLAGS_RECOVERY_ENABLED 0x2UL }; +/* hwrm_async_event_cmpl_ring_monitor_msg (size:128b/16B) */ +struct hwrm_async_event_cmpl_ring_monitor_msg { + __le16 type; + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_TYPE_MASK 0x3fUL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_TYPE_SFT 0 + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_TYPE_HWRM_ASYNC_EVENT 0x2eUL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_TYPE_LAST ASYNC_EVENT_CMPL_RING_MONITOR_MSG_TYPE_HWRM_ASYNC_EVENT + __le16 event_id; + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_ID_RING_MONITOR_MSG 0xaUL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_ID_LAST ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_ID_RING_MONITOR_MSG + __le32 event_data2; + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_MASK 0xffUL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_SFT 0 + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_TX 0x0UL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_RX 0x1UL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_CMPL 0x2UL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_LAST ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_CMPL + u8 opaque_v; + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_V 0x1UL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_OPAQUE_MASK 0xfeUL + #define ASYNC_EVENT_CMPL_RING_MONITOR_MSG_OPAQUE_SFT 1 + u8 timestamp_lo; + __le16 timestamp_hi; + __le32 event_data1; +}; + /* hwrm_async_event_cmpl_vf_cfg_change (size:128b/16B) */ struct hwrm_async_event_cmpl_vf_cfg_change { __le16 type; @@ -975,6 +1010,28 @@ struct hwrm_async_event_cmpl_eem_cache_flush_done { #define ASYNC_EVENT_CMPL_EEM_CACHE_FLUSH_DONE_EVENT_DATA1_FID_SFT 0 }; +/* hwrm_async_event_cmpl_deferred_response (size:128b/16B) */ +struct hwrm_async_event_cmpl_deferred_response { + __le16 type; + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_TYPE_MASK 0x3fUL + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_TYPE_SFT 0 + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_TYPE_HWRM_ASYNC_EVENT 0x2eUL + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_TYPE_LAST ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_TYPE_HWRM_ASYNC_EVENT + __le16 event_id; + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_EVENT_ID_DEFERRED_RESPONSE 0x40UL + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_EVENT_ID_LAST ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_EVENT_ID_DEFERRED_RESPONSE + __le32 event_data2; + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_EVENT_DATA2_SEQ_ID_MASK 0xffffUL + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_EVENT_DATA2_SEQ_ID_SFT 0 + u8 opaque_v; + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_V 0x1UL + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_OPAQUE_MASK 0xfeUL + #define ASYNC_EVENT_CMPL_DEFERRED_RESPONSE_OPAQUE_SFT 1 + u8 timestamp_lo; + __le16 timestamp_hi; + __le32 event_data1; +}; + /* hwrm_func_reset_input (size:192b/24B) */ struct hwrm_func_reset_input { __le16 req_type; @@ -1214,7 +1271,13 @@ struct hwrm_func_qcaps_output { #define FUNC_QCAPS_RESP_FLAGS_EXT_SCHQ_SUPPORTED 0x40UL #define FUNC_QCAPS_RESP_FLAGS_EXT_PPP_PUSH_MODE_SUPPORTED 0x80UL u8 max_schqs; - u8 unused_1[2]; + u8 mpc_chnls_cap; + #define FUNC_QCAPS_RESP_MPC_CHNLS_CAP_TCE 0x1UL + #define FUNC_QCAPS_RESP_MPC_CHNLS_CAP_RCE 0x2UL + #define FUNC_QCAPS_RESP_MPC_CHNLS_CAP_TE_CFA 0x4UL + #define FUNC_QCAPS_RESP_MPC_CHNLS_CAP_RE_CFA 0x8UL + #define FUNC_QCAPS_RESP_MPC_CHNLS_CAP_PRIMATE 0x10UL + u8 unused_1; u8 valid; }; @@ -1250,6 +1313,7 @@ struct hwrm_func_qcfg_output { #define FUNC_QCFG_RESP_FLAGS_PREBOOT_LEGACY_L2_RINGS 0x100UL #define FUNC_QCFG_RESP_FLAGS_HOT_RESET_ALLOWED 0x200UL #define FUNC_QCFG_RESP_FLAGS_PPP_PUSH_MODE_ENABLED 0x400UL + #define FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED 0x800UL u8 mac_address[6]; __le16 pci_id; __le16 alloc_rsscos_ctx; @@ -1341,7 +1405,13 @@ struct hwrm_func_qcfg_output { #define FUNC_QCFG_RESP_SVIF_INFO_SVIF_MASK 0x7fffUL #define FUNC_QCFG_RESP_SVIF_INFO_SVIF_SFT 0 #define FUNC_QCFG_RESP_SVIF_INFO_SVIF_VALID 0x8000UL - u8 unused_2[7]; + u8 mpc_chnls; + #define FUNC_QCFG_RESP_MPC_CHNLS_TCE_ENABLED 0x1UL + #define FUNC_QCFG_RESP_MPC_CHNLS_RCE_ENABLED 0x2UL + #define FUNC_QCFG_RESP_MPC_CHNLS_TE_CFA_ENABLED 0x4UL + #define FUNC_QCFG_RESP_MPC_CHNLS_RE_CFA_ENABLED 0x8UL + #define FUNC_QCFG_RESP_MPC_CHNLS_PRIMATE_ENABLED 0x10UL + u8 unused_2[6]; u8 valid; }; @@ -1405,6 +1475,7 @@ struct hwrm_func_cfg_input { #define FUNC_CFG_REQ_ENABLES_ADMIN_LINK_STATE 0x400000UL #define FUNC_CFG_REQ_ENABLES_HOT_RESET_IF_SUPPORT 0x800000UL #define FUNC_CFG_REQ_ENABLES_SCHQ_ID 0x1000000UL + #define FUNC_CFG_REQ_ENABLES_MPC_CHNLS 0x2000000UL __le16 mtu; __le16 mru; __le16 num_rsscos_ctxs; @@ -1479,7 +1550,18 @@ struct hwrm_func_cfg_input { #define FUNC_CFG_REQ_OPTIONS_RSVD_SFT 4 __le16 num_mcast_filters; __le16 schq_id; - u8 unused_0[6]; + __le16 mpc_chnls; + #define FUNC_CFG_REQ_MPC_CHNLS_TCE_ENABLE 0x1UL + #define FUNC_CFG_REQ_MPC_CHNLS_TCE_DISABLE 0x2UL + #define FUNC_CFG_REQ_MPC_CHNLS_RCE_ENABLE 0x4UL + #define FUNC_CFG_REQ_MPC_CHNLS_RCE_DISABLE 0x8UL + #define FUNC_CFG_REQ_MPC_CHNLS_TE_CFA_ENABLE 0x10UL + #define FUNC_CFG_REQ_MPC_CHNLS_TE_CFA_DISABLE 0x20UL + #define FUNC_CFG_REQ_MPC_CHNLS_RE_CFA_ENABLE 0x40UL + #define FUNC_CFG_REQ_MPC_CHNLS_RE_CFA_DISABLE 0x80UL + #define FUNC_CFG_REQ_MPC_CHNLS_PRIMATE_ENABLE 0x100UL + #define FUNC_CFG_REQ_MPC_CHNLS_PRIMATE_DISABLE 0x200UL + u8 unused_0[4]; }; /* hwrm_func_cfg_output (size:128b/16B) */ @@ -1559,7 +1641,7 @@ struct hwrm_func_qstats_ext_input { u8 unused_1[4]; }; -/* hwrm_func_qstats_ext_output (size:1472b/184B) */ +/* hwrm_func_qstats_ext_output (size:1536b/192B) */ struct hwrm_func_qstats_ext_output { __le16 error_code; __le16 req_type; @@ -1586,6 +1668,7 @@ struct hwrm_func_qstats_ext_output { __le64 rx_tpa_pkt; __le64 rx_tpa_bytes; __le64 rx_tpa_errors; + __le64 rx_tpa_events; u8 unused_0[7]; u8 valid; }; @@ -2412,25 +2495,29 @@ struct hwrm_port_phy_cfg_input { __le16 target_id; __le64 resp_addr; __le32 flags; - #define PORT_PHY_CFG_REQ_FLAGS_RESET_PHY 0x1UL - #define PORT_PHY_CFG_REQ_FLAGS_DEPRECATED 0x2UL - #define PORT_PHY_CFG_REQ_FLAGS_FORCE 0x4UL - #define PORT_PHY_CFG_REQ_FLAGS_RESTART_AUTONEG 0x8UL - #define PORT_PHY_CFG_REQ_FLAGS_EEE_ENABLE 0x10UL - #define PORT_PHY_CFG_REQ_FLAGS_EEE_DISABLE 0x20UL - #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_ENABLE 0x40UL - #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_DISABLE 0x80UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_ENABLE 0x100UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE 0x200UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_ENABLE 0x400UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE 0x800UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE 0x1000UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_DISABLE 0x2000UL - #define PORT_PHY_CFG_REQ_FLAGS_FORCE_LINK_DWN 0x4000UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_ENABLE 0x8000UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_DISABLE 0x10000UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_2XN_ENABLE 0x20000UL - #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_2XN_DISABLE 0x40000UL + #define PORT_PHY_CFG_REQ_FLAGS_RESET_PHY 0x1UL + #define PORT_PHY_CFG_REQ_FLAGS_DEPRECATED 0x2UL + #define PORT_PHY_CFG_REQ_FLAGS_FORCE 0x4UL + #define PORT_PHY_CFG_REQ_FLAGS_RESTART_AUTONEG 0x8UL + #define PORT_PHY_CFG_REQ_FLAGS_EEE_ENABLE 0x10UL + #define PORT_PHY_CFG_REQ_FLAGS_EEE_DISABLE 0x20UL + #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_ENABLE 0x40UL + #define PORT_PHY_CFG_REQ_FLAGS_EEE_TX_LPI_DISABLE 0x80UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_ENABLE 0x100UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE 0x200UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_ENABLE 0x400UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE 0x800UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE 0x1000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_DISABLE 0x2000UL + #define PORT_PHY_CFG_REQ_FLAGS_FORCE_LINK_DWN 0x4000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_ENABLE 0x8000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_DISABLE 0x10000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_IEEE_ENABLE 0x20000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_IEEE_DISABLE 0x40000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_1XN_ENABLE 0x80000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_1XN_DISABLE 0x100000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_IEEE_ENABLE 0x200000UL + #define PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_IEEE_DISABLE 0x400000UL __le32 enables; #define PORT_PHY_CFG_REQ_ENABLES_AUTO_MODE 0x1UL #define PORT_PHY_CFG_REQ_ENABLES_AUTO_DUPLEX 0x2UL @@ -2573,7 +2660,7 @@ struct hwrm_port_phy_qcfg_input { u8 unused_0[6]; }; -/* hwrm_port_phy_qcfg_output (size:832b/104B) */ +/* hwrm_port_phy_qcfg_output (size:768b/96B) */ struct hwrm_port_phy_qcfg_output { __le16 error_code; __le16 req_type; @@ -2584,10 +2671,22 @@ struct hwrm_port_phy_qcfg_output { #define PORT_PHY_QCFG_RESP_LINK_SIGNAL 0x1UL #define PORT_PHY_QCFG_RESP_LINK_LINK 0x2UL #define PORT_PHY_QCFG_RESP_LINK_LAST PORT_PHY_QCFG_RESP_LINK_LINK - u8 link_signal_mode; - #define PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_NRZ 0x0UL - #define PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_PAM4 0x1UL - #define PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_LAST PORT_PHY_QCFG_RESP_LINK_SIGNAL_MODE_PAM4 + u8 active_fec_signal_mode; + #define PORT_PHY_QCFG_RESP_SIGNAL_MODE_MASK 0xfUL + #define PORT_PHY_QCFG_RESP_SIGNAL_MODE_SFT 0 + #define PORT_PHY_QCFG_RESP_SIGNAL_MODE_NRZ 0x0UL + #define PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4 0x1UL + #define PORT_PHY_QCFG_RESP_SIGNAL_MODE_LAST PORT_PHY_QCFG_RESP_SIGNAL_MODE_PAM4 + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK 0xf0UL + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_SFT 4 + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE (0x0UL << 4) + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE (0x1UL << 4) + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE (0x2UL << 4) + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE (0x3UL << 4) + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE (0x4UL << 4) + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE (0x5UL << 4) + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE (0x6UL << 4) + #define PORT_PHY_QCFG_RESP_ACTIVE_FEC_LAST PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE __le16 link_speed; #define PORT_PHY_QCFG_RESP_LINK_SPEED_100MB 0x1UL #define PORT_PHY_QCFG_RESP_LINK_SPEED_1GB 0xaUL @@ -2809,21 +2908,21 @@ struct hwrm_port_phy_qcfg_output { #define PORT_PHY_QCFG_RESP_XCVR_IDENTIFIER_TYPE_QSFP28 (0x11UL << 24) #define PORT_PHY_QCFG_RESP_XCVR_IDENTIFIER_TYPE_LAST PORT_PHY_QCFG_RESP_XCVR_IDENTIFIER_TYPE_QSFP28 __le16 fec_cfg; - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED 0x1UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_SUPPORTED 0x2UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_ENABLED 0x4UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_SUPPORTED 0x8UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ENABLED 0x10UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_SUPPORTED 0x20UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED 0x40UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_SUPPORTED 0x80UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_ENABLED 0x100UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_2XN_SUPPORTED 0x200UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_2XN_ENABLED 0x400UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ACTIVE 0x800UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ACTIVE 0x1000UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_ACTIVE 0x2000UL - #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_2XN_ACTIVE 0x4000UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED 0x1UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_SUPPORTED 0x2UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_ENABLED 0x4UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_SUPPORTED 0x8UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ENABLED 0x10UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_SUPPORTED 0x20UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED 0x40UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_SUPPORTED 0x80UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_ENABLED 0x100UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_IEEE_SUPPORTED 0x200UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_IEEE_ENABLED 0x400UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_1XN_SUPPORTED 0x800UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_1XN_ENABLED 0x1000UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_IEEE_SUPPORTED 0x2000UL + #define PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_IEEE_ENABLED 0x4000UL u8 duplex_state; #define PORT_PHY_QCFG_RESP_DUPLEX_STATE_HALF 0x0UL #define PORT_PHY_QCFG_RESP_DUPLEX_STATE_FULL 0x1UL @@ -2845,11 +2944,10 @@ struct hwrm_port_phy_qcfg_output { #define PORT_PHY_QCFG_RESP_AUTO_PAM4_LINK_SPEED_MASK_50G 0x1UL #define PORT_PHY_QCFG_RESP_AUTO_PAM4_LINK_SPEED_MASK_100G 0x2UL #define PORT_PHY_QCFG_RESP_AUTO_PAM4_LINK_SPEED_MASK_200G 0x4UL - __le16 link_partner_pam4_adv_speeds; + u8 link_partner_pam4_adv_speeds; #define PORT_PHY_QCFG_RESP_LINK_PARTNER_PAM4_ADV_SPEEDS_50GB 0x1UL #define PORT_PHY_QCFG_RESP_LINK_PARTNER_PAM4_ADV_SPEEDS_100GB 0x2UL #define PORT_PHY_QCFG_RESP_LINK_PARTNER_PAM4_ADV_SPEEDS_200GB 0x4UL - u8 unused_0[7]; u8 valid; }; @@ -3293,6 +3391,47 @@ struct hwrm_port_lpbk_qstats_output { u8 valid; }; +/* hwrm_port_ecn_qstats_input (size:256b/32B) */ +struct hwrm_port_ecn_qstats_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 port_id; + __le16 ecn_stat_buf_size; + u8 flags; + #define PORT_ECN_QSTATS_REQ_FLAGS_UNUSED 0x0UL + #define PORT_ECN_QSTATS_REQ_FLAGS_COUNTER_MASK 0x1UL + #define PORT_ECN_QSTATS_REQ_FLAGS_LAST PORT_ECN_QSTATS_REQ_FLAGS_COUNTER_MASK + u8 unused_0[3]; + __le64 ecn_stat_host_addr; +}; + +/* hwrm_port_ecn_qstats_output (size:128b/16B) */ +struct hwrm_port_ecn_qstats_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 ecn_stat_buf_size; + u8 mark_en; + u8 unused_0[4]; + u8 valid; +}; + +/* port_stats_ecn (size:512b/64B) */ +struct port_stats_ecn { + __le64 mark_cnt_cos0; + __le64 mark_cnt_cos1; + __le64 mark_cnt_cos2; + __le64 mark_cnt_cos3; + __le64 mark_cnt_cos4; + __le64 mark_cnt_cos5; + __le64 mark_cnt_cos6; + __le64 mark_cnt_cos7; +}; + /* hwrm_port_clr_stats_input (size:192b/24B) */ struct hwrm_port_clr_stats_input { __le16 req_type; @@ -3387,8 +3526,9 @@ struct hwrm_port_phy_qcaps_output { #define PORT_PHY_QCAPS_RESP_FLAGS_AUTONEG_LPBK_SUPPORTED 0x4UL #define PORT_PHY_QCAPS_RESP_FLAGS_SHARED_PHY_CFG_SUPPORTED 0x8UL #define PORT_PHY_QCAPS_RESP_FLAGS_CUMULATIVE_COUNTERS_ON_RESET 0x10UL - #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_MASK 0xe0UL - #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_SFT 5 + #define PORT_PHY_QCAPS_RESP_FLAGS_LOCAL_LPBK_NOT_SUPPORTED 0x20UL + #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_MASK 0xc0UL + #define PORT_PHY_QCAPS_RESP_FLAGS_RSVD1_SFT 6 u8 port_cnt; #define PORT_PHY_QCAPS_RESP_PORT_CNT_UNKNOWN 0x0UL #define PORT_PHY_QCAPS_RESP_PORT_CNT_1 0x1UL @@ -5365,6 +5505,7 @@ struct hwrm_ring_alloc_input { #define RING_ALLOC_REQ_ENABLES_NQ_RING_ID_VALID 0x80UL #define RING_ALLOC_REQ_ENABLES_RX_BUF_SIZE_VALID 0x100UL #define RING_ALLOC_REQ_ENABLES_SCHQ_ID 0x200UL + #define RING_ALLOC_REQ_ENABLES_MPC_CHNLS_TYPE 0x400UL u8 ring_type; #define RING_ALLOC_REQ_RING_TYPE_L2_CMPL 0x0UL #define RING_ALLOC_REQ_RING_TYPE_TX 0x1UL @@ -5424,7 +5565,14 @@ struct hwrm_ring_alloc_input { #define RING_ALLOC_REQ_INT_MODE_MSIX 0x2UL #define RING_ALLOC_REQ_INT_MODE_POLL 0x3UL #define RING_ALLOC_REQ_INT_MODE_LAST RING_ALLOC_REQ_INT_MODE_POLL - u8 unused_4[3]; + u8 mpc_chnls_type; + #define RING_ALLOC_REQ_MPC_CHNLS_TYPE_TCE 0x0UL + #define RING_ALLOC_REQ_MPC_CHNLS_TYPE_RCE 0x1UL + #define RING_ALLOC_REQ_MPC_CHNLS_TYPE_TE_CFA 0x2UL + #define RING_ALLOC_REQ_MPC_CHNLS_TYPE_RE_CFA 0x3UL + #define RING_ALLOC_REQ_MPC_CHNLS_TYPE_PRIMATE 0x4UL + #define RING_ALLOC_REQ_MPC_CHNLS_TYPE_LAST RING_ALLOC_REQ_MPC_CHNLS_TYPE_PRIMATE + u8 unused_4[2]; __le64 cq_handle; }; @@ -6661,7 +6809,7 @@ struct hwrm_cfa_vfr_alloc_output { u8 valid; }; -/* hwrm_cfa_vfr_free_input (size:384b/48B) */ +/* hwrm_cfa_vfr_free_input (size:448b/56B) */ struct hwrm_cfa_vfr_free_input { __le16 req_type; __le16 cmpl_ring; @@ -6669,6 +6817,9 @@ struct hwrm_cfa_vfr_free_input { __le16 target_id; __le64 resp_addr; char vfr_name[32]; + __le16 vf_id; + __le16 reserved; + u8 unused_0[4]; }; /* hwrm_cfa_vfr_free_output (size:128b/16B) */ @@ -6970,7 +7121,7 @@ struct ctx_hw_stats { __le64 tpa_aborts; }; -/* ctx_hw_stats_ext (size:1344b/168B) */ +/* ctx_hw_stats_ext (size:1408b/176B) */ struct ctx_hw_stats_ext { __le64 rx_ucast_pkts; __le64 rx_mcast_pkts; @@ -6993,6 +7144,7 @@ struct ctx_hw_stats_ext { __le64 rx_tpa_pkt; __le64 rx_tpa_bytes; __le64 rx_tpa_errors; + __le64 rx_tpa_events; }; /* hwrm_stat_ctx_alloc_input (size:256b/32B) */ @@ -7065,16 +7217,16 @@ struct hwrm_stat_ctx_query_output { __le64 tx_ucast_pkts; __le64 tx_mcast_pkts; __le64 tx_bcast_pkts; - __le64 tx_err_pkts; - __le64 tx_drop_pkts; + __le64 tx_discard_pkts; + __le64 tx_error_pkts; __le64 tx_ucast_bytes; __le64 tx_mcast_bytes; __le64 tx_bcast_bytes; __le64 rx_ucast_pkts; __le64 rx_mcast_pkts; __le64 rx_bcast_pkts; - __le64 rx_err_pkts; - __le64 rx_drop_pkts; + __le64 rx_discard_pkts; + __le64 rx_error_pkts; __le64 rx_ucast_bytes; __le64 rx_mcast_bytes; __le64 rx_bcast_bytes; @@ -7099,7 +7251,7 @@ struct hwrm_stat_ext_ctx_query_input { u8 unused_0[3]; }; -/* hwrm_stat_ext_ctx_query_output (size:1472b/184B) */ +/* hwrm_stat_ext_ctx_query_output (size:1536b/192B) */ struct hwrm_stat_ext_ctx_query_output { __le16 error_code; __le16 req_type; @@ -7126,6 +7278,7 @@ struct hwrm_stat_ext_ctx_query_output { __le64 rx_tpa_pkt; __le64 rx_tpa_bytes; __le64 rx_tpa_errors; + __le64 rx_tpa_events; u8 unused_0[7]; u8 valid; }; @@ -7702,6 +7855,77 @@ struct hwrm_dbg_read_direct_output { u8 valid; }; +/* hwrm_dbg_qcaps_input (size:192b/24B) */ +struct hwrm_dbg_qcaps_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 fid; + u8 unused_0[6]; +}; + +/* hwrm_dbg_qcaps_output (size:192b/24B) */ +struct hwrm_dbg_qcaps_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 fid; + u8 unused_0[2]; + __le32 coredump_component_disable_caps; + #define DBG_QCAPS_RESP_COREDUMP_COMPONENT_DISABLE_CAPS_NVRAM 0x1UL + __le32 flags; + #define DBG_QCAPS_RESP_FLAGS_CRASHDUMP_NVM 0x1UL + #define DBG_QCAPS_RESP_FLAGS_CRASHDUMP_HOST_DDR 0x2UL + #define DBG_QCAPS_RESP_FLAGS_CRASHDUMP_SOC_DDR 0x4UL + u8 unused_1[3]; + u8 valid; +}; + +/* hwrm_dbg_qcfg_input (size:192b/24B) */ +struct hwrm_dbg_qcfg_input { + __le16 req_type; + __le16 cmpl_ring; + __le16 seq_id; + __le16 target_id; + __le64 resp_addr; + __le16 fid; + __le16 flags; + #define DBG_QCFG_REQ_FLAGS_CRASHDUMP_SIZE_FOR_DEST_MASK 0x3UL + #define DBG_QCFG_REQ_FLAGS_CRASHDUMP_SIZE_FOR_DEST_SFT 0 + #define DBG_QCFG_REQ_FLAGS_CRASHDUMP_SIZE_FOR_DEST_DEST_NVM 0x0UL + #define DBG_QCFG_REQ_FLAGS_CRASHDUMP_SIZE_FOR_DEST_DEST_HOST_DDR 0x1UL + #define DBG_QCFG_REQ_FLAGS_CRASHDUMP_SIZE_FOR_DEST_DEST_SOC_DDR 0x2UL + #define DBG_QCFG_REQ_FLAGS_CRASHDUMP_SIZE_FOR_DEST_LAST DBG_QCFG_REQ_FLAGS_CRASHDUMP_SIZE_FOR_DEST_DEST_SOC_DDR + __le32 coredump_component_disable_flags; + #define DBG_QCFG_REQ_COREDUMP_COMPONENT_DISABLE_FLAGS_NVRAM 0x1UL +}; + +/* hwrm_dbg_qcfg_output (size:256b/32B) */ +struct hwrm_dbg_qcfg_output { + __le16 error_code; + __le16 req_type; + __le16 seq_id; + __le16 resp_len; + __le16 fid; + u8 unused_0[2]; + __le32 coredump_size; + __le32 flags; + #define DBG_QCFG_RESP_FLAGS_UART_LOG 0x1UL + #define DBG_QCFG_RESP_FLAGS_UART_LOG_SECONDARY 0x2UL + #define DBG_QCFG_RESP_FLAGS_FW_TRACE 0x4UL + #define DBG_QCFG_RESP_FLAGS_FW_TRACE_SECONDARY 0x8UL + #define DBG_QCFG_RESP_FLAGS_DEBUG_NOTIFY 0x10UL + #define DBG_QCFG_RESP_FLAGS_JTAG_DEBUG 0x20UL + __le16 async_cmpl_ring; + u8 unused_2[2]; + __le32 crashdump_size; + u8 unused_3[3]; + u8 valid; +}; + /* coredump_segment_record (size:128b/16B) */ struct coredump_segment_record { __le16 component_id; @@ -8381,6 +8605,16 @@ struct hwrm_selftest_irq_output { u8 valid; }; +/* db_push_info (size:64b/8B) */ +struct db_push_info { + u32 push_size_push_index; + #define DB_PUSH_INFO_PUSH_INDEX_MASK 0xffffffUL + #define DB_PUSH_INFO_PUSH_INDEX_SFT 0 + #define DB_PUSH_INFO_PUSH_SIZE_MASK 0x1f000000UL + #define DB_PUSH_INFO_PUSH_SIZE_SFT 24 + u32 reserved32; +}; + /* fw_status_reg (size:32b/4B) */ struct fw_status_reg { u32 fw_status; @@ -8395,4 +8629,29 @@ struct fw_status_reg { #define FW_STATUS_REG_SHUTDOWN 0x100000UL }; +/* hcomm_status (size:64b/8B) */ +struct hcomm_status { + u32 sig_ver; + #define HCOMM_STATUS_VER_MASK 0xffUL + #define HCOMM_STATUS_VER_SFT 0 + #define HCOMM_STATUS_VER_LATEST 0x1UL + #define HCOMM_STATUS_VER_LAST HCOMM_STATUS_VER_LATEST + #define HCOMM_STATUS_SIGNATURE_MASK 0xffffff00UL + #define HCOMM_STATUS_SIGNATURE_SFT 8 + #define HCOMM_STATUS_SIGNATURE_VAL (0x484353UL << 8) + #define HCOMM_STATUS_SIGNATURE_LAST HCOMM_STATUS_SIGNATURE_VAL + u32 fw_status_loc; + #define HCOMM_STATUS_TRUE_ADDR_SPACE_MASK 0x3UL + #define HCOMM_STATUS_TRUE_ADDR_SPACE_SFT 0 + #define HCOMM_STATUS_FW_STATUS_LOC_ADDR_SPACE_PCIE_CFG 0x0UL + #define HCOMM_STATUS_FW_STATUS_LOC_ADDR_SPACE_GRC 0x1UL + #define HCOMM_STATUS_FW_STATUS_LOC_ADDR_SPACE_BAR0 0x2UL + #define HCOMM_STATUS_FW_STATUS_LOC_ADDR_SPACE_BAR1 0x3UL + #define HCOMM_STATUS_FW_STATUS_LOC_ADDR_SPACE_LAST HCOMM_STATUS_FW_STATUS_LOC_ADDR_SPACE_BAR1 + #define HCOMM_STATUS_TRUE_OFFSET_MASK 0xfffffffcUL + #define HCOMM_STATUS_TRUE_OFFSET_SFT 2 +}; + +#define HCOMM_STATUS_STRUCT_LOC 0x31001F0UL + #endif /* _BNXT_HSI_H_ */ diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index cc2ee4d0bd18..23b80aa171dd 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -1029,7 +1029,7 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf) rc = bnxt_hwrm_exec_fwd_resp( bp, vf, sizeof(struct hwrm_port_phy_qcfg_input)); } else { - struct hwrm_port_phy_qcfg_output_compat phy_qcfg_resp = {0}; + struct hwrm_port_phy_qcfg_output phy_qcfg_resp = {0}; struct hwrm_port_phy_qcfg_input *phy_qcfg_req; phy_qcfg_req = From c916062a8917463a469539eccee50d31e63c91c1 Mon Sep 17 00:00:00 2001 From: Edwin Peer Date: Sun, 27 Sep 2020 13:42:11 -0400 Subject: [PATCH 02/11] bnxt_en: refactor code to limit speed advertising Extract the code for determining an advertised speed is no longer supported into a separate function. This will avoid some code duplication in a later patch when supporting PAM4 speeds, since these speeds are specified in a separate field. Reviewed-by: Scott Branden Signed-off-by: Edwin Peer Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index b57f28d2e716..0ca4f7a78c5d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8835,6 +8835,13 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) return rc; } +static bool bnxt_support_dropped(u16 advertising, u16 supported) +{ + u16 diff = advertising ^ supported; + + return ((supported | diff) != supported); +} + static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) { int rc = 0; @@ -8842,7 +8849,6 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) struct hwrm_port_phy_qcfg_input req = {0}; struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr; u8 link_up = link_info->link_up; - u16 diff; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_QCFG, -1, -1); @@ -8941,13 +8947,11 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) if (!BNXT_PHY_CFG_ABLE(bp)) return 0; - diff = link_info->support_auto_speeds ^ link_info->advertising; - if ((link_info->support_auto_speeds | diff) != - link_info->support_auto_speeds) { - /* An advertised speed is no longer supported, so we need to - * update the advertisement settings. Caller holds RTNL - * so we can modify link settings. - */ + /* Check if any advertised speeds are no longer supported. The caller + * holds the link_lock mutex, so we can modify link_info settings. + */ + if (bnxt_support_dropped(link_info->advertising, + link_info->support_auto_speeds)) { link_info->advertising = link_info->support_auto_speeds; if (link_info->autoneg & BNXT_AUTONEG_SPEED) bnxt_hwrm_set_link_setting(bp, true, false); From f00530bf3c9828d22a15043da5bc142760197fc2 Mon Sep 17 00:00:00 2001 From: Edwin Peer Date: Sun, 27 Sep 2020 13:42:12 -0400 Subject: [PATCH 03/11] bnxt_en: refactor bnxt_get_fw_speed() It will be necessary to update more than one field in the link_info structure when PAM4 speeds are added in a later patch. Instead of merely translating ethtool speed values to firmware speed values, change the responsiblity of this function to update all the necessary link_info fields required to force the speed change to the desired ethtool value. This also reduces code duplication somewhat at the two call sites, which otherwise both have to independently update link_info fields to turn off auto negotiation advertisements. Also use the appropriate REQ_FORCE_LINK_SPEED definitions. These happen to have the same values, but req_link_speed is utilimately passed as force_link_speed in HWRM_PORT_PHY_CFG which is not defined in terms of REQ_AUTO_LINK_SPEED. Reviewed-by: Scott Branden Signed-off-by: Edwin Peer Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 9703ff48f2ab..ad6a5967ac21 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1636,55 +1636,63 @@ static int bnxt_get_link_ksettings(struct net_device *dev, return 0; } -static u32 bnxt_get_fw_speed(struct net_device *dev, u32 ethtool_speed) +static int bnxt_force_link_speed(struct net_device *dev, u32 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; + u16 fw_speed = 0; switch (ethtool_speed) { case SPEED_100: if (support_spds & BNXT_LINK_SPEED_MSK_100MB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_100MB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100MB; break; case SPEED_1000: if (support_spds & BNXT_LINK_SPEED_MSK_1GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_1GB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_1GB; break; case SPEED_2500: if (support_spds & BNXT_LINK_SPEED_MSK_2_5GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_2_5GB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_2_5GB; break; case SPEED_10000: if (support_spds & BNXT_LINK_SPEED_MSK_10GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_10GB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_10GB; break; case SPEED_20000: if (support_spds & BNXT_LINK_SPEED_MSK_20GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_20GB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_20GB; break; case SPEED_25000: if (support_spds & BNXT_LINK_SPEED_MSK_25GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_25GB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_25GB; break; case SPEED_40000: if (support_spds & BNXT_LINK_SPEED_MSK_40GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_40GB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_40GB; break; case SPEED_50000: if (support_spds & BNXT_LINK_SPEED_MSK_50GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_50GB; + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_50GB; break; case SPEED_100000: if (support_spds & BNXT_LINK_SPEED_MSK_100GB) - fw_speed = PORT_PHY_CFG_REQ_AUTO_LINK_SPEED_100GB; - break; - default: - netdev_err(dev, "unsupported speed!\n"); + fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB; break; } - return fw_speed; + + if (!fw_speed) { + netdev_err(dev, "unsupported speed!\n"); + return -EINVAL; + } + + link_info->req_link_speed = fw_speed; + link_info->req_duplex = BNXT_LINK_DUPLEX_FULL; + link_info->autoneg = 0; + link_info->advertising = 0; + + return 0; } u16 bnxt_get_fw_auto_link_speeds(u32 advertising) @@ -1737,7 +1745,6 @@ static int bnxt_set_link_ksettings(struct net_device *dev, */ set_pause = true; } else { - u16 fw_speed; u8 phy_type = link_info->phy_type; if (phy_type == PORT_PHY_QCFG_RESP_PHY_TYPE_BASET || @@ -1753,15 +1760,9 @@ static int bnxt_set_link_ksettings(struct net_device *dev, goto set_setting_exit; } speed = base->speed; - fw_speed = bnxt_get_fw_speed(dev, speed); - if (!fw_speed) { - rc = -EINVAL; + rc = bnxt_force_link_speed(dev, speed); + if (rc) 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; } if (netif_running(dev)) From d058426ea84fff2bb941ecb7291a876571860dd2 Mon Sep 17 00:00:00 2001 From: Edwin Peer Date: Sun, 27 Sep 2020 13:42:13 -0400 Subject: [PATCH 04/11] bnxt_en: add basic infrastructure to support PAM4 link speeds The firmware interface has added support for new link speeds using PAM4 modulation. Expand the bnxt_link_info structure to closely mirror the new firmware structures. Add logic to copy the PAM4 capabilities and settings from the firmware. Signed-off-by: Edwin Peer Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 74 ++++++++++++++++------- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 12 ++++ 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 0ca4f7a78c5d..f97b3ba8fc09 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8827,6 +8827,9 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) if (resp->supported_speeds_auto_mode) link_info->support_auto_speeds = le16_to_cpu(resp->supported_speeds_auto_mode); + if (resp->supported_pam4_speeds_auto_mode) + link_info->support_pam4_auto_speeds = + le16_to_cpu(resp->supported_pam4_speeds_auto_mode); bp->port_count = resp->port_cnt; @@ -8849,6 +8852,7 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) struct hwrm_port_phy_qcfg_input req = {0}; struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr; u8 link_up = link_info->link_up; + bool support_changed = false; bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_QCFG, -1, -1); @@ -8875,10 +8879,17 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) else link_info->link_speed = 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->support_speeds = le16_to_cpu(resp->support_speeds); + link_info->support_pam4_speeds = le16_to_cpu(resp->support_pam4_speeds); 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->lp_auto_link_speeds = le16_to_cpu(resp->link_partner_adv_speeds); + link_info->lp_auto_pam4_link_speeds = + resp->link_partner_pam4_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; @@ -8953,9 +8964,15 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) if (bnxt_support_dropped(link_info->advertising, link_info->support_auto_speeds)) { link_info->advertising = link_info->support_auto_speeds; - if (link_info->autoneg & BNXT_AUTONEG_SPEED) - bnxt_hwrm_set_link_setting(bp, true, false); + support_changed = true; } + if (bnxt_support_dropped(link_info->advertising_pam4, + link_info->support_pam4_auto_speeds)) { + link_info->advertising_pam4 = link_info->support_pam4_auto_speeds; + support_changed = true; + } + if (support_changed && (link_info->autoneg & BNXT_AUTONEG_SPEED)) + bnxt_hwrm_set_link_setting(bp, true, false); return 0; } @@ -9014,27 +9031,30 @@ bnxt_hwrm_set_pause_common(struct bnxt *bp, struct hwrm_port_phy_cfg_input *req) } } -static void bnxt_hwrm_set_link_common(struct bnxt *bp, - struct hwrm_port_phy_cfg_input *req) +static void bnxt_hwrm_set_link_common(struct bnxt *bp, struct hwrm_port_phy_cfg_input *req) { - u8 autoneg = bp->link_info.autoneg; - u16 fw_link_speed = bp->link_info.req_link_speed; - u16 advertising = bp->link_info.advertising; - - if (autoneg & BNXT_AUTONEG_SPEED) { - req->auto_mode |= - PORT_PHY_CFG_REQ_AUTO_MODE_SPEED_MASK; - - req->enables |= cpu_to_le32( - PORT_PHY_CFG_REQ_ENABLES_AUTO_LINK_SPEED_MASK); - req->auto_link_speed_mask = cpu_to_le16(advertising); - + if (bp->link_info.autoneg & BNXT_AUTONEG_SPEED) { + req->auto_mode |= PORT_PHY_CFG_REQ_AUTO_MODE_SPEED_MASK; + 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); + } + if (bp->link_info.advertising_pam4) { + req->enables |= + cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_PAM4_LINK_SPEED_MASK); + req->auto_link_pam4_speed_mask = + cpu_to_le16(bp->link_info.advertising_pam4); + } req->enables |= cpu_to_le32(PORT_PHY_CFG_REQ_ENABLES_AUTO_MODE); - req->flags |= - cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_RESTART_AUTONEG); + req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_RESTART_AUTONEG); } else { - req->force_link_speed = cpu_to_le16(fw_link_speed); req->flags |= cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE); + 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 { + req->force_link_speed = cpu_to_le16(bp->link_info.req_link_speed); + } } /* tell chimp that the setting takes effect immediately */ @@ -9430,14 +9450,19 @@ static int bnxt_update_phy_setting(struct bnxt *bp) if (!(link_info->autoneg & BNXT_AUTONEG_SPEED)) { if (BNXT_AUTO_MODE(link_info->auto_mode)) update_link = true; - if (link_info->req_link_speed != link_info->force_link_speed) + if (link_info->req_signal_mode == BNXT_SIG_MODE_NRZ && + link_info->req_link_speed != link_info->force_link_speed) + update_link = true; + else if (link_info->req_signal_mode == BNXT_SIG_MODE_PAM4 && + link_info->req_link_speed != link_info->force_pam4_link_speed) update_link = true; if (link_info->req_duplex != link_info->duplex_setting) update_link = true; } else { if (link_info->auto_mode == BNXT_LINK_AUTO_NONE) update_link = true; - if (link_info->advertising != link_info->auto_link_speeds) + if (link_info->advertising != link_info->auto_link_speeds || + link_info->advertising_pam4 != link_info->auto_pam4_link_speeds) update_link = true; } @@ -10697,8 +10722,15 @@ static void bnxt_init_ethtool_link_settings(struct bnxt *bp) link_info->autoneg |= BNXT_AUTONEG_FLOW_CTRL; } link_info->advertising = link_info->auto_link_speeds; + link_info->advertising_pam4 = link_info->auto_pam4_link_speeds; } else { 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) { + link_info->req_link_speed = + link_info->force_pam4_link_speed; + link_info->req_signal_mode = BNXT_SIG_MODE_PAM4; + } link_info->req_duplex = link_info->duplex_setting; } if (link_info->autoneg & BNXT_AUTONEG_FLOW_CTRL) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 21f2b82287a9..8ba113622425 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1188,6 +1188,7 @@ 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 u16 support_speeds; + u16 support_pam4_speeds; 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 @@ -1199,9 +1200,16 @@ struct bnxt_link_info { #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 #define BNXT_LINK_SPEED_MSK_100GB PORT_PHY_QCFG_RESP_SUPPORT_SPEEDS_100GB + u16 auto_pam4_link_speeds; +#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 support_auto_speeds; + u16 support_pam4_auto_speeds; u16 lp_auto_link_speeds; + u16 lp_auto_pam4_link_speeds; u16 force_link_speed; + u16 force_pam4_link_speed; u32 preemphasis; u8 module_status; u16 fec_cfg; @@ -1213,10 +1221,14 @@ struct bnxt_link_info { u8 autoneg; #define BNXT_AUTONEG_SPEED 1 #define BNXT_AUTONEG_FLOW_CTRL 2 + 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 u8 req_duplex; u8 req_flow_ctrl; u16 req_link_speed; u16 advertising; /* user adv setting */ + u16 advertising_pam4; bool force_link_chng; bool phy_retry; From 532262ba3b84fe77d7d420a24fa66b167bb0d93e Mon Sep 17 00:00:00 2001 From: Edwin Peer Date: Sun, 27 Sep 2020 13:42:14 -0400 Subject: [PATCH 05/11] bnxt_en: ethtool: support PAM4 link speeds up to 200G Add ethtool PAM4 link modes for: 50000baseCR_Full 100000baseCR2_Full 200000baseCR4_Full Signed-off-by: Edwin Peer Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 71 ++++++++++++++++--- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index ad6a5967ac21..2cb2495c2351 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1507,6 +1507,32 @@ u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause) (fw_speeds) |= BNXT_LINK_SPEED_MSK_100GB; \ } +#define BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, name) \ +{ \ + if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_50GB) \ + ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ + 50000baseCR_Full); \ + if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_100GB) \ + ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ + 100000baseCR2_Full);\ + if ((fw_speeds) & BNXT_LINK_PAM4_SPEED_MSK_200GB) \ + ethtool_link_ksettings_add_link_mode(lk_ksettings, name,\ + 200000baseCR4_Full);\ +} + +#define BNXT_ETHTOOL_TO_FW_PAM4_SPDS(fw_speeds, lk_ksettings, name) \ +{ \ + if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ + 50000baseCR_Full)) \ + (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_50GB; \ + if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ + 100000baseCR2_Full)) \ + (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_100GB; \ + if (ethtool_link_ksettings_test_link_mode(lk_ksettings, name, \ + 200000baseCR4_Full)) \ + (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_200GB; \ +} + static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info, struct ethtool_link_ksettings *lk_ksettings) { @@ -1517,6 +1543,8 @@ static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info, fw_pause = link_info->auto_pause_setting; BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, advertising); + fw_speeds = link_info->advertising_pam4; + BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, advertising); } static void bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info, @@ -1530,6 +1558,8 @@ static void bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info, BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, lp_advertising); + fw_speeds = link_info->lp_auto_pam4_link_speeds; + BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, lp_advertising); } static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info, @@ -1538,12 +1568,15 @@ static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info, u16 fw_speeds = link_info->support_speeds; BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, 0, lk_ksettings, supported); + fw_speeds = link_info->support_pam4_speeds; + BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, supported); ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, Pause); ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, Asym_Pause); - if (link_info->support_auto_speeds) + if (link_info->support_auto_speeds || + link_info->support_pam4_auto_speeds) ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, Autoneg); } @@ -1640,7 +1673,9 @@ static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed) { struct bnxt *bp = netdev_priv(dev); struct bnxt_link_info *link_info = &bp->link_info; + u16 support_pam4_spds = link_info->support_pam4_speeds; u16 support_spds = link_info->support_speeds; + u8 sig_mode = BNXT_SIG_MODE_NRZ; u16 fw_speed = 0; switch (ethtool_speed) { @@ -1673,12 +1708,26 @@ static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed) fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_40GB; break; case SPEED_50000: - if (support_spds & BNXT_LINK_SPEED_MSK_50GB) + if (support_spds & BNXT_LINK_SPEED_MSK_50GB) { fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_50GB; + } else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_50GB) { + fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_50GB; + sig_mode = BNXT_SIG_MODE_PAM4; + } break; case SPEED_100000: - if (support_spds & BNXT_LINK_SPEED_MSK_100GB) + if (support_spds & BNXT_LINK_SPEED_MSK_100GB) { fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB; + } else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_100GB) { + fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_100GB; + sig_mode = BNXT_SIG_MODE_PAM4; + } + break; + case SPEED_200000: + if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_200GB) { + fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_200GB; + sig_mode = BNXT_SIG_MODE_PAM4; + } break; } @@ -1688,9 +1737,11 @@ static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed) } link_info->req_link_speed = fw_speed; + link_info->req_signal_mode = sig_mode; link_info->req_duplex = BNXT_LINK_DUPLEX_FULL; link_info->autoneg = 0; link_info->advertising = 0; + link_info->advertising_pam4 = 0; return 0; } @@ -1724,7 +1775,6 @@ static int bnxt_set_link_ksettings(struct net_device *dev, struct bnxt_link_info *link_info = &bp->link_info; const struct ethtool_link_settings *base = &lk_ksettings->base; bool set_pause = false; - u16 fw_advertising = 0; u32 speed; int rc = 0; @@ -1733,13 +1783,18 @@ static int bnxt_set_link_ksettings(struct net_device *dev, mutex_lock(&bp->link_lock); if (base->autoneg == AUTONEG_ENABLE) { - BNXT_ETHTOOL_TO_FW_SPDS(fw_advertising, lk_ksettings, + link_info->advertising = 0; + link_info->advertising_pam4 = 0; + BNXT_ETHTOOL_TO_FW_SPDS(link_info->advertising, lk_ksettings, advertising); + BNXT_ETHTOOL_TO_FW_PAM4_SPDS(link_info->advertising_pam4, + lk_ksettings, advertising); link_info->autoneg |= BNXT_AUTONEG_SPEED; - if (!fw_advertising) + if (!link_info->advertising && !link_info->advertising_pam4) { link_info->advertising = link_info->support_auto_speeds; - else - link_info->advertising = fw_advertising; + link_info->advertising_pam4 = + link_info->support_pam4_auto_speeds; + } /* any change to autoneg will cause link change, therefore the * driver should put back the original pause setting in autoneg */ From 3128e811b134128aadcf8582dded81b70980f23a Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 27 Sep 2020 13:42:15 -0400 Subject: [PATCH 06/11] bnxt_en: Handle ethernet link being disabled by firmware. On some 200G dual port NICs, if one port is configured to 200G, firmware will disable the ethernet link on the other port. Firmware will send notification to the driver for the disabled port when this happens. Define a new field in the link_info structure to keep track of this state. The new phy_state field replaces the unused loop_back field. Log a message when the phy_state changes state. In the disabled state, disallow any PHY configurations on the disabled port as the firmware will fail all calls to configure the PHY in this state. Reviewed-by: Vasundhara Volam Reviewed-by: Edwin Peer Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 22 ++++++++++++++++++++++ drivers/net/ethernet/broadcom/bnxt/bnxt.h | 10 +++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index f97b3ba8fc09..a76ae6a68ca2 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8777,6 +8777,16 @@ static void bnxt_report_link(struct bnxt *bp) } } +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) + return true; + return false; +} + static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) { int rc = 0; @@ -8824,6 +8834,18 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp) if (resp->flags & PORT_PHY_QCAPS_RESP_FLAGS_CUMULATIVE_COUNTERS_ON_RESET) bp->fw_cap |= BNXT_FW_CAP_PORT_STATS_NO_RESET; + if (bp->hwrm_spec_code >= 0x10a01) { + if (bnxt_phy_qcaps_no_speed(resp)) { + link_info->phy_state = BNXT_PHY_STATE_DISABLED; + netdev_warn(bp->dev, "Ethernet link disabled\n"); + } else if (link_info->phy_state == BNXT_PHY_STATE_DISABLED) { + link_info->phy_state = BNXT_PHY_STATE_ENABLED; + netdev_info(bp->dev, "Ethernet link enabled\n"); + /* Phy re-enabled, reprobe the speeds */ + link_info->support_auto_speeds = 0; + link_info->support_pam4_auto_speeds = 0; + } + } if (resp->supported_speeds_auto_mode) link_info->support_auto_speeds = le16_to_cpu(resp->supported_speeds_auto_mode); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 8ba113622425..fbbc30288fa6 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1152,7 +1152,10 @@ struct bnxt_link_info { #define BNXT_LINK_SIGNAL PORT_PHY_QCFG_RESP_LINK_SIGNAL #define BNXT_LINK_LINK PORT_PHY_QCFG_RESP_LINK_LINK u8 wire_speed; - u8 loop_back; + u8 phy_state; +#define BNXT_PHY_STATE_ENABLED 0 +#define BNXT_PHY_STATE_DISABLED 1 + u8 link_up; u8 duplex; #define BNXT_LINK_DUPLEX_HALF PORT_PHY_QCFG_RESP_DUPLEX_STATE_HALF @@ -1601,8 +1604,9 @@ struct bnxt { #define BNXT_NPAR(bp) ((bp)->port_partition_type) #define BNXT_MH(bp) ((bp)->flags & BNXT_FLAG_MULTI_HOST) #define BNXT_SINGLE_PF(bp) (BNXT_PF(bp) && !BNXT_NPAR(bp) && !BNXT_MH(bp)) -#define BNXT_PHY_CFG_ABLE(bp) (BNXT_SINGLE_PF(bp) || \ - ((bp)->fw_cap & BNXT_FW_CAP_SHARED_PORT_CFG)) +#define BNXT_PHY_CFG_ABLE(bp) ((BNXT_SINGLE_PF(bp) || \ + ((bp)->fw_cap & BNXT_FW_CAP_SHARED_PORT_CFG)) && \ + (bp)->link_info.phy_state == BNXT_PHY_STATE_ENABLED) #define BNXT_CHIP_TYPE_NITRO_A0(bp) ((bp)->flags & BNXT_FLAG_CHIP_NITRO_A0) #define BNXT_RX_PAGE_MODE(bp) ((bp)->flags & BNXT_FLAG_RX_PAGE_MODE) #define BNXT_SUPPORTS_TPA(bp) (!BNXT_CHIP_TYPE_NITRO_A0(bp) && \ From 745b5c653913829ede6d4466f36b35426d6e1823 Mon Sep 17 00:00:00 2001 From: Edwin Peer Date: Sun, 27 Sep 2020 13:42:16 -0400 Subject: [PATCH 07/11] bnxt_en: avoid link reset if speed is not changed PORT_PHY_CONFIG is always sent with REQ_FLAGS_RESET_PHY set. This flag must be set in order for the firmware to institute the requested PHY change immediately, but it results in a link flap. This is unnecessary and results in an improved user experience if the PHY reconfiguration is avoided when the user requested speed does not constitute a change. Signed-off-by: Edwin Peer Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 2cb2495c2351..4fdb672a47a0 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1736,6 +1736,11 @@ static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed) return -EINVAL; } + if (link_info->req_link_speed == fw_speed && + link_info->req_signal_mode == sig_mode && + link_info->autoneg == 0) + return -EALREADY; + link_info->req_link_speed = fw_speed; link_info->req_signal_mode = sig_mode; link_info->req_duplex = BNXT_LINK_DUPLEX_FULL; @@ -1816,8 +1821,11 @@ static int bnxt_set_link_ksettings(struct net_device *dev, } speed = base->speed; rc = bnxt_force_link_speed(dev, speed); - if (rc) + if (rc) { + if (rc == -EALREADY) + rc = 0; goto set_setting_exit; + } } if (netif_running(dev)) From 8b2775890ad88d20a8f968aa88dbae487961240f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 27 Sep 2020 13:42:17 -0400 Subject: [PATCH 08/11] bnxt_en: Report FEC settings to ethtool. Implement .get_fecparam() method to report the configured and active FEC settings. Also report the supported and advertised FEC settings to the .get_link_ksettings() method. Reviewed-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 +- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 18 +++- .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 89 +++++++++++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index a76ae6a68ca2..ab3b36deaf66 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8960,9 +8960,10 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) } link_info->fec_cfg = PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED; - if (bp->hwrm_spec_code >= 0x10504) + if (bp->hwrm_spec_code >= 0x10504) { link_info->fec_cfg = le16_to_cpu(resp->fec_cfg); - + link_info->active_fec_sig_mode = resp->active_fec_signal_mode; + } /* TODO: need to add more logic to report VF link */ if (chng_link_state) { if (link_info->phy_link_status == BNXT_LINK_LINK) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index fbbc30288fa6..8a4c842ad06d 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1215,10 +1215,26 @@ struct bnxt_link_info { u16 force_pam4_link_speed; u32 preemphasis; u8 module_status; + u8 active_fec_sig_mode; u16 fec_cfg; +#define BNXT_FEC_NONE PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED +#define BNXT_FEC_AUTONEG_CAP PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_SUPPORTED #define BNXT_FEC_AUTONEG PORT_PHY_QCFG_RESP_FEC_CFG_FEC_AUTONEG_ENABLED +#define BNXT_FEC_ENC_BASE_R_CAP \ + PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_SUPPORTED #define BNXT_FEC_ENC_BASE_R PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE74_ENABLED -#define BNXT_FEC_ENC_RS PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED +#define BNXT_FEC_ENC_RS_CAP \ + PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_SUPPORTED +#define BNXT_FEC_ENC_LLRS_CAP \ + (PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_1XN_SUPPORTED | \ + PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_IEEE_SUPPORTED) +#define BNXT_FEC_ENC_RS \ + (PORT_PHY_QCFG_RESP_FEC_CFG_FEC_CLAUSE91_ENABLED | \ + PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_1XN_ENABLED | \ + PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS544_IEEE_ENABLED) +#define BNXT_FEC_ENC_LLRS \ + (PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_1XN_ENABLED | \ + PORT_PHY_QCFG_RESP_FEC_CFG_FEC_RS272_IEEE_ENABLED) /* copy of requested setting from ethtool cmd */ u8 autoneg; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 4fdb672a47a0..3dc5d084db35 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -1533,6 +1534,27 @@ u32 _bnxt_fw_to_ethtool_adv_spds(u16 fw_speeds, u8 fw_pause) (fw_speeds) |= BNXT_LINK_PAM4_SPEED_MSK_200GB; \ } +static void bnxt_fw_to_ethtool_advertised_fec(struct bnxt_link_info *link_info, + struct ethtool_link_ksettings *lk_ksettings) +{ + u16 fec_cfg = link_info->fec_cfg; + + if ((fec_cfg & BNXT_FEC_NONE) || !(fec_cfg & BNXT_FEC_AUTONEG)) { + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, + lk_ksettings->link_modes.advertising); + return; + } + if (fec_cfg & BNXT_FEC_ENC_BASE_R) + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, + lk_ksettings->link_modes.advertising); + if (fec_cfg & BNXT_FEC_ENC_RS) + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, + lk_ksettings->link_modes.advertising); + if (fec_cfg & BNXT_FEC_ENC_LLRS) + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, + lk_ksettings->link_modes.advertising); +} + static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info, struct ethtool_link_ksettings *lk_ksettings) { @@ -1545,6 +1567,7 @@ static void bnxt_fw_to_ethtool_advertised_spds(struct bnxt_link_info *link_info, BNXT_FW_TO_ETHTOOL_SPDS(fw_speeds, fw_pause, lk_ksettings, advertising); fw_speeds = link_info->advertising_pam4; BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, advertising); + bnxt_fw_to_ethtool_advertised_fec(link_info, lk_ksettings); } static void bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info, @@ -1562,6 +1585,27 @@ static void bnxt_fw_to_ethtool_lp_adv(struct bnxt_link_info *link_info, BNXT_FW_TO_ETHTOOL_PAM4_SPDS(fw_speeds, lk_ksettings, lp_advertising); } +static void bnxt_fw_to_ethtool_support_fec(struct bnxt_link_info *link_info, + struct ethtool_link_ksettings *lk_ksettings) +{ + u16 fec_cfg = link_info->fec_cfg; + + if (fec_cfg & BNXT_FEC_NONE) { + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_NONE_BIT, + lk_ksettings->link_modes.supported); + return; + } + if (fec_cfg & BNXT_FEC_ENC_BASE_R_CAP) + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_BASER_BIT, + lk_ksettings->link_modes.supported); + if (fec_cfg & BNXT_FEC_ENC_RS_CAP) + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_RS_BIT, + lk_ksettings->link_modes.supported); + if (fec_cfg & BNXT_FEC_ENC_LLRS_CAP) + linkmode_set_bit(ETHTOOL_LINK_MODE_FEC_LLRS_BIT, + lk_ksettings->link_modes.supported); +} + static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info, struct ethtool_link_ksettings *lk_ksettings) { @@ -1579,6 +1623,7 @@ static void bnxt_fw_to_ethtool_support_spds(struct bnxt_link_info *link_info, link_info->support_pam4_auto_speeds) ethtool_link_ksettings_add_link_mode(lk_ksettings, supported, Autoneg); + bnxt_fw_to_ethtool_support_fec(link_info, lk_ksettings); } u32 bnxt_fw_to_ethtool_speed(u16 fw_link_speed) @@ -1836,6 +1881,49 @@ static int bnxt_set_link_ksettings(struct net_device *dev, return rc; } +static int bnxt_get_fecparam(struct net_device *dev, + struct ethtool_fecparam *fec) +{ + struct bnxt *bp = netdev_priv(dev); + struct bnxt_link_info *link_info; + u8 active_fec; + u16 fec_cfg; + + link_info = &bp->link_info; + fec_cfg = link_info->fec_cfg; + active_fec = link_info->active_fec_sig_mode & + PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK; + if (fec_cfg & BNXT_FEC_NONE) { + fec->fec = ETHTOOL_FEC_NONE; + fec->active_fec = ETHTOOL_FEC_NONE; + return 0; + } + if (fec_cfg & BNXT_FEC_AUTONEG) + fec->fec |= ETHTOOL_FEC_AUTO; + if (fec_cfg & BNXT_FEC_ENC_BASE_R) + fec->fec |= ETHTOOL_FEC_BASER; + if (fec_cfg & BNXT_FEC_ENC_RS) + fec->fec |= ETHTOOL_FEC_RS; + if (fec_cfg & BNXT_FEC_ENC_LLRS) + fec->fec |= ETHTOOL_FEC_LLRS; + + switch (active_fec) { + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE: + fec->active_fec |= ETHTOOL_FEC_BASER; + break; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE: + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE: + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE: + fec->active_fec |= ETHTOOL_FEC_RS; + break; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE: + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE: + fec->active_fec |= ETHTOOL_FEC_LLRS; + break; + } + return 0; +} + static void bnxt_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { @@ -3741,6 +3829,7 @@ const struct ethtool_ops bnxt_ethtool_ops = { ETHTOOL_COALESCE_USE_ADAPTIVE_RX, .get_link_ksettings = bnxt_get_link_ksettings, .set_link_ksettings = bnxt_set_link_ksettings, + .get_fecparam = bnxt_get_fecparam, .get_pause_stats = bnxt_get_pause_stats, .get_pauseparam = bnxt_get_pauseparam, .set_pauseparam = bnxt_set_pauseparam, From 2046e3c356fd18f577cd0180a299cddd10fe5752 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 27 Sep 2020 13:42:18 -0400 Subject: [PATCH 09/11] bnxt_en: Report Active FEC encoding during link up. The current code is reporting the FEC configured settings during link up. Change it to report the more useful active FEC encoding that may be negotiated or auto detected. Reviewed-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 29 ++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index ab3b36deaf66..834f64f5f4d6 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8737,6 +8737,30 @@ void bnxt_tx_enable(struct bnxt *bp) netif_carrier_on(bp->dev); } +static char *bnxt_report_fec(struct bnxt_link_info *link_info) +{ + u8 active_fec = link_info->active_fec_sig_mode & + PORT_PHY_QCFG_RESP_ACTIVE_FEC_MASK; + + switch (active_fec) { + default: + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_NONE_ACTIVE: + return "None"; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE74_ACTIVE: + return "Clause 74 BaseR"; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_CLAUSE91_ACTIVE: + return "Clause 91 RS(528,514)"; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_1XN_ACTIVE: + return "Clause 91 RS544_1XN"; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS544_IEEE_ACTIVE: + return "Clause 91 RS(544,514)"; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_1XN_ACTIVE: + return "Clause 91 RS272_1XN"; + case PORT_PHY_QCFG_RESP_ACTIVE_FEC_FEC_RS272_IEEE_ACTIVE: + return "Clause 91 RS(272,257)"; + } +} + static void bnxt_report_link(struct bnxt *bp) { if (bp->link_info.link_up) { @@ -8767,10 +8791,9 @@ static void bnxt_report_link(struct bnxt *bp) "not active"); fec = bp->link_info.fec_cfg; if (!(fec & PORT_PHY_QCFG_RESP_FEC_CFG_FEC_NONE_SUPPORTED)) - netdev_info(bp->dev, "FEC autoneg %s encodings: %s\n", + netdev_info(bp->dev, "FEC autoneg %s encoding: %s\n", (fec & BNXT_FEC_AUTONEG) ? "on" : "off", - (fec & BNXT_FEC_ENC_BASE_R) ? "BaseR" : - (fec & BNXT_FEC_ENC_RS) ? "RS" : "None"); + bnxt_report_fec(&bp->link_info)); } else { netif_carrier_off(bp->dev); netdev_err(bp->dev, "NIC Link is Down\n"); From ccd6a9dcab79dc98d8d93d5aa3f68d71494f93fe Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 27 Sep 2020 13:42:19 -0400 Subject: [PATCH 10/11] bnxt_en: Implement ethtool set_fec_param() method. This feature allows the user to set the different FEC modes on the NIC port. Any new setting will take effect immediately after a link toggle. Reviewed-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 44 +++++++++++++ .../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 62 +++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 834f64f5f4d6..38bbd7631fca 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -8890,7 +8890,7 @@ static bool bnxt_support_dropped(u16 advertising, u16 supported) return ((supported | diff) != supported); } -static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) +int bnxt_update_link(struct bnxt *bp, bool chng_link_state) { int rc = 0; struct bnxt_link_info *link_info = &bp->link_info; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index 8a4c842ad06d..74387259e1c6 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1259,6 +1259,49 @@ struct bnxt_link_info { struct hwrm_port_phy_qcfg_output phy_qcfg_resp; }; +#define BNXT_FEC_RS544_ON \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_ENABLE | \ + PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_IEEE_ENABLE) + +#define BNXT_FEC_RS544_OFF \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_1XN_DISABLE | \ + PORT_PHY_CFG_REQ_FLAGS_FEC_RS544_IEEE_DISABLE) + +#define BNXT_FEC_RS272_ON \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_1XN_ENABLE | \ + PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_IEEE_ENABLE) + +#define BNXT_FEC_RS272_OFF \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_1XN_DISABLE | \ + PORT_PHY_CFG_REQ_FLAGS_FEC_RS272_IEEE_DISABLE) + +#define BNXT_PAM4_SUPPORTED(link_info) \ + ((link_info)->support_pam4_speeds) + +#define BNXT_FEC_RS_ON(link_info) \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE | \ + PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE | \ + (BNXT_PAM4_SUPPORTED(link_info) ? \ + (BNXT_FEC_RS544_ON | BNXT_FEC_RS272_OFF) : 0)) + +#define BNXT_FEC_LLRS_ON \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_ENABLE | \ + PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE | \ + BNXT_FEC_RS272_ON | BNXT_FEC_RS544_OFF) + +#define BNXT_FEC_RS_OFF(link_info) \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE91_DISABLE | \ + (BNXT_PAM4_SUPPORTED(link_info) ? \ + (BNXT_FEC_RS544_OFF | BNXT_FEC_RS272_OFF) : 0)) + +#define BNXT_FEC_BASE_R_ON(link_info) \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_ENABLE | \ + BNXT_FEC_RS_OFF(link_info)) + +#define BNXT_FEC_ALL_OFF(link_info) \ + (PORT_PHY_CFG_REQ_FLAGS_FEC_CLAUSE74_DISABLE | \ + BNXT_FEC_RS_OFF(link_info)) + #define BNXT_MAX_QUEUE 8 struct bnxt_queue_info { @@ -2125,6 +2168,7 @@ int bnxt_get_avail_msix(struct bnxt *bp, int num); int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init); void bnxt_tx_disable(struct bnxt *bp); void bnxt_tx_enable(struct bnxt *bp); +int bnxt_update_link(struct bnxt *bp, bool chng_link_state); int bnxt_hwrm_set_pause(struct bnxt *); int bnxt_hwrm_set_link_setting(struct bnxt *, bool, bool); int bnxt_hwrm_alloc_wol_fltr(struct bnxt *bp); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 3dc5d084db35..0d9fe14646f7 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -1924,6 +1924,67 @@ static int bnxt_get_fecparam(struct net_device *dev, return 0; } +static u32 bnxt_ethtool_forced_fec_to_fw(struct bnxt_link_info *link_info, + u32 fec) +{ + u32 fw_fec = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE; + + if (fec & ETHTOOL_FEC_BASER) + fw_fec |= BNXT_FEC_BASE_R_ON(link_info); + else if (fec & ETHTOOL_FEC_RS) + fw_fec |= BNXT_FEC_RS_ON(link_info); + else if (fec & ETHTOOL_FEC_LLRS) + fw_fec |= BNXT_FEC_LLRS_ON; + return fw_fec; +} + +static int bnxt_set_fecparam(struct net_device *dev, + struct ethtool_fecparam *fecparam) +{ + struct hwrm_port_phy_cfg_input req = {0}; + struct bnxt *bp = netdev_priv(dev); + struct bnxt_link_info *link_info; + u32 new_cfg, fec = fecparam->fec; + u16 fec_cfg; + int rc; + + link_info = &bp->link_info; + fec_cfg = link_info->fec_cfg; + if (fec_cfg & BNXT_FEC_NONE) + return -EOPNOTSUPP; + + if (fec & ETHTOOL_FEC_OFF) { + new_cfg = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_DISABLE | + BNXT_FEC_ALL_OFF(link_info); + goto apply_fec; + } + if (((fec & ETHTOOL_FEC_AUTO) && !(fec_cfg & BNXT_FEC_AUTONEG_CAP)) || + ((fec & ETHTOOL_FEC_RS) && !(fec_cfg & BNXT_FEC_ENC_RS_CAP)) || + ((fec & ETHTOOL_FEC_LLRS) && !(fec_cfg & BNXT_FEC_ENC_LLRS_CAP)) || + ((fec & ETHTOOL_FEC_BASER) && !(fec_cfg & BNXT_FEC_ENC_BASE_R_CAP))) + return -EINVAL; + + if (fec & ETHTOOL_FEC_AUTO) { + if (!link_info->autoneg) + return -EINVAL; + new_cfg = PORT_PHY_CFG_REQ_FLAGS_FEC_AUTONEG_ENABLE; + } else { + new_cfg = bnxt_ethtool_forced_fec_to_fw(link_info, fec); + } + +apply_fec: + bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_PORT_PHY_CFG, -1, -1); + req.flags = cpu_to_le32(new_cfg | PORT_PHY_CFG_REQ_FLAGS_RESET_PHY); + rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); + /* update current settings */ + if (!rc) { + mutex_lock(&bp->link_lock); + bnxt_update_link(bp, false); + mutex_unlock(&bp->link_lock); + } + return rc; +} + static void bnxt_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { @@ -3830,6 +3891,7 @@ const struct ethtool_ops bnxt_ethtool_ops = { .get_link_ksettings = bnxt_get_link_ksettings, .set_link_ksettings = bnxt_set_link_ksettings, .get_fecparam = bnxt_get_fecparam, + .set_fecparam = bnxt_set_fecparam, .get_pause_stats = bnxt_get_pause_stats, .get_pauseparam = bnxt_get_pauseparam, .set_pauseparam = bnxt_set_pauseparam, From 4301304b04cc79f7b79bc982469fce16397f949f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 27 Sep 2020 13:42:20 -0400 Subject: [PATCH 11/11] bnxt_en: Improve preset max value for ethtool -l. The current logic that calculates the preset maximum value for combined channel does not take into account the rings used for XDP and mqprio TCs. Each of these features will reduce the number of TX rings. Add the logic to divide the TX rings accordingly based on whether the device is currently in XDP mode and whether TCs are in use. Reviewed-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 0d9fe14646f7..19b8e3e822f1 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -801,7 +801,7 @@ static void bnxt_get_channels(struct net_device *dev, struct bnxt *bp = netdev_priv(dev); struct bnxt_hw_resc *hw_resc = &bp->hw_resc; int max_rx_rings, max_tx_rings, tcs; - int max_tx_sch_inputs; + int max_tx_sch_inputs, tx_grps; /* Get the most up-to-date max_tx_sch_inputs. */ if (netif_running(dev) && BNXT_NEW_RM(bp)) @@ -811,6 +811,12 @@ static void bnxt_get_channels(struct net_device *dev, bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, true); if (max_tx_sch_inputs) max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs); + + tcs = netdev_get_num_tc(dev); + tx_grps = max(tcs, 1); + if (bp->tx_nr_rings_xdp) + tx_grps++; + max_tx_rings /= tx_grps; channel->max_combined = min_t(int, max_rx_rings, max_tx_rings); if (bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, false)) { @@ -820,7 +826,6 @@ static void bnxt_get_channels(struct net_device *dev, if (max_tx_sch_inputs) max_tx_rings = min_t(int, max_tx_rings, max_tx_sch_inputs); - tcs = netdev_get_num_tc(dev); if (tcs > 1) max_tx_rings /= tcs;