Merge 5.17-rc6 into char-misc-next
[linux-2.6-microblaze.git] / drivers / net / wireless / intel / iwlwifi / mei / main.c
index d9733aa..2f7f0f9 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2021 Intel Corporation
+ * Copyright (C) 2021-2022 Intel Corporation
  */
 
 #include <linux/etherdevice.h>
@@ -146,6 +146,7 @@ struct iwl_mei_filters {
  * @csme_taking_ownership: true when CSME is taking ownership. Used to remember
  *     to send CSME_OWNERSHIP_CONFIRMED when the driver completes its down
  *     flow.
+ * @link_prot_state: true when we are in link protection PASSIVE
  * @csa_throttle_end_wk: used when &csa_throttled is true
  * @data_q_lock: protects the access to the data queues which are
  *     accessed without the mutex.
@@ -165,6 +166,7 @@ struct iwl_mei {
        bool amt_enabled;
        bool csa_throttled;
        bool csme_taking_ownership;
+       bool link_prot_state;
        struct delayed_work csa_throttle_end_wk;
        spinlock_t data_q_lock;
 
@@ -229,8 +231,6 @@ static int iwl_mei_alloc_shared_mem(struct mei_cl_device *cldev)
        if (IS_ERR(mem->ctrl)) {
                int ret = PTR_ERR(mem->ctrl);
 
-               dev_err(&cldev->dev, "Couldn't allocate the shared memory: %d\n",
-                       ret);
                mem->ctrl = NULL;
 
                return ret;
@@ -669,6 +669,8 @@ iwl_mei_handle_conn_status(struct mei_cl_device *cldev,
 
        iwl_mei_cache.ops->me_conn_status(iwl_mei_cache.priv, &conn_info);
 
+       mei->link_prot_state = status->link_prot_state;
+
        /*
         * Update the Rfkill state in case the host does not own the device:
         * if we are in Link Protection, ask to not touch the device, else,
@@ -1663,9 +1665,11 @@ int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
                        mei_cldev_get_drvdata(iwl_mei_global_cldev);
 
                /* we have already a SAP connection */
-               if (iwl_mei_is_connected())
+               if (iwl_mei_is_connected()) {
                        iwl_mei_send_sap_msg(mei->cldev,
                                             SAP_MSG_NOTIF_WIFIDR_UP);
+                       ops->rfkill(priv, mei->link_prot_state);
+               }
        }
        ret = 0;
 
@@ -1784,6 +1788,8 @@ static void iwl_mei_dbgfs_unregister(struct iwl_mei *mei) {}
 
 #endif /* CONFIG_DEBUG_FS */
 
+#define ALLOC_SHARED_MEM_RETRY_MAX_NUM 3
+
 /*
  * iwl_mei_probe - the probe function called by the mei bus enumeration
  *
@@ -1795,6 +1801,7 @@ static void iwl_mei_dbgfs_unregister(struct iwl_mei *mei) {}
 static int iwl_mei_probe(struct mei_cl_device *cldev,
                         const struct mei_cl_device_id *id)
 {
+       int alloc_retry = ALLOC_SHARED_MEM_RETRY_MAX_NUM;
        struct iwl_mei *mei;
        int ret;
 
@@ -1812,15 +1819,31 @@ static int iwl_mei_probe(struct mei_cl_device *cldev,
        mei_cldev_set_drvdata(cldev, mei);
        mei->cldev = cldev;
 
-       /*
-        * The CSME firmware needs to boot the internal WLAN client. Wait here
-        * so that the DMA map request will succeed.
-        */
-       msleep(20);
+       do {
+               ret = iwl_mei_alloc_shared_mem(cldev);
+               if (!ret)
+                       break;
+               /*
+                * The CSME firmware needs to boot the internal WLAN client.
+                * This can take time in certain configurations (usually
+                * upon resume and when the whole CSME firmware is shut down
+                * during suspend).
+                *
+                * Wait a bit before retrying and hope we'll succeed next time.
+                */
 
-       ret = iwl_mei_alloc_shared_mem(cldev);
-       if (ret)
+               dev_dbg(&cldev->dev,
+                       "Couldn't allocate the shared memory: %d, attempt %d / %d\n",
+                       ret, alloc_retry, ALLOC_SHARED_MEM_RETRY_MAX_NUM);
+               msleep(100);
+               alloc_retry--;
+       } while (alloc_retry);
+
+       if (ret) {
+               dev_err(&cldev->dev, "Couldn't allocate the shared memory: %d\n",
+                       ret);
                goto free;
+       }
 
        iwl_mei_init_shared_mem(mei);