summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
diff options
context:
space:
mode:
authorYufeng Mo <moyufeng@huawei.com>2021-11-10 16:42:52 +0300
committerDavid S. Miller <davem@davemloft.net>2021-11-10 17:20:43 +0300
commit3b6db4a0492beed36545a2bc6075117faecebfe2 (patch)
tree0cecd062f3232c56923dd70afaea647791af2cf5 /drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
parent0b653a81a26d66ffe526a54c2177e24fb1400301 (diff)
downloadlinux-3b6db4a0492beed36545a2bc6075117faecebfe2.tar.xz
net: hns3: sync rx ring head in echo common pull
When the driver processes rx packets, the head pointer is updated only after the number of received packets reaches 16. However, hardware relies on the head pointer to calculate the number of FBDs. As a result, the hardware calculates the FBD incorrectly. Therefore, the driver proactively updates the head pointer in each common poll to ensure that the number of FBDs calculated by the hardware is correct. Fixes: 68752b24f51a ("net: hns3: schedule the polling again when allocation fails") Signed-off-by: Yufeng Mo <moyufeng@huawei.com> Signed-off-by: Guangbin Huang <huangguangbin2@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c')
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
index f89bfb352adf..e605c2c5bcce 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_cmd.c
@@ -434,8 +434,28 @@ err_csq:
return ret;
}
+static int hclgevf_firmware_compat_config(struct hclgevf_dev *hdev, bool en)
+{
+ struct hclgevf_firmware_compat_cmd *req;
+ struct hclgevf_desc desc;
+ u32 compat = 0;
+
+ hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_IMP_COMPAT_CFG, false);
+
+ if (en) {
+ req = (struct hclgevf_firmware_compat_cmd *)desc.data;
+
+ hnae3_set_bit(compat, HCLGEVF_SYNC_RX_RING_HEAD_EN_B, 1);
+
+ req->compat = cpu_to_le32(compat);
+ }
+
+ return hclgevf_cmd_send(&hdev->hw, &desc, 1);
+}
+
int hclgevf_cmd_init(struct hclgevf_dev *hdev)
{
+ struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
int ret;
spin_lock_bh(&hdev->hw.cmq.csq.lock);
@@ -484,6 +504,17 @@ int hclgevf_cmd_init(struct hclgevf_dev *hdev)
hnae3_get_field(hdev->fw_version, HNAE3_FW_VERSION_BYTE0_MASK,
HNAE3_FW_VERSION_BYTE0_SHIFT));
+ if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) {
+ /* ask the firmware to enable some features, driver can work
+ * without it.
+ */
+ ret = hclgevf_firmware_compat_config(hdev, true);
+ if (ret)
+ dev_warn(&hdev->pdev->dev,
+ "Firmware compatible features not enabled(%d).\n",
+ ret);
+ }
+
return 0;
err_cmd_init:
@@ -508,6 +539,7 @@ static void hclgevf_cmd_uninit_regs(struct hclgevf_hw *hw)
void hclgevf_cmd_uninit(struct hclgevf_dev *hdev)
{
+ hclgevf_firmware_compat_config(hdev, false);
set_bit(HCLGEVF_STATE_CMD_DISABLE, &hdev->state);
/* wait to ensure that the firmware completes the possible left
* over commands.