cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20);
        cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2);
        cfg->num_multicast_filter_entries = __cpu_to_le32(5);
-       cfg->num_wow_filters = __cpu_to_le32(0x16);
+       cfg->num_wow_filters = __cpu_to_le32(ar->wow.max_num_patterns);
        cfg->num_keep_alive_pattern = __cpu_to_le32(6);
        cfg->keep_alive_pattern_size = __cpu_to_le32(0);
        cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1);
 
 static const struct wiphy_wowlan_support ath10k_wowlan_support = {
        .flags = WIPHY_WOWLAN_DISCONNECT |
                 WIPHY_WOWLAN_MAGIC_PKT,
+       .pattern_min_len = WOW_MIN_PATTERN_SIZE,
+       .pattern_max_len = WOW_MAX_PATTERN_SIZE,
+       .max_pkt_offset = WOW_MAX_PKT_OFFSET,
 };
 
 static int ath10k_wow_vif_cleanup(struct ath10k_vif *arvif)
                }
        }
 
+       for (i = 0; i < ar->wow.max_num_patterns; i++) {
+               ret = ath10k_wmi_wow_del_pattern(ar, arvif->vdev_id, i);
+               if (ret) {
+                       ath10k_warn(ar, "failed to delete wow pattern %d for vdev %i: %d\n",
+                                   i, arvif->vdev_id, ret);
+                       return ret;
+               }
+       }
+
        return 0;
 }
 
        int ret, i;
        unsigned long wow_mask = 0;
        struct ath10k *ar = arvif->ar;
+       const struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
+       int pattern_id = 0;
 
        /* Setup requested WOW features */
        switch (arvif->vdev_type) {
                break;
        }
 
+       for (i = 0; i < wowlan->n_patterns; i++) {
+               u8 bitmask[WOW_MAX_PATTERN_SIZE] = {};
+               int j;
+
+               if (patterns[i].pattern_len > WOW_MAX_PATTERN_SIZE)
+                       continue;
+
+               /* convert bytemask to bitmask */
+               for (j = 0; j < patterns[i].pattern_len; j++)
+                       if (patterns[i].mask[j / 8] & BIT(j % 8))
+                               bitmask[j] = 0xff;
+
+               ret = ath10k_wmi_wow_add_pattern(ar, arvif->vdev_id,
+                                                pattern_id,
+                                                patterns[i].pattern,
+                                                bitmask,
+                                                patterns[i].pattern_len,
+                                                patterns[i].pkt_offset);
+               if (ret) {
+                       ath10k_warn(ar, "failed to add pattern %i to vdev %i: %d\n",
+                                   pattern_id,
+                                   arvif->vdev_id, ret);
+                       return ret;
+               }
+
+               pattern_id++;
+               __set_bit(WOW_PATTERN_MATCH_EVENT, &wow_mask);
+       }
+
        for (i = 0; i < WOW_EVENT_MAX; i++) {
                if (!test_bit(i, &wow_mask))
                        continue;
        if (WARN_ON(!test_bit(WMI_SERVICE_WOW, ar->wmi.svc_map)))
                return -EINVAL;
 
-       ar->hw->wiphy->wowlan = &ath10k_wowlan_support;
+       ar->wow.wowlan_support = ath10k_wowlan_support;
+       ar->wow.wowlan_support.n_patterns = ar->wow.max_num_patterns;
+       ar->hw->wiphy->wowlan = &ar->wow.wowlan_support;
 
        return 0;
 }