ath10k: fix vdev-start timeout on error
authorBen Greear <greearb@candelatech.com>
Thu, 6 Sep 2018 16:46:20 +0000 (19:46 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 1 Oct 2018 13:30:04 +0000 (16:30 +0300)
The vdev-start-response message should cause the
completion to fire, even in the error case.  Otherwise,
the user still gets no useful information and everything
is blocked until the timeout period.

Add some warning text to print out the invalid status
code to aid debugging, and propagate failure code.

Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ath/ath10k/core.h
drivers/net/wireless/ath/ath10k/mac.c
drivers/net/wireless/ath/ath10k/wmi.c
drivers/net/wireless/ath/ath10k/wmi.h

index f6e5c29f74e77b57fb7efec4fb418a0fc01a067f..7328df1bf39fb18388b48af24588ff4e75bfe91d 100644 (file)
@@ -1043,6 +1043,7 @@ struct ath10k {
 
        struct completion install_key_done;
 
+       int last_wmi_vdev_start_status;
        struct completion vdev_setup_done;
 
        struct workqueue_struct *workqueue;
index 97548f96a2f74917f6ef2f57a48a6fd0774c866b..9afc9dc671520f4c2202b21e5381ecf523d7b338 100644 (file)
@@ -968,7 +968,7 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
        if (time_left == 0)
                return -ETIMEDOUT;
 
-       return 0;
+       return ar->last_wmi_vdev_start_status;
 }
 
 static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
index 0f9fccc6322bddec85603c5e9bad6237eabbe603..8093d947ddd259a47a88d81a75ffb2b2bd295ac4 100644 (file)
@@ -3243,18 +3243,31 @@ void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb)
 {
        struct wmi_vdev_start_ev_arg arg = {};
        int ret;
+       u32 status;
 
        ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n");
 
+       ar->last_wmi_vdev_start_status = 0;
+
        ret = ath10k_wmi_pull_vdev_start(ar, skb, &arg);
        if (ret) {
                ath10k_warn(ar, "failed to parse vdev start event: %d\n", ret);
-               return;
+               ar->last_wmi_vdev_start_status = ret;
+               goto out;
        }
 
-       if (WARN_ON(__le32_to_cpu(arg.status)))
-               return;
+       status = __le32_to_cpu(arg.status);
+       if (WARN_ON_ONCE(status)) {
+               ath10k_warn(ar, "vdev-start-response reports status error: %d (%s)\n",
+                           status, (status == WMI_VDEV_START_CHAN_INVALID) ?
+                           "chan-invalid" : "unknown");
+               /* Setup is done one way or another though, so we should still
+                * do the completion, so don't return here.
+                */
+               ar->last_wmi_vdev_start_status = -EINVAL;
+       }
 
+out:
        complete(&ar->vdev_setup_done);
 }
 
index 15622943a885c54a5ddac16159e27bce4de971fa..3c09b0e6bd9b3ea8f5cc1410294ced597029e71d 100644 (file)
@@ -6655,11 +6655,17 @@ struct wmi_ch_info_ev_arg {
        __le32 rx_frame_count;
 };
 
+/* From 10.4 firmware, not sure all have the same values. */
+enum wmi_vdev_start_status {
+       WMI_VDEV_START_OK = 0,
+       WMI_VDEV_START_CHAN_INVALID,
+};
+
 struct wmi_vdev_start_ev_arg {
        __le32 vdev_id;
        __le32 req_id;
        __le32 resp_type; /* %WMI_VDEV_RESP_ */
-       __le32 status;
+       __le32 status; /* See wmi_vdev_start_status enum above */
 };
 
 struct wmi_peer_kick_ev_arg {