OSDN Git Service

icnss: Send FW Down indication to WLAN host driver
authorAnurag Chouhan <achouhan@codeaurora.org>
Tue, 21 Mar 2017 13:46:53 +0000 (19:16 +0530)
committerAnurag Chouhan <achouhan@codeaurora.org>
Mon, 3 Apr 2017 06:48:37 +0000 (12:18 +0530)
If FW is down irrespective of crash, a uevent
is sent to wlan host driver to indicate FW is down.

Change-Id: I9fe2a2a11178f72ea27150d74d93a1e411eac030
CRs-fixed: 2027902
Signed-off-by: Hardik Kantilal Patel <hkpatel@codeaurora.org>
Signed-off-by: Anurag Chouhan <achouhan@codeaurora.org>
drivers/soc/qcom/icnss.c
include/soc/qcom/icnss.h

index 16ab240..5b92815 100644 (file)
@@ -1763,11 +1763,29 @@ static void icnss_qmi_wlfw_clnt_notify(struct qmi_handle *handle,
        }
 }
 
+static int icnss_call_driver_uevent(struct icnss_priv *priv,
+                                   enum icnss_uevent uevent, void *data)
+{
+       struct icnss_uevent_data uevent_data;
+
+       if (!priv->ops || !priv->ops->uevent)
+               return 0;
+
+       icnss_pr_dbg("Calling driver uevent state: 0x%lx, uevent: %d\n",
+                    priv->state, uevent);
+
+       uevent_data.uevent = uevent;
+       uevent_data.data = data;
+
+       return priv->ops->uevent(&priv->pdev->dev, &uevent_data);
+}
+
 static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle,
                          unsigned int msg_id, void *msg,
                          unsigned int msg_len, void *ind_cb_priv)
 {
        struct icnss_event_pd_service_down_data *event_data;
+       struct icnss_uevent_fw_down_data fw_down_data;
 
        if (!penv)
                return;
@@ -1799,6 +1817,9 @@ static void icnss_qmi_wlfw_clnt_ind(struct qmi_handle *handle,
                        return;
                event_data->crashed = true;
                event_data->fw_rejuvenate = true;
+               fw_down_data.crashed = true;
+               icnss_call_driver_uevent(penv, ICNSS_UEVENT_FW_DOWN,
+                                        &fw_down_data);
                icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
                                        0, event_data);
                break;
@@ -1912,23 +1933,6 @@ static int icnss_driver_event_server_exit(void *data)
        return 0;
 }
 
-static int icnss_call_driver_uevent(struct icnss_priv *priv,
-                                   enum icnss_uevent uevent, void *data)
-{
-       struct icnss_uevent_data uevent_data;
-
-       if (!priv->ops || !priv->ops->uevent)
-               return 0;
-
-       icnss_pr_dbg("Calling driver uevent state: 0x%lx, uevent: %d\n",
-                    priv->state, uevent);
-
-       uevent_data.uevent = uevent;
-       uevent_data.data = data;
-
-       return priv->ops->uevent(&priv->pdev->dev, &uevent_data);
-}
-
 static int icnss_call_driver_probe(struct icnss_priv *priv)
 {
        int ret;
@@ -2308,6 +2312,7 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
        struct notif_data *notif = data;
        struct icnss_priv *priv = container_of(nb, struct icnss_priv,
                                               modem_ssr_nb);
+       struct icnss_uevent_fw_down_data fw_down_data;
 
        icnss_pr_dbg("Modem-Notify: event %lu\n", code);
 
@@ -2340,6 +2345,9 @@ static int icnss_modem_notifier_nb(struct notifier_block *nb,
        if (notif->crashed == CRASH_STATUS_WDOG_BITE)
                event_data->wdog_bite = true;
 
+       fw_down_data.crashed = !!notif->crashed;
+       icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, &fw_down_data);
+
        icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
                                ICNSS_EVENT_SYNC, event_data);
 
@@ -2403,6 +2411,7 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
                                               service_notifier_nb);
        enum pd_subsys_state *state = data;
        struct icnss_event_pd_service_down_data *event_data;
+       struct icnss_uevent_fw_down_data fw_down_data;
 
        icnss_pr_dbg("PD service notification: 0x%lx state: 0x%lx\n",
                     notification, priv->state);
@@ -2438,6 +2447,8 @@ static int icnss_service_notifier_notify(struct notifier_block *nb,
 event_post:
        icnss_ignore_qmi_timeout(true);
 
+       fw_down_data.crashed = event_data->crashed;
+       icnss_call_driver_uevent(priv, ICNSS_UEVENT_FW_DOWN, &fw_down_data);
        icnss_driver_event_post(ICNSS_DRIVER_EVENT_PD_SERVICE_DOWN,
                                ICNSS_EVENT_SYNC, event_data);
 done:
index 731fa69..7ef984a 100644 (file)
 enum icnss_uevent {
        ICNSS_UEVENT_FW_READY,
        ICNSS_UEVENT_FW_CRASHED,
+       ICNSS_UEVENT_FW_DOWN,
+};
+
+struct icnss_uevent_fw_down_data {
+       bool crashed;
 };
 
 struct icnss_uevent_data {