void iwl_mei_host_disassociated(void);
 
 /**
- * iwl_mei_device_down() - must be called when the device is down
+ * iwl_mei_device_state() - must be called when the device changes up/down state
+ * @up: true if the device is up, false otherwise.
  */
-void iwl_mei_device_down(void);
+void iwl_mei_device_state(bool up);
 
 #else
 
 static inline void iwl_mei_host_disassociated(void)
 {}
 
-static inline void iwl_mei_device_down(void)
+static inline void iwl_mei_device_state(bool up)
 {}
 
 #endif /* CONFIG_IWLMEI */
 
  *     to send CSME_OWNERSHIP_CONFIRMED when the driver completes its down
  *     flow.
  * @link_prot_state: true when we are in link protection PASSIVE
+ * @device_down: true if the device is down. Used to remember to send
+ *     CSME_OWNERSHIP_CONFIRMED when the driver is already down.
  * @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.
        bool csa_throttled;
        bool csme_taking_ownership;
        bool link_prot_state;
+       bool device_down;
        struct delayed_work csa_throttle_end_wk;
        spinlock_t data_q_lock;
 
 
        mei->got_ownership = false;
 
-       /*
-        * Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi driver
-        * is finished taking the device down.
-        */
-       mei->csme_taking_ownership = true;
+       if (iwl_mei_cache.ops && !mei->device_down) {
+               /*
+                * Remember to send CSME_OWNERSHIP_CONFIRMED when the wifi
+                * driver is finished taking the device down.
+                */
+               mei->csme_taking_ownership = true;
 
-       if (iwl_mei_cache.ops)
-               iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true);
+               iwl_mei_cache.ops->rfkill(iwl_mei_cache.priv, true, true);
+       } else {
+               iwl_mei_send_sap_msg(cldev,
+                                    SAP_MSG_NOTIF_CSME_OWNERSHIP_CONFIRMED);
+       }
 }
 
 static void iwl_mei_handle_nvm(struct mei_cl_device *cldev,
 }
 EXPORT_SYMBOL_GPL(iwl_mei_set_netdev);
 
-void iwl_mei_device_down(void)
+void iwl_mei_device_state(bool up)
 {
        struct iwl_mei *mei;
 
        if (!mei)
                goto out;
 
-       if (!mei->csme_taking_ownership)
+       mei->device_down = !up;
+
+       if (up || !mei->csme_taking_ownership)
                goto out;
 
        iwl_mei_send_sap_msg(mei->cldev,
 out:
        mutex_unlock(&iwl_mei_mutex);
 }
-EXPORT_SYMBOL_GPL(iwl_mei_device_down);
+EXPORT_SYMBOL_GPL(iwl_mei_device_state);
 
 int iwl_mei_register(void *priv, const struct iwl_mei_ops *ops)
 {
 
        mei_cldev_set_drvdata(cldev, mei);
        mei->cldev = cldev;
+       mei->device_down = true;
 
        do {
                ret = iwl_mei_alloc_shared_mem(cldev);