From patchwork Tue Apr 13 13:47:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "humin (Q)" X-Patchwork-Id: 91255 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 45BF9A0524; Tue, 13 Apr 2021 15:47:38 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 18688160FDC; Tue, 13 Apr 2021 15:47:13 +0200 (CEST) Received: from szxga06-in.huawei.com (szxga06-in.huawei.com [45.249.212.32]) by mails.dpdk.org (Postfix) with ESMTP id D8D28160FC6 for ; Tue, 13 Apr 2021 15:47:06 +0200 (CEST) Received: from DGGEMS401-HUB.china.huawei.com (unknown [172.30.72.59]) by szxga06-in.huawei.com (SkyGuard) with ESMTP id 4FKRgY4LjLzlXpp for ; Tue, 13 Apr 2021 21:45:13 +0800 (CST) Received: from localhost.localdomain (10.69.192.56) by DGGEMS401-HUB.china.huawei.com (10.3.19.201) with Microsoft SMTP Server id 14.3.498.0; Tue, 13 Apr 2021 21:47:00 +0800 From: "Min Hu (Connor)" To: CC: Date: Tue, 13 Apr 2021 21:47:14 +0800 Message-ID: <1618321639-57642-5-git-send-email-humin29@huawei.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1618321639-57642-1-git-send-email-humin29@huawei.com> References: <1618321639-57642-1-git-send-email-humin29@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.69.192.56] X-CFilter-Loop: Reflected Subject: [dpdk-dev] [PATCH 4/9] net/hns3: fix firmware compatibility configuration 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 Sender: "dev" From: Huisong Li The firmware compatibility configuration in PF driver is used to maintain the compatibility of some features of the driver and firmware, and requires firmware to enable these features. Currently, the configuration is in hns3_init_hardware(), which is a little back. Because firmware may clear some configurations (such as, MAC related) after receiving the command. And firmware can not be aware of some default initializations (such as, flow control) before executing the command to set the copper PHY when the PHY is controlled by firmware. Therefore, it is recommended that no other hardware resources are configured before the compatibility configuration. And it should be moved to hns3_cmd_init(), which is responsible for the firmware command initialization of driver. In addition, the driver needs to perform corresponding processing if the command fails to be sent. 1) If firmware fails to take over the copper PHY, the copper port fails to initialize. 2) If fails to enable the report of link events, the device does not support the LSC capability. Fixes: 7035ee35e26b ("net/hns3: refactor PF LSC event report") Fixes: bac6a0644121 ("net/hns3: fix link status change from firmware") Cc: stable@dpdk.org Signed-off-by: Huisong Li Signed-off-by: Min Hu (Connor) --- drivers/net/hns3/hns3_cmd.c | 116 +++++++++++++++++++++++++++++++++++++++++ drivers/net/hns3/hns3_ethdev.c | 56 -------------------- 2 files changed, 116 insertions(+), 56 deletions(-) diff --git a/drivers/net/hns3/hns3_cmd.c b/drivers/net/hns3/hns3_cmd.c index 1d8ef7a..e6900ec 100644 --- a/drivers/net/hns3/hns3_cmd.c +++ b/drivers/net/hns3/hns3_cmd.c @@ -515,9 +515,99 @@ hns3_cmd_init_queue(struct hns3_hw *hw) return ret; } +static void +hns3_update_dev_lsc_cap(struct hns3_hw *hw, int fw_compact_cmd_result) +{ + struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; + + if (hw->adapter_state != HNS3_NIC_UNINITIALIZED) + return; + + if (fw_compact_cmd_result != 0) { + /* + * If fw_compact_cmd_result is not zero, it means firmware don't + * support link status change interrupt. + * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver + * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear + * the RTE_ETH_DEV_INTR_LSC capability when detect firmware + * don't support link status change interrupt. + */ + dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; + } +} + +static int +hns3_apply_fw_compat_cmd_result(struct hns3_hw *hw, int result) +{ + if (result != 0 && hns3_dev_copper_supported(hw)) { + hns3_err(hw, "firmware fails to initialize the PHY, ret = %d.", + result); + return result; + } + + hns3_update_dev_lsc_cap(hw, result); + + return 0; +} + +static int +hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init) +{ + struct hns3_firmware_compat_cmd *req; + struct hns3_cmd_desc desc; + uint32_t compat = 0; + +#if defined(RTE_HNS3_ONLY_1630_FPGA) + /* If resv reg enabled phy driver of imp is not configured, driver + * will use temporary phy driver. + */ + struct rte_pci_device *pci_dev; + struct rte_eth_dev *eth_dev; + uint8_t revision; + int ret; + + eth_dev = &rte_eth_devices[hw->data->port_id]; + pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + /* Get PCI revision id */ + ret = rte_pci_read_config(pci_dev, &revision, HNS3_PCI_REVISION_ID_LEN, + HNS3_PCI_REVISION_ID); + if (ret != HNS3_PCI_REVISION_ID_LEN) { + PMD_INIT_LOG(ERR, "failed to read pci revision id, ret = %d", + ret); + return -EIO; + } + if (revision == PCI_REVISION_ID_HIP09_A) { + struct hns3_pf *pf = HNS3_DEV_HW_TO_PF(hw); + if (hns3_dev_copper_supported(hw) == 0 || pf->is_tmp_phy) { + PMD_INIT_LOG(ERR, "***use temp phy driver in dpdk***"); + pf->is_tmp_phy = true; + hns3_set_bit(hw->capability, + HNS3_DEV_SUPPORT_COPPER_B, 1); + return 0; + } + + PMD_INIT_LOG(ERR, "***use phy driver in imp***"); + } +#endif + + hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false); + req = (struct hns3_firmware_compat_cmd *)desc.data; + + if (is_init) { + hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1); + hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0); + if (hns3_dev_copper_supported(hw)) + hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1); + } + req->compat = rte_cpu_to_le_32(compat); + + return hns3_cmd_send(hw, &desc, 1); +} + int hns3_cmd_init(struct hns3_hw *hw) { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); uint32_t version; int ret; @@ -564,6 +654,27 @@ hns3_cmd_init(struct hns3_hw *hw) hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M, HNS3_FW_VERSION_BYTE0_S)); + if (hns->is_vf) + return 0; + + /* + * Requiring firmware to enable some features, firber port can still + * work without it, but copper port can't work because the firmware + * fails to take over the PHY. + */ + ret = hns3_firmware_compat_config(hw, true); + if (ret) + PMD_INIT_LOG(WARNING, "firmware compatible features not " + "supported, ret = %d.", ret); + + /* + * Perform some corresponding operations based on the firmware + * compatibility configuration result. + */ + ret = hns3_apply_fw_compat_cmd_result(hw, ret); + if (ret) + goto err_cmd_init; + return 0; err_cmd_init: @@ -591,6 +702,11 @@ hns3_cmd_destroy_queue(struct hns3_hw *hw) void hns3_cmd_uninit(struct hns3_hw *hw) { + struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); + + if (!hns->is_vf) + (void)hns3_firmware_compat_config(hw, false); + __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED); /* diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 62a23b8..d22d31d 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -4118,28 +4118,6 @@ hns3_buffer_alloc(struct hns3_hw *hw) } static int -hns3_firmware_compat_config(struct hns3_hw *hw, bool is_init) -{ - struct hns3_firmware_compat_cmd *req; - struct hns3_cmd_desc desc; - uint32_t compat = 0; - - hns3_cmd_setup_basic_desc(&desc, HNS3_OPC_FIRMWARE_COMPAT_CFG, false); - req = (struct hns3_firmware_compat_cmd *)desc.data; - - if (is_init) { - hns3_set_bit(compat, HNS3_LINK_EVENT_REPORT_EN_B, 1); - hns3_set_bit(compat, HNS3_NCSI_ERROR_REPORT_EN_B, 0); - if (hw->mac.media_type == HNS3_MEDIA_TYPE_COPPER) - hns3_set_bit(compat, HNS3_FIRMWARE_PHY_DRIVER_EN_B, 1); - } - - req->compat = rte_cpu_to_le_32(compat); - - return hns3_cmd_send(hw, &desc, 1); -} - -static int hns3_mac_init(struct hns3_hw *hw) { struct hns3_adapter *hns = HNS3_DEV_HW_TO_ADAPTER(hw); @@ -4815,28 +4793,6 @@ hns3_service_handler(void *param) rte_eal_alarm_set(HNS3_SERVICE_INTERVAL, hns3_service_handler, eth_dev); } -static void -hns3_update_dev_lsc_cap(struct hns3_hw *hw, - int fw_compact_cmd_result) -{ - struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id]; - - if (hw->adapter_state != HNS3_NIC_UNINITIALIZED) - return; - - if (fw_compact_cmd_result != 0) { - /* - * If fw_compact_cmd_result is not zero, it means firmware don't - * support link status change interrupt. - * Framework already set RTE_ETH_DEV_INTR_LSC bit because driver - * declared RTE_PCI_DRV_INTR_LSC in drv_flags. It need to clear - * the RTE_ETH_DEV_INTR_LSC capability when detect firmware - * don't support link status change interrupt. - */ - dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC; - } -} - static int hns3_init_hardware(struct hns3_adapter *hns) { @@ -4916,16 +4872,6 @@ hns3_init_hardware(struct hns3_adapter *hns) goto err_mac_init; } - /* - * Requiring firmware to enable some features, driver can - * still work without it. - */ - ret = hns3_firmware_compat_config(hw, true); - if (ret) - PMD_INIT_LOG(WARNING, "firmware compatible features not " - "supported, ret = %d.", ret); - hns3_update_dev_lsc_cap(hw, ret); - return 0; err_mac_init: @@ -5073,7 +5019,6 @@ hns3_init_pf(struct rte_eth_dev *eth_dev) err_enable_intr: hns3_fdir_filter_uninit(hns); err_fdir: - (void)hns3_firmware_compat_config(hw, false); hns3_uninit_umv_space(hw); err_init_hw: hns3_tqp_stats_uninit(hw); @@ -5108,7 +5053,6 @@ hns3_uninit_pf(struct rte_eth_dev *eth_dev) (void)hns3_config_gro(hw, false); hns3_promisc_uninit(hw); hns3_fdir_filter_uninit(hns); - (void)hns3_firmware_compat_config(hw, false); hns3_uninit_umv_space(hw); hns3_tqp_stats_uninit(hw); hns3_config_mac_tnl_int(hw, false);