aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSalil Mehta <salil.mehta@huawei.com>2018-03-22 10:28:54 -0400
committerDavid S. Miller <davem@davemloft.net>2018-03-22 15:29:03 -0400
commit436667d2e1793995267915d2562f7b14f26c1f63 (patch)
tree3395a065e9bfbd4c01596aa90755603ce4063271
parent35a1e50343bdae07bffe911e2d9f7e825fafe4f1 (diff)
net: hns3: Add VF Reset device state and its handling
This introduces the hclge device reset states of "requested" and "pending" and also its handling in context to Reset Service Task. Device gets into requested state because of any VF reset request asserted from upper layers, for example due to watchdog timeout expiration. Requested state would result in eventually forwarding the VF reset request to PF which would actually reset the VF. Device will get into pending state if: 1. VF receives the acknowledgement from PF for the VF reset request it originally sent to PF. 2. Reset Service Task detects that after asserting VF reset for certain times the data-path is not working and device then decides to assert full VF reset(this means also resetting the PCIe interface). 3. PF intimates the VF that it has undergone reset. Pending state would result in VF to poll for hardware reset completion status and then resetting the stack/enet layer, which in turn means reinitializing the ring management/enet layer. Note: we would be adding support of 3. later as a separate patch. This decision should not affect VF reset as its event handling is generic in nature. Signed-off-by: Salil Mehta <salil.mehta@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hnae3.h1
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c67
-rw-r--r--drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h5
3 files changed, 68 insertions, 5 deletions
diff --git a/drivers/net/ethernet/hisilicon/hns3/hnae3.h b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
index 56f9e650d964..37ec1b3286c6 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hnae3.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hnae3.h
@@ -119,6 +119,7 @@ enum hnae3_reset_notify_type {
119 119
120enum hnae3_reset_type { 120enum hnae3_reset_type {
121 HNAE3_VF_RESET, 121 HNAE3_VF_RESET,
122 HNAE3_VF_FULL_RESET,
122 HNAE3_FUNC_RESET, 123 HNAE3_FUNC_RESET,
123 HNAE3_CORE_RESET, 124 HNAE3_CORE_RESET,
124 HNAE3_GLOBAL_RESET, 125 HNAE3_GLOBAL_RESET,
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
index cdb6e7ae3b70..0d204e2f6fcd 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c
@@ -840,7 +840,9 @@ static void hclgevf_reset_event(struct hnae3_handle *handle)
840 840
841 handle->reset_level = HNAE3_VF_RESET; 841 handle->reset_level = HNAE3_VF_RESET;
842 842
843 /* request VF reset here. Code added later */ 843 /* reset of this VF requested */
844 set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state);
845 hclgevf_reset_task_schedule(hdev);
844 846
845 handle->last_reset_time = jiffies; 847 handle->last_reset_time = jiffies;
846} 848}
@@ -889,6 +891,12 @@ static void hclgevf_task_schedule(struct hclgevf_dev *hdev)
889 schedule_work(&hdev->service_task); 891 schedule_work(&hdev->service_task);
890} 892}
891 893
894static void hclgevf_deferred_task_schedule(struct hclgevf_dev *hdev)
895{
896 if (test_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state))
897 hclgevf_reset_task_schedule(hdev);
898}
899
892static void hclgevf_service_timer(struct timer_list *t) 900static void hclgevf_service_timer(struct timer_list *t)
893{ 901{
894 struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer); 902 struct hclgevf_dev *hdev = from_timer(hdev, t, service_timer);
@@ -908,10 +916,57 @@ static void hclgevf_reset_service_task(struct work_struct *work)
908 916
909 clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state); 917 clear_bit(HCLGEVF_STATE_RST_SERVICE_SCHED, &hdev->state);
910 918
911 /* body of the reset service task will constitute of hclge device 919 if (test_and_clear_bit(HCLGEVF_RESET_PENDING,
912 * reset state handling. This code shall be added subsequently in 920 &hdev->reset_state)) {
913 * next patches. 921 /* PF has initmated that it is about to reset the hardware.
914 */ 922 * We now have to poll & check if harware has actually completed
923 * the reset sequence. On hardware reset completion, VF needs to
924 * reset the client and ae device.
925 */
926 hdev->reset_attempts = 0;
927
928 /* code to check/wait for hardware reset completion and the
929 * further initiating software stack reset would be added here
930 */
931
932 } else if (test_and_clear_bit(HCLGEVF_RESET_REQUESTED,
933 &hdev->reset_state)) {
934 /* we could be here when either of below happens:
935 * 1. reset was initiated due to watchdog timeout due to
936 * a. IMP was earlier reset and our TX got choked down and
937 * which resulted in watchdog reacting and inducing VF
938 * reset. This also means our cmdq would be unreliable.
939 * b. problem in TX due to other lower layer(example link
940 * layer not functioning properly etc.)
941 * 2. VF reset might have been initiated due to some config
942 * change.
943 *
944 * NOTE: Theres no clear way to detect above cases than to react
945 * to the response of PF for this reset request. PF will ack the
946 * 1b and 2. cases but we will not get any intimation about 1a
947 * from PF as cmdq would be in unreliable state i.e. mailbox
948 * communication between PF and VF would be broken.
949 */
950
951 /* if we are never geting into pending state it means either:
952 * 1. PF is not receiving our request which could be due to IMP
953 * reset
954 * 2. PF is screwed
955 * We cannot do much for 2. but to check first we can try reset
956 * our PCIe + stack and see if it alleviates the problem.
957 */
958 if (hdev->reset_attempts > 3) {
959 /* prepare for full reset of stack + pcie interface */
960 hdev->nic.reset_level = HNAE3_VF_FULL_RESET;
961
962 /* "defer" schedule the reset task again */
963 set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
964 } else {
965 hdev->reset_attempts++;
966
967 /* request PF for resetting this VF via mailbox */
968 }
969 }
915 970
916 clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state); 971 clear_bit(HCLGEVF_STATE_RST_HANDLING, &hdev->state);
917} 972}
@@ -943,6 +998,8 @@ static void hclgevf_service_task(struct work_struct *work)
943 */ 998 */
944 hclgevf_request_link_info(hdev); 999 hclgevf_request_link_info(hdev);
945 1000
1001 hclgevf_deferred_task_schedule(hdev);
1002
946 clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state); 1003 clear_bit(HCLGEVF_STATE_SERVICE_SCHED, &hdev->state);
947} 1004}
948 1005
diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
index 8b5fa670ed18..1c9cf87a73c0 100644
--- a/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
+++ b/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.h
@@ -124,6 +124,11 @@ struct hclgevf_dev {
124 struct hclgevf_rss_cfg rss_cfg; 124 struct hclgevf_rss_cfg rss_cfg;
125 unsigned long state; 125 unsigned long state;
126 126
127#define HCLGEVF_RESET_REQUESTED 0
128#define HCLGEVF_RESET_PENDING 1
129 unsigned long reset_state; /* requested, pending */
130 u32 reset_attempts;
131
127 u32 fw_version; 132 u32 fw_version;
128 u16 num_tqps; /* num task queue pairs of this PF */ 133 u16 num_tqps; /* num task queue pairs of this PF */
129 134