wifi: ath11k: Fix hardware restart failure due to twt debugfs failure
authorManikanta Pubbisetty <quic_mpubbise@quicinc.com>
Thu, 1 Sep 2022 16:21:25 +0000 (19:21 +0300)
committerKalle Valo <quic_kvalo@quicinc.com>
Fri, 2 Sep 2022 12:27:11 +0000 (15:27 +0300)
Currently, creation of debugfs entries for TWT is failing during
hardware restart because of the residual TWT files which were
created during add_interface(). Since, struct arvif{} is memset
to zero upon add_interface() invocation, when the hardware restart
is triggered, arvif is memset to 0 and TWT files are attempted to
create again which will fail because of the residual TWT files
already in place, this leads to hardware restart failure.

Also, it is not a good idea to return error from add_interface()
because of debugfs file creation failures. Moreover, debugfs
framework can very well handle the errors in it's create file &
remove file APIs and the errors returned by these APIs are not
checked in most usecases.

Fix the HW restart failure by ignoring the errors returned from
the debugfs APIs.

Tested-on: WCN6750 hw1.0 AHB WLAN.MSL.1.0.1-00887-QCAMSLSWPLZ-1

Fixes: fe98a6137d03 ("ath11k: add debugfs for TWT debug calls")
Signed-off-by: Manikanta Pubbisetty <quic_mpubbise@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20220720135150.22193-3-quic_mpubbise@quicinc.com
drivers/net/wireless/ath/ath11k/debugfs.c
drivers/net/wireless/ath/ath11k/debugfs.h
drivers/net/wireless/ath/ath11k/mac.c

index 3861616b48c86fa13eaadbe12194e54f6ab2a37f..8dcc5f7baf5f98f02c05396e534919686dc0e3df 100644 (file)
@@ -1673,42 +1673,35 @@ static const struct file_operations ath11k_fops_twt_resume_dialog = {
        .open = simple_open
 };
 
-int ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
+void ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
 {
        struct ath11k_base *ab = arvif->ar->ab;
 
        if (arvif->vif->type != NL80211_IFTYPE_AP &&
            !(arvif->vif->type == NL80211_IFTYPE_STATION &&
              test_bit(WMI_TLV_SERVICE_STA_TWT, ab->wmi_ab.svc_map)))
-               return 0;
-
-       if (!arvif->debugfs_twt) {
-               arvif->debugfs_twt = debugfs_create_dir("twt",
-                                                       arvif->vif->debugfs_dir);
-               if (!arvif->debugfs_twt || IS_ERR(arvif->debugfs_twt)) {
-                       ath11k_warn(ab, "failed to create directory %p\n",
-                                   arvif->debugfs_twt);
-                       arvif->debugfs_twt = NULL;
-                       return -1;
-               }
+               return;
 
-               debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt,
-                                   arvif, &ath11k_fops_twt_add_dialog);
+       arvif->debugfs_twt = debugfs_create_dir("twt",
+                                               arvif->vif->debugfs_dir);
+       debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt,
+                           arvif, &ath11k_fops_twt_add_dialog);
 
-               debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt,
-                                   arvif, &ath11k_fops_twt_del_dialog);
+       debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt,
+                           arvif, &ath11k_fops_twt_del_dialog);
 
-               debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt,
-                                   arvif, &ath11k_fops_twt_pause_dialog);
+       debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt,
+                           arvif, &ath11k_fops_twt_pause_dialog);
 
-               debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt,
-                                   arvif, &ath11k_fops_twt_resume_dialog);
-       }
-       return 0;
+       debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt,
+                           arvif, &ath11k_fops_twt_resume_dialog);
 }
 
 void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif)
 {
+       if (!arvif->debugfs_twt)
+               return;
+
        debugfs_remove_recursive(arvif->debugfs_twt);
        arvif->debugfs_twt = NULL;
 }
index 30c00cb283118872f2ce923a7952618c0e005caa..15edca8e0aecafcc123afd0700c15e8e52fcde93 100644 (file)
@@ -306,7 +306,7 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar)
        return ar->debug.rx_filter;
 }
 
-int ath11k_debugfs_add_interface(struct ath11k_vif *arvif);
+void ath11k_debugfs_add_interface(struct ath11k_vif *arvif);
 void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif);
 void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
                                     enum wmi_direct_buffer_module id,
@@ -386,9 +386,8 @@ static inline int ath11k_debugfs_get_fw_stats(struct ath11k *ar,
        return 0;
 }
 
-static inline int ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
+static inline void ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
 {
-       return 0;
 }
 
 static inline void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif)
index 17dce9871bdb80799abff1dee0f5a8a2f9e837ae..3053ca7868a30b10f2edd5ea88c03152ddfff375 100644 (file)
@@ -6178,6 +6178,13 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
                goto err;
        }
 
+       /* In the case of hardware recovery, debugfs files are
+        * not deleted since ieee80211_ops.remove_interface() is
+        * not invoked. In such cases, try to delete the files.
+        * These will be re-created later.
+        */
+       ath11k_debugfs_remove_interface(arvif);
+
        memset(arvif, 0, sizeof(*arvif));
 
        arvif->ar = ar;
@@ -6359,9 +6366,7 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
                }
        }
 
-       ret = ath11k_debugfs_add_interface(arvif);
-       if (ret)
-               goto err_peer_del;
+       ath11k_debugfs_add_interface(arvif);
 
        mutex_unlock(&ar->conf_mutex);