diff --git a/os_if/linux/tdls/src/wlan_cfg80211_tdls.c b/os_if/linux/tdls/src/wlan_cfg80211_tdls.c index e3e532791263..b1e376c4a0e9 100644 --- a/os_if/linux/tdls/src/wlan_cfg80211_tdls.c +++ b/os_if/linux/tdls/src/wlan_cfg80211_tdls.c @@ -128,16 +128,6 @@ void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev) ucfg_tdls_notify_reset_adapter(vdev); } -static void hdd_notify_sta_connect_callback(struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - cfg80211_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); -} - void hdd_notify_sta_connect(uint8_t session_id, bool tdls_chan_swit_prohibited, @@ -161,22 +151,7 @@ hdd_notify_sta_connect(uint8_t session_id, notify_info.vdev = vdev; notify_info.tdls_chan_swit_prohibited = tdls_chan_swit_prohibited; notify_info.tdls_prohibited = tdls_prohibited; - notify_info.callback = hdd_notify_sta_connect_callback; - status = ucfg_tdls_notify_sta_connect(¬ify_info); - if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_notify_sta_connect failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); - } -} - -static void hdd_notify_sta_disconnect_callback(struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - cfg80211_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + ucfg_tdls_notify_sta_connect(¬ify_info); } void hdd_notify_sta_disconnect(uint8_t session_id, @@ -204,12 +179,7 @@ void hdd_notify_sta_disconnect(uint8_t session_id, notify_info.tdls_prohibited = false; notify_info.vdev = vdev; notify_info.user_disconnect = user_disconnect; - notify_info.callback = hdd_notify_sta_disconnect_callback; - status = ucfg_tdls_notify_sta_disconnect(¬ify_info); - if (QDF_IS_STATUS_ERROR(status)) { - cfg80211_err("ucfg_tdls_notify_sta_disconnect failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); - } + ucfg_tdls_notify_sta_disconnect(¬ify_info); } int wlan_cfg80211_tdls_add_peer(struct wlan_objmgr_pdev *pdev, struct net_device *dev, const uint8_t *mac) diff --git a/umac/tdls/core/src/wlan_tdls_ct.c b/umac/tdls/core/src/wlan_tdls_ct.c index e81c2e5b428a..7be612d4b0ce 100644 --- a/umac/tdls/core/src/wlan_tdls_ct.c +++ b/umac/tdls/core/src/wlan_tdls_ct.c @@ -1121,6 +1121,15 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, return ret_value; } +static QDF_STATUS tdls_delete_all_tdls_peers_flush_cb(struct scheduler_msg *msg) +{ + if (msg && msg->bodyptr) + qdf_mem_free(msg->bodyptr); + + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} /** * tdls_delete_all_tdls_peers(): send request to delete tdls peers * @vdev: vdev object @@ -1166,10 +1175,15 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, msg.type = del_msg->msg_type; msg.bodyptr = del_msg; + msg.flush_callback = tdls_delete_all_tdls_peers_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_PE, QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post delete all peer req failed, status %d", status); + qdf_mem_free(del_msg); + } wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); return status; diff --git a/umac/tdls/core/src/wlan_tdls_main.c b/umac/tdls/core/src/wlan_tdls_main.c index 312a74bf6e77..7295adda9689 100644 --- a/umac/tdls/core/src/wlan_tdls_main.c +++ b/umac/tdls/core/src/wlan_tdls_main.c @@ -451,10 +451,10 @@ static QDF_STATUS tdls_reset_all_peers( status = tdls_process_reset_all_peers(delete_all_peers_ind->vdev); - if (delete_all_peers_ind->callback) - delete_all_peers_ind->callback(delete_all_peers_ind->vdev); - + wlan_objmgr_vdev_release_ref(delete_all_peers_ind->vdev, + WLAN_TDLS_SB_ID); qdf_mem_free(delete_all_peers_ind); + return status; } @@ -890,6 +890,33 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, return NULL; } +static QDF_STATUS tdls_post_msg_flush_cb(struct scheduler_msg *msg) +{ + void *ptr = msg->bodyptr; + struct wlan_objmgr_vdev *vdev = NULL; + + switch (msg->type) { + case TDLS_NOTIFY_STA_DISCONNECTION: + vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(ptr); + break; + + case TDLS_DELETE_ALL_PEERS_INDICATION: + vdev = ((struct tdls_delete_all_peers_params *)ptr)->vdev; + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(ptr); + break; + + case TDLS_CMD_SCAN_DONE: + case TDLS_CMD_SESSION_INCREMENT: + case TDLS_CMD_SESSION_DECREMENT: + break; + } + + return QDF_STATUS_SUCCESS; +} + /** * tdls_process_session_update() - update session count information * @psoc: soc object @@ -907,6 +934,7 @@ static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, msg.bodyptr = psoc; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_post_msg_flush_cb; msg.type = (uint16_t)cmd_type; status = scheduler_post_message(QDF_MODULE_ID_TDLS, @@ -1107,10 +1135,9 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) status = tdls_process_sta_connect(notify); - if (notify->callback) - notify->callback(notify->vdev); - + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); qdf_mem_free(notify); + return status; } @@ -1196,10 +1223,9 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) status = tdls_process_sta_disconnect(notify); - if (notify->callback) - notify->callback(notify->vdev); - + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); qdf_mem_free(notify); + return status; } @@ -1228,12 +1254,13 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } -QDF_STATUS tdls_peers_deleted_notification( - struct tdls_sta_notify_params *notify_info) +QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { @@ -1241,30 +1268,50 @@ QDF_STATUS tdls_peers_deleted_notification( return QDF_STATUS_E_NULL_VALUE; } - *notify = *notify_info; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + WLAN_TDLS_NB_ID); + + if (!vdev) { + tdls_err("vdev not exist for the vdev id %d", + vdev_id); + qdf_mem_free(notify); + return QDF_STATUS_E_INVAL; + } + + notify->lfr_roam = true; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->session_id = vdev_id; + notify->vdev = vdev; + notify->user_disconnect = false; msg.bodyptr = notify; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_post_msg_flush_cb; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); qdf_mem_free(notify); tdls_alert("message post failed "); + return QDF_STATUS_E_FAILURE; } return QDF_STATUS_SUCCESS; } -QDF_STATUS tdls_delete_all_peers_indication( - struct tdls_delete_all_peers_params *delete_peers_ind) +QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id) { struct scheduler_msg msg = {0, }; struct tdls_delete_all_peers_params *indication; QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; indication = qdf_mem_malloc(sizeof(*indication)); if (!indication) { @@ -1272,16 +1319,29 @@ QDF_STATUS tdls_delete_all_peers_indication( return QDF_STATUS_E_NULL_VALUE; } - *indication = *delete_peers_ind; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + WLAN_TDLS_SB_ID); + + if (!vdev) { + tdls_err("vdev not exist for the session id %d", + vdev_id); + qdf_mem_free(indication); + return QDF_STATUS_E_INVAL; + } + + indication->vdev = vdev; msg.bodyptr = indication; msg.callback = tdls_process_cmd; msg.type = TDLS_DELETE_ALL_PEERS_INDICATION; + msg.flush_callback = tdls_post_msg_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); qdf_mem_free(indication); tdls_alert("message post failed "); return QDF_STATUS_E_FAILURE; @@ -1450,15 +1510,10 @@ QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode) if (!tdls_set_mode || !tdls_set_mode->vdev) return QDF_STATUS_E_INVAL; - if (QDF_STATUS_SUCCESS != - wlan_objmgr_vdev_try_get_ref(tdls_set_mode->vdev, - WLAN_TDLS_NB_ID)) - return QDF_STATUS_E_INVAL; - status = tdls_get_vdev_objects(tdls_set_mode->vdev, &tdls_vdev, &tdls_soc); - if (status != QDF_STATUS_SUCCESS) + if (QDF_IS_STATUS_ERROR(status)) goto release_mode_ref; tdls_set_current_mode(tdls_soc, @@ -1518,12 +1573,12 @@ static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) msg.bodyptr = tdls_soc; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_post_msg_flush_cb; msg.type = TDLS_CMD_SCAN_DONE; - scheduler_post_message(QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_OS_IF, &msg); - return QDF_STATUS_SUCCESS; + return scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); } void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, diff --git a/umac/tdls/core/src/wlan_tdls_main.h b/umac/tdls/core/src/wlan_tdls_main.h index fc1230429131..c03eb16abf36 100644 --- a/umac/tdls/core/src/wlan_tdls_main.h +++ b/umac/tdls/core/src/wlan_tdls_main.h @@ -575,7 +575,7 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); /** * tdls_notify_reset_adapter() - notify reset adapter - * @vdev: vdev object manager + * @vdev: vdev object * * Notify TDLS about the adapter reset * @@ -585,7 +585,8 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); /** * tdls_peers_deleted_notification() - peer delete notification - * @notify_info: peer info + * @psoc: soc object + * @vdev_id: vdev id * * Legacy lim layer will delete tdls peers for roaming and heart beat failures * and notify the component about the delete event to update the tdls. @@ -593,8 +594,8 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); * * Return: QDF_STATUS */ -QDF_STATUS tdls_peers_deleted_notification( - struct tdls_sta_notify_params *notify_info); +QDF_STATUS tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); /** * tdls_notify_decrement_session() - Notify the session decrement @@ -727,13 +728,14 @@ QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, /** * tdls_delete_all_peers_indication() - update tdls status info - * @delete_peers_ind: Delete peers indication params + * @psoc: soc object + * @vdev_id: vdev id * * Notify tdls component to cleanup all peers * * Return: QDF_STATUS. */ -QDF_STATUS tdls_delete_all_peers_indication( - struct tdls_delete_all_peers_params *delete_peers_ind); +QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id); #endif diff --git a/umac/tdls/core/src/wlan_tdls_mgmt.c b/umac/tdls/core/src/wlan_tdls_mgmt.c index 0b4000e3fcd2..47b30c4f9bc6 100644 --- a/umac/tdls/core/src/wlan_tdls_mgmt.c +++ b/umac/tdls/core/src/wlan_tdls_mgmt.c @@ -213,6 +213,19 @@ tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req, return QDF_STATUS_SUCCESS; } +static QDF_STATUS tdls_activate_send_mgmt_request_flush_cb( + struct scheduler_msg *msg) +{ + struct tdls_send_mgmt_request *tdls_mgmt_req; + + tdls_mgmt_req = msg->bodyptr; + + qdf_mem_free(tdls_mgmt_req); + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS tdls_activate_send_mgmt_request( struct tdls_action_frame_request *action_req) { @@ -298,10 +311,15 @@ static QDF_STATUS tdls_activate_send_mgmt_request( msg.type = tdls_soc_obj->tdls_send_mgmt_req; msg.bodyptr = tdls_mgmt_req; + msg.flush_callback = tdls_activate_send_mgmt_request_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post msg, status %d", status); + qdf_mem_free(tdls_mgmt_req); + } wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); diff --git a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 261a1e9af8f3..9fbb273eefe3 100644 --- a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -587,17 +587,9 @@ typedef QDF_STATUS uint32_t vdev_param, bool is_link_up); -/* This callback is to release vdev ref for tdls sta notify msg */ -typedef void (*tdls_sta_notify_callback)(struct wlan_objmgr_vdev *vdev); - /* This callback is to release vdev ref for tdls offchan param related msg */ typedef void (*tdls_offchan_parms_callback)(struct wlan_objmgr_vdev *vdev); -/* This callback is to release vdev ref for tdls_delete_all_peers_ - * callback related msg. - */ -typedef void (*tdls_delete_all_peers_callback)(struct wlan_objmgr_vdev *vdev); - /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -1076,17 +1068,14 @@ struct tdls_sta_notify_params { bool lfr_roam; bool user_disconnect; uint8_t session_id; - tdls_sta_notify_callback callback; }; /** * struct tdls_delete_all_peers_params - TDLS set mode params * @vdev: vdev object - * @callback: callback to release vdev ref */ struct tdls_delete_all_peers_params { struct wlan_objmgr_vdev *vdev; - tdls_delete_all_peers_callback callback; }; /** diff --git a/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c b/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c index cf43a2f64b06..bb09a0e8b4a1 100644 --- a/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c +++ b/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c @@ -170,6 +170,19 @@ QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +static QDF_STATUS tgt_tdls_event_flush_cb(struct scheduler_msg *msg) +{ + struct tdls_event_notify *notify; + + notify = msg->bodyptr; + if (notify && notify->vdev) { + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(notify); + } + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, struct tdls_event_info *info) @@ -204,6 +217,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, msg.bodyptr = notify; msg.callback = tdls_process_evt; + msg.flush_callback = tgt_tdls_event_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, @@ -217,6 +231,23 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, return status; } +static QDF_STATUS tgt_tdls_mgmt_frame_rx_flush_cb(struct scheduler_msg *msg) +{ + struct tdls_rx_mgmt_event *rx_mgmt_event; + + rx_mgmt_event = msg->bodyptr; + + if (rx_mgmt_event) { + if (rx_mgmt_event->rx_mgmt) + qdf_mem_free(rx_mgmt_event->rx_mgmt); + + qdf_mem_free(rx_mgmt_event); + } + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( struct wlan_objmgr_psoc *psoc, @@ -285,9 +316,14 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( msg.type = TDLS_EVENT_RX_MGMT; msg.bodyptr = rx_mgmt_event; msg.callback = tdls_process_rx_frame; + msg.flush_callback = tgt_tdls_mgmt_frame_rx_flush_cb; status = scheduler_post_message(QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(rx_mgmt); + qdf_mem_free(rx_mgmt_event); + } qdf_nbuf_free(buf); @@ -333,92 +369,15 @@ release_nbuf: return status; } -static void tgt_tdls_peers_deleted_notification_callback( - struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - tdls_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); -} - void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, - uint32_t session_id) + uint32_t session_id) { - struct wlan_objmgr_vdev *vdev; - struct tdls_sta_notify_params notify_info; - QDF_STATUS status; - - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, - session_id, - WLAN_TDLS_SB_ID); - - if (!vdev) { - tdls_err("vdev not exist for the session id %d", - session_id); - return; - } - - notify_info.lfr_roam = true; - notify_info.tdls_chan_swit_prohibited = false; - notify_info.tdls_prohibited = false; - notify_info.session_id = session_id; - notify_info.vdev = vdev; - notify_info.user_disconnect = false; - notify_info.callback = tgt_tdls_peers_deleted_notification_callback; - status = tdls_peers_deleted_notification(¬ify_info); - if (QDF_IS_STATUS_ERROR(status)) { - tdls_err("tdls_peers_deleted_notification failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); - } -} - -/** - * tgt_tdls_delete_all_peers_ind_callback()- Callback to call from - * TDLS component - * @psoc: soc object - * @session_id: session id - * - * This function release the obj mgr vdev ref - * - * Return: None - */ -static void tgt_tdls_delete_all_peers_ind_callback( - struct wlan_objmgr_vdev *vdev) -{ - if (!vdev) { - tdls_err("vdev is NULL"); - return; - } - - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + tdls_peers_deleted_notification(psoc, session_id); } void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, uint32_t session_id) { - struct wlan_objmgr_vdev *vdev; - struct tdls_delete_all_peers_params delete_peers_ind; - QDF_STATUS status; - vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, - session_id, - WLAN_TDLS_SB_ID); - - if (!vdev) { - tdls_err("vdev not exist for the session id %d", - session_id); - return; - } - - delete_peers_ind.vdev = vdev; - delete_peers_ind.callback = tgt_tdls_delete_all_peers_ind_callback; - status = tdls_delete_all_peers_indication(&delete_peers_ind); - if (QDF_IS_STATUS_ERROR(status)) { - tdls_err("tdls_delete_all_peers_indication failed"); - wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); - } + tdls_delete_all_peers_indication(psoc, session_id); } - diff --git a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c index 62e5a73c24f0..e1936cfc6252 100644 --- a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c @@ -638,6 +638,41 @@ static QDF_STATUS tdls_send_mgmt_frame_flush_callback(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } +static QDF_STATUS ucfg_tdls_post_msg_flush_cb(struct scheduler_msg *msg) +{ + void *ptr = msg->bodyptr; + struct wlan_objmgr_vdev *vdev = NULL; + + switch (msg->type) { + case TDLS_CMD_TEARDOWN_LINKS: + case TDLS_NOTIFY_RESET_ADAPTERS: + ptr = NULL; + break; + case TDLS_NOTIFY_STA_CONNECTION: + vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; + break; + case TDLS_NOTIFY_STA_DISCONNECTION: + vdev = ((struct tdls_sta_notify_params *)ptr)->vdev; + break; + case TDLS_CMD_SET_TDLS_MODE: + vdev = ((struct tdls_set_mode_params *)ptr)->vdev; + break; + case TDLS_CMD_TX_ACTION: + case TDLS_CMD_SET_RESPONDER: + break; + } + + if (vdev) + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + + if (ptr) + qdf_mem_free(ptr); + + msg->bodyptr = NULL; + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *req) { @@ -719,10 +754,15 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) msg.bodyptr = msg_req; msg.callback = tdls_process_cmd; + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; msg.type = TDLS_CMD_SET_RESPONDER; status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS, QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post msg, status %d", status); + qdf_mem_free(msg_req); + } return status; } @@ -740,6 +780,7 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) msg.bodyptr = vdev; msg.callback = tdls_process_cmd; + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; msg.type = TDLS_CMD_TEARDOWN_LINKS; status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS, @@ -761,6 +802,7 @@ QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) tdls_debug("Enter "); msg.bodyptr = vdev; msg.callback = tdls_process_cmd; + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; msg.type = TDLS_NOTIFY_RESET_ADAPTERS; status = scheduler_post_message(QDF_MODULE_ID_HDD, QDF_MODULE_ID_TDLS, @@ -769,10 +811,11 @@ QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) } QDF_STATUS ucfg_tdls_notify_sta_connect( - struct tdls_sta_notify_params *notify_info) + struct tdls_sta_notify_params *notify_info) { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; + QDF_STATUS status; if (!notify_info || !notify_info->vdev) { tdls_err("notify_info %pK", notify_info); @@ -781,20 +824,28 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( tdls_debug("Enter "); notify = qdf_mem_malloc(sizeof(*notify)); - if (!notify) + if (!notify) { + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); return QDF_STATUS_E_NULL_VALUE; + } *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_CONNECTION; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_TARGET_IF, &msg); + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post message, status %d", status); + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(notify); + } tdls_debug("Exit "); - return QDF_STATUS_SUCCESS; + return status; } QDF_STATUS ucfg_tdls_notify_sta_disconnect( @@ -802,6 +853,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; + QDF_STATUS status; if (!notify_info || !notify_info->vdev) { tdls_err("notify_info %pK", notify_info); @@ -819,9 +871,15 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_TARGET_IF, &msg); + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to post message, status %d", status); + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(notify); + } tdls_debug("Exit "); @@ -833,6 +891,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( { struct scheduler_msg msg = {0, }; struct tdls_set_mode_params *set_mode; + QDF_STATUS status; if (!set_mode_params || !set_mode_params->vdev) { tdls_err("set_mode_params %pK", set_mode_params); @@ -842,8 +901,17 @@ QDF_STATUS ucfg_tdls_set_operating_mode( tdls_debug("Enter "); set_mode = qdf_mem_malloc(sizeof(*set_mode)); - if (!set_mode) + if (!set_mode) { + tdls_err("memory allocate fail"); return QDF_STATUS_E_NULL_VALUE; + } + + status = wlan_objmgr_vdev_try_get_ref(set_mode->vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("failed to get vdev ref"); + qdf_mem_free(set_mode); + return status; + } set_mode->source = set_mode_params->source; set_mode->tdls_mode = set_mode_params->tdls_mode; @@ -853,9 +921,14 @@ QDF_STATUS ucfg_tdls_set_operating_mode( msg.bodyptr = set_mode; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_SET_TDLS_MODE; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_OS_IF, &msg); + msg.flush_callback = ucfg_tdls_post_msg_flush_cb; + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + wlan_objmgr_vdev_release_ref(set_mode->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(set_mode); + } tdls_debug("Exit ");