diff --git a/core/cdf/inc/cdf_list.h b/core/cdf/inc/cdf_list.h index d4b793e39c9d..2076e1c3988e 100644 --- a/core/cdf/inc/cdf_list.h +++ b/core/cdf/inc/cdf_list.h @@ -107,4 +107,6 @@ CDF_STATUS cdf_list_peek_next(cdf_list_t *p_list, cdf_list_node_t *p_node, CDF_STATUS cdf_list_remove_node(cdf_list_t *p_list, cdf_list_node_t *p_node_to_remove); +bool cdf_list_empty(cdf_list_t *list); + #endif /* __CDF_LIST_H */ diff --git a/core/cdf/src/cdf_list.c b/core/cdf/src/cdf_list.c index 1d60f9e21027..9171f22c195c 100644 --- a/core/cdf/src/cdf_list.c +++ b/core/cdf/src/cdf_list.c @@ -223,3 +223,14 @@ CDF_STATUS cdf_list_peek_next(cdf_list_t *pList, cdf_list_node_t *pNode, return CDF_STATUS_SUCCESS; } + +/** + * cdf_list_empty() - check if the list is empty + * @list: pointer to the list + * + * Return: true if the list is empty and false otherwise. + */ +bool cdf_list_empty(cdf_list_t *list) +{ + return list_empty(&list->anchor); +} diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index d86c8f1d5d20..956c97c9b57f 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1239,7 +1239,7 @@ typedef struct { uint32_t scan_id; struct wma_txrx_node *interfaces; pdev_cli_config_t pdevconfig; - struct list_head vdev_resp_queue; + cdf_list_t vdev_resp_queue; cdf_spinlock_t vdev_respq_lock; cdf_list_t wma_hold_req_queue; cdf_spinlock_t wma_hold_req_q_lock; diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index b6375a114add..c455e12b77a8 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -104,6 +104,8 @@ #define LINK_RATE_VHT 0x3 #define MAX_ENTRY_HOLD_REQ_QUEUE 2 +#define MAX_ENTRY_VDEV_RESP_QUEUE 10 + /** * struct index_data_rate_type - non vht data rate type * @beacon_rate_index: Beacon rate index diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 79e17be2c54c..e847cced08cb 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -337,14 +337,13 @@ static struct wma_target_req *wma_find_req(tp_wma_handle wma, cdf_list_peek_next(&wma->wma_hold_req_queue, node1, &node2)); + cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); if (!found) { - cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); WMA_LOGE(FL("target request not found for vdev_id %d type %d"), vdev_id, type); return NULL; } - cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); WMA_LOGD(FL("target request found for vdev id: %d type %d"), vdev_id, type); @@ -362,28 +361,48 @@ static struct wma_target_req *wma_find_req(tp_wma_handle wma, static struct wma_target_req *wma_find_vdev_req(tp_wma_handle wma, uint8_t vdev_id, uint8_t type) { - struct wma_target_req *req_msg = NULL, *tmp; + struct wma_target_req *req_msg = NULL; bool found = false; + cdf_list_node_t *node1 = NULL, *node2 = NULL; + CDF_STATUS status; cdf_spin_lock_bh(&wma->vdev_respq_lock); - list_for_each_entry_safe(req_msg, tmp, &wma->vdev_resp_queue, node) { + if (CDF_STATUS_SUCCESS != cdf_list_peek_front(&wma->vdev_resp_queue, + &node2)) { + cdf_spin_unlock_bh(&wma->vdev_respq_lock); + WMA_LOGE(FL("unable to get target req from vdev resp queue")); + return NULL; + } + + do { + node1 = node2; + req_msg = cdf_container_of(node1, struct wma_target_req, node); if (req_msg->vdev_id != vdev_id) continue; if (req_msg->type != type) continue; found = true; - list_del(&req_msg->node); + status = cdf_list_remove_node(&wma->vdev_resp_queue, node1); + if (CDF_STATUS_SUCCESS != status) { + cdf_spin_unlock_bh(&wma->vdev_respq_lock); + WMA_LOGD(FL("Failed to target req for vdev_id %d type %d"), + vdev_id, type); + return NULL; + } break; - } + } while (CDF_STATUS_SUCCESS == + cdf_list_peek_next(&wma->vdev_resp_queue, + node1, &node2)); + cdf_spin_unlock_bh(&wma->vdev_respq_lock); if (!found) { - WMA_LOGP("%s: target request not found for vdev_id %d type %d", - __func__, vdev_id, type); + WMA_LOGP(FL("target request not found for vdev_id %d type %d"), + vdev_id, type); return NULL; } - WMA_LOGD("%s: target request found for vdev id: %d type %d msg %d", - __func__, vdev_id, type, req_msg->msg_type); + WMA_LOGD(FL("target request found for vdev id: %d type %d msg %d"), + vdev_id, type, req_msg->msg_type); return req_msg; } @@ -2619,6 +2638,7 @@ struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, void *params, uint32_t timeout) { struct wma_target_req *req; + CDF_STATUS status; req = cdf_mem_malloc(sizeof(*req)); if (!req) { @@ -2636,7 +2656,15 @@ struct wma_target_req *wma_fill_vdev_req(tp_wma_handle wma, wma_vdev_resp_timer, req); cdf_mc_timer_start(&req->event_timeout, timeout); cdf_spin_lock_bh(&wma->vdev_respq_lock); - list_add_tail(&req->node, &wma->vdev_resp_queue); + status = cdf_list_insert_back(&wma->vdev_resp_queue, &req->node); + if (CDF_STATUS_SUCCESS != status) { + cdf_spin_unlock_bh(&wma->vdev_respq_lock); + WMA_LOGE(FL("Failed add request in queue for vdev_id %d type %d"), + vdev_id, type); + cdf_mem_free(req); + return NULL; + } + cdf_spin_unlock_bh(&wma->vdev_respq_lock); return req; } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index 86868bf3885d..94ee880aaab0 100644 --- a/core/wma/src/wma_main.c +++ b/core/wma/src/wma_main.c @@ -1687,7 +1687,8 @@ CDF_STATUS wma_open(void *cds_context, goto err_event_init; } - INIT_LIST_HEAD(&wma_handle->vdev_resp_queue); + cdf_list_init(&wma_handle->vdev_resp_queue, + MAX_ENTRY_VDEV_RESP_QUEUE); cdf_spinlock_init(&wma_handle->vdev_respq_lock); cdf_list_init(&wma_handle->wma_hold_req_queue, MAX_ENTRY_HOLD_REQ_QUEUE); @@ -2769,7 +2770,7 @@ static void wma_cleanup_hold_req(tp_wma_handle wma) do { node1 = node2; - req_msg = (struct wma_target_req *)node1; + req_msg = cdf_container_of(node1, struct wma_target_req, node); status = cdf_list_remove_node(&wma->wma_hold_req_queue, node1); if (CDF_STATUS_SUCCESS != status) { cdf_spin_unlock_bh(&wma->wma_hold_req_q_lock); @@ -2795,13 +2796,29 @@ static void wma_cleanup_hold_req(tp_wma_handle wma) */ static void wma_cleanup_vdev_resp(tp_wma_handle wma) { - struct wma_target_req *msg, *tmp; + struct wma_target_req *req_msg = NULL; + cdf_list_node_t *node1 = NULL; + CDF_STATUS status; cdf_spin_lock_bh(&wma->vdev_respq_lock); - list_for_each_entry_safe(msg, tmp, &wma->vdev_resp_queue, node) { - list_del(&msg->node); - cdf_mc_timer_destroy(&msg->event_timeout); - cdf_mem_free(msg); + if (cdf_list_empty(&wma->vdev_resp_queue)) { + cdf_spin_unlock_bh(&wma->vdev_respq_lock); + WMA_LOGI(FL("request queue maybe empty")); + return; + } + + while (CDF_STATUS_SUCCESS != cdf_list_peek_front(&wma->vdev_resp_queue, + &node1)) { + req_msg = cdf_container_of(node1, struct wma_target_req, node); + status = cdf_list_remove_node(&wma->vdev_resp_queue, node1); + if (CDF_STATUS_SUCCESS != status) { + cdf_spin_unlock_bh(&wma->vdev_respq_lock); + WMA_LOGE(FL("Failed to remove request for vdev_id %d type %d"), + req_msg->vdev_id, req_msg->type); + return; + } + cdf_mc_timer_destroy(&req_msg->event_timeout); + cdf_mem_free(req_msg); } cdf_spin_unlock_bh(&wma->vdev_respq_lock); }