]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ath10k: add WOW patterns support
authorJanusz Dziedzic <janusz.dziedzic@tieto.com>
Mon, 23 Mar 2015 15:32:54 +0000 (17:32 +0200)
committerKalle Valo <kvalo@qca.qualcomm.com>
Mon, 30 Mar 2015 06:10:24 +0000 (09:10 +0300)
Add patterns support for WOW.

Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
drivers/net/wireless/ath/ath10k/core.c
drivers/net/wireless/ath/ath10k/hw.h
drivers/net/wireless/ath/ath10k/wmi-tlv.c
drivers/net/wireless/ath/ath10k/wmi.h
drivers/net/wireless/ath/ath10k/wow.c
drivers/net/wireless/ath/ath10k/wow.h

index e7fc531993ea46dddbc108424d868ec3518f0622..02da72ec99cf8be036d4c66a0544726573f944f6 100644 (file)
@@ -972,6 +972,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
                ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
                ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
                ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
+               ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
                break;
        case ATH10K_FW_WMI_OP_VERSION_UNSET:
        case ATH10K_FW_WMI_OP_VERSION_MAX:
index 7f04645414136182e73407843c2bf847878f3e16..22c993d4fdfceee9cf640d1b85bc5035c382eefd 100644 (file)
@@ -263,6 +263,7 @@ struct ath10k_pktlog_hdr {
                                                 2)
 #define TARGET_TLV_NUM_TIDS                    ((TARGET_TLV_NUM_PEERS) * 2)
 #define TARGET_TLV_NUM_MSDU_DESC               (1024 + 32)
+#define TARGET_TLV_NUM_WOW_PATTERNS            22
 
 /* Number of Copy Engines supported */
 #define CE_COUNT 8
index 923f5a66c60bccd98fb259c02ecdd7738eef3e52..afb822caca94566b269f100fbfd2ccb3d3f9d847 100644 (file)
@@ -1307,7 +1307,7 @@ static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar)
        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);
index 6ff8456d6cf476e0ac91c69c8130f04d50191d9f..f95b6982af92377fb9f034817981c9dd4d32240b 100644 (file)
@@ -5028,6 +5028,10 @@ struct wmi_wow_ev_arg {
        u32 data_len;
 };
 
+#define WOW_MIN_PATTERN_SIZE   1
+#define WOW_MAX_PATTERN_SIZE   148
+#define WOW_MAX_PKT_OFFSET     128
+
 struct ath10k;
 struct ath10k_vif;
 struct ath10k_fw_stats_pdev;
index dc1b02580e79766f9bb28027085ffc519c000177..a68d8fd853a3bb6f314a5c26d8f480c8d00a1792 100644 (file)
@@ -26,6 +26,9 @@
 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)
@@ -42,6 +45,15 @@ 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;
 }
 
@@ -70,6 +82,8 @@ static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif,
        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) {
@@ -100,6 +114,35 @@ static int ath10k_vif_wow_set_wakeups(struct ath10k_vif *arvif,
                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;
@@ -270,7 +313,9 @@ int ath10k_wow_init(struct ath10k *ar)
        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;
 }
index 21c43c9c91e095f96cb43571bab424a37157280c..abbb04b6d1bd9a2174f8fce1cb3b84975ce8df86 100644 (file)
@@ -17,7 +17,9 @@
 #define _WOW_H_
 
 struct ath10k_wow {
+       u32 max_num_patterns;
        struct completion wakeup_completed;
+       struct wiphy_wowlan_support wowlan_support;
 };
 
 #ifdef CONFIG_PM