From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 80463437A1; Wed, 27 Dec 2023 05:23:30 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 459D640E72; Wed, 27 Dec 2023 05:21:52 +0100 (CET) Received: from mail-qt1-f172.google.com (mail-qt1-f172.google.com [209.85.160.172]) by mails.dpdk.org (Postfix) with ESMTP id 63DEE40A4B for ; Wed, 27 Dec 2023 05:21:47 +0100 (CET) Received: by mail-qt1-f172.google.com with SMTP id d75a77b69052e-427941528d8so42552621cf.2 for ; Tue, 26 Dec 2023 20:21:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; t=1703650906; x=1704255706; darn=dpdk.org; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:from:to:cc:subject:date:message-id:reply-to; bh=Bplko7hCQu3X7lGDkPA6LKynR4D7jJPIDeMo+U1DtzI=; b=J2E/t3H/B2Bj7KvYpdfrFAbz5emR+cFhYsQmbr5qxi6mfPKezKdVMfP0u8U7o6Bgb2 Sn1qZXD5FZln6NRl7uL6nZw7gUX8q0VhqRIEjhHP5wNb+mWkJQLDYxMKj59krTZocQ2Q tn/+rn0i3MhS3bJ2M/ET1fOlBlGz76lbiMTeA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703650906; x=1704255706; h=mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=Bplko7hCQu3X7lGDkPA6LKynR4D7jJPIDeMo+U1DtzI=; b=lAj7Shbwwc2+ym9nAowLqO1ozYZgBPI7PjcgrUyzJ7ZNCe8XurkKRkCPdraBASpeb1 gQBiGgmwm5NgsfdvoBq45LMQjYW/nVrDhIjM8yuHL1nOiZcZMY80rfxEiNodKaSN7Omc ZjdYAvLbuwXa8jZ0QjAW6dm0yuKWU+hm7f7ALGmyB2VzQ30UwKjdjevxcNMH2lBbroxn EoV/B+r+oS2aZfTAHhjKS/bCHsFNK90vE980N9Wr7RYBaEUsdH9pZWQG6ASF7VQzdUM9 321fey1daIw38VH+c20go2Mxz30c02WteQpY1ooqCCfz4gSi9OkiU2xCw07QQsb9meMt /CXQ== X-Gm-Message-State: AOJu0YzZHMSEIgOvm1qrktGdZMDTKCSKhlndk2Lmh3pyUBdv0G5AXhpN uDy8ejJgLbkpmvJcRAJd1FtnM/WfekGZ37iGqlCl5OQEv0N1MZ8fDSFBrHDKHX37bbo7RdSkFM9 yvJiCDooVg1+DpgKWwu9ZDc4R8VB9AQ44/henVOp06MMy1MhB2j/CoHYqZRV2QiE6p81zMSOTFV E= X-Google-Smtp-Source: AGHT+IGmJ3K5Ptao0N7LO8jUEykGePOFj6Pidb3NT55GeJmN8YWV3x/981Wqq4IrfxeenkqB7fQC4g== X-Received: by 2002:a05:622a:34d:b0:427:8ff9:39af with SMTP id r13-20020a05622a034d00b004278ff939afmr13177316qtw.121.1703650905848; Tue, 26 Dec 2023 20:21:45 -0800 (PST) Received: from localhost.localdomain ([2605:a601:a780:1400:c066:75e3:74c8:50e6]) by smtp.gmail.com with ESMTPSA id bt7-20020ac86907000000b00427e120889bsm1415488qtb.91.2023.12.26.20.21.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Dec 2023 20:21:45 -0800 (PST) From: Ajit Khaparde To: dev@dpdk.org Cc: Damodharam Ammepalli Subject: [PATCH v3 15/18] net/bnxt: add 400G get support for P7 devices Date: Tue, 26 Dec 2023 20:21:16 -0800 Message-Id: <20231227042119.72469-16-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.39.2 (Apple Git-143) In-Reply-To: <20231227042119.72469-1-ajit.khaparde@broadcom.com> References: <20231227042119.72469-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="00000000000018c7c3060d7623d6" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --00000000000018c7c3060d7623d6 Content-Transfer-Encoding: 8bit From: Damodharam Ammepalli P7 devices report speeds over speeds2 hsi fields. Adding required support to capture the capability from phy_qcap and save the speeds2 fields into driver priv structure. In fixed mode update the link_speed from force_link_speeds2 field. Updates to logging to provide more info regarding numbers of lanes and the link signal mode. Some code refactoring done for PHY auto detect and displaying XCVR information. Signed-off-by: Damodharam Ammepalli Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 15 + drivers/net/bnxt/bnxt_ethdev.c | 57 ++- drivers/net/bnxt/bnxt_hwrm.c | 493 ++++++++++++++++++++++++- drivers/net/bnxt/bnxt_hwrm.h | 1 + drivers/net/bnxt/hsi_struct_def_dpdk.h | 10 +- 5 files changed, 568 insertions(+), 8 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 2357e9f747..858689533b 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -318,6 +318,16 @@ struct bnxt_link_info { uint16_t support_pam4_auto_speeds; uint8_t req_signal_mode; uint8_t module_status; + /* P7 speeds2 fields */ + bool support_speeds_v2; + uint16_t supported_speeds2_force_mode; + uint16_t supported_speeds2_auto_mode; + uint16_t support_speeds2; + uint16_t force_link_speeds2; + uint16_t auto_link_speeds2; + uint16_t cfg_auto_link_speeds2_mask; + uint8_t active_lanes; + uint8_t option_flags; }; #define BNXT_COS_QUEUE_COUNT 8 @@ -1156,6 +1166,11 @@ extern int bnxt_logtype_driver; #define PMD_DRV_LOG(level, fmt, args...) \ PMD_DRV_LOG_RAW(level, fmt, ## args) +#define BNXT_LINK_SPEEDS_V2_OPTIONS(f) \ + ((f) & HWRM_PORT_PHY_QCFG_OUTPUT_OPTION_FLAGS_SPEEDS2_SUPPORTED) +#define BNXT_LINK_SPEEDS_V2_VF(bp) (BNXT_VF((bp)) && ((bp)->link_info->option_flags)) +#define BNXT_LINK_SPEEDS_V2(bp) (((bp)->link_info) && (((bp)->link_info->support_speeds_v2) || \ + BNXT_LINK_SPEEDS_V2_VF((bp)))) extern const struct rte_flow_ops bnxt_ulp_rte_flow_ops; int32_t bnxt_ulp_port_init(struct bnxt *bp); void bnxt_ulp_port_deinit(struct bnxt *bp); diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 7aed6d3ab6..625e5f1f9a 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -697,7 +697,10 @@ static inline bool bnxt_force_link_config(struct bnxt *bp) static int bnxt_update_phy_setting(struct bnxt *bp) { + struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; + struct rte_eth_link *link = &bp->eth_dev->data->dev_link; struct rte_eth_link new; + uint32_t curr_speed_bit; int rc; rc = bnxt_get_hwrm_link_config(bp, &new); @@ -706,13 +709,17 @@ static int bnxt_update_phy_setting(struct bnxt *bp) return rc; } + /* convert to speedbit flag */ + curr_speed_bit = rte_eth_speed_bitflag((uint32_t)link->link_speed, 1); + /* * Device is not obliged link down in certain scenarios, even * when forced. When FW does not allow any user other than BMC * to shutdown the port, bnxt_get_hwrm_link_config() call always * returns link up. Force phy update always in that case. */ - if (!new.link_status || bnxt_force_link_config(bp)) { + if (!new.link_status || bnxt_force_link_config(bp) || + (BNXT_LINK_SPEEDS_V2(bp) && dev_conf->link_speeds != curr_speed_bit)) { rc = bnxt_set_hwrm_link_config(bp, true); if (rc) { PMD_DRV_LOG(ERR, "Failed to update PHY settings\n"); @@ -933,6 +940,50 @@ static int bnxt_shutdown_nic(struct bnxt *bp) * Device configuration and status function */ +static uint32_t bnxt_get_speed_capabilities_v2(struct bnxt *bp) +{ + uint32_t link_speed = 0; + uint32_t speed_capa = 0; + + if (bp->link_info == NULL) + return 0; + + link_speed = bp->link_info->support_speeds2; + + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_1GB) + speed_capa |= RTE_ETH_LINK_SPEED_1G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_10GB) + speed_capa |= RTE_ETH_LINK_SPEED_10G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_25GB) + speed_capa |= RTE_ETH_LINK_SPEED_25G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_40GB) + speed_capa |= RTE_ETH_LINK_SPEED_40G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB) + speed_capa |= RTE_ETH_LINK_SPEED_50G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB) + speed_capa |= RTE_ETH_LINK_SPEED_100G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB_PAM4_56) + speed_capa |= RTE_ETH_LINK_SPEED_50G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_56) + speed_capa |= RTE_ETH_LINK_SPEED_100G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_56) + speed_capa |= RTE_ETH_LINK_SPEED_200G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_56) + speed_capa |= RTE_ETH_LINK_SPEED_400G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_112) + speed_capa |= RTE_ETH_LINK_SPEED_100G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_112) + speed_capa |= RTE_ETH_LINK_SPEED_200G; + if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_112) + speed_capa |= RTE_ETH_LINK_SPEED_400G; + + if (bp->link_info->auto_mode == + HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE) + speed_capa |= RTE_ETH_LINK_SPEED_FIXED; + + return speed_capa; +} + uint32_t bnxt_get_speed_capabilities(struct bnxt *bp) { uint32_t pam4_link_speed = 0; @@ -942,6 +993,10 @@ uint32_t bnxt_get_speed_capabilities(struct bnxt *bp) if (bp->link_info == NULL) return 0; + /* P7 uses speeds_v2 */ + if (BNXT_LINK_SPEEDS_V2(bp)) + return bnxt_get_speed_capabilities_v2(bp); + link_speed = bp->link_info->support_speeds; /* If PAM4 is configured, use PAM4 supported speed */ diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index f896a41653..4f202361ea 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -68,6 +68,282 @@ const char *bnxt_backing_store_types[] = { "Invalid type" }; +const char *media_type[] = { "Unknown", "Twisted Pair", + "Direct Attached Copper", "Fiber" +}; + +#define MAX_MEDIA_TYPE (sizeof(media_type) / sizeof(const char *)) + +const char *link_status_str[] = { "Down. No link or cable detected.", + "Down. No link, but a cable has been detected.", "Up.", +}; + +#define MAX_LINK_STR (sizeof(link_status_str) / sizeof(const char *)) + +const char *fec_mode[] = { + "No active FEC", + "FEC CLAUSE 74 (Fire Code).", + "FEC CLAUSE 91 RS(528,514).", + "FEC RS544_1XN", + "FEC RS(544,528)", + "FEC RS272_1XN", + "FEC RS(272,257)" +}; + +#define MAX_FEC_MODE (sizeof(fec_mode) / sizeof(const char *)) + +const char *signal_mode[] = { + "NRZ", "PAM4", "PAM4_112" +}; + +#define MAX_SIG_MODE (sizeof(signal_mode) / sizeof(const char *)) + +/* multi-purpose multi-key table container. + * Add a unique entry for a new PHY attribs as per HW CAS. + * Query it using a helper functions. + */ +struct link_speeds2_tbl { + uint16_t force_val; + uint16_t auto_val; + uint32_t rte_speed; + uint32_t rte_speed_num; + uint16_t hwrm_speed; + uint16_t sig_mode; + const char *desc; +} link_speeds2_tbl[] = { + { + 10, + 0, + RTE_ETH_LINK_SPEED_1G, + RTE_ETH_SPEED_NUM_1G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_1GB, + BNXT_SIG_MODE_NRZ, + "1Gb NRZ", + }, { + 100, + 1, + RTE_ETH_LINK_SPEED_10G, + RTE_ETH_SPEED_NUM_10G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_10GB, + BNXT_SIG_MODE_NRZ, + "10Gb NRZ", + }, { + 250, + 2, + RTE_ETH_LINK_SPEED_25G, + RTE_ETH_SPEED_NUM_25G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_25GB, + BNXT_SIG_MODE_NRZ, + "25Gb NRZ", + }, { + 400, + 3, + RTE_ETH_LINK_SPEED_40G, + RTE_ETH_SPEED_NUM_40G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_40GB, + BNXT_SIG_MODE_NRZ, + "40Gb NRZ", + }, { + 500, + 4, + RTE_ETH_LINK_SPEED_50G, + RTE_ETH_SPEED_NUM_50G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_50GB, + BNXT_SIG_MODE_NRZ, + "50Gb NRZ", + }, { + 1000, + 5, + RTE_ETH_LINK_SPEED_100G, + RTE_ETH_SPEED_NUM_100G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB, + BNXT_SIG_MODE_NRZ, + "100Gb NRZ", + }, { + 501, + 6, + RTE_ETH_LINK_SPEED_50G, + RTE_ETH_SPEED_NUM_50G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_50GB_PAM4_56, + BNXT_SIG_MODE_PAM4, + "50Gb (PAM4-56: 50G per lane)", + }, { + 1001, + 7, + RTE_ETH_LINK_SPEED_100G, + RTE_ETH_SPEED_NUM_100G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB_PAM4_56, + BNXT_SIG_MODE_PAM4, + "100Gb (PAM4-56: 50G per lane)", + }, { + 2001, + 8, + RTE_ETH_LINK_SPEED_200G, + RTE_ETH_SPEED_NUM_200G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_200GB_PAM4_56, + BNXT_SIG_MODE_PAM4, + "200Gb (PAM4-56: 50G per lane)", + }, { + 4001, + 9, + RTE_ETH_LINK_SPEED_400G, + RTE_ETH_SPEED_NUM_400G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_400GB_PAM4_56, + BNXT_SIG_MODE_PAM4, + "400Gb (PAM4-56: 50G per lane)", + }, { + 1002, + 10, + RTE_ETH_LINK_SPEED_100G, + RTE_ETH_SPEED_NUM_100G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB_PAM4_112, + BNXT_SIG_MODE_PAM4_112, + "100Gb (PAM4-112: 100G per lane)", + }, { + 2002, + 11, + RTE_ETH_LINK_SPEED_200G, + RTE_ETH_SPEED_NUM_200G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_200GB_PAM4_112, + BNXT_SIG_MODE_PAM4_112, + "200Gb (PAM4-112: 100G per lane)", + }, { + 4002, + 12, + RTE_ETH_LINK_SPEED_400G, + RTE_ETH_SPEED_NUM_400G, + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_400GB_PAM4_112, + BNXT_SIG_MODE_PAM4_112, + "400Gb (PAM4-112: 100G per lane)", + }, { + 0, + 13, + RTE_ETH_LINK_SPEED_AUTONEG, /* None matches, AN is default 0 */ + RTE_ETH_SPEED_NUM_NONE, /* None matches, No speed */ + HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_1GB, /* Placeholder for wrong HWRM */ + BNXT_SIG_MODE_NRZ, /* default sig */ + "Unknown", + }, +}; + +#define BNXT_SPEEDS2_TBL_SZ (sizeof(link_speeds2_tbl) / sizeof(*link_speeds2_tbl)) + +/* In hwrm_phy_qcfg reports trained up speeds in link_speed(offset:0x8[31:16]) */ +struct link_speeds_tbl { + uint16_t hwrm_speed; + uint32_t rte_speed_num; + const char *desc; +} link_speeds_tbl[] = { + { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB, + RTE_ETH_SPEED_NUM_100M, "100 MB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB, + RTE_ETH_SPEED_NUM_1G, "1 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB, + RTE_ETH_SPEED_NUM_2_5G, "25 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB, + RTE_ETH_SPEED_NUM_10G, "10 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB, + RTE_ETH_SPEED_NUM_20G, "20 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB, + RTE_ETH_SPEED_NUM_40G, "40 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB, + RTE_ETH_SPEED_NUM_50G, "50 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB, + RTE_ETH_SPEED_NUM_100G, "100 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_200GB, + RTE_ETH_SPEED_NUM_200G, "200 GB", + }, { + HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_400GB, + RTE_ETH_SPEED_NUM_400G, "400 GB", + }, { + 0, RTE_ETH_SPEED_NUM_NONE, "None", + }, +}; + +#define BNXT_SPEEDS_TBL_SZ (sizeof(link_speeds_tbl) / sizeof(*link_speeds_tbl)) + +static const char *bnxt_get_xcvr_type(uint32_t xcvr_identifier_type_tx_lpi_timer) +{ + uint32_t xcvr_type = HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_MASK & + xcvr_identifier_type_tx_lpi_timer; + + /* Addressing only known CMIS types */ + switch (xcvr_type) { + case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFP: + return "SFP"; + case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP: + return "QSFP"; + case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPPLUS: + return "QSFP+"; + case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28: + return "QSFP28"; + case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPDD: + return "QSFP112"; + case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP112: + return "QSFP-DD"; + case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_UNKNOWN: + return "Unknown"; + default: + /* All other/new CMIS variants belong here */ + return "QSFP-xx new CMIS variant"; + } +} + +/* Utility function to lookup speeds2 table and + * return a rte to hwrm speed matching row to the client + */ +static +struct link_speeds2_tbl *bnxt_get_rte_hwrm_speeds2_entry(uint32_t speed) +{ + int i, max; + + max = BNXT_SPEEDS2_TBL_SZ - 1; + speed &= ~RTE_ETH_LINK_SPEED_FIXED; + for (i = 0; i < max; i++) { + if (speed == link_speeds2_tbl[i].rte_speed) + break; + } + return (struct link_speeds2_tbl *)&link_speeds2_tbl[i]; +} + +/* Utility function to lookup speeds2 table and + * return a hwrm to rte speed matching row to the client + */ +static struct link_speeds2_tbl *bnxt_get_hwrm_to_rte_speeds2_entry(uint16_t speed) +{ + int i, max; + + max = BNXT_SPEEDS2_TBL_SZ - 1; + for (i = 0; i < max; i++) { + if (speed == link_speeds2_tbl[i].hwrm_speed) + break; + } + return (struct link_speeds2_tbl *)&link_speeds2_tbl[i]; +} + +/* Helper function to lookup auto link_speed table */ +static struct link_speeds_tbl *bnxt_get_hwrm_to_rte_speeds_entry(uint16_t speed) +{ + int i, max; + + max = BNXT_SPEEDS_TBL_SZ - 1; + + for (i = 0; i < max ; i++) { + if (speed == link_speeds_tbl[i].hwrm_speed) + break; + } + return (struct link_speeds_tbl *)&link_speeds_tbl[i]; +} + static int page_getenum(size_t size) { if (size <= 1 << 4) @@ -1564,15 +1840,64 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp, link_info->phy_ver[2] = resp->phy_bld; link_info->link_signal_mode = resp->active_fec_signal_mode & HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_MASK; + link_info->option_flags = resp->option_flags; link_info->force_pam4_link_speed = rte_le_to_cpu_16(resp->force_pam4_link_speed); link_info->support_pam4_speeds = rte_le_to_cpu_16(resp->support_pam4_speeds); link_info->auto_pam4_link_speed_mask = rte_le_to_cpu_16(resp->auto_pam4_link_speed_mask); + /* P7 uses speeds2 fields */ + if (BNXT_LINK_SPEEDS_V2(bp) && BNXT_LINK_SPEEDS_V2_OPTIONS(link_info->option_flags)) { + link_info->support_speeds2 = rte_le_to_cpu_16(resp->support_speeds2); + link_info->force_link_speeds2 = rte_le_to_cpu_16(resp->force_link_speeds2); + link_info->auto_link_speeds2 = rte_le_to_cpu_16(resp->auto_link_speeds2); + link_info->active_lanes = resp->active_lanes; + if (!link_info->auto_mode) + link_info->link_speed = link_info->force_link_speeds2; + } link_info->module_status = resp->module_status; HWRM_UNLOCK(); + /* Display the captured P7 phy details */ + if (BNXT_LINK_SPEEDS_V2(bp)) { + PMD_DRV_LOG(DEBUG, "Phytype:%d, Media_type:%d, Status: %d, Link Signal:%d\n" + "Active Fec: %d Support_speeds2:%x, Force_link_speedsv2:%x\n" + "Auto_link_speedsv2:%x, Active_lanes:%d\n", + link_info->phy_type, + link_info->media_type, + link_info->phy_link_status, + link_info->link_signal_mode, + (resp->active_fec_signal_mode & + HWRM_PORT_PHY_QCFG_OUTPUT_ACTIVE_FEC_MASK) >> 4, + link_info->support_speeds2, link_info->force_link_speeds2, + link_info->auto_link_speeds2, + link_info->active_lanes); + + const char *desc; + + if (link_info->auto_mode) + desc = ((struct link_speeds_tbl *) + bnxt_get_hwrm_to_rte_speeds_entry(link_info->link_speed))->desc; + else + desc = ((struct link_speeds2_tbl *) + bnxt_get_hwrm_to_rte_speeds2_entry(link_info->link_speed))->desc; + + PMD_DRV_LOG(INFO, "Link Speed: %s %s, Status: %s Signal-mode: %s\n" + "Media type: %s, Xcvr type: %s, Active FEC: %s Lanes: %d\n", + desc, + !(link_info->auto_mode) ? "Forced" : "AutoNegotiated", + link_status_str[link_info->phy_link_status % MAX_LINK_STR], + signal_mode[link_info->link_signal_mode % MAX_SIG_MODE], + media_type[link_info->media_type % MAX_MEDIA_TYPE], + bnxt_get_xcvr_type(rte_le_to_cpu_32 + (resp->xcvr_identifier_type_tx_lpi_timer)), + fec_mode[((resp->active_fec_signal_mode & + HWRM_PORT_PHY_QCFG_OUTPUT_ACTIVE_FEC_MASK) >> 4) % + MAX_FEC_MODE], link_info->active_lanes); + return rc; + } + PMD_DRV_LOG(DEBUG, "Link Speed:%d,Auto:%d:%x:%x,Support:%x,Force:%x\n", link_info->link_speed, link_info->auto_mode, link_info->auto_link_speed, link_info->auto_link_speed_mask, @@ -1608,6 +1933,15 @@ int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp) if (resp->supported_pam4_speeds_auto_mode) link_info->support_pam4_auto_speeds = rte_le_to_cpu_16(resp->supported_pam4_speeds_auto_mode); + /* P7 chips now report all speeds here */ + if (resp->flags2 & HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS2_SPEEDS2_SUPPORTED) + link_info->support_speeds_v2 = true; + if (link_info->support_speeds_v2) { + link_info->supported_speeds2_force_mode = + rte_le_to_cpu_16(resp->supported_speeds2_force_mode); + link_info->supported_speeds2_auto_mode = + rte_le_to_cpu_16(resp->supported_speeds2_auto_mode); + } HWRM_UNLOCK(); @@ -3268,7 +3602,14 @@ static uint16_t bnxt_check_eth_link_autoneg(uint32_t conf_link) return !conf_link; } -static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed, +static uint16_t bnxt_parse_eth_link_speed_v2(uint32_t conf_link_speed) +{ + /* get bitmap value based on speed */ + return ((struct link_speeds2_tbl *) + bnxt_get_rte_hwrm_speeds2_entry(conf_link_speed))->force_val; +} + +static uint16_t bnxt_parse_eth_link_speed(struct bnxt *bp, uint32_t conf_link_speed, struct bnxt_link_info *link_info) { uint16_t support_pam4_speeds = link_info->support_pam4_speeds; @@ -3278,6 +3619,10 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed, if (conf_link_speed == RTE_ETH_LINK_SPEED_AUTONEG) return RTE_ETH_LINK_SPEED_AUTONEG; + /* Handle P7 chips saperately. It got enhanced phy attribs to choose from */ + if (BNXT_LINK_SPEEDS_V2(bp)) + return bnxt_parse_eth_link_speed_v2(conf_link_speed); + switch (conf_link_speed & ~RTE_ETH_LINK_SPEED_FIXED) { case RTE_ETH_LINK_SPEED_100M: case RTE_ETH_LINK_SPEED_100M_HD: @@ -3349,6 +3694,9 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed, RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_20G | RTE_ETH_LINK_SPEED_25G | \ RTE_ETH_LINK_SPEED_40G | RTE_ETH_LINK_SPEED_50G | \ RTE_ETH_LINK_SPEED_100G | RTE_ETH_LINK_SPEED_200G) +#define BNXT_SUPPORTED_SPEEDS2 ((BNXT_SUPPORTED_SPEEDS | RTE_ETH_LINK_SPEED_400G) & \ + ~(RTE_ETH_LINK_SPEED_100M | RTE_ETH_LINK_SPEED_100M_HD | \ + RTE_ETH_LINK_SPEED_2_5G | RTE_ETH_LINK_SPEED_20G)) static int bnxt_validate_link_speed(struct bnxt *bp) { @@ -3388,11 +3736,25 @@ static int bnxt_validate_link_speed(struct bnxt *bp) return 0; } +static uint16_t +bnxt_parse_eth_link_speed_mask_v2(struct bnxt *bp, uint32_t link_speed) +{ + uint16_t ret = 0; + + if (link_speed == RTE_ETH_LINK_SPEED_AUTONEG) + return bp->link_info->supported_speeds2_auto_mode; + + return ret; +} + static uint16_t bnxt_parse_eth_link_speed_mask(struct bnxt *bp, uint32_t link_speed) { uint16_t ret = 0; + if (BNXT_LINK_SPEEDS_V2(bp)) + return bnxt_parse_eth_link_speed_mask_v2(bp, link_speed); + if (link_speed == RTE_ETH_LINK_SPEED_AUTONEG) { if (bp->link_info->support_speeds) return bp->link_info->support_speeds; @@ -3424,10 +3786,21 @@ bnxt_parse_eth_link_speed_mask(struct bnxt *bp, uint32_t link_speed) return ret; } -static uint32_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed) +static uint32_t bnxt_parse_hw_link_speed_v2(uint16_t hw_link_speed) +{ + return ((struct link_speeds2_tbl *) + bnxt_get_hwrm_to_rte_speeds2_entry(hw_link_speed))->rte_speed_num; +} + +static uint32_t bnxt_parse_hw_link_speed(struct bnxt *bp, uint16_t hw_link_speed) { uint32_t eth_link_speed = RTE_ETH_SPEED_NUM_NONE; + /* query fixed speed2 table if not autoneg */ + if (BNXT_LINK_SPEEDS_V2(bp) && !bp->link_info->auto_mode) + return bnxt_parse_hw_link_speed_v2(hw_link_speed); + + /* for P7 and earlier nics link_speed carries AN'd speed */ switch (hw_link_speed) { case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB: eth_link_speed = RTE_ETH_SPEED_NUM_100M; @@ -3459,6 +3832,9 @@ static uint32_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed) case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_200GB: eth_link_speed = RTE_ETH_SPEED_NUM_200G; break; + case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_400GB: + eth_link_speed = RTE_ETH_SPEED_NUM_400G; + break; case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB: default: PMD_DRV_LOG(ERR, "HWRM link speed %d not defined\n", @@ -3505,8 +3881,7 @@ int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link) } if (link_info->link_speed) - link->link_speed = - bnxt_parse_hw_link_speed(link_info->link_speed); + link->link_speed = bnxt_parse_hw_link_speed(bp, link_info->link_speed); else link->link_speed = RTE_ETH_SPEED_NUM_NONE; link->link_duplex = bnxt_parse_hw_link_duplex(link_info->duplex); @@ -3518,6 +3893,111 @@ int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link) return rc; } +static int bnxt_hwrm_port_phy_cfg_v2(struct bnxt *bp, struct bnxt_link_info *conf) +{ + struct hwrm_port_phy_cfg_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_port_phy_cfg_input req = {0}; + uint32_t enables = 0; + int rc = 0; + + HWRM_PREP(&req, HWRM_PORT_PHY_CFG, BNXT_USE_CHIMP_MB); + + if (!conf->link_up) { + req.flags = + rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN); + PMD_DRV_LOG(ERR, "Force Link Down\n"); + goto link_down; + } + + /* Setting Fixed Speed. But AutoNeg is ON, So disable it */ + if (bp->link_info->auto_mode && conf->link_speed) { + req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE; + PMD_DRV_LOG(DEBUG, "Disabling AutoNeg\n"); + } + req.flags = rte_cpu_to_le_32(conf->phy_flags); + if (!conf->link_speed) { + /* No speeds specified. Enable AutoNeg - all speeds */ + enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEEDS2_MASK; + enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE; + req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK; + req.auto_link_speeds2_mask = + rte_cpu_to_le_16(bp->link_info->supported_speeds2_auto_mode); + } else { + enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_LINK_SPEEDS2; + req.force_link_speeds2 = rte_cpu_to_le_16(conf->link_speed); + } + + /* Fill rest of the req message */ + req.auto_duplex = conf->duplex; + if (req.auto_mode != HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK) + enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX; + req.auto_pause = conf->auto_pause; + req.force_pause = conf->force_pause; + if (req.auto_pause) + req.force_pause = 0; + /* Set force_pause if there is no auto or if there is a force */ + if (req.auto_pause && !req.force_pause) + enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE; + else + enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE; + req.enables = rte_cpu_to_le_32(enables); + +link_down: + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + + HWRM_CHECK_RESULT(); + HWRM_UNLOCK(); + return rc; +} + +static int bnxt_set_hwrm_link_config_v2(struct bnxt *bp, bool link_up) +{ + struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf; + struct bnxt_link_info link_req; + uint16_t speed, autoneg; + int rc = 0; + + memset(&link_req, 0, sizeof(link_req)); + link_req.link_up = link_up; + if (!link_up) + goto port_phy_cfg; + + autoneg = bnxt_check_eth_link_autoneg(dev_conf->link_speeds); + speed = bnxt_parse_eth_link_speed(bp, dev_conf->link_speeds, + bp->link_info); + link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY; + if (autoneg == 1) { + link_req.phy_flags |= + HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG; + link_req.cfg_auto_link_speeds2_mask = + bnxt_parse_eth_link_speed_mask(bp, dev_conf->link_speeds); + } else { + if (bp->link_info->phy_type == + HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET || + bp->link_info->phy_type == + HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE || + bp->link_info->media_type == + HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP) { + PMD_DRV_LOG(ERR, "10GBase-T devices must autoneg\n"); + return -EINVAL; + } + + link_req.phy_flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE; + /* If user wants a particular speed try that first. */ + link_req.link_speed = speed; + } + link_req.duplex = bnxt_parse_eth_link_duplex(dev_conf->link_speeds); + link_req.auto_pause = bp->link_info->auto_pause; + link_req.force_pause = bp->link_info->force_pause; + +port_phy_cfg: + rc = bnxt_hwrm_port_phy_cfg_v2(bp, &link_req); + if (rc) + PMD_DRV_LOG(ERR, "Set link config failed with rc %d\n", rc); + + return rc; +} + int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) { int rc = 0; @@ -3532,6 +4012,9 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) if (rc) goto error; + if (BNXT_LINK_SPEEDS_V2(bp)) + return bnxt_set_hwrm_link_config_v2(bp, link_up); + memset(&link_req, 0, sizeof(link_req)); link_req.link_up = link_up; if (!link_up) @@ -3557,7 +4040,7 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) PMD_DRV_LOG(DEBUG, "Disabling autoneg for 200G\n"); } - speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds, + speed = bnxt_parse_eth_link_speed(bp, dev_conf->link_speeds, bp->link_info); link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY; /* Autoneg can be done only when the FW allows. */ diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index 6116253787..179d5dc1f0 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -145,6 +145,7 @@ struct bnxt_pf_resource_info { #define BNXT_SIG_MODE_NRZ HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_NRZ #define BNXT_SIG_MODE_PAM4 HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4 +#define BNXT_SIG_MODE_PAM4_112 HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4_112 #define BNXT_TUNNELED_OFFLOADS_CAP_VXLAN_EN(bp) \ (!((bp)->tunnel_disable_flag & HWRM_FUNC_QCAPS_OUTPUT_TUNNEL_DISABLE_FLAG_DISABLE_VXLAN)) diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h index 65f3f0576b..b012a84d36 100644 --- a/drivers/net/bnxt/hsi_struct_def_dpdk.h +++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h @@ -27273,11 +27273,17 @@ struct hwrm_port_phy_qcfg_output { /* QSFP+ */ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPPLUS \ (UINT32_C(0xd) << 24) - /* QSFP28 */ + /* QSFP28/QSFP56 or later */ #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28 \ (UINT32_C(0x11) << 24) + /* QSFP-DD */ + #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPDD \ + (UINT32_C(0x18) << 24) + /* QSFP112 */ + #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP112 \ + (UINT32_C(0x1e) << 24) #define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_LAST \ - HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28 + HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP112 /* * This value represents the current configuration of * Forward Error Correction (FEC) on the port. -- 2.39.2 (Apple Git-143) --00000000000018c7c3060d7623d6 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIIQdgYJKoZIhvcNAQcCoIIQZzCCEGMCAQExDzANBglghkgBZQMEAgEFADALBgkqhkiG9w0BBwGg gg3NMIIFDTCCA/WgAwIBAgIQeEqpED+lv77edQixNJMdADANBgkqhkiG9w0BAQsFADBMMSAwHgYD VQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UE AxMKR2xvYmFsU2lnbjAeFw0yMDA5MTYwMDAwMDBaFw0yODA5MTYwMDAwMDBaMFsxCzAJBgNVBAYT AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWduIEdDQyBS MyBQZXJzb25hbFNpZ24gMiBDQSAyMDIwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA vbCmXCcsbZ/a0fRIQMBxp4gJnnyeneFYpEtNydrZZ+GeKSMdHiDgXD1UnRSIudKo+moQ6YlCOu4t rVWO/EiXfYnK7zeop26ry1RpKtogB7/O115zultAz64ydQYLe+a1e/czkALg3sgTcOOcFZTXk38e aqsXsipoX1vsNurqPtnC27TWsA7pk4uKXscFjkeUE8JZu9BDKaswZygxBOPBQBwrA5+20Wxlk6k1 e6EKaaNaNZUy30q3ArEf30ZDpXyfCtiXnupjSK8WU2cK4qsEtj09JS4+mhi0CTCrCnXAzum3tgcH cHRg0prcSzzEUDQWoFxyuqwiwhHu3sPQNmFOMwIDAQABo4IB2jCCAdYwDgYDVR0PAQH/BAQDAgGG MGAGA1UdJQRZMFcGCCsGAQUFBwMCBggrBgEFBQcDBAYKKwYBBAGCNxQCAgYKKwYBBAGCNwoDBAYJ KwYBBAGCNxUGBgorBgEEAYI3CgMMBggrBgEFBQcDBwYIKwYBBQUHAxEwEgYDVR0TAQH/BAgwBgEB /wIBADAdBgNVHQ4EFgQUljPR5lgXWzR1ioFWZNW+SN6hj88wHwYDVR0jBBgwFoAUj/BLf6guRSSu TVD6Y5qL3uLdG7wwegYIKwYBBQUHAQEEbjBsMC0GCCsGAQUFBzABhiFodHRwOi8vb2NzcC5nbG9i YWxzaWduLmNvbS9yb290cjMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5j b20vY2FjZXJ0L3Jvb3QtcjMuY3J0MDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwuZ2xvYmFs c2lnbi5jb20vcm9vdC1yMy5jcmwwWgYDVR0gBFMwUTALBgkrBgEEAaAyASgwQgYKKwYBBAGgMgEo CjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAN BgkqhkiG9w0BAQsFAAOCAQEAdAXk/XCnDeAOd9nNEUvWPxblOQ/5o/q6OIeTYvoEvUUi2qHUOtbf jBGdTptFsXXe4RgjVF9b6DuizgYfy+cILmvi5hfk3Iq8MAZsgtW+A/otQsJvK2wRatLE61RbzkX8 9/OXEZ1zT7t/q2RiJqzpvV8NChxIj+P7WTtepPm9AIj0Keue+gS2qvzAZAY34ZZeRHgA7g5O4TPJ /oTd+4rgiU++wLDlcZYd/slFkaT3xg4qWDepEMjT4T1qFOQIL+ijUArYS4owpPg9NISTKa1qqKWJ jFoyms0d0GwOniIIbBvhI2MJ7BSY9MYtWVT5jJO3tsVHwj4cp92CSFuGwunFMzCCA18wggJHoAMC AQICCwQAAAAAASFYUwiiMA0GCSqGSIb3DQEBCwUAMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9v dCBDQSAtIFIzMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTA5 MDMxODEwMDAwMFoXDTI5MDMxODEwMDAwMFowTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENB IC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMJXaQeQZ4Ihb1wIO2hMoonv0FdhHFrYhy/EYCQ8eyip0E XyTLLkvhYIJG4VKrDIFHcGzdZNHr9SyjD4I9DCuul9e2FIYQebs7E4B3jAjhSdJqYi8fXvqWaN+J J5U4nwbXPsnLJlkNc96wyOkmDoMVxu9bi9IEYMpJpij2aTv2y8gokeWdimFXN6x0FNx04Druci8u nPvQu7/1PQDhBjPogiuuU6Y6FnOM3UEOIDrAtKeh6bJPkC4yYOlXy7kEkmho5TgmYHWyn3f/kRTv riBJ/K1AFUjRAjFhGV64l++td7dkmnq/X8ET75ti+w1s4FRpFqkD2m7pg5NxdsZphYIXAgMBAAGj QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSP8Et/qC5FJK5N UPpjmove4t0bvDANBgkqhkiG9w0BAQsFAAOCAQEAS0DbwFCq/sgM7/eWVEVJu5YACUGssxOGhigH M8pr5nS5ugAtrqQK0/Xx8Q+Kv3NnSoPHRHt44K9ubG8DKY4zOUXDjuS5V2yq/BKW7FPGLeQkbLmU Y/vcU2hnVj6DuM81IcPJaP7O2sJTqsyQiunwXUaMld16WCgaLx3ezQA3QY/tRG3XUyiXfvNnBB4V 14qWtNPeTCekTBtzc3b0F5nCH3oO4y0IrQocLP88q1UOD5F+NuvDV0m+4S4tfGCLw0FREyOdzvcy a5QBqJnnLDMfOjsl0oZAzjsshnjJYS8Uuu7bVW/fhO4FCU29KNhyztNiUGUe65KXgzHZs7XKR1g/ XzCCBVUwggQ9oAMCAQICDAzZWuPidkrRZaiw2zANBgkqhkiG9w0BAQsFADBbMQswCQYDVQQGEwJC RTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTExMC8GA1UEAxMoR2xvYmFsU2lnbiBHQ0MgUjMg UGVyc29uYWxTaWduIDIgQ0EgMjAyMDAeFw0yMjA5MTAwODE4NDVaFw0yNTA5MTAwODE4NDVaMIGW MQswCQYDVQQGEwJJTjESMBAGA1UECBMJS2FybmF0YWthMRIwEAYDVQQHEwlCYW5nYWxvcmUxFjAU BgNVBAoTDUJyb2FkY29tIEluYy4xHDAaBgNVBAMTE0FqaXQgS3VtYXIgS2hhcGFyZGUxKTAnBgkq hkiG9w0BCQEWGmFqaXQua2hhcGFyZGVAYnJvYWRjb20uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEArZ/Aqg34lMOo2BabvAa+dRThl9OeUUJMob125dz+jvS78k4NZn1mYrHu53Dn YycqjtuSMlJ6vJuwN2W6QpgTaA2SDt5xTB7CwA2urpcm7vWxxLOszkr5cxMB1QBbTd77bXFuyTqW jrer3VIWqOujJ1n+n+1SigMwEr7PKQR64YKq2aRYn74ukY3DlQdKUrm2yUkcA7aExLcAwHWUna/u pZEyqKnwS1lKCzjX7mV5W955rFsFxChdAKfw0HilwtqdY24mhy62+GeaEkD0gYIj1tCmw9gnQToc K+0s7xEunfR9pBrzmOwS3OQbcP0nJ8SmQ8R+reroH6LYuFpaqK1rgQIDAQABo4IB2zCCAdcwDgYD VR0PAQH/BAQDAgWgMIGjBggrBgEFBQcBAQSBljCBkzBOBggrBgEFBQcwAoZCaHR0cDovL3NlY3Vy ZS5nbG9iYWxzaWduLmNvbS9jYWNlcnQvZ3NnY2NyM3BlcnNvbmFsc2lnbjJjYTIwMjAuY3J0MEEG CCsGAQUFBzABhjVodHRwOi8vb2NzcC5nbG9iYWxzaWduLmNvbS9nc2djY3IzcGVyc29uYWxzaWdu MmNhMjAyMDBNBgNVHSAERjBEMEIGCisGAQQBoDIBKAowNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93 d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8wCQYDVR0TBAIwADBJBgNVHR8EQjBAMD6gPKA6 hjhodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjNwZXJzb25hbHNpZ24yY2EyMDIwLmNy bDAlBgNVHREEHjAcgRphaml0LmtoYXBhcmRlQGJyb2FkY29tLmNvbTATBgNVHSUEDDAKBggrBgEF BQcDBDAfBgNVHSMEGDAWgBSWM9HmWBdbNHWKgVZk1b5I3qGPzzAdBgNVHQ4EFgQUbrcTuh0mr2qP xYdtyDgFeRIiE/gwDQYJKoZIhvcNAQELBQADggEBALrc1TljKrDhXicOaZlzIQyqOEkKAZ324i8X OwzA0n2EcPGmMZvgARurvanSLD3mLeeuyq1feCcjfGM1CJFh4+EY7EkbFbpVPOIdstSBhbnAJnOl aC/q0wTndKoC/xXBhXOZB8YL/Zq4ZclQLMUO6xi/fFRyHviI5/IrosdrpniXFJ9ukJoOXtvdrEF+ KlMYg/Deg9xo3wddCqQIsztHSkR4XaANdn+dbLRQpctZ13BY1lim4uz5bYn3M0IxyZWkQ1JuPHCK aRJv0SfR88PoI4RB7NCEHqFwARTj1KvFPQi8pK/YISFydZYbZrxQdyWDidqm4wSuJfpE6i0cWvCd u50xggJtMIICaQIBATBrMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNh MTEwLwYDVQQDEyhHbG9iYWxTaWduIEdDQyBSMyBQZXJzb25hbFNpZ24gMiBDQSAyMDIwAgwM2Vrj 4nZK0WWosNswDQYJYIZIAWUDBAIBBQCggdQwLwYJKoZIhvcNAQkEMSIEIAiUxZGSqz3Fd1nghs2V Jq8+nxNaiL//xh9ATG2yK2zMMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkF MQ8XDTIzMTIyNzA0MjE0NlowaQYJKoZIhvcNAQkPMVwwWjALBglghkgBZQMEASowCwYJYIZIAWUD BAEWMAsGCWCGSAFlAwQBAjAKBggqhkiG9w0DBzALBgkqhkiG9w0BAQowCwYJKoZIhvcNAQEHMAsG CWCGSAFlAwQCATANBgkqhkiG9w0BAQEFAASCAQB57oF8rKcDlOldYsRpK0QL/wkaBhJhYxJ1Cb7G KTjqIy/La/YLbmdzeCeLv+d5cNDdwzNVFM4SmrfWqv1cKBOG6VVbKimAfChQPQfeOEd4C7ynWrxj fzsPDC4yxJluIMiHuq8ycnfF5UQyLO3jCDwPqKpivMHplYRtb87aTtqPTdFxZPbARUJyTGyrEpjj 7UuQj8kNflzY1bi6zrcAJefnuHY06mi0y8KUrF/ijTRlUjEmVZ3jBS+EqXhxDZ/5n8l8a53jR8HR zqVtMLugxS1me2ySuos3D2Ogj6NFacDFml+qrWGLG57ZPX/VqDc54egfxewW8g3/+lxndKNnccWC --00000000000018c7c3060d7623d6--