diff --git a/target_if/cfr/inc/target_if_cfr.h b/target_if/cfr/inc/target_if_cfr.h index 0d1e39d47c..79cc6da00e 100644 --- a/target_if/cfr/inc/target_if_cfr.h +++ b/target_if/cfr/inc/target_if_cfr.h @@ -21,8 +21,6 @@ #include #include -#define PEER_CFR_CAPTURE_ENABLE 1 -#define PEER_CFR_CAPTURE_DISABLE 0 #define IEEE80211_ADDR_LEN 6 struct cfr_metadata_version_1 { diff --git a/target_if/cfr/src/target_if_cfr.c b/target_if/cfr/src/target_if_cfr.c index 5616c5831e..416f536d8c 100644 --- a/target_if/cfr/src/target_if_cfr.c +++ b/target_if/cfr/src/target_if_cfr.c @@ -33,11 +33,16 @@ int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_peer *peer) { + struct peer_cfr *pe; struct peer_cfr_params param = {0}; struct common_wmi_handle *pdev_wmi_handle = NULL; struct wlan_objmgr_vdev *vdev = {0}; int retv = 0; + pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); + if (pe == NULL) + return -EINVAL; + pdev_wmi_handle = lmac_get_pdev_wmi_handle(pdev); vdev = wlan_peer_get_vdev(peer); @@ -47,6 +52,10 @@ int target_if_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, param.macaddr = wlan_peer_get_macaddr(peer); param.vdev_id = wlan_vdev_get_id(vdev); + param.periodicity = pe->period; + param.bandwidth = pe->bandwidth; + param.capture_method = pe->capture_method; + retv = wmi_unified_send_peer_cfr_capture_cmd(pdev_wmi_handle, ¶m); return retv; @@ -98,18 +107,31 @@ int target_if_cfr_pdev_set_param(struct wlan_objmgr_pdev *pdev, int target_if_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer) { + struct pdev_cfr *pa; int retval; + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) + return QDF_STATUS_E_FAILURE; + if (!cfr_timer) { + /* disable periodic cfr capture */ retval = target_if_cfr_pdev_set_param(pdev, wmi_pdev_param_per_peer_prd_cfr_enable, WMI_HOST_PEER_CFR_TIMER_DISABLE); + + if (retval == QDF_STATUS_SUCCESS) + pa->cfr_timer_enable = 0; } else { + /* enable periodic cfr capture (default base timer is 10ms ) */ retval = target_if_cfr_pdev_set_param(pdev, wmi_pdev_param_per_peer_prd_cfr_enable, WMI_HOST_PEER_CFR_TIMER_ENABLE); + + if (retval == QDF_STATUS_SUCCESS) + pa->cfr_timer_enable = 1; } return retval; diff --git a/target_if/cfr/src/target_if_cfr_wifi2_0.c b/target_if/cfr/src/target_if_cfr_wifi2_0.c index 8c22e83844..b15889078e 100644 --- a/target_if/cfr/src/target_if_cfr_wifi2_0.c +++ b/target_if/cfr/src/target_if_cfr_wifi2_0.c @@ -40,8 +40,8 @@ #define NUM_SUBBUF_2S 2200 /* max subbuf size and number for 4 chains */ -#define MAX_SUBBUF_4S 2304 -#define NUM_SUBBUF_4S 910 +#define MAX_SUBBUF_4S 2200 +#define NUM_SUBBUF_4S 1100 #define MAX_CFR_CLIENTS_LEGACY 10 enum cfrmetaversion { @@ -109,7 +109,7 @@ target_if_mac_addr_deswizzle(u_int8_t *tgt_mac_addr, u_int8_t *buffer) #endif } -int ol_txrx_htt_cfr_rx_ind_handler(void *pdev_ptr, +QDF_STATUS ol_txrx_htt_cfr_rx_ind_handler(void *pdev_ptr, uint32_t *msg_word, size_t msg_len) { struct wlan_objmgr_pdev *pdev; @@ -131,20 +131,21 @@ int ol_txrx_htt_cfr_rx_ind_handler(void *pdev_ptr, status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_CFR_ID); if (QDF_IS_STATUS_ERROR(status)) { - qdf_print("%s, %d unable to get reference", __func__, __LINE__); + cfr_err("%s,%d unable to get reference", __func__, __LINE__); return status; } pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); if (pa == NULL) { + cfr_err("pdev_cfr is NULL\n"); wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); - return -1; + return QDF_STATUS_E_FAILURE; } if (!pa->is_cfr_capable) { - qdf_print("CFR capture not enabled/supported in Host SW\n"); + cfr_err("CFR capture not enabled/supported in Host SW\n"); wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); - return -1; + return QDF_STATUS_E_FAILURE; } psoc = wlan_pdev_get_psoc(pdev); @@ -225,9 +226,9 @@ int ol_txrx_htt_cfr_rx_ind_handler(void *pdev_ptr, break; default: - qdf_print(" Unsupported CFR capture type:%d\n", cfr_msg_type); + cfr_err("Unsupported CFR capture type:%d\n", cfr_msg_type); wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); - return -1; + return QDF_STATUS_E_NOSUPPORT; } vaddr = pa->cfr_mem_chunk.vaddr; @@ -247,9 +248,12 @@ int ol_txrx_htt_cfr_rx_ind_handler(void *pdev_ptr, prindex, cfr_dump_len, &end_magic, 4); } + cfr_debug("CFR:%s status=%d rindex=%x dump_len=%d\n", __func__, + cfr_cap_status, prindex, cfr_dump_len); + wlan_objmgr_pdev_release_ref(pdev, WLAN_CFR_ID); - return 0; + return QDF_STATUS_SUCCESS; } EXPORT_SYMBOL(ol_txrx_htt_cfr_rx_ind_handler); @@ -295,14 +299,14 @@ cfr_wifi2_0_init_pdev(struct wlan_objmgr_psoc *psoc, read_offset = pa->cfr_mem_chunk.vaddr; (*read_offset) = CFR_CAPTURE_HOST_MEM_DEFAULT_READ_OFFSET; - qdf_print("CFR:%s reqid=%d len=%d\n", __func__, + cfr_debug("CFR:%s reqid=%d len=%d\n", __func__, pa->cfr_mem_chunk.req_id, pa->cfr_mem_chunk.len); } if (idx >= info->num_mem_chunks) { pa->is_cfr_capable = 0; - qdf_info("CFR Shared memory not allocated\n"); + cfr_err("CFR Shared memory not allocated\n"); return QDF_STATUS_E_NOMEM; } diff --git a/tools/linux/cfr_test_app.c b/tools/linux/cfr_test_app.c index 417e3e386c..dd620d8fdd 100644 --- a/tools/linux/cfr_test_app.c +++ b/tools/linux/cfr_test_app.c @@ -42,7 +42,8 @@ #define CFR_DUMP_STREAMFS_FILE "/sys/kernel/debug/cfr%s/cfr_dump0" #define CFR_DUMP_FILE "/tmp/cfr_dump_%s.bin" -#define MAX_CAPTURE_SIZE 2048 +#define MAX_FILE_SIZE (8 * 1024 * 1024) +#define MAX_CAPTURE_SIZE (4096) static char rbuffer[MAX_CAPTURE_SIZE]; int stop_capture; @@ -54,13 +55,21 @@ void print_usage(char *argv[]) void streamfs_read_handler(int sfd, int cfd) { - int rlen = 0; + int rlen = 0, retval = 0; memset(rbuffer, 0, sizeof(rbuffer)); rlen = read(sfd, rbuffer, sizeof(rbuffer)); if (rlen <= 0) return; + if (lseek(cfd, 0, SEEK_CUR) + rlen > MAX_FILE_SIZE) { + retval = lseek(cfd, 0, SEEK_SET); + if (retval < 0) { + perror("lseek()"); + exit(EXIT_FAILURE); + } + } + write(cfd, rbuffer, rlen); } diff --git a/umac/cfr/core/src/cfr_common.c b/umac/cfr/core/src/cfr_common.c index 9f5de520a2..f26f046080 100644 --- a/umac/cfr/core/src/cfr_common.c +++ b/umac/cfr/core/src/cfr_common.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -135,13 +137,30 @@ QDF_STATUS wlan_cfr_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg) { struct peer_cfr *pe = NULL; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_pdev *pdev; + struct pdev_cfr *pa = NULL; if (NULL == peer) { cfr_err("PEER is NULL\n"); return QDF_STATUS_E_FAILURE; } + vdev = wlan_peer_get_vdev(peer); + if (vdev) + pdev = wlan_vdev_get_pdev(vdev); + + if (pdev) + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, + WLAN_UMAC_COMP_CFR); + pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); + + if (pa && pe) { + if (pe->period && pe->request) + pa->cfr_current_sta_count--; + } + if (NULL != pe) { wlan_objmgr_peer_component_obj_detach(peer, WLAN_UMAC_COMP_CFR, (void *)pe); diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h index a0e9a1ffbe..e1425c56d1 100644 --- a/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h +++ b/umac/cfr/dispatcher/inc/wlan_cfr_tgt_api.h @@ -78,8 +78,10 @@ int tgt_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, * tgt_cfr_enable_cfr_timer() - API to enable cfr timer * @pdev: pointer to pdev_object * @cfr_timer: Amount of time this timer has to run. If 0, it disables timer. + * + * Return: success/failure of timer enable */ -void +int tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer); /** diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h index dadb98066e..4ed242e9fb 100644 --- a/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h +++ b/umac/cfr/dispatcher/inc/wlan_cfr_ucfg_api.h @@ -22,13 +22,15 @@ #include #include +#define MAX_CFR_PRD (10*60*1000) /* 10 minutes */ + /** * ucfg_cfr_start_capture() - function to start cfr capture * @pdev: pointer to pdev object * @peer: pointer to peer object * @cfr_params: config params to cfr capture * - * Return: startus of start capture. + * Return: status of start capture. */ int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_peer *peer, @@ -39,7 +41,7 @@ int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, * @pdev: pointer to pdev object * @peer: pointer to peer object * - * Return: startus of stop capture. + * Return: status of stop capture. */ int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_peer *peer); @@ -51,4 +53,21 @@ int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, * Return: number of peers with cfr capture enabled */ int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev); + +/** + * ucfg_cfr_set_timer() - function to enable cfr timer + * @pdev: pointer to pdev object + * @value: value to be set + * + * Return: status of timer enable + */ +int ucfg_cfr_set_timer(struct wlan_objmgr_pdev *pdev, uint32_t value); + +/** + * ucfg_cfr_get_timer() - function to get cfr_timer_enable + * @pdev: pointer to pdev object + * + * Return: value of cfr_timer_enable + */ +int ucfg_cfr_get_timer(struct wlan_objmgr_pdev *pdev); #endif diff --git a/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h index 49530e84ef..e7b55a3f41 100644 --- a/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h +++ b/umac/cfr/dispatcher/inc/wlan_cfr_utils_api.h @@ -101,6 +101,8 @@ struct pdev_cfr { */ }; +#define PEER_CFR_CAPTURE_ENABLE 1 +#define PEER_CFR_CAPTURE_DISABLE 0 /** * struct peer_cfr - private peer object for cfr * peer_obj: pointer to peer_obj diff --git a/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c b/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c index b5cd0f6cea..c4198e6389 100644 --- a/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c +++ b/umac/cfr/dispatcher/src/wlan_cfr_tgt_api.c @@ -69,6 +69,8 @@ void tgt_cfr_support_set(struct wlan_objmgr_psoc *psoc, uint32_t value) return; cfr_sc->is_cfr_capable = !!value; + cfr_debug("CFR:%s FW support advert=%d\n", __func__, + cfr_sc->is_cfr_capable); } static inline struct wlan_lmac_if_cfr_tx_ops * @@ -161,15 +163,20 @@ int tgt_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, return status; } -void +int tgt_cfr_enable_cfr_timer(struct wlan_objmgr_pdev *pdev, uint32_t cfr_timer) { + int status; struct wlan_lmac_if_cfr_tx_ops *cfr_tx_ops = NULL; struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev); cfr_tx_ops = wlan_psoc_get_cfr_txops(psoc); if (cfr_tx_ops->cfr_enable_cfr_timer) - cfr_tx_ops->cfr_enable_cfr_timer(pdev, cfr_timer); + status = cfr_tx_ops->cfr_enable_cfr_timer(pdev, cfr_timer); + if (status != 0) + cfr_err("Error occurred with exit code %d\n", status); + + return status; } diff --git a/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c index 5d025438a2..52519585b0 100644 --- a/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c +++ b/umac/cfr/dispatcher/src/wlan_cfr_ucfg_api.c @@ -27,53 +27,131 @@ int ucfg_cfr_start_capture(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_peer *peer, struct cfr_capture_params *params) { + int status; struct pdev_cfr *pa; struct peer_cfr *pe; - if (NULL == pdev) { - cfr_err("PDEV is NULL!\n"); - return -EINVAL; - } pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); if (NULL == pa) { cfr_err("PDEV cfr object is NULL!\n"); return -EINVAL; } + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); + return -EINVAL; + } + /* Get peer private object */ pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); if (NULL == pe) { cfr_err("PEER cfr object is NULL!\n"); return -EINVAL; } - pe->bandwidth = params->bandwidth; - pe->period = params->period; - pe->capture_method = params->method; - if (params->period != 0) { - if (!(params->period % 10)) - tgt_cfr_enable_cfr_timer(pdev, 1); - else - return -EINVAL; + if ((params->period < 0) || (params->period > MAX_CFR_PRD) || + (params->period % 10) || + (!(params->period) && (pa->cfr_timer_enable))) { + qdf_info("Invalid period\n"); + return -EINVAL; } - return tgt_cfr_start_capture(pdev, peer, params); + if (params->period) { + if (pa->cfr_current_sta_count == pa->cfr_max_sta_count) { + qdf_info("max periodic cfr clients reached\n"); + return -EINVAL; + } + if (!(pe->request)) + pa->cfr_current_sta_count++; + } + + status = tgt_cfr_start_capture(pdev, peer, params); + + if (status == 0) { + pe->bandwidth = params->bandwidth; + pe->period = params->period; + pe->capture_method = params->method; + pe->request = PEER_CFR_CAPTURE_ENABLE; + } else + pa->cfr_current_sta_count--; + + return status; } +int ucfg_cfr_set_timer(struct wlan_objmgr_pdev *pdev, uint32_t value) +{ + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) { + cfr_err("PDEV cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); + return -EINVAL; + } + + return tgt_cfr_enable_cfr_timer(pdev, value); +} +qdf_export_symbol(ucfg_cfr_set_timer); + +int ucfg_cfr_get_timer(struct wlan_objmgr_pdev *pdev) +{ + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) { + cfr_err("PDEV cfr object is NULL!\n"); + return -EINVAL; + } + + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); + return -EINVAL; + } + + return pa->cfr_timer_enable; +} +qdf_export_symbol(ucfg_cfr_get_timer); + int ucfg_cfr_stop_capture(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_peer *peer) { - if (NULL == pdev) { - cfr_err("pdev is null!\n"); + int status; + struct peer_cfr *pe; + struct pdev_cfr *pa; + + pa = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_UMAC_COMP_CFR); + if (pa == NULL) { + cfr_err("PDEV cfr object is NULL!\n"); return -EINVAL; } - if (NULL == peer) { - cfr_err("peer is null!\n"); + if (!(pa->is_cfr_capable)) { + qdf_info("cfr is not supported on this chip\n"); return -EINVAL; } - return tgt_cfr_stop_capture(pdev, peer); + pe = wlan_objmgr_peer_get_comp_private_obj(peer, WLAN_UMAC_COMP_CFR); + if (pe == NULL) { + cfr_err("PEER cfr object is NULL!\n"); + return -EINVAL; + } + + if ((pe->period) && (pe->request)) + status = tgt_cfr_stop_capture(pdev, peer); + else { + qdf_info("periodic cfr not started for the client\n"); + return -EINVAL; + } + + if (status == 0) + pe->request = PEER_CFR_CAPTURE_DISABLE; + pa->cfr_current_sta_count--; + + return status; } int ucfg_cfr_list_peers(struct wlan_objmgr_pdev *pdev) diff --git a/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c b/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c index 018086d0f3..2021592402 100644 --- a/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c +++ b/umac/cfr/dispatcher/src/wlan_cfr_utils_api.c @@ -138,6 +138,9 @@ QDF_STATUS cfr_initialize_pdev(struct wlan_objmgr_pdev *pdev) status = tgt_cfr_init_pdev(pdev); + if (status != QDF_STATUS_SUCCESS) + cfr_err("cfr_initialize_pdev status=%d\n", status); + return status; } qdf_export_symbol(cfr_initialize_pdev); @@ -150,6 +153,9 @@ QDF_STATUS cfr_deinitialize_pdev(struct wlan_objmgr_pdev *pdev) status = tgt_cfr_deinit_pdev(pdev); + if (status != QDF_STATUS_SUCCESS) + cfr_err("cfr_deinitialize_pdev status=%d\n", status); + return status; } qdf_export_symbol(cfr_deinitialize_pdev);