From 2a773828bc06a399d82097e2ce72fe2372b0089e Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 4 Feb 2019 19:52:27 +0530 Subject: [PATCH] qcacld-3.0: Fix tdls idle peers data override As part of connection tracker handler, If the link is connected then current tx and rx stats are compared with configured threshold values. If the current stats fall below the threshold then idle timer is initialized and idle peer data is stored in tdls soc and given as userdata to the timer handler. The userdata is overwritten if the another tdls peer becomes idle and this can lead to wrong tdls peer teardown. Change-Id: I34638bdebe02e17e1c9e117e58352bdaab867921 CRs-Fixed: 2393320 --- .../tdls/core/src/wlan_tdls_cmds_process.c | 2 + components/tdls/core/src/wlan_tdls_ct.c | 44 ++++++++++--------- components/tdls/core/src/wlan_tdls_main.c | 4 +- components/tdls/core/src/wlan_tdls_main.h | 13 +----- .../dispatcher/inc/wlan_tdls_public_structs.h | 2 + .../tdls/dispatcher/src/wlan_tdls_ucfg_api.c | 2 + 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/components/tdls/core/src/wlan_tdls_cmds_process.c b/components/tdls/core/src/wlan_tdls_cmds_process.c index 6eb228d3ac4a..c34494ad0d4c 100644 --- a/components/tdls/core/src/wlan_tdls_cmds_process.c +++ b/components/tdls/core/src/wlan_tdls_cmds_process.c @@ -1420,6 +1420,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) if (INVALID_TDLS_PEER_ID == conn_rec[sta_idx].sta_id) { conn_rec[sta_idx].session_id = rsp->session_id; conn_rec[sta_idx].sta_id = rsp->sta_id; + conn_rec[sta_idx].index = sta_idx; qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, &rsp->peermac); tdls_warn("TDLS: STA IDX at %d is %d of mac " @@ -1531,6 +1532,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) tdls_reset_peer(vdev_obj, macaddr); conn_rec[sta_idx].sta_id = INVALID_TDLS_PEER_ID; conn_rec[sta_idx].session_id = 0xff; + conn_rec[sta_idx].index = INVALID_TDLS_PEER_INDEX; qdf_mem_zero(&conn_rec[sta_idx].peer_mac, QDF_MAC_ADDR_SIZE); diff --git a/components/tdls/core/src/wlan_tdls_ct.c b/components/tdls/core/src/wlan_tdls_ct.c index 499145c1b09d..63d8a6994c42 100644 --- a/components/tdls/core/src/wlan_tdls_ct.c +++ b/components/tdls/core/src/wlan_tdls_ct.c @@ -562,11 +562,11 @@ static struct tdls_conn_info * tdls_get_conn_info(struct tdls_soc_priv_obj *tdls_soc, uint8_t idx) { uint8_t sta_idx; - /* check if there is available index for this new TDLS STA */ for (sta_idx = 0; sta_idx < WLAN_TDLS_STA_MAX_NUM; sta_idx++) { if (idx == tdls_soc->tdls_conn_info[sta_idx].sta_id) { tdls_debug("tdls peer with sta_idx %u exists", idx); + tdls_soc->tdls_conn_info[sta_idx].index = sta_idx; return &tdls_soc->tdls_conn_info[sta_idx]; } } @@ -576,18 +576,13 @@ tdls_get_conn_info(struct tdls_soc_priv_obj *tdls_soc, uint8_t idx) } static void -tdls_ct_process_idle_handler( - struct tdls_ct_idle_peer_data *tdls_idle_peer_data) +tdls_ct_process_idle_handler(struct wlan_objmgr_vdev *vdev, + struct tdls_conn_info *tdls_info) { - struct tdls_conn_info *tdls_info; struct tdls_peer *curr_peer; - struct wlan_objmgr_vdev *vdev; struct tdls_vdev_priv_obj *tdls_vdev_obj; struct tdls_soc_priv_obj *tdls_soc_obj; - vdev = tdls_idle_peer_data->vdev; - tdls_info = tdls_idle_peer_data->tdls_info; - if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj)) return; @@ -637,22 +632,29 @@ tdls_ct_process_idle_handler( void tdls_ct_idle_handler(void *user_data) { - struct tdls_ct_idle_peer_data *tdls_idle_peer_data; struct wlan_objmgr_vdev *vdev; + struct tdls_conn_info *tdls_info; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint32_t idx; - tdls_idle_peer_data = (struct tdls_ct_idle_peer_data *) user_data; - - if (NULL == tdls_idle_peer_data || - NULL == tdls_idle_peer_data->vdev || - NULL == tdls_idle_peer_data->tdls_info) + tdls_info = (struct tdls_conn_info *)user_data; + if (!tdls_info) return; - vdev = tdls_idle_peer_data->vdev; - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, - WLAN_TDLS_NB_ID)) + idx = tdls_info->index; + if (tdls_info->index == INVALID_TDLS_PEER_INDEX) return; - tdls_ct_process_idle_handler(tdls_idle_peer_data); + tdls_soc_obj = qdf_container_of(tdls_info, struct tdls_soc_priv_obj, + tdls_conn_info[idx]); + + vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID); + if (!vdev) { + tdls_err("Unable to fetch the vdev"); + return; + } + + tdls_ct_process_idle_handler(vdev, tdls_info); wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } @@ -729,12 +731,10 @@ static void tdls_ct_process_connected_link( uint8_t sta_id = (uint8_t)curr_peer->sta_id; struct tdls_conn_info *tdls_info; tdls_info = tdls_get_conn_info(tdls_soc, sta_id); - tdls_soc->tdls_idle_peer_data.tdls_info = tdls_info; - tdls_soc->tdls_idle_peer_data.vdev = tdls_vdev->vdev; qdf_mc_timer_init(&curr_peer->peer_idle_timer, QDF_TIMER_TYPE_SW, tdls_ct_idle_handler, - &tdls_soc->tdls_idle_peer_data); + (void *)tdls_info); curr_peer->is_peer_idle_timer_initialised = true; } if (QDF_TIMER_STATE_RUNNING != @@ -1286,6 +1286,8 @@ void tdls_disable_offchan_and_teardown_links( tdls_decrement_peer_count(tdls_soc); tdls_soc->tdls_conn_info[staidx].sta_id = INVALID_TDLS_PEER_ID; tdls_soc->tdls_conn_info[staidx].session_id = 255; + tdls_soc->tdls_conn_info[staidx].index = + INVALID_TDLS_PEER_INDEX; qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, sizeof(struct qdf_mac_addr)); diff --git a/components/tdls/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c index 9df012ee3b2f..3a8ef25f41db 100644 --- a/components/tdls/core/src/wlan_tdls_main.c +++ b/components/tdls/core/src/wlan_tdls_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -423,6 +423,8 @@ static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev) tdls_decrement_peer_count(tdls_soc); tdls_soc->tdls_conn_info[staidx].sta_id = INVALID_TDLS_PEER_ID; tdls_soc->tdls_conn_info[staidx].session_id = 255; + tdls_soc->tdls_conn_info[staidx].index = + INVALID_TDLS_PEER_INDEX; qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, sizeof(struct qdf_mac_addr)); diff --git a/components/tdls/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h index e50b552bb396..d4d4a7aba4b4 100644 --- a/components/tdls/core/src/wlan_tdls_main.h +++ b/components/tdls/core/src/wlan_tdls_main.h @@ -94,10 +94,12 @@ * @session_id: session id * @sta_id: sta id * @peer_mac: peer address + * @index: index to store array offset. */ struct tdls_conn_info { uint8_t session_id; uint8_t sta_id; + uint8_t index; struct qdf_mac_addr peer_mac; }; @@ -127,16 +129,6 @@ struct tdls_conn_tracker_mac_table { uint32_t peer_timestamp_ms; }; -/** - * struct tdls_ct_idle_peer_data - connection tracker idle peer info - * @vdev: vdev object - * @tdls_info: tdls connection info - */ -struct tdls_ct_idle_peer_data { - struct wlan_objmgr_vdev *vdev; - struct tdls_conn_info *tdls_info; -}; - /** * struct tdls_set_state_db - to record set tdls state command, we need to * set correct tdls state to firmware: @@ -229,7 +221,6 @@ struct tdls_soc_priv_obj { uint16_t tdls_update_peer_state; uint16_t tdls_del_all_peers; uint32_t tdls_update_dp_vdev_flags; - struct tdls_ct_idle_peer_data tdls_idle_peer_data; qdf_spinlock_t tdls_ct_spinlock; }; diff --git a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 502193b1fade..6135fd6bfdb5 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -79,6 +79,8 @@ struct wlan_objmgr_psoc; #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 #define INVALID_TDLS_PEER_ID 0xFF +#define INVALID_TDLS_PEER_INDEX 0xFF + #define TDLS_STA_INDEX_CHECK(sta_id) \ (((sta_id) >= 0) && ((sta_id) < 0xFF)) diff --git a/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c index fd4a61cb6fd2..6b4260f97ddc 100644 --- a/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c @@ -339,6 +339,8 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { soc_obj->tdls_conn_info[sta_idx].sta_id = INVALID_TDLS_PEER_ID; + soc_obj->tdls_conn_info[sta_idx].index = + INVALID_TDLS_PEER_INDEX; soc_obj->tdls_conn_info[sta_idx].session_id = 255; qdf_mem_zero(&soc_obj->tdls_conn_info[sta_idx].peer_mac, QDF_MAC_ADDR_SIZE);