net: hns3: provide some interface & information for the client
authorHuazhong Tan <tanhuazhong@huawei.com>
Wed, 7 Nov 2018 04:06:09 +0000 (12:06 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 7 Nov 2018 19:42:17 +0000 (11:42 -0800)
The client needs to know if the hardware is resetting when
loading or unloading itself, because client may abort the loading
process or wait for the reset process to finish when unloading
if hardware is resetting.

So this patch provides these interfaces to do it.
1. get_hw_reset_stat, the reset status of hardware.
2. ae_dev_resetting, whether reset task is scheduling.
3. ae_dev_reset_cnt, how many reset has been done.

Also, the RoCE client needs some field in the hnae3_roce_private_info
to save its state, and process_hw_error interface in the
hnae3_client_ops to process hardware errors.

Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h

index 7deab9270d16c69830491f7290437da02fa0160e..f57034d1654cbc05585b2592acd9d743ac3214a1 100644 (file)
@@ -162,6 +162,7 @@ struct hnae3_client_ops {
        int (*setup_tc)(struct hnae3_handle *handle, u8 tc);
        int (*reset_notify)(struct hnae3_handle *handle,
                            enum hnae3_reset_notify_type type);
+       enum hnae3_reset_type (*process_hw_error)(struct hnae3_handle *handle);
 };
 
 #define HNAE3_CLIENT_NAME_LENGTH 16
@@ -432,6 +433,9 @@ struct hnae3_ae_ops {
        int (*restore_fd_rules)(struct hnae3_handle *handle);
        void (*enable_fd)(struct hnae3_handle *handle, bool enable);
        pci_ers_result_t (*process_hw_error)(struct hnae3_ae_dev *ae_dev);
+       bool (*get_hw_reset_stat)(struct hnae3_handle *handle);
+       bool (*ae_dev_resetting)(struct hnae3_handle *handle);
+       unsigned long (*ae_dev_reset_cnt)(struct hnae3_handle *handle);
 };
 
 struct hnae3_dcb_ops {
@@ -490,6 +494,14 @@ struct hnae3_roce_private_info {
        void __iomem *roce_io_base;
        int base_vector;
        int num_vectors;
+
+       /* The below attributes defined for RoCE client, hnae3 gives
+        * initial values to them, and RoCE client can modify and use
+        * them.
+        */
+       unsigned long reset_state;
+       unsigned long instance_state;
+       unsigned long state;
 };
 
 struct hnae3_unic_private_info {
index 5e6006b6ed1ad8056a55a99b405dd7103928e49d..b6695424805b229049a82bfa5bb5856fb7be34ef 100644 (file)
@@ -2466,6 +2466,7 @@ static void hclge_reset(struct hclge_dev *hdev)
         * know if device is undergoing reset
         */
        ae_dev->reset_type = hdev->reset_type;
+       hdev->reset_count++;
        /* perform reset of the stack & ae device for a client */
        handle = &hdev->vport[0].nic;
        rtnl_lock();
@@ -4604,6 +4605,31 @@ static int hclge_get_all_rules(struct hnae3_handle *handle,
        return 0;
 }
 
+static bool hclge_get_hw_reset_stat(struct hnae3_handle *handle)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       return hclge_read_dev(&hdev->hw, HCLGE_GLOBAL_RESET_REG) ||
+              hclge_read_dev(&hdev->hw, HCLGE_FUN_RST_ING);
+}
+
+static bool hclge_ae_dev_resetting(struct hnae3_handle *handle)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       return test_bit(HCLGE_STATE_RST_HANDLING, &hdev->state);
+}
+
+static unsigned long hclge_ae_dev_reset_cnt(struct hnae3_handle *handle)
+{
+       struct hclge_vport *vport = hclge_get_vport(handle);
+       struct hclge_dev *hdev = vport->back;
+
+       return hdev->reset_count;
+}
+
 static void hclge_enable_fd(struct hnae3_handle *handle, bool enable)
 {
        struct hclge_vport *vport = hclge_get_vport(handle);
@@ -7350,6 +7376,9 @@ static const struct hnae3_ae_ops hclge_ops = {
        .restore_fd_rules = hclge_restore_fd_entries,
        .enable_fd = hclge_enable_fd,
        .process_hw_error = hclge_process_ras_hw_error,
+       .get_hw_reset_stat = hclge_get_hw_reset_stat,
+       .ae_dev_resetting = hclge_ae_dev_resetting,
+       .ae_dev_reset_cnt = hclge_ae_dev_reset_cnt,
 };
 
 static struct hnae3_ae_algo ae_algo = {
index 7cfb61ebb92ee43e3d535f3620b470e501397abd..b6a17f56c8d8737a78030fcc5a009ae4cc40de4e 100644 (file)
@@ -598,6 +598,7 @@ struct hclge_dev {
        unsigned long default_reset_request;
        unsigned long reset_request;    /* reset has been requested */
        unsigned long reset_pending;    /* client rst is pending to be served */
+       unsigned long reset_count;      /* the number of reset has been done */
        u32 fw_version;
        u16 num_vmdq_vport;             /* Num vmdq vport this PF has set up */
        u16 num_tqps;                   /* Num task queue pairs of this PF */
index 42982fc2b5d7f1c4c950bb9a882db40875885a39..517204bbf0b7bf11446718a563f7c7bfb9aea9d5 100644 (file)
@@ -1165,6 +1165,7 @@ static int hclgevf_reset(struct hclgevf_dev *hdev)
 {
        int ret;
 
+       hdev->reset_count++;
        rtnl_lock();
 
        /* bring down the nic to stop any ongoing TX/RX */
@@ -2185,6 +2186,27 @@ static void hclgevf_get_media_type(struct hnae3_handle *handle,
                *media_type = hdev->hw.mac.media_type;
 }
 
+static bool hclgevf_get_hw_reset_stat(struct hnae3_handle *handle)
+{
+       struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+
+       return !!hclgevf_read_dev(&hdev->hw, HCLGEVF_FUN_RST_ING);
+}
+
+static bool hclgevf_ae_dev_resetting(struct hnae3_handle *handle)
+{
+       struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+
+       return test_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
+}
+
+static unsigned long hclgevf_ae_dev_reset_cnt(struct hnae3_handle *handle)
+{
+       struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
+
+       return hdev->reset_count;
+}
+
 static const struct hnae3_ae_ops hclgevf_ops = {
        .init_ae_dev = hclgevf_init_ae_dev,
        .uninit_ae_dev = hclgevf_uninit_ae_dev,
@@ -2225,6 +2247,9 @@ static const struct hnae3_ae_ops hclgevf_ops = {
        .get_status = hclgevf_get_status,
        .get_ksettings_an_result = hclgevf_get_ksettings_an_result,
        .get_media_type = hclgevf_get_media_type,
+       .get_hw_reset_stat = hclgevf_get_hw_reset_stat,
+       .ae_dev_resetting = hclgevf_ae_dev_resetting,
+       .ae_dev_reset_cnt = hclgevf_ae_dev_reset_cnt,
 };
 
 static struct hnae3_ae_algo ae_algovf = {
index 6b2fd5a0326fef7e8eb2165b111127e792791733..ffb8c7768b88a98216fbc7711246ca1f35ac1575 100644 (file)
@@ -150,6 +150,7 @@ struct hclgevf_dev {
 #define HCLGEVF_RESET_REQUESTED                0
 #define HCLGEVF_RESET_PENDING          1
        unsigned long reset_state;      /* requested, pending */
+       unsigned long reset_count;      /* the number of reset has been done */
        u32 reset_attempts;
 
        u32 fw_version;