--- /dev/null
+// SPDX-License-Identifier: GPL-2.0+
+/* Copyright (c) 2018-2019 Hisilicon Limited. */
+
+#include <linux/device.h>
+
+#include "hclge_cmd.h"
+#include "hclge_main.h"
+#include "hnae3.h"
+
+static void hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, u8 stage,
+                                  bool sel_x, u32 loc)
+{
+       struct hclge_fd_tcam_config_1_cmd *req1;
+       struct hclge_fd_tcam_config_2_cmd *req2;
+       struct hclge_fd_tcam_config_3_cmd *req3;
+       struct hclge_desc desc[3];
+       int ret, i;
+       u32 *req;
+
+       hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_FD_TCAM_OP, true);
+       desc[0].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
+       hclge_cmd_setup_basic_desc(&desc[1], HCLGE_OPC_FD_TCAM_OP, true);
+       desc[1].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
+       hclge_cmd_setup_basic_desc(&desc[2], HCLGE_OPC_FD_TCAM_OP, true);
+
+       req1 = (struct hclge_fd_tcam_config_1_cmd *)desc[0].data;
+       req2 = (struct hclge_fd_tcam_config_2_cmd *)desc[1].data;
+       req3 = (struct hclge_fd_tcam_config_3_cmd *)desc[2].data;
+
+       req1->stage  = stage;
+       req1->xy_sel = sel_x ? 1 : 0;
+       req1->index  = cpu_to_le32(loc);
+
+       ret = hclge_cmd_send(&hdev->hw, desc, 3);
+       if (ret)
+               return;
+
+       dev_info(&hdev->pdev->dev, " read result tcam key %s(%u):\n",
+                sel_x ? "x" : "y", loc);
+
+       req = (u32 *)req1->tcam_data;
+       for (i = 0; i < 2; i++)
+               dev_info(&hdev->pdev->dev, "%08x\n", *req++);
+
+       req = (u32 *)req2->tcam_data;
+       for (i = 0; i < 6; i++)
+               dev_info(&hdev->pdev->dev, "%08x\n", *req++);
+
+       req = (u32 *)req3->tcam_data;
+       for (i = 0; i < 5; i++)
+               dev_info(&hdev->pdev->dev, "%08x\n", *req++);
+}
+
+static void hclge_dbg_fd_tcam(struct hclge_dev *hdev)
+{
+       u32 i;
+
+       for (i = 0; i < hdev->fd_cfg.rule_num[0]; i++) {
+               hclge_dbg_fd_tcam_read(hdev, 0, true, i);
+               hclge_dbg_fd_tcam_read(hdev, 0, false, i);
+       }
+}
+
+int hclge_dbg_run_cmd(struct hnae3_handle *handle, char *cmd_buf)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       if (strncmp(cmd_buf, "dump fd tcam", 12) == 0) {
+               hclge_dbg_fd_tcam(hdev);
+       } else {
+               dev_info(&hdev->pdev->dev, "unknown command\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}