return ret;
 }
 
-static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
+                                 struct cfg80211_wowlan *wow, u32 *filter)
 {
+       struct ath6kl *ar = vif->ar;
        struct in_device *in_dev;
        struct in_ifaddr *ifa;
-       struct ath6kl_vif *vif;
        int ret;
-       u32 filter = 0;
        u16 i, bmiss_time;
-       u8 index = 0;
        __be32 ips[MAX_IP_ADDRS];
-
-       /* The FW currently can't support multi-vif WoW properly. */
-       if (ar->num_vif > 1)
-               return -EIO;
-
-       vif = ath6kl_vif_first(ar);
-       if (!vif)
-               return -EIO;
-
-       if (!ath6kl_cfg80211_ready(vif))
-               return -EIO;
-
-       if (!test_bit(CONNECTED, &vif->flags))
-               return -ENOTCONN;
-
-       if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
-               return -EINVAL;
+       u8 index = 0;
 
        if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
         * the user.
         */
        if (wow)
-               ret = ath6kl_wow_usr(ar, vif, wow, &filter);
+               ret = ath6kl_wow_usr(ar, vif, wow, filter);
        else if (vif->nw_type == AP_NETWORK)
                ret = ath6kl_wow_ap(ar, vif);
        else
                        return ret;
        }
 
-       ar->state = ATH6KL_STATE_SUSPENDING;
-
        /* Setup own IP addr for ARP agent. */
        in_dev = __in_dev_get_rtnl(vif->ndev);
        if (!in_dev)
-               goto skip_arp;
+               return 0;
 
        ifa = in_dev->ifa_list;
        memset(&ips, 0, sizeof(ips));
                return ret;
        }
 
-skip_arp:
-       ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
+       return ret;
+}
+
+static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
+{
+       struct ath6kl_vif *first_vif, *vif;
+       int ret = 0;
+       u32 filter = 0;
+       bool connected = false;
+
+       /* enter / leave wow suspend on first vif always */
+       first_vif = ath6kl_vif_first(ar);
+       if (WARN_ON(unlikely(!first_vif)) ||
+           !ath6kl_cfg80211_ready(first_vif))
+               return -EIO;
+
+       if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
+               return -EINVAL;
+
+       /* install filters for each connected vif */
+       spin_lock_bh(&ar->list_lock);
+       list_for_each_entry(vif, &ar->vif_list, list) {
+               if (!test_bit(CONNECTED, &vif->flags) ||
+                   !ath6kl_cfg80211_ready(vif))
+                       continue;
+               connected = true;
+
+               ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
+               if (ret)
+                       break;
+       }
+       spin_unlock_bh(&ar->list_lock);
+
+       if (!connected)
+               return -ENOTCONN;
+       else if (ret)
+               return ret;
+
+       ar->state = ATH6KL_STATE_SUSPENDING;
+
+       ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
                                          ATH6KL_WOW_MODE_ENABLE,
                                          filter,
                                          WOW_HOST_REQ_DELAY);
        if (ret)
                return ret;
 
-       ret = ath6kl_cfg80211_host_sleep(ar, vif);
-       if (ret)
-               return ret;
-
-       return 0;
+       return ath6kl_cfg80211_host_sleep(ar, first_vif);
 }
 
-static int ath6kl_wow_resume(struct ath6kl *ar)
+static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
 {
-       struct ath6kl_vif *vif;
+       struct ath6kl *ar = vif->ar;
        int ret;
 
-       vif = ath6kl_vif_first(ar);
-       if (!vif)
-               return -EIO;
-
-       ar->state = ATH6KL_STATE_RESUMING;
-
-       ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
-                                                ATH6KL_HOST_MODE_AWAKE);
-       if (ret) {
-               ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
-                           ret);
-               ar->state = ATH6KL_STATE_WOW;
-               return ret;
-       }
-
        if (vif->nw_type != AP_NETWORK) {
                ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
                                                0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
                        return ret;
        }
 
-       ar->state = ATH6KL_STATE_ON;
-
        if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
            test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
                     ar->fw_capabilities)) {
                ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
-                                       vif->fw_vif_idx, true);
+                                                 vif->fw_vif_idx, true);
                if (ret)
                        return ret;
        }
        return 0;
 }
 
+static int ath6kl_wow_resume(struct ath6kl *ar)
+{
+       struct ath6kl_vif *vif;
+       int ret;
+
+       vif = ath6kl_vif_first(ar);
+       if (WARN_ON(unlikely(!vif)) ||
+           !ath6kl_cfg80211_ready(vif))
+               return -EIO;
+
+       ar->state = ATH6KL_STATE_RESUMING;
+
+       ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
+                                                ATH6KL_HOST_MODE_AWAKE);
+       if (ret) {
+               ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
+                           ret);
+               goto cleanup;
+       }
+
+       spin_lock_bh(&ar->list_lock);
+       list_for_each_entry(vif, &ar->vif_list, list) {
+               if (!test_bit(CONNECTED, &vif->flags) ||
+                   !ath6kl_cfg80211_ready(vif))
+                       continue;
+               ret = ath6kl_wow_resume_vif(vif);
+               if (ret)
+                       break;
+       }
+       spin_unlock_bh(&ar->list_lock);
+
+       if (ret)
+               goto cleanup;
+
+       ar->state = ATH6KL_STATE_ON;
+       return 0;
+
+cleanup:
+       ar->state = ATH6KL_STATE_WOW;
+       return ret;
+}
+
 static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
 {
        struct ath6kl_vif *vif;