net: hns3: add support for dump MAC ID and loopback status in debugfs
authorYufeng Mo <moyufeng@huawei.com>
Wed, 19 Feb 2020 01:23:32 +0000 (09:23 +0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 20 Feb 2020 00:25:12 +0000 (16:25 -0800)
The MAC ID and loopback status information are obtained from
the hardware, which will be helpful for debugging. This patch
adds support for these two items in debugfs.

Signed-off-by: Yufeng Mo <moyufeng@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h

index 1d4ffc5f408ac35b17b6b199832b2f98cce80a3b..345a84b1433b20c7b7d1088bac088d7387a97f03 100644 (file)
@@ -260,6 +260,7 @@ static void hns3_dbg_help(struct hnae3_handle *h)
        dev_info(&h->pdev->dev, "dump m7 info\n");
        dev_info(&h->pdev->dev, "dump ncl_config <offset> <length>(in hex)\n");
        dev_info(&h->pdev->dev, "dump mac tnl status\n");
+       dev_info(&h->pdev->dev, "dump loopback\n");
 
        memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
        strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]",
index 5e94b35b05c09923581ff1969b9c7a6c187dbc5b..6295cf93c3501be61013551cfc596bae6cb9f95a 100644 (file)
@@ -1171,6 +1171,57 @@ static void hclge_dbg_dump_ncl_config(struct hclge_dev *hdev,
        }
 }
 
+static void hclge_dbg_dump_loopback(struct hclge_dev *hdev,
+                                   const char *cmd_buf)
+{
+       struct phy_device *phydev = hdev->hw.mac.phydev;
+       struct hclge_config_mac_mode_cmd *req_app;
+       struct hclge_serdes_lb_cmd *req_serdes;
+       struct hclge_desc desc;
+       u8 loopback_en;
+       int ret;
+
+       req_app = (struct hclge_config_mac_mode_cmd *)desc.data;
+       req_serdes = (struct hclge_serdes_lb_cmd *)desc.data;
+
+       dev_info(&hdev->pdev->dev, "mac id: %u\n", hdev->hw.mac.mac_id);
+
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CONFIG_MAC_MODE, true);
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "failed to dump app loopback status, ret = %d\n", ret);
+               return;
+       }
+
+       loopback_en = hnae3_get_bit(le32_to_cpu(req_app->txrx_pad_fcs_loop_en),
+                                   HCLGE_MAC_APP_LP_B);
+       dev_info(&hdev->pdev->dev, "app loopback: %s\n",
+                loopback_en ? "on" : "off");
+
+       hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_SERDES_LOOPBACK, true);
+       ret = hclge_cmd_send(&hdev->hw, &desc, 1);
+       if (ret) {
+               dev_err(&hdev->pdev->dev,
+                       "failed to dump serdes loopback status, ret = %d\n",
+                       ret);
+               return;
+       }
+
+       loopback_en = req_serdes->enable & HCLGE_CMD_SERDES_SERIAL_INNER_LOOP_B;
+       dev_info(&hdev->pdev->dev, "serdes serial loopback: %s\n",
+                loopback_en ? "on" : "off");
+
+       loopback_en = req_serdes->enable &
+                       HCLGE_CMD_SERDES_PARALLEL_INNER_LOOP_B;
+       dev_info(&hdev->pdev->dev, "serdes parallel loopback: %s\n",
+                loopback_en ? "on" : "off");
+
+       if (phydev)
+               dev_info(&hdev->pdev->dev, "phy loopback: %s\n",
+                        phydev->loopback_enabled ? "on" : "off");
+}
+
 /* hclge_dbg_dump_mac_tnl_status: print message about mac tnl interrupt
  * @hdev: pointer to struct hclge_dev
  */
@@ -1271,6 +1322,7 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf)
 {
 #define DUMP_REG       "dump reg"
 #define DUMP_TM_MAP    "dump tm map"
+#define DUMP_LOOPBACK  "dump loopback"
 
        struct hclge_vport *vport = hclge_get_vport(handle);
        struct hclge_dev *hdev = vport->back;
@@ -1304,6 +1356,9 @@ int hclge_dbg_run_cmd(struct hnae3_handle *handle, const char *cmd_buf)
                                          &cmd_buf[sizeof("dump ncl_config")]);
        } else if (strncmp(cmd_buf, "dump mac tnl status", 19) == 0) {
                hclge_dbg_dump_mac_tnl_status(hdev);
+       } else if (strncmp(cmd_buf, DUMP_LOOPBACK,
+                  strlen(DUMP_LOOPBACK)) == 0) {
+               hclge_dbg_dump_loopback(hdev, &cmd_buf[sizeof(DUMP_LOOPBACK)]);
        } else if (strncmp(cmd_buf, "dump qs shaper", 14) == 0) {
                hclge_dbg_dump_qs_shaper(hdev,
                                         &cmd_buf[sizeof("dump qs shaper")]);
index 492bc944646372bea3db8212884e9d3914dd2a5e..51399dbed77a6702b5a33bf408f545b0c5e73778 100644 (file)
@@ -824,6 +824,8 @@ static void hclge_get_mac_stat(struct hnae3_handle *handle,
 static int hclge_parse_func_status(struct hclge_dev *hdev,
                                   struct hclge_func_status_cmd *status)
 {
+#define HCLGE_MAC_ID_MASK      0xF
+
        if (!(status->pf_state & HCLGE_PF_STATE_DONE))
                return -EINVAL;
 
@@ -833,6 +835,7 @@ static int hclge_parse_func_status(struct hclge_dev *hdev,
        else
                hdev->flag &= ~HCLGE_FLAG_MAIN;
 
+       hdev->hw.mac.mac_id = status->mac_id & HCLGE_MAC_ID_MASK;
        return 0;
 }
 
index f78cbb4cc85eaee14320c6db8d5b4808c3237e3c..71df23d5f1b4d15036c27ddabd7ee07fa1388c00 100644 (file)
@@ -249,6 +249,7 @@ enum HCLGE_MAC_DUPLEX {
 #define QUERY_ACTIVE_SPEED     1
 
 struct hclge_mac {
+       u8 mac_id;
        u8 phy_addr;
        u8 flag;
        u8 media_type;  /* port media type, e.g. fibre/copper/backplane */