From ea20fa5e535f00abeb8078ecfee40d84cba892b2 Mon Sep 17 00:00:00 2001 From: Abhiram Jogadenu Date: Wed, 31 Jul 2019 18:49:59 +0530 Subject: [PATCH] qca-wifi: Add support for CFR capture on unassociated clients As part of FR 56301, add support to capture CFR data for unassociated clients on its Probe response's ACK Change-Id: I14a4eead4ceeb3eb21d8f2bdf76007f873db1f4e CRs-Fixed: 2501938 --- target_if/cfr/inc/target_if_cfr_8074v2.h | 1 - target_if/cfr/src/target_if_cfr_8074v2.c | 2 +- umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h | 28 ++++- umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h | 8 ++ umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c | 105 +++++++++++++++++++ 5 files changed, 140 insertions(+), 4 deletions(-) diff --git a/target_if/cfr/inc/target_if_cfr_8074v2.h b/target_if/cfr/inc/target_if_cfr_8074v2.h index 658d6458da..757ebc117f 100644 --- a/target_if/cfr/inc/target_if_cfr_8074v2.h +++ b/target_if/cfr/inc/target_if_cfr_8074v2.h @@ -21,7 +21,6 @@ #define STREAMFS_MAX_SUBBUF_8S 8500 #define STREAMFS_NUM_SUBBUF_8S 255 -#define MAX_PEERS_HKV2 10 #define PEER_CFR_CAPTURE_EVT_STATUS_MASK 0x80000000 #define CFR_TX_EVT_STATUS_MASK 0x00000003 diff --git a/target_if/cfr/src/target_if_cfr_8074v2.c b/target_if/cfr/src/target_if_cfr_8074v2.c index 8694a1f221..09a116b476 100644 --- a/target_if/cfr/src/target_if_cfr_8074v2.c +++ b/target_if/cfr/src/target_if_cfr_8074v2.c @@ -625,7 +625,7 @@ int cfr_8074v2_init_pdev(struct wlan_objmgr_psoc *psoc, return -EINVAL; } - pdev_cfrobj->cfr_max_sta_count = MAX_PEERS_HKV2; + pdev_cfrobj->cfr_max_sta_count = MAX_CFR_ENABLED_CLIENTS; pdev_cfrobj->subbuf_size = STREAMFS_MAX_SUBBUF_8S; pdev_cfrobj->num_subbufs = STREAMFS_NUM_SUBBUF_8S; diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h index 4ed242e9fb..c8c0a21e80 100644 --- a/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h +++ b/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h @@ -25,7 +25,7 @@ #define MAX_CFR_PRD (10*60*1000) /* 10 minutes */ /** - * ucfg_cfr_start_capture() - function to start cfr capture + * ucfg_cfr_start_capture() - function to start cfr capture for connected client * @pdev: pointer to pdev object * @peer: pointer to peer object * @cfr_params: config params to cfr capture @@ -37,7 +37,7 @@ int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, struct cfr_capture_params *cfr_params); /** - * ucfg_cfr_stop_capture() - function to stop cfr capture + * ucfg_cfr_stop_capture() - function to stop cfr capture for connected client * @pdev: pointer to pdev object * @peer: pointer to peer object * @@ -46,6 +46,30 @@ int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_peer *peer); +/** + * ucfg_cfr_start_capture_probe_req() - function to start cfr capture for + * unassociated clients + * @pdev: pointer to pdev object + * @unassoc_mac: mac address of un-associated client + * @cfr_params: config params to cfr capture + * + * Return: status of start capture. + */ +int ucfg_cfr_start_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac, + struct cfr_capture_params *params); + +/** + * ucfg_cfr_stop_capture_probe_req() - function to stop cfr capture for + * unassociated cleints + * @pdev: pointer to pdev object + * @unassoc_mac: mac address of un-associated client + * + * Return: status of stop capture. + */ +int ucfg_cfr_stop_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac); + /** * ucfg_cfr_list_peers() - Lists total number of peers with cfr capture enabled * @pdev: pointer to pdev object diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h index aa8c80e7fe..d36c7239d5 100644 --- a/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h +++ b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h @@ -39,6 +39,7 @@ #define DBR_EVENT_TIMEOUT_IN_MS_CFR 1 #define DBR_NUM_RESP_PER_EVENT_CFR 1 +#define MAX_CFR_ENABLED_CLIENTS 10 enum cfrmetaversion { CFR_META_VERSION_NONE, @@ -196,6 +197,12 @@ struct look_up_table { struct whal_cfir_dma_hdr dma_hdr; }; +struct unassoc_pool_entry { + struct qdf_mac_addr mac; + struct cfr_capture_params cfr_params; + bool is_valid; +}; + /** * struct pdev_cfr - private pdev object for cfr * pdev_obj: pointer to pdev object @@ -223,6 +230,7 @@ struct pdev_cfr { uint32_t tx_evt_cnt; uint32_t dbr_evt_cnt; uint32_t release_cnt; + struct unassoc_pool_entry unassoc_pool[MAX_CFR_ENABLED_CLIENTS]; }; #define PEER_CFR_CAPTURE_ENABLE 1 diff --git a/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c index 734e6b415f..6212a3ef5b 100644 --- a/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c +++ b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c @@ -86,6 +86,111 @@ int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, return status; } +int ucfg_cfr_start_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac, + struct cfr_capture_params *params) +{ + int idx, idx_to_insert = -1; + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (!pa) { + cfr_err("Pdev cfr object is null!"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + cfr_err("CFR is not supported on this chip"); + return -EINVAL; + } + + if (pa->cfr_current_sta_count == pa->cfr_max_sta_count) { + cfr_err("max cfr cleint reached"); + return -EINVAL; + } + + for (idx = 0; idx < MAX_CFR_ENABLED_CLIENTS; idx++) { + /* Store first invalid entry's index, to add mac entry if not + * already present. + */ + if (idx_to_insert < 0) { + if (pa->unassoc_pool[idx].is_valid != true) + idx_to_insert = idx; + } + + /* Add new mac entry only if it is not present. If already + * present, update the capture parameters + */ + if (qdf_mem_cmp(&pa->unassoc_pool[idx].mac, unassoc_mac, + sizeof(struct qdf_mac_addr)) == 0) { + cfr_info("Node already present. Updating params"); + qdf_mem_copy(&pa->unassoc_pool[idx].cfr_params, + params, + sizeof(struct cfr_capture_params)); + pa->unassoc_pool[idx].is_valid = true; + return 0; + } + } + + if (idx_to_insert < 0) { + /* All the entries in the table are valid. So we have reached + * max client capacity. To add a new client, capture on one of + * the clients in table has to be stopped. + */ + cfr_err("Maximum client capacity reached"); + return -EINVAL; + } + + /* If control reaches here, we did not find mac in the table + * and we have atleast one free entry in table. + * Add the entry at index = idx_to_insert + */ + qdf_mem_copy(&pa->unassoc_pool[idx_to_insert].mac, + unassoc_mac, sizeof(struct qdf_mac_addr)); + qdf_mem_copy(&pa->unassoc_pool[idx_to_insert].cfr_params, + params, sizeof(struct cfr_capture_params)); + pa->unassoc_pool[idx_to_insert].is_valid = true; + pa->cfr_current_sta_count++; + + return 0; +} + +int ucfg_cfr_stop_capture_probe_req(struct wlan_objmgr_pdev *pdev, + struct qdf_mac_addr *unassoc_mac) +{ + struct pdev_cfr *pa; + int idx; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (!pa) { + cfr_err("Pdev cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + cfr_err("CFR is not supported on this chip\n"); + return -EINVAL; + } + + for (idx = 0; idx < MAX_CFR_ENABLED_CLIENTS; idx++) { + /* Remove mac only if it is present */ + if (qdf_mem_cmp(&pa->unassoc_pool[idx].mac, unassoc_mac, + sizeof(struct qdf_mac_addr)) == 0) { + qdf_mem_zero(&pa->unassoc_pool[idx], + sizeof(struct unassoc_pool_entry)); + pa->cfr_current_sta_count--; + return 0; + } + } + + /* If mac was present in pool it would have been deleted in the + * above loop and returned from there. + * If control reached here, mac was not found. So, ignore the request. + */ + cfr_err("Trying to delete mac not present in pool. Ignoring request."); + return 0; +} + int ucfg_cfr_set_timer(struct wlan_objmgr_pdev *pdev, uint32_t value) { struct pdev_cfr *pa;